And i don't understand why this system behaves extremely unpredictable. What do i mean by that: Every so often, say every 20ms, stepSimulation() is called:
Code: Select all
m_physicsWorld->stepSimulation(msDelta / 1000.f, 30, 1. / 180.);
In this case, i can more or less smoothly control the vehicle, and he gains nice speed easy and reliably.
Now if i call stepSimulation() (exactly as above) more often, say every 2 ms, i can't control vehicle at all - it just stays still, and even if it moves, than it is so slow that i can't even see. Bear in mind, the only thing that changed is how often stepSimulation() is called.
What the hell is happening here?
Some more code,
excerpt from a btActionInterface class
Code: Select all
void ShipPhysicsActor::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep)
{
if (m_forceVec.fuzzyZero() && m_torqueVec.fuzzyZero())
return;
// if m_forceVector is not zero, than its length is roughly 60.0 units
static int a = 0;
btTransform trans;
m_slaveBody->getMotionState()->getWorldTransform(trans);
btQuaternion worldRot, worldRotInv, force(m_forceVec.x(), m_forceVec.y(), m_forceVec.z(), 0);
worldRot = trans.getRotation();
worldRotInv = worldRot.inverse();
force = worldRot * force * worldRotInv;
btVector3 myForce(force.x(), force.y(), force.z());
assert(std::abs(myForce.length2() - m_forceVec.length2()) < 0.01f);
// rotate torque vector as well
btQuaternion torque(m_torqueVec.x(), m_torqueVec.y(), m_torqueVec.z(), 0);
torque = worldRot * torque * worldRotInv;
btVector3 myTorque(torque.x(), torque.y(), torque.z());
assert(std::abs(myTorque.length2() - m_torqueVec.length2()) < 0.01f);
if ((++a) % 50 == 0)
{
std::cerr << "Body at " << trans.getOrigin().x() << ", " << trans.getOrigin().y() << ", " << trans.getOrigin().z() << "\n";
std::cerr << "Apply force " << myForce.x() << ", " << myForce.y() << ", " << myForce.z() << "\n";
}
if (!m_forceVec.fuzzyZero())
{
m_slaveBody->applyCentralForce(myForce);
}
if (!m_torqueVec.fuzzyZero())
{
m_slaveBody->applyTorque(myTorque);
}
m_slaveBody->activate(true);
}
Code: Select all
PhysicsEngine::PhysicsEngine() :
m_collisionConfig(new btDefaultCollisionConfiguration),
m_collisionDispatcher(new btCollisionDispatcher(m_collisionConfig)),
m_broadphase(new btDbvtBroadphase),
m_constraintSolver(new btSequentialImpulseConstraintSolver)
{
m_physicsWorld = new btDiscreteDynamicsWorld(m_collisionDispatcher, m_broadphase, m_constraintSolver, m_collisionConfig);
m_physicsWorld->setGravity(btVector3(0, 0, 0));
[...]
}
Code: Select all
if (! m_vehicleShape)
// size is (0.1, 0.1, 0.3), mass is 10.0
m_vehicleShape = new btBoxShape(btVector3(sizes.x() / 2, sizes.y() / 2, sizes.z() / 2));
btTransform startTransform;
startTransform.setIdentity();
startTransform.setRotation(btQuaternion(orient.x(), orient.y(), orient.z(), orient.w()));
startTransform.setOrigin(btVector3(pos.x(), pos.y(), pos.z()));
VehicleMotionState* motionState = new VehicleMotionState(this, m_nextUsedId, startTransform);
btVector3 inertia;
m_vehicleShape->calculateLocalInertia(mass, inertia);
btRigidBody* body = new btRigidBody(mass, motionState, m_vehicleShape, inertia);
m_vehicles[m_nextUsedId] = body;
++m_nextUsedId;
body->setDamping(0.5f, 0.7f);
m_physicsWorld->addRigidBody(body, COLLISION_SHIPGROUP, COLLISION_SHIPGROUP | COLLISION_ASTEROIDGROUP);