382 lines
13 KiB
C++
382 lines
13 KiB
C++
/********************************************************************************
|
|
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
|
* Copyright (c) 2010-2019 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_DEBUG_RENDERER_H
|
|
#define REACTPHYSICS3D_DEBUG_RENDERER_H
|
|
|
|
// Libraries
|
|
#include <reactphysics3d/containers/List.h>
|
|
#include <reactphysics3d/containers/Map.h>
|
|
#include <reactphysics3d/mathematics/mathematics.h>
|
|
#include <reactphysics3d/engine/EventListener.h>
|
|
#include <string>
|
|
|
|
/// ReactPhysics3D namespace
|
|
namespace reactphysics3d {
|
|
|
|
// Forward declarations
|
|
class ConcaveMeshShape;
|
|
class ConvexMeshShape;
|
|
class HeightFieldShape;
|
|
class Collider;
|
|
class PhysicsWorld;
|
|
|
|
// Class DebugRenderer
|
|
/**
|
|
* This class is used to display physics debug information directly into the user application view.
|
|
* For instance, it is possible to display AABBs of colliders, colliders or contact points. This class
|
|
* can be used to get the debug information as lists of basic primitives (points, linges, triangles, ...).
|
|
* You can use this to render physics debug information in your simulation on top of your object. Note that
|
|
* you should use this only for debugging purpose and you should disable it when you compile the final release
|
|
* version of your application because computing/rendering phyiscs debug information can be expensive.
|
|
*/
|
|
class DebugRenderer : public EventListener {
|
|
|
|
public:
|
|
|
|
/// Enumeration with basic colors
|
|
enum class DebugColor {
|
|
|
|
RED = 0xff0000,
|
|
GREEN = 0x00ff00,
|
|
BLUE = 0x0000ff,
|
|
BLACK = 0x000000,
|
|
WHITE = 0xffffff,
|
|
YELLOW = 0xffff00,
|
|
MAGENTA = 0xff00ff,
|
|
CYAN = 0x00ffff,
|
|
};
|
|
|
|
/// Enumeration with debug item to renderer
|
|
enum class DebugItem {
|
|
|
|
/// Display the AABB for each collider
|
|
COLLIDER_AABB = 1 << 0,
|
|
|
|
/// Display the fat AABB of the broad phase collision detection for each collider
|
|
COLLIDER_BROADPHASE_AABB = 1 << 1,
|
|
|
|
/// Display the collision shape of each collider
|
|
COLLISION_SHAPE = 1 << 2,
|
|
|
|
/// Display the contact points
|
|
CONTACT_POINT = 1 << 3,
|
|
|
|
/// Display the contact normals
|
|
CONTACT_NORMAL = 1 << 4,
|
|
};
|
|
|
|
/// Struture that represents a line of the DebugRenderer
|
|
struct DebugLine {
|
|
|
|
/// Constructor
|
|
DebugLine(const Vector3& point1, const Vector3& point2, uint32 color)
|
|
:point1(point1), color1(color), point2(point2), color2(color) {
|
|
|
|
}
|
|
|
|
/// First point of the line
|
|
Vector3 point1;
|
|
|
|
/// Color of the first point
|
|
uint32 color1;
|
|
|
|
/// Second point of the line
|
|
Vector3 point2;
|
|
|
|
/// Color of the second point
|
|
uint32 color2;
|
|
};
|
|
|
|
/// Struture that represents a triangle of the DebugRenderer
|
|
struct DebugTriangle {
|
|
|
|
/// Constructor
|
|
DebugTriangle(const Vector3& point1, const Vector3& point2, const Vector3& point3, uint32 color)
|
|
:point1(point1), color1(color), point2(point2), color2(color), point3(point3), color3(color) {
|
|
|
|
}
|
|
|
|
/// First point of the triangle
|
|
Vector3 point1;
|
|
|
|
/// Color of the first point
|
|
uint32 color1;
|
|
|
|
/// Second point of the triangle
|
|
Vector3 point2;
|
|
|
|
/// Color of the second point
|
|
uint32 color2;
|
|
|
|
/// Third point of the triangle
|
|
Vector3 point3;
|
|
|
|
/// Color of the third point
|
|
uint32 color3;
|
|
};
|
|
|
|
private:
|
|
|
|
// -------------------- Constants -------------------- //
|
|
|
|
/// Number of sectors used to draw a sphere or a capsule
|
|
static constexpr int NB_SECTORS_SPHERE = 18;
|
|
|
|
/// Number of stacks used to draw a sphere or a capsule
|
|
static constexpr int NB_STACKS_SPHERE = 10;
|
|
|
|
/// Default radius of the sphere displayed to represent contact points
|
|
static constexpr decimal DEFAULT_CONTACT_POINT_SPHERE_RADIUS = decimal(0.1);
|
|
|
|
/// Default radius of the sphere displayed to represent contact points
|
|
static constexpr decimal DEFAULT_CONTACT_NORMAL_LENGTH = decimal(1.0);
|
|
|
|
// -------------------- Attributes -------------------- //
|
|
|
|
/// Memory allocator
|
|
MemoryAllocator& mAllocator;
|
|
|
|
/// List with all the debug lines
|
|
List<DebugLine> mLines;
|
|
|
|
/// List with all the debug triangles
|
|
List<DebugTriangle> mTriangles;
|
|
|
|
/// 32-bits integer that contains all the flags of debug items to display
|
|
uint32 mDisplayedDebugItems;
|
|
|
|
/// Map a debug item with the color used to display it
|
|
Map<DebugItem, uint32> mMapDebugItemWithColor;
|
|
|
|
/// Radius of the sphere displayed to represent contact points
|
|
decimal mContactPointSphereRadius;
|
|
|
|
/// Lenght of contact normal
|
|
decimal mContactNormalLength;
|
|
|
|
// -------------------- Methods -------------------- //
|
|
|
|
/// Draw an AABB
|
|
void drawAABB(const AABB& aabb, uint32 color);
|
|
|
|
/// Draw a box
|
|
void drawBox(const Transform& transform, const Vector3& extents, uint32 color);
|
|
|
|
/// Draw a sphere
|
|
void drawSphere(const Vector3& position, decimal radius, uint32 color);
|
|
|
|
/// Draw a capsule
|
|
void drawCapsule(const Transform& transform, decimal radius, decimal height, uint32 color);
|
|
|
|
/// Draw a convex mesh
|
|
void drawConvexMesh(const Transform& transform, const ConvexMeshShape* convexMesh, uint32 color);
|
|
|
|
/// Draw a concave mesh shape
|
|
void drawConcaveMeshShape(const Transform& transform, const ConcaveMeshShape* concaveMeshShape, uint32 color);
|
|
|
|
/// Draw a height field shape
|
|
void drawHeightFieldShape(const Transform& transform, const HeightFieldShape* heightFieldShape, uint32 color);
|
|
|
|
/// Draw the collision shape of a collider
|
|
void drawCollisionShapeOfCollider(const Collider* collider, uint32 color);
|
|
|
|
public :
|
|
|
|
// -------------------- Methods -------------------- //
|
|
|
|
/// Constructor
|
|
DebugRenderer(MemoryAllocator& allocator);
|
|
|
|
/// Destructor
|
|
~DebugRenderer();
|
|
|
|
/// Return the number of lines
|
|
uint32 getNbLines() const;
|
|
|
|
/// Return a reference to the list of lines
|
|
const List<DebugLine>& getLines() const;
|
|
|
|
/// Return a pointer to the array of lines
|
|
const DebugLine* getLinesArray() const;
|
|
|
|
/// Return the number of triangles
|
|
uint32 getNbTriangles() const;
|
|
|
|
/// Return a reference to the list of triangles
|
|
const List<DebugTriangle>& getTriangles() const;
|
|
|
|
/// Return a pointer to the array of triangles
|
|
const DebugTriangle* getTrianglesArray() const;
|
|
|
|
/// Return whether a debug item is displayed or not
|
|
bool getIsDebugItemDisplayed(DebugItem item) const;
|
|
|
|
/// Set whether a debug info is displayed or not
|
|
void setIsDebugItemDisplayed(DebugItem item, bool isDisplayed);
|
|
|
|
/// Get the contact point sphere radius
|
|
decimal getContactPointSphereRadius() const;
|
|
|
|
/// Set the contact point sphere radius
|
|
void setContactPointSphereRadius(decimal radius);
|
|
|
|
/// Return the length of contact normal
|
|
decimal getContactNormalLength() const;
|
|
|
|
/// Return the length of contact normal
|
|
void setContactNormalLength(decimal contactNormalLength);
|
|
|
|
/// Generate the rendering primitives (triangles, lines, ...) of a physics world
|
|
void computeDebugRenderingPrimitives(const PhysicsWorld& world);
|
|
|
|
/// Clear all the debugging primitives (points, lines, triangles, ...)
|
|
void reset();
|
|
|
|
/// Called when some contacts occur
|
|
virtual void onContact(const CollisionCallback::CallbackData& callbackData) override;
|
|
};
|
|
|
|
// Return the number of lines
|
|
/**
|
|
* @return The number of lines in the array of lines to draw
|
|
*/
|
|
inline uint32 DebugRenderer::getNbLines() const {
|
|
return mLines.size();
|
|
}
|
|
|
|
// Return a reference to the list of lines
|
|
/**
|
|
* @return The list of lines to draw
|
|
*/
|
|
inline const List<DebugRenderer::DebugLine>& DebugRenderer::getLines() const {
|
|
return mLines;
|
|
}
|
|
|
|
// Return a pointer to the array of lines
|
|
/**
|
|
* @return A pointer to the first element of the lines array to draw
|
|
*/
|
|
inline const DebugRenderer::DebugLine* DebugRenderer::getLinesArray() const {
|
|
return &(mLines[0]);
|
|
}
|
|
|
|
// Return the number of triangles
|
|
/**
|
|
* @return The number of triangles in the array of triangles to draw
|
|
*/
|
|
inline uint32 DebugRenderer::getNbTriangles() const {
|
|
return mTriangles.size();
|
|
}
|
|
|
|
// Return a reference to the list of triangles
|
|
/**
|
|
* @return The list of triangles to draw
|
|
*/
|
|
inline const List<DebugRenderer::DebugTriangle>& DebugRenderer::getTriangles() const {
|
|
return mTriangles;
|
|
}
|
|
|
|
// Return a pointer to the array of triangles
|
|
/**
|
|
* @return A pointer to the first element of the triangles array to draw
|
|
*/
|
|
inline const DebugRenderer::DebugTriangle* DebugRenderer::getTrianglesArray() const {
|
|
return &(mTriangles[0]);
|
|
}
|
|
|
|
// Return whether a debug item is displayed or not
|
|
/**
|
|
* @param item A debug item
|
|
* @return True if the given debug item is being displayed and false otherwise
|
|
*/
|
|
inline bool DebugRenderer::getIsDebugItemDisplayed(DebugItem item) const {
|
|
return mDisplayedDebugItems & static_cast<uint32>(item);
|
|
}
|
|
|
|
// Set whether a debug info is displayed or not
|
|
/**
|
|
* @param item A debug item to draw
|
|
* @param isDisplayed True if the given debug item has to be displayed and false otherwise
|
|
*/
|
|
inline void DebugRenderer::setIsDebugItemDisplayed(DebugItem item, bool isDisplayed) {
|
|
const uint32 itemFlag = static_cast<uint32>(item);
|
|
uint32 resetBit = ~(itemFlag);
|
|
mDisplayedDebugItems &= resetBit;
|
|
if (isDisplayed) {
|
|
mDisplayedDebugItems |= itemFlag;
|
|
}
|
|
}
|
|
|
|
// Get the contact point sphere radius
|
|
/**
|
|
* @return The radius of the sphere used to display a contact point
|
|
*/
|
|
inline decimal DebugRenderer::getContactPointSphereRadius() const {
|
|
return mContactPointSphereRadius;
|
|
}
|
|
|
|
// Set the contact point sphere radius
|
|
/**
|
|
* @param radius The radius of the sphere used to display a contact point
|
|
*/
|
|
inline void DebugRenderer::setContactPointSphereRadius(decimal radius) {
|
|
assert(radius > decimal(0.0));
|
|
mContactPointSphereRadius = radius;
|
|
}
|
|
|
|
|
|
// Return the length of contact normal
|
|
/**
|
|
* @return The length of the contact normal to display
|
|
*/
|
|
inline decimal DebugRenderer::getContactNormalLength() const {
|
|
return mContactNormalLength;
|
|
}
|
|
|
|
// Return the length of contact normal
|
|
/**
|
|
* @param contactNormalLength The length of the contact normal to display
|
|
*/
|
|
inline void DebugRenderer::setContactNormalLength(decimal contactNormalLength) {
|
|
mContactNormalLength = contactNormalLength;
|
|
}
|
|
|
|
}
|
|
|
|
// Hash function for a DebugItem
|
|
namespace std {
|
|
|
|
template <> struct hash<reactphysics3d::DebugRenderer::DebugItem> {
|
|
|
|
size_t operator()(const reactphysics3d::DebugRenderer::DebugItem& debugItem) const {
|
|
|
|
return std::hash<reactphysics3d::uint32>{}(static_cast<unsigned int>(debugItem));
|
|
}
|
|
};
|
|
}
|
|
|
|
#endif
|