diff options
author | dan miller | 2007-09-29 04:08:33 +0000 |
---|---|---|
committer | dan miller | 2007-09-29 04:08:33 +0000 |
commit | c1d3e93fbb3284b38b85294d43189001bfce5214 (patch) | |
tree | b79de3dec16f268822463165040c3263b65bea66 /OpenSim/Region/Physics/OdePlugin/Meshing\/Meshmerizer.cs | |
parent | Hollow prims (box only), thanks Gerard! Enjoy (diff) | |
download | opensim-SC-c1d3e93fbb3284b38b85294d43189001bfce5214.zip opensim-SC-c1d3e93fbb3284b38b85294d43189001bfce5214.tar.gz opensim-SC-c1d3e93fbb3284b38b85294d43189001bfce5214.tar.bz2 opensim-SC-c1d3e93fbb3284b38b85294d43189001bfce5214.tar.xz |
Hollow prims (box only), thanks Gerard! Enjoy
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/Meshing\/Meshmerizer.cs | 560 |
1 files changed, 560 insertions, 0 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/Meshing\/Meshmerizer.cs b/OpenSim/Region/Physics/OdePlugin/Meshing\/Meshmerizer.cs new file mode 100644 index 0000000..28dca41 --- /dev/null +++ b/OpenSim/Region/Physics/OdePlugin/Meshing\/Meshmerizer.cs | |||
@@ -0,0 +1,560 @@ | |||
1 | using System; | ||
2 | using System.Globalization; | ||
3 | using System.Diagnostics; | ||
4 | using System.Collections.Generic; | ||
5 | using System.Text; | ||
6 | using System.Runtime.InteropServices; | ||
7 | |||
8 | using OpenSim.Framework.Types; | ||
9 | using OpenSim.Region.Physics.Manager; | ||
10 | |||
11 | namespace OpenSim.Region.Physics.OdePlugin | ||
12 | { | ||
13 | public class Mesh | ||
14 | { | ||
15 | public List<Vertex> vertices; | ||
16 | public List<Triangle> triangles; | ||
17 | |||
18 | public float[] normals; | ||
19 | |||
20 | public Mesh() | ||
21 | { | ||
22 | vertices = new List<Vertex>(); | ||
23 | triangles = new List<Triangle>(); | ||
24 | } | ||
25 | |||
26 | public void Add(Triangle triangle) | ||
27 | { | ||
28 | int i; | ||
29 | i = vertices.IndexOf(triangle.v1); | ||
30 | if (i < 0) | ||
31 | throw new ArgumentException("Vertex v1 not known to mesh"); | ||
32 | i = vertices.IndexOf(triangle.v2); | ||
33 | if (i < 0) | ||
34 | throw new ArgumentException("Vertex v2 not known to mesh"); | ||
35 | i = vertices.IndexOf(triangle.v3); | ||
36 | if (i < 0) | ||
37 | throw new ArgumentException("Vertex v3 not known to mesh"); | ||
38 | |||
39 | triangles.Add(triangle); | ||
40 | } | ||
41 | |||
42 | public void Add(Vertex v) | ||
43 | { | ||
44 | vertices.Add(v); | ||
45 | } | ||
46 | |||
47 | |||
48 | public float[] getVertexListAsFloat() | ||
49 | { | ||
50 | float[] result = new float[vertices.Count * 3]; | ||
51 | for (int i = 0; i < vertices.Count; i++) | ||
52 | { | ||
53 | Vertex v = vertices[i]; | ||
54 | PhysicsVector point = v.point; | ||
55 | result[3 * i + 0] = point.X; | ||
56 | result[3 * i + 1] = point.Y; | ||
57 | result[3 * i + 2] = point.Z; | ||
58 | } | ||
59 | GCHandle.Alloc(result, GCHandleType.Pinned); | ||
60 | return result; | ||
61 | } | ||
62 | |||
63 | public int[] getIndexListAsInt() | ||
64 | { | ||
65 | int[] result = new int[triangles.Count * 3]; | ||
66 | for (int i = 0; i < triangles.Count; i++) | ||
67 | { | ||
68 | Triangle t = triangles[i]; | ||
69 | result[3 * i + 0] = vertices.IndexOf(t.v1); | ||
70 | result[3 * i + 1] = vertices.IndexOf(t.v2); | ||
71 | result[3 * i + 2] = vertices.IndexOf(t.v3); | ||
72 | } | ||
73 | GCHandle.Alloc(result, GCHandleType.Pinned); | ||
74 | return result; | ||
75 | } | ||
76 | |||
77 | |||
78 | public void Append(Mesh newMesh) | ||
79 | { | ||
80 | foreach (Vertex v in newMesh.vertices) | ||
81 | vertices.Add(v); | ||
82 | |||
83 | foreach (Triangle t in newMesh.triangles) | ||
84 | Add(t); | ||
85 | |||
86 | } | ||
87 | } | ||
88 | |||
89 | |||
90 | |||
91 | public class Meshmerizer | ||
92 | { | ||
93 | |||
94 | static List<Triangle> FindInfluencedTriangles(List<Triangle> triangles, Vertex v) | ||
95 | { | ||
96 | List<Triangle> influenced = new List<Triangle>(); | ||
97 | foreach (Triangle t in triangles) | ||
98 | { | ||
99 | float dx, dy; | ||
100 | |||
101 | if (t.isInCircle(v.point.X, v.point.Y)) | ||
102 | { | ||
103 | influenced.Add(t); | ||
104 | } | ||
105 | } | ||
106 | return influenced; | ||
107 | } | ||
108 | |||
109 | |||
110 | static void InsertVertices(List<Vertex> vertices, int usedForSeed, List<Triangle> triangles, List<int> innerBorders) | ||
111 | { | ||
112 | // This is a variant of the delaunay algorithm | ||
113 | // each time a new vertex is inserted, all triangles that are influenced by it are deleted | ||
114 | // and replaced by new ones including the new vertex | ||
115 | // It is not very time efficient but easy to implement. | ||
116 | |||
117 | int iCurrentVertex; | ||
118 | int iMaxVertex=vertices.Count; | ||
119 | for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++) | ||
120 | { | ||
121 | // Background: A triangle mesh fulfills the delaunay condition if (iff!) | ||
122 | // each circumlocutory circle (i.e. the circle that touches all three corners) | ||
123 | // of each triangle is empty of other vertices. | ||
124 | // Obviously a single (seeding) triangle fulfills this condition. | ||
125 | // If we now add one vertex, we need to reconstruct all triangles, that | ||
126 | // do not fulfill this condition with respect to the new triangle | ||
127 | |||
128 | // Find the triangles that are influenced by the new vertex | ||
129 | Vertex v=vertices[iCurrentVertex]; | ||
130 | List<Triangle> influencedTriangles=FindInfluencedTriangles(triangles, v); | ||
131 | |||
132 | List<Simplex> simplices = new List<Simplex>(); | ||
133 | |||
134 | // Reconstruction phase. First step, dissolve each triangle into it's simplices, | ||
135 | // i.e. it's "border lines" | ||
136 | // Goal is to find "inner" borders and delete them, while the hull gets conserved. | ||
137 | // Inner borders are special in the way that they always come twice, which is how we detect them | ||
138 | foreach (Triangle t in influencedTriangles) | ||
139 | { | ||
140 | List<Simplex> newSimplices = t.GetSimplices(); | ||
141 | simplices.AddRange(newSimplices); | ||
142 | triangles.Remove(t); | ||
143 | } | ||
144 | // Now sort the simplices. That will make identical ones side by side in the list | ||
145 | simplices.Sort(); | ||
146 | |||
147 | // Look for duplicate simplices here. | ||
148 | // Remember, they are directly side by side in the list right now | ||
149 | int iSimplex; | ||
150 | List<Simplex> innerSimplices=new List<Simplex>(); | ||
151 | for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards | ||
152 | { | ||
153 | if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex])==0) | ||
154 | { | ||
155 | innerSimplices.Add(simplices[iSimplex - 1]); | ||
156 | innerSimplices.Add(simplices[iSimplex]); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | foreach (Simplex s in innerSimplices) | ||
161 | { | ||
162 | simplices.Remove(s); | ||
163 | } | ||
164 | |||
165 | // each simplex still in the list belongs to the hull of the region in question | ||
166 | // The new vertex (yes, we still deal with verices here :-) ) forms a triangle | ||
167 | // With each of these simplices. Build the new triangles and add them to the list | ||
168 | foreach (Simplex s in simplices) | ||
169 | { | ||
170 | Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]); | ||
171 | triangles.Add(t); | ||
172 | } | ||
173 | } | ||
174 | |||
175 | // At this point all vertices should be inserted into the mesh | ||
176 | // But the areas, that should be kept free still are filled with triangles | ||
177 | // We have to remove them. For this we have a list of indices to vertices. | ||
178 | // Each triangle that solemnly constists of vertices from the inner border | ||
179 | // are deleted | ||
180 | |||
181 | List<Triangle> innerTriangles = new List<Triangle>(); | ||
182 | foreach (Triangle t in triangles) | ||
183 | { | ||
184 | if ( | ||
185 | innerBorders.Contains(vertices.IndexOf(t.v1)) | ||
186 | && innerBorders.Contains(vertices.IndexOf(t.v2)) | ||
187 | && innerBorders.Contains(vertices.IndexOf(t.v3)) | ||
188 | ) | ||
189 | innerTriangles.Add(t); | ||
190 | } | ||
191 | foreach (Triangle t in innerTriangles) | ||
192 | { | ||
193 | triangles.Remove(t); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | |||
198 | static Mesh CreateBoxMeshX(PrimitiveBaseShape primShape, PhysicsVector size) | ||
199 | // Builds the x (+ and -) surfaces of a box shaped prim | ||
200 | { | ||
201 | UInt16 hollowFactor = primShape.ProfileHollow; | ||
202 | Mesh meshMX = new Mesh(); | ||
203 | |||
204 | |||
205 | // Surface 0, -X | ||
206 | meshMX.Add(new Vertex("-X-Y-Z", -size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); | ||
207 | meshMX.Add(new Vertex("-X+Y-Z", -size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); | ||
208 | meshMX.Add(new Vertex("-X-Y+Z", -size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f)); | ||
209 | meshMX.Add(new Vertex("-X+Y+Z", -size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f)); | ||
210 | |||
211 | meshMX.Add(new Triangle(meshMX.vertices[0], meshMX.vertices[2], meshMX.vertices[1])); | ||
212 | meshMX.Add(new Triangle(meshMX.vertices[1], meshMX.vertices[2], meshMX.vertices[3])); | ||
213 | |||
214 | |||
215 | Mesh meshPX = new Mesh(); | ||
216 | // Surface 1, +X | ||
217 | meshPX.Add(new Vertex("+X-Y-Z", +size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); | ||
218 | meshPX.Add(new Vertex("+X+Y-Z", +size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); | ||
219 | meshPX.Add(new Vertex("+X-Y+Z", +size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f)); | ||
220 | meshPX.Add(new Vertex("+X+Y+Z", +size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f)); | ||
221 | |||
222 | |||
223 | meshPX.Add(new Triangle(meshPX.vertices[0], meshPX.vertices[1], meshPX.vertices[2])); | ||
224 | meshPX.Add(new Triangle(meshPX.vertices[2], meshPX.vertices[1], meshPX.vertices[3])); | ||
225 | |||
226 | |||
227 | if (hollowFactor > 0) | ||
228 | { | ||
229 | float hollowFactorF = (float)hollowFactor / (float)50000; | ||
230 | |||
231 | Vertex IPP; | ||
232 | Vertex IPM; | ||
233 | Vertex IMP; | ||
234 | Vertex IMM; | ||
235 | |||
236 | IPP = new Vertex("Inner-X+Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); | ||
237 | IPM = new Vertex("Inner-X+Y-Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); | ||
238 | IMP = new Vertex("Inner-X-Y+Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); | ||
239 | IMM = new Vertex("Inner-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); | ||
240 | |||
241 | meshMX.Add(IPP); | ||
242 | meshMX.Add(IPM); | ||
243 | meshMX.Add(IMP); | ||
244 | meshMX.Add(IMM); | ||
245 | |||
246 | meshMX.Add(new Triangle(IPP, IMP, IPM)); | ||
247 | meshMX.Add(new Triangle(IPM, IMP, IMM)); | ||
248 | |||
249 | foreach (Triangle t in meshMX.triangles) | ||
250 | { | ||
251 | PhysicsVector n = t.getNormal(); | ||
252 | } | ||
253 | |||
254 | |||
255 | |||
256 | IPP = new Vertex("Inner+X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); | ||
257 | IPM = new Vertex("Inner+X+Y-Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); | ||
258 | IMP = new Vertex("Inner+X-Y+Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); | ||
259 | IMM = new Vertex("Inner+X-Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); | ||
260 | |||
261 | meshPX.Add(IPP); | ||
262 | meshPX.Add(IPM); | ||
263 | meshPX.Add(IMP); | ||
264 | meshPX.Add(IMM); | ||
265 | |||
266 | meshPX.Add(new Triangle(IPP, IPM, IMP)); | ||
267 | meshPX.Add(new Triangle(IMP, IPM, IMM)); | ||
268 | |||
269 | foreach (Triangle t in meshPX.triangles) | ||
270 | { | ||
271 | PhysicsVector n = t.getNormal(); | ||
272 | } | ||
273 | } | ||
274 | |||
275 | Mesh result = new Mesh(); | ||
276 | result.Append(meshMX); | ||
277 | result.Append(meshPX); | ||
278 | |||
279 | return result; | ||
280 | } | ||
281 | |||
282 | |||
283 | |||
284 | static Mesh CreateBoxMeshY(PrimitiveBaseShape primShape, PhysicsVector size) | ||
285 | // Builds the y (+ and -) surfaces of a box shaped prim | ||
286 | { | ||
287 | UInt16 hollowFactor = primShape.ProfileHollow; | ||
288 | |||
289 | // (M)inus Y | ||
290 | Mesh MeshMY = new Mesh(); | ||
291 | MeshMY.Add(new Vertex("-X-Y-Z", -size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); | ||
292 | MeshMY.Add(new Vertex("+X-Y-Z", +size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); | ||
293 | MeshMY.Add(new Vertex("-X-Y+Z", -size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f)); | ||
294 | MeshMY.Add(new Vertex("+X-Y+Z", +size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f)); | ||
295 | |||
296 | MeshMY.Add(new Triangle(MeshMY.vertices[0], MeshMY.vertices[1], MeshMY.vertices[2])); | ||
297 | MeshMY.Add(new Triangle(MeshMY.vertices[2], MeshMY.vertices[1], MeshMY.vertices[3])); | ||
298 | |||
299 | // (P)lus Y | ||
300 | Mesh MeshPY = new Mesh(); | ||
301 | |||
302 | MeshPY.Add(new Vertex("-X+Y-Z", -size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); | ||
303 | MeshPY.Add(new Vertex("+X+Y-Z", +size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); | ||
304 | MeshPY.Add(new Vertex("-X+Y+Z", -size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f)); | ||
305 | MeshPY.Add(new Vertex("+X+Y+Z", +size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f)); | ||
306 | |||
307 | MeshPY.Add(new Triangle(MeshPY.vertices[1], MeshPY.vertices[0], MeshPY.vertices[2])); | ||
308 | MeshPY.Add(new Triangle(MeshPY.vertices[1], MeshPY.vertices[2], MeshPY.vertices[3])); | ||
309 | |||
310 | if (hollowFactor > 0) | ||
311 | { | ||
312 | float hollowFactorF = (float)hollowFactor / (float)50000; | ||
313 | |||
314 | Vertex IPP; | ||
315 | Vertex IPM; | ||
316 | Vertex IMP; | ||
317 | Vertex IMM; | ||
318 | |||
319 | IPP = new Vertex("Inner+X-Y+Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); | ||
320 | IPM = new Vertex("Inner+X-Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); | ||
321 | IMP = new Vertex("Inner-X-Y+Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); | ||
322 | IMM = new Vertex("Inner-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); | ||
323 | |||
324 | MeshMY.Add(IPP); | ||
325 | MeshMY.Add(IPM); | ||
326 | MeshMY.Add(IMP); | ||
327 | MeshMY.Add(IMM); | ||
328 | |||
329 | MeshMY.Add(new Triangle(IPP, IPM, IMP)); | ||
330 | MeshMY.Add(new Triangle(IMP, IPM, IMM)); | ||
331 | |||
332 | foreach (Triangle t in MeshMY.triangles) | ||
333 | { | ||
334 | PhysicsVector n = t.getNormal(); | ||
335 | } | ||
336 | |||
337 | |||
338 | |||
339 | IPP = new Vertex("Inner+X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); | ||
340 | IPM=new Vertex("Inner+X+Y-Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); | ||
341 | IMP=new Vertex("Inner-X+Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); | ||
342 | IMM=new Vertex("Inner-X+Y-Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); | ||
343 | |||
344 | MeshPY.Add(IPP); | ||
345 | MeshPY.Add(IPM); | ||
346 | MeshPY.Add(IMP); | ||
347 | MeshPY.Add(IMM); | ||
348 | |||
349 | MeshPY.Add(new Triangle(IPM, IPP, IMP)); | ||
350 | MeshPY.Add(new Triangle(IMP, IMM, IPM)); | ||
351 | |||
352 | foreach (Triangle t in MeshPY.triangles) | ||
353 | { | ||
354 | PhysicsVector n = t.getNormal(); | ||
355 | } | ||
356 | |||
357 | |||
358 | |||
359 | } | ||
360 | |||
361 | |||
362 | Mesh result = new Mesh(); | ||
363 | result.Append(MeshMY); | ||
364 | result.Append(MeshPY); | ||
365 | |||
366 | return result; | ||
367 | } | ||
368 | |||
369 | static Mesh CreateBoxMeshZ(PrimitiveBaseShape primShape, PhysicsVector size) | ||
370 | // Builds the z (+ and -) surfaces of a box shaped prim | ||
371 | { | ||
372 | UInt16 hollowFactor = primShape.ProfileHollow; | ||
373 | |||
374 | // Base, i.e. outer shape | ||
375 | // (M)inus Z | ||
376 | Mesh MZ = new Mesh(); | ||
377 | |||
378 | MZ.Add(new Vertex("-X-Y-Z", -size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); | ||
379 | MZ.Add(new Vertex("+X-Y-Z", +size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); | ||
380 | MZ.Add(new Vertex("-X+Y-Z", -size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); | ||
381 | MZ.Add(new Vertex("+X+Y-Z", +size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); | ||
382 | |||
383 | |||
384 | MZ.Add(new Triangle(MZ.vertices[1], MZ.vertices[0], MZ.vertices[2])); | ||
385 | MZ.Add(new Triangle(MZ.vertices[1], MZ.vertices[2], MZ.vertices[3])); | ||
386 | |||
387 | // (P)lus Z | ||
388 | Mesh PZ = new Mesh(); | ||
389 | |||
390 | PZ.Add(new Vertex("-X-Y+Z", -size.X / 2.0f, -size.Y / 2.0f, 0.0f)); | ||
391 | PZ.Add(new Vertex("+X-Y+Z", +size.X / 2.0f, -size.Y / 2.0f, 0.0f)); | ||
392 | PZ.Add(new Vertex("-X+Y+Z", -size.X / 2.0f, +size.Y / 2.0f, 0.0f)); | ||
393 | PZ.Add(new Vertex("+X+Y+Z", +size.X / 2.0f, +size.Y / 2.0f, 0.0f)); | ||
394 | |||
395 | // Surface 5, +Z | ||
396 | PZ.Add(new Triangle(PZ.vertices[0], PZ.vertices[1], PZ.vertices[2])); | ||
397 | PZ.Add(new Triangle(PZ.vertices[2], PZ.vertices[1], PZ.vertices[3])); | ||
398 | |||
399 | if (hollowFactor > 0) | ||
400 | { | ||
401 | float hollowFactorF = (float)hollowFactor / (float)50000; | ||
402 | |||
403 | MZ.Add(new Vertex("-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f)); | ||
404 | MZ.Add(new Vertex("-X+Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f)); | ||
405 | MZ.Add(new Vertex("-X-Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f)); | ||
406 | MZ.Add(new Vertex("-X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f)); | ||
407 | |||
408 | List<int> innerBorders = new List<int>(); | ||
409 | innerBorders.Add(4); | ||
410 | innerBorders.Add(5); | ||
411 | innerBorders.Add(6); | ||
412 | innerBorders.Add(7); | ||
413 | |||
414 | InsertVertices(MZ.vertices, 4, MZ.triangles, innerBorders); | ||
415 | |||
416 | PZ.Add(new Vertex("-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f)); | ||
417 | PZ.Add(new Vertex("-X+Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f)); | ||
418 | PZ.Add(new Vertex("-X-Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f)); | ||
419 | PZ.Add(new Vertex("-X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f)); | ||
420 | |||
421 | innerBorders = new List<int>(); | ||
422 | innerBorders.Add(4); | ||
423 | innerBorders.Add(5); | ||
424 | innerBorders.Add(6); | ||
425 | innerBorders.Add(7); | ||
426 | |||
427 | InsertVertices(PZ.vertices, 4, PZ.triangles, innerBorders); | ||
428 | |||
429 | } | ||
430 | |||
431 | foreach (Vertex v in PZ.vertices) | ||
432 | { | ||
433 | v.point.Z = size.Z / 2.0f; | ||
434 | } | ||
435 | foreach (Vertex v in MZ.vertices) | ||
436 | { | ||
437 | v.point.Z = -size.Z / 2.0f; | ||
438 | } | ||
439 | |||
440 | foreach (Triangle t in MZ.triangles) | ||
441 | { | ||
442 | PhysicsVector n = t.getNormal(); | ||
443 | if (n.Z > 0.0) | ||
444 | t.invertNormal(); | ||
445 | } | ||
446 | |||
447 | foreach (Triangle t in PZ.triangles) | ||
448 | { | ||
449 | PhysicsVector n = t.getNormal(); | ||
450 | if (n.Z < 0.0) | ||
451 | t.invertNormal(); | ||
452 | } | ||
453 | |||
454 | Mesh result = new Mesh(); | ||
455 | result.Append(MZ); | ||
456 | result.Append(PZ); | ||
457 | |||
458 | return result; | ||
459 | } | ||
460 | |||
461 | static Mesh CreateBoxMesh(PrimitiveBaseShape primShape, PhysicsVector size) | ||
462 | { | ||
463 | Mesh result = new Mesh(); | ||
464 | |||
465 | |||
466 | |||
467 | Mesh MeshX = Meshmerizer.CreateBoxMeshX(primShape, size); | ||
468 | Mesh MeshY = Meshmerizer.CreateBoxMeshY(primShape, size); | ||
469 | Mesh MeshZ = Meshmerizer.CreateBoxMeshZ(primShape, size); | ||
470 | |||
471 | result.Append(MeshX); | ||
472 | result.Append(MeshY); | ||
473 | result.Append(MeshZ); | ||
474 | |||
475 | return result; | ||
476 | } | ||
477 | |||
478 | |||
479 | public static void CalcNormals(Mesh mesh) | ||
480 | { | ||
481 | int iTriangles = mesh.triangles.Count; | ||
482 | |||
483 | mesh.normals = new float[iTriangles*3]; | ||
484 | |||
485 | int i=0; | ||
486 | foreach (Triangle t in mesh.triangles) | ||
487 | { | ||
488 | |||
489 | float ux, uy, uz; | ||
490 | float vx, vy, vz; | ||
491 | float wx, wy, wz; | ||
492 | |||
493 | ux = t.v1.point.X; | ||
494 | uy = t.v1.point.Y; | ||
495 | uz = t.v1.point.Z; | ||
496 | |||
497 | vx = t.v2.point.X; | ||
498 | vy = t.v2.point.Y; | ||
499 | vz = t.v2.point.Z; | ||
500 | |||
501 | wx = t.v3.point.X; | ||
502 | wy = t.v3.point.Y; | ||
503 | wz = t.v3.point.Z; | ||
504 | |||
505 | // Vectors for edges | ||
506 | float e1x, e1y, e1z; | ||
507 | float e2x, e2y, e2z; | ||
508 | |||
509 | e1x = ux - vx; | ||
510 | e1y = uy - vy; | ||
511 | e1z = uz - vz; | ||
512 | |||
513 | e2x = ux - wx; | ||
514 | e2y = uy - wy; | ||
515 | e2z = uz - wz; | ||
516 | |||
517 | |||
518 | // Cross product for normal | ||
519 | float nx, ny, nz; | ||
520 | nx = e1y * e2z - e1z * e2y; | ||
521 | ny = e1z * e2x - e1x * e2z; | ||
522 | nz = e1x * e2y - e1y * e2x; | ||
523 | |||
524 | // Length | ||
525 | float l = (float)Math.Sqrt(nx * nx + ny * ny + nz * nz); | ||
526 | |||
527 | // Normalized "normal" | ||
528 | nx /= l; | ||
529 | ny /= l; | ||
530 | nz /= l; | ||
531 | |||
532 | mesh.normals[i] = nx; | ||
533 | mesh.normals[i + 1] = ny; | ||
534 | mesh.normals[i + 2] = nz; | ||
535 | |||
536 | i+=3; | ||
537 | } | ||
538 | } | ||
539 | |||
540 | public static Mesh CreateMesh(PrimitiveBaseShape primShape, PhysicsVector size) | ||
541 | { | ||
542 | Mesh mesh = null; | ||
543 | |||
544 | switch (primShape.ProfileShape) | ||
545 | { | ||
546 | case ProfileShape.Square: | ||
547 | mesh=CreateBoxMesh(primShape, size); | ||
548 | CalcNormals(mesh); | ||
549 | break; | ||
550 | default: | ||
551 | mesh=null; | ||
552 | break; | ||
553 | } | ||
554 | |||
555 | return mesh; | ||
556 | |||
557 | } | ||
558 | } | ||
559 | } | ||
560 | |||