Hey,
I have the next objective in my project:
Doing a Character Controller and make that character being able to "bounce" on the top of a SoftBody. I'm using Bullet (obviously) and Ogre3D, but I think that this doesn't mind right now.
Right now, I have my world running, with a Kinematic Character Controller (quite similar to the one that comes with the demos) that makes use of a GhostObject to simulate the character behaviour, RigidBodies being "shot" when I press F key and a single SoftBody lying at some height.
All is working fine when I shoot RigidBodies to the SoftBody since both of them are reacting as it is intended: the SoftBody is getting deformed, and the RigiBody is bouncing on it.
Troubles comes when it refers to the main character. When I jump with the character into the SoftBody, the GhostObject (and the rendered model) are sinking into the SoftBody, ignoring the collision with it, but the SoftBody is actually reacting to the collision, being deformed.
I did some debugging and I could see that after my convexSweepTest call, my callback doesn't have any hit. Furthermore, I'm not receiving any call to the addSingleResult() function of my ClosestConvexResultCallback implementation. Does this means that convexSweepTest doesn't detect Ghost-Soft collisions? Because, obviously, this is the same method I follow to detect collisions between the character and the ground RigidBody and it's working perfectly.
Thanks in advance.
Ghost Object collide with Soft Bodies?
-
- Posts: 19
- Joined: Wed Aug 27, 2014 5:02 pm
Re: Ghost Object collide with Soft Bodies?
Is it possible to post the code that you are using? At least for the initialization of the objects but preferably for everything else?
-
- Posts: 5
- Joined: Fri Oct 17, 2014 12:14 pm
Re: Ghost Object collide with Soft Bodies?
Hi!
Since the code is really huge, I will post only what I think is the key.
Setting up the world:
Initializing the RigidBodies (those which collide perfectly with the SoftBody):
The "SceneNode" thing is just a reference to the Graphic Engine's node, so I can update its position every frame in the MotionState. And shapes are mainly btStaticPlaneShape and btBoxShape.
Initializing the ghost object:
Later on, I have created a CharacterControllerInterface implementation which works well.
Initializing the SoftBody:
The code to create the SoftBody from a trimesh is just a code that count the vertices and triangles and create the indexes array from an Ogre3D mesh, and the make this call:
No further modifications are made to this SoftBody until it returns to the other function.
To control the collisions with the GhostObject, I implement several functions, first one is to make the other bodies suffer the transformations:
And this one (and others, but this is the one which does it when the character is falling), is the one who must tell the GhostObject that he has collided with the other object, so he will change his movement behaviour:
As you can see, I've put a flag there and checked if the GhostBody is detecting the collision in his covexSweepTest, and it is not detecting it when we are talking about the SoftBody, but yes when it refers to the main static plane or the other RigidBody boxes.
With this code, the RigidBodies are colliding and "getting collided by" the SoftBody nicely; I mean, they both suffer transformations when interacting together.
Thank you so much, and please, let me know if you need other fragments of my code.
Since the code is really huge, I will post only what I think is the key.
Setting up the world:
Code: Select all
mCollisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
mDispatcher = new btCollisionDispatcher(mCollisionConfiguration);
//mBroadphase = new btDbvtBroadphase();
mBroadphase = new btAxisSweep3(btVector3(-10000,-10000,-10000), btVector3(10000,10000,10000), 1024);
mSolver = new btSequentialImpulseConstraintSolver();
mWorld = new btSoftRigidDynamicsWorld(mDispatcher, mBroadphase, mSolver, mCollisionConfiguration);
mWorld->setGravity(btVector3(0,-10,0));
Code: Select all
btRigidBody* Physics::addRigidBody(btTransform transform, btCollisionShape * shape, btScalar mass, Ogre::SceneNode * node)
{
numCollisionObjects++;
mCollisionShapes.push_back(shape);
btVector3 localInertia(0, 0, 0);
shape->calculateLocalInertia(mass, localInertia);
MyMotionState * motionState = new MyMotionState(transform, node);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, motionState, shape, localInertia);
btRigidBody * body = new btRigidBody(rbInfo);
mWorld->addRigidBody(body, COL_WORLD, everythingCollidesWith);
return body;
}
Initializing the ghost object:
Code: Select all
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(0, 20, 0));
Ogre::Vector3 origin(0, 20, 0);
btPairCachingGhostObject * characterGhostObject = new btPairCachingGhostObject();
characterGhostObject->setWorldTransform(startTransform);
btScalar characterHeight = 7.f;
btScalar characterWidth = 1.75f;
btConvexShape * capsule = new btCapsuleShape(characterWidth, characterHeight);
mPhysicsEngine->addCollisionShape(capsule);
characterGhostObject->setCollisionShape(capsule);
characterGhostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
Initializing the SoftBody:
Code: Select all
btSoftBody* Physics::addSoftFromEntity(Ogre::SceneNode* node, Ogre::Entity* ent)
{
StaticMeshToSoftBodyConverter converter(&mWorld->getWorldInfo(), ent);
btSoftBody* msb = converter.createSoftBodyFromTrimesh();
msb->setTotalMass(5,true);
mWorld->addSoftBody(msb, COL_CLOAK, cloakCollidesWith);
msb->m_cfg.piterations = 3;
msb->m_cfg.kDF = 0.5;
msb->randomizeConstraints();
MySoftBody* mMsb = new MySoftBody(node, msb);
mSoftBodies.push_back(mMsb);
return msb;
}
Code: Select all
btSoftBody* mSoftBody = btSoftBodyHelpers::CreateFromTriMesh(*mWorldInfo, vertices, indexes, ntriangles);
To control the collisions with the GhostObject, I implement several functions, first one is to make the other bodies suffer the transformations:
Code: Select all
void CharacterPhysics::setRBForceImpulseBasedOnCollision()
{
if (!mWalkDirection.isZero())
{
for (int i = 0; i < mGhostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++)
{
btBroadphasePair * collisionPair = &mGhostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
btRigidBody * rb = (btRigidBody*)collisionPair->m_pProxy1->m_clientObject;
if (mMass > rb->getInvMass())
{
btScalar resultMass = mMass - rb->getInvMass();
btVector3 reflection = computeReflectionDirection(mWalkDirection * resultMass, getNormalizedVector(mWalkDirection));
rb->applyCentralImpulse(reflection * -1);
}
}
}
}
Code: Select all
void CharacterPhysics::stepDown(btCollisionWorld * collisionWorld, btScalar dt)
{
btTransform start, end;
btScalar downVelocity = (mVerticalVelocity < 0 ? -mVerticalVelocity : 0) * dt;
if (downVelocity > 0 && downVelocity < mStepHeight && (mWasOnGround || !mWasJumping))
{
downVelocity = mStepHeight;
}
btVector3 stepDrop = getUpAxisDirections()[mUpAxis] * (mCurrentStepOffset + downVelocity);
mTargetPosition -= stepDrop;
start.setIdentity();
end.setIdentity();
start.setOrigin(mCurrentPosition);
end.setOrigin(mTargetPosition);
ClosestNotMeConvexResultCallback callback(mGhostObject, getUpAxisDirections()[mUpAxis], mMaxSlopeCosine);
callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
if (mUseGhostObjectSweepTest)
mGhostObject->convexSweepTest(mConvexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
else
collisionWorld->convexSweepTest(mConvexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
if (callback.hasHit())
{
std::cout << "Down Callback has hit" << std::endl;
mCurrentPosition.setInterpolate3(mCurrentPosition, mTargetPosition, callback.m_closestHitFraction);
mVerticalOffset = mVerticalVelocity = 0;
mWasJumping = false;
}
else{
mCurrentPosition = mTargetPosition;
}
}
With this code, the RigidBodies are colliding and "getting collided by" the SoftBody nicely; I mean, they both suffer transformations when interacting together.
Thank you so much, and please, let me know if you need other fragments of my code.
-
- Posts: 5
- Joined: Fri Oct 17, 2014 12:14 pm
Re: Ghost Object collide with Soft Bodies?
I've been thinking and maybe the solution is to make the character to be simulated by a RigidBody instead of by a GhostObject?
Do you guys know any example of this?
Thank you.
Do you guys know any example of this?
Thank you.
-
- Posts: 225
- Joined: Wed Jan 07, 2009 11:43 am
- Location: London
Re: Ghost Object collide with Soft Bodies?
Have you set up a ghost pair callback? rusty on this, but think that the ghost object won't have any overlapping pairs added (and thus convexsweep will fail) unless this is in place. If you're getting collisions with rigid bodies this may be wrong though. You should at least be able to breakpoint if a softbody is being added to the ghost objects internal pairs.