git-svn-id: https://reactphysics3d.googlecode.com/svn/trunk@94 92aac97c-a6ce-11dd-a772-7fcde58d38e6

This commit is contained in:
chappuis.daniel 2009-02-12 12:38:27 +00:00
parent 87627f856d
commit 778d2dbf72
8 changed files with 119 additions and 70 deletions

View File

@ -24,7 +24,7 @@
using namespace reactphysics3d;
// Constructor
DynamicEngine::DynamicEngine(DynamicsWorld& world, const Time& timeStep)
DynamicEngine::DynamicEngine(DynamicWorld& world, const Time& timeStep)
:PhysicsEngine(world, timeStep) {
}
@ -40,23 +40,42 @@ DynamicEngine::~DynamicEngine() {
}
// Compute the interpolation state between the previous body state and the current body state
// This is used to avoid visual stuttering when the display and physics framerates are out of synchronization
BodyState DynamicEngine::interpolateState(const BodyState& previousBodyState, const BodyState& currentBodyState) const {
// Compute the interpolation factor
double alpha = timer.getInterpolationFactor();
// TODO : Implement this method
}
// Update the state of a rigid body
void DynamicEngine::updateBodyState(RigidBody* const rigidBody) {
// TODO : Implement this method
// The current body state of the body becomes the previous body state
rigidBody->updatePreviousBodyState();
// Integrate the current body state at time t to get the next state at time t + dt
numericalIntegrator.integrate(rigidBody->getCurrentBodyState(), timer.getTime(), timer.getTimeStep());
}
// Update the physics simulation
void DynamicEngine::update() {
// TODO : Implement this method
// While the time accumulator is not empty
while(timer.getAccumulator() >= timer.getTimeStep().getValue()) {
// For each body in the dynamic world
for(std::vector<Body*>::const_iterator it = world.getBodyListStartIterator(); it != world.getBodyListEndIterator(); ++it) {
// If the body is a RigidBody
RigidBody* rigidBody = dynamic_cast<RigidBody*>(*it);
if (rigidBody) {
// Update the state of the rigid body
updateBodyState(rigidBody);
}
}
// Update the timer
timer.update();
}
// For each body in the dynamic world
for(std::vector<Body*>::const_iterator it = world.getBodyListStartIterator(); it != world.getBodyListEndIterator(); ++it) {
// If the body is a RigidBody
RigidBody* rigidBody = dynamic_cast<RigidBody*>(*it);
if (rigidBody) {
// Update the interpolation factor of the rigid body
// This one will be used to compute the interpolated state
rigidBody->setInterpolationFactor(timer.getInterpolationFactor());
}
}
}

View File

@ -26,6 +26,8 @@
#include "../body/Body.h"
#include "../body/RigidBody.h"
#include "../body/BodyState.h"
#include "DynamicWorld.h"
#include "../physics/physics.h"
// Namespace ReactPhysics3D
namespace reactphysics3d {
@ -41,11 +43,10 @@ class DynamicEngine : public PhysicsEngine {
protected :
NumericalIntegrator numericalIntegrator; // Numerical integrator used to solve differential equations of movement
BodyState interpolateState(const BodyState& previousBodyState, const BodyState& currentBodyState) const; // Compute the interpolation state
void updateBodyState(RigidBody* const rigidBody); // Update the state of a rigid body
public :
DynamicEngine(DynamicsWorld& world, const Time& timeStep); // Constructor
DynamicEngine(DynamicWorld& world, const Time& timeStep); // Constructor
DynamicEngine(const DynamicEngine& engine); // Copy-constructor
virtual ~DynamicEngine(); // Destructor

View File

@ -29,6 +29,12 @@ PhysicsEngine::PhysicsEngine(PhysicsWorld& world, const Time& timeStep)
}
// Copy-constructor
PhysicsEngine::PhysicsEngine(const PhysicsEngine& engine)
:world(engine.world), timer(engine.timer) {
}
// Destructor
PhysicsEngine::~PhysicsEngine() {

View File

@ -34,15 +34,13 @@ namespace reactphysics3d {
-------------------------------------------------------------------
*/
class PhysicsEngine {
private :
PhysicsEngine(const PhysicsEngine&); // Copy-constructor is private because we don't want it to be used
protected :
PhysicsWorld world; // Physics world of the physics engine
Timer timer; // Timer of the physics engine
public :
PhysicsEngine(PhysicsWorld& world, const Time& timeStep); // Constructor
PhysicsEngine(const PhysicsEngine& engine); // Copy-constructor
virtual ~PhysicsEngine(); // Destructor
virtual void update()=0; // Update the physics simulation

View File

@ -44,7 +44,7 @@ void PhysicsWorld::addBody(Body* body) throw(std::invalid_argument) {
// Check if the body pointer is not null
if (body != 0) {
// Check if the body pointer isn't already in the bodyList
for(std::vector<Body*>::iterator it = bodyList.begin(); it != bodyList.end(); ) {
for(std::vector<Body*>::iterator it = bodyList.begin(); it != bodyList.end(); ++it) {
if (*it == body) {
// The body is already in the bodyList, therefore we throw an exception
throw std::invalid_argument("Exception in PhysicsWorld::addBody() : The argument body is already in the PhysicsWorld");

View File

@ -48,8 +48,30 @@ class PhysicsWorld {
void addBody(Body* body) throw(std::invalid_argument); // Add a body to the physics world
void removeBody(Body const* const body) throw(std::invalid_argument); // Remove a body from the physics world
Vector3D getGravity() const; // Return the gravity vector of the world
std::vector<Body*>::const_iterator getBodyListStartIterator() const; // Return a start iterator on the body list
std::vector<Body*>::const_iterator getBodyListEndIterator() const; // Return a end iterator on the body list
};
// --- Inline functions --- //
// Return the gravity vector of the world
inline Vector3D PhysicsWorld::getGravity() const {
return gravity;
}
// Return a start iterator on the body list
inline std::vector<Body*>::const_iterator PhysicsWorld::getBodyListStartIterator() const {
// Return an iterator on the start of the body list
return bodyList.begin();
}
// Return a end iterator on the body list
inline std::vector<Body*>::const_iterator PhysicsWorld::getBodyListEndIterator() const {
// Return an iterator on the end of the body list
return bodyList.end();
}
} // End of the ReactPhysics3D namespace
#endif

View File

@ -25,7 +25,7 @@ using namespace reactphysics3d;
// Constructor
Timer::Timer(const Time& initialTime, const Time& timeStep) throw(std::invalid_argument)
: timeStep(timeStep), time(initialTime), currentDisplayTime(Time(0.0)), deltatDisplayTime(Time(0.0)) {
: timeStep(timeStep), time(initialTime), currentDisplayTime(Time(0.0)), deltaDisplayTime(Time(0.0)) {
// Check if the timestep is different from zero
if (timeStep.getValue() != 0.0) {
accumulator = 0.0;
@ -42,7 +42,7 @@ using namespace reactphysics3d;
// Copy-constructor
Timer::Timer(const Timer& timer)
: timeStep(timer.timeStep), time(timer.time), currentDisplayTime(timer.currentDisplayTime),
deltatDisplayTime(timer.deltatDisplayTime), accumulator(timer.accumulator) {
deltaDisplayTime(timer.deltaDisplayTime), accumulator(timer.accumulator) {
isRunning = timer.isRunning;
}
@ -51,30 +51,6 @@ Timer::~Timer() {
}
// Update the timer
void Timer::update() {
// Update the current time of the physics engine
time.setValue(time.getValue() + timeStep.getValue());
// Update the accumulator value
accumulator -= timeStep.getValue();
}
// Compute and return the interpolation factor between two body states
double Timer::getInterpolationFactor() const {
// Compute and return the interpolation factor
return (accumulator / timeStep.getValue());
}
// Set the new currentDisplayTime value
void Timer::updateDisplayTime(const Time& newDisplayTime) {
// Compute the delta display time between two display frames
deltatDisplayTime.setValue(newDisplayTime.getValue() - currentDisplayTime.getValue());
// Update the current display time
currentDisplayTime = newDisplayTime;
}

View File

@ -37,7 +37,7 @@ class Timer {
Time timeStep; // Timestep dt of the physics engine (timestep > 0.0)
Time time; // Current time of the physics engine
Time currentDisplayTime; // Current display time
Time deltatDisplayTime; // Current time difference between two display frames
Time deltaDisplayTime; // Current time difference between two display frames
double accumulator; // Used to fix the time step and avoid strange time effects
bool isRunning; // True if the timer is running
@ -103,6 +103,33 @@ inline double Timer::getAccumulator() const {
return accumulator;
}
// Update the timer
inline void Timer::update() {
// Update the current time of the physics engine
time.setValue(time.getValue() + timeStep.getValue());
// Update the accumulator value
accumulator -= timeStep.getValue();
}
// Compute and return the interpolation factor between two body states
inline double Timer::getInterpolationFactor() const {
// Compute and return the interpolation factor
return (accumulator / timeStep.getValue());
}
// Set the new currentDisplayTime value
inline void Timer::updateDisplayTime(const Time& newDisplayTime) {
// Compute the delta display time between two display frames
deltaDisplayTime.setValue(newDisplayTime.getValue() - currentDisplayTime.getValue());
// Update the current display time
currentDisplayTime.setValue(newDisplayTime.getValue());
// Update the accumulator value
accumulator += deltaDisplayTime.getValue();
}
} // End of the ReactPhysics3D namespace
#endif