diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/Meshing/HelperTypes.cs | 158 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/Meshing/Meshmerizer.cs | 514 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 121 |
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; | |||
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Diagnostics; | 31 | using System.Diagnostics; |
32 | using System.Globalization; | 32 | using System.Globalization; |
33 | using OpenSim.Framework.Console; | ||
33 | using OpenSim.Region.Physics.Manager; | 34 | using OpenSim.Region.Physics.Manager; |
34 | 35 | ||
35 | public class Vertex : IComparable<Vertex> | 36 | using OpenSim.Region.Physics.OdePlugin.Meshing; |
37 | |||
38 | public 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 | |||
80 | public 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 | ||
124 | public class Triangle | 123 | public 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 | ||
29 | using System; | 29 | using System; |
30 | using System.IO; | ||
31 | using System.Globalization; | ||
32 | using System.Diagnostics; | ||
30 | using System.Collections.Generic; | 33 | using System.Collections.Generic; |
31 | using System.Runtime.InteropServices; | 34 | using System.Runtime.InteropServices; |
32 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Framework.Console; | ||
33 | using OpenSim.Region.Physics.Manager; | 37 | using OpenSim.Region.Physics.Manager; |
34 | 38 | ||
35 | namespace OpenSim.Region.Physics.OdePlugin | 39 | namespace 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; | |||
32 | using Ode.NET; | 32 | using Ode.NET; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Region.Physics.Manager; | 34 | using OpenSim.Region.Physics.Manager; |
35 | using OpenSim.Region.Physics.OdePlugin.Meshing; | ||
36 | |||
35 | 37 | ||
36 | namespace OpenSim.Region.Physics.OdePlugin | 38 | namespace 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 | } |