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
path: root/source
diff options
context:
space:
mode:
authorErwin Coumans <blender@erwincoumans.com>2008-09-25 07:02:30 +0400
committerErwin Coumans <blender@erwincoumans.com>2008-09-25 07:02:30 +0400
commit718e2bf74f0ba2dcabe5bee7d88c1975ecfe9f06 (patch)
tree4b39512b98daef011a4f1031b3f87c0da6c10a5a /source
parent38a80ff9a5c6d7bebef42bc3b8320d781b4e4f1c (diff)
improved game soft bodies, works for objects that are using 'set smooth'
use shape matching by default for game soft bodies store soft body index for game vertices
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/object.c2
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp7
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObject.h6
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp180
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp100
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h10
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.h21
8 files changed, 219 insertions, 108 deletions
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 54908230d88..9f6921fbade 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -967,7 +967,7 @@ Object *add_only_object(int type, char *name)
ob->linearStiffness = 1.0f;
ob->angularStiffness = 1.0f;
ob->volumePreservation = 1.0f;
- ob->gamesoftFlag = 0;
+ ob->gamesoftFlag = OB_SOFT_SHAPE_MATCHING;
/* NT fluid sim defaults */
ob->fluidsimFlag = 0;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index d966d691fdd..f1823de954c 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -7853,6 +7853,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ob->linearStiffness = 1.0f;
ob->angularStiffness = 1.0f;
ob->volumePreservation = 1.0f;
+ ob->softflag = OB_SOFT_SHAPE_MATCHING;
}
}
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 6a5048a9f15..b3df2d7bc85 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1321,6 +1321,13 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0;
objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
+
+ ///for game soft bodies
+ objprop.m_linearStiffness = blenderobject->linearStiffness;
+ objprop.m_angularStiffness = blenderobject->angularStiffness;
+ objprop.m_volumePreservation = blenderobject->volumePreservation;
+ objprop.m_gamesoftFlag = blenderobject->gamesoftFlag;
+
objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0;
objprop.m_disableSleeping = (blenderobject->gameflag & OB_COLLISION_RESPONSE) != 0;//abuse the OB_COLLISION_RESPONSE flag
//mmm, for now, taks this for the size of the dynamicobject
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
index 2b6c2535878..6325c9365fd 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
@@ -87,6 +87,12 @@ struct KX_ObjectProperties
bool m_disableSleeping;
bool m_hasCompoundChildren;
bool m_isCompoundChild;
+
+ float m_linearStiffness;
+ float m_angularStiffness;
+ float m_volumePreservation;
+ int m_gamesoftFlag;
+
double m_margin;
KX_BoundBoxClass m_boundclass;
union {
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index c4411a58856..5744a860e92 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -667,6 +667,85 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj,
#endif //WIN32
+
+ class KX_SoftBodyDeformer : public RAS_Deformer
+ {
+ btSoftBody* m_softBody;
+ class RAS_MeshObject* m_pMeshObject;
+ class BL_DeformableGameObject* m_gameobj;
+
+
+ public:
+ KX_SoftBodyDeformer(btSoftBody* softBody,RAS_MeshObject* pMeshObject,BL_DeformableGameObject* gameobj)
+ : m_softBody(softBody),
+ m_pMeshObject(pMeshObject),
+ m_gameobj(gameobj)
+ {
+ //printf("KX_SoftBodyDeformer\n");
+ };
+
+ virtual ~KX_SoftBodyDeformer()
+ {
+ //printf("~KX_SoftBodyDeformer\n");
+ };
+ virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
+ {
+ //printf("relink\n");
+ }
+ virtual bool Apply(class RAS_IPolyMaterial *polymat)
+ {
+ //printf("apply\n");
+ RAS_MeshSlot::iterator it;
+ RAS_MeshMaterial *mmat;
+ RAS_MeshSlot *slot;
+ size_t i;
+
+ // update the vertex in m_transverts
+ Update();
+
+ // 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.
+ mmat = m_pMeshObject->GetMeshMaterial(polymat);
+ if(!mmat->m_slots[(void*)m_gameobj])
+ return true;
+
+ slot = *mmat->m_slots[(void*)m_gameobj];
+
+ // for each array
+ for(slot->begin(it); !slot->end(it); slot->next(it))
+ {
+ btSoftBody::tNodeArray& nodes(m_softBody->m_nodes);
+
+ int index = 0;
+ for(i=it.startvertex; i<it.endvertex; i++,index++) {
+ RAS_TexVert& v = it.vertex[i];
+
+ MT_Point3 pt (
+ nodes[v.getSoftBodyIndex()].m_x.getX(),
+ nodes[v.getSoftBodyIndex()].m_x.getY(),
+ nodes[v.getSoftBodyIndex()].m_x.getZ());
+ v.SetXYZ(pt);
+ }
+ }
+ return true;
+ }
+ virtual bool Update(void)
+ {
+ //printf("update\n");
+ return true;//??
+ }
+ virtual RAS_Deformer *GetReplica()
+ {
+ //printf("getReplica\n");
+ return 0;
+ }
+ protected:
+ //class RAS_MeshObject *m_pMesh;
+ };
+
+
// forward declarations
void KX_ConvertBulletObject( class KX_GameObject* gameobj,
@@ -916,6 +995,11 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
ci.m_angularDamping = 1.f - shapeprops->m_ang_drag;
//need a bit of damping, else system doesn't behave well
ci.m_inertiaFactor = shapeprops->m_inertia/0.4f;//defaults to 0.4, don't want to change behaviour
+ ci.m_linearStiffness = objprop->m_linearStiffness;
+ ci.m_angularStiffness= objprop->m_angularStiffness;
+ ci.m_volumePreservation= objprop->m_volumePreservation;
+ ci.m_gamesoftFlag = objprop->m_gamesoftFlag;
+
ci.m_collisionFilterGroup = (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : short(CcdConstructionInfo::StaticFilter);
ci.m_collisionFilterMask = (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody;
@@ -990,107 +1074,15 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
physicscontroller->SetObject(gameobj->GetSGNode());
- class KX_SoftBodyDeformer : public RAS_Deformer
- {
- btSoftBody* m_softBody;
- class BL_SkinMeshObject* m_pMeshObject;
- class BL_DeformableGameObject* m_gameobj;
-
-
- public:
- KX_SoftBodyDeformer(btSoftBody* softBody,BL_SkinMeshObject* pMeshObject,BL_DeformableGameObject* gameobj)
- : m_softBody(softBody),
- m_pMeshObject(pMeshObject),
- m_gameobj(gameobj)
- {
- //printf("KX_SoftBodyDeformer\n");
- };
-
- virtual ~KX_SoftBodyDeformer()
- {
- //printf("~KX_SoftBodyDeformer\n");
- };
- virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
- {
- //printf("relink\n");
- }
- virtual bool Apply(class RAS_IPolyMaterial *polymat)
- {
- //printf("apply\n");
- RAS_MeshSlot::iterator it;
- RAS_MeshMaterial *mmat;
- RAS_MeshSlot *slot;
- size_t i;
-
- // update the vertex in m_transverts
- Update();
-
- // 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.
- mmat = m_pMeshObject->GetMeshMaterial(polymat);
- if(!mmat->m_slots[(void*)m_gameobj])
- return true;
-
- 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
- int count = 0;
- {
-
- for(i=it.startvertex; i<it.endvertex; i++,count++)
- {
- }
- }
- btSoftBody::tNodeArray& nodes(m_softBody->m_nodes);
-
- if (count == m_softBody->m_userIndexMapping.size())
- {
- int index = 0;
- for(i=it.startvertex; i<it.endvertex; i++,index++) {
- RAS_TexVert& v = it.vertex[i];
-
- MT_Point3 pt (
- nodes[m_softBody->m_userIndexMapping[index]].m_x.getX(),
- nodes[m_softBody->m_userIndexMapping[index]].m_x.getY(),
- nodes[m_softBody->m_userIndexMapping[index]].m_x.getZ());
- v.SetXYZ(pt);
-
- //(m_transverts[v.getOrigIndex()]);
- }
- }
-
- }
-
- return true;
- }
- virtual bool Update(void)
- {
- //printf("update\n");
- return true;//??
- }
- virtual RAS_Deformer *GetReplica()
- {
- //printf("getReplica\n");
- return 0;
- }
- protected:
- //class RAS_MeshObject *m_pMesh;
- };
///test for soft bodies
if (objprop->m_softbody && physicscontroller)
{
btSoftBody* softBody = physicscontroller->GetSoftBody();
- if (softBody && gameobj->GetMesh(0))
+ if (softBody && gameobj->GetMesh(0))//only the first mesh, if any
{
//should be a mesh then, so add a soft body deformer
- KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer(softBody, (BL_SkinMeshObject*)gameobj->GetMesh(0),(BL_DeformableGameObject*)gameobj);
+ KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer(softBody, gameobj->GetMesh(0),(BL_DeformableGameObject*)gameobj);
gameobj->SetDeformer(softbodyDeformer);
}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index ad79db16dc4..333ecd6ea11 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -222,14 +222,57 @@ void CcdPhysicsController::CreateRigidbody()
psb->appendFace(idx[0],idx[1],idx[2]);
}
+ ///create a mapping between graphics mesh vertices and soft body vertices
{
- for (int i=0;i<hlib.m_vertexIndexMapping.size();i++)
- psb->m_userIndexMapping.push_back(hlib.m_vertexIndexMapping[i]);
- //psb->m_userIndexMapping.push_back(hres.m_Indices[i]);
+ RAS_MeshObject* rasMesh= GetShapeInfo()->GetMesh();
+
+ if (rasMesh)
+ {
+
+ //printf("apply\n");
+ RAS_MeshSlot::iterator it;
+ RAS_MeshMaterial *mmat;
+ RAS_MeshSlot *slot;
+ size_t i;
+
+ //for each material
+ for (int m=0;m<rasMesh->NumMaterials();m++)
+ {
+ // 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.
+ mmat = rasMesh->GetMeshMaterial(m);
+
+ slot = mmat->m_baseslot;
+ for(slot->begin(it); !slot->end(it); slot->next(it))
+ {
+ int index = 0;
+ for(i=it.startvertex; i<it.endvertex; i++,index++)
+ {
+ RAS_TexVert* vertex = &it.vertex[i];
+ //search closest index, and store it in vertex
+ vertex->setSoftBodyIndex(0);
+ btScalar maxDistSqr = 1e30;
+ btSoftBody::tNodeArray& nodes(psb->m_nodes);
+ btVector3 xyz = trans(btVector3(vertex->getXYZ()[0],vertex->getXYZ()[1],vertex->getXYZ()[2]));
+ for (int n=0;n<nodes.size();n++)
+ {
+ btScalar distSqr = (nodes[n].m_x - xyz).length2();
+ if (distSqr<maxDistSqr)
+ {
+ maxDistSqr = distSqr;
+ vertex->setSoftBodyIndex(n);
+ }
+ }
+ }
+ }
+ }
+ }
}
hlib.ReleaseResult(hres);
- psb->randomizeConstraints();
+
}
@@ -292,13 +335,42 @@ void CcdPhysicsController::CreateRigidbody()
//psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RS;//btSoftBody::fCollision::CL_SS+ btSoftBody::fCollision::CL_RS;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RS + btSoftBody::fCollision::CL_SS;
+ //psb->m_cfg.collisions = btSoftBody::fCollision::CL_SS + btSoftBody::fCollision::CL_RS;
//btSoftBody::Material* pm=psb->appendMaterial();
btSoftBody::Material* pm=psb->m_materials[0];
- pm->m_kLST = 0.1f;
+
+ pm->m_kLST = m_cci.m_linearStiffness;
+ pm->m_kAST = m_cci.m_angularStiffness;
+ pm->m_kVST = m_cci.m_volumePreservation;
+
+
+
+
//pm->m_kAST = 0.01f;
//pm->m_kVST = 0.001f;
psb->generateBendingConstraints(2,pm);
+ //psb->m_cfg.piterations = 4;
+ //psb->m_cfg.viterations = 4;
+ //psb->m_cfg.diterations = 4;
+ //psb->m_cfg.citerations = 4;
+ if (m_cci.m_gamesoftFlag & 1)///OB_SOFT_SHAPE_MATCHING)
+ {
+ psb->setPose(false,true);//
+ } else
+ {
+ psb->setPose(true,false);
+ }
+
+ psb->m_cfg.kDF = 0.5;
+ psb->m_cfg.kMT = 0.05;
+ psb->m_cfg.piterations = 5;
+
+ psb->m_cfg.piterations = 5;
+ //psb->m_cfg.kVC = 20;
+
+ psb->randomizeConstraints();
+
/*
psb->m_cfg.kDF = 0.1f;//1.f;
psb->m_cfg.kDP = 0.0001;
@@ -315,10 +387,10 @@ void CcdPhysicsController::CreateRigidbody()
// psb->activate();
// psb->setActivationState(1);
// psb->setDeactivationTime(1.f);
- //psb->m_cfg.piterations = 4;
+
//psb->m_materials[0]->m_kLST = 0.1+(i/(btScalar)(n-1))*0.9;
psb->setTotalMass(m_cci.m_mass);
- psb->generateClusters(64);
+ //psb->generateClusters(8);//(64);
psb->setCollisionFlags(0);
// m_object->setCollisionShape(rbci.m_collisionShape);
btTransform startTrans;
@@ -1147,7 +1219,19 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope)
{
const float* vtx = poly->GetVertex(i)->getXYZ();
btPoint3 point(vtx[0],vtx[1],vtx[2]);
- m_vertexArray.push_back(point);
+ //avoid duplicates (could better directly use vertex offsets, rather than a vertex compare)
+ bool found = false;
+ for (int j=0;j<m_vertexArray.size();j++)
+ {
+ if (m_vertexArray[j]==point)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ m_vertexArray.push_back(point);
+
numvalidpolys++;
}
} else
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index c45f4590749..65c23eb2543 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -147,6 +147,10 @@ struct CcdConstructionInfo
m_linearDamping(0.1f),
m_angularDamping(0.1f),
m_margin(0.06f),
+ m_linearStiffness(1.f),
+ m_angularStiffness(1.f),
+ m_volumePreservation(1.f),
+ m_gamesoftFlag(0),
m_collisionFlags(0),
m_bRigid(false),
m_bSoft(false),
@@ -169,6 +173,12 @@ struct CcdConstructionInfo
btScalar m_linearDamping;
btScalar m_angularDamping;
btScalar m_margin;
+
+ btScalar m_linearStiffness;
+ btScalar m_angularStiffness;
+ btScalar m_volumePreservation;
+ int m_gamesoftFlag;
+
int m_collisionFlags;
bool m_bRigid;
bool m_bSoft;
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h
index 4ec4db19e53..54da109cbf1 100644
--- a/source/gameengine/Rasterizer/RAS_TexVert.h
+++ b/source/gameengine/Rasterizer/RAS_TexVert.h
@@ -44,15 +44,16 @@ class RAS_TexVert
float m_uv1[2]; // 2*4 = 8
float m_uv2[2]; // 2*4 = 8
unsigned int m_rgba; // 4
- float m_tangent[4]; // 4*2 = 8
- float m_normal[3]; // 3*2 = 6
+ float m_tangent[4]; // 4*4 = 16
+ float m_normal[3]; // 3*4 = 12
short m_flag; // 2
+ short m_softBodyIndex; //2
unsigned int m_unit; // 4
- unsigned int m_origindex; // 4
+ unsigned int m_origindex; // 4
//---------
- // 56
+ // 56+6+8+2=72
// 32 bytes total size, fits nice = 56 = not fit nice.
- // We'll go for 64 bytes total size - 24 bytes left.
+
public:
enum {
FLAT = 1,
@@ -91,6 +92,16 @@ public:
return m_normal;
}
+ short int getSoftBodyIndex() const
+ {
+ return m_softBodyIndex;
+ }
+
+ void setSoftBodyIndex(short int sbIndex)
+ {
+ m_softBodyIndex = sbIndex;
+ }
+
const float* getTangent() const {
return m_tangent;
}