diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs | 210 |
1 files changed, 97 insertions, 113 deletions
diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs index e93175f..23e87d1 100644 --- a/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs +++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs | |||
@@ -43,6 +43,13 @@ namespace PrimMesher | |||
43 | /// <summary>W value</summary> | 43 | /// <summary>W value</summary> |
44 | public float W; | 44 | public float W; |
45 | 45 | ||
46 | public enum MainAxis : int | ||
47 | { | ||
48 | X = 0, | ||
49 | Y = 1, | ||
50 | Z = 2 | ||
51 | } | ||
52 | |||
46 | public Quat(float x, float y, float z, float w) | 53 | public Quat(float x, float y, float z, float w) |
47 | { | 54 | { |
48 | X = x; | 55 | X = x; |
@@ -51,20 +58,37 @@ namespace PrimMesher | |||
51 | W = w; | 58 | W = w; |
52 | } | 59 | } |
53 | 60 | ||
54 | public Quat(Coord axis, float angle) | 61 | public Quat(MainAxis BaseAxis, float angle) |
55 | { | 62 | { |
56 | axis = axis.Normalize(); | ||
57 | |||
58 | angle *= 0.5f; | 63 | angle *= 0.5f; |
59 | float c = (float)Math.Cos(angle); | 64 | double c = Math.Cos(angle); |
60 | float s = (float)Math.Sin(angle); | 65 | float s = (float)Math.Sqrt(1.0 - c * c); |
61 | |||
62 | X = axis.X * s; | ||
63 | Y = axis.Y * s; | ||
64 | Z = axis.Z * s; | ||
65 | W = c; | ||
66 | 66 | ||
67 | Normalize(); | 67 | W = (float)c; |
68 | switch (BaseAxis) | ||
69 | { | ||
70 | case MainAxis.X: | ||
71 | X = s; | ||
72 | Y = 0; | ||
73 | Z = 0; | ||
74 | break; | ||
75 | case MainAxis.Y: | ||
76 | X = 0; | ||
77 | Y = s; | ||
78 | Z = 0; | ||
79 | break; | ||
80 | case MainAxis.Z: | ||
81 | X = 0; | ||
82 | Y = 0; | ||
83 | Z = s; | ||
84 | break; | ||
85 | default: //error | ||
86 | X = 0; | ||
87 | Y = 0; | ||
88 | Z = 0; | ||
89 | W = 1; | ||
90 | break; | ||
91 | } | ||
68 | } | 92 | } |
69 | 93 | ||
70 | public float Length() | 94 | public float Length() |
@@ -108,7 +132,7 @@ namespace PrimMesher | |||
108 | 132 | ||
109 | public override string ToString() | 133 | public override string ToString() |
110 | { | 134 | { |
111 | return "< X: " + this.X.ToString() + ", Y: " + this.Y.ToString() + ", Z: " + this.Z.ToString() + ", W: " + this.W.ToString() + ">"; | 135 | return "< X: " + X.ToString() + ", Y: " + Y.ToString() + ", Z: " + Z.ToString() + ", W: " + W.ToString() + ">"; |
112 | } | 136 | } |
113 | } | 137 | } |
114 | 138 | ||
@@ -120,21 +144,21 @@ namespace PrimMesher | |||
120 | 144 | ||
121 | public Coord(float x, float y, float z) | 145 | public Coord(float x, float y, float z) |
122 | { | 146 | { |
123 | this.X = x; | 147 | X = x; |
124 | this.Y = y; | 148 | Y = y; |
125 | this.Z = z; | 149 | Z = z; |
126 | } | 150 | } |
127 | 151 | ||
128 | public float Length() | 152 | public float Length() |
129 | { | 153 | { |
130 | return (float)Math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z); | 154 | return (float)Math.Sqrt(X * X + Y * Y + Z * Z); |
131 | } | 155 | } |
132 | 156 | ||
133 | public Coord Invert() | 157 | public Coord Invert() |
134 | { | 158 | { |
135 | this.X = -this.X; | 159 | X = -X; |
136 | this.Y = -this.Y; | 160 | Y = -Y; |
137 | this.Z = -this.Z; | 161 | Z = -Z; |
138 | 162 | ||
139 | return this; | 163 | return this; |
140 | } | 164 | } |
@@ -148,15 +172,15 @@ namespace PrimMesher | |||
148 | if (mag > MAG_THRESHOLD) | 172 | if (mag > MAG_THRESHOLD) |
149 | { | 173 | { |
150 | float oomag = 1.0f / mag; | 174 | float oomag = 1.0f / mag; |
151 | this.X *= oomag; | 175 | X *= oomag; |
152 | this.Y *= oomag; | 176 | Y *= oomag; |
153 | this.Z *= oomag; | 177 | Z *= oomag; |
154 | } | 178 | } |
155 | else | 179 | else |
156 | { | 180 | { |
157 | this.X = 0.0f; | 181 | X = 0.0f; |
158 | this.Y = 0.0f; | 182 | Y = 0.0f; |
159 | this.Z = 0.0f; | 183 | Z = 0.0f; |
160 | } | 184 | } |
161 | 185 | ||
162 | return this; | 186 | return this; |
@@ -164,7 +188,7 @@ namespace PrimMesher | |||
164 | 188 | ||
165 | public override string ToString() | 189 | public override string ToString() |
166 | { | 190 | { |
167 | return this.X.ToString() + " " + this.Y.ToString() + " " + this.Z.ToString(); | 191 | return "<"+X.ToString() + "," + Y.ToString() + "," + Z.ToString()+ ">"; |
168 | } | 192 | } |
169 | 193 | ||
170 | public static Coord Cross(Coord c1, Coord c2) | 194 | public static Coord Cross(Coord c1, Coord c2) |
@@ -188,40 +212,14 @@ namespace PrimMesher | |||
188 | 212 | ||
189 | public static Coord operator *(Coord v, Quat q) | 213 | public static Coord operator *(Coord v, Quat q) |
190 | { | 214 | { |
191 | // From http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/ | 215 | float rx = q.W * v.X + q.Y * v.Z - q.Z * v.Y; |
192 | 216 | float ry = q.W * v.Y + q.Z * v.X - q.X * v.Z; | |
193 | Coord c2 = new Coord(0.0f, 0.0f, 0.0f); | 217 | float rz = q.W * v.Z + q.X * v.Y - q.Y * v.X; |
194 | 218 | ||
195 | c2.X = q.W * q.W * v.X + | 219 | return new Coord( |
196 | 2f * q.Y * q.W * v.Z - | 220 | 2.0f * (rz * q.Y - ry * q.Z) + v.X, |
197 | 2f * q.Z * q.W * v.Y + | 221 | 2.0f * (rx * q.Z - rz * q.X) + v.Y, |
198 | q.X * q.X * v.X + | 222 | 2.0f * (ry * q.X - rx * q.Y) + v.Z ); |
199 | 2f * q.Y * q.X * v.Y + | ||
200 | 2f * q.Z * q.X * v.Z - | ||
201 | q.Z * q.Z * v.X - | ||
202 | q.Y * q.Y * v.X; | ||
203 | |||
204 | c2.Y = | ||
205 | 2f * q.X * q.Y * v.X + | ||
206 | q.Y * q.Y * v.Y + | ||
207 | 2f * q.Z * q.Y * v.Z + | ||
208 | 2f * q.W * q.Z * v.X - | ||
209 | q.Z * q.Z * v.Y + | ||
210 | q.W * q.W * v.Y - | ||
211 | 2f * q.X * q.W * v.Z - | ||
212 | q.X * q.X * v.Y; | ||
213 | |||
214 | c2.Z = | ||
215 | 2f * q.X * q.Z * v.X + | ||
216 | 2f * q.Y * q.Z * v.Y + | ||
217 | q.Z * q.Z * v.Z - | ||
218 | 2f * q.W * q.Y * v.X - | ||
219 | q.Y * q.Y * v.Z + | ||
220 | 2f * q.W * q.X * v.Y - | ||
221 | q.X * q.X * v.Z + | ||
222 | q.W * q.W * v.Z; | ||
223 | |||
224 | return c2; | ||
225 | } | 223 | } |
226 | } | 224 | } |
227 | 225 | ||
@@ -234,25 +232,13 @@ namespace PrimMesher | |||
234 | public int v2; | 232 | public int v2; |
235 | public int v3; | 233 | public int v3; |
236 | 234 | ||
237 | public Face(int v1, int v2, int v3) | 235 | public Face(int _v1, int _v2, int _v3) |
238 | { | 236 | { |
239 | primFace = 0; | 237 | primFace = 0; |
240 | 238 | ||
241 | this.v1 = v1; | 239 | v1 = _v1; |
242 | this.v2 = v2; | 240 | v2 = _v2; |
243 | this.v3 = v3; | 241 | v3 = _v3; |
244 | } | ||
245 | |||
246 | public Coord SurfaceNormal(List<Coord> coordList) | ||
247 | { | ||
248 | Coord c1 = coordList[this.v1]; | ||
249 | Coord c2 = coordList[this.v2]; | ||
250 | Coord c3 = coordList[this.v3]; | ||
251 | |||
252 | Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); | ||
253 | Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z); | ||
254 | |||
255 | return Coord.Cross(edge1, edge2).Normalize(); | ||
256 | } | 242 | } |
257 | } | 243 | } |
258 | 244 | ||
@@ -264,9 +250,9 @@ namespace PrimMesher | |||
264 | 250 | ||
265 | internal Angle(float angle, float x, float y) | 251 | internal Angle(float angle, float x, float y) |
266 | { | 252 | { |
267 | this.angle = angle; | 253 | this.angle = angle; // 1 is 2pi |
268 | this.X = x; | 254 | X = x; // cos |
269 | this.Y = y; | 255 | Y = y; // sin |
270 | } | 256 | } |
271 | } | 257 | } |
272 | 258 | ||
@@ -373,8 +359,8 @@ namespace PrimMesher | |||
373 | { | 359 | { |
374 | angles = new List<Angle>(); | 360 | angles = new List<Angle>(); |
375 | 361 | ||
376 | const double twoPi = System.Math.PI * 2.0; | 362 | const float twoPi = (float)(Math.PI * 2.0); |
377 | const float twoPiInv = (float)(1.0d / twoPi); | 363 | const float twoPiInv = (float)(0.5 / Math.PI); |
378 | 364 | ||
379 | if (sides < 1) | 365 | if (sides < 1) |
380 | throw new Exception("number of sides not greater than zero"); | 366 | throw new Exception("number of sides not greater than zero"); |
@@ -493,7 +479,7 @@ namespace PrimMesher | |||
493 | /// </summary> | 479 | /// </summary> |
494 | public class Profile | 480 | public class Profile |
495 | { | 481 | { |
496 | private const float twoPi = 2.0f * (float)Math.PI; | 482 | private const float twoPi = (float)(2.0 * Math.PI); |
497 | 483 | ||
498 | public string errorMessage = null; | 484 | public string errorMessage = null; |
499 | 485 | ||
@@ -1032,7 +1018,7 @@ namespace PrimMesher | |||
1032 | 1018 | ||
1033 | float twist = twistBegin + twistTotal * percentOfPath; | 1019 | float twist = twistBegin + twistTotal * percentOfPath; |
1034 | 1020 | ||
1035 | newNode.rotation = new Quat(new Coord(0.0f, 0.0f, 1.0f), twist); | 1021 | newNode.rotation = new Quat(Quat.MainAxis.Z, twist); |
1036 | newNode.position = new Coord(xOffset, yOffset, zOffset); | 1022 | newNode.position = new Coord(xOffset, yOffset, zOffset); |
1037 | newNode.percentOfPath = percentOfPath; | 1023 | newNode.percentOfPath = percentOfPath; |
1038 | 1024 | ||
@@ -1134,11 +1120,11 @@ namespace PrimMesher | |||
1134 | // now orient the rotation of the profile layer relative to it's position on the path | 1120 | // now orient the rotation of the profile layer relative to it's position on the path |
1135 | // adding taperY to the angle used to generate the quat appears to approximate the viewer | 1121 | // adding taperY to the angle used to generate the quat appears to approximate the viewer |
1136 | 1122 | ||
1137 | newNode.rotation = new Quat(new Coord(1.0f, 0.0f, 0.0f), angle + topShearY); | 1123 | newNode.rotation = new Quat(Quat.MainAxis.X, angle + topShearY); |
1138 | 1124 | ||
1139 | // next apply twist rotation to the profile layer | 1125 | // next apply twist rotation to the profile layer |
1140 | if (twistTotal != 0.0f || twistBegin != 0.0f) | 1126 | if (twistTotal != 0.0f || twistBegin != 0.0f) |
1141 | newNode.rotation *= new Quat(new Coord(0.0f, 0.0f, 1.0f), twist); | 1127 | newNode.rotation *= new Quat(Quat.MainAxis.Z, twist); |
1142 | 1128 | ||
1143 | newNode.percentOfPath = percentOfPath; | 1129 | newNode.percentOfPath = percentOfPath; |
1144 | 1130 | ||
@@ -1175,8 +1161,8 @@ namespace PrimMesher | |||
1175 | private float profileStart = 0.0f; | 1161 | private float profileStart = 0.0f; |
1176 | private float profileEnd = 1.0f; | 1162 | private float profileEnd = 1.0f; |
1177 | private float hollow = 0.0f; | 1163 | private float hollow = 0.0f; |
1178 | public int twistBegin = 0; | 1164 | public float twistBegin = 0; |
1179 | public int twistEnd = 0; | 1165 | public float twistEnd = 0; |
1180 | public float topShearX = 0.0f; | 1166 | public float topShearX = 0.0f; |
1181 | public float topShearY = 0.0f; | 1167 | public float topShearY = 0.0f; |
1182 | public float pathCutBegin = 0.0f; | 1168 | public float pathCutBegin = 0.0f; |
@@ -1299,8 +1285,6 @@ namespace PrimMesher | |||
1299 | 1285 | ||
1300 | hasHollow = (this.hollow > 0.001f); | 1286 | hasHollow = (this.hollow > 0.001f); |
1301 | 1287 | ||
1302 | float twistBegin = this.twistBegin / 360.0f * twoPi; | ||
1303 | float twistEnd = this.twistEnd / 360.0f * twoPi; | ||
1304 | float twistTotal = twistEnd - twistBegin; | 1288 | float twistTotal = twistEnd - twistBegin; |
1305 | float twistTotalAbs = Math.Abs(twistTotal); | 1289 | float twistTotalAbs = Math.Abs(twistTotal); |
1306 | if (twistTotalAbs > 0.01f) | 1290 | if (twistTotalAbs > 0.01f) |
@@ -1385,7 +1369,7 @@ namespace PrimMesher | |||
1385 | 1369 | ||
1386 | if (initialProfileRot != 0.0f) | 1370 | if (initialProfileRot != 0.0f) |
1387 | { | 1371 | { |
1388 | profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); | 1372 | profile.AddRot(new Quat(Quat.MainAxis.Z, initialProfileRot)); |
1389 | } | 1373 | } |
1390 | 1374 | ||
1391 | Path path = new Path(); | 1375 | Path path = new Path(); |
@@ -1592,29 +1576,29 @@ namespace PrimMesher | |||
1592 | /// <returns></returns> | 1576 | /// <returns></returns> |
1593 | public PrimMesh Copy() | 1577 | public PrimMesh Copy() |
1594 | { | 1578 | { |
1595 | PrimMesh copy = new PrimMesh(this.sides, this.profileStart, this.profileEnd, this.hollow, this.hollowSides); | 1579 | PrimMesh copy = new PrimMesh(sides, profileStart, profileEnd, hollow, hollowSides); |
1596 | copy.twistBegin = this.twistBegin; | 1580 | copy.twistBegin = twistBegin; |
1597 | copy.twistEnd = this.twistEnd; | 1581 | copy.twistEnd = twistEnd; |
1598 | copy.topShearX = this.topShearX; | 1582 | copy.topShearX = topShearX; |
1599 | copy.topShearY = this.topShearY; | 1583 | copy.topShearY = topShearY; |
1600 | copy.pathCutBegin = this.pathCutBegin; | 1584 | copy.pathCutBegin = pathCutBegin; |
1601 | copy.pathCutEnd = this.pathCutEnd; | 1585 | copy.pathCutEnd = pathCutEnd; |
1602 | copy.dimpleBegin = this.dimpleBegin; | 1586 | copy.dimpleBegin = dimpleBegin; |
1603 | copy.dimpleEnd = this.dimpleEnd; | 1587 | copy.dimpleEnd = dimpleEnd; |
1604 | copy.skew = this.skew; | 1588 | copy.skew = skew; |
1605 | copy.holeSizeX = this.holeSizeX; | 1589 | copy.holeSizeX = holeSizeX; |
1606 | copy.holeSizeY = this.holeSizeY; | 1590 | copy.holeSizeY = holeSizeY; |
1607 | copy.taperX = this.taperX; | 1591 | copy.taperX = taperX; |
1608 | copy.taperY = this.taperY; | 1592 | copy.taperY = taperY; |
1609 | copy.radius = this.radius; | 1593 | copy.radius = radius; |
1610 | copy.revolutions = this.revolutions; | 1594 | copy.revolutions = revolutions; |
1611 | copy.stepsPerRevolution = this.stepsPerRevolution; | 1595 | copy.stepsPerRevolution = stepsPerRevolution; |
1612 | 1596 | ||
1613 | copy.numPrimFaces = this.numPrimFaces; | 1597 | copy.numPrimFaces = numPrimFaces; |
1614 | copy.errorMessage = this.errorMessage; | 1598 | copy.errorMessage = errorMessage; |
1615 | 1599 | ||
1616 | copy.coords = new List<Coord>(this.coords); | 1600 | copy.coords = new List<Coord>(coords); |
1617 | copy.faces = new List<Face>(this.faces); | 1601 | copy.faces = new List<Face>(faces); |
1618 | 1602 | ||
1619 | return copy; | 1603 | return copy; |
1620 | } | 1604 | } |