189 lines
4.6 KiB
C++
189 lines
4.6 KiB
C++
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
|
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#pragma once
|
|
|
|
#include <Jolt/Math/Mat44.h>
|
|
|
|
JPH_NAMESPACE_BEGIN
|
|
|
|
/// Helper functions to get the support point for a convex object
|
|
/// Structure that transforms a convex object (supports only uniform scaling)
|
|
template <typename ConvexObject>
|
|
struct TransformedConvexObject
|
|
{
|
|
/// Create transformed convex object.
|
|
TransformedConvexObject(Mat44Arg inTransform, const ConvexObject &inObject) :
|
|
mTransform(inTransform),
|
|
mObject(inObject)
|
|
{
|
|
}
|
|
|
|
/// Calculate the support vector for this convex shape.
|
|
Vec3 GetSupport(Vec3Arg inDirection) const
|
|
{
|
|
return mTransform * mObject.GetSupport(mTransform.Multiply3x3Transposed(inDirection));
|
|
}
|
|
|
|
/// Get the vertices of the face that faces inDirection the most
|
|
template <class VERTEX_ARRAY>
|
|
void GetSupportingFace(Vec3Arg inDirection, VERTEX_ARRAY &outVertices) const
|
|
{
|
|
mObject.GetSupportingFace(mTransform.Multiply3x3Transposed(inDirection), outVertices);
|
|
|
|
for (Vec3 &v : outVertices)
|
|
v = mTransform * v;
|
|
}
|
|
|
|
Mat44 mTransform;
|
|
const ConvexObject & mObject;
|
|
};
|
|
|
|
/// Structure that adds a convex radius
|
|
template <typename ConvexObject>
|
|
struct AddConvexRadius
|
|
{
|
|
AddConvexRadius(const ConvexObject &inObject, float inRadius) :
|
|
mObject(inObject),
|
|
mRadius(inRadius)
|
|
{
|
|
}
|
|
|
|
/// Calculate the support vector for this convex shape.
|
|
Vec3 GetSupport(Vec3Arg inDirection) const
|
|
{
|
|
float length = inDirection.Length();
|
|
return length > 0.0f ? mObject.GetSupport(inDirection) + (mRadius / length) * inDirection : mObject.GetSupport(inDirection);
|
|
}
|
|
|
|
const ConvexObject & mObject;
|
|
float mRadius;
|
|
};
|
|
|
|
/// Structure that performs a Minkowski difference A - B
|
|
template <typename ConvexObjectA, typename ConvexObjectB>
|
|
struct MinkowskiDifference
|
|
{
|
|
MinkowskiDifference(const ConvexObjectA &inObjectA, const ConvexObjectB &inObjectB) :
|
|
mObjectA(inObjectA),
|
|
mObjectB(inObjectB)
|
|
{
|
|
}
|
|
|
|
/// Calculate the support vector for this convex shape.
|
|
Vec3 GetSupport(Vec3Arg inDirection) const
|
|
{
|
|
return mObjectA.GetSupport(inDirection) - mObjectB.GetSupport(-inDirection);
|
|
}
|
|
|
|
const ConvexObjectA & mObjectA;
|
|
const ConvexObjectB & mObjectB;
|
|
};
|
|
|
|
/// Class that wraps a point so that it can be used with convex collision detection
|
|
struct PointConvexSupport
|
|
{
|
|
/// Calculate the support vector for this convex shape.
|
|
Vec3 GetSupport([[maybe_unused]] Vec3Arg inDirection) const
|
|
{
|
|
return mPoint;
|
|
}
|
|
|
|
Vec3 mPoint;
|
|
};
|
|
|
|
/// Class that wraps a triangle so that it can used with convex collision detection
|
|
struct TriangleConvexSupport
|
|
{
|
|
/// Constructor
|
|
TriangleConvexSupport(Vec3Arg inV1, Vec3Arg inV2, Vec3Arg inV3) :
|
|
mV1(inV1),
|
|
mV2(inV2),
|
|
mV3(inV3)
|
|
{
|
|
}
|
|
|
|
/// Calculate the support vector for this convex shape.
|
|
Vec3 GetSupport(Vec3Arg inDirection) const
|
|
{
|
|
// Project vertices on inDirection
|
|
float d1 = mV1.Dot(inDirection);
|
|
float d2 = mV2.Dot(inDirection);
|
|
float d3 = mV3.Dot(inDirection);
|
|
|
|
// Return vertex with biggest projection
|
|
if (d1 > d2)
|
|
{
|
|
if (d1 > d3)
|
|
return mV1;
|
|
else
|
|
return mV3;
|
|
}
|
|
else
|
|
{
|
|
if (d2 > d3)
|
|
return mV2;
|
|
else
|
|
return mV3;
|
|
}
|
|
}
|
|
|
|
/// Get the vertices of the face that faces inDirection the most
|
|
template <class VERTEX_ARRAY>
|
|
void GetSupportingFace([[maybe_unused]] Vec3Arg inDirection, VERTEX_ARRAY &outVertices) const
|
|
{
|
|
outVertices.push_back(mV1);
|
|
outVertices.push_back(mV2);
|
|
outVertices.push_back(mV3);
|
|
}
|
|
|
|
/// The three vertices of the triangle
|
|
Vec3 mV1;
|
|
Vec3 mV2;
|
|
Vec3 mV3;
|
|
};
|
|
|
|
/// Class that wraps a polygon so that it can used with convex collision detection
|
|
template <class VERTEX_ARRAY>
|
|
struct PolygonConvexSupport
|
|
{
|
|
/// Constructor
|
|
explicit PolygonConvexSupport(const VERTEX_ARRAY &inVertices) :
|
|
mVertices(inVertices)
|
|
{
|
|
}
|
|
|
|
/// Calculate the support vector for this convex shape.
|
|
Vec3 GetSupport(Vec3Arg inDirection) const
|
|
{
|
|
Vec3 support_point = mVertices[0];
|
|
float best_dot = mVertices[0].Dot(inDirection);
|
|
|
|
for (typename VERTEX_ARRAY::const_iterator v = mVertices.begin() + 1; v < mVertices.end(); ++v)
|
|
{
|
|
float dot = v->Dot(inDirection);
|
|
if (dot > best_dot)
|
|
{
|
|
best_dot = dot;
|
|
support_point = *v;
|
|
}
|
|
}
|
|
|
|
return support_point;
|
|
}
|
|
|
|
/// Get the vertices of the face that faces inDirection the most
|
|
template <class VERTEX_ARRAY_ARG>
|
|
void GetSupportingFace([[maybe_unused]] Vec3Arg inDirection, VERTEX_ARRAY_ARG &outVertices) const
|
|
{
|
|
for (Vec3 v : mVertices)
|
|
outVertices.push_back(v);
|
|
}
|
|
|
|
/// The vertices of the polygon
|
|
const VERTEX_ARRAY & mVertices;
|
|
};
|
|
|
|
JPH_NAMESPACE_END
|