aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/OdePlugin
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/Meshing/HelperTypes.cs158
-rw-r--r--OpenSim/Region/Physics/OdePlugin/Meshing/Meshmerizer.cs514
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs121
3 files changed, 333 insertions, 460 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/Meshing/HelperTypes.cs b/OpenSim/Region/Physics/OdePlugin/Meshing/HelperTypes.cs
index 13184e2..3b20af7 100644
--- a/OpenSim/Region/Physics/OdePlugin/Meshing/HelperTypes.cs
+++ b/OpenSim/Region/Physics/OdePlugin/Meshing/HelperTypes.cs
@@ -30,37 +30,63 @@ using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; 31using System.Diagnostics;
32using System.Globalization; 32using System.Globalization;
33using OpenSim.Framework.Console;
33using OpenSim.Region.Physics.Manager; 34using OpenSim.Region.Physics.Manager;
34 35
35public class Vertex : IComparable<Vertex> 36using OpenSim.Region.Physics.OdePlugin.Meshing;
37
38public class Vertex : PhysicsVector, IComparable<Vertex>
36{ 39{
37 public String name; 40 public Vertex(float x, float y, float z)
38 public PhysicsVector point; 41 : base(x, y, z)
42 {
43 }
44
45 public Vertex(PhysicsVector v)
46 : base(v.X, v.Y, v.Z)
47 {
48 }
49
50 public Vertex Clone()
51 {
52 return new Vertex(X, Y, Z);
53 }
54
55 public static Vertex FromAngle(double angle)
56 {
57 return new Vertex((float)Math.Cos(angle), (float)Math.Sin(angle), 0.0f);
58 }
59
39 60
40 public Vertex(String name, float x, float y, float z) 61 public virtual bool Equals(Vertex v, float tolerance)
41 { 62 {
42 this.name = name; 63 PhysicsVector diff = this - v;
43 point = new PhysicsVector(x, y, z); 64 float d = diff.length();
65 if (d < tolerance)
66 return true;
67
68 return false;
44 } 69 }
45 70
71
46 public int CompareTo(Vertex other) 72 public int CompareTo(Vertex other)
47 { 73 {
48 if (point.X < other.point.X) 74 if (X < other.X)
49 return -1; 75 return -1;
50 76
51 if (point.X > other.point.X) 77 if (X > other.X)
52 return 1; 78 return 1;
53 79
54 if (point.Y < other.point.Y) 80 if (Y < other.Y)
55 return -1; 81 return -1;
56 82
57 if (point.Y > other.point.Y) 83 if (Y > other.Y)
58 return 1; 84 return 1;
59 85
60 if (point.Z < other.point.Z) 86 if (Z < other.Z)
61 return -1; 87 return -1;
62 88
63 if (point.Z > other.point.Z) 89 if (Z > other.Z)
64 return 1; 90 return 1;
65 91
66 return 0; 92 return 0;
@@ -75,51 +101,24 @@ public class Vertex : IComparable<Vertex>
75 { 101 {
76 return me.CompareTo(other) < 0; 102 return me.CompareTo(other) < 0;
77 } 103 }
78} 104 public String ToRaw()
79
80public class Simplex : IComparable<Simplex>
81{
82 public Vertex v1;
83 public Vertex v2;
84
85 public Simplex(Vertex _v1, Vertex _v2)
86 {
87 // Presort indices to make sorting (comparing) easier
88 if (_v1 > _v2)
89 {
90 v1 = _v1;
91 v2 = _v2;
92 }
93 else
94 {
95 v1 = _v2;
96 v2 = _v1;
97 }
98 }
99
100 public int CompareTo(Simplex other)
101 { 105 {
102 if (v1 > other.v1) 106 // Why this stuff with the number formatter?
103 { 107 // Well, the raw format uses the english/US notation of numbers
104 return 1; 108 // where the "," separates groups of 1000 while the "." marks the border between 1 and 10E-1.
105 } 109 // The german notation uses these characters exactly vice versa!
106 if (v1 < other.v1) 110 // The Float.ToString() routine is a localized one, giving different results depending on the country
107 { 111 // settings your machine works with. Unusable for a machine readable file format :-(
108 return -1; 112 NumberFormatInfo nfi = new NumberFormatInfo();
109 } 113 nfi.NumberDecimalSeparator = ".";
114 nfi.NumberDecimalDigits = 3;
110 115
111 if (v2 > other.v2) 116 String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi);
112 {
113 return 1;
114 }
115 if (v2 < other.v2)
116 {
117 return -1;
118 }
119 117
120 return 0; 118 return s1;
121 } 119 }
122} ; 120
121}
123 122
124public class Triangle 123public class Triangle
125{ 124{
@@ -155,6 +154,12 @@ public class Triangle
155 return false; 154 return false;
156 } 155 }
157 156
157 public bool isDegraded()
158 {
159 // This means, the vertices of this triangle are somewhat strange.
160 // They either line up or at least two of them are identical
161 return (radius_square == 0.0);
162 }
158 163
159 private void CalcCircle() 164 private void CalcCircle()
160 { 165 {
@@ -184,14 +189,14 @@ public class Triangle
184 double rx, ry; 189 double rx, ry;
185 190
186 // Readout the three points, the triangle consists of 191 // Readout the three points, the triangle consists of
187 p1x = v1.point.X; 192 p1x = v1.X;
188 p1y = v1.point.Y; 193 p1y = v1.Y;
189 194
190 p2x = v2.point.X; 195 p2x = v2.X;
191 p2y = v2.point.Y; 196 p2y = v2.Y;
192 197
193 p3x = v3.point.X; 198 p3x = v3.X;
194 p3y = v3.point.Y; 199 p3y = v3.Y;
195 200
196 /* calc helping values first */ 201 /* calc helping values first */
197 c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2; 202 c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2;
@@ -253,12 +258,9 @@ public class Triangle
253 nfi.CurrencyDecimalDigits = 2; 258 nfi.CurrencyDecimalDigits = 2;
254 nfi.CurrencyDecimalSeparator = "."; 259 nfi.CurrencyDecimalSeparator = ".";
255 260
256 String s1 = "<" + v1.point.X.ToString(nfi) + "," + v1.point.Y.ToString(nfi) + "," + v1.point.Z.ToString(nfi) + 261 String s1 = "<" + v1.X.ToString(nfi) + "," + v1.Y.ToString(nfi) + "," + v1.Z.ToString(nfi) + ">";
257 ">"; 262 String s2 = "<" + v2.X.ToString(nfi) + "," + v2.Y.ToString(nfi) + "," + v2.Z.ToString(nfi) + ">";
258 String s2 = "<" + v2.point.X.ToString(nfi) + "," + v2.point.Y.ToString(nfi) + "," + v2.point.Z.ToString(nfi) + 263 String s3 = "<" + v3.X.ToString(nfi) + "," + v3.Y.ToString(nfi) + "," + v3.Z.ToString(nfi) + ">";
259 ">";
260 String s3 = "<" + v3.point.X.ToString(nfi) + "," + v3.point.Y.ToString(nfi) + "," + v3.point.Z.ToString(nfi) +
261 ">";
262 264
263 return s1 + ";" + s2 + ";" + s3; 265 return s1 + ";" + s2 + ";" + s3;
264 } 266 }
@@ -271,23 +273,17 @@ public class Triangle
271 PhysicsVector e1; 273 PhysicsVector e1;
272 PhysicsVector e2; 274 PhysicsVector e2;
273 275
274 e1 = new PhysicsVector(v1.point.X - v2.point.X, v1.point.Y - v2.point.Y, v1.point.Z - v2.point.Z); 276 e1 = new PhysicsVector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
275 e2 = new PhysicsVector(v1.point.X - v3.point.X, v1.point.Y - v3.point.Y, v1.point.Z - v3.point.Z); 277 e2 = new PhysicsVector(v1.X - v3.X, v1.Y - v3.Y, v1.Z - v3.Z);
276 278
277 // Cross product for normal 279 // Cross product for normal
278 PhysicsVector n = new PhysicsVector(); 280 PhysicsVector n = PhysicsVector.cross(e1, e2);
279 float nx, ny, nz;
280 n.X = e1.Y*e2.Z - e1.Z*e2.Y;
281 n.Y = e1.Z*e2.X - e1.X*e2.Z;
282 n.Z = e1.X*e2.Y - e1.Y*e2.X;
283 281
284 // Length 282 // Length
285 float l = (float) Math.Sqrt(n.X*n.X + n.Y*n.Y + n.Z*n.Z); 283 float l = n.length();
286 284
287 // Normalized "normal" 285 // Normalized "normal"
288 n.X /= l; 286 n = n / l;
289 n.Y /= l;
290 n.Z /= l;
291 287
292 return n; 288 return n;
293 } 289 }
@@ -299,4 +295,12 @@ public class Triangle
299 v1 = v2; 295 v1 = v2;
300 v2 = vt; 296 v2 = vt;
301 } 297 }
302} \ No newline at end of file 298
299 // Dumps a triangle in the "raw faces" format, blender can import. This is for visualisation and
300 // debugging purposes
301 public String ToStringRaw()
302 {
303 String output = v1.ToRaw() + " " + v2.ToRaw() + " " +v3.ToRaw();
304 return output;
305 }
306}
diff --git a/OpenSim/Region/Physics/OdePlugin/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/OdePlugin/Meshing/Meshmerizer.cs
index 46de15e..2a304cb 100644
--- a/OpenSim/Region/Physics/OdePlugin/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/OdePlugin/Meshing/Meshmerizer.cs
@@ -27,109 +27,70 @@
27*/ 27*/
28 28
29using System; 29using System;
30using System.IO;
31using System.Globalization;
32using System.Diagnostics;
30using System.Collections.Generic; 33using System.Collections.Generic;
31using System.Runtime.InteropServices; 34using System.Runtime.InteropServices;
32using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Console;
33using OpenSim.Region.Physics.Manager; 37using OpenSim.Region.Physics.Manager;
34 38
35namespace OpenSim.Region.Physics.OdePlugin 39namespace OpenSim.Region.Physics.OdePlugin.Meshing
36{ 40{
37 public class Mesh
38 {
39 public List<Vertex> vertices;
40 public List<Triangle> triangles;
41
42 public float[] normals;
43
44 public Mesh()
45 {
46 vertices = new List<Vertex>();
47 triangles = new List<Triangle>();
48 }
49
50 public void Add(Triangle triangle)
51 {
52 int i;
53 i = vertices.IndexOf(triangle.v1);
54 if (i < 0)
55 throw new ArgumentException("Vertex v1 not known to mesh");
56 i = vertices.IndexOf(triangle.v2);
57 if (i < 0)
58 throw new ArgumentException("Vertex v2 not known to mesh");
59 i = vertices.IndexOf(triangle.v3);
60 if (i < 0)
61 throw new ArgumentException("Vertex v3 not known to mesh");
62
63 triangles.Add(triangle);
64 }
65
66 public void Add(Vertex v)
67 {
68 vertices.Add(v);
69 }
70
71
72 public float[] getVertexListAsFloat()
73 {
74 float[] result = new float[vertices.Count*3];
75 for (int i = 0; i < vertices.Count; i++)
76 {
77 Vertex v = vertices[i];
78 PhysicsVector point = v.point;
79 result[3*i + 0] = point.X;
80 result[3*i + 1] = point.Y;
81 result[3*i + 2] = point.Z;
82 }
83 GCHandle.Alloc(result, GCHandleType.Pinned);
84 return result;
85 }
86 41
87 public int[] getIndexListAsInt() 42 public class Meshmerizer
88 { 43 {
89 int[] result = new int[triangles.Count*3]; 44 // Setting baseDir to a path will enable the dumping of raw files
90 for (int i = 0; i < triangles.Count; i++) 45 // raw files can be imported by blender so a visual inspection of the results can be done
46 // const string baseDir = "rawFiles";
47 const string baseDir = null;
48
49 static void IntersectionParameterPD(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu)
50 {
51 // p1, p2, points on the straight
52 // r1, r2, directional vectors of the straight. Not necessarily of length 1!
53 // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
54 // thus allowing to decide whether an intersection is between two points
55
56 float r1x = r1.X;
57 float r1y = r1.Y;
58 float r2x = r2.X;
59 float r2y = r2.Y;
60
61 float denom = r1y*r2x - r1x*r2y;
62
63 if (denom == 0.0)
91 { 64 {
92 Triangle t = triangles[i]; 65 lambda = Single.NaN;
93 result[3*i + 0] = vertices.IndexOf(t.v1); 66 mu = Single.NaN;
94 result[3*i + 1] = vertices.IndexOf(t.v2); 67 return;
95 result[3*i + 2] = vertices.IndexOf(t.v3);
96 } 68 }
97 GCHandle.Alloc(result, GCHandleType.Pinned);
98 return result;
99 }
100
101 69
102 public void Append(Mesh newMesh) 70 float p1x = p1.X;
103 { 71 float p1y = p1.Y;
104 foreach (Vertex v in newMesh.vertices) 72 float p2x = p2.X;
105 vertices.Add(v); 73 float p2y = p2.Y;
106 74 lambda = (-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x) / denom;
107 foreach (Triangle t in newMesh.triangles) 75 mu = (-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x) / denom;
108 Add(t); 76
109 } 77 }
110 }
111
112 78
113 public class Meshmerizer
114 {
115 private static List<Triangle> FindInfluencedTriangles(List<Triangle> triangles, Vertex v) 79 private static List<Triangle> FindInfluencedTriangles(List<Triangle> triangles, Vertex v)
116 { 80 {
117 List<Triangle> influenced = new List<Triangle>(); 81 List<Triangle> influenced = new List<Triangle>();
118 foreach (Triangle t in triangles) 82 foreach (Triangle t in triangles)
119 { 83 {
120 float dx, dy; 84 if (t.isInCircle(v.X, v.Y))
121
122 if (t.isInCircle(v.point.X, v.point.Y))
123 { 85 {
124 influenced.Add(t); 86 influenced.Add(t);
125 } 87 }
126 } 88 }
127 return influenced; 89 return influenced;
128 } 90 }
129 91
130 92
131 private static void InsertVertices(List<Vertex> vertices, int usedForSeed, List<Triangle> triangles, 93 private static void InsertVertices(List<Vertex> vertices, int usedForSeed, List<Triangle> triangles)
132 List<int> innerBorders)
133 { 94 {
134 // This is a variant of the delaunay algorithm 95 // This is a variant of the delaunay algorithm
135 // each time a new vertex is inserted, all triangles that are influenced by it are deleted 96 // each time a new vertex is inserted, all triangles that are influenced by it are deleted
@@ -148,8 +109,10 @@ namespace OpenSim.Region.Physics.OdePlugin
148 // do not fulfill this condition with respect to the new triangle 109 // do not fulfill this condition with respect to the new triangle
149 110
150 // Find the triangles that are influenced by the new vertex 111 // Find the triangles that are influenced by the new vertex
151 Vertex v = vertices[iCurrentVertex]; 112 Vertex v=vertices[iCurrentVertex];
152 List<Triangle> influencedTriangles = FindInfluencedTriangles(triangles, v); 113 if (v == null)
114 continue; // Null is polygon stop marker. Ignore it
115 List<Triangle> influencedTriangles=FindInfluencedTriangles(triangles, v);
153 116
154 List<Simplex> simplices = new List<Simplex>(); 117 List<Simplex> simplices = new List<Simplex>();
155 118
@@ -163,11 +126,12 @@ namespace OpenSim.Region.Physics.OdePlugin
163 simplices.AddRange(newSimplices); 126 simplices.AddRange(newSimplices);
164 triangles.Remove(t); 127 triangles.Remove(t);
165 } 128 }
166 // Now sort the simplices. That will make identical ones side by side in the list 129 // Now sort the simplices. That will make identical ones reside side by side in the list
167 simplices.Sort(); 130 simplices.Sort();
168 131
169 // Look for duplicate simplices here. 132 // Look for duplicate simplices here.
170 // Remember, they are directly side by side in the list right now 133 // Remember, they are directly side by side in the list right now,
134 // So we only check directly neighbours
171 int iSimplex; 135 int iSimplex;
172 List<Simplex> innerSimplices = new List<Simplex>(); 136 List<Simplex> innerSimplices = new List<Simplex>();
173 for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards 137 for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards
@@ -186,310 +150,145 @@ namespace OpenSim.Region.Physics.OdePlugin
186 150
187 // each simplex still in the list belongs to the hull of the region in question 151 // each simplex still in the list belongs to the hull of the region in question
188 // The new vertex (yes, we still deal with verices here :-) ) forms a triangle 152 // The new vertex (yes, we still deal with verices here :-) ) forms a triangle
189 // With each of these simplices. Build the new triangles and add them to the list 153 // with each of these simplices. Build the new triangles and add them to the list
190 foreach (Simplex s in simplices) 154 foreach (Simplex s in simplices)
191 { 155 {
192 Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]); 156 Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]);
193 triangles.Add(t); 157 if (!t.isDegraded())
158 {
159 triangles.Add(t);
160 }
194 } 161 }
195 } 162 }
196 163
197 // At this point all vertices should be inserted into the mesh
198 // But the areas, that should be kept free still are filled with triangles
199 // We have to remove them. For this we have a list of indices to vertices.
200 // Each triangle that solemnly constists of vertices from the inner border
201 // are deleted
202
203 List<Triangle> innerTriangles = new List<Triangle>();
204 foreach (Triangle t in triangles)
205 {
206 if (
207 innerBorders.Contains(vertices.IndexOf(t.v1))
208 && innerBorders.Contains(vertices.IndexOf(t.v2))
209 && innerBorders.Contains(vertices.IndexOf(t.v3))
210 )
211 innerTriangles.Add(t);
212 }
213 foreach (Triangle t in innerTriangles)
214 {
215 triangles.Remove(t);
216 }
217 } 164 }
218 165
219 166
220 private static Mesh CreateBoxMeshX(PrimitiveBaseShape primShape, PhysicsVector size) 167 static Mesh CreateBoxMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
221 // Builds the x (+ and -) surfaces of a box shaped prim 168 // Builds the z (+ and -) surfaces of a box shaped prim
222 { 169 {
223 UInt16 hollowFactor = primShape.ProfileHollow; 170 UInt16 hollowFactor = primShape.ProfileHollow;
224 Mesh meshMX = new Mesh(); 171 UInt16 profileBegin = primShape.ProfileBegin;
225 172 UInt16 profileEnd = primShape.ProfileEnd;
226 173
227 // Surface 0, -X 174 // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
228 meshMX.Add(new Vertex("-X-Y-Z", -size.X/2.0f, -size.Y/2.0f, -size.Z/2.0f)); 175 // of a block are basically the same
229 meshMX.Add(new Vertex("-X+Y-Z", -size.X/2.0f, +size.Y/2.0f, -size.Z/2.0f)); 176 // They may be warped differently but the shape is identical
230 meshMX.Add(new Vertex("-X-Y+Z", -size.X/2.0f, -size.Y/2.0f, +size.Z/2.0f)); 177 // So we only create one surface as a model and derive both plus and minus surface of the block from it
231 meshMX.Add(new Vertex("-X+Y+Z", -size.X/2.0f, +size.Y/2.0f, +size.Z/2.0f)); 178 // This is done in a model space where the block spans from -.5 to +.5 in X and Y
232 179 // The mapping to Scene space is done later during the "extrusion" phase
233 meshMX.Add(new Triangle(meshMX.vertices[0], meshMX.vertices[2], meshMX.vertices[1])); 180
234 meshMX.Add(new Triangle(meshMX.vertices[1], meshMX.vertices[2], meshMX.vertices[3])); 181 // Base
235 182 Vertex MM = new Vertex(-0.5f, -0.5f, 0.0f);
236 183 Vertex PM = new Vertex(+0.5f, -0.5f, 0.0f);
237 Mesh meshPX = new Mesh(); 184 Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f);
238 // Surface 1, +X 185 Vertex PP = new Vertex(+0.5f, +0.5f, 0.0f);
239 meshPX.Add(new Vertex("+X-Y-Z", +size.X/2.0f, -size.Y/2.0f, -size.Z/2.0f)); 186
240 meshPX.Add(new Vertex("+X+Y-Z", +size.X/2.0f, +size.Y/2.0f, -size.Z/2.0f)); 187 Meshing.SimpleHull outerHull = new SimpleHull();
241 meshPX.Add(new Vertex("+X-Y+Z", +size.X/2.0f, -size.Y/2.0f, +size.Z/2.0f)); 188 outerHull.AddVertex(MM);
242 meshPX.Add(new Vertex("+X+Y+Z", +size.X/2.0f, +size.Y/2.0f, +size.Z/2.0f)); 189 outerHull.AddVertex(PM);
243 190 outerHull.AddVertex(PP);
244 191 outerHull.AddVertex(MP);
245 meshPX.Add(new Triangle(meshPX.vertices[0], meshPX.vertices[1], meshPX.vertices[2])); 192
246 meshPX.Add(new Triangle(meshPX.vertices[2], meshPX.vertices[1], meshPX.vertices[3])); 193 // Deal with cuts now
247 194 if ((profileBegin != 0) || (profileEnd != 0))
248
249 if (hollowFactor > 0)
250 { 195 {
251 float hollowFactorF = (float) hollowFactor/(float) 50000; 196 double fProfileBeginAngle = profileBegin / 50000.0 * 360.0; // In degree, for easier debugging and understanding
252 197 fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
253 Vertex IPP; 198 double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
254 Vertex IPM; 199 fProfileEndAngle -= (90.0 + 45.0);
255 Vertex IMP; 200 if (fProfileBeginAngle < fProfileEndAngle)
256 Vertex IMM; 201 fProfileEndAngle -= 360.0;
257 202
258 IPP = new Vertex("Inner-X+Y+Z", -size.X*hollowFactorF/2.0f, +size.Y*hollowFactorF/2.0f, +size.Z/2.0f); 203 // Note, that we don't want to cut out a triangle, even if this is a
259 IPM = new Vertex("Inner-X+Y-Z", -size.X*hollowFactorF/2.0f, +size.Y*hollowFactorF/2.0f, -size.Z/2.0f); 204 // good approximation for small cuts. Indeed we want to cut out an arc
260 IMP = new Vertex("Inner-X-Y+Z", -size.X*hollowFactorF/2.0f, -size.Y*hollowFactorF/2.0f, +size.Z/2.0f); 205 // and we approximate this arc by a polygon chain
261 IMM = new Vertex("Inner-X-Y-Z", -size.X*hollowFactorF/2.0f, -size.Y*hollowFactorF/2.0f, -size.Z/2.0f); 206 // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
262 207 // So it can easily be subtracted from the outer hull
263 meshMX.Add(IPP); 208 int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5); // how many steps do we need with approximately 45 degree
264 meshMX.Add(IPM); 209 double dStepWidth=(fProfileBeginAngle-fProfileEndAngle)/iSteps;
265 meshMX.Add(IMP); 210
266 meshMX.Add(IMM); 211 Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
267 212
268 meshMX.Add(new Triangle(IPP, IMP, IPM)); 213 // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
269 meshMX.Add(new Triangle(IPM, IMP, IMM)); 214 SimpleHull cutHull = new SimpleHull();
270 215 cutHull.AddVertex(origin);
271 foreach (Triangle t in meshMX.triangles) 216 for (int i=0; i<iSteps; i++) {
272 { 217 double angle=fProfileBeginAngle-i*dStepWidth; // we count against the angle orientation!!!!
273 PhysicsVector n = t.getNormal(); 218 Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0);
219 cutHull.AddVertex(v);
274 } 220 }
221 Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0); // Calculated separately to avoid errors
222 cutHull.AddVertex(legEnd);
275 223
224 MainLog.Instance.Debug("Starting cutting of the hollow shape from the prim {1}", 0, primName);
225 SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
276 226
277 IPP = new Vertex("Inner+X+Y+Z", +size.X*hollowFactorF/2.0f, +size.Y*hollowFactorF/2.0f, +size.Z/2.0f); 227 outerHull = cuttedHull;
278 IPM = new Vertex("Inner+X+Y-Z", +size.X*hollowFactorF/2.0f, +size.Y*hollowFactorF/2.0f, -size.Z/2.0f);
279 IMP = new Vertex("Inner+X-Y+Z", +size.X*hollowFactorF/2.0f, -size.Y*hollowFactorF/2.0f, +size.Z/2.0f);
280 IMM = new Vertex("Inner+X-Y-Z", +size.X*hollowFactorF/2.0f, -size.Y*hollowFactorF/2.0f, -size.Z/2.0f);
281
282 meshPX.Add(IPP);
283 meshPX.Add(IPM);
284 meshPX.Add(IMP);
285 meshPX.Add(IMM);
286
287 meshPX.Add(new Triangle(IPP, IPM, IMP));
288 meshPX.Add(new Triangle(IMP, IPM, IMM));
289
290 foreach (Triangle t in meshPX.triangles)
291 {
292 PhysicsVector n = t.getNormal();
293 }
294 } 228 }
295 229
296 Mesh result = new Mesh(); 230 // Deal with the hole here
297 result.Append(meshMX);
298 result.Append(meshPX);
299
300 return result;
301 }
302
303
304 private static Mesh CreateBoxMeshY(PrimitiveBaseShape primShape, PhysicsVector size)
305 // Builds the y (+ and -) surfaces of a box shaped prim
306 {
307 UInt16 hollowFactor = primShape.ProfileHollow;
308
309 // (M)inus Y
310 Mesh MeshMY = new Mesh();
311 MeshMY.Add(new Vertex("-X-Y-Z", -size.X/2.0f, -size.Y/2.0f, -size.Z/2.0f));
312 MeshMY.Add(new Vertex("+X-Y-Z", +size.X/2.0f, -size.Y/2.0f, -size.Z/2.0f));
313 MeshMY.Add(new Vertex("-X-Y+Z", -size.X/2.0f, -size.Y/2.0f, +size.Z/2.0f));
314 MeshMY.Add(new Vertex("+X-Y+Z", +size.X/2.0f, -size.Y/2.0f, +size.Z/2.0f));
315
316 MeshMY.Add(new Triangle(MeshMY.vertices[0], MeshMY.vertices[1], MeshMY.vertices[2]));
317 MeshMY.Add(new Triangle(MeshMY.vertices[2], MeshMY.vertices[1], MeshMY.vertices[3]));
318
319 // (P)lus Y
320 Mesh MeshPY = new Mesh();
321
322 MeshPY.Add(new Vertex("-X+Y-Z", -size.X/2.0f, +size.Y/2.0f, -size.Z/2.0f));
323 MeshPY.Add(new Vertex("+X+Y-Z", +size.X/2.0f, +size.Y/2.0f, -size.Z/2.0f));
324 MeshPY.Add(new Vertex("-X+Y+Z", -size.X/2.0f, +size.Y/2.0f, +size.Z/2.0f));
325 MeshPY.Add(new Vertex("+X+Y+Z", +size.X/2.0f, +size.Y/2.0f, +size.Z/2.0f));
326
327 MeshPY.Add(new Triangle(MeshPY.vertices[1], MeshPY.vertices[0], MeshPY.vertices[2]));
328 MeshPY.Add(new Triangle(MeshPY.vertices[1], MeshPY.vertices[2], MeshPY.vertices[3]));
329
330 if (hollowFactor > 0) 231 if (hollowFactor > 0)
331 { 232 {
332 float hollowFactorF = (float) hollowFactor/(float) 50000; 233 float hollowFactorF = (float) hollowFactor/(float) 50000;
234 Vertex IMM = new Vertex(-0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
235 Vertex IPM = new Vertex(+0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
236 Vertex IMP = new Vertex(-0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
237 Vertex IPP = new Vertex(+0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
333 238
334 Vertex IPP; 239 SimpleHull holeHull = new SimpleHull();
335 Vertex IPM;
336 Vertex IMP;
337 Vertex IMM;
338 240
339 IPP = new Vertex("Inner+X-Y+Z", +size.X*hollowFactorF/2.0f, -size.Y*hollowFactorF/2.0f, +size.Z/2.0f); 241 holeHull.AddVertex(IMM);
340 IPM = new Vertex("Inner+X-Y-Z", +size.X*hollowFactorF/2.0f, -size.Y*hollowFactorF/2.0f, -size.Z/2.0f); 242 holeHull.AddVertex(IMP);
341 IMP = new Vertex("Inner-X-Y+Z", -size.X*hollowFactorF/2.0f, -size.Y*hollowFactorF/2.0f, +size.Z/2.0f); 243 holeHull.AddVertex(IPP);
342 IMM = new Vertex("Inner-X-Y-Z", -size.X*hollowFactorF/2.0f, -size.Y*hollowFactorF/2.0f, -size.Z/2.0f); 244 holeHull.AddVertex(IPM);
343 245
344 MeshMY.Add(IPP); 246 SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
345 MeshMY.Add(IPM);
346 MeshMY.Add(IMP);
347 MeshMY.Add(IMM);
348 247
349 MeshMY.Add(new Triangle(IPP, IPM, IMP)); 248 outerHull = hollowedHull;
350 MeshMY.Add(new Triangle(IMP, IPM, IMM));
351 249
352 foreach (Triangle t in MeshMY.triangles)
353 {
354 PhysicsVector n = t.getNormal();
355 }
356
357
358 IPP = new Vertex("Inner+X+Y+Z", +size.X*hollowFactorF/2.0f, +size.Y*hollowFactorF/2.0f, +size.Z/2.0f);
359 IPM = new Vertex("Inner+X+Y-Z", +size.X*hollowFactorF/2.0f, +size.Y*hollowFactorF/2.0f, -size.Z/2.0f);
360 IMP = new Vertex("Inner-X+Y+Z", -size.X*hollowFactorF/2.0f, +size.Y*hollowFactorF/2.0f, +size.Z/2.0f);
361 IMM = new Vertex("Inner-X+Y-Z", -size.X*hollowFactorF/2.0f, +size.Y*hollowFactorF/2.0f, -size.Z/2.0f);
362
363 MeshPY.Add(IPP);
364 MeshPY.Add(IPM);
365 MeshPY.Add(IMP);
366 MeshPY.Add(IMM);
367
368 MeshPY.Add(new Triangle(IPM, IPP, IMP));
369 MeshPY.Add(new Triangle(IMP, IMM, IPM));
370
371 foreach (Triangle t in MeshPY.triangles)
372 {
373 PhysicsVector n = t.getNormal();
374 }
375 } 250 }
376 251
252 Mesh m = new Mesh();
377 253
378 Mesh result = new Mesh(); 254 Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
379 result.Append(MeshMY); 255 Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
380 result.Append(MeshPY); 256 Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
381
382 return result;
383 }
384
385 private static Mesh CreateBoxMeshZ(PrimitiveBaseShape primShape, PhysicsVector size)
386 // Builds the z (+ and -) surfaces of a box shaped prim
387 {
388 UInt16 hollowFactor = primShape.ProfileHollow;
389
390 // Base, i.e. outer shape
391 // (M)inus Z
392 Mesh MZ = new Mesh();
393
394 MZ.Add(new Vertex("-X-Y-Z", -size.X/2.0f, -size.Y/2.0f, -size.Z/2.0f));
395 MZ.Add(new Vertex("+X-Y-Z", +size.X/2.0f, -size.Y/2.0f, -size.Z/2.0f));
396 MZ.Add(new Vertex("-X+Y-Z", -size.X/2.0f, +size.Y/2.0f, -size.Z/2.0f));
397 MZ.Add(new Vertex("+X+Y-Z", +size.X/2.0f, +size.Y/2.0f, -size.Z/2.0f));
398 257
258 m.Add(Seed1);
259 m.Add(Seed2);
260 m.Add(Seed3);
399 261
400 MZ.Add(new Triangle(MZ.vertices[1], MZ.vertices[0], MZ.vertices[2])); 262 m.Add(new Triangle(Seed1, Seed2, Seed3));
401 MZ.Add(new Triangle(MZ.vertices[1], MZ.vertices[2], MZ.vertices[3])); 263 m.Add(outerHull.getVertices());
402 264
403 // (P)lus Z 265 InsertVertices(m.vertices, 3, m.triangles);
404 Mesh PZ = new Mesh(); 266 m.DumpRaw(baseDir, primName, "Proto first Mesh");
405 267
406 PZ.Add(new Vertex("-X-Y+Z", -size.X/2.0f, -size.Y/2.0f, 0.0f)); 268 m.Remove(Seed1);
407 PZ.Add(new Vertex("+X-Y+Z", +size.X/2.0f, -size.Y/2.0f, 0.0f)); 269 m.Remove(Seed2);
408 PZ.Add(new Vertex("-X+Y+Z", -size.X/2.0f, +size.Y/2.0f, 0.0f)); 270 m.Remove(Seed3);
409 PZ.Add(new Vertex("+X+Y+Z", +size.X/2.0f, +size.Y/2.0f, 0.0f)); 271 m.DumpRaw(baseDir, primName, "Proto seeds removed");
272
273 m.RemoveTrianglesOutside(outerHull);
274 m.DumpRaw(baseDir, primName, "Proto outsides removed");
410 275
411 // Surface 5, +Z 276 foreach (Triangle t in m.triangles)
412 PZ.Add(new Triangle(PZ.vertices[0], PZ.vertices[1], PZ.vertices[2]));
413 PZ.Add(new Triangle(PZ.vertices[2], PZ.vertices[1], PZ.vertices[3]));
414
415 if (hollowFactor > 0)
416 {
417 float hollowFactorF = (float) hollowFactor/(float) 50000;
418
419 MZ.Add(new Vertex("-X-Y-Z", -size.X*hollowFactorF/2.0f, -size.Y*hollowFactorF/2.0f, 0.0f));
420 MZ.Add(new Vertex("-X+Y-Z", +size.X*hollowFactorF/2.0f, -size.Y*hollowFactorF/2.0f, 0.0f));
421 MZ.Add(new Vertex("-X-Y+Z", -size.X*hollowFactorF/2.0f, +size.Y*hollowFactorF/2.0f, 0.0f));
422 MZ.Add(new Vertex("-X+Y+Z", +size.X*hollowFactorF/2.0f, +size.Y*hollowFactorF/2.0f, 0.0f));
423
424 List<int> innerBorders = new List<int>();
425 innerBorders.Add(4);
426 innerBorders.Add(5);
427 innerBorders.Add(6);
428 innerBorders.Add(7);
429
430 InsertVertices(MZ.vertices, 4, MZ.triangles, innerBorders);
431
432 PZ.Add(new Vertex("-X-Y-Z", -size.X*hollowFactorF/2.0f, -size.Y*hollowFactorF/2.0f, 0.0f));
433 PZ.Add(new Vertex("-X+Y-Z", +size.X*hollowFactorF/2.0f, -size.Y*hollowFactorF/2.0f, 0.0f));
434 PZ.Add(new Vertex("-X-Y+Z", -size.X*hollowFactorF/2.0f, +size.Y*hollowFactorF/2.0f, 0.0f));
435 PZ.Add(new Vertex("-X+Y+Z", +size.X*hollowFactorF/2.0f, +size.Y*hollowFactorF/2.0f, 0.0f));
436
437 innerBorders = new List<int>();
438 innerBorders.Add(4);
439 innerBorders.Add(5);
440 innerBorders.Add(6);
441 innerBorders.Add(7);
442
443 InsertVertices(PZ.vertices, 4, PZ.triangles, innerBorders);
444 }
445
446 foreach (Vertex v in PZ.vertices)
447 {
448 v.point.Z = size.Z/2.0f;
449 }
450 foreach (Vertex v in MZ.vertices)
451 {
452 v.point.Z = -size.Z/2.0f;
453 }
454
455 foreach (Triangle t in MZ.triangles)
456 {
457 PhysicsVector n = t.getNormal();
458 if (n.Z > 0.0)
459 t.invertNormal();
460 }
461
462 foreach (Triangle t in PZ.triangles)
463 { 277 {
464 PhysicsVector n = t.getNormal(); 278 PhysicsVector n = t.getNormal();
465 if (n.Z < 0.0) 279 if (n.Z < 0.0)
466 t.invertNormal(); 280 t.invertNormal();
467 } 281 }
468 282
469 Mesh result = new Mesh(); 283 Extruder extr = new Extruder();
470 result.Append(MZ);
471 result.Append(PZ);
472 284
473 return result; 285 extr.size = size;
474 }
475
476 private static Mesh CreateBoxMesh(PrimitiveBaseShape primShape, PhysicsVector size)
477 {
478 Mesh result = new Mesh();
479
480
481 Mesh MeshX = CreateBoxMeshX(primShape, size);
482 Mesh MeshY = CreateBoxMeshY(primShape, size);
483 Mesh MeshZ = CreateBoxMeshZ(primShape, size);
484
485 result.Append(MeshX);
486 result.Append(MeshY);
487 result.Append(MeshZ);
488 286
287 Mesh result = extr.Extrude(m);
288 result.DumpRaw(baseDir, primName, "Z extruded");
489 return result; 289 return result;
490 } 290 }
491 291
492
493 public static void CalcNormals(Mesh mesh) 292 public static void CalcNormals(Mesh mesh)
494 { 293 {
495 int iTriangles = mesh.triangles.Count; 294 int iTriangles = mesh.triangles.Count;
@@ -503,17 +302,18 @@ namespace OpenSim.Region.Physics.OdePlugin
503 float vx, vy, vz; 302 float vx, vy, vz;
504 float wx, wy, wz; 303 float wx, wy, wz;
505 304
506 ux = t.v1.point.X; 305 ux = t.v1.X;
507 uy = t.v1.point.Y; 306 uy = t.v1.Y;
508 uz = t.v1.point.Z; 307 uz = t.v1.Z;
308
309 vx = t.v2.X;
310 vy = t.v2.Y;
311 vz = t.v2.Z;
509 312
510 vx = t.v2.point.X; 313 wx = t.v3.X;
511 vy = t.v2.point.Y; 314 wy = t.v3.Y;
512 vz = t.v2.point.Z; 315 wz = t.v3.Z;
513 316
514 wx = t.v3.point.X;
515 wy = t.v3.point.Y;
516 wz = t.v3.point.Z;
517 317
518 // Vectors for edges 318 // Vectors for edges
519 float e1x, e1y, e1z; 319 float e1x, e1y, e1z;
@@ -550,14 +350,14 @@ namespace OpenSim.Region.Physics.OdePlugin
550 } 350 }
551 } 351 }
552 352
553 public static Mesh CreateMesh(PrimitiveBaseShape primShape, PhysicsVector size) 353 public static Mesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
554 { 354 {
555 Mesh mesh = null; 355 Mesh mesh = null;
556 356
557 switch (primShape.ProfileShape) 357 switch (primShape.ProfileShape)
558 { 358 {
559 case ProfileShape.Square: 359 case ProfileShape.Square:
560 mesh = CreateBoxMesh(primShape, size); 360 mesh=CreateBoxMesh(primName, primShape, size);
561 CalcNormals(mesh); 361 CalcNormals(mesh);
562 break; 362 break;
563 default: 363 default:
@@ -568,4 +368,4 @@ namespace OpenSim.Region.Physics.OdePlugin
568 return mesh; 368 return mesh;
569 } 369 }
570 } 370 }
571} \ No newline at end of file 371}
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index f1db034..9ac43bf 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -32,6 +32,8 @@ using Axiom.Math;
32using Ode.NET; 32using Ode.NET;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.Physics.Manager; 34using OpenSim.Region.Physics.Manager;
35using OpenSim.Region.Physics.OdePlugin.Meshing;
36
35 37
36namespace OpenSim.Region.Physics.OdePlugin 38namespace OpenSim.Region.Physics.OdePlugin
37{ 39{
@@ -274,6 +276,7 @@ namespace OpenSim.Region.Physics.OdePlugin
274 276
275 public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex) 277 public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex)
276 { 278 {
279/*
277 String name1 = null; 280 String name1 = null;
278 String name2 = null; 281 String name2 = null;
279 282
@@ -294,45 +297,52 @@ namespace OpenSim.Region.Physics.OdePlugin
294 297
295 d.GeomTriMeshGetTriangle(trimesh, 0, ref v0, ref v1, ref v2); 298 d.GeomTriMeshGetTriangle(trimesh, 0, ref v0, ref v1, ref v2);
296// MainLog.Instance.Debug("Triangle {0} is <{1},{2},{3}>, <{4},{5},{6}>, <{7},{8},{9}>", triangleIndex, v0.X, v0.Y, v0.Z, v1.X, v1.Y, v1.Z, v2.X, v2.Y, v2.Z); 299// MainLog.Instance.Debug("Triangle {0} is <{1},{2},{3}>, <{4},{5},{6}>, <{7},{8},{9}>", triangleIndex, v0.X, v0.Y, v0.Z, v1.X, v1.Y, v1.Z, v2.X, v2.Y, v2.Z);
297 300*/
298 return 1; 301 return 1;
299 } 302 }
300 303
304
305 public bool needsMeshing(PrimitiveBaseShape pbs)
306 {
307 if (pbs.ProfileHollow != 0)
308 return true;
309
310 if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
311 return true;
312
313 return false;
314 }
301 315
302 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, 316 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
303 PhysicsVector size, Quaternion rotation) //To be removed 317 PhysicsVector size, Quaternion rotation) //To be removed
304 { 318 {
305 return this.AddPrimShape(primName, pbs, position, size, rotation, false); 319 return this.AddPrimShape(primName, pbs, position, size, rotation, false);
306 } 320 }
321
307 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, 322 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
308 PhysicsVector size, Quaternion rotation, bool isPhysical) 323 PhysicsVector size, Quaternion rotation, bool isPhysical)
309 { 324 {
310 PhysicsActor result; 325 PhysicsActor result;
326 Mesh mesh = null;
311 327
312 switch (pbs.ProfileShape) 328 switch (pbs.ProfileShape)
313 { 329 {
314 case ProfileShape.Square: 330 case ProfileShape.Square:
315 /// support simple box & hollow box now; later, more shapes 331 /// support simple box & hollow box now; later, more shapes
316 if (pbs.ProfileHollow == 0) 332 if (needsMeshing(pbs))
317 {
318 result = AddPrim(primName, position, size, rotation, null, null);
319 }
320 else
321 { 333 {
322 Mesh mesh = Meshmerizer.CreateMesh(pbs, size); 334 mesh = Meshmerizer.CreateMesh(primName, pbs, size);
323 result = AddPrim(primName, position, size, rotation, mesh, pbs);
324 } 335 }
325 break; 336
326
327 default:
328 result = AddPrim(primName, position, size, rotation, null, null);
329 break; 337 break;
330 } 338 }
339
340 result = AddPrim(primName, position, size, rotation, mesh, pbs);
341
331 342
332 return result; 343 return result;
333 } 344 }
334 345
335
336 public override void Simulate(float timeStep) 346 public override void Simulate(float timeStep)
337 { 347 {
338 step_time += timeStep; 348 step_time += timeStep;
@@ -551,6 +561,13 @@ namespace OpenSim.Region.Physics.OdePlugin
551 set { } 561 set { }
552 } 562 }
553 563
564 public override PrimitiveBaseShape Shape
565 {
566 set
567 {
568 return;
569 }
570 }
554 571
555 public override PhysicsVector Velocity 572 public override PhysicsVector Velocity
556 { 573 {
@@ -753,6 +770,12 @@ namespace OpenSim.Region.Physics.OdePlugin
753 } 770 }
754 } 771 }
755 772
773 public override bool IsPhysical
774 {
775 get { return false; }
776 set { return; }
777 }
778
756 public void setMesh(OdeScene parent_scene, Mesh mesh) 779 public void setMesh(OdeScene parent_scene, Mesh mesh)
757 { 780 {
758 float[] vertexList = mesh.getVertexListAsFloat(); // Note, that vertextList is pinned in memory 781 float[] vertexList = mesh.getVertexListAsFloat(); // Note, that vertextList is pinned in memory
@@ -769,12 +792,6 @@ namespace OpenSim.Region.Physics.OdePlugin
769 prim_geom = d.CreateTriMesh(parent_scene.space, _triMeshData, parent_scene.triCallback, null, null); 792 prim_geom = d.CreateTriMesh(parent_scene.space, _triMeshData, parent_scene.triCallback, null, null);
770 } 793 }
771 794
772 public override bool IsPhysical
773 {
774 get { return false; }
775 set { return; }
776 }
777
778 public override bool Flying 795 public override bool Flying
779 { 796 {
780 get { return false; //no flying prims for you 797 get { return false; //no flying prims for you
@@ -810,18 +827,70 @@ namespace OpenSim.Region.Physics.OdePlugin
810 _size = value; 827 _size = value;
811 lock (OdeScene.OdeLock) 828 lock (OdeScene.OdeLock)
812 { 829 {
813 if (_mesh != null) // We deal with a mesh here 830 string oldname = _parent_scene.geom_name_map[prim_geom];
831
832 // Cleanup of old prim geometry
833 d.GeomDestroy(prim_geom);
834 if (_mesh != null)
814 { 835 {
815 string oldname = _parent_scene.geom_name_map[prim_geom]; 836 // Cleanup meshing here
816 d.GeomDestroy(prim_geom); 837 }
817 Mesh mesh = Meshmerizer.CreateMesh(_pbs, _size); 838
839 // Construction of new prim
840 if (this._parent_scene.needsMeshing(_pbs))
841 {
842 Mesh mesh = Meshmerizer.CreateMesh(oldname, _pbs, _size);
818 setMesh(_parent_scene, mesh); 843 setMesh(_parent_scene, mesh);
819 _parent_scene.geom_name_map[prim_geom] = oldname; 844 } else {
845 prim_geom = d.CreateBox(_parent_scene.space, _size.X, _size.Y, _size.Z);
846 }
847 _parent_scene.geom_name_map[prim_geom] = oldname;
848
849 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
850 d.Quaternion myrot = new d.Quaternion();
851 myrot.W = _orientation.w;
852 myrot.X = _orientation.x;
853 myrot.Y = _orientation.y;
854 myrot.Z = _orientation.z;
855 d.GeomSetQuaternion(prim_geom, ref myrot);
856 }
857 }
858 }
859
860 public override PrimitiveBaseShape Shape
861 {
862 set
863 {
864 _pbs = value;
865 lock (OdeScene.OdeLock)
866 {
867 string oldname = _parent_scene.geom_name_map[prim_geom];
868
869 // Cleanup of old prim geometry
870 d.GeomDestroy(prim_geom);
871 if (_mesh != null)
872 {
873 // Cleanup meshing here
820 } 874 }
821 else 875
876 // Construction of new prim
877 if (this._parent_scene.needsMeshing(_pbs))
822 { 878 {
823 d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); 879 Mesh mesh = Meshmerizer.CreateMesh(oldname, _pbs, _size);
880 setMesh(_parent_scene, mesh);
881 } else {
882 prim_geom = d.CreateBox(_parent_scene.space, _size.X, _size.Y, _size.Z);
824 } 883 }
884 _parent_scene.geom_name_map[prim_geom] = oldname;
885
886 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
887 d.Quaternion myrot = new d.Quaternion();
888 myrot.W = _orientation.w;
889 myrot.X = _orientation.x;
890 myrot.Y = _orientation.y;
891 myrot.Z = _orientation.z;
892 d.GeomSetQuaternion(prim_geom, ref myrot);
893
825 } 894 }
826 } 895 }
827 } 896 }