godot-module-template/engine/thirdparty/jolt_physics/Jolt/Geometry/ConvexSupport.h

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