12#ifndef TOYMAKERENGINE_SPATIALQUERYTYPES_H
13#define TOYMAKERENGINE_SPATIALQUERYTYPES_H
19#include <glm/gtc/quaternion.hpp>
26 inline float squareDistance(
const glm::vec3& vector) {
27 return glm::dot(vector, vector);
58 return std::isfinite(number);
68 inline bool isFinite(
const glm::vec3& vector) {
104 return number >= 0.f;
120 template <
typename TDerived>
141 std::array<glm::vec3, 8> cornerSigns {};
142 for(
BoxCorner corner {0}; corner < 8; ++corner) {
143 cornerSigns[corner].x = corner&BoxCornerSpecifier::RIGHT? 1.f: -1.f;
144 cornerSigns[corner].y = corner&BoxCornerSpecifier::TOP? 1.f: -1.f;
145 cornerSigns[corner].z = corner&BoxCornerSpecifier::FRONT? 1.f: -1.f;
158 glm::vec3 absoluteCornerOffset { .5f * boxDimensions };
159 std::array<glm::vec3, 8> cornerArray { .5f * boxDimensions };
160 for(uint8_t corner{0}; corner < 8; ++corner) {
161 cornerArray[corner] = cornerSignsArray[corner] * absoluteCornerOffset;
175 template <
typename TDerived>
190 template <
typename TDerived>
203 template <
typename TDerived>
210 template <
typename TDerived>
219 return TDerived::getVolumeRelativeBoxCorners();
229 return TDerived::isSensible();
239 return TDerived::isPositiveStrict();
411 glm::length(glm::cross(
528 float mLength { std::numeric_limits<float>::infinity() };
645 inline bool append(
const glm::vec3& candidatePoint,
const glm::vec3& supportA,
const glm::vec3& supportB) {
646 assert(
mNPoints < 4 &&
"We already have 4 (or more) points, there's no more needed");
647 assert(supportA - supportB == candidatePoint &&
"The difference in supports should yield the candidate point");
652 for(uint8_t index { 0 }; index <
mNPoints; ++index) {
653 if(
mPoints[index] == candidatePoint) {
669 inline void reorder(
const std::vector<uint8_t> reorderedIndices) {
670 assert(reorderedIndices.size() <= 4 &&
"Invalid point list provided");
671 const std::array<glm::vec3, 4> oldPoints {
mPoints };
675 for(
const auto& index: reorderedIndices) {
676 const bool pointAddedSuccessfully{
append(oldPoints[index], oldPointsSupportA[index], oldPointsSupportB[index]) };
677 assert(pointAddedSuccessfully &&
"Invalid point list provided");
692 std::pair<bool, glm::vec3>
evaluate();
695 std::pair<bool, glm::vec3> doSimplex4();
696 glm::vec3 doSimplex3();
697 glm::vec3 doSimplex2();
714 std::array<uint16_t, 3> mIndices {};
727 std::priority_queue<Face, std::vector<Face>, std::function<bool(
const Face&,
const Face&)>>
mFaces;
745 inline glm::vec3 getTriangleCross(
const Face& face)
const {
752 inline glm::vec3 getTriangleNorm(
const Face& face)
const {
753 return glm::normalize(getTriangleCross(face));
777 std::size_t getNumPoints()
const {
832 bool append(
const glm::vec3& newPoint,
const glm::vec3& supportA,
const glm::vec3& supportB);
940 VolumeBox mBox { .mDimensions{ glm::vec3{0.f} } };
1189 AxisAlignedBounds operator+(
const AxisAlignedBounds& other)
const;
1196 std::array<glm::vec3, 8> getAxisAlignedBoxCorners()
const;
1210 Extents getAxisAlignedBoxExtents()
const;
1247 glm::vec3 getSupportAlong(
const glm::vec3& axis)
const;
1267 assert(
isFinite(position) &&
"Invalid position specified. Position must be finite");
1279 assert(
isNonNegative(dimensions) &&
isFinite(dimensions) &&
"Invalid dimensions provided. Dimensions must be non negative and finite");
1281 const glm::vec3 deltaDimensions { dimensions -
getDimensions() };
1282 mExtents.first += .5f * deltaDimensions;
1283 mExtents.second -= .5f * deltaDimensions;
1291 void setByExtents(
const Extents& axisAlignedExtents);
1304 NLOHMANN_JSON_SERIALIZE_ENUM( ObjectBounds::TrueVolumeType, {
1305 {ObjectBounds::TrueVolumeType::BOX,
"box"},
1306 {ObjectBounds::TrueVolumeType::SPHERE,
"sphere"},
1307 {ObjectBounds::TrueVolumeType::CAPSULE,
"capsule"},
1314 inline void to_json(nlohmann::json& json,
const ObjectBounds& objectBounds) {
1316 {
"type", ObjectBounds::getComponentTypeName()},
1317 {
"volume_type", objectBounds.mType},
1318 {
"position_offset", { objectBounds.mPositionOffset.x, objectBounds.mPositionOffset.y, objectBounds.mPositionOffset.z}},
1319 {
"orientation_offset", { objectBounds.mOrientationOffset.w, objectBounds.mOrientationOffset.x, objectBounds.mOrientationOffset.y, objectBounds.mOrientationOffset.z }},
1321 switch(objectBounds.mType) {
1322 case ObjectBounds::TrueVolumeType::BOX:
1323 json[
"volume_properties"] = {
1324 {
"width", objectBounds.mTrueVolume.mBox.mDimensions.x},
1325 {
"height", objectBounds.mTrueVolume.mBox.mDimensions.y},
1326 {
"depth", objectBounds.mTrueVolume.mBox.mDimensions.z},
1329 case ObjectBounds::TrueVolumeType::SPHERE:
1330 json[
"volume_properties"] = {
1331 {
"radius", objectBounds.mTrueVolume.mSphere.mRadius},
1334 case ObjectBounds::TrueVolumeType::CAPSULE:
1335 json[
"volume_properties"] = {
1336 {
"radius", objectBounds.mTrueVolume.mCapsule.mRadius},
1337 {
"height", objectBounds.mTrueVolume.mCapsule.mHeight},
1344 inline void from_json(
const nlohmann::json& json, ObjectBounds& objectBounds) {
1345 assert(json.at(
"type") == ObjectBounds::getComponentTypeName() &&
"Incorrect type property for an objectBounds component");
1346 const glm::vec3 positionOffset {
1347 json.at(
"position_offset")[0],
1348 json.at(
"position_offset")[1],
1349 json.at(
"position_offset")[2],
1351 const glm::vec3 orientationOffset {
1352 glm::eulerAngles(glm::normalize(glm::quat {
1353 json.at(
"orientation_offset")[0],
1354 json.at(
"orientation_offset")[1],
1355 json.at(
"orientation_offset")[2],
1356 json.at(
"orientation_offset")[3]
1360 switch (
static_cast<ObjectBounds::TrueVolumeType
>(json.at(
"volume_type"))) {
1361 case ObjectBounds::TrueVolumeType::BOX:
1362 objectBounds = ObjectBounds::create(
1363 VolumeBox{ .mDimensions {
1364 json.at(
"volume_properties").at(
"width").get<
float>(),
1365 json.at(
"volume_properties").at(
"height").get<
float>(),
1366 json.at(
"volume_properties").at(
"depth").get<
float>(),
1373 case ObjectBounds::TrueVolumeType::SPHERE:
1374 objectBounds = ObjectBounds::create(
1375 VolumeSphere { .mRadius { json.at(
"volume_properties").at(
"radius").get<
float>() }},
1381 case ObjectBounds::TrueVolumeType::CAPSULE:
1382 objectBounds = ObjectBounds::create(
1384 .mHeight { json.at(
"volume_properties").at(
"height").get<
float>() },
1385 .mRadius { json.at(
"volume_properties").at(
"radius").get<
float>() },
1395 inline void to_json(nlohmann::json& json,
const AxisAlignedBounds& axisAlignedBounds) {
1397 (void)axisAlignedBounds;
1401 inline void from_json(
const nlohmann::json& json, AxisAlignedBounds& objectBounds) {
std::array< AreaTriangle, 12 > getAxisAlignedBoxFaceTriangles() const
Gets an array of triangles in the world which make up the surface of this box.
Definition types.hpp:1203
void setPosition(const glm::vec3 &position)
Sets the position of this box.
Definition types.hpp:1266
void setDimensions(const glm::vec3 &dimensions)
Sets the dimensions of this box.
Definition types.hpp:1278
AxisAlignedBounds(const glm::vec3 &position, const glm::vec3 &dimensions)
Constructs a new Axis Aligned Bounds object based on the position of the origin and the dimensions of...
Definition types.hpp:1179
std::pair< glm::vec3, glm::vec3 > Extents
Pair where first: right top front corner; second: left back bottom corner of an AABB.
Definition types.hpp:1151
glm::vec3 getDimensions() const
Gets the dimensions of this box.
Definition types.hpp:1217
Extents mExtents
The pair of coordinates at the extreme corners of this box (i.e., the top-right-front and bottom-left...
Definition types.hpp:1297
std::array< glm::vec3, 8 > getAxisAlignedBoxCorners() const
Gets an array of coordinates of the corners of this box.
Definition types.cpp:333
glm::vec3 getComputedWorldPosition() const
Gets the coordinates of the center of this box.
Definition types.hpp:1224
AxisAlignedBounds()
Constructs a new empty Axis Aligned Bounds object.
Definition types.cpp:313
bool isSensible() const
Tests whether this box is sensible (it has a finite position, and finite non-negative dimensions).
Definition types.hpp:1232
bool isPositiveStrict() const
Tests whether this box has strictly positive parameters and hence encloses some region in space.
Definition types.hpp:1255
static std::string getComponentTypeName()
Gets the component type string for this object.
Definition types.hpp:1145
AreaTriangle getClosestTriangle() const
Returns the closest polytope triangle.
Definition types.cpp:88
AreaTriangle getClosestTriangleSupportB() const
Gets the points of shape B that were responsible for generating the closest triangle of the polytope.
Definition types.cpp:106
bool append(const glm::vec3 &newPoint, const glm::vec3 &supportA, const glm::vec3 &supportB)
Appends a new point, replacing the topmost triangle in the polygon with 3 more triangles including th...
Definition types.cpp:138
std::size_t getNumFaces() const
Definition types.hpp:773
std::vector< glm::vec3 > mPointsSupportA
List of points representing support point A, where each point corresponds to the polytope point it ge...
Definition types.hpp:737
glm::vec3 getClosestPoint() const
Returns the closest point to the origin on the triangle face closest to the origin.
Definition types.cpp:74
AreaTriangle getClosestTriangleSupportA() const
Gets the points of shape A that were responsible for generating the closest triangle of the polytope.
Definition types.cpp:97
Polytope()
Definition types.cpp:115
glm::vec3 getClosestTriangleNormal() const
Returns the direction to the closest point on the polytope's surface from the origin.
Definition types.cpp:80
std::vector< glm::vec3 > mPointsSupportB
List of points representing support point B, where each point corresponds to the polytope point it ge...
Definition types.hpp:743
glm::vec3 getNextSearch() const
Returns the next search direction for a point to add to the polytope.
Definition types.cpp:63
std::priority_queue< Face, std::vector< Face >, std::function< bool(const Face &, const Face &)> > mFaces
The list of triangle faces representing this polytope.
Definition types.hpp:727
std::vector< glm::vec3 > mPoints
List of points representing this polytope.
Definition types.hpp:732
ToyMaker Engine's implementation of an ECS system.
bool isPositiveStrict(float number)
Tests whether a number is strictly positive.
Definition types.hpp:80
bool isPositiveStrict() const
Checks whether underlying bounds is non-trivial, as in each important parameter that represents the v...
Definition types.cpp:18
uint8_t BoxCorner
Type used to represent the name of the corner of a box.
Definition types.hpp:35
BoxCornerSpecifier
Enum values correspond to bits on a BoxCorner which help specify which side of the box on each axis i...
Definition types.hpp:42
bool isNonNegative(float number)
Tests whether a number is non-negative.
Definition types.hpp:103
std::array< AreaTriangle, 12 > computeBoxFaceTriangles(const std::array< glm::vec3, 8 > &boxCorners)
Generates a list of triangles making up the surface of a box situated somewhere in the world,...
Definition types.cpp:442
bool isFinite(float number)
Tests whether a given number is finite.
Definition types.hpp:57
Namespace containing all class definitions and functions related to the ToyMaker engine.
Definition application.hpp:24
A set of numbers representing a single circle situated somewhere in the world.
Definition types.hpp:455
glm::vec3 mCenter
The real-world coordinates of the center of the circle.
Definition types.hpp:466
glm::vec3 mNormal
A vector normal to the surface of the circle, in whose direction it may be assumed the circle is faci...
Definition types.hpp:472
bool isSensible() const
Tests whether the circle described by these parameters is valid (as opposed to invalid or infinite).
Definition types.hpp:480
bool isPositiveStrict() const
Tests whether the circle's parameters are strictly positive, and hence whether the circle encloses so...
Definition types.hpp:499
float mRadius
The radius of the circle.
Definition types.hpp:460
A set of 3 points located in the world forming a (hopefully sensible) triangle.
Definition types.hpp:392
std::array< glm::vec3, 3 > mPoints
The points of the triangle, where each point has 3 components.
Definition types.hpp:397
bool isPositiveStrict() const
Tests whether the points of this triangle encapsulate some area in space.
Definition types.hpp:426
bool isSensible() const
Tests whether the points describing the triangle are sensible (as opposed to invalid or infinite).
Definition types.hpp:405
Data representing everything about a collision.
Definition types.hpp:888
Contact mContactA
Contact information relative to the first collision shape.
Definition types.hpp:899
Contact mContactB
Contact information relative to the second collision shape.
Definition types.hpp:905
bool mCollided
Whether a collision occurred.
Definition types.hpp:893
A component defining the true bounds of a spatially queryable object situated somewhere in the world.
Definition types.hpp:917
glm::quat getComputedWorldOrientation() const
The final orientation of the object bounds in the world.
Definition types.cpp:224
TrueVolume mTrueVolume
The data defining the volume itself, independent of its position.
Definition types.hpp:994
bool isSensible() const
Returns whether the underlying volume has sensible parameters (i.e., finite, non-degenerate,...
Definition types.cpp:244
static std::string getComponentTypeName()
Fetches the component type string associated with this class.
Definition types.hpp:923
glm::vec3 getComputedWorldPosition() const
The final position of the origin of the object bounds in the world.
Definition types.cpp:221
std::pair< float, float > getProjectionAlong(const glm::vec3 &axis) const
Returns this shape's projection along some unit vector.
Definition types.cpp:271
static ObjectBounds create(const VolumeBox &box, const glm::vec3 &positionOffset, const glm::quat &orientationOffset)
Creates bounds for an object in the shape of a box.
Definition types.cpp:36
std::array< glm::vec3, 8 > getLocalOrientedBoxCorners() const
Gets the corners of the box just encapsulating this object's true volume and sharing its position and...
Definition types.cpp:228
std::array< glm::vec3, 8 > getWorldOrientedBoxCorners() const
Gets the corners of the box just encapsulating this object's true volume relative to the origin of th...
Definition types.cpp:236
TrueVolumeType mType
Value indicating the type of the volume represented by this object.
Definition types.hpp:988
void applyModelMatrix(const glm::mat4 &modelMatrix)
Computes new mPosition and mOrientation offsets based on (presumably) the model transform of the unde...
Definition types.cpp:202
glm::quat mOrientation
The orientation in the real world of the scene node this bounds component is attached to.
Definition types.hpp:1012
glm::vec3 mPosition
The position, in the real world, of the scene node this data is attached to.
Definition types.hpp:1000
std::array< AreaTriangle, 12 > getWorldOrientedBoxFaceTriangles() const
Gets an array of triangles that make up the faces of the bounds-aligned box corners in world space.
Definition types.hpp:1089
glm::vec3 getSupportAlong(const glm::vec3 &axis) const
Returns the point on this object's surface furthest along a given axis from the origin of this object...
Definition types.cpp:289
glm::vec3 mPositionOffset
The position of the origin of the spatial query volume relative to the origin of the node it is attac...
Definition types.hpp:1006
glm::mat3 getWorldRotationTransform() const
Gets the rotation matrix associated with the underlying scene object's orientation,...
Definition types.hpp:1042
glm::mat3 getLocalRotationTransform() const
Gets the rotation matrix associated with this object's orientation offset.
Definition types.hpp:1033
glm::quat mOrientationOffset
The transformation mapping forward as known by the underlying scene node, to forward as known by the ...
Definition types.hpp:1019
std::array< glm::vec3, 8 > getVolumeRelativeBoxCorners() const
Gets the corners of the box just encapsulating this object's true volume, relative to the origin of t...
Definition types.cpp:207
TrueVolumeType
The types of volumes supported by the engine.
Definition types.hpp:929
A set of numbers describing a plane situated somewhere in the world.
Definition types.hpp:564
bool isPositiveStrict() const
Same as Plane::isSensible().
Definition types.hpp:601
glm::vec3 mNormal
A vector normal to the plane.
Definition types.hpp:575
glm::vec3 mPointOnPlane
A known point on the plane.
Definition types.hpp:569
bool isSensible() const
Tests whether the plane described is sensible (as opposed to invalid, infinite, or degenerate).
Definition types.hpp:583
Stores the indices of a single face of this polytope.
Definition types.hpp:713
A set of numbers describing a ray with its source at some finite point in the world,...
Definition types.hpp:511
float mLength
The length of the ray, infinite by default.
Definition types.hpp:528
glm::vec3 mStart
A point representing the starting point of the ray.
Definition types.hpp:516
glm::vec3 mDirection
The direction the ray is pointing in.
Definition types.hpp:522
bool isPositiveStrict() const
Tests whether the ray actually travels any distance from its origin.
Definition types.hpp:554
bool isSensible() const
Tests whether the ray is sensible (as opposed to invalid).
Definition types.hpp:536
Primitive for GJK algorithm.
Definition types.hpp:613
std::array< glm::vec3, 4 > mPointsSupportA
The point on the LHS of the Minkowski difference, where each index corresponds to a point on mPoints.
Definition types.hpp:625
std::array< glm::vec3, 4 > mPointsSupportB
The point on the RHS of the Minkowski difference, where each index corresponds to a point on mPoints.
Definition types.hpp:631
std::pair< bool, glm::vec3 > evaluate()
Tries to find a 3-simplex that encloses the origin.
Definition types.cpp:581
bool append(const glm::vec3 &candidatePoint, const glm::vec3 &supportA, const glm::vec3 &supportB)
Adds a new point to the simplex.
Definition types.hpp:645
uint8_t mNPoints
The number of points in this simplex.
Definition types.hpp:637
void reorder(const std::vector< uint8_t > reorderedIndices)
Replaces the current simplex with points from a new list (which will usually have as many or fewer po...
Definition types.hpp:669
std::array< glm::vec3, 4 > mPoints
Points representing the simplex, derived by finding the Minksowski difference of support points on tw...
Definition types.hpp:619
The base class of all spatial query volumes.
Definition types.hpp:131
bool isSensible() const
Returns whether or not the derived volume has sensible parameters (i.e., isn't infinite or invalid).
Definition types.hpp:191
static std::array< glm::vec3, 8 > ComputeBoxCorners(const glm::vec3 &boxDimensions)
Computes the model relative corners of a box, given the dimensions of the box.
Definition types.hpp:156
static constexpr std::array< glm::vec3, 8 > GetCornerSignsArray()
Returns an array populated with axis-wise sign multipliers, where the positions on the array correspo...
Definition types.hpp:140
bool isPositiveStrict() const
Returns whether or not the derived volume has strictly positive parameters.
Definition types.hpp:204
std::array< glm::vec3, 8 > getVolumeRelativeBoxCorners() const
Gets corners of the object-relative bounding box that encapsulates the derived volume.
Definition types.hpp:176
Holds the parameters describing the spatial query volume of a simple three-dimensionsal box.
Definition types.hpp:248
bool isSensible() const
Tests whether the values representing the box are valid (as opposed to invalid or infinite).
Definition types.hpp:270
glm::vec3 mDimensions
The dimensions of the box, its width, height, and depth.
Definition types.hpp:253
bool isPositiveStrict() const
Tests whether the values representing the box are strictly positive.
Definition types.hpp:280
std::array< glm::vec3, 8 > getVolumeRelativeBoxCorners() const
Returns an array of coordinates corresponding to the corners of the box.
Definition types.hpp:260
Holds the parameters describing the spatial query volume of a simple three-dimensionsal capsule (or p...
Definition types.hpp:290
float mRadius
The radius of the hemispheres on either end of the capsule.
Definition types.hpp:301
std::array< glm::vec3, 8 > getVolumeRelativeBoxCorners() const
Gets an array containing the coordinates of the corners of the volume aligned box just containing the...
Definition types.hpp:308
float mHeight
The height of the cylindrical section of the capsule.
Definition types.hpp:295
bool isPositiveStrict() const
Tests whether the values representing the capsule are all strictly positive.
Definition types.hpp:335
bool isSensible() const
Tests whether the values representing the capsule make sense (as opposed to being invalid or infinite...
Definition types.hpp:321
Holds parameters describing a spherical spatial query volume.
Definition types.hpp:349
float mRadius
The radius of the sphere.
Definition types.hpp:354
std::array< glm::vec3, 8 > getVolumeRelativeBoxCorners() const
Gets an array of coordinates of corners of a box just encapsulating the sphere.
Definition types.hpp:361
bool isPositiveStrict() const
Tests whether this volume's parameters are strictly positive.
Definition types.hpp:382
bool isSensible() const
Tests whether this volume's parameters are sensible (as opposed to invalid or infinite).
Definition types.hpp:371
bool isPositiveStrict() const
Poor man's vtable cont'd.
Definition types.hpp:238
bool isSensible() const
Poor man's vtable cont'd.
Definition types.hpp:228
std::array< glm::vec3, 8 > getVolumeRelativeBoxCorners() const
Poor man's vtable cont'd.
Definition types.hpp:218
A union of supported volume structs.
Definition types.hpp:939