diff options
author | Benoit Bolsee <benoit.bolsee@online.be> | 2008-07-17 01:24:54 +0400 |
---|---|---|
committer | Benoit Bolsee <benoit.bolsee@online.be> | 2008-07-17 01:24:54 +0400 |
commit | dbfc5f6b7110031a82da4482d62ed8b36873b369 (patch) | |
tree | 60dde75906eeae76e29ab9c2c3f9d4904e8af028 /source | |
parent | 7ef48296fca31796a7c27d09c5fbe07333ca8a54 (diff) |
BGE patch: fix mesh deformation errors with duplicated objects sharing the same mesh in case of 1) armature+multiple material 2) shape drivers
Diffstat (limited to 'source')
-rw-r--r-- | source/gameengine/Converter/BL_ShapeDeformer.cpp | 7 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_SkinDeformer.cpp | 48 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_SkinDeformer.h | 6 |
3 files changed, 36 insertions, 25 deletions
diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index eb5c1467ea5..b2e54539b19 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -109,6 +109,13 @@ bool BL_ShapeDeformer::ExecuteShapeDrivers(void) vector<IpoCurve*>::iterator it; void *poin; int type; + // the shape drivers use the bone matrix as input. Must + // update the matrix now + Object* par_arma = m_armobj->GetArmatureObject(); + m_armobj->ApplyPose(); + where_is_pose( par_arma ); + PoseApplied(true); + for (it=m_shapeDrivers.begin(); it!=m_shapeDrivers.end(); it++) { // no need to set a specific time: this curve has a driver IpoCurve *icu = *it; diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index d3442fe5298..f96c40c098f 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -66,7 +66,8 @@ BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj, m_armobj(arma), m_lastArmaUpdate(-1), m_defbase(&bmeshobj->defbase), - m_releaseobject(false) + m_releaseobject(false), + m_poseApplied(false) { Mat4CpyMat4(m_obmat, bmeshobj->obmat); }; @@ -98,32 +99,28 @@ BL_SkinDeformer::~BL_SkinDeformer() m_armobj->Release(); } -bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *) +bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat) { size_t i, j; - if (!Update()) - // no need to update the cache - return false; + // update the vertex in m_transverts + Update(); - // Update all materials at once, so we can do the above update test - // without ending up with some materials not updated - for(RAS_MaterialBucket::Set::iterator mit = m_pMeshObject->GetFirstMaterial(); - mit != m_pMeshObject->GetLastMaterial(); ++ mit) { - RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial(); + // The vertex cache can only be updated for this deformer: + // Duplicated objects with more than one ploymaterial (=multiple mesh slot per object) + // share the same mesh (=the same cache). As the rendering is done per polymaterial + // cycling through the objects, the entire mesh cache cannot be updated in one shot. + vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat); - vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat); + // For each array + for (i=0; i<vertexarrays.size(); i++) { + KX_VertexArray& vertexarray = (*vertexarrays[i]); - // For each array - for (i=0; i<vertexarrays.size(); i++) { - KX_VertexArray& vertexarray = (*vertexarrays[i]); - - // For each vertex - // copy the untransformed data from the original mvert - for (j=0; j<vertexarray.size(); j++) { - RAS_TexVert& v = vertexarray[j]; - v.SetXYZ(m_transverts[v.getOrigIndex()]); - } + // For each vertex + // copy the untransformed data from the original mvert + for (j=0; j<vertexarray.size(); j++) { + RAS_TexVert& v = vertexarray[j]; + v.SetXYZ(m_transverts[v.getOrigIndex()]); } } @@ -153,9 +150,11 @@ bool BL_SkinDeformer::Update(void) /* XXX note: where_is_pose() (from BKE_armature.h) calculates all matrices needed to start deforming */ /* but it requires the blender object pointer... */ - Object* par_arma = m_armobj->GetArmatureObject(); - where_is_pose( par_arma ); + if (!PoseApplied()){ + m_armobj->ApplyPose(); + where_is_pose( par_arma ); + } /* store verts locally */ VerifyStorage(); @@ -180,7 +179,8 @@ bool BL_SkinDeformer::Update(void) /* Update the current frame */ m_lastArmaUpdate=m_armobj->GetLastFrame(); - + /* reset for next frame */ + PoseApplied(false); /* indicate that the m_transverts and normals are up to date */ return true; } diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index f35db8273c4..d3fc5ae2a81 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -81,10 +81,13 @@ public: virtual ~BL_SkinDeformer(); bool Update (void); bool Apply (class RAS_IPolyMaterial *polymat); + bool PoseApplied() + { return m_poseApplied; } + void PoseApplied(bool applied) + { m_poseApplied = applied; } bool PoseUpdated(void) { if (m_armobj && m_lastArmaUpdate!=m_armobj->GetLastFrame()) { - m_armobj->ApplyPose(); return true; } return false; @@ -102,6 +105,7 @@ protected: ListBase* m_defbase; float m_obmat[4][4]; // the reference matrix for skeleton deform bool m_releaseobject; + bool m_poseApplied; }; |