Final KRObject file format for v1.1

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40185
This commit is contained in:
kearwood
2012-12-12 22:15:09 +00:00
parent 8bd02e4bbc
commit fe7d4f8238
5 changed files with 134 additions and 92 deletions

View File

@@ -213,7 +213,7 @@ bool KRModel::hasTransparency() {
vector<KRModel::Submesh *> KRModel::getSubmeshes() {
if(m_submeshes.size() == 0) {
pack_header *pHeader = (pack_header *)m_pData->getStart();
pack_header *pHeader = getHeader();
pack_material *pPackMaterials = (pack_material *)(pHeader+1);
m_submeshes.clear();
for(int iMaterial=0; iMaterial < pHeader->submesh_count; iMaterial++) {
@@ -223,8 +223,8 @@ vector<KRModel::Submesh *> KRModel::getSubmeshes() {
pSubmesh->start_vertex = pPackMaterial->start_vertex;
pSubmesh->vertex_count = pPackMaterial->vertex_count;
strncpy(pSubmesh->szMaterialName, pPackMaterial->szName, 256);
pSubmesh->szMaterialName[255] = '\0';
strncpy(pSubmesh->szMaterialName, pPackMaterial->szName, KRENGINE_MAX_NAME_LENGTH);
pSubmesh->szMaterialName[KRENGINE_MAX_NAME_LENGTH-1] = '\0';
//fprintf(stderr, "Submesh material: \"%s\"\n", pSubmesh->szMaterialName);
m_submeshes.push_back(pSubmesh);
}
@@ -235,7 +235,7 @@ vector<KRModel::Submesh *> KRModel::getSubmeshes() {
void KRModel::renderSubmesh(int iSubmesh) {
unsigned char *pVertexData = getVertexData();
pack_header *pHeader = (pack_header *)m_pData->getStart();
pack_header *pHeader = getHeader();
int cBuffers = (pHeader->vertex_count + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE;
vector<KRModel::Submesh *> submeshes = getSubmeshes();
@@ -248,7 +248,6 @@ void KRModel::renderSubmesh(int iSubmesh) {
while(cVertexes > 0) {
GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : pHeader->vertex_count % MAX_VBO_SIZE;
int vertex_size = m_vertex_size;
assert(pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size >= m_pData->getStart());
void *vbo_end = (unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size + vertex_size * cBufferVertexes;
void *buffer_end = m_pData->getEnd();
@@ -277,14 +276,7 @@ void KRModel::renderSubmesh(int iSubmesh) {
}
}
unsigned char *KRModel::getVertexData() const {
pack_header *pHeader = (pack_header *)m_pData->getStart();
pack_material *pPackMaterials = (pack_material *)(pHeader+1);
return (unsigned char *)(pPackMaterials + pHeader->submesh_count);
}
void KRModel::LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> uva, std::vector<KRVector2> uvb, std::vector<KRVector3> normals, std::vector<KRVector3> tangents, std::vector<int> submesh_starts, std::vector<int> submesh_lengths, std::vector<std::string> material_names, std::list<std::string> bone_names, std::vector<std::vector<int> > bone_indexes, std::vector<std::vector<float> > bone_weights) {
void KRModel::LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> uva, std::vector<KRVector2> uvb, std::vector<KRVector3> normals, std::vector<KRVector3> tangents, std::vector<int> submesh_starts, std::vector<int> submesh_lengths, std::vector<std::string> material_names, std::vector<std::string> bone_names, std::vector<std::vector<int> > bone_indexes, std::vector<std::vector<float> > bone_weights) {
clearData();
@@ -308,18 +300,23 @@ void KRModel::LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> u
if(uvb.size()) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB);
}
if(bone_names.size()) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_BONEINDEXES) + (1 << KRENGINE_ATTRIB_BONEWEIGHTS);
}
size_t vertex_size = VertexSizeForAttributes(vertex_attrib_flags);
int submesh_count = submesh_lengths.size();
int vertex_count = vertices.size();
size_t new_file_size = sizeof(pack_header) + sizeof(pack_material) * submesh_count + vertex_size * vertex_count;
size_t submesh_count = submesh_lengths.size();
size_t vertex_count = vertices.size();
size_t bone_count = bone_names.size();
size_t new_file_size = sizeof(pack_header) + sizeof(pack_material) * submesh_count + sizeof(pack_bone) * bone_count + vertex_size * vertex_count;
m_pData->expand(new_file_size);
pack_header *pHeader = (pack_header *)m_pData->getStart();
pack_header *pHeader = getHeader();
memset(pHeader, 0, sizeof(pack_header));
pHeader->vertex_attrib_flags = vertex_attrib_flags;
pHeader->submesh_count = submesh_lengths.size();
pHeader->vertex_count = vertices.size();
pHeader->submesh_count = (__int32_t)submesh_count;
pHeader->vertex_count = (__int32_t)vertex_count;
pHeader->bone_count = (__int32_t)bone_count;
strcpy(pHeader->szTag, "KROBJPACK1.1 ");
updateAttributeOffsets();
@@ -329,7 +326,14 @@ void KRModel::LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> u
pack_material *pPackMaterial = pPackMaterials + iMaterial;
pPackMaterial->start_vertex = submesh_starts[iMaterial];
pPackMaterial->vertex_count = submesh_lengths[iMaterial];
strncpy(pPackMaterial->szName, material_names[iMaterial].c_str(), 256);
memset(pPackMaterial->szName, 0, KRENGINE_MAX_NAME_LENGTH);
strncpy(pPackMaterial->szName, material_names[iMaterial].c_str(), KRENGINE_MAX_NAME_LENGTH);
}
for(int bone_index=0; bone_index < bone_count; bone_index++) {
pack_bone *bone = getBone(bone_index);
memset(bone->szName, 0, KRENGINE_MAX_NAME_LENGTH);
strncpy(bone->szName, bone_names[bone_index].c_str(), KRENGINE_MAX_NAME_LENGTH);
}
bool bFirstVertex = true;
@@ -340,6 +344,12 @@ void KRModel::LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> u
for(int iVertex=0; iVertex < vertices.size(); iVertex++) {
KRVector3 source_vertex = vertices[iVertex];
setVertexPosition(iVertex, source_vertex);
if(bone_names.size()) {
for(int bone_weight_index=0; bone_weight_index<KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; bone_weight_index++) {
setBoneIndex(iVertex, bone_weight_index, bone_indexes[iVertex][bone_weight_index]);
setBoneWeight(iVertex, bone_weight_index, bone_weights[iVertex][bone_weight_index]);
}
}
if(bFirstVertex) {
bFirstVertex = false;
m_minPoint = source_vertex;
@@ -354,23 +364,15 @@ void KRModel::LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> u
}
if(uva.size() > iVertex) {
setVertexUVA(iVertex, uva[iVertex]);
} else {
setVertexUVA(iVertex, KRVector2::Zero());
}
if(uvb.size() > iVertex) {
setVertexUVB(iVertex, uvb[iVertex]);
} else {
setVertexUVB(iVertex, KRVector2::Zero());
}
if(normals.size() > iVertex) {
setVertexNormal(iVertex, normals[iVertex]);
} else {
setVertexNormal(iVertex, KRVector3::Zero());
}
if(tangents.size() > iVertex) {
setVertexTangent(iVertex, tangents[iVertex]);
} else {
setVertexTangent(iVertex, KRVector3::Zero());
}
}
@@ -475,9 +477,20 @@ KRModel::pack_header *KRModel::getHeader() const
return (pack_header *)m_pData->getStart();
}
KRModel::pack_bone *KRModel::getBone(int index)
{
pack_header *header = getHeader();
return (pack_bone *)((unsigned char *)m_pData->getStart()) + sizeof(pack_header) + sizeof(pack_material) * header->submesh_count;
}
unsigned char *KRModel::getVertexData() const {
pack_header *pHeader = getHeader();
return ((unsigned char *)m_pData->getStart()) + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count;
}
KRModel::pack_material *KRModel::getSubmesh(int mesh_index)
{
return (pack_material *)(getHeader()+1) + mesh_index;
return (pack_material *)((unsigned char *)m_pData->getStart() + sizeof(pack_header)) + mesh_index;
}
unsigned char *KRModel::getVertexData(int index) const
@@ -487,7 +500,7 @@ unsigned char *KRModel::getVertexData(int index) const
int KRModel::getSubmeshCount()
{
pack_header *header = (pack_header *)m_pData->getStart();
pack_header *header = getHeader();
return header->submesh_count;
}
@@ -579,6 +592,31 @@ void KRModel::setVertexUVB(int index, const KRVector2 &v)
vert[1] = v.y;
}
int KRModel::getBoneIndex(int index, int weight_index) const
{
unsigned char *vert = (unsigned char *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_BONEINDEXES]);
return vert[weight_index];
}
void KRModel::setBoneIndex(int index, int weight_index, int bone_index)
{
unsigned char *vert = (unsigned char *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_BONEINDEXES]);
vert[weight_index] = bone_index;
}
float KRModel::getBoneWeight(int index, int weight_index) const
{
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_BONEWEIGHTS]);
return vert[weight_index];
}
void KRModel::setBoneWeight(int index, int weight_index, float bone_weight)
{
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_BONEWEIGHTS]);
vert[weight_index] = bone_weight;
}
size_t KRModel::VertexSizeForAttributes(__int32_t vertex_attrib_flags)
{
size_t data_size = 0;
@@ -616,7 +654,18 @@ void KRModel::updateAttributeOffsets()
} else {
m_vertex_attribute_offset[i] = -1;
}
mask = (mask << 1) & 1;
mask = (mask << 1) | 1;
}
m_vertex_size = VertexSizeForAttributes(header->vertex_attrib_flags);
}
size_t KRModel::AttributeOffset(__int32_t vertex_attrib, __int32_t vertex_attrib_flags)
{
int mask = 0;
for(int i=0; i < vertex_attrib; i++) {
if(vertex_attrib_flags & (1 << i)) {
mask |= (1 << i);
}
}
return VertexSizeForAttributes(mask);
}

View File

@@ -43,6 +43,8 @@ using std::list;
#define MAX_VBO_SIZE 65535
#define KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX 4
#define KRENGINE_MAX_NAME_LENGTH 256
// MAX_VBO_SIZE must be divisible by 3 so triangles aren't split across VBO objects...
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
@@ -78,7 +80,7 @@ public:
virtual std::string getExtension();
virtual bool save(const std::string& path);
void LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> uva, std::vector<KRVector2> uvb, std::vector<KRVector3> normals, std::vector<KRVector3> tangents, std::vector<int> submesh_starts, std::vector<int> submesh_lengths, std::vector<std::string> material_names, std::list<std::string> bone_names, std::vector<std::vector<int> > bone_indexes, std::vector<std::vector<float> > bone_weights);
void LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> uva, std::vector<KRVector2> uvb, std::vector<KRVector3> normals, std::vector<KRVector3> tangents, std::vector<int> submesh_starts, std::vector<int> submesh_lengths, std::vector<std::string> material_names, std::vector<std::string> bone_names, std::vector<std::vector<int> > bone_indexes, std::vector<std::vector<float> > bone_weights);
void loadPack(KRDataBlock *data);
@@ -108,7 +110,7 @@ public:
typedef struct {
GLint start_vertex;
GLsizei vertex_count;
char szMaterialName[256];
char szMaterialName[KRENGINE_MAX_NAME_LENGTH];
} Submesh;
typedef struct {
@@ -135,8 +137,12 @@ public:
typedef struct {
int32_t start_vertex;
int32_t vertex_count;
char szName[256];
char szName[KRENGINE_MAX_NAME_LENGTH];
} pack_material;
typedef struct {
char szName[KRENGINE_MAX_NAME_LENGTH];
} pack_bone;
int getLODCoverage() const;
std::string getLODBaseName() const;
@@ -152,11 +158,19 @@ public:
KRVector3 getVertexTangent(int index) const;
KRVector2 getVertexUVA(int index) const;
KRVector2 getVertexUVB(int index) const;
int getBoneIndex(int index, int weight_index) const;
float getBoneWeight(int index, int weight_index) const;
void setVertexPosition(int index, const KRVector3 &v);
void setVertexNormal(int index, const KRVector3 &v);
void setVertexTangent(int index, const KRVector3 & v);
void setVertexUVA(int index, const KRVector2 &v);
void setVertexUVB(int index, const KRVector2 &v);
void setBoneIndex(int index, int weight_index, int bone_index);
void setBoneWeight(int index, int weight_index, float bone_weight);
static size_t VertexSizeForAttributes(__int32_t vertex_attrib_flags);
static size_t AttributeOffset(__int32_t vertex_attrib, __int32_t vertex_attrib_flags);
private:
int m_lodCoverage; // This LOD level is activated when the bounding box of the model will cover less than this percent of the screen (100 = highest detail model)
@@ -172,12 +186,13 @@ private:
typedef struct {
char szTag[16];
int32_t format_type; // 0 == Triangle list, 1 == Indexed list, rest are reserved (model_format_t enum)
int32_t format_type; // 0 == Triangle list, 1 == Indexed triangle list, 2 == Indexed triangle strips, rest are reserved (model_format_t enum)
int32_t vertex_attrib_flags;
int32_t vertex_count;
int32_t submesh_count;
int32_t bone_count;
float minx, miny, minz, maxx, maxy, maxz; // Axis aligned bounding box, in model's coordinate space
unsigned char reserved[412]; // Pad out to 512 bytes
unsigned char reserved[452]; // Pad out to 512 bytes
} pack_header;
vector<Submesh *> m_submeshes;
@@ -191,13 +206,13 @@ private:
void setName(const std::string name);
static size_t VertexSizeForAttributes(__int32_t vertex_attrib_flags);
pack_material *getSubmesh(int mesh_index);
unsigned char *getVertexData() const;
unsigned char *getVertexData(int index) const;
pack_header *getHeader() const;
pack_bone *getBone(int index);
};

View File

@@ -165,99 +165,79 @@ void KRModelManager::bindVBO(GLvoid *data, GLsizeiptr size, bool enable_vertex,
void KRModelManager::configureAttribs(bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights)
{
__int32_t attributes = 0;
if(enable_vertex) {
attributes |= (1 << KRModel::KRENGINE_ATTRIB_VERTEX);
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_VERTEX));
} else {
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_VERTEX));
}
if(enable_normal) {
attributes |= (1 << KRModel::KRENGINE_ATTRIB_NORMAL);
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_NORMAL));
} else {
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_NORMAL));
}
if(enable_tangent) {
attributes |= (1 << KRModel::KRENGINE_ATTRIB_TANGENT);
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TANGENT));
} else {
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TANGENT));
}
if(enable_uva) {
attributes |= (1 << KRModel::KRENGINE_ATTRIB_TEXUVA);
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVA));
} else {
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVA));
}
if(enable_uvb) {
attributes |= (1 << KRModel::KRENGINE_ATTRIB_TEXUVB);
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVB));
} else {
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVB));
}
if(enable_bone_indexes) {
attributes |= (1 << KRModel::KRENGINE_ATTRIB_BONEINDEXES);
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEINDEXES));
} else {
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEINDEXES));
}
if(enable_bone_weights) {
attributes |= (1 << KRModel::KRENGINE_ATTRIB_BONEWEIGHTS);
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS));
} else {
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS));
}
int data_size = 0;
if(enable_vertex) {
data_size += sizeof(GLfloat) * 3;
}
if(enable_normal) {
data_size += sizeof(GLfloat) * 3;
}
if(enable_tangent) {
data_size += sizeof(GLfloat) * 3;
}
if(enable_uva) {
data_size += sizeof(GLfloat) * 2;
}
if(enable_uvb) {
data_size += sizeof(GLfloat) * 2;
}
if(enable_bone_indexes ) {
data_size += 4; // 4 bytes
}
if(enable_bone_weights) {
data_size += sizeof(GLfloat) * 4;
}
int offset = 0;
GLsizei data_size = (GLsizei)KRModel::VertexSizeForAttributes(attributes);
if(enable_vertex) {
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
offset += sizeof(KRModel::KRVector3D);
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_VERTEX, attributes))));
}
if(enable_normal) {
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
offset += sizeof(KRModel::KRVector3D);
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_NORMAL, attributes))));
}
if(enable_tangent) {
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
offset += sizeof(KRModel::KRVector3D);
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_TANGENT, attributes))));
}
if(enable_uva) {
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
offset += sizeof(KRModel::TexCoord);
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_TEXUVA, attributes))));
}
if(enable_uvb) {
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TEXUVB, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
offset += sizeof(KRModel::TexCoord);
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TEXUVB, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_TEXUVB, attributes))));
}
if(enable_bone_indexes ) {
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_BONEINDEXES, 1, GL_UNSIGNED_BYTE, 0, data_size, BUFFER_OFFSET(offset)));
offset += 4; // 4 bytes
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_BONEINDEXES, 1, GL_UNSIGNED_BYTE, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_BONEINDEXES, attributes))));
}
if(enable_bone_weights) {
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS, 4, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
offset += sizeof(GLfloat) * 4;
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS, 4, GL_FLOAT, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS, attributes))));
}
}

View File

@@ -703,23 +703,21 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
int control_point_count = pMesh->GetControlPointsCount();
KFbxVector4* control_points = pMesh->GetControlPoints();
const int MAX_BONE_WEIGHTS = 4;
struct control_point_weight_info {
float weights[MAX_BONE_WEIGHTS];
int bone_indexes[MAX_BONE_WEIGHTS];
float weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX];
int bone_indexes[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX];
};
control_point_weight_info *control_point_weights = new control_point_weight_info[control_point_count];
for(int control_point=0; control_point < control_point_count; control_point++) {
for(int i=0; i<MAX_BONE_WEIGHTS; i++) {
for(int i=0; i<KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) {
control_point_weights[control_point].weights[i] = 0.0f;
control_point_weights[control_point].bone_indexes[i] = 0;
}
}
std::list<std::string> bone_names;
std::vector<std::string> bone_names;
bool too_many_bone_weights = false;
// Collect the top 4 bone weights per vertex ...
@@ -741,13 +739,13 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
for(int control_point=0; control_point<cluster_control_point_count; control_point++) {
control_point_weight_info &weight_info = control_point_weights[cluster->GetControlPointIndices()[control_point]];
float bone_weight = cluster->GetControlPointWeights()[control_point];
if(bone_weight > weight_info.weights[MAX_BONE_WEIGHTS - 1]) {
if(weight_info.weights[MAX_BONE_WEIGHTS - 1] != 0.0f) {
if(bone_weight > weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1]) {
if(weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] != 0.0f) {
too_many_bone_weights = true;
}
weight_info.weights[MAX_BONE_WEIGHTS - 1] = bone_weight;
weight_info.bone_indexes[MAX_BONE_WEIGHTS - 1] = target_bone_index;
for(int bone_index=MAX_BONE_WEIGHTS - 1; bone_index >=0; bone_index--) {
weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = bone_weight;
weight_info.bone_indexes[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = target_bone_index;
for(int bone_index=KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1; bone_index >=0; bone_index--) {
if(bone_weight > weight_info.weights[bone_index]) {
weight_info.weights[bone_index+1] = weight_info.weights[bone_index];
weight_info.bone_indexes[bone_index+1] = weight_info.bone_indexes[bone_index];
@@ -764,18 +762,18 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
}
if(too_many_bone_weights) {
printf(" WARNING! - Clipped bone weights to limit of %i per vertex (selecting largest weights and re-normalizing).\n", MAX_BONE_WEIGHTS);
printf(" WARNING! - Clipped bone weights to limit of %i per vertex (selecting largest weights and re-normalizing).\n", KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX);
}
// Normalize bone weights
if(bone_names.size() > 0) {
for(int control_point_index=0; control_point_index < control_point_count; control_point_index++) {
control_point_weight_info &weight_info = control_point_weights[control_point_index];
float total_weights = 0.0f;
for(int i=0; i < MAX_BONE_WEIGHTS; i++) {
for(int i=0; i < KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) {
total_weights += weight_info.weights[i];
}
if(total_weights == 0.0f) total_weights = 1.0f; // Prevent any divisions by zero
for(int i=0; i < MAX_BONE_WEIGHTS; i++) {
for(int i=0; i < KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) {
weight_info.weights[i] = weight_info.weights[i] / total_weights;
}
}
@@ -843,7 +841,7 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
control_point_weight_info &weight_info = control_point_weights[lControlPointIndex];
std::vector<int> vertex_bone_indexes;
std::vector<float> vertex_bone_weights;
for(int i=0; i<MAX_BONE_WEIGHTS; i++) {
for(int i=0; i<KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) {
vertex_bone_indexes.push_back(weight_info.bone_indexes[i]);
vertex_bone_weights.push_back(weight_info.weights[i]);
}

View File

@@ -334,7 +334,7 @@ std::vector<KRResource *> KRResource::LoadObj(KRContext &context, const std::str
}
// TODO: Bones not yet supported for OBJ
std::list<std::string> bone_names;
std::vector<std::string> bone_names;
std::vector<std::vector<int> > bone_indexes;
std::vector<std::vector<float> > bone_weights;