From 393bb0ed88fdd1098623a46a7a48c735bd33bd57 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Wed, 14 Mar 2018 07:33:28 +0100 Subject: [PATCH 1/5] Refactor profiler and start working on logger --- CMakeLists.txt | 11 +- src/body/Body.h | 6 +- src/body/CollisionBody.h | 2 +- src/body/RigidBody.cpp | 2 +- src/collision/CollisionDetection.cpp | 30 +- src/collision/CollisionDetection.h | 2 +- .../broadphase/BroadPhaseAlgorithm.cpp | 4 +- .../broadphase/BroadPhaseAlgorithm.h | 4 +- src/collision/broadphase/DynamicAABBTree.cpp | 6 +- .../narrowphase/GJK/GJKAlgorithm.cpp | 4 +- .../narrowphase/SAT/SATAlgorithm.cpp | 28 +- src/collision/shapes/CollisionShape.cpp | 4 +- src/collision/shapes/CollisionShape.h | 2 +- src/collision/shapes/ConcaveMeshShape.cpp | 2 +- src/collision/shapes/ConcaveMeshShape.h | 2 +- src/collision/shapes/HeightFieldShape.cpp | 2 +- src/collision/shapes/HeightFieldShape.h | 2 +- src/collision/shapes/TriangleShape.cpp | 4 +- src/constraint/BallAndSocketJoint.cpp | 4 +- src/constraint/BallAndSocketJoint.h | 2 +- src/constraint/FixedJoint.cpp | 4 +- src/constraint/FixedJoint.h | 2 +- src/constraint/HingeJoint.cpp | 4 +- src/constraint/HingeJoint.h | 2 +- src/constraint/Joint.cpp | 4 +- src/constraint/Joint.h | 19 +- src/constraint/SliderJoint.cpp | 4 +- src/constraint/SliderJoint.h | 2 +- src/containers/List.h | 1 + src/containers/Pair.h | 2 +- src/engine/CollisionWorld.cpp | 68 +++- src/engine/CollisionWorld.h | 64 +++- src/engine/ConstraintSolver.cpp | 8 +- src/engine/ContactSolver.cpp | 14 +- src/engine/DynamicsWorld.cpp | 94 +++-- src/engine/DynamicsWorld.h | 33 +- src/engine/OverlappingPair.h | 6 +- src/mathematics/Matrix2x2.h | 10 + src/mathematics/Matrix3x3.h | 11 + src/mathematics/Quaternion.h | 9 + src/mathematics/Transform.h | 8 + src/mathematics/Vector2.h | 9 + src/mathematics/Vector3.h | 9 + src/utils/Logger.cpp | 102 ++++++ src/utils/Logger.h | 332 ++++++++++++++++++ src/{engine => utils}/Profiler.cpp | 82 +++-- src/{engine => utils}/Profiler.h | 147 ++++++-- test/tests/collision/TestCollisionWorld.h | 160 ++++----- test/tests/collision/TestRaycast.h | 3 +- .../CollisionDetectionScene.cpp | 8 +- .../collisionshapes/CollisionShapesScene.cpp | 9 +- .../scenes/concavemesh/ConcaveMeshScene.cpp | 8 +- testbed/scenes/cubes/CubesScene.cpp | 8 +- testbed/scenes/cubestack/CubeStackScene.cpp | 8 +- .../scenes/heightfield/HeightFieldScene.cpp | 9 +- testbed/scenes/joints/JointsScene.cpp | 8 +- testbed/scenes/raycast/RaycastScene.cpp | 8 +- 57 files changed, 1059 insertions(+), 343 deletions(-) create mode 100644 src/utils/Logger.cpp create mode 100644 src/utils/Logger.h rename src/{engine => utils}/Profiler.cpp (85%) rename src/{engine => utils}/Profiler.h (77%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0566a735..09a5ae73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ ENABLE_TESTING() 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(LOGS_ENABLED "Select this if you want to compile with logs enabled during execution" OFF) OPTION(DOUBLE_PRECISION_ENABLED "Select this if you want to compile using double precision floating values" OFF) @@ -45,6 +46,10 @@ IF(PROFILING_ENABLED) ADD_DEFINITIONS(-DIS_PROFILING_ACTIVE) ENDIF(PROFILING_ENABLED) +IF(LOGS_ENABLED) + ADD_DEFINITIONS(-DIS_LOGGING_ACTIVE) +ENDIF(LOGS_ENABLED) + IF(DOUBLE_PRECISION_ENABLED) ADD_DEFINITIONS(-DIS_DOUBLE_PRECISION_ENABLED) ENDIF(DOUBLE_PRECISION_ENABLED) @@ -164,8 +169,6 @@ SET (REACTPHYSICS3D_SOURCES "src/engine/Material.cpp" "src/engine/OverlappingPair.h" "src/engine/OverlappingPair.cpp" - "src/engine/Profiler.h" - "src/engine/Profiler.cpp" "src/engine/Timer.h" "src/engine/Timer.cpp" "src/collision/CollisionCallback.h" @@ -201,6 +204,10 @@ SET (REACTPHYSICS3D_SOURCES "src/containers/Map.h" "src/containers/Set.h" "src/containers/Pair.h" + "src/utils/Profiler.h" + "src/utils/Profiler.cpp" + "src/utils/Logger.h" + "src/utils/Logger.cpp" ) # Create the library diff --git a/src/body/Body.h b/src/body/Body.h index b1b18325..4a46e83f 100644 --- a/src/body/Body.h +++ b/src/body/Body.h @@ -92,7 +92,7 @@ class Body { virtual ~Body() = default; /// Return the ID of the body - bodyindex getID() const; + bodyindex getId() const; /// Return whether or not the body is allowed to sleep bool isAllowedToSleep() const; @@ -137,9 +137,9 @@ class Body { // Return the id of the body /** - * @return The ID of the body + * @return The id of the body */ -inline bodyindex Body::getID() const { +inline bodyindex Body::getId() const { return mID; } diff --git a/src/body/CollisionBody.h b/src/body/CollisionBody.h index 9943dc86..2520cab4 100644 --- a/src/body/CollisionBody.h +++ b/src/body/CollisionBody.h @@ -36,7 +36,7 @@ #include "collision/RaycastInfo.h" #include "memory/PoolAllocator.h" #include "configuration.h" -#include "engine/Profiler.h" +#include "utils/Profiler.h" /// Namespace reactphysics3d namespace reactphysics3d { diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index 4d79f186..ab4b0c8e 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -459,7 +459,7 @@ void RigidBody::recomputeMassInformation() { // Update the broad-phase state for this body (because it has moved for instance) void RigidBody::updateBroadPhaseState() const { - PROFILE("RigidBody::updateBroadPhaseState()", mProfiler); + RP3D_PROFILE("RigidBody::updateBroadPhaseState()", mProfiler); DynamicsWorld& world = static_cast(mWorld); const Vector3 displacement = world.mTimeStep * mLinearVelocity; diff --git a/src/collision/CollisionDetection.cpp b/src/collision/CollisionDetection.cpp index ffbc56c7..dc2272f9 100644 --- a/src/collision/CollisionDetection.cpp +++ b/src/collision/CollisionDetection.cpp @@ -68,7 +68,7 @@ CollisionDetection::CollisionDetection(CollisionWorld* world, MemoryManager& mem // Compute the collision detection void CollisionDetection::computeCollisionDetection() { - PROFILE("CollisionDetection::computeCollisionDetection()", mProfiler); + RP3D_PROFILE("CollisionDetection::computeCollisionDetection()", mProfiler); // Compute the broad-phase collision detection computeBroadPhase(); @@ -86,7 +86,7 @@ void CollisionDetection::computeCollisionDetection() { // Compute the broad-phase collision detection void CollisionDetection::computeBroadPhase() { - PROFILE("CollisionDetection::computeBroadPhase()", mProfiler); + RP3D_PROFILE("CollisionDetection::computeBroadPhase()", mProfiler); // If new collision shapes have been added to bodies if (mIsCollisionShapesAdded) { @@ -101,7 +101,7 @@ void CollisionDetection::computeBroadPhase() { // Compute the middle-phase collision detection void CollisionDetection::computeMiddlePhase() { - PROFILE("CollisionDetection::computeMiddlePhase()", mProfiler); + RP3D_PROFILE("CollisionDetection::computeMiddlePhase()", mProfiler); // For each possible collision pair of bodies Map, OverlappingPair*>::Iterator it; @@ -251,7 +251,7 @@ void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair // Compute the narrow-phase collision detection void CollisionDetection::computeNarrowPhase() { - PROFILE("CollisionDetection::computeNarrowPhase()", mProfiler); + RP3D_PROFILE("CollisionDetection::computeNarrowPhase()", mProfiler); NarrowPhaseInfo* currentNarrowPhaseInfo = mNarrowPhaseInfoList; while (currentNarrowPhaseInfo != nullptr) { @@ -364,7 +364,7 @@ void CollisionDetection::removeProxyCollisionShape(ProxyShape* proxyShape) { void CollisionDetection::addAllContactManifoldsToBodies() { - PROFILE("CollisionDetection::addAllContactManifoldsToBodies()", mProfiler); + RP3D_PROFILE("CollisionDetection::addAllContactManifoldsToBodies()", mProfiler); // For each overlapping pairs in contact during the narrow-phase Map, OverlappingPair*>::Iterator it; @@ -415,7 +415,7 @@ void CollisionDetection::addContactManifoldToBody(OverlappingPair* pair) { /// Convert the potential contact into actual contacts void CollisionDetection::processAllPotentialContacts() { - PROFILE("CollisionDetection::processAllPotentialContacts()", mProfiler); + RP3D_PROFILE("CollisionDetection::processAllPotentialContacts()", mProfiler); // For each overlapping pairs in contact during the narrow-phase Map, OverlappingPair*>::Iterator it; @@ -454,7 +454,7 @@ void CollisionDetection::processPotentialContacts(OverlappingPair* pair) { // Report contacts for all the colliding overlapping pairs void CollisionDetection::reportAllContacts() { - PROFILE("CollisionDetection::reportAllContacts()", mProfiler); + RP3D_PROFILE("CollisionDetection::reportAllContacts()", mProfiler); // For each overlapping pairs in contact during the narrow-phase Map, OverlappingPair*>::Iterator it; @@ -532,13 +532,13 @@ void CollisionDetection::testAABBOverlap(const AABB& aabb, OverlapCallback* over CollisionBody* overlapBody = proxyShape->getBody(); // If the proxy shape is from a body that we have not already reported collision - if (reportedBodies.find(overlapBody->getID()) == reportedBodies.end()) { + if (reportedBodies.find(overlapBody->getId()) == reportedBodies.end()) { // Check if the collision filtering allows collision between the two shapes if ((proxyShape->getCollisionCategoryBits() & categoryMaskBits) != 0) { // Add the body into the set of reported bodies - reportedBodies.add(overlapBody->getID()); + reportedBodies.add(overlapBody->getId()); // Notify the overlap to the user overlapCallback->notifyOverlap(overlapBody); @@ -646,7 +646,7 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl LinkedList overlappingNodes(mMemoryManager.getPoolAllocator()); mBroadPhaseAlgorithm.reportAllShapesOverlappingWithAABB(shapeAABB, overlappingNodes); - const bodyindex bodyId = body->getID(); + const bodyindex bodyId = body->getId(); // For each overlaping proxy shape LinkedList::ListElement* element = overlappingNodes.getListHead(); @@ -658,8 +658,8 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl // If the proxy shape is from a body that we have not already reported collision and the // two proxy collision shapes are not from the same body - if (reportedBodies.find(proxyShape->getBody()->getID()) == reportedBodies.end() && - proxyShape->getBody()->getID() != bodyId) { + if (reportedBodies.find(proxyShape->getBody()->getId()) == reportedBodies.end() && + proxyShape->getBody()->getId() != bodyId) { // Check if the collision filtering allows collision between the two shapes if ((proxyShape->getCollisionCategoryBits() & categoryMaskBits) != 0) { @@ -711,7 +711,7 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl CollisionBody* overlapBody = proxyShape->getBody(); // Add the body into the set of reported bodies - reportedBodies.add(overlapBody->getID()); + reportedBodies.add(overlapBody->getId()); // Notify the overlap to the user overlapCallback->notifyOverlap(overlapBody); @@ -826,7 +826,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c LinkedList overlappingNodes(mMemoryManager.getPoolAllocator()); mBroadPhaseAlgorithm.reportAllShapesOverlappingWithAABB(shapeAABB, overlappingNodes); - const bodyindex bodyId = body->getID(); + const bodyindex bodyId = body->getId(); // For each overlaping proxy shape LinkedList::ListElement* element = overlappingNodes.getListHead(); @@ -837,7 +837,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c ProxyShape* proxyShape = mBroadPhaseAlgorithm.getProxyShapeForBroadPhaseId(broadPhaseId); // If the two proxy collision shapes are not from the same body - if (proxyShape->getBody()->getID() != bodyId) { + if (proxyShape->getBody()->getId() != bodyId) { // Check if the collision filtering allows collision between the two shapes if ((proxyShape->getCollisionCategoryBits() & categoryMaskBits) != 0) { diff --git a/src/collision/CollisionDetection.h b/src/collision/CollisionDetection.h index 4dc45634..d8f5240a 100644 --- a/src/collision/CollisionDetection.h +++ b/src/collision/CollisionDetection.h @@ -314,7 +314,7 @@ inline void CollisionDetection::raycast(RaycastCallback* raycastCallback, const Ray& ray, unsigned short raycastWithCategoryMaskBits) const { - PROFILE("CollisionDetection::raycast()", mProfiler); + RP3D_PROFILE("CollisionDetection::raycast()", mProfiler); RaycastTest rayCastTest(raycastCallback); diff --git a/src/collision/broadphase/BroadPhaseAlgorithm.cpp b/src/collision/broadphase/BroadPhaseAlgorithm.cpp index 5f76e2c2..fbad0cfd 100644 --- a/src/collision/broadphase/BroadPhaseAlgorithm.cpp +++ b/src/collision/broadphase/BroadPhaseAlgorithm.cpp @@ -26,7 +26,7 @@ // Libraries #include "BroadPhaseAlgorithm.h" #include "collision/CollisionDetection.h" -#include "engine/Profiler.h" +#include "utils/Profiler.h" // We want to use the ReactPhysics3D namespace using namespace reactphysics3d; @@ -257,7 +257,7 @@ void BroadPhaseAlgorithm::computeOverlappingPairs(MemoryManager& memoryManager) ProxyShape* shape2 = static_cast(mDynamicAABBTree.getNodeDataPointer(pair->collisionShape2ID)); // If the two proxy collision shapes are from the same body, skip it - if (shape1->getBody()->getID() != shape2->getBody()->getID()) { + if (shape1->getBody()->getId() != shape2->getBody()->getId()) { // Notify the collision detection about the overlapping pair mCollisionDetection.broadPhaseNotifyOverlappingPair(shape1, shape2); diff --git a/src/collision/broadphase/BroadPhaseAlgorithm.h b/src/collision/broadphase/BroadPhaseAlgorithm.h index 3ae18677..df642677 100644 --- a/src/collision/broadphase/BroadPhaseAlgorithm.h +++ b/src/collision/broadphase/BroadPhaseAlgorithm.h @@ -30,7 +30,7 @@ #include "body/CollisionBody.h" #include "collision/ProxyShape.h" #include "DynamicAABBTree.h" -#include "engine/Profiler.h" +#include "utils/Profiler.h" #include "containers/LinkedList.h" /// Namespace ReactPhysics3D @@ -265,7 +265,7 @@ inline const AABB& BroadPhaseAlgorithm::getFatAABB(int broadPhaseId) const { inline void BroadPhaseAlgorithm::raycast(const Ray& ray, RaycastTest& raycastTest, unsigned short raycastWithCategoryMaskBits) const { - PROFILE("BroadPhaseAlgorithm::raycast()", mProfiler); + RP3D_PROFILE("BroadPhaseAlgorithm::raycast()", mProfiler); BroadPhaseRaycastCallback broadPhaseRaycastCallback(mDynamicAABBTree, raycastWithCategoryMaskBits, raycastTest); diff --git a/src/collision/broadphase/DynamicAABBTree.cpp b/src/collision/broadphase/DynamicAABBTree.cpp index bbc4b109..8e8bab04 100644 --- a/src/collision/broadphase/DynamicAABBTree.cpp +++ b/src/collision/broadphase/DynamicAABBTree.cpp @@ -27,7 +27,7 @@ #include "DynamicAABBTree.h" #include "BroadPhaseAlgorithm.h" #include "containers/Stack.h" -#include "engine/Profiler.h" +#include "utils/Profiler.h" using namespace reactphysics3d; @@ -173,7 +173,7 @@ void DynamicAABBTree::removeObject(int nodeID) { /// (this can be useful if the shape AABB has become much smaller than the previous one for instance). bool DynamicAABBTree::updateObject(int nodeID, const AABB& newAABB, const Vector3& displacement, bool forceReinsert) { - PROFILE("DynamicAABBTree::updateObject()", mProfiler); + RP3D_PROFILE("DynamicAABBTree::updateObject()", mProfiler); assert(nodeID >= 0 && nodeID < mNbAllocatedNodes); assert(mNodes[nodeID].isLeaf()); @@ -635,7 +635,7 @@ void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb, // Ray casting method void DynamicAABBTree::raycast(const Ray& ray, DynamicAABBTreeRaycastCallback &callback) const { - PROFILE("DynamicAABBTree::raycast()", mProfiler); + RP3D_PROFILE("DynamicAABBTree::raycast()", mProfiler); decimal maxFraction = ray.maxFraction; diff --git a/src/collision/narrowphase/GJK/GJKAlgorithm.cpp b/src/collision/narrowphase/GJK/GJKAlgorithm.cpp index a7bc8667..a7d647ae 100644 --- a/src/collision/narrowphase/GJK/GJKAlgorithm.cpp +++ b/src/collision/narrowphase/GJK/GJKAlgorithm.cpp @@ -29,7 +29,7 @@ #include "engine/OverlappingPair.h" #include "collision/shapes/TriangleShape.h" #include "configuration.h" -#include "engine/Profiler.h" +#include "utils/Profiler.h" #include #include #include @@ -49,7 +49,7 @@ using namespace reactphysics3d; /// the correct penetration depth and contact points between the enlarged objects. GJKAlgorithm::GJKResult GJKAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) { - PROFILE("GJKAlgorithm::testCollision()", mProfiler); + RP3D_PROFILE("GJKAlgorithm::testCollision()", mProfiler); Vector3 suppA; // Support point of object A Vector3 suppB; // Support point of object B diff --git a/src/collision/narrowphase/SAT/SATAlgorithm.cpp b/src/collision/narrowphase/SAT/SATAlgorithm.cpp index 66be7d06..421a4b5d 100644 --- a/src/collision/narrowphase/SAT/SATAlgorithm.cpp +++ b/src/collision/narrowphase/SAT/SATAlgorithm.cpp @@ -32,7 +32,7 @@ #include "engine/OverlappingPair.h" #include "collision/shapes/TriangleShape.h" #include "configuration.h" -#include "engine/Profiler.h" +#include "utils/Profiler.h" #include #include #include @@ -52,7 +52,7 @@ SATAlgorithm::SATAlgorithm(MemoryAllocator& memoryAllocator) : mMemoryAllocator( // Test collision between a sphere and a convex mesh bool SATAlgorithm::testCollisionSphereVsConvexPolyhedron(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) const { - PROFILE("SATAlgorithm::testCollisionSphereVsConvexPolyhedron()", mProfiler); + RP3D_PROFILE("SATAlgorithm::testCollisionSphereVsConvexPolyhedron()", mProfiler); bool isSphereShape1 = narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::SPHERE; @@ -127,7 +127,7 @@ bool SATAlgorithm::testCollisionSphereVsConvexPolyhedron(NarrowPhaseInfo* narrow decimal SATAlgorithm::computePolyhedronFaceVsSpherePenetrationDepth(uint faceIndex, const ConvexPolyhedronShape* polyhedron, const SphereShape* sphere, const Vector3& sphereCenter) const { - PROFILE("SATAlgorithm::computePolyhedronFaceVsSpherePenetrationDepth)", mProfiler); + RP3D_PROFILE("SATAlgorithm::computePolyhedronFaceVsSpherePenetrationDepth)", mProfiler); // Get the face const HalfEdgeStructure::Face& face = polyhedron->getFace(faceIndex); @@ -144,7 +144,7 @@ decimal SATAlgorithm::computePolyhedronFaceVsSpherePenetrationDepth(uint faceInd // Test collision between a capsule and a convex mesh bool SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) const { - PROFILE("SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron()", mProfiler); + RP3D_PROFILE("SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron()", mProfiler); bool isCapsuleShape1 = narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CAPSULE; @@ -304,7 +304,7 @@ decimal SATAlgorithm::computeEdgeVsCapsuleInnerSegmentPenetrationDepth(const Con const Vector3& edgeDirectionCapsuleSpace, const Transform& polyhedronToCapsuleTransform, Vector3& outAxis) const { - PROFILE("SATAlgorithm::computeEdgeVsCapsuleInnerSegmentPenetrationDepth)", mProfiler); + RP3D_PROFILE("SATAlgorithm::computeEdgeVsCapsuleInnerSegmentPenetrationDepth)", mProfiler); decimal penetrationDepth = DECIMAL_LARGEST; @@ -338,7 +338,7 @@ decimal SATAlgorithm::computePolyhedronFaceVsCapsulePenetrationDepth(uint polyhe const CapsuleShape* capsule, const Transform& polyhedronToCapsuleTransform, Vector3& outFaceNormalCapsuleSpace) const { - PROFILE("SATAlgorithm::computePolyhedronFaceVsCapsulePenetrationDepth", mProfiler); + RP3D_PROFILE("SATAlgorithm::computePolyhedronFaceVsCapsulePenetrationDepth", mProfiler); // Get the face const HalfEdgeStructure::Face& face = polyhedron->getFace(polyhedronFaceIndex); @@ -364,7 +364,7 @@ bool SATAlgorithm::computeCapsulePolyhedronFaceContactPoints(uint referenceFaceI const Vector3& capsuleSegAPolyhedronSpace, const Vector3& capsuleSegBPolyhedronSpace, NarrowPhaseInfo* narrowPhaseInfo, bool isCapsuleShape1) const { - PROFILE("SATAlgorithm::computeCapsulePolyhedronFaceContactPoints", mProfiler); + RP3D_PROFILE("SATAlgorithm::computeCapsulePolyhedronFaceContactPoints", mProfiler); const HalfEdgeStructure::Face& face = polyhedron->getFace(referenceFaceIndex); @@ -459,7 +459,7 @@ bool SATAlgorithm::isMinkowskiFaceCapsuleVsEdge(const Vector3& capsuleSegment, c // Test collision between two convex polyhedrons bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) const { - PROFILE("SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron()", mProfiler); + RP3D_PROFILE("SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron()", mProfiler); assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CONVEX_POLYHEDRON); assert(narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::CONVEX_POLYHEDRON); @@ -804,7 +804,7 @@ bool SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints(bool isMinPene const Transform& polyhedron1ToPolyhedron2, const Transform& polyhedron2ToPolyhedron1, uint minFaceIndex, NarrowPhaseInfo* narrowPhaseInfo, decimal minPenetrationDepth) const { - PROFILE("SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints", mProfiler); + RP3D_PROFILE("SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints", mProfiler); const ConvexPolyhedronShape* referencePolyhedron = isMinPenetrationFaceNormalPolyhedron1 ? polyhedron1 : polyhedron2; const ConvexPolyhedronShape* incidentPolyhedron = isMinPenetrationFaceNormalPolyhedron1 ? polyhedron2 : polyhedron1; @@ -919,7 +919,7 @@ decimal SATAlgorithm::computeDistanceBetweenEdges(const Vector3& edge1A, const V const Vector3& edge1Direction, const Vector3& edge2Direction, Vector3& outSeparatingAxisPolyhedron2Space) const { - PROFILE("SATAlgorithm::computeDistanceBetweenEdges", mProfiler); + RP3D_PROFILE("SATAlgorithm::computeDistanceBetweenEdges", mProfiler); // If the two edges are parallel if (areParallelVectors(edge1Direction, edge2Direction)) { @@ -948,7 +948,7 @@ decimal SATAlgorithm::testSingleFaceDirectionPolyhedronVsPolyhedron(const Convex const Transform& polyhedron1ToPolyhedron2, uint faceIndex) const { - PROFILE("SATAlgorithm::testSingleFaceDirectionPolyhedronVsPolyhedron", mProfiler); + RP3D_PROFILE("SATAlgorithm::testSingleFaceDirectionPolyhedronVsPolyhedron", mProfiler); const HalfEdgeStructure::Face& face = polyhedron1->getFace(faceIndex); @@ -974,7 +974,7 @@ decimal SATAlgorithm::testFacesDirectionPolyhedronVsPolyhedron(const ConvexPolyh const Transform& polyhedron1ToPolyhedron2, uint& minFaceIndex) const { - PROFILE("SATAlgorithm::testFacesDirectionPolyhedronVsPolyhedron", mProfiler); + RP3D_PROFILE("SATAlgorithm::testFacesDirectionPolyhedronVsPolyhedron", mProfiler); decimal minPenetrationDepth = DECIMAL_LARGEST; @@ -1006,7 +1006,7 @@ bool SATAlgorithm::testEdgesBuildMinkowskiFace(const ConvexPolyhedronShape* poly const ConvexPolyhedronShape* polyhedron2, const HalfEdgeStructure::Edge& edge2, const Transform& polyhedron1ToPolyhedron2) const { - PROFILE("SATAlgorithm::testEdgesBuildMinkowskiFace", mProfiler); + RP3D_PROFILE("SATAlgorithm::testEdgesBuildMinkowskiFace", mProfiler); const Vector3 a = polyhedron1ToPolyhedron2.getOrientation() * polyhedron1->getFaceNormal(edge1.faceIndex); const Vector3 b = polyhedron1ToPolyhedron2.getOrientation() * polyhedron1->getFaceNormal(polyhedron1->getHalfEdge(edge1.twinEdgeIndex).faceIndex); @@ -1039,7 +1039,7 @@ bool SATAlgorithm::testEdgesBuildMinkowskiFace(const ConvexPolyhedronShape* poly bool SATAlgorithm::testGaussMapArcsIntersect(const Vector3& a, const Vector3& b, const Vector3& c, const Vector3& d, const Vector3& bCrossA, const Vector3& dCrossC) const { - PROFILE("SATAlgorithm::testGaussMapArcsIntersect", mProfiler); + RP3D_PROFILE("SATAlgorithm::testGaussMapArcsIntersect", mProfiler); const decimal cba = c.dot(bCrossA); const decimal dba = d.dot(bCrossA); diff --git a/src/collision/shapes/CollisionShape.cpp b/src/collision/shapes/CollisionShape.cpp index 0b64190e..976c7a51 100644 --- a/src/collision/shapes/CollisionShape.cpp +++ b/src/collision/shapes/CollisionShape.cpp @@ -25,7 +25,7 @@ // Libraries #include "CollisionShape.h" -#include "engine/Profiler.h" +#include "utils/Profiler.h" #include "body/CollisionBody.h" // We want to use the ReactPhysics3D namespace @@ -48,7 +48,7 @@ CollisionShape::CollisionShape(CollisionShapeName name, CollisionShapeType type) */ void CollisionShape::computeAABB(AABB& aabb, const Transform& transform) const { - PROFILE("CollisionShape::computeAABB()", mProfiler); + RP3D_PROFILE("CollisionShape::computeAABB()", mProfiler); // Get the local bounds in x,y and z direction Vector3 minBounds; diff --git a/src/collision/shapes/CollisionShape.h b/src/collision/shapes/CollisionShape.h index 8d84ab55..3fdf4470 100644 --- a/src/collision/shapes/CollisionShape.h +++ b/src/collision/shapes/CollisionShape.h @@ -35,7 +35,7 @@ #include "AABB.h" #include "collision/RaycastInfo.h" #include "memory/PoolAllocator.h" -#include "engine/Profiler.h" +#include "utils/Profiler.h" /// ReactPhysics3D namespace namespace reactphysics3d { diff --git a/src/collision/shapes/ConcaveMeshShape.cpp b/src/collision/shapes/ConcaveMeshShape.cpp index d2046adc..768f7c2e 100644 --- a/src/collision/shapes/ConcaveMeshShape.cpp +++ b/src/collision/shapes/ConcaveMeshShape.cpp @@ -114,7 +114,7 @@ void ConcaveMeshShape::testAllTriangles(TriangleCallback& callback, const AABB& /// the ray hits many triangles. bool ConcaveMeshShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const { - PROFILE("ConcaveMeshShape::raycast()", mProfiler); + RP3D_PROFILE("ConcaveMeshShape::raycast()", mProfiler); // Create the callback object that will compute ray casting against triangles ConcaveMeshRaycastCallback raycastCallback(mDynamicAABBTree, *this, proxyShape, raycastInfo, ray, allocator); diff --git a/src/collision/shapes/ConcaveMeshShape.h b/src/collision/shapes/ConcaveMeshShape.h index 2ecefb94..d35c9d23 100644 --- a/src/collision/shapes/ConcaveMeshShape.h +++ b/src/collision/shapes/ConcaveMeshShape.h @@ -32,7 +32,7 @@ #include "collision/TriangleMesh.h" #include "collision/shapes/TriangleShape.h" #include "containers/List.h" -#include "engine/Profiler.h" +#include "utils/Profiler.h" namespace reactphysics3d { diff --git a/src/collision/shapes/HeightFieldShape.cpp b/src/collision/shapes/HeightFieldShape.cpp index badfb68d..df2019c0 100644 --- a/src/collision/shapes/HeightFieldShape.cpp +++ b/src/collision/shapes/HeightFieldShape.cpp @@ -217,7 +217,7 @@ bool HeightFieldShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxySh // TODO : Implement raycasting without using an AABB for the ray // but using a dynamic AABB tree or octree instead - PROFILE("HeightFieldShape::raycast()", mProfiler); + RP3D_PROFILE("HeightFieldShape::raycast()", mProfiler); TriangleOverlapCallback triangleCallback(ray, proxyShape, raycastInfo, *this, allocator); diff --git a/src/collision/shapes/HeightFieldShape.h b/src/collision/shapes/HeightFieldShape.h index fc587d4c..7b834e2b 100644 --- a/src/collision/shapes/HeightFieldShape.h +++ b/src/collision/shapes/HeightFieldShape.h @@ -29,7 +29,7 @@ // Libraries #include "ConcaveShape.h" #include "collision/shapes/TriangleShape.h" -#include "engine/Profiler.h" +#include "utils/Profiler.h" namespace reactphysics3d { diff --git a/src/collision/shapes/TriangleShape.cpp b/src/collision/shapes/TriangleShape.cpp index 2257c0e6..d3b7d753 100644 --- a/src/collision/shapes/TriangleShape.cpp +++ b/src/collision/shapes/TriangleShape.cpp @@ -27,7 +27,7 @@ #include "TriangleShape.h" #include "collision/ProxyShape.h" #include "mathematics/mathematics_functions.h" -#include "engine/Profiler.h" +#include "utils/Profiler.h" #include "configuration.h" #include @@ -213,7 +213,7 @@ Vector3 TriangleShape::computeSmoothLocalContactNormalForTriangle(const Vector3& /// Real-time Collision Detection by Christer Ericson. bool TriangleShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const { - PROFILE("TriangleShape::raycast()", mProfiler); + RP3D_PROFILE("TriangleShape::raycast()", mProfiler); const Vector3 pq = ray.point2 - ray.point1; const Vector3 pa = mPoints[0] - ray.point1; diff --git a/src/constraint/BallAndSocketJoint.cpp b/src/constraint/BallAndSocketJoint.cpp index 272d922e..b1966d93 100644 --- a/src/constraint/BallAndSocketJoint.cpp +++ b/src/constraint/BallAndSocketJoint.cpp @@ -33,8 +33,8 @@ using namespace reactphysics3d; const decimal BallAndSocketJoint::BETA = decimal(0.2); // Constructor -BallAndSocketJoint::BallAndSocketJoint(const BallAndSocketJointInfo& jointInfo) - : Joint(jointInfo), mImpulse(Vector3(0, 0, 0)) { +BallAndSocketJoint::BallAndSocketJoint(uint id, const BallAndSocketJointInfo& jointInfo) + : Joint(id, jointInfo), mImpulse(Vector3(0, 0, 0)) { // Compute the local-space anchor point for each body mLocalAnchorPointBody1 = mBody1->getTransform().getInverse() * jointInfo.anchorPointWorldSpace; diff --git a/src/constraint/BallAndSocketJoint.h b/src/constraint/BallAndSocketJoint.h index c8836a23..ed66320f 100644 --- a/src/constraint/BallAndSocketJoint.h +++ b/src/constraint/BallAndSocketJoint.h @@ -125,7 +125,7 @@ class BallAndSocketJoint : public Joint { // -------------------- Methods -------------------- // /// Constructor - BallAndSocketJoint(const BallAndSocketJointInfo& jointInfo); + BallAndSocketJoint(uint id, const BallAndSocketJointInfo& jointInfo); /// Destructor virtual ~BallAndSocketJoint() override = default; diff --git a/src/constraint/FixedJoint.cpp b/src/constraint/FixedJoint.cpp index 17f9e455..94663c80 100644 --- a/src/constraint/FixedJoint.cpp +++ b/src/constraint/FixedJoint.cpp @@ -33,8 +33,8 @@ using namespace reactphysics3d; const decimal FixedJoint::BETA = decimal(0.2); // Constructor -FixedJoint::FixedJoint(const FixedJointInfo& jointInfo) - : Joint(jointInfo), mImpulseTranslation(0, 0, 0), mImpulseRotation(0, 0, 0) { +FixedJoint::FixedJoint(uint id, const FixedJointInfo& jointInfo) + : Joint(id, jointInfo), mImpulseTranslation(0, 0, 0), mImpulseRotation(0, 0, 0) { // Compute the local-space anchor point for each body const Transform& transform1 = mBody1->getTransform(); diff --git a/src/constraint/FixedJoint.h b/src/constraint/FixedJoint.h index e08b31cc..45fe1185 100644 --- a/src/constraint/FixedJoint.h +++ b/src/constraint/FixedJoint.h @@ -136,7 +136,7 @@ class FixedJoint : public Joint { // -------------------- Methods -------------------- // /// Constructor - FixedJoint(const FixedJointInfo& jointInfo); + FixedJoint(uint id, const FixedJointInfo& jointInfo); /// Destructor virtual ~FixedJoint() override = default; diff --git a/src/constraint/HingeJoint.cpp b/src/constraint/HingeJoint.cpp index 7b400a2a..990e7be1 100644 --- a/src/constraint/HingeJoint.cpp +++ b/src/constraint/HingeJoint.cpp @@ -34,8 +34,8 @@ using namespace reactphysics3d; const decimal HingeJoint::BETA = decimal(0.2); // Constructor -HingeJoint::HingeJoint(const HingeJointInfo& jointInfo) - : Joint(jointInfo), mImpulseTranslation(0, 0, 0), mImpulseRotation(0, 0), +HingeJoint::HingeJoint(uint id, const HingeJointInfo& jointInfo) + : Joint(id, jointInfo), mImpulseTranslation(0, 0, 0), mImpulseRotation(0, 0), mImpulseLowerLimit(0), mImpulseUpperLimit(0), mImpulseMotor(0), mIsLimitEnabled(jointInfo.isLimitEnabled), mIsMotorEnabled(jointInfo.isMotorEnabled), mLowerLimit(jointInfo.minAngleLimit), mUpperLimit(jointInfo.maxAngleLimit), diff --git a/src/constraint/HingeJoint.h b/src/constraint/HingeJoint.h index c553755d..fbcfeacf 100644 --- a/src/constraint/HingeJoint.h +++ b/src/constraint/HingeJoint.h @@ -287,7 +287,7 @@ class HingeJoint : public Joint { // -------------------- Methods -------------------- // /// Constructor - HingeJoint(const HingeJointInfo& jointInfo); + HingeJoint(uint id, const HingeJointInfo& jointInfo); /// Destructor virtual ~HingeJoint() override = default; diff --git a/src/constraint/Joint.cpp b/src/constraint/Joint.cpp index 2c0695ab..7582c1e0 100644 --- a/src/constraint/Joint.cpp +++ b/src/constraint/Joint.cpp @@ -29,8 +29,8 @@ using namespace reactphysics3d; // Constructor -Joint::Joint(const JointInfo& jointInfo) - :mBody1(jointInfo.body1), mBody2(jointInfo.body2), mType(jointInfo.type), +Joint::Joint(uint id, const JointInfo& jointInfo) + :mId(id), mBody1(jointInfo.body1), mBody2(jointInfo.body2), mType(jointInfo.type), mPositionCorrectionTechnique(jointInfo.positionCorrectionTechnique), mIsCollisionEnabled(jointInfo.isCollisionEnabled), mIsAlreadyInIsland(false) { diff --git a/src/constraint/Joint.h b/src/constraint/Joint.h index ead08a53..10d1680e 100644 --- a/src/constraint/Joint.h +++ b/src/constraint/Joint.h @@ -120,6 +120,9 @@ class Joint { // -------------------- Attributes -------------------- // + /// Id of the joint + uint mId; + /// Pointer to the first body of the joint RigidBody* const mBody1; @@ -144,6 +147,9 @@ class Joint { /// True if the joint has already been added into an island bool mIsAlreadyInIsland; + /// Total number of joints + static uint mNbTotalNbJoints; + // -------------------- Methods -------------------- // /// Return true if the joint has already been added into an island @@ -169,7 +175,7 @@ class Joint { // -------------------- Methods -------------------- // /// Constructor - Joint(const JointInfo& jointInfo); + Joint(uint id, const JointInfo& jointInfo); /// Destructor virtual ~Joint() = default; @@ -195,6 +201,9 @@ class Joint { /// Return true if the collision between the two bodies of the joint is enabled bool isCollisionEnabled() const; + /// Return the id of the joint + uint getId() const; + // -------------------- Friendship -------------------- // friend class DynamicsWorld; @@ -243,6 +252,14 @@ inline bool Joint::isCollisionEnabled() const { return mIsCollisionEnabled; } +// Return the id of the joint +/** + * @return The id of the joint + */ +inline uint Joint::getId() const { + return mId; +} + // Return true if the joint has already been added into an island inline bool Joint::isAlreadyInIsland() const { return mIsAlreadyInIsland; diff --git a/src/constraint/SliderJoint.cpp b/src/constraint/SliderJoint.cpp index 715bdc25..174ddb67 100644 --- a/src/constraint/SliderJoint.cpp +++ b/src/constraint/SliderJoint.cpp @@ -32,8 +32,8 @@ using namespace reactphysics3d; const decimal SliderJoint::BETA = decimal(0.2); // Constructor -SliderJoint::SliderJoint(const SliderJointInfo& jointInfo) - : Joint(jointInfo), mImpulseTranslation(0, 0), mImpulseRotation(0, 0, 0), +SliderJoint::SliderJoint(uint id, const SliderJointInfo& jointInfo) + : Joint(id, jointInfo), mImpulseTranslation(0, 0), mImpulseRotation(0, 0, 0), mImpulseLowerLimit(0), mImpulseUpperLimit(0), mImpulseMotor(0), mIsLimitEnabled(jointInfo.isLimitEnabled), mIsMotorEnabled(jointInfo.isMotorEnabled), mLowerLimit(jointInfo.minTranslationLimit), diff --git a/src/constraint/SliderJoint.h b/src/constraint/SliderJoint.h index e01a9ab4..3fd0035e 100644 --- a/src/constraint/SliderJoint.h +++ b/src/constraint/SliderJoint.h @@ -285,7 +285,7 @@ class SliderJoint : public Joint { // -------------------- Methods -------------------- // /// Constructor - SliderJoint(const SliderJointInfo& jointInfo); + SliderJoint(uint id, const SliderJointInfo& jointInfo); /// Destructor virtual ~SliderJoint() override = default; diff --git a/src/containers/List.h b/src/containers/List.h index 49bd2d21..2af3b76e 100644 --- a/src/containers/List.h +++ b/src/containers/List.h @@ -29,6 +29,7 @@ // Libraries #include "configuration.h" #include "memory/MemoryAllocator.h" +#include #include #include diff --git a/src/containers/Pair.h b/src/containers/Pair.h index 8c34b4ac..89d333b2 100644 --- a/src/containers/Pair.h +++ b/src/containers/Pair.h @@ -86,7 +86,7 @@ class Pair { } -// Hash function for struct VerticesPair +// Hash function for a reactphysics3d Pair namespace std { template struct hash> { diff --git a/src/engine/CollisionWorld.cpp b/src/engine/CollisionWorld.cpp index b91897e1..7fb223e2 100644 --- a/src/engine/CollisionWorld.cpp +++ b/src/engine/CollisionWorld.cpp @@ -26,28 +26,64 @@ // Libraries #include "CollisionWorld.h" #include +#include // Namespaces using namespace reactphysics3d; using namespace std; +// Initialization of static fields +uint CollisionWorld::mNbWorlds = 0; + // Constructor -CollisionWorld::CollisionWorld(const WorldSettings& worldSettings) - : mConfig(worldSettings), mCollisionDetection(this, mMemoryManager), mBodies(mMemoryManager.getPoolAllocator()), mCurrentBodyID(0), - mFreeBodiesIDs(mMemoryManager.getPoolAllocator()), mEventListener(nullptr) { +CollisionWorld::CollisionWorld(const string& name, const WorldSettings& worldSettings) + : mConfig(worldSettings), mCollisionDetection(this, mMemoryManager), mBodies(mMemoryManager.getPoolAllocator()), mCurrentBodyId(0), + mFreeBodiesIds(mMemoryManager.getPoolAllocator()), mEventListener(nullptr), mName(name) { + + // Automatically generate a name for the world + if (mName == "") { + + std::stringstream ss; + ss << "world"; + + if (mNbWorlds > 0) { + ss << mNbWorlds; + } + + mName = ss.str(); + } #ifdef IS_PROFILING_ACTIVE - // Set the profiler - mCollisionDetection.setProfiler(&mProfiler); + // Add a destination file for the profiling data + mProfiler.addFileDestination("rp3d_profiling_" + mName + ".txt", Profiler::Format::Text); + + // Set the profiler + mCollisionDetection.setProfiler(&mProfiler); #endif +#ifdef IS_LOGGING_ACTIVE + + // Add a log destination file + uint logLevel = static_cast(Logger::Level::Info) | static_cast(Logger::Level::Warning) | + static_cast(Logger::Level::Error); + mLogger.addFileDestination("rp3d_log_" + mName + ".html", logLevel, Logger::Format::HTML); + +#endif + + mNbWorlds++; + + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + "Collision World: Collision world " + mName + " has been created"); } // Destructor CollisionWorld::~CollisionWorld() { + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + "Collision World: Collision world " + mName + " has been destroyed"); + // Destroy all the collision bodies that have not been removed for (int i=mBodies.size() - 1 ; i >= 0; i--) { destroyCollisionBody(mBodies[i]); @@ -64,7 +100,7 @@ CollisionWorld::~CollisionWorld() { CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) { // Get the next available body ID - bodyindex bodyID = computeNextAvailableBodyID(); + bodyindex bodyID = computeNextAvailableBodyId(); // Largest index cannot be used (it is used for invalid index) assert(bodyID < std::numeric_limits::max()); @@ -85,6 +121,9 @@ CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) { #endif + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Body, + "Collision Body " + std::to_string(bodyID) + ": New collision body created"); + // Return the pointer to the rigid body return collisionBody; } @@ -95,11 +134,14 @@ CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) { */ void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) { + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Body, + "Collision Body " + std::to_string(collisionBody->getId()) + ": collision body destroyed"); + // Remove all the collision shapes of the body collisionBody->removeAllCollisionShapes(); // Add the body ID to the list of free IDs - mFreeBodiesIDs.add(collisionBody->getID()); + mFreeBodiesIds.add(collisionBody->getId()); // Call the destructor of the collision body collisionBody->~CollisionBody(); @@ -112,17 +154,17 @@ void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) { } // Return the next available body ID -bodyindex CollisionWorld::computeNextAvailableBodyID() { +bodyindex CollisionWorld::computeNextAvailableBodyId() { // Compute the body ID bodyindex bodyID; - if (mFreeBodiesIDs.size() != 0) { - bodyID = mFreeBodiesIDs[mFreeBodiesIDs.size() - 1]; - mFreeBodiesIDs.removeAt(mFreeBodiesIDs.size() - 1); + if (mFreeBodiesIds.size() != 0) { + bodyID = mFreeBodiesIds[mFreeBodiesIds.size() - 1]; + mFreeBodiesIds.removeAt(mFreeBodiesIds.size() - 1); } else { - bodyID = mCurrentBodyID; - mCurrentBodyID++; + bodyID = mCurrentBodyId; + mCurrentBodyId++; } return bodyID; diff --git a/src/engine/CollisionWorld.h b/src/engine/CollisionWorld.h index b3664ea1..f85d2fc6 100644 --- a/src/engine/CollisionWorld.h +++ b/src/engine/CollisionWorld.h @@ -30,7 +30,8 @@ #include #include "mathematics/mathematics.h" #include "containers/List.h" -#include "Profiler.h" +#include "utils/Profiler.h" +#include "utils/Logger.h" #include "body/CollisionBody.h" #include "collision/RaycastInfo.h" #include "OverlappingPair.h" @@ -71,25 +72,37 @@ class CollisionWorld { /// All the bodies (rigid and soft) of the world List mBodies; - /// Current body ID - bodyindex mCurrentBodyID; + /// Current body id + bodyindex mCurrentBodyId; - /// List of free ID for rigid bodies - List mFreeBodiesIDs; + /// List of free ids for rigid bodies + List mFreeBodiesIds; /// Pointer to an event listener object EventListener* mEventListener; + /// Name of the collision world + std::string mName; + #ifdef IS_PROFILING_ACTIVE /// Real-time hierarchical profiler Profiler mProfiler; #endif +#ifdef IS_LOGGING_ACTIVE + + /// Logger + Logger mLogger; +#endif + + /// Total number of worlds + static uint mNbWorlds; + // -------------------- Methods -------------------- // - /// Return the next available body ID - bodyindex computeNextAvailableBodyID(); + /// Return the next available body id + bodyindex computeNextAvailableBodyId(); /// Reset all the contact manifolds linked list of each body void resetContactManifoldListsOfBodies(); @@ -99,7 +112,7 @@ class CollisionWorld { // -------------------- Methods -------------------- // /// Constructor - CollisionWorld(const WorldSettings& worldSettings = WorldSettings()); + CollisionWorld(const std::string& name = "", const WorldSettings& worldSettings = WorldSettings()); /// Destructor virtual ~CollisionWorld(); @@ -147,13 +160,24 @@ class CollisionWorld { #ifdef IS_PROFILING_ACTIVE - /// Set the name of the profiler - void setProfilerName(std::string name); + /// Return a reference to the profiler + Profiler& getProfiler(); + +#endif + +#ifdef IS_LOGGING_ACTIVE + + /// Return a reference to the logger + Logger& getLogger(); + #endif /// Return the current world-space AABB of given proxy shape AABB getWorldAABB(const ProxyShape* proxyShape) const; + /// Return the name of the world + const std::string& getName() const; + // -------------------- Friendship -------------------- // friend class CollisionDetection; @@ -224,11 +248,25 @@ inline void CollisionWorld::testOverlap(CollisionBody* body, OverlapCallback* ov mCollisionDetection.testOverlap(body, overlapCallback, categoryMaskBits); } +// Return the name of the world +inline const std::string& CollisionWorld::getName() const { + return mName; +} + #ifdef IS_PROFILING_ACTIVE -// Set the name of the profiler -inline void CollisionWorld::setProfilerName(std::string name) { - mProfiler.setName(name); +// Return a reference to the profiler +inline Profiler& CollisionWorld::getProfiler() { + return mProfiler; +} + +#endif + +#ifdef IS_LOGGING_ACTIVE + +// Return a reference to the logger +inline Logger& CollisionWorld::getLogger() { + return mLogger; } #endif diff --git a/src/engine/ConstraintSolver.cpp b/src/engine/ConstraintSolver.cpp index 5345cbaf..f3b94396 100644 --- a/src/engine/ConstraintSolver.cpp +++ b/src/engine/ConstraintSolver.cpp @@ -25,7 +25,7 @@ // Libraries #include "ConstraintSolver.h" -#include "Profiler.h" +#include "utils/Profiler.h" using namespace reactphysics3d; @@ -43,7 +43,7 @@ ConstraintSolver::ConstraintSolver() : mIsWarmStartingActive(true) { // Initialize the constraint solver for a given island void ConstraintSolver::initializeForIsland(decimal dt, Island* island) { - PROFILE("ConstraintSolver::initializeForIsland()", mProfiler); + RP3D_PROFILE("ConstraintSolver::initializeForIsland()", mProfiler); assert(island != nullptr); assert(island->getNbBodies() > 0); @@ -73,7 +73,7 @@ void ConstraintSolver::initializeForIsland(decimal dt, Island* island) { // Solve the velocity constraints void ConstraintSolver::solveVelocityConstraints(Island* island) { - PROFILE("ConstraintSolver::solveVelocityConstraints()", mProfiler); + RP3D_PROFILE("ConstraintSolver::solveVelocityConstraints()", mProfiler); assert(island != nullptr); assert(island->getNbJoints() > 0); @@ -90,7 +90,7 @@ void ConstraintSolver::solveVelocityConstraints(Island* island) { // Solve the position constraints void ConstraintSolver::solvePositionConstraints(Island* island) { - PROFILE("ConstraintSolver::solvePositionConstraints()", mProfiler); + RP3D_PROFILE("ConstraintSolver::solvePositionConstraints()", mProfiler); assert(island != nullptr); assert(island->getNbJoints() > 0); diff --git a/src/engine/ContactSolver.cpp b/src/engine/ContactSolver.cpp index c6ef746e..d7539ca9 100644 --- a/src/engine/ContactSolver.cpp +++ b/src/engine/ContactSolver.cpp @@ -27,7 +27,7 @@ #include "ContactSolver.h" #include "DynamicsWorld.h" #include "body/RigidBody.h" -#include "Profiler.h" +#include "utils/Profiler.h" #include using namespace reactphysics3d; @@ -50,7 +50,7 @@ ContactSolver::ContactSolver(MemoryManager& memoryManager, const WorldSettings& // Initialize the contact constraints void ContactSolver::init(Island** islands, uint nbIslands, decimal timeStep) { - PROFILE("ContactSolver::init()", mProfiler); + RP3D_PROFILE("ContactSolver::init()", mProfiler); mTimeStep = timeStep; @@ -98,7 +98,7 @@ void ContactSolver::init(Island** islands, uint nbIslands, decimal timeStep) { // Initialize the constraint solver for a given island void ContactSolver::initializeForIsland(Island* island) { - PROFILE("ContactSolver::initializeForIsland()", mProfiler); + RP3D_PROFILE("ContactSolver::initializeForIsland()", mProfiler); assert(island != nullptr); assert(island->getNbBodies() > 0); @@ -326,7 +326,7 @@ void ContactSolver::initializeForIsland(Island* island) { /// the solution of the linear system void ContactSolver::warmStart() { - PROFILE("ContactSolver::warmStart()", mProfiler); + RP3D_PROFILE("ContactSolver::warmStart()", mProfiler); uint contactPointIndex = 0; @@ -479,7 +479,7 @@ void ContactSolver::warmStart() { // Solve the contacts void ContactSolver::solve() { - PROFILE("ContactSolver::solve()", mProfiler); + RP3D_PROFILE("ContactSolver::solve()", mProfiler); decimal deltaLambda; decimal lambdaTemp; @@ -758,7 +758,7 @@ void ContactSolver::solve() { // warm start the solver at the next iteration void ContactSolver::storeImpulses() { - PROFILE("ContactSolver::storeImpulses()", mProfiler); + RP3D_PROFILE("ContactSolver::storeImpulses()", mProfiler); uint contactPointIndex = 0; @@ -786,7 +786,7 @@ void ContactSolver::storeImpulses() { void ContactSolver::computeFrictionVectors(const Vector3& deltaVelocity, ContactManifoldSolver& contact) const { - PROFILE("ContactSolver::computeFrictionVectors()", mProfiler); + RP3D_PROFILE("ContactSolver::computeFrictionVectors()", mProfiler); assert(contact.normal.length() > decimal(0.0)); diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index 3199b775..f8ac6033 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -39,8 +39,8 @@ using namespace std; /** * @param gravity Gravity vector in the world (in meters per second squared) */ -DynamicsWorld::DynamicsWorld(const Vector3 &gravity, const WorldSettings& worldSettings) - : CollisionWorld(worldSettings), +DynamicsWorld::DynamicsWorld(const Vector3& gravity, const string& name, const WorldSettings& worldSettings) + : CollisionWorld(name, worldSettings), mContactSolver(mMemoryManager, mConfig), mNbVelocitySolverIterations(mConfig.defaultVelocitySolverNbIterations), mNbPositionSolverIterations(mConfig.defaultPositionSolverNbIterations), @@ -52,7 +52,8 @@ DynamicsWorld::DynamicsWorld(const Vector3 &gravity, const WorldSettings& worldS mConstrainedOrientations(nullptr), mNbIslands(0), mIslands(nullptr), mSleepLinearVelocity(mConfig.defaultSleepLinearVelocity), mSleepAngularVelocity(mConfig.defaultSleepAngularVelocity), - mTimeBeforeSleep(mConfig.defaultTimeBeforeSleep) { + mTimeBeforeSleep(mConfig.defaultTimeBeforeSleep), + mFreeJointsIDs(mMemoryManager.getPoolAllocator()), mCurrentJointId(0) { #ifdef IS_PROFILING_ACTIVE @@ -62,6 +63,9 @@ DynamicsWorld::DynamicsWorld(const Vector3 &gravity, const WorldSettings& worldS #endif + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + "Dynamics world " + mName + " has been created"); + } // Destructor @@ -82,13 +86,12 @@ DynamicsWorld::~DynamicsWorld() { #ifdef IS_PROFILING_ACTIVE - // Print the profiling report - ofstream myfile; - myfile.open(mProfiler.getName() + ".txt"); - mProfiler.printReport(myfile); - myfile.close(); + // Print the profiling report into the destinations + mProfiler.printReport(); #endif + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + "Dynamics world " + mName + " has been destroyed"); } // Update the physics simulation @@ -102,7 +105,7 @@ void DynamicsWorld::update(decimal timeStep) { mProfiler.incrementFrameCounter(); #endif - PROFILE("DynamicsWorld::update()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::update()", &mProfiler); mTimeStep = timeStep; @@ -150,7 +153,7 @@ void DynamicsWorld::update(decimal timeStep) { /// the sympletic Euler time stepping scheme. void DynamicsWorld::integrateRigidBodiesPositions() { - PROFILE("DynamicsWorld::integrateRigidBodiesPositions()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::integrateRigidBodiesPositions()", &mProfiler); // For each island of the world for (uint i=0; i < mNbIslands; i++) { @@ -189,7 +192,7 @@ void DynamicsWorld::integrateRigidBodiesPositions() { // Update the postion/orientation of the bodies void DynamicsWorld::updateBodiesState() { - PROFILE("DynamicsWorld::updateBodiesState()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::updateBodiesState()", &mProfiler); // For each island of the world for (uint islandIndex = 0; islandIndex < mNbIslands; islandIndex++) { @@ -226,7 +229,7 @@ void DynamicsWorld::updateBodiesState() { // Initialize the bodies velocities arrays for the next simulation step. void DynamicsWorld::initVelocityArrays() { - PROFILE("DynamicsWorld::initVelocityArrays()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::initVelocityArrays()", &mProfiler); // Allocate memory for the bodies velocity arrays uint nbBodies = mRigidBodies.size(); @@ -268,7 +271,7 @@ void DynamicsWorld::initVelocityArrays() { /// contact solver. void DynamicsWorld::integrateRigidBodiesVelocities() { - PROFILE("DynamicsWorld::integrateRigidBodiesVelocities()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::integrateRigidBodiesVelocities()", &mProfiler); // Initialize the bodies velocity arrays initVelocityArrays(); @@ -330,7 +333,7 @@ void DynamicsWorld::integrateRigidBodiesVelocities() { // Solve the contacts and constraints void DynamicsWorld::solveContactsAndConstraints() { - PROFILE("DynamicsWorld::solveContactsAndConstraints()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::solveContactsAndConstraints()", &mProfiler); // Set the velocities arrays mContactSolver.setSplitVelocitiesArrays(mSplitLinearVelocities, mSplitAngularVelocities); @@ -380,7 +383,7 @@ void DynamicsWorld::solveContactsAndConstraints() { // Solve the position error correction of the constraints void DynamicsWorld::solvePositionCorrection() { - PROFILE("DynamicsWorld::solvePositionCorrection()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::solvePositionCorrection()", &mProfiler); // Do not continue if there is no constraints if (mJoints.size() == 0) return; @@ -407,7 +410,7 @@ void DynamicsWorld::solvePositionCorrection() { RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) { // Compute the body ID - bodyindex bodyID = computeNextAvailableBodyID(); + bodyindex bodyID = computeNextAvailableBodyId(); // Largest index cannot be used (it is used for invalid index) assert(bodyID < std::numeric_limits::max()); @@ -427,6 +430,9 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) { #endif + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Body, + "Rigid Body " + std::to_string(bodyID) + ": New collision body created"); + // Return the pointer to the rigid body return rigidBody; } @@ -437,11 +443,14 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) { */ void DynamicsWorld::destroyRigidBody(RigidBody* rigidBody) { + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Body, + "Rigid Body " + std::to_string(rigidBody->getId()) + ": rigid body destroyed"); + // Remove all the collision shapes of the body rigidBody->removeAllCollisionShapes(); // Add the body ID to the list of free IDs - mFreeBodiesIDs.add(rigidBody->getID()); + mFreeBodiesIds.add(rigidBody->getId()); // Destroy all the joints in which the rigid body to be destroyed is involved JointListElement* element; @@ -472,6 +481,9 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) { Joint* newJoint = nullptr; + // Get the next available joint ID + uint jointId = computeNextAvailableJointId(); + // Allocate memory to create the new joint switch(jointInfo.type) { @@ -482,7 +494,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) { sizeof(BallAndSocketJoint)); const BallAndSocketJointInfo& info = static_cast( jointInfo); - newJoint = new (allocatedMemory) BallAndSocketJoint(info); + newJoint = new (allocatedMemory) BallAndSocketJoint(jointId, info); break; } @@ -492,7 +504,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) { void* allocatedMemory = mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(SliderJoint)); const SliderJointInfo& info = static_cast(jointInfo); - newJoint = new (allocatedMemory) SliderJoint(info); + newJoint = new (allocatedMemory) SliderJoint(jointId, info); break; } @@ -502,7 +514,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) { void* allocatedMemory = mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(HingeJoint)); const HingeJointInfo& info = static_cast(jointInfo); - newJoint = new (allocatedMemory) HingeJoint(info); + newJoint = new (allocatedMemory) HingeJoint(jointId, info); break; } @@ -512,7 +524,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) { void* allocatedMemory = mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(FixedJoint)); const FixedJointInfo& info = static_cast(jointInfo); - newJoint = new (allocatedMemory) FixedJoint(info); + newJoint = new (allocatedMemory) FixedJoint(jointId, info); break; } @@ -536,6 +548,9 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) { // Add the joint into the joint list of the bodies involved in the joint addJointToBody(newJoint); + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Joint, + "Joint " + std::to_string(newJoint->getId()) + ": New joint created"); + // Return the pointer to the created joint return newJoint; } @@ -548,6 +563,9 @@ void DynamicsWorld::destroyJoint(Joint* joint) { assert(joint != nullptr); + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Joint, + "Joint " + std::to_string(joint->getId()) + ": joint destroyed"); + // If the collision between the two bodies of the constraint was disabled if (!joint->isCollisionEnabled()) { @@ -568,9 +586,15 @@ void DynamicsWorld::destroyJoint(Joint* joint) { size_t nbBytes = joint->getSizeInBytes(); + // Add the joint ID to the list of free IDs + mFreeJointsIDs.add(joint->getId()); + // Call the destructor of the joint joint->~Joint(); + // Add the joint ID to the list of free IDs + mFreeJointsIDs.add(joint->getId()); + // Release the allocated memory mMemoryManager.release(MemoryManager::AllocationType::Pool, joint, nbBytes); } @@ -595,6 +619,23 @@ void DynamicsWorld::addJointToBody(Joint* joint) { joint->mBody2->mJointsList = jointListElement2; } +// Return the next available joint Id +uint DynamicsWorld::computeNextAvailableJointId() { + + // Compute the joint ID + uint jointId; + if (mFreeJointsIDs.size() != 0) { + jointId = mFreeJointsIDs[mFreeJointsIDs.size() - 1]; + mFreeJointsIDs.removeAt(mFreeJointsIDs.size() - 1); + } + else { + jointId = mCurrentJointId; + mCurrentJointId++; + } + + return jointId; +} + // Compute the islands of awake bodies. /// An island is an isolated group of rigid bodies that have constraints (joints or contacts) /// between each other. This method computes the islands at each time step as follows: For each @@ -604,7 +645,7 @@ void DynamicsWorld::addJointToBody(Joint* joint) { /// it). Then, we create an island with this group of connected bodies. void DynamicsWorld::computeIslands() { - PROFILE("DynamicsWorld::computeIslands()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::computeIslands()", &mProfiler); uint nbBodies = mRigidBodies.size(); @@ -693,7 +734,7 @@ void DynamicsWorld::computeIslands() { // Get the other body of the contact manifold RigidBody* body1 = static_cast(contactManifold->getBody1()); RigidBody* body2 = static_cast(contactManifold->getBody2()); - RigidBody* otherBody = (body1->getID() == bodyToVisit->getID()) ? body2 : body1; + RigidBody* otherBody = (body1->getId() == bodyToVisit->getId()) ? body2 : body1; // Check if the other body has already been added to the island if (otherBody->mIsAlreadyInIsland) continue; @@ -721,7 +762,7 @@ void DynamicsWorld::computeIslands() { // Get the other body of the contact manifold RigidBody* body1 = static_cast(joint->getBody1()); RigidBody* body2 = static_cast(joint->getBody2()); - RigidBody* otherBody = (body1->getID() == bodyToVisit->getID()) ? body2 : body1; + RigidBody* otherBody = (body1->getId() == bodyToVisit->getId()) ? body2 : body1; // Check if the other body has already been added to the island if (otherBody->mIsAlreadyInIsland) continue; @@ -751,7 +792,7 @@ void DynamicsWorld::computeIslands() { /// time, we put all the bodies of the island to sleep. void DynamicsWorld::updateSleepingBodies() { - PROFILE("DynamicsWorld::updateSleepingBodies()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::updateSleepingBodies()", &mProfiler); const decimal sleepLinearVelocitySquare = mSleepLinearVelocity * mSleepLinearVelocity; const decimal sleepAngularVelocitySquare = mSleepAngularVelocity * mSleepAngularVelocity; @@ -820,6 +861,9 @@ void DynamicsWorld::enableSleeping(bool isSleepingEnabled) { (*it)->setIsSleeping(false); } } + + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + "Dynamics World: isSleepingEnabled=" + (isSleepingEnabled ? std::string("true") : std::string("false")) ); } /// Return the list of all contacts of the world diff --git a/src/engine/DynamicsWorld.h b/src/engine/DynamicsWorld.h index e71c83e4..f8016fdc 100644 --- a/src/engine/DynamicsWorld.h +++ b/src/engine/DynamicsWorld.h @@ -116,6 +116,12 @@ class DynamicsWorld : public CollisionWorld { /// becomes smaller than the sleep velocity. decimal mTimeBeforeSleep; + /// List of free ID for joints + List mFreeJointsIDs; + + /// Current joint id + uint mCurrentJointId; + // -------------------- Methods -------------------- // /// Integrate the positions and orientations of rigid bodies. @@ -148,12 +154,16 @@ class DynamicsWorld : public CollisionWorld { /// Add the joint to the list of joints of the two bodies involved in the joint void addJointToBody(Joint* joint); + /// Return the next available joint id + uint computeNextAvailableJointId(); + public : // -------------------- Methods -------------------- // /// Constructor - DynamicsWorld(const Vector3& mGravity, const WorldSettings& worldSettings = WorldSettings()); + DynamicsWorld(const Vector3& mGravity, const std::string& name = "", + const WorldSettings& worldSettings = WorldSettings()); /// Destructor virtual ~DynamicsWorld() override; @@ -272,6 +282,9 @@ inline uint DynamicsWorld::getNbIterationsVelocitySolver() const { */ inline void DynamicsWorld::setNbIterationsVelocitySolver(uint nbIterations) { mNbVelocitySolverIterations = nbIterations; + + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + "Dynamics World: Set nb iterations velocity solver to " + std::to_string(nbIterations)); } // Get the number of iterations for the position constraint solver @@ -285,6 +298,9 @@ inline uint DynamicsWorld::getNbIterationsPositionSolver() const { */ inline void DynamicsWorld::setNbIterationsPositionSolver(uint nbIterations) { mNbPositionSolverIterations = nbIterations; + + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + "Dynamics World: Set nb iterations position solver to " + std::to_string(nbIterations)); } // Set the position correction technique used for contacts @@ -329,6 +345,9 @@ inline Vector3 DynamicsWorld::getGravity() const { */ inline void DynamicsWorld::setGravity(Vector3& gravity) { mGravity = gravity; + + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + "Dynamics World: Set gravity vector to " + gravity.to_string()); } // Return if the gravity is enaled @@ -346,6 +365,9 @@ inline bool DynamicsWorld::isGravityEnabled() const { */ inline void DynamicsWorld::setIsGratityEnabled(bool isGravityEnabled) { mIsGravityEnabled = isGravityEnabled; + + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + "Dynamics World: isGravityEnabled= " + (isGravityEnabled ? std::string("true") : std::string("false"))); } // Return the number of rigid bodies in the world @@ -390,6 +412,9 @@ inline decimal DynamicsWorld::getSleepLinearVelocity() const { inline void DynamicsWorld::setSleepLinearVelocity(decimal sleepLinearVelocity) { assert(sleepLinearVelocity >= decimal(0.0)); mSleepLinearVelocity = sleepLinearVelocity; + + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + "Dynamics World: sleepLinearVelocity= " + std::to_string(sleepLinearVelocity)); } // Return the current sleep angular velocity @@ -410,6 +435,9 @@ inline decimal DynamicsWorld::getSleepAngularVelocity() const { inline void DynamicsWorld::setSleepAngularVelocity(decimal sleepAngularVelocity) { assert(sleepAngularVelocity >= decimal(0.0)); mSleepAngularVelocity = sleepAngularVelocity; + + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + "Dynamics World: sleepAngularVelocity= " + std::to_string(sleepAngularVelocity)); } // Return the time a body is required to stay still before sleeping @@ -428,6 +456,9 @@ inline decimal DynamicsWorld::getTimeBeforeSleep() const { inline void DynamicsWorld::setTimeBeforeSleep(decimal timeBeforeSleep) { assert(timeBeforeSleep >= decimal(0.0)); mTimeBeforeSleep = timeBeforeSleep; + + RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + "Dynamics World: timeBeforeSleep= " + std::to_string(timeBeforeSleep)); } // Set an event listener object to receive events callbacks. diff --git a/src/engine/OverlappingPair.h b/src/engine/OverlappingPair.h index 4b98c9be..3fa083a1 100644 --- a/src/engine/OverlappingPair.h +++ b/src/engine/OverlappingPair.h @@ -263,9 +263,9 @@ inline bodyindexpair OverlappingPair::computeBodiesIndexPair(CollisionBody* body CollisionBody* body2) { // Construct the pair of body index - bodyindexpair indexPair = body1->getID() < body2->getID() ? - bodyindexpair(body1->getID(), body2->getID()) : - bodyindexpair(body2->getID(), body1->getID()); + bodyindexpair indexPair = body1->getId() < body2->getId() ? + bodyindexpair(body1->getId(), body2->getId()) : + bodyindexpair(body2->getId(), body1->getId()); assert(indexPair.first != indexPair.second); return indexPair; } diff --git a/src/mathematics/Matrix2x2.h b/src/mathematics/Matrix2x2.h index 8315eb99..0aeb3f5c 100644 --- a/src/mathematics/Matrix2x2.h +++ b/src/mathematics/Matrix2x2.h @@ -28,6 +28,7 @@ // Libraries #include +#include #include "Vector2.h" /// ReactPhysics3D namespace @@ -145,6 +146,9 @@ class Matrix2x2 { /// Overloaded operator to read/write element of the matrix. Vector2& operator[](int row); + + /// Return the string representation + std::string to_string() const; }; // Constructor of the class Matrix2x2 @@ -340,6 +344,12 @@ inline Vector2& Matrix2x2::operator[](int row) { return mRows[row]; } +// Get the string representation +inline std::string Matrix2x2::to_string() const { + return "Matrix2x2(" + std::to_string(mRows[0][0]) + "," + std::to_string(mRows[0][1]) + "," + + std::to_string(mRows[1][0]) + "," + std::to_string(mRows[1][1]) + ")"; +} + } #endif diff --git a/src/mathematics/Matrix3x3.h b/src/mathematics/Matrix3x3.h index 6897a2cf..fe2b053a 100644 --- a/src/mathematics/Matrix3x3.h +++ b/src/mathematics/Matrix3x3.h @@ -29,6 +29,7 @@ // Libraries #include +#include #include "Vector3.h" /// ReactPhysics3D namespace @@ -153,6 +154,9 @@ class Matrix3x3 { /// Overloaded operator to read/write element of the matrix. Vector3& operator[](int row); + + /// Return the string representation + std::string to_string() const; }; // Constructor of the class Matrix3x3 @@ -392,6 +396,13 @@ inline Vector3& Matrix3x3::operator[](int row) { return mRows[row]; } +// Get the string representation +inline std::string Matrix3x3::to_string() const { + return "Matrix3x3(" + std::to_string(mRows[0][0]) + "," + std::to_string(mRows[0][1]) + "," + std::to_string(mRows[0][2]) + "," + + std::to_string(mRows[1][0]) + "," + std::to_string(mRows[1][1]) + "," + std::to_string(mRows[1][2]) + "," + + std::to_string(mRows[2][0]) + "," + std::to_string(mRows[2][1]) + "," + std::to_string(mRows[2][2]) + ")"; +} + } #endif diff --git a/src/mathematics/Quaternion.h b/src/mathematics/Quaternion.h index dd0726dc..70f5a729 100644 --- a/src/mathematics/Quaternion.h +++ b/src/mathematics/Quaternion.h @@ -163,6 +163,9 @@ struct Quaternion { /// Overloaded operator for equality condition bool operator==(const Quaternion& quaternion) const; + /// Return the string representation + std::string to_string() const; + private: /// Initialize the quaternion using Euler angles @@ -379,6 +382,12 @@ inline bool Quaternion::operator==(const Quaternion& quaternion) const { z == quaternion.z && w == quaternion.w); } +// Get the string representation +inline std::string Quaternion::to_string() const { + return "Quaternion(" + std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z) + "," + + std::to_string(w) + ")"; +} + } #endif diff --git a/src/mathematics/Transform.h b/src/mathematics/Transform.h index aeaf4234..91dd4cb1 100644 --- a/src/mathematics/Transform.h +++ b/src/mathematics/Transform.h @@ -116,6 +116,9 @@ class Transform { /// Assignment operator Transform& operator=(const Transform& transform); + + /// Return the string representation + std::string to_string() const; }; // Constructor @@ -268,6 +271,11 @@ inline Transform& Transform::operator=(const Transform& transform) { return *this; } +// Get the string representation +inline std::string Transform::to_string() const { + return "Transform(" + mPosition.to_string() + "," + mOrientation.to_string() + ")"; +} + } #endif diff --git a/src/mathematics/Vector2.h b/src/mathematics/Vector2.h index bc5f8872..9f66ef4b 100644 --- a/src/mathematics/Vector2.h +++ b/src/mathematics/Vector2.h @@ -29,6 +29,7 @@ // Libraries #include #include +#include #include "mathematics_functions.h" #include "decimal.h" @@ -135,6 +136,9 @@ struct Vector2 { /// Overloaded less than operator for ordering to be used inside std::set for instance bool operator<(const Vector2& vector) const; + /// Return the string representation + std::string to_string() const; + /// Return a vector taking the minimum components of two vectors static Vector2 min(const Vector2& vector1, const Vector2& vector2); @@ -352,6 +356,11 @@ inline Vector2 Vector2::max(const Vector2& vector1, const Vector2& vector2) { std::max(vector1.y, vector2.y)); } +// Get the string representation +inline std::string Vector2::to_string() const { + return "Vector2(" + std::to_string(x) + "," + std::to_string(y) + ")"; +} + // Return the zero vector inline Vector2 Vector2::zero() { return Vector2(0, 0); diff --git a/src/mathematics/Vector3.h b/src/mathematics/Vector3.h index 95255fdb..27f5bcf6 100644 --- a/src/mathematics/Vector3.h +++ b/src/mathematics/Vector3.h @@ -29,6 +29,7 @@ // Libraries #include #include +#include #include "mathematics_functions.h" #include "decimal.h" @@ -147,6 +148,9 @@ struct Vector3 { /// Overloaded less than operator for ordering to be used inside std::set for instance bool operator<(const Vector3& vector) const; + /// Get the string representation + std::string to_string() const; + /// Return a vector taking the minimum components of two vectors static Vector3 min(const Vector3& vector1, const Vector3& vector2); @@ -391,6 +395,11 @@ inline decimal Vector3::getMaxValue() const { return std::max(std::max(x, y), z); } +// Get the string representation +inline std::string Vector3::to_string() const { + return "Vector3(" + std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z) + ")"; +} + // Return the zero vector inline Vector3 Vector3::zero() { return Vector3(0, 0, 0); diff --git a/src/utils/Logger.cpp b/src/utils/Logger.cpp new file mode 100644 index 00000000..89634598 --- /dev/null +++ b/src/utils/Logger.cpp @@ -0,0 +1,102 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2016 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. * +* * +********************************************************************************/ + +#ifdef IS_LOGGING_ACTIVE + +// Libraries +#include "Logger.h" +#include "memory/MemoryManager.h" + +using namespace reactphysics3d; + +// Constructor +Logger::Logger() + : mDestinations(MemoryManager::getBaseAllocator()), mFormatters(MemoryManager::getBaseAllocator()) +{ + + // Create the log formatters + mFormatters.add(Pair(Format::Text, new TextFormatter())); + mFormatters.add(Pair(Format::HTML, new HtmlFormatter())); +} + +// Destructor +Logger::~Logger() { + + removeAllDestinations(); + + // Remove all the loggers + for (auto it = mFormatters.begin(); it != mFormatters.end(); ++it) { + + delete it->second; + } +} + +// Return the corresponding formatter +Logger::Formatter* Logger::getFormatter(Format format) const { + + auto it = mFormatters.find(format); + if (it != mFormatters.end()) { + return it->second; + } + + return nullptr; +} + +// Add a log file destination to the logger +void Logger::addFileDestination(const std::string& filePath, uint logLevelFlag, Format format) { + + FileDestination* destination = new FileDestination(filePath, logLevelFlag, getFormatter(format)); + mDestinations.add(destination); +} + +/// Add a stream destination to the logger +void Logger::addStreamDestination(std::ostream& outputStream, uint logLevelFlag, Format format) { + + StreamDestination* destination = new StreamDestination(outputStream, logLevelFlag, getFormatter(format)); + mDestinations.add(destination); +} + +// Remove all logs destination previously set +void Logger::removeAllDestinations() { + + // Delete all the destinations + for (uint i=0; iwrite(message, level, category); + } +} + +#endif diff --git a/src/utils/Logger.h b/src/utils/Logger.h new file mode 100644 index 00000000..9c6421db --- /dev/null +++ b/src/utils/Logger.h @@ -0,0 +1,332 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2016 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 REACTPHYSICS3D_LOGGER_H +#define REACTPHYSICS3D_LOGGER_H + +#ifdef IS_LOGGING_ACTIVE + +// Libraries +#include "containers/List.h" +#include "containers/Map.h" +#include +#include +#include +#include + +/// ReactPhysics3D namespace +namespace reactphysics3d { + +// Class Logger +/** + * This class is used to log information, warnings or errors during the execution of the + * library code for easier debugging. + */ +class Logger { + + public: + + /// Log verbosity levels + enum class Level {Error = 1, Warning = 2, Info = 4}; + + /// Log categories + enum class Category {World, Body, Joint}; + + /// Log verbosity level + enum class Format {Text, HTML}; + + /// Log formatter + class Formatter { + + public: + + /// Constructor + Formatter() { + + } + + /// Destructor + virtual ~Formatter() { + + } + + /// Return the header to write at the beginning of the stream + virtual std::string getHeader() const { + return ""; + } + + /// Return the tail to write at the end of the stream + virtual std::string getTail() const { + return ""; + } + + /// Format a log message + virtual std::string format(const std::string& message, Level level, Category category) = 0; + }; + + class TextFormatter : public Formatter { + + public: + + /// Constructor + TextFormatter() { + + } + + /// Destructor + virtual ~TextFormatter() { + + } + + /// Format a log message + virtual std::string format(const std::string& message, Level level, + Category category) override { + return message; + } + }; + + class HtmlFormatter : public Formatter { + + private: + + /// Return the header to write at the beginning of the stream + virtual std::string getHeader() const override { + + std::stringstream ss; + + ss << "" << std::endl; + ss << "" << std::endl; + ss << "" << std::endl; + ss << "ReactPhysics3D Logs" << std::endl; + ss << "" << std::endl; + ss << "" << std::endl; + + return ss.str(); + } + + /// Return the tail to write at the end of the stream + virtual std::string getTail() const override { + + std::stringstream ss; + + ss << "" << std::endl; + ss << "" << std::endl; + + return ss.str(); + } + + public: + + /// Constructor + HtmlFormatter() { + + } + + /// Destructor + virtual ~HtmlFormatter() { + + } + + /// Format a log message + virtual std::string format(const std::string& message, Level level, + Category category) override { + + std::stringstream ss; + + ss << "

"; + ss << message; + ss << "

"; + + return ss.str(); + } + }; + + + /// Log destination + class Destination { + + public: + + /// Log level flag for this destination + uint levelFlag; + + /// Pointer to the formatter + Formatter* formatter; + + /// Constructor + Destination(uint levelFlag, Formatter* logFormatter) + : levelFlag(levelFlag), formatter(logFormatter) { + + } + + /// Destructor + virtual ~Destination() { + + } + + /// Write a message into the output stream + virtual void write(const std::string& message, Level level, Category category) = 0; + }; + + class FileDestination : public Destination { + + private: + + std::string mFilePath; + + /// Output file stream + std::ofstream mFileStream; + + public: + + /// Constructor + FileDestination(const std::string& filePath, uint levelFlag, Formatter* formatter) + :Destination(levelFlag, formatter), mFilePath(filePath), + mFileStream(filePath, std::ios::binary) { + + if(!mFileStream.is_open()) { + throw(std::runtime_error("ReactPhysics3D Logger: Unable to open an output stream to file " + mFilePath)); + } + + // Writer the head + mFileStream << formatter->getHeader() << std::endl; + } + + /// Destructor + virtual ~FileDestination() override { + + // Writer the tail + mFileStream << formatter->getTail() << std::endl; + + if (mFileStream.is_open()) { + + // Close the stream + mFileStream.close(); + } + } + + /// Write a message into the output stream + virtual void write(const std::string& message, Level level, Category category) override { + mFileStream << formatter->format(message, level, category) << std::endl; + } + }; + + /// Stream destination to output the logs into a stream + class StreamDestination : public Destination { + + private: + + /// Output stream + std::ostream& mOutputStream; + + public: + + /// Constructor + StreamDestination(std::ostream& outputStream, uint levelFlag, Formatter* formatter) + :Destination(levelFlag, formatter), mOutputStream(outputStream) { + + // Writer the head + mOutputStream << formatter->getHeader() << std::endl; + } + + /// Destructor + virtual ~StreamDestination() override { + + // Writer the tail + mOutputStream << formatter->getTail() << std::endl; + } + + /// Write a message into the output stream + virtual void write(const std::string& message, Level level, Category category) override { + mOutputStream << message << std::endl; + } + }; + + + private: + + // -------------------- Attributes -------------------- // + + /// All the log destinations + List mDestinations; + + /// Map a log format to the given formatter object + Map mFormatters; + + // -------------------- Methods -------------------- // + + /// Return the corresponding formatter + Formatter* getFormatter(Format format) const; + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + Logger(); + + /// Destructor + ~Logger(); + + /// Add a file destination to the logger + void addFileDestination(const std::string& filePath, uint logLevelFlag, Format format); + + /// Add a stream destination to the logger + void addStreamDestination(std::ostream& outputStream, uint logLevelFlag, Format format); + + /// Remove all logs destination previously set + void removeAllDestinations(); + + /// Log something + void log(Level level, Category category, const std::string& message); +}; + + +// Use this macro to log something +#define RP3D_LOG(logger, level, category, message) logger.log(level, category, message) + + +} + +#else // If logger is not active + +// Empty macro in case logs are not enabled +#define RP3D_LOG(logger, level, message) + +#endif + +// Hash function for struct VerticesPair +namespace std { + + template<> struct hash { + + size_t operator()(const reactphysics3d::Logger::Format format) const { + + return static_cast(format); + } + }; +} + +#endif diff --git a/src/engine/Profiler.cpp b/src/utils/Profiler.cpp similarity index 85% rename from src/engine/Profiler.cpp rename to src/utils/Profiler.cpp index 3212e4a1..12b449f1 100644 --- a/src/engine/Profiler.cpp +++ b/src/utils/Profiler.cpp @@ -28,12 +28,10 @@ // Libraries #include "Profiler.h" #include +#include "memory/MemoryManager.h" using namespace reactphysics3d; -// Initialization of static variables -int Profiler::mNbProfilers = 0; - // Constructor ProfileNode::ProfileNode(const char* name, ProfileNode* parentNode) :mName(name), mNbTotalCalls(0), mStartingTime(0), mTotalTime(0), @@ -79,7 +77,7 @@ void ProfileNode::enterBlockOfCode() { // Get the current system time to initialize the starting time of // the profiling of the current block of code - mStartingTime = Timer::getCurrentSystemTime() * 1000.0; + mStartingTime = Timer::getCurrentSystemTime() * 1000.0L; } mRecursionCounter++; @@ -92,7 +90,7 @@ bool ProfileNode::exitBlockOfCode() { if (mRecursionCounter == 0 && mNbTotalCalls != 0) { // Get the current system time - long double currentTime = Timer::getCurrentSystemTime() * 1000.0; + long double currentTime = Timer::getCurrentSystemTime() * 1000.0L; // Increase the total elasped time in the current block of code mTotalTime += currentTime - mStartingTime; @@ -105,7 +103,7 @@ bool ProfileNode::exitBlockOfCode() { // Reset the profiling of the node void ProfileNode::reset() { mNbTotalCalls = 0; - mTotalTime = 0.0; + mTotalTime = 0.0L; // Reset the child node if (mChildNode != nullptr) { @@ -156,27 +154,11 @@ void ProfileNodeIterator::enterParent() { } // Constructor -Profiler::Profiler(std::string name) :mRootNode("Root", nullptr) { - - // Set the name of the profiler - if (name == "") { - - if (mNbProfilers == 0) { - mName = "profiler"; - } - else { - mName = std::string("profiler") + std::to_string(mNbProfilers); - } - } - else { - mName = name; - } +Profiler::Profiler() :mRootNode("Root", nullptr), mDestinations(MemoryManager::getBaseAllocator()) { mCurrentNode = &mRootNode; - mProfilingStartTime = Timer::getCurrentSystemTime() * 1000.0; + mProfilingStartTime = Timer::getCurrentSystemTime() * 1000.0L; mFrameCounter = 0; - - mNbProfilers++; } // Destructor @@ -213,18 +195,48 @@ void Profiler::reset() { mRootNode.reset(); mRootNode.enterBlockOfCode(); mFrameCounter = 0; - mProfilingStartTime = Timer::getCurrentSystemTime() * 1000.0; + mProfilingStartTime = Timer::getCurrentSystemTime() * 1000.0L; } // Print the report of the profiler in a given output stream -void Profiler::printReport(std::ostream& outputStream) { - ProfileNodeIterator* iterator = Profiler::getIterator(); +void Profiler::printReport() { - // Recursively print the report of each node of the profiler tree - printRecursiveNodeReport(iterator, 0, outputStream); + // For each destination + for (auto it = mDestinations.begin(); it != mDestinations.end(); ++it) { - // Destroy the iterator - destroyIterator(iterator); + ProfileNodeIterator* iterator = Profiler::getIterator(); + + // Recursively print the report of each node of the profiler tree + printRecursiveNodeReport(iterator, 0, (*it)->getOutputStream()); + + // Destroy the iterator + destroyIterator(iterator); + } +} + +// Remove all output profiling destinations previously set +void Profiler::removeAllDestinations() { + + // Delete all the destinations + for (size_t i=0; iisRoot() ? getElapsedTimeSinceStart() : iterator->getCurrentParentTotalTime(); - long double accumulatedTime = 0.0; + long double accumulatedTime = 0.0L; uint nbFrames = Profiler::getNbFrames(); for (int i=0; igetCurrentParentName() << " (total running time : " << parentTime << " ms) ---" << std::endl; - long double totalTime = 0.0; + long double totalTime = 0.0L; // Recurse over the children of the current node int nbChildren = 0; @@ -256,7 +268,7 @@ void Profiler::printRecursiveNodeReport(ProfileNodeIterator* iterator, long double currentTotalTime = iterator->getCurrentTotalTime(); accumulatedTime += currentTotalTime; long double fraction = parentTime > std::numeric_limits::epsilon() ? - (currentTotalTime / parentTime) * 100.0 : 0.0; + (currentTotalTime / parentTime) * 100.0L : 0.0L; for (int j=0; jgetCurrentName() << " : " << fraction << " % | " << (currentTotalTime / (long double) (nbFrames)) << @@ -270,7 +282,7 @@ void Profiler::printRecursiveNodeReport(ProfileNodeIterator* iterator, } for (int i=0; i std::numeric_limits::epsilon() ? - ((parentTime - accumulatedTime) / parentTime) * 100.0 : 0.0; + ((parentTime - accumulatedTime) / parentTime) * 100.0L : 0.0L; long double difference = parentTime - accumulatedTime; outputStream << "| Unaccounted : " << difference << " ms (" << percentage << " %)" << std::endl; diff --git a/src/engine/Profiler.h b/src/utils/Profiler.h similarity index 77% rename from src/engine/Profiler.h rename to src/utils/Profiler.h index 84b7ed59..df64dfd6 100644 --- a/src/engine/Profiler.h +++ b/src/utils/Profiler.h @@ -30,7 +30,9 @@ // Libraries #include "configuration.h" -#include "Timer.h" +#include "engine/Timer.h" +#include +#include "containers/List.h" /// ReactPhysics3D namespace namespace reactphysics3d { @@ -180,16 +182,102 @@ class ProfileNodeIterator { */ class Profiler { + public: + + /// Format of the profiling data (text, ...) + enum class Format {Text}; + + /// Profile destination + class Destination { + + public: + + /// Log format (text, ...) + Format format; + + /// Constructor + Destination(Format logFormat) : format(logFormat) { + + } + + /// Destructor + virtual ~Destination() { + + } + + /// Return the current output stream + virtual std::ostream& getOutputStream() = 0; + }; + + /// File destination to output profiling data into a file + class FileDestination : public Destination { + + private: + + std::string mFilePath; + + /// Output file stream + std::ofstream mFileStream; + + public: + + /// Constructor + FileDestination(const std::string& filePath, Format format) + :Destination(format), mFilePath(filePath), + mFileStream(filePath, std::ios::binary) { + + if(!mFileStream.is_open()) { + throw(std::runtime_error("ReactPhysics3D Logger: Unable to open an output stream to file " + mFilePath)); + } + } + + /// Destructor + virtual ~FileDestination() override { + + if (mFileStream.is_open()) { + + // Close the stream + mFileStream.close(); + } + } + + /// Return the current output stream + virtual std::ostream& getOutputStream() override { + return mFileStream; + } + }; + + /// Stream destination to output profiling data into a stream + class StreamDestination : public Destination { + + private: + + /// Output stream + std::ostream& mOutputStream; + + public: + + /// Constructor + StreamDestination(std::ostream& outputStream, Format format) + :Destination(format), mOutputStream(outputStream) { + + } + + /// Destructor + virtual ~StreamDestination() override { + + } + + /// Return the current output stream + virtual std::ostream& getOutputStream() override { + return mOutputStream; + } + }; + private : // -------------------- Attributes -------------------- // - /// Profiler name - std::string mName; - - /// Total number of profilers - static int mNbProfilers; - /// Root node of the profiler tree ProfileNode mRootNode; @@ -202,8 +290,12 @@ class Profiler { /// Starting profiling time long double mProfilingStartTime; + /// All the output destinations + List mDestinations; + /// Recursively print the report of a given node of the profiler tree - void printRecursiveNodeReport(ProfileNodeIterator* iterator, int spacing, std::ostream& outputStream); + void printRecursiveNodeReport(ProfileNodeIterator* iterator, int spacing, + std::ostream &outputStream); /// Destroy a previously allocated iterator void destroyIterator(ProfileNodeIterator* iterator); @@ -216,7 +308,7 @@ class Profiler { // -------------------- Methods -------------------- // /// Constructor - Profiler(std::string name = ""); + Profiler(); /// Destructor ~Profiler(); @@ -234,12 +326,6 @@ class Profiler { /// Return the number of frames uint getNbFrames(); - /// Get the name of the profiler - std::string getName() const; - - /// Set the name of the profiler - void setName(std::string name); - /// Return the elasped time since the start/reset of the profiling long double getElapsedTimeSinceStart(); @@ -249,8 +335,17 @@ class Profiler { /// Return an iterator over the profiler tree starting at the root ProfileNodeIterator* getIterator(); - /// Print the report of the profiler in a given output stream - void printReport(std::ostream& outputStream); + // Add a file destination to the profiler + void addFileDestination(const std::string& filePath, Format format); + + // Add a stream destination to the profiler + void addStreamDestination(std::ostream& outputStream, Format format); + + /// Remove all logs destination previously set + void removeAllDestinations(); + + /// Print the report of the profiler in every output destinations + void printReport(); }; // Class ProfileSample @@ -287,7 +382,7 @@ class ProfileSample { }; // Use this macro to start profile a block of code -#define PROFILE(name, profiler) ProfileSample profileSample(name, profiler) +#define RP3D_PROFILE(name, profiler) ProfileSample profileSample(name, profiler) // Return true if we are at the root of the profiler tree inline bool ProfileNodeIterator::isRoot() { @@ -374,19 +469,9 @@ inline uint Profiler::getNbFrames() { return mFrameCounter; } -// Get the name of the profiler -inline std::string Profiler::getName() const { - return mName; -} - -// Set the name of the profiler -inline void Profiler::setName(std::string name) { - mName = name; -} - // Return the elasped time since the start/reset of the profiling inline long double Profiler::getElapsedTimeSinceStart() { - long double currentTime = Timer::getCurrentSystemTime() * 1000.0; + long double currentTime = Timer::getCurrentSystemTime() * 1000.0L; return currentTime - mProfilingStartTime; } @@ -412,10 +497,10 @@ inline void Profiler::destroy() { } -#else // In profile is not active +#else // If profile is not active // Empty macro in case profiling is not active -#define PROFILE(name, profiler) +#define RP3D_PROFILE(name, profiler) #endif diff --git a/test/tests/collision/TestCollisionWorld.h b/test/tests/collision/TestCollisionWorld.h index 64abab25..372b9dc5 100644 --- a/test/tests/collision/TestCollisionWorld.h +++ b/test/tests/collision/TestCollisionWorld.h @@ -639,7 +639,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points Vector3 localBody1Point(3, 0, 0); @@ -663,7 +663,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -684,7 +684,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -705,7 +705,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -759,7 +759,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points Vector3 localBody1Point(3, 0, 0); @@ -783,7 +783,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -804,7 +804,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -825,7 +825,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -869,7 +869,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points localBody1Point = std::sqrt(4.5f) * Vector3(1, -1, 0); @@ -893,7 +893,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -914,7 +914,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -935,7 +935,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -979,7 +979,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points localBody1Point = std::sqrt(9.0f / 3.0f) * Vector3(1, -1, -1); @@ -1003,7 +1003,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1024,7 +1024,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1045,7 +1045,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1099,7 +1099,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points Vector3 localBody1Point(0, -3, 0); @@ -1123,7 +1123,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1144,7 +1144,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1165,7 +1165,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1209,7 +1209,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points localBody1Point = Vector3(3, 0, 0); @@ -1233,7 +1233,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1254,7 +1254,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1275,7 +1275,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1329,7 +1329,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points Vector3 localBody1Point(3, 0, 0); @@ -1353,7 +1353,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1374,7 +1374,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1395,7 +1395,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1439,7 +1439,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points localBody1Point = std::sqrt(4.5f) * Vector3(1, -1, 0); @@ -1463,7 +1463,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1484,7 +1484,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1505,7 +1505,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1549,7 +1549,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points localBody1Point = std::sqrt(9.0f / 3.0f) * Vector3(1, -1, -1); @@ -1573,7 +1573,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1594,7 +1594,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1615,7 +1615,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1669,7 +1669,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points Vector3 localBody1Point(0, -3, 0); @@ -1693,7 +1693,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1714,7 +1714,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1735,7 +1735,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -1789,7 +1789,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); // Test contact points Vector3 localBody1Point1(-3, -2, -2); @@ -1831,7 +1831,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -1860,7 +1860,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -1890,7 +1890,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -1953,7 +1953,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); // Test contact points Vector3 localBody1Point1(-3, -2, -2); @@ -1995,7 +1995,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -2024,7 +2024,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -2054,7 +2054,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -2117,7 +2117,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId(); // Test contact points Vector3 localBody1Point1(-3, -2, -2); @@ -2159,7 +2159,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -2188,7 +2188,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -2218,7 +2218,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -2281,7 +2281,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); // Test contact points Vector3 localBody1Point1(3, 1, 0); @@ -2304,7 +2304,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -2325,7 +2325,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -2346,7 +2346,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -2400,7 +2400,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId(); // Test contact points Vector3 localBody1Point1(3, 1, 0); @@ -2423,7 +2423,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -2444,7 +2444,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -2465,7 +2465,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1, @@ -2519,7 +2519,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); for (int i=0; icontactManifolds[0].contactPoints.size(); i++) { test(approxEqual(collisionData->contactManifolds[0].contactPoints[i].penetrationDepth, 1.0f)); @@ -2539,7 +2539,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); for (int i=0; icontactManifolds[0].contactPoints.size(); i++) { test(approxEqual(collisionData->contactManifolds[0].contactPoints[i].penetrationDepth, 1.0f)); @@ -2559,7 +2559,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); for (int i=0; icontactManifolds[0].contactPoints.size(); i++) { test(approxEqual(collisionData->contactManifolds[0].contactPoints[i].penetrationDepth, 1.0f)); @@ -2579,7 +2579,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId(); // Test contact points for (int i=0; icontactManifolds[0].contactPoints.size(); i++) { @@ -2633,7 +2633,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId(); for (int i=0; icontactManifolds[0].contactPoints.size(); i++) { test(approxEqual(collisionData->contactManifolds[0].contactPoints[i].penetrationDepth, 1.0f)); @@ -2653,7 +2653,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId(); for (int i=0; icontactManifolds[0].contactPoints.size(); i++) { test(approxEqual(collisionData->contactManifolds[0].contactPoints[i].penetrationDepth, 1.0f)); @@ -2673,7 +2673,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId(); for (int i=0; icontactManifolds[0].contactPoints.size(); i++) { test(approxEqual(collisionData->contactManifolds[0].contactPoints[i].penetrationDepth, 1.0f)); @@ -2693,7 +2693,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 4); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId(); // Test contact points for (int i=0; icontactManifolds[0].contactPoints.size(); i++) { @@ -2747,7 +2747,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId(); // Test contact points Vector3 localBody1Point(2, 3, 0); @@ -2771,7 +2771,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -2792,7 +2792,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -2813,7 +2813,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -2857,7 +2857,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId(); // Test contact points localBody1Point = Vector3(0, 5, 0); @@ -2881,7 +2881,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -2902,7 +2902,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -2923,7 +2923,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -2977,7 +2977,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID(); + bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId(); // Test contact points Vector3 localBody1Point(0, -5, 0); @@ -3001,7 +3001,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -3022,7 +3022,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, @@ -3043,7 +3043,7 @@ class TestCollisionWorld : public Test { test(collisionData->getTotalNbContactPoints() == 1); // True if the bodies are swapped in the collision callback response - swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID(); + swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId(); // Test contact points test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point, diff --git a/test/tests/collision/TestRaycast.h b/test/tests/collision/TestRaycast.h index 60d3068b..7714264a 100644 --- a/test/tests/collision/TestRaycast.h +++ b/test/tests/collision/TestRaycast.h @@ -63,7 +63,7 @@ class WorldRaycastCallback : public RaycastCallback { virtual decimal notifyRaycastHit(const RaycastInfo& info) override { - if (shapeToTest->getBody()->getID() == info.body->getID()) { + if (shapeToTest->getBody()->getId() == info.body->getId()) { raycastInfo.body = info.body; raycastInfo.hitFraction = info.hitFraction; raycastInfo.proxyShape = info.proxyShape; @@ -1310,7 +1310,6 @@ class TestRaycast : public Test { // CollisionWorld::raycast() mCallback.reset(); mWorld->raycast(ray, &mCallback); - Vector3 localTest = inverse * mCallback.raycastInfo.worldPoint; test(mCallback.isHit); test(mCallback.raycastInfo.body == mConvexMeshBody); test(mCallback.raycastInfo.proxyShape == mConvexMeshProxyShape); diff --git a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp index 02e8acc1..644b378f 100755 --- a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp +++ b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp @@ -47,13 +47,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine setScenePosition(center, SCENE_RADIUS); // Create the dynamics world for the physics simulation - mPhysicsWorld = new rp3d::CollisionWorld(); - -#ifdef IS_PROFILING_ACTIVE - - mPhysicsWorld->setProfilerName(name + "_profiler"); - -#endif + mPhysicsWorld = new rp3d::CollisionWorld(name); // ---------- Sphere 1 ---------- // diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index 8efc13de..e5fb3110 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -46,14 +46,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin rp3d::Vector3 gravity(0, -9.81f, 0); // Create the dynamics world for the physics simulation - mPhysicsWorld = new rp3d::DynamicsWorld(gravity); - -#ifdef IS_PROFILING_ACTIVE - - mPhysicsWorld->setProfilerName(name + "_profiler"); - -#endif - + mPhysicsWorld = new rp3d::DynamicsWorld(gravity, name); for (int i=0; isetProfilerName(name + "_profiler"); - -#endif + mPhysicsWorld = new rp3d::DynamicsWorld(gravity, name); // ---------- Create the boxes ----------- // for (int i = 0; isetProfilerName(name + "_profiler"); - -#endif + mPhysicsWorld = new rp3d::DynamicsWorld(gravity, name); // Create all the cubes of the scene for (int i=0; isetProfilerName(name + "_profiler"); - -#endif + mPhysicsWorld = new rp3d::DynamicsWorld(gravity, name); // Create all the cubes of the scene for (int i=1; i<=NB_FLOORS; i++) { diff --git a/testbed/scenes/heightfield/HeightFieldScene.cpp b/testbed/scenes/heightfield/HeightFieldScene.cpp index 0d13d40d..ed8f1313 100644 --- a/testbed/scenes/heightfield/HeightFieldScene.cpp +++ b/testbed/scenes/heightfield/HeightFieldScene.cpp @@ -46,14 +46,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); // Create the dynamics world for the physics simulation - mPhysicsWorld = new rp3d::DynamicsWorld(gravity); - -#ifdef IS_PROFILING_ACTIVE - - mPhysicsWorld->setProfilerName(name + "_profiler"); - -#endif - + mPhysicsWorld = new rp3d::DynamicsWorld(gravity, name); for (int i = 0; isetProfilerName(name + "_profiler"); - -#endif + mPhysicsWorld = new rp3d::DynamicsWorld(gravity, name); // Create the Ball-and-Socket joint createBallAndSocketJoints(); diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index 5705627d..6ef8a54c 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -45,13 +45,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings) setScenePosition(center, SCENE_RADIUS); // Create the dynamics world for the physics simulation - mPhysicsWorld = new rp3d::CollisionWorld(); - -#ifdef IS_PROFILING_ACTIVE - - mPhysicsWorld->setProfilerName(name + "_profiler"); - -#endif + mPhysicsWorld = new rp3d::CollisionWorld(name); // ---------- Dumbbell ---------- // From 2e28b5ad8fb18c637094d11ece969f69367ce89a Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Thu, 15 Mar 2018 23:11:26 +0100 Subject: [PATCH 2/5] Refactor profiler and add logger --- src/configuration.h | 4 + src/engine/CollisionWorld.cpp | 53 +++++-- src/engine/CollisionWorld.h | 25 ++-- src/engine/DynamicsWorld.cpp | 37 ++--- src/engine/DynamicsWorld.h | 4 +- src/utils/Logger.cpp | 6 +- src/utils/Logger.h | 130 +++++++++++++++--- .../CollisionDetectionScene.cpp | 5 +- .../collisionshapes/CollisionShapesScene.cpp | 5 +- .../scenes/concavemesh/ConcaveMeshScene.cpp | 5 +- testbed/scenes/cubes/CubesScene.cpp | 5 +- testbed/scenes/cubestack/CubeStackScene.cpp | 5 +- .../scenes/heightfield/HeightFieldScene.cpp | 5 +- testbed/scenes/joints/JointsScene.cpp | 5 +- testbed/scenes/raycast/RaycastScene.cpp | 5 +- testbed/src/Gui.cpp | 8 ++ testbed/src/Scene.h | 3 + testbed/src/SceneDemo.cpp | 31 +++-- testbed/src/SceneDemo.h | 3 + testbed/src/TestbedApplication.cpp | 7 + testbed/src/TestbedApplication.h | 3 + 21 files changed, 277 insertions(+), 77 deletions(-) diff --git a/src/configuration.h b/src/configuration.h index 539f66b9..aa71e88a 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -31,6 +31,7 @@ #include #include #include +#include #include "decimal.h" #include "containers/Pair.h" @@ -110,6 +111,9 @@ constexpr decimal DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER = decimal(1.7); */ struct WorldSettings { + /// Name of the world + std::string worldName = ""; + /// Distance threshold for two contact points for a valid persistent contact (in meters) decimal persistentContactDistanceThreshold = decimal(0.03); diff --git a/src/engine/CollisionWorld.cpp b/src/engine/CollisionWorld.cpp index 7fb223e2..1dbf1b6f 100644 --- a/src/engine/CollisionWorld.cpp +++ b/src/engine/CollisionWorld.cpp @@ -36,9 +36,11 @@ using namespace std; uint CollisionWorld::mNbWorlds = 0; // Constructor -CollisionWorld::CollisionWorld(const string& name, const WorldSettings& worldSettings) +CollisionWorld::CollisionWorld(const WorldSettings& worldSettings, Logger* logger, Profiler* profiler) : mConfig(worldSettings), mCollisionDetection(this, mMemoryManager), mBodies(mMemoryManager.getPoolAllocator()), mCurrentBodyId(0), - mFreeBodiesIds(mMemoryManager.getPoolAllocator()), mEventListener(nullptr), mName(name) { + mFreeBodiesIds(mMemoryManager.getPoolAllocator()), mEventListener(nullptr), mName(worldSettings.worldName), + mProfiler(profiler), mLogger(logger), mIsProfilerCreatedByUser(profiler != nullptr), + mIsLoggerCreatedByUser(logger != nullptr) { // Automatically generate a name for the world if (mName == "") { @@ -55,20 +57,33 @@ CollisionWorld::CollisionWorld(const string& name, const WorldSettings& worldSet #ifdef IS_PROFILING_ACTIVE - // Add a destination file for the profiling data - mProfiler.addFileDestination("rp3d_profiling_" + mName + ".txt", Profiler::Format::Text); + // If the user has not provided its own profiler, we create one + if (mProfiler == nullptr) { + + mProfiler = new Profiler(); + + // Add a destination file for the profiling data + mProfiler->addFileDestination("rp3d_profiling_" + mName + ".txt", Profiler::Format::Text); + } + // Set the profiler - mCollisionDetection.setProfiler(&mProfiler); + mCollisionDetection.setProfiler(mProfiler); #endif #ifdef IS_LOGGING_ACTIVE - // Add a log destination file - uint logLevel = static_cast(Logger::Level::Info) | static_cast(Logger::Level::Warning) | - static_cast(Logger::Level::Error); - mLogger.addFileDestination("rp3d_log_" + mName + ".html", logLevel, Logger::Format::HTML); + // If the user has not provided its own logger, we create one + if (mLogger == nullptr) { + + mLogger = new Logger(); + + // Add a log destination file + uint logLevel = static_cast(Logger::Level::Info) | static_cast(Logger::Level::Warning) | + static_cast(Logger::Level::Error); + mLogger->addFileDestination("rp3d_log_" + mName + ".html", logLevel, Logger::Format::HTML); + } #endif @@ -89,6 +104,24 @@ CollisionWorld::~CollisionWorld() { destroyCollisionBody(mBodies[i]); } +#ifdef IS_PROFILING_ACTIVE + + /// Delete the profiler + if (!mIsProfilerCreatedByUser) { + delete mProfiler; + } + +#endif + +#ifdef IS_LOGGING_ACTIVE + + /// Delete the logger + if (!mIsLoggerCreatedByUser) { + delete mLogger; + } + +#endif + assert(mBodies.size() == 0); } @@ -117,7 +150,7 @@ CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) { #ifdef IS_PROFILING_ACTIVE - collisionBody->setProfiler(&mProfiler); + collisionBody->setProfiler(mProfiler); #endif diff --git a/src/engine/CollisionWorld.h b/src/engine/CollisionWorld.h index f85d2fc6..ad3549fe 100644 --- a/src/engine/CollisionWorld.h +++ b/src/engine/CollisionWorld.h @@ -87,15 +87,21 @@ class CollisionWorld { #ifdef IS_PROFILING_ACTIVE /// Real-time hierarchical profiler - Profiler mProfiler; + Profiler* mProfiler; #endif #ifdef IS_LOGGING_ACTIVE /// Logger - Logger mLogger; + Logger* mLogger; #endif + /// True if the profiler has been created by the user + bool mIsProfilerCreatedByUser; + + /// True if the logger has been created by the user + bool mIsLoggerCreatedByUser; + /// Total number of worlds static uint mNbWorlds; @@ -112,7 +118,8 @@ class CollisionWorld { // -------------------- Methods -------------------- // /// Constructor - CollisionWorld(const std::string& name = "", const WorldSettings& worldSettings = WorldSettings()); + CollisionWorld(const WorldSettings& worldSettings = WorldSettings(), Logger* logger = nullptr, + Profiler* profiler = nullptr); /// Destructor virtual ~CollisionWorld(); @@ -161,14 +168,14 @@ class CollisionWorld { #ifdef IS_PROFILING_ACTIVE /// Return a reference to the profiler - Profiler& getProfiler(); + Profiler* getProfiler(); #endif #ifdef IS_LOGGING_ACTIVE /// Return a reference to the logger - Logger& getLogger(); + Logger* getLogger(); #endif @@ -255,8 +262,8 @@ inline const std::string& CollisionWorld::getName() const { #ifdef IS_PROFILING_ACTIVE -// Return a reference to the profiler -inline Profiler& CollisionWorld::getProfiler() { +// Return a pointer to the profiler +inline Profiler* CollisionWorld::getProfiler() { return mProfiler; } @@ -264,8 +271,8 @@ inline Profiler& CollisionWorld::getProfiler() { #ifdef IS_LOGGING_ACTIVE -// Return a reference to the logger -inline Logger& CollisionWorld::getLogger() { +// Return a pointer to the logger +inline Logger* CollisionWorld::getLogger() { return mLogger; } diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index f8ac6033..7164458d 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -39,8 +39,9 @@ using namespace std; /** * @param gravity Gravity vector in the world (in meters per second squared) */ -DynamicsWorld::DynamicsWorld(const Vector3& gravity, const string& name, const WorldSettings& worldSettings) - : CollisionWorld(name, worldSettings), +DynamicsWorld::DynamicsWorld(const Vector3& gravity, const WorldSettings& worldSettings, + Logger* logger, Profiler* profiler) + : CollisionWorld(worldSettings, logger, profiler), mContactSolver(mMemoryManager, mConfig), mNbVelocitySolverIterations(mConfig.defaultVelocitySolverNbIterations), mNbPositionSolverIterations(mConfig.defaultPositionSolverNbIterations), @@ -58,13 +59,13 @@ DynamicsWorld::DynamicsWorld(const Vector3& gravity, const string& name, const W #ifdef IS_PROFILING_ACTIVE // Set the profiler - mConstraintSolver.setProfiler(&mProfiler); - mContactSolver.setProfiler(&mProfiler); + mConstraintSolver.setProfiler(mProfiler); + mContactSolver.setProfiler(mProfiler); #endif RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, - "Dynamics world " + mName + " has been created"); + "Dynamics World: Dynamics world " + mName + " has been created"); } @@ -87,11 +88,11 @@ DynamicsWorld::~DynamicsWorld() { #ifdef IS_PROFILING_ACTIVE // Print the profiling report into the destinations - mProfiler.printReport(); + mProfiler->printReport(); #endif RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, - "Dynamics world " + mName + " has been destroyed"); + "Dynamics World: Dynamics world " + mName + " has been destroyed"); } // Update the physics simulation @@ -102,10 +103,10 @@ void DynamicsWorld::update(decimal timeStep) { #ifdef IS_PROFILING_ACTIVE // Increment the frame counter of the profiler - mProfiler.incrementFrameCounter(); + mProfiler->incrementFrameCounter(); #endif - RP3D_PROFILE("DynamicsWorld::update()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::update()", mProfiler); mTimeStep = timeStep; @@ -153,7 +154,7 @@ void DynamicsWorld::update(decimal timeStep) { /// the sympletic Euler time stepping scheme. void DynamicsWorld::integrateRigidBodiesPositions() { - RP3D_PROFILE("DynamicsWorld::integrateRigidBodiesPositions()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::integrateRigidBodiesPositions()", mProfiler); // For each island of the world for (uint i=0; i < mNbIslands; i++) { @@ -192,7 +193,7 @@ void DynamicsWorld::integrateRigidBodiesPositions() { // Update the postion/orientation of the bodies void DynamicsWorld::updateBodiesState() { - RP3D_PROFILE("DynamicsWorld::updateBodiesState()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::updateBodiesState()", mProfiler); // For each island of the world for (uint islandIndex = 0; islandIndex < mNbIslands; islandIndex++) { @@ -229,7 +230,7 @@ void DynamicsWorld::updateBodiesState() { // Initialize the bodies velocities arrays for the next simulation step. void DynamicsWorld::initVelocityArrays() { - RP3D_PROFILE("DynamicsWorld::initVelocityArrays()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::initVelocityArrays()", mProfiler); // Allocate memory for the bodies velocity arrays uint nbBodies = mRigidBodies.size(); @@ -271,7 +272,7 @@ void DynamicsWorld::initVelocityArrays() { /// contact solver. void DynamicsWorld::integrateRigidBodiesVelocities() { - RP3D_PROFILE("DynamicsWorld::integrateRigidBodiesVelocities()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::integrateRigidBodiesVelocities()", mProfiler); // Initialize the bodies velocity arrays initVelocityArrays(); @@ -333,7 +334,7 @@ void DynamicsWorld::integrateRigidBodiesVelocities() { // Solve the contacts and constraints void DynamicsWorld::solveContactsAndConstraints() { - RP3D_PROFILE("DynamicsWorld::solveContactsAndConstraints()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::solveContactsAndConstraints()", mProfiler); // Set the velocities arrays mContactSolver.setSplitVelocitiesArrays(mSplitLinearVelocities, mSplitAngularVelocities); @@ -383,7 +384,7 @@ void DynamicsWorld::solveContactsAndConstraints() { // Solve the position error correction of the constraints void DynamicsWorld::solvePositionCorrection() { - RP3D_PROFILE("DynamicsWorld::solvePositionCorrection()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::solvePositionCorrection()", mProfiler); // Do not continue if there is no constraints if (mJoints.size() == 0) return; @@ -426,7 +427,7 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) { #ifdef IS_PROFILING_ACTIVE - rigidBody->setProfiler(&mProfiler); + rigidBody->setProfiler(mProfiler); #endif @@ -645,7 +646,7 @@ uint DynamicsWorld::computeNextAvailableJointId() { /// it). Then, we create an island with this group of connected bodies. void DynamicsWorld::computeIslands() { - RP3D_PROFILE("DynamicsWorld::computeIslands()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::computeIslands()", mProfiler); uint nbBodies = mRigidBodies.size(); @@ -792,7 +793,7 @@ void DynamicsWorld::computeIslands() { /// time, we put all the bodies of the island to sleep. void DynamicsWorld::updateSleepingBodies() { - RP3D_PROFILE("DynamicsWorld::updateSleepingBodies()", &mProfiler); + RP3D_PROFILE("DynamicsWorld::updateSleepingBodies()", mProfiler); const decimal sleepLinearVelocitySquare = mSleepLinearVelocity * mSleepLinearVelocity; const decimal sleepAngularVelocitySquare = mSleepAngularVelocity * mSleepAngularVelocity; diff --git a/src/engine/DynamicsWorld.h b/src/engine/DynamicsWorld.h index f8016fdc..f435f4b9 100644 --- a/src/engine/DynamicsWorld.h +++ b/src/engine/DynamicsWorld.h @@ -162,8 +162,8 @@ class DynamicsWorld : public CollisionWorld { // -------------------- Methods -------------------- // /// Constructor - DynamicsWorld(const Vector3& mGravity, const std::string& name = "", - const WorldSettings& worldSettings = WorldSettings()); + DynamicsWorld(const Vector3& mGravity, const WorldSettings& worldSettings = WorldSettings(), + Logger* logger = nullptr, Profiler* profiler = nullptr); /// Destructor virtual ~DynamicsWorld() override; diff --git a/src/utils/Logger.cpp b/src/utils/Logger.cpp index 89634598..9410cc29 100644 --- a/src/utils/Logger.cpp +++ b/src/utils/Logger.cpp @@ -92,10 +92,14 @@ void Logger::removeAllDestinations() { // Log something void Logger::log(Level level, Category category, const std::string& message) { + // Get current time + auto now = std::chrono::system_clock::now(); + auto time = std::chrono::system_clock::to_time_t(now); + // For each destination for (auto it = mDestinations.begin(); it != mDestinations.end(); ++it) { - (*it)->write(message, level, category); + (*it)->write(time, message, level, category); } } diff --git a/src/utils/Logger.h b/src/utils/Logger.h index 9c6421db..908da806 100644 --- a/src/utils/Logger.h +++ b/src/utils/Logger.h @@ -26,7 +26,6 @@ #ifndef REACTPHYSICS3D_LOGGER_H #define REACTPHYSICS3D_LOGGER_H -#ifdef IS_LOGGING_ACTIVE // Libraries #include "containers/List.h" @@ -35,6 +34,7 @@ #include #include #include +#include /// ReactPhysics3D namespace namespace reactphysics3d { @@ -57,6 +57,26 @@ class Logger { /// Log verbosity level enum class Format {Text, HTML}; + /// Return the name of a category + static std::string getCategoryName(Category category) { + + switch(category) { + case Category::World: return "World"; + case Category::Body: return "Body"; + case Category::Joint: return "Joint"; + } + } + + /// Return the name of a level + static std::string getLevelName(Level level) { + + switch(level) { + case Level::Info: return "Information"; + case Level::Warning: return "Warning"; + case Level::Error: return "Error"; + } + } + /// Log formatter class Formatter { @@ -83,7 +103,7 @@ class Logger { } /// Format a log message - virtual std::string format(const std::string& message, Level level, Category category) = 0; + virtual std::string format(const time_t& time, const std::string& message, Level level, Category category) = 0; }; class TextFormatter : public Formatter { @@ -101,8 +121,8 @@ class Logger { } /// Format a log message - virtual std::string format(const std::string& message, Level level, - Category category) override { + virtual std::string format(const time_t& time, const std::string& message, + Level level, Category category) override { return message; } }; @@ -120,6 +140,7 @@ class Logger { ss << "" << std::endl; ss << "" << std::endl; ss << "ReactPhysics3D Logs" << std::endl; + ss << "" << std::endl; ss << "" << std::endl; ss << "" << std::endl; @@ -137,6 +158,60 @@ class Logger { return ss.str(); } + std::string generateCSS() const { + return "body {" + " background-color: #f7f7f9;" + "} " + "body > div { clear:both; } " + "body > div > div { float: left; } " + ".line { " + "font-family: SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace; " + "font-size: 13px; " + "color: #212529; " + "margin: 0px 5px 2px 5px; " + "} " + ".time { " + "margin-right: 10px; " + "width:100px; " + "} " + ".level { " + "margin-right: 10px; " + "width: 110px; " + "}" + ".category { " + "margin-right: 10px; " + "width: 120px; " + "font-weight: bold; " + "}" + ".message { " + "color: #2e2e2e; " + "word-wrap: break-word; " + "max-width: 800px; " + "} " + ".body > .category { " + "color: #007bff; " + "} " + ".world > .category { " + "color: #4f9fcf; " + "} " + ".joint > .category { " + "color: #6c757d; " + "} " + ".warning { " + "color: #f0ad4e; " + "} " + ".error { " + "color: #d44950; " + "} "; + } + + /// Convert a string to lower case + std::string toLowerCase(const std::string& text) { + std::string textLower = text; + std::transform(textLower.begin(), textLower.end(), textLower.begin(), ::tolower); + return textLower; + } + public: /// Constructor @@ -150,14 +225,34 @@ class Logger { } /// Format a log message - virtual std::string format(const std::string& message, Level level, - Category category) override { + virtual std::string format(const time_t& time, const std::string& message, + Level level, Category category) override { std::stringstream ss; - ss << "

"; + ss << "

"; + + // Time + ss << "
"; + ss << std::put_time(std::localtime(&time), "%X"); + ss << "
"; + + // Level + ss << "
"; + ss << getLevelName(level); + ss << "
"; + + // Category + ss << "
"; + ss << getCategoryName(category); + ss << "
"; + + // Message + ss << "
"; ss << message; - ss << "

"; + ss << "
"; + + ss << "
"; return ss.str(); } @@ -187,7 +282,7 @@ class Logger { } /// Write a message into the output stream - virtual void write(const std::string& message, Level level, Category category) = 0; + virtual void write(const time_t& time, const std::string& message, Level level, Category category) = 0; }; class FileDestination : public Destination { @@ -228,8 +323,8 @@ class Logger { } /// Write a message into the output stream - virtual void write(const std::string& message, Level level, Category category) override { - mFileStream << formatter->format(message, level, category) << std::endl; + virtual void write(const time_t& time, const std::string& message, Level level, Category category) override { + mFileStream << formatter->format(time, message, level, category) << std::endl << std::flush; } }; @@ -259,8 +354,9 @@ class Logger { } /// Write a message into the output stream - virtual void write(const std::string& message, Level level, Category category) override { - mOutputStream << message << std::endl; + virtual void write(const time_t& time, const std::string& message, Level level, Category category) override { + mOutputStream << std::put_time(std::localtime(&time), "%Y-%m-%d %X") << ": "; + mOutputStream << message << std::endl << std::flush; } }; @@ -303,12 +399,12 @@ class Logger { void log(Level level, Category category, const std::string& message); }; +} + +#ifdef IS_LOGGING_ACTIVE // Use this macro to log something -#define RP3D_LOG(logger, level, category, message) logger.log(level, category, message) - - -} +#define RP3D_LOG(logger, level, category, message) logger->log(level, category, message) #else // If logger is not active diff --git a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp index 644b378f..3b4c7fc5 100755 --- a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp +++ b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp @@ -46,8 +46,11 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine // Set the center of the scene setScenePosition(center, SCENE_RADIUS); + rp3d::WorldSettings worldSettings; + worldSettings.worldName = name; + // Create the dynamics world for the physics simulation - mPhysicsWorld = new rp3d::CollisionWorld(name); + mPhysicsWorld = new rp3d::CollisionWorld(worldSettings); // ---------- Sphere 1 ---------- // diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index e5fb3110..cffe7b50 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -45,8 +45,11 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin // Gravity vector in the dynamics world rp3d::Vector3 gravity(0, -9.81f, 0); + rp3d::WorldSettings worldSettings; + worldSettings.worldName = name; + // Create the dynamics world for the physics simulation - mPhysicsWorld = new rp3d::DynamicsWorld(gravity, name); + mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings); for (int i=0; isetChecked(mApp->mEngineSettings.isSleepingEnabled); checkboxSleeping->setCallback([&](bool value) { mApp->mEngineSettings.isSleepingEnabled = value; + mApp->notifyEngineSetttingsChanged(); }); // Enabled/Disable Gravity @@ -177,6 +178,7 @@ void Gui::createSettingsPanel() { checkboxGravity->setChecked(mApp->mEngineSettings.isGravityEnabled); checkboxGravity->setCallback([&](bool value) { mApp->mEngineSettings.isGravityEnabled = value; + mApp->notifyEngineSetttingsChanged(); }); // Timestep @@ -202,6 +204,7 @@ void Gui::createSettingsPanel() { if (finalValue < 1 || finalValue > 1000) return false; mApp->mEngineSettings.timeStep = finalValue / 1000.0f; + mApp->notifyEngineSetttingsChanged(); textboxTimeStep->setValue(out.str()); } catch (...) { @@ -233,6 +236,7 @@ void Gui::createSettingsPanel() { if (value < 1 || value > 1000) return false; mApp->mEngineSettings.nbVelocitySolverIterations = value; + mApp->notifyEngineSetttingsChanged(); textboxVelocityIterations->setValue(out.str()); } catch (...) { @@ -264,6 +268,7 @@ void Gui::createSettingsPanel() { if (value < 1 || value > 1000) return false; mApp->mEngineSettings.nbPositionSolverIterations = value; + mApp->notifyEngineSetttingsChanged(); textboxPositionIterations->setValue(out.str()); } catch (...) { @@ -298,6 +303,7 @@ void Gui::createSettingsPanel() { if (finalValue < 1 || finalValue > 100000) return false; mApp->mEngineSettings.timeBeforeSleep = finalValue / 1000.0f; + mApp->notifyEngineSetttingsChanged(); textboxTimeSleep->setValue(out.str()); } catch (...) { @@ -332,6 +338,7 @@ void Gui::createSettingsPanel() { if (finalValue < 0 || finalValue > 10000) return false; mApp->mEngineSettings.sleepLinearVelocity = finalValue; + mApp->notifyEngineSetttingsChanged(); textboxSleepLinearVel->setValue(out.str()); } catch (...) { @@ -366,6 +373,7 @@ void Gui::createSettingsPanel() { if (finalValue < 0 || finalValue > 10000) return false; mApp->mEngineSettings.sleepAngularVelocity = finalValue; + mApp->notifyEngineSetttingsChanged(); textboxSleepAngularVel->setValue(out.str()); } catch (...) { diff --git a/testbed/src/Scene.h b/testbed/src/Scene.h index 5471379e..8fffff2a 100644 --- a/testbed/src/Scene.h +++ b/testbed/src/Scene.h @@ -232,6 +232,9 @@ class Scene { /// Return all the contact points of the scene std::vector virtual getContactPoints(); + + /// Update the engine settings + virtual void updateEngineSettings() = 0; }; // Called when a keyboard event occurs diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 8e2a92da..e4f13d99 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -123,18 +123,6 @@ void SceneDemo::updatePhysics() { if (getDynamicsWorld() != nullptr) { - // Update the physics engine parameters - getDynamicsWorld()->setIsGratityEnabled(mEngineSettings.isGravityEnabled); - rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y, - mEngineSettings.gravity.z); - getDynamicsWorld()->setGravity(gravity); - getDynamicsWorld()->enableSleeping(mEngineSettings.isSleepingEnabled); - getDynamicsWorld()->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity); - getDynamicsWorld()->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity); - getDynamicsWorld()->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations); - getDynamicsWorld()->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations); - getDynamicsWorld()->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep); - // Take a simulation step getDynamicsWorld()->update(mEngineSettings.timeStep); } @@ -448,3 +436,22 @@ std::vector SceneDemo::computeContactPointsOfWorld(rp3d::DynamicsW return contactPoints; } + +// Update the engine settings +void SceneDemo::updateEngineSettings() { + + if (getDynamicsWorld() != nullptr) { + + // Update the physics engine parameters + getDynamicsWorld()->setIsGratityEnabled(mEngineSettings.isGravityEnabled); + rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y, + mEngineSettings.gravity.z); + getDynamicsWorld()->setGravity(gravity); + getDynamicsWorld()->enableSleeping(mEngineSettings.isSleepingEnabled); + getDynamicsWorld()->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity); + getDynamicsWorld()->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity); + getDynamicsWorld()->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations); + getDynamicsWorld()->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations); + getDynamicsWorld()->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep); + } +} diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 1eaa30b9..95e1ece0 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -151,6 +151,9 @@ class SceneDemo : public Scene { /// Render the scene (possibly in multiple passes for shadow mapping) virtual void render() override; + /// Update the engine settings + virtual void updateEngineSettings() override; + /// Render the scene in a single pass virtual void renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index 63230e0c..7240ad7e 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -271,9 +271,16 @@ void TestbedApplication::switchScene(Scene* newScene) { // Reset the scene mCurrentScene->reset(); + mCurrentScene->updateEngineSettings(); + resizeEvent(Vector2i(0, 0)); } +// Notify that the engine settings have changed +void TestbedApplication::notifyEngineSetttingsChanged() { + mCurrentScene->updateEngineSettings(); +} + // Check the OpenGL errors void TestbedApplication::checkOpenGLErrorsInternal(const char* file, int line) { GLenum glError; diff --git a/testbed/src/TestbedApplication.h b/testbed/src/TestbedApplication.h index 3a9fe071..26a04bdd 100644 --- a/testbed/src/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -199,6 +199,9 @@ class TestbedApplication : public Screen { /// Enable/Disable Vertical synchronization void enableVSync(bool enable); + /// Notify that the engine settings have changed + void notifyEngineSetttingsChanged(); + // -------------------- Friendship -------------------- // friend class Gui; From 1bc50de2c930e1cdb8a061c5cfa6205877ed2d31 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Mon, 19 Mar 2018 23:02:13 +0100 Subject: [PATCH 3/5] Working on logger --- src/body/Body.h | 34 +++++++++ src/body/CollisionBody.cpp | 27 +++++-- src/body/CollisionBody.h | 7 ++ src/body/RigidBody.cpp | 34 ++++++++- src/body/RigidBody.h | 13 ++++ src/collision/CollisionDetection.cpp | 30 ++++---- src/collision/CollisionDetection.h | 4 +- src/collision/ProxyShape.h | 48 ++++++++++++ src/collision/TriangleVertexArray.cpp | 52 +++++++++++++ src/collision/TriangleVertexArray.h | 6 ++ .../broadphase/BroadPhaseAlgorithm.cpp | 10 +-- .../broadphase/BroadPhaseAlgorithm.h | 6 +- src/collision/shapes/BoxShape.h | 8 ++ src/collision/shapes/CapsuleShape.h | 8 ++ src/collision/shapes/CollisionShape.h | 3 + src/collision/shapes/ConcaveMeshShape.cpp | 65 ++++++++++++++++ src/collision/shapes/ConcaveMeshShape.h | 4 + src/collision/shapes/ConvexMeshShape.cpp | 44 +++++++++++ src/collision/shapes/ConvexMeshShape.h | 3 + src/collision/shapes/HeightFieldShape.cpp | 20 +++++ src/collision/shapes/HeightFieldShape.h | 3 + src/collision/shapes/SphereShape.h | 8 ++ src/collision/shapes/TriangleShape.h | 9 +++ src/configuration.h | 28 +++++++ src/engine/CollisionWorld.cpp | 22 ++++-- src/engine/DynamicsWorld.cpp | 24 +++--- src/engine/DynamicsWorld.h | 14 ++-- src/engine/Material.h | 15 ++++ src/engine/OverlappingPair.h | 8 +- src/utils/Logger.h | 75 ++++++++++++++----- 30 files changed, 551 insertions(+), 81 deletions(-) diff --git a/src/body/Body.h b/src/body/Body.h index 4a46e83f..dbacc55d 100644 --- a/src/body/Body.h +++ b/src/body/Body.h @@ -30,6 +30,7 @@ #include #include #include "configuration.h" +#include "utils/Logger.h" /// Namespace reactphysics3d namespace reactphysics3d { @@ -75,6 +76,12 @@ class Body { /// Pointer that can be used to attach user data to the body void* mUserData; +#ifdef IS_LOGGING_ACTIVE + + /// Logger + Logger* mLogger; +#endif + public : // -------------------- Methods -------------------- // @@ -118,6 +125,12 @@ class Body { /// Attach user data to this body void setUserData(void* userData); +#ifdef IS_LOGGING_ACTIVE + + /// Set the logger + void setLogger(Logger* logger); +#endif + /// Smaller than operator bool operator<(const Body& body2) const; @@ -159,6 +172,10 @@ inline void Body::setIsAllowedToSleep(bool isAllowedToSleep) { mIsAllowedToSleep = isAllowedToSleep; if (!mIsAllowedToSleep) setIsSleeping(false); + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set isAllowedToSleep=" + + (mIsAllowedToSleep ? "true" : "false")); } // Return whether or not the body is sleeping @@ -183,6 +200,10 @@ inline bool Body::isActive() const { */ inline void Body::setIsActive(bool isActive) { mIsActive = isActive; + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set isActive=" + + (mIsActive ? "true" : "false")); } // Set the variable to know whether or not the body is sleeping @@ -198,6 +219,10 @@ inline void Body::setIsSleeping(bool isSleeping) { } mIsSleeping = isSleeping; + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set isSleeping=" + + (mIsSleeping ? "true" : "false")); } // Return a pointer to the user data attached to this body @@ -216,6 +241,15 @@ inline void Body::setUserData(void* userData) { mUserData = userData; } +#ifdef IS_LOGGING_ACTIVE + +// Set the logger +inline void Body::setLogger(Logger* logger) { + mLogger = logger; +} + +#endif + // Smaller than operator inline bool Body::operator<(const Body& body2) const { return (mID < body2.mID); diff --git a/src/body/CollisionBody.cpp b/src/body/CollisionBody.cpp index bb8b0408..f7e7fe1d 100644 --- a/src/body/CollisionBody.cpp +++ b/src/body/CollisionBody.cpp @@ -79,6 +79,13 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape, // Set the profiler proxyShape->setProfiler(mProfiler); +#endif + +#ifdef IS_LOGGING_ACTIVE + + // Set the logger + proxyShape->setLogger(mLogger); + #endif // Add it to the list of proxy collision shapes of the body @@ -99,6 +106,9 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape, mNbCollisionShapes++; + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Proxy shape " + std::to_string(proxyShape->getBroadPhaseId()) + " added to body"); + // Return a pointer to the collision shape return proxyShape; } @@ -114,11 +124,14 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) { ProxyShape* current = mProxyCollisionShapes; + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Proxy shape " + std::to_string(proxyShape->getBroadPhaseId()) + " removed from body"); + // If the the first proxy shape is the one to remove if (current == proxyShape) { mProxyCollisionShapes = current->mNext; - if (mIsActive && proxyShape->mBroadPhaseID != -1) { + if (mIsActive && proxyShape->getBroadPhaseId() != -1) { mWorld.mCollisionDetection.removeProxyCollisionShape(current); } @@ -138,7 +151,7 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) { ProxyShape* elementToRemove = current->mNext; current->mNext = elementToRemove->mNext; - if (mIsActive && proxyShape->mBroadPhaseID != -1) { + if (mIsActive && proxyShape->getBroadPhaseId() != -1) { mWorld.mCollisionDetection.removeProxyCollisionShape(elementToRemove); } @@ -164,7 +177,7 @@ void CollisionBody::removeAllCollisionShapes() { // Remove the proxy collision shape ProxyShape* nextElement = current->mNext; - if (mIsActive && current->mBroadPhaseID != -1) { + if (mIsActive && current->getBroadPhaseId() != -1) { mWorld.mCollisionDetection.removeProxyCollisionShape(current); } @@ -209,7 +222,7 @@ void CollisionBody::updateBroadPhaseState() const { // Update the broad-phase state of a proxy collision shape of the body void CollisionBody::updateProxyShapeInBroadPhase(ProxyShape* proxyShape, bool forceReinsert) const { - if (proxyShape->mBroadPhaseID != -1) { + if (proxyShape->getBroadPhaseId() != -1) { // Recompute the world-space AABB of the collision shape AABB aabb; @@ -250,7 +263,7 @@ void CollisionBody::setIsActive(bool isActive) { // For each proxy shape of the body for (ProxyShape* shape = mProxyCollisionShapes; shape != nullptr; shape = shape->mNext) { - if (shape->mBroadPhaseID != -1) { + if (shape->getBroadPhaseId() != -1) { // Remove the proxy shape from the collision detection mWorld.mCollisionDetection.removeProxyCollisionShape(shape); @@ -260,6 +273,10 @@ void CollisionBody::setIsActive(bool isActive) { // Reset the contact manifold list of the body resetContactManifoldsList(); } + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set isActive=" + + (mIsActive ? "true" : "false")); } // Ask the broad-phase to test again the collision shapes of the body for collision diff --git a/src/body/CollisionBody.h b/src/body/CollisionBody.h index 2520cab4..e98b9a7d 100644 --- a/src/body/CollisionBody.h +++ b/src/body/CollisionBody.h @@ -231,6 +231,10 @@ inline void CollisionBody::setType(BodyType type) { // Update the broad-phase state of the body updateBroadPhaseState(); } + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set type=" + + (mType == BodyType::STATIC ? "Static" : (mType == BodyType::DYNAMIC ? "Dynamic" : "Kinematic"))); } // Return the current position and orientation @@ -254,6 +258,9 @@ inline void CollisionBody::setTransform(const Transform& transform) { // Update the broad-phase state of the body updateBroadPhaseState(); + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set transform=" + mTransform.to_string()); } // Return the first element of the linked list of contact manifolds involving this body diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index ab4b0c8e..3791c9d9 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -139,6 +139,9 @@ void RigidBody::setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal) { // Update the world inverse inertia tensor updateInertiaTensorInverseWorld(); + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string()); } // Set the inverse local inertia tensor of the body (in local-space coordinates) @@ -160,6 +163,9 @@ void RigidBody::setInverseInertiaTensorLocal(const Matrix3x3& inverseInertiaTens // Update the world inverse inertia tensor updateInertiaTensorInverseWorld(); + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set inverseInertiaTensorLocal=" + inverseInertiaTensorLocal.to_string()); } // Set the local center of mass of the body (in local-space coordinates) @@ -183,6 +189,9 @@ void RigidBody::setCenterOfMassLocal(const Vector3& centerOfMassLocal) { // Update the linear velocity of the center of mass mLinearVelocity += mAngularVelocity.cross(mCenterOfMassWorld - oldCenterOfMass); + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set centerOfMassLocal=" + centerOfMassLocal.to_string()); } // Set the mass of the rigid body @@ -202,6 +211,9 @@ void RigidBody::setMass(decimal mass) { mInitMass = decimal(1.0); mMassInverse = decimal(1.0); } + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set mass=" + std::to_string(mass)); } // Remove a joint from the joints list @@ -264,6 +276,13 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* collisionShape, // Set the profiler proxyShape->setProfiler(mProfiler); +#endif + +#ifdef IS_LOGGING_ACTIVE + + // Set the logger + proxyShape->setLogger(mLogger); + #endif // Add it to the list of proxy collision shapes of the body @@ -288,6 +307,9 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* collisionShape, // collision shape recomputeMassInformation(); + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Proxy shape " + std::to_string(proxyShape->getBroadPhaseId()) + " added to body"); + // Return a pointer to the proxy collision shape return proxyShape; } @@ -324,6 +346,9 @@ void RigidBody::setLinearVelocity(const Vector3& linearVelocity) { if (mLinearVelocity.lengthSquare() > decimal(0.0)) { setIsSleeping(false); } + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set linearVelocity=" + mLinearVelocity.to_string()); } // Set the angular velocity. @@ -342,6 +367,9 @@ void RigidBody::setAngularVelocity(const Vector3& angularVelocity) { if (mAngularVelocity.lengthSquare() > decimal(0.0)) { setIsSleeping(false); } + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set angularVelocity=" + mAngularVelocity.to_string()); } // Set the current position and orientation @@ -367,6 +395,9 @@ void RigidBody::setTransform(const Transform& transform) { // Update the broad-phase state of the body updateBroadPhaseState(); + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set transform=" + mTransform.to_string()); } // Recompute the center of mass, total mass and inertia tensor of the body using all @@ -469,7 +500,7 @@ void RigidBody::updateBroadPhaseState() const { // Recompute the world-space AABB of the collision shape AABB aabb; - shape->getCollisionShape()->computeAABB(aabb, mTransform *shape->getLocalToBodyTransform()); + shape->getCollisionShape()->computeAABB(aabb, mTransform * shape->getLocalToBodyTransform()); // Update the broad-phase state for the proxy collision shape mWorld.mCollisionDetection.updateProxyCollisionShape(shape, aabb, displacement); @@ -494,4 +525,3 @@ void RigidBody::setProfiler(Profiler* profiler) { } #endif - diff --git a/src/body/RigidBody.h b/src/body/RigidBody.h index 22c784ef..ad794513 100644 --- a/src/body/RigidBody.h +++ b/src/body/RigidBody.h @@ -325,6 +325,10 @@ inline bool RigidBody::isGravityEnabled() const { */ inline void RigidBody::enableGravity(bool isEnabled) { mIsGravityEnabled = isEnabled; + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set isGravityEnabled=" + + (mIsGravityEnabled ? "true" : "false")); } // Return a reference to the material properties of the rigid body @@ -341,6 +345,9 @@ inline Material& RigidBody::getMaterial() { */ inline void RigidBody::setMaterial(const Material& material) { mMaterial = material; + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set Material" + mMaterial.to_string()); } // Return the linear velocity damping factor @@ -359,6 +366,9 @@ inline decimal RigidBody::getLinearDamping() const { inline void RigidBody::setLinearDamping(decimal linearDamping) { assert(linearDamping >= decimal(0.0)); mLinearDamping = linearDamping; + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set linearDamping=" + std::to_string(mLinearDamping)); } // Return the angular velocity damping factor @@ -377,6 +387,9 @@ inline decimal RigidBody::getAngularDamping() const { inline void RigidBody::setAngularDamping(decimal angularDamping) { assert(angularDamping >= decimal(0.0)); mAngularDamping = angularDamping; + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(mID) + ": Set angularDamping=" + std::to_string(mAngularDamping)); } // Return the first element of the linked list of joints involving this body diff --git a/src/collision/CollisionDetection.cpp b/src/collision/CollisionDetection.cpp index dc2272f9..f56672ca 100644 --- a/src/collision/CollisionDetection.cpp +++ b/src/collision/CollisionDetection.cpp @@ -118,9 +118,9 @@ void CollisionDetection::computeMiddlePhase() { ProxyShape* shape1 = pair->getShape1(); ProxyShape* shape2 = pair->getShape2(); - assert(shape1->mBroadPhaseID != -1); - assert(shape2->mBroadPhaseID != -1); - assert(shape1->mBroadPhaseID != shape2->mBroadPhaseID); + assert(shape1->getBroadPhaseId() != -1); + assert(shape2->getBroadPhaseId() != -1); + assert(shape1->getBroadPhaseId() != shape2->getBroadPhaseId()); // Check if the two shapes are still overlapping. Otherwise, we destroy the // overlapping pair @@ -308,9 +308,9 @@ void CollisionDetection::computeNarrowPhase() { /// This method is called by the broad-phase collision detection algorithm void CollisionDetection::broadPhaseNotifyOverlappingPair(ProxyShape* shape1, ProxyShape* shape2) { - assert(shape1->mBroadPhaseID != -1); - assert(shape2->mBroadPhaseID != -1); - assert(shape1->mBroadPhaseID != shape2->mBroadPhaseID); + assert(shape1->getBroadPhaseId() != -1); + assert(shape2->getBroadPhaseId() != -1); + assert(shape1->getBroadPhaseId() != shape2->getBroadPhaseId()); // Check if the collision filtering allows collision between the two shapes if ((shape1->getCollideWithMaskBits() & shape2->getCollisionCategoryBits()) == 0 || @@ -338,13 +338,13 @@ void CollisionDetection::broadPhaseNotifyOverlappingPair(ProxyShape* shape1, Pro // Remove a body from the collision detection void CollisionDetection::removeProxyCollisionShape(ProxyShape* proxyShape) { - assert(proxyShape->mBroadPhaseID != -1); + assert(proxyShape->getBroadPhaseId() != -1); // Remove all the overlapping pairs involving this proxy shape Map, OverlappingPair*>::Iterator it; for (it = mOverlappingPairs.begin(); it != mOverlappingPairs.end(); ) { - if (it->second->getShape1()->mBroadPhaseID == proxyShape->mBroadPhaseID|| - it->second->getShape2()->mBroadPhaseID == proxyShape->mBroadPhaseID) { + if (it->second->getShape1()->getBroadPhaseId() == proxyShape->getBroadPhaseId()|| + it->second->getShape2()->getBroadPhaseId() == proxyShape->getBroadPhaseId()) { // TODO : Remove all the contact manifold of the overlapping pair from the contact manifolds list of the two bodies involved @@ -637,10 +637,10 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl ProxyShape* bodyProxyShape = body->getProxyShapesList(); while (bodyProxyShape != nullptr) { - if (bodyProxyShape->mBroadPhaseID != -1) { + if (bodyProxyShape->getBroadPhaseId() != -1) { // Get the AABB of the shape - const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->mBroadPhaseID); + const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->getBroadPhaseId()); // Ask the broad-phase to get all the overlapping shapes LinkedList overlappingNodes(mMemoryManager.getPoolAllocator()); @@ -817,10 +817,10 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c ProxyShape* bodyProxyShape = body->getProxyShapesList(); while (bodyProxyShape != nullptr) { - if (bodyProxyShape->mBroadPhaseID != -1) { + if (bodyProxyShape->getBroadPhaseId() != -1) { // Get the AABB of the shape - const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->mBroadPhaseID); + const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->getBroadPhaseId()); // Ask the broad-phase to get all the overlapping shapes LinkedList overlappingNodes(mMemoryManager.getPoolAllocator()); @@ -996,6 +996,6 @@ EventListener* CollisionDetection::getWorldEventListener() { // Return the world-space AABB of a given proxy shape const AABB CollisionDetection::getWorldAABB(const ProxyShape* proxyShape) const { - assert(proxyShape->mBroadPhaseID > -1); - return mBroadPhaseAlgorithm.getFatAABB(proxyShape->mBroadPhaseID); + assert(proxyShape->getBroadPhaseId() > -1); + return mBroadPhaseAlgorithm.getFatAABB(proxyShape->getBroadPhaseId()); } diff --git a/src/collision/CollisionDetection.h b/src/collision/CollisionDetection.h index d8f5240a..ecfa766d 100644 --- a/src/collision/CollisionDetection.h +++ b/src/collision/CollisionDetection.h @@ -279,8 +279,8 @@ inline void CollisionDetection::removeNoCollisionPair(CollisionBody* body1, /// previous frame so that it is tested for collision again in the broad-phase. inline void CollisionDetection::askForBroadPhaseCollisionCheck(ProxyShape* shape) { - if (shape->mBroadPhaseID != -1) { - mBroadPhaseAlgorithm.addMovedCollisionShape(shape->mBroadPhaseID); + if (shape->getBroadPhaseId() != -1) { + mBroadPhaseAlgorithm.addMovedCollisionShape(shape->getBroadPhaseId()); } } diff --git a/src/collision/ProxyShape.h b/src/collision/ProxyShape.h index 0da79e28..61118d45 100644 --- a/src/collision/ProxyShape.h +++ b/src/collision/ProxyShape.h @@ -93,6 +93,12 @@ class ProxyShape { #endif +#ifdef IS_LOGGING_ACTIVE + + /// Logger + Logger* mLogger; +#endif + // -------------------- Methods -------------------- // /// Return the collision shape @@ -175,6 +181,9 @@ class ProxyShape { /// Set the local scaling vector of the collision shape virtual void setLocalScaling(const Vector3& scaling); + /// Return the broad-phase id + int getBroadPhaseId() const; + #ifdef IS_PROFILING_ACTIVE /// Set the profiler @@ -182,6 +191,12 @@ class ProxyShape { #endif +#ifdef IS_LOGGING_ACTIVE + + /// Set the logger + void setLogger(Logger* logger); +#endif + // -------------------- Friendship -------------------- // friend class OverlappingPair; @@ -265,6 +280,10 @@ inline void ProxyShape::setLocalToBodyTransform(const Transform& transform) { // Notify the body that the proxy shape has to be updated in the broad-phase mBody->updateProxyShapeInBroadPhase(this, true); + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape, + "ProxyShape " + std::to_string(mBroadPhaseID) + ": Set localToBodyTransform=" + + mLocalToBodyTransform.to_string()); } // Return the local to world transform @@ -316,6 +335,10 @@ inline unsigned short ProxyShape::getCollisionCategoryBits() const { */ inline void ProxyShape::setCollisionCategoryBits(unsigned short collisionCategoryBits) { mCollisionCategoryBits = collisionCategoryBits; + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape, + "ProxyShape " + std::to_string(mBroadPhaseID) + ": Set collisionCategoryBits=" + + std::to_string(mCollisionCategoryBits)); } // Return the collision bits mask @@ -332,6 +355,10 @@ inline unsigned short ProxyShape::getCollideWithMaskBits() const { */ inline void ProxyShape::setCollideWithMaskBits(unsigned short collideWithMaskBits) { mCollideWithMaskBits = collideWithMaskBits; + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape, + "ProxyShape " + std::to_string(mBroadPhaseID) + ": Set collideWithMaskBits=" + + std::to_string(mCollideWithMaskBits)); } // Return the local scaling vector of the collision shape @@ -348,6 +375,8 @@ inline Vector3 ProxyShape::getLocalScaling() const { */ inline void ProxyShape::setLocalScaling(const Vector3& scaling) { + // TODO : Do not use a local of the collision shape in case of shared collision shapes + // Set the local scaling of the collision shape mCollisionShape->setLocalScaling(scaling); @@ -355,6 +384,15 @@ inline void ProxyShape::setLocalScaling(const Vector3& scaling) { // Notify the body that the proxy shape has to be updated in the broad-phase mBody->updateProxyShapeInBroadPhase(this, true); + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape, + "ProxyShape " + std::to_string(mBroadPhaseID) + ": Set localScaling=" + + mCollisionShape->getLocalScaling().to_string()); +} + +// Return the broad-phase id +inline int ProxyShape::getBroadPhaseId() const { + return mBroadPhaseID; } /// Test if the proxy shape overlaps with a given AABB @@ -378,6 +416,16 @@ inline void ProxyShape::setProfiler(Profiler* profiler) { #endif +#ifdef IS_LOGGING_ACTIVE + +// Set the logger +inline void ProxyShape::setLogger(Logger* logger) { + + mLogger = logger; +} + +#endif + } #endif diff --git a/src/collision/TriangleVertexArray.cpp b/src/collision/TriangleVertexArray.cpp index 7cfb2076..a54ad425 100644 --- a/src/collision/TriangleVertexArray.cpp +++ b/src/collision/TriangleVertexArray.cpp @@ -280,3 +280,55 @@ void TriangleVertexArray::getTriangleVerticesNormals(uint triangleIndex, Vector3 } } } + +// Return a vertex of the array +void TriangleVertexArray::getVertex(uint vertexIndex, Vector3* outVertex) { + + assert(vertexIndex < mNbVertices); + + const uchar* vertexPointerChar = mVerticesStart + vertexIndex * mVerticesStride; + const void* vertexPointer = static_cast(vertexPointerChar); + + // Get the vertices components of the triangle + if (mVertexDataType == TriangleVertexArray::VertexDataType::VERTEX_FLOAT_TYPE) { + const float* vertices = static_cast(vertexPointer); + (*outVertex)[0] = decimal(vertices[0]); + (*outVertex)[1] = decimal(vertices[1]); + (*outVertex)[2] = decimal(vertices[2]); + } + else if (mVertexDataType == TriangleVertexArray::VertexDataType::VERTEX_DOUBLE_TYPE) { + const double* vertices = static_cast(vertexPointer); + (*outVertex)[0] = decimal(vertices[0]); + (*outVertex)[1] = decimal(vertices[1]); + (*outVertex)[2] = decimal(vertices[2]); + } + else { + assert(false); + } +} + +// Return a vertex normal of the array +void TriangleVertexArray::getNormal(uint vertexIndex, Vector3* outNormal) { + + assert(vertexIndex < mNbVertices); + + const uchar* vertexNormalPointerChar = mVerticesNormalsStart + vertexIndex * mVerticesNormalsStride; + const void* vertexNormalPointer = static_cast(vertexNormalPointerChar); + + // Get the normals from the array + if (mVertexNormaldDataType == TriangleVertexArray::NormalDataType::NORMAL_FLOAT_TYPE) { + const float* normal = static_cast(vertexNormalPointer); + (*outNormal)[0] = decimal(normal[0]); + (*outNormal)[1] = decimal(normal[1]); + (*outNormal)[2] = decimal(normal[2]); + } + else if (mVertexNormaldDataType == TriangleVertexArray::NormalDataType::NORMAL_DOUBLE_TYPE) { + const double* normal = static_cast(vertexNormalPointer); + (*outNormal)[0] = decimal(normal[0]); + (*outNormal)[1] = decimal(normal[1]); + (*outNormal)[2] = decimal(normal[2]); + } + else { + assert(false); + } +} diff --git a/src/collision/TriangleVertexArray.h b/src/collision/TriangleVertexArray.h index 3a48c2e3..4fe2fe07 100644 --- a/src/collision/TriangleVertexArray.h +++ b/src/collision/TriangleVertexArray.h @@ -169,6 +169,12 @@ class TriangleVertexArray { /// Return the indices of the three vertices of a given triangle in the array void getTriangleVerticesIndices(uint triangleIndex, uint* outVerticesIndices) const; + + /// Return a vertex of the array + void getVertex(uint vertexIndex, Vector3* outVertex); + + /// Return a vertex normal of the array + void getNormal(uint vertexIndex, Vector3* outNormal); }; // Return the vertex data type diff --git a/src/collision/broadphase/BroadPhaseAlgorithm.cpp b/src/collision/broadphase/BroadPhaseAlgorithm.cpp index fbad0cfd..0d722a0a 100644 --- a/src/collision/broadphase/BroadPhaseAlgorithm.cpp +++ b/src/collision/broadphase/BroadPhaseAlgorithm.cpp @@ -140,7 +140,7 @@ void BroadPhaseAlgorithm::removeMovedCollisionShape(int broadPhaseID) { // Add a proxy collision shape into the broad-phase collision detection void BroadPhaseAlgorithm::addProxyCollisionShape(ProxyShape* proxyShape, const AABB& aabb) { - assert(proxyShape->mBroadPhaseID == -1); + assert(proxyShape->getBroadPhaseId() == -1); // Add the collision shape into the dynamic AABB tree and get its broad-phase ID int nodeId = mDynamicAABBTree.addObject(aabb, proxyShape); @@ -150,15 +150,15 @@ void BroadPhaseAlgorithm::addProxyCollisionShape(ProxyShape* proxyShape, const A // Add the collision shape into the array of bodies that have moved (or have been created) // during the last simulation step - addMovedCollisionShape(proxyShape->mBroadPhaseID); + addMovedCollisionShape(proxyShape->getBroadPhaseId()); } // Remove a proxy collision shape from the broad-phase collision detection void BroadPhaseAlgorithm::removeProxyCollisionShape(ProxyShape* proxyShape) { - assert(proxyShape->mBroadPhaseID != -1); + assert(proxyShape->getBroadPhaseId() != -1); - int broadPhaseID = proxyShape->mBroadPhaseID; + int broadPhaseID = proxyShape->getBroadPhaseId(); proxyShape->mBroadPhaseID = -1; @@ -174,7 +174,7 @@ void BroadPhaseAlgorithm::removeProxyCollisionShape(ProxyShape* proxyShape) { void BroadPhaseAlgorithm::updateProxyCollisionShape(ProxyShape* proxyShape, const AABB& aabb, const Vector3& displacement, bool forceReinsert) { - int broadPhaseID = proxyShape->mBroadPhaseID; + int broadPhaseID = proxyShape->getBroadPhaseId(); assert(broadPhaseID >= 0); diff --git a/src/collision/broadphase/BroadPhaseAlgorithm.h b/src/collision/broadphase/BroadPhaseAlgorithm.h index df642677..4e8360b9 100644 --- a/src/collision/broadphase/BroadPhaseAlgorithm.h +++ b/src/collision/broadphase/BroadPhaseAlgorithm.h @@ -246,11 +246,11 @@ inline bool BroadPhasePair::smallerThan(const BroadPhasePair& pair1, const Broad inline bool BroadPhaseAlgorithm::testOverlappingShapes(const ProxyShape* shape1, const ProxyShape* shape2) const { - if (shape1->mBroadPhaseID == -1 || shape2->mBroadPhaseID == -1) return false; + if (shape1->getBroadPhaseId() == -1 || shape2->getBroadPhaseId() == -1) return false; // Get the two AABBs of the collision shapes - const AABB& aabb1 = mDynamicAABBTree.getFatAABB(shape1->mBroadPhaseID); - const AABB& aabb2 = mDynamicAABBTree.getFatAABB(shape2->mBroadPhaseID); + const AABB& aabb1 = mDynamicAABBTree.getFatAABB(shape1->getBroadPhaseId()); + const AABB& aabb2 = mDynamicAABBTree.getFatAABB(shape2->getBroadPhaseId()); // Check if the two AABBs are overlapping return aabb1.testCollision(aabb2); diff --git a/src/collision/shapes/BoxShape.h b/src/collision/shapes/BoxShape.h index 2ebcdce1..0c261a6f 100644 --- a/src/collision/shapes/BoxShape.h +++ b/src/collision/shapes/BoxShape.h @@ -123,6 +123,9 @@ class BoxShape : public ConvexPolyhedronShape { /// Return the centroid of the polyhedron virtual Vector3 getCentroid() const override; + + /// Return the string representation of the shape + virtual std::string to_string() const override; }; // Return the extents of the box @@ -237,6 +240,11 @@ inline Vector3 BoxShape::getCentroid() const { return Vector3::zero(); } +// Return the string representation of the shape +inline std::string BoxShape::to_string() const { + return "BoxShape {extents=" + mExtent.to_string() + "}"; +} + // Return the number of half-edges of the polyhedron inline uint BoxShape::getNbHalfEdges() const { return 24; diff --git a/src/collision/shapes/CapsuleShape.h b/src/collision/shapes/CapsuleShape.h index 7843f139..6a58f115 100644 --- a/src/collision/shapes/CapsuleShape.h +++ b/src/collision/shapes/CapsuleShape.h @@ -105,6 +105,9 @@ class CapsuleShape : public ConvexShape { /// Return the local inertia tensor of the collision shape virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override; + + /// Return the string representation of the shape + virtual std::string to_string() const override; }; // Get the radius of the capsule @@ -185,6 +188,11 @@ inline Vector3 CapsuleShape::getLocalSupportPointWithoutMargin(const Vector3& di } } +// Return the string representation of the shape +inline std::string CapsuleShape::to_string() const { + return "CapsuleShape {halfHeight=" + std::to_string(mHalfHeight) + ", radius=" + std::to_string(getRadius()) + "}"; +} + } #endif diff --git a/src/collision/shapes/CollisionShape.h b/src/collision/shapes/CollisionShape.h index 3fdf4470..a7b07fc3 100644 --- a/src/collision/shapes/CollisionShape.h +++ b/src/collision/shapes/CollisionShape.h @@ -138,6 +138,9 @@ class CollisionShape { /// Compute the world-space AABB of the collision shape given a transform virtual void computeAABB(AABB& aabb, const Transform& transform) const; + /// Return the string representation of the shape + virtual std::string to_string() const=0; + #ifdef IS_PROFILING_ACTIVE /// Set the profiler diff --git a/src/collision/shapes/ConcaveMeshShape.cpp b/src/collision/shapes/ConcaveMeshShape.cpp index 768f7c2e..bde756e4 100644 --- a/src/collision/shapes/ConcaveMeshShape.cpp +++ b/src/collision/shapes/ConcaveMeshShape.cpp @@ -214,3 +214,68 @@ void ConcaveMeshRaycastCallback::raycastTriangles() { } } + +// Return the string representation of the shape +std::string ConcaveMeshShape::to_string() const { + + std::stringstream ss; + + ss << "ConcaveMeshShape {" << std::endl; + ss << "nbSubparts=" << mTriangleMesh->getNbSubparts() << std::endl; + + // Vertices array + for (uint subPart=0; subPartgetNbSubparts(); subPart++) { + + // Get the triangle vertex array of the current sub-part + TriangleVertexArray* triangleVertexArray = mTriangleMesh->getSubpart(subPart); + + ss << "subpart" << subPart << "={" << std::endl; + ss << "nbVertices=" << triangleVertexArray->getNbVertices() << std::endl; + ss << "nbTriangles=" << triangleVertexArray->getNbTriangles() << std::endl; + + ss << "vertices=["; + + // For each triangle of the concave mesh + for (uint v=0; vgetNbVertices(); v++) { + + Vector3 vertex; + triangleVertexArray->getVertex(v, &vertex); + + ss << vertex.to_string() << ", "; + } + + ss << "], " << std::endl; + + ss << "normals=["; + + // For each triangle of the concave mesh + for (uint v=0; vgetNbVertices(); v++) { + + Vector3 normal; + triangleVertexArray->getNormal(v, &normal); + + ss << normal.to_string() << ", "; + } + + ss << "], " << std::endl; + + ss << "triangles=["; + + // For each triangle of the concave mesh + // For each triangle of the concave mesh + for (uint triangleIndex=0; triangleIndexgetNbTriangles(); triangleIndex++) { + + uint indices[3]; + + triangleVertexArray->getTriangleVerticesIndices(triangleIndex, indices); + + ss << "(" << indices[0] << "," << indices[1] << "," << indices[2] << "), "; + } + + ss << "], " << std::endl; + + ss << "}" << std::endl; + } + + return ss.str(); +} diff --git a/src/collision/shapes/ConcaveMeshShape.h b/src/collision/shapes/ConcaveMeshShape.h index d35c9d23..ccafbba9 100644 --- a/src/collision/shapes/ConcaveMeshShape.h +++ b/src/collision/shapes/ConcaveMeshShape.h @@ -186,6 +186,9 @@ class ConcaveMeshShape : public ConcaveShape { /// Use a callback method on all triangles of the concave shape inside a given AABB virtual void testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const override; + /// Return the string representation of the shape + virtual std::string to_string() const override; + #ifdef IS_PROFILING_ACTIVE /// Set the profiler @@ -277,6 +280,7 @@ inline void ConcaveMeshShape::setProfiler(Profiler* profiler) { mDynamicAABBTree.setProfiler(profiler); } + #endif } diff --git a/src/collision/shapes/ConvexMeshShape.cpp b/src/collision/shapes/ConvexMeshShape.cpp index d4037a8c..1c47b4d9 100644 --- a/src/collision/shapes/ConvexMeshShape.cpp +++ b/src/collision/shapes/ConvexMeshShape.cpp @@ -201,3 +201,47 @@ bool ConvexMeshShape::testPointInside(const Vector3& localPoint, ProxyShape* pro return true; } +// Return the string representation of the shape +std::string ConvexMeshShape::to_string() const { + + std::stringstream ss; + ss << "ConvexMeshShape {" << std::endl; + ss << "nbVertices=" << mPolyhedronMesh->getNbVertices() << std::endl; + ss << "nbFaces=" << mPolyhedronMesh->getNbFaces() << std::endl; + + ss << "vertices=["; + + for (uint v=0; v < mPolyhedronMesh->getNbVertices(); v++) { + + Vector3 vertex = mPolyhedronMesh->getVertex(v); + ss << vertex.to_string(); + if (v != mPolyhedronMesh->getNbVertices() - 1) { + ss << ", "; + } + } + + ss << "], faces=["; + + HalfEdgeStructure halfEdgeStruct = mPolyhedronMesh->getHalfEdgeStructure(); + for (uint f=0; f < mPolyhedronMesh->getNbFaces(); f++) { + + const HalfEdgeStructure::Face& face = halfEdgeStruct.getFace(f); + + ss << "["; + + for (uint v=0; v < face.faceVertices.size(); v++) { + + ss << face.faceVertices[v]; + if (v != face.faceVertices.size() - 1) { + ss << ","; + } + } + + ss << "]"; + } + + ss << "]}"; + + return ss.str(); +} + diff --git a/src/collision/shapes/ConvexMeshShape.h b/src/collision/shapes/ConvexMeshShape.h index 49d3f773..ebec6a09 100644 --- a/src/collision/shapes/ConvexMeshShape.h +++ b/src/collision/shapes/ConvexMeshShape.h @@ -130,6 +130,9 @@ class ConvexMeshShape : public ConvexPolyhedronShape { /// Return the centroid of the polyhedron virtual Vector3 getCentroid() const override; + + /// Return the string representation of the shape + virtual std::string to_string() const override; }; /// Set the scaling vector of the collision shape diff --git a/src/collision/shapes/HeightFieldShape.cpp b/src/collision/shapes/HeightFieldShape.cpp index df2019c0..0b3a4044 100644 --- a/src/collision/shapes/HeightFieldShape.cpp +++ b/src/collision/shapes/HeightFieldShape.cpp @@ -297,3 +297,23 @@ void TriangleOverlapCallback::testTriangle(const Vector3* trianglePoints, const mIsHit = true; } } + +// Return the string representation of the shape +std::string HeightFieldShape::to_string() const { + + std::stringstream ss; + + ss << "HeightFieldShape {" << std::endl; + + ss << "nbColumns=" << mNbColumns << std::endl; + ss << "nbRows=" << mNbRows << std::endl; + ss << "width=" << mWidth << std::endl; + ss << "length=" << mLength << std::endl; + ss << "minHeight=" << mMinHeight << std::endl; + ss << "maxHeight=" << mMaxHeight << std::endl; + ss << "upAxis=" << mUpAxis << std::endl; + ss << "integerHeightScale=" << mIntegerHeightScale << std::endl; + ss << "}"; + + return ss.str(); +} diff --git a/src/collision/shapes/HeightFieldShape.h b/src/collision/shapes/HeightFieldShape.h index 7b834e2b..e796e208 100644 --- a/src/collision/shapes/HeightFieldShape.h +++ b/src/collision/shapes/HeightFieldShape.h @@ -209,6 +209,9 @@ class HeightFieldShape : public ConcaveShape { /// Use a callback method on all triangles of the concave shape inside a given AABB virtual void testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const override; + /// Return the string representation of the shape + virtual std::string to_string() const override; + // ---------- Friendship ----------- // friend class ConvexTriangleAABBOverlapCallback; diff --git a/src/collision/shapes/SphereShape.h b/src/collision/shapes/SphereShape.h index 90b20d2d..a0010b06 100644 --- a/src/collision/shapes/SphereShape.h +++ b/src/collision/shapes/SphereShape.h @@ -93,6 +93,9 @@ class SphereShape : public ConvexShape { /// Update the AABB of a body using its collision shape virtual void computeAABB(AABB& aabb, const Transform& transform) const override; + + /// Return the string representation of the shape + virtual std::string to_string() const override; }; // Get the radius of the sphere @@ -181,6 +184,11 @@ inline bool SphereShape::testPointInside(const Vector3& localPoint, ProxyShape* return (localPoint.lengthSquare() < mMargin * mMargin); } +// Return the string representation of the shape +inline std::string SphereShape::to_string() const { + return "SphereShape { radius=" + std::to_string(getRadius()) + "}"; +} + } #endif diff --git a/src/collision/shapes/TriangleShape.h b/src/collision/shapes/TriangleShape.h index 23f26adc..5a5a49b2 100644 --- a/src/collision/shapes/TriangleShape.h +++ b/src/collision/shapes/TriangleShape.h @@ -175,6 +175,9 @@ class TriangleShape : public ConvexPolyhedronShape { const Transform& shape1ToWorld, const Transform& shape2ToWorld, decimal penetrationDepth, Vector3& outSmoothVertexNormal); + /// Return the string representation of the shape + virtual std::string to_string() const override; + // ---------- Friendship ---------- // friend class ConcaveMeshRaycastCallback; @@ -325,6 +328,12 @@ inline void TriangleShape::setRaycastTestType(TriangleRaycastSide testType) { mRaycastTestType = testType; } +// Return the string representation of the shape +inline std::string TriangleShape::to_string() const { + return "TriangleShape {v1=" + mPoints[0].to_string() + ", v2=" + mPoints[1].to_string() + "," + + "v3=" + mPoints[2].to_string() + "}"; +} + } #endif diff --git a/src/configuration.h b/src/configuration.h index aa71e88a..aa8a0535 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "decimal.h" #include "containers/Pair.h" @@ -105,6 +106,9 @@ constexpr decimal DYNAMIC_TREE_AABB_GAP = decimal(0.1); /// followin constant with the linear velocity and the elapsed time between two frames. constexpr decimal DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER = decimal(1.7); +/// Current version of ReactPhysics3D +const std::string RP3D_VERSION = std::string("0.7.0"); + /// Structure WorldSettings /** * This class is used to describe some settings of a physics world. @@ -161,6 +165,30 @@ struct WorldSettings { /// merge them. If the cosine of the angle between the normals of the two manifold are larger /// than the value bellow, the manifold are considered to be similar. decimal cosAngleSimilarContactManifold = decimal(0.95); + + /// Return a string with the world settings + std::string to_string() const { + + std::stringstream ss; + + ss << "worldName=" << worldName << std::endl; + ss << "persistentContactDistanceThreshold=" << persistentContactDistanceThreshold << std::endl; + ss << "defaultFrictionCoefficient=" << defaultFrictionCoefficient << std::endl; + ss << "defaultBounciness=" << defaultBounciness << std::endl; + ss << "restitutionVelocityThreshold=" << restitutionVelocityThreshold << std::endl; + ss << "defaultRollingRestistance=" << defaultRollingRestistance << std::endl; + ss << "isSleepingEnabled=" << isSleepingEnabled << std::endl; + ss << "defaultVelocitySolverNbIterations=" << defaultVelocitySolverNbIterations << std::endl; + ss << "defaultPositionSolverNbIterations=" << defaultPositionSolverNbIterations << std::endl; + ss << "defaultTimeBeforeSleep=" << defaultTimeBeforeSleep << std::endl; + ss << "defaultSleepLinearVelocity=" << defaultSleepLinearVelocity << std::endl; + ss << "defaultSleepAngularVelocity=" << defaultSleepAngularVelocity << std::endl; + ss << "nbMaxContactManifoldsConvexShape=" << nbMaxContactManifoldsConvexShape << std::endl; + ss << "nbMaxContactManifoldsConcaveShape=" << nbMaxContactManifoldsConcaveShape << std::endl; + ss << "cosAngleSimilarContactManifold=" << cosAngleSimilarContactManifold << std::endl; + + return ss.str(); + } }; } diff --git a/src/engine/CollisionWorld.cpp b/src/engine/CollisionWorld.cpp index 1dbf1b6f..d9b5f258 100644 --- a/src/engine/CollisionWorld.cpp +++ b/src/engine/CollisionWorld.cpp @@ -80,7 +80,7 @@ CollisionWorld::CollisionWorld(const WorldSettings& worldSettings, Logger* logge mLogger = new Logger(); // Add a log destination file - uint logLevel = static_cast(Logger::Level::Info) | static_cast(Logger::Level::Warning) | + uint logLevel = static_cast(Logger::Level::Information) | static_cast(Logger::Level::Warning) | static_cast(Logger::Level::Error); mLogger->addFileDestination("rp3d_log_" + mName + ".html", logLevel, Logger::Format::HTML); } @@ -89,14 +89,16 @@ CollisionWorld::CollisionWorld(const WorldSettings& worldSettings, Logger* logge mNbWorlds++; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Collision World: Collision world " + mName + " has been created"); + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, + "Collision World: Initial world settings: " + worldSettings.to_string()); } // Destructor CollisionWorld::~CollisionWorld() { - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Collision World: Collision world " + mName + " has been destroyed"); // Destroy all the collision bodies that have not been removed @@ -154,8 +156,12 @@ CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) { #endif - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Body, - "Collision Body " + std::to_string(bodyID) + ": New collision body created"); +#ifdef IS_LOGGING_ACTIVE + collisionBody->setLogger(mLogger); +#endif + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(bodyID) + ": New collision body created"); // Return the pointer to the rigid body return collisionBody; @@ -167,8 +173,8 @@ CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) { */ void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) { - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Body, - "Collision Body " + std::to_string(collisionBody->getId()) + ": collision body destroyed"); + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(collisionBody->getId()) + ": collision body destroyed"); // Remove all the collision shapes of the body collisionBody->removeAllCollisionShapes(); @@ -253,7 +259,7 @@ bool CollisionWorld::testOverlap(CollisionBody* body1, CollisionBody* body2) { // Return the current world-space AABB of given proxy shape AABB CollisionWorld::getWorldAABB(const ProxyShape* proxyShape) const { - if (proxyShape->mBroadPhaseID == -1) { + if (proxyShape->getBroadPhaseId() == -1) { return AABB(); } diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index 7164458d..8fb71e08 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -64,7 +64,7 @@ DynamicsWorld::DynamicsWorld(const Vector3& gravity, const WorldSettings& worldS #endif - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: Dynamics world " + mName + " has been created"); } @@ -91,7 +91,7 @@ DynamicsWorld::~DynamicsWorld() { mProfiler->printReport(); #endif - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: Dynamics world " + mName + " has been destroyed"); } @@ -426,13 +426,15 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) { mRigidBodies.add(rigidBody); #ifdef IS_PROFILING_ACTIVE - rigidBody->setProfiler(mProfiler); - #endif - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Body, - "Rigid Body " + std::to_string(bodyID) + ": New collision body created"); +#ifdef IS_LOGGING_ACTIVE + rigidBody->setLogger(mLogger); +#endif + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(bodyID) + ": New collision body created"); // Return the pointer to the rigid body return rigidBody; @@ -444,8 +446,8 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) { */ void DynamicsWorld::destroyRigidBody(RigidBody* rigidBody) { - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Body, - "Rigid Body " + std::to_string(rigidBody->getId()) + ": rigid body destroyed"); + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(rigidBody->getId()) + ": rigid body destroyed"); // Remove all the collision shapes of the body rigidBody->removeAllCollisionShapes(); @@ -549,7 +551,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) { // Add the joint into the joint list of the bodies involved in the joint addJointToBody(newJoint); - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Joint, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Joint, "Joint " + std::to_string(newJoint->getId()) + ": New joint created"); // Return the pointer to the created joint @@ -564,7 +566,7 @@ void DynamicsWorld::destroyJoint(Joint* joint) { assert(joint != nullptr); - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Joint, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Joint, "Joint " + std::to_string(joint->getId()) + ": joint destroyed"); // If the collision between the two bodies of the constraint was disabled @@ -863,7 +865,7 @@ void DynamicsWorld::enableSleeping(bool isSleepingEnabled) { } } - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: isSleepingEnabled=" + (isSleepingEnabled ? std::string("true") : std::string("false")) ); } diff --git a/src/engine/DynamicsWorld.h b/src/engine/DynamicsWorld.h index f435f4b9..53ef8d9e 100644 --- a/src/engine/DynamicsWorld.h +++ b/src/engine/DynamicsWorld.h @@ -283,7 +283,7 @@ inline uint DynamicsWorld::getNbIterationsVelocitySolver() const { inline void DynamicsWorld::setNbIterationsVelocitySolver(uint nbIterations) { mNbVelocitySolverIterations = nbIterations; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: Set nb iterations velocity solver to " + std::to_string(nbIterations)); } @@ -299,7 +299,7 @@ inline uint DynamicsWorld::getNbIterationsPositionSolver() const { inline void DynamicsWorld::setNbIterationsPositionSolver(uint nbIterations) { mNbPositionSolverIterations = nbIterations; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: Set nb iterations position solver to " + std::to_string(nbIterations)); } @@ -346,7 +346,7 @@ inline Vector3 DynamicsWorld::getGravity() const { inline void DynamicsWorld::setGravity(Vector3& gravity) { mGravity = gravity; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: Set gravity vector to " + gravity.to_string()); } @@ -366,7 +366,7 @@ inline bool DynamicsWorld::isGravityEnabled() const { inline void DynamicsWorld::setIsGratityEnabled(bool isGravityEnabled) { mIsGravityEnabled = isGravityEnabled; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: isGravityEnabled= " + (isGravityEnabled ? std::string("true") : std::string("false"))); } @@ -413,7 +413,7 @@ inline void DynamicsWorld::setSleepLinearVelocity(decimal sleepLinearVelocity) { assert(sleepLinearVelocity >= decimal(0.0)); mSleepLinearVelocity = sleepLinearVelocity; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: sleepLinearVelocity= " + std::to_string(sleepLinearVelocity)); } @@ -436,7 +436,7 @@ inline void DynamicsWorld::setSleepAngularVelocity(decimal sleepAngularVelocity) assert(sleepAngularVelocity >= decimal(0.0)); mSleepAngularVelocity = sleepAngularVelocity; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: sleepAngularVelocity= " + std::to_string(sleepAngularVelocity)); } @@ -457,7 +457,7 @@ inline void DynamicsWorld::setTimeBeforeSleep(decimal timeBeforeSleep) { assert(timeBeforeSleep >= decimal(0.0)); mTimeBeforeSleep = timeBeforeSleep; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: timeBeforeSleep= " + std::to_string(timeBeforeSleep)); } diff --git a/src/engine/Material.h b/src/engine/Material.h index d55724a1..ffe6b1e9 100644 --- a/src/engine/Material.h +++ b/src/engine/Material.h @@ -84,6 +84,9 @@ class Material { /// Set the rolling resistance factor void setRollingResistance(decimal rollingResistance); + /// Return a string representation for the material + std::string to_string() const; + /// Overloaded assignment operator Material& operator=(const Material& material); }; @@ -147,6 +150,18 @@ inline void Material::setRollingResistance(decimal rollingResistance) { mRollingResistance = rollingResistance; } +// Return a string representation for the material +inline std::string Material::to_string() const { + + std::stringstream ss; + + ss << "frictionCoefficient=" << mFrictionCoefficient << std::endl; + ss << "rollingResistance=" << mRollingResistance << std::endl; + ss << "bounciness=" << mBounciness << std::endl; + + return ss.str(); +} + // Overloaded assignment operator inline Material& Material::operator=(const Material& material) { diff --git a/src/engine/OverlappingPair.h b/src/engine/OverlappingPair.h index 3fa083a1..a16ea84e 100644 --- a/src/engine/OverlappingPair.h +++ b/src/engine/OverlappingPair.h @@ -248,12 +248,12 @@ inline void OverlappingPair::makeContactsObsolete() { // Return the pair of bodies index inline OverlappingPair::OverlappingPairId OverlappingPair::computeID(ProxyShape* shape1, ProxyShape* shape2) { - assert(shape1->mBroadPhaseID >= 0 && shape2->mBroadPhaseID >= 0); + assert(shape1->getBroadPhaseId() >= 0 && shape2->getBroadPhaseId() >= 0); // Construct the pair of body index - OverlappingPairId pairID = shape1->mBroadPhaseID < shape2->mBroadPhaseID ? - OverlappingPairId(shape1->mBroadPhaseID, shape2->mBroadPhaseID) : - OverlappingPairId(shape2->mBroadPhaseID, shape1->mBroadPhaseID); + OverlappingPairId pairID = shape1->getBroadPhaseId() < shape2->getBroadPhaseId() ? + OverlappingPairId(shape1->getBroadPhaseId(), shape2->getBroadPhaseId()) : + OverlappingPairId(shape2->getBroadPhaseId(), shape1->getBroadPhaseId()); assert(pairID.first != pairID.second); return pairID; } diff --git a/src/utils/Logger.h b/src/utils/Logger.h index 908da806..8ce51fb3 100644 --- a/src/utils/Logger.h +++ b/src/utils/Logger.h @@ -49,10 +49,10 @@ class Logger { public: /// Log verbosity levels - enum class Level {Error = 1, Warning = 2, Info = 4}; + enum class Level {Error = 1, Warning = 2, Information = 4}; /// Log categories - enum class Category {World, Body, Joint}; + enum class Category {World, Body, Joint, ProxyShape}; /// Log verbosity level enum class Format {Text, HTML}; @@ -64,6 +64,7 @@ class Logger { case Category::World: return "World"; case Category::Body: return "Body"; case Category::Joint: return "Joint"; + case Category::ProxyShape: return "ProxyShape"; } } @@ -71,7 +72,7 @@ class Logger { static std::string getLevelName(Level level) { switch(level) { - case Level::Info: return "Information"; + case Level::Information: return "Information"; case Level::Warning: return "Warning"; case Level::Error: return "Error"; } @@ -120,6 +121,22 @@ class Logger { } + /// Return the header to write at the beginning of the stream + virtual std::string getHeader() const override { + + // Get current date + auto now = std::chrono::system_clock::now(); + auto time = std::chrono::system_clock::to_time_t(now); + + std::stringstream ss; + ss << "ReactPhysics3D Logs" << std::endl; + ss << "ReactPhysics3D Version: " << RP3D_VERSION << std::endl; + ss << "Date: " << std::put_time(std::localtime(&time), "%Y-%m-%d") << std::endl; + ss << "---------------------------------------------------------" << std::endl; + + return ss.str(); + } + /// Format a log message virtual std::string format(const time_t& time, const std::string& message, Level level, Category category) override { @@ -134,8 +151,11 @@ class Logger { /// Return the header to write at the beginning of the stream virtual std::string getHeader() const override { - std::stringstream ss; + // Get current date + auto now = std::chrono::system_clock::now(); + auto time = std::chrono::system_clock::to_time_t(now); + std::stringstream ss; ss << "" << std::endl; ss << "" << std::endl; ss << "" << std::endl; @@ -143,6 +163,12 @@ class Logger { ss << "" << std::endl; ss << "" << std::endl; ss << "" << std::endl; + ss << "

ReactPhysics3D Logs

" << std::endl; + ss << "
" << std::endl; + ss << "

ReactPhysics3D version: " << RP3D_VERSION << "

" << std::endl; + ss << "

Date: " << std::put_time(std::localtime(&time), "%Y-%m-%d") << "

" << std::endl; + ss << "
" << std::endl; + ss << "
"; return ss.str(); } @@ -161,26 +187,33 @@ class Logger { std::string generateCSS() const { return "body {" " background-color: #f7f7f9;" + " font-family: SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace; " "} " "body > div { clear:both; } " "body > div > div { float: left; } " + "h1 {" + " margin: 5px 5px 5px 5px;" + "} " + ".general_info > p {" + "margin: 5px;" + "font-weight: bold;" + "} " ".line { " - "font-family: SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace; " "font-size: 13px; " "color: #212529; " "margin: 0px 5px 2px 5px; " "} " ".time { " - "margin-right: 10px; " - "width:100px; " + "margin-right: 20px; " + "width:80px; " "} " ".level { " - "margin-right: 10px; " - "width: 110px; " + "margin-right: 20px; " + "width: 90px; " "}" ".category { " - "margin-right: 10px; " - "width: 120px; " + "margin-right: 20px; " + "width: 100px; " "font-weight: bold; " "}" ".message { " @@ -188,20 +221,23 @@ class Logger { "word-wrap: break-word; " "max-width: 800px; " "} " - ".body > .category { " - "color: #007bff; " + ".body > .category, .body > .message { " + "color: #8bc34a;" "} " - ".world > .category { " + ".world > .category, .world > .message { " "color: #4f9fcf; " "} " - ".joint > .category { " - "color: #6c757d; " + ".joint .category, .joint > .message { " + "color: #aa00ff; " + "} " + ".proxyshape .category, .proxyshape > .message { " + "color: #009933; " "} " ".warning { " - "color: #f0ad4e; " + "color: #ff9900 !important; " "} " ".error { " - "color: #d44950; " + "color: red !important; " "} "; } @@ -248,7 +284,8 @@ class Logger { ss << ""; // Message - ss << "
"; + ss << "
" << std::endl; ss << message; ss << "
"; From 71bfa6afce00c41164c05eab21e4ac3687158ff8 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Mon, 26 Mar 2018 22:00:52 +0200 Subject: [PATCH 4/5] Remove setLocalScaling() method from CollisionShape and ProxyShape and use scaling only for HeightFieldShape, ConvexMeshShape and ConcaveMeshShape --- src/collision/ProxyShape.h | 35 ----------------------- src/collision/shapes/BoxShape.h | 11 ------- src/collision/shapes/CapsuleShape.h | 12 -------- src/collision/shapes/CollisionShape.cpp | 2 +- src/collision/shapes/CollisionShape.h | 16 ----------- src/collision/shapes/ConcaveMeshShape.cpp | 5 ++-- src/collision/shapes/ConcaveMeshShape.h | 28 ++++++++---------- src/collision/shapes/ConvexMeshShape.cpp | 5 ++-- src/collision/shapes/ConvexMeshShape.h | 22 +++++++------- src/collision/shapes/HeightFieldShape.cpp | 4 +-- src/collision/shapes/HeightFieldShape.h | 22 ++++++++------ src/collision/shapes/SphereShape.h | 11 ------- src/collision/shapes/TriangleShape.h | 13 --------- test/tests/collision/TestRaycast.h | 1 - testbed/common/Box.cpp | 13 --------- testbed/common/Box.h | 3 -- testbed/common/Capsule.cpp | 13 --------- testbed/common/Capsule.h | 3 -- testbed/common/ConcaveMesh.cpp | 14 --------- testbed/common/ConcaveMesh.h | 3 -- testbed/common/ConvexMesh.cpp | 13 --------- testbed/common/ConvexMesh.h | 3 -- testbed/common/Dumbbell.cpp | 27 ----------------- testbed/common/Dumbbell.h | 3 -- testbed/common/HeightField.cpp | 13 --------- testbed/common/HeightField.h | 3 -- testbed/common/PhysicsObject.h | 3 -- testbed/common/Sphere.cpp | 13 --------- testbed/common/Sphere.h | 3 -- 29 files changed, 46 insertions(+), 271 deletions(-) diff --git a/src/collision/ProxyShape.h b/src/collision/ProxyShape.h index 61118d45..9e4ea298 100644 --- a/src/collision/ProxyShape.h +++ b/src/collision/ProxyShape.h @@ -175,12 +175,6 @@ class ProxyShape { /// Return the next proxy shape in the linked list of proxy shapes const ProxyShape* getNext() const; - /// Return the local scaling vector of the collision shape - Vector3 getLocalScaling() const; - - /// Set the local scaling vector of the collision shape - virtual void setLocalScaling(const Vector3& scaling); - /// Return the broad-phase id int getBroadPhaseId() const; @@ -361,35 +355,6 @@ inline void ProxyShape::setCollideWithMaskBits(unsigned short collideWithMaskBit std::to_string(mCollideWithMaskBits)); } -// Return the local scaling vector of the collision shape -/** - * @return The local scaling vector - */ -inline Vector3 ProxyShape::getLocalScaling() const { - return mCollisionShape->getLocalScaling(); -} - -// Set the local scaling vector of the collision shape -/** - * @param scaling The new local scaling vector - */ -inline void ProxyShape::setLocalScaling(const Vector3& scaling) { - - // TODO : Do not use a local of the collision shape in case of shared collision shapes - - // Set the local scaling of the collision shape - mCollisionShape->setLocalScaling(scaling); - - mBody->setIsSleeping(false); - - // Notify the body that the proxy shape has to be updated in the broad-phase - mBody->updateProxyShapeInBroadPhase(this, true); - - RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape, - "ProxyShape " + std::to_string(mBroadPhaseID) + ": Set localScaling=" + - mCollisionShape->getLocalScaling().to_string()); -} - // Return the broad-phase id inline int ProxyShape::getBroadPhaseId() const { return mBroadPhaseID; diff --git a/src/collision/shapes/BoxShape.h b/src/collision/shapes/BoxShape.h index 0c261a6f..b1128582 100644 --- a/src/collision/shapes/BoxShape.h +++ b/src/collision/shapes/BoxShape.h @@ -88,9 +88,6 @@ class BoxShape : public ConvexPolyhedronShape { /// Return the extents of the box Vector3 getExtent() const; - /// Set the scaling vector of the collision shape - virtual void setLocalScaling(const Vector3& scaling) override; - /// Return the local bounds of the shape in x, y and z directions virtual void getLocalBounds(Vector3& min, Vector3& max) const override; @@ -136,14 +133,6 @@ inline Vector3 BoxShape::getExtent() const { return mExtent; } -// Set the scaling vector of the collision shape -inline void BoxShape::setLocalScaling(const Vector3& scaling) { - - mExtent = (mExtent / mScaling) * scaling; - - CollisionShape::setLocalScaling(scaling); -} - // Return the local bounds of the shape in x, y and z directions /// This method is used to compute the AABB of the box /** diff --git a/src/collision/shapes/CapsuleShape.h b/src/collision/shapes/CapsuleShape.h index 6a58f115..decf6474 100644 --- a/src/collision/shapes/CapsuleShape.h +++ b/src/collision/shapes/CapsuleShape.h @@ -94,9 +94,6 @@ class CapsuleShape : public ConvexShape { /// Return the height of the capsule decimal getHeight() const; - /// Set the scaling vector of the collision shape - virtual void setLocalScaling(const Vector3& scaling) override; - /// Return the local bounds of the shape in x, y and z directions virtual void getLocalBounds(Vector3& min, Vector3& max) const override; @@ -126,15 +123,6 @@ inline decimal CapsuleShape::getHeight() const { return mHalfHeight + mHalfHeight; } -// Set the scaling vector of the collision shape -inline void CapsuleShape::setLocalScaling(const Vector3& scaling) { - - mHalfHeight = (mHalfHeight / mScaling.y) * scaling.y; - mMargin = (mMargin / mScaling.x) * scaling.x; - - CollisionShape::setLocalScaling(scaling); -} - // Return the number of bytes used by the collision shape inline size_t CapsuleShape::getSizeInBytes() const { return sizeof(CapsuleShape); diff --git a/src/collision/shapes/CollisionShape.cpp b/src/collision/shapes/CollisionShape.cpp index 976c7a51..4e6e4b9b 100644 --- a/src/collision/shapes/CollisionShape.cpp +++ b/src/collision/shapes/CollisionShape.cpp @@ -33,7 +33,7 @@ using namespace reactphysics3d; // Constructor CollisionShape::CollisionShape(CollisionShapeName name, CollisionShapeType type) - : mType(type), mName(name), mScaling(1.0, 1.0, 1.0), mId(0) { + : mType(type), mName(name), mId(0) { } diff --git a/src/collision/shapes/CollisionShape.h b/src/collision/shapes/CollisionShape.h index a7b07fc3..990ef33f 100644 --- a/src/collision/shapes/CollisionShape.h +++ b/src/collision/shapes/CollisionShape.h @@ -68,9 +68,6 @@ class CollisionShape { /// Name of the colision shape CollisionShapeName mName; - /// Scaling vector of the collision shape - Vector3 mScaling; - /// Unique identifier of the shape inside an overlapping pair uint mId; @@ -126,9 +123,6 @@ class CollisionShape { /// Return the scaling vector of the collision shape Vector3 getLocalScaling() const; - /// Set the local scaling vector of the collision shape - virtual void setLocalScaling(const Vector3& scaling); - /// Return the id of the shape uint getId() const; @@ -170,16 +164,6 @@ inline CollisionShapeType CollisionShape::getType() const { return mType; } -// Return the scaling vector of the collision shape -inline Vector3 CollisionShape::getLocalScaling() const { - return mScaling; -} - -// Set the scaling vector of the collision shape -inline void CollisionShape::setLocalScaling(const Vector3& scaling) { - mScaling = scaling; -} - // Return the id of the shape inline uint CollisionShape::getId() const { return mId; diff --git a/src/collision/shapes/ConcaveMeshShape.cpp b/src/collision/shapes/ConcaveMeshShape.cpp index bde756e4..a6cfcb9c 100644 --- a/src/collision/shapes/ConcaveMeshShape.cpp +++ b/src/collision/shapes/ConcaveMeshShape.cpp @@ -30,8 +30,9 @@ using namespace reactphysics3d; // Constructor -ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh) - : ConcaveShape(CollisionShapeName::TRIANGLE_MESH), mDynamicAABBTree(MemoryManager::getBaseAllocator()) { +ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh, const Vector3& scaling) + : ConcaveShape(CollisionShapeName::TRIANGLE_MESH), mDynamicAABBTree(MemoryManager::getBaseAllocator()), + mScaling(scaling) { mTriangleMesh = triangleMesh; mRaycastTestType = TriangleRaycastSide::FRONT; diff --git a/src/collision/shapes/ConcaveMeshShape.h b/src/collision/shapes/ConcaveMeshShape.h index ccafbba9..e8ad78e5 100644 --- a/src/collision/shapes/ConcaveMeshShape.h +++ b/src/collision/shapes/ConcaveMeshShape.h @@ -140,6 +140,9 @@ class ConcaveMeshShape : public ConcaveShape { /// if the user did not provide its own vertices normals) Vector3** mComputedVerticesNormals; + /// Scaling + const Vector3 mScaling; + // -------------------- Methods -------------------- // /// Raycast method with feedback information @@ -163,7 +166,7 @@ class ConcaveMeshShape : public ConcaveShape { public: /// Constructor - ConcaveMeshShape(TriangleMesh* triangleMesh); + ConcaveMeshShape(TriangleMesh* triangleMesh, const Vector3& scaling = Vector3(1, 1, 1)); /// Destructor virtual ~ConcaveMeshShape() = default; @@ -174,12 +177,12 @@ class ConcaveMeshShape : public ConcaveShape { /// Deleted assignment operator ConcaveMeshShape& operator=(const ConcaveMeshShape& shape) = delete; + /// Return the scaling vector + const Vector3& getScaling() const; + /// Return the local bounds of the shape in x, y and z directions. virtual void getLocalBounds(Vector3& min, Vector3& max) const override; - /// Set the local scaling vector of the collision shape - virtual void setLocalScaling(const Vector3& scaling) override; - /// Return the local inertia tensor of the collision shape virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override; @@ -207,6 +210,11 @@ inline size_t ConcaveMeshShape::getSizeInBytes() const { return sizeof(ConcaveMeshShape); } +// Return the scaling vector +inline const Vector3& ConcaveMeshShape::getScaling() const { + return mScaling; +} + // Return the local bounds of the shape in x, y and z directions. // This method is used to compute the AABB of the box /** @@ -222,18 +230,6 @@ inline void ConcaveMeshShape::getLocalBounds(Vector3& min, Vector3& max) const { max = treeAABB.getMax(); } -// Set the local scaling vector of the collision shape -inline void ConcaveMeshShape::setLocalScaling(const Vector3& scaling) { - - CollisionShape::setLocalScaling(scaling); - - // Reset the Dynamic AABB Tree - mDynamicAABBTree.reset(); - - // Rebuild Dynamic AABB Tree here - initBVHTree(); -} - // Return the local inertia tensor of the shape /** * @param[out] tensor The 3x3 inertia tensor matrix of the shape in local-space diff --git a/src/collision/shapes/ConvexMeshShape.cpp b/src/collision/shapes/ConvexMeshShape.cpp index 1c47b4d9..3dadfee4 100644 --- a/src/collision/shapes/ConvexMeshShape.cpp +++ b/src/collision/shapes/ConvexMeshShape.cpp @@ -38,8 +38,9 @@ using namespace reactphysics3d; * @param stride Stride between the beginning of two elements in the vertices array * @param margin Collision margin (in meters) around the collision shape */ -ConvexMeshShape::ConvexMeshShape(PolyhedronMesh* polyhedronMesh) - : ConvexPolyhedronShape(CollisionShapeName::CONVEX_MESH), mPolyhedronMesh(polyhedronMesh), mMinBounds(0, 0, 0), mMaxBounds(0, 0, 0) { +ConvexMeshShape::ConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scaling) + : ConvexPolyhedronShape(CollisionShapeName::CONVEX_MESH), mPolyhedronMesh(polyhedronMesh), + mMinBounds(0, 0, 0), mMaxBounds(0, 0, 0), mScaling(scaling) { // Recalculate the bounds of the mesh recalculateBounds(); diff --git a/src/collision/shapes/ConvexMeshShape.h b/src/collision/shapes/ConvexMeshShape.h index ebec6a09..5ce02b19 100644 --- a/src/collision/shapes/ConvexMeshShape.h +++ b/src/collision/shapes/ConvexMeshShape.h @@ -30,7 +30,7 @@ #include "ConvexPolyhedronShape.h" #include "engine/CollisionWorld.h" #include "mathematics/mathematics.h" -#include "collision/TriangleMesh.h" + #include "collision/PolyhedronMesh.h" #include "collision/narrowphase/GJK/GJKAlgorithm.h" @@ -62,6 +62,9 @@ class ConvexMeshShape : public ConvexPolyhedronShape { /// Mesh maximum bounds in the three local x, y and z directions Vector3 mMaxBounds; + /// Local scaling + const Vector3 mScaling; + // -------------------- Methods -------------------- // /// Recompute the bounds of the mesh @@ -84,7 +87,7 @@ class ConvexMeshShape : public ConvexPolyhedronShape { // -------------------- Methods -------------------- // /// Constructor - ConvexMeshShape(PolyhedronMesh* polyhedronMesh); + ConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scaling = Vector3(1,1,1)); /// Destructor virtual ~ConvexMeshShape() override = default; @@ -95,8 +98,8 @@ class ConvexMeshShape : public ConvexPolyhedronShape { /// Deleted assignment operator ConvexMeshShape& operator=(const ConvexMeshShape& shape) = delete; - /// Set the scaling vector of the collision shape - virtual void setLocalScaling(const Vector3& scaling) override; + /// Return the scaling vector + const Vector3& getScaling() const; /// Return the local bounds of the shape in x, y and z directions virtual void getLocalBounds(Vector3& min, Vector3& max) const override; @@ -135,17 +138,16 @@ class ConvexMeshShape : public ConvexPolyhedronShape { virtual std::string to_string() const override; }; -/// Set the scaling vector of the collision shape -inline void ConvexMeshShape::setLocalScaling(const Vector3& scaling) { - ConvexShape::setLocalScaling(scaling); - recalculateBounds(); -} - // Return the number of bytes used by the collision shape inline size_t ConvexMeshShape::getSizeInBytes() const { return sizeof(ConvexMeshShape); } +// Return the scaling vector +inline const Vector3& ConvexMeshShape::getScaling() const { + return mScaling; +} + // Return the local bounds of the shape in x, y and z directions /** * @param min The minimum bounds of the shape in local-space coordinates diff --git a/src/collision/shapes/HeightFieldShape.cpp b/src/collision/shapes/HeightFieldShape.cpp index 0b3a4044..0136c881 100644 --- a/src/collision/shapes/HeightFieldShape.cpp +++ b/src/collision/shapes/HeightFieldShape.cpp @@ -41,11 +41,11 @@ using namespace reactphysics3d; */ HeightFieldShape::HeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight, const void* heightFieldData, HeightDataType dataType, int upAxis, - decimal integerHeightScale) + decimal integerHeightScale, const Vector3& scaling) : ConcaveShape(CollisionShapeName::HEIGHTFIELD), mNbColumns(nbGridColumns), mNbRows(nbGridRows), mWidth(nbGridColumns - 1), mLength(nbGridRows - 1), mMinHeight(minHeight), mMaxHeight(maxHeight), mUpAxis(upAxis), mIntegerHeightScale(integerHeightScale), - mHeightDataType(dataType) { + mHeightDataType(dataType), mScaling(scaling) { assert(nbGridColumns >= 2); assert(nbGridRows >= 2); diff --git a/src/collision/shapes/HeightFieldShape.h b/src/collision/shapes/HeightFieldShape.h index e796e208..8d4574d2 100644 --- a/src/collision/shapes/HeightFieldShape.h +++ b/src/collision/shapes/HeightFieldShape.h @@ -141,6 +141,9 @@ class HeightFieldShape : public ConcaveShape { /// Local AABB of the height field (without scaling) AABB mAABB; + /// Scaling vector + const Vector3 mScaling; + // -------------------- Methods -------------------- // /// Raycast method with feedback information @@ -177,7 +180,8 @@ class HeightFieldShape : public ConcaveShape { /// Constructor HeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight, const void* heightFieldData, HeightDataType dataType, - int upAxis = 1, decimal integerHeightScale = 1.0f); + int upAxis = 1, decimal integerHeightScale = 1.0f, + const Vector3& scaling = Vector3(1,1,1)); /// Destructor virtual ~HeightFieldShape() override = default; @@ -188,6 +192,9 @@ class HeightFieldShape : public ConcaveShape { /// Deleted assignment operator HeightFieldShape& operator=(const HeightFieldShape& shape) = delete; + /// Return the scaling factor + const Vector3& getScaling() const; + /// Return the number of rows in the height field int getNbRows() const; @@ -200,9 +207,6 @@ class HeightFieldShape : public ConcaveShape { /// Return the local bounds of the shape in x, y and z directions. virtual void getLocalBounds(Vector3& min, Vector3& max) const override; - /// Set the local scaling vector of the collision shape - virtual void setLocalScaling(const Vector3& scaling) override; - /// Return the local inertia tensor of the collision shape virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override; @@ -218,6 +222,11 @@ class HeightFieldShape : public ConcaveShape { friend class ConcaveMeshRaycastCallback; }; +// Return the scaling factor +inline const Vector3& HeightFieldShape::getScaling() const { + return mScaling; +} + // Return the number of rows in the height field inline int HeightFieldShape::getNbRows() const { return mNbRows; @@ -238,11 +247,6 @@ inline size_t HeightFieldShape::getSizeInBytes() const { return sizeof(HeightFieldShape); } -// Set the local scaling vector of the collision shape -inline void HeightFieldShape::setLocalScaling(const Vector3& scaling) { - CollisionShape::setLocalScaling(scaling); -} - // Return the height of a given (x,y) point in the height field inline decimal HeightFieldShape::getHeightAt(int x, int y) const { diff --git a/src/collision/shapes/SphereShape.h b/src/collision/shapes/SphereShape.h index a0010b06..01e2001e 100644 --- a/src/collision/shapes/SphereShape.h +++ b/src/collision/shapes/SphereShape.h @@ -82,9 +82,6 @@ class SphereShape : public ConvexShape { /// Return true if the collision shape is a polyhedron virtual bool isPolyhedron() const override; - /// Set the scaling vector of the collision shape - virtual void setLocalScaling(const Vector3& scaling) override; - /// Return the local bounds of the shape in x, y and z directions. virtual void getLocalBounds(Vector3& min, Vector3& max) const override; @@ -111,14 +108,6 @@ inline bool SphereShape::isPolyhedron() const { return false; } -// Set the scaling vector of the collision shape -inline void SphereShape::setLocalScaling(const Vector3& scaling) { - - mMargin = (mMargin / mScaling.x) * scaling.x; - - CollisionShape::setLocalScaling(scaling); -} - // Return the number of bytes used by the collision shape inline size_t SphereShape::getSizeInBytes() const { return sizeof(SphereShape); diff --git a/src/collision/shapes/TriangleShape.h b/src/collision/shapes/TriangleShape.h index 5a5a49b2..23a55c38 100644 --- a/src/collision/shapes/TriangleShape.h +++ b/src/collision/shapes/TriangleShape.h @@ -127,9 +127,6 @@ class TriangleShape : public ConvexPolyhedronShape { /// Return the local bounds of the shape in x, y and z directions. virtual void getLocalBounds(Vector3& min, Vector3& max) const override; - /// Set the local scaling vector of the collision shape - virtual void setLocalScaling(const Vector3& scaling) override; - /// Return the local inertia tensor of the collision shape virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override; @@ -214,16 +211,6 @@ inline void TriangleShape::getLocalBounds(Vector3& min, Vector3& max) const { max += Vector3(mMargin, mMargin, mMargin); } -// Set the local scaling vector of the collision shape -inline void TriangleShape::setLocalScaling(const Vector3& scaling) { - - mPoints[0] = (mPoints[0] / mScaling) * scaling; - mPoints[1] = (mPoints[1] / mScaling) * scaling; - mPoints[2] = (mPoints[2] / mScaling) * scaling; - - CollisionShape::setLocalScaling(scaling); -} - // Return the local inertia tensor of the triangle shape /** * @param[out] tensor The 3x3 inertia tensor matrix of the shape in local-space diff --git a/test/tests/collision/TestRaycast.h b/test/tests/collision/TestRaycast.h index 7714264a..70397ed0 100644 --- a/test/tests/collision/TestRaycast.h +++ b/test/tests/collision/TestRaycast.h @@ -1303,7 +1303,6 @@ class TestRaycast : public Test { Vector3 point2 = mLocalShapeToWorld * Vector3(1, 2, -4); Ray ray(point1, point2); Vector3 hitPoint = mLocalShapeToWorld * Vector3(1, 2, 4); - Transform inverse = mLocalShapeToWorld.getInverse(); mCallback.shapeToTest = mConvexMeshProxyShape; diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index 508fa516..6d685086 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -255,16 +255,3 @@ void Box::createVBOAndVAO() { // Unbind the VAO mVAO.unbind(); } - -// Set the scaling of the object -void Box::setScaling(const openglframework::Vector3& scaling) { - - // Scale the collision shape - mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z)); - - // Scale the graphics object - mScalingMatrix = openglframework::Matrix4(mSize[0] * scaling.x, 0, 0, 0, - 0, mSize[1] * scaling.y, 0, 0, - 0, 0, mSize[2] * scaling.z, 0, - 0, 0, 0, 1); -} diff --git a/testbed/common/Box.h b/testbed/common/Box.h index 42d234f9..21fe0ed1 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -88,9 +88,6 @@ class Box : public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; - - /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object diff --git a/testbed/common/Capsule.cpp b/testbed/common/Capsule.cpp index b48baf69..160030b7 100644 --- a/testbed/common/Capsule.cpp +++ b/testbed/common/Capsule.cpp @@ -235,16 +235,3 @@ void Capsule::createVBOAndVAO() { // Unbind the VAO mVAO.unbind(); } - -// Set the scaling of the object -void Capsule::setScaling(const openglframework::Vector3& scaling) { - - // Scale the collision shape - mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z)); - - // Scale the graphics object - mScalingMatrix = openglframework::Matrix4(mRadius * scaling.x, 0, 0, 0, - 0, (mHeight * scaling.y + 2.0f * mRadius * scaling.x) / 3, 0,0, - 0, 0, mRadius * scaling.x, 0, - 0, 0, 0, 1.0f); -} diff --git a/testbed/common/Capsule.h b/testbed/common/Capsule.h index d0e74436..1591f247 100644 --- a/testbed/common/Capsule.h +++ b/testbed/common/Capsule.h @@ -96,9 +96,6 @@ class Capsule : public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; - - /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object diff --git a/testbed/common/ConcaveMesh.cpp b/testbed/common/ConcaveMesh.cpp index f6b04b9c..553a83ca 100644 --- a/testbed/common/ConcaveMesh.cpp +++ b/testbed/common/ConcaveMesh.cpp @@ -244,17 +244,3 @@ void ConcaveMesh::createVBOAndVAO() { // Unbind the VAO mVAO.unbind(); } - -// Set the scaling of the object -void ConcaveMesh::setScaling(const openglframework::Vector3& scaling) { - - // Scale the collision shape - mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z)); - - // Scale the graphics object - mScalingMatrix = openglframework::Matrix4(scaling.x, 0, 0, 0, - 0, scaling.y, 0,0, - 0, 0, scaling.z, 0, - 0, 0, 0, 1.0f); -} - diff --git a/testbed/common/ConcaveMesh.h b/testbed/common/ConcaveMesh.h index 17755352..21d40082 100644 --- a/testbed/common/ConcaveMesh.h +++ b/testbed/common/ConcaveMesh.h @@ -90,9 +90,6 @@ class ConcaveMesh : public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; - - /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object diff --git a/testbed/common/ConvexMesh.cpp b/testbed/common/ConvexMesh.cpp index a59c2f3d..95e41dd1 100644 --- a/testbed/common/ConvexMesh.cpp +++ b/testbed/common/ConvexMesh.cpp @@ -254,16 +254,3 @@ void ConvexMesh::createVBOAndVAO() { // Unbind the VAO mVAO.unbind(); } - -// Set the scaling of the object -void ConvexMesh::setScaling(const openglframework::Vector3& scaling) { - - // Scale the collision shape - mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z)); - - // Scale the graphics object - mScalingMatrix = openglframework::Matrix4(scaling.x, 0, 0, 0, - 0, scaling.y, 0, 0, - 0, 0, scaling.z, 0, - 0, 0, 0, 1); -} diff --git a/testbed/common/ConvexMesh.h b/testbed/common/ConvexMesh.h index 865921ca..cc8c1599 100644 --- a/testbed/common/ConvexMesh.h +++ b/testbed/common/ConvexMesh.h @@ -92,9 +92,6 @@ class ConvexMesh : public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; - - /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object diff --git a/testbed/common/Dumbbell.cpp b/testbed/common/Dumbbell.cpp index f90f0cc9..866c35b1 100644 --- a/testbed/common/Dumbbell.cpp +++ b/testbed/common/Dumbbell.cpp @@ -272,30 +272,3 @@ void Dumbbell::createVBOAndVAO() { // Unbind the VAO mVAO.unbind(); } - -// Set the scaling of the object -void Dumbbell::setScaling(const openglframework::Vector3& scaling) { - - // Scale the collision shape - rp3d::Vector3 newScaling(scaling.x, scaling.y, scaling.z); - mProxyShapeCapsule->setLocalScaling(newScaling); - mProxyShapeSphere1->setLocalScaling(newScaling); - mProxyShapeSphere2->setLocalScaling(newScaling); - - mDistanceBetweenSphere = (mDistanceBetweenSphere / mScalingMatrix.getValue(1, 1)) * scaling.y; - - // Initial transform of the first sphere collision shape of the dumbbell (in local-space) - rp3d::Transform transformSphereShape1(rp3d::Vector3(0, mDistanceBetweenSphere / 2.0f, 0), rp3d::Quaternion::identity()); - - // Initial transform of the second sphere collision shape of the dumbell (in local-space) - rp3d::Transform transformSphereShape2(rp3d::Vector3(0, -mDistanceBetweenSphere / 2.0f, 0), rp3d::Quaternion::identity()); - - mProxyShapeSphere1->setLocalToBodyTransform(transformSphereShape1); - mProxyShapeSphere2->setLocalToBodyTransform(transformSphereShape2); - - // Scale the graphics object - mScalingMatrix = openglframework::Matrix4(scaling.x, 0, 0, 0, - 0, scaling.y, 0, 0, - 0, 0, scaling.z, 0, - 0, 0, 0, 1); -} diff --git a/testbed/common/Dumbbell.h b/testbed/common/Dumbbell.h index 135beabc..8044e434 100644 --- a/testbed/common/Dumbbell.h +++ b/testbed/common/Dumbbell.h @@ -95,9 +95,6 @@ class Dumbbell : public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; - - /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object diff --git a/testbed/common/HeightField.cpp b/testbed/common/HeightField.cpp index e979936d..b1077fad 100644 --- a/testbed/common/HeightField.cpp +++ b/testbed/common/HeightField.cpp @@ -303,16 +303,3 @@ void HeightField::createVBOAndVAO() { // Unbind the VAO mVAO.unbind(); } - -// Set the scaling of the object -void HeightField::setScaling(const openglframework::Vector3& scaling) { - - // Scale the collision shape - mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z)); - - // Scale the graphics object - mScalingMatrix = openglframework::Matrix4(scaling.x, 0, 0, 0, - 0, scaling.y, 0,0, - 0, 0, scaling.z, 0, - 0, 0, 0, 1.0f); -} diff --git a/testbed/common/HeightField.h b/testbed/common/HeightField.h index 1ff390ee..e68c8388 100644 --- a/testbed/common/HeightField.h +++ b/testbed/common/HeightField.h @@ -103,9 +103,6 @@ class HeightField : public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; - - /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object diff --git a/testbed/common/PhysicsObject.h b/testbed/common/PhysicsObject.h index e1714048..31e01c4f 100644 --- a/testbed/common/PhysicsObject.h +++ b/testbed/common/PhysicsObject.h @@ -82,9 +82,6 @@ class PhysicsObject : public openglframework::Mesh { /// Return a pointer to the rigid body of the box reactphysics3d::RigidBody* getRigidBody(); - - /// Set the scaling of the object - virtual void setScaling(const openglframework::Vector3& scaling)=0; }; // Set the color of the box diff --git a/testbed/common/Sphere.cpp b/testbed/common/Sphere.cpp index f7c53579..15375e05 100644 --- a/testbed/common/Sphere.cpp +++ b/testbed/common/Sphere.cpp @@ -234,16 +234,3 @@ void Sphere::createVBOAndVAO() { // Unbind the VAO mVAO.unbind(); } - -// Set the scaling of the object -void Sphere::setScaling(const openglframework::Vector3& scaling) { - - // Scale the collision shape - mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z)); - - // Scale the graphics object - mScalingMatrix = openglframework::Matrix4(mRadius * scaling.x, 0, 0, 0, - 0, mRadius * scaling.y, 0, 0, - 0, 0, mRadius * scaling.z, 0, - 0, 0, 0, 1); -} diff --git a/testbed/common/Sphere.h b/testbed/common/Sphere.h index fe2b3f83..e1ba6ed6 100644 --- a/testbed/common/Sphere.h +++ b/testbed/common/Sphere.h @@ -92,9 +92,6 @@ class Sphere : public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; - - /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object From 100cdbc64a14ef855b4f6a890caee8267ae4b016 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Wed, 28 Mar 2018 22:55:02 +0200 Subject: [PATCH 5/5] Working on logger --- src/body/Body.h | 7 +++-- src/body/CollisionBody.cpp | 4 +++ src/body/RigidBody.cpp | 4 +++ src/collision/shapes/BoxShape.h | 2 +- src/collision/shapes/CapsuleShape.h | 2 +- src/collision/shapes/ConcaveMeshShape.cpp | 2 +- src/collision/shapes/ConvexMeshShape.cpp | 2 +- src/collision/shapes/HeightFieldShape.cpp | 16 +++++------ src/collision/shapes/SphereShape.h | 2 +- src/collision/shapes/TriangleShape.h | 2 +- src/constraint/BallAndSocketJoint.h | 9 +++++++ src/constraint/FixedJoint.h | 11 ++++++++ src/constraint/HingeJoint.cpp | 4 +-- src/constraint/HingeJoint.h | 14 ++++++++++ src/constraint/Joint.h | 3 +++ src/constraint/SliderJoint.cpp | 6 ++--- src/constraint/SliderJoint.h | 14 ++++++++++ src/engine/DynamicsWorld.cpp | 16 ++++++++--- src/utils/Logger.cpp | 4 +++ src/utils/Logger.h | 33 +++++++++++++++++------ 20 files changed, 125 insertions(+), 32 deletions(-) diff --git a/src/body/Body.h b/src/body/Body.h index dbacc55d..337b9df1 100644 --- a/src/body/Body.h +++ b/src/body/Body.h @@ -218,11 +218,14 @@ inline void Body::setIsSleeping(bool isSleeping) { } } - mIsSleeping = isSleeping; + if (mIsSleeping != isSleeping) { - RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + mIsSleeping = isSleeping; + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, "Body " + std::to_string(mID) + ": Set isSleeping=" + (mIsSleeping ? "true" : "false")); + } } // Return a pointer to the user data attached to this body diff --git a/src/body/CollisionBody.cpp b/src/body/CollisionBody.cpp index f7e7fe1d..62c035ff 100644 --- a/src/body/CollisionBody.cpp +++ b/src/body/CollisionBody.cpp @@ -109,6 +109,10 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape, RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, "Body " + std::to_string(mID) + ": Proxy shape " + std::to_string(proxyShape->getBroadPhaseId()) + " added to body"); + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape, + "ProxyShape " + std::to_string(proxyShape->getBroadPhaseId()) + ": collisionShape=" + + proxyShape->getCollisionShape()->to_string()); + // Return a pointer to the collision shape return proxyShape; } diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index 3791c9d9..4a05010b 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -310,6 +310,10 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* collisionShape, RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, "Body " + std::to_string(mID) + ": Proxy shape " + std::to_string(proxyShape->getBroadPhaseId()) + " added to body"); + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape, + "ProxyShape " + std::to_string(proxyShape->getBroadPhaseId()) + ": collisionShape=" + + proxyShape->getCollisionShape()->to_string()); + // Return a pointer to the proxy collision shape return proxyShape; } diff --git a/src/collision/shapes/BoxShape.h b/src/collision/shapes/BoxShape.h index b1128582..7e5fba31 100644 --- a/src/collision/shapes/BoxShape.h +++ b/src/collision/shapes/BoxShape.h @@ -231,7 +231,7 @@ inline Vector3 BoxShape::getCentroid() const { // Return the string representation of the shape inline std::string BoxShape::to_string() const { - return "BoxShape {extents=" + mExtent.to_string() + "}"; + return "BoxShape{extents=" + mExtent.to_string() + "}"; } // Return the number of half-edges of the polyhedron diff --git a/src/collision/shapes/CapsuleShape.h b/src/collision/shapes/CapsuleShape.h index decf6474..c595da77 100644 --- a/src/collision/shapes/CapsuleShape.h +++ b/src/collision/shapes/CapsuleShape.h @@ -178,7 +178,7 @@ inline Vector3 CapsuleShape::getLocalSupportPointWithoutMargin(const Vector3& di // Return the string representation of the shape inline std::string CapsuleShape::to_string() const { - return "CapsuleShape {halfHeight=" + std::to_string(mHalfHeight) + ", radius=" + std::to_string(getRadius()) + "}"; + return "CapsuleShape{halfHeight=" + std::to_string(mHalfHeight) + ", radius=" + std::to_string(getRadius()) + "}"; } } diff --git a/src/collision/shapes/ConcaveMeshShape.cpp b/src/collision/shapes/ConcaveMeshShape.cpp index a6cfcb9c..21677154 100644 --- a/src/collision/shapes/ConcaveMeshShape.cpp +++ b/src/collision/shapes/ConcaveMeshShape.cpp @@ -221,7 +221,7 @@ std::string ConcaveMeshShape::to_string() const { std::stringstream ss; - ss << "ConcaveMeshShape {" << std::endl; + ss << "ConcaveMeshShape{" << std::endl; ss << "nbSubparts=" << mTriangleMesh->getNbSubparts() << std::endl; // Vertices array diff --git a/src/collision/shapes/ConvexMeshShape.cpp b/src/collision/shapes/ConvexMeshShape.cpp index 3dadfee4..01cb9dc6 100644 --- a/src/collision/shapes/ConvexMeshShape.cpp +++ b/src/collision/shapes/ConvexMeshShape.cpp @@ -206,7 +206,7 @@ bool ConvexMeshShape::testPointInside(const Vector3& localPoint, ProxyShape* pro std::string ConvexMeshShape::to_string() const { std::stringstream ss; - ss << "ConvexMeshShape {" << std::endl; + ss << "ConvexMeshShape{" << std::endl; ss << "nbVertices=" << mPolyhedronMesh->getNbVertices() << std::endl; ss << "nbFaces=" << mPolyhedronMesh->getNbFaces() << std::endl; diff --git a/src/collision/shapes/HeightFieldShape.cpp b/src/collision/shapes/HeightFieldShape.cpp index 0136c881..37d73005 100644 --- a/src/collision/shapes/HeightFieldShape.cpp +++ b/src/collision/shapes/HeightFieldShape.cpp @@ -303,16 +303,16 @@ std::string HeightFieldShape::to_string() const { std::stringstream ss; - ss << "HeightFieldShape {" << std::endl; + ss << "HeightFieldShape{" << std::endl; ss << "nbColumns=" << mNbColumns << std::endl; - ss << "nbRows=" << mNbRows << std::endl; - ss << "width=" << mWidth << std::endl; - ss << "length=" << mLength << std::endl; - ss << "minHeight=" << mMinHeight << std::endl; - ss << "maxHeight=" << mMaxHeight << std::endl; - ss << "upAxis=" << mUpAxis << std::endl; - ss << "integerHeightScale=" << mIntegerHeightScale << std::endl; + ss << ", nbRows=" << mNbRows << std::endl; + ss << ", width=" << mWidth << std::endl; + ss << ", length=" << mLength << std::endl; + ss << ", minHeight=" << mMinHeight << std::endl; + ss << ", maxHeight=" << mMaxHeight << std::endl; + ss << ", upAxis=" << mUpAxis << std::endl; + ss << ", integerHeightScale=" << mIntegerHeightScale << std::endl; ss << "}"; return ss.str(); diff --git a/src/collision/shapes/SphereShape.h b/src/collision/shapes/SphereShape.h index 01e2001e..baebf6e1 100644 --- a/src/collision/shapes/SphereShape.h +++ b/src/collision/shapes/SphereShape.h @@ -175,7 +175,7 @@ inline bool SphereShape::testPointInside(const Vector3& localPoint, ProxyShape* // Return the string representation of the shape inline std::string SphereShape::to_string() const { - return "SphereShape { radius=" + std::to_string(getRadius()) + "}"; + return "SphereShape{radius=" + std::to_string(getRadius()) + "}"; } } diff --git a/src/collision/shapes/TriangleShape.h b/src/collision/shapes/TriangleShape.h index 23a55c38..87ae5398 100644 --- a/src/collision/shapes/TriangleShape.h +++ b/src/collision/shapes/TriangleShape.h @@ -317,7 +317,7 @@ inline void TriangleShape::setRaycastTestType(TriangleRaycastSide testType) { // Return the string representation of the shape inline std::string TriangleShape::to_string() const { - return "TriangleShape {v1=" + mPoints[0].to_string() + ", v2=" + mPoints[1].to_string() + "," + + return "TriangleShape{v1=" + mPoints[0].to_string() + ", v2=" + mPoints[1].to_string() + "," + "v3=" + mPoints[2].to_string() + "}"; } diff --git a/src/constraint/BallAndSocketJoint.h b/src/constraint/BallAndSocketJoint.h index ed66320f..33260bfb 100644 --- a/src/constraint/BallAndSocketJoint.h +++ b/src/constraint/BallAndSocketJoint.h @@ -133,6 +133,9 @@ class BallAndSocketJoint : public Joint { /// Deleted copy-constructor BallAndSocketJoint(const BallAndSocketJoint& constraint) = delete; + /// Return a string representation + virtual std::string to_string() const override; + /// Deleted assignment operator BallAndSocketJoint& operator=(const BallAndSocketJoint& constraint) = delete; }; @@ -142,6 +145,12 @@ inline size_t BallAndSocketJoint::getSizeInBytes() const { return sizeof(BallAndSocketJoint); } +// Return a string representation +inline std::string BallAndSocketJoint::to_string() const { + return "BallAndSocketJoint{ localAnchorPointBody1=" + mLocalAnchorPointBody1.to_string() + + ", localAnchorPointBody2=" + mLocalAnchorPointBody2.to_string() + "}"; +} + } #endif diff --git a/src/constraint/FixedJoint.h b/src/constraint/FixedJoint.h index 45fe1185..bc472cfa 100644 --- a/src/constraint/FixedJoint.h +++ b/src/constraint/FixedJoint.h @@ -144,6 +144,9 @@ class FixedJoint : public Joint { /// Deleted copy-constructor FixedJoint(const FixedJoint& constraint) = delete; + /// Return a string representation + virtual std::string to_string() const override; + /// Deleted assignment operator FixedJoint& operator=(const FixedJoint& constraint) = delete; }; @@ -153,6 +156,14 @@ inline size_t FixedJoint::getSizeInBytes() const { return sizeof(FixedJoint); } +// Return a string representation +inline std::string FixedJoint::to_string() const { + return "FixedJoint{ localAnchorPointBody1=" + mLocalAnchorPointBody1.to_string() + + ", localAnchorPointBody2=" + mLocalAnchorPointBody2.to_string() + + ", initOrientationDifferenceInv=" + mInitOrientationDifferenceInv.to_string() + + "}"; +} + } #endif diff --git a/src/constraint/HingeJoint.cpp b/src/constraint/HingeJoint.cpp index 990e7be1..bccd0cb1 100644 --- a/src/constraint/HingeJoint.cpp +++ b/src/constraint/HingeJoint.cpp @@ -42,8 +42,8 @@ HingeJoint::HingeJoint(uint id, const HingeJointInfo& jointInfo) mIsLowerLimitViolated(false), mIsUpperLimitViolated(false), mMotorSpeed(jointInfo.motorSpeed), mMaxMotorTorque(jointInfo.maxMotorTorque) { - assert(mLowerLimit <= 0 && mLowerLimit >= -2.0 * PI); - assert(mUpperLimit >= 0 && mUpperLimit <= 2.0 * PI); + assert(mLowerLimit <= decimal(0) && mLowerLimit >= decimal(-2.0) * PI); + assert(mUpperLimit >= decimal(0) && mUpperLimit <= decimal(2.0) * PI); // Compute the local-space anchor point for each body Transform transform1 = mBody1->getTransform(); diff --git a/src/constraint/HingeJoint.h b/src/constraint/HingeJoint.h index fbcfeacf..435064d2 100644 --- a/src/constraint/HingeJoint.h +++ b/src/constraint/HingeJoint.h @@ -336,6 +336,9 @@ class HingeJoint : public Joint { /// Return the intensity of the current torque applied for the joint motor decimal getMotorTorque(decimal timeStep) const; + + /// Return a string representation + virtual std::string to_string() const override; }; // Return true if the limits of the joint are enabled @@ -400,6 +403,17 @@ inline size_t HingeJoint::getSizeInBytes() const { return sizeof(HingeJoint); } +// Return a string representation +inline std::string HingeJoint::to_string() const { + return "HingeJoint{ lowerLimit=" + std::to_string(mLowerLimit) + ", upperLimit=" + std::to_string(mUpperLimit) + + "localAnchorPointBody1=" + mLocalAnchorPointBody1.to_string() + ", localAnchorPointBody2=" + + mLocalAnchorPointBody2.to_string() + ", hingeLocalAxisBody1=" + mHingeLocalAxisBody1.to_string() + + ", hingeLocalAxisBody2=" + mHingeLocalAxisBody2.to_string() + ", initOrientationDifferenceInv=" + + mInitOrientationDifferenceInv.to_string() + ", motorSpeed=" + std::to_string(mMotorSpeed) + + ", maxMotorTorque=" + std::to_string(mMaxMotorTorque) + ", isLimitEnabled=" + + (mIsLimitEnabled ? "true" : "false") + ", isMotorEnabled=" + (mIsMotorEnabled ? "true" : "false") + "}"; +} + } diff --git a/src/constraint/Joint.h b/src/constraint/Joint.h index 10d1680e..92c413da 100644 --- a/src/constraint/Joint.h +++ b/src/constraint/Joint.h @@ -204,6 +204,9 @@ class Joint { /// Return the id of the joint uint getId() const; + /// Return a string representation + virtual std::string to_string() const=0; + // -------------------- Friendship -------------------- // friend class DynamicsWorld; diff --git a/src/constraint/SliderJoint.cpp b/src/constraint/SliderJoint.cpp index 174ddb67..839cc4dc 100644 --- a/src/constraint/SliderJoint.cpp +++ b/src/constraint/SliderJoint.cpp @@ -41,9 +41,9 @@ SliderJoint::SliderJoint(uint id, const SliderJointInfo& jointInfo) mIsUpperLimitViolated(false), mMotorSpeed(jointInfo.motorSpeed), mMaxMotorForce(jointInfo.maxMotorForce){ - assert(mUpperLimit >= 0.0); - assert(mLowerLimit <= 0.0); - assert(mMaxMotorForce >= 0.0); + assert(mUpperLimit >= decimal(0.0)); + assert(mLowerLimit <= decimal(0.0)); + assert(mMaxMotorForce >= decimal(0.0)); // Compute the local-space anchor point for each body const Transform& transform1 = mBody1->getTransform(); diff --git a/src/constraint/SliderJoint.h b/src/constraint/SliderJoint.h index 3fd0035e..e6ae05dd 100644 --- a/src/constraint/SliderJoint.h +++ b/src/constraint/SliderJoint.h @@ -337,6 +337,9 @@ class SliderJoint : public Joint { /// Return the intensity of the current force applied for the joint motor decimal getMotorForce(decimal timeStep) const; + + /// Return a string representation + virtual std::string to_string() const override; }; // Return true if the limits or the joint are enabled @@ -401,6 +404,17 @@ inline size_t SliderJoint::getSizeInBytes() const { return sizeof(SliderJoint); } +// Return a string representation +inline std::string SliderJoint::to_string() const { + return "SliderJoint{ lowerLimit=" + std::to_string(mLowerLimit) + ", upperLimit=" + std::to_string(mUpperLimit) + + "localAnchorPointBody1=" + mLocalAnchorPointBody1.to_string() + ", localAnchorPointBody2=" + + mLocalAnchorPointBody2.to_string() + ", sliderAxisBody1=" + mSliderAxisBody1.to_string() + + ", initOrientationDifferenceInv=" + + mInitOrientationDifferenceInv.to_string() + ", motorSpeed=" + std::to_string(mMotorSpeed) + + ", maxMotorForce=" + std::to_string(mMaxMotorForce) + ", isLimitEnabled=" + + (mIsLimitEnabled ? "true" : "false") + ", isMotorEnabled=" + (mIsMotorEnabled ? "true" : "false") + "}"; +} + } #endif diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index 8fb71e08..8f06ca74 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -548,11 +548,13 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) { // Add the joint into the world mJoints.add(newJoint); - // Add the joint into the joint list of the bodies involved in the joint - addJointToBody(newJoint); - RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Joint, "Joint " + std::to_string(newJoint->getId()) + ": New joint created"); + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Joint, + "Joint " + std::to_string(newJoint->getId()) + ": " + newJoint->to_string()); + + // Add the joint into the joint list of the bodies involved in the joint + addJointToBody(newJoint); // Return the pointer to the created joint return newJoint; @@ -614,12 +616,20 @@ void DynamicsWorld::addJointToBody(Joint* joint) { joint->mBody1->mJointsList); joint->mBody1->mJointsList = jointListElement1; + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(joint->mBody1->getId()) + ": Joint " + std::to_string(joint->getId()) + + " added to body"); + // Add the joint at the beginning of the linked list of joints of the second body void* allocatedMemory2 = mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(JointListElement)); JointListElement* jointListElement2 = new (allocatedMemory2) JointListElement(joint, joint->mBody2->mJointsList); joint->mBody2->mJointsList = jointListElement2; + + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + "Body " + std::to_string(joint->mBody2->getId()) + ": Joint " + std::to_string(joint->getId()) + + " added to body"); } // Return the next available joint Id diff --git a/src/utils/Logger.cpp b/src/utils/Logger.cpp index 9410cc29..2b213020 100644 --- a/src/utils/Logger.cpp +++ b/src/utils/Logger.cpp @@ -96,11 +96,15 @@ void Logger::log(Level level, Category category, const std::string& message) { auto now = std::chrono::system_clock::now(); auto time = std::chrono::system_clock::to_time_t(now); + mMutex.lock(); + // For each destination for (auto it = mDestinations.begin(); it != mDestinations.end(); ++it) { (*it)->write(time, message, level, category); } + + mMutex.unlock(); } #endif diff --git a/src/utils/Logger.h b/src/utils/Logger.h index 8ce51fb3..879909c7 100644 --- a/src/utils/Logger.h +++ b/src/utils/Logger.h @@ -35,6 +35,7 @@ #include #include #include +#include /// ReactPhysics3D namespace namespace reactphysics3d { @@ -140,7 +141,21 @@ class Logger { /// Format a log message virtual std::string format(const time_t& time, const std::string& message, Level level, Category category) override { - return message; + std::stringstream ss; + + // Time + ss << std::put_time(std::localtime(&time), "%X") << " "; + + // Level + ss << getLevelName(level) << " "; + + // Category + ss << getCategoryName(category) << " "; + + // Message + ss << message << std::endl; + + return ss.str(); } }; @@ -186,7 +201,7 @@ class Logger { std::string generateCSS() const { return "body {" - " background-color: #f7f7f9;" + " background-color: #e6e6e6;" " font-family: SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace; " "} " "body > div { clear:both; } " @@ -222,16 +237,16 @@ class Logger { "max-width: 800px; " "} " ".body > .category, .body > .message { " - "color: #8bc34a;" + "color: #00994d;" "} " ".world > .category, .world > .message { " - "color: #4f9fcf; " + "color: #3477DB; " "} " ".joint .category, .joint > .message { " - "color: #aa00ff; " + "color: #bf8040; " "} " ".proxyshape .category, .proxyshape > .message { " - "color: #009933; " + "color: #9933ff; " "} " ".warning { " "color: #ff9900 !important; " @@ -392,8 +407,7 @@ class Logger { /// Write a message into the output stream virtual void write(const time_t& time, const std::string& message, Level level, Category category) override { - mOutputStream << std::put_time(std::localtime(&time), "%Y-%m-%d %X") << ": "; - mOutputStream << message << std::endl << std::flush; + mOutputStream << formatter->format(time, message, level, category) << std::endl << std::flush; } }; @@ -408,6 +422,9 @@ class Logger { /// Map a log format to the given formatter object Map mFormatters; + /// Mutex + std::mutex mMutex; + // -------------------- Methods -------------------- // /// Return the corresponding formatter