From beca8adb61c9b0f6f462fcbecfce3b100e275d86 Mon Sep 17 00:00:00 2001 From: no-author Date: Wed, 22 Dec 2004 20:30:13 +0000 Subject: This commit was manufactured by cvs2svn to create tag 'blender-2-36-release'. --- source/gameengine/Converter/BL_ActionActuator.cpp | 31 +- source/gameengine/Converter/BL_ActionActuator.h | 22 +- source/gameengine/Ketsji/KX_IpoActuator.cpp | 29 +- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 2 +- source/gameengine/Ketsji/KX_Scene.cpp | 12 +- .../Physics/Sumo/Fuzzics/include/SM_MotionState.h | 1 - .../Physics/Sumo/Fuzzics/include/SM_Object.h | 39 +-- .../Physics/Sumo/Fuzzics/include/SM_Scene.h | 3 +- .../Physics/Sumo/Fuzzics/src/SM_MotionState.cpp | 42 +-- .../Physics/Sumo/Fuzzics/src/SM_Object.cpp | 312 +++++---------------- .../Physics/Sumo/Fuzzics/src/SM_Scene.cpp | 146 +++++----- .../Physics/Sumo/SumoPhysicsController.cpp | 3 +- 12 files changed, 196 insertions(+), 446 deletions(-) diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 22ee2371e8c..0289ec42d74 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -166,28 +166,18 @@ bool BL_ActionActuator::Update(double curtime, bool frame) // result = true if animation has to be continued, false if animation stops // maybe there are events for us in the queue ! - if (frame) + + for (vector::iterator i=m_events.end(); !(i==m_events.begin());) { - for (vector::iterator i=m_events.end(); !(i==m_events.begin());) - { - i--; - if ((*i)->GetNumber() == 0.0f) - bNegativeEvent = true; - else - bPositiveEvent= true; - (*i)->Release(); - m_events.pop_back(); - } - - if (bPositiveEvent) - m_flag |= ACT_FLAG_ACTIVE; - - if (bNegativeEvent) + i--; + if ((*i)->GetNumber() == 0.0f) { - if (!(m_flag & ACT_FLAG_ACTIVE)) - return false; - m_flag &= ~ACT_FLAG_ACTIVE; + bNegativeEvent = true; } + else + bPositiveEvent= true; + (*i)->Release(); + m_events.pop_back(); } /* We know that action actuators have been discarded from all non armature objects: @@ -246,7 +236,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame) if (!(m_flag & ACT_FLAG_LOCKINPUT)){ m_flag &= ~ACT_FLAG_REVERSE; m_flag |= ACT_FLAG_LOCKINPUT; - SetStartTime(curtime); + m_starttime = curtime; } } else if (bNegativeEvent){ @@ -334,7 +324,6 @@ bool BL_ActionActuator::Update(double curtime, bool frame) m_localtime = m_endframe; m_flag &= ~ACT_FLAG_LOCKINPUT; } - SetStartTime(curtime); } break; case ACT_ACTION_PLAY: diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h index 1c3f57e965a..0c1eb780bcb 100644 --- a/source/gameengine/Converter/BL_ActionActuator.h +++ b/source/gameengine/Converter/BL_ActionActuator.h @@ -52,22 +52,22 @@ public: PyTypeObject* T=&Type) : SCA_IActuator(gameobj,T), - m_lastpos(0, 0, 0), m_blendframe(0), + m_lastpos(0, 0, 0), m_flag(0), m_startframe (starttime), m_endframe(endtime) , m_localtime(starttime), m_lastUpdate(-1), - m_blendin(blendin), - m_stridelength(stride), m_playtype(playtype), + m_blendin(blendin), m_priority(priority), + m_stridelength(stride), m_pose(NULL), m_blendpose(NULL), m_userpose(NULL), - m_action(action), - m_propname(propname) + m_propname(propname), + m_action(action) { }; virtual ~BL_ActionActuator(); @@ -115,8 +115,8 @@ protected: void SetLocalTime(float curtime); bool ClampLocalTime(); - MT_Point3 m_lastpos; float m_blendframe; + MT_Point3 m_lastpos; int m_flag; /** The frame this action starts */ float m_startframe; @@ -128,23 +128,23 @@ protected: float m_localtime; float m_lastUpdate; + short m_playtype; float m_blendin; float m_blendstart; - float m_stridelength; - short m_playtype; short m_priority; + float m_stridelength; struct bPose* m_pose; struct bPose* m_blendpose; struct bPose* m_userpose; - struct bAction *m_action; STR_String m_propname; + struct bAction *m_action; + }; enum { ACT_FLAG_REVERSE = 0x00000001, ACT_FLAG_LOCKINPUT = 0x00000002, - ACT_FLAG_KEYUP = 0x00000004, - ACT_FLAG_ACTIVE = 0x00000008 + ACT_FLAG_KEYUP = 0x00000004 }; #endif diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp index df4a5047ef1..ea9fe8554cc 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.cpp +++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp @@ -112,13 +112,14 @@ KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj, m_endframe(endtime), m_recurse(recurse), m_localtime(starttime), + m_starttime(-1.0), m_direction(1), m_propname(propname), m_ipo_as_force(ipo_as_force), m_force_ipo_local(force_ipo_local), m_type((IpoActType)acttype) { - m_starttime = -2.0*fabs(m_endframe - m_startframe) - 1.0; + // intentionally empty } void KX_IpoActuator::SetStart(float starttime) @@ -188,11 +189,10 @@ bool KX_IpoActuator::Update(double curtime, bool frame) // result = true if animation has to be continued, false if animation stops // maybe there are events for us in the queue ! bool bNegativeEvent = false; - int numevents = 0; + int numevents = m_events.size(); if (frame) { - numevents = m_events.size(); for (vector::iterator i=m_events.end(); !(i==m_events.begin());) { --i; @@ -204,13 +204,15 @@ bool KX_IpoActuator::Update(double curtime, bool frame) m_events.clear(); if (bNegativeEvent) + { RemoveAllEvents(); + } } double start_smaller_then_end = ( m_startframe < m_endframe ? 1.0 : -1.0); bool result=true; - if (m_starttime < -2.0*start_smaller_then_end*(m_endframe - m_startframe)) + if (m_starttime < 0.0) m_starttime = curtime; switch (m_type) @@ -271,7 +273,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame) } case KX_ACT_IPO_FLIPPER: { - result = !(bNegativeEvent && (m_localtime == m_startframe)); + result = true; if (numevents) { if (bNegativeEvent) @@ -367,7 +369,20 @@ bool KX_IpoActuator::Update(double curtime, bool frame) CValue* propval = GetParent()->GetProperty(m_propname); if (propval) { - m_localtime = propval->GetNumber(); + float target = propval->GetNumber(); + float delta_time = (curtime - m_starttime)*KX_FIXED_FRAME_PER_SEC; + if (target > m_localtime) + { + m_localtime += delta_time; + if (m_localtime > target) + m_localtime = target; + } + else + { + m_localtime -= delta_time; + if (m_localtime < target) + m_localtime = target; + } CIpoAction ipoaction( (KX_GameObject*) GetParent(), @@ -389,7 +404,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame) } if (!result && m_type != KX_ACT_IPO_LOOPSTOP) - m_starttime = -2.0*start_smaller_then_end*(m_endframe - m_startframe) - 1.0; + m_starttime = -1.0; return result; } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index af75e3493c1..f74cdc31fcd 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -83,7 +83,7 @@ // not valid, skip rendering this frame. //#define NZC_GUARDED_OUTPUT #define DEFAULT_LOGIC_TIC_RATE 30.0 -#define DEFAULT_PHYSICS_TIC_RATE 90.0 +#define DEFAULT_PHYSICS_TIC_RATE 60.0 const char KX_KetsjiEngine::m_profileLabels[tc_numCategories][15] = { "Physics:", // tc_physics diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 09e4ae7bbb1..26825fe5e1f 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -600,23 +600,21 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject, MT_Matrix3x3 newori = ((KX_GameObject*) parentobject)->NodeGetWorldOrientation(); replica->NodeSetLocalOrientation(newori); - - // get the rootnode's scale - MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale(); - - // set the replica's relative scale with the rootnode's scale - replica->NodeSetRelativeScale(newscale); if (replica->GetPhysicsController()) { replica->GetPhysicsController()->setPosition(newpos); replica->GetPhysicsController()->setOrientation(newori.getRotation()); - replica->GetPhysicsController()->setScaling(newscale); } // here we want to set the relative scale: the rootnode's scale will override all other // scalings, so lets better prepare for it + // get the rootnode's scale + MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale(); + + // set the replica's relative scale with the rootnode's scale + replica->NodeSetRelativeScale(newscale); replica->GetSGNode()->UpdateWorldData(0); replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox()); diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h index 08e29265d0c..b0e0717cf8c 100644 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h +++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h @@ -61,7 +61,6 @@ public: void integrateBackward(MT_Scalar timeStep, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel); void integrateForward(MT_Scalar timeStep, const SM_MotionState &prev_state); - void lerp(const SM_MotionState &prev, const SM_MotionState &next); void lerp(MT_Scalar t, const SM_MotionState &other); virtual MT_Transform getTransform() const { diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h index 07eb5a7637f..b37e1a5466b 100644 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h +++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h @@ -81,8 +81,7 @@ public: * It encapsulates an object in the physics scene, and is responsible * for calculating the collision response of objects. */ -class SM_Object -{ +class SM_Object : public SM_MotionState { public: SM_Object() ; SM_Object( @@ -267,29 +266,7 @@ public: void relax(); - SM_MotionState &getCurrentFrame(); - SM_MotionState &getPreviousFrame(); - SM_MotionState &getNextFrame(); - - const SM_MotionState &getCurrentFrame() const; - const SM_MotionState &getPreviousFrame() const; - const SM_MotionState &getNextFrame() const; - - // Motion state functions - const MT_Point3& getPosition() const; - const MT_Quaternion& getOrientation() const; - const MT_Vector3& getLinearVelocity() const; - const MT_Vector3& getAngularVelocity() const; - - MT_Scalar getTime() const; - - void setTime(MT_Scalar time); - - void interpolate(MT_Scalar timeStep); - void endFrame(); - private: - friend class Contact; // Tweak parameters static MT_Scalar ImpulseThreshold; @@ -347,12 +324,14 @@ private: MT_Vector3 m_reaction_impulse; // The accumulated impulse resulting from collisions MT_Vector3 m_reaction_force; // The reaction force derived from the reaction impulse + unsigned int m_kinematic : 1; // Have I been displaced (translated, rotated, scaled) in this frame? + unsigned int m_prev_kinematic : 1; // Have I been displaced (translated, rotated, scaled) in the previous frame? + unsigned int m_is_rigid_body : 1; // Should friction give me a change in angular momentum? + MT_Vector3 m_lin_mom; // Linear momentum (linear velocity times mass) MT_Vector3 m_ang_mom; // Angular momentum (angualr velocity times inertia) MT_Vector3 m_force; // Force on center of mass (afffects linear momentum) - MT_Vector3 m_torque; // Torque around center of mass (affects angular momentum) - - SM_MotionState m_frames[3]; + MT_Vector3 m_torque; // Torque around center of mass (affects angualr momentum) MT_Vector3 m_error; // Error in position:- amount object must be moved to prevent intersection with scene @@ -376,12 +355,6 @@ private: MT_Scalar m_inv_mass; // 1/mass MT_Vector3 m_inv_inertia; // [1/inertia_x, 1/inertia_y, 1/inertia_z] MT_Matrix3x3 m_inv_inertia_tensor; // Inverse Inertia Tensor - - bool m_kinematic; // Have I been displaced (translated, rotated, scaled) in this frame? - bool m_prev_kinematic; // Have I been displaced (translated, rotated, scaled) in the previous frame? - bool m_is_rigid_body; // Should friction give me a change in angular momentum? - int m_static; // temporarily static. - }; #endif diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h index a0d5c983031..80e8c635cbb 100644 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h +++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h @@ -104,7 +104,6 @@ public: // 'subSampling' can be used to control aliasing effects // (fast moving objects traversing through walls and such). bool proceed(MT_Scalar curtime, MT_Scalar ticrate); - void proceed(MT_Scalar subStep); /** * Test whether any objects lie on the line defined by from and @@ -168,7 +167,7 @@ private: * collision tests. */ T_ObjectList m_objectList; - unsigned int m_frames; + MT_Scalar m_lastTime; }; #endif diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp index 1fadbdadfa0..a3285b19116 100644 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp +++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp @@ -29,7 +29,7 @@ * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ -#include + #include #include @@ -56,47 +56,15 @@ void SM_MotionState::integrateForward(MT_Scalar timeStep, const SM_MotionState & m_orn.normalize(); } -/* -// Newtonian lerp: interpolate based on Newtonian motion -void SM_MotionState::nlerp(const SM_MotionState &prev, const SM_MotionState &next) -{ - MT_Scalar dt = next.getTime() - prev.getTime(); - MT_Scalar t = getTime() - prev.getTime(); - MT_Vector3 dx = next.getPosition() - prev.getPosition(); - MT_Vector3 a = dx/(dt*dt) - prev.getLinearVelocity()/dt; - - m_pos = prev.getPosition() + prev.getLinearVelocity()*t + a*t*t; -} -*/ - -void SM_MotionState::lerp(const SM_MotionState &prev, const SM_MotionState &next) -{ - MT_Scalar dt = next.getTime() - prev.getTime(); - if (MT_fuzzyZero(dt)) - { - *this = next; - return; - } - - MT_Scalar x = (getTime() - prev.getTime())/dt; - - m_pos = x*next.getPosition() + (1-x)*prev.getPosition(); - - m_orn = prev.getOrientation().slerp(next.getOrientation(), 1-x); - - m_lin_vel = x*next.getLinearVelocity() + (1-x)*prev.getLinearVelocity(); - m_ang_vel = x*next.getAngularVelocity() + (1-x)*prev.getAngularVelocity(); -} - void SM_MotionState::lerp(MT_Scalar t, const SM_MotionState &other) { MT_Scalar x = (t - getTime())/(other.getTime() - getTime()); - m_pos = (1-x)*m_pos + x*other.getPosition(); + m_pos = x*m_pos + (1-x)*other.getPosition(); - m_orn = other.getOrientation().slerp(m_orn, x); + m_orn = m_orn.slerp(other.getOrientation(), x); - m_lin_vel = (1-x)*m_lin_vel + x*other.getLinearVelocity(); - m_ang_vel = (1-x)*m_ang_vel + x*other.getAngularVelocity(); + m_lin_vel = x*m_lin_vel + (1-x)*other.getLinearVelocity(); + m_ang_vel = x*m_ang_vel + (1-x)*other.getAngularVelocity(); m_time = t; } diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp index 26687663006..ed5171a87a2 100644 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp +++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp @@ -49,95 +49,7 @@ #include "MT_MinMax.h" -MT_Scalar SM_Object::ImpulseThreshold = -1.0; - -struct Contact -{ - SM_Object *obj1; - SM_Object *obj2; - MT_Vector3 normal; - MT_Point3 pos; - - // Sort objects by height - bool operator()(const Contact *a, const Contact *b) - { - return a->pos[2] < b->pos[2]; - } - - Contact(SM_Object *o1, SM_Object *o2, const MT_Vector3 nor, const MT_Point3 p) - : obj1(o1), - obj2(o2), - normal(nor), - pos(p) - { - } - - Contact() - { - } - - void resolve() - { - if (obj1->m_static || obj2->m_static) - { - if (obj1->isDynamic()) - { - if (obj1->m_static && obj2->m_static) - { - if (obj1->m_static < obj2->m_static) - { - obj2->m_error -= normal; - obj2->m_static = obj1->m_static + 1; - } - else - { - obj1->m_error += normal; - obj1->m_static = obj2->m_static + 1; - } - } - else - { - if (obj1->m_static) - { - obj2->m_error -= normal; - obj2->m_static = obj1->m_static + 1; - } - else - { - obj1->m_error += normal; - obj1->m_static = obj2->m_static + 1; - } - } - } - else - { - obj2->m_error -= normal; - obj2->m_static = 1; - } - } - else - { - // This distinction between dynamic and non-dynamic objects should not be - // necessary. Non-dynamic objects are assumed to have infinite mass. - if (obj1->isDynamic()) { - MT_Vector3 error = normal * 0.5f; - obj1->m_error += error; - obj2->m_error -= error; - } - else { - // Same again but now obj1 is non-dynamic - obj2->m_error -= normal; - obj2->m_static = obj1->m_static + 1; - } - } - - } - - - typedef std::set Set; -}; - -static Contact::Set contacts; +MT_Scalar SM_Object::ImpulseThreshold = -10.; SM_Object::SM_Object( DT_ShapeHandle shape, @@ -157,6 +69,9 @@ SM_Object::SM_Object( m_scaling(1.0, 1.0, 1.0), m_reaction_impulse(0.0, 0.0, 0.0), m_reaction_force(0.0, 0.0, 0.0), + m_kinematic(false), + m_prev_kinematic(false), + m_is_rigid_body(false), m_lin_mom(0.0, 0.0, 0.0), m_ang_mom(0.0, 0.0, 0.0), m_force(0.0, 0.0, 0.0), @@ -166,11 +81,7 @@ SM_Object::SM_Object( m_combined_ang_vel (0.0, 0.0, 0.0), m_fh_object(0), m_inv_mass(0.0), - m_inv_inertia(0., 0., 0.), - m_kinematic(false), - m_prev_kinematic(false), - m_is_rigid_body(false), - m_static(0) + m_inv_inertia(0., 0., 0.) { m_object = DT_CreateObject(this, shape); m_xform.setIdentity(); @@ -197,7 +108,7 @@ integrateForces( MT_Scalar timeStep ){ if (!m_suspended) { - m_prev_state = getNextFrame(); + m_prev_state = *this; m_prev_state.setLinearVelocity(actualLinVelocity()); m_prev_state.setAngularVelocity(actualAngVelocity()); if (isDynamic()) { @@ -208,8 +119,8 @@ integrateForces( m_lin_mom *= pow(m_shapeProps->m_lin_drag, timeStep); m_ang_mom *= pow(m_shapeProps->m_ang_drag, timeStep); // Set velocities according momentum - getNextFrame().setLinearVelocity(m_lin_mom * m_inv_mass); - getNextFrame().setAngularVelocity(m_inv_inertia_tensor * m_ang_mom); + m_lin_vel = m_lin_mom * m_inv_mass; + m_ang_vel = m_inv_inertia_tensor * m_ang_mom; } } @@ -235,13 +146,13 @@ integrateMomentum( //#define BACKWARD #ifdef MIDPOINT // Midpoint rule - getNextFrame().integrateMidpoint(timeStep, m_prev_state, actualLinVelocity(), actualAngVelocity()); + integrateMidpoint(timeStep, m_prev_state, actualLinVelocity(), actualAngVelocity()); #elif defined BACKWARD // Backward Euler - getNextFrame().integrateBackward(timeStep, actualLinVelocity(), actualAngVelocity()); + integrateBackward(timeStep, actualLinVelocity(), actualAngVelocity()); #else // Forward Euler - getNextFrame().integrateForward(timeStep, m_prev_state); + integrateForward(timeStep, m_prev_state); #endif calcXform(); @@ -278,11 +189,11 @@ void SM_Object::dynamicCollision(const MT_Point3 &local2, /** * if rel_vel_normal > 0, the objects are moving apart! */ - if (rel_vel_normal < -MT_EPSILON) { + if (rel_vel_normal < 0.) { /** * if rel_vel_normal < ImpulseThreshold, scale the restitution down. * This should improve the simulation where the object is stacked. - */ + */ restitution *= MT_min(MT_Scalar(1.0), rel_vel_normal/ImpulseThreshold); MT_Scalar impulse = -(1.0 + restitution) * rel_vel_normal; @@ -296,7 +207,7 @@ void SM_Object::dynamicCollision(const MT_Point3 &local2, * Apply impulse at the collision point. * Take rotational inertia into account. */ - applyImpulse(local2 + getNextFrame().getPosition(), impulse * normal); + applyImpulse(local2 + getPosition(), impulse * normal); } else { /** * Apply impulse through object centre. (no rotation.) @@ -333,7 +244,7 @@ void SM_Object::dynamicCollision(const MT_Point3 &local2, * local coordinates. */ - MT_Matrix3x3 lcs(getNextFrame().getOrientation()); + MT_Matrix3x3 lcs(m_orn); /** * We cannot use m_xform.getBasis() for the matrix, since @@ -407,7 +318,7 @@ void SM_Object::dynamicCollision(const MT_Point3 &local2, (invMass + lateral.dot(temp.cross(local2))); MT_Scalar friction = MT_min(impulse_lateral, max_friction); - applyImpulse(local2 + getNextFrame().getPosition(), -lateral * friction); + applyImpulse(local2 + getPosition(), -lateral * friction); } else { MT_Scalar impulse_lateral = rel_vel_lateral / invMass; @@ -488,8 +399,8 @@ DT_Bool SM_Object::boing( (obj2->getClientObject() && obj2->getClientObject()->hasCollisionCallback())) scene->notifyCollision(obj1, obj2); - local1 -= obj1->getNextFrame().getPosition(); - local2 -= obj2->getNextFrame().getPosition(); + local1 -= obj1->getPosition(); + local2 -= obj2->getPosition(); // Calculate collision parameters MT_Vector3 rel_vel = obj1->getVelocity(local1) - obj2->getVelocity(local2); @@ -511,11 +422,7 @@ DT_Bool SM_Object::boing( obj1->dynamicCollision(local1, normal, dist, rel_vel, restitution, friction_factor, invMass); if (obj2->isDynamic()) - { obj2->dynamicCollision(local2, -normal, dist, -rel_vel, restitution, friction_factor, invMass); - if (!obj1->isDynamic() || obj1->m_static) - obj2->m_static = obj1->m_static + 1; - } return DT_CONTINUE; } @@ -559,38 +466,31 @@ DT_Bool SM_Object::fix( if (dist < MT_EPSILON || dist > obj2->m_shapeProps->m_radius*obj2->m_shapeProps->m_radius) return DT_CONTINUE; - - if ((obj1->m_static || !obj1->isDynamic()) && obj1->m_static < obj2->m_static) - { - obj2->m_static = obj1->m_static + 1; - } else if (obj2->m_static && obj2->m_static < obj1->m_static) - { - obj1->m_static = obj2->m_static + 1; + // This distinction between dynamic and non-dynamic objects should not be + // necessary. Non-dynamic objects are assumed to have infinite mass. + if (obj1->isDynamic()) { + MT_Vector3 error = normal * 0.5f; + obj1->m_error += error; + obj2->m_error -= error; + } + else { + // Same again but now obj1 is non-dynamic + obj2->m_error -= normal; } - - contacts.insert(new Contact(obj1, obj2, normal, MT_Point3(local1 + 0.5*(local2 - local1)))); - return DT_CONTINUE; } void SM_Object::relax(void) -{ - for (Contact::Set::iterator csit = contacts.begin() ; csit != contacts.end(); ++csit) - { - (*csit)->resolve(); - delete (*csit); - } - - contacts.clear(); +{ if (m_error.fuzzyZero()) return; //std::cout << "SM_Object::relax: { " << m_error << " }" << std::endl; - getNextFrame().setPosition(getNextFrame().getPosition() + m_error); + setPosition(getPosition() + m_error); m_error.setValue(0., 0., 0.); - //calcXform(); - //notifyClient(); + calcXform(); + notifyClient(); } SM_Object::SM_Object() : @@ -607,6 +507,9 @@ SM_Object::SM_Object() : m_scaling(1.0, 1.0, 1.0), m_reaction_impulse(0.0, 0.0, 0.0), m_reaction_force(0.0, 0.0, 0.0), + m_kinematic(false), + m_prev_kinematic(false), + m_is_rigid_body(false), m_lin_mom(0.0, 0.0, 0.0), m_ang_mom(0.0, 0.0, 0.0), m_force(0.0, 0.0, 0.0), @@ -614,10 +517,7 @@ SM_Object::SM_Object() : m_error(0.0, 0.0, 0.0), m_combined_lin_vel (0.0, 0.0, 0.0), m_combined_ang_vel (0.0, 0.0, 0.0), - m_fh_object(0), - m_kinematic(false), - m_prev_kinematic(false), - m_is_rigid_body(false) + m_fh_object(0) { // warning no initialization of variables done by moto. } @@ -736,15 +636,15 @@ calcXform() { printf(" m_scaling = { %-0.5f, %-0.5f, %-0.5f }\n", m_scaling[0], m_scaling[1], m_scaling[2]); #endif - m_xform.setOrigin(getNextFrame().getPosition()); - m_xform.setBasis(MT_Matrix3x3(getNextFrame().getOrientation(), m_scaling)); + m_xform.setOrigin(getPosition()); + m_xform.setBasis(MT_Matrix3x3(getOrientation(), m_scaling)); m_xform.getValue(m_ogl_matrix); /* Blender has been known to crash here. This usually means SM_Object *this has been deleted more than once. */ DT_SetMatrixd(m_object, m_ogl_matrix); if (m_fh_object) { - m_fh_object->setPosition(getNextFrame().getPosition()); + m_fh_object->setPosition(getPosition()); m_fh_object->calcXform(); } updateInvInertiaTensor(); @@ -860,8 +760,7 @@ setPosition( const MT_Point3& pos ){ m_kinematic = true; - getNextFrame().setPosition(pos); - endFrame(); + SM_MotionState::setPosition(pos); } void @@ -871,8 +770,7 @@ setOrientation( ){ assert(!orn.fuzzyZero()); m_kinematic = true; - getNextFrame().setOrientation(orn); - endFrame(); + SM_MotionState::setOrientation(orn); } void @@ -909,7 +807,10 @@ SM_Object:: addLinearVelocity( const MT_Vector3& lin_vel ){ - setLinearVelocity(getNextFrame().getLinearVelocity() + lin_vel); + m_lin_vel += lin_vel; + if (m_shapeProps) { + m_lin_mom = m_lin_vel * m_shapeProps->m_mass; + } } void @@ -917,9 +818,9 @@ SM_Object:: setLinearVelocity( const MT_Vector3& lin_vel ){ - getNextFrame().setLinearVelocity(lin_vel); + m_lin_vel = lin_vel; if (m_shapeProps) { - m_lin_mom = getNextFrame().getLinearVelocity() * m_shapeProps->m_mass; + m_lin_mom = m_lin_vel * m_shapeProps->m_mass; } } @@ -948,9 +849,9 @@ SM_Object:: setAngularVelocity( const MT_Vector3& ang_vel ) { - getNextFrame().setAngularVelocity(ang_vel); + m_ang_vel = ang_vel; if (m_shapeProps) { - m_ang_mom = getNextFrame().getAngularVelocity() * m_shapeProps->m_inertia; + m_ang_mom = m_ang_vel * m_shapeProps->m_inertia; } } @@ -959,7 +860,10 @@ SM_Object:: addAngularVelocity( const MT_Vector3& ang_vel ) { - setAngularVelocity(getNextFrame().getAngularVelocity() + ang_vel); + m_ang_vel += ang_vel; + if (m_shapeProps) { + m_ang_mom = m_ang_vel * m_shapeProps->m_inertia; + } } @@ -992,18 +896,18 @@ resolveCombinedVelocities( if (isDynamic()) { #if 1 - getNextFrame().setLinearVelocity(getNextFrame().getLinearVelocity() + lin_vel); - getNextFrame().setAngularVelocity(getNextFrame().getAngularVelocity() + ang_vel); + m_lin_vel += lin_vel; + m_ang_vel += ang_vel; #else //compute the component of the physics velocity in the // direction of the set velocity and set it to zero. MT_Vector3 lin_vel_norm = lin_vel.normalized(); - setLinearVelocity(getNextFrame().getLinearVelocity() - (getNextFrame().getLinearVelocity().dot(lin_vel_norm) * lin_vel_norm)); + m_lin_vel -= (m_lin_vel.dot(lin_vel_norm) * lin_vel_norm); #endif - m_lin_mom = getNextFrame().getLinearVelocity() * m_shapeProps->m_mass; - m_ang_mom = getNextFrame().getAngularVelocity() * m_shapeProps->m_inertia; + m_lin_mom = m_lin_vel * m_shapeProps->m_mass; + m_ang_mom = m_ang_vel * m_shapeProps->m_inertia; clearCombinedVelocities(); } @@ -1066,7 +970,7 @@ applyImpulse( const MT_Point3& attach, const MT_Vector3& impulse ) { applyCenterImpulse(impulse); // Change in linear momentum - applyAngularImpulse((attach - getNextFrame().getPosition()).cross(impulse)); // Change in angular momentump + applyAngularImpulse((attach - m_pos).cross(impulse)); // Change in angular momentump } void @@ -1077,7 +981,7 @@ applyCenterImpulse( if (m_shapeProps) { m_lin_mom += impulse; m_reaction_impulse += impulse; - getNextFrame().setLinearVelocity(m_lin_mom * m_inv_mass); + m_lin_vel = m_lin_mom * m_inv_mass; // The linear velocity is immedialtely updated since otherwise // simultaneous collisions will get a double impulse. @@ -1091,7 +995,7 @@ applyAngularImpulse( ) { if (m_shapeProps) { m_ang_mom += impulse; - getNextFrame().setAngularVelocity( m_inv_inertia_tensor * m_ang_mom); + m_ang_vel = m_inv_inertia_tensor * m_ang_mom; } } @@ -1195,7 +1099,7 @@ const SM_Object:: actualLinVelocity( ) const { - return m_combined_lin_vel + getNextFrame().getLinearVelocity(); + return m_combined_lin_vel + m_lin_vel; }; const @@ -1203,98 +1107,10 @@ const SM_Object:: actualAngVelocity( ) const { - return m_combined_ang_vel + getNextFrame().getAngularVelocity(); -} - - -SM_MotionState& -SM_Object:: -getCurrentFrame() -{ - return m_frames[1]; -} - -SM_MotionState& -SM_Object:: -getPreviousFrame() -{ - return m_frames[0]; -} - -SM_MotionState & -SM_Object:: -getNextFrame() -{ - return m_frames[2]; -} - -const SM_MotionState & -SM_Object:: -getCurrentFrame() const -{ - return m_frames[1]; -} - -const SM_MotionState & -SM_Object:: -getPreviousFrame() const -{ - return m_frames[0]; -} - -const SM_MotionState & -SM_Object:: -getNextFrame() const -{ - return m_frames[2]; -} - - -const MT_Point3& -SM_Object:: -getPosition() const -{ - return m_frames[1].getPosition(); -} + return m_combined_ang_vel + m_ang_vel; +}; -const MT_Quaternion& -SM_Object:: -getOrientation() const -{ - return m_frames[1].getOrientation(); -} -const MT_Vector3& -SM_Object:: -getLinearVelocity() const -{ - return m_frames[1].getLinearVelocity(); -} -const MT_Vector3& -SM_Object:: -getAngularVelocity() const -{ - return m_frames[1].getAngularVelocity(); -} -void -SM_Object:: -interpolate(MT_Scalar timeStep) -{ - if (!actualLinVelocity().fuzzyZero() || !actualAngVelocity().fuzzyZero()) - { - getCurrentFrame().setTime(timeStep); - getCurrentFrame().lerp(getPreviousFrame(), getNextFrame()); - notifyClient(); - } -} -void -SM_Object:: -endFrame() -{ - getPreviousFrame() = getNextFrame(); - getCurrentFrame() = getNextFrame(); - m_static = 0; -} diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp index fdd8079b241..c29be228d64 100644 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp +++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp @@ -54,7 +54,7 @@ SM_Scene::SM_Scene() : m_secondaryRespTable(DT_CreateRespTable()), m_fixRespTable(DT_CreateRespTable()), m_forceField(0.0, 0.0, 0.0), - m_frames(0) + m_lastTime(-1.0) { for (int i = 0 ; i < NUM_RESPONSE; i++) { @@ -83,8 +83,8 @@ SM_Scene::SM_Scene() : /* Fh Object */ DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], 0, DT_NO_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this); + DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_FhObject::ray_hit, DT_BROAD_RESPONSE, this); + DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_FhObject::ray_hit, DT_BROAD_RESPONSE, this); DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[FH_RESPONSE], 0, DT_NO_RESPONSE, this); /* Object (Fix Pass) */ @@ -177,111 +177,105 @@ void SM_Scene::endFrame() (*i)->clearForce(); } -bool SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) -{ - if (!m_frames) +bool SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) { + if (m_lastTime < 0.0) { - if (ticrate > 0.) - m_frames = (unsigned int)(curtime*ticrate + 1.0); - else - m_frames = (unsigned int)(curtime*65536.0); + m_lastTime = curtime; + return false; } - + // Divide the timeStep into a number of subsamples of size roughly // equal to subS (might be a little smaller). + MT_Scalar timeStep = curtime - m_lastTime; MT_Scalar subStep; int num_samples; - int frames = m_frames; - // Compute the number of steps to do this update. if (ticrate > 0.0) { - // Fixed time step subStep = 1.0/ticrate; - num_samples = (unsigned int)(curtime*ticrate + 1.0) - m_frames; + num_samples = int(timeStep * ticrate); if (num_samples > 4) { - std::cout << "Dropping physics frames! frames:" << num_samples << " substep: " << subStep << std::endl; - MT_Scalar tr = ticrate; - do - { - frames = frames / 2; - tr = tr / 2.0; - num_samples = (unsigned int)(curtime*tr + 1.0) - frames; - subStep *= 2.0; - } while (num_samples > 8); - std::cout << " frames:" << num_samples << " substep: " << subStep << std::endl; + std::cout << "Dropping physics frames! step: " << timeStep << " frames:" << num_samples << std::endl; + num_samples /= 4; + subStep *= 4.0; } } else { // Variable time step. (old update) // Integrate at least 100 Hz - MT_Scalar timeStep = curtime - m_frames/65536.0; subStep = timeStep > 0.01 ? 0.01 : timeStep; num_samples = int(timeStep * 0.01); if (num_samples < 1) num_samples = 1; } - // Do a physics timestep. T_ObjectList::iterator i; - if (num_samples > 0) + + // No timestep! (should do a mini update) + if (num_samples <= 0) { - // Do the integration steps per object. - for (int step = 0; step != num_samples; ++step) + // Apply a forcefield (such as gravity) +#if 0 + for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { - MT_Scalar time; - if (ticrate > 0.) - time = MT_Scalar(frames + step + 1) * subStep; - else - time = MT_Scalar(m_frames)/65536.0 + MT_Scalar(step + 1)*subStep; - - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { - (*i)->endFrame(); - // Apply a forcefield (such as gravity) - (*i)->integrateForces(subStep); - // And second we update the object positions by performing - // an integration step for each object - (*i)->integrateMomentum(subStep); - } - - // So now first we let the physics scene respond to - // new forces, velocities set externally. - // The collsion and friction impulses are computed here. - // Collision phase - DT_Test(m_scene, m_respTable); - - // Contact phase - DT_Test(m_scene, m_fixRespTable); - - // Finish this timestep by saving al state information for the next - // timestep and clearing the accumulated forces. - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { - (*i)->relax(); - (*i)->proceedKinematic(subStep); - (*i)->saveReactionForce(subStep); - (*i)->getNextFrame().setTime(time); - //(*i)->clearForce(); - } + //(*i)->applyForceField(m_forceField); + //(*i)->integrateForces(timeStep); + // And second we update the object positions by performing + // an integration step for each object + (*i)->integrateMomentum(timeStep); + //(*i)->clearForce(); } +#endif + return false; } - - if (ticrate > 0) - { - // Interpolate between time steps. - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) - (*i)->interpolate(curtime); - m_frames = (unsigned int)(curtime*ticrate + 1.0); - } - else - { - m_frames = (unsigned int)(curtime*65536.0); - } + m_lastTime += MT_Scalar(num_samples)*subStep; + + // Do the integration steps per object. + int step; + for (step = 0; step != num_samples; ++step) { + + for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { + // Apply a forcefield (such as gravity) + //(*i)->applyForceField(m_forceField); + //(*i)->setTimeStep(timeStep); + (*i)->integrateForces(subStep); + // And second we update the object positions by performing + // an integration step for each object + (*i)->integrateMomentum(subStep); + } + + // I changed the order of the next 2 statements. + // Originally objects were first integrated with a call + // to proceed(). However if external objects were + // directly manipulating the velocities etc of physics + // objects then the physics environment would not be able + // to react before object positions were updated. --- Laurence. + + // So now first we let the physics scene respond to + // new forces, velocities set externally. + // The collsion and friction impulses are computed here. + DT_Test(m_scene, m_respTable); + + // clear the user set velocities. +#if 0 + clearObjectCombinedVelocities(); +#endif + DT_Test(m_scene, m_fixRespTable); - return num_samples != 0; + // Finish this timestep by saving al state information for the next + // timestep and clearing the accumulated forces. + for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { + (*i)->relax(); + (*i)->proceedKinematic(subStep); + (*i)->saveReactionForce(subStep); + //(*i)->clearForce(); + } + } + return true; } void SM_Scene::notifyCollision(SM_Object *obj1, SM_Object *obj2) diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp index 46eeef264de..5301e125ce1 100644 --- a/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp +++ b/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp @@ -174,8 +174,7 @@ void SumoPhysicsController::setPosition(float posX,float posY,float posZ) void SumoPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ) { - if (!m_bDyna) - m_sumoObj->setScaling(MT_Vector3(scaleX,scaleY,scaleZ)); + m_sumoObj->setScaling(MT_Vector3(scaleX,scaleY,scaleZ)); } // physics methods -- cgit v1.2.3