Skip to content
This repository was archived by the owner on Mar 30, 2019. It is now read-only.

Commit 9f847c5

Browse files
author
AndrewSt
committed
[Mathematics] fix bug in Collision.ClosestPointPointTriangle()
1 parent 8a2aab2 commit 9f847c5

3 files changed

Lines changed: 60 additions & 0 deletions

File tree

Source/SharpDX.Mathematics/Collision.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,36 +97,47 @@ public static void ClosestPointPointTriangle(ref Vector3 point, ref Vector3 vert
9797
float d1 = Vector3.Dot(ab, ap);
9898
float d2 = Vector3.Dot(ac, ap);
9999
if (d1 <= 0.0f && d2 <= 0.0f)
100+
{
100101
result = vertex1; //Barycentric coordinates (1,0,0)
102+
return;
103+
}
101104

102105
//Check if P in vertex region outside B
103106
Vector3 bp = point - vertex2;
104107
float d3 = Vector3.Dot(ab, bp);
105108
float d4 = Vector3.Dot(ac, bp);
106109
if (d3 >= 0.0f && d4 <= d3)
110+
{
107111
result = vertex2; // Barycentric coordinates (0,1,0)
112+
return;
113+
}
108114

109115
//Check if P in edge region of AB, if so return projection of P onto AB
110116
float vc = d1 * d4 - d3 * d2;
111117
if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f)
112118
{
113119
float v = d1 / (d1 - d3);
114120
result = vertex1 + v * ab; //Barycentric coordinates (1-v,v,0)
121+
return;
115122
}
116123

117124
//Check if P in vertex region outside C
118125
Vector3 cp = point - vertex3;
119126
float d5 = Vector3.Dot(ab, cp);
120127
float d6 = Vector3.Dot(ac, cp);
121128
if (d6 >= 0.0f && d5 <= d6)
129+
{
122130
result = vertex3; //Barycentric coordinates (0,0,1)
131+
return;
132+
}
123133

124134
//Check if P in edge region of AC, if so return projection of P onto AC
125135
float vb = d5 * d2 - d1 * d6;
126136
if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f)
127137
{
128138
float w = d2 / (d2 - d6);
129139
result = vertex1 + w * ac; //Barycentric coordinates (1-w,0,w)
140+
return;
130141
}
131142

132143
//Check if P in edge region of BC, if so return projection of P onto BC
@@ -135,6 +146,7 @@ public static void ClosestPointPointTriangle(ref Vector3 point, ref Vector3 vert
135146
{
136147
float w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
137148
result = vertex2 + w * (vertex3 - vertex2); //Barycentric coordinates (0,1-w,w)
149+
return;
138150
}
139151

140152
//P inside face region. Compute Q through its Barycentric coordinates (u,v,w)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to deal
5+
// in the Software without restriction, including without limitation the rights
6+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
// copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
// THE SOFTWARE.
20+
using NUnit.Framework;
21+
22+
namespace SharpDX.Tests
23+
{
24+
[TestFixture]
25+
public class MathCollisionTest
26+
{
27+
[Test]
28+
public void ClosestPointPointTriangleTest()
29+
{
30+
Assert.AreEqual(ClosestPointPointTriangle(new Vector3(0, 0, 0), new Vector3(1, 1, 0), new Vector3(2, 2, 0), new Vector3(3, 1, 0)), new Vector3(1, 1, 0));
31+
Assert.AreEqual(ClosestPointPointTriangle(new Vector3(1, 1, 0), new Vector3(1, 1, 0), new Vector3(2, 2, 0), new Vector3(3, 1, 0)), new Vector3(1, 1, 0));
32+
Assert.AreEqual(ClosestPointPointTriangle(new Vector3(2, 3, 0), new Vector3(1, 1, 0), new Vector3(2, 2, 0), new Vector3(3, 1, 0)), new Vector3(2, 2, 0));
33+
Assert.AreEqual(ClosestPointPointTriangle(new Vector3(4, 1, 0), new Vector3(1, 1, 0), new Vector3(2, 2, 0), new Vector3(3, 1, 0)), new Vector3(3, 1, 0));
34+
Assert.AreEqual(ClosestPointPointTriangle(new Vector3(1, 2, 0), new Vector3(1, 1, 0), new Vector3(2, 2, 0), new Vector3(3, 1, 0)), new Vector3(1.5f, 1.5f, 0));
35+
Assert.AreEqual(ClosestPointPointTriangle(new Vector3(3, 2, 0), new Vector3(1, 1, 0), new Vector3(2, 2, 0), new Vector3(3, 1, 0)), new Vector3(2.5f, 1.5f, 0));
36+
Assert.AreEqual(ClosestPointPointTriangle(new Vector3(2, 0, 0), new Vector3(1, 1, 0), new Vector3(2, 2, 0), new Vector3(3, 1, 0)), new Vector3(2, 1, 0));
37+
38+
Assert.AreEqual(ClosestPointPointTriangle(new Vector3(2, 1.5f, 1), new Vector3(1, 1, 0), new Vector3(2, 2, 0), new Vector3(3, 1, 0)), new Vector3(2, 1.5f, 0));
39+
}
40+
private static Vector3 ClosestPointPointTriangle(Vector3 point, Vector3 vertex1, Vector3 vertex2, Vector3 vertex3)
41+
{
42+
Vector3 result;
43+
Collision.ClosestPointPointTriangle(ref point, ref vertex1, ref vertex2, ref vertex3, out result);
44+
return result;
45+
}
46+
}
47+
}

Source/Tests/SharpDX.Tests/SharpDX.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<Reference Include="System.Xml" />
4747
</ItemGroup>
4848
<ItemGroup>
49+
<Compile Include="MathCollisionTest.cs" />
4950
<Compile Include="MathUtilNearEqualTests.cs" />
5051
<Compile Include="MathUtilWrapTests.cs" />
5152
<Compile Include="RayTests.cs" />

0 commit comments

Comments
 (0)