Update the testbed application to perform the interpolation externally
This commit is contained in:
parent
b8192db3ef
commit
e35db3f150
|
@ -20,7 +20,7 @@ FILE(COPY "shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/")
|
|||
FILE(COPY "meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/")
|
||||
|
||||
# Headers
|
||||
INCLUDE_DIRECTORIES("src" "opengl-framework/src/" "glfw/include/" "common/" "scenes/")
|
||||
INCLUDE_DIRECTORIES("src/" "opengl-framework/src/" "glfw/include/" "common/" "scenes/")
|
||||
|
||||
# Testbed source files
|
||||
SET(TESTBED_SOURCES
|
||||
|
@ -31,6 +31,8 @@ SET(TESTBED_SOURCES
|
|||
src/Gui.cpp
|
||||
src/Scene.h
|
||||
src/Scene.cpp
|
||||
src/Timer.h
|
||||
src/Timer.cpp
|
||||
)
|
||||
|
||||
# Common source files
|
||||
|
|
|
@ -85,6 +85,8 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
|
|||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transform;
|
||||
|
||||
// Create a rigid body in the dynamics world
|
||||
mRigidBody = world->createCollisionBody(transform);
|
||||
|
||||
|
@ -205,14 +207,19 @@ void Box::render(openglframework::Shader& shader,
|
|||
}
|
||||
|
||||
// Update the transform matrix of the box
|
||||
void Box::updateTransform() {
|
||||
void Box::updateTransform(float interpolationFactor) {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
// Get the transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getTransform();
|
||||
|
||||
// Interpolate the transform between the previous one and the new one
|
||||
rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform,
|
||||
transform,
|
||||
interpolationFactor);
|
||||
|
||||
// Compute the transform used for rendering the box
|
||||
rp3d::decimal matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
interpolatedTransform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
|
|
|
@ -56,6 +56,9 @@ class Box : public openglframework::Object3D {
|
|||
/// Rigid body used to simulate the dynamics of the box
|
||||
rp3d::CollisionBody* mRigidBody;
|
||||
|
||||
/// Previous transform of the body (for interpolation)
|
||||
rp3d::Transform mPreviousTransform;
|
||||
|
||||
/// Scaling matrix (applied to a cube to obtain the correct box dimensions)
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
|
@ -104,7 +107,7 @@ class Box : public openglframework::Object3D {
|
|||
reactphysics3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Update the transform matrix of the box
|
||||
void updateTransform();
|
||||
void updateTransform(float interpolationFactor);
|
||||
|
||||
/// Render the cube at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
|
|
@ -57,6 +57,8 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
|
|||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transform;
|
||||
|
||||
// Create a rigid body corresponding in the dynamics world
|
||||
mRigidBody = world->createCollisionBody(transform);
|
||||
|
||||
|
@ -161,14 +163,19 @@ void Capsule::render(openglframework::Shader& shader,
|
|||
}
|
||||
|
||||
// Update the transform matrix of the sphere
|
||||
void Capsule::updateTransform() {
|
||||
void Capsule::updateTransform(float interpolationFactor) {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
// Get the transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getTransform();
|
||||
|
||||
// Interpolate the transform between the previous one and the new one
|
||||
rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform,
|
||||
transform,
|
||||
interpolationFactor);
|
||||
|
||||
// Compute the transform used for rendering the sphere
|
||||
rp3d::decimal matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
interpolatedTransform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
|
|
|
@ -49,6 +49,9 @@ class Capsule : public openglframework::Mesh {
|
|||
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
/// Previous transform (for interpolation)
|
||||
rp3d::Transform mPreviousTransform;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
public :
|
||||
|
@ -74,7 +77,7 @@ class Capsule : public openglframework::Mesh {
|
|||
reactphysics3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Update the transform matrix of the sphere
|
||||
void updateTransform();
|
||||
void updateTransform(float interpolationFactor);
|
||||
|
||||
/// Render the sphere at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
|
|
|
@ -57,6 +57,8 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
|
|||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transform;
|
||||
|
||||
// Create a rigid body corresponding to the cone in the dynamics world
|
||||
mRigidBody = world->createCollisionBody(transform);
|
||||
|
||||
|
@ -161,14 +163,19 @@ void Cone::render(openglframework::Shader& shader,
|
|||
}
|
||||
|
||||
// Update the transform matrix of the cone
|
||||
void Cone::updateTransform() {
|
||||
void Cone::updateTransform(float interpolationFactor) {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
// Get the transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getTransform();
|
||||
|
||||
// Interpolate the transform between the previous one and the new one
|
||||
rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform,
|
||||
transform,
|
||||
interpolationFactor);
|
||||
|
||||
// Compute the transform used for rendering the cone
|
||||
rp3d::decimal matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
interpolatedTransform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
|
|
|
@ -49,6 +49,9 @@ class Cone : public openglframework::Mesh {
|
|||
/// Scaling matrix (applied to a sphere to obtain the correct cone dimensions)
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
/// Previous transform (for interpolation)
|
||||
rp3d::Transform mPreviousTransform;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
public :
|
||||
|
@ -73,7 +76,7 @@ class Cone : public openglframework::Mesh {
|
|||
reactphysics3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Update the transform matrix of the cone
|
||||
void updateTransform();
|
||||
void updateTransform(float interpolationFactor);
|
||||
|
||||
/// Render the cone at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
|
|
|
@ -79,6 +79,8 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
|
|||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transform;
|
||||
|
||||
// Create a rigid body corresponding to the sphere in the dynamics world
|
||||
mRigidBody = world->createCollisionBody(transform);
|
||||
|
||||
|
@ -200,14 +202,19 @@ void ConvexMesh::render(openglframework::Shader& shader,
|
|||
}
|
||||
|
||||
// Update the transform matrix of the sphere
|
||||
void ConvexMesh::updateTransform() {
|
||||
void ConvexMesh::updateTransform(float interpolationFactor) {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
// Get the transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getTransform();
|
||||
|
||||
// Interpolate the transform between the previous one and the new one
|
||||
rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform,
|
||||
transform,
|
||||
interpolationFactor);
|
||||
|
||||
// Compute the transform used for rendering the sphere
|
||||
rp3d::decimal matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
interpolatedTransform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
|
|
|
@ -40,6 +40,9 @@ class ConvexMesh : public openglframework::Mesh {
|
|||
/// Rigid body used to simulate the dynamics of the mesh
|
||||
rp3d::CollisionBody* mRigidBody;
|
||||
|
||||
/// Previous transform (for interpolation)
|
||||
rp3d::Transform mPreviousTransform;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
public :
|
||||
|
@ -64,7 +67,7 @@ class ConvexMesh : public openglframework::Mesh {
|
|||
reactphysics3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Update the transform matrix of the mesh
|
||||
void updateTransform();
|
||||
void updateTransform(float interpolationFactor);
|
||||
|
||||
/// Render the mesh at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
|
|
|
@ -57,6 +57,8 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
|
|||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transform;
|
||||
|
||||
// Create a rigid body corresponding to the cylinder in the dynamics world
|
||||
mRigidBody = world->createCollisionBody(transform);
|
||||
|
||||
|
@ -161,14 +163,19 @@ void Cylinder::render(openglframework::Shader& shader,
|
|||
}
|
||||
|
||||
// Update the transform matrix of the cylinder
|
||||
void Cylinder::updateTransform() {
|
||||
void Cylinder::updateTransform(float interpolationFactor) {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
// Get the transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getTransform();
|
||||
|
||||
// Interpolate the transform between the previous one and the new one
|
||||
rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform,
|
||||
transform,
|
||||
interpolationFactor);
|
||||
|
||||
// Compute the transform used for rendering the cylinder
|
||||
rp3d::decimal matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
interpolatedTransform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
|
|
|
@ -49,6 +49,9 @@ class Cylinder : public openglframework::Mesh {
|
|||
/// Scaling matrix (applied to a sphere to obtain the correct cylinder dimensions)
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
/// Previous transform (for interpolation)
|
||||
rp3d::Transform mPreviousTransform;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
public :
|
||||
|
@ -73,7 +76,7 @@ class Cylinder : public openglframework::Mesh {
|
|||
reactphysics3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Update the transform matrix of the cylinder
|
||||
void updateTransform();
|
||||
void updateTransform(float interpolationFactor);
|
||||
|
||||
/// Render the cylinder at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
|
|
|
@ -64,6 +64,8 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
|
|||
rp3d::Quaternion initOrientation(angleAroundX, 0, 0);
|
||||
rp3d::Transform transformBody(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transformBody;
|
||||
|
||||
// Initial transform of the first sphere collision shape of the dumbbell (in local-space)
|
||||
rp3d::Transform transformSphereShape1(rp3d::Vector3(0, 4.0, 0), rp3d::Quaternion::identity());
|
||||
|
||||
|
@ -197,14 +199,19 @@ void Dumbbell::render(openglframework::Shader& shader,
|
|||
}
|
||||
|
||||
// Update the transform matrix of the sphere
|
||||
void Dumbbell::updateTransform() {
|
||||
void Dumbbell::updateTransform(float interpolationFactor) {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mBody->getInterpolatedTransform();
|
||||
// Get the transform of the rigid body
|
||||
rp3d::Transform transform = mBody->getTransform();
|
||||
|
||||
// Interpolate the transform between the previous one and the new one
|
||||
rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform,
|
||||
transform,
|
||||
interpolationFactor);
|
||||
|
||||
// Compute the transform used for rendering the sphere
|
||||
rp3d::decimal matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
interpolatedTransform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
|
|
|
@ -46,6 +46,9 @@ class Dumbbell : public openglframework::Mesh {
|
|||
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
/// Previous transform (for interpolation)
|
||||
rp3d::Transform mPreviousTransform;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
public :
|
||||
|
@ -71,7 +74,7 @@ class Dumbbell : public openglframework::Mesh {
|
|||
rp3d::CollisionBody* getCollisionBody();
|
||||
|
||||
/// Update the transform matrix of the sphere
|
||||
void updateTransform();
|
||||
void updateTransform(float interpolationFactor);
|
||||
|
||||
/// Render the sphere at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
|
|
|
@ -58,9 +58,6 @@ class Line : public openglframework::Object3D {
|
|||
/// Return the second point of the line
|
||||
openglframework::Vector3 getPoint2() const;
|
||||
|
||||
/// Update the transform matrix of the sphere
|
||||
void updateTransform();
|
||||
|
||||
/// Render the line at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
|
|
@ -57,6 +57,8 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
|
|||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transform;
|
||||
|
||||
// Create a rigid body corresponding to the sphere in the dynamics world
|
||||
mRigidBody = world->createCollisionBody(transform);
|
||||
|
||||
|
@ -161,14 +163,19 @@ void Sphere::render(openglframework::Shader& shader,
|
|||
}
|
||||
|
||||
// Update the transform matrix of the sphere
|
||||
void Sphere::updateTransform() {
|
||||
void Sphere::updateTransform(float interpolationFactor) {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
// Get the transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getTransform();
|
||||
|
||||
// Interpolate the transform between the previous one and the new one
|
||||
rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform,
|
||||
transform,
|
||||
interpolationFactor);
|
||||
|
||||
// Compute the transform used for rendering the sphere
|
||||
rp3d::decimal matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
interpolatedTransform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
|
|
|
@ -46,6 +46,9 @@ class Sphere : public openglframework::Mesh {
|
|||
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
/// Previous transform (for interpolation)
|
||||
rp3d::Transform mPreviousTransform;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
public :
|
||||
|
@ -70,7 +73,7 @@ class Sphere : public openglframework::Mesh {
|
|||
reactphysics3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Update the transform matrix of the sphere
|
||||
void updateTransform();
|
||||
void updateTransform(float interpolationFactor);
|
||||
|
||||
/// Render the sphere at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
|
|
|
@ -53,7 +53,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
|
|||
rp3d::decimal timeStep = 1.0f / 60.0f;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep);
|
||||
mDynamicsWorld = new rp3d::DynamicsWorld(gravity);
|
||||
|
||||
// Set the number of iterations of the constraint solver
|
||||
mDynamicsWorld->setNbIterationsVelocitySolver(15);
|
||||
|
@ -216,9 +216,6 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
|
|||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material = mFloor->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.2));
|
||||
|
||||
// Start the simulation
|
||||
mDynamicsWorld->start();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
@ -309,46 +306,49 @@ CollisionShapesScene::~CollisionShapesScene() {
|
|||
delete mDynamicsWorld;
|
||||
}
|
||||
|
||||
// Take a step for the simulation
|
||||
void CollisionShapesScene::update() {
|
||||
|
||||
// Update the physics world (take a simulation step)
|
||||
void CollisionShapesScene::updatePhysics() {
|
||||
|
||||
// Take a simulation step
|
||||
mDynamicsWorld->update();
|
||||
mDynamicsWorld->update(mEngineSettings.timeStep);
|
||||
}
|
||||
|
||||
// Take a step for the simulation
|
||||
void CollisionShapesScene::update() {
|
||||
|
||||
// Update the position and orientation of the boxes
|
||||
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
(*it)->updateTransform(mInterpolationFactor);
|
||||
}
|
||||
|
||||
// Update the position and orientation of the sphere
|
||||
for (std::vector<Sphere*>::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
(*it)->updateTransform(mInterpolationFactor);
|
||||
}
|
||||
|
||||
// Update the position and orientation of the cones
|
||||
for (std::vector<Cone*>::iterator it = mCones.begin(); it != mCones.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
(*it)->updateTransform(mInterpolationFactor);
|
||||
}
|
||||
|
||||
// Update the position and orientation of the cylinders
|
||||
for (std::vector<Cylinder*>::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
(*it)->updateTransform(mInterpolationFactor);
|
||||
}
|
||||
|
||||
// Update the position and orientation of the capsules
|
||||
for (std::vector<Capsule*>::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
(*it)->updateTransform(mInterpolationFactor);
|
||||
}
|
||||
|
||||
// Update the position and orientation of the convex meshes
|
||||
|
@ -356,7 +356,7 @@ void CollisionShapesScene::update() {
|
|||
it != mConvexMeshes.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
(*it)->updateTransform(mInterpolationFactor);
|
||||
}
|
||||
|
||||
// Update the position and orientation of the dumbbells
|
||||
|
@ -364,10 +364,10 @@ void CollisionShapesScene::update() {
|
|||
it != mDumbbells.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
(*it)->updateTransform(mInterpolationFactor);
|
||||
}
|
||||
|
||||
mFloor->updateTransform();
|
||||
mFloor->updateTransform(mInterpolationFactor);
|
||||
}
|
||||
|
||||
// Render the scene
|
||||
|
|
|
@ -114,6 +114,10 @@ class CollisionShapesScene : public Scene{
|
|||
/// Destructor
|
||||
virtual ~CollisionShapesScene();
|
||||
|
||||
/// Update the physics world (take a simulation step)
|
||||
/// Can be called several times per frame
|
||||
virtual void updatePhysics();
|
||||
|
||||
/// Take a step for the simulation
|
||||
virtual void update();
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ CubesScene::CubesScene(const std::string& name)
|
|||
rp3d::decimal timeStep = 1.0f / 60.0f;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep);
|
||||
mDynamicsWorld = new rp3d::DynamicsWorld(gravity);
|
||||
|
||||
// Set the number of iterations of the constraint solver
|
||||
mDynamicsWorld->setNbIterationsVelocitySolver(15);
|
||||
|
@ -89,18 +89,11 @@ CubesScene::CubesScene(const std::string& name)
|
|||
// Change the material properties of the floor rigid body
|
||||
rp3d::Material& material = mFloor->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.3));
|
||||
|
||||
// Start the simulation
|
||||
mDynamicsWorld->start();
|
||||
|
||||
counter=0;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
CubesScene::~CubesScene() {
|
||||
|
||||
mDynamicsWorld->stop();
|
||||
|
||||
// Destroy the shader
|
||||
mPhongShader.destroy();
|
||||
|
||||
|
@ -124,25 +117,24 @@ CubesScene::~CubesScene() {
|
|||
delete mDynamicsWorld;
|
||||
}
|
||||
|
||||
// Take a step for the simulation
|
||||
void CubesScene::update() {
|
||||
|
||||
counter++;
|
||||
if (counter == 400) {
|
||||
//mIsRunning = false;
|
||||
}
|
||||
// Update the physics world (take a simulation step)
|
||||
void CubesScene::updatePhysics() {
|
||||
|
||||
// Take a simulation step
|
||||
mDynamicsWorld->update();
|
||||
mDynamicsWorld->update(mEngineSettings.timeStep);
|
||||
}
|
||||
|
||||
// Update the scene
|
||||
void CubesScene::update() {
|
||||
|
||||
// Update the position and orientation of the boxes
|
||||
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
(*it)->updateTransform(mInterpolationFactor);
|
||||
}
|
||||
|
||||
mFloor->updateTransform();
|
||||
mFloor->updateTransform(mInterpolationFactor);
|
||||
|
||||
// Set the color of the awake/sleeping bodies
|
||||
for (uint i=0; i<mBoxes.size(); i++) {
|
||||
|
|
|
@ -48,8 +48,6 @@ class CubesScene : public Scene {
|
|||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
int counter;
|
||||
|
||||
/// Light 0
|
||||
openglframework::Light mLight0;
|
||||
|
||||
|
@ -75,6 +73,10 @@ class CubesScene : public Scene {
|
|||
/// Destructor
|
||||
virtual ~CubesScene();
|
||||
|
||||
/// Update the physics world (take a simulation step)
|
||||
/// Can be called several times per frame
|
||||
virtual void updatePhysics();
|
||||
|
||||
/// Update the scene (take a simulation step)
|
||||
virtual void update();
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ JointsScene::JointsScene(const std::string& name)
|
|||
rp3d::decimal timeStep = 1.0f / 60.0f;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep);
|
||||
mDynamicsWorld = new rp3d::DynamicsWorld(gravity);
|
||||
|
||||
// Set the number of iterations of the constraint solver
|
||||
mDynamicsWorld->setNbIterationsVelocitySolver(15);
|
||||
|
@ -72,17 +72,11 @@ JointsScene::JointsScene(const std::string& name)
|
|||
|
||||
// Create the floor
|
||||
createFloor();
|
||||
|
||||
// Start the simulation
|
||||
mDynamicsWorld->start();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
JointsScene::~JointsScene() {
|
||||
|
||||
// Stop the physics simulation
|
||||
mDynamicsWorld->stop();
|
||||
|
||||
// Destroy the shader
|
||||
mPhongShader.destroy();
|
||||
|
||||
|
@ -122,28 +116,32 @@ JointsScene::~JointsScene() {
|
|||
delete mDynamicsWorld;
|
||||
}
|
||||
|
||||
// Take a step for the simulation
|
||||
void JointsScene::update() {
|
||||
// Update the physics world (take a simulation step)
|
||||
void JointsScene::updatePhysics() {
|
||||
|
||||
// Update the motor speed of the Slider Joint (to move up and down)
|
||||
long double motorSpeed = 2 * cos(mDynamicsWorld->getPhysicsTime() * 1.5);
|
||||
long double motorSpeed = 2 * cos(mEngineSettings.elapsedTime * 1.5);
|
||||
mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed));
|
||||
|
||||
// Take a simulation step
|
||||
mDynamicsWorld->update();
|
||||
mDynamicsWorld->update(mEngineSettings.timeStep);
|
||||
}
|
||||
|
||||
// Take a step for the simulation
|
||||
void JointsScene::update() {
|
||||
|
||||
// Update the position and orientation of the boxes
|
||||
mSliderJointBottomBox->updateTransform();
|
||||
mSliderJointTopBox->updateTransform();
|
||||
mPropellerBox->updateTransform();
|
||||
mFixedJointBox1->updateTransform();
|
||||
mFixedJointBox2->updateTransform();
|
||||
mSliderJointBottomBox->updateTransform(mInterpolationFactor);
|
||||
mSliderJointTopBox->updateTransform(mInterpolationFactor);
|
||||
mPropellerBox->updateTransform(mInterpolationFactor);
|
||||
mFixedJointBox1->updateTransform(mInterpolationFactor);
|
||||
mFixedJointBox2->updateTransform(mInterpolationFactor);
|
||||
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) {
|
||||
mBallAndSocketJointChainBoxes[i]->updateTransform();
|
||||
mBallAndSocketJointChainBoxes[i]->updateTransform(mInterpolationFactor);
|
||||
}
|
||||
|
||||
// Update the position and orientation of the floor
|
||||
mFloor->updateTransform();
|
||||
mFloor->updateTransform(mInterpolationFactor);
|
||||
}
|
||||
|
||||
// Render the scene
|
||||
|
|
|
@ -127,6 +127,10 @@ class JointsScene : public Scene {
|
|||
/// Destructor
|
||||
virtual ~JointsScene();
|
||||
|
||||
/// Update the physics world (take a simulation step)
|
||||
/// Can be called several times per frame
|
||||
virtual void updatePhysics();
|
||||
|
||||
/// Take a step for the simulation
|
||||
virtual void update();
|
||||
|
||||
|
|
|
@ -227,6 +227,11 @@ RaycastScene::~RaycastScene() {
|
|||
}
|
||||
}
|
||||
|
||||
// Update the physics world (take a simulation step)
|
||||
void RaycastScene::updatePhysics() {
|
||||
|
||||
}
|
||||
|
||||
// Take a step for the simulation
|
||||
void RaycastScene::update() {
|
||||
|
||||
|
|
|
@ -177,6 +177,10 @@ class RaycastScene : public Scene {
|
|||
/// Destructor
|
||||
virtual ~RaycastScene();
|
||||
|
||||
/// Update the physics world (take a simulation step)
|
||||
/// Can be called several times per frame
|
||||
virtual void updatePhysics();
|
||||
|
||||
/// Take a step for the simulation
|
||||
virtual void update();
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
Scene::Scene(const std::string& name) : mName(name) {
|
||||
Scene::Scene(const std::string& name) : mName(name), mInterpolationFactor(0.0f) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,16 @@
|
|||
// Libraries
|
||||
#include "openglframework.h"
|
||||
|
||||
/// Structure EngineSettings
|
||||
/// This structure contains several physics engine parameters
|
||||
struct EngineSettings {
|
||||
|
||||
public:
|
||||
|
||||
float elapsedTime; // Elapsed time (in seconds)
|
||||
float timeStep; // Current time step (in seconds)
|
||||
};
|
||||
|
||||
// Class Scene
|
||||
// Abstract class that represents a 3D scene.
|
||||
class Scene {
|
||||
|
@ -40,6 +50,9 @@ class Scene {
|
|||
/// Scene name
|
||||
std::string mName;
|
||||
|
||||
/// Physics engine settings
|
||||
EngineSettings mEngineSettings;
|
||||
|
||||
/// Camera
|
||||
openglframework::Camera mCamera;
|
||||
|
||||
|
@ -58,6 +71,9 @@ class Scene {
|
|||
/// True if the last point computed on a sphere (for camera rotation) is valid
|
||||
bool mIsLastPointOnSphereValid;
|
||||
|
||||
/// Interpolation factor for the bodies in the current frame
|
||||
float mInterpolationFactor;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Set the scene position (where the camera needs to look at)
|
||||
|
@ -93,7 +109,11 @@ class Scene {
|
|||
/// Reshape the view
|
||||
virtual void reshape(int width, int height);
|
||||
|
||||
/// Update the scene (take a simulation step)
|
||||
/// Update the physics world (take a simulation step)
|
||||
/// Can be called several times per frame
|
||||
virtual void updatePhysics()=0;
|
||||
|
||||
/// Update the scene
|
||||
virtual void update()=0;
|
||||
|
||||
/// Render the scene
|
||||
|
@ -121,6 +141,12 @@ class Scene {
|
|||
|
||||
/// Return a reference to the camera
|
||||
const openglframework::Camera& getCamera() const;
|
||||
|
||||
/// Set the engine settings
|
||||
void setEngineSettings(const EngineSettings& settings);
|
||||
|
||||
/// Set the interpolation factor
|
||||
void setInterpolationFactor(float interpolationFactor);
|
||||
};
|
||||
|
||||
// Called when a keyboard event occurs
|
||||
|
@ -144,5 +170,14 @@ inline void Scene::setWindowDimension(int width, int height) {
|
|||
mWindowHeight = height;
|
||||
}
|
||||
|
||||
// Set the engine settings
|
||||
inline void Scene::setEngineSettings(const EngineSettings& settings) {
|
||||
mEngineSettings = settings;
|
||||
}
|
||||
|
||||
// Set the interpolation factor
|
||||
inline void Scene::setInterpolationFactor(float interpolationFactor) {
|
||||
mInterpolationFactor = interpolationFactor;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -124,6 +124,8 @@ void TestbedApplication::init() {
|
|||
|
||||
// Create all the scenes
|
||||
createScenes();
|
||||
|
||||
mTimer.start();
|
||||
}
|
||||
|
||||
// Create all the scenes
|
||||
|
@ -159,9 +161,40 @@ void TestbedApplication::destroyScenes() {
|
|||
mCurrentScene = NULL;
|
||||
}
|
||||
|
||||
// Update the physics of the current scene
|
||||
void TestbedApplication::updatePhysics() {
|
||||
|
||||
// Set the engine settings
|
||||
mEngineSettings.elapsedTime = mTimer.getPhysicsTime();
|
||||
mCurrentScene->setEngineSettings(mEngineSettings);
|
||||
|
||||
if (mTimer.isRunning()) {
|
||||
|
||||
// Compute the time since the last update() call and update the timer
|
||||
mTimer.update();
|
||||
|
||||
// While the time accumulator is not empty
|
||||
while(mTimer.isPossibleToTakeStep()) {
|
||||
|
||||
// Take a physics simulation step
|
||||
mCurrentScene->updatePhysics();
|
||||
|
||||
// Update the timer
|
||||
mTimer.nextStep();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TestbedApplication::update() {
|
||||
|
||||
// Physics simulation
|
||||
// Compute the interpolation factor
|
||||
float factor = mTimer.computeInterpolationFactor(mEngineSettings.timeStep);
|
||||
assert(factor >= 0.0f && factor <= 1.0f);
|
||||
|
||||
// Notify the scene about the interpolation factor
|
||||
mCurrentScene->setInterpolationFactor(factor);
|
||||
|
||||
// Update the scene
|
||||
mCurrentScene->update();
|
||||
|
||||
// Compute the current framerate
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "openglframework.h"
|
||||
#include "GUI.h"
|
||||
#include "Scene.h"
|
||||
#include "Timer.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
/// Class TestbedApplication
|
||||
|
@ -50,12 +51,18 @@ class TestbedApplication {
|
|||
/// Graphical User Interface
|
||||
Gui mGUI;
|
||||
|
||||
/// Timer
|
||||
Timer mTimer;
|
||||
|
||||
/// List of 3D scenes
|
||||
std::vector<Scene*> mScenes;
|
||||
|
||||
/// Current 3D scene
|
||||
Scene* mCurrentScene;
|
||||
|
||||
/// Physics engine settings
|
||||
EngineSettings mEngineSettings;
|
||||
|
||||
/// Current number of frames per seconds
|
||||
double mFPS;
|
||||
|
||||
|
@ -85,6 +92,9 @@ class TestbedApplication {
|
|||
/// Private assignment operator (for the singleton class)
|
||||
void operator=(TestbedApplication const&);
|
||||
|
||||
/// Update the physics of the current scene
|
||||
void updatePhysics();
|
||||
|
||||
/// Update
|
||||
void update();
|
||||
|
||||
|
|
64
testbed/src/Timer.cpp
Normal file
64
testbed/src/Timer.cpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||
* Copyright (c) 2010-2015 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Timer.h"
|
||||
|
||||
|
||||
// Constructor
|
||||
Timer::Timer() : mIsRunning(false) {
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Timer::~Timer() {
|
||||
|
||||
}
|
||||
|
||||
// Return the current time of the system in seconds
|
||||
long double Timer::getCurrentSystemTime() {
|
||||
|
||||
#if defined(WINDOWS_OS)
|
||||
LARGE_INTEGER ticksPerSecond;
|
||||
LARGE_INTEGER ticks;
|
||||
QueryPerformanceFrequency(&ticksPerSecond);
|
||||
QueryPerformanceCounter(&ticks);
|
||||
return (long double(ticks.QuadPart) / long double(ticksPerSecond.QuadPart));
|
||||
#else
|
||||
// Initialize the lastUpdateTime with the current time in seconds
|
||||
timeval timeValue;
|
||||
gettimeofday(&timeValue, NULL);
|
||||
return (timeValue.tv_sec + (timeValue.tv_usec / 1000000.0));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
177
testbed/src/Timer.h
Normal file
177
testbed/src/Timer.h
Normal file
|
@ -0,0 +1,177 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||
* Copyright (c) 2010-2015 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
// Libraries
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include <cassert>
|
||||
#include "configuration.h"
|
||||
|
||||
#if defined(WINDOWS_OS) // For Windows platform
|
||||
#define NOMINMAX // This is used to avoid definition of max() and min() macros
|
||||
#include <windows.h>
|
||||
#else // For Mac OS or Linux platform
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
// Class Timer
|
||||
/**
|
||||
* This class will take care of the time in the physics engine. It
|
||||
* uses functions that depend on the current platform to get the
|
||||
* current time.
|
||||
*/
|
||||
class Timer {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Timestep dt of the physics engine (timestep > 0.0)
|
||||
double mTimeStep;
|
||||
|
||||
/// Last time the timer has been updated
|
||||
long double mLastUpdateTime;
|
||||
|
||||
/// Time difference between the two last timer update() calls
|
||||
long double mDeltaTime;
|
||||
|
||||
/// Used to fix the time step and avoid strange time effects
|
||||
double mAccumulator;
|
||||
|
||||
/// True if the timer is running
|
||||
bool mIsRunning;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Private copy-constructor
|
||||
Timer(const Timer& timer);
|
||||
|
||||
/// Private assignment operator
|
||||
Timer& operator=(const Timer& timer);
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Timer();
|
||||
|
||||
/// Destructor
|
||||
virtual ~Timer();
|
||||
|
||||
/// Return the current time of the physics engine
|
||||
long double getPhysicsTime() const;
|
||||
|
||||
/// Start the timer
|
||||
void start();
|
||||
|
||||
/// Stop the timer
|
||||
void stop();
|
||||
|
||||
/// Return true if the timer is running
|
||||
bool isRunning() const;
|
||||
|
||||
/// True if it's possible to take a new step
|
||||
bool isPossibleToTakeStep() const;
|
||||
|
||||
/// Compute the time since the last update() call and add it to the accumulator
|
||||
void update();
|
||||
|
||||
/// Take a new step => update the timer by adding the timeStep value to the current time
|
||||
void nextStep();
|
||||
|
||||
/// Compute the interpolation factor
|
||||
float computeInterpolationFactor(float timeStep);
|
||||
|
||||
/// Return the current time of the system in seconds
|
||||
static long double getCurrentSystemTime();
|
||||
};
|
||||
|
||||
// Return the current time
|
||||
inline long double Timer::getPhysicsTime() const {
|
||||
return mLastUpdateTime;
|
||||
}
|
||||
|
||||
// Return if the timer is running
|
||||
inline bool Timer::isRunning() const {
|
||||
return mIsRunning;
|
||||
}
|
||||
|
||||
// Start the timer
|
||||
inline void Timer::start() {
|
||||
if (!mIsRunning) {
|
||||
|
||||
// Get the current system time
|
||||
mLastUpdateTime = getCurrentSystemTime();
|
||||
|
||||
mAccumulator = 0.0;
|
||||
mIsRunning = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Stop the timer
|
||||
inline void Timer::stop() {
|
||||
mIsRunning = false;
|
||||
}
|
||||
|
||||
// True if it's possible to take a new step
|
||||
inline bool Timer::isPossibleToTakeStep() const {
|
||||
return (mAccumulator >= mTimeStep);
|
||||
}
|
||||
|
||||
// Take a new step => update the timer by adding the timeStep value to the current time
|
||||
inline void Timer::nextStep() {
|
||||
assert(mIsRunning);
|
||||
|
||||
// Update the accumulator value
|
||||
mAccumulator -= mTimeStep;
|
||||
}
|
||||
|
||||
// Compute the interpolation factor
|
||||
inline float Timer::computeInterpolationFactor(float timeStep) {
|
||||
return (float(mAccumulator) / timeStep);
|
||||
}
|
||||
|
||||
// Compute the time since the last update() call and add it to the accumulator
|
||||
inline void Timer::update() {
|
||||
|
||||
// Get the current system time
|
||||
long double currentTime = getCurrentSystemTime();
|
||||
|
||||
// Compute the delta display time between two display frames
|
||||
mDeltaTime = currentTime - mLastUpdateTime;
|
||||
|
||||
// Update the current display time
|
||||
mLastUpdateTime = currentTime;
|
||||
|
||||
// Update the accumulator value
|
||||
mAccumulator += mDeltaTime;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user