What should I do if I want to maximize the physical realism of my simulation? I understand there are different options for constraint solvers and whatnot; would using an alternate solver help? What can I do to get things bouncing to the height specified by their restitution coefficients?
Here's the code that demonstrates part of my issue:
Code: Select all
#include <bullet/btBulletDynamicsCommon.h>
#include <vector>
#include <iostream>
using std::cout;
using std::endl;
using std::vector;
class test {
private:
btDefaultCollisionConfiguration config;
btSimpleBroadphase broadphase;
btSequentialImpulseConstraintSolver solver;
btScalar timestep;
btCollisionDispatcher dispatcher;
btDiscreteDynamicsWorld world;
vector<btRigidBody> bodies;
btStaticPlaneShape plane_shape;
btSphereShape sphere_shape;
public:
test(btScalar dt) :
config (btDefaultCollisionConfiguration()),
broadphase (btSimpleBroadphase()),
solver (btSequentialImpulseConstraintSolver()),
timestep (dt),
dispatcher (btCollisionDispatcher(&config)),
world (btDiscreteDynamicsWorld(&dispatcher, &broadphase, &solver, &config)),
plane_shape (btStaticPlaneShape(btVector3(0, 0, 1), 0)),
sphere_shape (btSphereShape(1))
{
world.setGravity(btVector3(0, 0, -9.80665));
btRigidBody::btRigidBodyConstructionInfo plane_params(0, nullptr, &plane_shape, btVector3(0, 0, 0));
btVector3 inertia;
sphere_shape.calculateLocalInertia(3, inertia);
btRigidBody::btRigidBodyConstructionInfo ball_params(3, nullptr, &sphere_shape, inertia);
plane_params.m_restitution = 0.5;
ball_params.m_restitution = 0.9;
bodies.emplace_back(plane_params);
bodies.emplace_back(ball_params);
btTransform position;
position.setIdentity();
bodies[0].setWorldTransform(position);
position.setOrigin(btVector3(0, 0, 50));
bodies[1].setWorldTransform(position);
world.addRigidBody(&bodies[0]);
world.addRigidBody(&bodies[1]);
}
btScalar step() {
world.stepSimulation(timestep, 1, timestep);
return bodies[1].getWorldTransform().getOrigin().z();
}
};
int main() {
test t1(0.001);
test t2(0.01);
for (float i = 0; i < 10; i += 0.001) {
cout << i << " " << t1.step() << endl;
}
cout << endl;
for (float i = 0; i < 10; i += 0.01) {
cout << i << " " << t2.step() << endl;
}
}
EDIT: When I increase the restitution of the ground and ball to 1, the red ball bounces, but does not exhibit the correct rebound force like the green ball does. Here's the plot: