Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Use wheel radius for wheel shape, filter(break) contacts at contact p…
…atch(lower quarter of the wheel shape).
  • Loading branch information
logzero committed Jan 23, 2012
1 parent 80bb1d2 commit 210d8fd
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/game.cpp
Expand Up @@ -113,6 +113,7 @@ GAME::GAME(std::ostream & info_out, std::ostream & error_out) :
http("/tmp")
{
carcontrols_local.first = 0;
dynamics.setContactAddedCallback(&sim::Vehicle::WheelContactCallback);
}

/* Start the game with the given arguments... */
Expand Down
3 changes: 1 addition & 2 deletions src/loadvehicle.cpp
Expand Up @@ -547,8 +547,7 @@ bool LoadVehicle(
btScalar mass = info.wheel[i].mass;
btScalar width = info.wheel[i].width;
btScalar radius = info.wheel[i].radius;
btScalar dr = 0.1f; // offset due to wheel ray model
btVector3 size(width * 0.5f, radius - dr, radius - dr);
btVector3 size(width * 0.5f, radius, radius);
btCollisionShape * shape = new btCylinderShapeX(size);
loadBody(cfg_wheel, error, shape, mass, true);
}
Expand Down
2 changes: 1 addition & 1 deletion src/sim/fracturebody.cpp
Expand Up @@ -38,7 +38,7 @@ FractureBody::FractureBody(const FractureBodyInfo & info) :
m_connections(info.m_connections),
m_motionState(*this)
{
m_internalType = CUSTOM_FRACTURE_TYPE | CO_RIGID_BODY;
m_internalType = CO_FRACTURE_TYPE | CO_RIGID_BODY;

// calculate center of mass and inertia
m_centerOfMassOffset = -info.m_massCenter / info.m_mass;
Expand Down
4 changes: 2 additions & 2 deletions src/sim/fracturebody.h
Expand Up @@ -4,7 +4,7 @@
#include "BulletDynamics/Dynamics/btRigidBody.h"
#include "LinearMath/btAlignedObjectArray.h"

#define CUSTOM_FRACTURE_TYPE (btRigidBody::CO_USER_TYPE*2)
#define CO_FRACTURE_TYPE (btRigidBody::CO_USER_TYPE)

class btDynamicsWorld;
class btCompoundShape;
Expand Down Expand Up @@ -66,7 +66,7 @@ class FractureBody : public btRigidBody
FrMotionState m_motionState;

// separate shape, return child body
btRigidBody* FractureBody::breakConnection(int con_id);
btRigidBody* breakConnection(int con_id);
};

struct FractureBodyInfo
Expand Down
37 changes: 36 additions & 1 deletion src/sim/vehicle.cpp
Expand Up @@ -22,7 +22,8 @@
#include "sim/solveconstraintrow.h"
#include "sim/world.h"
#include "coordinatesystem.h"
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
#include "BulletCollision/CollisionShapes/btCylinderShape.h"

namespace sim
{
Expand Down Expand Up @@ -87,6 +88,7 @@ void Vehicle::init(
body->setCenterOfMassTransform(transform);
body->setActivationState(DISABLE_DEACTIVATION);
body->setContactProcessingThreshold(0.0);
body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
world.addRigidBody(body);
world.addAction(this);
this->world = &world;
Expand Down Expand Up @@ -789,4 +791,37 @@ void Vehicle::print(std::ostream & out) const
}
}

bool Vehicle::WheelContactCallback(
btManifoldPoint& cp,
const btCollisionObject* colObj0,
int partId0,
int index0,
const btCollisionObject* colObj1,
int partId1,
int index1)
{
// cars are fracture bodies, wheel is a cylinder shape
if (colObj0->getInternalType() & CO_FRACTURE_TYPE)
{
const btCollisionShape* shape = colObj0->getCollisionShape();
if (shape->getShapeType() == CYLINDER_SHAPE_PROXYTYPE)
{
// is contact within contact patch?
const btCompoundShape* car = static_cast<const btCompoundShape*>(colObj0->getRootCollisionShape());
const btCylinderShapeX* wheel = static_cast<const btCylinderShapeX*>(shape);
btVector3 contactPoint = cp.m_localPointA - car->getChildTransform(cp.m_index0).getOrigin();
if (-direction::up.dot(contactPoint) > 0.5 * wheel->getRadius())
{
// break contact (hack)
cp.m_normalWorldOnB = btVector3(0, 0, 0);
cp.m_distance1 = 0;
cp.m_combinedFriction = 0;
cp.m_combinedRestitution = 0;
return true;
}
}
}
return false;
}

}
10 changes: 10 additions & 0 deletions src/sim/vehicle.h
Expand Up @@ -132,6 +132,16 @@ class Vehicle : public btActionInterface
// debugging
void print(std::ostream & out) const;

// to be registered before adding vehicles to world
static bool WheelContactCallback(
btManifoldPoint& cp,
const btCollisionObject* colObj0,
int partId0,
int index0,
const btCollisionObject* colObj1,
int partId1,
int index1);

protected:
World * world;
FractureBody * body;
Expand Down
9 changes: 7 additions & 2 deletions src/sim/world.cpp
Expand Up @@ -64,6 +64,11 @@ void World::setRayTestProcessor(RayTestProcessor & rtp)
rayTestProc = &rtp;
}

void World::setContactAddedCallback(ContactAddedCallback cb)
{
gContactAddedCallback = cb;
}

void World::addCollisionObject(btCollisionObject * object)
{
// disable shape drawing for meshes
Expand Down Expand Up @@ -107,7 +112,7 @@ void World::fractureCallback()
btPersistentManifold* manifold = getDispatcher()->getManifoldByIndexInternal(i);
if (!manifold->getNumContacts()) continue;

if (((btCollisionObject*)manifold->getBody0())->getInternalType() & CUSTOM_FRACTURE_TYPE)
if (((btCollisionObject*)manifold->getBody0())->getInternalType() & CO_FRACTURE_TYPE)
{
FractureBody* body = static_cast<FractureBody*>(manifold->getBody0());
for (int k = 0; k < manifold->getNumContacts(); ++k)
Expand All @@ -122,7 +127,7 @@ void World::fractureCallback()
}
}

if (((btCollisionObject*)manifold->getBody1())->getInternalType() & CUSTOM_FRACTURE_TYPE)
if (((btCollisionObject*)manifold->getBody1())->getInternalType() & CO_FRACTURE_TYPE)
{
FractureBody* body = static_cast<FractureBody*>(manifold->getBody1());
for (int k = 0; k < manifold->getNumContacts(); ++k)
Expand Down
2 changes: 2 additions & 0 deletions src/sim/world.h
Expand Up @@ -61,6 +61,8 @@ class World : public btDiscreteDynamicsWorld
struct RayTestProcessor;
void setRayTestProcessor(RayTestProcessor & rtp);

void setContactAddedCallback(ContactAddedCallback cb);

void addCollisionObject(btCollisionObject * object);

void update(btScalar dt);
Expand Down

0 comments on commit 210d8fd

Please sign in to comment.