diff --git a/CHANGELOG.md b/CHANGELOG.md index f9c714d0..effb8541 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Version 0.8.0 +Note that this release contains some public API changes. Please read carefully the following changes before upgrading to this new version and +do not hesitate to take a look at the user manual. + ### Added - It is now possible to change the size of a BoxShape using the BoxShape::setHalfExtents() method diff --git a/include/reactphysics3d/collision/shapes/CapsuleShape.h b/include/reactphysics3d/collision/shapes/CapsuleShape.h index 0aaf3b99..ab1b276e 100644 --- a/include/reactphysics3d/collision/shapes/CapsuleShape.h +++ b/include/reactphysics3d/collision/shapes/CapsuleShape.h @@ -137,7 +137,7 @@ inline decimal CapsuleShape::getRadius() const { * @param radius The radius of the capsule (in meters) */ inline void CapsuleShape::setRadius(decimal radius) { - // TODO : Throw a library error here if radius is not larger than zero + assert(radius > decimal(0.0)); mMargin = radius; @@ -160,7 +160,6 @@ inline decimal CapsuleShape::getHeight() const { */ inline void CapsuleShape::setHeight(decimal height) { - // TODO : Throw a library error here if radius is not larger than zero assert(height > decimal(0.0)); mHalfHeight = height * decimal(0.5); diff --git a/include/reactphysics3d/configuration.h b/include/reactphysics3d/configuration.h index f90c2b11..54c5666c 100644 --- a/include/reactphysics3d/configuration.h +++ b/include/reactphysics3d/configuration.h @@ -63,7 +63,6 @@ using uint32 = std::uint32_t; using int64 = std::int64_t; using uint64 = std::uint64_t; -// TODO : Delete this struct Entity; using bodypair = Pair; diff --git a/include/reactphysics3d/engine/PhysicsWorld.h b/include/reactphysics3d/engine/PhysicsWorld.h index 301d6554..15615149 100644 --- a/include/reactphysics3d/engine/PhysicsWorld.h +++ b/include/reactphysics3d/engine/PhysicsWorld.h @@ -710,34 +710,6 @@ inline uint PhysicsWorld::getNbCollisionBodies() const { return mCollisionBodies.size(); } -// Return a constant pointer to a given CollisionBody of the world -/** - * @param index Index of a CollisionBody in the world - * @return Constant pointer to a given CollisionBody - */ -inline const CollisionBody* PhysicsWorld::getCollisionBody(uint index) const { - - assert(index < mCollisionBodies.size()); - - // TODO : Report error here if index is not within bounds - - return mCollisionBodies[index]; -} - -// Return a pointer to a given CollisionBody of the world -/** - * @param index Index of a CollisionBody in the world - * @return Pointer to a given CollisionBody - */ -inline CollisionBody* PhysicsWorld::getCollisionBody(uint index) { - - assert(index < mCollisionBodies.size()); - - // TODO : Report error here if index is not within bounds - - return mCollisionBodies[index]; -} - // Return the number of RigidBody in the physics world /** * @return The number of rigid bodies in the physics world @@ -746,34 +718,6 @@ inline uint PhysicsWorld::getNbRigidBodies() const { return mRigidBodies.size(); } - -// Return a constant pointer to a given RigidBody of the world -/** - * @param index Index of a RigidBody in the world - * @return Constant pointer to a given RigidBody - */ -inline const RigidBody* PhysicsWorld::getRigidBody(uint index) const { - assert(index < mRigidBodies.size()); - - // TODO : Report error here if index is not within bounds - - return mRigidBodies[index]; -} - -// Return a pointer to a given RigidBody of the world -/** - * @param index Index of a RigidBody in the world - * @return Pointer to a given RigidBody - */ -inline RigidBody* PhysicsWorld::getRigidBody(uint index) { - - assert(index < mRigidBodies.size()); - - // TODO : Report error here if index is not within bounds - - return mRigidBodies[index]; -} - // Return true if the debug rendering is enabled /** * @return True if the debug rendering is enabled and false otherwise diff --git a/include/reactphysics3d/systems/CollisionDetectionSystem.h b/include/reactphysics3d/systems/CollisionDetectionSystem.h index 677b6733..8c4fae6f 100644 --- a/include/reactphysics3d/systems/CollisionDetectionSystem.h +++ b/include/reactphysics3d/systems/CollisionDetectionSystem.h @@ -319,7 +319,7 @@ class CollisionDetectionSystem { void removeNoCollisionPair(Entity body1Entity, Entity body2Entity); /// Ask for a collision shape to be tested again during broad-phase. - void askForBroadPhaseCollisionCheck(Collider* shape); + void askForBroadPhaseCollisionCheck(Collider* collider); /// Notify that the overlapping pairs where a given collider is involved need to be tested for overlap void notifyOverlappingPairsToTestOverlap(Collider* collider); @@ -411,10 +411,10 @@ inline void CollisionDetectionSystem::removeNoCollisionPair(Entity body1Entity, // Ask for a collision shape to be tested again during broad-phase. /// We simply put the shape in the list of collision shape that have moved in the /// previous frame so that it is tested for collision again in the broad-phase. -inline void CollisionDetectionSystem::askForBroadPhaseCollisionCheck(Collider* shape) { +inline void CollisionDetectionSystem::askForBroadPhaseCollisionCheck(Collider* collider) { - if (shape->getBroadPhaseId() != -1) { - mBroadPhaseSystem.addMovedCollider(shape->getBroadPhaseId(), shape); + if (collider->getBroadPhaseId() != -1) { + mBroadPhaseSystem.addMovedCollider(collider->getBroadPhaseId(), collider); } } diff --git a/include/reactphysics3d/systems/ContactSolverSystem.h b/include/reactphysics3d/systems/ContactSolverSystem.h index 6afc3d5f..ddb0f200 100644 --- a/include/reactphysics3d/systems/ContactSolverSystem.h +++ b/include/reactphysics3d/systems/ContactSolverSystem.h @@ -296,11 +296,9 @@ class ContactSolverSystem { decimal& mRestitutionVelocityThreshold; /// Contact constraints - // TODO : Use List<> here ContactManifoldSolver* mContactConstraints; /// Contact points - // TODO : Use List<> here ContactPointSolver* mContactPoints; /// Number of contact point constraints diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index 34c88fd7..831d023d 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -531,7 +531,11 @@ void RigidBody::setMass(decimal mass) { mWorld.mRigidBodyComponents.setMass(mEntity, mass); - // TODO : Report error if mass is negative + if (mass < decimal(0.0)) { + + RP3D_LOG(mWorld.mConfig.worldName, Logger::Level::Error, Logger::Category::Body, + "Error when setting the mass of a rigid body: the mass must be a positive value", __FILE__, __LINE__); + } if (mWorld.mRigidBodyComponents.getMass(mEntity) > decimal(0.0)) { mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / mass); diff --git a/src/collision/Collider.cpp b/src/collision/Collider.cpp index 0b9109ab..07a41cb4 100644 --- a/src/collision/Collider.cpp +++ b/src/collision/Collider.cpp @@ -71,14 +71,13 @@ bool Collider::testPointInside(const Vector3& worldPoint) { */ void Collider::setCollisionCategoryBits(unsigned short collisionCategoryBits) { - // TODO : Here we should probably remove all overlapping pairs with this shape in the - // broad-phase and add the shape in the "has moved" shape list so it is reevaluated - // with the new mask bits - mBody->mWorld.mCollidersComponents.setCollisionCategoryBits(mEntity, collisionCategoryBits); int broadPhaseId = mBody->mWorld.mCollidersComponents.getBroadPhaseId(mEntity); + // Ask the broad-phase collision detection to test this collider next frame + mBody->mWorld.mCollisionDetection.askForBroadPhaseCollisionCheck(this); + RP3D_LOG(mBody->mWorld.mConfig.worldName, Logger::Level::Information, Logger::Category::Collider, "Collider " + std::to_string(broadPhaseId) + ": Set collisionCategoryBits=" + std::to_string(collisionCategoryBits), __FILE__, __LINE__); @@ -90,14 +89,13 @@ void Collider::setCollisionCategoryBits(unsigned short collisionCategoryBits) { */ void Collider::setCollideWithMaskBits(unsigned short collideWithMaskBits) { - // TODO : Here we should probably remove all overlapping pairs with this shape in the - // broad-phase and add the shape in the "has moved" shape list so it is reevaluated - // with the new mask bits - mBody->mWorld.mCollidersComponents.setCollideWithMaskBits(mEntity, collideWithMaskBits); int broadPhaseId = mBody->mWorld.mCollidersComponents.getBroadPhaseId(mEntity); + // Ask the broad-phase collision detection to test this collider next frame + mBody->mWorld.mCollisionDetection.askForBroadPhaseCollisionCheck(this); + RP3D_LOG(mBody->mWorld.mConfig.worldName, Logger::Level::Information, Logger::Category::Collider, "Collider" + std::to_string(broadPhaseId) + ": Set collideWithMaskBits=" + std::to_string(collideWithMaskBits), __FILE__, __LINE__); diff --git a/src/collision/TriangleVertexArray.cpp b/src/collision/TriangleVertexArray.cpp index f86febc1..de841127 100644 --- a/src/collision/TriangleVertexArray.cpp +++ b/src/collision/TriangleVertexArray.cpp @@ -196,7 +196,7 @@ void TriangleVertexArray::computeVerticesNormals() { */ void TriangleVertexArray::getTriangleVerticesIndices(uint triangleIndex, uint* outVerticesIndices) const { - assert(triangleIndex >= 0 && triangleIndex < mNbTriangles); + assert(triangleIndex < mNbTriangles); const uchar* triangleIndicesPointer = mIndicesStart + triangleIndex * mIndicesStride; const void* startTriangleIndices = static_cast(triangleIndicesPointer); @@ -224,7 +224,7 @@ void TriangleVertexArray::getTriangleVerticesIndices(uint triangleIndex, uint* o */ void TriangleVertexArray::getTriangleVertices(uint triangleIndex, Vector3* outTriangleVertices) const { - assert(triangleIndex >= 0 && triangleIndex < mNbTriangles); + assert(triangleIndex < mNbTriangles); // Get the three vertex index of the three vertices of the triangle uint verticesIndices[3]; @@ -262,7 +262,7 @@ void TriangleVertexArray::getTriangleVertices(uint triangleIndex, Vector3* outTr */ void TriangleVertexArray::getTriangleVerticesNormals(uint triangleIndex, Vector3* outTriangleVerticesNormals) const { - assert(triangleIndex >= 0 && triangleIndex < mNbTriangles); + assert(triangleIndex < mNbTriangles); // Get the three vertex index of the three vertices of the triangle uint verticesIndices[3]; diff --git a/src/collision/narrowphase/SAT/SATAlgorithm.cpp b/src/collision/narrowphase/SAT/SATAlgorithm.cpp index 6c11b444..d47468a0 100644 --- a/src/collision/narrowphase/SAT/SATAlgorithm.cpp +++ b/src/collision/narrowphase/SAT/SATAlgorithm.cpp @@ -823,7 +823,6 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn // Now, we will clip the shapes along this axis to find the contact points assert(minPenetrationDepth > decimal(0.0)); - assert((isMinPenetrationFaceNormal && minFaceIndex >= 0) || !isMinPenetrationFaceNormal); // If the minimum separating axis is a face normal if (isMinPenetrationFaceNormal) { diff --git a/src/collision/shapes/CapsuleShape.cpp b/src/collision/shapes/CapsuleShape.cpp index c1004c9b..b9ba70c5 100644 --- a/src/collision/shapes/CapsuleShape.cpp +++ b/src/collision/shapes/CapsuleShape.cpp @@ -39,7 +39,7 @@ using namespace reactphysics3d; */ CapsuleShape::CapsuleShape(decimal radius, decimal height, MemoryAllocator& allocator) : ConvexShape(CollisionShapeName::CAPSULE, CollisionShapeType::CAPSULE, allocator, radius), mHalfHeight(height * decimal(0.5)) { - // TODO : Throw a library error here if radius or height is not larger than zero + assert(radius > decimal(0.0)); assert(height > decimal(0.0)); } diff --git a/src/engine/PhysicsCommon.cpp b/src/engine/PhysicsCommon.cpp index 4c72d42c..a0b848b0 100644 --- a/src/engine/PhysicsCommon.cpp +++ b/src/engine/PhysicsCommon.cpp @@ -167,6 +167,12 @@ void PhysicsCommon::destroyPhysicsWorld(PhysicsWorld* world) { */ SphereShape* PhysicsCommon::createSphereShape(const decimal radius) { + if (radius <= decimal(0.0)) { + + RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::PhysicCommon, + "Error when creating a SphereShape: radius must be a positive value", __FILE__, __LINE__); + } + SphereShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(SphereShape))) SphereShape(radius, mMemoryManager.getHeapAllocator()); mSphereShapes.add(shape); @@ -182,7 +188,7 @@ void PhysicsCommon::destroySphereShape(SphereShape* sphereShape) { // If the shape is still part of some colliders if (sphereShape->mColliders.size() > 0) { - RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::World, + RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::PhysicCommon, "Error when destroying the SphereShape because it is still used by some colliders", __FILE__, __LINE__); } @@ -202,6 +208,11 @@ void PhysicsCommon::destroySphereShape(SphereShape* sphereShape) { */ BoxShape* PhysicsCommon::createBoxShape(const Vector3& halfExtents) { + if (halfExtents.x <= decimal(0.0) || halfExtents.y <= decimal(0.0) || halfExtents.z <= decimal(0.0)) { + + RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::PhysicCommon, + "Error when creating a BoxShape: the half extents must be positive values", __FILE__, __LINE__); + } BoxShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(BoxShape))) BoxShape(halfExtents, mMemoryManager.getHeapAllocator()); mBoxShapes.add(shape); @@ -218,7 +229,7 @@ void PhysicsCommon::destroyBoxShape(BoxShape* boxShape) { // If the shape is still part of some colliders if (boxShape->mColliders.size() > 0) { - RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::World, + RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::PhysicCommon, "Error when destroying the BoxShape because it is still used by some colliders", __FILE__, __LINE__); } @@ -239,6 +250,18 @@ void PhysicsCommon::destroyBoxShape(BoxShape* boxShape) { */ CapsuleShape* PhysicsCommon::createCapsuleShape(decimal radius, decimal height) { + if (radius <= decimal(0.0)) { + + RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::PhysicCommon, + "Error when creating a CapsuleShape: radius must be a positive value", __FILE__, __LINE__); + } + + if (height <= decimal(0.0)) { + + RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::PhysicCommon, + "Error when creating a CapsuleShape: height must be a positive value", __FILE__, __LINE__); + } + CapsuleShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(CapsuleShape))) CapsuleShape(radius, height, mMemoryManager.getHeapAllocator()); mCapsuleShapes.add(shape); @@ -255,7 +278,7 @@ void PhysicsCommon::destroyCapsuleShape(CapsuleShape* capsuleShape) { // If the shape is still part of some colliders if (capsuleShape->mColliders.size() > 0) { - RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::World, + RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::PhysicCommon, "Error when destroying the CapsuleShape because it is still used by some colliders", __FILE__, __LINE__); } @@ -292,7 +315,7 @@ void PhysicsCommon::destroyConvexMeshShape(ConvexMeshShape* convexMeshShape) { // If the shape is still part of some colliders if (convexMeshShape->mColliders.size() > 0) { - RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::World, + RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::PhysicCommon, "Error when destroying the ConvexMeshShape because it is still used by some colliders", __FILE__, __LINE__); } @@ -338,7 +361,7 @@ void PhysicsCommon::destroyHeightFieldShape(HeightFieldShape* heightFieldShape) // If the shape is still part of some colliders if (heightFieldShape->mColliders.size() > 0) { - RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::World, + RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::PhysicCommon, "Error when destroying the HeightFieldShape because it is still used by some colliders", __FILE__, __LINE__); } @@ -375,7 +398,7 @@ void PhysicsCommon::destroyConcaveMeshShape(ConcaveMeshShape* concaveMeshShape) // If the shape is still part of some colliders if (concaveMeshShape->mColliders.size() > 0) { - RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::World, + RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::PhysicCommon, "Error when destroying the ConcaveMeshShape because it is still used by some colliders", __FILE__, __LINE__); } diff --git a/src/engine/PhysicsWorld.cpp b/src/engine/PhysicsWorld.cpp index bc04aaad..d9ac4e61 100644 --- a/src/engine/PhysicsWorld.cpp +++ b/src/engine/PhysicsWorld.cpp @@ -775,7 +775,6 @@ void PhysicsWorld::createIslands() { // Add the body into the island mIslands.bodyEntities[islandIndex].add(bodyToVisitEntity); - // TODO : Do not use pointer to rigid body here (maybe move getType() into a component) RigidBody* rigidBodyToVisit = static_cast(mCollisionBodyComponents.getBody(bodyToVisitEntity)); // Awake the body if it is sleeping @@ -1023,3 +1022,76 @@ void PhysicsWorld::setIsGravityEnabled(bool isGravityEnabled) { RP3D_LOG(mConfig.worldName, Logger::Level::Information, Logger::Category::World, "Physics World: isGravityEnabled= " + (isGravityEnabled ? std::string("true") : std::string("false")), __FILE__, __LINE__); } + +// Return a constant pointer to a given CollisionBody of the world +/** + * @param index Index of a CollisionBody in the world + * @return Constant pointer to a given CollisionBody + */ +const CollisionBody* PhysicsWorld::getCollisionBody(uint index) const { + + if (index >= getNbCollisionBodies()) { + + RP3D_LOG(mConfig.worldName, Logger::Level::Error, Logger::Category::World, + "Error when getting collision body: index is out of bounds", __FILE__, __LINE__); + } + + assert(index < mCollisionBodies.size()); + + return mCollisionBodies[index]; +} + +// Return a pointer to a given CollisionBody of the world +/** + * @param index Index of a CollisionBody in the world + * @return Pointer to a given CollisionBody + */ +CollisionBody* PhysicsWorld::getCollisionBody(uint index) { + + if (index >= getNbCollisionBodies()) { + + RP3D_LOG(mConfig.worldName, Logger::Level::Error, Logger::Category::World, + "Error when getting collision body: index is out of bounds", __FILE__, __LINE__); + } + + assert(index < mCollisionBodies.size()); + + return mCollisionBodies[index]; +} + +// Return a constant pointer to a given RigidBody of the world +/** + * @param index Index of a RigidBody in the world + * @return Constant pointer to a given RigidBody + */ +const RigidBody* PhysicsWorld::getRigidBody(uint index) const { + + if (index >= getNbRigidBodies()) { + + RP3D_LOG(mConfig.worldName, Logger::Level::Error, Logger::Category::World, + "Error when getting rigid body: index is out of bounds", __FILE__, __LINE__); + } + + assert(index < mRigidBodies.size()); + + return mRigidBodies[index]; +} + +// Return a pointer to a given RigidBody of the world +/** + * @param index Index of a RigidBody in the world + * @return Pointer to a given RigidBody + */ +RigidBody* PhysicsWorld::getRigidBody(uint index) { + + if (index >= getNbRigidBodies()) { + + RP3D_LOG(mConfig.worldName, Logger::Level::Error, Logger::Category::World, + "Error when getting rigid body: index is out of bounds", __FILE__, __LINE__); + } + + assert(index < mRigidBodies.size()); + + return mRigidBodies[index]; +} + diff --git a/src/systems/BroadPhaseSystem.cpp b/src/systems/BroadPhaseSystem.cpp index 58b270e0..5d8b1f22 100644 --- a/src/systems/BroadPhaseSystem.cpp +++ b/src/systems/BroadPhaseSystem.cpp @@ -165,12 +165,10 @@ void BroadPhaseSystem::updateCollidersComponents(uint32 startIndex, uint32 nbIte startIndex = std::min(startIndex, mCollidersComponents.getNbEnabledComponents()); uint32 endIndex = std::min(startIndex + nbItems, mCollidersComponents.getNbEnabledComponents()); nbItems = endIndex - startIndex; - assert(nbItems >= 0); // For each collider component to update for (uint32 i = startIndex; i < startIndex + nbItems; i++) { - // TODO : Can we remove this test const int32 broadPhaseId = mCollidersComponents.mBroadPhaseIds[i]; if (broadPhaseId != -1) { diff --git a/src/systems/CollisionDetectionSystem.cpp b/src/systems/CollisionDetectionSystem.cpp index 823ab321..d4fab122 100644 --- a/src/systems/CollisionDetectionSystem.cpp +++ b/src/systems/CollisionDetectionSystem.cpp @@ -1598,8 +1598,6 @@ void CollisionDetectionSystem::filterOverlappingPairs(Entity bodyEntity, List& convexPairs, List& concavePairs) const { - // TODO : Do not go through all the overlapping pairs here but get all the involded overlapping pairs directly from the bodies - // For each possible collision pair of bodies for (uint i=0; i < mOverlappingPairs.getNbPairs(); i++) { diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 34b78155..c30868fa 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -87,10 +87,8 @@ class SceneDemo : public Scene { /// Constant color shader openglframework::Shader mColorShader; - // TODO : Delete this openglframework::Shader mQuadShader; - // TODO : Delete this openglframework::VertexArrayObject mVAOQuad; openglframework::VertexBufferObject mVBOQuad; @@ -134,7 +132,6 @@ class SceneDemo : public Scene { /// Create a the VAO and VBOs to render the debug infos void createDebugVBO(); - /// TODO : Delete this void drawTextureQuad(); /// Update the contact points