diff options
author | Erwin Coumans <blender@erwincoumans.com> | 2008-10-01 03:34:25 +0400 |
---|---|---|
committer | Erwin Coumans <blender@erwincoumans.com> | 2008-10-01 03:34:25 +0400 |
commit | 808d6197cfa372c15067aa14a91791ba9b167915 (patch) | |
tree | 972dcafe2f60a767cc6b266310f6551681c1eea1 /source/gameengine | |
parent | 09f79a8e9f26d931667884f1147484e5d93ad63b (diff) |
add support for Bullet soft body constraints against a Bullet rigid body, as well as 'fixing' it. Just use the existing rigid body joint to use it. For now, it searches the closest node/vertex to the pivot. So you can use multiple constraints/joint to attach a cloth, soft body etc.
Diffstat (limited to 'source/gameengine')
-rw-r--r-- | source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp | 86 |
1 files changed, 85 insertions, 1 deletions
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index fc19789196d..72caadadac5 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -1464,6 +1464,26 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::CreateSphereController(float radi return sphereController; } +int findClosestNode(btSoftBody* sb,const btVector3& worldPoint); +int findClosestNode(btSoftBody* sb,const btVector3& worldPoint) +{ + int node = -1; + + btSoftBody::tNodeArray& nodes(sb->m_nodes); + float maxDistSqr = 1e30f; + + for (int n=0;n<nodes.size();n++) + { + btScalar distSqr = (nodes[n].m_x - worldPoint).length2(); + if (distSqr<maxDistSqr) + { + maxDistSqr = distSqr; + node = n; + } + } + return node; +} + int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl0,class PHY_IPhysicsController* ctrl1,PHY_ConstraintType type, float pivotX,float pivotY,float pivotZ, float axisX,float axisY,float axisZ, @@ -1479,14 +1499,78 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl btRigidBody* rb0 = c0 ? c0->GetRigidBody() : 0; btRigidBody* rb1 = c1 ? c1->GetRigidBody() : 0; + + + bool rb0static = rb0 ? rb0->isStaticOrKinematicObject() : true; bool rb1static = rb1 ? rb1->isStaticOrKinematicObject() : true; + + btCollisionObject* colObj0 = c0->GetCollisionObject(); + if (!colObj0) + { + return 0; + } + + btVector3 pivotInA(pivotX,pivotY,pivotZ); + + //it might be a soft body, let's try + btSoftBody* sb0 = c0 ? c0->GetSoftBody() : 0; + btSoftBody* sb1 = c1 ? c1->GetSoftBody() : 0; + if (sb0 && sb1) + { + //not between two soft bodies? + return 0; + } + + if (sb0) + { + //either cluster or node attach, let's find closest node first + //the soft body doesn't have a 'real' world transform, so get its initial world transform for now + btVector3 pivotPointSoftWorld = sb0->m_initialWorldTransform(pivotInA); + int node=findClosestNode(sb0,pivotPointSoftWorld); + if (node >=0) + { + if (rb1) + { + sb0->appendAnchor(node,rb1); + } else + { + sb0->setMass(node,0.f); + } + } + return 0;//can't remove soft body anchors yet + } + + if (sb1) + { + btVector3 pivotPointAWorld = colObj0->getWorldTransform()(pivotInA); + int node=findClosestNode(sb1,pivotPointAWorld); + if (node >=0) + { + if (rb0) + { + sb1->appendAnchor(node,rb0); + } else + { + sb1->setMass(node,0.f); + } + } + return 0;//can't remove soft body anchors yet + } + if (rb0static && rb1static) + { + return 0; + } + - btVector3 pivotInA(pivotX,pivotY,pivotZ); + if (!rb0) + return 0; + + btVector3 pivotInB = rb1 ? rb1->getCenterOfMassTransform().inverse()(rb0->getCenterOfMassTransform()(pivotInA)) : rb0->getCenterOfMassTransform() * pivotInA; btVector3 axisInA(axisX,axisY,axisZ); |