Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Bolsee <benoit.bolsee@online.be>2009-05-14 17:47:08 +0400
committerBenoit Bolsee <benoit.bolsee@online.be>2009-05-14 17:47:08 +0400
commitd95a10999052ad308599cb0fbbe7ed4f59870c9c (patch)
treec8ab32463f7e774319e35ab23855743dd0dea341 /source/gameengine
parent003534513645576215092b79f1aa46e85c89e3bd (diff)
BGE modifier: generate correct physic shape, share static derived mesh, share display list.
This commit completes the support for modifiers in the BGE. - The physic shape is generated according to the derived mesh. This is true for all types of shapes and all types of objects except soft body. - Optimization for static derived mesh (mesh with modifiers but no armature and no shape keys). Replicas will share the derived mesh and the display list: less memory and faster rendering. With this optimization, the static derived mesh will render as fast as if the modifiers were applied. Known Limits: - Sharing of mesh and display list is only possible between in-game replicas or dupligroup. If you want to instantiate multiple objects with modifiers, use dupligroup to ensure best memory and GPU utilization. - rayCast() will interact with the derived mesh as follow: Hit position and hit normal are the real values according to the derived mesh but the KX_PolyProxy object refers to the original mesh. You should use it only to retrieve the material. - Dynamic derived mesh have very poor performance: They use direct openGL calls for rendering (no support for display list and vertex array) and they dont't share the derived mesh memory. Always apply modifiers on dynamic mesh for best performance. - Time dependent modifiers are not supported. - Modifiers are not supported for Bullet soft body.
Diffstat (limited to 'source/gameengine')
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp102
-rw-r--r--source/gameengine/Converter/BL_MeshDeformer.cpp9
-rw-r--r--source/gameengine/Converter/BL_MeshDeformer.h2
-rw-r--r--source/gameengine/Converter/BL_ModifierDeformer.cpp73
-rw-r--r--source/gameengine/Converter/BL_ModifierDeformer.h5
-rw-r--r--source/gameengine/Converter/BL_ShapeDeformer.cpp9
-rw-r--r--source/gameengine/Converter/BL_ShapeDeformer.h1
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.cpp45
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.h2
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObject.h2
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp51
-rw-r--r--source/gameengine/Physics/Bullet/CMakeLists.txt3
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp200
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h5
-rw-r--r--source/gameengine/Physics/Bullet/Makefile2
-rw-r--r--source/gameengine/Physics/Bullet/SConscript3
-rw-r--r--source/gameengine/Rasterizer/RAS_Deformer.h10
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp46
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h6
19 files changed, 353 insertions, 223 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 09604e5c2e3..9ea623f17e4 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1249,18 +1249,34 @@ static void my_tex_space_mesh(Mesh *me)
}
-static void my_get_local_bounds(Object *ob, float *center, float *size)
+static void my_get_local_bounds(Object *ob, DerivedMesh *dm, float *center, float *size)
{
BoundBox *bb= NULL;
/* uses boundbox, function used by Ketsji */
switch (ob->type)
{
case OB_MESH:
- bb= ( (Mesh *)ob->data )->bb;
- if(bb==0)
+ if (dm)
+ {
+ float min_r[3], max_r[3];
+ INIT_MINMAX(min_r, max_r);
+ dm->getMinMax(dm, min_r, max_r);
+ size[0]= 0.5*fabs(max_r[0] - min_r[0]);
+ size[1]= 0.5*fabs(max_r[1] - min_r[1]);
+ size[2]= 0.5*fabs(max_r[2] - min_r[2]);
+
+ center[0]= 0.5*(max_r[0] + min_r[0]);
+ center[1]= 0.5*(max_r[1] + min_r[1]);
+ center[2]= 0.5*(max_r[2] + min_r[2]);
+ return;
+ } else
{
- my_tex_space_mesh((struct Mesh *)ob->data);
bb= ( (Mesh *)ob->data )->bb;
+ if(bb==0)
+ {
+ my_tex_space_mesh((struct Mesh *)ob->data);
+ bb= ( (Mesh *)ob->data )->bb;
+ }
}
break;
case OB_CURVE:
@@ -1498,7 +1514,10 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
}
KX_BoxBounds bb;
- my_get_local_bounds(blenderobject,objprop.m_boundobject.box.m_center,bb.m_extends);
+ DerivedMesh* dm = NULL;
+ if (gameobj->GetDeformer())
+ dm = gameobj->GetDeformer()->GetFinalMesh();
+ my_get_local_bounds(blenderobject,dm,objprop.m_boundobject.box.m_center,bb.m_extends);
if (blenderobject->gameflag & OB_BOUNDS)
{
switch (blenderobject->boundtype)
@@ -1567,7 +1586,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
{
#ifdef USE_BULLET
case UseBullet:
- KX_ConvertBulletObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop);
+ KX_ConvertBulletObject(gameobj, meshobj, dm, kxscene, shapeprops, smmaterial, &objprop);
break;
#endif
@@ -1947,8 +1966,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
int activeLayerBitInfo = blenderscene->lay;
- // templist to find Root Parents (object with no parents)
- CListValue* templist = new CListValue();
+ // list of all object converted, active and inactive
CListValue* sumolist = new CListValue();
vector<parentChildLink> vec_parent_child;
@@ -2048,9 +2066,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->SetName(blenderobject->id.name);
- // templist to find Root Parents (object with no parents)
- templist->Add(gameobj->AddRef());
-
// update children/parent hierarchy
if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
{
@@ -2243,9 +2258,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->SetName(blenderobject->id.name);
- // templist to find Root Parents (object with no parents)
- templist->Add(gameobj->AddRef());
-
// update children/parent hierarchy
if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
{
@@ -2398,8 +2410,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
for ( i=0;i<childrenlist->GetCount();i++)
{
KX_GameObject* obj = static_cast<KX_GameObject*>(childrenlist->GetValue(i));
- if (templist->RemoveValue(obj))
- obj->Release();
if (sumolist->RemoveValue(obj))
obj->Release();
if (logicbrick_conversionlist->RemoveValue(obj))
@@ -2455,16 +2465,47 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
vec_parent_child.clear();
// find 'root' parents (object that has not parents in SceneGraph)
- for (i=0;i<templist->GetCount();++i)
+ for (i=0;i<sumolist->GetCount();++i)
{
- KX_GameObject* gameobj = (KX_GameObject*) templist->GetValue(i);
+ KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
if (gameobj->GetSGNode()->GetSGParent() == 0)
{
parentlist->Add(gameobj->AddRef());
gameobj->NodeUpdateGS(0);
}
}
-
+
+ // create graphic controller for culling
+ if (kxscene->GetDbvtCulling())
+ {
+ bool occlusion = false;
+ for (i=0; i<sumolist->GetCount();i++)
+ {
+ KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
+ if (gameobj->GetMeshCount() > 0)
+ {
+ MT_Point3 box[2];
+ gameobj->GetSGNode()->BBox().getmm(box, MT_Transform::Identity());
+ // box[0] is the min, box[1] is the max
+ bool isactive = objectlist->SearchValue(gameobj);
+ BL_CreateGraphicObjectNew(gameobj,box[0],box[1],kxscene,isactive,physics_engine);
+ if (gameobj->GetOccluder())
+ occlusion = true;
+ }
+ }
+ if (occlusion)
+ kxscene->SetDbvtOcclusionRes(blenderscene->world->occlusionRes);
+ }
+
+ // now that the scenegraph is complete, let's instantiate the deformers.
+ // We need that to create reusable derived mesh and physic shapes
+ for (i=0;i<sumolist->GetCount();++i)
+ {
+ KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
+ if (gameobj->GetDeformer())
+ gameobj->GetDeformer()->UpdateBuckets();
+ }
+
bool processCompoundChildren = false;
// create physics information
@@ -2498,28 +2539,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
}
- // create graphic controller for culling
- if (kxscene->GetDbvtCulling())
- {
- bool occlusion = false;
- for (i=0; i<sumolist->GetCount();i++)
- {
- KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
- if (gameobj->GetMeshCount() > 0)
- {
- MT_Point3 box[2];
- gameobj->GetSGNode()->BBox().getmm(box, MT_Transform::Identity());
- // box[0] is the min, box[1] is the max
- bool isactive = objectlist->SearchValue(gameobj);
- BL_CreateGraphicObjectNew(gameobj,box[0],box[1],kxscene,isactive,physics_engine);
- if (gameobj->GetOccluder())
- occlusion = true;
- }
- }
- if (occlusion)
- kxscene->SetDbvtOcclusionRes(blenderscene->world->occlusionRes);
- }
-
//set ini linearVel and int angularVel //rcruiz
if (converter->addInitFromFrame)
for (i=0;i<sumolist->GetCount();i++)
@@ -2605,7 +2624,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
}
}
- templist->Release();
sumolist->Release();
// convert global sound stuff
diff --git a/source/gameengine/Converter/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp
index b6a59774636..b49544050d1 100644
--- a/source/gameengine/Converter/BL_MeshDeformer.cpp
+++ b/source/gameengine/Converter/BL_MeshDeformer.cpp
@@ -91,6 +91,15 @@ BL_MeshDeformer::~BL_MeshDeformer()
delete [] m_transnors;
}
+void BL_MeshDeformer::ProcessReplica()
+{
+ m_transverts = NULL;
+ m_transnors = NULL;
+ m_tvtot = 0;
+ m_bDynamic=false;
+ m_lastDeformUpdate = -1;
+}
+
void BL_MeshDeformer::Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
{
void **h_obj = (*map)[m_gameobj];
diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h
index 11ca3b00a1d..99ae5f9dea0 100644
--- a/source/gameengine/Converter/BL_MeshDeformer.h
+++ b/source/gameengine/Converter/BL_MeshDeformer.h
@@ -66,7 +66,7 @@ public:
virtual bool Update(void){ return false; };
virtual bool UpdateBuckets(void){ return false; };
virtual RAS_Deformer* GetReplica(){return NULL;};
- virtual void ProcessReplica() {m_bDynamic=false;};
+ virtual void ProcessReplica();
struct Mesh* GetMesh() { return m_bmesh; };
// virtual void InitDeform(double time){};
diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp
index 3c4c0c5caad..fe539f9a6c5 100644
--- a/source/gameengine/Converter/BL_ModifierDeformer.cpp
+++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp
@@ -72,8 +72,11 @@ extern "C"{
BL_ModifierDeformer::~BL_ModifierDeformer()
{
if (m_dm) {
- m_dm->needsFree = 1;
- m_dm->release(m_dm);
+ // deformedOnly is used as a user counter
+ if (--m_dm->deformedOnly == 0) {
+ m_dm->needsFree = 1;
+ m_dm->release(m_dm);
+ }
}
};
@@ -90,7 +93,10 @@ void BL_ModifierDeformer::ProcessReplica()
{
/* Note! - This is not inherited from PyObjectPlus */
BL_ShapeDeformer::ProcessReplica();
- m_dm = NULL;
+ if (m_dm)
+ // by default try to reuse mesh, deformedOnly is used as a user count
+ m_dm->deformedOnly++;
+ // this will force an update and if the mesh cannot be reused, a new one will be created
m_lastModifierUpdate = -1;
}
@@ -117,29 +123,40 @@ bool BL_ModifierDeformer::Update(void)
bool bShapeUpdate = BL_ShapeDeformer::Update();
if (bShapeUpdate || m_lastModifierUpdate != m_gameobj->GetLastFrame()) {
- /* execute the modifiers */
- 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;
- /* execute the modifiers */
- DerivedMesh *dm = mesh_create_derived_no_virtual(blendobj, m_transverts, CD_MASK_MESH);
- /* restore object data */
- blendobj->data = oldmesh;
- /* free the current derived mesh and replace, (dm should never be NULL) */
- if (m_dm != NULL) {
- m_dm->needsFree = 1;
+ // static derived mesh are not updated
+ if (m_dm == NULL || m_bDynamic) {
+ /* execute the modifiers */
+ 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;
+ /* execute the modifiers */
+ DerivedMesh *dm = mesh_create_derived_no_virtual(blendobj, m_transverts, CD_MASK_MESH);
+ /* restore object data */
+ blendobj->data = oldmesh;
+ /* free the current derived mesh and replace, (dm should never be NULL) */
+ if (m_dm != NULL) {
+ // HACK! use deformedOnly as a user counter
+ if (--m_dm->deformedOnly == 0) {
+ m_dm->needsFree = 1;
+ m_dm->release(m_dm);
+ }
+ }
+ m_dm = dm;
+ // get rid of temporary data
+ m_dm->needsFree = 0;
m_dm->release(m_dm);
- }
- m_dm = dm;
- /* update the graphic controller */
- PHY_IGraphicController *ctrl = m_gameobj->GetGraphicController();
- if (ctrl) {
- float min_r[3], max_r[3];
- INIT_MINMAX(min_r, max_r);
- m_dm->getMinMax(m_dm, min_r, max_r);
- ctrl->setLocalAabb(min_r, max_r);
+ // HACK! use deformedOnly as a user counter
+ m_dm->deformedOnly = 1;
+ /* update the graphic controller */
+ PHY_IGraphicController *ctrl = m_gameobj->GetGraphicController();
+ if (ctrl) {
+ float min_r[3], max_r[3];
+ INIT_MINMAX(min_r, max_r);
+ m_dm->getMinMax(m_dm, min_r, max_r);
+ ctrl->setLocalAabb(min_r, max_r);
+ }
}
m_lastModifierUpdate=m_gameobj->GetLastFrame();
bShapeUpdate = true;
@@ -156,10 +173,10 @@ bool BL_ModifierDeformer::Apply(RAS_IPolyMaterial *mat)
int nmat = m_pMeshObject->NumMaterials();
for (int imat=0; imat<nmat; imat++) {
RAS_MeshMaterial *mmat = m_pMeshObject->GetMeshMaterial(imat);
- RAS_MeshSlot *slot = *mmat->m_slots[(void*)m_gameobj];
- if(!slot)
+ RAS_MeshSlot **slot = mmat->m_slots[(void*)m_gameobj];
+ if(!slot || !*slot)
continue;
- slot->m_pDerivedMesh = m_dm;
+ (*slot)->m_pDerivedMesh = m_dm;
}
return true;
}
diff --git a/source/gameengine/Converter/BL_ModifierDeformer.h b/source/gameengine/Converter/BL_ModifierDeformer.h
index 465c287a88b..d5a1caeb91f 100644
--- a/source/gameengine/Converter/BL_ModifierDeformer.h
+++ b/source/gameengine/Converter/BL_ModifierDeformer.h
@@ -86,6 +86,11 @@ public:
{
m_lastModifierUpdate = -1.0;
};
+ virtual struct DerivedMesh* GetFinalMesh()
+ {
+ return m_dm;
+ }
+
protected:
double m_lastModifierUpdate;
diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp
index e04d4dad015..12ef3ff84f1 100644
--- a/source/gameengine/Converter/BL_ShapeDeformer.cpp
+++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp
@@ -77,6 +77,12 @@ RAS_Deformer *BL_ShapeDeformer::GetReplica()
return result;
}
+void BL_ShapeDeformer::ProcessReplica()
+{
+ BL_SkinDeformer::ProcessReplica();
+ m_lastShapeUpdate = -1;
+}
+
bool BL_ShapeDeformer::LoadShapeDrivers(Object* arma)
{
IpoCurve *icu;
@@ -163,7 +169,8 @@ bool BL_ShapeDeformer::Update(void)
// check for armature deform
bSkinUpdate = BL_SkinDeformer::Update();
- if (!bSkinUpdate && bShapeUpdate) {
+ // non dynamic deformer = Modifer without armature and shape keys, no need to create storage
+ if (!bSkinUpdate && bShapeUpdate && m_bDynamic) {
// this means that there is no armature, we still need to copy the vertex to m_transverts
// and update the normal (was not done after shape key calculation)
diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h
index 1ec7bfdf74a..949e5e1e3ad 100644
--- a/source/gameengine/Converter/BL_ShapeDeformer.h
+++ b/source/gameengine/Converter/BL_ShapeDeformer.h
@@ -67,6 +67,7 @@ public:
};
virtual RAS_Deformer *GetReplica();
+ virtual void ProcessReplica();
virtual ~BL_ShapeDeformer();
bool Update (void);
diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp
index e92c3b29543..a13f78e1b27 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.cpp
+++ b/source/gameengine/Converter/BL_SkinDeformer.cpp
@@ -127,24 +127,26 @@ bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
if (!Update())
return false;
- // the vertex cache is unique to this deformer, no need to update it
- // if it wasn't updated! We must update all the materials at once
- // because we will not get here again for the other material
- nmat = m_pMeshObject->NumMaterials();
- for (imat=0; imat<nmat; imat++) {
- mmat = m_pMeshObject->GetMeshMaterial(imat);
- if(!mmat->m_slots[(void*)m_gameobj])
- continue;
-
- slot = *mmat->m_slots[(void*)m_gameobj];
-
- // for each array
- for(slot->begin(it); !slot->end(it); slot->next(it)) {
- // for each vertex
- // copy the untransformed data from the original mvert
- for(i=it.startvertex; i<it.endvertex; i++) {
- RAS_TexVert& v = it.vertex[i];
- v.SetXYZ(m_transverts[v.getOrigIndex()]);
+ if (m_transverts) {
+ // the vertex cache is unique to this deformer, no need to update it
+ // if it wasn't updated! We must update all the materials at once
+ // because we will not get here again for the other material
+ nmat = m_pMeshObject->NumMaterials();
+ for (imat=0; imat<nmat; imat++) {
+ mmat = m_pMeshObject->GetMeshMaterial(imat);
+ if(!mmat->m_slots[(void*)m_gameobj])
+ continue;
+
+ slot = *mmat->m_slots[(void*)m_gameobj];
+
+ // for each array
+ for(slot->begin(it); !slot->end(it); slot->next(it)) {
+ // for each vertex
+ // copy the untransformed data from the original mvert
+ for(i=it.startvertex; i<it.endvertex; i++) {
+ RAS_TexVert& v = it.vertex[i];
+ v.SetXYZ(m_transverts[v.getOrigIndex()]);
+ }
}
}
}
@@ -161,6 +163,13 @@ RAS_Deformer *BL_SkinDeformer::GetReplica()
return result;
}
+void BL_SkinDeformer::ProcessReplica()
+{
+ BL_MeshDeformer::ProcessReplica();
+ m_lastArmaUpdate = -1;
+ m_releaseobject = false;
+}
+
//void where_is_pose (Object *ob);
//void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts, int deformflag);
bool BL_SkinDeformer::Update(void)
diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h
index 0a7b60788f9..8d3167746be 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.h
+++ b/source/gameengine/Converter/BL_SkinDeformer.h
@@ -68,6 +68,8 @@ public:
BL_ArmatureObject* arma = NULL);
virtual RAS_Deformer *GetReplica();
+ virtual void ProcessReplica();
+
virtual ~BL_SkinDeformer();
bool Update (void);
bool Apply (class RAS_IPolyMaterial *polymat);
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
index 40c715974f9..5b912a123fe 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
@@ -47,6 +47,7 @@
class RAS_MeshObject;
class KX_Scene;
+struct DerivedMesh;
typedef enum {
KX_BOUNDBOX,
@@ -183,6 +184,7 @@ bool KX_ReInstanceShapeFromMesh(RAS_MeshObject* meshobj);
void KX_ConvertBulletObject( class KX_GameObject* gameobj,
class RAS_MeshObject* meshobj,
+ struct DerivedMesh* dm,
class KX_Scene* kxscene,
struct PHY_ShapeProps* shapeprops,
struct PHY_MaterialProps* smmaterial,
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index 07fdc8ec41b..f18ffb56ccb 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -52,6 +52,10 @@
#include "KX_MotionState.h" // bridge between motionstate and scenegraph node
+extern "C"{
+ #include "BKE_DerivedMesh.h"
+}
+
#ifdef USE_ODE
#include "KX_OdePhysicsController.h"
@@ -792,6 +796,7 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj,
void KX_ConvertBulletObject( class KX_GameObject* gameobj,
class RAS_MeshObject* meshobj,
+ struct DerivedMesh* dm,
class KX_Scene* kxscene,
struct PHY_ShapeProps* shapeprops,
struct PHY_MaterialProps* smmaterial,
@@ -884,42 +889,36 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
}
case KX_BOUNDPOLYTOPE:
{
- shapeInfo->SetMesh(meshobj, true,false);
+ shapeInfo->SetMesh(meshobj, dm,true,false);
bm = shapeInfo->CreateBulletShape();
break;
}
case KX_BOUNDMESH:
{
-
- if (!ci.m_mass ||objprop->m_softbody)
- {
- // mesh shapes can be shared, check first if we already have a shape on that mesh
- class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, false);
- if (sharedShapeInfo != NULL)
- {
- delete shapeInfo;
- shapeInfo = sharedShapeInfo;
- shapeInfo->AddRef();
- } else
- {
- shapeInfo->SetMesh(meshobj, false,false);
- }
+ bool useGimpact = (ci.m_mass && !objprop->m_softbody);
- // Soft bodies require welding. Only avoid remove doubles for non-soft bodies!
- if (objprop->m_softbody)
- {
- shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI
- }
-
- bm = shapeInfo->CreateBulletShape();
- //no moving concave meshes, so don't bother calculating inertia
- //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
+ // mesh shapes can be shared, check first if we already have a shape on that mesh
+ class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, dm, false,useGimpact);
+ if (sharedShapeInfo != NULL)
+ {
+ delete shapeInfo;
+ shapeInfo = sharedShapeInfo;
+ shapeInfo->AddRef();
} else
{
- shapeInfo->SetMesh(meshobj, false,true);
- bm = shapeInfo->CreateBulletShape();
+ shapeInfo->SetMesh(meshobj, dm, false,useGimpact);
}
+ // Soft bodies require welding. Only avoid remove doubles for non-soft bodies!
+ if (objprop->m_softbody)
+ {
+ shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI
+ }
+
+ bm = shapeInfo->CreateBulletShape();
+ //should we compute inertia for dynamic shape?
+ //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
+
break;
}
}
diff --git a/source/gameengine/Physics/Bullet/CMakeLists.txt b/source/gameengine/Physics/Bullet/CMakeLists.txt
index ec2cdede683..02f2aa635af 100644
--- a/source/gameengine/Physics/Bullet/CMakeLists.txt
+++ b/source/gameengine/Physics/Bullet/CMakeLists.txt
@@ -32,6 +32,7 @@ SET(INC
../../../../extern/bullet2/src
../../../../extern/glew/include
../../../../intern/moto/include
+ ../../../../intern/guardedalloc
../../../kernel/gen_system
../../../../intern/string
../../../../intern/SoundSystem
@@ -41,6 +42,8 @@ SET(INC
../../GameLogic
../../SceneGraph
../../../../source/blender/makesdna
+ ../../../../source/blender/blenlib
+ ../../../../source/blender/blenkernel
${PYTHON_INC}
)
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 961e9096442..01e8aa2560f 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -35,6 +35,10 @@ subject to the following restrictions:
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+extern "C"{
+#include "BKE_cdderivedmesh.h"
+}
+
class BP_Proxy;
///todo: fill all the empty CcdPhysicsController methods, hook them up to the btRigidBody class
@@ -1312,9 +1316,9 @@ void DefaultMotionState::calculateWorldTransformations()
// Shape constructor
std::map<RAS_MeshObject*, CcdShapeConstructionInfo*> CcdShapeConstructionInfo::m_meshShapeMap;
-CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mesh, bool polytope)
+CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope, bool gimpact)
{
- if (polytope)
+ if (polytope || dm || gimpact)
// not yet supported
return NULL;
@@ -1324,9 +1328,9 @@ CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mes
return NULL;
}
-bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bool useGimpact)
+bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, bool polytope,bool useGimpact)
{
- int numpolys;
+ int numpolys, numverts;
m_useGimpact = useGimpact;
@@ -1335,6 +1339,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo
assert(IsUnused());
m_shapeType = PHY_SHAPE_NONE;
m_meshObject = NULL;
+ bool free_dm = false;
// No mesh object or mesh has no polys
if (!meshobj || meshobj->HasColliderPolygon()==false) {
@@ -1344,12 +1349,21 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo
return false;
}
- numpolys = meshobj->NumPolygons();
+ if (!dm) {
+ free_dm = true;
+ dm = CDDM_from_mesh(meshobj->GetMesh(), NULL);
+ }
+
+ MVert *mvert = dm->getVertArray(dm);
+ MFace *mface = dm->getFaceArray(dm);
+ numpolys = dm->getNumFaces(dm);
+ numverts = dm->getNumVerts(dm);
+ int* index = (int*)dm->getFaceDataArray(dm, CD_ORIGINDEX);
m_shapeType = (polytope) ? PHY_SHAPE_POLYTOPE : PHY_SHAPE_MESH;
/* Convert blender geometry into bullet mesh, need these vars for mapping */
- vector<bool> vert_tag_array(meshobj->GetMesh()->totvert, false);
+ vector<bool> vert_tag_array(numverts, false);
unsigned int tot_bt_verts= 0;
unsigned int orig_index;
int i;
@@ -1359,19 +1373,16 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo
// Tag verts we're using
for (int p2=0; p2<numpolys; p2++)
{
- RAS_Polygon* poly= meshobj->GetPolygon(p2);
+ MFace* mf = &mface[p2];
+ RAS_Polygon* poly = meshobj->GetPolygon(index[p2]);
// only add polygons that have the collision flag set
if (poly->IsCollider())
{
- for(i=0; i<poly->VertexCount(); i++) {
- orig_index= poly->GetVertex(i)->getOrigIndex();
- if (vert_tag_array[orig_index]==false)
- {
- vert_tag_array[orig_index]= true;
- tot_bt_verts++;
- }
- }
+ if (vert_tag_array[mf->v1]==false) {vert_tag_array[mf->v1]= true;tot_bt_verts++;}
+ if (vert_tag_array[mf->v2]==false) {vert_tag_array[mf->v2]= true;tot_bt_verts++;}
+ if (vert_tag_array[mf->v3]==false) {vert_tag_array[mf->v3]= true;tot_bt_verts++;}
+ if (mf->v4 && vert_tag_array[mf->v4]==false) {vert_tag_array[mf->v4]= true;tot_bt_verts++;}
}
}
@@ -1381,51 +1392,69 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo
for (int p2=0; p2<numpolys; p2++)
{
- RAS_Polygon* poly= meshobj->GetPolygon(p2);
+ MFace* mf = &mface[p2];
+ RAS_Polygon* poly= meshobj->GetPolygon(index[p2]);
// only add polygons that have the collisionflag set
if (poly->IsCollider())
{
- for(i=0; i<poly->VertexCount(); i++) {
- RAS_TexVert *v= poly->GetVertex(i);
- orig_index= v->getOrigIndex();
-
- if (vert_tag_array[orig_index]==true)
- {
- const float* vtx = v->getXYZ();
- vert_tag_array[orig_index]= false;
-
- *bt++ = vtx[0];
- *bt++ = vtx[1];
- *bt++ = vtx[2];
- }
+ if (vert_tag_array[mf->v1]==true)
+ {
+ const float* vtx = mvert[mf->v1].co;
+ vert_tag_array[mf->v1]= false;
+ *bt++ = vtx[0];
+ *bt++ = vtx[1];
+ *bt++ = vtx[2];
+ }
+ if (vert_tag_array[mf->v2]==true)
+ {
+ const float* vtx = mvert[mf->v2].co;
+ vert_tag_array[mf->v2]= false;
+ *bt++ = vtx[0];
+ *bt++ = vtx[1];
+ *bt++ = vtx[2];
+ }
+ if (vert_tag_array[mf->v3]==true)
+ {
+ const float* vtx = mvert[mf->v3].co;
+ vert_tag_array[mf->v3]= false;
+ *bt++ = vtx[0];
+ *bt++ = vtx[1];
+ *bt++ = vtx[2];
+ }
+ if (mf->v4 && vert_tag_array[mf->v4]==true)
+ {
+ const float* vtx = mvert[mf->v4].co;
+ vert_tag_array[mf->v4]= false;
+ *bt++ = vtx[0];
+ *bt++ = vtx[1];
+ *bt++ = vtx[2];
}
}
}
}
else {
unsigned int tot_bt_tris= 0;
- vector<int> vert_remap_array(meshobj->GetMesh()->totvert, 0);
+ vector<int> vert_remap_array(numverts, 0);
// Tag verts we're using
for (int p2=0; p2<numpolys; p2++)
{
- RAS_Polygon* poly= meshobj->GetPolygon(p2);
+ MFace* mf = &mface[p2];
+ RAS_Polygon* poly= meshobj->GetPolygon(index[p2]);
// only add polygons that have the collision flag set
if (poly->IsCollider())
{
- for(i=0; i<poly->VertexCount(); i++) {
- orig_index= poly->GetVertex(i)->getOrigIndex();
- if (vert_tag_array[orig_index]==false)
- {
- vert_tag_array[orig_index]= true;
- vert_remap_array[orig_index]= tot_bt_verts;
- tot_bt_verts++;
- }
- }
-
- tot_bt_tris += (i==4 ? 2:1); /* a quad or a tri */
+ if (vert_tag_array[mf->v1]==false)
+ {vert_tag_array[mf->v1]= true;vert_remap_array[mf->v1]= tot_bt_verts;tot_bt_verts++;}
+ if (vert_tag_array[mf->v2]==false)
+ {vert_tag_array[mf->v2]= true;vert_remap_array[mf->v2]= tot_bt_verts;tot_bt_verts++;}
+ if (vert_tag_array[mf->v3]==false)
+ {vert_tag_array[mf->v3]= true;vert_remap_array[mf->v3]= tot_bt_verts;tot_bt_verts++;}
+ if (mf->v4 && vert_tag_array[mf->v4]==false)
+ {vert_tag_array[mf->v4]= true;vert_remap_array[mf->v4]= tot_bt_verts;tot_bt_verts++;}
+ tot_bt_tris += (mf->v4 ? 2:1); /* a quad or a tri */
}
}
@@ -1437,76 +1466,67 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo
int *poly_index_pt= &m_polygonIndexArray[0];
int *tri_pt= &m_triFaceArray[0];
-
for (int p2=0; p2<numpolys; p2++)
{
- RAS_Polygon* poly= meshobj->GetPolygon(p2);
+ MFace* mf = &mface[p2];
+ RAS_Polygon* poly= meshobj->GetPolygon(index[p2]);
// only add polygons that have the collisionflag set
if (poly->IsCollider())
{
- RAS_TexVert *v1= poly->GetVertex(0);
- RAS_TexVert *v2= poly->GetVertex(1);
- RAS_TexVert *v3= poly->GetVertex(2);
- int i1= v1->getOrigIndex();
- int i2= v2->getOrigIndex();
- int i3= v3->getOrigIndex();
- const float* vtx;
+ MVert *v1= &mvert[mf->v1];
+ MVert *v2= &mvert[mf->v2];
+ MVert *v3= &mvert[mf->v3];
// the face indicies
- tri_pt[0]= vert_remap_array[i1];
- tri_pt[1]= vert_remap_array[i2];
- tri_pt[2]= vert_remap_array[i3];
+ tri_pt[0]= vert_remap_array[mf->v1];
+ tri_pt[1]= vert_remap_array[mf->v2];
+ tri_pt[2]= vert_remap_array[mf->v3];
tri_pt= tri_pt+3;
// m_polygonIndexArray
- *poly_index_pt= p2;
+ *poly_index_pt= index[p2];
poly_index_pt++;
// the vertex location
- if (vert_tag_array[i1]==true) { /* *** v1 *** */
- vert_tag_array[i1]= false;
- vtx = v1->getXYZ();
- *bt++ = vtx[0];
- *bt++ = vtx[1];
- *bt++ = vtx[2];
+ if (vert_tag_array[mf->v1]==true) { /* *** v1 *** */
+ vert_tag_array[mf->v1]= false;
+ *bt++ = v1->co[0];
+ *bt++ = v1->co[1];
+ *bt++ = v1->co[2];
}
- if (vert_tag_array[i2]==true) { /* *** v2 *** */
- vert_tag_array[i2]= false;
- vtx = v2->getXYZ();
- *bt++ = vtx[0];
- *bt++ = vtx[1];
- *bt++ = vtx[2];
+ if (vert_tag_array[mf->v2]==true) { /* *** v2 *** */
+ vert_tag_array[mf->v2]= false;
+ *bt++ = v2->co[0];
+ *bt++ = v2->co[1];
+ *bt++ = v2->co[2];
}
- if (vert_tag_array[i3]==true) { /* *** v3 *** */
- vert_tag_array[i3]= false;
- vtx = v3->getXYZ();
- *bt++ = vtx[0];
- *bt++ = vtx[1];
- *bt++ = vtx[2];
+ if (vert_tag_array[mf->v3]==true) { /* *** v3 *** */
+ vert_tag_array[mf->v3]= false;
+ *bt++ = v3->co[0];
+ *bt++ = v3->co[1];
+ *bt++ = v3->co[2];
}
- if (poly->VertexCount()==4)
+ if (mf->v4)
{
- RAS_TexVert *v4= poly->GetVertex(3);
- int i4= v4->getOrigIndex();
+ MVert *v4= &mvert[mf->v4];
- tri_pt[0]= vert_remap_array[i1];
- tri_pt[1]= vert_remap_array[i3];
- tri_pt[2]= vert_remap_array[i4];
+ tri_pt[0]= vert_remap_array[mf->v1];
+ tri_pt[1]= vert_remap_array[mf->v3];
+ tri_pt[2]= vert_remap_array[mf->v4];
tri_pt= tri_pt+3;
// m_polygonIndexArray
- *poly_index_pt= p2;
+ *poly_index_pt= index[p2];
poly_index_pt++;
// the vertex location
- if (vert_tag_array[i4]==true) { /* *** v4 *** */
- vert_tag_array[i4]= false;
- vtx = v4->getXYZ();
- *bt++ = vtx[0];
- *bt++ = vtx[1];
- *bt++ = vtx[2];
+ if (vert_tag_array[mf->v4]==true) { /* *** v4 *** */
+ vert_tag_array[mf->v4]= false;
+ *bt++ = v4->co[0];
+ *bt++ = v4->co[1];
+ *bt++ = v4->co[2];
}
}
}
@@ -1538,7 +1558,13 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo
#endif
m_meshObject = meshobj;
- if (!polytope)
+ if (free_dm) {
+ dm->release(dm);
+ dm = NULL;
+ }
+
+ // sharing only on static mesh at present, if you change that, you must also change in FindMesh
+ if (!polytope && !dm && !useGimpact)
{
// triangle shape can be shared, store the mesh object in the map
m_meshShapeMap.insert(std::pair<RAS_MeshObject*,CcdShapeConstructionInfo*>(meshobj,this));
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 4ab478b2106..315e2bdf429 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -36,6 +36,7 @@ extern bool gDisableDeactivation;
class CcdPhysicsEnvironment;
class btMotionState;
class RAS_MeshObject;
+struct DerivedMesh;
class btCollisionShape;
@@ -59,7 +60,7 @@ class CcdShapeConstructionInfo
public:
- static CcdShapeConstructionInfo* FindMesh(RAS_MeshObject* mesh, bool polytope);
+ static CcdShapeConstructionInfo* FindMesh(class RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope, bool gimpact);
CcdShapeConstructionInfo() :
m_shapeType(PHY_SHAPE_NONE),
@@ -139,7 +140,7 @@ public:
return true;
}
- bool SetMesh(RAS_MeshObject* mesh, bool polytope,bool useGimpact);
+ bool SetMesh(class RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope,bool useGimpact);
RAS_MeshObject* GetMesh(void)
{
return m_meshObject;
diff --git a/source/gameengine/Physics/Bullet/Makefile b/source/gameengine/Physics/Bullet/Makefile
index 48e537bb6a3..19b17de275a 100644
--- a/source/gameengine/Physics/Bullet/Makefile
+++ b/source/gameengine/Physics/Bullet/Makefile
@@ -51,4 +51,6 @@ CPPFLAGS += -I../../Expressions
CPPFLAGS += -I../../GameLogic
CPPFLAGS += -I../../SceneGraph
CPPFLAGS += -I../../../../source/blender/makesdna
+CPPFLAGS += -I../../../../source/blender/blenkernel
+CPPFLAGS += -I../../../../source/blender/blenlib
diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript
index 115ab8bf730..c517d8b5d9d 100644
--- a/source/gameengine/Physics/Bullet/SConscript
+++ b/source/gameengine/Physics/Bullet/SConscript
@@ -14,7 +14,10 @@ incs += ' #source/gameengine/Expressions'
incs += ' #source/gameengine/GameLogic'
incs += ' #source/gameengine/SceneGraph'
incs += ' #source/blender/makesdna'
+incs += ' #source/blender/blenkernel'
+incs += ' #source/blender/blenlib'
incs += ' #intern/SoundSystem'
+incs += ' #intern/guardedalloc'
incs += ' ' + env['BF_BULLET_INC']
incs += ' ' + env['BF_PYTHON_INC']
diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h
index bb8e3750485..9dc656ba56a 100644
--- a/source/gameengine/Rasterizer/RAS_Deformer.h
+++ b/source/gameengine/Rasterizer/RAS_Deformer.h
@@ -34,12 +34,15 @@
#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
#endif //WIN32
+#include <stdlib.h>
#include "GEN_Map.h"
+struct DerivedMesh;
+
class RAS_Deformer
{
public:
- RAS_Deformer() : m_pMesh(0), m_bDynamic(false) {};
+ RAS_Deformer() : m_pMesh(NULL), m_bDynamic(false) {};
virtual ~RAS_Deformer(){};
virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map)=0;
virtual bool Apply(class RAS_IPolyMaterial *polymat)=0;
@@ -60,6 +63,11 @@ public:
{
return m_bDynamic;
}
+ virtual struct DerivedMesh* GetFinalMesh()
+ {
+ return NULL;
+ }
+
protected:
class RAS_MeshObject *m_pMesh;
bool m_bDynamic;
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
index f5324c6fbc9..014169f8838 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
@@ -118,16 +118,24 @@ RAS_ListRasterizer::~RAS_ListRasterizer()
void RAS_ListRasterizer::RemoveListSlot(RAS_ListSlot* list)
{
- if (list->m_flag & LIST_STANDALONE)
- return ;
-
- RAS_ArrayLists::iterator it = mArrayLists.begin();
- while(it != mArrayLists.end()) {
- if (it->second == list) {
- mArrayLists.erase(it);
- break;
+ if (list->m_flag & LIST_DERIVEDMESH) {
+ RAS_DerivedMeshLists::iterator it = mDerivedMeshLists.begin();
+ while(it != mDerivedMeshLists.end()) {
+ if (it->second == list) {
+ mDerivedMeshLists.erase(it);
+ break;
+ }
+ it++;
+ }
+ } else {
+ RAS_ArrayLists::iterator it = mArrayLists.begin();
+ while(it != mArrayLists.end()) {
+ if (it->second == list) {
+ mArrayLists.erase(it);
+ break;
+ }
+ it++;
}
- it++;
}
}
@@ -143,9 +151,15 @@ RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(RAS_MeshSlot& ms)
if(!localSlot) {
if (ms.m_pDerivedMesh) {
// that means that we draw based on derived mesh, a display list is possible
- // but it's unique to this mesh slot
- localSlot = new RAS_ListSlot(this);
- localSlot->m_flag |= LIST_STANDALONE;
+ // Note that we come here only for static derived mesh
+ RAS_DerivedMeshLists::iterator it = mDerivedMeshLists.find(ms.m_pDerivedMesh);
+ if(it == mDerivedMeshLists.end()) {
+ localSlot = new RAS_ListSlot(this);
+ localSlot->m_flag |= LIST_DERIVEDMESH;
+ mDerivedMeshLists.insert(std::pair<DerivedMesh*, RAS_ListSlot*>(ms.m_pDerivedMesh, localSlot));
+ } else {
+ localSlot = static_cast<RAS_ListSlot*>(it->second->AddRef());
+ }
} else {
RAS_ArrayLists::iterator it = mArrayLists.find(ms.m_displayArrays);
if(it == mArrayLists.end()) {
@@ -162,12 +176,12 @@ RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(RAS_MeshSlot& ms)
void RAS_ListRasterizer::ReleaseAlloc()
{
- RAS_ArrayLists::iterator it = mArrayLists.begin();
- while(it != mArrayLists.end()) {
+ for(RAS_ArrayLists::iterator it = mArrayLists.begin();it != mArrayLists.end();++it)
delete it->second;
- it++;
- }
mArrayLists.clear();
+ for (RAS_DerivedMeshLists::iterator it = mDerivedMeshLists.begin();it != mDerivedMeshLists.end();++it)
+ delete it->second;
+ mDerivedMeshLists.clear();
}
void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
index 912f28af6aa..fe358808e4a 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
@@ -34,16 +34,20 @@ enum RAS_ListSlotFlags {
LIST_BEGIN =16,
LIST_END =32,
LIST_REGEN =64,
- LIST_STANDALONE =128,
+ LIST_DERIVEDMESH=128,
};
+struct DerivedMesh;
+
typedef std::map<RAS_DisplayArrayList, RAS_ListSlot*> RAS_ArrayLists;
+typedef std::map<DerivedMesh*, RAS_ListSlot*> RAS_DerivedMeshLists;
class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
{
bool mUseVertexArrays;
bool mATI;
RAS_ArrayLists mArrayLists;
+ RAS_DerivedMeshLists mDerivedMeshLists;
RAS_ListSlot* FindOrAdd(class RAS_MeshSlot& ms);
void ReleaseAlloc();