From ce80426a2c713daac80465d97ee5318e42f9855a Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Tue, 11 Aug 2015 18:32:45 +0200 Subject: [PATCH] Shadow map issue --- testbed/CMakeLists.txt | 2 - testbed/common/VisualContactPoint.cpp | 29 ++---- testbed/common/VisualContactPoint.h | 5 +- .../collisionshapes/CollisionShapesScene.cpp | 4 +- .../collisionshapes/CollisionShapesScene.h | 22 +++-- testbed/scenes/cubes/CubesScene.cpp | 10 +- testbed/scenes/cubes/CubesScene.h | 7 +- testbed/scenes/joints/JointsScene.cpp | 4 +- testbed/scenes/joints/JointsScene.h | 8 ++ testbed/scenes/raycast/RaycastScene.cpp | 4 + testbed/scenes/raycast/RaycastScene.h | 32 ++++++- testbed/shaders/phong.frag | 28 +++++- testbed/src/Gui.cpp | 7 ++ testbed/src/Gui.h | 2 +- testbed/src/Scene.cpp | 3 +- testbed/src/Scene.h | 25 ++++- testbed/src/SceneDemo.cpp | 96 ++++++++++++++++++- testbed/src/SceneDemo.h | 24 ++++- testbed/src/TestbedApplication.cpp | 6 +- testbed/src/TestbedApplication.h | 11 +++ 20 files changed, 268 insertions(+), 61 deletions(-) diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index 1696484d..4d3ecdac 100644 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -43,8 +43,6 @@ SET(TESTBED_SOURCES src/SceneDemo.cpp src/Timer.h src/Timer.cpp - src/PhysicsEventListener.h - src/PhysicsEventListener.cpp ) # IMGUI source files diff --git a/testbed/common/VisualContactPoint.cpp b/testbed/common/VisualContactPoint.cpp index fa4a177b..c3048a69 100644 --- a/testbed/common/VisualContactPoint.cpp +++ b/testbed/common/VisualContactPoint.cpp @@ -33,7 +33,6 @@ openglframework::VertexBufferObject VisualContactPoint::mVBOIndices(GL_ELEMENT_A openglframework::VertexArrayObject VisualContactPoint::mVAO; int VisualContactPoint::mNbTotalPoints = 0; openglframework::Mesh VisualContactPoint::mMesh; -int VisualContactPoint::totalNbBoxes = 0; // Constructor VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position, @@ -42,31 +41,11 @@ VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position, // Initialize the position where the mesh will be rendered translateWorld(position); - - // Create the VBOs and VAO - if (totalNbBoxes == 0) { - createStaticData(meshFolderPath); - createVBOAndVAO(); - } - - totalNbBoxes++; } // Destructor VisualContactPoint::~VisualContactPoint() { - if (totalNbBoxes == 1) { - - // Destroy the VBOs and VAO - mVBOIndices.destroy(); - mVBOVertices.destroy(); - mVBONormals.destroy(); - mVAO.destroy(); - - destroyStaticData(); - } - - totalNbBoxes--; } // Load and initialize the mesh for all the contact points @@ -79,11 +58,19 @@ void VisualContactPoint::createStaticData(const std::string& meshFolderPath) { mMesh.calculateNormals(); mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS); + + createVBOAndVAO(); } // Destroy the mesh for the contact points void VisualContactPoint::destroyStaticData() { + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVAO.destroy(); + mMesh.destroy(); } diff --git a/testbed/common/VisualContactPoint.h b/testbed/common/VisualContactPoint.h index 9294a757..fb2e7012 100644 --- a/testbed/common/VisualContactPoint.h +++ b/testbed/common/VisualContactPoint.h @@ -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 { @@ -56,9 +56,6 @@ class VisualContactPoint : public openglframework::Object3D { /// Vertex Array Object for the vertex data static openglframework::VertexArrayObject mVAO; - /// Total number of points created - static int totalNbBoxes; - /// Color openglframework::Color mColor; diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index aa0e1ca0..b63cb03c 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -233,7 +233,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Set the box color mFloor->setColor(mGreyColorDemo); - mFloor->setSleepingColor(mRedColorDemo); + mFloor->setSleepingColor(mGreyColorDemo); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); @@ -361,6 +361,8 @@ void CollisionShapesScene::updatePhysics() { // Take a step for the simulation void CollisionShapesScene::update() { + SceneDemo::update(); + // Update the position and orientation of the boxes for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.h b/testbed/scenes/collisionshapes/CollisionShapesScene.h index 8c7a13e1..d7f41726 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.h +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.h @@ -45,13 +45,13 @@ namespace collisionshapesscene { // Constants const float SCENE_RADIUS = 30.0f; -const int NB_BOXES = 5; -const int NB_CUBES = 4; -const int NB_CONES = 4; -const int NB_CYLINDERS = 6; -const int NB_CAPSULES = 5; -const int NB_MESHES = 7; -const int NB_COMPOUND_SHAPES = 3; +const int NB_BOXES = 4; +const int NB_CUBES = 6; +const int NB_CONES = 6; +const int NB_CYLINDERS = 5; +const int NB_CAPSULES = 4; +const int NB_MESHES = 5; +const int NB_COMPOUND_SHAPES = 4; const openglframework::Vector3 BOX_SIZE(2, 2, 2); const float SPHERE_RADIUS = 1.5f; const float CONE_RADIUS = 2.0f; @@ -122,8 +122,16 @@ class CollisionShapesScene : public SceneDemo { /// Reset the scene virtual void reset(); + + /// Return all the contact points of the scene + virtual std::vector getContactPoints() const; }; +// Return all the contact points of the scene +inline std::vector CollisionShapesScene::getContactPoints() const { + return computeContactPointsOfWorld(mDynamicsWorld); +} + } #endif diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index 05c05063..0898801f 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -149,6 +149,8 @@ void CubesScene::updatePhysics() { // Update the scene void CubesScene::update() { + SceneDemo::update(); + // Update the position and orientation of the boxes for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { @@ -198,11 +200,3 @@ void CubesScene::reset() { mBoxes[i]->resetTransform(transform); } } - -// Return all the contact points of the scene -std::vector CubesScene::getContactPoints() const { - - std::vector contactPoints; - - return contactPoints; -} diff --git a/testbed/scenes/cubes/CubesScene.h b/testbed/scenes/cubes/CubesScene.h index 05331724..57dfb99f 100644 --- a/testbed/scenes/cubes/CubesScene.h +++ b/testbed/scenes/cubes/CubesScene.h @@ -83,9 +83,14 @@ class CubesScene : public SceneDemo { virtual void reset(); /// Return all the contact points of the scene - std::vector virtual getContactPoints() const; + virtual std::vector getContactPoints() const; }; +// Return all the contact points of the scene +inline std::vector CubesScene::getContactPoints() const { + return computeContactPointsOfWorld(mDynamicsWorld); +} + } #endif diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index 9406ee21..dd3255d4 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -145,6 +145,8 @@ void JointsScene::updatePhysics() { // Take a step for the simulation void JointsScene::update() { + SceneDemo::update(); + // Update the position and orientation of the boxes mSliderJointBottomBox->updateTransform(mInterpolationFactor); mSliderJointTopBox->updateTransform(mInterpolationFactor); @@ -474,7 +476,7 @@ void JointsScene::createFloor() { // Set the box color mFloor->setColor(mGreyColorDemo); - mFloor->setSleepingColor(mRedColorDemo); + mFloor->setSleepingColor(mGreyColorDemo); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); diff --git a/testbed/scenes/joints/JointsScene.h b/testbed/scenes/joints/JointsScene.h index b2d22c07..39ceecb2 100644 --- a/testbed/scenes/joints/JointsScene.h +++ b/testbed/scenes/joints/JointsScene.h @@ -135,8 +135,16 @@ class JointsScene : public SceneDemo { /// Reset the scene virtual void reset(); + + /// Return all the contact points of the scene + virtual std::vector getContactPoints() const; }; +// Return all the contact points of the scene +inline std::vector JointsScene::getContactPoints() const { + return computeContactPointsOfWorld(mDynamicsWorld); +} + } #endif diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index ed60e7df..c1eef947 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -36,6 +36,8 @@ RaycastScene::RaycastScene(const std::string& name) mMeshFolderPath("meshes/"), mRaycastManager(mPhongShader, mMeshFolderPath), mVBOVertices(GL_ARRAY_BUFFER) { + mIsContactPointsDisplayed = true; + // Compute the radius and the center of the scene openglframework::Vector3 center(0, 0, 0); @@ -286,6 +288,8 @@ void RaycastScene::update() { // callback class in argument. mCollisionWorld->raycast(ray, &mRaycastManager); } + + SceneDemo::update(); } // Render the scene diff --git a/testbed/scenes/raycast/RaycastScene.h b/testbed/scenes/raycast/RaycastScene.h index 67e0f873..bccfb9cb 100644 --- a/testbed/scenes/raycast/RaycastScene.h +++ b/testbed/scenes/raycast/RaycastScene.h @@ -66,7 +66,7 @@ class RaycastManager : public rp3d::RaycastCallback { private: /// All the visual contact points - std::vector mHitPoints; + std::vector mHitPoints; /// All the normals at hit points std::vector mNormals; @@ -88,8 +88,7 @@ class RaycastManager : public rp3d::RaycastCallback { virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) { rp3d::Vector3 hitPos = raycastInfo.worldPoint; openglframework::Vector3 position(hitPos.x, hitPos.y, hitPos.z); - VisualContactPoint* point = new VisualContactPoint(position, mMeshFolderPath); - mHitPoints.push_back(point); + mHitPoints.push_back(ContactPoint(position)); // Create a line to display the normal at hit point rp3d::Vector3 n = raycastInfo.worldNormal; @@ -103,11 +102,13 @@ class RaycastManager : public rp3d::RaycastCallback { void render(const openglframework::Matrix4& worldToCameraMatrix, bool showNormals) { + /* // Render all the raycast hit points - for (std::vector::iterator it = mHitPoints.begin(); + for (std::vector::iterator it = mHitPoints.begin(); it != mHitPoints.end(); ++it) { (*it)->render(mShader, worldToCameraMatrix); } + */ if (showNormals) { @@ -121,11 +122,13 @@ class RaycastManager : public rp3d::RaycastCallback { void resetPoints() { + /* // Destroy all the visual contact points for (std::vector::iterator it = mHitPoints.begin(); it != mHitPoints.end(); ++it) { delete (*it); } + */ mHitPoints.clear(); // Destroy all the normals @@ -135,6 +138,10 @@ class RaycastManager : public rp3d::RaycastCallback { } mNormals.clear(); } + + std::vector getHitPoints() const { + return mHitPoints; + } }; // Class RaycastScene @@ -224,6 +231,12 @@ class RaycastScene : public SceneDemo { /// Enabled/Disable the shadow mapping void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled); + + /// Display/Hide the contact points + void virtual setIsContactPointsDisplayed(bool display); + + /// Return all the contact points of the scene + virtual std::vector getContactPoints() const; }; // Display or not the surface normals at hit points @@ -233,10 +246,19 @@ inline void RaycastScene::showHideNormals() { // Enabled/Disable the shadow mapping inline void RaycastScene::setIsShadowMappingEnabled(bool isShadowMappingEnabled) { - SceneDemo::setIsShadowMappingEnabled(false); } +// Display/Hide the contact points +inline void RaycastScene::setIsContactPointsDisplayed(bool display) { + SceneDemo::setIsContactPointsDisplayed(true); +} + +// Return all the contact points of the scene +inline std::vector RaycastScene::getContactPoints() const { + return mRaycastManager.getHitPoints(); +} + } #endif diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag index e34c8abd..cbf7f0e4 100644 --- a/testbed/shaders/phong.frag +++ b/testbed/shaders/phong.frag @@ -34,6 +34,7 @@ uniform sampler2D shadowMapSampler; // Shadow map texture sampler uniform bool isTexture; // True if we need to use the texture uniform vec4 vertexColor; // Vertex color uniform bool isShadowEnabled; // True if shadow mapping is enabled +uniform vec2 shadowMapDimension; // Shadow map dimension // In variables in vec3 vertexPosCameraSpace; // Camera-space position of the vertex @@ -44,6 +45,13 @@ in vec4 shadowMapCoords; // Shadow map texture coords // Out variable out vec4 color; // Output color +// Texture for PCF Shadow mapping +float textureLookupPCF(sampler2D map, vec2 texCoords, vec2 offset) +{ + vec2 shadowMapScale = vec2(1.0, 1.0) / shadowMapDimension; + return texture(map, texCoords.xy + offset * shadowMapScale).r; +} + void main() { // Compute the ambient term @@ -61,18 +69,36 @@ void main() { float diffuseFactor = max(dot(N, L0), 0.0); vec3 diffuse = light0DiffuseColor * diffuseFactor * textureColor; + // Compute shadow factor float shadow = 1.0; if (isShadowEnabled) { + shadow = 0.0; float bias = 0.0003; float shadowBias = -0.000; vec4 shadowMapUV = shadowMapCoords; shadowMapUV.z -= shadowBias; - vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w ; + vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w; + + /* + // PCF Shadow Mapping + for (float i=-1; i<=1; i++) { + for (float j=-1; j<=1; j++) { + float distInShadowMap = textureLookupPCF(shadowMapSampler, shadowMapCoordsOverW.xy, vec2(i, j)) + bias; + if (shadowMapCoords.w > 0) { + shadow += distInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0; + } + } + } + shadow /= 9.0; + */ + + float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r + bias; if (shadowMapCoords.w > 0) { shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0; } + } // Compute the final color diff --git a/testbed/src/Gui.cpp b/testbed/src/Gui.cpp index d45e0fce..a80ed525 100644 --- a/testbed/src/Gui.cpp +++ b/testbed/src/Gui.cpp @@ -299,6 +299,13 @@ void Gui::displayRenderingPane() { imguiVerticalSpace(15); + + // Display/Hide contact points + bool toggleContactPoints = imguiCheck("Contacts", app.mIsContactPointsDisplayed); + if (toggleContactPoints) { + app.displayContactPoints(!app.mIsContactPointsDisplayed); + } + // Enabled/Disable VSync bool toggleVSync = imguiCheck("V Sync", app.mIsVSyncEnabled); if (toggleVSync) { diff --git a/testbed/src/Gui.h b/testbed/src/Gui.h index c794d57d..19d5dc07 100644 --- a/testbed/src/Gui.h +++ b/testbed/src/Gui.h @@ -37,7 +37,7 @@ const float GUI_SCALING = 2.0f; const int LEFT_PANE_WIDTH = 300; const int LEFT_PANE_HEADER_HEIGHT = 90; -const double TIME_INTERVAL_DISPLAY_PROFILING_INFO = 0.2; +const double TIME_INTERVAL_DISPLAY_PROFILING_INFO = 0.3; using namespace openglframework; diff --git a/testbed/src/Scene.cpp b/testbed/src/Scene.cpp index 65ac681f..7e71968b 100644 --- a/testbed/src/Scene.cpp +++ b/testbed/src/Scene.cpp @@ -32,7 +32,8 @@ using namespace openglframework; // Constructor Scene::Scene(const std::string& name, bool isShadowMappingEnabled) : mName(name), mInterpolationFactor(0.0f), mViewportX(0), mViewportY(0), - mViewportWidth(0), mViewportHeight(0), mIsShadowMappingEnabled(isShadowMappingEnabled) { + mViewportWidth(0), mViewportHeight(0), mIsShadowMappingEnabled(isShadowMappingEnabled), + mIsContactPointsDisplayed(true) { } diff --git a/testbed/src/Scene.h b/testbed/src/Scene.h index a558f95b..2091caac 100644 --- a/testbed/src/Scene.h +++ b/testbed/src/Scene.h @@ -28,7 +28,18 @@ // Libraries #include "openglframework.h" -#include "PhysicsEventListener.h" + +// Structure ContactPoint +struct ContactPoint { + + public: + openglframework::Vector3 point; + + /// Constructor + ContactPoint(const openglframework::Vector3& pointWorld) : point(pointWorld) { + + } +}; /// Structure EngineSettings /// This structure contains several physics engine parameters @@ -94,6 +105,9 @@ class Scene { /// True if the shadow mapping is enabled bool mIsShadowMappingEnabled; + /// True if contact points are displayed + bool mIsContactPointsDisplayed; + // -------------------- Methods -------------------- // /// Set the scene position (where the camera needs to look at) @@ -106,7 +120,6 @@ class Scene { bool mapMouseCoordinatesToSphere(double xMouse, double yMouse, openglframework::Vector3& spherePoint) const; - /// Zoom the camera void zoom(float zoomDiff); @@ -183,6 +196,9 @@ class Scene { /// Enabled/Disable the shadow mapping void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled); + /// Display/Hide the contact points + void virtual setIsContactPointsDisplayed(bool display); + /// Return all the contact points of the scene std::vector virtual getContactPoints() const; }; @@ -246,6 +262,11 @@ inline void Scene::setIsShadowMappingEnabled(bool isShadowMappingEnabled) { mIsShadowMappingEnabled = isShadowMappingEnabled; } +// Display/Hide the contact points +inline void Scene::setIsContactPointsDisplayed(bool display) { + mIsContactPointsDisplayed = display; +} + // Return all the contact points of the scene inline std::vector Scene::getContactPoints() const { diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 8be46a64..ea8c9305 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -47,7 +47,7 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMa mDepthShader("shaders/depth.vert", "shaders/depth.frag"), mPhongShader("shaders/phong.vert", "shaders/phong.frag"), mQuadShader("shaders/quad.vert", "shaders/quad.frag"), - mVBOQuad(GL_ARRAY_BUFFER) { + mVBOQuad(GL_ARRAY_BUFFER), mMeshFolderPath("meshes/") { shadowMapTextureLevel++; @@ -74,6 +74,8 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMa } createQuadVBO(); + + VisualContactPoint::createStaticData(mMeshFolderPath); } // Destructor @@ -83,13 +85,23 @@ SceneDemo::~SceneDemo() { mFBOShadowMap.destroy(); mVBOQuad.destroy(); + // Destroy the contact points + removeAllContactPoints(); + + VisualContactPoint::destroyStaticData(); +} + +// Update the scene +void SceneDemo::update() { + + // Update the contact points + updateContactPoints(); } // Render the scene (in multiple passes for shadow mapping) void SceneDemo::render() { const Color& diffCol = mLight0.getDiffuseColor(); - const Color& specCol = mLight0.getSpecularColor(); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); @@ -154,6 +166,7 @@ void SceneDemo::render() { mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); mPhongShader.setIntUniform("shadowMapSampler", textureUnit); mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled); + //mPhongShader.setVector2Uniform("shadowMapDimension", Vector2(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT)); // Set the viewport to render the scene glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); @@ -167,10 +180,15 @@ void SceneDemo::render() { // Render the objects of the scene renderSinglePass(mPhongShader, worldToCameraMatrix); + // Render the contact points + if (mIsContactPointsDisplayed) { + renderContactPoints(mPhongShader, worldToCameraMatrix); + } + if (mIsShadowMappingEnabled) mShadowMapTexture.unbind(); mPhongShader.unbind(); - //drawTextureQuad(); + drawTextureQuad(); } // Create the Shadow map FBO and texture @@ -194,6 +212,7 @@ void SceneDemo::createShadowMapFBOAndTexture() { mIsShadowMappingInitialized = true; } +// Used for debugging shadow maps void SceneDemo::createQuadVBO() { mVAOQuad.create(); @@ -254,3 +273,74 @@ void SceneDemo::drawTextureQuad() { mQuadShader.unbind(); mVAOQuad.unbind(); } + +// Gather and create contact points +void SceneDemo::updateContactPoints() { + + // Remove the previous contact points + removeAllContactPoints(); + + if (mIsContactPointsDisplayed) { + + // Get the current contact points of the scene + std::vector contactPoints = getContactPoints(); + + // For each contact point + std::vector::const_iterator it; + for (it = contactPoints.begin(); it != contactPoints.end(); ++it) { + + // Create a visual contact point for rendering + VisualContactPoint* point = new VisualContactPoint(it->point, mMeshFolderPath); + mContactPoints.push_back(point); + } + } +} + +// Render the contact points +void SceneDemo::renderContactPoints(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { + + // Render all the raycast hit points + for (std::vector::iterator it = mContactPoints.begin(); + it != mContactPoints.end(); ++it) { + (*it)->render(shader, worldToCameraMatrix); + } +} + +void SceneDemo::removeAllContactPoints() { + + // Destroy all the visual contact points + for (std::vector::iterator it = mContactPoints.begin(); + it != mContactPoints.end(); ++it) { + delete (*it); + } + mContactPoints.clear(); +} + +// Return all the contact points of the scene +std::vector SceneDemo::computeContactPointsOfWorld(const rp3d::DynamicsWorld* world) const { + + std::vector contactPoints; + + // Get the list of contact manifolds from the world + std::vector manifolds = world->getContactsList(); + + // For each contact manifold + std::vector::const_iterator it; + for (it = manifolds.begin(); it != manifolds.end(); ++it) { + + const rp3d::ContactManifold* manifold = *it; + + // For each contact point of the manifold + for (uint i=0; igetNbContactPoints(); i++) { + + rp3d::ContactPoint* contactPoint = manifold->getContactPoint(i); + rp3d::Vector3 point = contactPoint->getWorldPointOnBody1(); + ContactPoint contact(openglframework::Vector3(point.x, point.y, point.z)); + contactPoints.push_back(contact); + } + + } + + return contactPoints; +} diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 770a4e26..5ec37b45 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -28,6 +28,8 @@ // Libraries #include "Scene.h" +#include "VisualContactPoint.h" +#include "reactphysics3d.h" // Constants const int SHADOWMAP_WIDTH = 2048; @@ -56,6 +58,9 @@ class SceneDemo : public Scene { static int shadowMapTextureLevel; + /// All the visual contact points + std::vector mContactPoints; + /// Shadow map bias matrix openglframework::Matrix4 mShadowMapBiasMatrix; @@ -85,17 +90,28 @@ class SceneDemo : public Scene { static openglframework::Color mDemoColors[]; static int mNbDemoColors; + std::string mMeshFolderPath; + // -------------------- Methods -------------------- // // Create the Shadow map FBO and texture void createShadowMapFBOAndTexture(); - // TODO : Delete this + // Used for debugging shadow maps void createQuadVBO(); // TODO : Delete this void drawTextureQuad(); + // Update the contact points + void updateContactPoints(); + + // Render the contact points + void renderContactPoints(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); + + void removeAllContactPoints(); + public: // -------------------- Methods -------------------- // @@ -106,6 +122,9 @@ class SceneDemo : public Scene { /// Destructor virtual ~SceneDemo(); + /// Update the scene + virtual void update(); + /// Render the scene (possibly in multiple passes for shadow mapping) virtual void render(); @@ -115,6 +134,9 @@ class SceneDemo : public Scene { /// Enabled/Disable the shadow mapping void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled); + + /// Return all the contact points of the scene + std::vector computeContactPointsOfWorld(const rp3d::DynamicsWorld* world) const; }; // Enabled/Disable the shadow mapping diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index 973d648e..fc958671 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -63,13 +63,12 @@ TestbedApplication::TestbedApplication() mWindowToFramebufferRatio = Vector2(1, 1); mIsShadowMappingEnabled = true; mIsVSyncEnabled = true; + mIsContactPointsDisplayed = false; } // Destructor TestbedApplication::~TestbedApplication() { - // TODO : Check that this method is called at the end - // Destroy all the scenes destroyScenes(); @@ -242,6 +241,9 @@ void TestbedApplication::update() { // Enable/Disable shadow mapping mCurrentScene->setIsShadowMappingEnabled(mIsShadowMappingEnabled); + // Display/Hide contact points + mCurrentScene->setIsContactPointsDisplayed(mIsContactPointsDisplayed); + // Update the scene mCurrentScene->update(); } diff --git a/testbed/src/TestbedApplication.h b/testbed/src/TestbedApplication.h index 75d14918..6abd7b8a 100644 --- a/testbed/src/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -98,6 +98,9 @@ class TestbedApplication { /// True if shadow mapping is enabled bool mIsShadowMappingEnabled; + /// True if contact points are displayed + bool mIsContactPointsDisplayed; + /// True if vsync is enabled bool mIsVSyncEnabled; @@ -175,6 +178,9 @@ class TestbedApplication { /// Enable/Disable shadow mapping void enableShadows(bool enable); + /// Display/Hide contact points + void displayContactPoints(bool display); + public : // -------------------- Methods -------------------- // @@ -239,6 +245,11 @@ inline void TestbedApplication::enableShadows(bool enable) { mIsShadowMappingEnabled = enable; } +/// Display/Hide contact points +inline void TestbedApplication::displayContactPoints(bool display) { + mIsContactPointsDisplayed = display; +} + // Enable/Disable Vertical synchronization inline void TestbedApplication::enableVSync(bool enable) { mIsVSyncEnabled = enable;