2012-12-12 18:28:52 +00:00
|
|
|
/********************************************************************************
|
2015-02-15 20:56:45 +00:00
|
|
|
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
2016-04-11 18:15:20 +00:00
|
|
|
* Copyright (c) 2010-2016 Daniel Chappuis *
|
2012-12-12 18:28:52 +00:00
|
|
|
*********************************************************************************
|
|
|
|
* *
|
|
|
|
* 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. *
|
|
|
|
* *
|
|
|
|
********************************************************************************/
|
|
|
|
|
2013-04-18 20:54:36 +00:00
|
|
|
#ifndef REACTPHYSICS3D_CONTACT_MANIFOLD_H
|
|
|
|
#define REACTPHYSICS3D_CONTACT_MANIFOLD_H
|
2012-12-12 18:28:52 +00:00
|
|
|
|
|
|
|
// Libraries
|
2013-02-26 21:43:45 +00:00
|
|
|
#include <vector>
|
2014-08-07 19:38:31 +00:00
|
|
|
#include "body/CollisionBody.h"
|
2014-12-27 23:54:34 +00:00
|
|
|
#include "collision/ProxyShape.h"
|
2014-08-07 19:38:31 +00:00
|
|
|
#include "constraint/ContactPoint.h"
|
2017-02-26 11:48:50 +00:00
|
|
|
#include "collision/ContactManifoldInfo.h"
|
2016-09-21 20:03:45 +00:00
|
|
|
#include "memory/PoolAllocator.h"
|
2012-12-12 18:28:52 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// ReactPhysics3D namespace
|
2012-12-12 18:28:52 +00:00
|
|
|
namespace reactphysics3d {
|
|
|
|
|
2013-08-26 19:28:48 +00:00
|
|
|
// Class declarations
|
|
|
|
class ContactManifold;
|
|
|
|
|
|
|
|
// Structure ContactManifoldListElement
|
|
|
|
/**
|
|
|
|
* This structure represents a single element of a linked list of contact manifolds
|
|
|
|
*/
|
|
|
|
struct ContactManifoldListElement {
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
// -------------------- Attributes -------------------- //
|
|
|
|
|
|
|
|
/// Pointer to the actual contact manifold
|
|
|
|
ContactManifold* contactManifold;
|
|
|
|
|
|
|
|
/// Next element of the list
|
|
|
|
ContactManifoldListElement* next;
|
|
|
|
|
|
|
|
// -------------------- Methods -------------------- //
|
|
|
|
|
|
|
|
/// Constructor
|
|
|
|
ContactManifoldListElement(ContactManifold* initContactManifold,
|
|
|
|
ContactManifoldListElement* initNext)
|
|
|
|
:contactManifold(initContactManifold), next(initNext) {
|
|
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
// Class ContactManifold
|
|
|
|
/**
|
|
|
|
* This class represents the set of contact points between two bodies.
|
|
|
|
* The contact manifold is implemented in a way to cache the contact
|
|
|
|
* points among the frames for better stability following the
|
|
|
|
* "Contact Generation" presentation of Erwin Coumans at GDC 2010
|
|
|
|
* conference (bullet.googlecode.com/files/GDC10_Coumans_Erwin_Contact.pdf).
|
|
|
|
* Some code of this class is based on the implementation of the
|
|
|
|
* btPersistentManifold class from Bullet physics engine (www.http://bulletphysics.org).
|
|
|
|
* The contacts between two bodies are added one after the other in the cache.
|
|
|
|
* When the cache is full, we have to remove one point. The idea is to keep
|
|
|
|
* the point with the deepest penetration depth and also to keep the
|
|
|
|
* points producing the larger area (for a more stable contact manifold).
|
|
|
|
* The new added point is always kept.
|
|
|
|
*/
|
2013-02-26 21:43:45 +00:00
|
|
|
class ContactManifold {
|
|
|
|
|
|
|
|
private:
|
2012-12-12 18:28:52 +00:00
|
|
|
|
|
|
|
// -------------------- Attributes -------------------- //
|
|
|
|
|
2014-12-27 23:54:34 +00:00
|
|
|
/// Pointer to the first proxy shape of the contact
|
|
|
|
ProxyShape* mShape1;
|
2012-12-12 18:28:52 +00:00
|
|
|
|
2014-12-27 23:54:34 +00:00
|
|
|
/// Pointer to the second proxy shape of the contact
|
|
|
|
ProxyShape* mShape2;
|
2013-02-26 21:43:45 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Contact points in the manifold
|
2013-02-26 21:43:45 +00:00
|
|
|
ContactPoint* mContactPoints[MAX_CONTACT_POINTS_IN_MANIFOLD];
|
|
|
|
|
2015-10-08 19:28:37 +00:00
|
|
|
/// Normal direction Id (Unique Id representing the normal direction)
|
|
|
|
short int mNormalDirectionId;
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Number of contacts in the cache
|
2016-10-17 20:41:33 +00:00
|
|
|
int8 mNbContactPoints;
|
2012-12-12 18:28:52 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// First friction vector of the contact manifold
|
2013-02-26 21:43:45 +00:00
|
|
|
Vector3 mFrictionVector1;
|
2013-02-16 15:14:04 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Second friction vector of the contact manifold
|
2013-02-26 21:43:45 +00:00
|
|
|
Vector3 mFrictionVector2;
|
2013-02-16 15:14:04 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// First friction constraint accumulated impulse
|
2013-02-26 21:43:45 +00:00
|
|
|
decimal mFrictionImpulse1;
|
2013-02-16 15:14:04 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Second friction constraint accumulated impulse
|
2013-02-26 21:43:45 +00:00
|
|
|
decimal mFrictionImpulse2;
|
2013-02-16 15:14:04 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Twist friction constraint accumulated impulse
|
2013-02-26 21:43:45 +00:00
|
|
|
decimal mFrictionTwistImpulse;
|
|
|
|
|
2016-03-20 22:01:38 +00:00
|
|
|
/// Accumulated rolling resistance impulse
|
|
|
|
Vector3 mRollingResistanceImpulse;
|
|
|
|
|
2013-08-26 19:28:48 +00:00
|
|
|
/// True if the contact manifold has already been added into an island
|
|
|
|
bool mIsAlreadyInIsland;
|
|
|
|
|
2013-04-01 21:43:50 +00:00
|
|
|
/// Reference to the memory allocator
|
2016-09-21 20:03:45 +00:00
|
|
|
PoolAllocator& mMemoryAllocator;
|
2013-02-26 21:43:45 +00:00
|
|
|
|
|
|
|
// -------------------- Methods -------------------- //
|
|
|
|
|
2013-08-26 19:28:48 +00:00
|
|
|
/// Return true if the contact manifold has already been added into an island
|
|
|
|
bool isAlreadyInIsland() const;
|
2013-02-26 21:43:45 +00:00
|
|
|
|
|
|
|
public:
|
2013-02-16 15:14:04 +00:00
|
|
|
|
2012-12-12 18:28:52 +00:00
|
|
|
// -------------------- Methods -------------------- //
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Constructor
|
2017-02-26 11:48:50 +00:00
|
|
|
ContactManifold(const ContactManifoldInfo& manifoldInfo, ProxyShape* shape1, ProxyShape* shape2,
|
2016-09-21 20:03:45 +00:00
|
|
|
PoolAllocator& memoryAllocator, short int normalDirectionId);
|
2013-02-26 21:43:45 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Destructor
|
2013-02-26 21:43:45 +00:00
|
|
|
~ContactManifold();
|
|
|
|
|
2016-07-08 05:25:37 +00:00
|
|
|
/// Deleted copy-constructor
|
|
|
|
ContactManifold(const ContactManifold& contactManifold) = delete;
|
|
|
|
|
|
|
|
/// Deleted assignment operator
|
|
|
|
ContactManifold& operator=(const ContactManifold& contactManifold) = delete;
|
|
|
|
|
2014-12-27 23:54:34 +00:00
|
|
|
/// Return a pointer to the first proxy shape of the contact
|
|
|
|
ProxyShape* getShape1() const;
|
|
|
|
|
|
|
|
/// Return a pointer to the second proxy shape of the contact
|
|
|
|
ProxyShape* getShape2() const;
|
|
|
|
|
|
|
|
/// Return a pointer to the first body of the contact manifold
|
|
|
|
CollisionBody* getBody1() const;
|
|
|
|
|
|
|
|
/// Return a pointer to the second body of the contact manifold
|
|
|
|
CollisionBody* getBody2() const;
|
|
|
|
|
2015-10-08 19:28:37 +00:00
|
|
|
/// Return the normal direction Id
|
|
|
|
short int getNormalDirectionId() const;
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Clear the contact manifold
|
2013-02-26 21:43:45 +00:00
|
|
|
void clear();
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Return the number of contact points in the manifold
|
2016-10-17 20:41:33 +00:00
|
|
|
int8 getNbContactPoints() const;
|
2013-02-26 21:43:45 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Return the first friction vector at the center of the contact manifold
|
2013-02-26 21:43:45 +00:00
|
|
|
const Vector3& getFrictionVector1() const;
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// set the first friction vector at the center of the contact manifold
|
2013-02-26 21:43:45 +00:00
|
|
|
void setFrictionVector1(const Vector3& mFrictionVector1);
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Return the second friction vector at the center of the contact manifold
|
2013-02-26 21:43:45 +00:00
|
|
|
const Vector3& getFrictionVector2() const;
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// set the second friction vector at the center of the contact manifold
|
2013-02-26 21:43:45 +00:00
|
|
|
void setFrictionVector2(const Vector3& mFrictionVector2);
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Return the first friction accumulated impulse
|
2013-02-26 21:43:45 +00:00
|
|
|
decimal getFrictionImpulse1() const;
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Set the first friction accumulated impulse
|
2013-02-26 21:43:45 +00:00
|
|
|
void setFrictionImpulse1(decimal frictionImpulse1);
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Return the second friction accumulated impulse
|
2013-02-26 21:43:45 +00:00
|
|
|
decimal getFrictionImpulse2() const;
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Set the second friction accumulated impulse
|
2013-02-26 21:43:45 +00:00
|
|
|
void setFrictionImpulse2(decimal frictionImpulse2);
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Return the friction twist accumulated impulse
|
2013-02-26 21:43:45 +00:00
|
|
|
decimal getFrictionTwistImpulse() const;
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Set the friction twist accumulated impulse
|
2013-02-26 21:43:45 +00:00
|
|
|
void setFrictionTwistImpulse(decimal frictionTwistImpulse);
|
|
|
|
|
2016-03-20 22:01:38 +00:00
|
|
|
/// Set the accumulated rolling resistance impulse
|
|
|
|
void setRollingResistanceImpulse(const Vector3& rollingResistanceImpulse);
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Return a contact point of the manifold
|
2013-02-26 21:43:45 +00:00
|
|
|
ContactPoint* getContactPoint(uint index) const;
|
2013-08-26 19:28:48 +00:00
|
|
|
|
2015-10-08 19:28:37 +00:00
|
|
|
/// Return the normalized averaged normal vector
|
|
|
|
Vector3 getAverageContactNormal() const;
|
|
|
|
|
|
|
|
/// Return the largest depth of all the contact points
|
|
|
|
decimal getLargestContactDepth() const;
|
|
|
|
|
2017-02-26 11:48:50 +00:00
|
|
|
/// Add a contact point
|
|
|
|
void addContactPoint(const ContactPointInfo* contactPointInfo);
|
|
|
|
|
|
|
|
/// Remove a contact point
|
|
|
|
void removeContactPoint(int index);
|
|
|
|
|
2013-08-26 19:28:48 +00:00
|
|
|
// -------------------- Friendship -------------------- //
|
|
|
|
|
|
|
|
friend class DynamicsWorld;
|
|
|
|
friend class Island;
|
2014-11-21 20:27:09 +00:00
|
|
|
friend class CollisionBody;
|
2012-12-12 18:28:52 +00:00
|
|
|
};
|
|
|
|
|
2014-12-27 23:54:34 +00:00
|
|
|
// Return a pointer to the first proxy shape of the contact
|
|
|
|
inline ProxyShape* ContactManifold::getShape1() const {
|
|
|
|
return mShape1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return a pointer to the second proxy shape of the contact
|
|
|
|
inline ProxyShape* ContactManifold::getShape2() const {
|
|
|
|
return mShape2;
|
|
|
|
}
|
|
|
|
|
2013-08-26 19:28:48 +00:00
|
|
|
// Return a pointer to the first body of the contact manifold
|
|
|
|
inline CollisionBody* ContactManifold::getBody1() const {
|
2014-12-27 23:54:34 +00:00
|
|
|
return mShape1->getBody();
|
2013-08-26 19:28:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return a pointer to the second body of the contact manifold
|
|
|
|
inline CollisionBody* ContactManifold::getBody2() const {
|
2014-12-27 23:54:34 +00:00
|
|
|
return mShape2->getBody();
|
2013-08-26 19:28:48 +00:00
|
|
|
}
|
|
|
|
|
2015-10-08 19:28:37 +00:00
|
|
|
// Return the normal direction Id
|
|
|
|
inline short int ContactManifold::getNormalDirectionId() const {
|
|
|
|
return mNormalDirectionId;
|
|
|
|
}
|
|
|
|
|
2013-02-26 21:43:45 +00:00
|
|
|
// Return the number of contact points in the manifold
|
2016-10-17 20:41:33 +00:00
|
|
|
inline int8 ContactManifold::getNbContactPoints() const {
|
2013-02-26 21:43:45 +00:00
|
|
|
return mNbContactPoints;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the first friction vector at the center of the contact manifold
|
|
|
|
inline const Vector3& ContactManifold::getFrictionVector1() const {
|
|
|
|
return mFrictionVector1;
|
2012-12-12 18:28:52 +00:00
|
|
|
}
|
|
|
|
|
2013-02-26 21:43:45 +00:00
|
|
|
// set the first friction vector at the center of the contact manifold
|
|
|
|
inline void ContactManifold::setFrictionVector1(const Vector3& frictionVector1) {
|
|
|
|
mFrictionVector1 = frictionVector1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the second friction vector at the center of the contact manifold
|
|
|
|
inline const Vector3& ContactManifold::getFrictionVector2() const {
|
|
|
|
return mFrictionVector2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set the second friction vector at the center of the contact manifold
|
|
|
|
inline void ContactManifold::setFrictionVector2(const Vector3& frictionVector2) {
|
|
|
|
mFrictionVector2 = frictionVector2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the first friction accumulated impulse
|
|
|
|
inline decimal ContactManifold::getFrictionImpulse1() const {
|
|
|
|
return mFrictionImpulse1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the first friction accumulated impulse
|
|
|
|
inline void ContactManifold::setFrictionImpulse1(decimal frictionImpulse1) {
|
|
|
|
mFrictionImpulse1 = frictionImpulse1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the second friction accumulated impulse
|
|
|
|
inline decimal ContactManifold::getFrictionImpulse2() const {
|
|
|
|
return mFrictionImpulse2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the second friction accumulated impulse
|
|
|
|
inline void ContactManifold::setFrictionImpulse2(decimal frictionImpulse2) {
|
|
|
|
mFrictionImpulse2 = frictionImpulse2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the friction twist accumulated impulse
|
|
|
|
inline decimal ContactManifold::getFrictionTwistImpulse() const {
|
|
|
|
return mFrictionTwistImpulse;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the friction twist accumulated impulse
|
|
|
|
inline void ContactManifold::setFrictionTwistImpulse(decimal frictionTwistImpulse) {
|
|
|
|
mFrictionTwistImpulse = frictionTwistImpulse;
|
|
|
|
}
|
|
|
|
|
2016-03-20 22:01:38 +00:00
|
|
|
// Set the accumulated rolling resistance impulse
|
|
|
|
inline void ContactManifold::setRollingResistanceImpulse(const Vector3& rollingResistanceImpulse) {
|
|
|
|
mRollingResistanceImpulse = rollingResistanceImpulse;
|
|
|
|
}
|
|
|
|
|
2013-02-26 21:43:45 +00:00
|
|
|
// Return a contact point of the manifold
|
|
|
|
inline ContactPoint* ContactManifold::getContactPoint(uint index) const {
|
2016-02-22 22:26:50 +00:00
|
|
|
assert(index < mNbContactPoints);
|
2013-02-26 21:43:45 +00:00
|
|
|
return mContactPoints[index];
|
2013-02-27 21:10:10 +00:00
|
|
|
}
|
2013-02-26 21:43:45 +00:00
|
|
|
|
2013-08-26 19:28:48 +00:00
|
|
|
// Return true if the contact manifold has already been added into an island
|
|
|
|
inline bool ContactManifold::isAlreadyInIsland() const {
|
|
|
|
return mIsAlreadyInIsland;
|
|
|
|
}
|
|
|
|
|
2015-10-02 05:04:05 +00:00
|
|
|
// Return the normalized averaged normal vector
|
|
|
|
inline Vector3 ContactManifold::getAverageContactNormal() const {
|
|
|
|
Vector3 averageNormal;
|
|
|
|
|
2016-02-22 22:26:50 +00:00
|
|
|
for (uint i=0; i<mNbContactPoints; i++) {
|
2015-10-02 05:04:05 +00:00
|
|
|
averageNormal += mContactPoints[i]->getNormal();
|
|
|
|
}
|
|
|
|
|
|
|
|
return averageNormal.getUnit();
|
|
|
|
}
|
|
|
|
|
2015-10-08 19:28:37 +00:00
|
|
|
// Return the largest depth of all the contact points
|
|
|
|
inline decimal ContactManifold::getLargestContactDepth() const {
|
|
|
|
decimal largestDepth = 0.0f;
|
|
|
|
|
2016-02-22 22:26:50 +00:00
|
|
|
for (uint i=0; i<mNbContactPoints; i++) {
|
2015-10-08 19:28:37 +00:00
|
|
|
decimal depth = mContactPoints[i]->getPenetrationDepth();
|
|
|
|
if (depth > largestDepth) {
|
|
|
|
largestDepth = depth;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return largestDepth;
|
|
|
|
}
|
|
|
|
|
2013-02-26 21:43:45 +00:00
|
|
|
}
|
2012-12-12 18:28:52 +00:00
|
|
|
#endif
|
2013-02-26 21:43:45 +00:00
|
|
|
|