forked from bartvdbraak/blender
Improved rigid body handling for non spherical bounds type.
Polyheder dynamic objects are now converted properly.
This commit is contained in:
parent
98b8c5102d
commit
4e2f7baff2
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,14 +14,14 @@ public:
|
|||||||
|
|
||||||
void setPosition(const MT_Point3& pos) { m_pos = pos; }
|
void setPosition(const MT_Point3& pos) { m_pos = pos; }
|
||||||
void setOrientation(const MT_Quaternion& orn) { m_orn = orn; }
|
void setOrientation(const MT_Quaternion& orn) { m_orn = orn; }
|
||||||
void setLinearVelocity(const MT_Vector3& lin_vel) { m_lin_vel = lin_vel; }
|
void setLinearVelocity(const MT_Vector3& lin_vel) { m_lin_vel = lin_vel; }
|
||||||
void setAngularVelocity(const MT_Vector3& ang_vel) { m_ang_vel = ang_vel; }
|
void setAngularVelocity(const MT_Vector3& ang_vel) { m_ang_vel = ang_vel; }
|
||||||
|
|
||||||
const MT_Point3& getPosition() const { return m_pos; }
|
const MT_Point3& getPosition() const { return m_pos; }
|
||||||
const MT_Quaternion& getOrientation() const { return m_orn; }
|
const MT_Quaternion& getOrientation() const { return m_orn; }
|
||||||
const MT_Vector3& getLinearVelocity() const { return m_lin_vel; }
|
const MT_Vector3& getLinearVelocity() const { return m_lin_vel; }
|
||||||
const MT_Vector3& getAngularVelocity() const { return m_ang_vel; }
|
const MT_Vector3& getAngularVelocity() const { return m_ang_vel; }
|
||||||
|
|
||||||
virtual MT_Transform getTransform() const {
|
virtual MT_Transform getTransform() const {
|
||||||
return MT_Transform(m_pos, m_orn);
|
return MT_Transform(m_pos, m_orn);
|
||||||
}
|
}
|
||||||
|
@ -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,15 +356,8 @@ 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,
|
||||||
obj2->getMaterialProps()->m_restitution);
|
obj2->getMaterialProps()->m_restitution);
|
||||||
@ -1013,9 +1001,9 @@ 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()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user