initial commit, 4.5 stable
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
This commit is contained in:
248
thirdparty/jolt_physics/Jolt/Physics/Collision/Shape/GetTrianglesContext.h
vendored
Normal file
248
thirdparty/jolt_physics/Jolt/Physics/Collision/Shape/GetTrianglesContext.h
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/Physics/Collision/Shape/Shape.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
class PhysicsMaterial;
|
||||
|
||||
/// Implementation of GetTrianglesStart/Next that uses a fixed list of vertices for the triangles. These are transformed into world space when getting the triangles.
|
||||
class GetTrianglesContextVertexList
|
||||
{
|
||||
public:
|
||||
/// Constructor, to be called in GetTrianglesStart
|
||||
GetTrianglesContextVertexList(Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, Mat44Arg inLocalTransform, const Vec3 *inTriangleVertices, size_t inNumTriangleVertices, const PhysicsMaterial *inMaterial) :
|
||||
mLocalToWorld(Mat44::sRotationTranslation(inRotation, inPositionCOM) * Mat44::sScale(inScale) * inLocalTransform),
|
||||
mTriangleVertices(inTriangleVertices),
|
||||
mNumTriangleVertices(inNumTriangleVertices),
|
||||
mMaterial(inMaterial),
|
||||
mIsInsideOut(ScaleHelpers::IsInsideOut(inScale))
|
||||
{
|
||||
static_assert(sizeof(GetTrianglesContextVertexList) <= sizeof(Shape::GetTrianglesContext), "GetTrianglesContext too small");
|
||||
JPH_ASSERT(IsAligned(this, alignof(GetTrianglesContextVertexList)));
|
||||
JPH_ASSERT(inNumTriangleVertices % 3 == 0);
|
||||
}
|
||||
|
||||
/// @see Shape::GetTrianglesNext
|
||||
int GetTrianglesNext(int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials)
|
||||
{
|
||||
JPH_ASSERT(inMaxTrianglesRequested >= Shape::cGetTrianglesMinTrianglesRequested);
|
||||
|
||||
int total_num_vertices = min(inMaxTrianglesRequested * 3, int(mNumTriangleVertices - mCurrentVertex));
|
||||
|
||||
if (mIsInsideOut)
|
||||
{
|
||||
// Store triangles flipped
|
||||
for (const Vec3 *v = mTriangleVertices + mCurrentVertex, *v_end = v + total_num_vertices; v < v_end; v += 3)
|
||||
{
|
||||
(mLocalToWorld * v[0]).StoreFloat3(outTriangleVertices++);
|
||||
(mLocalToWorld * v[2]).StoreFloat3(outTriangleVertices++);
|
||||
(mLocalToWorld * v[1]).StoreFloat3(outTriangleVertices++);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store triangles
|
||||
for (const Vec3 *v = mTriangleVertices + mCurrentVertex, *v_end = v + total_num_vertices; v < v_end; v += 3)
|
||||
{
|
||||
(mLocalToWorld * v[0]).StoreFloat3(outTriangleVertices++);
|
||||
(mLocalToWorld * v[1]).StoreFloat3(outTriangleVertices++);
|
||||
(mLocalToWorld * v[2]).StoreFloat3(outTriangleVertices++);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the current vertex to point to the next vertex to get
|
||||
mCurrentVertex += total_num_vertices;
|
||||
int total_num_triangles = total_num_vertices / 3;
|
||||
|
||||
// Store materials
|
||||
if (outMaterials != nullptr)
|
||||
for (const PhysicsMaterial **m = outMaterials, **m_end = outMaterials + total_num_triangles; m < m_end; ++m)
|
||||
*m = mMaterial;
|
||||
|
||||
return total_num_triangles;
|
||||
}
|
||||
|
||||
/// Helper function that creates a vertex list of a half unit sphere (top part)
|
||||
template <class A>
|
||||
static void sCreateHalfUnitSphereTop(A &ioVertices, int inDetailLevel)
|
||||
{
|
||||
sCreateUnitSphereHelper(ioVertices, Vec3::sAxisX(), Vec3::sAxisY(), Vec3::sAxisZ(), inDetailLevel);
|
||||
sCreateUnitSphereHelper(ioVertices, Vec3::sAxisY(), -Vec3::sAxisX(), Vec3::sAxisZ(), inDetailLevel);
|
||||
sCreateUnitSphereHelper(ioVertices, Vec3::sAxisY(), Vec3::sAxisX(), -Vec3::sAxisZ(), inDetailLevel);
|
||||
sCreateUnitSphereHelper(ioVertices, -Vec3::sAxisX(), Vec3::sAxisY(), -Vec3::sAxisZ(), inDetailLevel);
|
||||
}
|
||||
|
||||
/// Helper function that creates a vertex list of a half unit sphere (bottom part)
|
||||
template <class A>
|
||||
static void sCreateHalfUnitSphereBottom(A &ioVertices, int inDetailLevel)
|
||||
{
|
||||
sCreateUnitSphereHelper(ioVertices, -Vec3::sAxisX(), -Vec3::sAxisY(), Vec3::sAxisZ(), inDetailLevel);
|
||||
sCreateUnitSphereHelper(ioVertices, -Vec3::sAxisY(), Vec3::sAxisX(), Vec3::sAxisZ(), inDetailLevel);
|
||||
sCreateUnitSphereHelper(ioVertices, Vec3::sAxisX(), -Vec3::sAxisY(), -Vec3::sAxisZ(), inDetailLevel);
|
||||
sCreateUnitSphereHelper(ioVertices, -Vec3::sAxisY(), -Vec3::sAxisX(), -Vec3::sAxisZ(), inDetailLevel);
|
||||
}
|
||||
|
||||
/// Helper function that creates an open cylinder of half height 1 and radius 1
|
||||
template <class A>
|
||||
static void sCreateUnitOpenCylinder(A &ioVertices, int inDetailLevel)
|
||||
{
|
||||
const Vec3 bottom_offset(0.0f, -2.0f, 0.0f);
|
||||
int num_verts = 4 * (1 << inDetailLevel);
|
||||
for (int i = 0; i < num_verts; ++i)
|
||||
{
|
||||
float angle1 = 2.0f * JPH_PI * (float(i) / num_verts);
|
||||
float angle2 = 2.0f * JPH_PI * (float(i + 1) / num_verts);
|
||||
|
||||
Vec3 t1(Sin(angle1), 1.0f, Cos(angle1));
|
||||
Vec3 t2(Sin(angle2), 1.0f, Cos(angle2));
|
||||
Vec3 b1 = t1 + bottom_offset;
|
||||
Vec3 b2 = t2 + bottom_offset;
|
||||
|
||||
ioVertices.push_back(t1);
|
||||
ioVertices.push_back(b1);
|
||||
ioVertices.push_back(t2);
|
||||
|
||||
ioVertices.push_back(t2);
|
||||
ioVertices.push_back(b1);
|
||||
ioVertices.push_back(b2);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/// Recursive helper function for creating a sphere
|
||||
template <class A>
|
||||
static void sCreateUnitSphereHelper(A &ioVertices, Vec3Arg inV1, Vec3Arg inV2, Vec3Arg inV3, int inLevel)
|
||||
{
|
||||
Vec3 center1 = (inV1 + inV2).Normalized();
|
||||
Vec3 center2 = (inV2 + inV3).Normalized();
|
||||
Vec3 center3 = (inV3 + inV1).Normalized();
|
||||
|
||||
if (inLevel > 0)
|
||||
{
|
||||
int new_level = inLevel - 1;
|
||||
sCreateUnitSphereHelper(ioVertices, inV1, center1, center3, new_level);
|
||||
sCreateUnitSphereHelper(ioVertices, center1, center2, center3, new_level);
|
||||
sCreateUnitSphereHelper(ioVertices, center1, inV2, center2, new_level);
|
||||
sCreateUnitSphereHelper(ioVertices, center3, center2, inV3, new_level);
|
||||
}
|
||||
else
|
||||
{
|
||||
ioVertices.push_back(inV1);
|
||||
ioVertices.push_back(inV2);
|
||||
ioVertices.push_back(inV3);
|
||||
}
|
||||
}
|
||||
|
||||
Mat44 mLocalToWorld;
|
||||
const Vec3 * mTriangleVertices;
|
||||
size_t mNumTriangleVertices;
|
||||
size_t mCurrentVertex = 0;
|
||||
const PhysicsMaterial * mMaterial;
|
||||
bool mIsInsideOut;
|
||||
};
|
||||
|
||||
/// Implementation of GetTrianglesStart/Next that uses a multiple fixed lists of vertices for the triangles. These are transformed into world space when getting the triangles.
|
||||
class GetTrianglesContextMultiVertexList
|
||||
{
|
||||
public:
|
||||
/// Constructor, to be called in GetTrianglesStart
|
||||
GetTrianglesContextMultiVertexList(bool inIsInsideOut, const PhysicsMaterial *inMaterial) :
|
||||
mMaterial(inMaterial),
|
||||
mIsInsideOut(inIsInsideOut)
|
||||
{
|
||||
static_assert(sizeof(GetTrianglesContextMultiVertexList) <= sizeof(Shape::GetTrianglesContext), "GetTrianglesContext too small");
|
||||
JPH_ASSERT(IsAligned(this, alignof(GetTrianglesContextMultiVertexList)));
|
||||
}
|
||||
|
||||
/// Add a mesh part and its transform
|
||||
void AddPart(Mat44Arg inLocalToWorld, const Vec3 *inTriangleVertices, size_t inNumTriangleVertices)
|
||||
{
|
||||
JPH_ASSERT(inNumTriangleVertices % 3 == 0);
|
||||
|
||||
mParts.push_back({ inLocalToWorld, inTriangleVertices, inNumTriangleVertices });
|
||||
}
|
||||
|
||||
/// @see Shape::GetTrianglesNext
|
||||
int GetTrianglesNext(int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials)
|
||||
{
|
||||
JPH_ASSERT(inMaxTrianglesRequested >= Shape::cGetTrianglesMinTrianglesRequested);
|
||||
|
||||
int total_num_vertices = 0;
|
||||
int max_vertices_requested = inMaxTrianglesRequested * 3;
|
||||
|
||||
// Loop over parts
|
||||
for (; mCurrentPart < mParts.size(); ++mCurrentPart)
|
||||
{
|
||||
const Part &part = mParts[mCurrentPart];
|
||||
|
||||
// Calculate how many vertices to take from this part
|
||||
int part_num_vertices = min(max_vertices_requested, int(part.mNumTriangleVertices - mCurrentVertex));
|
||||
if (part_num_vertices == 0)
|
||||
break;
|
||||
|
||||
max_vertices_requested -= part_num_vertices;
|
||||
total_num_vertices += part_num_vertices;
|
||||
|
||||
if (mIsInsideOut)
|
||||
{
|
||||
// Store triangles flipped
|
||||
for (const Vec3 *v = part.mTriangleVertices + mCurrentVertex, *v_end = v + part_num_vertices; v < v_end; v += 3)
|
||||
{
|
||||
(part.mLocalToWorld * v[0]).StoreFloat3(outTriangleVertices++);
|
||||
(part.mLocalToWorld * v[2]).StoreFloat3(outTriangleVertices++);
|
||||
(part.mLocalToWorld * v[1]).StoreFloat3(outTriangleVertices++);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store triangles
|
||||
for (const Vec3 *v = part.mTriangleVertices + mCurrentVertex, *v_end = v + part_num_vertices; v < v_end; v += 3)
|
||||
{
|
||||
(part.mLocalToWorld * v[0]).StoreFloat3(outTriangleVertices++);
|
||||
(part.mLocalToWorld * v[1]).StoreFloat3(outTriangleVertices++);
|
||||
(part.mLocalToWorld * v[2]).StoreFloat3(outTriangleVertices++);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the current vertex to point to the next vertex to get
|
||||
mCurrentVertex += part_num_vertices;
|
||||
|
||||
// Check if we completed this part
|
||||
if (mCurrentVertex < part.mNumTriangleVertices)
|
||||
break;
|
||||
|
||||
// Reset current vertex for the next part
|
||||
mCurrentVertex = 0;
|
||||
}
|
||||
|
||||
int total_num_triangles = total_num_vertices / 3;
|
||||
|
||||
// Store materials
|
||||
if (outMaterials != nullptr)
|
||||
for (const PhysicsMaterial **m = outMaterials, **m_end = outMaterials + total_num_triangles; m < m_end; ++m)
|
||||
*m = mMaterial;
|
||||
|
||||
return total_num_triangles;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Part
|
||||
{
|
||||
Mat44 mLocalToWorld;
|
||||
const Vec3 * mTriangleVertices;
|
||||
size_t mNumTriangleVertices;
|
||||
};
|
||||
|
||||
StaticArray<Part, 3> mParts;
|
||||
uint mCurrentPart = 0;
|
||||
size_t mCurrentVertex = 0;
|
||||
const PhysicsMaterial * mMaterial;
|
||||
bool mIsInsideOut;
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
Reference in New Issue
Block a user