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()
|
||||
|
||||
# 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(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
|
||||
|
@ -142,10 +142,10 @@ SET (REACTPHYSICS3D_SOURCES
|
|||
# Create the library
|
||||
ADD_LIBRARY (reactphysics3d STATIC ${REACTPHYSICS3D_SOURCES})
|
||||
|
||||
# If we need to compile the examples
|
||||
IF(COMPILE_EXAMPLES)
|
||||
add_subdirectory(examples/)
|
||||
ENDIF(COMPILE_EXAMPLES)
|
||||
# If we need to compile the testbed application
|
||||
IF(COMPILE_TESTBED)
|
||||
add_subdirectory(testbed/)
|
||||
ENDIF(COMPILE_TESTBED)
|
||||
|
||||
# If we need to compile the 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
|
||||
Body& operator=(const Body& body);
|
||||
|
||||
/// Set the variable to know whether or not the body is sleeping
|
||||
virtual void setIsSleeping(bool isSleeping);
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
@ -105,6 +102,9 @@ class Body {
|
|||
/// Set whether or not the body is allowed to go to sleep
|
||||
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
|
||||
bool isSleeping() const;
|
||||
|
||||
|
|
|
@ -41,8 +41,6 @@ CollisionBody::CollisionBody(const Transform& transform, CollisionWorld& world,
|
|||
: Body(id), mType(DYNAMIC), mTransform(transform), mProxyCollisionShapes(NULL),
|
||||
mNbCollisionShapes(0), mContactManifoldsList(NULL), mWorld(world) {
|
||||
|
||||
// Initialize the old transform
|
||||
mOldTransform = transform;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
|
|
@ -73,9 +73,6 @@ class CollisionBody : public Body {
|
|||
/// Position and orientation of the body
|
||||
Transform mTransform;
|
||||
|
||||
/// Last position and orientation of the body
|
||||
Transform mOldTransform;
|
||||
|
||||
/// First element of the linked list of proxy collision shapes of this body
|
||||
ProxyShape* mProxyCollisionShapes;
|
||||
|
||||
|
@ -102,9 +99,6 @@ class CollisionBody : public Body {
|
|||
/// Remove all the collision shapes
|
||||
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)
|
||||
virtual void updateBroadPhaseState() const;
|
||||
|
||||
|
@ -138,7 +132,7 @@ class CollisionBody : public Body {
|
|||
const Transform& getTransform() const;
|
||||
|
||||
/// Set the current position and orientation
|
||||
void setTransform(const Transform& transform);
|
||||
virtual void setTransform(const Transform& transform);
|
||||
|
||||
/// Add a collision shape to the body.
|
||||
virtual ProxyShape* addCollisionShape(const CollisionShape& collisionShape,
|
||||
|
@ -241,12 +235,6 @@ inline void CollisionBody::setTransform(const Transform& transform) {
|
|||
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 A pointer to the first element of the linked-list with the contact
|
||||
|
|
|
@ -265,6 +265,64 @@ void RigidBody::removeCollisionShape(const ProxyShape* proxyShape) {
|
|||
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
|
||||
// the collision shapes attached to the body.
|
||||
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)
|
||||
virtual void updateBroadPhaseState() const;
|
||||
|
||||
/// Set the variable to know whether or not the body is sleeping
|
||||
virtual void setIsSleeping(bool isSleeping);
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
@ -134,6 +131,9 @@ class RigidBody : public CollisionBody {
|
|||
/// Set the type of the body (static, kinematic or dynamic)
|
||||
void setType(BodyType type);
|
||||
|
||||
/// Set the current position and orientation
|
||||
virtual void setTransform(const Transform& transform);
|
||||
|
||||
/// Return the mass of the body
|
||||
decimal getMass() const;
|
||||
|
||||
|
@ -149,6 +149,9 @@ class RigidBody : public CollisionBody {
|
|||
/// Set the angular velocity.
|
||||
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)
|
||||
const Matrix3x3& getInertiaTensorLocal() const;
|
||||
|
||||
|
@ -252,20 +255,6 @@ inline Vector3 RigidBody::getAngularVelocity() const {
|
|||
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 3x3 inertia tensor matrix of the body (in local-space coordinates)
|
||||
|
@ -310,22 +299,6 @@ inline Matrix3x3 RigidBody::getInertiaTensorInverseWorld() const {
|
|||
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 is applied to the body
|
||||
|
|
|
@ -142,9 +142,6 @@ void DynamicsWorld::update(decimal timeStep) {
|
|||
|
||||
// Reset the external force and torque applied to the bodies
|
||||
resetBodiesForceAndTorque();
|
||||
|
||||
// Compute and set the interpolation factor to all the bodies
|
||||
setInterpolationFactorToAllBodies();
|
||||
}
|
||||
|
||||
// Integrate position and orientation of the rigid bodies.
|
||||
|
@ -331,9 +328,6 @@ void DynamicsWorld::integrateRigidBodiesVelocities() {
|
|||
mConstrainedAngularVelocities[indexBody] *= clamp(angularDamping, decimal(0.0),
|
||||
decimal(1.0));
|
||||
|
||||
// Update the old Transform of the body
|
||||
bodies[b]->updateOldTransform();
|
||||
|
||||
indexBody++;
|
||||
}
|
||||
}
|
||||
|
@ -958,3 +952,23 @@ void DynamicsWorld::testCollision(CollisionCallback* callback) {
|
|||
// Perform the collision detection and report contacts
|
||||
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
|
||||
virtual ~DynamicsWorld();
|
||||
|
||||
/// Start the physics simulation
|
||||
void start();
|
||||
|
||||
/// Stop the physics simulation
|
||||
void stop();
|
||||
|
||||
/// Update the physics simulation
|
||||
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
|
||||
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
|
||||
void setNbIterationsPositionSolver(uint nbIterations);
|
||||
|
||||
|
@ -226,6 +226,9 @@ class DynamicsWorld : public CollisionWorld {
|
|||
/// Return the gravity vector of the world
|
||||
Vector3 getGravity() const;
|
||||
|
||||
/// Set the gravity vector of the world
|
||||
void setGravity(Vector3& gravity);
|
||||
|
||||
/// Return if the gravity is on
|
||||
bool isGravityEnabled() const;
|
||||
|
||||
|
@ -238,9 +241,6 @@ class DynamicsWorld : public CollisionWorld {
|
|||
/// Return the number of joints in the world
|
||||
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
|
||||
std::set<RigidBody*>::iterator getRigidBodiesBeginIterator();
|
||||
|
||||
|
@ -297,6 +297,9 @@ class DynamicsWorld : public CollisionWorld {
|
|||
/// Test and report collisions between all shapes of the world
|
||||
virtual void testCollision(CollisionCallback* callback);
|
||||
|
||||
/// Return the list of all contacts of the world
|
||||
std::vector<const ContactManifold*> getContactsList() const;
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
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
|
||||
/**
|
||||
* @param nbIterations Number of iterations for the velocity solver
|
||||
|
@ -321,6 +329,11 @@ inline void DynamicsWorld::setNbIterationsVelocitySolver(uint 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
|
||||
/**
|
||||
* @param nbIterations Number of iterations for the position solver
|
||||
|
@ -375,6 +388,14 @@ inline Vector3 DynamicsWorld::getGravity() const {
|
|||
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 True if the gravity is enabled in the world
|
||||
|
|
|
@ -54,7 +54,9 @@ Vector2::~Vector2() {
|
|||
Vector2 Vector2::getUnit() const {
|
||||
decimal lengthVector = length();
|
||||
|
||||
assert(lengthVector > MACHINE_EPSILON);
|
||||
if (lengthVector < MACHINE_EPSILON) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Compute and return the unit vector
|
||||
decimal lengthInv = decimal(1.0) / lengthVector;
|
||||
|
|
|
@ -178,7 +178,9 @@ inline decimal Vector2::dot(const Vector2& vector) const {
|
|||
// Normalize the vector
|
||||
inline void Vector2::normalize() {
|
||||
decimal l = length();
|
||||
assert(l > std::numeric_limits<decimal>::epsilon());
|
||||
if (l < MACHINE_EPSILON) {
|
||||
return;
|
||||
}
|
||||
x /= l;
|
||||
y /= l;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,9 @@ Vector3::~Vector3() {
|
|||
Vector3 Vector3::getUnit() const {
|
||||
decimal lengthVector = length();
|
||||
|
||||
assert(lengthVector > MACHINE_EPSILON);
|
||||
if (lengthVector < MACHINE_EPSILON) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Compute and return the unit vector
|
||||
decimal lengthInv = decimal(1.0) / lengthVector;
|
||||
|
|
|
@ -193,7 +193,9 @@ inline Vector3 Vector3::cross(const Vector3& vector) const {
|
|||
// Normalize the vector
|
||||
inline void Vector3::normalize() {
|
||||
decimal l = length();
|
||||
assert(l > std::numeric_limits<decimal>::epsilon());
|
||||
if (l < MACHINE_EPSILON) {
|
||||
return;
|
||||
}
|
||||
x /= l;
|
||||
y /= 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
|
||||
openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER);
|
||||
openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
|
||||
bool Box::areVBOsCreated = false;
|
||||
VertexData Box::mCubeVertices[8] = {
|
||||
{openglframework::Vector3(1,1,1),openglframework::Vector3(1,1,1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(-1,1,1),openglframework::Vector3(-1,1,1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(-1,-1,1),openglframework::Vector3(-1,-1,1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(1,-1,1),openglframework::Vector3(1,-1,1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(1,-1,-1),openglframework::Vector3(1,-1,-1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(-1,-1,-1),openglframework::Vector3(-1,-1,-1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(-1,1,-1),openglframework::Vector3(-1,1,-1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(1,1,-1),openglframework::Vector3(1,1,-1),openglframework::Color(1,0,0,1)}
|
||||
openglframework::VertexBufferObject Box::mVBONormals(GL_ARRAY_BUFFER);
|
||||
openglframework::VertexArrayObject Box::mVAO;
|
||||
int Box::totalNbBoxes = 0;
|
||||
GLfloat Box::mCubeVertices[108] = {
|
||||
-1.0f,-1.0f,-1.0f, // triangle 1 : begin
|
||||
-1.0f,-1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 1.0f, // triangle 1 : end
|
||||
1.0f, 1.0f,-1.0f, // triangle 2 : begin
|
||||
-1.0f,-1.0f,-1.0f,
|
||||
-1.0f, 1.0f,-1.0f, // triangle 2 : end
|
||||
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
|
||||
Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position,
|
||||
reactphysics3d::CollisionWorld* world)
|
||||
: openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
|
||||
: openglframework::Object3D() {
|
||||
|
||||
// Initialize the size of the box
|
||||
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::Transform transform(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transform;
|
||||
|
||||
// Create a rigid body in the dynamics world
|
||||
mRigidBody = world->createCollisionBody(transform);
|
||||
mBody = world->createCollisionBody(transform);
|
||||
|
||||
// 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 (!areVBOsCreated) {
|
||||
if (totalNbBoxes == 0) {
|
||||
|
||||
// Create the Vertex Buffer
|
||||
createVBO();
|
||||
createVBOAndVAO();
|
||||
}
|
||||
|
||||
totalNbBoxes++;
|
||||
|
||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||
}
|
||||
|
||||
// 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)
|
||||
: openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
|
||||
: openglframework::Object3D() {
|
||||
|
||||
// Initialize the size of the box
|
||||
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::Transform transform(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transform;
|
||||
|
||||
// Create a rigid body in the dynamics world
|
||||
rp3d::RigidBody* body = world->createRigidBody(transform);
|
||||
|
||||
// Add the collision shape to the body
|
||||
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
||||
|
||||
mRigidBody = body;
|
||||
mBody = body;
|
||||
|
||||
// If the Vertex Buffer object has not been created yet
|
||||
if (!areVBOsCreated) {
|
||||
if (totalNbBoxes == 0) {
|
||||
|
||||
// Create the Vertex Buffer
|
||||
createVBO();
|
||||
createVBOAndVAO();
|
||||
}
|
||||
|
||||
totalNbBoxes++;
|
||||
|
||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
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
|
||||
void Box::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
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
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);
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||
|
||||
// Set the vertex color
|
||||
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
||||
shader.setVector4Uniform("vertexColor", color);
|
||||
openglframework::Color currentColor = mBody->isSleeping() ? mSleepingColor : mColor;
|
||||
openglframework::Vector4 color(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
|
||||
shader.setVector4Uniform("vertexColor", color, false);
|
||||
|
||||
// Bind the vertices VBO
|
||||
mVBOVertices.bind();
|
||||
// Get the location of shader attribute variables
|
||||
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
|
||||
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false);
|
||||
|
||||
// Enable the vertex, normal and color arrays
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glEnableVertexAttribArray(vertexPositionLoc);
|
||||
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, NULL);
|
||||
|
||||
// Set the arrays pointers
|
||||
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));
|
||||
mVBONormals.bind();
|
||||
|
||||
// Bind the indices VBO
|
||||
mVBOIndices.bind();
|
||||
if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc);
|
||||
if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, NULL);
|
||||
|
||||
// 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();
|
||||
mVBOIndices.unbind();
|
||||
|
||||
// Disable the arrays
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
|
||||
// Unbind the shader
|
||||
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.
|
||||
/// We create two VBOs (one for vertices and one for indices) to render all the boxes
|
||||
/// in the simulation.
|
||||
void Box::createVBO() {
|
||||
void Box::createVBOAndVAO() {
|
||||
|
||||
// Create the VBOs
|
||||
// Create the VBO for the vertices data
|
||||
mVBOVertices.create();
|
||||
mVBOIndices.create();
|
||||
|
||||
// Copy the data into the VBOs
|
||||
mVBOVertices.bind();
|
||||
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
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
|
||||
// Structure VertexData
|
||||
struct VertexData {
|
||||
|
||||
/// Vertex position
|
||||
openglframework::Vector3 position;
|
||||
|
||||
/// Vertex normal
|
||||
openglframework::Vector3 normal;
|
||||
|
||||
// Vertex color
|
||||
openglframework::Color color;
|
||||
};
|
||||
#include "PhysicsObject.h"
|
||||
|
||||
// Class Box
|
||||
class Box : public openglframework::Object3D {
|
||||
class Box : public openglframework::Object3D, public PhysicsObject {
|
||||
|
||||
private :
|
||||
|
||||
|
@ -53,34 +41,31 @@ class Box : public openglframework::Object3D {
|
|||
/// Size of each side of the box
|
||||
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)
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
/// Vertex Buffer Object for the vertices data used to render the box with OpenGL
|
||||
static openglframework::VertexBufferObject mVBOVertices;
|
||||
|
||||
/// Vertex Buffer Object for the indices used to render the box with OpenGL
|
||||
static openglframework::VertexBufferObject mVBOIndices;
|
||||
/// Vertex Buffer Object for the normales used to render the box with OpenGL
|
||||
static openglframework::VertexBufferObject mVBONormals;
|
||||
|
||||
/// Vertex data for each vertex of the cube (used to render the box)
|
||||
static VertexData mCubeVertices[8];
|
||||
/// Vertex Array Object for the vertex data
|
||||
static openglframework::VertexArrayObject mVAO;
|
||||
|
||||
/// Indices of the cube (used to render the box)
|
||||
static GLuint mCubeIndices[36];
|
||||
/// Vertices coordinates of the triangles of the box
|
||||
static GLfloat mCubeVertices[108];
|
||||
|
||||
/// True if the VBOs have already been created
|
||||
static bool areVBOsCreated;
|
||||
/// Vertices normals of the triangles of the box
|
||||
static GLfloat mCubeNormals[108];
|
||||
|
||||
/// Main color of the box
|
||||
openglframework::Color mColor;
|
||||
/// Total number of boxes created
|
||||
static int totalNbBoxes;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Create a Vertex Buffer Object to render to box with OpenGL
|
||||
static void createVBO();
|
||||
/// Create a the VAO and VBOs to render to box with OpenGL
|
||||
static void createVBOAndVAO();
|
||||
|
||||
public :
|
||||
|
||||
|
@ -97,35 +82,20 @@ class Box : public openglframework::Object3D {
|
|||
/// Destructor
|
||||
~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
|
||||
void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
||||
/// Set the color of the box
|
||||
void setColor(const openglframework::Color& color);
|
||||
/// 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
|
||||
inline rp3d::CollisionBody* Box::getCollisionBody() {
|
||||
return mRigidBody;
|
||||
// Update the transform matrix of the object
|
||||
inline void Box::updateTransform(float interpolationFactor) {
|
||||
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
|
|
@ -26,6 +26,13 @@
|
|||
// Libraries
|
||||
#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
|
||||
Capsule::Capsule(float radius, float height, const openglframework::Vector3& position,
|
||||
reactphysics3d::CollisionWorld* world,
|
||||
|
@ -57,13 +64,22 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
|
|||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transform;
|
||||
|
||||
// Create a rigid body corresponding in the dynamics world
|
||||
mRigidBody = world->createCollisionBody(transform);
|
||||
mBody = world->createCollisionBody(transform);
|
||||
|
||||
// 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;
|
||||
|
||||
// Create the VBOs and VAO
|
||||
if (totalNbCapsules == 0) {
|
||||
createVBOAndVAO();
|
||||
}
|
||||
|
||||
totalNbCapsules++;
|
||||
}
|
||||
|
||||
// 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
|
||||
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
||||
|
||||
mRigidBody = body;
|
||||
mBody = body;
|
||||
|
||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||
|
||||
// Create the VBOs and VAO
|
||||
if (totalNbCapsules == 0) {
|
||||
createVBOAndVAO();
|
||||
}
|
||||
|
||||
totalNbCapsules++;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Capsule::~Capsule() {
|
||||
|
||||
if (totalNbCapsules == 1) {
|
||||
|
||||
// Destroy the mesh
|
||||
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
|
||||
|
@ -123,57 +158,126 @@ void Capsule::render(openglframework::Shader& shader,
|
|||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
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);
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
// Set the vertex color
|
||||
openglframework::Color currentColor = mBody->isSleeping() ? mSleepingColor : mColor;
|
||||
openglframework::Vector4 color(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
|
||||
shader.setVector4Uniform("vertexColor", color, false);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
||||
if(hasTexture()) {
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
||||
}
|
||||
// Bind the VAO
|
||||
mVAO.bind();
|
||||
|
||||
mVBOVertices.bind();
|
||||
|
||||
// Get the location of shader attribute variables
|
||||
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
|
||||
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false);
|
||||
|
||||
glEnableVertexAttribArray(vertexPositionLoc);
|
||||
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
|
||||
mVBONormals.bind();
|
||||
|
||||
if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc);
|
||||
|
||||
// For each part of the mesh
|
||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
||||
GL_UNSIGNED_INT, getIndicesPointer());
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
|
||||
}
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
glDisableVertexAttribArray(vertexPositionLoc);
|
||||
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||
|
||||
mVBONormals.unbind();
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Update the transform matrix of the sphere
|
||||
void Capsule::updateTransform() {
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
/// We create two VBOs (one for vertices and one for indices)
|
||||
void Capsule::createVBOAndVAO() {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
// Create the VBO for the vertices data
|
||||
mVBOVertices.create();
|
||||
mVBOVertices.bind();
|
||||
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
|
||||
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Compute the transform used for rendering the sphere
|
||||
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]);
|
||||
// Create the VBO for the normals data
|
||||
mVBONormals.create();
|
||||
mVBONormals.bind();
|
||||
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
|
||||
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
|
||||
mVBONormals.unbind();
|
||||
|
||||
// Apply the scaling matrix to have the correct sphere dimensions
|
||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
||||
if (hasTexture()) {
|
||||
// Create the VBO for the texture co data
|
||||
mVBOTextureCoords.create();
|
||||
mVBOTextureCoords.bind();
|
||||
size_t sizeTextureCoords = mUVs.size() * sizeof(openglframework::Vector2);
|
||||
mVBOTextureCoords.copyDataIntoVBO(sizeTextureCoords, getUVTextureCoordinatesPointer(), GL_STATIC_DRAW);
|
||||
mVBOTextureCoords.unbind();
|
||||
}
|
||||
|
||||
// Create th VBO for the indices data
|
||||
mVBOIndices.create();
|
||||
mVBOIndices.bind();
|
||||
size_t sizeIndices = mIndices[0].size() * sizeof(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
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
#include "PhysicsObject.h"
|
||||
|
||||
// Class Sphere
|
||||
class Capsule : public openglframework::Mesh {
|
||||
class Capsule : public openglframework::Mesh, public PhysicsObject {
|
||||
|
||||
private :
|
||||
|
||||
|
@ -43,14 +44,35 @@ class Capsule : public openglframework::Mesh {
|
|||
/// Height of the capsule
|
||||
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)
|
||||
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 -------------------- //
|
||||
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
void createVBOAndVAO();
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
@ -67,28 +89,20 @@ class Capsule : public openglframework::Mesh {
|
|||
/// Destructor
|
||||
~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
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
||||
/// Set the position of the box
|
||||
void resetTransform(const rp3d::Transform& transform);
|
||||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor);
|
||||
};
|
||||
|
||||
// Return a pointer to the collision body of the box
|
||||
inline rp3d::CollisionBody* Capsule::getCollisionBody() {
|
||||
return mRigidBody;
|
||||
}
|
||||
|
||||
// Return a pointer to the rigid body of the box
|
||||
inline rp3d::RigidBody* Capsule::getRigidBody() {
|
||||
return dynamic_cast<rp3d::RigidBody*>(mRigidBody);
|
||||
// Update the transform matrix of the object
|
||||
inline void Capsule::updateTransform(float interpolationFactor) {
|
||||
mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -26,6 +26,13 @@
|
|||
// Libraries
|
||||
#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
|
||||
Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
|
||||
reactphysics3d::CollisionWorld* world,
|
||||
|
@ -57,13 +64,22 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
|
|||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transform;
|
||||
|
||||
// Create a rigid body corresponding to the cone in the dynamics world
|
||||
mRigidBody = world->createCollisionBody(transform);
|
||||
mBody = world->createCollisionBody(transform);
|
||||
|
||||
// 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;
|
||||
|
||||
// Create the VBOs and VAO
|
||||
if (totalNbCones == 0) {
|
||||
createVBOAndVAO();
|
||||
}
|
||||
|
||||
totalNbCones++;
|
||||
}
|
||||
|
||||
// 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
|
||||
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
||||
|
||||
mRigidBody = body;
|
||||
mBody = body;
|
||||
|
||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||
|
||||
// Create the VBOs and VAO
|
||||
if (totalNbCones == 0) {
|
||||
createVBOAndVAO();
|
||||
}
|
||||
|
||||
totalNbCones++;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Cone::~Cone() {
|
||||
|
||||
if (totalNbCones == 1) {
|
||||
// Destroy the mesh
|
||||
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
|
||||
|
@ -123,57 +157,126 @@ void Cone::render(openglframework::Shader& shader,
|
|||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
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);
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
// Set the vertex color
|
||||
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
||||
shader.setVector4Uniform("vertexColor", color, false);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
||||
if(hasTexture()) {
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
||||
}
|
||||
// Bind the VAO
|
||||
mVAO.bind();
|
||||
|
||||
mVBOVertices.bind();
|
||||
|
||||
// Get the location of shader attribute variables
|
||||
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
|
||||
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false);
|
||||
|
||||
glEnableVertexAttribArray(vertexPositionLoc);
|
||||
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
|
||||
mVBONormals.bind();
|
||||
|
||||
if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc);
|
||||
|
||||
// For each part of the mesh
|
||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
||||
GL_UNSIGNED_INT, getIndicesPointer());
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
|
||||
}
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
glDisableVertexAttribArray(vertexPositionLoc);
|
||||
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||
|
||||
mVBONormals.unbind();
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Update the transform matrix of the cone
|
||||
void Cone::updateTransform() {
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
/// We create two VBOs (one for vertices and one for indices)
|
||||
void Cone::createVBOAndVAO() {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
// Create the VBO for the vertices data
|
||||
mVBOVertices.create();
|
||||
mVBOVertices.bind();
|
||||
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
|
||||
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Compute the transform used for rendering the cone
|
||||
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]);
|
||||
// Create the VBO for the normals data
|
||||
mVBONormals.create();
|
||||
mVBONormals.bind();
|
||||
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
|
||||
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
|
||||
mVBONormals.unbind();
|
||||
|
||||
// Apply the scaling matrix to have the correct cone dimensions
|
||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
||||
if (hasTexture()) {
|
||||
// Create the VBO for the texture co data
|
||||
mVBOTextureCoords.create();
|
||||
mVBOTextureCoords.bind();
|
||||
size_t sizeTextureCoords = mUVs.size() * sizeof(openglframework::Vector2);
|
||||
mVBOTextureCoords.copyDataIntoVBO(sizeTextureCoords, getUVTextureCoordinatesPointer(), GL_STATIC_DRAW);
|
||||
mVBOTextureCoords.unbind();
|
||||
}
|
||||
|
||||
// Create th VBO for the indices data
|
||||
mVBOIndices.create();
|
||||
mVBOIndices.bind();
|
||||
size_t sizeIndices = mIndices[0].size() * sizeof(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
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
#include "PhysicsObject.h"
|
||||
|
||||
// Class Cone
|
||||
class Cone : public openglframework::Mesh {
|
||||
class Cone : public openglframework::Mesh, public PhysicsObject {
|
||||
|
||||
private :
|
||||
|
||||
|
@ -43,14 +44,35 @@ class Cone : public openglframework::Mesh {
|
|||
/// Height of the cone
|
||||
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)
|
||||
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 -------------------- //
|
||||
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
void createVBOAndVAO();
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
@ -66,28 +88,20 @@ class Cone : public openglframework::Mesh {
|
|||
/// Destructor
|
||||
~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
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
||||
/// Set the position of the box
|
||||
void resetTransform(const rp3d::Transform& transform);
|
||||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor);
|
||||
};
|
||||
|
||||
// Return a pointer to the collision body of the box
|
||||
inline rp3d::CollisionBody* Cone::getCollisionBody() {
|
||||
return mRigidBody;
|
||||
}
|
||||
|
||||
// Return a pointer to the rigid body of the box
|
||||
inline rp3d::RigidBody* Cone::getRigidBody() {
|
||||
return dynamic_cast<rp3d::RigidBody*>(mRigidBody);
|
||||
// Update the transform matrix of the object
|
||||
inline void Cone::updateTransform(float interpolationFactor) {
|
||||
mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -30,7 +30,9 @@
|
|||
ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
|
||||
reactphysics3d::CollisionWorld* world,
|
||||
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
|
||||
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this);
|
||||
|
@ -79,18 +81,25 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
|
|||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transform;
|
||||
|
||||
// Create a rigid body corresponding to the sphere in the dynamics world
|
||||
mRigidBody = world->createCollisionBody(transform);
|
||||
mBody = world->createCollisionBody(transform);
|
||||
|
||||
// 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
|
||||
ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass,
|
||||
reactphysics3d::DynamicsWorld* dynamicsWorld,
|
||||
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
|
||||
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
|
||||
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
||||
|
||||
mRigidBody = body;
|
||||
mBody = body;
|
||||
|
||||
// Create the VBOs and VAO
|
||||
createVBOAndVAO();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
@ -152,6 +164,13 @@ ConvexMesh::~ConvexMesh() {
|
|||
|
||||
// Destroy the mesh
|
||||
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
|
||||
|
@ -162,57 +181,125 @@ void ConvexMesh::render(openglframework::Shader& shader,
|
|||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
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);
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
// Set the vertex color
|
||||
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
||||
shader.setVector4Uniform("vertexColor", color, false);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
||||
if(hasTexture()) {
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
||||
}
|
||||
// Bind the VAO
|
||||
mVAO.bind();
|
||||
|
||||
mVBOVertices.bind();
|
||||
|
||||
// Get the location of shader attribute variables
|
||||
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
|
||||
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false);
|
||||
|
||||
glEnableVertexAttribArray(vertexPositionLoc);
|
||||
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
|
||||
mVBONormals.bind();
|
||||
|
||||
if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc);
|
||||
|
||||
// For each part of the mesh
|
||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
||||
GL_UNSIGNED_INT, getIndicesPointer());
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
|
||||
}
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
glDisableVertexAttribArray(vertexPositionLoc);
|
||||
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||
|
||||
mVBONormals.unbind();
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Update the transform matrix of the sphere
|
||||
void ConvexMesh::updateTransform() {
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
/// We create two VBOs (one for vertices and one for indices)
|
||||
void ConvexMesh::createVBOAndVAO() {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
// Create the VBO for the vertices data
|
||||
mVBOVertices.create();
|
||||
mVBOVertices.bind();
|
||||
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
|
||||
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Compute the transform used for rendering the sphere
|
||||
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]);
|
||||
// Create the VBO for the normals data
|
||||
mVBONormals.create();
|
||||
mVBONormals.bind();
|
||||
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
|
||||
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
|
||||
mVBONormals.unbind();
|
||||
|
||||
// Apply the scaling matrix to have the correct sphere dimensions
|
||||
mTransformMatrix = newMatrix;
|
||||
if (hasTexture()) {
|
||||
// Create the VBO for the texture co data
|
||||
mVBOTextureCoords.create();
|
||||
mVBOTextureCoords.bind();
|
||||
size_t sizeTextureCoords = mUVs.size() * sizeof(openglframework::Vector2);
|
||||
mVBOTextureCoords.copyDataIntoVBO(sizeTextureCoords, getUVTextureCoordinatesPointer(), GL_STATIC_DRAW);
|
||||
mVBOTextureCoords.unbind();
|
||||
}
|
||||
|
||||
// Create th VBO for the indices data
|
||||
mVBOIndices.create();
|
||||
mVBOIndices.bind();
|
||||
size_t sizeIndices = mIndices[0].size() * sizeof(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
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
#include "PhysicsObject.h"
|
||||
|
||||
// Class ConvexMesh
|
||||
class ConvexMesh : public openglframework::Mesh {
|
||||
class ConvexMesh : public openglframework::Mesh, public PhysicsObject {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Rigid body used to simulate the dynamics of the mesh
|
||||
rp3d::CollisionBody* mRigidBody;
|
||||
/// Previous transform (for interpolation)
|
||||
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 -------------------- //
|
||||
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
void createVBOAndVAO();
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
@ -57,28 +76,20 @@ class ConvexMesh : public openglframework::Mesh {
|
|||
/// Destructor
|
||||
~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
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
||||
/// Set the position of the box
|
||||
void resetTransform(const rp3d::Transform& transform);
|
||||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor);
|
||||
};
|
||||
|
||||
// Return a pointer to the collision body of the box
|
||||
inline rp3d::CollisionBody* ConvexMesh::getCollisionBody() {
|
||||
return mRigidBody;
|
||||
}
|
||||
|
||||
// Return a pointer to the rigid body of the box
|
||||
inline rp3d::RigidBody* ConvexMesh::getRigidBody() {
|
||||
return dynamic_cast<rp3d::RigidBody*>(mRigidBody);
|
||||
// Update the transform matrix of the object
|
||||
inline void ConvexMesh::updateTransform(float interpolationFactor) {
|
||||
mTransformMatrix = computeTransform(interpolationFactor, openglframework::Matrix4::identity());
|
||||
}
|
||||
|
||||
#endif
|
|
@ -26,6 +26,13 @@
|
|||
// Libraries
|
||||
#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
|
||||
Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position,
|
||||
reactphysics3d::CollisionWorld* world,
|
||||
|
@ -57,13 +64,22 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
|
|||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transform;
|
||||
|
||||
// Create a rigid body corresponding to the cylinder in the dynamics world
|
||||
mRigidBody = world->createCollisionBody(transform);
|
||||
mBody = world->createCollisionBody(transform);
|
||||
|
||||
// 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;
|
||||
|
||||
// Create the VBOs and VAO
|
||||
if (totalNbCylinders == 0) {
|
||||
createVBOAndVAO();
|
||||
}
|
||||
|
||||
totalNbCylinders++;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
|
@ -105,14 +121,33 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
|
|||
|
||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||
|
||||
mRigidBody = body;
|
||||
mBody = body;
|
||||
|
||||
// Create the VBOs and VAO
|
||||
if (totalNbCylinders == 0) {
|
||||
createVBOAndVAO();
|
||||
}
|
||||
|
||||
totalNbCylinders++;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Cylinder::~Cylinder() {
|
||||
|
||||
if (totalNbCylinders == 1) {
|
||||
|
||||
// Destroy the mesh
|
||||
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
|
||||
|
@ -123,57 +158,125 @@ void Cylinder::render(openglframework::Shader& shader,
|
|||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
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);
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
// Set the vertex color
|
||||
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
||||
shader.setVector4Uniform("vertexColor", color, false);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
||||
if(hasTexture()) {
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
||||
}
|
||||
// Bind the VAO
|
||||
mVAO.bind();
|
||||
|
||||
mVBOVertices.bind();
|
||||
|
||||
// Get the location of shader attribute variables
|
||||
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
|
||||
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false);
|
||||
|
||||
glEnableVertexAttribArray(vertexPositionLoc);
|
||||
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
|
||||
mVBONormals.bind();
|
||||
|
||||
if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc);
|
||||
|
||||
// For each part of the mesh
|
||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
||||
GL_UNSIGNED_INT, getIndicesPointer());
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
|
||||
}
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
glDisableVertexAttribArray(vertexPositionLoc);
|
||||
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||
|
||||
mVBONormals.unbind();
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Update the transform matrix of the cylinder
|
||||
void Cylinder::updateTransform() {
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
/// We create two VBOs (one for vertices and one for indices)
|
||||
void Cylinder::createVBOAndVAO() {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
// Create the VBO for the vertices data
|
||||
mVBOVertices.create();
|
||||
mVBOVertices.bind();
|
||||
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
|
||||
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Compute the transform used for rendering the cylinder
|
||||
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]);
|
||||
// Create the VBO for the normals data
|
||||
mVBONormals.create();
|
||||
mVBONormals.bind();
|
||||
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
|
||||
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
|
||||
mVBONormals.unbind();
|
||||
|
||||
// Apply the scaling matrix to have the correct cylinder dimensions
|
||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
||||
if (hasTexture()) {
|
||||
// Create the VBO for the texture co data
|
||||
mVBOTextureCoords.create();
|
||||
mVBOTextureCoords.bind();
|
||||
size_t sizeTextureCoords = mUVs.size() * sizeof(openglframework::Vector2);
|
||||
mVBOTextureCoords.copyDataIntoVBO(sizeTextureCoords, getUVTextureCoordinatesPointer(), GL_STATIC_DRAW);
|
||||
mVBOTextureCoords.unbind();
|
||||
}
|
||||
|
||||
// Create th VBO for the indices data
|
||||
mVBOIndices.create();
|
||||
mVBOIndices.bind();
|
||||
size_t sizeIndices = mIndices[0].size() * sizeof(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
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
#include "PhysicsObject.h"
|
||||
|
||||
// Class Cylinder
|
||||
class Cylinder : public openglframework::Mesh {
|
||||
class Cylinder : public openglframework::Mesh, public PhysicsObject {
|
||||
|
||||
private :
|
||||
|
||||
|
@ -43,14 +44,35 @@ class Cylinder : public openglframework::Mesh {
|
|||
/// Height of the cylinder
|
||||
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)
|
||||
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 -------------------- //
|
||||
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
void createVBOAndVAO();
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
@ -66,28 +88,20 @@ class Cylinder : public openglframework::Mesh {
|
|||
/// Destructor
|
||||
~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
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
||||
/// Set the position of the box
|
||||
void resetTransform(const rp3d::Transform& transform);
|
||||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor);
|
||||
};
|
||||
|
||||
// Return a pointer to the collision body of the box
|
||||
inline rp3d::CollisionBody* Cylinder::getCollisionBody() {
|
||||
return mRigidBody;
|
||||
}
|
||||
|
||||
// Return a pointer to the rigid body of the box
|
||||
inline rp3d::RigidBody* Cylinder::getRigidBody() {
|
||||
return dynamic_cast<rp3d::RigidBody*>(mRigidBody);
|
||||
// Update the transform matrix of the object
|
||||
inline void Cylinder::updateTransform(float interpolationFactor) {
|
||||
mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -26,6 +26,13 @@
|
|||
// Libraries
|
||||
#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
|
||||
Dumbbell::Dumbbell(const openglframework::Vector3 &position,
|
||||
reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath)
|
||||
|
@ -64,6 +71,8 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
|
|||
rp3d::Quaternion initOrientation(angleAroundX, 0, 0);
|
||||
rp3d::Transform transformBody(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transformBody;
|
||||
|
||||
// Initial transform of the first sphere collision shape of the dumbbell (in local-space)
|
||||
rp3d::Transform transformSphereShape1(rp3d::Vector3(0, 4.0, 0), rp3d::Quaternion::identity());
|
||||
|
||||
|
@ -84,6 +93,13 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
|
|||
mBody = body;
|
||||
|
||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||
|
||||
// Create the VBOs and VAO
|
||||
if (totalNbDumbbells == 0) {
|
||||
createVBOAndVAO();
|
||||
}
|
||||
|
||||
totalNbDumbbells++;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
|
@ -142,13 +158,32 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
|
|||
mBody->addCollisionShape(cylinderCollisionShape, transformCylinderShape);
|
||||
|
||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||
|
||||
// Create the VBOs and VAO
|
||||
if (totalNbDumbbells == 0) {
|
||||
createVBOAndVAO();
|
||||
}
|
||||
|
||||
totalNbDumbbells++;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Dumbbell::~Dumbbell() {
|
||||
|
||||
if (totalNbDumbbells == 1) {
|
||||
|
||||
// Destroy the mesh
|
||||
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
|
||||
|
@ -159,58 +194,125 @@ void Dumbbell::render(openglframework::Shader& shader,
|
|||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
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);
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
// Set the vertex color
|
||||
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
||||
shader.setVector4Uniform("vertexColor", color, false);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
||||
if(hasTexture()) {
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
||||
}
|
||||
// Bind the VAO
|
||||
mVAO.bind();
|
||||
|
||||
mVBOVertices.bind();
|
||||
|
||||
// Get the location of shader attribute variables
|
||||
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
|
||||
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false);
|
||||
|
||||
glEnableVertexAttribArray(vertexPositionLoc);
|
||||
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
|
||||
mVBONormals.bind();
|
||||
|
||||
if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc);
|
||||
if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
|
||||
// For each part of the mesh
|
||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
||||
GL_UNSIGNED_INT, getIndicesPointer());
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
|
||||
}
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
glDisableVertexAttribArray(vertexPositionLoc);
|
||||
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||
|
||||
mVBONormals.unbind();
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Update the transform matrix of the sphere
|
||||
void Dumbbell::updateTransform() {
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
/// We create two VBOs (one for vertices and one for indices)
|
||||
void Dumbbell::createVBOAndVAO() {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mBody->getInterpolatedTransform();
|
||||
// Create the VBO for the vertices data
|
||||
mVBOVertices.create();
|
||||
mVBOVertices.bind();
|
||||
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
|
||||
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Compute the transform used for rendering the sphere
|
||||
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]);
|
||||
// Create the VBO for the normals data
|
||||
mVBONormals.create();
|
||||
mVBONormals.bind();
|
||||
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
|
||||
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
|
||||
mVBONormals.unbind();
|
||||
|
||||
// Apply the scaling matrix to have the correct sphere dimensions
|
||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
||||
if (hasTexture()) {
|
||||
// Create the VBO for the texture co data
|
||||
mVBOTextureCoords.create();
|
||||
mVBOTextureCoords.bind();
|
||||
size_t sizeTextureCoords = mUVs.size() * sizeof(openglframework::Vector2);
|
||||
mVBOTextureCoords.copyDataIntoVBO(sizeTextureCoords, getUVTextureCoordinatesPointer(), GL_STATIC_DRAW);
|
||||
mVBOTextureCoords.unbind();
|
||||
}
|
||||
|
||||
// Create th VBO for the indices data
|
||||
mVBOIndices.create();
|
||||
mVBOIndices.bind();
|
||||
size_t sizeIndices = mIndices[0].size() * sizeof(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
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
#include "PhysicsObject.h"
|
||||
|
||||
// Class Sphere
|
||||
class Dumbbell : public openglframework::Mesh {
|
||||
class Dumbbell : public openglframework::Mesh, public PhysicsObject {
|
||||
|
||||
private :
|
||||
|
||||
|
@ -40,14 +41,35 @@ class Dumbbell : public openglframework::Mesh {
|
|||
/// Radius of the spheres
|
||||
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)
|
||||
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 -------------------- //
|
||||
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
void createVBOAndVAO();
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
@ -64,28 +86,20 @@ class Dumbbell : public openglframework::Mesh {
|
|||
/// Destructor
|
||||
~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
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
||||
/// Set the position of the box
|
||||
void resetTransform(const rp3d::Transform& transform);
|
||||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor);
|
||||
};
|
||||
|
||||
// Return a pointer to the rigid body of the sphere
|
||||
inline rp3d::RigidBody* Dumbbell::getRigidBody() {
|
||||
return dynamic_cast<rp3d::RigidBody*>(mBody);
|
||||
}
|
||||
|
||||
// Return a pointer to the body
|
||||
inline rp3d::CollisionBody* Dumbbell::getCollisionBody() {
|
||||
return mBody;
|
||||
// Update the transform matrix of the object
|
||||
inline void Dumbbell::updateTransform(float interpolationFactor) {
|
||||
mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -47,7 +47,12 @@ void Line::render(openglframework::Shader& shader,
|
|||
shader.bind();
|
||||
|
||||
// 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);
|
||||
glVertex3f(mWorldPoint1.x, mWorldPoint1.y, mWorldPoint1.z);
|
|
@ -58,9 +58,6 @@ class Line : public openglframework::Object3D {
|
|||
/// Return the second point of the line
|
||||
openglframework::Vector3 getPoint2() const;
|
||||
|
||||
/// Update the transform matrix of the sphere
|
||||
void updateTransform();
|
||||
|
||||
/// Render the line at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
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
|
||||
#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
|
||||
Sphere::Sphere(float radius, const openglframework::Vector3 &position,
|
||||
reactphysics3d::CollisionWorld* world,
|
||||
|
@ -57,13 +64,22 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
|
|||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
mPreviousTransform = transform;
|
||||
|
||||
// Create a rigid body corresponding to the sphere in the dynamics world
|
||||
mRigidBody = world->createCollisionBody(transform);
|
||||
mBody = world->createCollisionBody(transform);
|
||||
|
||||
// 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;
|
||||
|
||||
// Create the VBOs and VAO
|
||||
if (totalNbSpheres == 0) {
|
||||
createVBOAndVAO();
|
||||
}
|
||||
|
||||
totalNbSpheres++;
|
||||
}
|
||||
|
||||
// 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
|
||||
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
|
||||
|
||||
mRigidBody = body;
|
||||
mBody = body;
|
||||
|
||||
mTransformMatrix = mTransformMatrix * mScalingMatrix;
|
||||
|
||||
// Create the VBOs and VAO
|
||||
if (totalNbSpheres == 0) {
|
||||
createVBOAndVAO();
|
||||
}
|
||||
|
||||
totalNbSpheres++;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Sphere::~Sphere() {
|
||||
|
||||
if (totalNbSpheres == 1) {
|
||||
// Destroy the mesh
|
||||
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
|
||||
|
@ -123,57 +157,125 @@ void Sphere::render(openglframework::Shader& shader,
|
|||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
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);
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
// Set the vertex color
|
||||
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
||||
shader.setVector4Uniform("vertexColor", color, false);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
||||
if(hasTexture()) {
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
||||
}
|
||||
// Bind the VAO
|
||||
mVAO.bind();
|
||||
|
||||
mVBOVertices.bind();
|
||||
|
||||
// Get the location of shader attribute variables
|
||||
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
|
||||
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false);
|
||||
|
||||
glEnableVertexAttribArray(vertexPositionLoc);
|
||||
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
|
||||
mVBONormals.bind();
|
||||
|
||||
if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
|
||||
if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc);
|
||||
|
||||
// For each part of the mesh
|
||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
||||
GL_UNSIGNED_INT, getIndicesPointer());
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
|
||||
}
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
glDisableVertexAttribArray(vertexPositionLoc);
|
||||
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
|
||||
|
||||
mVBONormals.unbind();
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Update the transform matrix of the sphere
|
||||
void Sphere::updateTransform() {
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
/// We create two VBOs (one for vertices and one for indices)
|
||||
void Sphere::createVBOAndVAO() {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
// Create the VBO for the vertices data
|
||||
mVBOVertices.create();
|
||||
mVBOVertices.bind();
|
||||
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
|
||||
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
|
||||
mVBOVertices.unbind();
|
||||
|
||||
// Compute the transform used for rendering the sphere
|
||||
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]);
|
||||
// Create the VBO for the normals data
|
||||
mVBONormals.create();
|
||||
mVBONormals.bind();
|
||||
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
|
||||
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
|
||||
mVBONormals.unbind();
|
||||
|
||||
// Apply the scaling matrix to have the correct sphere dimensions
|
||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
||||
if (hasTexture()) {
|
||||
// Create the VBO for the texture co data
|
||||
mVBOTextureCoords.create();
|
||||
mVBOTextureCoords.bind();
|
||||
size_t sizeTextureCoords = mUVs.size() * sizeof(openglframework::Vector2);
|
||||
mVBOTextureCoords.copyDataIntoVBO(sizeTextureCoords, getUVTextureCoordinatesPointer(), GL_STATIC_DRAW);
|
||||
mVBOTextureCoords.unbind();
|
||||
}
|
||||
|
||||
// Create th VBO for the indices data
|
||||
mVBOIndices.create();
|
||||
mVBOIndices.bind();
|
||||
size_t sizeIndices = mIndices[0].size() * sizeof(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
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
#include "PhysicsObject.h"
|
||||
|
||||
// Class Sphere
|
||||
class Sphere : public openglframework::Mesh {
|
||||
class Sphere : public openglframework::Mesh, public PhysicsObject {
|
||||
|
||||
private :
|
||||
|
||||
|
@ -40,14 +41,35 @@ class Sphere : public openglframework::Mesh {
|
|||
/// Radius of the sphere
|
||||
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)
|
||||
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 -------------------- //
|
||||
|
||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||
void createVBOAndVAO();
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
@ -63,28 +85,20 @@ class Sphere : public openglframework::Mesh {
|
|||
/// Destructor
|
||||
~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
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
||||
/// Set the position of the box
|
||||
void resetTransform(const rp3d::Transform& transform);
|
||||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor);
|
||||
};
|
||||
|
||||
// Return a pointer to the collision body of the box
|
||||
inline rp3d::CollisionBody* Sphere::getCollisionBody() {
|
||||
return mRigidBody;
|
||||
}
|
||||
|
||||
// Return a pointer to the rigid body of the box
|
||||
inline rp3d::RigidBody* Sphere::getRigidBody() {
|
||||
return dynamic_cast<rp3d::RigidBody*>(mRigidBody);
|
||||
// Update the transform matrix of the object
|
||||
inline void Sphere::updateTransform(float interpolationFactor) {
|
||||
mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix);
|
||||
}
|
||||
|
||||
#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
|
||||
#include "openglframework.h"
|
||||
|
||||
const float VISUAL_CONTACT_POINT_RADIUS = 0.1f;
|
||||
const float VISUAL_CONTACT_POINT_RADIUS = 0.2f;
|
||||
|
||||
// Class VisualContactPoint
|
||||
class VisualContactPoint : public openglframework::Object3D {
|
||||
|
@ -44,8 +44,26 @@ class VisualContactPoint : public openglframework::Object3D {
|
|||
/// Sphere mesh for the visual contact point
|
||||
static openglframework::Mesh mMesh;
|
||||
|
||||
/// True if the mesh has been initialized
|
||||
static bool mIsMeshInitialized;
|
||||
/// 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 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 -------------------- //
|
||||
|
||||
|
@ -54,7 +72,8 @@ class VisualContactPoint : public openglframework::Object3D {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
VisualContactPoint(const openglframework::Vector3& position);
|
||||
VisualContactPoint(const openglframework::Vector3& position,
|
||||
const std::string &meshFolderPath);
|
||||
|
||||
/// Destructor
|
||||
~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