diff options
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 2 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_BlenderDataConversion.cpp | 7 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_ConvertPhysicsObject.h | 6 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp | 180 | ||||
-rw-r--r-- | source/gameengine/Physics/Bullet/CcdPhysicsController.cpp | 100 | ||||
-rw-r--r-- | source/gameengine/Physics/Bullet/CcdPhysicsController.h | 10 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_TexVert.h | 21 |
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; } |