Working on testCollision() and testOverlap() methods
This commit is contained in:
parent
3f5916a280
commit
74b442077f
|
@ -6,6 +6,12 @@
|
|||
|
||||
- The CollisionWorld::testCollision() methods do not have the 'categoryMaskBits' parameter anymore.
|
||||
- The CollisionWorld::testOverlap() methods do not have the 'categoryMaskBits' parameter anymore.
|
||||
- Many methods in the EventListener class have changed. Check the user manual for more information.
|
||||
- The way to retrieve contacts from a CollisionCallbackInfo object has changed. Check the user manual for more information.
|
||||
|
||||
### Removed
|
||||
|
||||
- DynamicsWorld::getContactsList(). You need to use the EventListener class to retrieve contacts now.
|
||||
|
||||
## Release Candidate
|
||||
|
||||
|
|
|
@ -239,6 +239,7 @@ SET (REACTPHYSICS3D_SOURCES
|
|||
"src/components/ProxyShapeComponents.cpp"
|
||||
"src/components/DynamicsComponents.cpp"
|
||||
"src/collision/CollisionCallback.cpp"
|
||||
"src/collision/OverlapCallback.cpp"
|
||||
"src/mathematics/mathematics_functions.cpp"
|
||||
"src/mathematics/Matrix2x2.cpp"
|
||||
"src/mathematics/Matrix3x3.cpp"
|
||||
|
|
|
@ -140,6 +140,8 @@ class Body {
|
|||
void setLogger(Logger* logger);
|
||||
#endif
|
||||
|
||||
// TODO : Check if those operators are still used
|
||||
|
||||
/// Smaller than operator
|
||||
bool operator<(const Body& body2) const;
|
||||
|
||||
|
|
|
@ -25,66 +25,71 @@
|
|||
|
||||
// Libraries
|
||||
#include "collision/CollisionCallback.h"
|
||||
#include "engine/OverlappingPair.h"
|
||||
#include "memory/MemoryAllocator.h"
|
||||
#include "collision/ContactManifold.h"
|
||||
#include "memory/MemoryManager.h"
|
||||
#include "collision/ContactPair.h"
|
||||
#include "constraint/ContactPoint.h"
|
||||
#include "engine/CollisionWorld.h"
|
||||
|
||||
// We want to use the ReactPhysics3D namespace
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
CollisionCallback::CollisionCallbackInfo::CollisionCallbackInfo(OverlappingPair* pair, MemoryManager& memoryManager) :
|
||||
contactManifoldElements(nullptr), body1(pair->getShape1()->getBody()),
|
||||
body2(pair->getShape2()->getBody()),
|
||||
proxyShape1(pair->getShape1()), proxyShape2(pair->getShape2()),
|
||||
mMemoryManager(memoryManager) {
|
||||
CollisionCallback::ContactPoint::ContactPoint(const reactphysics3d::ContactPoint& contactPoint) : mContactPoint(contactPoint) {
|
||||
|
||||
assert(pair != nullptr);
|
||||
|
||||
|
||||
// TODO : Rework how to report contacts
|
||||
/*
|
||||
const ContactManifoldSet& manifoldSet = pair->getContactManifoldSet();
|
||||
|
||||
// For each contact manifold in the set of manifolds in the pair
|
||||
ContactManifold* contactManifold = manifoldSet.getContactManifolds();
|
||||
assert(contactManifold != nullptr);
|
||||
while (contactManifold != nullptr) {
|
||||
|
||||
assert(contactManifold->getNbContactPoints() > 0);
|
||||
|
||||
// Add the contact manifold at the beginning of the linked
|
||||
// list of contact manifolds of the first body
|
||||
ContactManifoldListElement* element = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
|
||||
sizeof(ContactManifoldListElement)))
|
||||
ContactManifoldListElement(contactManifold,
|
||||
contactManifoldElements);
|
||||
contactManifoldElements = element;
|
||||
|
||||
contactManifold = contactManifold->getNext();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Destructor
|
||||
CollisionCallback::CollisionCallbackInfo::~CollisionCallbackInfo() {
|
||||
// Contact Pair Constructor
|
||||
CollisionCallback::ContactPair::ContactPair(const reactphysics3d::ContactPair& contactPair,
|
||||
List<reactphysics3d::ContactPoint>* contactPoints, CollisionWorld& world)
|
||||
:mContactPair(contactPair), mContactPoints(contactPoints),
|
||||
mWorld(world) {
|
||||
|
||||
// TODO : Rework how to report contacts
|
||||
/*
|
||||
// Release memory allocator for the contact manifold list elements
|
||||
ContactManifoldListElement* element = contactManifoldElements;
|
||||
while (element != nullptr) {
|
||||
|
||||
ContactManifoldListElement* nextElement = element->getNext();
|
||||
|
||||
// Delete and release memory
|
||||
element->~ContactManifoldListElement();
|
||||
mMemoryManager.release(MemoryManager::AllocationType::Pool, element,
|
||||
sizeof(ContactManifoldListElement));
|
||||
|
||||
element = nextElement;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Return a pointer to the first body in contact
|
||||
CollisionBody* CollisionCallback::ContactPair::getBody1() const {
|
||||
return static_cast<CollisionBody*>(mWorld.mBodyComponents.getBody(mContactPair.body1Entity));
|
||||
}
|
||||
|
||||
// Return a pointer to the second body in contact
|
||||
CollisionBody* CollisionCallback::ContactPair::getBody2() const {
|
||||
return static_cast<CollisionBody*>(mWorld.mBodyComponents.getBody(mContactPair.body2Entity));
|
||||
}
|
||||
|
||||
// Return a pointer to the first proxy-shape in contact (in body 1)
|
||||
ProxyShape* CollisionCallback::ContactPair::getProxyShape1() const {
|
||||
return mWorld.mProxyShapesComponents.getProxyShape(mContactPair.proxyShape1Entity);
|
||||
}
|
||||
|
||||
// Return a pointer to the second proxy-shape in contact (in body 1)
|
||||
ProxyShape* CollisionCallback::ContactPair::getProxyShape2() const {
|
||||
return mWorld.mProxyShapesComponents.getProxyShape(mContactPair.proxyShape2Entity);
|
||||
}
|
||||
|
||||
// CollisionCallbackInfo Constructor
|
||||
CollisionCallback::CallbackData::CallbackData(List<reactphysics3d::ContactPair>* contactPairs, List<ContactManifold>* manifolds,
|
||||
List<reactphysics3d::ContactPoint>* contactPoints, CollisionWorld& world)
|
||||
:mContactPairs(contactPairs), mContactManifolds(manifolds), mContactPoints(contactPoints), mWorld(world) {
|
||||
|
||||
}
|
||||
|
||||
// Return a given contact point of the contact pair
|
||||
/// Note that the returned ContactPoint object is only valid during the call of the CollisionCallback::onContact()
|
||||
/// method. Therefore, you need to get contact data from it and make a copy. Do not make a copy of the ContactPoint
|
||||
/// object itself because it won't be valid after the CollisionCallback::onContact() call.
|
||||
CollisionCallback::ContactPoint CollisionCallback::ContactPair::getContactPoint(uint index) const {
|
||||
|
||||
assert(index < getNbContactPoints());
|
||||
|
||||
return CollisionCallback::ContactPoint((*mContactPoints)[mContactPair.contactPointsIndex + index]);
|
||||
}
|
||||
|
||||
// Return a given contact pair
|
||||
/// Note that the returned ContactPair object is only valid during the call of the CollisionCallback::onContact()
|
||||
/// method. Therefore, you need to get contact data from it and make a copy. Do not make a copy of the ContactPair
|
||||
/// object itself because it won't be valid after the CollisionCallback::onContact() call.
|
||||
CollisionCallback::ContactPair CollisionCallback::CallbackData::getContactPair(uint index) const {
|
||||
|
||||
assert(index < getNbContactPairs());
|
||||
|
||||
return CollisionCallback::ContactPair((*mContactPairs)[index], mContactPoints, mWorld);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
#ifndef REACTPHYSICS3D_COLLISION_CALLBACK_H
|
||||
#define REACTPHYSICS3D_COLLISION_CALLBACK_H
|
||||
|
||||
// Libraries
|
||||
#include "containers/List.h"
|
||||
#include "collision/ContactPair.h"
|
||||
#include "constraint/ContactPoint.h"
|
||||
|
||||
/// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
||||
|
@ -36,10 +41,11 @@ struct ContactManifoldListElement;
|
|||
class CollisionBody;
|
||||
class ProxyShape;
|
||||
class MemoryManager;
|
||||
class CollisionCallbackInfo;
|
||||
|
||||
// Class CollisionCallback
|
||||
/**
|
||||
* This class can be used to register a callback for collision test queries.
|
||||
* This abstract class can be used to register a callback for collision test queries.
|
||||
* You should implement your own class inherited from this one and implement
|
||||
* the notifyContact() method. This method will called each time a contact
|
||||
* point is reported.
|
||||
|
@ -48,47 +54,221 @@ class CollisionCallback {
|
|||
|
||||
public:
|
||||
|
||||
// Structure CollisionCallbackInfo
|
||||
// Class ContactPoint
|
||||
/**
|
||||
* This structure represents the contact information between two collision
|
||||
* shapes of two bodies
|
||||
* This class represents a contact point between two bodies of the physics world.
|
||||
*/
|
||||
struct CollisionCallbackInfo {
|
||||
class ContactPoint {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
const reactphysics3d::ContactPoint& mContactPoint;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
ContactPoint(const reactphysics3d::ContactPoint& contactPoint);
|
||||
|
||||
public:
|
||||
|
||||
/// Pointer to the first element of the linked-list that contains contact manifolds
|
||||
ContactManifoldListElement* contactManifoldElements;
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Pointer to the first body of the contact
|
||||
CollisionBody* body1;
|
||||
/// Copy constructor
|
||||
ContactPoint(const ContactPoint& contactPoint) = default;
|
||||
|
||||
/// Pointer to the second body of the contact
|
||||
CollisionBody* body2;
|
||||
/// Assignment operator
|
||||
ContactPoint& operator=(const ContactPoint& contactPoint) = default;
|
||||
|
||||
/// Pointer to the proxy shape of first body
|
||||
const ProxyShape* proxyShape1;
|
||||
/// Destructor
|
||||
~ContactPoint() = default;
|
||||
|
||||
/// Pointer to the proxy shape of second body
|
||||
const ProxyShape* proxyShape2;
|
||||
/// Return the penetration depth
|
||||
decimal getPenetrationDepth() const;
|
||||
|
||||
/// Memory manager
|
||||
MemoryManager& mMemoryManager;
|
||||
/// Return the world-space contact normal
|
||||
const Vector3& getWorldNormal() const;
|
||||
|
||||
// Constructor
|
||||
CollisionCallbackInfo(OverlappingPair* pair, MemoryManager& memoryManager);
|
||||
/// Return the contact point on the first proxy shape in the local-space of the first proxy shape
|
||||
const Vector3& getLocalPointOnShape1() const;
|
||||
|
||||
// Destructor
|
||||
~CollisionCallbackInfo();
|
||||
/// Return the contact point on the second proxy shape in the local-space of the second proxy shape
|
||||
const Vector3& getLocalPointOnShape2() const;
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class CollisionCallback;
|
||||
};
|
||||
|
||||
// Class ContactPair
|
||||
/**
|
||||
* This class represents the contact between two bodies of the physics world.
|
||||
* A contact pair contains a list of contact points.
|
||||
*/
|
||||
class ContactPair {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
const reactphysics3d::ContactPair& mContactPair;
|
||||
|
||||
/// Pointer to the contact points
|
||||
List<reactphysics3d::ContactPoint>* mContactPoints;
|
||||
|
||||
/// Reference to the physics world
|
||||
CollisionWorld& mWorld;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
ContactPair(const reactphysics3d::ContactPair& contactPair, List<reactphysics3d::ContactPoint>* contactPoints,
|
||||
CollisionWorld& world);
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Copy constructor
|
||||
ContactPair(const ContactPair& contactPair) = default;
|
||||
|
||||
/// Assignment operator
|
||||
ContactPair& operator=(const ContactPair& contactPair) = default;
|
||||
|
||||
/// Destructor
|
||||
~ContactPair() = default;
|
||||
|
||||
/// Return the number of contact points in the contact pair
|
||||
uint getNbContactPoints() const;
|
||||
|
||||
/// Return a given contact point
|
||||
ContactPoint getContactPoint(uint index) const;
|
||||
|
||||
/// Return a pointer to the first body in contact
|
||||
CollisionBody* getBody1() const;
|
||||
|
||||
/// Return a pointer to the second body in contact
|
||||
CollisionBody* getBody2() const;
|
||||
|
||||
/// Return a pointer to the first proxy-shape in contact (in body 1)
|
||||
ProxyShape* getProxyShape1() const;
|
||||
|
||||
/// Return a pointer to the second proxy-shape in contact (in body 2)
|
||||
ProxyShape* getProxyShape2() const;
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class CollisionCallback;
|
||||
};
|
||||
|
||||
// Class CallbackData
|
||||
/**
|
||||
* This class contains data about contacts between bodies
|
||||
*/
|
||||
class CallbackData {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Pointer to the list of contact pairs
|
||||
List<reactphysics3d::ContactPair>* mContactPairs;
|
||||
|
||||
/// Pointer to the list of contact manifolds
|
||||
List<ContactManifold>* mContactManifolds;
|
||||
|
||||
/// Pointer to the contact points
|
||||
List<reactphysics3d::ContactPoint>* mContactPoints;
|
||||
|
||||
/// Reference to the physics world
|
||||
CollisionWorld& mWorld;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
CallbackData(List<reactphysics3d::ContactPair>* contactPairs, List<ContactManifold>* manifolds,
|
||||
List<reactphysics3d::ContactPoint>* contactPoints, CollisionWorld& world);
|
||||
|
||||
/// Deleted copy constructor
|
||||
CallbackData(const CallbackData& callbackData) = delete;
|
||||
|
||||
/// Deleted assignment operator
|
||||
CallbackData& operator=(const CallbackData& callbackData) = delete;
|
||||
|
||||
/// Destructor
|
||||
~CallbackData() = default;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Return the number of contact pairs
|
||||
uint getNbContactPairs() const;
|
||||
|
||||
/// Return a given contact pair
|
||||
ContactPair getContactPair(uint index) const;
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class CollisionDetection;
|
||||
};
|
||||
|
||||
/// Destructor
|
||||
virtual ~CollisionCallback() = default;
|
||||
|
||||
/// This method will be called for each reported contact point
|
||||
virtual void notifyContact(const CollisionCallbackInfo& collisionCallbackInfo)=0;
|
||||
/// This method is called when some contacts occur
|
||||
virtual void onContact(const CallbackData& callbackData)=0;
|
||||
};
|
||||
|
||||
// Return the number of contact pairs (there is a single contact pair between two bodies in contact)
|
||||
/**
|
||||
* @return The number of contact pairs
|
||||
*/
|
||||
inline uint CollisionCallback::CallbackData::getNbContactPairs() const {
|
||||
return mContactPairs->size();
|
||||
}
|
||||
|
||||
// Return the number of contact points in the contact pair
|
||||
/**
|
||||
* @return The number of contact points
|
||||
*/
|
||||
inline uint CollisionCallback::ContactPair::getNbContactPoints() const {
|
||||
return mContactPair.nbToTalContactPoints;
|
||||
}
|
||||
|
||||
// Return the penetration depth between the two bodies in contact
|
||||
/**
|
||||
* @return The penetration depth (larger than zero)
|
||||
*/
|
||||
inline decimal CollisionCallback::ContactPoint::getPenetrationDepth() const {
|
||||
return mContactPoint.getPenetrationDepth();
|
||||
}
|
||||
|
||||
// Return the world-space contact normal (vector from first body toward second body)
|
||||
/**
|
||||
* @return The contact normal direction at the contact point (in world-space)
|
||||
*/
|
||||
inline const Vector3& CollisionCallback::ContactPoint::getWorldNormal() const {
|
||||
return mContactPoint.getNormal();
|
||||
}
|
||||
|
||||
// Return the contact point on the first proxy shape in the local-space of the first proxy shape
|
||||
/**
|
||||
* @return The contact point in the local-space of the first proxy-shape (from body1) in contact
|
||||
*/
|
||||
inline const Vector3& CollisionCallback::ContactPoint::getLocalPointOnShape1() const {
|
||||
return mContactPoint.getLocalPointOnShape1();
|
||||
}
|
||||
|
||||
// Return the contact point on the second proxy shape in the local-space of the second proxy shape
|
||||
/**
|
||||
* @return The contact point in the local-space of the second proxy-shape (from body2) in contact
|
||||
*/
|
||||
inline const Vector3& CollisionCallback::ContactPoint::getLocalPointOnShape2() const {
|
||||
return mContactPoint.getLocalPointOnShape2();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "engine/EventListener.h"
|
||||
#include "collision/RaycastInfo.h"
|
||||
#include "engine/Islands.h"
|
||||
#include "containers/Pair.h"
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
|
@ -431,9 +432,6 @@ void CollisionDetection::computeNarrowPhase() {
|
|||
// Reduce the number of contact points in the manifolds
|
||||
reducePotentialContactManifolds(mCurrentContactPairs, mPotentialContactManifolds, mPotentialContactPoints);
|
||||
|
||||
// Report contacts to the user
|
||||
reportAllContacts();
|
||||
|
||||
assert(mCurrentContactManifolds->size() == 0);
|
||||
assert(mCurrentContactPoints->size() == 0);
|
||||
|
||||
|
@ -442,24 +440,89 @@ void CollisionDetection::computeNarrowPhase() {
|
|||
mNarrowPhaseInput.clear();
|
||||
}
|
||||
|
||||
// Compute the narrow-phase collision detection for the testCollision() methods.
|
||||
// This method returns true if contacts are found.
|
||||
bool CollisionDetection::computeNarrowPhaseSnapshot(NarrowPhaseInput& narrowPhaseInput, bool reportContacts) {
|
||||
// Compute the narrow-phase collision detection for the testOverlap() methods.
|
||||
/// This method returns true if contacts are found.
|
||||
bool CollisionDetection::computeNarrowPhaseOverlapSnapshot(NarrowPhaseInput& narrowPhaseInput, OverlapCallback* callback) {
|
||||
|
||||
RP3D_PROFILE("CollisionDetection::computeNarrowPhaseSnapshot()", mProfiler);
|
||||
RP3D_PROFILE("CollisionDetection::computeNarrowPhaseOverlapSnapshot()", mProfiler);
|
||||
|
||||
MemoryAllocator& allocator = mMemoryManager.getPoolAllocator();
|
||||
|
||||
// Test the narrow-phase collision detection on the batches to be tested
|
||||
bool collisionFound = testNarrowPhaseCollision(narrowPhaseInput, reportContacts, allocator);
|
||||
if (!reportContacts) {
|
||||
bool collisionFound = testNarrowPhaseCollision(narrowPhaseInput, false, allocator);
|
||||
if (collisionFound && callback != nullptr) {
|
||||
|
||||
// Compute the overlapping bodies
|
||||
List<Pair<Entity, Entity>> overlapBodies(allocator);
|
||||
computeSnapshotContactPairs(narrowPhaseInput, overlapBodies);
|
||||
|
||||
// Report overlapping bodies
|
||||
OverlapCallback::CallbackData callbackData(overlapBodies, *mWorld);
|
||||
(*callback).onOverlap(callbackData);
|
||||
}
|
||||
|
||||
return collisionFound;
|
||||
}
|
||||
|
||||
// Process the potential overlapping bodies for the testOverlap() methods
|
||||
void CollisionDetection::computeSnapshotContactPairs(NarrowPhaseInput& narrowPhaseInput, List<Pair<Entity, Entity>>& overlapPairs) const {
|
||||
|
||||
// get the narrow-phase batches to test for collision
|
||||
NarrowPhaseInfoBatch& sphereVsSphereBatch = narrowPhaseInput.getSphereVsSphereBatch();
|
||||
NarrowPhaseInfoBatch& sphereVsCapsuleBatch = narrowPhaseInput.getSphereVsCapsuleBatch();
|
||||
NarrowPhaseInfoBatch& capsuleVsCapsuleBatch = narrowPhaseInput.getCapsuleVsCapsuleBatch();
|
||||
NarrowPhaseInfoBatch& sphereVsConvexPolyhedronBatch = narrowPhaseInput.getSphereVsConvexPolyhedronBatch();
|
||||
NarrowPhaseInfoBatch& capsuleVsConvexPolyhedronBatch = narrowPhaseInput.getCapsuleVsConvexPolyhedronBatch();
|
||||
NarrowPhaseInfoBatch& convexPolyhedronVsConvexPolyhedronBatch = narrowPhaseInput.getConvexPolyhedronVsConvexPolyhedronBatch();
|
||||
|
||||
// Process the potential contacts
|
||||
computeSnapshotContactPairs(sphereVsSphereBatch, overlapPairs);
|
||||
computeSnapshotContactPairs(sphereVsCapsuleBatch, overlapPairs);
|
||||
computeSnapshotContactPairs(capsuleVsCapsuleBatch, overlapPairs);
|
||||
computeSnapshotContactPairs(sphereVsConvexPolyhedronBatch, overlapPairs);
|
||||
computeSnapshotContactPairs(capsuleVsConvexPolyhedronBatch, overlapPairs);
|
||||
computeSnapshotContactPairs(convexPolyhedronVsConvexPolyhedronBatch, overlapPairs);
|
||||
}
|
||||
|
||||
// Convert the potential overlapping bodies for the testOverlap() methods
|
||||
void CollisionDetection::computeSnapshotContactPairs(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, List<Pair<Entity, Entity>>& overlapPairs) const {
|
||||
|
||||
RP3D_PROFILE("CollisionDetection::computeSnapshotContactPairs()", mProfiler);
|
||||
|
||||
// For each narrow phase info object
|
||||
for(uint i=0; i < narrowPhaseInfoBatch.getNbObjects(); i++) {
|
||||
|
||||
// If there is a contact
|
||||
if (narrowPhaseInfoBatch.isColliding[i]) {
|
||||
|
||||
// Add the pair of bodies in contact into the list
|
||||
overlapPairs.add(Pair<Entity, Entity>(narrowPhaseInfoBatch.overlappingPairs[i]->getShape1()->getBody()->getEntity(),
|
||||
narrowPhaseInfoBatch.overlappingPairs[i]->getShape2()->getBody()->getEntity()));
|
||||
}
|
||||
|
||||
narrowPhaseInfoBatch.resetContactPoints(i);
|
||||
}
|
||||
}
|
||||
// Compute the narrow-phase collision detection for the testCollision() methods.
|
||||
// This method returns true if contacts are found.
|
||||
bool CollisionDetection::computeNarrowPhaseCollisionSnapshot(NarrowPhaseInput& narrowPhaseInput, CollisionCallback& callback) {
|
||||
|
||||
RP3D_PROFILE("CollisionDetection::computeNarrowPhaseCollisionSnapshot()", mProfiler);
|
||||
|
||||
MemoryAllocator& allocator = mMemoryManager.getPoolAllocator();
|
||||
|
||||
// Test the narrow-phase collision detection on the batches to be tested
|
||||
bool collisionFound = testNarrowPhaseCollision(narrowPhaseInput, true, allocator);
|
||||
|
||||
// If collision has been found, create contacts
|
||||
if (collisionFound) {
|
||||
|
||||
List<ContactPointInfo> potentialContactPoints(allocator);
|
||||
List<ContactManifoldInfo> potentialContactManifolds(allocator);
|
||||
Map<OverlappingPair::OverlappingPairId, uint> mapPairIdToContactPairIndex(allocator);
|
||||
List<ContactPair> contactPairs(allocator);
|
||||
List<ContactManifold> contactManifolds(allocator);
|
||||
List<ContactPoint> contactPoints(allocator);
|
||||
Map<Entity, List<uint>> mapBodyToContactPairs(allocator);
|
||||
|
||||
// Process all the potential contacts after narrow-phase collision
|
||||
|
@ -469,6 +532,14 @@ bool CollisionDetection::computeNarrowPhaseSnapshot(NarrowPhaseInput& narrowPhas
|
|||
// Reduce the number of contact points in the manifolds
|
||||
reducePotentialContactManifolds(&contactPairs, potentialContactManifolds, potentialContactPoints);
|
||||
|
||||
// Create the actual contact manifolds and contact points
|
||||
createSnapshotContacts(contactPairs, contactManifolds, contactPoints, potentialContactManifolds,
|
||||
potentialContactPoints);
|
||||
|
||||
// Report the contacts to the user
|
||||
reportContacts(callback, &contactPairs, &contactManifolds, &contactPoints);
|
||||
}
|
||||
|
||||
return collisionFound;
|
||||
}
|
||||
|
||||
|
@ -502,10 +573,6 @@ void CollisionDetection::swapPreviousAndCurrentContacts() {
|
|||
}
|
||||
|
||||
// Create the actual contact manifolds and contacts points
|
||||
/// List of the indices of the contact pairs (in mCurrentContacPairs array) with contact pairs of
|
||||
/// same islands packed together linearly and contact pairs that are not part of islands at the end.
|
||||
/// This is used when we create contact manifolds and contact points so that there are also packed
|
||||
/// together linearly if they are part of the same island.
|
||||
void CollisionDetection::createContacts() {
|
||||
|
||||
RP3D_PROFILE("CollisionDetection::createContacts()", mProfiler);
|
||||
|
@ -561,12 +628,73 @@ void CollisionDetection::createContacts() {
|
|||
// Initialize the current contacts with the contacts from the previous frame (for warmstarting)
|
||||
initContactsWithPreviousOnes();
|
||||
|
||||
// Report contacts to the user
|
||||
if (mWorld->mEventListener != nullptr) {
|
||||
reportContacts(*(mWorld->mEventListener), mCurrentContactPairs, mCurrentContactManifolds, mCurrentContactPoints);
|
||||
}
|
||||
|
||||
// Reset the potential contacts
|
||||
mPotentialContactPoints.clear(true);
|
||||
mPotentialContactManifolds.clear(true);
|
||||
mContactPairsIndicesOrderingForContacts.clear(true);
|
||||
}
|
||||
|
||||
// Create the actual contact manifolds and contacts points for testCollision() methods
|
||||
void CollisionDetection::createSnapshotContacts(List<ContactPair>& contactPairs,
|
||||
List<ContactManifold>& contactManifolds,
|
||||
List<ContactPoint>& contactPoints,
|
||||
List<ContactManifoldInfo>& potentialContactManifolds,
|
||||
List<ContactPointInfo>& potentialContactPoints) {
|
||||
|
||||
RP3D_PROFILE("CollisionDetection::createSnapshotContacts()", mProfiler);
|
||||
|
||||
contactManifolds.reserve(contactPairs.size());
|
||||
contactPoints.reserve(contactManifolds.size());
|
||||
|
||||
// For each contact pair
|
||||
for (uint p=0; p < contactPairs.size(); p++) {
|
||||
|
||||
ContactPair& contactPair = contactPairs[p];
|
||||
assert(contactPair.potentialContactManifoldsIndices.size() > 0);
|
||||
|
||||
contactPair.contactManifoldsIndex = contactManifolds.size();
|
||||
contactPair.nbContactManifolds = contactPair.potentialContactManifoldsIndices.size();
|
||||
contactPair.contactPointsIndex = contactPoints.size();
|
||||
|
||||
// For each potential contact manifold of the pair
|
||||
for (uint m=0; m < contactPair.potentialContactManifoldsIndices.size(); m++) {
|
||||
|
||||
ContactManifoldInfo& potentialManifold = potentialContactManifolds[contactPair.potentialContactManifoldsIndices[m]];
|
||||
|
||||
// Start index and number of contact points for this manifold
|
||||
const uint contactPointsIndex = contactPoints.size();
|
||||
const int8 nbContactPoints = static_cast<int8>(potentialManifold.potentialContactPointsIndices.size());
|
||||
contactPair.nbToTalContactPoints += nbContactPoints;
|
||||
|
||||
// We create a new contact manifold
|
||||
ContactManifold contactManifold(contactPair.body1Entity, contactPair.body2Entity, contactPair.proxyShape1Entity,
|
||||
contactPair.proxyShape2Entity, contactPointsIndex, nbContactPoints);
|
||||
|
||||
// Add the contact manifold
|
||||
contactManifolds.add(contactManifold);
|
||||
|
||||
assert(potentialManifold.potentialContactPointsIndices.size() > 0);
|
||||
|
||||
// For each contact point of the manifold
|
||||
for (uint c=0; c < potentialManifold.potentialContactPointsIndices.size(); c++) {
|
||||
|
||||
ContactPointInfo& potentialContactPoint = potentialContactPoints[potentialManifold.potentialContactPointsIndices[c]];
|
||||
|
||||
// Create a new contact point
|
||||
ContactPoint contactPoint(potentialContactPoint, mWorld->mConfig);
|
||||
|
||||
// Add the contact point
|
||||
contactPoints.add(contactPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the current contacts with the contacts from the previous frame (for warmstarting)
|
||||
void CollisionDetection::initContactsWithPreviousOnes() {
|
||||
|
||||
|
@ -660,46 +788,6 @@ void CollisionDetection::initContactsWithPreviousOnes() {
|
|||
mPreviousContactManifolds->clear();
|
||||
mPreviousContactPairs->clear();
|
||||
mPreviousMapPairIdToContactPairIndex->clear();
|
||||
|
||||
/*
|
||||
// TODO : DELETE THIS
|
||||
std::cout << "_______________ RECAP ACTUAL CONTACTS___________________" << std::endl;
|
||||
std::cout << "ContactPairs :" << std::endl;
|
||||
for (uint i=0; i < mCurrentContactPairs->size(); i++) {
|
||||
|
||||
ContactPair& pair = (*mCurrentContactPairs)[i];
|
||||
std::cout << " PairId : (" << pair.pairId.first << ", " << pair.pairId.second << std::endl;
|
||||
std::cout << " Index : " << i << std::endl;
|
||||
std::cout << " ContactManifoldsIndex : " << pair.contactManifoldsIndex << std::endl;
|
||||
std::cout << " nbManifolds : " << pair.nbContactManifolds << std::endl;
|
||||
std::cout << " ContactPointsIndex : " << pair.contactPointsIndex << std::endl;
|
||||
std::cout << " nbTotalPoints : " << pair.nbToTalContactPoints << std::endl;
|
||||
|
||||
}
|
||||
std::cout << "ContactManifolds :" << std::endl;
|
||||
for (uint i=0; i < mCurrentContactManifolds->size(); i++) {
|
||||
|
||||
ContactManifold& manifold = (*mCurrentContactManifolds)[i];
|
||||
std::cout << " Index : " << i << std::endl;
|
||||
std::cout << " >>ContactPointsIndex : " << manifold.mContactPointsIndex << std::endl;
|
||||
std::cout << " >>Nb Contact Points : " << manifold.mNbContactPoints << std::endl;
|
||||
}
|
||||
std::cout << "ContactPoints :" << std::endl;
|
||||
for (uint i=0; i < mCurrentContactPoints->size(); i++) {
|
||||
|
||||
ContactPoint& contactPoint = (*mCurrentContactPoints)[i];
|
||||
std::cout << " Index : " << i << std::endl;
|
||||
std::cout << " Point : (" << contactPoint.getLocalPointOnShape1().x << ", " << contactPoint.getLocalPointOnShape1().y << ", " << contactPoint.getLocalPointOnShape1().z << std::endl;
|
||||
}
|
||||
std::cout << "mCurrentMapPairIdToContactPairIndex :" << std::endl;
|
||||
for (auto it = mCurrentMapPairIdToContactPairIndex->begin(); it != mCurrentMapPairIdToContactPairIndex->end(); ++it) {
|
||||
|
||||
OverlappingPair::OverlappingPairId pairId = it->first;
|
||||
uint index = it->second;
|
||||
std::cout << " PairId : " << pairId.first << ", " << pairId.second << std::endl;
|
||||
std::cout << " ContactPair Index : " << index << std::endl;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Remove a body from the collision detection
|
||||
|
@ -902,7 +990,7 @@ void CollisionDetection::reducePotentialContactManifolds(List<ContactPair>* cont
|
|||
|
||||
assert(contactPair.potentialContactManifoldsIndices.size() > 0);
|
||||
|
||||
// While there are too many manifolds
|
||||
// While there are too many manifolds in the contact pair
|
||||
while(contactPair.potentialContactManifoldsIndices.size() > mWorld->mConfig.nbMaxContactManifolds) {
|
||||
|
||||
// Look for a manifold with the smallest contact penetration depth.
|
||||
|
@ -1150,32 +1238,32 @@ void CollisionDetection::reduceContactPoints(ContactManifoldInfo& manifold, cons
|
|||
manifold.potentialContactPointsIndices.add(pointsToKeepIndices[3]);
|
||||
}
|
||||
|
||||
// Report contacts for all the colliding overlapping pairs
|
||||
// TODO : What do we do with this method
|
||||
void CollisionDetection::reportAllContacts() {
|
||||
// Report contacts
|
||||
void CollisionDetection::reportContacts() {
|
||||
|
||||
RP3D_PROFILE("CollisionDetection::reportAllContacts()", mProfiler);
|
||||
|
||||
// TODO : Rework how we report contacts
|
||||
/*
|
||||
// For each overlapping pairs in contact during the narrow-phase
|
||||
for (auto it = mOverlappingPairs.begin(); it != mOverlappingPairs.end(); ++it) {
|
||||
|
||||
OverlappingPair* pair = it->second;
|
||||
|
||||
// If there is a user callback
|
||||
if (mWorld->mEventListener != nullptr && pair->hasContacts()) {
|
||||
|
||||
CollisionCallback::CollisionCallbackInfo collisionInfo(pair, mMemoryManager);
|
||||
|
||||
// Trigger a callback event to report the new contact to the user
|
||||
mWorld->mEventListener->newContact(collisionInfo);
|
||||
if (mWorld->mEventListener != nullptr) {
|
||||
reportContacts(*(mWorld->mEventListener), mCurrentContactPairs, mCurrentContactManifolds,
|
||||
mCurrentContactPoints);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Report all contacts
|
||||
void CollisionDetection::reportContacts(CollisionCallback& callback, List<ContactPair>* contactPairs,
|
||||
List<ContactManifold>* manifolds, List<ContactPoint>* contactPoints) {
|
||||
|
||||
RP3D_PROFILE("CollisionDetection::reportContacts()", mProfiler);
|
||||
|
||||
// If there are contacts
|
||||
if (contactPairs->size() > 0) {
|
||||
|
||||
CollisionCallback::CallbackData callbackData(contactPairs, manifolds, contactPoints, *mWorld);
|
||||
|
||||
// Call the callback method to report the contacts
|
||||
callback.onContact(callbackData);
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if two bodies overlap
|
||||
// Return true if two bodies overlap (collide)
|
||||
bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2) {
|
||||
|
||||
NarrowPhaseInput narrowPhaseInput(mMemoryManager.getPoolAllocator());
|
||||
|
@ -1193,16 +1281,14 @@ bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2)
|
|||
computeMiddlePhase(overlappingPairs, narrowPhaseInput);
|
||||
|
||||
// Compute the narrow-phase collision detection
|
||||
return computeNarrowPhaseSnapshot(narrowPhaseInput, true);
|
||||
return computeNarrowPhaseOverlapSnapshot(narrowPhaseInput, nullptr);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Report all the bodies that overlap in the world
|
||||
void CollisionDetection::testOverlap(OverlapCallback* callback) {
|
||||
|
||||
assert(callback != nullptr);
|
||||
// Report all the bodies that overlap (collide) in the world
|
||||
void CollisionDetection::testOverlap(OverlapCallback& callback) {
|
||||
|
||||
NarrowPhaseInput narrowPhaseInput(mMemoryManager.getPoolAllocator());
|
||||
|
||||
|
@ -1212,16 +1298,12 @@ void CollisionDetection::testOverlap(OverlapCallback* callback) {
|
|||
// Compute the middle-phase collision detection
|
||||
computeMiddlePhase(mOverlappingPairs, narrowPhaseInput);
|
||||
|
||||
// Compute the narrow-phase collision detection
|
||||
computeNarrowPhaseSnapshot(narrowPhaseInput, false);
|
||||
|
||||
// TODO : Report overlaps
|
||||
// Compute the narrow-phase collision detection and report overlapping shapes
|
||||
computeNarrowPhaseOverlapSnapshot(narrowPhaseInput, &callback);
|
||||
}
|
||||
|
||||
// Report all the bodies that overlap with the body in parameter
|
||||
void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* callback) {
|
||||
|
||||
assert(callback != nullptr);
|
||||
// Report all the bodies that overlap (collide) with the body in parameter
|
||||
void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback& callback) {
|
||||
|
||||
NarrowPhaseInput narrowPhaseInput(mMemoryManager.getPoolAllocator());
|
||||
|
||||
|
@ -1238,16 +1320,12 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* callb
|
|||
computeMiddlePhase(overlappingPairs, narrowPhaseInput);
|
||||
|
||||
// Compute the narrow-phase collision detection
|
||||
computeNarrowPhaseSnapshot(narrowPhaseInput, false);
|
||||
|
||||
// TODO : Report contacts
|
||||
computeNarrowPhaseOverlapSnapshot(narrowPhaseInput, &callback);
|
||||
}
|
||||
}
|
||||
|
||||
// Test collision and report contacts between two bodies.
|
||||
void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body2, CollisionCallback* callback) {
|
||||
|
||||
assert(callback != nullptr);
|
||||
void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body2, CollisionCallback& callback) {
|
||||
|
||||
NarrowPhaseInput narrowPhaseInput(mMemoryManager.getPoolAllocator());
|
||||
|
||||
|
@ -1263,17 +1341,13 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
|
|||
// Compute the middle-phase collision detection
|
||||
computeMiddlePhase(overlappingPairs, narrowPhaseInput);
|
||||
|
||||
// Compute the narrow-phase collision detection
|
||||
computeNarrowPhaseSnapshot(narrowPhaseInput, true);
|
||||
|
||||
// TODO : Report contacts
|
||||
// Compute the narrow-phase collision detection and report contacts
|
||||
computeNarrowPhaseCollisionSnapshot(narrowPhaseInput, callback);
|
||||
}
|
||||
}
|
||||
|
||||
// Test collision and report all the contacts involving the body in parameter
|
||||
void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* callback) {
|
||||
|
||||
assert(callback != nullptr);
|
||||
void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback& callback) {
|
||||
|
||||
NarrowPhaseInput narrowPhaseInput(mMemoryManager.getPoolAllocator());
|
||||
|
||||
|
@ -1289,17 +1363,13 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
|
|||
// Compute the middle-phase collision detection
|
||||
computeMiddlePhase(overlappingPairs, narrowPhaseInput);
|
||||
|
||||
// Compute the narrow-phase collision detection
|
||||
computeNarrowPhaseSnapshot(narrowPhaseInput, true);
|
||||
|
||||
// TODO : Report contacts
|
||||
// Compute the narrow-phase collision detection and report contacts
|
||||
computeNarrowPhaseCollisionSnapshot(narrowPhaseInput, callback);
|
||||
}
|
||||
}
|
||||
|
||||
// Test collision and report contacts between each colliding bodies in the world
|
||||
void CollisionDetection::testCollision(CollisionCallback* callback) {
|
||||
|
||||
assert(callback != nullptr);
|
||||
void CollisionDetection::testCollision(CollisionCallback& callback) {
|
||||
|
||||
NarrowPhaseInput narrowPhaseInput(mMemoryManager.getPoolAllocator());
|
||||
|
||||
|
@ -1309,10 +1379,8 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
|
|||
// Compute the middle-phase collision detection
|
||||
computeMiddlePhase(mOverlappingPairs, narrowPhaseInput);
|
||||
|
||||
// Compute the narrow-phase collision detection
|
||||
computeNarrowPhaseSnapshot(narrowPhaseInput, true);
|
||||
|
||||
// TODO : Report contacts
|
||||
// Compute the narrow-phase collision detection and report contacts
|
||||
computeNarrowPhaseCollisionSnapshot(narrowPhaseInput, callback);
|
||||
}
|
||||
|
||||
// Filter the overlapping pairs to keep only the pairs where a given body is involved
|
||||
|
|
|
@ -186,8 +186,17 @@ class CollisionDetection {
|
|||
/// Compute the narrow-phase collision detection
|
||||
void computeNarrowPhase();
|
||||
|
||||
/// Compute the narrow-phase collision detection for the testOverlap() methods.
|
||||
bool computeNarrowPhaseOverlapSnapshot(NarrowPhaseInput& narrowPhaseInput, OverlapCallback* callback);
|
||||
|
||||
/// Compute the narrow-phase collision detection for the testCollision() methods
|
||||
bool computeNarrowPhaseSnapshot(NarrowPhaseInput& narrowPhaseInput, bool reportContacts);
|
||||
bool computeNarrowPhaseCollisionSnapshot(NarrowPhaseInput& narrowPhaseInput, CollisionCallback& callback);
|
||||
|
||||
/// Process the potential contacts after narrow-phase collision detection
|
||||
void computeSnapshotContactPairs(NarrowPhaseInput& narrowPhaseInput, List<Pair<Entity, Entity>>& overlapPairs) const;
|
||||
|
||||
/// Convert the potential contact into actual contacts
|
||||
void computeSnapshotContactPairs(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, List<Pair<Entity, Entity>>& overlapPairs) const;
|
||||
|
||||
/// Take a list of overlapping nodes in the broad-phase and create new overlapping pairs if necessary
|
||||
void updateOverlappingPairs(const List<Pair<int, int>>& overlappingNodes);
|
||||
|
@ -225,6 +234,12 @@ class CollisionDetection {
|
|||
/// Create the actual contact manifolds and contacts points (from potential contacts) for a given contact pair
|
||||
void createContacts();
|
||||
|
||||
/// Create the actual contact manifolds and contacts points for testCollision() methods
|
||||
void createSnapshotContacts(List<ContactPair>& contactPairs, List<ContactManifold> &contactManifolds,
|
||||
List<ContactPoint>& contactPoints,
|
||||
List<ContactManifoldInfo>& potentialContactManifolds,
|
||||
List<ContactPointInfo>& potentialContactPoints);
|
||||
|
||||
/// Initialize the current contacts with the contacts from the previous frame (for warmstarting)
|
||||
void initContactsWithPreviousOnes();
|
||||
|
||||
|
@ -232,8 +247,9 @@ class CollisionDetection {
|
|||
void reduceContactPoints(ContactManifoldInfo& manifold, const Transform& shape1ToWorldTransform,
|
||||
const List<ContactPointInfo>& potentialContactPoints) const;
|
||||
|
||||
/// Report contacts for all the colliding overlapping pairs
|
||||
void reportAllContacts();
|
||||
/// Report contacts
|
||||
void reportContacts(CollisionCallback& callback, List<ContactPair>* contactPairs,
|
||||
List<ContactManifold>* manifolds, List<ContactPoint>* contactPoints);
|
||||
|
||||
/// Return the largest depth of all the contact points of a potential manifold
|
||||
decimal computePotentialManifoldLargestContactDepth(const ContactManifoldInfo& manifold,
|
||||
|
@ -290,6 +306,9 @@ class CollisionDetection {
|
|||
/// Ask for a collision shape to be tested again during broad-phase.
|
||||
void askForBroadPhaseCollisionCheck(ProxyShape* shape);
|
||||
|
||||
/// Report contacts
|
||||
void reportContacts();
|
||||
|
||||
/// Compute the collision detection
|
||||
void computeCollisionDetection();
|
||||
|
||||
|
@ -301,19 +320,19 @@ class CollisionDetection {
|
|||
bool testOverlap(CollisionBody* body1, CollisionBody* body2);
|
||||
|
||||
/// Report all the bodies that overlap (collide) with the body in parameter
|
||||
void testOverlap(CollisionBody* body, OverlapCallback* callback);
|
||||
void testOverlap(CollisionBody* body, OverlapCallback& callback);
|
||||
|
||||
/// Report all the bodies that overlap (collide) in the world
|
||||
void testOverlap(OverlapCallback* overlapCallback);
|
||||
void testOverlap(OverlapCallback& overlapCallback);
|
||||
|
||||
/// Test collision and report contacts between two bodies.
|
||||
void testCollision(CollisionBody* body1, CollisionBody* body2, CollisionCallback* callback);
|
||||
void testCollision(CollisionBody* body1, CollisionBody* body2, CollisionCallback& callback);
|
||||
|
||||
/// Test collision and report all the contacts involving the body in parameter
|
||||
void testCollision(CollisionBody* body, CollisionCallback* callback);
|
||||
void testCollision(CollisionBody* body, CollisionCallback& callback);
|
||||
|
||||
/// Test collision and report contacts between each colliding bodies in the world
|
||||
void testCollision(CollisionCallback* callback);
|
||||
void testCollision(CollisionCallback& callback);
|
||||
|
||||
/// Return a reference to the memory manager
|
||||
MemoryManager& getMemoryManager() const;
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
// TODO : REMOVE worldSettings from this constructor
|
||||
ContactManifold::ContactManifold(Entity bodyEntity1, Entity bodyEntity2, Entity proxyShapeEntity1, Entity proxyShapeEntity2,
|
||||
uint contactPointsIndex, int8 nbContactPoints)
|
||||
:mContactPointsIndex(0), bodyEntity1(bodyEntity1), bodyEntity2(bodyEntity2),
|
||||
|
|
|
@ -162,9 +162,6 @@ class ContactManifold {
|
|||
/// Return the number of contact points in the manifold
|
||||
int8 getNbContactPoints() const;
|
||||
|
||||
/// Return a pointer to the first contact point of the manifold
|
||||
ContactPoint* getContactPoints() const;
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class DynamicsWorld;
|
||||
|
|
53
src/collision/OverlapCallback.cpp
Normal file
53
src/collision/OverlapCallback.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||
* Copyright (c) 2010-2018 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. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "collision/OverlapCallback.h"
|
||||
#include "engine/CollisionWorld.h"
|
||||
|
||||
// We want to use the ReactPhysics3D namespace
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Contact Pair Constructor
|
||||
OverlapCallback::OverlapPair::OverlapPair(Pair<Entity, Entity>& overlapPair, CollisionWorld& world)
|
||||
: mOverlapPair(overlapPair), mWorld(world) {
|
||||
|
||||
}
|
||||
|
||||
// Return a pointer to the first body in contact
|
||||
CollisionBody* OverlapCallback::OverlapPair::getBody1() const {
|
||||
return static_cast<CollisionBody*>(mWorld.mBodyComponents.getBody(mOverlapPair.first));
|
||||
}
|
||||
|
||||
// Return a pointer to the second body in contact
|
||||
CollisionBody* OverlapCallback::OverlapPair::getBody2() const {
|
||||
return static_cast<CollisionBody*>(mWorld.mBodyComponents.getBody(mOverlapPair.second));
|
||||
}
|
||||
|
||||
// CollisionCallbackData Constructor
|
||||
OverlapCallback::CallbackData::CallbackData(List<Pair<Entity, Entity>>& overlapBodies, CollisionWorld& world)
|
||||
:mOverlapBodies(overlapBodies), mWorld(world) {
|
||||
|
||||
}
|
|
@ -26,32 +26,141 @@
|
|||
#ifndef REACTPHYSICS3D_OVERLAP_CALLBACK_H
|
||||
#define REACTPHYSICS3D_OVERLAP_CALLBACK_H
|
||||
|
||||
// Libraries
|
||||
#include "containers/List.h"
|
||||
|
||||
/// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
||||
// Declarations
|
||||
class CollisionBody;
|
||||
class CollisionWorld;
|
||||
class ProxyShape;
|
||||
struct Entity;
|
||||
|
||||
// Class OverlapCallback
|
||||
/**
|
||||
* This class can be used to register a callback for collision overlap queries.
|
||||
* You should implement your own class inherited from this one and implement
|
||||
* the notifyOverlap() method. This method will called each time a contact
|
||||
* point is reported.
|
||||
* This class can be used to register a callback for collision overlap queries between bodies.
|
||||
* You should implement your own class inherited from this one and implement the onOverlap() method.
|
||||
*/
|
||||
class OverlapCallback {
|
||||
|
||||
public:
|
||||
|
||||
// Class OverlapPair
|
||||
/**
|
||||
* This class represents the contact between two proxy-shapes of the physics world.
|
||||
*/
|
||||
class OverlapPair {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Pair of overlapping body entities
|
||||
Pair<Entity, Entity>& mOverlapPair;
|
||||
|
||||
/// Reference to the physics world
|
||||
CollisionWorld& mWorld;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
OverlapPair(Pair<Entity, Entity>& overlapPair, CollisionWorld& world);
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Copy constructor
|
||||
OverlapPair(const OverlapPair& contactPair) = default;
|
||||
|
||||
/// Assignment operator
|
||||
OverlapPair& operator=(const OverlapPair& contactPair) = default;
|
||||
|
||||
/// Destructor
|
||||
~OverlapPair() = default;
|
||||
|
||||
/// Return a pointer to the first body in contact
|
||||
CollisionBody* getBody1() const;
|
||||
|
||||
/// Return a pointer to the second body in contact
|
||||
CollisionBody* getBody2() const;
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class OverlapCallback;
|
||||
};
|
||||
|
||||
// Class CallbackData
|
||||
/**
|
||||
* This class contains data about overlap between bodies
|
||||
*/
|
||||
class CallbackData {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
List<Pair<Entity, Entity>>& mOverlapBodies;
|
||||
|
||||
/// Reference to the physics world
|
||||
CollisionWorld& mWorld;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
CallbackData(List<Pair<Entity, Entity>>& overlapProxyShapes, CollisionWorld& world);
|
||||
|
||||
/// Deleted copy constructor
|
||||
CallbackData(const CallbackData& callbackData) = delete;
|
||||
|
||||
/// Deleted assignment operator
|
||||
CallbackData& operator=(const CallbackData& callbackData) = delete;
|
||||
|
||||
/// Destructor
|
||||
~CallbackData() = default;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Return the number of overlapping pairs of bodies
|
||||
uint getNbOverlappingPairs() const;
|
||||
|
||||
/// Return a given overlapping pair of bodies
|
||||
OverlapPair getOverlappingPair(uint index) const;
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class CollisionDetection;
|
||||
};
|
||||
|
||||
/// Destructor
|
||||
virtual ~OverlapCallback() {
|
||||
|
||||
}
|
||||
|
||||
/// This method will be called for each reported overlapping bodies
|
||||
virtual void notifyOverlap(CollisionBody* collisionBody)=0;
|
||||
/// This method will be called to report bodies that overlap
|
||||
virtual void onOverlap(CallbackData& callbackData)=0;
|
||||
};
|
||||
|
||||
// Return the number of overlapping pairs of bodies
|
||||
inline uint OverlapCallback::CallbackData::getNbOverlappingPairs() const {
|
||||
return mOverlapBodies.size();
|
||||
}
|
||||
|
||||
// Return a given overlapping pair of bodies
|
||||
/// Note that the returned OverlapPair object is only valid during the call of the CollisionCallback::onOverlap()
|
||||
/// method. Therefore, you need to get contact data from it and make a copy. Do not make a copy of the OverlapPair
|
||||
/// object itself because it won't be valid after the CollisionCallback::onOverlap() call.
|
||||
inline OverlapCallback::OverlapPair OverlapCallback::CallbackData::getOverlappingPair(uint index) const {
|
||||
|
||||
assert(index < getNbOverlappingPairs());
|
||||
|
||||
return OverlapPair(mOverlapBodies[index], mWorld);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -78,10 +78,6 @@ void NarrowPhaseInfoBatch::addContactPoint(uint index, const Vector3& contactNor
|
|||
ContactPointInfo* contactPointInfo = new (allocator.allocate(sizeof(ContactPointInfo)))
|
||||
ContactPointInfo(contactNormal, penDepth, localPt1, localPt2);
|
||||
|
||||
// TODO : DELETE THIS
|
||||
//std::cout << "Pair: " << overlappingPairs[index]->getId().first << ", " << overlappingPairs[index]->getId().second << std::endl;
|
||||
//std::cout << ">> Contact Point: " << localPt1.x << ", " << localPt1.y << ", " << localPt1.z << std::endl;
|
||||
|
||||
// Add it into the list of contact points
|
||||
contactPoints[index].add(contactPointInfo);
|
||||
}
|
||||
|
|
|
@ -93,18 +93,6 @@ class ContactPoint {
|
|||
/// Set the mIsRestingContact variable
|
||||
void setIsRestingContact(bool isRestingContact);
|
||||
|
||||
/// Set to true to make the contact point obsolete
|
||||
void setIsObsolete(bool isObselete);
|
||||
|
||||
/// Set the next contact point in the linked list
|
||||
void setNext(ContactPoint* next);
|
||||
|
||||
/// Set the previous contact point in the linked list
|
||||
void setPrevious(ContactPoint* previous);
|
||||
|
||||
/// Return true if the contact point is obsolete
|
||||
bool getIsObsolete() const;
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
@ -139,12 +127,6 @@ class ContactPoint {
|
|||
/// Return true if the contact is a resting contact
|
||||
bool getIsRestingContact() const;
|
||||
|
||||
/// Return the previous contact point in the linked list
|
||||
inline ContactPoint* getPrevious() const;
|
||||
|
||||
/// Return the next contact point in the linked list
|
||||
ContactPoint* getNext() const;
|
||||
|
||||
/// Return the penetration depth
|
||||
decimal getPenetrationDepth() const;
|
||||
|
||||
|
@ -220,54 +202,6 @@ inline void ContactPoint::setIsRestingContact(bool isRestingContact) {
|
|||
mIsRestingContact = isRestingContact;
|
||||
}
|
||||
|
||||
// Return true if the contact point is obsolete
|
||||
/**
|
||||
* @return True if the contact is obsolete
|
||||
*/
|
||||
inline bool ContactPoint::getIsObsolete() const {
|
||||
return mIsObsolete;
|
||||
}
|
||||
|
||||
// Set to true to make the contact point obsolete
|
||||
/**
|
||||
* @param isObsolete True if the contact is obsolete
|
||||
*/
|
||||
inline void ContactPoint::setIsObsolete(bool isObsolete) {
|
||||
mIsObsolete = isObsolete;
|
||||
}
|
||||
|
||||
// Return the next contact point in the linked list
|
||||
/**
|
||||
* @return A pointer to the next contact point in the linked-list of points
|
||||
*/
|
||||
inline ContactPoint* ContactPoint::getNext() const {
|
||||
return mNext;
|
||||
}
|
||||
|
||||
// Set the next contact point in the linked list
|
||||
/**
|
||||
* @param next Pointer to the next contact point in the linked-list of points
|
||||
*/
|
||||
inline void ContactPoint::setNext(ContactPoint* next) {
|
||||
mNext = next;
|
||||
}
|
||||
|
||||
// Return the previous contact point in the linked list
|
||||
/**
|
||||
* @return A pointer to the previous contact point in the linked-list of points
|
||||
*/
|
||||
inline ContactPoint* ContactPoint::getPrevious() const {
|
||||
return mPrevious;
|
||||
}
|
||||
|
||||
// Set the previous contact point in the linked list
|
||||
/**
|
||||
* @param previous Pointer to the previous contact point in the linked-list of points
|
||||
*/
|
||||
inline void ContactPoint::setPrevious(ContactPoint* previous) {
|
||||
mPrevious = previous;
|
||||
}
|
||||
|
||||
// Return the penetration depth of the contact
|
||||
/**
|
||||
* @return the penetration depth (in meters)
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "components/TransformComponents.h"
|
||||
#include "components/ProxyShapeComponents.h"
|
||||
#include "components/DynamicsComponents.h"
|
||||
#include "collision/CollisionCallback.h"
|
||||
#include "collision/OverlapCallback.h"
|
||||
|
||||
/// Namespace reactphysics3d
|
||||
namespace reactphysics3d {
|
||||
|
@ -166,19 +168,19 @@ class CollisionWorld {
|
|||
bool testOverlap(CollisionBody* body1, CollisionBody* body2);
|
||||
|
||||
/// Report all the bodies that overlap (collide) with the body in parameter
|
||||
void testOverlap(CollisionBody* body, OverlapCallback* overlapCallback);
|
||||
void testOverlap(CollisionBody* body, OverlapCallback& overlapCallback);
|
||||
|
||||
/// Report all the bodies that overlap (collide) in the world
|
||||
void testOverlap(OverlapCallback* overlapCallback);
|
||||
void testOverlap(OverlapCallback& overlapCallback);
|
||||
|
||||
/// Test collision and report contacts between two bodies.
|
||||
void testCollision(CollisionBody* body1, CollisionBody* body2, CollisionCallback* callback);
|
||||
void testCollision(CollisionBody* body1, CollisionBody* body2, CollisionCallback& callback);
|
||||
|
||||
/// Test collision and report all the contacts involving the body in parameter
|
||||
void testCollision(CollisionBody* body, CollisionCallback* callback);
|
||||
void testCollision(CollisionBody* body, CollisionCallback& callback);
|
||||
|
||||
/// Test collision and report contacts between each colliding bodies in the world
|
||||
void testCollision(CollisionCallback* callback);
|
||||
void testCollision(CollisionCallback& callback);
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
|
@ -207,6 +209,8 @@ class CollisionWorld {
|
|||
friend class RigidBody;
|
||||
friend class ProxyShape;
|
||||
friend class ConvexMeshShape;
|
||||
friend class CollisionCallback::ContactPair;
|
||||
friend class OverlapCallback::OverlapPair;
|
||||
};
|
||||
|
||||
// Set the collision dispatch configuration
|
||||
|
@ -243,7 +247,7 @@ inline void CollisionWorld::raycast(const Ray& ray,
|
|||
* @param body2 Pointer to the second body to test
|
||||
* @param callback Pointer to the object with the callback method
|
||||
*/
|
||||
inline void CollisionWorld::testCollision(CollisionBody* body1, CollisionBody* body2, CollisionCallback* callback) {
|
||||
inline void CollisionWorld::testCollision(CollisionBody* body1, CollisionBody* body2, CollisionCallback& callback) {
|
||||
mCollisionDetection.testCollision(body1, body2, callback);
|
||||
}
|
||||
|
||||
|
@ -256,7 +260,7 @@ inline void CollisionWorld::testCollision(CollisionBody* body1, CollisionBody* b
|
|||
* @param body Pointer to the body against which we need to test collision
|
||||
* @param callback Pointer to the object with the callback method to report contacts
|
||||
*/
|
||||
inline void CollisionWorld::testCollision(CollisionBody* body, CollisionCallback* callback) {
|
||||
inline void CollisionWorld::testCollision(CollisionBody* body, CollisionCallback& callback) {
|
||||
mCollisionDetection.testCollision(body, callback);
|
||||
}
|
||||
|
||||
|
@ -268,7 +272,7 @@ inline void CollisionWorld::testCollision(CollisionBody* body, CollisionCallback
|
|||
/**
|
||||
* @param callback Pointer to the object with the callback method to report contacts
|
||||
*/
|
||||
inline void CollisionWorld::testCollision(CollisionCallback* callback) {
|
||||
inline void CollisionWorld::testCollision(CollisionCallback& callback) {
|
||||
mCollisionDetection.testCollision(callback);
|
||||
}
|
||||
|
||||
|
@ -280,7 +284,7 @@ inline void CollisionWorld::testCollision(CollisionCallback* callback) {
|
|||
* @param body Pointer to the collision body to test overlap with
|
||||
* @param overlapCallback Pointer to the callback class to report overlap
|
||||
*/
|
||||
inline void CollisionWorld::testOverlap(CollisionBody* body, OverlapCallback* overlapCallback) {
|
||||
inline void CollisionWorld::testOverlap(CollisionBody* body, OverlapCallback& overlapCallback) {
|
||||
mCollisionDetection.testOverlap(body, overlapCallback);
|
||||
}
|
||||
|
||||
|
@ -288,7 +292,7 @@ inline void CollisionWorld::testOverlap(CollisionBody* body, OverlapCallback* ov
|
|||
/// Use this method if you are not interested in contacts but if you simply want to know
|
||||
/// which bodies overlap. If you want to get the contacts, you need to use the
|
||||
/// testCollision() method instead.
|
||||
inline void CollisionWorld::testOverlap(OverlapCallback* overlapCallback) {
|
||||
inline void CollisionWorld::testOverlap(OverlapCallback& overlapCallback) {
|
||||
mCollisionDetection.testOverlap(overlapCallback);
|
||||
}
|
||||
|
||||
|
|
|
@ -126,6 +126,9 @@ void DynamicsWorld::update(decimal timeStep) {
|
|||
// Create the actual narrow-phase contacts
|
||||
mCollisionDetection.createContacts();
|
||||
|
||||
// Report the contacts to the user
|
||||
mCollisionDetection.reportContacts();
|
||||
|
||||
// Integrate the velocities
|
||||
integrateRigidBodiesVelocities();
|
||||
|
||||
|
@ -876,36 +879,3 @@ void DynamicsWorld::enableSleeping(bool isSleepingEnabled) {
|
|||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Dynamics World: isSleepingEnabled=" + (isSleepingEnabled ? std::string("true") : std::string("false")) );
|
||||
}
|
||||
|
||||
// Return the list of all contacts of the world
|
||||
/**
|
||||
* @return A pointer to the first contact manifold in the linked-list of manifolds
|
||||
*/
|
||||
List<const ContactManifold*> DynamicsWorld::getContactsList() {
|
||||
|
||||
List<const ContactManifold*> contactManifolds(mMemoryManager.getPoolAllocator());
|
||||
|
||||
// TODO : Rework how to report contacts
|
||||
/*
|
||||
// For each currently overlapping pair of bodies
|
||||
for (auto it = mCollisionDetection.mOverlappingPairs.begin();
|
||||
it != mCollisionDetection.mOverlappingPairs.end(); ++it) {
|
||||
|
||||
OverlappingPair* pair = it->second;
|
||||
|
||||
// For each contact manifold of the pair
|
||||
const ContactManifoldSet& manifoldSet = pair->getContactManifoldSet();
|
||||
ContactManifold* manifold = manifoldSet.getContactManifolds();
|
||||
while (manifold != nullptr) {
|
||||
|
||||
// Get the contact manifold
|
||||
contactManifolds.add(manifold);
|
||||
|
||||
manifold = manifold->getNext();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Return all the contact manifold
|
||||
return contactManifolds;
|
||||
}
|
||||
|
|
|
@ -240,9 +240,6 @@ class DynamicsWorld : public CollisionWorld {
|
|||
/// Set an event listener object to receive events callbacks.
|
||||
void setEventListener(EventListener* eventListener);
|
||||
|
||||
/// Return the list of all contacts of the world
|
||||
List<const ContactManifold*> getContactsList();
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class RigidBody;
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace reactphysics3d {
|
|||
* new event listener class to the physics world using the DynamicsWorld::setEventListener()
|
||||
* method.
|
||||
*/
|
||||
class EventListener {
|
||||
class EventListener : public CollisionCallback {
|
||||
|
||||
public :
|
||||
|
||||
|
@ -47,20 +47,22 @@ class EventListener {
|
|||
EventListener() = default;
|
||||
|
||||
/// Destructor
|
||||
virtual ~EventListener() = default;
|
||||
virtual ~EventListener() override = default;
|
||||
|
||||
/// Called when a new contact point is found between two bodies
|
||||
/// Called when some contacts occur
|
||||
/**
|
||||
* @param contact Information about the contact
|
||||
* @param collisionInfo Information about the contacts
|
||||
*/
|
||||
virtual void newContact(const CollisionCallback::CollisionCallbackInfo& collisionInfo) {}
|
||||
virtual void onContact(const CollisionCallback::CallbackData& callbackData) override {}
|
||||
|
||||
// TODO : Remove this method (no internal steps anymore)
|
||||
/// Called at the beginning of an internal tick of the simulation step.
|
||||
/// Each time the DynamicsWorld::update() method is called, the physics
|
||||
/// engine will do several internal simulation steps. This method is
|
||||
/// called at the beginning of each internal simulation step.
|
||||
virtual void beginInternalTick() {}
|
||||
|
||||
// TODO : Remove this method (no internal steps anymore)
|
||||
/// Called at the end of an internal tick of the simulation step.
|
||||
/// Each time the DynamicsWorld::update() metho is called, the physics
|
||||
/// engine will do several internal simulation steps. This method is
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -35,7 +35,7 @@ using namespace collisiondetectionscene;
|
|||
// Constructor
|
||||
CollisionDetectionScene::CollisionDetectionScene(const std::string& name, EngineSettings& settings)
|
||||
: SceneDemo(name, settings, SCENE_RADIUS, false), mMeshFolderPath("meshes/"),
|
||||
mContactManager(mPhongShader, mMeshFolderPath),
|
||||
mContactManager(mPhongShader, mMeshFolderPath, mContactPoints),
|
||||
mAreNormalsDisplayed(false) {
|
||||
|
||||
mSelectedShapeIndex = 0;
|
||||
|
@ -160,6 +160,8 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
|
|||
// Reset the scene
|
||||
void CollisionDetectionScene::reset() {
|
||||
|
||||
SceneDemo::reset();
|
||||
|
||||
mSphere1->setTransform(rp3d::Transform(rp3d::Vector3(15, 5, 0), rp3d::Quaternion::identity()));
|
||||
mSphere2->setTransform(rp3d::Transform(rp3d::Vector3(0, 6, 0), rp3d::Quaternion::identity()));
|
||||
mCapsule1->setTransform(rp3d::Transform(rp3d::Vector3(-8, 7, 0), rp3d::Quaternion::identity()));
|
||||
|
@ -206,8 +208,6 @@ CollisionDetectionScene::~CollisionDetectionScene() {
|
|||
mPhysicsWorld->destroyCollisionBody(mHeightField->getCollisionBody());
|
||||
delete mHeightField;
|
||||
|
||||
mContactManager.resetPoints();
|
||||
|
||||
// Destroy the static data for the visual contact points
|
||||
VisualContactPoint::destroyStaticData();
|
||||
|
||||
|
@ -218,9 +218,9 @@ CollisionDetectionScene::~CollisionDetectionScene() {
|
|||
// Take a step for the simulation
|
||||
void CollisionDetectionScene::update() {
|
||||
|
||||
mContactManager.resetPoints();
|
||||
mContactPoints.clear();
|
||||
|
||||
mPhysicsWorld->testCollision(&mContactManager);
|
||||
mPhysicsWorld->testCollision(mContactManager);
|
||||
|
||||
SceneDemo::update();
|
||||
}
|
||||
|
@ -313,41 +313,33 @@ bool CollisionDetectionScene::keyboardEvent(int key, int scancode, int action, i
|
|||
return false;
|
||||
}
|
||||
|
||||
// This method will be called for each reported contact point
|
||||
void ContactManager::notifyContact(const CollisionCallbackInfo& collisionCallbackInfo) {
|
||||
// This method is called when some contacts occur
|
||||
void ContactManager::onContact(const CallbackData& callbackData) {
|
||||
|
||||
// TODO : Rework how to report contacts
|
||||
/*
|
||||
// For each contact manifold
|
||||
rp3d::ContactManifoldListElement* manifoldElement = collisionCallbackInfo.contactManifoldElements;
|
||||
while (manifoldElement != nullptr) {
|
||||
// For each contact pair
|
||||
for (uint p=0; p < callbackData.getNbContactPairs(); p++) {
|
||||
|
||||
// Get the contact manifold
|
||||
rp3d::ContactManifold* contactManifold = manifoldElement->getContactManifold();
|
||||
ContactPair contactPair = callbackData.getContactPair(p);
|
||||
|
||||
// For each contact point
|
||||
rp3d::ContactPoint* contactPoint = contactManifold->getContactPoints();
|
||||
while (contactPoint != nullptr) {
|
||||
// For each contact point of the contact pair
|
||||
for (uint c=0; c < contactPair.getNbContactPoints(); c++) {
|
||||
|
||||
ContactPoint contactPoint = contactPair.getContactPoint(c);
|
||||
|
||||
// Contact normal
|
||||
rp3d::Vector3 normal = contactPoint->getNormal();
|
||||
rp3d::Vector3 normal = contactPoint.getWorldNormal();
|
||||
openglframework::Vector3 contactNormal(normal.x, normal.y, normal.z);
|
||||
|
||||
rp3d::Vector3 point1 = contactPoint->getLocalPointOnShape1();
|
||||
point1 = collisionCallbackInfo.proxyShape1->getLocalToWorldTransform() * point1;
|
||||
rp3d::Vector3 point1 = contactPoint.getLocalPointOnShape1();
|
||||
point1 = contactPair.getProxyShape1()->getLocalToWorldTransform() * point1;
|
||||
|
||||
openglframework::Vector3 position1(point1.x, point1.y, point1.z);
|
||||
mContactPoints.push_back(ContactPoint(position1, contactNormal, openglframework::Color::red()));
|
||||
mContactPoints.push_back(SceneContactPoint(position1, contactNormal, openglframework::Color::red()));
|
||||
|
||||
rp3d::Vector3 point2 = contactPoint->getLocalPointOnShape2();
|
||||
point2 = collisionCallbackInfo.proxyShape2->getLocalToWorldTransform() * point2;
|
||||
rp3d::Vector3 point2 = contactPoint.getLocalPointOnShape2();
|
||||
point2 = contactPair.getProxyShape2()->getLocalToWorldTransform() * point2;
|
||||
openglframework::Vector3 position2(point2.x, point2.y, point2.z);
|
||||
mContactPoints.push_back(ContactPoint(position2, contactNormal, openglframework::Color::blue()));
|
||||
|
||||
contactPoint = contactPoint->getNext();
|
||||
mContactPoints.push_back(SceneContactPoint(position2, contactNormal, openglframework::Color::blue()));
|
||||
}
|
||||
|
||||
manifoldElement = manifoldElement->getNext();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -63,30 +63,22 @@ class ContactManager : public rp3d::CollisionCallback {
|
|||
|
||||
private:
|
||||
|
||||
/// All the visual contact points
|
||||
std::vector<ContactPoint> mContactPoints;
|
||||
|
||||
/// Contact point mesh folder path
|
||||
std::string mMeshFolderPath;
|
||||
|
||||
/// Reference to the list of all the visual contact points
|
||||
std::vector<SceneContactPoint>& mContactPoints;
|
||||
|
||||
public:
|
||||
|
||||
ContactManager(openglframework::Shader& shader, const std::string& meshFolderPath)
|
||||
: mMeshFolderPath(meshFolderPath) {
|
||||
ContactManager(openglframework::Shader& shader, const std::string& meshFolderPath,
|
||||
std::vector<SceneContactPoint>& contactPoints)
|
||||
: mMeshFolderPath(meshFolderPath), mContactPoints(contactPoints) {
|
||||
|
||||
}
|
||||
|
||||
/// This method will be called for each reported contact point
|
||||
virtual void notifyContact(const CollisionCallbackInfo& collisionCallbackInfo) override;
|
||||
|
||||
void resetPoints() {
|
||||
|
||||
mContactPoints.clear();
|
||||
}
|
||||
|
||||
std::vector<ContactPoint> getContactPoints() const {
|
||||
return mContactPoints;
|
||||
}
|
||||
/// This method is called when some contacts occur
|
||||
virtual void onContact(const CallbackData& callbackData) override;
|
||||
};
|
||||
|
||||
// Class CollisionDetectionScene
|
||||
|
@ -151,9 +143,6 @@ class CollisionDetectionScene : public SceneDemo {
|
|||
|
||||
/// Display/Hide the contact points
|
||||
virtual void setIsContactPointsDisplayed(bool display) override;
|
||||
|
||||
/// Return all the contact points of the scene
|
||||
virtual std::vector<ContactPoint> getContactPoints() override;
|
||||
};
|
||||
|
||||
// Display or not the surface normals at hit points
|
||||
|
@ -171,11 +160,6 @@ inline void CollisionDetectionScene::setIsContactPointsDisplayed(bool display) {
|
|||
SceneDemo::setIsContactPointsDisplayed(true);
|
||||
}
|
||||
|
||||
// Return all the contact points of the scene
|
||||
inline std::vector<ContactPoint> CollisionDetectionScene::getContactPoints() {
|
||||
return mContactManager.getContactPoints();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -49,7 +49,9 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
|
|||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
rp3d::DynamicsWorld* dynamicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
dynamicsWorld->setEventListener(this);
|
||||
mPhysicsWorld = dynamicsWorld;
|
||||
|
||||
for (int i=0; i<NB_COMPOUND_SHAPES; i++) {
|
||||
|
||||
|
@ -199,6 +201,8 @@ CollisionShapesScene::~CollisionShapesScene() {
|
|||
/// Reset the scene
|
||||
void CollisionShapesScene::reset() {
|
||||
|
||||
SceneDemo::reset();
|
||||
|
||||
const float radius = 3.0f;
|
||||
|
||||
for (uint i = 0; i<NB_COMPOUND_SHAPES; i++) {
|
||||
|
|
|
@ -99,16 +99,8 @@ class CollisionShapesScene : public SceneDemo {
|
|||
|
||||
/// Reset the scene
|
||||
virtual void reset() override;
|
||||
|
||||
/// Return all the contact points of the scene
|
||||
virtual std::vector<ContactPoint> getContactPoints() override;
|
||||
};
|
||||
|
||||
// Return all the contact points of the scene
|
||||
inline std::vector<ContactPoint> CollisionShapesScene::getContactPoints() {
|
||||
return computeContactPointsOfWorld(getDynamicsWorld());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -49,7 +49,9 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
|
|||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
rp3d::DynamicsWorld* dynamicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
dynamicsWorld->setEventListener(this);
|
||||
mPhysicsWorld = dynamicsWorld;
|
||||
|
||||
// ---------- Create the boxes ----------- //
|
||||
for (int i = 0; i<NB_COMPOUND_SHAPES; i++) {
|
||||
|
@ -206,6 +208,8 @@ ConcaveMeshScene::~ConcaveMeshScene() {
|
|||
// Reset the scene
|
||||
void ConcaveMeshScene::reset() {
|
||||
|
||||
SceneDemo::reset();
|
||||
|
||||
const float radius = 15.0f;
|
||||
|
||||
for (uint i = 0; i<NB_COMPOUND_SHAPES; i++) {
|
||||
|
|
|
@ -96,16 +96,8 @@ class ConcaveMeshScene : public SceneDemo {
|
|||
|
||||
/// Reset the scene
|
||||
virtual void reset() override;
|
||||
|
||||
/// Return all the contact points of the scene
|
||||
virtual std::vector<ContactPoint> getContactPoints() override;
|
||||
};
|
||||
|
||||
// Return all the contact points of the scene
|
||||
inline std::vector<ContactPoint> ConcaveMeshScene::getContactPoints() {
|
||||
return computeContactPointsOfWorld(getDynamicsWorld());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,7 +47,9 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
|
|||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
rp3d::DynamicsWorld* dynamicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
dynamicsWorld->setEventListener(this);
|
||||
mPhysicsWorld = dynamicsWorld;
|
||||
|
||||
// Create all the cubes of the scene
|
||||
for (int i=0; i<NB_CUBES; i++) {
|
||||
|
@ -117,6 +119,8 @@ CubesScene::~CubesScene() {
|
|||
// Reset the scene
|
||||
void CubesScene::reset() {
|
||||
|
||||
SceneDemo::reset();
|
||||
|
||||
float radius = 2.0f;
|
||||
|
||||
// Create all the cubes of the scene
|
||||
|
|
|
@ -67,16 +67,8 @@ class CubesScene : public SceneDemo {
|
|||
|
||||
/// Reset the scene
|
||||
virtual void reset() override;
|
||||
|
||||
/// Return all the contact points of the scene
|
||||
virtual std::vector<ContactPoint> getContactPoints() override;
|
||||
};
|
||||
|
||||
// Return all the contact points of the scene
|
||||
inline std::vector<ContactPoint> CubesScene::getContactPoints() {
|
||||
return computeContactPointsOfWorld(getDynamicsWorld());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,7 +47,9 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings
|
|||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
rp3d::DynamicsWorld* dynamicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
dynamicsWorld->setEventListener(this);
|
||||
mPhysicsWorld = dynamicsWorld;
|
||||
|
||||
// Create all the cubes of the scene
|
||||
for (int i=1; i<=NB_FLOORS; i++) {
|
||||
|
@ -120,6 +122,8 @@ CubeStackScene::~CubeStackScene() {
|
|||
// Reset the scene
|
||||
void CubeStackScene::reset() {
|
||||
|
||||
SceneDemo::reset();
|
||||
|
||||
int index = 0;
|
||||
for (int i=NB_FLOORS; i > 0; i--) {
|
||||
|
||||
|
|
|
@ -67,16 +67,8 @@ class CubeStackScene : public SceneDemo {
|
|||
|
||||
/// Reset the scene
|
||||
virtual void reset() override;
|
||||
|
||||
/// Return all the contact points of the scene
|
||||
virtual std::vector<ContactPoint> getContactPoints() override;
|
||||
};
|
||||
|
||||
// Return all the contact points of the scene
|
||||
inline std::vector<ContactPoint> CubeStackScene::getContactPoints() {
|
||||
return computeContactPointsOfWorld(getDynamicsWorld());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -49,7 +49,9 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
|
|||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
rp3d::DynamicsWorld* dynamicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
dynamicsWorld->setEventListener(this);
|
||||
mPhysicsWorld = dynamicsWorld;
|
||||
|
||||
for (int i = 0; i<NB_COMPOUND_SHAPES; i++) {
|
||||
|
||||
|
@ -205,6 +207,8 @@ HeightFieldScene::~HeightFieldScene() {
|
|||
// Reset the scene
|
||||
void HeightFieldScene::reset() {
|
||||
|
||||
SceneDemo::reset();
|
||||
|
||||
const float radius = 3.0f;
|
||||
|
||||
for (uint i = 0; i<NB_COMPOUND_SHAPES; i++) {
|
||||
|
|
|
@ -98,16 +98,8 @@ class HeightFieldScene : public SceneDemo {
|
|||
|
||||
/// Reset the scene
|
||||
virtual void reset() override ;
|
||||
|
||||
/// Return all the contact points of the scene
|
||||
virtual std::vector<ContactPoint> getContactPoints() override ;
|
||||
};
|
||||
|
||||
// Return all the contact points of the scene
|
||||
inline std::vector<ContactPoint> HeightFieldScene::getContactPoints() {
|
||||
return computeContactPointsOfWorld(getDynamicsWorld());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -48,7 +48,9 @@ JointsScene::JointsScene(const std::string& name, EngineSettings& settings)
|
|||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
rp3d::DynamicsWorld* dynamicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
dynamicsWorld->setEventListener(this);
|
||||
mPhysicsWorld = dynamicsWorld;
|
||||
|
||||
// Create the Ball-and-Socket joint
|
||||
createBallAndSocketJoints();
|
||||
|
@ -129,6 +131,8 @@ void JointsScene::updatePhysics() {
|
|||
// Reset the scene
|
||||
void JointsScene::reset() {
|
||||
|
||||
SceneDemo::reset();
|
||||
|
||||
openglframework::Vector3 positionBox(0, 15, 5);
|
||||
openglframework::Vector3 boxDimension(1, 1, 1);
|
||||
|
||||
|
|
|
@ -125,16 +125,8 @@ class JointsScene : public SceneDemo {
|
|||
|
||||
/// Reset the scene
|
||||
virtual void reset() override;
|
||||
|
||||
/// Return all the contact points of the scene
|
||||
virtual std::vector<ContactPoint> getContactPoints() override;
|
||||
};
|
||||
|
||||
// Return all the contact points of the scene
|
||||
inline std::vector<ContactPoint> JointsScene::getContactPoints() {
|
||||
return computeContactPointsOfWorld(getDynamicsWorld());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -196,6 +196,8 @@ void RaycastScene::changeBody() {
|
|||
// Reset the scene
|
||||
void RaycastScene::reset() {
|
||||
|
||||
SceneDemo::reset();
|
||||
|
||||
std::vector<PhysicsObject*>::iterator it;
|
||||
for (it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) {
|
||||
(*it)->setTransform(rp3d::Transform(rp3d::Vector3::zero(), rp3d::Quaternion::identity()));
|
||||
|
|
|
@ -65,7 +65,7 @@ class RaycastManager : public rp3d::RaycastCallback {
|
|||
private:
|
||||
|
||||
/// All the visual contact points
|
||||
std::vector<ContactPoint> mHitPoints;
|
||||
std::vector<SceneContactPoint> mHitPoints;
|
||||
|
||||
/// Contact point mesh folder path
|
||||
std::string mMeshFolderPath;
|
||||
|
@ -85,7 +85,7 @@ class RaycastManager : public rp3d::RaycastCallback {
|
|||
|
||||
rp3d::Vector3 hitPos = raycastInfo.worldPoint;
|
||||
openglframework::Vector3 position(hitPos.x, hitPos.y, hitPos.z);
|
||||
mHitPoints.push_back(ContactPoint(position, normal, openglframework::Color::red()));
|
||||
mHitPoints.push_back(SceneContactPoint(position, normal, openglframework::Color::red()));
|
||||
|
||||
return raycastInfo.hitFraction;
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ class RaycastManager : public rp3d::RaycastCallback {
|
|||
mHitPoints.clear();
|
||||
}
|
||||
|
||||
std::vector<ContactPoint> getHitPoints() const {
|
||||
std::vector<SceneContactPoint> getHitPoints() const {
|
||||
return mHitPoints;
|
||||
}
|
||||
};
|
||||
|
@ -181,9 +181,6 @@ class RaycastScene : public SceneDemo {
|
|||
|
||||
/// Display/Hide the contact points
|
||||
virtual void setIsContactPointsDisplayed(bool display) override;
|
||||
|
||||
/// Return all the contact points of the scene
|
||||
virtual std::vector<ContactPoint> getContactPoints() override;
|
||||
};
|
||||
|
||||
// Display or not the surface normals at hit points
|
||||
|
@ -201,11 +198,6 @@ inline void RaycastScene::setIsContactPointsDisplayed(bool display) {
|
|||
SceneDemo::setIsContactPointsDisplayed(true);
|
||||
}
|
||||
|
||||
// Return all the contact points of the scene
|
||||
inline std::vector<ContactPoint> RaycastScene::getContactPoints() {
|
||||
return mRaycastManager.getHitPoints();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -185,3 +185,28 @@ void Scene::rotate(int xMouse, int yMouse) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Called when some contacts occur
|
||||
void Scene::onContact(const rp3d::CollisionCallback::CallbackData& callbackData) {
|
||||
|
||||
// Clear contacts points
|
||||
mContactPoints.clear();
|
||||
|
||||
// For each contact pair
|
||||
for (uint p=0; p < callbackData.getNbContactPairs(); p++) {
|
||||
|
||||
rp3d::CollisionCallback::ContactPair contactPair = callbackData.getContactPair(p);
|
||||
|
||||
// For each contact point of the contact pair
|
||||
for (uint c=0; c < contactPair.getNbContactPoints(); c++) {
|
||||
|
||||
rp3d::CollisionCallback::ContactPoint contactPoint = contactPair.getContactPoint(c);
|
||||
|
||||
rp3d::Vector3 point = contactPair.getProxyShape1()->getLocalToWorldTransform() * contactPoint.getLocalPointOnShape1();
|
||||
rp3d::Vector3 normalWorld = contactPoint.getWorldNormal();
|
||||
openglframework::Vector3 normal = openglframework::Vector3(normalWorld.x, normalWorld.y, normalWorld.z);
|
||||
SceneContactPoint contact(openglframework::Vector3(point.x, point.y, point.z), normal, openglframework::Color::red());
|
||||
mContactPoints.push_back(contact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "reactphysics3d.h"
|
||||
|
||||
// Structure ContactPoint
|
||||
struct ContactPoint {
|
||||
struct SceneContactPoint {
|
||||
|
||||
public:
|
||||
openglframework::Vector3 point;
|
||||
|
@ -39,7 +39,7 @@ struct ContactPoint {
|
|||
openglframework::Color color;
|
||||
|
||||
/// Constructor
|
||||
ContactPoint(const openglframework::Vector3& pointWorld, const openglframework::Vector3& normalWorld, const openglframework::Color colorPoint)
|
||||
SceneContactPoint(const openglframework::Vector3& pointWorld, const openglframework::Vector3& normalWorld, const openglframework::Color colorPoint)
|
||||
: point(pointWorld), normal(normalWorld), color(colorPoint) {
|
||||
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ struct EngineSettings {
|
|||
|
||||
// Class Scene
|
||||
// Abstract class that represents a 3D scene.
|
||||
class Scene {
|
||||
class Scene : public rp3d::EventListener {
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -130,12 +130,15 @@ class Scene {
|
|||
/// True if contact points are displayed
|
||||
bool mIsContactPointsDisplayed;
|
||||
|
||||
/// True if the AABBs of the phycis objects are displayed
|
||||
/// True if the AABBs of the physics objects are displayed
|
||||
bool mIsAABBsDisplayed;
|
||||
|
||||
/// True if we render shapes in wireframe mode
|
||||
bool mIsWireframeEnabled;
|
||||
|
||||
/// Contact points
|
||||
std::vector<SceneContactPoint> mContactPoints;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Set the scene position (where the camera needs to look at)
|
||||
|
@ -165,7 +168,7 @@ class Scene {
|
|||
Scene(const std::string& name, EngineSettings& engineSettings, bool isShadowMappingEnabled = false);
|
||||
|
||||
/// Destructor
|
||||
virtual ~Scene();
|
||||
virtual ~Scene() override;
|
||||
|
||||
/// Reshape the view
|
||||
virtual void reshape(int width, int height);
|
||||
|
@ -181,7 +184,7 @@ class Scene {
|
|||
virtual void render()=0;
|
||||
|
||||
/// Reset the scene
|
||||
virtual void reset()=0;
|
||||
virtual void reset();
|
||||
|
||||
/// Called when a keyboard event occurs
|
||||
virtual bool keyboardEvent(int key, int scancode, int action, int mods);
|
||||
|
@ -230,11 +233,11 @@ class Scene {
|
|||
/// Enable/disbale wireframe rendering
|
||||
void setIsWireframeEnabled(bool isEnabled);
|
||||
|
||||
/// Return all the contact points of the scene
|
||||
std::vector<ContactPoint> virtual getContactPoints();
|
||||
|
||||
/// Update the engine settings
|
||||
virtual void updateEngineSettings() = 0;
|
||||
|
||||
/// Called when some contacts occur
|
||||
virtual void onContact(const rp3d::CollisionCallback::CallbackData& callbackData) override;
|
||||
};
|
||||
|
||||
// Called when a keyboard event occurs
|
||||
|
@ -247,6 +250,11 @@ inline void Scene::reshape(int width, int height) {
|
|||
mCamera.setDimensions(width, height);
|
||||
}
|
||||
|
||||
// Reset the scene
|
||||
inline void Scene::reset() {
|
||||
mContactPoints.clear();
|
||||
}
|
||||
|
||||
// Return a reference to the camera
|
||||
inline const openglframework::Camera& Scene::getCamera() const {
|
||||
return mCamera;
|
||||
|
@ -306,11 +314,4 @@ inline void Scene::setIsWireframeEnabled(bool isEnabled) {
|
|||
mIsWireframeEnabled = isEnabled;
|
||||
}
|
||||
|
||||
// Return all the contact points of the scene
|
||||
inline std::vector<ContactPoint> Scene::getContactPoints() {
|
||||
|
||||
// Return an empty list of contact points
|
||||
return std::vector<ContactPoint>();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -98,7 +98,7 @@ SceneDemo::~SceneDemo() {
|
|||
mColorShader.destroy();
|
||||
|
||||
// Destroy the contact points
|
||||
removeAllContactPoints();
|
||||
removeAllVisualContactPoints();
|
||||
|
||||
// Destroy rendering data for the AABB
|
||||
AABB::destroy();
|
||||
|
@ -345,20 +345,17 @@ void SceneDemo::drawTextureQuad() {
|
|||
void SceneDemo::updateContactPoints() {
|
||||
|
||||
// Remove the previous contact points
|
||||
removeAllContactPoints();
|
||||
removeAllVisualContactPoints();
|
||||
|
||||
if (mIsContactPointsDisplayed) {
|
||||
|
||||
// Get the current contact points of the scene
|
||||
std::vector<ContactPoint> contactPoints = getContactPoints();
|
||||
|
||||
// For each contact point
|
||||
std::vector<ContactPoint>::const_iterator it;
|
||||
for (it = contactPoints.begin(); it != contactPoints.end(); ++it) {
|
||||
std::vector<SceneContactPoint>::const_iterator it;
|
||||
for (it = mContactPoints.begin(); it != mContactPoints.end(); ++it) {
|
||||
|
||||
// Create a visual contact point for rendering
|
||||
VisualContactPoint* point = new VisualContactPoint(it->point, mMeshFolderPath, it->point + it->normal, it->color);
|
||||
mContactPoints.push_back(point);
|
||||
mVisualContactPoints.push_back(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -367,8 +364,8 @@ void SceneDemo::updateContactPoints() {
|
|||
void SceneDemo::renderContactPoints(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
|
||||
|
||||
// Render all the contact points
|
||||
for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin();
|
||||
it != mContactPoints.end(); ++it) {
|
||||
for (std::vector<VisualContactPoint*>::iterator it = mVisualContactPoints.begin();
|
||||
it != mVisualContactPoints.end(); ++it) {
|
||||
(*it)->render(mColorShader, worldToCameraMatrix);
|
||||
}
|
||||
}
|
||||
|
@ -397,48 +394,14 @@ void SceneDemo::renderAABBs(const openglframework::Matrix4& worldToCameraMatrix)
|
|||
}
|
||||
}
|
||||
|
||||
void SceneDemo::removeAllContactPoints() {
|
||||
void SceneDemo::removeAllVisualContactPoints() {
|
||||
|
||||
// Destroy all the visual contact points
|
||||
for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin();
|
||||
it != mContactPoints.end(); ++it) {
|
||||
for (std::vector<VisualContactPoint*>::iterator it = mVisualContactPoints.begin();
|
||||
it != mVisualContactPoints.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
mContactPoints.clear();
|
||||
}
|
||||
|
||||
// Return all the contact points of the scene
|
||||
std::vector<ContactPoint> SceneDemo::computeContactPointsOfWorld(rp3d::DynamicsWorld* world) {
|
||||
|
||||
std::vector<ContactPoint> contactPoints;
|
||||
|
||||
// Get the list of contact manifolds from the world
|
||||
rp3d::List<const rp3d::ContactManifold*> manifolds = world->getContactsList();
|
||||
|
||||
// TODO : Uncomment and fix this
|
||||
/*
|
||||
// For each contact manifold
|
||||
rp3d::List<const rp3d::ContactManifold*>::Iterator it;
|
||||
for (it = manifolds.begin(); it != manifolds.end(); ++it) {
|
||||
|
||||
const rp3d::ContactManifold* manifold = *it;
|
||||
|
||||
// For each contact point of the manifold
|
||||
rp3d::ContactPoint* contactPoint = manifold->getContactPoints();
|
||||
while (contactPoint != nullptr) {
|
||||
|
||||
rp3d::Vector3 point = manifold->getShape1()->getLocalToWorldTransform() * contactPoint->getLocalPointOnShape1();
|
||||
rp3d::Vector3 normalWorld = contactPoint->getNormal();
|
||||
openglframework::Vector3 normal = openglframework::Vector3(normalWorld.x, normalWorld.y, normalWorld.z);
|
||||
ContactPoint contact(openglframework::Vector3(point.x, point.y, point.z), normal, openglframework::Color::red());
|
||||
contactPoints.push_back(contact);
|
||||
|
||||
contactPoint = contactPoint->getNext();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return contactPoints;
|
||||
mVisualContactPoints.clear();
|
||||
}
|
||||
|
||||
// Update the engine settings
|
||||
|
|
|
@ -60,7 +60,7 @@ class SceneDemo : public Scene {
|
|||
static int shadowMapTextureLevel;
|
||||
|
||||
/// All the visual contact points
|
||||
std::vector<VisualContactPoint*> mContactPoints;
|
||||
std::vector<VisualContactPoint*> mVisualContactPoints;
|
||||
|
||||
/// Shadow map bias matrix
|
||||
openglframework::Matrix4 mShadowMapBiasMatrix;
|
||||
|
@ -123,7 +123,7 @@ class SceneDemo : public Scene {
|
|||
void renderAABBs(const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
||||
/// Remove all contact points
|
||||
void removeAllContactPoints();
|
||||
void removeAllVisualContactPoints();
|
||||
|
||||
/// Return a reference to the dynamics world
|
||||
rp3d::DynamicsWorld* getDynamicsWorld();
|
||||
|
@ -144,6 +144,9 @@ class SceneDemo : public Scene {
|
|||
/// Update the scene
|
||||
virtual void update() override;
|
||||
|
||||
/// Reset the scene
|
||||
virtual void reset() override;
|
||||
|
||||
/// Update the physics world (take a simulation step)
|
||||
/// Can be called several times per frame
|
||||
virtual void updatePhysics() override;
|
||||
|
@ -159,9 +162,6 @@ class SceneDemo : public Scene {
|
|||
|
||||
/// Enabled/Disable the shadow mapping
|
||||
virtual void setIsShadowMappingEnabled(bool isShadowMappingEnabled) override;
|
||||
|
||||
/// Return all the contact points of the scene
|
||||
std::vector<ContactPoint> computeContactPointsOfWorld(reactphysics3d::DynamicsWorld *world);
|
||||
};
|
||||
|
||||
// Enabled/Disable the shadow mapping
|
||||
|
@ -184,6 +184,14 @@ inline const rp3d::DynamicsWorld* SceneDemo::getDynamicsWorld() const {
|
|||
return dynamic_cast<rp3d::DynamicsWorld*>(mPhysicsWorld);
|
||||
}
|
||||
|
||||
// Reset the scene
|
||||
inline void SceneDemo::reset() {
|
||||
|
||||
Scene::reset();
|
||||
|
||||
removeAllVisualContactPoints();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user