Add heightfield scene in Testbed application
This commit is contained in:
parent
ece6db9636
commit
6489be1953
|
@ -69,6 +69,8 @@ SET(COMMON_SOURCES
|
|||
common/Cylinder.cpp
|
||||
common/Dumbbell.h
|
||||
common/Dumbbell.cpp
|
||||
common/HeightField.h
|
||||
common/HeightField.cpp
|
||||
common/PhysicsObject.h
|
||||
common/PhysicsObject.cpp
|
||||
common/VisualContactPoint.h
|
||||
|
@ -87,6 +89,8 @@ SET(SCENES_SOURCES
|
|||
scenes/collisionshapes/CollisionShapesScene.cpp
|
||||
scenes/concavemesh/ConcaveMeshScene.h
|
||||
scenes/concavemesh/ConcaveMeshScene.cpp
|
||||
scenes/heightfield/HeightFieldScene.h
|
||||
scenes/heightfield/HeightFieldScene.cpp
|
||||
)
|
||||
|
||||
# Add .user file to set debug path in Visual Studio
|
||||
|
|
|
@ -121,6 +121,8 @@ ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, float mass,
|
|||
// do not forget to delete it at the end
|
||||
mConcaveShape = new rp3d::ConcaveMeshShape(&mPhysicsTriangleMesh);
|
||||
|
||||
mConcaveShape->setIsSmoothMeshCollisionEnabled(false);
|
||||
|
||||
// Initial position and orientation of the rigid body
|
||||
rp3d::Vector3 initPosition(position.x, position.y, position.z);
|
||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
|
|
329
testbed/common/HeightField.cpp
Normal file
329
testbed/common/HeightField.cpp
Normal file
|
@ -0,0 +1,329 @@
|
|||
/********************************************************************************
|
||||
* 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 "HeightField.h"
|
||||
|
||||
// Constructor
|
||||
HeightField::HeightField(const openglframework::Vector3 &position,
|
||||
reactphysics3d::CollisionWorld* world)
|
||||
: openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER),
|
||||
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
|
||||
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
|
||||
|
||||
// Initialize the position where the sphere will be rendered
|
||||
translateWorld(position);
|
||||
|
||||
// Compute the scaling matrix
|
||||
mScalingMatrix = openglframework::Matrix4::identity();
|
||||
|
||||
// Generate the height field
|
||||
generateHeightField();
|
||||
|
||||
// Generate the graphics mesh
|
||||
generateGraphicsMesh();
|
||||
|
||||
// Create the collision shape for the rigid body (convex mesh shape) and
|
||||
// do not forget to delete it at the end
|
||||
mHeightFieldShape = new rp3d::HeightFieldShape(HEIGHTFIELD_WIDTH, HEIGHTFIELD_LENGTH, 0, 5,
|
||||
mHeightData, rp3d::HeightFieldShape::HEIGHT_FLOAT_TYPE);
|
||||
|
||||
// Initial position and orientation of the rigid body
|
||||
rp3d::Vector3 initPosition(position.x, position.y, position.z);
|
||||
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
|
||||
mBody = world->createCollisionBody(transform);
|
||||
|
||||
// Add a collision shape to the body and specify the mass of the collision shape
|
||||
mProxyShape = mBody->addCollisionShape(mHeightFieldShape, rp3d::Transform::identity());
|
||||
|
||||
// Create the VBOs and VAO
|
||||
createVBOAndVAO();
|
||||
|
||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
HeightField::HeightField(const openglframework::Vector3 &position, float mass,
|
||||
reactphysics3d::DynamicsWorld* dynamicsWorld)
|
||||
: openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER),
|
||||
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
|
||||
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
|
||||
|
||||
// Initialize the position where the sphere will be rendered
|
||||
translateWorld(position);
|
||||
|
||||
// Compute the scaling matrix
|
||||
mScalingMatrix = openglframework::Matrix4::identity();
|
||||
|
||||
// Generate the height field
|
||||
generateHeightField();
|
||||
|
||||
// Generate the graphics mesh
|
||||
generateGraphicsMesh();
|
||||
|
||||
// Create the collision shape for the rigid body (convex mesh shape) and
|
||||
// do not forget to delete it at the end
|
||||
mHeightFieldShape = new rp3d::HeightFieldShape(HEIGHTFIELD_WIDTH, HEIGHTFIELD_LENGTH, 0, 5,
|
||||
mHeightData, rp3d::HeightFieldShape::HEIGHT_FLOAT_TYPE);
|
||||
|
||||
// Initial position and orientation of the rigid body
|
||||
rp3d::Vector3 initPosition(position.x, position.y, position.z);
|
||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
// Create a rigid body corresponding to the sphere in the dynamics world
|
||||
rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform);
|
||||
|
||||
// Add a collision shape to the body and specify the mass of the collision shape
|
||||
mProxyShape = body->addCollisionShape(mHeightFieldShape, rp3d::Transform::identity(), mass);
|
||||
|
||||
mBody = body;
|
||||
|
||||
// Create the VBOs and VAO
|
||||
createVBOAndVAO();
|
||||
|
||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
HeightField::~HeightField() {
|
||||
|
||||
// Destroy the mesh
|
||||
destroy();
|
||||
|
||||
// Destroy the VBOs and VAO
|
||||
mVBOIndices.destroy();
|
||||
mVBOVertices.destroy();
|
||||
mVBONormals.destroy();
|
||||
mVBOTextureCoords.destroy();
|
||||
mVAO.destroy();
|
||||
|
||||
delete mHeightFieldShape;
|
||||
}
|
||||
|
||||
// Render the sphere at the correct position and with the correct orientation
|
||||
void HeightField::render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix) {
|
||||
|
||||
// Bind the shader
|
||||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix);
|
||||
shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix);
|
||||
|
||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||
// model-view matrix)
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
const openglframework::Matrix3 normalMatrix =
|
||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||
|
||||
// Set the vertex color
|
||||
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
||||
shader.setVector4Uniform("vertexColor", color, false);
|
||||
|
||||
// Bind the VAO
|
||||
mVAO.bind();
|
||||
|
||||
mVBOVertices.bind();
|
||||
|
||||
// Get the location of shader attribute variables
|
||||
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
|
||||
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false);
|
||||
|
||||
glEnableVertexAttribArray(vertexPositionLoc);
|
||||
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
|
||||
mVBONormals.bind();
|
||||
|
||||
if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc);
|
||||
|
||||
// For each part of the mesh
|
||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(vertexPositionLoc);
|
||||
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||
|
||||
mVBONormals.unbind();
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Compute the heights of the height field
|
||||
void HeightField::generateHeightField() {
|
||||
|
||||
mMinHeight = 0.0;
|
||||
mMaxHeight = 5.0;
|
||||
|
||||
for (int i=0; i<HEIGHTFIELD_WIDTH; i++) {
|
||||
for (int j=0; j<HEIGHTFIELD_LENGTH; j++) {
|
||||
mHeightData[i][j] = 5.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the graphics mesh to render the height field
|
||||
void HeightField::generateGraphicsMesh() {
|
||||
|
||||
std::vector<uint> indices;
|
||||
int vertexId = 0;
|
||||
|
||||
for (int i=0; i<HEIGHTFIELD_WIDTH; i++) {
|
||||
for (int j=0; j<HEIGHTFIELD_LENGTH; j++) {
|
||||
|
||||
float height = mHeightData[i][j] - (mMaxHeight - mMinHeight) * 0.5f;
|
||||
openglframework::Vector3 vertex(-HEIGHTFIELD_WIDTH * 0.5f + i, height, -HEIGHTFIELD_LENGTH * 0.5 + j);
|
||||
|
||||
mVertices.push_back(vertex);
|
||||
|
||||
// Triangle indices
|
||||
if ((i < HEIGHTFIELD_WIDTH - 1) && (j < HEIGHTFIELD_LENGTH - 1)) {
|
||||
|
||||
int v1 = vertexId;
|
||||
int v2 = vertexId + 1;
|
||||
int v3 = vertexId + HEIGHTFIELD_LENGTH;
|
||||
int v4 = vertexId + HEIGHTFIELD_LENGTH + 1;
|
||||
|
||||
// First triangle
|
||||
indices.push_back(v1);
|
||||
indices.push_back(v2);
|
||||
indices.push_back(v3);
|
||||
|
||||
// Second triangle
|
||||
indices.push_back(v2);
|
||||
indices.push_back(v4);
|
||||
indices.push_back(v3);
|
||||
}
|
||||
|
||||
vertexId++;
|
||||
}
|
||||
}
|
||||
|
||||
mIndices.push_back(indices);
|
||||
|
||||
calculateNormals();
|
||||
}
|
||||
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
/// We create two VBOs (one for vertices and one for indices)
|
||||
void HeightField::createVBOAndVAO() {
|
||||
|
||||
// Create the VBO for the vertices data
|
||||
mVBOVertices.create();
|
||||
mVBOVertices.bind();
|
||||
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
|
||||
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Create the VBO for the normals data
|
||||
mVBONormals.create();
|
||||
mVBONormals.bind();
|
||||
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
|
||||
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
|
||||
mVBONormals.unbind();
|
||||
|
||||
if (hasTexture()) {
|
||||
// Create the VBO for the texture co data
|
||||
mVBOTextureCoords.create();
|
||||
mVBOTextureCoords.bind();
|
||||
size_t sizeTextureCoords = mUVs.size() * sizeof(openglframework::Vector2);
|
||||
mVBOTextureCoords.copyDataIntoVBO(sizeTextureCoords, getUVTextureCoordinatesPointer(), GL_STATIC_DRAW);
|
||||
mVBOTextureCoords.unbind();
|
||||
}
|
||||
|
||||
// Create th VBO for the indices data
|
||||
mVBOIndices.create();
|
||||
mVBOIndices.bind();
|
||||
size_t sizeIndices = mIndices[0].size() * sizeof(unsigned int);
|
||||
mVBOIndices.copyDataIntoVBO(sizeIndices, getIndicesPointer(), GL_STATIC_DRAW);
|
||||
mVBOIndices.unbind();
|
||||
|
||||
// Create the VAO for both VBOs
|
||||
mVAO.create();
|
||||
mVAO.bind();
|
||||
|
||||
// Bind the VBO of vertices
|
||||
mVBOVertices.bind();
|
||||
|
||||
// Bind the VBO of normals
|
||||
mVBONormals.bind();
|
||||
|
||||
if (hasTexture()) {
|
||||
// Bind the VBO of texture coords
|
||||
mVBOTextureCoords.bind();
|
||||
}
|
||||
|
||||
// Bind the VBO of indices
|
||||
mVBOIndices.bind();
|
||||
|
||||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
}
|
||||
|
||||
// Reset the transform
|
||||
void HeightField::resetTransform(const rp3d::Transform& transform) {
|
||||
|
||||
// Reset the transform
|
||||
mBody->setTransform(transform);
|
||||
|
||||
mBody->setIsSleeping(false);
|
||||
|
||||
// Reset the velocity of the rigid body
|
||||
rp3d::RigidBody* rigidBody = dynamic_cast<rp3d::RigidBody*>(mBody);
|
||||
if (rigidBody != NULL) {
|
||||
rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0));
|
||||
rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0));
|
||||
}
|
||||
|
||||
updateTransform(1.0f);
|
||||
}
|
||||
|
||||
// Set the scaling of the object
|
||||
void HeightField::setScaling(const openglframework::Vector3& scaling) {
|
||||
|
||||
// Scale the collision shape
|
||||
mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z));
|
||||
|
||||
// Scale the graphics object
|
||||
mScalingMatrix = openglframework::Matrix4(scaling.x, 0, 0, 0,
|
||||
0, scaling.y, 0,0,
|
||||
0, 0, scaling.z, 0,
|
||||
0, 0, 0, 1.0f);
|
||||
}
|
||||
|
120
testbed/common/HeightField.h
Normal file
120
testbed/common/HeightField.h
Normal file
|
@ -0,0 +1,120 @@
|
|||
/********************************************************************************
|
||||
* 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 HEIGHT_FIELD_H
|
||||
#define HEIGHT_FIELD_H
|
||||
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
#include "PhysicsObject.h"
|
||||
|
||||
// Class HeightField
|
||||
class HeightField : public openglframework::Mesh, public PhysicsObject {
|
||||
|
||||
private :
|
||||
|
||||
static const int HEIGHTFIELD_WIDTH = 10;
|
||||
static const int HEIGHTFIELD_LENGTH = 5;
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Height field data
|
||||
float mHeightData[HEIGHTFIELD_WIDTH][HEIGHTFIELD_LENGTH];
|
||||
|
||||
/// Previous transform (for interpolation)
|
||||
rp3d::Transform mPreviousTransform;
|
||||
|
||||
/// Collision shape
|
||||
rp3d::HeightFieldShape* mHeightFieldShape;
|
||||
rp3d::ProxyShape* mProxyShape;
|
||||
|
||||
/// Scaling matrix
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
/// Vertex Buffer Object for the vertices data
|
||||
openglframework::VertexBufferObject mVBOVertices;
|
||||
|
||||
/// Vertex Buffer Object for the normals data
|
||||
openglframework::VertexBufferObject mVBONormals;
|
||||
|
||||
/// Vertex Buffer Object for the texture coords
|
||||
openglframework::VertexBufferObject mVBOTextureCoords;
|
||||
|
||||
/// Vertex Buffer Object for the indices
|
||||
openglframework::VertexBufferObject mVBOIndices;
|
||||
|
||||
/// Vertex Array Object for the vertex data
|
||||
openglframework::VertexArrayObject mVAO;
|
||||
|
||||
/// Min/Max height of the height field values
|
||||
float mMinHeight, mMaxHeight;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
void createVBOAndVAO();
|
||||
|
||||
// Compute the heights of the height field
|
||||
void generateHeightField();
|
||||
|
||||
// Generate the graphics mesh to render the height field
|
||||
void generateGraphicsMesh();
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
HeightField(const openglframework::Vector3& position,
|
||||
rp3d::CollisionWorld* world);
|
||||
|
||||
/// Constructor
|
||||
HeightField(const openglframework::Vector3& position, float mass,
|
||||
rp3d::DynamicsWorld* dynamicsWorld);
|
||||
|
||||
/// Destructor
|
||||
~HeightField();
|
||||
|
||||
/// Render the mesh at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
||||
/// Set the position of the box
|
||||
void resetTransform(const rp3d::Transform& transform);
|
||||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor);
|
||||
|
||||
/// Set the scaling of the object
|
||||
void setScaling(const openglframework::Vector3& scaling);
|
||||
};
|
||||
|
||||
// Update the transform matrix of the object
|
||||
inline void HeightField::updateTransform(float interpolationFactor) {
|
||||
mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix);
|
||||
}
|
||||
|
||||
#endif
|
171
testbed/scenes/heightfield/HeightFieldScene.cpp
Normal file
171
testbed/scenes/heightfield/HeightFieldScene.cpp
Normal file
|
@ -0,0 +1,171 @@
|
|||
|
||||
/********************************************************************************
|
||||
* 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 "HeightFieldScene.h"
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
using namespace heightfieldscene;
|
||||
|
||||
// Constructor
|
||||
HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SCENE_RADIUS) {
|
||||
|
||||
// Compute the radius and the center of the scene
|
||||
openglframework::Vector3 center(0, 5, 0);
|
||||
|
||||
// Set the center of the scene
|
||||
setScenePosition(center, SCENE_RADIUS);
|
||||
|
||||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mDynamicsWorld = new rp3d::DynamicsWorld(gravity);
|
||||
|
||||
// Set the number of iterations of the constraint solver
|
||||
mDynamicsWorld->setNbIterationsVelocitySolver(15);
|
||||
|
||||
// ---------- Create the cube ----------- //
|
||||
|
||||
// Position
|
||||
rp3d::decimal radius = 2.0;
|
||||
openglframework::Vector3 spherePos(15, 10, 0);
|
||||
|
||||
// Create a sphere and a corresponding rigid in the dynamics world
|
||||
mBox = new Box(Vector3(3, 3, 3), spherePos, 80.1, mDynamicsWorld);
|
||||
|
||||
// Set the sphere color
|
||||
mBox->setColor(mDemoColors[1]);
|
||||
mBox->setSleepingColor(mRedColorDemo);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& sphereMat = mBox->getRigidBody()->getMaterial();
|
||||
sphereMat.setBounciness(rp3d::decimal(0.2));
|
||||
|
||||
// ---------- Create the height field ---------- //
|
||||
|
||||
// Position
|
||||
openglframework::Vector3 position(0, 0, 0);
|
||||
rp3d::decimal mass = 1.0;
|
||||
|
||||
// Create a convex mesh and a corresponding rigid in the dynamics world
|
||||
mHeightField = new HeightField(position, mass, mDynamicsWorld);
|
||||
|
||||
// Set the mesh as beeing static
|
||||
mHeightField->getRigidBody()->setType(rp3d::STATIC);
|
||||
|
||||
// Set the color
|
||||
mHeightField->setColor(mDemoColors[0]);
|
||||
mHeightField->setSleepingColor(mRedColorDemo);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material = mHeightField->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.2));
|
||||
material.setFrictionCoefficient(0.1);
|
||||
|
||||
// Get the physics engine parameters
|
||||
mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled();
|
||||
rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity();
|
||||
mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z);
|
||||
mEngineSettings.isSleepingEnabled = mDynamicsWorld->isSleepingEnabled();
|
||||
mEngineSettings.sleepLinearVelocity = mDynamicsWorld->getSleepLinearVelocity();
|
||||
mEngineSettings.sleepAngularVelocity = mDynamicsWorld->getSleepAngularVelocity();
|
||||
mEngineSettings.nbPositionSolverIterations = mDynamicsWorld->getNbIterationsPositionSolver();
|
||||
mEngineSettings.nbVelocitySolverIterations = mDynamicsWorld->getNbIterationsVelocitySolver();
|
||||
mEngineSettings.timeBeforeSleep = mDynamicsWorld->getTimeBeforeSleep();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
HeightFieldScene::~HeightFieldScene() {
|
||||
|
||||
mDynamicsWorld->destroyRigidBody(mBox->getRigidBody());
|
||||
// Destroy the corresponding rigid body from the dynamics world
|
||||
mDynamicsWorld->destroyRigidBody(mHeightField->getRigidBody());
|
||||
|
||||
delete mBox;
|
||||
|
||||
// Destroy the convex mesh
|
||||
delete mHeightField;
|
||||
|
||||
// Destroy the dynamics world
|
||||
delete mDynamicsWorld;
|
||||
}
|
||||
|
||||
// Update the physics world (take a simulation step)
|
||||
void HeightFieldScene::updatePhysics() {
|
||||
|
||||
// Update the physics engine parameters
|
||||
mDynamicsWorld->setIsGratityEnabled(mEngineSettings.isGravityEnabled);
|
||||
rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y,
|
||||
mEngineSettings.gravity.z);
|
||||
mDynamicsWorld->setGravity(gravity);
|
||||
mDynamicsWorld->enableSleeping(mEngineSettings.isSleepingEnabled);
|
||||
mDynamicsWorld->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity);
|
||||
mDynamicsWorld->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity);
|
||||
mDynamicsWorld->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations);
|
||||
mDynamicsWorld->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations);
|
||||
mDynamicsWorld->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep);
|
||||
|
||||
// Take a simulation step
|
||||
mDynamicsWorld->update(mEngineSettings.timeStep);
|
||||
}
|
||||
|
||||
// Update the scene
|
||||
void HeightFieldScene::update() {
|
||||
|
||||
SceneDemo::update();
|
||||
|
||||
// Update the transform used for the rendering
|
||||
mHeightField->updateTransform(mInterpolationFactor);
|
||||
mBox->updateTransform(mInterpolationFactor);
|
||||
}
|
||||
|
||||
// Render the scene in a single pass
|
||||
void HeightFieldScene::renderSinglePass(Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
|
||||
|
||||
// Bind the shader
|
||||
shader.bind();
|
||||
|
||||
mHeightField->render(shader, worldToCameraMatrix);
|
||||
mBox->render(shader, worldToCameraMatrix);
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Reset the scene
|
||||
void HeightFieldScene::reset() {
|
||||
|
||||
// Reset the transform
|
||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(rp3d::Vector3(0, 0, 0), initOrientation);
|
||||
mHeightField->resetTransform(transform);
|
||||
|
||||
rp3d::Vector3 spherePos(2, 15, 0);
|
||||
rp3d::Transform sphereTransform(spherePos, initOrientation);
|
||||
mBox->resetTransform(sphereTransform);
|
||||
}
|
91
testbed/scenes/heightfield/HeightFieldScene.h
Normal file
91
testbed/scenes/heightfield/HeightFieldScene.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/********************************************************************************
|
||||
* 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 HEIGHT_FIELD_SCENE_H
|
||||
#define HEIGHT_FIELD_SCENE_H
|
||||
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
#include "Box.h"
|
||||
#include "SceneDemo.h"
|
||||
#include "HeightField.h"
|
||||
|
||||
namespace heightfieldscene {
|
||||
|
||||
// Constants
|
||||
const float SCENE_RADIUS = 30.0f;
|
||||
|
||||
// Class HeightFieldScene
|
||||
class HeightFieldScene : public SceneDemo {
|
||||
|
||||
protected :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
Box* mBox;
|
||||
|
||||
/// Height field
|
||||
HeightField* mHeightField;
|
||||
|
||||
/// Dynamics world used for the physics simulation
|
||||
rp3d::DynamicsWorld* mDynamicsWorld;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
HeightFieldScene(const std::string& name);
|
||||
|
||||
/// Destructor
|
||||
virtual ~HeightFieldScene();
|
||||
|
||||
/// 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();
|
||||
|
||||
/// Render the scene in a single pass
|
||||
virtual void renderSinglePass(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
||||
/// Reset the scene
|
||||
virtual void reset();
|
||||
|
||||
/// Return all the contact points of the scene
|
||||
virtual std::vector<ContactPoint> getContactPoints() const;
|
||||
};
|
||||
|
||||
// Return all the contact points of the scene
|
||||
inline std::vector<ContactPoint> HeightFieldScene::getContactPoints() const {
|
||||
return computeContactPointsOfWorld(mDynamicsWorld);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -32,6 +32,7 @@
|
|||
#include "cubes/CubesScene.h"
|
||||
#include "joints/JointsScene.h"
|
||||
#include "collisionshapes/CollisionShapesScene.h"
|
||||
#include "heightfield/HeightFieldScene.h"
|
||||
#include "raycast/RaycastScene.h"
|
||||
#include "concavemesh/ConcaveMeshScene.h"
|
||||
|
||||
|
@ -41,6 +42,7 @@ using namespace cubesscene;
|
|||
using namespace raycastscene;
|
||||
using namespace collisionshapesscene;
|
||||
using namespace trianglemeshscene;
|
||||
using namespace heightfieldscene;
|
||||
|
||||
// Initialization of static variables
|
||||
const float TestbedApplication::SCROLL_SENSITIVITY = 0.02f;
|
||||
|
@ -164,6 +166,10 @@ void TestbedApplication::createScenes() {
|
|||
CollisionShapesScene* collisionShapesScene = new CollisionShapesScene("Collision Shapes");
|
||||
mScenes.push_back(collisionShapesScene);
|
||||
|
||||
// Heightfield shape scene
|
||||
HeightFieldScene* heightFieldScene = new HeightFieldScene("Heightfield");
|
||||
mScenes.push_back(heightFieldScene);
|
||||
|
||||
// Raycast scene
|
||||
RaycastScene* raycastScene = new RaycastScene("Raycast");
|
||||
mScenes.push_back(raycastScene);
|
||||
|
|
Loading…
Reference in New Issue
Block a user