Improved rigid body handling for non spherical bounds type.

Polyheder dynamic objects are now converted properly.
This commit is contained in:
Kester Maddock 2004-04-16 06:26:33 +00:00
parent 98b8c5102d
commit 4e2f7baff2
4 changed files with 42 additions and 34 deletions

@ -496,7 +496,7 @@ static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blendero
// in Blender, inertia stands for the size value which is equivalent to // in Blender, inertia stands for the size value which is equivalent to
// the sphere radius // the sphere radius
shapeProps->m_inertia = blenderobject->formfactor * blenderobject->mass * blenderobject->inertia * blenderobject->inertia; shapeProps->m_inertia = blenderobject->formfactor;
assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f); assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f);
assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f); assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f);
@ -734,6 +734,11 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2]; objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
break; break;
} }
case OB_BOUND_POLYH:
{
objprop.m_boundclass = KX_BOUNDMESH;
break;
}
} }
} }

@ -130,27 +130,42 @@ void KX_ConvertSumoObject( KX_GameObject* gameobj,
switch (objprop->m_boundclass) switch (objprop->m_boundclass)
{ {
case KX_BOUNDBOX: case KX_BOUNDBOX:
shape = DT_NewBox(objprop->m_boundobject.box.m_extends[0], objprop->m_boundobject.box.m_extends[1], objprop->m_boundobject.box.m_extends[2]); shape = DT_NewBox(objprop->m_boundobject.box.m_extends[0],
smprop->m_inertia.scale(objprop->m_boundobject.box.m_extends[0], objprop->m_boundobject.box.m_extends[1], objprop->m_boundobject.box.m_extends[2]); objprop->m_boundobject.box.m_extends[1],
smprop->m_inertia /= (objprop->m_boundobject.box.m_extends[0] + objprop->m_boundobject.box.m_extends[1] + objprop->m_boundobject.box.m_extends[2]) / 3.; objprop->m_boundobject.box.m_extends[2]);
smprop->m_inertia.scale(objprop->m_boundobject.box.m_extends[0]*objprop->m_boundobject.box.m_extends[0],
objprop->m_boundobject.box.m_extends[1]*objprop->m_boundobject.box.m_extends[1],
objprop->m_boundobject.box.m_extends[2]*objprop->m_boundobject.box.m_extends[2]);
smprop->m_inertia *= smprop->m_mass/MT_Vector3(objprop->m_boundobject.box.m_extends).length();
break; break;
case KX_BOUNDCYLINDER: case KX_BOUNDCYLINDER:
shape = DT_NewCylinder(objprop->m_radius, objprop->m_boundobject.c.m_height); shape = DT_NewCylinder(smprop->m_radius, objprop->m_boundobject.c.m_height);
smprop->m_inertia.scale(smprop->m_mass*smprop->m_radius*smprop->m_radius,
smprop->m_mass*smprop->m_radius*smprop->m_radius,
smprop->m_mass*objprop->m_boundobject.c.m_height*objprop->m_boundobject.c.m_height);
break; break;
case KX_BOUNDCONE: case KX_BOUNDCONE:
shape = DT_NewCone(objprop->m_radius, objprop->m_boundobject.c.m_height); shape = DT_NewCone(objprop->m_radius, objprop->m_boundobject.c.m_height);
smprop->m_inertia.scale(smprop->m_mass*smprop->m_radius*smprop->m_radius,
smprop->m_mass*smprop->m_radius*smprop->m_radius,
smprop->m_mass*objprop->m_boundobject.c.m_height*objprop->m_boundobject.c.m_height);
break; break;
/* Enabling this allows you to use dynamic mesh objects. It's disabled 'cause it's really slow. */ /* Dynamic mesh objects. WARNING! slow. */
case KX_BOUNDMESH: case KX_BOUNDMESH:
if (meshobj && meshobj->NumPolygons() > 0) if (meshobj && meshobj->NumPolygons() > 0)
{ {
if ((shape = CreateShapeFromMesh(meshobj))) if ((shape = CreateShapeFromMesh(meshobj)))
{
// TODO: calculate proper inertia
smprop->m_inertia *= smprop->m_mass*smprop->m_radius*smprop->m_radius;
break; break;
} }
}
/* If CreateShapeFromMesh fails, fall through and use sphere */ /* If CreateShapeFromMesh fails, fall through and use sphere */
default: default:
case KX_BOUNDSPHERE: case KX_BOUNDSPHERE:
shape = DT_NewSphere(objprop->m_radius); shape = DT_NewSphere(objprop->m_radius);
smprop->m_inertia *= smprop->m_mass*smprop->m_radius*smprop->m_radius;
break; break;
} }

@ -51,7 +51,7 @@
// Tweak parameters // Tweak parameters
static const MT_Scalar ImpulseThreshold = 0.5; static const MT_Scalar ImpulseThreshold = -10.;
static const MT_Scalar FixThreshold = 0.01; static const MT_Scalar FixThreshold = 0.01;
static const MT_Scalar FixVelocity = 0.01; static const MT_Scalar FixVelocity = 0.01;
SM_Object::SM_Object( SM_Object::SM_Object(
@ -177,27 +177,22 @@ void SM_Object::dynamicCollision(const MT_Point3 &local2,
MT_Scalar invMass MT_Scalar invMass
) )
{ {
// Same again but now obj1 is non-dynamic
// Compute the point on obj1 closest to obj2 (= sphere with radius = 0)
// local1 is th point closest to obj2
// local2 is the local origin of obj2
// This should look familiar.... // This should look familiar....
MT_Scalar rel_vel_normal = normal.dot(rel_vel); MT_Scalar rel_vel_normal = normal.dot(rel_vel);
if (rel_vel_normal <= 0.0) { if (rel_vel_normal < -MT_EPSILON) {
if (-rel_vel_normal < ImpulseThreshold) { restitution *= MT_min(MT_Scalar(1.0), rel_vel_normal/ImpulseThreshold);
restitution = 0.0;
}
MT_Scalar impulse = -(1.0 + restitution) * rel_vel_normal; MT_Scalar impulse = -(1.0 + restitution) * rel_vel_normal;
if (isRigidBody()) if (isRigidBody())
{ {
MT_Vector3 temp = getInvInertiaTensor() * local2.cross(normal); MT_Vector3 temp = getInvInertiaTensor() * local2.cross(normal);
applyImpulse(local2 + m_pos, (impulse / (invMass + normal.dot(temp.cross(local2)))) * normal); impulse /= invMass + normal.dot(temp.cross(local2));
applyImpulse(local2 + m_pos, impulse * normal);
} else { } else {
applyCenterImpulse( ( impulse / invMass ) * normal ); impulse /= invMass;
applyCenterImpulse( impulse * normal );
} }
// The friction part starts here!!!!!!!! // The friction part starts here!!!!!!!!
@ -361,14 +356,7 @@ DT_Bool SM_Object::boing(
local1 -= obj1->m_pos, local2 -= obj2->m_pos; local1 -= obj1->m_pos, local2 -= obj2->m_pos;
// Calculate collision parameters // Calculate collision parameters
MT_Vector3 rel_vel = obj1->getVelocity(local1) + obj1->m_combined_lin_vel - MT_Vector3 rel_vel = obj1->getVelocity(local1) - obj2->getVelocity(local2);
obj2->getVelocity(local2) - obj2->m_combined_lin_vel;
if (obj1->isRigidBody())
rel_vel += obj1->actualAngVelocity().cross(local1);
if (obj2->isRigidBody())
rel_vel -= obj2->actualAngVelocity().cross(local2);
MT_Scalar restitution = MT_Scalar restitution =
MT_min(obj1->getMaterialProps()->m_restitution, MT_min(obj1->getMaterialProps()->m_restitution,
@ -1013,7 +1001,7 @@ getVelocity(
*/ */
return m_prev_kinematic && !isDynamic() ? return m_prev_kinematic && !isDynamic() ?
(m_xform(local) - m_prev_xform(local)) / m_timeStep : (m_xform(local) - m_prev_xform(local)) / m_timeStep :
m_lin_vel + m_ang_vel.cross(local); actualLinVelocity() + actualAngVelocity().cross(local);
//m_lin_vel + m_ang_vel.cross(m_xform.getBasis() * local); //m_lin_vel + m_ang_vel.cross(m_xform.getBasis() * local);
// NB: m_xform.getBasis() * local == m_xform(local) - m_xform.getOrigin() // NB: m_xform.getBasis() * local == m_xform(local) - m_xform.getOrigin()