-
Notifications
You must be signed in to change notification settings - Fork 69
/
Copy pathMRMeshCollidePrecise.cs
132 lines (115 loc) · 5.24 KB
/
MRMeshCollidePrecise.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using System.Text;
namespace MR
{
public partial class DotNet
{
[StructLayout(LayoutKind.Sequential)]
public struct EdgeTri
{
EdgeId edge;
FaceId tri;
};
public class PreciseCollisionResult : IDisposable
{
[DllImport("MRMeshC", CharSet = CharSet.Auto)]
private static extern bool mrEdgeTriEq(ref EdgeTri a, ref EdgeTri b);
[StructLayout(LayoutKind.Sequential)]
internal struct MRVectorEdgeTri
{
public IntPtr data = IntPtr.Zero;
public ulong size = 0;
public IntPtr reserved = IntPtr.Zero;
public MRVectorEdgeTri() { }
};
/// each edge is directed to have its origin inside and its destination outside of the other mesh
[DllImport("MRMeshC", CharSet = CharSet.Auto)]
private static extern MRVectorEdgeTri mrPreciseCollisionResultEdgesAtrisB(IntPtr result);
/// each edge is directed to have its origin inside and its destination outside of the other mesh
[DllImport("MRMeshC", CharSet = CharSet.Auto)]
private static extern MRVectorEdgeTri mrPreciseCollisionResultEdgesBtrisA(IntPtr result);
/// deallocates the PreciseCollisionResult object
[DllImport("MRMeshC", CharSet = CharSet.Auto)]
private static extern void mrPreciseCollisionResultFree(IntPtr result);
internal PreciseCollisionResult(IntPtr nativeResult)
{
nativeResult_ = nativeResult;
}
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (nativeResult_ != IntPtr.Zero)
{
mrPreciseCollisionResultFree(nativeResult_);
}
disposed = true;
}
}
~PreciseCollisionResult()
{
Dispose(false);
}
/// each edge is directed to have its origin inside and its destination outside of the other mesh
public ReadOnlyCollection<EdgeTri> EdgesAtrisB
{
get
{
if (edgesAtrisB_ is null)
{
var mrEdges = mrPreciseCollisionResultEdgesAtrisB(nativeResult_);
int sizeOfEdgeTri = Marshal.SizeOf(typeof(EdgeTri));
edgesAtrisB_ = new List<EdgeTri>((int)mrEdges.size);
for (int i = 0; i < (int)mrEdges.size; ++i)
{
edgesAtrisB_.Add(Marshal.PtrToStructure<EdgeTri>(IntPtr.Add(mrEdges.data, i * sizeOfEdgeTri)));
}
}
return edgesAtrisB_.AsReadOnly();
}
}
/// each edge is directed to have its origin inside and its destination outside of the other mesh
public ReadOnlyCollection<EdgeTri> EdgesBtrisA
{
get
{
if (edgesBtrisA_ is null)
{
var mrEdges = mrPreciseCollisionResultEdgesBtrisA(nativeResult_);
int sizeOfEdgeTri = Marshal.SizeOf(typeof(EdgeTri));
edgesBtrisA_ = new List<EdgeTri>((int)mrEdges.size);
for (int i = 0; i < (int)mrEdges.size; ++i)
{
edgesBtrisA_.Add(Marshal.PtrToStructure<EdgeTri>(IntPtr.Add(mrEdges.data, i * sizeOfEdgeTri)));
}
}
return edgesBtrisA_.AsReadOnly();
}
}
private List<EdgeTri>? edgesAtrisB_;
private List<EdgeTri>? edgesBtrisA_;
internal IntPtr nativeResult_;
};
/**
* \brief finds all pairs of colliding edges from one mesh and triangle from another mesh
* \param rigidB2A rigid transformation from B-mesh space to A mesh space, NULL considered as identity transformation
* \param anyIntersection if true then the function returns as fast as it finds any intersection
*/
[DllImport("MRMeshC", CharSet = CharSet.Auto)]
private static extern IntPtr mrFindCollidingEdgeTrisPrecise(ref MRMeshPart a, ref MRMeshPart b, IntPtr conv, IntPtr rigidB2A, bool anyIntersection);
public static PreciseCollisionResult FindCollidingEdgeTrisPrecise(MeshPart meshA, MeshPart meshB, CoordinateConverters conv, AffineXf3f? rigidB2A = null, bool anyIntersection = false)
{
var mrResult = mrFindCollidingEdgeTrisPrecise(ref meshA.mrMeshPart, ref meshB.mrMeshPart, conv.GetConvertToIntVector(), rigidB2A is null ? IntPtr.Zero : rigidB2A.XfAddr(), anyIntersection);
return new PreciseCollisionResult(mrResult);
}
}
}