aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
diff options
context:
space:
mode:
authorJeff Ames2007-11-11 09:19:21 +0000
committerJeff Ames2007-11-11 09:19:21 +0000
commitdb174dfa2061ce35b657cd8f119f1176b53c6207 (patch)
tree7ff889f817ab0ebac5a90c6adbecf4a263239a73 /OpenSim/Region/Physics/Meshing/Meshmerizer.cs
parentfixed chatting while sitting (diff)
downloadopensim-SC_OLD-db174dfa2061ce35b657cd8f119f1176b53c6207.zip
opensim-SC_OLD-db174dfa2061ce35b657cd8f119f1176b53c6207.tar.gz
opensim-SC_OLD-db174dfa2061ce35b657cd8f119f1176b53c6207.tar.bz2
opensim-SC_OLD-db174dfa2061ce35b657cd8f119f1176b53c6207.tar.xz
set svn:eol-style
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/Meshmerizer.cs')
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs786
1 files changed, 393 insertions, 393 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index da4ee58..9c35f81 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -1,393 +1,393 @@
1/* 1/*
2* Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4* 4*
5* Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the 12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15* 15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28 28
29using System; 29using System;
30using System.IO; 30using System.IO;
31using System.Globalization; 31using System.Globalization;
32using System.Diagnostics; 32using System.Diagnostics;
33using System.Collections.Generic; 33using System.Collections.Generic;
34using System.Runtime.InteropServices; 34using System.Runtime.InteropServices;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Console; 36using OpenSim.Framework.Console;
37using OpenSim.Region.Physics.Manager; 37using OpenSim.Region.Physics.Manager;
38 38
39namespace OpenSim.Region.Physics.Meshing 39namespace OpenSim.Region.Physics.Meshing
40{ 40{
41 41
42 public class MeshmerizerPlugin : IMeshingPlugin 42 public class MeshmerizerPlugin : IMeshingPlugin
43 { 43 {
44 public MeshmerizerPlugin() 44 public MeshmerizerPlugin()
45 { 45 {
46 } 46 }
47 47
48 public string GetName() 48 public string GetName()
49 { 49 {
50 return "Meshmerizer"; 50 return "Meshmerizer";
51 } 51 }
52 52
53 public IMesher GetMesher() 53 public IMesher GetMesher()
54 { 54 {
55 return new Meshmerizer(); 55 return new Meshmerizer();
56 } 56 }
57 } 57 }
58 58
59 public class Meshmerizer : IMesher 59 public class Meshmerizer : IMesher
60 { 60 {
61 // Setting baseDir to a path will enable the dumping of raw files 61 // Setting baseDir to a path will enable the dumping of raw files
62 // raw files can be imported by blender so a visual inspection of the results can be done 62 // raw files can be imported by blender so a visual inspection of the results can be done
63 // const string baseDir = "rawFiles"; 63 // const string baseDir = "rawFiles";
64 const string baseDir = null; 64 const string baseDir = null;
65 65
66 static void IntersectionParameterPD(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu) 66 static void IntersectionParameterPD(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu)
67 { 67 {
68 // p1, p2, points on the straight 68 // p1, p2, points on the straight
69 // r1, r2, directional vectors of the straight. Not necessarily of length 1! 69 // r1, r2, directional vectors of the straight. Not necessarily of length 1!
70 // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points, 70 // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
71 // thus allowing to decide whether an intersection is between two points 71 // thus allowing to decide whether an intersection is between two points
72 72
73 float r1x = r1.X; 73 float r1x = r1.X;
74 float r1y = r1.Y; 74 float r1y = r1.Y;
75 float r2x = r2.X; 75 float r2x = r2.X;
76 float r2y = r2.Y; 76 float r2y = r2.Y;
77 77
78 float denom = r1y*r2x - r1x*r2y; 78 float denom = r1y*r2x - r1x*r2y;
79 79
80 if (denom == 0.0) 80 if (denom == 0.0)
81 { 81 {
82 lambda = Single.NaN; 82 lambda = Single.NaN;
83 mu = Single.NaN; 83 mu = Single.NaN;
84 return; 84 return;
85 } 85 }
86 86
87 float p1x = p1.X; 87 float p1x = p1.X;
88 float p1y = p1.Y; 88 float p1y = p1.Y;
89 float p2x = p2.X; 89 float p2x = p2.X;
90 float p2y = p2.Y; 90 float p2y = p2.Y;
91 lambda = (-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x) / denom; 91 lambda = (-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x) / denom;
92 mu = (-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x) / denom; 92 mu = (-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x) / denom;
93 93
94 } 94 }
95 95
96 private static List<Triangle> FindInfluencedTriangles(List<Triangle> triangles, Vertex v) 96 private static List<Triangle> FindInfluencedTriangles(List<Triangle> triangles, Vertex v)
97 { 97 {
98 List<Triangle> influenced = new List<Triangle>(); 98 List<Triangle> influenced = new List<Triangle>();
99 foreach (Triangle t in triangles) 99 foreach (Triangle t in triangles)
100 { 100 {
101 if (t.isInCircle(v.X, v.Y)) 101 if (t.isInCircle(v.X, v.Y))
102 { 102 {
103 influenced.Add(t); 103 influenced.Add(t);
104 } 104 }
105 } 105 }
106 return influenced; 106 return influenced;
107 } 107 }
108 108
109 109
110 private static void InsertVertices(List<Vertex> vertices, int usedForSeed, List<Triangle> triangles) 110 private static void InsertVertices(List<Vertex> vertices, int usedForSeed, List<Triangle> triangles)
111 { 111 {
112 // This is a variant of the delaunay algorithm 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 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 114 // and replaced by new ones including the new vertex
115 // It is not very time efficient but easy to implement. 115 // It is not very time efficient but easy to implement.
116 116
117 int iCurrentVertex; 117 int iCurrentVertex;
118 int iMaxVertex = vertices.Count; 118 int iMaxVertex = vertices.Count;
119 for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++) 119 for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++)
120 { 120 {
121 // Background: A triangle mesh fulfills the delaunay condition if (iff!) 121 // Background: A triangle mesh fulfills the delaunay condition if (iff!)
122 // each circumlocutory circle (i.e. the circle that touches all three corners) 122 // each circumlocutory circle (i.e. the circle that touches all three corners)
123 // of each triangle is empty of other vertices. 123 // of each triangle is empty of other vertices.
124 // Obviously a single (seeding) triangle fulfills this condition. 124 // Obviously a single (seeding) triangle fulfills this condition.
125 // If we now add one vertex, we need to reconstruct all triangles, that 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 126 // do not fulfill this condition with respect to the new triangle
127 127
128 // Find the triangles that are influenced by the new vertex 128 // Find the triangles that are influenced by the new vertex
129 Vertex v=vertices[iCurrentVertex]; 129 Vertex v=vertices[iCurrentVertex];
130 if (v == null) 130 if (v == null)
131 continue; // Null is polygon stop marker. Ignore it 131 continue; // Null is polygon stop marker. Ignore it
132 List<Triangle> influencedTriangles=FindInfluencedTriangles(triangles, v); 132 List<Triangle> influencedTriangles=FindInfluencedTriangles(triangles, v);
133 133
134 List<Simplex> simplices = new List<Simplex>(); 134 List<Simplex> simplices = new List<Simplex>();
135 135
136 // Reconstruction phase. First step, dissolve each triangle into it's simplices, 136 // Reconstruction phase. First step, dissolve each triangle into it's simplices,
137 // i.e. it's "border lines" 137 // i.e. it's "border lines"
138 // Goal is to find "inner" borders and delete them, while the hull gets conserved. 138 // Goal is to find "inner" borders and delete them, while the hull gets conserved.
139 // Inner borders are special in the way that they always come twice, which is how we detect them 139 // Inner borders are special in the way that they always come twice, which is how we detect them
140 foreach (Triangle t in influencedTriangles) 140 foreach (Triangle t in influencedTriangles)
141 { 141 {
142 List<Simplex> newSimplices = t.GetSimplices(); 142 List<Simplex> newSimplices = t.GetSimplices();
143 simplices.AddRange(newSimplices); 143 simplices.AddRange(newSimplices);
144 triangles.Remove(t); 144 triangles.Remove(t);
145 } 145 }
146 // Now sort the simplices. That will make identical ones reside side by side in the list 146 // Now sort the simplices. That will make identical ones reside side by side in the list
147 simplices.Sort(); 147 simplices.Sort();
148 148
149 // Look for duplicate simplices here. 149 // Look for duplicate simplices here.
150 // Remember, they are directly side by side in the list right now, 150 // Remember, they are directly side by side in the list right now,
151 // So we only check directly neighbours 151 // So we only check directly neighbours
152 int iSimplex; 152 int iSimplex;
153 List<Simplex> innerSimplices = new List<Simplex>(); 153 List<Simplex> innerSimplices = new List<Simplex>();
154 for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards 154 for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards
155 { 155 {
156 if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex]) == 0) 156 if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex]) == 0)
157 { 157 {
158 innerSimplices.Add(simplices[iSimplex - 1]); 158 innerSimplices.Add(simplices[iSimplex - 1]);
159 innerSimplices.Add(simplices[iSimplex]); 159 innerSimplices.Add(simplices[iSimplex]);
160 } 160 }
161 } 161 }
162 162
163 foreach (Simplex s in innerSimplices) 163 foreach (Simplex s in innerSimplices)
164 { 164 {
165 simplices.Remove(s); 165 simplices.Remove(s);
166 } 166 }
167 167
168 // each simplex still in the list belongs to the hull of the region in question 168 // each simplex still in the list belongs to the hull of the region in question
169 // The new vertex (yes, we still deal with verices here :-) ) forms a triangle 169 // The new vertex (yes, we still deal with verices here :-) ) forms a triangle
170 // with each of these simplices. Build the new triangles and add them to the list 170 // with each of these simplices. Build the new triangles and add them to the list
171 foreach (Simplex s in simplices) 171 foreach (Simplex s in simplices)
172 { 172 {
173 Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]); 173 Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]);
174 if (!t.isDegraded()) 174 if (!t.isDegraded())
175 { 175 {
176 triangles.Add(t); 176 triangles.Add(t);
177 } 177 }
178 } 178 }
179 } 179 }
180 180
181 } 181 }
182 182
183 183
184 static Mesh CreateBoxMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size) 184 static Mesh CreateBoxMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
185 // Builds the z (+ and -) surfaces of a box shaped prim 185 // Builds the z (+ and -) surfaces of a box shaped prim
186 { 186 {
187 UInt16 hollowFactor = primShape.ProfileHollow; 187 UInt16 hollowFactor = primShape.ProfileHollow;
188 UInt16 profileBegin = primShape.ProfileBegin; 188 UInt16 profileBegin = primShape.ProfileBegin;
189 UInt16 profileEnd = primShape.ProfileEnd; 189 UInt16 profileEnd = primShape.ProfileEnd;
190 190
191 // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface 191 // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
192 // of a block are basically the same 192 // of a block are basically the same
193 // They may be warped differently but the shape is identical 193 // They may be warped differently but the shape is identical
194 // So we only create one surface as a model and derive both plus and minus surface of the block from it 194 // So we only create one surface as a model and derive both plus and minus surface of the block from it
195 // This is done in a model space where the block spans from -.5 to +.5 in X and Y 195 // This is done in a model space where the block spans from -.5 to +.5 in X and Y
196 // The mapping to Scene space is done later during the "extrusion" phase 196 // The mapping to Scene space is done later during the "extrusion" phase
197 197
198 // Base 198 // Base
199 Vertex MM = new Vertex(-0.5f, -0.5f, 0.0f); 199 Vertex MM = new Vertex(-0.5f, -0.5f, 0.0f);
200 Vertex PM = new Vertex(+0.5f, -0.5f, 0.0f); 200 Vertex PM = new Vertex(+0.5f, -0.5f, 0.0f);
201 Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f); 201 Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f);
202 Vertex PP = new Vertex(+0.5f, +0.5f, 0.0f); 202 Vertex PP = new Vertex(+0.5f, +0.5f, 0.0f);
203 203
204 Meshing.SimpleHull outerHull = new SimpleHull(); 204 Meshing.SimpleHull outerHull = new SimpleHull();
205 outerHull.AddVertex(MM); 205 outerHull.AddVertex(MM);
206 outerHull.AddVertex(PM); 206 outerHull.AddVertex(PM);
207 outerHull.AddVertex(PP); 207 outerHull.AddVertex(PP);
208 outerHull.AddVertex(MP); 208 outerHull.AddVertex(MP);
209 209
210 // Deal with cuts now 210 // Deal with cuts now
211 if ((profileBegin != 0) || (profileEnd != 0)) 211 if ((profileBegin != 0) || (profileEnd != 0))
212 { 212 {
213 double fProfileBeginAngle = profileBegin / 50000.0 * 360.0; // In degree, for easier debugging and understanding 213 double fProfileBeginAngle = profileBegin / 50000.0 * 360.0; // In degree, for easier debugging and understanding
214 fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y 214 fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
215 double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0 215 double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
216 fProfileEndAngle -= (90.0 + 45.0); 216 fProfileEndAngle -= (90.0 + 45.0);
217 if (fProfileBeginAngle < fProfileEndAngle) 217 if (fProfileBeginAngle < fProfileEndAngle)
218 fProfileEndAngle -= 360.0; 218 fProfileEndAngle -= 360.0;
219 219
220 // Note, that we don't want to cut out a triangle, even if this is a 220 // Note, that we don't want to cut out a triangle, even if this is a
221 // good approximation for small cuts. Indeed we want to cut out an arc 221 // good approximation for small cuts. Indeed we want to cut out an arc
222 // and we approximate this arc by a polygon chain 222 // and we approximate this arc by a polygon chain
223 // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space 223 // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
224 // So it can easily be subtracted from the outer hull 224 // So it can easily be subtracted from the outer hull
225 int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5); // how many steps do we need with approximately 45 degree 225 int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5); // how many steps do we need with approximately 45 degree
226 double dStepWidth=(fProfileBeginAngle-fProfileEndAngle)/iSteps; 226 double dStepWidth=(fProfileBeginAngle-fProfileEndAngle)/iSteps;
227 227
228 Vertex origin = new Vertex(0.0f, 0.0f, 0.0f); 228 Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
229 229
230 // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull 230 // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
231 SimpleHull cutHull = new SimpleHull(); 231 SimpleHull cutHull = new SimpleHull();
232 cutHull.AddVertex(origin); 232 cutHull.AddVertex(origin);
233 for (int i=0; i<iSteps; i++) { 233 for (int i=0; i<iSteps; i++) {
234 double angle=fProfileBeginAngle-i*dStepWidth; // we count against the angle orientation!!!! 234 double angle=fProfileBeginAngle-i*dStepWidth; // we count against the angle orientation!!!!
235 Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0); 235 Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0);
236 cutHull.AddVertex(v); 236 cutHull.AddVertex(v);
237 } 237 }
238 Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0); // Calculated separately to avoid errors 238 Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0); // Calculated separately to avoid errors
239 cutHull.AddVertex(legEnd); 239 cutHull.AddVertex(legEnd);
240 240
241 MainLog.Instance.Debug("Starting cutting of the hollow shape from the prim {1}", 0, primName); 241 MainLog.Instance.Debug("Starting cutting of the hollow shape from the prim {1}", 0, primName);
242 SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull); 242 SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
243 243
244 outerHull = cuttedHull; 244 outerHull = cuttedHull;
245 } 245 }
246 246
247 // Deal with the hole here 247 // Deal with the hole here
248 if (hollowFactor > 0) 248 if (hollowFactor > 0)
249 { 249 {
250 float hollowFactorF = (float) hollowFactor/(float) 50000; 250 float hollowFactorF = (float) hollowFactor/(float) 50000;
251 Vertex IMM = new Vertex(-0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f); 251 Vertex IMM = new Vertex(-0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
252 Vertex IPM = new Vertex(+0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f); 252 Vertex IPM = new Vertex(+0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
253 Vertex IMP = new Vertex(-0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f); 253 Vertex IMP = new Vertex(-0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
254 Vertex IPP = new Vertex(+0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f); 254 Vertex IPP = new Vertex(+0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
255 255
256 SimpleHull holeHull = new SimpleHull(); 256 SimpleHull holeHull = new SimpleHull();
257 257
258 holeHull.AddVertex(IMM); 258 holeHull.AddVertex(IMM);
259 holeHull.AddVertex(IMP); 259 holeHull.AddVertex(IMP);
260 holeHull.AddVertex(IPP); 260 holeHull.AddVertex(IPP);
261 holeHull.AddVertex(IPM); 261 holeHull.AddVertex(IPM);
262 262
263 SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull); 263 SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
264 264
265 outerHull = hollowedHull; 265 outerHull = hollowedHull;
266 266
267 } 267 }
268 268
269 Mesh m = new Mesh(); 269 Mesh m = new Mesh();
270 270
271 Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f); 271 Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
272 Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f); 272 Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
273 Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f); 273 Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
274 274
275 m.Add(Seed1); 275 m.Add(Seed1);
276 m.Add(Seed2); 276 m.Add(Seed2);
277 m.Add(Seed3); 277 m.Add(Seed3);
278 278
279 m.Add(new Triangle(Seed1, Seed2, Seed3)); 279 m.Add(new Triangle(Seed1, Seed2, Seed3));
280 m.Add(outerHull.getVertices()); 280 m.Add(outerHull.getVertices());
281 281
282 InsertVertices(m.vertices, 3, m.triangles); 282 InsertVertices(m.vertices, 3, m.triangles);
283 m.DumpRaw(baseDir, primName, "Proto first Mesh"); 283 m.DumpRaw(baseDir, primName, "Proto first Mesh");
284 284
285 m.Remove(Seed1); 285 m.Remove(Seed1);
286 m.Remove(Seed2); 286 m.Remove(Seed2);
287 m.Remove(Seed3); 287 m.Remove(Seed3);
288 m.DumpRaw(baseDir, primName, "Proto seeds removed"); 288 m.DumpRaw(baseDir, primName, "Proto seeds removed");
289 289
290 m.RemoveTrianglesOutside(outerHull); 290 m.RemoveTrianglesOutside(outerHull);
291 m.DumpRaw(baseDir, primName, "Proto outsides removed"); 291 m.DumpRaw(baseDir, primName, "Proto outsides removed");
292 292
293 foreach (Triangle t in m.triangles) 293 foreach (Triangle t in m.triangles)
294 { 294 {
295 PhysicsVector n = t.getNormal(); 295 PhysicsVector n = t.getNormal();
296 if (n.Z < 0.0) 296 if (n.Z < 0.0)
297 t.invertNormal(); 297 t.invertNormal();
298 } 298 }
299 299
300 Extruder extr = new Extruder(); 300 Extruder extr = new Extruder();
301 301
302 extr.size = size; 302 extr.size = size;
303 303
304 Mesh result = extr.Extrude(m); 304 Mesh result = extr.Extrude(m);
305 result.DumpRaw(baseDir, primName, "Z extruded"); 305 result.DumpRaw(baseDir, primName, "Z extruded");
306 return result; 306 return result;
307 } 307 }
308 308
309 public static void CalcNormals(Mesh mesh) 309 public static void CalcNormals(Mesh mesh)
310 { 310 {
311 int iTriangles = mesh.triangles.Count; 311 int iTriangles = mesh.triangles.Count;
312 312
313 mesh.normals = new float[iTriangles*3]; 313 mesh.normals = new float[iTriangles*3];
314 314
315 int i = 0; 315 int i = 0;
316 foreach (Triangle t in mesh.triangles) 316 foreach (Triangle t in mesh.triangles)
317 { 317 {
318 float ux, uy, uz; 318 float ux, uy, uz;
319 float vx, vy, vz; 319 float vx, vy, vz;
320 float wx, wy, wz; 320 float wx, wy, wz;
321 321
322 ux = t.v1.X; 322 ux = t.v1.X;
323 uy = t.v1.Y; 323 uy = t.v1.Y;
324 uz = t.v1.Z; 324 uz = t.v1.Z;
325 325
326 vx = t.v2.X; 326 vx = t.v2.X;
327 vy = t.v2.Y; 327 vy = t.v2.Y;
328 vz = t.v2.Z; 328 vz = t.v2.Z;
329 329
330 wx = t.v3.X; 330 wx = t.v3.X;
331 wy = t.v3.Y; 331 wy = t.v3.Y;
332 wz = t.v3.Z; 332 wz = t.v3.Z;
333 333
334 334
335 // Vectors for edges 335 // Vectors for edges
336 float e1x, e1y, e1z; 336 float e1x, e1y, e1z;
337 float e2x, e2y, e2z; 337 float e2x, e2y, e2z;
338 338
339 e1x = ux - vx; 339 e1x = ux - vx;
340 e1y = uy - vy; 340 e1y = uy - vy;
341 e1z = uz - vz; 341 e1z = uz - vz;
342 342
343 e2x = ux - wx; 343 e2x = ux - wx;
344 e2y = uy - wy; 344 e2y = uy - wy;
345 e2z = uz - wz; 345 e2z = uz - wz;
346 346
347 347
348 // Cross product for normal 348 // Cross product for normal
349 float nx, ny, nz; 349 float nx, ny, nz;
350 nx = e1y*e2z - e1z*e2y; 350 nx = e1y*e2z - e1z*e2y;
351 ny = e1z*e2x - e1x*e2z; 351 ny = e1z*e2x - e1x*e2z;
352 nz = e1x*e2y - e1y*e2x; 352 nz = e1x*e2y - e1y*e2x;
353 353
354 // Length 354 // Length
355 float l = (float) Math.Sqrt(nx*nx + ny*ny + nz*nz); 355 float l = (float) Math.Sqrt(nx*nx + ny*ny + nz*nz);
356 356
357 // Normalized "normal" 357 // Normalized "normal"
358 nx /= l; 358 nx /= l;
359 ny /= l; 359 ny /= l;
360 nz /= l; 360 nz /= l;
361 361
362 mesh.normals[i] = nx; 362 mesh.normals[i] = nx;
363 mesh.normals[i + 1] = ny; 363 mesh.normals[i + 1] = ny;
364 mesh.normals[i + 2] = nz; 364 mesh.normals[i + 2] = nz;
365 365
366 i += 3; 366 i += 3;
367 } 367 }
368 } 368 }
369 369
370 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size) 370 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
371 { 371 {
372 Mesh mesh = null; 372 Mesh mesh = null;
373 373
374 switch (primShape.ProfileShape) 374 switch (primShape.ProfileShape)
375 { 375 {
376 case ProfileShape.Square: 376 case ProfileShape.Square:
377 mesh=CreateBoxMesh(primName, primShape, size); 377 mesh=CreateBoxMesh(primName, primShape, size);
378 CalcNormals(mesh); 378 CalcNormals(mesh);
379 break; 379 break;
380 default: 380 default:
381 mesh = CreateBoxMesh(primName, primShape, size); 381 mesh = CreateBoxMesh(primName, primShape, size);
382 CalcNormals(mesh); 382 CalcNormals(mesh);
383 //Set default mesh to cube otherwise it'll return 383 //Set default mesh to cube otherwise it'll return
384 // null and crash on the 'setMesh' method in the physics plugins. 384 // null and crash on the 'setMesh' method in the physics plugins.
385 //mesh = null; 385 //mesh = null;
386 break; 386 break;
387 } 387 }
388 388
389 return mesh; 389 return mesh;
390 } 390 }
391 } 391 }
392 392
393} 393}