From ec6bd06bd71d7442f3759c9b02bb872fafa5f500 Mon Sep 17 00:00:00 2001 From: kearwood Date: Wed, 12 Dec 2012 23:21:15 +0000 Subject: [PATCH] Corrected bone names in krobject file format --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40186 --- KREngine/KREngine/Classes/KRInstance.cpp | 28 ++++++++++++++++++++---- KREngine/KREngine/Classes/KRInstance.h | 2 ++ KREngine/KREngine/Classes/KRModel.cpp | 15 +++++++++++-- KREngine/KREngine/Classes/KRModel.h | 6 ++++- 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/KREngine/KREngine/Classes/KRInstance.cpp b/KREngine/KREngine/Classes/KRInstance.cpp index ea9b6cd..4c1fd08 100644 --- a/KREngine/KREngine/Classes/KRInstance.cpp +++ b/KREngine/KREngine/Classes/KRInstance.cpp @@ -66,9 +66,29 @@ tinyxml2::XMLElement *KRInstance::saveXML( tinyxml2::XMLNode *parent) void KRInstance::loadModel() { if(m_models.size() == 0) { - m_models = m_pContext->getModelManager()->getModel(m_model_name.c_str()); // The model manager returns the LOD levels in sorted order, with the highest detail first - if(m_models.size() > 0) { - getScene().notify_sceneGraphModify(this); + std::vector models = m_pContext->getModelManager()->getModel(m_model_name.c_str()); // The model manager returns the LOD levels in sorted order, with the highest detail first + std::map > bones; + if(models.size() > 0) { + bool all_bones_found = true; + for(std::vector::iterator model_itr = models.begin(); model_itr != models.end(); model_itr++) { + KRModel *model = *model_itr; + std::vector model_bones; + int bone_count = model->getBoneCount(); + for(int bone_index=0; bone_index < bone_count; bone_index++) { + KRBone *matching_bone = dynamic_cast(getScene().getRootNode()->findChild(model->getBoneName(bone_index))); + if(matching_bone) { + model_bones.push_back(matching_bone); + } else { + all_bones_found = false; // Reject when there are any missing bones or multiple matches + } + } + bones[model] = model_bones; + } + if(all_bones_found) { + m_models = models; + m_bones = bones; + getScene().notify_sceneGraphModify(this); + } } } } @@ -117,7 +137,7 @@ void KRInstance::render(KRCamera *pCamera, std::vector &lights, const matModel = KRQuaternion(KRVector3::Forward(), KRVector3::Normalize(camera_pos - model_center)).rotationMatrix() * matModel; } - pModel->render(pCamera, lights, viewport, matModel, m_pLightMap, renderPass); + pModel->render(pCamera, lights, viewport, matModel, m_pLightMap, renderPass, m_bones[pModel]); } } } diff --git a/KREngine/KREngine/Classes/KRInstance.h b/KREngine/KREngine/Classes/KRInstance.h index 0b80c7e..94e3d5a 100644 --- a/KREngine/KREngine/Classes/KRInstance.h +++ b/KREngine/KREngine/Classes/KRInstance.h @@ -46,6 +46,7 @@ #import "KRContext.h" #import "KRModel.h" #import "KRTexture.h" +#import "KRBone.h" class KRInstance : public KRNode { @@ -68,6 +69,7 @@ public: private: std::vector m_models; + std::map > m_bones; // Outer std::map connects model to set of bones KRTexture *m_pLightMap; std::string m_lightMap; std::string m_model_name; diff --git a/KREngine/KREngine/Classes/KRModel.cpp b/KREngine/KREngine/Classes/KRModel.cpp index 7e3f067..761f447 100644 --- a/KREngine/KREngine/Classes/KRModel.cpp +++ b/KREngine/KREngine/Classes/KRModel.cpp @@ -112,7 +112,7 @@ void KRModel::loadPack(KRDataBlock *data) { #if TARGET_OS_IPHONE -void KRModel::render(KRCamera *pCamera, std::vector &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) { +void KRModel::render(KRCamera *pCamera, std::vector &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones) { //fprintf(stderr, "Rendering model: %s\n", m_name.c_str()); if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { @@ -480,7 +480,7 @@ KRModel::pack_header *KRModel::getHeader() const 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; + return (pack_bone *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * header->submesh_count + sizeof(pack_bone) * index); } unsigned char *KRModel::getVertexData() const { @@ -669,3 +669,14 @@ size_t KRModel::AttributeOffset(__int32_t vertex_attrib, __int32_t vertex_attrib } return VertexSizeForAttributes(mask); } + +int KRModel::getBoneCount() +{ + pack_header *header = getHeader(); + return header->bone_count; +} + +char *KRModel::getBoneName(int bone_index) +{ + return getBone(bone_index)->szName; +} diff --git a/KREngine/KREngine/Classes/KRModel.h b/KREngine/KREngine/Classes/KRModel.h index 700ed17..c390138 100644 --- a/KREngine/KREngine/Classes/KRModel.h +++ b/KREngine/KREngine/Classes/KRModel.h @@ -34,6 +34,7 @@ #import #import "KRVector2.h" #import "KRContext.h" +#import "KRBone.h" #import "KREngine-common.h" @@ -71,7 +72,7 @@ public: #if TARGET_OS_IPHONE - void render(KRCamera *pCamera, std::vector &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass); + void render(KRCamera *pCamera, std::vector &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones); #endif @@ -171,6 +172,9 @@ public: static size_t VertexSizeForAttributes(__int32_t vertex_attrib_flags); static size_t AttributeOffset(__int32_t vertex_attrib, __int32_t vertex_attrib_flags); + + int getBoneCount(); + char *getBoneName(int bone_index); 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)