reactphysics3d/include/reactphysics3d/collision/CollisionCallback.h
2020-07-26 20:47:23 +02:00

346 lines
13 KiB
C++

/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2020 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. *
* *
********************************************************************************/
#ifndef REACTPHYSICS3D_COLLISION_CALLBACK_H
#define REACTPHYSICS3D_COLLISION_CALLBACK_H
// Libraries
#include <reactphysics3d/containers/List.h>
#include <reactphysics3d/collision/ContactPair.h>
#include <reactphysics3d/constraint/ContactPoint.h>
/// ReactPhysics3D namespace
namespace reactphysics3d {
// Declarations
class OverlappingPair;
class ContactManifold;
class CollisionBody;
class Collider;
class MemoryManager;
// Class CollisionCallback
/**
* 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.
*/
class CollisionCallback {
public:
// Class ContactPoint
/**
* This class represents a contact point between two colliders of the physics world.
*/
class ContactPoint {
private:
// -------------------- Attributes -------------------- //
const reactphysics3d::ContactPoint& mContactPoint;
// -------------------- Methods -------------------- //
/// Constructor
ContactPoint(const reactphysics3d::ContactPoint& contactPoint);
public:
// -------------------- Methods -------------------- //
/// Copy constructor
ContactPoint(const ContactPoint& contactPoint) = default;
/// Assignment operator
ContactPoint& operator=(const ContactPoint& contactPoint) = delete;
/// Destructor
~ContactPoint() = default;
/// Return the penetration depth
/**
* @return The penetration depth between the two colliders at this contact point
*/
decimal getPenetrationDepth() const;
/// Return the world-space contact normal
/**
* @return The world-space contact normal
*/
const Vector3& getWorldNormal() const;
/// Return the contact point on the first collider in the local-space of the first collider
/**
* @return The local-space contact point on the first collider
*/
const Vector3& getLocalPointOnCollider1() const;
/// Return the contact point on the second collider in the local-space of the second collider
/**
* @return The local-space contact point on the second collider
*/
const Vector3& getLocalPointOnCollider2() const;
// -------------------- Friendship -------------------- //
friend class CollisionCallback;
};
// Class ContactPair
/**
* This class represents the contact between two colliders of the physics world.
* A contact pair contains a list of contact points.
*/
class ContactPair {
public:
/// Enumeration EventType that describes the type of contact event
enum class EventType {
/// This contact is a new contact between the two
/// colliders (the colliders where not touching in the previous frame)
ContactStart,
/// The two colliders were already touching in the previous frame and this is a new or updated contact
ContactStay,
/// The two colliders were in contact in the previous frame and are not in contact anymore
ContactExit
};
private:
// -------------------- Attributes -------------------- //
const reactphysics3d::ContactPair& mContactPair;
/// Pointer to the contact points
List<reactphysics3d::ContactPoint>* mContactPoints;
/// Reference to the physics world
PhysicsWorld& mWorld;
/// True if this is a lost contact pair (contact pair colliding in previous frame but not in current one)
bool mIsLostContactPair;
// -------------------- Methods -------------------- //
/// Constructor
ContactPair(const reactphysics3d::ContactPair& contactPair, List<reactphysics3d::ContactPoint>* contactPoints,
PhysicsWorld& world, bool mIsLostContactPair);
public:
// -------------------- Methods -------------------- //
/// Copy constructor
ContactPair(const ContactPair& contactPair) = default;
/// Assignment operator
ContactPair& operator=(const ContactPair& contactPair) = delete;
/// Destructor
~ContactPair() = default;
/// Return the number of contact points in the contact pair
/**
* @return The number of contact points in the contact pair
*/
uint getNbContactPoints() const;
/// Return a given contact point
/**
* @param index Index of the contact point to retrieve
* @return A contact point object
*/
ContactPoint getContactPoint(uint index) const;
/// Return a pointer to the first body in contact
/**
* @return A pointer to the first colliding body of the pair
*/
CollisionBody* getBody1() const;
/// Return a pointer to the second body in contact
/**
* @return A pointer to the second colliding body of the pair
*/
CollisionBody* getBody2() const;
/// Return a pointer to the first collider in contact (in body 1)
/**
* @return A pointer to the first collider of the contact pair
*/
Collider* getCollider1() const;
/// Return a pointer to the second collider in contact (in body 2)
/**
* @return A pointer to the second collider of the contact pair
*/
Collider* getCollider2() const;
/// Return the corresponding type of event for this contact pair
/**
* @return The type of contact event for this contact pair
*/
EventType getEventType() 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 (contains contacts and triggers events)
List<reactphysics3d::ContactPair>* mContactPairs;
/// Pointer to the list of contact manifolds
List<ContactManifold>* mContactManifolds;
/// Pointer to the contact points
List<reactphysics3d::ContactPoint>* mContactPoints;
/// Pointer to the list of lost contact pairs (contains contacts and triggers events)
List<reactphysics3d::ContactPair>& mLostContactPairs;
/// List of indices of the mContactPairs list that are contact events (not overlap/triggers)
List<uint> mContactPairsIndices;
/// List of indices of the mLostContactPairs list that are contact events (not overlap/triggers)
List<uint> mLostContactPairsIndices;
/// Reference to the physics world
PhysicsWorld& mWorld;
// -------------------- Methods -------------------- //
/// Constructor
CallbackData(List<reactphysics3d::ContactPair>* contactPairs, List<ContactManifold>* manifolds,
List<reactphysics3d::ContactPoint>* contactPoints, List<reactphysics3d::ContactPair>& lostContactPairs,
PhysicsWorld& 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
/**
* @return The number of contact pairs
*/
uint getNbContactPairs() const;
/// Return a given contact pair
/**
* @param index Index of the contact pair to retrieve
* @return A contact pair object
*/
ContactPair getContactPair(uint index) const;
// -------------------- Friendship -------------------- //
friend class CollisionDetectionSystem;
};
/// Destructor
virtual ~CollisionCallback() = default;
/// 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
*/
RP3D_FORCE_INLINE uint CollisionCallback::CallbackData::getNbContactPairs() const {
return mContactPairsIndices.size() + mLostContactPairsIndices.size();
}
// Return the number of contact points in the contact pair
/**
* @return The number of contact points
*/
RP3D_FORCE_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)
*/
RP3D_FORCE_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)
*/
RP3D_FORCE_INLINE const Vector3& CollisionCallback::ContactPoint::getWorldNormal() const {
return mContactPoint.getNormal();
}
// Return the contact point on the first collider in the local-space of the first collider
/**
* @return The contact point in the local-space of the first collider (from body1) in contact
*/
RP3D_FORCE_INLINE const Vector3& CollisionCallback::ContactPoint::getLocalPointOnCollider1() const {
return mContactPoint.getLocalPointOnShape1();
}
// Return the contact point on the second collider in the local-space of the second collider
/**
* @return The contact point in the local-space of the second collider (from body2) in contact
*/
RP3D_FORCE_INLINE const Vector3& CollisionCallback::ContactPoint::getLocalPointOnCollider2() const {
return mContactPoint.getLocalPointOnShape2();
}
}
#endif