Remove contactNormaldId attribute and fix typo

This commit is contained in:
Daniel Chappuis 2017-10-19 07:26:11 +02:00
parent cdec7413c5
commit c1295f1d7a
9 changed files with 38 additions and 86 deletions

View File

@ -31,7 +31,7 @@ using namespace reactphysics3d;
// Constructor // Constructor
ContactManifold::ContactManifold(const ContactManifoldInfo* manifoldInfo, ProxyShape* shape1, ProxyShape* shape2, Allocator& memoryAllocator) 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), mNbContactPoints(0), mFrictionImpulse1(0.0), mFrictionImpulse2(0.0),
mFrictionTwistImpulse(0.0), mIsAlreadyInIsland(false), mFrictionTwistImpulse(0.0), mIsAlreadyInIsland(false),
mMemoryAllocator(memoryAllocator), mNext(nullptr), mPrevious(nullptr), mIsObsolete(false) { mMemoryAllocator(memoryAllocator), mNext(nullptr), mPrevious(nullptr), mIsObsolete(false) {

View File

@ -104,9 +104,6 @@ class ContactManifold {
/// Contact points in the manifold /// Contact points in the manifold
ContactPoint* mContactPoints; ContactPoint* mContactPoints;
/// Normal direction Id (Unique Id representing the normal direction)
short int mContactNormalId;
/// Number of contacts in the cache /// Number of contacts in the cache
int8 mNbContactPoints; 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 #endif

View File

@ -30,8 +30,9 @@ using namespace reactphysics3d;
// Constructor // Constructor
ContactManifoldInfo::ContactManifoldInfo(Allocator& allocator) ContactManifoldInfo::ContactManifoldInfo(Allocator& allocator)
: mContactPointsList(nullptr), mNbContactPoints(0), mNext(nullptr), mAllocator(allocator), : mContactPointsList(nullptr), mNbContactPoints(0), mNext(nullptr), mAllocator(allocator) {
mContactNormalId(-1) {}
}
// Destructor // Destructor
ContactManifoldInfo::~ContactManifoldInfo() { ContactManifoldInfo::~ContactManifoldInfo() {
@ -41,13 +42,9 @@ ContactManifoldInfo::~ContactManifoldInfo() {
} }
// Add a new contact point into the manifold // 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(contactPointInfo->penetrationDepth > decimal(0.0));
assert(contactNormalId >= 0);
assert(mContactNormalId == -1 || contactNormalId == mContactNormalId);
mContactNormalId = contactNormalId;
// Add it into the linked list of contact points // Add it into the linked list of contact points
contactPointInfo->next = mContactPointsList; contactPointInfo->next = mContactPointsList;

View File

@ -59,9 +59,6 @@ class ContactManifoldInfo {
/// Reference the the memory allocator where the contact point infos have been allocated /// Reference the the memory allocator where the contact point infos have been allocated
Allocator& mAllocator; Allocator& mAllocator;
/// Contact normal direction Id (Identify the contact normal direction of points in manifold)
short mContactNormalId;
public: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
@ -79,7 +76,7 @@ class ContactManifoldInfo {
ContactManifoldInfo& operator=(const ContactManifoldInfo& contactManifold) = delete; ContactManifoldInfo& operator=(const ContactManifoldInfo& contactManifold) = delete;
/// Add a new contact point into the manifold /// Add a new contact point into the manifold
void addContactPoint(ContactPointInfo* contactPointInfo, short contactNormalId); void addContactPoint(ContactPointInfo* contactPointInfo);
/// Remove all the contact points /// Remove all the contact points
void reset(); void reset();
@ -93,9 +90,6 @@ class ContactManifoldInfo {
/// Return the pointer to the next manifold info in the linked-list /// Return the pointer to the next manifold info in the linked-list
ContactManifoldInfo* getNext(); ContactManifoldInfo* getNext();
/// Return the contact normal Id
short getContactNormalId() const;
/// Reduce the number of contact points of the currently computed manifold /// Reduce the number of contact points of the currently computed manifold
void reduce(const Transform& shape1ToWorldTransform); void reduce(const Transform& shape1ToWorldTransform);
@ -114,11 +108,6 @@ inline ContactManifoldInfo* ContactManifoldInfo::getNext() {
return mNext; return mNext;
} }
// Return the contact normal Id
inline short ContactManifoldInfo::getContactNormalId() const {
return mContactNormalId;
}
} }
#endif #endif

View File

@ -50,7 +50,7 @@ void ContactManifoldSet::addContactManifold(const ContactManifoldInfo* contactMa
assert(contactManifoldInfo->getFirstContactPointInfo() != nullptr); assert(contactManifoldInfo->getFirstContactPointInfo() != nullptr);
// Try to find an existing contact manifold with similar contact normal // 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 a similar manifold has been found
if (similarManifold != nullptr) { if (similarManifold != nullptr) {
@ -139,15 +139,25 @@ void ContactManifoldSet::removeNonOptimalManifold() {
removeManifold(minDepthManifold); removeManifold(minDepthManifold);
} }
// Return the contact manifold with a similar average normal. // Return the contact manifold with a similar contact normal.
// If no manifold has close enough average normal, it returns nullptr // If no manifold has close enough contact normal, it returns nullptr
ContactManifold* ContactManifoldSet::selectManifoldWithSimilarNormal(short int normalDirectionId) const { 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; ContactManifold* manifold = mManifolds;
// Return the Id of the manifold with the same normal direction id (if exists) // Return the Id of the manifold with the same normal direction id (if exists)
while (manifold != nullptr) { 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; return manifold;
} }
@ -157,43 +167,6 @@ ContactManifold* ContactManifoldSet::selectManifoldWithSimilarNormal(short int n
return nullptr; 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 // Clear the contact manifold set
void ContactManifoldSet::clear() { void ContactManifoldSet::clear() {

View File

@ -71,8 +71,8 @@ class ContactManifoldSet {
/// Create a new contact manifold and add it to the set /// Create a new contact manifold and add it to the set
void createManifold(const ContactManifoldInfo* manifoldInfo); void createManifold(const ContactManifoldInfo* manifoldInfo);
// Return the contact manifold with a similar average normal. // Return the contact manifold with a similar contact normal.
ContactManifold* selectManifoldWithSimilarNormal(short int normalDirectionId) const; ContactManifold* selectManifoldWithSimilarNormal(const ContactManifoldInfo* contactManifold) const;
/// Remove a contact manifold that is the least optimal (smaller penetration depth) /// Remove a contact manifold that is the least optimal (smaller penetration depth)
void removeNonOptimalManifold(); void removeNonOptimalManifold();
@ -126,11 +126,6 @@ class ContactManifoldSet {
// Remove some contact manifolds and contact points if there are too many of them // Remove some contact manifolds and contact points if there are too many of them
void reduce(); 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 // Return the first proxy shape

View File

@ -99,8 +99,8 @@ constexpr decimal DEFAULT_BOUNCINESS = decimal(0.5);
/// Default rolling resistance /// Default rolling resistance
constexpr decimal DEFAULT_ROLLING_RESISTANCE = decimal(0.0); constexpr decimal DEFAULT_ROLLING_RESISTANCE = decimal(0.0);
/// True if the spleeping technique is enabled /// True if the sleeping technique is enabled
constexpr bool SPLEEPING_ENABLED = true; constexpr bool SLEEPING_ENABLED = true;
/// Distance threshold for two contact points for a valid persistent contact (in meters) /// Distance threshold for two contact points for a valid persistent contact (in meters)
constexpr decimal PERSISTENT_CONTACT_DIST_THRESHOLD = decimal(0.03); 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. /// least one concave collision shape.
constexpr int NB_MAX_CONTACT_MANIFOLDS_CONCAVE_SHAPE = 3; 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 /// Size (in bytes) of the single frame allocator
constexpr size_t SIZE_SINGLE_FRAME_ALLOCATOR_BYTES = 15728640; // 15 Mb constexpr size_t SIZE_SINGLE_FRAME_ALLOCATOR_BYTES = 15728640; // 15 Mb

View File

@ -44,7 +44,7 @@ DynamicsWorld::DynamicsWorld(const Vector3 &gravity)
mConstraintSolver(mMapBodyToConstrainedVelocityIndex), mConstraintSolver(mMapBodyToConstrainedVelocityIndex),
mNbVelocitySolverIterations(DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS), mNbVelocitySolverIterations(DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS),
mNbPositionSolverIterations(DEFAULT_POSITION_SOLVER_NB_ITERATIONS), mNbPositionSolverIterations(DEFAULT_POSITION_SOLVER_NB_ITERATIONS),
mIsSleepingEnabled(SPLEEPING_ENABLED), mGravity(gravity), mIsSleepingEnabled(SLEEPING_ENABLED), mGravity(gravity),
mIsGravityEnabled(true), mConstrainedLinearVelocities(nullptr), mIsGravityEnabled(true), mConstrainedLinearVelocities(nullptr),
mConstrainedAngularVelocities(nullptr), mSplitLinearVelocities(nullptr), mConstrainedAngularVelocities(nullptr), mSplitLinearVelocities(nullptr),
mSplitAngularVelocities(nullptr), mConstrainedPositions(nullptr), mSplitAngularVelocities(nullptr), mConstrainedPositions(nullptr),

View File

@ -54,21 +54,22 @@ void OverlappingPair::addPotentialContactPoints(NarrowPhaseInfo* narrowPhaseInfo
ContactPointInfo* nextContactPoint = contactPoint->next; 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 // 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) // (if the contact point normal is similar to the normal of an existing manifold)
ContactManifoldInfo* manifold = mPotentialContactManifolds; ContactManifoldInfo* manifold = mPotentialContactManifolds;
bool similarManifoldFound = false; bool similarManifoldFound = false;
while(manifold != nullptr) { 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 // If we have found a corresponding manifold for the new contact point
// (a manifold with a similar contact normal direction) // (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 // Add the contact point to the manifold
manifold->addContactPoint(contactPoint, contactNormalId); manifold->addContactPoint(contactPoint);
similarManifoldFound = true; similarManifoldFound = true;
@ -90,7 +91,7 @@ void OverlappingPair::addPotentialContactPoints(NarrowPhaseInfo* narrowPhaseInfo
mPotentialContactManifolds = manifoldInfo; mPotentialContactManifolds = manifoldInfo;
// Add the contact point to the manifold // Add the contact point to the manifold
manifoldInfo->addContactPoint(contactPoint, contactNormalId); manifoldInfo->addContactPoint(contactPoint);
} }
contactPoint = nextContactPoint; contactPoint = nextContactPoint;