Final KRObject file format for v1.1
--HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40185
This commit is contained in:
@@ -213,7 +213,7 @@ bool KRModel::hasTransparency() {
|
|||||||
|
|
||||||
vector<KRModel::Submesh *> KRModel::getSubmeshes() {
|
vector<KRModel::Submesh *> KRModel::getSubmeshes() {
|
||||||
if(m_submeshes.size() == 0) {
|
if(m_submeshes.size() == 0) {
|
||||||
pack_header *pHeader = (pack_header *)m_pData->getStart();
|
pack_header *pHeader = getHeader();
|
||||||
pack_material *pPackMaterials = (pack_material *)(pHeader+1);
|
pack_material *pPackMaterials = (pack_material *)(pHeader+1);
|
||||||
m_submeshes.clear();
|
m_submeshes.clear();
|
||||||
for(int iMaterial=0; iMaterial < pHeader->submesh_count; iMaterial++) {
|
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->start_vertex = pPackMaterial->start_vertex;
|
||||||
pSubmesh->vertex_count = pPackMaterial->vertex_count;
|
pSubmesh->vertex_count = pPackMaterial->vertex_count;
|
||||||
|
|
||||||
strncpy(pSubmesh->szMaterialName, pPackMaterial->szName, 256);
|
strncpy(pSubmesh->szMaterialName, pPackMaterial->szName, KRENGINE_MAX_NAME_LENGTH);
|
||||||
pSubmesh->szMaterialName[255] = '\0';
|
pSubmesh->szMaterialName[KRENGINE_MAX_NAME_LENGTH-1] = '\0';
|
||||||
//fprintf(stderr, "Submesh material: \"%s\"\n", pSubmesh->szMaterialName);
|
//fprintf(stderr, "Submesh material: \"%s\"\n", pSubmesh->szMaterialName);
|
||||||
m_submeshes.push_back(pSubmesh);
|
m_submeshes.push_back(pSubmesh);
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,7 @@ vector<KRModel::Submesh *> KRModel::getSubmeshes() {
|
|||||||
void KRModel::renderSubmesh(int iSubmesh) {
|
void KRModel::renderSubmesh(int iSubmesh) {
|
||||||
unsigned char *pVertexData = getVertexData();
|
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;
|
int cBuffers = (pHeader->vertex_count + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE;
|
||||||
|
|
||||||
vector<KRModel::Submesh *> submeshes = getSubmeshes();
|
vector<KRModel::Submesh *> submeshes = getSubmeshes();
|
||||||
@@ -248,7 +248,6 @@ void KRModel::renderSubmesh(int iSubmesh) {
|
|||||||
while(cVertexes > 0) {
|
while(cVertexes > 0) {
|
||||||
GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : pHeader->vertex_count % MAX_VBO_SIZE;
|
GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : pHeader->vertex_count % MAX_VBO_SIZE;
|
||||||
int vertex_size = m_vertex_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 *vbo_end = (unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size + vertex_size * cBufferVertexes;
|
||||||
void *buffer_end = m_pData->getEnd();
|
void *buffer_end = m_pData->getEnd();
|
||||||
@@ -277,14 +276,7 @@ void KRModel::renderSubmesh(int iSubmesh) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *KRModel::getVertexData() const {
|
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) {
|
||||||
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) {
|
|
||||||
|
|
||||||
clearData();
|
clearData();
|
||||||
|
|
||||||
@@ -308,18 +300,23 @@ void KRModel::LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> u
|
|||||||
if(uvb.size()) {
|
if(uvb.size()) {
|
||||||
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB);
|
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);
|
size_t vertex_size = VertexSizeForAttributes(vertex_attrib_flags);
|
||||||
|
|
||||||
int submesh_count = submesh_lengths.size();
|
size_t submesh_count = submesh_lengths.size();
|
||||||
int vertex_count = vertices.size();
|
size_t vertex_count = vertices.size();
|
||||||
size_t new_file_size = sizeof(pack_header) + sizeof(pack_material) * submesh_count + vertex_size * vertex_count;
|
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);
|
m_pData->expand(new_file_size);
|
||||||
|
|
||||||
pack_header *pHeader = (pack_header *)m_pData->getStart();
|
pack_header *pHeader = getHeader();
|
||||||
memset(pHeader, 0, sizeof(pack_header));
|
memset(pHeader, 0, sizeof(pack_header));
|
||||||
pHeader->vertex_attrib_flags = vertex_attrib_flags;
|
pHeader->vertex_attrib_flags = vertex_attrib_flags;
|
||||||
pHeader->submesh_count = submesh_lengths.size();
|
pHeader->submesh_count = (__int32_t)submesh_count;
|
||||||
pHeader->vertex_count = vertices.size();
|
pHeader->vertex_count = (__int32_t)vertex_count;
|
||||||
|
pHeader->bone_count = (__int32_t)bone_count;
|
||||||
strcpy(pHeader->szTag, "KROBJPACK1.1 ");
|
strcpy(pHeader->szTag, "KROBJPACK1.1 ");
|
||||||
updateAttributeOffsets();
|
updateAttributeOffsets();
|
||||||
|
|
||||||
@@ -329,7 +326,14 @@ void KRModel::LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> u
|
|||||||
pack_material *pPackMaterial = pPackMaterials + iMaterial;
|
pack_material *pPackMaterial = pPackMaterials + iMaterial;
|
||||||
pPackMaterial->start_vertex = submesh_starts[iMaterial];
|
pPackMaterial->start_vertex = submesh_starts[iMaterial];
|
||||||
pPackMaterial->vertex_count = submesh_lengths[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;
|
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++) {
|
for(int iVertex=0; iVertex < vertices.size(); iVertex++) {
|
||||||
KRVector3 source_vertex = vertices[iVertex];
|
KRVector3 source_vertex = vertices[iVertex];
|
||||||
setVertexPosition(iVertex, source_vertex);
|
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) {
|
if(bFirstVertex) {
|
||||||
bFirstVertex = false;
|
bFirstVertex = false;
|
||||||
m_minPoint = source_vertex;
|
m_minPoint = source_vertex;
|
||||||
@@ -354,23 +364,15 @@ void KRModel::LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> u
|
|||||||
}
|
}
|
||||||
if(uva.size() > iVertex) {
|
if(uva.size() > iVertex) {
|
||||||
setVertexUVA(iVertex, uva[iVertex]);
|
setVertexUVA(iVertex, uva[iVertex]);
|
||||||
} else {
|
|
||||||
setVertexUVA(iVertex, KRVector2::Zero());
|
|
||||||
}
|
}
|
||||||
if(uvb.size() > iVertex) {
|
if(uvb.size() > iVertex) {
|
||||||
setVertexUVB(iVertex, uvb[iVertex]);
|
setVertexUVB(iVertex, uvb[iVertex]);
|
||||||
} else {
|
|
||||||
setVertexUVB(iVertex, KRVector2::Zero());
|
|
||||||
}
|
}
|
||||||
if(normals.size() > iVertex) {
|
if(normals.size() > iVertex) {
|
||||||
setVertexNormal(iVertex, normals[iVertex]);
|
setVertexNormal(iVertex, normals[iVertex]);
|
||||||
} else {
|
|
||||||
setVertexNormal(iVertex, KRVector3::Zero());
|
|
||||||
}
|
}
|
||||||
if(tangents.size() > iVertex) {
|
if(tangents.size() > iVertex) {
|
||||||
setVertexTangent(iVertex, tangents[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();
|
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)
|
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
|
unsigned char *KRModel::getVertexData(int index) const
|
||||||
@@ -487,7 +500,7 @@ unsigned char *KRModel::getVertexData(int index) const
|
|||||||
|
|
||||||
int KRModel::getSubmeshCount()
|
int KRModel::getSubmeshCount()
|
||||||
{
|
{
|
||||||
pack_header *header = (pack_header *)m_pData->getStart();
|
pack_header *header = getHeader();
|
||||||
return header->submesh_count;
|
return header->submesh_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,6 +592,31 @@ void KRModel::setVertexUVB(int index, const KRVector2 &v)
|
|||||||
vert[1] = v.y;
|
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 KRModel::VertexSizeForAttributes(__int32_t vertex_attrib_flags)
|
||||||
{
|
{
|
||||||
size_t data_size = 0;
|
size_t data_size = 0;
|
||||||
@@ -616,7 +654,18 @@ void KRModel::updateAttributeOffsets()
|
|||||||
} else {
|
} else {
|
||||||
m_vertex_attribute_offset[i] = -1;
|
m_vertex_attribute_offset[i] = -1;
|
||||||
}
|
}
|
||||||
mask = (mask << 1) & 1;
|
mask = (mask << 1) | 1;
|
||||||
}
|
}
|
||||||
m_vertex_size = VertexSizeForAttributes(header->vertex_attrib_flags);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ using std::list;
|
|||||||
|
|
||||||
|
|
||||||
#define MAX_VBO_SIZE 65535
|
#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...
|
// MAX_VBO_SIZE must be divisible by 3 so triangles aren't split across VBO objects...
|
||||||
|
|
||||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||||
@@ -78,7 +80,7 @@ public:
|
|||||||
virtual std::string getExtension();
|
virtual std::string getExtension();
|
||||||
virtual bool save(const std::string& path);
|
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);
|
void loadPack(KRDataBlock *data);
|
||||||
|
|
||||||
|
|
||||||
@@ -108,7 +110,7 @@ public:
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
GLint start_vertex;
|
GLint start_vertex;
|
||||||
GLsizei vertex_count;
|
GLsizei vertex_count;
|
||||||
char szMaterialName[256];
|
char szMaterialName[KRENGINE_MAX_NAME_LENGTH];
|
||||||
} Submesh;
|
} Submesh;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -135,8 +137,12 @@ public:
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t start_vertex;
|
int32_t start_vertex;
|
||||||
int32_t vertex_count;
|
int32_t vertex_count;
|
||||||
char szName[256];
|
char szName[KRENGINE_MAX_NAME_LENGTH];
|
||||||
} pack_material;
|
} pack_material;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char szName[KRENGINE_MAX_NAME_LENGTH];
|
||||||
|
} pack_bone;
|
||||||
|
|
||||||
int getLODCoverage() const;
|
int getLODCoverage() const;
|
||||||
std::string getLODBaseName() const;
|
std::string getLODBaseName() const;
|
||||||
@@ -152,11 +158,19 @@ public:
|
|||||||
KRVector3 getVertexTangent(int index) const;
|
KRVector3 getVertexTangent(int index) const;
|
||||||
KRVector2 getVertexUVA(int index) const;
|
KRVector2 getVertexUVA(int index) const;
|
||||||
KRVector2 getVertexUVB(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 setVertexPosition(int index, const KRVector3 &v);
|
||||||
void setVertexNormal(int index, const KRVector3 &v);
|
void setVertexNormal(int index, const KRVector3 &v);
|
||||||
void setVertexTangent(int index, const KRVector3 & v);
|
void setVertexTangent(int index, const KRVector3 & v);
|
||||||
void setVertexUVA(int index, const KRVector2 &v);
|
void setVertexUVA(int index, const KRVector2 &v);
|
||||||
void setVertexUVB(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:
|
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)
|
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 {
|
typedef struct {
|
||||||
char szTag[16];
|
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_attrib_flags;
|
||||||
int32_t vertex_count;
|
int32_t vertex_count;
|
||||||
int32_t submesh_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
|
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;
|
} pack_header;
|
||||||
|
|
||||||
vector<Submesh *> m_submeshes;
|
vector<Submesh *> m_submeshes;
|
||||||
@@ -191,13 +206,13 @@ private:
|
|||||||
|
|
||||||
void setName(const std::string name);
|
void setName(const std::string name);
|
||||||
|
|
||||||
static size_t VertexSizeForAttributes(__int32_t vertex_attrib_flags);
|
|
||||||
|
|
||||||
pack_material *getSubmesh(int mesh_index);
|
pack_material *getSubmesh(int mesh_index);
|
||||||
unsigned char *getVertexData() const;
|
unsigned char *getVertexData() const;
|
||||||
unsigned char *getVertexData(int index) const;
|
unsigned char *getVertexData(int index) const;
|
||||||
pack_header *getHeader() const;
|
pack_header *getHeader() const;
|
||||||
|
pack_bone *getBone(int index);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
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) {
|
if(enable_vertex) {
|
||||||
|
attributes |= (1 << KRModel::KRENGINE_ATTRIB_VERTEX);
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_VERTEX));
|
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_VERTEX));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_VERTEX));
|
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_VERTEX));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enable_normal) {
|
if(enable_normal) {
|
||||||
|
attributes |= (1 << KRModel::KRENGINE_ATTRIB_NORMAL);
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_NORMAL));
|
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_NORMAL));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_NORMAL));
|
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_NORMAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enable_tangent) {
|
if(enable_tangent) {
|
||||||
|
attributes |= (1 << KRModel::KRENGINE_ATTRIB_TANGENT);
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TANGENT));
|
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TANGENT));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TANGENT));
|
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TANGENT));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enable_uva) {
|
if(enable_uva) {
|
||||||
|
attributes |= (1 << KRModel::KRENGINE_ATTRIB_TEXUVA);
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVA));
|
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVA));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVA));
|
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVA));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enable_uvb) {
|
if(enable_uvb) {
|
||||||
|
attributes |= (1 << KRModel::KRENGINE_ATTRIB_TEXUVB);
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVB));
|
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVB));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVB));
|
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVB));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enable_bone_indexes) {
|
if(enable_bone_indexes) {
|
||||||
|
attributes |= (1 << KRModel::KRENGINE_ATTRIB_BONEINDEXES);
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEINDEXES));
|
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEINDEXES));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEINDEXES));
|
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEINDEXES));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enable_bone_weights) {
|
if(enable_bone_weights) {
|
||||||
|
attributes |= (1 << KRModel::KRENGINE_ATTRIB_BONEWEIGHTS);
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS));
|
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS));
|
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) {
|
if(enable_vertex) {
|
||||||
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
|
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_VERTEX, attributes))));
|
||||||
offset += sizeof(KRModel::KRVector3D);
|
|
||||||
}
|
}
|
||||||
if(enable_normal) {
|
if(enable_normal) {
|
||||||
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
|
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_NORMAL, attributes))));
|
||||||
offset += sizeof(KRModel::KRVector3D);
|
|
||||||
}
|
}
|
||||||
if(enable_tangent) {
|
if(enable_tangent) {
|
||||||
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
|
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_TANGENT, attributes))));
|
||||||
offset += sizeof(KRModel::KRVector3D);
|
|
||||||
}
|
}
|
||||||
if(enable_uva) {
|
if(enable_uva) {
|
||||||
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
|
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_TEXUVA, attributes))));
|
||||||
offset += sizeof(KRModel::TexCoord);
|
|
||||||
}
|
}
|
||||||
if(enable_uvb) {
|
if(enable_uvb) {
|
||||||
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TEXUVB, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
|
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TEXUVB, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_TEXUVB, attributes))));
|
||||||
offset += sizeof(KRModel::TexCoord);
|
|
||||||
}
|
}
|
||||||
if(enable_bone_indexes ) {
|
if(enable_bone_indexes ) {
|
||||||
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_BONEINDEXES, 1, GL_UNSIGNED_BYTE, 0, data_size, BUFFER_OFFSET(offset)));
|
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_BONEINDEXES, 1, GL_UNSIGNED_BYTE, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_BONEINDEXES, attributes))));
|
||||||
offset += 4; // 4 bytes
|
|
||||||
}
|
}
|
||||||
if(enable_bone_weights) {
|
if(enable_bone_weights) {
|
||||||
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS, 4, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
|
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS, 4, GL_FLOAT, 0, data_size, BUFFER_OFFSET(KRModel::AttributeOffset(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS, attributes))));
|
||||||
offset += sizeof(GLfloat) * 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -703,23 +703,21 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
|
|||||||
int control_point_count = pMesh->GetControlPointsCount();
|
int control_point_count = pMesh->GetControlPointsCount();
|
||||||
KFbxVector4* control_points = pMesh->GetControlPoints();
|
KFbxVector4* control_points = pMesh->GetControlPoints();
|
||||||
|
|
||||||
const int MAX_BONE_WEIGHTS = 4;
|
|
||||||
|
|
||||||
struct control_point_weight_info {
|
struct control_point_weight_info {
|
||||||
float weights[MAX_BONE_WEIGHTS];
|
float weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX];
|
||||||
int bone_indexes[MAX_BONE_WEIGHTS];
|
int bone_indexes[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX];
|
||||||
};
|
};
|
||||||
|
|
||||||
control_point_weight_info *control_point_weights = new control_point_weight_info[control_point_count];
|
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 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].weights[i] = 0.0f;
|
||||||
control_point_weights[control_point].bone_indexes[i] = 0;
|
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;
|
bool too_many_bone_weights = false;
|
||||||
|
|
||||||
// Collect the top 4 bone weights per vertex ...
|
// 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++) {
|
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]];
|
control_point_weight_info &weight_info = control_point_weights[cluster->GetControlPointIndices()[control_point]];
|
||||||
float bone_weight = cluster->GetControlPointWeights()[control_point];
|
float bone_weight = cluster->GetControlPointWeights()[control_point];
|
||||||
if(bone_weight > weight_info.weights[MAX_BONE_WEIGHTS - 1]) {
|
if(bone_weight > weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1]) {
|
||||||
if(weight_info.weights[MAX_BONE_WEIGHTS - 1] != 0.0f) {
|
if(weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] != 0.0f) {
|
||||||
too_many_bone_weights = true;
|
too_many_bone_weights = true;
|
||||||
}
|
}
|
||||||
weight_info.weights[MAX_BONE_WEIGHTS - 1] = bone_weight;
|
weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = bone_weight;
|
||||||
weight_info.bone_indexes[MAX_BONE_WEIGHTS - 1] = target_bone_index;
|
weight_info.bone_indexes[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = target_bone_index;
|
||||||
for(int bone_index=MAX_BONE_WEIGHTS - 1; bone_index >=0; 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]) {
|
if(bone_weight > weight_info.weights[bone_index]) {
|
||||||
weight_info.weights[bone_index+1] = 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];
|
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) {
|
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
|
// Normalize bone weights
|
||||||
if(bone_names.size() > 0) {
|
if(bone_names.size() > 0) {
|
||||||
for(int control_point_index=0; control_point_index < control_point_count; control_point_index++) {
|
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];
|
control_point_weight_info &weight_info = control_point_weights[control_point_index];
|
||||||
float total_weights = 0.0f;
|
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];
|
total_weights += weight_info.weights[i];
|
||||||
}
|
}
|
||||||
if(total_weights == 0.0f) total_weights = 1.0f; // Prevent any divisions by zero
|
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;
|
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];
|
control_point_weight_info &weight_info = control_point_weights[lControlPointIndex];
|
||||||
std::vector<int> vertex_bone_indexes;
|
std::vector<int> vertex_bone_indexes;
|
||||||
std::vector<float> vertex_bone_weights;
|
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_indexes.push_back(weight_info.bone_indexes[i]);
|
||||||
vertex_bone_weights.push_back(weight_info.weights[i]);
|
vertex_bone_weights.push_back(weight_info.weights[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -334,7 +334,7 @@ std::vector<KRResource *> KRResource::LoadObj(KRContext &context, const std::str
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Bones not yet supported for OBJ
|
// 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<int> > bone_indexes;
|
||||||
std::vector<std::vector<float> > bone_weights;
|
std::vector<std::vector<float> > bone_weights;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user