Merge branch 'testbed' into develop
This commit is contained in:
commit
8a26d8a0ca
|
@ -18,7 +18,7 @@ SET(OUR_EXECUTABLE_OUTPUT_PATH "${PROJECT_BINARY_DIR}/bin")
|
||||||
ENABLE_TESTING()
|
ENABLE_TESTING()
|
||||||
|
|
||||||
# Options
|
# Options
|
||||||
OPTION(COMPILE_EXAMPLES "Select this if you want to build the examples" OFF)
|
OPTION(COMPILE_TESTBED "Select this if you want to build the testbed application" OFF)
|
||||||
OPTION(COMPILE_TESTS "Select this if you want to build the tests" OFF)
|
OPTION(COMPILE_TESTS "Select this if you want to build the tests" OFF)
|
||||||
OPTION(PROFILING_ENABLED "Select this if you want to compile with enabled profiling" OFF)
|
OPTION(PROFILING_ENABLED "Select this if you want to compile with enabled profiling" OFF)
|
||||||
OPTION(DOUBLE_PRECISION_ENABLED "Select this if you want to compile using double precision floating
|
OPTION(DOUBLE_PRECISION_ENABLED "Select this if you want to compile using double precision floating
|
||||||
|
@ -142,10 +142,10 @@ SET (REACTPHYSICS3D_SOURCES
|
||||||
# Create the library
|
# Create the library
|
||||||
ADD_LIBRARY (reactphysics3d STATIC ${REACTPHYSICS3D_SOURCES})
|
ADD_LIBRARY (reactphysics3d STATIC ${REACTPHYSICS3D_SOURCES})
|
||||||
|
|
||||||
# If we need to compile the examples
|
# If we need to compile the testbed application
|
||||||
IF(COMPILE_EXAMPLES)
|
IF(COMPILE_TESTBED)
|
||||||
add_subdirectory(examples/)
|
add_subdirectory(testbed/)
|
||||||
ENDIF(COMPILE_EXAMPLES)
|
ENDIF(COMPILE_TESTBED)
|
||||||
|
|
||||||
# If we need to compile the tests
|
# If we need to compile the tests
|
||||||
IF(COMPILE_TESTS)
|
IF(COMPILE_TESTS)
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
# Minimum cmake version required
|
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
|
||||||
|
|
||||||
# Set a variable for the directory of the opengl-framework
|
|
||||||
SET(OPENGLFRAMEWORK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/common/opengl-framework")
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(common/)
|
|
||||||
ADD_SUBDIRECTORY(cubes/)
|
|
||||||
ADD_SUBDIRECTORY(joints/)
|
|
||||||
ADD_SUBDIRECTORY(collisionshapes/)
|
|
||||||
ADD_SUBDIRECTORY(raycast/)
|
|
|
@ -1,42 +0,0 @@
|
||||||
# Minimum cmake version required
|
|
||||||
cmake_minimum_required(VERSION 2.6)
|
|
||||||
|
|
||||||
# Project configuration
|
|
||||||
PROJECT(CollisionShapes)
|
|
||||||
|
|
||||||
# Where to build the executables
|
|
||||||
SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/collisionshapes")
|
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
|
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH})
|
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH})
|
|
||||||
|
|
||||||
# Copy the shaders used for the demo into the build directory
|
|
||||||
FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/")
|
|
||||||
|
|
||||||
# Copy the meshes used for the demo into the build directory
|
|
||||||
FILE(COPY "../common/meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/")
|
|
||||||
|
|
||||||
# Headers
|
|
||||||
INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/")
|
|
||||||
|
|
||||||
# Source files
|
|
||||||
SET(COLLISION_SHAPES_SOURCES
|
|
||||||
CollisionShapes.cpp
|
|
||||||
Scene.cpp
|
|
||||||
Scene.h
|
|
||||||
"../common/VisualContactPoint.cpp"
|
|
||||||
"../common/ConvexMesh.cpp"
|
|
||||||
"../common/Capsule.cpp"
|
|
||||||
"../common/Sphere.cpp"
|
|
||||||
"../common/Cylinder.cpp"
|
|
||||||
"../common/Cone.cpp"
|
|
||||||
"../common/Dumbbell.cpp"
|
|
||||||
"../common/Box.cpp"
|
|
||||||
"../common/Viewer.cpp"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create the executable
|
|
||||||
ADD_EXECUTABLE(collisionshapes ${COLLISION_SHAPES_SOURCES})
|
|
||||||
|
|
||||||
# Link with libraries
|
|
||||||
TARGET_LINK_LIBRARIES(collisionshapes reactphysics3d openglframework glfw ${GLFW_LIBRARIES})
|
|
|
@ -1,152 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* 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 "Scene.h"
|
|
||||||
#include "../common/Viewer.h"
|
|
||||||
|
|
||||||
// Declarations
|
|
||||||
void simulate();
|
|
||||||
void render();
|
|
||||||
void update();
|
|
||||||
void mouseButton(GLFWwindow* window, int button, int action, int mods);
|
|
||||||
void mouseMotion(GLFWwindow* window, double x, double y);
|
|
||||||
void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods);
|
|
||||||
void scroll(GLFWwindow* window, double xAxis, double yAxis);
|
|
||||||
void init();
|
|
||||||
|
|
||||||
// Namespaces
|
|
||||||
using namespace openglframework;
|
|
||||||
|
|
||||||
// Global variables
|
|
||||||
Viewer* viewer;
|
|
||||||
Scene* scene;
|
|
||||||
|
|
||||||
// Main function
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
|
|
||||||
// Create and initialize the Viewer
|
|
||||||
viewer = new Viewer();
|
|
||||||
Vector2 windowsSize = Vector2(800, 600);
|
|
||||||
Vector2 windowsPosition = Vector2(100, 100);
|
|
||||||
viewer->init(argc, argv, "ReactPhysics3D Examples - Collision Shapes",
|
|
||||||
windowsSize, windowsPosition, true);
|
|
||||||
|
|
||||||
// If the shaders and meshes folders are not specified as an argument
|
|
||||||
if (argc < 3) {
|
|
||||||
std::cerr << "Error : You need to specify the shaders folder as the first argument"
|
|
||||||
<< " and the meshes folder as the second argument" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the path of the shaders folder
|
|
||||||
std::string shaderFolderPath(argv[1]);
|
|
||||||
std::string meshFolderPath(argv[2]);
|
|
||||||
|
|
||||||
// Register callback methods
|
|
||||||
viewer->registerUpdateFunction(update);
|
|
||||||
viewer->registerKeyboardCallback(keyboard);
|
|
||||||
viewer->registerMouseButtonCallback(mouseButton);
|
|
||||||
viewer->registerMouseCursorCallback(mouseMotion);
|
|
||||||
viewer->registerScrollingCallback(scroll);
|
|
||||||
|
|
||||||
// Create the scene
|
|
||||||
scene = new Scene(viewer, shaderFolderPath, meshFolderPath);
|
|
||||||
|
|
||||||
init();
|
|
||||||
|
|
||||||
viewer->startMainLoop();
|
|
||||||
|
|
||||||
delete viewer;
|
|
||||||
delete scene;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update function that is called each frame
|
|
||||||
void update() {
|
|
||||||
|
|
||||||
// Take a simulation step
|
|
||||||
simulate();
|
|
||||||
|
|
||||||
// Render
|
|
||||||
render();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simulate function
|
|
||||||
void simulate() {
|
|
||||||
|
|
||||||
// Physics simulation
|
|
||||||
scene->simulate();
|
|
||||||
|
|
||||||
viewer->computeFPS();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialization
|
|
||||||
void init() {
|
|
||||||
|
|
||||||
// Define the background color (black)
|
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback method to receive keyboard events
|
|
||||||
void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
|
||||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
|
||||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
|
||||||
}
|
|
||||||
else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) {
|
|
||||||
scene->pauseContinueSimulation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback method to receive scrolling events
|
|
||||||
void scroll(GLFWwindow* window, double xAxis, double yAxis) {
|
|
||||||
viewer->scrollingEvent(static_cast<float>(yAxis));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when a mouse button event occurs
|
|
||||||
void mouseButton(GLFWwindow* window, int button, int action, int mods) {
|
|
||||||
viewer->mouseButtonEvent(button, action);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when a mouse motion event occurs
|
|
||||||
void mouseMotion(GLFWwindow* window, double x, double y) {
|
|
||||||
viewer->mouseMotionEvent(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display the scene
|
|
||||||
void render() {
|
|
||||||
|
|
||||||
// Render the scene
|
|
||||||
scene->render();
|
|
||||||
|
|
||||||
// Display the FPS
|
|
||||||
viewer->displayGUI();
|
|
||||||
|
|
||||||
// Check the OpenGL errors
|
|
||||||
Viewer::checkOpenGLErrors();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
# Minimum cmake version required
|
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(opengl-framework/)
|
|
||||||
ADD_SUBDIRECTORY(glfw/)
|
|
|
@ -1,115 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* 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 "VisualContactPoint.h"
|
|
||||||
|
|
||||||
// Initialization of static variables
|
|
||||||
int VisualContactPoint::mNbTotalPoints = 0;
|
|
||||||
bool VisualContactPoint::mIsMeshInitialized = false;
|
|
||||||
openglframework::Mesh VisualContactPoint::mMesh;
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position) {
|
|
||||||
|
|
||||||
assert(mIsMeshInitialized);
|
|
||||||
|
|
||||||
// Initialize the position where the sphere will be rendered
|
|
||||||
translateWorld(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
VisualContactPoint::~VisualContactPoint() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load and initialize the mesh for all the contact points
|
|
||||||
void VisualContactPoint::createStaticData(const std::string& meshFolderPath) {
|
|
||||||
|
|
||||||
if (!mIsMeshInitialized) {
|
|
||||||
|
|
||||||
// Load the mesh from a file
|
|
||||||
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", mMesh);
|
|
||||||
|
|
||||||
// Calculate the normals of the mesh
|
|
||||||
mMesh.calculateNormals();
|
|
||||||
|
|
||||||
mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS);
|
|
||||||
|
|
||||||
mIsMeshInitialized = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroy the mesh for the contact points
|
|
||||||
void VisualContactPoint::destroyStaticData() {
|
|
||||||
|
|
||||||
mMesh.destroy();
|
|
||||||
mIsMeshInitialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render the sphere at the correct position and with the correct orientation
|
|
||||||
void VisualContactPoint::render(openglframework::Shader& shader,
|
|
||||||
const openglframework::Matrix4& worldToCameraMatrix) {
|
|
||||||
|
|
||||||
// Bind the shader
|
|
||||||
shader.bind();
|
|
||||||
|
|
||||||
// Set the model to camera matrix
|
|
||||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
|
||||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
|
||||||
|
|
||||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
|
||||||
// model-view matrix)
|
|
||||||
const openglframework::Matrix3 normalMatrix =
|
|
||||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
|
||||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
|
||||||
if (mMesh.hasTexture()) {
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
glVertexPointer(3, GL_FLOAT, 0, mMesh.getVerticesPointer());
|
|
||||||
glNormalPointer(GL_FLOAT, 0, mMesh.getNormalsPointer());
|
|
||||||
if(mMesh.hasTexture()) {
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, mMesh.getUVTextureCoordinatesPointer());
|
|
||||||
}
|
|
||||||
|
|
||||||
// For each part of the mesh
|
|
||||||
for (unsigned int i=0; i<mMesh.getNbParts(); i++) {
|
|
||||||
glDrawElements(GL_TRIANGLES, mMesh.getNbFaces(i) * 3,
|
|
||||||
GL_UNSIGNED_INT, mMesh.getIndicesPointer());
|
|
||||||
}
|
|
||||||
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
if (mMesh.hasTexture()) {
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unbind the shader
|
|
||||||
shader.unbind();
|
|
||||||
}
|
|
|
@ -1,100 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* OpenGL-Framework *
|
|
||||||
* Copyright (c) 2013 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 "Light.h"
|
|
||||||
|
|
||||||
// Namespaces
|
|
||||||
using namespace openglframework;
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
Light::Light(GLuint id)
|
|
||||||
: mLightID(id), mDiffuseColor(Color::white()),
|
|
||||||
mSpecularColor(Color::white()), mIsActive(false) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
Light::Light(GLuint id, Color diffuseColor, Color specularColor)
|
|
||||||
: mLightID(id), mDiffuseColor(diffuseColor),
|
|
||||||
mSpecularColor(specularColor), mIsActive(false) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
Light::~Light() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the light
|
|
||||||
void Light::init() {
|
|
||||||
|
|
||||||
// Enable the light
|
|
||||||
enable();
|
|
||||||
|
|
||||||
// Set the diffuse and specular color
|
|
||||||
GLfloat diffuseColor[] = {mDiffuseColor.r, mDiffuseColor.g, mDiffuseColor.b, mDiffuseColor.a};
|
|
||||||
GLfloat specularColor[] = {mSpecularColor.r,mSpecularColor.g,mSpecularColor.b,mSpecularColor.a};
|
|
||||||
glLightfv(mLightID, GL_DIFFUSE, diffuseColor);
|
|
||||||
glLightfv(mLightID, GL_SPECULAR, specularColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a shadow map associated with this light
|
|
||||||
bool Light::createShadowMap(uint width, uint height) {
|
|
||||||
|
|
||||||
// Destroy the current shadow map
|
|
||||||
destroyShadowMap();
|
|
||||||
|
|
||||||
// Create the Framebuffer object to render the shadow map
|
|
||||||
bool isFBOCreated = mFBOShadowMap.create(width, height, false);
|
|
||||||
if (!isFBOCreated) {
|
|
||||||
std::cerr << "Error : Cannot create the Shadow Map !" << std::endl;
|
|
||||||
destroyShadowMap();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind the Framebuffer object
|
|
||||||
mFBOShadowMap.bind(GL_NONE);
|
|
||||||
|
|
||||||
// Create the shadow map depth texture
|
|
||||||
mShadowMap.create(width, height, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE);
|
|
||||||
|
|
||||||
// Attache the shadow map texture to the Framebuffer object
|
|
||||||
mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT_EXT, mShadowMap.getID());
|
|
||||||
|
|
||||||
// Unbind the Framebuffer object
|
|
||||||
mFBOShadowMap.unbind();
|
|
||||||
|
|
||||||
// TODO : Change the path of the shader here so that it does not depend on the build folder
|
|
||||||
bool isShaderCreated = mDepthShader.create("../../opengl-framework/src/shaders/depth.vert",
|
|
||||||
"../../opengl-framework/src/shaders/depth.vert");
|
|
||||||
if (!isShaderCreated) {
|
|
||||||
std::cerr << "Error : Cannot create the Shadow Map !" << std::endl;
|
|
||||||
destroyShadowMap();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
# Minimum cmake version required
|
|
||||||
cmake_minimum_required(VERSION 2.6)
|
|
||||||
|
|
||||||
# Project configuration
|
|
||||||
PROJECT(Cubes)
|
|
||||||
|
|
||||||
# Where to build the executables
|
|
||||||
SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/cubes")
|
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
|
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH})
|
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH})
|
|
||||||
|
|
||||||
# Copy the shaders used for the demo into the build directory
|
|
||||||
FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/")
|
|
||||||
|
|
||||||
# Headers
|
|
||||||
INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/")
|
|
||||||
|
|
||||||
# Source files
|
|
||||||
SET(CUBES_SOURCES
|
|
||||||
Cubes.cpp
|
|
||||||
Scene.cpp
|
|
||||||
Scene.h
|
|
||||||
"../common/Box.cpp"
|
|
||||||
"../common/Box.h"
|
|
||||||
"../common/Viewer.cpp"
|
|
||||||
"../common/Viewer.h"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create the executable
|
|
||||||
ADD_EXECUTABLE(cubes ${CUBES_SOURCES})
|
|
||||||
|
|
||||||
# Link with libraries
|
|
||||||
TARGET_LINK_LIBRARIES(cubes reactphysics3d openglframework glfw ${GLFW_LIBRARIES})
|
|
|
@ -1,148 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* 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 "Scene.h"
|
|
||||||
#include "Viewer.h"
|
|
||||||
|
|
||||||
// Declarations
|
|
||||||
void simulate();
|
|
||||||
void render();
|
|
||||||
void update();
|
|
||||||
void mouseButton(GLFWwindow* window, int button, int action, int mods);
|
|
||||||
void mouseMotion(GLFWwindow* window, double x, double y);
|
|
||||||
void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods);
|
|
||||||
void scroll(GLFWwindow* window, double xAxis, double yAxis);
|
|
||||||
void init();
|
|
||||||
|
|
||||||
// Namespaces
|
|
||||||
using namespace openglframework;
|
|
||||||
|
|
||||||
// Global variables
|
|
||||||
Viewer* viewer;
|
|
||||||
Scene* scene;
|
|
||||||
|
|
||||||
// Main function
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
|
|
||||||
// Create and initialize the Viewer
|
|
||||||
viewer = new Viewer();
|
|
||||||
Vector2 windowsSize = Vector2(800, 600);
|
|
||||||
Vector2 windowsPosition = Vector2(100, 100);
|
|
||||||
viewer->init(argc, argv, "ReactPhysics3D Examples - Cubes", windowsSize, windowsPosition, true);
|
|
||||||
|
|
||||||
// If the shaders folder is not specified as an argument
|
|
||||||
if (argc < 2) {
|
|
||||||
std::cerr << "Error : You need to specify the shaders folder as argument !" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the path of the shaders folder
|
|
||||||
std::string shaderFolderPath(argv[1]);
|
|
||||||
|
|
||||||
// Register callback methods
|
|
||||||
viewer->registerUpdateFunction(update);
|
|
||||||
viewer->registerKeyboardCallback(keyboard);
|
|
||||||
viewer->registerMouseButtonCallback(mouseButton);
|
|
||||||
viewer->registerMouseCursorCallback(mouseMotion);
|
|
||||||
viewer->registerScrollingCallback(scroll);
|
|
||||||
|
|
||||||
// Create the scene
|
|
||||||
scene = new Scene(viewer, shaderFolderPath);
|
|
||||||
|
|
||||||
init();
|
|
||||||
|
|
||||||
viewer->startMainLoop();
|
|
||||||
|
|
||||||
delete viewer;
|
|
||||||
delete scene;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update function that is called each frame
|
|
||||||
void update() {
|
|
||||||
|
|
||||||
// Take a simulation step
|
|
||||||
simulate();
|
|
||||||
|
|
||||||
// Render
|
|
||||||
render();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simulate function
|
|
||||||
void simulate() {
|
|
||||||
|
|
||||||
// Physics simulation
|
|
||||||
scene->simulate();
|
|
||||||
|
|
||||||
// Compute the current framerate
|
|
||||||
viewer->computeFPS();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialization
|
|
||||||
void init() {
|
|
||||||
|
|
||||||
// Define the background color (black)
|
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback method to receive keyboard events
|
|
||||||
void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
|
||||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
|
||||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
|
||||||
}
|
|
||||||
else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) {
|
|
||||||
scene->pauseContinueSimulation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback method to receive scrolling events
|
|
||||||
void scroll(GLFWwindow* window, double xAxis, double yAxis) {
|
|
||||||
viewer->scrollingEvent(static_cast<float>(yAxis));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when a mouse button event occurs
|
|
||||||
void mouseButton(GLFWwindow* window, int button, int action, int mods) {
|
|
||||||
viewer->mouseButtonEvent(button, action);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when a mouse motion event occurs
|
|
||||||
void mouseMotion(GLFWwindow* window, double x, double y) {
|
|
||||||
viewer->mouseMotionEvent(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display the scene
|
|
||||||
void render() {
|
|
||||||
|
|
||||||
// Render the scene
|
|
||||||
scene->render();
|
|
||||||
|
|
||||||
// Display the FPS
|
|
||||||
viewer->displayGUI();
|
|
||||||
|
|
||||||
// Check the OpenGL errors
|
|
||||||
Viewer::checkOpenGLErrors();
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
# Minimum cmake version required
|
|
||||||
cmake_minimum_required(VERSION 2.6)
|
|
||||||
|
|
||||||
# Project configuration
|
|
||||||
PROJECT(Joints)
|
|
||||||
|
|
||||||
# Where to build the executables
|
|
||||||
SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/joints")
|
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
|
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH})
|
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH})
|
|
||||||
|
|
||||||
# Copy the shaders used for the demo into the build directory
|
|
||||||
FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/")
|
|
||||||
|
|
||||||
# Headers
|
|
||||||
INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/")
|
|
||||||
|
|
||||||
# Source files
|
|
||||||
SET(JOINTS_SOURCES
|
|
||||||
Joints.cpp
|
|
||||||
Scene.cpp
|
|
||||||
Scene.h
|
|
||||||
"../common/Box.cpp"
|
|
||||||
"../common/Box.h"
|
|
||||||
"../common/Viewer.cpp"
|
|
||||||
"../common/Viewer.h"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create the executable
|
|
||||||
ADD_EXECUTABLE(joints ${JOINTS_SOURCES})
|
|
||||||
|
|
||||||
# Link with libraries
|
|
||||||
TARGET_LINK_LIBRARIES(joints reactphysics3d openglframework glfw ${GLFW_LIBRARIES})
|
|
|
@ -1,149 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* 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 "Scene.h"
|
|
||||||
#include "../common/Viewer.h"
|
|
||||||
|
|
||||||
// Declarations
|
|
||||||
void simulate();
|
|
||||||
void update();
|
|
||||||
void render();
|
|
||||||
void mouseButton(GLFWwindow* window, int button, int action, int mods);
|
|
||||||
void mouseMotion(GLFWwindow* window, double x, double y);
|
|
||||||
void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods);
|
|
||||||
void scroll(GLFWwindow* window, double xAxis, double yAxis);
|
|
||||||
void init();
|
|
||||||
|
|
||||||
// Namespaces
|
|
||||||
using namespace openglframework;
|
|
||||||
|
|
||||||
// Global variables
|
|
||||||
Viewer* viewer;
|
|
||||||
Scene* scene;
|
|
||||||
|
|
||||||
// Main function
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
|
|
||||||
// Create and initialize the Viewer
|
|
||||||
viewer = new Viewer();
|
|
||||||
Vector2 windowsSize = Vector2(800, 600);
|
|
||||||
Vector2 windowsPosition = Vector2(100, 100);
|
|
||||||
viewer->init(argc, argv, "ReactPhysics3D Examples - Joints", windowsSize, windowsPosition, true);
|
|
||||||
|
|
||||||
// If the shaders folder is not specified as an argument
|
|
||||||
if (argc < 2) {
|
|
||||||
std::cerr << "Error : You need to specify the shaders folder as argument !" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the path of the shaders folder
|
|
||||||
std::string shaderFolderPath(argv[1]);
|
|
||||||
|
|
||||||
// Register callback methods
|
|
||||||
viewer->registerUpdateFunction(update);
|
|
||||||
viewer->registerKeyboardCallback(keyboard);
|
|
||||||
viewer->registerMouseButtonCallback(mouseButton);
|
|
||||||
viewer->registerMouseCursorCallback(mouseMotion);
|
|
||||||
viewer->registerScrollingCallback(scroll);
|
|
||||||
|
|
||||||
// Create the scene
|
|
||||||
scene = new Scene(viewer, shaderFolderPath);
|
|
||||||
|
|
||||||
init();
|
|
||||||
|
|
||||||
viewer->startMainLoop();
|
|
||||||
|
|
||||||
delete viewer;
|
|
||||||
delete scene;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update function that is called each frame
|
|
||||||
void update() {
|
|
||||||
|
|
||||||
// Take a simulation step
|
|
||||||
simulate();
|
|
||||||
|
|
||||||
// Render
|
|
||||||
render();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simulate function
|
|
||||||
void simulate() {
|
|
||||||
|
|
||||||
// Physics simulation
|
|
||||||
scene->simulate();
|
|
||||||
|
|
||||||
viewer->computeFPS();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialization
|
|
||||||
void init() {
|
|
||||||
|
|
||||||
// Define the background color (black)
|
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback method to receive keyboard events
|
|
||||||
void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
|
||||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
|
||||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
|
||||||
}
|
|
||||||
else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) {
|
|
||||||
scene->pauseContinueSimulation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback method to receive scrolling events
|
|
||||||
void scroll(GLFWwindow* window, double xAxis, double yAxis) {
|
|
||||||
viewer->scrollingEvent(static_cast<float>(yAxis));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when a mouse button event occurs
|
|
||||||
void mouseButton(GLFWwindow* window, int button, int action, int mods) {
|
|
||||||
viewer->mouseButtonEvent(button, action);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when a mouse motion event occurs
|
|
||||||
void mouseMotion(GLFWwindow* window, double x, double y) {
|
|
||||||
viewer->mouseMotionEvent(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display the scene
|
|
||||||
void render() {
|
|
||||||
|
|
||||||
// Render the scene
|
|
||||||
scene->render();
|
|
||||||
|
|
||||||
// Display the FPS
|
|
||||||
viewer->displayGUI();
|
|
||||||
|
|
||||||
// Check the OpenGL errors
|
|
||||||
Viewer::checkOpenGLErrors();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
# Minimum cmake version required
|
|
||||||
cmake_minimum_required(VERSION 2.6)
|
|
||||||
|
|
||||||
# Project configuration
|
|
||||||
PROJECT(Raycast)
|
|
||||||
|
|
||||||
# Where to build the executables
|
|
||||||
SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/raycast")
|
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
|
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH})
|
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH})
|
|
||||||
|
|
||||||
# Copy the shaders used for the demo into the build directory
|
|
||||||
FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/")
|
|
||||||
|
|
||||||
# Copy the meshes used for the demo into the build directory
|
|
||||||
FILE(COPY "../common/meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/")
|
|
||||||
|
|
||||||
# Headers
|
|
||||||
INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/")
|
|
||||||
|
|
||||||
# Source files
|
|
||||||
SET(RAYCAST_SOURCES
|
|
||||||
Raycast.cpp
|
|
||||||
Scene.cpp
|
|
||||||
Scene.h
|
|
||||||
"../common/VisualContactPoint.cpp"
|
|
||||||
"../common/ConvexMesh.cpp"
|
|
||||||
"../common/Capsule.cpp"
|
|
||||||
"../common/Sphere.cpp"
|
|
||||||
"../common/Line.cpp"
|
|
||||||
"../common/Cylinder.cpp"
|
|
||||||
"../common/Cone.cpp"
|
|
||||||
"../common/Dumbbell.cpp"
|
|
||||||
"../common/Box.cpp"
|
|
||||||
"../common/Viewer.cpp"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create the executable
|
|
||||||
ADD_EXECUTABLE(raycast ${RAYCAST_SOURCES})
|
|
||||||
|
|
||||||
# Link with libraries
|
|
||||||
TARGET_LINK_LIBRARIES(raycast reactphysics3d openglframework glfw ${GLFW_LIBRARIES})
|
|
|
@ -1,155 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* 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 "Scene.h"
|
|
||||||
#include "../common/Viewer.h"
|
|
||||||
|
|
||||||
// Declarations
|
|
||||||
void simulate();
|
|
||||||
void render();
|
|
||||||
void update();
|
|
||||||
void mouseButton(GLFWwindow* window, int button, int action, int mods);
|
|
||||||
void mouseMotion(GLFWwindow* window, double x, double y);
|
|
||||||
void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods);
|
|
||||||
void scroll(GLFWwindow* window, double xAxis, double yAxis);
|
|
||||||
void init();
|
|
||||||
|
|
||||||
// Namespaces
|
|
||||||
using namespace openglframework;
|
|
||||||
|
|
||||||
// Global variables
|
|
||||||
Viewer* viewer;
|
|
||||||
Scene* scene;
|
|
||||||
|
|
||||||
// Main function
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
|
|
||||||
// Create and initialize the Viewer
|
|
||||||
viewer = new Viewer();
|
|
||||||
Vector2 windowsSize = Vector2(800, 600);
|
|
||||||
Vector2 windowsPosition = Vector2(100, 100);
|
|
||||||
viewer->init(argc, argv, "ReactPhysics3D Examples - Raycast",
|
|
||||||
windowsSize, windowsPosition, true);
|
|
||||||
|
|
||||||
// If the shaders and meshes folders are not specified as an argument
|
|
||||||
if (argc < 3) {
|
|
||||||
std::cerr << "Error : You need to specify the shaders folder as the first argument"
|
|
||||||
<< " and the meshes folder as the second argument" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the path of the shaders folder
|
|
||||||
std::string shaderFolderPath(argv[1]);
|
|
||||||
std::string meshFolderPath(argv[2]);
|
|
||||||
|
|
||||||
// Register callback methods
|
|
||||||
viewer->registerUpdateFunction(update);
|
|
||||||
viewer->registerKeyboardCallback(keyboard);
|
|
||||||
viewer->registerMouseButtonCallback(mouseButton);
|
|
||||||
viewer->registerMouseCursorCallback(mouseMotion);
|
|
||||||
viewer->registerScrollingCallback(scroll);
|
|
||||||
|
|
||||||
// Create the scene
|
|
||||||
scene = new Scene(viewer, shaderFolderPath, meshFolderPath);
|
|
||||||
|
|
||||||
init();
|
|
||||||
|
|
||||||
viewer->startMainLoop();
|
|
||||||
|
|
||||||
delete viewer;
|
|
||||||
delete scene;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update function that is called each frame
|
|
||||||
void update() {
|
|
||||||
|
|
||||||
// Take a simulation step
|
|
||||||
simulate();
|
|
||||||
|
|
||||||
// Render
|
|
||||||
render();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simulate function
|
|
||||||
void simulate() {
|
|
||||||
|
|
||||||
// Physics simulation
|
|
||||||
scene->simulate();
|
|
||||||
|
|
||||||
viewer->computeFPS();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialization
|
|
||||||
void init() {
|
|
||||||
|
|
||||||
// Define the background color (black)
|
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback method to receive keyboard events
|
|
||||||
void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
|
||||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
|
||||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
|
||||||
}
|
|
||||||
if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) {
|
|
||||||
scene->changeBody();
|
|
||||||
}
|
|
||||||
if (key == GLFW_KEY_N && action == GLFW_PRESS) {
|
|
||||||
scene->showHideNormals();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback method to receive scrolling events
|
|
||||||
void scroll(GLFWwindow* window, double xAxis, double yAxis) {
|
|
||||||
viewer->scrollingEvent(static_cast<float>(yAxis));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when a mouse button event occurs
|
|
||||||
void mouseButton(GLFWwindow* window, int button, int action, int mods) {
|
|
||||||
viewer->mouseButtonEvent(button, action);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when a mouse motion event occurs
|
|
||||||
void mouseMotion(GLFWwindow* window, double x, double y) {
|
|
||||||
viewer->mouseMotionEvent(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display the scene
|
|
||||||
void render() {
|
|
||||||
|
|
||||||
// Render the scene
|
|
||||||
scene->render();
|
|
||||||
|
|
||||||
// Display the FPS
|
|
||||||
viewer->displayGUI();
|
|
||||||
|
|
||||||
// Check the OpenGL errors
|
|
||||||
Viewer::checkOpenGLErrors();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -83,9 +83,6 @@ class Body {
|
||||||
/// Private assignment operator
|
/// Private assignment operator
|
||||||
Body& operator=(const Body& body);
|
Body& operator=(const Body& body);
|
||||||
|
|
||||||
/// Set the variable to know whether or not the body is sleeping
|
|
||||||
virtual void setIsSleeping(bool isSleeping);
|
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
@ -105,6 +102,9 @@ class Body {
|
||||||
/// Set whether or not the body is allowed to go to sleep
|
/// Set whether or not the body is allowed to go to sleep
|
||||||
void setIsAllowedToSleep(bool isAllowedToSleep);
|
void setIsAllowedToSleep(bool isAllowedToSleep);
|
||||||
|
|
||||||
|
/// Set the variable to know whether or not the body is sleeping
|
||||||
|
virtual void setIsSleeping(bool isSleeping);
|
||||||
|
|
||||||
/// Return whether or not the body is sleeping
|
/// Return whether or not the body is sleeping
|
||||||
bool isSleeping() const;
|
bool isSleeping() const;
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,6 @@ CollisionBody::CollisionBody(const Transform& transform, CollisionWorld& world,
|
||||||
: Body(id), mType(DYNAMIC), mTransform(transform), mProxyCollisionShapes(NULL),
|
: Body(id), mType(DYNAMIC), mTransform(transform), mProxyCollisionShapes(NULL),
|
||||||
mNbCollisionShapes(0), mContactManifoldsList(NULL), mWorld(world) {
|
mNbCollisionShapes(0), mContactManifoldsList(NULL), mWorld(world) {
|
||||||
|
|
||||||
// Initialize the old transform
|
|
||||||
mOldTransform = transform;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
|
|
|
@ -73,9 +73,6 @@ class CollisionBody : public Body {
|
||||||
/// Position and orientation of the body
|
/// Position and orientation of the body
|
||||||
Transform mTransform;
|
Transform mTransform;
|
||||||
|
|
||||||
/// Last position and orientation of the body
|
|
||||||
Transform mOldTransform;
|
|
||||||
|
|
||||||
/// First element of the linked list of proxy collision shapes of this body
|
/// First element of the linked list of proxy collision shapes of this body
|
||||||
ProxyShape* mProxyCollisionShapes;
|
ProxyShape* mProxyCollisionShapes;
|
||||||
|
|
||||||
|
@ -102,9 +99,6 @@ class CollisionBody : public Body {
|
||||||
/// Remove all the collision shapes
|
/// Remove all the collision shapes
|
||||||
void removeAllCollisionShapes();
|
void removeAllCollisionShapes();
|
||||||
|
|
||||||
/// Update the old transform with the current one.
|
|
||||||
void updateOldTransform();
|
|
||||||
|
|
||||||
/// Update the broad-phase state for this body (because it has moved for instance)
|
/// Update the broad-phase state for this body (because it has moved for instance)
|
||||||
virtual void updateBroadPhaseState() const;
|
virtual void updateBroadPhaseState() const;
|
||||||
|
|
||||||
|
@ -138,7 +132,7 @@ class CollisionBody : public Body {
|
||||||
const Transform& getTransform() const;
|
const Transform& getTransform() const;
|
||||||
|
|
||||||
/// Set the current position and orientation
|
/// Set the current position and orientation
|
||||||
void setTransform(const Transform& transform);
|
virtual void setTransform(const Transform& transform);
|
||||||
|
|
||||||
/// Add a collision shape to the body.
|
/// Add a collision shape to the body.
|
||||||
virtual ProxyShape* addCollisionShape(const CollisionShape& collisionShape,
|
virtual ProxyShape* addCollisionShape(const CollisionShape& collisionShape,
|
||||||
|
@ -241,12 +235,6 @@ inline void CollisionBody::setTransform(const Transform& transform) {
|
||||||
updateBroadPhaseState();
|
updateBroadPhaseState();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the old transform with the current one.
|
|
||||||
/// This is used to compute the interpolated position and orientation of the body
|
|
||||||
inline void CollisionBody::updateOldTransform() {
|
|
||||||
mOldTransform = mTransform;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the first element of the linked list of contact manifolds involving this body
|
// Return the first element of the linked list of contact manifolds involving this body
|
||||||
/**
|
/**
|
||||||
* @return A pointer to the first element of the linked-list with the contact
|
* @return A pointer to the first element of the linked-list with the contact
|
||||||
|
|
|
@ -265,6 +265,64 @@ void RigidBody::removeCollisionShape(const ProxyShape* proxyShape) {
|
||||||
recomputeMassInformation();
|
recomputeMassInformation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the linear velocity of the rigid body.
|
||||||
|
/**
|
||||||
|
* @param linearVelocity Linear velocity vector of the body
|
||||||
|
*/
|
||||||
|
void RigidBody::setLinearVelocity(const Vector3& linearVelocity) {
|
||||||
|
|
||||||
|
// If it is a static body, we do nothing
|
||||||
|
if (mType == STATIC) return;
|
||||||
|
|
||||||
|
// Update the linear velocity of the current body state
|
||||||
|
mLinearVelocity = linearVelocity;
|
||||||
|
|
||||||
|
// If the linear velocity is not zero, awake the body
|
||||||
|
if (mLinearVelocity.lengthSquare() > decimal(0.0)) {
|
||||||
|
setIsSleeping(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the angular velocity.
|
||||||
|
/**
|
||||||
|
* @param angularVelocity The angular velocity vector of the body
|
||||||
|
*/
|
||||||
|
void RigidBody::setAngularVelocity(const Vector3& angularVelocity) {
|
||||||
|
|
||||||
|
// If it is a static body, we do nothing
|
||||||
|
if (mType == STATIC) return;
|
||||||
|
|
||||||
|
// Set the angular velocity
|
||||||
|
mAngularVelocity = angularVelocity;
|
||||||
|
|
||||||
|
// If the velocity is not zero, awake the body
|
||||||
|
if (mAngularVelocity.lengthSquare() > decimal(0.0)) {
|
||||||
|
setIsSleeping(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the current position and orientation
|
||||||
|
/**
|
||||||
|
* @param transform The transformation of the body that transforms the local-space
|
||||||
|
* of the body into world-space
|
||||||
|
*/
|
||||||
|
void RigidBody::setTransform(const Transform& transform) {
|
||||||
|
|
||||||
|
// Update the transform of the body
|
||||||
|
mTransform = transform;
|
||||||
|
|
||||||
|
const Vector3 oldCenterOfMass = mCenterOfMassWorld;
|
||||||
|
|
||||||
|
// Compute the new center of mass in world-space coordinates
|
||||||
|
mCenterOfMassWorld = mTransform * mCenterOfMassLocal;
|
||||||
|
|
||||||
|
// Update the linear velocity of the center of mass
|
||||||
|
mLinearVelocity += mAngularVelocity.cross(mCenterOfMassWorld - oldCenterOfMass);
|
||||||
|
|
||||||
|
// Update the broad-phase state of the body
|
||||||
|
updateBroadPhaseState();
|
||||||
|
}
|
||||||
|
|
||||||
// Recompute the center of mass, total mass and inertia tensor of the body using all
|
// Recompute the center of mass, total mass and inertia tensor of the body using all
|
||||||
// the collision shapes attached to the body.
|
// the collision shapes attached to the body.
|
||||||
void RigidBody::recomputeMassInformation() {
|
void RigidBody::recomputeMassInformation() {
|
||||||
|
|
|
@ -118,9 +118,6 @@ class RigidBody : public CollisionBody {
|
||||||
/// Update the broad-phase state for this body (because it has moved for instance)
|
/// Update the broad-phase state for this body (because it has moved for instance)
|
||||||
virtual void updateBroadPhaseState() const;
|
virtual void updateBroadPhaseState() const;
|
||||||
|
|
||||||
/// Set the variable to know whether or not the body is sleeping
|
|
||||||
virtual void setIsSleeping(bool isSleeping);
|
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
@ -134,6 +131,9 @@ class RigidBody : public CollisionBody {
|
||||||
/// Set the type of the body (static, kinematic or dynamic)
|
/// Set the type of the body (static, kinematic or dynamic)
|
||||||
void setType(BodyType type);
|
void setType(BodyType type);
|
||||||
|
|
||||||
|
/// Set the current position and orientation
|
||||||
|
virtual void setTransform(const Transform& transform);
|
||||||
|
|
||||||
/// Return the mass of the body
|
/// Return the mass of the body
|
||||||
decimal getMass() const;
|
decimal getMass() const;
|
||||||
|
|
||||||
|
@ -149,6 +149,9 @@ class RigidBody : public CollisionBody {
|
||||||
/// Set the angular velocity.
|
/// Set the angular velocity.
|
||||||
void setAngularVelocity(const Vector3& angularVelocity);
|
void setAngularVelocity(const Vector3& angularVelocity);
|
||||||
|
|
||||||
|
/// Set the variable to know whether or not the body is sleeping
|
||||||
|
virtual void setIsSleeping(bool isSleeping);
|
||||||
|
|
||||||
/// Return the local inertia tensor of the body (in body coordinates)
|
/// Return the local inertia tensor of the body (in body coordinates)
|
||||||
const Matrix3x3& getInertiaTensorLocal() const;
|
const Matrix3x3& getInertiaTensorLocal() const;
|
||||||
|
|
||||||
|
@ -252,20 +255,6 @@ inline Vector3 RigidBody::getAngularVelocity() const {
|
||||||
return mAngularVelocity;
|
return mAngularVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the angular velocity.
|
|
||||||
/// You should only call this method for a kinematic body. Otherwise, it
|
|
||||||
/// will do nothing.
|
|
||||||
/**
|
|
||||||
* @param angularVelocity The angular velocity vector of the body
|
|
||||||
*/
|
|
||||||
inline void RigidBody::setAngularVelocity(const Vector3& angularVelocity) {
|
|
||||||
|
|
||||||
// If it is a kinematic body
|
|
||||||
if (mType == KINEMATIC) {
|
|
||||||
mAngularVelocity = angularVelocity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the local inertia tensor of the body (in local-space coordinates)
|
// Return the local inertia tensor of the body (in local-space coordinates)
|
||||||
/**
|
/**
|
||||||
* @return The 3x3 inertia tensor matrix of the body (in local-space coordinates)
|
* @return The 3x3 inertia tensor matrix of the body (in local-space coordinates)
|
||||||
|
@ -310,22 +299,6 @@ inline Matrix3x3 RigidBody::getInertiaTensorInverseWorld() const {
|
||||||
mTransform.getOrientation().getMatrix().getTranspose();
|
mTransform.getOrientation().getMatrix().getTranspose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the linear velocity of the rigid body.
|
|
||||||
/// You should only call this method for a kinematic body. Otherwise, it
|
|
||||||
/// will do nothing.
|
|
||||||
/**
|
|
||||||
* @param linearVelocity Linear velocity vector of the body
|
|
||||||
*/
|
|
||||||
inline void RigidBody::setLinearVelocity(const Vector3& linearVelocity) {
|
|
||||||
|
|
||||||
// If it is a kinematic body
|
|
||||||
if (mType == KINEMATIC) {
|
|
||||||
|
|
||||||
// Update the linear velocity of the current body state
|
|
||||||
mLinearVelocity = linearVelocity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return true if the gravity needs to be applied to this rigid body
|
// Return true if the gravity needs to be applied to this rigid body
|
||||||
/**
|
/**
|
||||||
* @return True if the gravity is applied to the body
|
* @return True if the gravity is applied to the body
|
||||||
|
|
|
@ -142,9 +142,6 @@ void DynamicsWorld::update(decimal timeStep) {
|
||||||
|
|
||||||
// Reset the external force and torque applied to the bodies
|
// Reset the external force and torque applied to the bodies
|
||||||
resetBodiesForceAndTorque();
|
resetBodiesForceAndTorque();
|
||||||
|
|
||||||
// Compute and set the interpolation factor to all the bodies
|
|
||||||
setInterpolationFactorToAllBodies();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Integrate position and orientation of the rigid bodies.
|
// Integrate position and orientation of the rigid bodies.
|
||||||
|
@ -331,9 +328,6 @@ void DynamicsWorld::integrateRigidBodiesVelocities() {
|
||||||
mConstrainedAngularVelocities[indexBody] *= clamp(angularDamping, decimal(0.0),
|
mConstrainedAngularVelocities[indexBody] *= clamp(angularDamping, decimal(0.0),
|
||||||
decimal(1.0));
|
decimal(1.0));
|
||||||
|
|
||||||
// Update the old Transform of the body
|
|
||||||
bodies[b]->updateOldTransform();
|
|
||||||
|
|
||||||
indexBody++;
|
indexBody++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -958,3 +952,23 @@ void DynamicsWorld::testCollision(CollisionCallback* callback) {
|
||||||
// Perform the collision detection and report contacts
|
// Perform the collision detection and report contacts
|
||||||
mCollisionDetection.reportCollisionBetweenShapes(callback, emptySet, emptySet);
|
mCollisionDetection.reportCollisionBetweenShapes(callback, emptySet, emptySet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the list of all contacts of the world
|
||||||
|
std::vector<const ContactManifold*> DynamicsWorld::getContactsList() const {
|
||||||
|
|
||||||
|
std::vector<const ContactManifold*> contactManifolds;
|
||||||
|
|
||||||
|
// For each currently overlapping pair of bodies
|
||||||
|
std::map<overlappingpairid, OverlappingPair*>::const_iterator it;
|
||||||
|
for (it = mCollisionDetection.mOverlappingPairs.begin();
|
||||||
|
it != mCollisionDetection.mOverlappingPairs.end(); ++it) {
|
||||||
|
|
||||||
|
OverlappingPair* pair = it->second;
|
||||||
|
|
||||||
|
// Get the contact manifold
|
||||||
|
contactManifolds.push_back(pair->getContactManifold());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return all the contact manifold
|
||||||
|
return contactManifolds;
|
||||||
|
}
|
||||||
|
|
|
@ -186,18 +186,18 @@ class DynamicsWorld : public CollisionWorld {
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~DynamicsWorld();
|
virtual ~DynamicsWorld();
|
||||||
|
|
||||||
/// Start the physics simulation
|
|
||||||
void start();
|
|
||||||
|
|
||||||
/// Stop the physics simulation
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
/// Update the physics simulation
|
/// Update the physics simulation
|
||||||
void update(decimal timeStep);
|
void update(decimal timeStep);
|
||||||
|
|
||||||
|
/// Get the number of iterations for the velocity constraint solver
|
||||||
|
uint getNbIterationsVelocitySolver() const;
|
||||||
|
|
||||||
/// Set the number of iterations for the velocity constraint solver
|
/// Set the number of iterations for the velocity constraint solver
|
||||||
void setNbIterationsVelocitySolver(uint nbIterations);
|
void setNbIterationsVelocitySolver(uint nbIterations);
|
||||||
|
|
||||||
|
/// Get the number of iterations for the position constraint solver
|
||||||
|
uint getNbIterationsPositionSolver() const;
|
||||||
|
|
||||||
/// Set the number of iterations for the position constraint solver
|
/// Set the number of iterations for the position constraint solver
|
||||||
void setNbIterationsPositionSolver(uint nbIterations);
|
void setNbIterationsPositionSolver(uint nbIterations);
|
||||||
|
|
||||||
|
@ -226,6 +226,9 @@ class DynamicsWorld : public CollisionWorld {
|
||||||
/// Return the gravity vector of the world
|
/// Return the gravity vector of the world
|
||||||
Vector3 getGravity() const;
|
Vector3 getGravity() const;
|
||||||
|
|
||||||
|
/// Set the gravity vector of the world
|
||||||
|
void setGravity(Vector3& gravity);
|
||||||
|
|
||||||
/// Return if the gravity is on
|
/// Return if the gravity is on
|
||||||
bool isGravityEnabled() const;
|
bool isGravityEnabled() const;
|
||||||
|
|
||||||
|
@ -238,9 +241,6 @@ class DynamicsWorld : public CollisionWorld {
|
||||||
/// Return the number of joints in the world
|
/// Return the number of joints in the world
|
||||||
uint getNbJoints() const;
|
uint getNbJoints() const;
|
||||||
|
|
||||||
/// Return the current physics time (in seconds)
|
|
||||||
long double getPhysicsTime() const;
|
|
||||||
|
|
||||||
/// Return an iterator to the beginning of the rigid bodies of the physics world
|
/// Return an iterator to the beginning of the rigid bodies of the physics world
|
||||||
std::set<RigidBody*>::iterator getRigidBodiesBeginIterator();
|
std::set<RigidBody*>::iterator getRigidBodiesBeginIterator();
|
||||||
|
|
||||||
|
@ -297,6 +297,9 @@ class DynamicsWorld : public CollisionWorld {
|
||||||
/// Test and report collisions between all shapes of the world
|
/// Test and report collisions between all shapes of the world
|
||||||
virtual void testCollision(CollisionCallback* callback);
|
virtual void testCollision(CollisionCallback* callback);
|
||||||
|
|
||||||
|
/// Return the list of all contacts of the world
|
||||||
|
std::vector<const ContactManifold*> getContactsList() const;
|
||||||
|
|
||||||
// -------------------- Friendship -------------------- //
|
// -------------------- Friendship -------------------- //
|
||||||
|
|
||||||
friend class RigidBody;
|
friend class RigidBody;
|
||||||
|
@ -313,6 +316,11 @@ inline void DynamicsWorld::resetBodiesForceAndTorque() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the number of iterations for the velocity constraint solver
|
||||||
|
inline uint DynamicsWorld::getNbIterationsVelocitySolver() const {
|
||||||
|
return mNbVelocitySolverIterations;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the number of iterations for the velocity constraint solver
|
// Set the number of iterations for the velocity constraint solver
|
||||||
/**
|
/**
|
||||||
* @param nbIterations Number of iterations for the velocity solver
|
* @param nbIterations Number of iterations for the velocity solver
|
||||||
|
@ -321,6 +329,11 @@ inline void DynamicsWorld::setNbIterationsVelocitySolver(uint nbIterations) {
|
||||||
mNbVelocitySolverIterations = nbIterations;
|
mNbVelocitySolverIterations = nbIterations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the number of iterations for the position constraint solver
|
||||||
|
inline uint DynamicsWorld::getNbIterationsPositionSolver() const {
|
||||||
|
return mNbPositionSolverIterations;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the number of iterations for the position constraint solver
|
// Set the number of iterations for the position constraint solver
|
||||||
/**
|
/**
|
||||||
* @param nbIterations Number of iterations for the position solver
|
* @param nbIterations Number of iterations for the position solver
|
||||||
|
@ -375,6 +388,14 @@ inline Vector3 DynamicsWorld::getGravity() const {
|
||||||
return mGravity;
|
return mGravity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the gravity vector of the world
|
||||||
|
/**
|
||||||
|
* @param gravity The gravity vector (in meter per seconds squared)
|
||||||
|
*/
|
||||||
|
inline void DynamicsWorld::setGravity(Vector3& gravity) {
|
||||||
|
mGravity = gravity;
|
||||||
|
}
|
||||||
|
|
||||||
// Return if the gravity is enaled
|
// Return if the gravity is enaled
|
||||||
/**
|
/**
|
||||||
* @return True if the gravity is enabled in the world
|
* @return True if the gravity is enabled in the world
|
||||||
|
|
|
@ -54,7 +54,9 @@ Vector2::~Vector2() {
|
||||||
Vector2 Vector2::getUnit() const {
|
Vector2 Vector2::getUnit() const {
|
||||||
decimal lengthVector = length();
|
decimal lengthVector = length();
|
||||||
|
|
||||||
assert(lengthVector > MACHINE_EPSILON);
|
if (lengthVector < MACHINE_EPSILON) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// Compute and return the unit vector
|
// Compute and return the unit vector
|
||||||
decimal lengthInv = decimal(1.0) / lengthVector;
|
decimal lengthInv = decimal(1.0) / lengthVector;
|
||||||
|
|
|
@ -178,7 +178,9 @@ inline decimal Vector2::dot(const Vector2& vector) const {
|
||||||
// Normalize the vector
|
// Normalize the vector
|
||||||
inline void Vector2::normalize() {
|
inline void Vector2::normalize() {
|
||||||
decimal l = length();
|
decimal l = length();
|
||||||
assert(l > std::numeric_limits<decimal>::epsilon());
|
if (l < MACHINE_EPSILON) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
x /= l;
|
x /= l;
|
||||||
y /= l;
|
y /= l;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,9 @@ Vector3::~Vector3() {
|
||||||
Vector3 Vector3::getUnit() const {
|
Vector3 Vector3::getUnit() const {
|
||||||
decimal lengthVector = length();
|
decimal lengthVector = length();
|
||||||
|
|
||||||
assert(lengthVector > MACHINE_EPSILON);
|
if (lengthVector < MACHINE_EPSILON) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// Compute and return the unit vector
|
// Compute and return the unit vector
|
||||||
decimal lengthInv = decimal(1.0) / lengthVector;
|
decimal lengthInv = decimal(1.0) / lengthVector;
|
||||||
|
|
|
@ -193,7 +193,9 @@ inline Vector3 Vector3::cross(const Vector3& vector) const {
|
||||||
// Normalize the vector
|
// Normalize the vector
|
||||||
inline void Vector3::normalize() {
|
inline void Vector3::normalize() {
|
||||||
decimal l = length();
|
decimal l = length();
|
||||||
assert(l > std::numeric_limits<decimal>::epsilon());
|
if (l < MACHINE_EPSILON) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
x /= l;
|
x /= l;
|
||||||
y /= l;
|
y /= l;
|
||||||
z /= l;
|
z /= l;
|
||||||
|
|
97
testbed/CMakeLists.txt
Normal file
97
testbed/CMakeLists.txt
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
# Minimum cmake version required
|
||||||
|
cmake_minimum_required(VERSION 2.6)
|
||||||
|
|
||||||
|
# Project configuration
|
||||||
|
PROJECT(Testbed)
|
||||||
|
|
||||||
|
# Where to build the executables
|
||||||
|
SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/testbed")
|
||||||
|
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
|
||||||
|
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH})
|
||||||
|
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH})
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY(opengl-framework/)
|
||||||
|
ADD_SUBDIRECTORY(glfw/)
|
||||||
|
|
||||||
|
# Copy the shaders used for the demo into the build directory
|
||||||
|
FILE(COPY "shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/")
|
||||||
|
|
||||||
|
# Copy the meshes used for the demo into the build directory
|
||||||
|
FILE(COPY "meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/")
|
||||||
|
|
||||||
|
# Copy the fonts used for the GUI into the build directory
|
||||||
|
FILE(COPY "imgui/DroidSans.ttf" DESTINATION "${EXECUTABLE_OUTPUT_PATH}")
|
||||||
|
|
||||||
|
# Enable C++11 features
|
||||||
|
SET(CMAKE_CXX_FLAGS "-std=c++0x")
|
||||||
|
|
||||||
|
#ADD_DEFINITIONS(-DGL3)
|
||||||
|
|
||||||
|
# Headers
|
||||||
|
INCLUDE_DIRECTORIES("src/" "opengl-framework/src/" "glfw/include/" "common/" "scenes/" "imgui/")
|
||||||
|
|
||||||
|
# Testbed source files
|
||||||
|
SET(TESTBED_SOURCES
|
||||||
|
src/Main.cpp
|
||||||
|
src/TestbedApplication.h
|
||||||
|
src/TestbedApplication.cpp
|
||||||
|
src/Gui.h
|
||||||
|
src/Gui.cpp
|
||||||
|
src/Scene.h
|
||||||
|
src/Scene.cpp
|
||||||
|
src/SceneDemo.h
|
||||||
|
src/SceneDemo.cpp
|
||||||
|
src/Timer.h
|
||||||
|
src/Timer.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# IMGUI source files
|
||||||
|
SET(IMGUI_SOURCES
|
||||||
|
imgui/imgui.cpp
|
||||||
|
imgui/imgui.h
|
||||||
|
imgui/imguiRenderGL3.h
|
||||||
|
imgui/imguiRenderGL3.cpp
|
||||||
|
imgui/stb_truetype.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# Common source files
|
||||||
|
SET(COMMON_SOURCES
|
||||||
|
common/Box.h
|
||||||
|
common/Box.cpp
|
||||||
|
common/Cone.h
|
||||||
|
common/Cone.cpp
|
||||||
|
common/Sphere.h
|
||||||
|
common/Sphere.cpp
|
||||||
|
common/Line.h
|
||||||
|
common/Line.cpp
|
||||||
|
common/Capsule.h
|
||||||
|
common/Capsule.cpp
|
||||||
|
common/ConvexMesh.h
|
||||||
|
common/ConvexMesh.cpp
|
||||||
|
common/Cylinder.h
|
||||||
|
common/Cylinder.cpp
|
||||||
|
common/Dumbbell.h
|
||||||
|
common/Dumbbell.cpp
|
||||||
|
common/PhysicsObject.h
|
||||||
|
common/PhysicsObject.cpp
|
||||||
|
common/VisualContactPoint.h
|
||||||
|
common/VisualContactPoint.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# Examples scenes source files
|
||||||
|
SET(SCENES_SOURCES
|
||||||
|
scenes/cubes/CubesScene.h
|
||||||
|
scenes/cubes/CubesScene.cpp
|
||||||
|
scenes/joints/JointsScene.h
|
||||||
|
scenes/joints/JointsScene.cpp
|
||||||
|
scenes/raycast/RaycastScene.h
|
||||||
|
scenes/raycast/RaycastScene.cpp
|
||||||
|
scenes/collisionshapes/CollisionShapesScene.h
|
||||||
|
scenes/collisionshapes/CollisionShapesScene.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create the executable
|
||||||
|
ADD_EXECUTABLE(testbed ${TESTBED_SOURCES} ${SCENES_SOURCES} ${COMMON_SOURCES} ${IMGUI_SOURCES})
|
||||||
|
|
||||||
|
# Link with libraries
|
||||||
|
TARGET_LINK_LIBRARIES(testbed reactphysics3d openglframework glfw ${GLFW_LIBRARIES})
|
|
@ -31,35 +31,89 @@
|
||||||
|
|
||||||
// Initialize static variables
|
// Initialize static variables
|
||||||
openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER);
|
openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER);
|
||||||
openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
|
openglframework::VertexBufferObject Box::mVBONormals(GL_ARRAY_BUFFER);
|
||||||
bool Box::areVBOsCreated = false;
|
openglframework::VertexArrayObject Box::mVAO;
|
||||||
VertexData Box::mCubeVertices[8] = {
|
int Box::totalNbBoxes = 0;
|
||||||
{openglframework::Vector3(1,1,1),openglframework::Vector3(1,1,1),openglframework::Color(1,0,0,1)},
|
GLfloat Box::mCubeVertices[108] = {
|
||||||
{openglframework::Vector3(-1,1,1),openglframework::Vector3(-1,1,1),openglframework::Color(1,0,0,1)},
|
-1.0f,-1.0f,-1.0f, // triangle 1 : begin
|
||||||
{openglframework::Vector3(-1,-1,1),openglframework::Vector3(-1,-1,1),openglframework::Color(1,0,0,1)},
|
-1.0f,-1.0f, 1.0f,
|
||||||
{openglframework::Vector3(1,-1,1),openglframework::Vector3(1,-1,1),openglframework::Color(1,0,0,1)},
|
-1.0f, 1.0f, 1.0f, // triangle 1 : end
|
||||||
{openglframework::Vector3(1,-1,-1),openglframework::Vector3(1,-1,-1),openglframework::Color(1,0,0,1)},
|
1.0f, 1.0f,-1.0f, // triangle 2 : begin
|
||||||
{openglframework::Vector3(-1,-1,-1),openglframework::Vector3(-1,-1,-1),openglframework::Color(1,0,0,1)},
|
-1.0f,-1.0f,-1.0f,
|
||||||
{openglframework::Vector3(-1,1,-1),openglframework::Vector3(-1,1,-1),openglframework::Color(1,0,0,1)},
|
-1.0f, 1.0f,-1.0f, // triangle 2 : end
|
||||||
{openglframework::Vector3(1,1,-1),openglframework::Vector3(1,1,-1),openglframework::Color(1,0,0,1)}
|
1.0f,-1.0f, 1.0f,
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
1.0f,-1.0f,-1.0f,
|
||||||
|
1.0f, 1.0f,-1.0f,
|
||||||
|
1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f,-1.0f,
|
||||||
|
1.0f,-1.0f, 1.0f,
|
||||||
|
-1.0f,-1.0f, 1.0f,
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f,-1.0f, 1.0f,
|
||||||
|
1.0f,-1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f,-1.0f,-1.0f,
|
||||||
|
1.0f, 1.0f,-1.0f,
|
||||||
|
1.0f,-1.0f,-1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f,-1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f,-1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f,-1.0f, 1.0f
|
||||||
|
};
|
||||||
|
GLfloat Box::mCubeNormals[108] = {
|
||||||
|
-1.0f, 0.0f, 0.0f, // triangle 1 : begin
|
||||||
|
-1.0f, 0.0f, 0.0f,
|
||||||
|
-1.0f, 0.0f, 0.0f, // triangle 1 : end
|
||||||
|
0.0f, 0.0f,-1.0f, // triangle 2 : begin
|
||||||
|
0.0f, 0.0f,-1.0f,
|
||||||
|
0.0f, 0.0f,-1.0f, // triangle 2 : end
|
||||||
|
0.0f,-1.0f, 0.0f,
|
||||||
|
0.0f,-1.0f, 0.0f,
|
||||||
|
0.0f,-1.0f, 0.0f,//
|
||||||
|
0.0f, 0.0f,-1.0f,
|
||||||
|
0.0f, 0.0f,-1.0f,
|
||||||
|
0.0f, 0.0f,-1.0f,//
|
||||||
|
-1.0f, 0.0f, 0.0f,
|
||||||
|
-1.0f, 0.0f, 0.0f,
|
||||||
|
-1.0f, 0.0f,0.0f,//
|
||||||
|
0.0f,-1.0f, 0.0f,
|
||||||
|
0.0f,-1.0f, 0.0f,
|
||||||
|
0.0f,-1.0f, 0.0f,//
|
||||||
|
0.0f, 0.0f, 1.0f,
|
||||||
|
0.0f, 0.0f, 1.0f,
|
||||||
|
0.0f, 0.0f, 1.0f,//
|
||||||
|
1.0f, 0.0f, 0.0f,
|
||||||
|
1.0f, 0.0f, 0.0f,
|
||||||
|
1.0f, 0.0f, 0.0f,//
|
||||||
|
1.0f, 0.0f, 0.0f,
|
||||||
|
1.0f, 0.0f, 0.0f,
|
||||||
|
1.0f, 0.0f, 0.0f,//
|
||||||
|
0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 1.0f, 0.0f,//
|
||||||
|
0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 1.0f, 0.0f,//
|
||||||
|
0.0f, 0.0f, 1.0f,
|
||||||
|
0.0f, 0.0f, 1.0f,
|
||||||
|
0.0f, 0.0f, 1.0f//
|
||||||
};
|
};
|
||||||
GLuint Box::mCubeIndices[36] = { 0, 1, 2,
|
|
||||||
2, 3, 0,
|
|
||||||
7, 4, 5,
|
|
||||||
5, 6, 7,
|
|
||||||
6, 5, 2,
|
|
||||||
2, 1, 6,
|
|
||||||
7, 0, 3,
|
|
||||||
3, 4, 7,
|
|
||||||
7, 6, 1,
|
|
||||||
1, 0, 7,
|
|
||||||
3, 2, 5,
|
|
||||||
5, 4, 3};
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position,
|
Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position,
|
||||||
reactphysics3d::CollisionWorld* world)
|
reactphysics3d::CollisionWorld* world)
|
||||||
: openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
|
: openglframework::Object3D() {
|
||||||
|
|
||||||
// Initialize the size of the box
|
// Initialize the size of the box
|
||||||
mSize[0] = size.x * 0.5f;
|
mSize[0] = size.x * 0.5f;
|
||||||
|
@ -85,25 +139,30 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
|
||||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||||
rp3d::Transform transform(initPosition, initOrientation);
|
rp3d::Transform transform(initPosition, initOrientation);
|
||||||
|
|
||||||
|
mPreviousTransform = transform;
|
||||||
|
|
||||||
// Create a rigid body in the dynamics world
|
// Create a rigid body in the dynamics world
|
||||||
mRigidBody = world->createCollisionBody(transform);
|
mBody = world->createCollisionBody(transform);
|
||||||
|
|
||||||
// Add the collision shape to the body
|
// Add the collision shape to the body
|
||||||
mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
|
mBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
|
||||||
|
|
||||||
// If the Vertex Buffer object has not been created yet
|
// If the Vertex Buffer object has not been created yet
|
||||||
if (!areVBOsCreated) {
|
if (totalNbBoxes == 0) {
|
||||||
|
|
||||||
// Create the Vertex Buffer
|
// Create the Vertex Buffer
|
||||||
createVBO();
|
createVBOAndVAO();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
totalNbBoxes++;
|
||||||
|
|
||||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position,
|
Box::Box(const openglframework::Vector3& size, const openglframework::Vector3& position,
|
||||||
float mass, reactphysics3d::DynamicsWorld* world)
|
float mass, reactphysics3d::DynamicsWorld* world)
|
||||||
: openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
|
: openglframework::Object3D() {
|
||||||
|
|
||||||
// Initialize the size of the box
|
// Initialize the size of the box
|
||||||
mSize[0] = size.x * 0.5f;
|
mSize[0] = size.x * 0.5f;
|
||||||
|
@ -129,111 +188,145 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
|
||||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||||
rp3d::Transform transform(initPosition, initOrientation);
|
rp3d::Transform transform(initPosition, initOrientation);
|
||||||
|
|
||||||
|
mPreviousTransform = transform;
|
||||||
|
|
||||||
// Create a rigid body in the dynamics world
|
// Create a rigid body in the dynamics world
|
||||||
rp3d::RigidBody* body = world->createRigidBody(transform);
|
rp3d::RigidBody* body = world->createRigidBody(transform);
|
||||||
|
|
||||||
// Add the collision shape to the body
|
// Add the collision shape to the body
|
||||||
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
||||||
|
|
||||||
mRigidBody = body;
|
mBody = body;
|
||||||
|
|
||||||
// If the Vertex Buffer object has not been created yet
|
// If the Vertex Buffer object has not been created yet
|
||||||
if (!areVBOsCreated) {
|
if (totalNbBoxes == 0) {
|
||||||
|
|
||||||
// Create the Vertex Buffer
|
// Create the Vertex Buffer
|
||||||
createVBO();
|
createVBOAndVAO();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
totalNbBoxes++;
|
||||||
|
|
||||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
Box::~Box() {
|
Box::~Box() {
|
||||||
|
|
||||||
|
if (totalNbBoxes == 1) {
|
||||||
|
|
||||||
|
// Destroy the VBOs and VAO
|
||||||
|
mVBOVertices.destroy();
|
||||||
|
mVBONormals.destroy();
|
||||||
|
mVAO.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbBoxes--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the cube at the correct position and with the correct orientation
|
// Render the cube at the correct position and with the correct orientation
|
||||||
void Box::render(openglframework::Shader& shader,
|
void Box::render(openglframework::Shader& shader,
|
||||||
const openglframework::Matrix4& worldToCameraMatrix) {
|
const openglframework::Matrix4& worldToCameraMatrix) {
|
||||||
|
|
||||||
|
// Bind the VAO
|
||||||
|
mVAO.bind();
|
||||||
|
|
||||||
// Bind the shader
|
// Bind the shader
|
||||||
shader.bind();
|
shader.bind();
|
||||||
|
|
||||||
|
mVBOVertices.bind();
|
||||||
|
|
||||||
// Set the model to camera matrix
|
// Set the model to camera matrix
|
||||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix);
|
||||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix);
|
||||||
|
|
||||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||||
// model-view matrix)
|
// model-view matrix)
|
||||||
|
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||||
const openglframework::Matrix3 normalMatrix =
|
const openglframework::Matrix3 normalMatrix =
|
||||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||||
|
|
||||||
// Set the vertex color
|
// Set the vertex color
|
||||||
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
openglframework::Color currentColor = mBody->isSleeping() ? mSleepingColor : mColor;
|
||||||
shader.setVector4Uniform("vertexColor", color);
|
openglframework::Vector4 color(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
|
||||||
|
shader.setVector4Uniform("vertexColor", color, false);
|
||||||
|
|
||||||
// Bind the vertices VBO
|
// Get the location of shader attribute variables
|
||||||
mVBOVertices.bind();
|
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
|
||||||
|
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false);
|
||||||
|
|
||||||
// Enable the vertex, normal and color arrays
|
glEnableVertexAttribArray(vertexPositionLoc);
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, NULL);
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
|
||||||
|
|
||||||
// Set the arrays pointers
|
mVBONormals.bind();
|
||||||
glVertexPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, position));
|
|
||||||
glNormalPointer(GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal));
|
|
||||||
glColorPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, color));
|
|
||||||
|
|
||||||
// Bind the indices VBO
|
if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc);
|
||||||
mVBOIndices.bind();
|
if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, NULL);
|
||||||
|
|
||||||
// Draw the geometry of the box
|
// Draw the geometry of the box
|
||||||
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (char*)NULL);
|
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||||
|
|
||||||
// Unbind the VBOs
|
glDisableVertexAttribArray(vertexPositionLoc);
|
||||||
|
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||||
|
|
||||||
|
mVBONormals.unbind();
|
||||||
mVBOVertices.unbind();
|
mVBOVertices.unbind();
|
||||||
mVBOIndices.unbind();
|
|
||||||
|
|
||||||
// Disable the arrays
|
// Unbind the VAO
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
mVAO.unbind();
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
|
||||||
|
|
||||||
// Unbind the shader
|
// Unbind the shader
|
||||||
shader.unbind();
|
shader.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the transform matrix of the box
|
|
||||||
void Box::updateTransform() {
|
|
||||||
|
|
||||||
// Get the interpolated transform of the rigid body
|
|
||||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
|
||||||
|
|
||||||
// Compute the transform used for rendering the box
|
|
||||||
rp3d::decimal matrix[16];
|
|
||||||
transform.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],
|
|
||||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
|
||||||
|
|
||||||
// Apply the scaling matrix to have the correct box dimensions
|
|
||||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the Vertex Buffer Objects used to render to box with OpenGL.
|
// Create the Vertex Buffer Objects used to render to box with OpenGL.
|
||||||
/// We create two VBOs (one for vertices and one for indices) to render all the boxes
|
/// We create two VBOs (one for vertices and one for indices) to render all the boxes
|
||||||
/// in the simulation.
|
/// in the simulation.
|
||||||
void Box::createVBO() {
|
void Box::createVBOAndVAO() {
|
||||||
|
|
||||||
// Create the VBOs
|
// Create the VBO for the vertices data
|
||||||
mVBOVertices.create();
|
mVBOVertices.create();
|
||||||
mVBOIndices.create();
|
mVBOVertices.bind();
|
||||||
|
|
||||||
// Copy the data into the VBOs
|
|
||||||
mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW);
|
mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW);
|
||||||
mVBOIndices.copyDataIntoVBO(sizeof(mCubeIndices), mCubeIndices, GL_STATIC_DRAW);
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
areVBOsCreated = true;
|
// Create th VBO for the normals data
|
||||||
|
mVBONormals.create();
|
||||||
|
mVBONormals.bind();
|
||||||
|
mVBONormals.copyDataIntoVBO(sizeof(mCubeNormals), mCubeNormals, GL_STATIC_DRAW);
|
||||||
|
mVBONormals.unbind();
|
||||||
|
|
||||||
|
// Create the VAO for both VBOs
|
||||||
|
mVAO.create();
|
||||||
|
mVAO.bind();
|
||||||
|
|
||||||
|
// Bind the VBO of vertices
|
||||||
|
mVBOVertices.bind();
|
||||||
|
|
||||||
|
// Bind the VBO of indices
|
||||||
|
mVBONormals.bind();
|
||||||
|
|
||||||
|
// Unbind the VAO
|
||||||
|
mVAO.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the transform
|
||||||
|
void Box::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);
|
||||||
}
|
}
|
|
@ -29,22 +29,10 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "openglframework.h"
|
#include "openglframework.h"
|
||||||
#include "reactphysics3d.h"
|
#include "reactphysics3d.h"
|
||||||
|
#include "PhysicsObject.h"
|
||||||
// Structure VertexData
|
|
||||||
struct VertexData {
|
|
||||||
|
|
||||||
/// Vertex position
|
|
||||||
openglframework::Vector3 position;
|
|
||||||
|
|
||||||
/// Vertex normal
|
|
||||||
openglframework::Vector3 normal;
|
|
||||||
|
|
||||||
// Vertex color
|
|
||||||
openglframework::Color color;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Class Box
|
// Class Box
|
||||||
class Box : public openglframework::Object3D {
|
class Box : public openglframework::Object3D, public PhysicsObject {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
|
@ -53,34 +41,31 @@ class Box : public openglframework::Object3D {
|
||||||
/// Size of each side of the box
|
/// Size of each side of the box
|
||||||
float mSize[3];
|
float mSize[3];
|
||||||
|
|
||||||
/// Rigid body used to simulate the dynamics of the box
|
|
||||||
rp3d::CollisionBody* mRigidBody;
|
|
||||||
|
|
||||||
/// Scaling matrix (applied to a cube to obtain the correct box dimensions)
|
/// Scaling matrix (applied to a cube to obtain the correct box dimensions)
|
||||||
openglframework::Matrix4 mScalingMatrix;
|
openglframework::Matrix4 mScalingMatrix;
|
||||||
|
|
||||||
/// Vertex Buffer Object for the vertices data used to render the box with OpenGL
|
/// Vertex Buffer Object for the vertices data used to render the box with OpenGL
|
||||||
static openglframework::VertexBufferObject mVBOVertices;
|
static openglframework::VertexBufferObject mVBOVertices;
|
||||||
|
|
||||||
/// Vertex Buffer Object for the indices used to render the box with OpenGL
|
/// Vertex Buffer Object for the normales used to render the box with OpenGL
|
||||||
static openglframework::VertexBufferObject mVBOIndices;
|
static openglframework::VertexBufferObject mVBONormals;
|
||||||
|
|
||||||
/// Vertex data for each vertex of the cube (used to render the box)
|
/// Vertex Array Object for the vertex data
|
||||||
static VertexData mCubeVertices[8];
|
static openglframework::VertexArrayObject mVAO;
|
||||||
|
|
||||||
/// Indices of the cube (used to render the box)
|
/// Vertices coordinates of the triangles of the box
|
||||||
static GLuint mCubeIndices[36];
|
static GLfloat mCubeVertices[108];
|
||||||
|
|
||||||
/// True if the VBOs have already been created
|
/// Vertices normals of the triangles of the box
|
||||||
static bool areVBOsCreated;
|
static GLfloat mCubeNormals[108];
|
||||||
|
|
||||||
/// Main color of the box
|
/// Total number of boxes created
|
||||||
openglframework::Color mColor;
|
static int totalNbBoxes;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Create a Vertex Buffer Object to render to box with OpenGL
|
/// Create a the VAO and VBOs to render to box with OpenGL
|
||||||
static void createVBO();
|
static void createVBOAndVAO();
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
|
@ -97,35 +82,20 @@ class Box : public openglframework::Object3D {
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Box();
|
~Box();
|
||||||
|
|
||||||
/// Return a pointer to the collision body of the box
|
|
||||||
reactphysics3d::CollisionBody* getCollisionBody();
|
|
||||||
|
|
||||||
/// Return a pointer to the rigid body of the box
|
|
||||||
reactphysics3d::RigidBody* getRigidBody();
|
|
||||||
|
|
||||||
/// Update the transform matrix of the box
|
|
||||||
void updateTransform();
|
|
||||||
|
|
||||||
/// Render the cube at the correct position and with the correct orientation
|
/// Render the cube at the correct position and with the correct orientation
|
||||||
void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix);
|
void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix);
|
||||||
|
|
||||||
/// Set the color of the box
|
/// Set the position of the box
|
||||||
void setColor(const openglframework::Color& color);
|
void resetTransform(const rp3d::Transform& transform);
|
||||||
|
|
||||||
|
/// Update the transform matrix of the object
|
||||||
|
virtual void updateTransform(float interpolationFactor);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return a pointer to the collision body of the box
|
// Update the transform matrix of the object
|
||||||
inline rp3d::CollisionBody* Box::getCollisionBody() {
|
inline void Box::updateTransform(float interpolationFactor) {
|
||||||
return mRigidBody;
|
mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a pointer to the rigid body of the box
|
|
||||||
inline rp3d::RigidBody* Box::getRigidBody() {
|
|
||||||
return dynamic_cast<rp3d::RigidBody*>(mRigidBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the color of the box
|
|
||||||
inline void Box::setColor(const openglframework::Color& color) {
|
|
||||||
mColor = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -26,6 +26,13 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "Capsule.h"
|
#include "Capsule.h"
|
||||||
|
|
||||||
|
openglframework::VertexBufferObject Capsule::mVBOVertices(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Capsule::mVBONormals(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Capsule::mVBOTextureCoords(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Capsule::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexArrayObject Capsule::mVAO;
|
||||||
|
int Capsule::totalNbCapsules = 0;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Capsule::Capsule(float radius, float height, const openglframework::Vector3& position,
|
Capsule::Capsule(float radius, float height, const openglframework::Vector3& position,
|
||||||
reactphysics3d::CollisionWorld* world,
|
reactphysics3d::CollisionWorld* world,
|
||||||
|
@ -57,13 +64,22 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
|
||||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||||
rp3d::Transform transform(initPosition, initOrientation);
|
rp3d::Transform transform(initPosition, initOrientation);
|
||||||
|
|
||||||
|
mPreviousTransform = transform;
|
||||||
|
|
||||||
// Create a rigid body corresponding in the dynamics world
|
// Create a rigid body corresponding in the dynamics world
|
||||||
mRigidBody = world->createCollisionBody(transform);
|
mBody = world->createCollisionBody(transform);
|
||||||
|
|
||||||
// Add a collision shape to the body and specify the mass of the shape
|
// Add a collision shape to the body and specify the mass of the shape
|
||||||
mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
|
mBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
|
||||||
|
|
||||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||||
|
|
||||||
|
// Create the VBOs and VAO
|
||||||
|
if (totalNbCapsules == 0) {
|
||||||
|
createVBOAndVAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbCapsules++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -103,16 +119,35 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
|
||||||
// Add a collision shape to the body and specify the mass of the shape
|
// Add a collision shape to the body and specify the mass of the shape
|
||||||
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
||||||
|
|
||||||
mRigidBody = body;
|
mBody = body;
|
||||||
|
|
||||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||||
|
|
||||||
|
// Create the VBOs and VAO
|
||||||
|
if (totalNbCapsules == 0) {
|
||||||
|
createVBOAndVAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbCapsules++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
Capsule::~Capsule() {
|
Capsule::~Capsule() {
|
||||||
|
|
||||||
|
if (totalNbCapsules == 1) {
|
||||||
|
|
||||||
// Destroy the mesh
|
// Destroy the mesh
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
|
// Destroy the VBOs and VAO
|
||||||
|
mVBOIndices.destroy();
|
||||||
|
mVBOVertices.destroy();
|
||||||
|
mVBONormals.destroy();
|
||||||
|
mVBOTextureCoords.destroy();
|
||||||
|
mVAO.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbCapsules--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the sphere at the correct position and with the correct orientation
|
// Render the sphere at the correct position and with the correct orientation
|
||||||
|
@ -123,57 +158,126 @@ void Capsule::render(openglframework::Shader& shader,
|
||||||
shader.bind();
|
shader.bind();
|
||||||
|
|
||||||
// Set the model to camera matrix
|
// Set the model to camera matrix
|
||||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix);
|
||||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix);
|
||||||
|
|
||||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||||
// model-view matrix)
|
// model-view matrix)
|
||||||
|
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||||
const openglframework::Matrix3 normalMatrix =
|
const openglframework::Matrix3 normalMatrix =
|
||||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
// Set the vertex color
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
openglframework::Color currentColor = mBody->isSleeping() ? mSleepingColor : mColor;
|
||||||
if (hasTexture()) {
|
openglframework::Vector4 color(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
shader.setVector4Uniform("vertexColor", color, false);
|
||||||
}
|
|
||||||
|
|
||||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
// Bind the VAO
|
||||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
mVAO.bind();
|
||||||
if(hasTexture()) {
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
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 each part of the mesh
|
||||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
|
||||||
GL_UNSIGNED_INT, getIndicesPointer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableVertexAttribArray(vertexPositionLoc);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||||
if (hasTexture()) {
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
mVBONormals.unbind();
|
||||||
}
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
|
// Unbind the VAO
|
||||||
|
mVAO.unbind();
|
||||||
|
|
||||||
// Unbind the shader
|
// Unbind the shader
|
||||||
shader.unbind();
|
shader.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the transform matrix of the sphere
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
void Capsule::updateTransform() {
|
/// We create two VBOs (one for vertices and one for indices)
|
||||||
|
void Capsule::createVBOAndVAO() {
|
||||||
|
|
||||||
// Get the interpolated transform of the rigid body
|
// Create the VBO for the vertices data
|
||||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
mVBOVertices.create();
|
||||||
|
mVBOVertices.bind();
|
||||||
|
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
|
||||||
|
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
|
||||||
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
// Compute the transform used for rendering the sphere
|
// Create the VBO for the normals data
|
||||||
rp3d::decimal matrix[16];
|
mVBONormals.create();
|
||||||
transform.getOpenGLMatrix(matrix);
|
mVBONormals.bind();
|
||||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
|
||||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
|
||||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
mVBONormals.unbind();
|
||||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
|
||||||
|
|
||||||
// Apply the scaling matrix to have the correct sphere dimensions
|
if (hasTexture()) {
|
||||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
// 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(uint);
|
||||||
|
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 Capsule::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);
|
||||||
}
|
}
|
|
@ -29,9 +29,10 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "openglframework.h"
|
#include "openglframework.h"
|
||||||
#include "reactphysics3d.h"
|
#include "reactphysics3d.h"
|
||||||
|
#include "PhysicsObject.h"
|
||||||
|
|
||||||
// Class Sphere
|
// Class Sphere
|
||||||
class Capsule : public openglframework::Mesh {
|
class Capsule : public openglframework::Mesh, public PhysicsObject {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
|
@ -43,14 +44,35 @@ class Capsule : public openglframework::Mesh {
|
||||||
/// Height of the capsule
|
/// Height of the capsule
|
||||||
float mHeight;
|
float mHeight;
|
||||||
|
|
||||||
/// Rigid body used to simulate the dynamics of the sphere
|
|
||||||
rp3d::CollisionBody* mRigidBody;
|
|
||||||
|
|
||||||
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
|
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
|
||||||
openglframework::Matrix4 mScalingMatrix;
|
openglframework::Matrix4 mScalingMatrix;
|
||||||
|
|
||||||
|
/// Previous transform (for interpolation)
|
||||||
|
rp3d::Transform mPreviousTransform;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the vertices data
|
||||||
|
static openglframework::VertexBufferObject mVBOVertices;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the normals data
|
||||||
|
static openglframework::VertexBufferObject mVBONormals;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the texture coords
|
||||||
|
static openglframework::VertexBufferObject mVBOTextureCoords;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the indices
|
||||||
|
static openglframework::VertexBufferObject mVBOIndices;
|
||||||
|
|
||||||
|
/// Vertex Array Object for the vertex data
|
||||||
|
static openglframework::VertexArrayObject mVAO;
|
||||||
|
|
||||||
|
// Total number of capsules created
|
||||||
|
static int totalNbCapsules;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
|
void createVBOAndVAO();
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
@ -67,28 +89,20 @@ class Capsule : public openglframework::Mesh {
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Capsule();
|
~Capsule();
|
||||||
|
|
||||||
/// Return a pointer to the collision body of the box
|
|
||||||
reactphysics3d::CollisionBody* getCollisionBody();
|
|
||||||
|
|
||||||
/// Return a pointer to the rigid body of the box
|
|
||||||
reactphysics3d::RigidBody* getRigidBody();
|
|
||||||
|
|
||||||
/// Update the transform matrix of the sphere
|
|
||||||
void updateTransform();
|
|
||||||
|
|
||||||
/// Render the sphere at the correct position and with the correct orientation
|
/// Render the sphere at the correct position and with the correct orientation
|
||||||
void render(openglframework::Shader& shader,
|
void render(openglframework::Shader& shader,
|
||||||
const openglframework::Matrix4& worldToCameraMatrix);
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return a pointer to the collision body of the box
|
// Update the transform matrix of the object
|
||||||
inline rp3d::CollisionBody* Capsule::getCollisionBody() {
|
inline void Capsule::updateTransform(float interpolationFactor) {
|
||||||
return mRigidBody;
|
mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix);
|
||||||
}
|
|
||||||
|
|
||||||
// Return a pointer to the rigid body of the box
|
|
||||||
inline rp3d::RigidBody* Capsule::getRigidBody() {
|
|
||||||
return dynamic_cast<rp3d::RigidBody*>(mRigidBody);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -26,6 +26,13 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "Cone.h"
|
#include "Cone.h"
|
||||||
|
|
||||||
|
openglframework::VertexBufferObject Cone::mVBOVertices(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Cone::mVBONormals(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Cone::mVBOTextureCoords(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Cone::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexArrayObject Cone::mVAO;
|
||||||
|
int Cone::totalNbCones = 0;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
|
Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
|
||||||
reactphysics3d::CollisionWorld* world,
|
reactphysics3d::CollisionWorld* world,
|
||||||
|
@ -57,13 +64,22 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
|
||||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||||
rp3d::Transform transform(initPosition, initOrientation);
|
rp3d::Transform transform(initPosition, initOrientation);
|
||||||
|
|
||||||
|
mPreviousTransform = transform;
|
||||||
|
|
||||||
// Create a rigid body corresponding to the cone in the dynamics world
|
// Create a rigid body corresponding to the cone in the dynamics world
|
||||||
mRigidBody = world->createCollisionBody(transform);
|
mBody = world->createCollisionBody(transform);
|
||||||
|
|
||||||
// Add a collision shape to the body and specify the mass of the shape
|
// Add a collision shape to the body and specify the mass of the shape
|
||||||
mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
|
mBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
|
||||||
|
|
||||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||||
|
|
||||||
|
// Create the VBOs and VAO
|
||||||
|
if (totalNbCones == 0) {
|
||||||
|
createVBOAndVAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbCones++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -103,16 +119,34 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
|
||||||
// Add a collision shape to the body and specify the mass of the shape
|
// Add a collision shape to the body and specify the mass of the shape
|
||||||
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
||||||
|
|
||||||
mRigidBody = body;
|
mBody = body;
|
||||||
|
|
||||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||||
|
|
||||||
|
// Create the VBOs and VAO
|
||||||
|
if (totalNbCones == 0) {
|
||||||
|
createVBOAndVAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbCones++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
Cone::~Cone() {
|
Cone::~Cone() {
|
||||||
|
|
||||||
|
if (totalNbCones == 1) {
|
||||||
// Destroy the mesh
|
// Destroy the mesh
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
|
// Destroy the VBOs and VAO
|
||||||
|
mVBOIndices.destroy();
|
||||||
|
mVBOVertices.destroy();
|
||||||
|
mVBONormals.destroy();
|
||||||
|
mVBOTextureCoords.destroy();
|
||||||
|
mVAO.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbCones--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the cone at the correct position and with the correct orientation
|
// Render the cone at the correct position and with the correct orientation
|
||||||
|
@ -123,57 +157,126 @@ void Cone::render(openglframework::Shader& shader,
|
||||||
shader.bind();
|
shader.bind();
|
||||||
|
|
||||||
// Set the model to camera matrix
|
// Set the model to camera matrix
|
||||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix);
|
||||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix);
|
||||||
|
|
||||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||||
// model-view matrix)
|
// model-view matrix)
|
||||||
|
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||||
const openglframework::Matrix3 normalMatrix =
|
const openglframework::Matrix3 normalMatrix =
|
||||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
// Set the vertex color
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
||||||
if (hasTexture()) {
|
shader.setVector4Uniform("vertexColor", color, false);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
// Bind the VAO
|
||||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
mVAO.bind();
|
||||||
if(hasTexture()) {
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
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 each part of the mesh
|
||||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
|
||||||
GL_UNSIGNED_INT, getIndicesPointer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableVertexAttribArray(vertexPositionLoc);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||||
if (hasTexture()) {
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
mVBONormals.unbind();
|
||||||
}
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
|
// Unbind the VAO
|
||||||
|
mVAO.unbind();
|
||||||
|
|
||||||
// Unbind the shader
|
// Unbind the shader
|
||||||
shader.unbind();
|
shader.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the transform matrix of the cone
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
void Cone::updateTransform() {
|
/// We create two VBOs (one for vertices and one for indices)
|
||||||
|
void Cone::createVBOAndVAO() {
|
||||||
|
|
||||||
// Get the interpolated transform of the rigid body
|
// Create the VBO for the vertices data
|
||||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
mVBOVertices.create();
|
||||||
|
mVBOVertices.bind();
|
||||||
|
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
|
||||||
|
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
|
||||||
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
// Compute the transform used for rendering the cone
|
// Create the VBO for the normals data
|
||||||
rp3d::decimal matrix[16];
|
mVBONormals.create();
|
||||||
transform.getOpenGLMatrix(matrix);
|
mVBONormals.bind();
|
||||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
|
||||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
|
||||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
mVBONormals.unbind();
|
||||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
|
||||||
|
|
||||||
// Apply the scaling matrix to have the correct cone dimensions
|
if (hasTexture()) {
|
||||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
// 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(uint);
|
||||||
|
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 Cone::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);
|
||||||
|
}
|
||||||
|
|
|
@ -29,9 +29,10 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "openglframework.h"
|
#include "openglframework.h"
|
||||||
#include "reactphysics3d.h"
|
#include "reactphysics3d.h"
|
||||||
|
#include "PhysicsObject.h"
|
||||||
|
|
||||||
// Class Cone
|
// Class Cone
|
||||||
class Cone : public openglframework::Mesh {
|
class Cone : public openglframework::Mesh, public PhysicsObject {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
|
@ -43,14 +44,35 @@ class Cone : public openglframework::Mesh {
|
||||||
/// Height of the cone
|
/// Height of the cone
|
||||||
float mHeight;
|
float mHeight;
|
||||||
|
|
||||||
/// Rigid body used to simulate the dynamics of the cone
|
|
||||||
rp3d::CollisionBody* mRigidBody;
|
|
||||||
|
|
||||||
/// Scaling matrix (applied to a sphere to obtain the correct cone dimensions)
|
/// Scaling matrix (applied to a sphere to obtain the correct cone dimensions)
|
||||||
openglframework::Matrix4 mScalingMatrix;
|
openglframework::Matrix4 mScalingMatrix;
|
||||||
|
|
||||||
|
/// Previous transform (for interpolation)
|
||||||
|
rp3d::Transform mPreviousTransform;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the vertices data
|
||||||
|
static openglframework::VertexBufferObject mVBOVertices;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the normals data
|
||||||
|
static openglframework::VertexBufferObject mVBONormals;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the texture coords
|
||||||
|
static openglframework::VertexBufferObject mVBOTextureCoords;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the indices
|
||||||
|
static openglframework::VertexBufferObject mVBOIndices;
|
||||||
|
|
||||||
|
/// Vertex Array Object for the vertex data
|
||||||
|
static openglframework::VertexArrayObject mVAO;
|
||||||
|
|
||||||
|
// Total number of cones created
|
||||||
|
static int totalNbCones;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
|
void createVBOAndVAO();
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
@ -66,28 +88,20 @@ class Cone : public openglframework::Mesh {
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Cone();
|
~Cone();
|
||||||
|
|
||||||
/// Return a pointer to the collision body of the box
|
|
||||||
reactphysics3d::CollisionBody* getCollisionBody();
|
|
||||||
|
|
||||||
/// Return a pointer to the rigid body of the box
|
|
||||||
reactphysics3d::RigidBody* getRigidBody();
|
|
||||||
|
|
||||||
/// Update the transform matrix of the cone
|
|
||||||
void updateTransform();
|
|
||||||
|
|
||||||
/// Render the cone at the correct position and with the correct orientation
|
/// Render the cone at the correct position and with the correct orientation
|
||||||
void render(openglframework::Shader& shader,
|
void render(openglframework::Shader& shader,
|
||||||
const openglframework::Matrix4& worldToCameraMatrix);
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return a pointer to the collision body of the box
|
// Update the transform matrix of the object
|
||||||
inline rp3d::CollisionBody* Cone::getCollisionBody() {
|
inline void Cone::updateTransform(float interpolationFactor) {
|
||||||
return mRigidBody;
|
mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix);
|
||||||
}
|
|
||||||
|
|
||||||
// Return a pointer to the rigid body of the box
|
|
||||||
inline rp3d::RigidBody* Cone::getRigidBody() {
|
|
||||||
return dynamic_cast<rp3d::RigidBody*>(mRigidBody);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -30,7 +30,9 @@
|
||||||
ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
|
ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
|
||||||
reactphysics3d::CollisionWorld* world,
|
reactphysics3d::CollisionWorld* world,
|
||||||
const std::string& meshFolderPath)
|
const std::string& meshFolderPath)
|
||||||
: openglframework::Mesh() {
|
: openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER),
|
||||||
|
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
|
||||||
|
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
|
||||||
|
|
||||||
// Load the mesh from a file
|
// Load the mesh from a file
|
||||||
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this);
|
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this);
|
||||||
|
@ -79,18 +81,25 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
|
||||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||||
rp3d::Transform transform(initPosition, initOrientation);
|
rp3d::Transform transform(initPosition, initOrientation);
|
||||||
|
|
||||||
|
mPreviousTransform = transform;
|
||||||
|
|
||||||
// Create a rigid body corresponding to the sphere in the dynamics world
|
// Create a rigid body corresponding to the sphere in the dynamics world
|
||||||
mRigidBody = world->createCollisionBody(transform);
|
mBody = world->createCollisionBody(transform);
|
||||||
|
|
||||||
// Add a collision shape to the body and specify the mass of the collision shape
|
// Add a collision shape to the body and specify the mass of the collision shape
|
||||||
mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
|
mBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
|
||||||
|
|
||||||
|
// Create the VBOs and VAO
|
||||||
|
createVBOAndVAO();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass,
|
ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass,
|
||||||
reactphysics3d::DynamicsWorld* dynamicsWorld,
|
reactphysics3d::DynamicsWorld* dynamicsWorld,
|
||||||
const std::string& meshFolderPath)
|
const std::string& meshFolderPath)
|
||||||
: openglframework::Mesh() {
|
: openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER),
|
||||||
|
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
|
||||||
|
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
|
||||||
|
|
||||||
// Load the mesh from a file
|
// Load the mesh from a file
|
||||||
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this);
|
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this);
|
||||||
|
@ -144,7 +153,10 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass,
|
||||||
// Add a collision shape to the body and specify the mass of the collision shape
|
// Add a collision shape to the body and specify the mass of the collision shape
|
||||||
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
||||||
|
|
||||||
mRigidBody = body;
|
mBody = body;
|
||||||
|
|
||||||
|
// Create the VBOs and VAO
|
||||||
|
createVBOAndVAO();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
|
@ -152,6 +164,13 @@ ConvexMesh::~ConvexMesh() {
|
||||||
|
|
||||||
// Destroy the mesh
|
// Destroy the mesh
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
|
// Destroy the VBOs and VAO
|
||||||
|
mVBOIndices.destroy();
|
||||||
|
mVBOVertices.destroy();
|
||||||
|
mVBONormals.destroy();
|
||||||
|
mVBOTextureCoords.destroy();
|
||||||
|
mVAO.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the sphere at the correct position and with the correct orientation
|
// Render the sphere at the correct position and with the correct orientation
|
||||||
|
@ -162,57 +181,125 @@ void ConvexMesh::render(openglframework::Shader& shader,
|
||||||
shader.bind();
|
shader.bind();
|
||||||
|
|
||||||
// Set the model to camera matrix
|
// Set the model to camera matrix
|
||||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix);
|
||||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix);
|
||||||
|
|
||||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||||
// model-view matrix)
|
// model-view matrix)
|
||||||
|
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||||
const openglframework::Matrix3 normalMatrix =
|
const openglframework::Matrix3 normalMatrix =
|
||||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
// Set the vertex color
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
||||||
if (hasTexture()) {
|
shader.setVector4Uniform("vertexColor", color, false);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
// Bind the VAO
|
||||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
mVAO.bind();
|
||||||
if(hasTexture()) {
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
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 each part of the mesh
|
||||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
|
||||||
GL_UNSIGNED_INT, getIndicesPointer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableVertexAttribArray(vertexPositionLoc);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||||
if (hasTexture()) {
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
mVBONormals.unbind();
|
||||||
}
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
|
// Unbind the VAO
|
||||||
|
mVAO.unbind();
|
||||||
|
|
||||||
// Unbind the shader
|
// Unbind the shader
|
||||||
shader.unbind();
|
shader.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the transform matrix of the sphere
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
void ConvexMesh::updateTransform() {
|
/// We create two VBOs (one for vertices and one for indices)
|
||||||
|
void ConvexMesh::createVBOAndVAO() {
|
||||||
|
|
||||||
// Get the interpolated transform of the rigid body
|
// Create the VBO for the vertices data
|
||||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
mVBOVertices.create();
|
||||||
|
mVBOVertices.bind();
|
||||||
|
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
|
||||||
|
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
|
||||||
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
// Compute the transform used for rendering the sphere
|
// Create the VBO for the normals data
|
||||||
rp3d::decimal matrix[16];
|
mVBONormals.create();
|
||||||
transform.getOpenGLMatrix(matrix);
|
mVBONormals.bind();
|
||||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
|
||||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
|
||||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
mVBONormals.unbind();
|
||||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
|
||||||
|
|
||||||
// Apply the scaling matrix to have the correct sphere dimensions
|
if (hasTexture()) {
|
||||||
mTransformMatrix = newMatrix;
|
// 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(uint);
|
||||||
|
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 ConvexMesh::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);
|
||||||
}
|
}
|
|
@ -29,19 +29,38 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "openglframework.h"
|
#include "openglframework.h"
|
||||||
#include "reactphysics3d.h"
|
#include "reactphysics3d.h"
|
||||||
|
#include "PhysicsObject.h"
|
||||||
|
|
||||||
// Class ConvexMesh
|
// Class ConvexMesh
|
||||||
class ConvexMesh : public openglframework::Mesh {
|
class ConvexMesh : public openglframework::Mesh, public PhysicsObject {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
/// Rigid body used to simulate the dynamics of the mesh
|
/// Previous transform (for interpolation)
|
||||||
rp3d::CollisionBody* mRigidBody;
|
rp3d::Transform mPreviousTransform;
|
||||||
|
|
||||||
|
/// 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;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
|
void createVBOAndVAO();
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
@ -57,28 +76,20 @@ class ConvexMesh : public openglframework::Mesh {
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~ConvexMesh();
|
~ConvexMesh();
|
||||||
|
|
||||||
/// Return a pointer to the collision body of the box
|
|
||||||
reactphysics3d::CollisionBody* getCollisionBody();
|
|
||||||
|
|
||||||
/// Return a pointer to the rigid body of the box
|
|
||||||
reactphysics3d::RigidBody* getRigidBody();
|
|
||||||
|
|
||||||
/// Update the transform matrix of the mesh
|
|
||||||
void updateTransform();
|
|
||||||
|
|
||||||
/// Render the mesh at the correct position and with the correct orientation
|
/// Render the mesh at the correct position and with the correct orientation
|
||||||
void render(openglframework::Shader& shader,
|
void render(openglframework::Shader& shader,
|
||||||
const openglframework::Matrix4& worldToCameraMatrix);
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return a pointer to the collision body of the box
|
// Update the transform matrix of the object
|
||||||
inline rp3d::CollisionBody* ConvexMesh::getCollisionBody() {
|
inline void ConvexMesh::updateTransform(float interpolationFactor) {
|
||||||
return mRigidBody;
|
mTransformMatrix = computeTransform(interpolationFactor, openglframework::Matrix4::identity());
|
||||||
}
|
|
||||||
|
|
||||||
// Return a pointer to the rigid body of the box
|
|
||||||
inline rp3d::RigidBody* ConvexMesh::getRigidBody() {
|
|
||||||
return dynamic_cast<rp3d::RigidBody*>(mRigidBody);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -26,6 +26,13 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "Cylinder.h"
|
#include "Cylinder.h"
|
||||||
|
|
||||||
|
openglframework::VertexBufferObject Cylinder::mVBOVertices(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Cylinder::mVBONormals(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Cylinder::mVBOTextureCoords(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Cylinder::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexArrayObject Cylinder::mVAO;
|
||||||
|
int Cylinder::totalNbCylinders = 0;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position,
|
Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position,
|
||||||
reactphysics3d::CollisionWorld* world,
|
reactphysics3d::CollisionWorld* world,
|
||||||
|
@ -57,13 +64,22 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
|
||||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||||
rp3d::Transform transform(initPosition, initOrientation);
|
rp3d::Transform transform(initPosition, initOrientation);
|
||||||
|
|
||||||
|
mPreviousTransform = transform;
|
||||||
|
|
||||||
// Create a rigid body corresponding to the cylinder in the dynamics world
|
// Create a rigid body corresponding to the cylinder in the dynamics world
|
||||||
mRigidBody = world->createCollisionBody(transform);
|
mBody = world->createCollisionBody(transform);
|
||||||
|
|
||||||
// Add a collision shape to the body and specify the mass of the shape
|
// Add a collision shape to the body and specify the mass of the shape
|
||||||
mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
|
mBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
|
||||||
|
|
||||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||||
|
|
||||||
|
// Create the VBOs and VAO
|
||||||
|
if (totalNbCylinders == 0) {
|
||||||
|
createVBOAndVAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbCylinders++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -105,14 +121,33 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
|
||||||
|
|
||||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||||
|
|
||||||
mRigidBody = body;
|
mBody = body;
|
||||||
|
|
||||||
|
// Create the VBOs and VAO
|
||||||
|
if (totalNbCylinders == 0) {
|
||||||
|
createVBOAndVAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbCylinders++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
Cylinder::~Cylinder() {
|
Cylinder::~Cylinder() {
|
||||||
|
|
||||||
|
if (totalNbCylinders == 1) {
|
||||||
|
|
||||||
// Destroy the mesh
|
// Destroy the mesh
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
|
// Destroy the VBOs and VAO
|
||||||
|
mVBOIndices.destroy();
|
||||||
|
mVBOVertices.destroy();
|
||||||
|
mVBONormals.destroy();
|
||||||
|
mVBOTextureCoords.destroy();
|
||||||
|
mVAO.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbCylinders--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the cylinder at the correct position and with the correct orientation
|
// Render the cylinder at the correct position and with the correct orientation
|
||||||
|
@ -123,57 +158,125 @@ void Cylinder::render(openglframework::Shader& shader,
|
||||||
shader.bind();
|
shader.bind();
|
||||||
|
|
||||||
// Set the model to camera matrix
|
// Set the model to camera matrix
|
||||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix);
|
||||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix);
|
||||||
|
|
||||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||||
// model-view matrix)
|
// model-view matrix)
|
||||||
|
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||||
const openglframework::Matrix3 normalMatrix =
|
const openglframework::Matrix3 normalMatrix =
|
||||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
// Set the vertex color
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
||||||
if (hasTexture()) {
|
shader.setVector4Uniform("vertexColor", color, false);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
// Bind the VAO
|
||||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
mVAO.bind();
|
||||||
if(hasTexture()) {
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
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 each part of the mesh
|
||||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
|
||||||
GL_UNSIGNED_INT, getIndicesPointer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableVertexAttribArray(vertexPositionLoc);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||||
if (hasTexture()) {
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
mVBONormals.unbind();
|
||||||
}
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
|
// Unbind the VAO
|
||||||
|
mVAO.unbind();
|
||||||
|
|
||||||
// Unbind the shader
|
// Unbind the shader
|
||||||
shader.unbind();
|
shader.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the transform matrix of the cylinder
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
void Cylinder::updateTransform() {
|
/// We create two VBOs (one for vertices and one for indices)
|
||||||
|
void Cylinder::createVBOAndVAO() {
|
||||||
|
|
||||||
// Get the interpolated transform of the rigid body
|
// Create the VBO for the vertices data
|
||||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
mVBOVertices.create();
|
||||||
|
mVBOVertices.bind();
|
||||||
|
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
|
||||||
|
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
|
||||||
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
// Compute the transform used for rendering the cylinder
|
// Create the VBO for the normals data
|
||||||
rp3d::decimal matrix[16];
|
mVBONormals.create();
|
||||||
transform.getOpenGLMatrix(matrix);
|
mVBONormals.bind();
|
||||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
|
||||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
|
||||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
mVBONormals.unbind();
|
||||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
|
||||||
|
|
||||||
// Apply the scaling matrix to have the correct cylinder dimensions
|
if (hasTexture()) {
|
||||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
// 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(uint);
|
||||||
|
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 Cylinder::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);
|
||||||
}
|
}
|
|
@ -29,9 +29,10 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "openglframework.h"
|
#include "openglframework.h"
|
||||||
#include "reactphysics3d.h"
|
#include "reactphysics3d.h"
|
||||||
|
#include "PhysicsObject.h"
|
||||||
|
|
||||||
// Class Cylinder
|
// Class Cylinder
|
||||||
class Cylinder : public openglframework::Mesh {
|
class Cylinder : public openglframework::Mesh, public PhysicsObject {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
|
@ -43,14 +44,35 @@ class Cylinder : public openglframework::Mesh {
|
||||||
/// Height of the cylinder
|
/// Height of the cylinder
|
||||||
float mHeight;
|
float mHeight;
|
||||||
|
|
||||||
/// Rigid body used to simulate the dynamics of the cylinder
|
|
||||||
rp3d::CollisionBody* mRigidBody;
|
|
||||||
|
|
||||||
/// Scaling matrix (applied to a sphere to obtain the correct cylinder dimensions)
|
/// Scaling matrix (applied to a sphere to obtain the correct cylinder dimensions)
|
||||||
openglframework::Matrix4 mScalingMatrix;
|
openglframework::Matrix4 mScalingMatrix;
|
||||||
|
|
||||||
|
/// Previous transform (for interpolation)
|
||||||
|
rp3d::Transform mPreviousTransform;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the vertices data
|
||||||
|
static openglframework::VertexBufferObject mVBOVertices;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the normals data
|
||||||
|
static openglframework::VertexBufferObject mVBONormals;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the texture coords
|
||||||
|
static openglframework::VertexBufferObject mVBOTextureCoords;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the indices
|
||||||
|
static openglframework::VertexBufferObject mVBOIndices;
|
||||||
|
|
||||||
|
/// Vertex Array Object for the vertex data
|
||||||
|
static openglframework::VertexArrayObject mVAO;
|
||||||
|
|
||||||
|
// Total number of capsules created
|
||||||
|
static int totalNbCylinders;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
|
void createVBOAndVAO();
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
@ -66,28 +88,20 @@ class Cylinder : public openglframework::Mesh {
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Cylinder();
|
~Cylinder();
|
||||||
|
|
||||||
/// Return a pointer to the collision body of the box
|
|
||||||
reactphysics3d::CollisionBody* getCollisionBody();
|
|
||||||
|
|
||||||
/// Return a pointer to the rigid body of the box
|
|
||||||
reactphysics3d::RigidBody* getRigidBody();
|
|
||||||
|
|
||||||
/// Update the transform matrix of the cylinder
|
|
||||||
void updateTransform();
|
|
||||||
|
|
||||||
/// Render the cylinder at the correct position and with the correct orientation
|
/// Render the cylinder at the correct position and with the correct orientation
|
||||||
void render(openglframework::Shader& shader,
|
void render(openglframework::Shader& shader,
|
||||||
const openglframework::Matrix4& worldToCameraMatrix);
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return a pointer to the collision body of the box
|
// Update the transform matrix of the object
|
||||||
inline rp3d::CollisionBody* Cylinder::getCollisionBody() {
|
inline void Cylinder::updateTransform(float interpolationFactor) {
|
||||||
return mRigidBody;
|
mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix);
|
||||||
}
|
|
||||||
|
|
||||||
// Return a pointer to the rigid body of the box
|
|
||||||
inline rp3d::RigidBody* Cylinder::getRigidBody() {
|
|
||||||
return dynamic_cast<rp3d::RigidBody*>(mRigidBody);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -26,6 +26,13 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "Dumbbell.h"
|
#include "Dumbbell.h"
|
||||||
|
|
||||||
|
openglframework::VertexBufferObject Dumbbell::mVBOVertices(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Dumbbell::mVBONormals(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Dumbbell::mVBOTextureCoords(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Dumbbell::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexArrayObject Dumbbell::mVAO;
|
||||||
|
int Dumbbell::totalNbDumbbells = 0;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Dumbbell::Dumbbell(const openglframework::Vector3 &position,
|
Dumbbell::Dumbbell(const openglframework::Vector3 &position,
|
||||||
reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath)
|
reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath)
|
||||||
|
@ -64,6 +71,8 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
|
||||||
rp3d::Quaternion initOrientation(angleAroundX, 0, 0);
|
rp3d::Quaternion initOrientation(angleAroundX, 0, 0);
|
||||||
rp3d::Transform transformBody(initPosition, initOrientation);
|
rp3d::Transform transformBody(initPosition, initOrientation);
|
||||||
|
|
||||||
|
mPreviousTransform = transformBody;
|
||||||
|
|
||||||
// Initial transform of the first sphere collision shape of the dumbbell (in local-space)
|
// 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());
|
rp3d::Transform transformSphereShape1(rp3d::Vector3(0, 4.0, 0), rp3d::Quaternion::identity());
|
||||||
|
|
||||||
|
@ -84,6 +93,13 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
|
||||||
mBody = body;
|
mBody = body;
|
||||||
|
|
||||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||||
|
|
||||||
|
// Create the VBOs and VAO
|
||||||
|
if (totalNbDumbbells == 0) {
|
||||||
|
createVBOAndVAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbDumbbells++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -142,13 +158,32 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
|
||||||
mBody->addCollisionShape(cylinderCollisionShape, transformCylinderShape);
|
mBody->addCollisionShape(cylinderCollisionShape, transformCylinderShape);
|
||||||
|
|
||||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||||
|
|
||||||
|
// Create the VBOs and VAO
|
||||||
|
if (totalNbDumbbells == 0) {
|
||||||
|
createVBOAndVAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbDumbbells++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
Dumbbell::~Dumbbell() {
|
Dumbbell::~Dumbbell() {
|
||||||
|
|
||||||
|
if (totalNbDumbbells == 1) {
|
||||||
|
|
||||||
// Destroy the mesh
|
// Destroy the mesh
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
|
// Destroy the VBOs and VAO
|
||||||
|
mVBOIndices.destroy();
|
||||||
|
mVBOVertices.destroy();
|
||||||
|
mVBONormals.destroy();
|
||||||
|
mVBOTextureCoords.destroy();
|
||||||
|
mVAO.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbDumbbells--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the sphere at the correct position and with the correct orientation
|
// Render the sphere at the correct position and with the correct orientation
|
||||||
|
@ -159,58 +194,125 @@ void Dumbbell::render(openglframework::Shader& shader,
|
||||||
shader.bind();
|
shader.bind();
|
||||||
|
|
||||||
// Set the model to camera matrix
|
// Set the model to camera matrix
|
||||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix);
|
||||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix);
|
||||||
|
|
||||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||||
// model-view matrix)
|
// model-view matrix)
|
||||||
|
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||||
const openglframework::Matrix3 normalMatrix =
|
const openglframework::Matrix3 normalMatrix =
|
||||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
// Set the vertex color
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
||||||
if (hasTexture()) {
|
shader.setVector4Uniform("vertexColor", color, false);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
// Bind the VAO
|
||||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
mVAO.bind();
|
||||||
if(hasTexture()) {
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
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) glEnableVertexAttribArray(vertexNormalLoc);
|
||||||
|
if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||||
|
|
||||||
// For each part of the mesh
|
// For each part of the mesh
|
||||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
|
||||||
GL_UNSIGNED_INT, getIndicesPointer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableVertexAttribArray(vertexPositionLoc);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||||
if (hasTexture()) {
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
mVBONormals.unbind();
|
||||||
}
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
|
// Unbind the VAO
|
||||||
|
mVAO.unbind();
|
||||||
|
|
||||||
// Unbind the shader
|
// Unbind the shader
|
||||||
shader.unbind();
|
shader.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the transform matrix of the sphere
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
void Dumbbell::updateTransform() {
|
/// We create two VBOs (one for vertices and one for indices)
|
||||||
|
void Dumbbell::createVBOAndVAO() {
|
||||||
|
|
||||||
// Get the interpolated transform of the rigid body
|
// Create the VBO for the vertices data
|
||||||
rp3d::Transform transform = mBody->getInterpolatedTransform();
|
mVBOVertices.create();
|
||||||
|
mVBOVertices.bind();
|
||||||
|
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
|
||||||
|
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
|
||||||
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
// Compute the transform used for rendering the sphere
|
// Create the VBO for the normals data
|
||||||
rp3d::decimal matrix[16];
|
mVBONormals.create();
|
||||||
transform.getOpenGLMatrix(matrix);
|
mVBONormals.bind();
|
||||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
|
||||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
|
||||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
mVBONormals.unbind();
|
||||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
|
||||||
|
|
||||||
// Apply the scaling matrix to have the correct sphere dimensions
|
if (hasTexture()) {
|
||||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
// 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(uint);
|
||||||
|
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 Dumbbell::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);
|
||||||
|
}
|
|
@ -29,9 +29,10 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "openglframework.h"
|
#include "openglframework.h"
|
||||||
#include "reactphysics3d.h"
|
#include "reactphysics3d.h"
|
||||||
|
#include "PhysicsObject.h"
|
||||||
|
|
||||||
// Class Sphere
|
// Class Sphere
|
||||||
class Dumbbell : public openglframework::Mesh {
|
class Dumbbell : public openglframework::Mesh, public PhysicsObject {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
|
@ -40,14 +41,35 @@ class Dumbbell : public openglframework::Mesh {
|
||||||
/// Radius of the spheres
|
/// Radius of the spheres
|
||||||
float mRadius;
|
float mRadius;
|
||||||
|
|
||||||
/// Rigid body used to simulate the dynamics of the sphere
|
|
||||||
rp3d::CollisionBody* mBody;
|
|
||||||
|
|
||||||
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
|
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
|
||||||
openglframework::Matrix4 mScalingMatrix;
|
openglframework::Matrix4 mScalingMatrix;
|
||||||
|
|
||||||
|
/// Previous transform (for interpolation)
|
||||||
|
rp3d::Transform mPreviousTransform;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the vertices data
|
||||||
|
static openglframework::VertexBufferObject mVBOVertices;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the normals data
|
||||||
|
static openglframework::VertexBufferObject mVBONormals;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the texture coords
|
||||||
|
static openglframework::VertexBufferObject mVBOTextureCoords;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the indices
|
||||||
|
static openglframework::VertexBufferObject mVBOIndices;
|
||||||
|
|
||||||
|
/// Vertex Array Object for the vertex data
|
||||||
|
static openglframework::VertexArrayObject mVAO;
|
||||||
|
|
||||||
|
// Total number of capsules created
|
||||||
|
static int totalNbDumbbells;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
|
void createVBOAndVAO();
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
@ -64,28 +86,20 @@ class Dumbbell : public openglframework::Mesh {
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Dumbbell();
|
~Dumbbell();
|
||||||
|
|
||||||
/// Return a pointer to the rigid body
|
|
||||||
rp3d::RigidBody* getRigidBody();
|
|
||||||
|
|
||||||
/// Return a pointer to the body
|
|
||||||
rp3d::CollisionBody* getCollisionBody();
|
|
||||||
|
|
||||||
/// Update the transform matrix of the sphere
|
|
||||||
void updateTransform();
|
|
||||||
|
|
||||||
/// Render the sphere at the correct position and with the correct orientation
|
/// Render the sphere at the correct position and with the correct orientation
|
||||||
void render(openglframework::Shader& shader,
|
void render(openglframework::Shader& shader,
|
||||||
const openglframework::Matrix4& worldToCameraMatrix);
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return a pointer to the rigid body of the sphere
|
// Update the transform matrix of the object
|
||||||
inline rp3d::RigidBody* Dumbbell::getRigidBody() {
|
inline void Dumbbell::updateTransform(float interpolationFactor) {
|
||||||
return dynamic_cast<rp3d::RigidBody*>(mBody);
|
mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix);
|
||||||
}
|
|
||||||
|
|
||||||
// Return a pointer to the body
|
|
||||||
inline rp3d::CollisionBody* Dumbbell::getCollisionBody() {
|
|
||||||
return mBody;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -47,7 +47,12 @@ void Line::render(openglframework::Shader& shader,
|
||||||
shader.bind();
|
shader.bind();
|
||||||
|
|
||||||
// Set the model to camera matrix
|
// Set the model to camera matrix
|
||||||
shader.setMatrix4x4Uniform("localToCameraMatrix", worldToCameraMatrix);
|
shader.setMatrix4x4Uniform("localToWorldMatrix", openglframework::Matrix4::identity());
|
||||||
|
shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix);
|
||||||
|
|
||||||
|
// Set the vertex color
|
||||||
|
openglframework::Vector4 color(1, 0, 0, 1);
|
||||||
|
shader.setVector4Uniform("vertexColor", color, false);
|
||||||
|
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
glVertex3f(mWorldPoint1.x, mWorldPoint1.y, mWorldPoint1.z);
|
glVertex3f(mWorldPoint1.x, mWorldPoint1.y, mWorldPoint1.z);
|
|
@ -58,9 +58,6 @@ class Line : public openglframework::Object3D {
|
||||||
/// Return the second point of the line
|
/// Return the second point of the line
|
||||||
openglframework::Vector3 getPoint2() const;
|
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
|
/// Render the line at the correct position and with the correct orientation
|
||||||
void render(openglframework::Shader& shader,
|
void render(openglframework::Shader& shader,
|
||||||
const openglframework::Matrix4& worldToCameraMatrix);
|
const openglframework::Matrix4& worldToCameraMatrix);
|
59
testbed/common/PhysicsObject.cpp
Normal file
59
testbed/common/PhysicsObject.cpp
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* 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 "PhysicsObject.h"
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
PhysicsObject::PhysicsObject() {
|
||||||
|
|
||||||
|
mColor = openglframework::Color(1, 1, 1, 1);
|
||||||
|
mSleepingColor = openglframework::Color(1, 0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the new transform matrix
|
||||||
|
openglframework::Matrix4 PhysicsObject::computeTransform(float interpolationFactor,
|
||||||
|
const openglframework::Matrix4& scalingMatrix) {
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
mPreviousTransform = transform;
|
||||||
|
|
||||||
|
// Compute the transform used for rendering the box
|
||||||
|
rp3d::decimal matrix[16];
|
||||||
|
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],
|
||||||
|
matrix[3], matrix[7], matrix[11], matrix[15]);
|
||||||
|
|
||||||
|
// Apply the scaling matrix to have the correct box dimensions
|
||||||
|
return newMatrix * scalingMatrix;
|
||||||
|
}
|
96
testbed/common/PhysicsObject.h
Normal file
96
testbed/common/PhysicsObject.h
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* 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 PHYSICSOBJECT_H
|
||||||
|
#define PHYSICSOBJECT_H
|
||||||
|
|
||||||
|
// Libraries
|
||||||
|
#include "openglframework.h"
|
||||||
|
#include "reactphysics3d.h"
|
||||||
|
|
||||||
|
// Class PhysicsObject
|
||||||
|
class PhysicsObject {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// Body used to simulate the dynamics of the box
|
||||||
|
rp3d::CollisionBody* mBody;
|
||||||
|
|
||||||
|
/// Previous transform of the body (for interpolation)
|
||||||
|
rp3d::Transform mPreviousTransform;
|
||||||
|
|
||||||
|
/// Main color of the box
|
||||||
|
openglframework::Color mColor;
|
||||||
|
|
||||||
|
/// Sleeping color
|
||||||
|
openglframework::Color mSleepingColor;
|
||||||
|
|
||||||
|
// Compute the new transform matrix
|
||||||
|
openglframework::Matrix4 computeTransform(float interpolationFactor,
|
||||||
|
const openglframework::Matrix4 &scalingMatrix);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
PhysicsObject();
|
||||||
|
|
||||||
|
/// Update the transform matrix of the object
|
||||||
|
virtual void updateTransform(float interpolationFactor)=0;
|
||||||
|
|
||||||
|
/// Set the color of the box
|
||||||
|
void setColor(const openglframework::Color& color);
|
||||||
|
|
||||||
|
/// Set the sleeping color of the box
|
||||||
|
void setSleepingColor(const openglframework::Color& color);
|
||||||
|
|
||||||
|
/// Return a pointer to the collision body of the box
|
||||||
|
reactphysics3d::CollisionBody* getCollisionBody();
|
||||||
|
|
||||||
|
/// Return a pointer to the rigid body of the box
|
||||||
|
reactphysics3d::RigidBody* getRigidBody();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the color of the box
|
||||||
|
inline void PhysicsObject::setColor(const openglframework::Color& color) {
|
||||||
|
mColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the sleeping color of the box
|
||||||
|
inline void PhysicsObject::setSleepingColor(const openglframework::Color& color) {
|
||||||
|
mSleepingColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a pointer to the collision body of the box
|
||||||
|
inline rp3d::CollisionBody* PhysicsObject::getCollisionBody() {
|
||||||
|
return mBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a pointer to the rigid body of the box (NULL if it's not a rigid body)
|
||||||
|
inline rp3d::RigidBody* PhysicsObject::getRigidBody() {
|
||||||
|
return dynamic_cast<rp3d::RigidBody*>(mBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -26,6 +26,13 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "Sphere.h"
|
#include "Sphere.h"
|
||||||
|
|
||||||
|
openglframework::VertexBufferObject Sphere::mVBOVertices(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Sphere::mVBONormals(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Sphere::mVBOTextureCoords(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject Sphere::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexArrayObject Sphere::mVAO;
|
||||||
|
int Sphere::totalNbSpheres = 0;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Sphere::Sphere(float radius, const openglframework::Vector3 &position,
|
Sphere::Sphere(float radius, const openglframework::Vector3 &position,
|
||||||
reactphysics3d::CollisionWorld* world,
|
reactphysics3d::CollisionWorld* world,
|
||||||
|
@ -57,13 +64,22 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
|
||||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||||
rp3d::Transform transform(initPosition, initOrientation);
|
rp3d::Transform transform(initPosition, initOrientation);
|
||||||
|
|
||||||
|
mPreviousTransform = transform;
|
||||||
|
|
||||||
// Create a rigid body corresponding to the sphere in the dynamics world
|
// Create a rigid body corresponding to the sphere in the dynamics world
|
||||||
mRigidBody = world->createCollisionBody(transform);
|
mBody = world->createCollisionBody(transform);
|
||||||
|
|
||||||
// Add a collision shape to the body and specify the mass of the shape
|
// Add a collision shape to the body and specify the mass of the shape
|
||||||
mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
|
mBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
|
||||||
|
|
||||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||||
|
|
||||||
|
// Create the VBOs and VAO
|
||||||
|
if (totalNbSpheres == 0) {
|
||||||
|
createVBOAndVAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbSpheres++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -103,16 +119,34 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
|
||||||
// Add a collision shape to the body and specify the mass of the shape
|
// Add a collision shape to the body and specify the mass of the shape
|
||||||
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
||||||
|
|
||||||
mRigidBody = body;
|
mBody = body;
|
||||||
|
|
||||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||||
|
|
||||||
|
// Create the VBOs and VAO
|
||||||
|
if (totalNbSpheres == 0) {
|
||||||
|
createVBOAndVAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbSpheres++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
Sphere::~Sphere() {
|
Sphere::~Sphere() {
|
||||||
|
|
||||||
|
if (totalNbSpheres == 1) {
|
||||||
// Destroy the mesh
|
// Destroy the mesh
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
|
// Destroy the VBOs and VAO
|
||||||
|
mVBOIndices.destroy();
|
||||||
|
mVBOVertices.destroy();
|
||||||
|
mVBONormals.destroy();
|
||||||
|
mVBOTextureCoords.destroy();
|
||||||
|
mVAO.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNbSpheres--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the sphere at the correct position and with the correct orientation
|
// Render the sphere at the correct position and with the correct orientation
|
||||||
|
@ -123,57 +157,125 @@ void Sphere::render(openglframework::Shader& shader,
|
||||||
shader.bind();
|
shader.bind();
|
||||||
|
|
||||||
// Set the model to camera matrix
|
// Set the model to camera matrix
|
||||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix);
|
||||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix);
|
||||||
|
|
||||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||||
// model-view matrix)
|
// model-view matrix)
|
||||||
|
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||||
const openglframework::Matrix3 normalMatrix =
|
const openglframework::Matrix3 normalMatrix =
|
||||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
// Set the vertex color
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
||||||
if (hasTexture()) {
|
shader.setVector4Uniform("vertexColor", color, false);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
// Bind the VAO
|
||||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
mVAO.bind();
|
||||||
if(hasTexture()) {
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
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 each part of the mesh
|
||||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
|
||||||
GL_UNSIGNED_INT, getIndicesPointer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableVertexAttribArray(vertexPositionLoc);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||||
if (hasTexture()) {
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
mVBONormals.unbind();
|
||||||
}
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
|
// Unbind the VAO
|
||||||
|
mVAO.unbind();
|
||||||
|
|
||||||
// Unbind the shader
|
// Unbind the shader
|
||||||
shader.unbind();
|
shader.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the transform matrix of the sphere
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
void Sphere::updateTransform() {
|
/// We create two VBOs (one for vertices and one for indices)
|
||||||
|
void Sphere::createVBOAndVAO() {
|
||||||
|
|
||||||
// Get the interpolated transform of the rigid body
|
// Create the VBO for the vertices data
|
||||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
mVBOVertices.create();
|
||||||
|
mVBOVertices.bind();
|
||||||
|
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
|
||||||
|
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
|
||||||
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
// Compute the transform used for rendering the sphere
|
// Create the VBO for the normals data
|
||||||
rp3d::decimal matrix[16];
|
mVBONormals.create();
|
||||||
transform.getOpenGLMatrix(matrix);
|
mVBONormals.bind();
|
||||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
|
||||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
|
||||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
mVBONormals.unbind();
|
||||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
|
||||||
|
|
||||||
// Apply the scaling matrix to have the correct sphere dimensions
|
if (hasTexture()) {
|
||||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
// 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(uint);
|
||||||
|
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 Sphere::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);
|
||||||
}
|
}
|
|
@ -29,9 +29,10 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "openglframework.h"
|
#include "openglframework.h"
|
||||||
#include "reactphysics3d.h"
|
#include "reactphysics3d.h"
|
||||||
|
#include "PhysicsObject.h"
|
||||||
|
|
||||||
// Class Sphere
|
// Class Sphere
|
||||||
class Sphere : public openglframework::Mesh {
|
class Sphere : public openglframework::Mesh, public PhysicsObject {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
|
@ -40,14 +41,35 @@ class Sphere : public openglframework::Mesh {
|
||||||
/// Radius of the sphere
|
/// Radius of the sphere
|
||||||
float mRadius;
|
float mRadius;
|
||||||
|
|
||||||
/// Rigid body used to simulate the dynamics of the sphere
|
|
||||||
rp3d::CollisionBody* mRigidBody;
|
|
||||||
|
|
||||||
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
|
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
|
||||||
openglframework::Matrix4 mScalingMatrix;
|
openglframework::Matrix4 mScalingMatrix;
|
||||||
|
|
||||||
|
/// Previous transform (for interpolation)
|
||||||
|
rp3d::Transform mPreviousTransform;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the vertices data
|
||||||
|
static openglframework::VertexBufferObject mVBOVertices;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the normals data
|
||||||
|
static openglframework::VertexBufferObject mVBONormals;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the texture coords
|
||||||
|
static openglframework::VertexBufferObject mVBOTextureCoords;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the indices
|
||||||
|
static openglframework::VertexBufferObject mVBOIndices;
|
||||||
|
|
||||||
|
/// Vertex Array Object for the vertex data
|
||||||
|
static openglframework::VertexArrayObject mVAO;
|
||||||
|
|
||||||
|
// Total number of capsules created
|
||||||
|
static int totalNbSpheres;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
|
void createVBOAndVAO();
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
@ -63,28 +85,20 @@ class Sphere : public openglframework::Mesh {
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Sphere();
|
~Sphere();
|
||||||
|
|
||||||
/// Return a pointer to the collision body of the box
|
|
||||||
reactphysics3d::CollisionBody* getCollisionBody();
|
|
||||||
|
|
||||||
/// Return a pointer to the rigid body of the box
|
|
||||||
reactphysics3d::RigidBody* getRigidBody();
|
|
||||||
|
|
||||||
/// Update the transform matrix of the sphere
|
|
||||||
void updateTransform();
|
|
||||||
|
|
||||||
/// Render the sphere at the correct position and with the correct orientation
|
/// Render the sphere at the correct position and with the correct orientation
|
||||||
void render(openglframework::Shader& shader,
|
void render(openglframework::Shader& shader,
|
||||||
const openglframework::Matrix4& worldToCameraMatrix);
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return a pointer to the collision body of the box
|
// Update the transform matrix of the object
|
||||||
inline rp3d::CollisionBody* Sphere::getCollisionBody() {
|
inline void Sphere::updateTransform(float interpolationFactor) {
|
||||||
return mRigidBody;
|
mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix);
|
||||||
}
|
|
||||||
|
|
||||||
// Return a pointer to the rigid body of the box
|
|
||||||
inline rp3d::RigidBody* Sphere::getRigidBody() {
|
|
||||||
return dynamic_cast<rp3d::RigidBody*>(mRigidBody);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
183
testbed/common/VisualContactPoint.cpp
Normal file
183
testbed/common/VisualContactPoint.cpp
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* 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 "VisualContactPoint.h"
|
||||||
|
|
||||||
|
// Initialization of static variables
|
||||||
|
openglframework::VertexBufferObject VisualContactPoint::mVBOVertices(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject VisualContactPoint::mVBONormals(GL_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexBufferObject VisualContactPoint::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
openglframework::VertexArrayObject VisualContactPoint::mVAO;
|
||||||
|
int VisualContactPoint::mNbTotalPoints = 0;
|
||||||
|
openglframework::Mesh VisualContactPoint::mMesh;
|
||||||
|
bool VisualContactPoint::mStaticDataCreated = false;
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position,
|
||||||
|
const std::string& meshFolderPath)
|
||||||
|
: mColor(1.0f, 0.0f, 0.0f, 1.0f) {
|
||||||
|
|
||||||
|
// Initialize the position where the mesh will be rendered
|
||||||
|
translateWorld(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
VisualContactPoint::~VisualContactPoint() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load and initialize the mesh for all the contact points
|
||||||
|
void VisualContactPoint::createStaticData(const std::string& meshFolderPath) {
|
||||||
|
|
||||||
|
if (mStaticDataCreated) return;
|
||||||
|
|
||||||
|
// Load the mesh from a file
|
||||||
|
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", mMesh);
|
||||||
|
|
||||||
|
// Calculate the normals of the mesh
|
||||||
|
mMesh.calculateNormals();
|
||||||
|
|
||||||
|
mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS);
|
||||||
|
|
||||||
|
createVBOAndVAO();
|
||||||
|
|
||||||
|
mStaticDataCreated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy the mesh for the contact points
|
||||||
|
void VisualContactPoint::destroyStaticData() {
|
||||||
|
|
||||||
|
if (!mStaticDataCreated) return;
|
||||||
|
|
||||||
|
// Destroy the VBOs and VAO
|
||||||
|
mVBOIndices.destroy();
|
||||||
|
mVBOVertices.destroy();
|
||||||
|
mVBONormals.destroy();
|
||||||
|
mVAO.destroy();
|
||||||
|
|
||||||
|
mMesh.destroy();
|
||||||
|
|
||||||
|
mStaticDataCreated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the sphere at the correct position and with the correct orientation
|
||||||
|
void VisualContactPoint::render(openglframework::Shader& shader,
|
||||||
|
const openglframework::Matrix4& worldToCameraMatrix) {
|
||||||
|
|
||||||
|
// Bind the VAO
|
||||||
|
mVAO.bind();
|
||||||
|
|
||||||
|
// Bind the shader
|
||||||
|
shader.bind();
|
||||||
|
|
||||||
|
mVBOVertices.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);
|
||||||
|
|
||||||
|
// 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<mMesh.getNbParts(); i++) {
|
||||||
|
glDrawElements(GL_TRIANGLES, mMesh.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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
|
/// We create two VBOs (one for vertices and one for indices)
|
||||||
|
void VisualContactPoint::createVBOAndVAO() {
|
||||||
|
|
||||||
|
// Create the VBO for the vertices data
|
||||||
|
mVBOVertices.create();
|
||||||
|
mVBOVertices.bind();
|
||||||
|
size_t sizeVertices = mMesh.getVertices().size() * sizeof(openglframework::Vector3);
|
||||||
|
mVBOVertices.copyDataIntoVBO(sizeVertices, mMesh.getVerticesPointer(), GL_STATIC_DRAW);
|
||||||
|
mVBOVertices.unbind();
|
||||||
|
|
||||||
|
// Create the VBO for the normals data
|
||||||
|
mVBONormals.create();
|
||||||
|
mVBONormals.bind();
|
||||||
|
size_t sizeNormals = mMesh.getNormals().size() * sizeof(openglframework::Vector3);
|
||||||
|
mVBONormals.copyDataIntoVBO(sizeNormals, mMesh.getNormalsPointer(), GL_STATIC_DRAW);
|
||||||
|
mVBONormals.unbind();
|
||||||
|
|
||||||
|
// Create th VBO for the indices data
|
||||||
|
mVBOIndices.create();
|
||||||
|
mVBOIndices.bind();
|
||||||
|
size_t sizeIndices = mMesh.getIndices(0).size() * sizeof(uint);
|
||||||
|
mVBOIndices.copyDataIntoVBO(sizeIndices, mMesh.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();
|
||||||
|
|
||||||
|
// Bind the VBO of indices
|
||||||
|
mVBOIndices.bind();
|
||||||
|
|
||||||
|
// Unbind the VAO
|
||||||
|
mVAO.unbind();
|
||||||
|
}
|
|
@ -29,7 +29,7 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "openglframework.h"
|
#include "openglframework.h"
|
||||||
|
|
||||||
const float VISUAL_CONTACT_POINT_RADIUS = 0.1f;
|
const float VISUAL_CONTACT_POINT_RADIUS = 0.2f;
|
||||||
|
|
||||||
// Class VisualContactPoint
|
// Class VisualContactPoint
|
||||||
class VisualContactPoint : public openglframework::Object3D {
|
class VisualContactPoint : public openglframework::Object3D {
|
||||||
|
@ -44,8 +44,26 @@ class VisualContactPoint : public openglframework::Object3D {
|
||||||
/// Sphere mesh for the visual contact point
|
/// Sphere mesh for the visual contact point
|
||||||
static openglframework::Mesh mMesh;
|
static openglframework::Mesh mMesh;
|
||||||
|
|
||||||
/// True if the mesh has been initialized
|
/// Vertex Buffer Object for the vertices data
|
||||||
static bool mIsMeshInitialized;
|
static openglframework::VertexBufferObject mVBOVertices;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the normals data
|
||||||
|
static openglframework::VertexBufferObject mVBONormals;
|
||||||
|
|
||||||
|
/// Vertex Buffer Object for the indices
|
||||||
|
static openglframework::VertexBufferObject mVBOIndices;
|
||||||
|
|
||||||
|
/// Vertex Array Object for the vertex data
|
||||||
|
static openglframework::VertexArrayObject mVAO;
|
||||||
|
|
||||||
|
/// True if static data (VBO, VAO) has been created already
|
||||||
|
static bool mStaticDataCreated;
|
||||||
|
|
||||||
|
/// Color
|
||||||
|
openglframework::Color mColor;
|
||||||
|
|
||||||
|
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
|
static void createVBOAndVAO();
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
|
@ -54,7 +72,8 @@ class VisualContactPoint : public openglframework::Object3D {
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
VisualContactPoint(const openglframework::Vector3& position);
|
VisualContactPoint(const openglframework::Vector3& position,
|
||||||
|
const std::string &meshFolderPath);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~VisualContactPoint();
|
~VisualContactPoint();
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 109 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user