Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
ActiveEdges.h
Go to the documentation of this file.
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
8
10
12namespace ActiveEdges
13{
19 inline static bool IsEdgeActive(Vec3Arg inNormal1, Vec3Arg inNormal2, Vec3Arg inEdgeDirection, float inCosThresholdAngle)
20 {
21 // If normals are opposite the edges are active (the triangles are back to back)
22 float cos_angle_normals = inNormal1.Dot(inNormal2);
23 if (cos_angle_normals < -0.999848f) // cos(179 degrees)
24 return true;
25
26 // Check if concave edge, if so we are not active
27 if (inNormal1.Cross(inNormal2).Dot(inEdgeDirection) < 0.0f)
28 return false;
29
30 // Convex edge, active when angle bigger than threshold
31 return cos_angle_normals < inCosThresholdAngle;
32 }
33
42 inline static Vec3 FixNormal(Vec3Arg inV0, Vec3Arg inV1, Vec3Arg inV2, Vec3Arg inTriangleNormal, uint8 inActiveEdges, Vec3Arg inPoint, Vec3Arg inNormal, Vec3Arg inMovementDirection)
43 {
44 // Check: All of the edges are active, we have the correct normal already. No need to call this function!
45 JPH_ASSERT(inActiveEdges != 0b111);
46
47 // If inNormal would affect movement less than inTriangleNormal use inNormal
48 // This is done since it is really hard to make a distinction between sliding over a horizontal triangulated grid and hitting an edge (in this case you want to use the triangle normal)
49 // and sliding over a triangulated grid and grazing a vertical triangle with an inactive edge (in this case using the triangle normal will cause the object to bounce back so we want to use the calculated normal).
50 // To solve this we take a movement hint to give an indication of what direction our object is moving. If the edge normal results in less motion difference than the triangle normal we use the edge normal.
51 float normal_length = inNormal.Length();
52 float triangle_normal_length = inTriangleNormal.Length();
53 if (inMovementDirection.Dot(inNormal) * triangle_normal_length < inMovementDirection.Dot(inTriangleNormal) * normal_length)
54 return inNormal;
55
56 // Check: None of the edges are active, we need to use the triangle normal
57 if (inActiveEdges == 0)
58 return inTriangleNormal;
59
60 // Some edges are active.
61 // If normal is parallel to the triangle normal we don't need to check the active edges.
62 if (inTriangleNormal.Dot(inNormal) > 0.999848f * normal_length * triangle_normal_length) // cos(1 degree)
63 return inNormal;
64
65 const float cEpsilon = 1.0e-4f;
66 const float cOneMinusEpsilon = 1.0f - cEpsilon;
67
68 uint colliding_edge;
69
70 // Test where the contact point is in the triangle
71 float u, v, w;
72 ClosestPoint::GetBaryCentricCoordinates(inV0 - inPoint, inV1 - inPoint, inV2 - inPoint, u, v, w);
73 if (u > cOneMinusEpsilon)
74 {
75 // Colliding with v0, edge 0 or 2 needs to be active
76 colliding_edge = 0b101;
77 }
78 else if (v > cOneMinusEpsilon)
79 {
80 // Colliding with v1, edge 0 or 1 needs to be active
81 colliding_edge = 0b011;
82 }
83 else if (w > cOneMinusEpsilon)
84 {
85 // Colliding with v2, edge 1 or 2 needs to be active
86 colliding_edge = 0b110;
87 }
88 else if (u < cEpsilon)
89 {
90 // Colliding with edge v1, v2, edge 1 needs to be active
91 colliding_edge = 0b010;
92 }
93 else if (v < cEpsilon)
94 {
95 // Colliding with edge v0, v2, edge 2 needs to be active
96 colliding_edge = 0b100;
97 }
98 else if (w < cEpsilon)
99 {
100 // Colliding with edge v0, v1, edge 0 needs to be active
101 colliding_edge = 0b001;
102 }
103 else
104 {
105 // Interior hit
106 return inTriangleNormal;
107 }
108
109 // If this edge is active, use the provided normal instead of the triangle normal
110 return (inActiveEdges & colliding_edge) != 0? inNormal : inTriangleNormal;
111 }
112}
113
std::uint8_t uint8
Definition: Core.h:453
unsigned int uint
Definition: Core.h:452
#define JPH_NAMESPACE_END
Definition: Core.h:378
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:372
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
Definition: Vec3.h:17
JPH_INLINE float Dot(Vec3Arg inV2) const
Dot product.
Definition: Vec3.inl:645
JPH_INLINE Vec3 Cross(Vec3Arg inV2) const
Cross product.
Definition: Vec3.inl:590
JPH_INLINE float Length() const
Length of vector.
Definition: Vec3.inl:677
An active edge is an edge that either has no neighbouring edge or if the angle between the two connec...
Definition: ActiveEdges.h:13
bool GetBaryCentricCoordinates(Vec3Arg inA, Vec3Arg inB, float &outU, float &outV)
Definition: ClosestPoint.h:18