From c1295f1d7aa71f092dce03a5be2207d6f67bbe1f Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Thu, 19 Oct 2017 07:26:11 +0200 Subject: [PATCH] Remove contactNormaldId attribute and fix typo --- src/collision/ContactManifold.cpp | 2 +- src/collision/ContactManifold.h | 8 ---- src/collision/ContactManifoldInfo.cpp | 11 ++---- src/collision/ContactManifoldInfo.h | 13 +----- src/collision/ContactManifoldSet.cpp | 57 +++++++-------------------- src/collision/ContactManifoldSet.h | 9 +---- src/configuration.h | 9 ++++- src/engine/DynamicsWorld.cpp | 2 +- src/engine/OverlappingPair.cpp | 13 +++--- 9 files changed, 38 insertions(+), 86 deletions(-) diff --git a/src/collision/ContactManifold.cpp b/src/collision/ContactManifold.cpp index 55ce8ba3..c2d60422 100644 --- a/src/collision/ContactManifold.cpp +++ b/src/collision/ContactManifold.cpp @@ -31,7 +31,7 @@ using namespace reactphysics3d; // Constructor ContactManifold::ContactManifold(const ContactManifoldInfo* manifoldInfo, ProxyShape* shape1, ProxyShape* shape2, Allocator& memoryAllocator) - : mShape1(shape1), mShape2(shape2), mContactPoints(nullptr), mContactNormalId(manifoldInfo->getContactNormalId()), + : mShape1(shape1), mShape2(shape2), mContactPoints(nullptr), mNbContactPoints(0), mFrictionImpulse1(0.0), mFrictionImpulse2(0.0), mFrictionTwistImpulse(0.0), mIsAlreadyInIsland(false), mMemoryAllocator(memoryAllocator), mNext(nullptr), mPrevious(nullptr), mIsObsolete(false) { diff --git a/src/collision/ContactManifold.h b/src/collision/ContactManifold.h index b5c25cb9..80a9f456 100644 --- a/src/collision/ContactManifold.h +++ b/src/collision/ContactManifold.h @@ -104,9 +104,6 @@ class ContactManifold { /// Contact points in the manifold ContactPoint* mContactPoints; - /// Normal direction Id (Unique Id representing the normal direction) - short int mContactNormalId; - /// Number of contacts in the cache int8 mNbContactPoints; @@ -412,11 +409,6 @@ inline void ContactManifold::setIsObsolete(bool isObsolete, bool setContactPoint } } -// Return the contact normal direction Id of the manifold -inline short ContactManifold::getContactNormalId() const { - return mContactNormalId; -} - } #endif diff --git a/src/collision/ContactManifoldInfo.cpp b/src/collision/ContactManifoldInfo.cpp index a6b8c6df..f22593ac 100644 --- a/src/collision/ContactManifoldInfo.cpp +++ b/src/collision/ContactManifoldInfo.cpp @@ -30,8 +30,9 @@ using namespace reactphysics3d; // Constructor ContactManifoldInfo::ContactManifoldInfo(Allocator& allocator) - : mContactPointsList(nullptr), mNbContactPoints(0), mNext(nullptr), mAllocator(allocator), - mContactNormalId(-1) {} + : mContactPointsList(nullptr), mNbContactPoints(0), mNext(nullptr), mAllocator(allocator) { + +} // Destructor ContactManifoldInfo::~ContactManifoldInfo() { @@ -41,13 +42,9 @@ ContactManifoldInfo::~ContactManifoldInfo() { } // Add a new contact point into the manifold -void ContactManifoldInfo::addContactPoint(ContactPointInfo* contactPointInfo, short contactNormalId) { +void ContactManifoldInfo::addContactPoint(ContactPointInfo* contactPointInfo) { assert(contactPointInfo->penetrationDepth > decimal(0.0)); - assert(contactNormalId >= 0); - assert(mContactNormalId == -1 || contactNormalId == mContactNormalId); - - mContactNormalId = contactNormalId; // Add it into the linked list of contact points contactPointInfo->next = mContactPointsList; diff --git a/src/collision/ContactManifoldInfo.h b/src/collision/ContactManifoldInfo.h index 5851c375..4126f4c8 100644 --- a/src/collision/ContactManifoldInfo.h +++ b/src/collision/ContactManifoldInfo.h @@ -59,9 +59,6 @@ class ContactManifoldInfo { /// Reference the the memory allocator where the contact point infos have been allocated Allocator& mAllocator; - /// Contact normal direction Id (Identify the contact normal direction of points in manifold) - short mContactNormalId; - public: // -------------------- Methods -------------------- // @@ -79,7 +76,7 @@ class ContactManifoldInfo { ContactManifoldInfo& operator=(const ContactManifoldInfo& contactManifold) = delete; /// Add a new contact point into the manifold - void addContactPoint(ContactPointInfo* contactPointInfo, short contactNormalId); + void addContactPoint(ContactPointInfo* contactPointInfo); /// Remove all the contact points void reset(); @@ -93,9 +90,6 @@ class ContactManifoldInfo { /// Return the pointer to the next manifold info in the linked-list ContactManifoldInfo* getNext(); - /// Return the contact normal Id - short getContactNormalId() const; - /// Reduce the number of contact points of the currently computed manifold void reduce(const Transform& shape1ToWorldTransform); @@ -114,11 +108,6 @@ inline ContactManifoldInfo* ContactManifoldInfo::getNext() { return mNext; } -// Return the contact normal Id -inline short ContactManifoldInfo::getContactNormalId() const { - return mContactNormalId; -} - } #endif diff --git a/src/collision/ContactManifoldSet.cpp b/src/collision/ContactManifoldSet.cpp index 9b8bf58b..ce3e4492 100644 --- a/src/collision/ContactManifoldSet.cpp +++ b/src/collision/ContactManifoldSet.cpp @@ -50,7 +50,7 @@ void ContactManifoldSet::addContactManifold(const ContactManifoldInfo* contactMa assert(contactManifoldInfo->getFirstContactPointInfo() != nullptr); // Try to find an existing contact manifold with similar contact normal - ContactManifold* similarManifold = selectManifoldWithSimilarNormal(contactManifoldInfo->getContactNormalId()); + ContactManifold* similarManifold = selectManifoldWithSimilarNormal(contactManifoldInfo); // If a similar manifold has been found if (similarManifold != nullptr) { @@ -139,15 +139,25 @@ void ContactManifoldSet::removeNonOptimalManifold() { removeManifold(minDepthManifold); } -// Return the contact manifold with a similar average normal. -// If no manifold has close enough average normal, it returns nullptr -ContactManifold* ContactManifoldSet::selectManifoldWithSimilarNormal(short int normalDirectionId) const { +// Return the contact manifold with a similar contact normal. +// If no manifold has close enough contact normal, it returns nullptr +ContactManifold* ContactManifoldSet::selectManifoldWithSimilarNormal(const ContactManifoldInfo* contactManifold) const { + + // Get the contact normal of the first point of the manifold + const ContactPointInfo* contactPoint = contactManifold->getFirstContactPointInfo(); + assert(contactPoint != nullptr); ContactManifold* manifold = mManifolds; // Return the Id of the manifold with the same normal direction id (if exists) while (manifold != nullptr) { - if (normalDirectionId == manifold->getContactNormalId()) { + + // Get the first contact point of the current manifold + const ContactPoint* point = manifold->getContactPoints(); + assert(point != nullptr); + + // If the contact normal of the two manifolds are close enough + if (contactPoint->normal.dot(point->getNormal()) >= COS_ANGLE_SIMILAR_CONTACT_MANIFOLD) { return manifold; } @@ -157,43 +167,6 @@ ContactManifold* ContactManifoldSet::selectManifoldWithSimilarNormal(short int n return nullptr; } -// Map the normal vector into a cubemap face bucket (a face contains 4x4 buckets) -// Each face of the cube is divided into 4x4 buckets. This method maps the -// normal vector into of the of the bucket and returns a unique Id for the bucket -short int ContactManifoldSet::computeCubemapNormalId(const Vector3& normal) { - - assert(normal.lengthSquare() > MACHINE_EPSILON); - - int faceNo; - decimal u, v; - decimal max = max3(std::fabs(normal.x), std::fabs(normal.y), std::fabs(normal.z)); - Vector3 normalScaled = normal / max; - - if (normalScaled.x >= normalScaled.y && normalScaled.x >= normalScaled.z) { - faceNo = normalScaled.x > 0 ? 0 : 1; - u = normalScaled.y; - v = normalScaled.z; - } - else if (normalScaled.y >= normalScaled.x && normalScaled.y >= normalScaled.z) { - faceNo = normalScaled.y > 0 ? 2 : 3; - u = normalScaled.x; - v = normalScaled.z; - } - else { - faceNo = normalScaled.z > 0 ? 4 : 5; - u = normalScaled.x; - v = normalScaled.y; - } - - int indexU = std::floor(((u + 1)/2) * CONTACT_CUBEMAP_FACE_NB_SUBDIVISIONS); - int indexV = std::floor(((v + 1)/2) * CONTACT_CUBEMAP_FACE_NB_SUBDIVISIONS); - if (indexU == CONTACT_CUBEMAP_FACE_NB_SUBDIVISIONS) indexU--; - if (indexV == CONTACT_CUBEMAP_FACE_NB_SUBDIVISIONS) indexV--; - - const int nbSubDivInFace = CONTACT_CUBEMAP_FACE_NB_SUBDIVISIONS * CONTACT_CUBEMAP_FACE_NB_SUBDIVISIONS; - return faceNo * 200 + indexU * nbSubDivInFace + indexV; -} - // Clear the contact manifold set void ContactManifoldSet::clear() { diff --git a/src/collision/ContactManifoldSet.h b/src/collision/ContactManifoldSet.h index 4b33eb8c..13d27b70 100644 --- a/src/collision/ContactManifoldSet.h +++ b/src/collision/ContactManifoldSet.h @@ -71,8 +71,8 @@ class ContactManifoldSet { /// Create a new contact manifold and add it to the set void createManifold(const ContactManifoldInfo* manifoldInfo); - // Return the contact manifold with a similar average normal. - ContactManifold* selectManifoldWithSimilarNormal(short int normalDirectionId) const; + // Return the contact manifold with a similar contact normal. + ContactManifold* selectManifoldWithSimilarNormal(const ContactManifoldInfo* contactManifold) const; /// Remove a contact manifold that is the least optimal (smaller penetration depth) void removeNonOptimalManifold(); @@ -126,11 +126,6 @@ class ContactManifoldSet { // Remove some contact manifolds and contact points if there are too many of them void reduce(); - - // Map the normal vector into a cubemap face bucket (a face contains 4x4 buckets) - // Each face of the cube is divided into 4x4 buckets. This method maps the - // normal vector into of the of the bucket and returns a unique Id for the bucket - static short int computeCubemapNormalId(const Vector3& normal); }; // Return the first proxy shape diff --git a/src/configuration.h b/src/configuration.h index 444bd1db..779b45e2 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -99,8 +99,8 @@ constexpr decimal DEFAULT_BOUNCINESS = decimal(0.5); /// Default rolling resistance constexpr decimal DEFAULT_ROLLING_RESISTANCE = decimal(0.0); -/// True if the spleeping technique is enabled -constexpr bool SPLEEPING_ENABLED = true; +/// True if the sleeping technique is enabled +constexpr bool SLEEPING_ENABLED = true; /// Distance threshold for two contact points for a valid persistent contact (in meters) constexpr decimal PERSISTENT_CONTACT_DIST_THRESHOLD = decimal(0.03); @@ -143,6 +143,11 @@ constexpr int NB_MAX_CONTACT_MANIFOLDS_CONVEX_SHAPE = 1; /// least one concave collision shape. constexpr int NB_MAX_CONTACT_MANIFOLDS_CONCAVE_SHAPE = 3; +/// This is used to test if two contact manifold are similar (same contact normal) in order to +/// 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. +constexpr decimal COS_ANGLE_SIMILAR_CONTACT_MANIFOLD = decimal(0.95); + /// Size (in bytes) of the single frame allocator constexpr size_t SIZE_SINGLE_FRAME_ALLOCATOR_BYTES = 15728640; // 15 Mb diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index 136d34f6..09712c3c 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -44,7 +44,7 @@ DynamicsWorld::DynamicsWorld(const Vector3 &gravity) mConstraintSolver(mMapBodyToConstrainedVelocityIndex), mNbVelocitySolverIterations(DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS), mNbPositionSolverIterations(DEFAULT_POSITION_SOLVER_NB_ITERATIONS), - mIsSleepingEnabled(SPLEEPING_ENABLED), mGravity(gravity), + mIsSleepingEnabled(SLEEPING_ENABLED), mGravity(gravity), mIsGravityEnabled(true), mConstrainedLinearVelocities(nullptr), mConstrainedAngularVelocities(nullptr), mSplitLinearVelocities(nullptr), mSplitAngularVelocities(nullptr), mConstrainedPositions(nullptr), diff --git a/src/engine/OverlappingPair.cpp b/src/engine/OverlappingPair.cpp index f3f85fa1..0055e683 100644 --- a/src/engine/OverlappingPair.cpp +++ b/src/engine/OverlappingPair.cpp @@ -54,21 +54,22 @@ void OverlappingPair::addPotentialContactPoints(NarrowPhaseInfo* narrowPhaseInfo ContactPointInfo* nextContactPoint = contactPoint->next; - // Compute the contact normal id - short contactNormalId = ContactManifoldSet::computeCubemapNormalId(contactPoint->normal); - // Look if the contact point correspond to an existing potential manifold // (if the contact point normal is similar to the normal of an existing manifold) ContactManifoldInfo* manifold = mPotentialContactManifolds; bool similarManifoldFound = false; while(manifold != nullptr) { + // Get the first contact point + const ContactPointInfo* point = manifold->getFirstContactPointInfo(); + assert(point != nullptr); + // If we have found a corresponding manifold for the new contact point // (a manifold with a similar contact normal direction) - if (manifold->getContactNormalId() == contactNormalId) { + if (point->normal.dot(contactPoint->normal) >= COS_ANGLE_SIMILAR_CONTACT_MANIFOLD) { // Add the contact point to the manifold - manifold->addContactPoint(contactPoint, contactNormalId); + manifold->addContactPoint(contactPoint); similarManifoldFound = true; @@ -90,7 +91,7 @@ void OverlappingPair::addPotentialContactPoints(NarrowPhaseInfo* narrowPhaseInfo mPotentialContactManifolds = manifoldInfo; // Add the contact point to the manifold - manifoldInfo->addContactPoint(contactPoint, contactNormalId); + manifoldInfo->addContactPoint(contactPoint); } contactPoint = nextContactPoint;