Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Geometry/IndexedTriangle.h
9913 views
1
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3
// SPDX-License-Identifier: MIT
4
5
#pragma once
6
7
#include <Jolt/Core/HashCombine.h>
8
9
JPH_NAMESPACE_BEGIN
10
11
/// Triangle with 32-bit indices
12
class IndexedTriangleNoMaterial
13
{
14
public:
15
JPH_OVERRIDE_NEW_DELETE
16
17
/// Constructor
18
IndexedTriangleNoMaterial() = default;
19
constexpr IndexedTriangleNoMaterial(uint32 inI1, uint32 inI2, uint32 inI3) : mIdx { inI1, inI2, inI3 } { }
20
21
/// Check if two triangles are identical
22
bool operator == (const IndexedTriangleNoMaterial &inRHS) const
23
{
24
return mIdx[0] == inRHS.mIdx[0] && mIdx[1] == inRHS.mIdx[1] && mIdx[2] == inRHS.mIdx[2];
25
}
26
27
/// Check if two triangles are equivalent (using the same vertices)
28
bool IsEquivalent(const IndexedTriangleNoMaterial &inRHS) const
29
{
30
return (mIdx[0] == inRHS.mIdx[0] && mIdx[1] == inRHS.mIdx[1] && mIdx[2] == inRHS.mIdx[2])
31
|| (mIdx[0] == inRHS.mIdx[1] && mIdx[1] == inRHS.mIdx[2] && mIdx[2] == inRHS.mIdx[0])
32
|| (mIdx[0] == inRHS.mIdx[2] && mIdx[1] == inRHS.mIdx[0] && mIdx[2] == inRHS.mIdx[1]);
33
}
34
35
/// Check if two triangles are opposite (using the same vertices but in opposing order)
36
bool IsOpposite(const IndexedTriangleNoMaterial &inRHS) const
37
{
38
return (mIdx[0] == inRHS.mIdx[0] && mIdx[1] == inRHS.mIdx[2] && mIdx[2] == inRHS.mIdx[1])
39
|| (mIdx[0] == inRHS.mIdx[1] && mIdx[1] == inRHS.mIdx[0] && mIdx[2] == inRHS.mIdx[2])
40
|| (mIdx[0] == inRHS.mIdx[2] && mIdx[1] == inRHS.mIdx[1] && mIdx[2] == inRHS.mIdx[0]);
41
}
42
43
/// Check if triangle is degenerate
44
bool IsDegenerate(const VertexList &inVertices) const
45
{
46
Vec3 v0(inVertices[mIdx[0]]);
47
Vec3 v1(inVertices[mIdx[1]]);
48
Vec3 v2(inVertices[mIdx[2]]);
49
50
return (v1 - v0).Cross(v2 - v0).IsNearZero();
51
}
52
53
/// Rotate the vertices so that the second vertex becomes first etc. This does not change the represented triangle.
54
void Rotate()
55
{
56
uint32 tmp = mIdx[0];
57
mIdx[0] = mIdx[1];
58
mIdx[1] = mIdx[2];
59
mIdx[2] = tmp;
60
}
61
62
/// Get center of triangle
63
Vec3 GetCentroid(const VertexList &inVertices) const
64
{
65
return (Vec3(inVertices[mIdx[0]]) + Vec3(inVertices[mIdx[1]]) + Vec3(inVertices[mIdx[2]])) / 3.0f;
66
}
67
68
/// Get the hash value of this structure
69
uint64 GetHash() const
70
{
71
static_assert(sizeof(IndexedTriangleNoMaterial) == 3 * sizeof(uint32), "Class should have no padding");
72
return HashBytes(this, sizeof(IndexedTriangleNoMaterial));
73
}
74
75
uint32 mIdx[3];
76
};
77
78
/// Triangle with 32-bit indices and material index
79
class IndexedTriangle : public IndexedTriangleNoMaterial
80
{
81
public:
82
using IndexedTriangleNoMaterial::IndexedTriangleNoMaterial;
83
84
/// Constructor
85
constexpr IndexedTriangle(uint32 inI1, uint32 inI2, uint32 inI3, uint32 inMaterialIndex, uint inUserData = 0) : IndexedTriangleNoMaterial(inI1, inI2, inI3), mMaterialIndex(inMaterialIndex), mUserData(inUserData) { }
86
87
/// Check if two triangles are identical
88
bool operator == (const IndexedTriangle &inRHS) const
89
{
90
return mMaterialIndex == inRHS.mMaterialIndex && mUserData == inRHS.mUserData && IndexedTriangleNoMaterial::operator==(inRHS);
91
}
92
93
/// Rotate the vertices so that the lowest vertex becomes the first. This does not change the represented triangle.
94
IndexedTriangle GetLowestIndexFirst() const
95
{
96
if (mIdx[0] < mIdx[1])
97
{
98
if (mIdx[0] < mIdx[2])
99
return IndexedTriangle(mIdx[0], mIdx[1], mIdx[2], mMaterialIndex, mUserData); // 0 is smallest
100
else
101
return IndexedTriangle(mIdx[2], mIdx[0], mIdx[1], mMaterialIndex, mUserData); // 2 is smallest
102
}
103
else
104
{
105
if (mIdx[1] < mIdx[2])
106
return IndexedTriangle(mIdx[1], mIdx[2], mIdx[0], mMaterialIndex, mUserData); // 1 is smallest
107
else
108
return IndexedTriangle(mIdx[2], mIdx[0], mIdx[1], mMaterialIndex, mUserData); // 2 is smallest
109
}
110
}
111
112
/// Get the hash value of this structure
113
uint64 GetHash() const
114
{
115
static_assert(sizeof(IndexedTriangle) == 5 * sizeof(uint32), "Class should have no padding");
116
return HashBytes(this, sizeof(IndexedTriangle));
117
}
118
119
uint32 mMaterialIndex = 0;
120
uint32 mUserData = 0; ///< User data that can be used for anything by the application, e.g. for tracking the original index of the triangle
121
};
122
123
using IndexedTriangleNoMaterialList = Array<IndexedTriangleNoMaterial>;
124
using IndexedTriangleList = Array<IndexedTriangle>;
125
126
JPH_NAMESPACE_END
127
128
// Create a std::hash for IndexedTriangleNoMaterial and IndexedTriangle
129
JPH_MAKE_STD_HASH(JPH::IndexedTriangleNoMaterial)
130
JPH_MAKE_STD_HASH(JPH::IndexedTriangle)
131
132