diff options
author | Benoit Bolsee <benoit.bolsee@online.be> | 2011-01-23 20:17:21 +0300 |
---|---|---|
committer | Benoit Bolsee <benoit.bolsee@online.be> | 2011-01-23 20:17:21 +0300 |
commit | fc66b3f2efcb5b7579f06c1966900b2ecf3c1310 (patch) | |
tree | 029fa673af575ff1f3fce63e49c29fa2359be360 /source/gameengine | |
parent | fa38da021cd08409f1bda4722a6cf8a607f86838 (diff) |
BGE: support modifiers without mapping to original mesh both graphically and physically, fixes bug #24942 and #25286.
Support for physics is done by skiping the modifiers that
don't support mapping to original mesh. This mapping is
required to report the hit polygon to the application
by the rayCast() function.
Support for graphics is done by using the same render
function that blender uses for the 3D view. This guantees
equal result.
Limitation: there is still a known bug if all these conditions are met:
- Display list enabled
- Old tex face with a several textures mapped to the same material
- no armature or shape keys
- active modifiers
In this case, only a part of the mesh will be rendered
with the wrong texture. To avoid this bug, use the GLSL
materials or make sure to have 1 material=1 texture in
your old tex face objects.
Diffstat (limited to 'source/gameengine')
10 files changed, 92 insertions, 7 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 3cdc688f55d..ab9882cab87 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1525,7 +1525,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, KX_BoxBounds bb; DerivedMesh* dm = NULL; if (gameobj->GetDeformer()) - dm = gameobj->GetDeformer()->GetFinalMesh(); + dm = gameobj->GetDeformer()->GetPhysicsMesh(); my_get_local_bounds(blenderobject,dm,objprop.m_boundobject.box.m_center,bb.m_extends); if (blenderobject->gameflag & OB_BOUNDS) { @@ -1618,6 +1618,10 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, } delete shapeprops; delete smmaterial; + if (dm) { + dm->needsFree = 1; + dm->release(dm); + } } diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp index 5eb25b05567..205892f5c77 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.cpp +++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp @@ -135,6 +135,30 @@ bool BL_ModifierDeformer::HasArmatureDeformer(Object *ob) return false; } +// return a deformed mesh that supports mapping (with a valid CD_ORIGINDEX layer) +struct DerivedMesh* BL_ModifierDeformer::GetPhysicsMesh() +{ + // we need to compute the deformed mesh taking into account the current + // shape and skin deformers, we cannot just call mesh_create_derived_physics() + // because that would use the m_transvers already deformed previously by BL_ModifierDeformer::Update(), + // so restart from scratch by forcing a full update the shape/skin deformers + // (will do nothing if there is no such deformer) + BL_ShapeDeformer::ForceUpdate(); + BL_ShapeDeformer::Update(); + // now apply the modifiers but without those that don't support mapping + Object* blendobj = m_gameobj->GetBlendObject(); + /* hack: the modifiers require that the mesh is attached to the object + It may not be the case here because of replace mesh actuator */ + Mesh *oldmesh = (Mesh*)blendobj->data; + blendobj->data = m_bmesh; + DerivedMesh *dm = mesh_create_derived_physics(m_scene, blendobj, m_transverts, CD_MASK_MESH); + /* restore object data */ + blendobj->data = oldmesh; + /* m_transverts is correct here (takes into account deform only modifiers) */ + /* the derived mesh returned by this function must be released by the caller !!! */ + return dm; +} + bool BL_ModifierDeformer::Update(void) { bool bShapeUpdate = BL_ShapeDeformer::Update(); diff --git a/source/gameengine/Converter/BL_ModifierDeformer.h b/source/gameengine/Converter/BL_ModifierDeformer.h index 49998f36ccb..caf1741ecaf 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.h +++ b/source/gameengine/Converter/BL_ModifierDeformer.h @@ -95,7 +95,8 @@ public: { return m_dm; } - + // The derived mesh returned by this function must be released! + virtual struct DerivedMesh* GetPhysicsMesh(); protected: double m_lastModifierUpdate; diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index 57e11e02d5a..1f4a3491695 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -108,6 +108,11 @@ KX_PolygonMaterial::~KX_PolygonMaterial() #endif // WITH_PYTHON } +Image *KX_PolygonMaterial::GetBlenderImage() const +{ + return (m_tface) ? m_tface->tpage : NULL; +} + bool KX_PolygonMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const { bool dopass = false; diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h index 17adbac79c0..d71a34989a0 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.h +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h @@ -42,6 +42,7 @@ struct MTFace; struct Material; struct MTex; +struct Image; /** * Material class. @@ -107,6 +108,8 @@ public: return m_material; } + Image *GetBlenderImage() const; + /** * Returns the Blender texture face structure that is used for this material. * @return The material's texture face. diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 54f98d16cf6..8d3c1565d3a 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -1694,12 +1694,16 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA return false; RAS_Deformer *deformer= gameobj ? gameobj->GetDeformer():NULL; + DerivedMesh* dm = NULL; + + if (deformer) + dm = deformer->GetPhysicsMesh(); /* get the mesh from the object if not defined */ if(meshobj==NULL) { /* modifier mesh */ - if(deformer && deformer->GetFinalMesh()) + if(dm) meshobj= deformer->GetRasMesh(); /* game object first mesh */ @@ -1710,14 +1714,12 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA } } - if(deformer && deformer->GetFinalMesh() && deformer->GetRasMesh() == meshobj) + if(dm && deformer->GetRasMesh() == meshobj) { /* * Derived Mesh Update * * */ - DerivedMesh* dm= gameobj->GetDeformer()->GetFinalMesh(); - MVert *mvert = dm->getVertArray(dm); MFace *mface = dm->getFaceArray(dm); numpolys = dm->getNumFaces(dm); @@ -1977,6 +1979,10 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA m_meshObject= meshobj; + if (dm) { + dm->needsFree = 1; + dm->release(dm); + } return true; } diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h index f61ac7ea18a..37543092e68 100644 --- a/source/gameengine/Rasterizer/RAS_Deformer.h +++ b/source/gameengine/Rasterizer/RAS_Deformer.h @@ -76,6 +76,10 @@ public: { return NULL; } + virtual struct DerivedMesh* GetPhysicsMesh() + { + return NULL; + } virtual class RAS_MeshObject* GetRasMesh() { /* m_pMesh does not seem to be being used?? */ diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index 0c81d7d8274..00f1f5f2848 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -208,6 +208,11 @@ Material *RAS_IPolyMaterial::GetBlenderMaterial() const return NULL; } +Image *RAS_IPolyMaterial::GetBlenderImage() const +{ + return NULL; +} + Scene* RAS_IPolyMaterial::GetBlenderScene() const { return NULL; diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index e7bd78c2309..59554e31c36 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -45,6 +45,7 @@ class RAS_IRasterizer; struct MTFace; struct Material; +struct Image; struct Scene; class SCA_IScene; @@ -160,6 +161,7 @@ public: int GetMaterialIndex() const; virtual Material* GetBlenderMaterial() const; + virtual Image* GetBlenderImage() const; virtual Scene* GetBlenderScene() const; virtual void ReleaseMaterial(); virtual void GetMaterialRGBAColor(unsigned char *rgba) const; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index e8c2db5526a..c2859394176 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -731,6 +731,7 @@ static RAS_MeshSlot *current_ms; static RAS_MeshObject *current_mesh; static int current_blmat_nr; static GPUVertexAttribs current_gpu_attribs; +static Image *current_image; static int CheckMaterialDM(int matnr, void *attribs) { // only draw the current material @@ -769,6 +770,33 @@ static int CheckTexfaceDM(void *mcol, int index) return 0; } +static int CheckTexDM(MTFace *tface, MCol *mcol, int matnr) +{ + + // index is the original face index, retrieve the polygon + if (matnr == current_blmat_nr && + (tface == NULL || tface->tpage == current_image)) { + // must handle color. + if (current_wireframe) + return 2; + if (current_ms->m_bObjectColor) { + MT_Vector4& rgba = current_ms->m_RGBAcolor; + glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + // don't use mcol + return 2; + } + if (!mcol) { + // we have to set the color from the material + unsigned char rgba[4]; + current_polymat->GetMaterialRGBAColor(rgba); + glColor4ubv((const GLubyte *)rgba); + return 2; + } + return 1; + } + return 0; +} + void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) { bool obcolor = ms.m_bObjectColor; @@ -807,7 +835,10 @@ void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM); GPU_set_material_blend_mode(current_blend_mode); } else { - ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol); + //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol); + current_blmat_nr = current_polymat->GetMaterialIndex(); + current_image = current_polymat->GetBlenderImage(); + ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM); } return; } |