I'm trying to manually place a dynamic rigid body using setWorldTransform, but I'm running into some snags. I'm setting a new transform between simulation steps, but my "changes" seem to be overwritten/ignored on subsequent steps.
Here's a program demonstrating my problem (output follows):
Code:
#include <iostream>
#include "btBulletDynamicsCommon.h"
struct MyMotionState : public btMotionState
{
MyMotionState(const btTransform& transform)
: mTransform(transform)
{
}
virtual void getWorldTransform(btTransform& returnTransform) const
{
std::cout << "getWorldTransform called... Y: " << mTransform.getOrigin().getY() << std::endl;
returnTransform = mTransform;
}
virtual void setWorldTransform(const btTransform& newTransform)
{
std::cout << "setWorldTransform called... Y: " << newTransform.getOrigin().getY() << std::endl;
mTransform = newTransform;
}
btTransform mTransform;
};
const float DEFAULT_X = 0.0f;
const float DEFAULT_Y = 10.0f;
const float DEFAULT_Z = 0.0f;
const float RADIUS = 5.0f;
const float MASS = 5.0f;
const float SIM_DELAY = 10.0f;
const int SLEEP_DELAY = 1000; // ms
int main()
{
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btBroadphaseInterface* broadphase = new btDbvtBroadphase;
btConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
btDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(DEFAULT_X, DEFAULT_Y, DEFAULT_Z));
btCollisionShape* fallShape = new btSphereShape(RADIUS);
MyMotionState* motionState = new MyMotionState(startTransform);
btVector3 fallInertia(0,0,0);
fallShape->calculateLocalInertia(MASS, fallInertia);
btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(MASS, motionState, fallShape, fallInertia);
btRigidBody* rigidBody = new btRigidBody(fallRigidBodyCI);
dynamicsWorld->addRigidBody(rigidBody);
for (int frameCount = 1; ; ++frameCount)
{
dynamicsWorld->stepSimulation(SIM_DELAY);
btTransform btt;
rigidBody->getMotionState()->getWorldTransform(btt);
std::cout << "Frame stepped.... Actual Y position: " << btt.getOrigin().getY() << std::endl;
if (frameCount % 3 == 0) // every few frames, try to reset rigidbody's MotionState
{
std::cout << "Resetting position..." << std::endl;
btTransform bttReset;
bttReset.setIdentity();
bttReset.setOrigin(btVector3(DEFAULT_X, DEFAULT_Y, DEFAULT_Z));
rigidBody->getMotionState()->setWorldTransform(bttReset);
}
Sleep(SLEEP_DELAY);
}
}
And here's the ouput:
Code:
getWorldTransform called... Y: 9.98611
Frame stepped.... Actual Y position: 9.98611
setWorldTransform called... Y: 9.975
getWorldTransform called... Y: 9.975
Frame stepped.... Actual Y position: 9.975
Resetting position...
setWorldTransform called... Y: 10
setWorldTransform called... Y: 9.96111
getWorldTransform called... Y: 9.96111
Frame stepped.... Actual Y position: 9.96111
setWorldTransform called... Y: 9.94445
getWorldTransform called... Y: 9.94445
Frame stepped.... Actual Y position: 9.94445
setWorldTransform called... Y: 9.92501
getWorldTransform called... Y: 9.92501
Frame stepped.... Actual Y position: 9.92501
Resetting position...
setWorldTransform called... Y: 10
setWorldTransform called... Y: 9.90279
getWorldTransform called... Y: 9.90279
Frame stepped.... Actual Y position: 9.90279
setWorldTransform called... Y: 9.87779
getWorldTransform called... Y: 9.87779
Frame stepped.... Actual Y position: 9.87779
...
I've run a similar simulation using a falling dynamic rigid body in which the body lands and bounces on a static rigid body. If I let the simulation run long enough for the dynamic body to come to a rest, I can set the transform and it holds between frames. Unfortunately, once I can do this, stepping the simulation doesn't affect the transform anymore. Is it possible to "restart" the simulation at that point so that further calls to stepSimulation affect the repositioned dynamic rigid body?