Working on testCollision() and testOverlap() methods

This commit is contained in:
Daniel Chappuis 2019-06-25 23:26:06 +02:00
parent 3f5916a280
commit 74b442077f
38 changed files with 1136 additions and 878 deletions

View File

@ -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

View File

@ -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"

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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,32 +440,105 @@ 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) {
return collisionFound;
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);
}
List<ContactPointInfo> potentialContactPoints(allocator);
List<ContactManifoldInfo> potentialContactManifolds(allocator);
Map<OverlappingPair::OverlappingPairId, uint> mapPairIdToContactPairIndex(allocator);
List<ContactPair> contactPairs(allocator);
Map<Entity, List<uint>> mapBodyToContactPairs(allocator);
return collisionFound;
}
// Process all the potential contacts after narrow-phase collision
processAllPotentialContacts(narrowPhaseInput, true, potentialContactPoints, &mapPairIdToContactPairIndex, potentialContactManifolds,
&contactPairs, mapBodyToContactPairs);
// Process the potential overlapping bodies for the testOverlap() methods
void CollisionDetection::computeSnapshotContactPairs(NarrowPhaseInput& narrowPhaseInput, List<Pair<Entity, Entity>>& overlapPairs) const {
// Reduce the number of contact points in the manifolds
reducePotentialContactManifolds(&contactPairs, potentialContactManifolds, potentialContactPoints);
// 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
processAllPotentialContacts(narrowPhaseInput, true, potentialContactPoints, &mapPairIdToContactPairIndex, potentialContactManifolds,
&contactPairs, mapBodyToContactPairs);
// 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);
}
*/
}
// Return true if two bodies overlap
// 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 (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

View File

@ -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;

View File

@ -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),

View File

@ -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;

View 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) {
}

View File

@ -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

View File

@ -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);
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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++) {
// Contact normal
rp3d::Vector3 normal = contactPoint->getNormal();
openglframework::Vector3 contactNormal(normal.x, normal.y, normal.z);
ContactPoint contactPoint = contactPair.getContactPoint(c);
rp3d::Vector3 point1 = contactPoint->getLocalPointOnShape1();
point1 = collisionCallbackInfo.proxyShape1->getLocalToWorldTransform() * point1;
// Contact normal
rp3d::Vector3 normal = contactPoint.getWorldNormal();
openglframework::Vector3 contactNormal(normal.x, normal.y, normal.z);
openglframework::Vector3 position1(point1.x, point1.y, point1.z);
mContactPoints.push_back(ContactPoint(position1, contactNormal, openglframework::Color::red()));
rp3d::Vector3 point1 = contactPoint.getLocalPointOnShape1();
point1 = contactPair.getProxyShape1()->getLocalToWorldTransform() * point1;
rp3d::Vector3 point2 = contactPoint->getLocalPointOnShape2();
point2 = collisionCallbackInfo.proxyShape2->getLocalToWorldTransform() * point2;
openglframework::Vector3 position2(point2.x, point2.y, point2.z);
mContactPoints.push_back(ContactPoint(position2, contactNormal, openglframework::Color::blue()));
openglframework::Vector3 position1(point1.x, point1.y, point1.z);
mContactPoints.push_back(SceneContactPoint(position1, contactNormal, openglframework::Color::red()));
contactPoint = contactPoint->getNext();
rp3d::Vector3 point2 = contactPoint.getLocalPointOnShape2();
point2 = contactPair.getProxyShape2()->getLocalToWorldTransform() * point2;
openglframework::Vector3 position2(point2.x, point2.y, point2.z);
mContactPoints.push_back(SceneContactPoint(position2, contactNormal, openglframework::Color::blue()));
}
}
manifoldElement = manifoldElement->getNext();
}
*/
}

View File

@ -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

View File

@ -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++) {

View File

@ -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

View File

@ -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++) {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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--) {

View File

@ -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

View File

@ -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++) {

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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()));

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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