[Add] Angular response for dynamic on dynamic collisions.
This commit is contained in:
parent
d305487e8f
commit
748eee9e94
@ -6,8 +6,8 @@
|
||||
|
||||
DynamicBody::DynamicBody(void) : ModelBody() {
|
||||
m_flags = Body::FLAG_CAN_MOVE_FRAME;
|
||||
|
||||
m_orient = matrix4x4d::Identity();
|
||||
m_oldOrient = m_orient;
|
||||
m_force = vector3d(0.0);
|
||||
m_torque = vector3d(0.0);
|
||||
m_vel = vector3d(0.0);
|
||||
@ -26,6 +26,10 @@ void DynamicBody::AddForce(const vector3d f) {
|
||||
m_force += f;
|
||||
}
|
||||
|
||||
void DynamicBody::AddTorque(const vector3d t) {
|
||||
m_torque += t;
|
||||
}
|
||||
|
||||
void DynamicBody::AddForceAtPos(const vector3d force, const vector3d pos) {
|
||||
assert(0);
|
||||
/*
|
||||
@ -60,6 +64,7 @@ void DynamicBody::Load(void) {
|
||||
using namespace Serializer::Read;
|
||||
ModelBody::Load();
|
||||
for(int i = 0; i < 16; i++) m_orient[i] = rd_double();
|
||||
m_oldOrient = m_orient;
|
||||
m_force = rd_vector3d();
|
||||
m_torque = rd_vector3d();
|
||||
m_vel = rd_vector3d();
|
||||
@ -93,11 +98,8 @@ vector3d DynamicBody::GetPosition(void) const {
|
||||
}
|
||||
|
||||
void DynamicBody::TimeStepUpdate(const float timeStep) {
|
||||
/*
|
||||
* XXX Remember this is used to step back also in the collision code.
|
||||
* very silly btw.
|
||||
*/
|
||||
if(m_enabled) {
|
||||
m_oldOrient = m_orient;
|
||||
m_vel += timeStep * m_force * (1.0/m_mass);
|
||||
m_angVel += timeStep * m_torque * (1.0 / m_angInertia);
|
||||
|
||||
@ -124,6 +126,12 @@ void DynamicBody::TimeStepUpdate(const float timeStep) {
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicBody::UndoTimestep(void) {
|
||||
m_orient = m_oldOrient;
|
||||
TriMeshUpdateLastPos(m_orient);
|
||||
TriMeshUpdateLastPos(m_orient);
|
||||
}
|
||||
|
||||
void DynamicBody::Enable(void) {
|
||||
ModelBody::Enable();
|
||||
m_enabled = true;
|
||||
|
@ -20,6 +20,7 @@ public:
|
||||
void SetMesh(ObjMesh* m);
|
||||
virtual bool OnCollision(Body* b, Uint32 flags) { return true; }
|
||||
vector3d GetAngularMomentum(void);
|
||||
double GetAngularInertia(void) const { return m_angInertia; }
|
||||
void SetMassDistributionFromCollMesh(const CollMesh* m);
|
||||
void DisableBodyOnly(void) { m_enabled = false; }
|
||||
bool IsEnabled(void) { return m_enabled; }
|
||||
@ -27,10 +28,12 @@ public:
|
||||
virtual void Enable(void);
|
||||
virtual double GetMass(void) const { return m_mass; }
|
||||
virtual void TimeStepUpdate(const float timeStep);
|
||||
void UndoTimestep(void);
|
||||
|
||||
void SetMass(double);
|
||||
void AddForceAtPos(const vector3d force, const vector3d pos);
|
||||
void AddForce(const vector3d);
|
||||
void AddTorque(const vector3d);
|
||||
void SetForce(const vector3d);
|
||||
void SetTorque(const vector3d);
|
||||
/* body-relative forces. */
|
||||
@ -44,6 +47,7 @@ protected:
|
||||
private:
|
||||
/* New odeless stuff. */
|
||||
matrix4x4d m_orient; /* Contains pos. */
|
||||
matrix4x4d m_oldOrient;
|
||||
vector3d m_force;
|
||||
vector3d m_torque;
|
||||
vector3d m_vel;
|
||||
|
@ -342,6 +342,8 @@ static void hitCallback(CollisionContact* c) {
|
||||
if(po1_isDynBody && po2_isDynBody) {
|
||||
DynamicBody* b1 = static_cast<DynamicBody*>(po1);
|
||||
DynamicBody* b2 = static_cast<DynamicBody*>(po2);
|
||||
vector3d hitPos1 = c->pos - b1->GetPosition();
|
||||
vector3d hitPos2 = c->pos - b2->GetPosition();
|
||||
vector3d vel1 = b1->GetVelocity();
|
||||
vector3d vel2 = b2->GetVelocity();
|
||||
const vector3d relVel = vel2 - vel1;
|
||||
@ -350,15 +352,19 @@ static void hitCallback(CollisionContact* c) {
|
||||
|
||||
const double coeff_rest = 0.8;
|
||||
const double j = (-(1+coeff_rest) * (vector3d::Dot(relVel, c->normal))) /
|
||||
(vector3d::Dot(c->normal, c->normal) *
|
||||
(invMass1 + invMass2));
|
||||
( (invMass1 + invMass2) +
|
||||
(vector3d::Dot(c->normal, vector3d::Cross(vector3d::Cross(hitPos1, c->normal) * (1.0/b1->GetAngularInertia()), hitPos1))) +
|
||||
(vector3d::Dot(c->normal, vector3d::Cross(vector3d::Cross(hitPos2, c->normal) * (1.0/b2->GetAngularInertia()), hitPos2)))
|
||||
);
|
||||
|
||||
/* Step back. */
|
||||
b1->TimeStepUpdate(-L3D::GetTimeStep());
|
||||
b2->TimeStepUpdate(-L3D::GetTimeStep());
|
||||
//b1->UndoTimestep();
|
||||
//b2->UndoTimestep();
|
||||
/* Apply impulse. */
|
||||
b1->SetVelocity(vel1 - (j*c->normal)*invMass1);
|
||||
b2->SetVelocity(vel2 + (j*c->normal)*invMass2);
|
||||
b1->SetAngVelocity(b1->GetAngVelocity() - vector3d::Cross(hitPos1, (j*c->normal))*(1.0/b1->GetAngularInertia()));
|
||||
b2->SetAngVelocity(b2->GetAngVelocity() + vector3d::Cross(hitPos2, (j*c->normal))*(1.0/b2->GetAngularInertia()));
|
||||
} else {
|
||||
/* One body is static. */
|
||||
vector3d hitNormal;
|
||||
@ -379,7 +385,7 @@ static void hitCallback(CollisionContact* c) {
|
||||
reflect = reflect * 0.5;
|
||||
|
||||
/* Step back. */
|
||||
mover->TimeStepUpdate(-L3D::GetTimeStep());
|
||||
mover->UndoTimestep();
|
||||
/* and set altered velocity. */
|
||||
mover->SetVelocity(reflect);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user