diff options
author | UbitUmarov | 2013-05-29 02:08:14 +0100 |
---|---|---|
committer | UbitUmarov | 2013-05-29 02:08:14 +0100 |
commit | 4e72cf9ee21dd8833af860fa5af4fc91e11018cb (patch) | |
tree | dc3992d2d9383172524eeacf939d9a3bca165ad2 | |
parent | Allow Linden trees to preserve their type when taken into inventory and rezze... (diff) | |
download | opensim-SC-4e72cf9ee21dd8833af860fa5af4fc91e11018cb.zip opensim-SC-4e72cf9ee21dd8833af860fa5af4fc91e11018cb.tar.gz opensim-SC-4e72cf9ee21dd8833af860fa5af4fc91e11018cb.tar.bz2 opensim-SC-4e72cf9ee21dd8833af860fa5af4fc91e11018cb.tar.xz |
*** DANGER TESTING **** changed prims mesh generation hopefully removing
spurius faces. CHanged several aspects. Fixed prims inertia that was too
low, still using box as model. Increased number of quickstep SOR
iterations to 15. Keep it 15 even on heavy load ( will only jump
simulation time).
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs | 4 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/Mesh.cs | 33 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 64 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs | 1230 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs | 6 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 52 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 288 |
9 files changed, 503 insertions, 1178 deletions
diff --git a/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs b/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs index 2938257..5dc1e78 100644 --- a/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs +++ b/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs | |||
@@ -256,9 +256,9 @@ public class Vertex : IComparable<Vertex> | |||
256 | // settings your machine works with. Unusable for a machine readable file format :-( | 256 | // settings your machine works with. Unusable for a machine readable file format :-( |
257 | NumberFormatInfo nfi = new NumberFormatInfo(); | 257 | NumberFormatInfo nfi = new NumberFormatInfo(); |
258 | nfi.NumberDecimalSeparator = "."; | 258 | nfi.NumberDecimalSeparator = "."; |
259 | nfi.NumberDecimalDigits = 3; | 259 | nfi.NumberDecimalDigits = 6; |
260 | 260 | ||
261 | String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi); | 261 | String s1 = X.ToString(nfi) + " " + Y.ToString(nfi) + " " + Z.ToString(nfi); |
262 | 262 | ||
263 | return s1; | 263 | return s1; |
264 | } | 264 | } |
diff --git a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs index fa06926..0418893 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs | |||
@@ -205,34 +205,21 @@ namespace OpenSim.Region.Physics.Meshing | |||
205 | 205 | ||
206 | } | 206 | } |
207 | 207 | ||
208 | private float fRound(float f) | ||
209 | { | ||
210 | int i; | ||
211 | if (f == 0f) | ||
212 | return f; | ||
213 | else if (f > 0f) | ||
214 | i = (int)(1e5f * f + 0.5f); | ||
215 | else | ||
216 | i = (int)(1e5f * f - 0.5f); | ||
217 | |||
218 | return ((float)i * 1e-5f); | ||
219 | } | ||
220 | |||
221 | public void Add(Triangle triangle) | 208 | public void Add(Triangle triangle) |
222 | { | 209 | { |
223 | if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) | 210 | if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) |
224 | throw new NotSupportedException("Attempt to Add to a pinned Mesh"); | 211 | throw new NotSupportedException("Attempt to Add to a pinned Mesh"); |
225 | 212 | ||
226 | // round down | 213 | |
227 | triangle.v1.X = fRound(triangle.v1.X); | 214 | triangle.v1.X = (float)Math.Round(triangle.v1.X, 6); |
228 | triangle.v1.Y = fRound(triangle.v1.Y); | 215 | triangle.v1.Y = (float)Math.Round(triangle.v1.Y, 6); |
229 | triangle.v1.Z = fRound(triangle.v1.Z); | 216 | triangle.v1.Z = (float)Math.Round(triangle.v1.Z, 6); |
230 | triangle.v2.X = fRound(triangle.v2.X); | 217 | triangle.v2.X = (float)Math.Round(triangle.v2.X, 6); |
231 | triangle.v2.Y = fRound(triangle.v2.Y); | 218 | triangle.v2.Y = (float)Math.Round(triangle.v2.Y, 6); |
232 | triangle.v2.Z = fRound(triangle.v2.Z); | 219 | triangle.v2.Z = (float)Math.Round(triangle.v2.Z, 6); |
233 | triangle.v3.X = fRound(triangle.v3.X); | 220 | triangle.v3.X = (float)Math.Round(triangle.v3.X, 6); |
234 | triangle.v3.Y = fRound(triangle.v3.Y); | 221 | triangle.v3.Y = (float)Math.Round(triangle.v3.Y, 6); |
235 | triangle.v3.Z = fRound(triangle.v3.Z); | 222 | triangle.v3.Z = (float)Math.Round(triangle.v3.Z, 6); |
236 | 223 | ||
237 | if ((triangle.v1.X == triangle.v2.X && triangle.v1.Y == triangle.v2.Y && triangle.v1.Z == triangle.v2.Z) | 224 | if ((triangle.v1.X == triangle.v2.X && triangle.v1.Y == triangle.v2.Y && triangle.v1.Z == triangle.v2.Z) |
238 | || (triangle.v1.X == triangle.v3.X && triangle.v1.Y == triangle.v3.Y && triangle.v1.Z == triangle.v3.Z) | 225 | || (triangle.v1.X == triangle.v3.X && triangle.v1.Y == triangle.v3.Y && triangle.v1.Z == triangle.v3.Z) |
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index 00cbfbd..c131c6f 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | |||
@@ -816,15 +816,31 @@ namespace OpenSim.Region.Physics.Meshing | |||
816 | 816 | ||
817 | float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f; | 817 | float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f; |
818 | float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f; | 818 | float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f; |
819 | |||
820 | if (profileBegin < 0.0f) | ||
821 | profileBegin = 0.0f; | ||
822 | |||
823 | if (profileEnd < 0.02f) | ||
824 | profileEnd = 0.02f; | ||
825 | else if (profileEnd > 1.0f) | ||
826 | profileEnd = 1.0f; | ||
827 | |||
828 | if (profileBegin >= profileEnd) | ||
829 | profileBegin = profileEnd - 0.02f; | ||
830 | |||
819 | float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f; | 831 | float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f; |
820 | if (profileHollow > 0.95f) | 832 | if (profileHollow > 0.95f) |
821 | profileHollow = 0.95f; | 833 | profileHollow = 0.95f; |
822 | 834 | ||
823 | int sides = 4; | 835 | int sides = 4; |
824 | LevelOfDetail iLOD = (LevelOfDetail)lod; | 836 | LevelOfDetail iLOD = (LevelOfDetail)lod; |
825 | if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) | 837 | byte profshape = (byte)(primShape.ProfileCurve & 0x07); |
838 | |||
839 | if (profshape == (byte)ProfileShape.EquilateralTriangle | ||
840 | || profshape == (byte)ProfileShape.IsometricTriangle | ||
841 | || profshape == (byte)ProfileShape.RightTriangle) | ||
826 | sides = 3; | 842 | sides = 3; |
827 | else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) | 843 | else if (profshape == (byte)ProfileShape.Circle) |
828 | { | 844 | { |
829 | switch (iLOD) | 845 | switch (iLOD) |
830 | { | 846 | { |
@@ -835,7 +851,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
835 | default: sides = 24; break; | 851 | default: sides = 24; break; |
836 | } | 852 | } |
837 | } | 853 | } |
838 | else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) | 854 | else if (profshape == (byte)ProfileShape.HalfCircle) |
839 | { // half circle, prim is a sphere | 855 | { // half circle, prim is a sphere |
840 | switch (iLOD) | 856 | switch (iLOD) |
841 | { | 857 | { |
@@ -865,10 +881,15 @@ namespace OpenSim.Region.Physics.Meshing | |||
865 | else if (primShape.HollowShape == HollowShape.Square) | 881 | else if (primShape.HollowShape == HollowShape.Square) |
866 | hollowSides = 4; | 882 | hollowSides = 4; |
867 | else if (primShape.HollowShape == HollowShape.Triangle) | 883 | else if (primShape.HollowShape == HollowShape.Triangle) |
868 | hollowSides = 3; | 884 | { |
885 | if (profshape == (byte)ProfileShape.HalfCircle) | ||
886 | hollowSides = 6; | ||
887 | else | ||
888 | hollowSides = 3; | ||
889 | } | ||
869 | 890 | ||
870 | primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides); | 891 | primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides); |
871 | 892 | ||
872 | if (primMesh.errorMessage != null) | 893 | if (primMesh.errorMessage != null) |
873 | if (primMesh.errorMessage.Length > 0) | 894 | if (primMesh.errorMessage.Length > 0) |
874 | m_log.Error("[ERROR] " + primMesh.errorMessage); | 895 | m_log.Error("[ERROR] " + primMesh.errorMessage); |
@@ -880,17 +901,11 @@ namespace OpenSim.Region.Physics.Meshing | |||
880 | 901 | ||
881 | if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible) | 902 | if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible) |
882 | { | 903 | { |
883 | primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10; | 904 | primMesh.twistBegin = (primShape.PathTwistBegin * 18) / 10; |
884 | primMesh.twistEnd = primShape.PathTwist * 18 / 10; | 905 | primMesh.twistEnd = (primShape.PathTwist * 18) / 10; |
885 | primMesh.taperX = pathScaleX; | 906 | primMesh.taperX = pathScaleX; |
886 | primMesh.taperY = pathScaleY; | 907 | primMesh.taperY = pathScaleY; |
887 | 908 | ||
888 | if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) | ||
889 | { | ||
890 | ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); | ||
891 | if (profileBegin < 0.0f) profileBegin = 0.0f; | ||
892 | if (profileEnd > 1.0f) profileEnd = 1.0f; | ||
893 | } | ||
894 | #if SPAM | 909 | #if SPAM |
895 | m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString()); | 910 | m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString()); |
896 | #endif | 911 | #endif |
@@ -911,17 +926,11 @@ namespace OpenSim.Region.Physics.Meshing | |||
911 | primMesh.radius = 0.01f * primShape.PathRadiusOffset; | 926 | primMesh.radius = 0.01f * primShape.PathRadiusOffset; |
912 | primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions; | 927 | primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions; |
913 | primMesh.skew = 0.01f * primShape.PathSkew; | 928 | primMesh.skew = 0.01f * primShape.PathSkew; |
914 | primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10; | 929 | primMesh.twistBegin = (primShape.PathTwistBegin * 36) / 10; |
915 | primMesh.twistEnd = primShape.PathTwist * 36 / 10; | 930 | primMesh.twistEnd = (primShape.PathTwist * 36) / 10; |
916 | primMesh.taperX = primShape.PathTaperX * 0.01f; | 931 | primMesh.taperX = primShape.PathTaperX * 0.01f; |
917 | primMesh.taperY = primShape.PathTaperY * 0.01f; | 932 | primMesh.taperY = primShape.PathTaperY * 0.01f; |
918 | 933 | ||
919 | if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) | ||
920 | { | ||
921 | ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); | ||
922 | if (profileBegin < 0.0f) profileBegin = 0.0f; | ||
923 | if (profileEnd > 1.0f) profileEnd = 1.0f; | ||
924 | } | ||
925 | #if SPAM | 934 | #if SPAM |
926 | m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString()); | 935 | m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString()); |
927 | #endif | 936 | #endif |
@@ -1031,14 +1040,19 @@ namespace OpenSim.Region.Physics.Meshing | |||
1031 | 1040 | ||
1032 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) | 1041 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) |
1033 | { | 1042 | { |
1034 | return CreateMesh(primName, primShape, size, lod, false,false,false,false); | 1043 | return CreateMesh(primName, primShape, size, lod, false,false,false); |
1035 | } | 1044 | } |
1036 | 1045 | ||
1037 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) | 1046 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) |
1038 | { | 1047 | { |
1039 | return CreateMesh(primName, primShape, size, lod, false,false,false,false); | 1048 | return CreateMesh(primName, primShape, size, lod, false,false,false); |
1040 | } | 1049 | } |
1041 | 1050 | ||
1051 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, bool convex, bool forOde) | ||
1052 | { | ||
1053 | return CreateMesh(primName, primShape, size, lod, false, false, false); | ||
1054 | } | ||
1055 | |||
1042 | public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) | 1056 | public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) |
1043 | { | 1057 | { |
1044 | Mesh mesh = null; | 1058 | Mesh mesh = null; |
@@ -1080,7 +1094,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
1080 | 1094 | ||
1081 | private static Vector3 m_MeshUnitSize = new Vector3(1.0f, 1.0f, 1.0f); | 1095 | private static Vector3 m_MeshUnitSize = new Vector3(1.0f, 1.0f, 1.0f); |
1082 | 1096 | ||
1083 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, bool convex, bool forOde) | 1097 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde) |
1084 | { | 1098 | { |
1085 | #if SPAM | 1099 | #if SPAM |
1086 | m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName); | 1100 | m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName); |
diff --git a/OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs b/OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs index 4049ee1..8eb136b 100644 --- a/OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs +++ b/OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs | |||
@@ -225,26 +225,6 @@ namespace PrimMesher | |||
225 | } | 225 | } |
226 | } | 226 | } |
227 | 227 | ||
228 | public struct UVCoord | ||
229 | { | ||
230 | public float U; | ||
231 | public float V; | ||
232 | |||
233 | |||
234 | public UVCoord(float u, float v) | ||
235 | { | ||
236 | this.U = u; | ||
237 | this.V = v; | ||
238 | } | ||
239 | |||
240 | public UVCoord Flip() | ||
241 | { | ||
242 | this.U = 1.0f - this.U; | ||
243 | this.V = 1.0f - this.V; | ||
244 | return this; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | public struct Face | 228 | public struct Face |
249 | { | 229 | { |
250 | public int primFace; | 230 | public int primFace; |
@@ -254,16 +234,6 @@ namespace PrimMesher | |||
254 | public int v2; | 234 | public int v2; |
255 | public int v3; | 235 | public int v3; |
256 | 236 | ||
257 | //normals | ||
258 | public int n1; | ||
259 | public int n2; | ||
260 | public int n3; | ||
261 | |||
262 | // uvs | ||
263 | public int uv1; | ||
264 | public int uv2; | ||
265 | public int uv3; | ||
266 | |||
267 | public Face(int v1, int v2, int v3) | 237 | public Face(int v1, int v2, int v3) |
268 | { | 238 | { |
269 | primFace = 0; | 239 | primFace = 0; |
@@ -272,31 +242,6 @@ namespace PrimMesher | |||
272 | this.v2 = v2; | 242 | this.v2 = v2; |
273 | this.v3 = v3; | 243 | this.v3 = v3; |
274 | 244 | ||
275 | this.n1 = 0; | ||
276 | this.n2 = 0; | ||
277 | this.n3 = 0; | ||
278 | |||
279 | this.uv1 = 0; | ||
280 | this.uv2 = 0; | ||
281 | this.uv3 = 0; | ||
282 | |||
283 | } | ||
284 | |||
285 | public Face(int v1, int v2, int v3, int n1, int n2, int n3) | ||
286 | { | ||
287 | primFace = 0; | ||
288 | |||
289 | this.v1 = v1; | ||
290 | this.v2 = v2; | ||
291 | this.v3 = v3; | ||
292 | |||
293 | this.n1 = n1; | ||
294 | this.n2 = n2; | ||
295 | this.n3 = n3; | ||
296 | |||
297 | this.uv1 = 0; | ||
298 | this.uv2 = 0; | ||
299 | this.uv3 = 0; | ||
300 | } | 245 | } |
301 | 246 | ||
302 | public Coord SurfaceNormal(List<Coord> coordList) | 247 | public Coord SurfaceNormal(List<Coord> coordList) |
@@ -312,96 +257,6 @@ namespace PrimMesher | |||
312 | } | 257 | } |
313 | } | 258 | } |
314 | 259 | ||
315 | public struct ViewerFace | ||
316 | { | ||
317 | public int primFaceNumber; | ||
318 | |||
319 | public Coord v1; | ||
320 | public Coord v2; | ||
321 | public Coord v3; | ||
322 | |||
323 | public int coordIndex1; | ||
324 | public int coordIndex2; | ||
325 | public int coordIndex3; | ||
326 | |||
327 | public Coord n1; | ||
328 | public Coord n2; | ||
329 | public Coord n3; | ||
330 | |||
331 | public UVCoord uv1; | ||
332 | public UVCoord uv2; | ||
333 | public UVCoord uv3; | ||
334 | |||
335 | public ViewerFace(int primFaceNumber) | ||
336 | { | ||
337 | this.primFaceNumber = primFaceNumber; | ||
338 | |||
339 | this.v1 = new Coord(); | ||
340 | this.v2 = new Coord(); | ||
341 | this.v3 = new Coord(); | ||
342 | |||
343 | this.coordIndex1 = this.coordIndex2 = this.coordIndex3 = -1; // -1 means not assigned yet | ||
344 | |||
345 | this.n1 = new Coord(); | ||
346 | this.n2 = new Coord(); | ||
347 | this.n3 = new Coord(); | ||
348 | |||
349 | this.uv1 = new UVCoord(); | ||
350 | this.uv2 = new UVCoord(); | ||
351 | this.uv3 = new UVCoord(); | ||
352 | } | ||
353 | |||
354 | public void Scale(float x, float y, float z) | ||
355 | { | ||
356 | this.v1.X *= x; | ||
357 | this.v1.Y *= y; | ||
358 | this.v1.Z *= z; | ||
359 | |||
360 | this.v2.X *= x; | ||
361 | this.v2.Y *= y; | ||
362 | this.v2.Z *= z; | ||
363 | |||
364 | this.v3.X *= x; | ||
365 | this.v3.Y *= y; | ||
366 | this.v3.Z *= z; | ||
367 | } | ||
368 | |||
369 | public void AddPos(float x, float y, float z) | ||
370 | { | ||
371 | this.v1.X += x; | ||
372 | this.v2.X += x; | ||
373 | this.v3.X += x; | ||
374 | |||
375 | this.v1.Y += y; | ||
376 | this.v2.Y += y; | ||
377 | this.v3.Y += y; | ||
378 | |||
379 | this.v1.Z += z; | ||
380 | this.v2.Z += z; | ||
381 | this.v3.Z += z; | ||
382 | } | ||
383 | |||
384 | public void AddRot(Quat q) | ||
385 | { | ||
386 | this.v1 *= q; | ||
387 | this.v2 *= q; | ||
388 | this.v3 *= q; | ||
389 | |||
390 | this.n1 *= q; | ||
391 | this.n2 *= q; | ||
392 | this.n3 *= q; | ||
393 | } | ||
394 | |||
395 | public void CalcSurfaceNormal() | ||
396 | { | ||
397 | |||
398 | Coord edge1 = new Coord(this.v2.X - this.v1.X, this.v2.Y - this.v1.Y, this.v2.Z - this.v1.Z); | ||
399 | Coord edge2 = new Coord(this.v3.X - this.v1.X, this.v3.Y - this.v1.Y, this.v3.Z - this.v1.Z); | ||
400 | |||
401 | this.n1 = this.n2 = this.n3 = Coord.Cross(edge1, edge2).Normalize(); | ||
402 | } | ||
403 | } | ||
404 | |||
405 | internal struct Angle | 260 | internal struct Angle |
406 | { | 261 | { |
407 | internal float angle; | 262 | internal float angle; |
@@ -428,14 +283,6 @@ namespace PrimMesher | |||
428 | new Angle(1.0f, 1.0f, 0.0f) | 283 | new Angle(1.0f, 1.0f, 0.0f) |
429 | }; | 284 | }; |
430 | 285 | ||
431 | private static Coord[] normals3 = | ||
432 | { | ||
433 | new Coord(0.25f, 0.4330127019f, 0.0f).Normalize(), | ||
434 | new Coord(-0.5f, 0.0f, 0.0f).Normalize(), | ||
435 | new Coord(0.25f, -0.4330127019f, 0.0f).Normalize(), | ||
436 | new Coord(0.25f, 0.4330127019f, 0.0f).Normalize() | ||
437 | }; | ||
438 | |||
439 | private static Angle[] angles4 = | 286 | private static Angle[] angles4 = |
440 | { | 287 | { |
441 | new Angle(0.0f, 1.0f, 0.0f), | 288 | new Angle(0.0f, 1.0f, 0.0f), |
@@ -445,13 +292,32 @@ namespace PrimMesher | |||
445 | new Angle(1.0f, 1.0f, 0.0f) | 292 | new Angle(1.0f, 1.0f, 0.0f) |
446 | }; | 293 | }; |
447 | 294 | ||
448 | private static Coord[] normals4 = | 295 | private static Angle[] angles6 = |
449 | { | 296 | { |
450 | new Coord(0.5f, 0.5f, 0.0f).Normalize(), | 297 | new Angle(0.0f, 1.0f, 0.0f), |
451 | new Coord(-0.5f, 0.5f, 0.0f).Normalize(), | 298 | new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f), |
452 | new Coord(-0.5f, -0.5f, 0.0f).Normalize(), | 299 | new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), |
453 | new Coord(0.5f, -0.5f, 0.0f).Normalize(), | 300 | new Angle(0.5f, -1.0f, 0.0f), |
454 | new Coord(0.5f, 0.5f, 0.0f).Normalize() | 301 | new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), |
302 | new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f), | ||
303 | new Angle(1.0f, 1.0f, 0.0f) | ||
304 | }; | ||
305 | |||
306 | private static Angle[] angles12 = | ||
307 | { | ||
308 | new Angle(0.0f, 1.0f, 0.0f), | ||
309 | new Angle(0.083333333333333329f, 0.86602540378443871f, 0.5f), | ||
310 | new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f), | ||
311 | new Angle(0.25f, 0.0f, 1.0f), | ||
312 | new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), | ||
313 | new Angle(0.41666666666666663f, -0.86602540378443849f, 0.5f), | ||
314 | new Angle(0.5f, -1.0f, 0.0f), | ||
315 | new Angle(0.58333333333333326f, -0.86602540378443882f, -0.5f), | ||
316 | new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), | ||
317 | new Angle(0.75f, 0.0f, -1.0f), | ||
318 | new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f), | ||
319 | new Angle(0.91666666666666663f, 0.86602540378443837f, -0.5f), | ||
320 | new Angle(1.0f, 1.0f, 0.0f) | ||
455 | }; | 321 | }; |
456 | 322 | ||
457 | private static Angle[] angles24 = | 323 | private static Angle[] angles24 = |
@@ -503,56 +369,72 @@ namespace PrimMesher | |||
503 | } | 369 | } |
504 | 370 | ||
505 | internal List<Angle> angles; | 371 | internal List<Angle> angles; |
506 | internal List<Coord> normals; | ||
507 | 372 | ||
508 | internal void makeAngles(int sides, float startAngle, float stopAngle) | 373 | internal void makeAngles(int sides, float startAngle, float stopAngle, bool hasCut) |
509 | { | 374 | { |
510 | angles = new List<Angle>(); | 375 | angles = new List<Angle>(); |
511 | normals = new List<Coord>(); | ||
512 | 376 | ||
513 | double twoPi = System.Math.PI * 2.0; | 377 | const double twoPi = System.Math.PI * 2.0; |
514 | float twoPiInv = 1.0f / (float)twoPi; | 378 | const float twoPiInv = (float)(1.0d / twoPi); |
515 | 379 | ||
516 | if (sides < 1) | 380 | if (sides < 1) |
517 | throw new Exception("number of sides not greater than zero"); | 381 | throw new Exception("number of sides not greater than zero"); |
518 | if (stopAngle <= startAngle) | 382 | if (stopAngle <= startAngle) |
519 | throw new Exception("stopAngle not greater than startAngle"); | 383 | throw new Exception("stopAngle not greater than startAngle"); |
520 | 384 | ||
521 | if ((sides == 3 || sides == 4 || sides == 24)) | 385 | if ((sides == 3 || sides == 4 || sides == 6 || sides == 12 || sides == 24)) |
522 | { | 386 | { |
523 | startAngle *= twoPiInv; | 387 | startAngle *= twoPiInv; |
524 | stopAngle *= twoPiInv; | 388 | stopAngle *= twoPiInv; |
525 | 389 | ||
526 | Angle[] sourceAngles; | 390 | Angle[] sourceAngles; |
527 | if (sides == 3) | 391 | switch (sides) |
528 | sourceAngles = angles3; | 392 | { |
529 | else if (sides == 4) | 393 | case 3: |
530 | sourceAngles = angles4; | 394 | sourceAngles = angles3; |
531 | else sourceAngles = angles24; | 395 | break; |
396 | case 4: | ||
397 | sourceAngles = angles4; | ||
398 | break; | ||
399 | case 6: | ||
400 | sourceAngles = angles6; | ||
401 | break; | ||
402 | case 12: | ||
403 | sourceAngles = angles12; | ||
404 | break; | ||
405 | default: | ||
406 | sourceAngles = angles24; | ||
407 | break; | ||
408 | } | ||
532 | 409 | ||
533 | int startAngleIndex = (int)(startAngle * sides); | 410 | int startAngleIndex = (int)(startAngle * sides); |
534 | int endAngleIndex = sourceAngles.Length - 1; | 411 | int endAngleIndex = sourceAngles.Length - 1; |
535 | if (stopAngle < 1.0f) | ||
536 | endAngleIndex = (int)(stopAngle * sides) + 1; | ||
537 | if (endAngleIndex == startAngleIndex) | ||
538 | endAngleIndex++; | ||
539 | 412 | ||
540 | for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++) | 413 | if (hasCut) |
541 | { | 414 | { |
542 | angles.Add(sourceAngles[angleIndex]); | 415 | if (stopAngle < 1.0f) |
543 | if (sides == 3) | 416 | endAngleIndex = (int)(stopAngle * sides) + 1; |
544 | normals.Add(normals3[angleIndex]); | 417 | if (endAngleIndex == startAngleIndex) |
545 | else if (sides == 4) | 418 | endAngleIndex++; |
546 | normals.Add(normals4[angleIndex]); | 419 | |
547 | } | 420 | for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++) |
421 | { | ||
422 | angles.Add(sourceAngles[angleIndex]); | ||
423 | } | ||
548 | 424 | ||
549 | if (startAngle > 0.0f) | 425 | if (startAngle > 0.0f) |
550 | angles[0] = interpolatePoints(startAngle, angles[0], angles[1]); | 426 | angles[0] = interpolatePoints(startAngle, angles[0], angles[1]); |
551 | 427 | ||
552 | if (stopAngle < 1.0f) | 428 | if (stopAngle < 1.0f) |
429 | { | ||
430 | int lastAngleIndex = angles.Count - 1; | ||
431 | angles[lastAngleIndex] = interpolatePoints(stopAngle, angles[lastAngleIndex - 1], angles[lastAngleIndex]); | ||
432 | } | ||
433 | } | ||
434 | else | ||
553 | { | 435 | { |
554 | int lastAngleIndex = angles.Count - 1; | 436 | for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex; angleIndex++) |
555 | angles[lastAngleIndex] = interpolatePoints(stopAngle, angles[lastAngleIndex - 1], angles[lastAngleIndex]); | 437 | angles.Add(sourceAngles[angleIndex]); |
556 | } | 438 | } |
557 | } | 439 | } |
558 | else | 440 | else |
@@ -618,20 +500,10 @@ namespace PrimMesher | |||
618 | 500 | ||
619 | public List<Coord> coords; | 501 | public List<Coord> coords; |
620 | public List<Face> faces; | 502 | public List<Face> faces; |
621 | public List<Coord> vertexNormals; | ||
622 | public List<float> us; | ||
623 | public List<UVCoord> faceUVs; | ||
624 | public List<int> faceNumbers; | ||
625 | 503 | ||
626 | // use these for making individual meshes for each prim face | 504 | // use these for making individual meshes for each prim face |
627 | public List<int> outerCoordIndices = null; | 505 | public List<int> outerCoordIndices = null; |
628 | public List<int> hollowCoordIndices = null; | 506 | public List<int> hollowCoordIndices = null; |
629 | public List<int> cut1CoordIndices = null; | ||
630 | public List<int> cut2CoordIndices = null; | ||
631 | |||
632 | public Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f); | ||
633 | public Coord cutNormal1 = new Coord(); | ||
634 | public Coord cutNormal2 = new Coord(); | ||
635 | 507 | ||
636 | public int numOuterVerts = 0; | 508 | public int numOuterVerts = 0; |
637 | public int numHollowVerts = 0; | 509 | public int numHollowVerts = 0; |
@@ -639,7 +511,6 @@ namespace PrimMesher | |||
639 | public int outerFaceNumber = -1; | 511 | public int outerFaceNumber = -1; |
640 | public int hollowFaceNumber = -1; | 512 | public int hollowFaceNumber = -1; |
641 | 513 | ||
642 | public bool calcVertexNormals = false; | ||
643 | public int bottomFaceNumber = 0; | 514 | public int bottomFaceNumber = 0; |
644 | public int numPrimFaces = 0; | 515 | public int numPrimFaces = 0; |
645 | 516 | ||
@@ -647,40 +518,19 @@ namespace PrimMesher | |||
647 | { | 518 | { |
648 | this.coords = new List<Coord>(); | 519 | this.coords = new List<Coord>(); |
649 | this.faces = new List<Face>(); | 520 | this.faces = new List<Face>(); |
650 | this.vertexNormals = new List<Coord>(); | ||
651 | this.us = new List<float>(); | ||
652 | this.faceUVs = new List<UVCoord>(); | ||
653 | this.faceNumbers = new List<int>(); | ||
654 | } | 521 | } |
655 | 522 | ||
656 | public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) | 523 | public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool hasProfileCut, bool createFaces) |
657 | { | 524 | { |
658 | this.calcVertexNormals = calcVertexNormals; | 525 | const float halfSqr2 = 0.7071067811866f; |
526 | |||
659 | this.coords = new List<Coord>(); | 527 | this.coords = new List<Coord>(); |
660 | this.faces = new List<Face>(); | 528 | this.faces = new List<Face>(); |
661 | this.vertexNormals = new List<Coord>(); | ||
662 | this.us = new List<float>(); | ||
663 | this.faceUVs = new List<UVCoord>(); | ||
664 | this.faceNumbers = new List<int>(); | ||
665 | |||
666 | Coord center = new Coord(0.0f, 0.0f, 0.0f); | ||
667 | 529 | ||
668 | List<Coord> hollowCoords = new List<Coord>(); | 530 | List<Coord> hollowCoords = new List<Coord>(); |
669 | List<Coord> hollowNormals = new List<Coord>(); | ||
670 | List<float> hollowUs = new List<float>(); | ||
671 | |||
672 | if (calcVertexNormals) | ||
673 | { | ||
674 | this.outerCoordIndices = new List<int>(); | ||
675 | this.hollowCoordIndices = new List<int>(); | ||
676 | this.cut1CoordIndices = new List<int>(); | ||
677 | this.cut2CoordIndices = new List<int>(); | ||
678 | } | ||
679 | 531 | ||
680 | bool hasHollow = (hollow > 0.0f); | 532 | bool hasHollow = (hollow > 0.0f); |
681 | 533 | ||
682 | bool hasProfileCut = (profileStart > 0.0f || profileEnd < 1.0f); | ||
683 | |||
684 | AngleList angles = new AngleList(); | 534 | AngleList angles = new AngleList(); |
685 | AngleList hollowAngles = new AngleList(); | 535 | AngleList hollowAngles = new AngleList(); |
686 | 536 | ||
@@ -688,14 +538,14 @@ namespace PrimMesher | |||
688 | float yScale = 0.5f; | 538 | float yScale = 0.5f; |
689 | if (sides == 4) // corners of a square are sqrt(2) from center | 539 | if (sides == 4) // corners of a square are sqrt(2) from center |
690 | { | 540 | { |
691 | xScale = 0.707107f; | 541 | xScale = halfSqr2; |
692 | yScale = 0.707107f; | 542 | yScale = halfSqr2; |
693 | } | 543 | } |
694 | 544 | ||
695 | float startAngle = profileStart * twoPi; | 545 | float startAngle = profileStart * twoPi; |
696 | float stopAngle = profileEnd * twoPi; | 546 | float stopAngle = profileEnd * twoPi; |
697 | 547 | ||
698 | try { angles.makeAngles(sides, startAngle, stopAngle); } | 548 | try { angles.makeAngles(sides, startAngle, stopAngle,hasProfileCut); } |
699 | catch (Exception ex) | 549 | catch (Exception ex) |
700 | { | 550 | { |
701 | 551 | ||
@@ -707,6 +557,9 @@ namespace PrimMesher | |||
707 | 557 | ||
708 | this.numOuterVerts = angles.angles.Count; | 558 | this.numOuterVerts = angles.angles.Count; |
709 | 559 | ||
560 | Angle angle; | ||
561 | Coord newVert = new Coord(); | ||
562 | |||
710 | // flag to create as few triangles as possible for 3 or 4 side profile | 563 | // flag to create as few triangles as possible for 3 or 4 side profile |
711 | bool simpleFace = (sides < 5 && !hasHollow && !hasProfileCut); | 564 | bool simpleFace = (sides < 5 && !hasHollow && !hasProfileCut); |
712 | 565 | ||
@@ -716,7 +569,7 @@ namespace PrimMesher | |||
716 | hollowAngles = angles; | 569 | hollowAngles = angles; |
717 | else | 570 | else |
718 | { | 571 | { |
719 | try { hollowAngles.makeAngles(hollowSides, startAngle, stopAngle); } | 572 | try { hollowAngles.makeAngles(hollowSides, startAngle, stopAngle, hasProfileCut); } |
720 | catch (Exception ex) | 573 | catch (Exception ex) |
721 | { | 574 | { |
722 | errorMessage = "makeAngles failed: Exception: " + ex.ToString() | 575 | errorMessage = "makeAngles failed: Exception: " + ex.ToString() |
@@ -724,116 +577,48 @@ namespace PrimMesher | |||
724 | 577 | ||
725 | return; | 578 | return; |
726 | } | 579 | } |
580 | |||
581 | int numHollowAngles = hollowAngles.angles.Count; | ||
582 | for (int i = 0; i < numHollowAngles; i++) | ||
583 | { | ||
584 | angle = hollowAngles.angles[i]; | ||
585 | newVert.X = hollow * xScale * angle.X; | ||
586 | newVert.Y = hollow * yScale * angle.Y; | ||
587 | newVert.Z = 0.0f; | ||
588 | |||
589 | hollowCoords.Add(newVert); | ||
590 | } | ||
727 | } | 591 | } |
728 | this.numHollowVerts = hollowAngles.angles.Count; | 592 | this.numHollowVerts = hollowAngles.angles.Count; |
729 | } | 593 | } |
730 | else if (!simpleFace) | 594 | else if (!simpleFace) |
731 | { | 595 | { |
596 | Coord center = new Coord(0.0f, 0.0f, 0.0f); | ||
732 | this.coords.Add(center); | 597 | this.coords.Add(center); |
733 | if (this.calcVertexNormals) | ||
734 | this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); | ||
735 | this.us.Add(0.0f); | ||
736 | } | ||
737 | |||
738 | float z = 0.0f; | ||
739 | |||
740 | Angle angle; | ||
741 | Coord newVert = new Coord(); | ||
742 | if (hasHollow && hollowSides != sides) | ||
743 | { | ||
744 | int numHollowAngles = hollowAngles.angles.Count; | ||
745 | for (int i = 0; i < numHollowAngles; i++) | ||
746 | { | ||
747 | angle = hollowAngles.angles[i]; | ||
748 | newVert.X = hollow * xScale * angle.X; | ||
749 | newVert.Y = hollow * yScale * angle.Y; | ||
750 | newVert.Z = z; | ||
751 | |||
752 | hollowCoords.Add(newVert); | ||
753 | if (this.calcVertexNormals) | ||
754 | { | ||
755 | if (hollowSides < 5) | ||
756 | hollowNormals.Add(hollowAngles.normals[i].Invert()); | ||
757 | else | ||
758 | hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); | ||
759 | |||
760 | if (hollowSides == 4) | ||
761 | hollowUs.Add(angle.angle * hollow * 0.707107f); | ||
762 | else | ||
763 | hollowUs.Add(angle.angle * hollow); | ||
764 | } | ||
765 | } | ||
766 | } | 598 | } |
767 | 599 | ||
768 | int index = 0; | ||
769 | int numAngles = angles.angles.Count; | 600 | int numAngles = angles.angles.Count; |
601 | bool hollowsame = (hasHollow && hollowSides == sides); | ||
770 | 602 | ||
771 | for (int i = 0; i < numAngles; i++) | 603 | for (int i = 0; i < numAngles; i++) |
772 | { | 604 | { |
773 | angle = angles.angles[i]; | 605 | angle = angles.angles[i]; |
774 | newVert.X = angle.X * xScale; | 606 | newVert.X = angle.X * xScale; |
775 | newVert.Y = angle.Y * yScale; | 607 | newVert.Y = angle.Y * yScale; |
776 | newVert.Z = z; | 608 | newVert.Z = 0.0f; |
777 | this.coords.Add(newVert); | 609 | this.coords.Add(newVert); |
778 | if (this.calcVertexNormals) | 610 | if (hollowsame) |
779 | { | 611 | { |
780 | this.outerCoordIndices.Add(this.coords.Count - 1); | 612 | newVert.X *= hollow; |
781 | 613 | newVert.Y *= hollow; | |
782 | if (sides < 5) | 614 | hollowCoords.Add(newVert); |
783 | { | ||
784 | this.vertexNormals.Add(angles.normals[i]); | ||
785 | float u = angle.angle; | ||
786 | this.us.Add(u); | ||
787 | } | ||
788 | else | ||
789 | { | ||
790 | this.vertexNormals.Add(new Coord(angle.X, angle.Y, 0.0f)); | ||
791 | this.us.Add(angle.angle); | ||
792 | } | ||
793 | } | ||
794 | |||
795 | if (hasHollow) | ||
796 | { | ||
797 | if (hollowSides == sides) | ||
798 | { | ||
799 | newVert.X *= hollow; | ||
800 | newVert.Y *= hollow; | ||
801 | newVert.Z = z; | ||
802 | hollowCoords.Add(newVert); | ||
803 | if (this.calcVertexNormals) | ||
804 | { | ||
805 | if (sides < 5) | ||
806 | { | ||
807 | hollowNormals.Add(angles.normals[i].Invert()); | ||
808 | } | ||
809 | |||
810 | else | ||
811 | hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); | ||
812 | |||
813 | hollowUs.Add(angle.angle * hollow); | ||
814 | } | ||
815 | } | ||
816 | } | ||
817 | else if (!simpleFace && createFaces && angle.angle > 0.0001f) | ||
818 | { | ||
819 | Face newFace = new Face(); | ||
820 | newFace.v1 = 0; | ||
821 | newFace.v2 = index; | ||
822 | newFace.v3 = index + 1; | ||
823 | |||
824 | this.faces.Add(newFace); | ||
825 | } | 615 | } |
826 | index += 1; | ||
827 | } | 616 | } |
828 | 617 | ||
829 | if (hasHollow) | 618 | if (hasHollow) |
830 | { | 619 | { |
831 | hollowCoords.Reverse(); | 620 | hollowCoords.Reverse(); |
832 | if (this.calcVertexNormals) | 621 | this.coords.AddRange(hollowCoords); |
833 | { | ||
834 | hollowNormals.Reverse(); | ||
835 | hollowUs.Reverse(); | ||
836 | } | ||
837 | 622 | ||
838 | if (createFaces) | 623 | if (createFaces) |
839 | { | 624 | { |
@@ -855,187 +640,176 @@ namespace PrimMesher | |||
855 | newFace.v3 = numTotalVerts - coordIndex - 1; | 640 | newFace.v3 = numTotalVerts - coordIndex - 1; |
856 | this.faces.Add(newFace); | 641 | this.faces.Add(newFace); |
857 | } | 642 | } |
643 | if (!hasProfileCut) | ||
644 | { | ||
645 | newFace.v1 = this.numOuterVerts - 1; | ||
646 | newFace.v2 = 0; | ||
647 | newFace.v3 = this.numOuterVerts; | ||
648 | this.faces.Add(newFace); | ||
649 | |||
650 | newFace.v1 = 0; | ||
651 | newFace.v2 = numTotalVerts - 1; | ||
652 | newFace.v3 = this.numOuterVerts; | ||
653 | this.faces.Add(newFace); | ||
654 | } | ||
858 | } | 655 | } |
859 | else | 656 | else if (this.numOuterVerts < this.numHollowVerts) |
860 | { | 657 | { |
861 | if (this.numOuterVerts < this.numHollowVerts) | 658 | Face newFace = new Face(); |
659 | int j = 0; // j is the index for outer vertices | ||
660 | int i; | ||
661 | int maxJ = this.numOuterVerts - 1; | ||
662 | float curHollowAngle = 0; | ||
663 | for (i = 0; i < this.numHollowVerts; i++) // i is the index for inner vertices | ||
862 | { | 664 | { |
863 | Face newFace = new Face(); | 665 | curHollowAngle = hollowAngles.angles[i].angle; |
864 | int j = 0; // j is the index for outer vertices | 666 | if (j < maxJ) |
865 | int maxJ = this.numOuterVerts - 1; | ||
866 | for (int i = 0; i < this.numHollowVerts; i++) // i is the index for inner vertices | ||
867 | { | 667 | { |
868 | if (j < maxJ) | 668 | if (angles.angles[j + 1].angle - curHollowAngle < curHollowAngle - angles.angles[j].angle + 0.000001f) |
869 | if (angles.angles[j + 1].angle - hollowAngles.angles[i].angle < hollowAngles.angles[i].angle - angles.angles[j].angle + 0.000001f) | 669 | { |
870 | { | 670 | newFace.v1 = numTotalVerts - i - 1; |
871 | newFace.v1 = numTotalVerts - i - 1; | 671 | newFace.v2 = j; |
872 | newFace.v2 = j; | 672 | newFace.v3 = j + 1; |
873 | newFace.v3 = j + 1; | 673 | this.faces.Add(newFace); |
674 | j++; | ||
675 | } | ||
676 | } | ||
677 | else | ||
678 | { | ||
679 | if (1.0f - curHollowAngle < curHollowAngle - angles.angles[j].angle + 0.000001f) | ||
680 | break; | ||
681 | } | ||
682 | |||
683 | newFace.v1 = j; | ||
684 | newFace.v2 = numTotalVerts - i - 2; | ||
685 | newFace.v3 = numTotalVerts - i - 1; | ||
874 | 686 | ||
875 | this.faces.Add(newFace); | 687 | this.faces.Add(newFace); |
876 | j += 1; | 688 | } |
877 | } | ||
878 | 689 | ||
879 | newFace.v1 = j; | 690 | if (!hasProfileCut) |
880 | newFace.v2 = numTotalVerts - i - 2; | 691 | { |
881 | newFace.v3 = numTotalVerts - i - 1; | 692 | if (i == this.numHollowVerts) |
693 | { | ||
694 | newFace.v1 = numTotalVerts - this.numHollowVerts; | ||
695 | newFace.v2 = maxJ; | ||
696 | newFace.v3 = 0; | ||
882 | 697 | ||
883 | this.faces.Add(newFace); | 698 | this.faces.Add(newFace); |
884 | } | 699 | } |
885 | } | 700 | else |
886 | else // numHollowVerts < numOuterVerts | ||
887 | { | ||
888 | Face newFace = new Face(); | ||
889 | int j = 0; // j is the index for inner vertices | ||
890 | int maxJ = this.numHollowVerts - 1; | ||
891 | for (int i = 0; i < this.numOuterVerts; i++) | ||
892 | { | 701 | { |
893 | if (j < maxJ) | 702 | if (1.0f - curHollowAngle < curHollowAngle - angles.angles[maxJ].angle + 0.000001f) |
894 | if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f) | 703 | { |
895 | { | 704 | newFace.v1 = numTotalVerts - i - 1; |
896 | newFace.v1 = i; | 705 | newFace.v2 = maxJ; |
897 | newFace.v2 = numTotalVerts - j - 2; | 706 | newFace.v3 = 0; |
898 | newFace.v3 = numTotalVerts - j - 1; | ||
899 | 707 | ||
900 | this.faces.Add(newFace); | 708 | this.faces.Add(newFace); |
901 | j += 1; | 709 | } |
902 | } | ||
903 | 710 | ||
904 | newFace.v1 = numTotalVerts - j - 1; | 711 | for (; i < this.numHollowVerts - 1; i++) |
905 | newFace.v2 = i; | 712 | { |
906 | newFace.v3 = i + 1; | 713 | newFace.v1 = 0; |
714 | newFace.v2 = numTotalVerts - i - 2; | ||
715 | newFace.v3 = numTotalVerts - i - 1; | ||
907 | 716 | ||
908 | this.faces.Add(newFace); | 717 | this.faces.Add(newFace); |
718 | } | ||
909 | } | 719 | } |
720 | |||
721 | newFace.v1 = 0; | ||
722 | newFace.v2 = numTotalVerts - this.numHollowVerts; | ||
723 | newFace.v3 = numTotalVerts - 1; | ||
724 | this.faces.Add(newFace); | ||
910 | } | 725 | } |
911 | } | 726 | } |
912 | } | 727 | else // numHollowVerts < numOuterVerts |
913 | |||
914 | if (calcVertexNormals) | ||
915 | { | ||
916 | foreach (Coord hc in hollowCoords) | ||
917 | { | 728 | { |
918 | this.coords.Add(hc); | 729 | Face newFace = new Face(); |
919 | hollowCoordIndices.Add(this.coords.Count - 1); | 730 | int j = 0; // j is the index for inner vertices |
920 | } | 731 | int maxJ = this.numHollowVerts - 1; |
921 | } | 732 | for (int i = 0; i < this.numOuterVerts; i++) |
922 | else | 733 | { |
923 | this.coords.AddRange(hollowCoords); | 734 | if (j < maxJ) |
735 | if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f) | ||
736 | { | ||
737 | newFace.v1 = i; | ||
738 | newFace.v2 = numTotalVerts - j - 2; | ||
739 | newFace.v3 = numTotalVerts - j - 1; | ||
924 | 740 | ||
925 | if (this.calcVertexNormals) | 741 | this.faces.Add(newFace); |
926 | { | 742 | j += 1; |
927 | this.vertexNormals.AddRange(hollowNormals); | 743 | } |
928 | this.us.AddRange(hollowUs); | ||
929 | 744 | ||
930 | } | 745 | newFace.v1 = numTotalVerts - j - 1; |
931 | } | 746 | newFace.v2 = i; |
747 | newFace.v3 = i + 1; | ||
932 | 748 | ||
933 | if (simpleFace && createFaces) | 749 | this.faces.Add(newFace); |
934 | { | 750 | } |
935 | if (sides == 3) | ||
936 | this.faces.Add(new Face(0, 1, 2)); | ||
937 | else if (sides == 4) | ||
938 | { | ||
939 | this.faces.Add(new Face(0, 1, 2)); | ||
940 | this.faces.Add(new Face(0, 2, 3)); | ||
941 | } | ||
942 | } | ||
943 | 751 | ||
944 | if (calcVertexNormals && hasProfileCut) | 752 | if (!hasProfileCut) |
945 | { | 753 | { |
946 | int lastOuterVertIndex = this.numOuterVerts - 1; | 754 | int i = this.numOuterVerts - 1; |
947 | 755 | ||
948 | if (hasHollow) | 756 | if (hollowAngles.angles[0].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[maxJ].angle + 0.000001f) |
949 | { | 757 | { |
950 | this.cut1CoordIndices.Add(0); | 758 | newFace.v1 = 0; |
951 | this.cut1CoordIndices.Add(this.coords.Count - 1); | 759 | newFace.v2 = numTotalVerts - maxJ - 1; |
760 | newFace.v3 = numTotalVerts - 1; | ||
952 | 761 | ||
953 | this.cut2CoordIndices.Add(lastOuterVertIndex + 1); | 762 | this.faces.Add(newFace); |
954 | this.cut2CoordIndices.Add(lastOuterVertIndex); | 763 | } |
955 | 764 | ||
956 | this.cutNormal1.X = this.coords[0].Y - this.coords[this.coords.Count - 1].Y; | 765 | newFace.v1 = numTotalVerts - maxJ - 1; |
957 | this.cutNormal1.Y = -(this.coords[0].X - this.coords[this.coords.Count - 1].X); | 766 | newFace.v2 = i; |
767 | newFace.v3 = 0; | ||
958 | 768 | ||
959 | this.cutNormal2.X = this.coords[lastOuterVertIndex + 1].Y - this.coords[lastOuterVertIndex].Y; | 769 | this.faces.Add(newFace); |
960 | this.cutNormal2.Y = -(this.coords[lastOuterVertIndex + 1].X - this.coords[lastOuterVertIndex].X); | 770 | } |
771 | } | ||
961 | } | 772 | } |
773 | |||
774 | } | ||
962 | 775 | ||
776 | else if (createFaces) | ||
777 | { | ||
778 | if (simpleFace) | ||
779 | { | ||
780 | if (sides == 3) | ||
781 | this.faces.Add(new Face(0, 1, 2)); | ||
782 | else if (sides == 4) | ||
783 | { | ||
784 | this.faces.Add(new Face(0, 1, 2)); | ||
785 | this.faces.Add(new Face(0, 2, 3)); | ||
786 | } | ||
787 | } | ||
963 | else | 788 | else |
964 | { | 789 | { |
965 | this.cut1CoordIndices.Add(0); | 790 | for (int i = 1; i < numAngles ; i++) |
966 | this.cut1CoordIndices.Add(1); | 791 | { |
967 | 792 | Face newFace = new Face(); | |
968 | this.cut2CoordIndices.Add(lastOuterVertIndex); | 793 | newFace.v1 = 0; |
969 | this.cut2CoordIndices.Add(0); | 794 | newFace.v2 = i; |
970 | 795 | newFace.v3 = i + 1; | |
971 | this.cutNormal1.X = this.vertexNormals[1].Y; | 796 | this.faces.Add(newFace); |
972 | this.cutNormal1.Y = -this.vertexNormals[1].X; | 797 | } |
973 | 798 | if (!hasProfileCut) | |
974 | this.cutNormal2.X = -this.vertexNormals[this.vertexNormals.Count - 2].Y; | 799 | { |
975 | this.cutNormal2.Y = this.vertexNormals[this.vertexNormals.Count - 2].X; | 800 | Face newFace = new Face(); |
976 | 801 | newFace.v1 = 0; | |
802 | newFace.v2 = numAngles; | ||
803 | newFace.v3 = 1; | ||
804 | this.faces.Add(newFace); | ||
805 | } | ||
977 | } | 806 | } |
978 | this.cutNormal1.Normalize(); | ||
979 | this.cutNormal2.Normalize(); | ||
980 | } | 807 | } |
981 | 808 | ||
982 | this.MakeFaceUVs(); | ||
983 | 809 | ||
984 | hollowCoords = null; | 810 | hollowCoords = null; |
985 | hollowNormals = null; | ||
986 | hollowUs = null; | ||
987 | |||
988 | if (calcVertexNormals) | ||
989 | { // calculate prim face numbers | ||
990 | |||
991 | // face number order is top, outer, hollow, bottom, start cut, end cut | ||
992 | // I know it's ugly but so is the whole concept of prim face numbers | ||
993 | |||
994 | int faceNum = 1; // start with outer faces | ||
995 | this.outerFaceNumber = faceNum; | ||
996 | |||
997 | int startVert = hasProfileCut && !hasHollow ? 1 : 0; | ||
998 | if (startVert > 0) | ||
999 | this.faceNumbers.Add(-1); | ||
1000 | for (int i = 0; i < this.numOuterVerts - 1; i++) | ||
1001 | this.faceNumbers.Add(sides < 5 && i <= sides ? faceNum++ : faceNum); | ||
1002 | |||
1003 | this.faceNumbers.Add(hasProfileCut ? -1 : faceNum++); | ||
1004 | |||
1005 | if (sides > 4 && (hasHollow || hasProfileCut)) | ||
1006 | faceNum++; | ||
1007 | |||
1008 | if (sides < 5 && (hasHollow || hasProfileCut) && this.numOuterVerts < sides) | ||
1009 | faceNum++; | ||
1010 | |||
1011 | if (hasHollow) | ||
1012 | { | ||
1013 | for (int i = 0; i < this.numHollowVerts; i++) | ||
1014 | this.faceNumbers.Add(faceNum); | ||
1015 | |||
1016 | this.hollowFaceNumber = faceNum++; | ||
1017 | } | ||
1018 | |||
1019 | this.bottomFaceNumber = faceNum++; | ||
1020 | |||
1021 | if (hasHollow && hasProfileCut) | ||
1022 | this.faceNumbers.Add(faceNum++); | ||
1023 | |||
1024 | for (int i = 0; i < this.faceNumbers.Count; i++) | ||
1025 | if (this.faceNumbers[i] == -1) | ||
1026 | this.faceNumbers[i] = faceNum++; | ||
1027 | |||
1028 | this.numPrimFaces = faceNum; | ||
1029 | } | ||
1030 | |||
1031 | } | 811 | } |
1032 | 812 | ||
1033 | public void MakeFaceUVs() | ||
1034 | { | ||
1035 | this.faceUVs = new List<UVCoord>(); | ||
1036 | foreach (Coord c in this.coords) | ||
1037 | this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y))); | ||
1038 | } | ||
1039 | 813 | ||
1040 | public Profile Copy() | 814 | public Profile Copy() |
1041 | { | 815 | { |
@@ -1047,24 +821,10 @@ namespace PrimMesher | |||
1047 | Profile copy = new Profile(); | 821 | Profile copy = new Profile(); |
1048 | 822 | ||
1049 | copy.coords.AddRange(this.coords); | 823 | copy.coords.AddRange(this.coords); |
1050 | copy.faceUVs.AddRange(this.faceUVs); | ||
1051 | 824 | ||
1052 | if (needFaces) | 825 | if (needFaces) |
1053 | copy.faces.AddRange(this.faces); | 826 | copy.faces.AddRange(this.faces); |
1054 | if ((copy.calcVertexNormals = this.calcVertexNormals) == true) | 827 | |
1055 | { | ||
1056 | copy.vertexNormals.AddRange(this.vertexNormals); | ||
1057 | copy.faceNormal = this.faceNormal; | ||
1058 | copy.cutNormal1 = this.cutNormal1; | ||
1059 | copy.cutNormal2 = this.cutNormal2; | ||
1060 | copy.us.AddRange(this.us); | ||
1061 | copy.faceNumbers.AddRange(this.faceNumbers); | ||
1062 | |||
1063 | copy.cut1CoordIndices = new List<int>(this.cut1CoordIndices); | ||
1064 | copy.cut2CoordIndices = new List<int>(this.cut2CoordIndices); | ||
1065 | copy.hollowCoordIndices = new List<int>(this.hollowCoordIndices); | ||
1066 | copy.outerCoordIndices = new List<int>(this.outerCoordIndices); | ||
1067 | } | ||
1068 | copy.numOuterVerts = this.numOuterVerts; | 828 | copy.numOuterVerts = this.numOuterVerts; |
1069 | copy.numHollowVerts = this.numHollowVerts; | 829 | copy.numHollowVerts = this.numHollowVerts; |
1070 | 830 | ||
@@ -1099,18 +859,6 @@ namespace PrimMesher | |||
1099 | 859 | ||
1100 | for (i = 0; i < numVerts; i++) | 860 | for (i = 0; i < numVerts; i++) |
1101 | this.coords[i] *= q; | 861 | this.coords[i] *= q; |
1102 | |||
1103 | if (this.calcVertexNormals) | ||
1104 | { | ||
1105 | int numNormals = this.vertexNormals.Count; | ||
1106 | for (i = 0; i < numNormals; i++) | ||
1107 | this.vertexNormals[i] *= q; | ||
1108 | |||
1109 | this.faceNormal *= q; | ||
1110 | this.cutNormal1 *= q; | ||
1111 | this.cutNormal2 *= q; | ||
1112 | |||
1113 | } | ||
1114 | } | 862 | } |
1115 | 863 | ||
1116 | public void Scale(float x, float y) | 864 | public void Scale(float x, float y) |
@@ -1146,29 +894,6 @@ namespace PrimMesher | |||
1146 | tmpFace.v1 = tmp; | 894 | tmpFace.v1 = tmp; |
1147 | this.faces[i] = tmpFace; | 895 | this.faces[i] = tmpFace; |
1148 | } | 896 | } |
1149 | |||
1150 | if (this.calcVertexNormals) | ||
1151 | { | ||
1152 | int normalCount = this.vertexNormals.Count; | ||
1153 | if (normalCount > 0) | ||
1154 | { | ||
1155 | Coord n = this.vertexNormals[normalCount - 1]; | ||
1156 | n.Z = -n.Z; | ||
1157 | this.vertexNormals[normalCount - 1] = n; | ||
1158 | } | ||
1159 | } | ||
1160 | |||
1161 | this.faceNormal.X = -this.faceNormal.X; | ||
1162 | this.faceNormal.Y = -this.faceNormal.Y; | ||
1163 | this.faceNormal.Z = -this.faceNormal.Z; | ||
1164 | |||
1165 | int numfaceUVs = this.faceUVs.Count; | ||
1166 | for (i = 0; i < numfaceUVs; i++) | ||
1167 | { | ||
1168 | UVCoord uv = this.faceUVs[i]; | ||
1169 | uv.V = 1.0f - uv.V; | ||
1170 | this.faceUVs[i] = uv; | ||
1171 | } | ||
1172 | } | 897 | } |
1173 | 898 | ||
1174 | public void AddValue2FaceVertexIndices(int num) | 899 | public void AddValue2FaceVertexIndices(int num) |
@@ -1186,25 +911,7 @@ namespace PrimMesher | |||
1186 | } | 911 | } |
1187 | } | 912 | } |
1188 | 913 | ||
1189 | public void AddValue2FaceNormalIndices(int num) | 914 | public void DumpRaw(String path, String name, String title) |
1190 | { | ||
1191 | if (this.calcVertexNormals) | ||
1192 | { | ||
1193 | int numFaces = this.faces.Count; | ||
1194 | Face tmpFace; | ||
1195 | for (int i = 0; i < numFaces; i++) | ||
1196 | { | ||
1197 | tmpFace = this.faces[i]; | ||
1198 | tmpFace.n1 += num; | ||
1199 | tmpFace.n2 += num; | ||
1200 | tmpFace.n3 += num; | ||
1201 | |||
1202 | this.faces[i] = tmpFace; | ||
1203 | } | ||
1204 | } | ||
1205 | } | ||
1206 | |||
1207 | public void DumpRaw(String path, String name, String title) | ||
1208 | { | 915 | { |
1209 | if (path == null) | 916 | if (path == null) |
1210 | return; | 917 | return; |
@@ -1451,11 +1158,9 @@ namespace PrimMesher | |||
1451 | private const float twoPi = 2.0f * (float)Math.PI; | 1158 | private const float twoPi = 2.0f * (float)Math.PI; |
1452 | 1159 | ||
1453 | public List<Coord> coords; | 1160 | public List<Coord> coords; |
1454 | public List<Coord> normals; | 1161 | // public List<Coord> normals; |
1455 | public List<Face> faces; | 1162 | public List<Face> faces; |
1456 | 1163 | ||
1457 | public List<ViewerFace> viewerFaces; | ||
1458 | |||
1459 | private int sides = 4; | 1164 | private int sides = 4; |
1460 | private int hollowSides = 4; | 1165 | private int hollowSides = 4; |
1461 | private float profileStart = 0.0f; | 1166 | private float profileStart = 0.0f; |
@@ -1478,15 +1183,8 @@ namespace PrimMesher | |||
1478 | public float revolutions = 1.0f; | 1183 | public float revolutions = 1.0f; |
1479 | public int stepsPerRevolution = 24; | 1184 | public int stepsPerRevolution = 24; |
1480 | 1185 | ||
1481 | private int profileOuterFaceNumber = -1; | ||
1482 | private int profileHollowFaceNumber = -1; | ||
1483 | |||
1484 | private bool hasProfileCut = false; | 1186 | private bool hasProfileCut = false; |
1485 | private bool hasHollow = false; | 1187 | private bool hasHollow = false; |
1486 | public bool calcVertexNormals = false; | ||
1487 | private bool normalsProcessed = false; | ||
1488 | public bool viewerMode = false; | ||
1489 | public bool sphereMode = false; | ||
1490 | 1188 | ||
1491 | public int numPrimFaces = 0; | 1189 | public int numPrimFaces = 0; |
1492 | 1190 | ||
@@ -1518,27 +1216,16 @@ namespace PrimMesher | |||
1518 | s += "\nradius...............: " + this.radius.ToString(); | 1216 | s += "\nradius...............: " + this.radius.ToString(); |
1519 | s += "\nrevolutions..........: " + this.revolutions.ToString(); | 1217 | s += "\nrevolutions..........: " + this.revolutions.ToString(); |
1520 | s += "\nstepsPerRevolution...: " + this.stepsPerRevolution.ToString(); | 1218 | s += "\nstepsPerRevolution...: " + this.stepsPerRevolution.ToString(); |
1521 | s += "\nsphereMode...........: " + this.sphereMode.ToString(); | ||
1522 | s += "\nhasProfileCut........: " + this.hasProfileCut.ToString(); | 1219 | s += "\nhasProfileCut........: " + this.hasProfileCut.ToString(); |
1523 | s += "\nhasHollow............: " + this.hasHollow.ToString(); | 1220 | s += "\nhasHollow............: " + this.hasHollow.ToString(); |
1524 | s += "\nviewerMode...........: " + this.viewerMode.ToString(); | ||
1525 | 1221 | ||
1526 | return s; | 1222 | return s; |
1527 | } | 1223 | } |
1528 | 1224 | ||
1529 | public int ProfileOuterFaceNumber | ||
1530 | { | ||
1531 | get { return profileOuterFaceNumber; } | ||
1532 | } | ||
1533 | |||
1534 | public int ProfileHollowFaceNumber | ||
1535 | { | ||
1536 | get { return profileHollowFaceNumber; } | ||
1537 | } | ||
1538 | |||
1539 | public bool HasProfileCut | 1225 | public bool HasProfileCut |
1540 | { | 1226 | { |
1541 | get { return hasProfileCut; } | 1227 | get { return hasProfileCut; } |
1228 | set { hasProfileCut = value; } | ||
1542 | } | 1229 | } |
1543 | 1230 | ||
1544 | public bool HasHollow | 1231 | public bool HasHollow |
@@ -1555,6 +1242,7 @@ namespace PrimMesher | |||
1555 | /// <param name="profileEnd"></param> | 1242 | /// <param name="profileEnd"></param> |
1556 | /// <param name="hollow"></param> | 1243 | /// <param name="hollow"></param> |
1557 | /// <param name="hollowSides"></param> | 1244 | /// <param name="hollowSides"></param> |
1245 | /// <param name="sphereMode"></param> | ||
1558 | public PrimMesh(int sides, float profileStart, float profileEnd, float hollow, int hollowSides) | 1246 | public PrimMesh(int sides, float profileStart, float profileEnd, float hollow, int hollowSides) |
1559 | { | 1247 | { |
1560 | this.coords = new List<Coord>(); | 1248 | this.coords = new List<Coord>(); |
@@ -1594,32 +1282,12 @@ namespace PrimMesher | |||
1594 | this.coords = new List<Coord>(); | 1282 | this.coords = new List<Coord>(); |
1595 | this.faces = new List<Face>(); | 1283 | this.faces = new List<Face>(); |
1596 | 1284 | ||
1597 | if (this.viewerMode) | ||
1598 | { | ||
1599 | this.viewerFaces = new List<ViewerFace>(); | ||
1600 | this.calcVertexNormals = true; | ||
1601 | } | ||
1602 | |||
1603 | if (this.calcVertexNormals) | ||
1604 | this.normals = new List<Coord>(); | ||
1605 | |||
1606 | int steps = 1; | 1285 | int steps = 1; |
1607 | 1286 | ||
1608 | float length = this.pathCutEnd - this.pathCutBegin; | 1287 | float length = this.pathCutEnd - this.pathCutBegin; |
1609 | normalsProcessed = false; | ||
1610 | 1288 | ||
1611 | if (this.viewerMode && this.sides == 3) | 1289 | this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f; |
1612 | { | ||
1613 | // prisms don't taper well so add some vertical resolution | ||
1614 | // other prims may benefit from this but just do prisms for now | ||
1615 | if (Math.Abs(this.taperX) > 0.01 || Math.Abs(this.taperY) > 0.01) | ||
1616 | steps = (int)(steps * 4.5 * length); | ||
1617 | } | ||
1618 | 1290 | ||
1619 | if (this.sphereMode) | ||
1620 | this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f; | ||
1621 | else | ||
1622 | this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f; | ||
1623 | this.hasHollow = (this.hollow > 0.001f); | 1291 | this.hasHollow = (this.hollow > 0.001f); |
1624 | 1292 | ||
1625 | float twistBegin = this.twistBegin / 360.0f * twoPi; | 1293 | float twistBegin = this.twistBegin / 360.0f * twoPi; |
@@ -1701,47 +1369,16 @@ namespace PrimMesher | |||
1701 | hollow *= 1.414f; | 1369 | hollow *= 1.414f; |
1702 | } | 1370 | } |
1703 | 1371 | ||
1704 | Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals); | 1372 | Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, this.hasProfileCut,true); |
1705 | this.errorMessage = profile.errorMessage; | 1373 | this.errorMessage = profile.errorMessage; |
1706 | 1374 | ||
1707 | this.numPrimFaces = profile.numPrimFaces; | 1375 | this.numPrimFaces = profile.numPrimFaces; |
1708 | 1376 | ||
1709 | int cut1FaceNumber = profile.bottomFaceNumber + 1; | ||
1710 | int cut2FaceNumber = cut1FaceNumber + 1; | ||
1711 | if (!needEndFaces) | ||
1712 | { | ||
1713 | cut1FaceNumber -= 2; | ||
1714 | cut2FaceNumber -= 2; | ||
1715 | } | ||
1716 | |||
1717 | profileOuterFaceNumber = profile.outerFaceNumber; | ||
1718 | if (!needEndFaces) | ||
1719 | profileOuterFaceNumber--; | ||
1720 | |||
1721 | if (hasHollow) | ||
1722 | { | ||
1723 | profileHollowFaceNumber = profile.hollowFaceNumber; | ||
1724 | if (!needEndFaces) | ||
1725 | profileHollowFaceNumber--; | ||
1726 | } | ||
1727 | |||
1728 | int cut1Vert = -1; | ||
1729 | int cut2Vert = -1; | ||
1730 | if (hasProfileCut) | ||
1731 | { | ||
1732 | cut1Vert = hasHollow ? profile.coords.Count - 1 : 0; | ||
1733 | cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts; | ||
1734 | } | ||
1735 | |||
1736 | if (initialProfileRot != 0.0f) | 1377 | if (initialProfileRot != 0.0f) |
1737 | { | 1378 | { |
1738 | profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); | 1379 | profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); |
1739 | if (viewerMode) | ||
1740 | profile.MakeFaceUVs(); | ||
1741 | } | 1380 | } |
1742 | 1381 | ||
1743 | Coord lastCutNormal1 = new Coord(); | ||
1744 | Coord lastCutNormal2 = new Coord(); | ||
1745 | float thisV = 0.0f; | 1382 | float thisV = 0.0f; |
1746 | float lastV = 0.0f; | 1383 | float lastV = 0.0f; |
1747 | 1384 | ||
@@ -1764,57 +1401,21 @@ namespace PrimMesher | |||
1764 | path.stepsPerRevolution = stepsPerRevolution; | 1401 | path.stepsPerRevolution = stepsPerRevolution; |
1765 | 1402 | ||
1766 | path.Create(pathType, steps); | 1403 | path.Create(pathType, steps); |
1404 | |||
1405 | int lastNode = path.pathNodes.Count -1; | ||
1767 | 1406 | ||
1768 | for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) | 1407 | for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) |
1769 | { | 1408 | { |
1770 | PathNode node = path.pathNodes[nodeIndex]; | 1409 | PathNode node = path.pathNodes[nodeIndex]; |
1771 | Profile newLayer = profile.Copy(); | 1410 | Profile newLayer = profile.Copy(); |
1772 | newLayer.Scale(node.xScale, node.yScale); | ||
1773 | 1411 | ||
1412 | newLayer.Scale(node.xScale, node.yScale); | ||
1774 | newLayer.AddRot(node.rotation); | 1413 | newLayer.AddRot(node.rotation); |
1775 | newLayer.AddPos(node.position); | 1414 | newLayer.AddPos(node.position); |
1776 | 1415 | ||
1777 | if (needEndFaces && nodeIndex == 0) | 1416 | if (needEndFaces && nodeIndex == 0) |
1778 | { | 1417 | { |
1779 | newLayer.FlipNormals(); | 1418 | newLayer.FlipNormals(); |
1780 | |||
1781 | // add the bottom faces to the viewerFaces list | ||
1782 | if (this.viewerMode) | ||
1783 | { | ||
1784 | Coord faceNormal = newLayer.faceNormal; | ||
1785 | ViewerFace newViewerFace = new ViewerFace(profile.bottomFaceNumber); | ||
1786 | int numFaces = newLayer.faces.Count; | ||
1787 | List<Face> faces = newLayer.faces; | ||
1788 | |||
1789 | for (int i = 0; i < numFaces; i++) | ||
1790 | { | ||
1791 | Face face = faces[i]; | ||
1792 | newViewerFace.v1 = newLayer.coords[face.v1]; | ||
1793 | newViewerFace.v2 = newLayer.coords[face.v2]; | ||
1794 | newViewerFace.v3 = newLayer.coords[face.v3]; | ||
1795 | |||
1796 | newViewerFace.coordIndex1 = face.v1; | ||
1797 | newViewerFace.coordIndex2 = face.v2; | ||
1798 | newViewerFace.coordIndex3 = face.v3; | ||
1799 | |||
1800 | newViewerFace.n1 = faceNormal; | ||
1801 | newViewerFace.n2 = faceNormal; | ||
1802 | newViewerFace.n3 = faceNormal; | ||
1803 | |||
1804 | newViewerFace.uv1 = newLayer.faceUVs[face.v1]; | ||
1805 | newViewerFace.uv2 = newLayer.faceUVs[face.v2]; | ||
1806 | newViewerFace.uv3 = newLayer.faceUVs[face.v3]; | ||
1807 | |||
1808 | if (pathType == PathType.Linear) | ||
1809 | { | ||
1810 | newViewerFace.uv1.Flip(); | ||
1811 | newViewerFace.uv2.Flip(); | ||
1812 | newViewerFace.uv3.Flip(); | ||
1813 | } | ||
1814 | |||
1815 | this.viewerFaces.Add(newViewerFace); | ||
1816 | } | ||
1817 | } | ||
1818 | } // if (nodeIndex == 0) | 1419 | } // if (nodeIndex == 0) |
1819 | 1420 | ||
1820 | // append this layer | 1421 | // append this layer |
@@ -1824,15 +1425,17 @@ namespace PrimMesher | |||
1824 | 1425 | ||
1825 | this.coords.AddRange(newLayer.coords); | 1426 | this.coords.AddRange(newLayer.coords); |
1826 | 1427 | ||
1827 | if (this.calcVertexNormals) | 1428 | if (needEndFaces) |
1828 | { | 1429 | { |
1829 | newLayer.AddValue2FaceNormalIndices(this.normals.Count); | 1430 | if (nodeIndex == 0) |
1830 | this.normals.AddRange(newLayer.vertexNormals); | 1431 | this.faces.AddRange(newLayer.faces); |
1432 | else if (nodeIndex == lastNode) | ||
1433 | { | ||
1434 | if (node.xScale > 1e-6 && node.yScale > 1e-6) | ||
1435 | this.faces.AddRange(newLayer.faces); | ||
1436 | } | ||
1831 | } | 1437 | } |
1832 | 1438 | ||
1833 | if (node.percentOfPath < this.pathCutBegin + 0.01f || node.percentOfPath > this.pathCutEnd - 0.01f) | ||
1834 | this.faces.AddRange(newLayer.faces); | ||
1835 | |||
1836 | // fill faces between layers | 1439 | // fill faces between layers |
1837 | 1440 | ||
1838 | int numVerts = newLayer.coords.Count; | 1441 | int numVerts = newLayer.coords.Count; |
@@ -1843,219 +1446,88 @@ namespace PrimMesher | |||
1843 | 1446 | ||
1844 | if (nodeIndex > 0) | 1447 | if (nodeIndex > 0) |
1845 | { | 1448 | { |
1846 | int startVert = coordsLen + 1; | 1449 | int startVert = coordsLen; |
1847 | int endVert = this.coords.Count; | 1450 | int endVert = this.coords.Count; |
1848 | 1451 | if (!this.hasProfileCut) | |
1849 | if (sides < 5 || this.hasProfileCut || this.hasHollow) | ||
1850 | startVert--; | ||
1851 | |||
1852 | for (int i = startVert; i < endVert; i++) | ||
1853 | { | 1452 | { |
1854 | int iNext = i + 1; | 1453 | int i = startVert; |
1855 | if (i == endVert - 1) | 1454 | for (int l = 0; l < profile.numOuterVerts - 1; l++) |
1856 | iNext = startVert; | 1455 | { |
1857 | 1456 | newFace1.v1 = i; | |
1858 | int whichVert = i - startVert; | 1457 | newFace1.v2 = i - numVerts; |
1458 | newFace1.v3 = i + 1; | ||
1459 | this.faces.Add(newFace1); | ||
1460 | |||
1461 | newFace2.v1 = i + 1; | ||
1462 | newFace2.v2 = i - numVerts; | ||
1463 | newFace2.v3 = i + 1 - numVerts; | ||
1464 | this.faces.Add(newFace2); | ||
1465 | i++; | ||
1466 | } | ||
1859 | 1467 | ||
1860 | newFace1.v1 = i; | 1468 | newFace1.v1 = i; |
1861 | newFace1.v2 = i - numVerts; | 1469 | newFace1.v2 = i - numVerts; |
1862 | newFace1.v3 = iNext; | 1470 | newFace1.v3 = startVert; |
1863 | |||
1864 | newFace1.n1 = newFace1.v1; | ||
1865 | newFace1.n2 = newFace1.v2; | ||
1866 | newFace1.n3 = newFace1.v3; | ||
1867 | this.faces.Add(newFace1); | 1471 | this.faces.Add(newFace1); |
1868 | 1472 | ||
1869 | newFace2.v1 = iNext; | 1473 | newFace2.v1 = startVert; |
1870 | newFace2.v2 = i - numVerts; | 1474 | newFace2.v2 = i - numVerts; |
1871 | newFace2.v3 = iNext - numVerts; | 1475 | newFace2.v3 = startVert - numVerts; |
1872 | |||
1873 | newFace2.n1 = newFace2.v1; | ||
1874 | newFace2.n2 = newFace2.v2; | ||
1875 | newFace2.n3 = newFace2.v3; | ||
1876 | this.faces.Add(newFace2); | 1476 | this.faces.Add(newFace2); |
1877 | 1477 | ||
1878 | if (this.viewerMode) | 1478 | if (this.hasHollow) |
1879 | { | 1479 | { |
1880 | // add the side faces to the list of viewerFaces here | 1480 | startVert = ++i; |
1881 | 1481 | for (int l = 0; l < profile.numHollowVerts - 1; l++) | |
1882 | int primFaceNum = profile.faceNumbers[whichVert]; | ||
1883 | if (!needEndFaces) | ||
1884 | primFaceNum -= 1; | ||
1885 | |||
1886 | ViewerFace newViewerFace1 = new ViewerFace(primFaceNum); | ||
1887 | ViewerFace newViewerFace2 = new ViewerFace(primFaceNum); | ||
1888 | |||
1889 | int uIndex = whichVert; | ||
1890 | if (!hasHollow && sides > 4 && uIndex < newLayer.us.Count - 1) | ||
1891 | { | ||
1892 | uIndex++; | ||
1893 | } | ||
1894 | |||
1895 | float u1 = newLayer.us[uIndex]; | ||
1896 | float u2 = 1.0f; | ||
1897 | if (uIndex < (int)newLayer.us.Count - 1) | ||
1898 | u2 = newLayer.us[uIndex + 1]; | ||
1899 | |||
1900 | if (whichVert == cut1Vert || whichVert == cut2Vert) | ||
1901 | { | ||
1902 | u1 = 0.0f; | ||
1903 | u2 = 1.0f; | ||
1904 | } | ||
1905 | else if (sides < 5) | ||
1906 | { | ||
1907 | if (whichVert < profile.numOuterVerts) | ||
1908 | { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled | ||
1909 | // to reflect the entire texture width | ||
1910 | u1 *= sides; | ||
1911 | u2 *= sides; | ||
1912 | u2 -= (int)u1; | ||
1913 | u1 -= (int)u1; | ||
1914 | if (u2 < 0.1f) | ||
1915 | u2 = 1.0f; | ||
1916 | } | ||
1917 | } | ||
1918 | |||
1919 | if (this.sphereMode) | ||
1920 | { | 1482 | { |
1921 | if (whichVert != cut1Vert && whichVert != cut2Vert) | 1483 | newFace1.v1 = i; |
1922 | { | 1484 | newFace1.v2 = i - numVerts; |
1923 | u1 = u1 * 2.0f - 1.0f; | 1485 | newFace1.v3 = i + 1; |
1924 | u2 = u2 * 2.0f - 1.0f; | 1486 | this.faces.Add(newFace1); |
1925 | 1487 | ||
1926 | if (whichVert >= newLayer.numOuterVerts) | 1488 | newFace2.v1 = i + 1; |
1927 | { | 1489 | newFace2.v2 = i - numVerts; |
1928 | u1 -= hollow; | 1490 | newFace2.v3 = i + 1 - numVerts; |
1929 | u2 -= hollow; | 1491 | this.faces.Add(newFace2); |
1930 | } | 1492 | i++; |
1931 | |||
1932 | } | ||
1933 | } | ||
1934 | |||
1935 | newViewerFace1.uv1.U = u1; | ||
1936 | newViewerFace1.uv2.U = u1; | ||
1937 | newViewerFace1.uv3.U = u2; | ||
1938 | |||
1939 | newViewerFace1.uv1.V = thisV; | ||
1940 | newViewerFace1.uv2.V = lastV; | ||
1941 | newViewerFace1.uv3.V = thisV; | ||
1942 | |||
1943 | newViewerFace2.uv1.U = u2; | ||
1944 | newViewerFace2.uv2.U = u1; | ||
1945 | newViewerFace2.uv3.U = u2; | ||
1946 | |||
1947 | newViewerFace2.uv1.V = thisV; | ||
1948 | newViewerFace2.uv2.V = lastV; | ||
1949 | newViewerFace2.uv3.V = lastV; | ||
1950 | |||
1951 | newViewerFace1.v1 = this.coords[newFace1.v1]; | ||
1952 | newViewerFace1.v2 = this.coords[newFace1.v2]; | ||
1953 | newViewerFace1.v3 = this.coords[newFace1.v3]; | ||
1954 | |||
1955 | newViewerFace2.v1 = this.coords[newFace2.v1]; | ||
1956 | newViewerFace2.v2 = this.coords[newFace2.v2]; | ||
1957 | newViewerFace2.v3 = this.coords[newFace2.v3]; | ||
1958 | |||
1959 | newViewerFace1.coordIndex1 = newFace1.v1; | ||
1960 | newViewerFace1.coordIndex2 = newFace1.v2; | ||
1961 | newViewerFace1.coordIndex3 = newFace1.v3; | ||
1962 | |||
1963 | newViewerFace2.coordIndex1 = newFace2.v1; | ||
1964 | newViewerFace2.coordIndex2 = newFace2.v2; | ||
1965 | newViewerFace2.coordIndex3 = newFace2.v3; | ||
1966 | |||
1967 | // profile cut faces | ||
1968 | if (whichVert == cut1Vert) | ||
1969 | { | ||
1970 | newViewerFace1.primFaceNumber = cut1FaceNumber; | ||
1971 | newViewerFace2.primFaceNumber = cut1FaceNumber; | ||
1972 | newViewerFace1.n1 = newLayer.cutNormal1; | ||
1973 | newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1; | ||
1974 | |||
1975 | newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1; | ||
1976 | newViewerFace2.n2 = lastCutNormal1; | ||
1977 | } | ||
1978 | else if (whichVert == cut2Vert) | ||
1979 | { | ||
1980 | newViewerFace1.primFaceNumber = cut2FaceNumber; | ||
1981 | newViewerFace2.primFaceNumber = cut2FaceNumber; | ||
1982 | newViewerFace1.n1 = newLayer.cutNormal2; | ||
1983 | newViewerFace1.n2 = lastCutNormal2; | ||
1984 | newViewerFace1.n3 = lastCutNormal2; | ||
1985 | |||
1986 | newViewerFace2.n1 = newLayer.cutNormal2; | ||
1987 | newViewerFace2.n3 = newLayer.cutNormal2; | ||
1988 | newViewerFace2.n2 = lastCutNormal2; | ||
1989 | } | ||
1990 | |||
1991 | else // outer and hollow faces | ||
1992 | { | ||
1993 | if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)) | ||
1994 | { // looks terrible when path is twisted... need vertex normals here | ||
1995 | newViewerFace1.CalcSurfaceNormal(); | ||
1996 | newViewerFace2.CalcSurfaceNormal(); | ||
1997 | } | ||
1998 | else | ||
1999 | { | ||
2000 | newViewerFace1.n1 = this.normals[newFace1.n1]; | ||
2001 | newViewerFace1.n2 = this.normals[newFace1.n2]; | ||
2002 | newViewerFace1.n3 = this.normals[newFace1.n3]; | ||
2003 | |||
2004 | newViewerFace2.n1 = this.normals[newFace2.n1]; | ||
2005 | newViewerFace2.n2 = this.normals[newFace2.n2]; | ||
2006 | newViewerFace2.n3 = this.normals[newFace2.n3]; | ||
2007 | } | ||
2008 | } | 1493 | } |
2009 | 1494 | ||
2010 | this.viewerFaces.Add(newViewerFace1); | 1495 | newFace1.v1 = i; |
2011 | this.viewerFaces.Add(newViewerFace2); | 1496 | newFace1.v2 = i - numVerts; |
1497 | newFace1.v3 = startVert; | ||
1498 | this.faces.Add(newFace1); | ||
2012 | 1499 | ||
1500 | newFace2.v1 = startVert; | ||
1501 | newFace2.v2 = i - numVerts; | ||
1502 | newFace2.v3 = startVert - numVerts; | ||
1503 | this.faces.Add(newFace2); | ||
2013 | } | 1504 | } |
2014 | } | ||
2015 | } | ||
2016 | 1505 | ||
2017 | lastCutNormal1 = newLayer.cutNormal1; | ||
2018 | lastCutNormal2 = newLayer.cutNormal2; | ||
2019 | lastV = thisV; | ||
2020 | 1506 | ||
2021 | if (needEndFaces && nodeIndex == path.pathNodes.Count - 1 && viewerMode) | 1507 | } |
2022 | { | 1508 | else |
2023 | // add the top faces to the viewerFaces list here | ||
2024 | Coord faceNormal = newLayer.faceNormal; | ||
2025 | ViewerFace newViewerFace = new ViewerFace(0); | ||
2026 | int numFaces = newLayer.faces.Count; | ||
2027 | List<Face> faces = newLayer.faces; | ||
2028 | |||
2029 | for (int i = 0; i < numFaces; i++) | ||
2030 | { | 1509 | { |
2031 | Face face = faces[i]; | 1510 | for (int i = startVert; i < endVert; i++) |
2032 | newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen]; | 1511 | { |
2033 | newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen]; | 1512 | int iNext = i + 1; |
2034 | newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen]; | 1513 | if (i == endVert - 1) |
2035 | 1514 | iNext = startVert; | |
2036 | newViewerFace.coordIndex1 = face.v1 - coordsLen; | ||
2037 | newViewerFace.coordIndex2 = face.v2 - coordsLen; | ||
2038 | newViewerFace.coordIndex3 = face.v3 - coordsLen; | ||
2039 | 1515 | ||
2040 | newViewerFace.n1 = faceNormal; | 1516 | newFace1.v1 = i; |
2041 | newViewerFace.n2 = faceNormal; | 1517 | newFace1.v2 = i - numVerts; |
2042 | newViewerFace.n3 = faceNormal; | 1518 | newFace1.v3 = iNext; |
1519 | this.faces.Add(newFace1); | ||
2043 | 1520 | ||
2044 | newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen]; | 1521 | newFace2.v1 = iNext; |
2045 | newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen]; | 1522 | newFace2.v2 = i - numVerts; |
2046 | newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen]; | 1523 | newFace2.v3 = iNext - numVerts; |
1524 | this.faces.Add(newFace2); | ||
2047 | 1525 | ||
2048 | if (pathType == PathType.Linear) | ||
2049 | { | ||
2050 | newViewerFace.uv1.Flip(); | ||
2051 | newViewerFace.uv2.Flip(); | ||
2052 | newViewerFace.uv3.Flip(); | ||
2053 | } | 1526 | } |
2054 | |||
2055 | this.viewerFaces.Add(newViewerFace); | ||
2056 | } | 1527 | } |
2057 | } | 1528 | } |
2058 | 1529 | ||
1530 | lastV = thisV; | ||
2059 | 1531 | ||
2060 | } // for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) | 1532 | } // for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) |
2061 | 1533 | ||
@@ -2138,51 +1610,17 @@ namespace PrimMesher | |||
2138 | copy.radius = this.radius; | 1610 | copy.radius = this.radius; |
2139 | copy.revolutions = this.revolutions; | 1611 | copy.revolutions = this.revolutions; |
2140 | copy.stepsPerRevolution = this.stepsPerRevolution; | 1612 | copy.stepsPerRevolution = this.stepsPerRevolution; |
2141 | copy.calcVertexNormals = this.calcVertexNormals; | 1613 | |
2142 | copy.normalsProcessed = this.normalsProcessed; | ||
2143 | copy.viewerMode = this.viewerMode; | ||
2144 | copy.numPrimFaces = this.numPrimFaces; | 1614 | copy.numPrimFaces = this.numPrimFaces; |
2145 | copy.errorMessage = this.errorMessage; | 1615 | copy.errorMessage = this.errorMessage; |
2146 | 1616 | ||
2147 | copy.coords = new List<Coord>(this.coords); | 1617 | copy.coords = new List<Coord>(this.coords); |
2148 | copy.faces = new List<Face>(this.faces); | 1618 | copy.faces = new List<Face>(this.faces); |
2149 | copy.viewerFaces = new List<ViewerFace>(this.viewerFaces); | ||
2150 | copy.normals = new List<Coord>(this.normals); | ||
2151 | 1619 | ||
2152 | return copy; | 1620 | return copy; |
2153 | } | 1621 | } |
2154 | 1622 | ||
2155 | /// <summary> | 1623 | /// <summary> |
2156 | /// Calculate surface normals for all of the faces in the list of faces in this mesh | ||
2157 | /// </summary> | ||
2158 | public void CalcNormals() | ||
2159 | { | ||
2160 | if (normalsProcessed) | ||
2161 | return; | ||
2162 | |||
2163 | normalsProcessed = true; | ||
2164 | |||
2165 | int numFaces = faces.Count; | ||
2166 | |||
2167 | if (!this.calcVertexNormals) | ||
2168 | this.normals = new List<Coord>(); | ||
2169 | |||
2170 | for (int i = 0; i < numFaces; i++) | ||
2171 | { | ||
2172 | Face face = faces[i]; | ||
2173 | |||
2174 | this.normals.Add(SurfaceNormal(i).Normalize()); | ||
2175 | |||
2176 | int normIndex = normals.Count - 1; | ||
2177 | face.n1 = normIndex; | ||
2178 | face.n2 = normIndex; | ||
2179 | face.n3 = normIndex; | ||
2180 | |||
2181 | this.faces[i] = face; | ||
2182 | } | ||
2183 | } | ||
2184 | |||
2185 | /// <summary> | ||
2186 | /// Adds a value to each XYZ vertex coordinate in the mesh | 1624 | /// Adds a value to each XYZ vertex coordinate in the mesh |
2187 | /// </summary> | 1625 | /// </summary> |
2188 | /// <param name="x"></param> | 1626 | /// <param name="x"></param> |
@@ -2202,18 +1640,6 @@ namespace PrimMesher | |||
2202 | vert.Z += z; | 1640 | vert.Z += z; |
2203 | this.coords[i] = vert; | 1641 | this.coords[i] = vert; |
2204 | } | 1642 | } |
2205 | |||
2206 | if (this.viewerFaces != null) | ||
2207 | { | ||
2208 | int numViewerFaces = this.viewerFaces.Count; | ||
2209 | |||
2210 | for (i = 0; i < numViewerFaces; i++) | ||
2211 | { | ||
2212 | ViewerFace v = this.viewerFaces[i]; | ||
2213 | v.AddPos(x, y, z); | ||
2214 | this.viewerFaces[i] = v; | ||
2215 | } | ||
2216 | } | ||
2217 | } | 1643 | } |
2218 | 1644 | ||
2219 | /// <summary> | 1645 | /// <summary> |
@@ -2227,38 +1653,11 @@ namespace PrimMesher | |||
2227 | 1653 | ||
2228 | for (i = 0; i < numVerts; i++) | 1654 | for (i = 0; i < numVerts; i++) |
2229 | this.coords[i] *= q; | 1655 | this.coords[i] *= q; |
2230 | |||
2231 | if (this.normals != null) | ||
2232 | { | ||
2233 | int numNormals = this.normals.Count; | ||
2234 | for (i = 0; i < numNormals; i++) | ||
2235 | this.normals[i] *= q; | ||
2236 | } | ||
2237 | |||
2238 | if (this.viewerFaces != null) | ||
2239 | { | ||
2240 | int numViewerFaces = this.viewerFaces.Count; | ||
2241 | |||
2242 | for (i = 0; i < numViewerFaces; i++) | ||
2243 | { | ||
2244 | ViewerFace v = this.viewerFaces[i]; | ||
2245 | v.v1 *= q; | ||
2246 | v.v2 *= q; | ||
2247 | v.v3 *= q; | ||
2248 | |||
2249 | v.n1 *= q; | ||
2250 | v.n2 *= q; | ||
2251 | v.n3 *= q; | ||
2252 | this.viewerFaces[i] = v; | ||
2253 | } | ||
2254 | } | ||
2255 | } | 1656 | } |
2256 | 1657 | ||
2257 | #if VERTEX_INDEXER | 1658 | #if VERTEX_INDEXER |
2258 | public VertexIndexer GetVertexIndexer() | 1659 | public VertexIndexer GetVertexIndexer() |
2259 | { | 1660 | { |
2260 | if (this.viewerMode && this.viewerFaces.Count > 0) | ||
2261 | return new VertexIndexer(this); | ||
2262 | return null; | 1661 | return null; |
2263 | } | 1662 | } |
2264 | #endif | 1663 | #endif |
@@ -2278,21 +1677,6 @@ namespace PrimMesher | |||
2278 | Coord m = new Coord(x, y, z); | 1677 | Coord m = new Coord(x, y, z); |
2279 | for (i = 0; i < numVerts; i++) | 1678 | for (i = 0; i < numVerts; i++) |
2280 | this.coords[i] *= m; | 1679 | this.coords[i] *= m; |
2281 | |||
2282 | if (this.viewerFaces != null) | ||
2283 | { | ||
2284 | int numViewerFaces = this.viewerFaces.Count; | ||
2285 | for (i = 0; i < numViewerFaces; i++) | ||
2286 | { | ||
2287 | ViewerFace v = this.viewerFaces[i]; | ||
2288 | v.v1 *= m; | ||
2289 | v.v2 *= m; | ||
2290 | v.v3 *= m; | ||
2291 | this.viewerFaces[i] = v; | ||
2292 | } | ||
2293 | |||
2294 | } | ||
2295 | |||
2296 | } | 1680 | } |
2297 | 1681 | ||
2298 | /// <summary> | 1682 | /// <summary> |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs index 0df71eb..5030cec 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs | |||
@@ -448,7 +448,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
448 | else | 448 | else |
449 | { | 449 | { |
450 | repData.meshState = MeshState.needMesh; | 450 | repData.meshState = MeshState.needMesh; |
451 | mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, false, convex, true); | 451 | mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex, true); |
452 | if (mesh == null) | 452 | if (mesh == null) |
453 | { | 453 | { |
454 | repData.meshState = MeshState.MeshFailed; | 454 | repData.meshState = MeshState.MeshFailed; |
@@ -513,7 +513,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
513 | clod = (int)LevelOfDetail.Low; | 513 | clod = (int)LevelOfDetail.Low; |
514 | } | 514 | } |
515 | 515 | ||
516 | mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, false, convex, true); | 516 | mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex, true); |
517 | 517 | ||
518 | if (mesh == null) | 518 | if (mesh == null) |
519 | { | 519 | { |
@@ -929,4 +929,4 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
929 | repData.actor.Name); | 929 | repData.actor.Name); |
930 | } | 930 | } |
931 | } | 931 | } |
932 | } | 932 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index faa9488..7cabddd 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | |||
@@ -25,7 +25,7 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | /* Revision 2011/12 by Ubit Umarov | 28 | /* Revision 2011/12/13 by Ubit Umarov |
29 | * | 29 | * |
30 | * | 30 | * |
31 | */ | 31 | */ |
@@ -1736,7 +1736,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1736 | 1736 | ||
1737 | d.BodySetAutoDisableFlag(Body, true); | 1737 | d.BodySetAutoDisableFlag(Body, true); |
1738 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); | 1738 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); |
1739 | d.BodySetDamping(Body, .005f, .005f); | 1739 | d.BodySetAutoDisableAngularThreshold(Body, 0.01f); |
1740 | d.BodySetAutoDisableLinearThreshold(Body, 0.01f); | ||
1741 | d.BodySetDamping(Body, .005f, .001f); | ||
1740 | 1742 | ||
1741 | if (m_targetSpace != IntPtr.Zero) | 1743 | if (m_targetSpace != IntPtr.Zero) |
1742 | { | 1744 | { |
@@ -2144,7 +2146,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2144 | 2146 | ||
2145 | _mass = primMass; // just in case | 2147 | _mass = primMass; // just in case |
2146 | 2148 | ||
2147 | d.MassSetBoxTotal(out primdMass, primMass, m_OBB.X, m_OBB.Y, m_OBB.Z); | 2149 | d.MassSetBoxTotal(out primdMass, primMass, 2.0f * m_OBB.X, 2.0f * m_OBB.Y, 2.0f * m_OBB.Z); |
2148 | 2150 | ||
2149 | d.MassTranslate(ref primdMass, | 2151 | d.MassTranslate(ref primdMass, |
2150 | m_OBBOffset.X, | 2152 | m_OBBOffset.X, |
@@ -2362,6 +2364,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2362 | MakeBody(); | 2364 | MakeBody(); |
2363 | } | 2365 | } |
2364 | 2366 | ||
2367 | |||
2365 | #region changes | 2368 | #region changes |
2366 | 2369 | ||
2367 | private void changeadd() | 2370 | private void changeadd() |
@@ -3213,7 +3216,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3213 | 3216 | ||
3214 | if (++bodydisablecontrol < 20) | 3217 | if (++bodydisablecontrol < 20) |
3215 | return; | 3218 | return; |
3216 | |||
3217 | 3219 | ||
3218 | d.BodyEnable(Body); | 3220 | d.BodyEnable(Body); |
3219 | } | 3221 | } |
@@ -3381,11 +3383,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3381 | } | 3383 | } |
3382 | } | 3384 | } |
3383 | 3385 | ||
3384 | public void UpdatePositionAndVelocity() | 3386 | public void UpdatePositionAndVelocity(int frame) |
3385 | { | 3387 | { |
3386 | if (_parent == null && !m_disabled && !m_building && !m_outbounds && Body != IntPtr.Zero) | 3388 | if (_parent == null && !m_disabled && !m_building && !m_outbounds && Body != IntPtr.Zero) |
3387 | { | 3389 | { |
3388 | if (d.BodyIsEnabled(Body) || !_zeroFlag) | 3390 | bool bodyenabled = d.BodyIsEnabled(Body); |
3391 | if (bodyenabled || !_zeroFlag) | ||
3389 | { | 3392 | { |
3390 | bool lastZeroFlag = _zeroFlag; | 3393 | bool lastZeroFlag = _zeroFlag; |
3391 | 3394 | ||
@@ -3478,13 +3481,13 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3478 | // tolerance values depende a lot on simulation noise... | 3481 | // tolerance values depende a lot on simulation noise... |
3479 | // use simple math.abs since we dont need to be exact | 3482 | // use simple math.abs since we dont need to be exact |
3480 | 3483 | ||
3481 | if ( | 3484 | if (!bodyenabled || |
3482 | (Math.Abs(_position.X - lpos.X) < 0.001f) | 3485 | (Math.Abs(_position.X - lpos.X) < 0.005f) |
3483 | && (Math.Abs(_position.Y - lpos.Y) < 0.001f) | 3486 | && (Math.Abs(_position.Y - lpos.Y) < 0.005f) |
3484 | && (Math.Abs(_position.Z - lpos.Z) < 0.001f) | 3487 | && (Math.Abs(_position.Z - lpos.Z) < 0.005f) |
3485 | && (Math.Abs(_orientation.X - ori.X) < 0.0001f) | 3488 | && (Math.Abs(_orientation.X - ori.X) < 0.001f) |
3486 | && (Math.Abs(_orientation.Y - ori.Y) < 0.0001f) | 3489 | && (Math.Abs(_orientation.Y - ori.Y) < 0.001f) |
3487 | && (Math.Abs(_orientation.Z - ori.Z) < 0.0001f) // ignore W | 3490 | && (Math.Abs(_orientation.Z - ori.Z) < 0.001f) // ignore W |
3488 | ) | 3491 | ) |
3489 | { | 3492 | { |
3490 | _zeroFlag = true; | 3493 | _zeroFlag = true; |
@@ -3499,9 +3502,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3499 | 3502 | ||
3500 | _acceleration = _velocity; | 3503 | _acceleration = _velocity; |
3501 | 3504 | ||
3502 | if ((Math.Abs(vel.X) < 0.001f) && | 3505 | if ((Math.Abs(vel.X) < 0.005f) && |
3503 | (Math.Abs(vel.Y) < 0.001f) && | 3506 | (Math.Abs(vel.Y) < 0.005f) && |
3504 | (Math.Abs(vel.Z) < 0.001f)) | 3507 | (Math.Abs(vel.Z) < 0.005f)) |
3505 | { | 3508 | { |
3506 | _velocity = Vector3.Zero; | 3509 | _velocity = Vector3.Zero; |
3507 | float t = -m_invTimeStep; | 3510 | float t = -m_invTimeStep; |
@@ -3538,6 +3541,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3538 | } | 3541 | } |
3539 | } | 3542 | } |
3540 | 3543 | ||
3544 | _position.X = lpos.X; | ||
3545 | _position.Y = lpos.Y; | ||
3546 | _position.Z = lpos.Z; | ||
3547 | |||
3548 | _orientation.X = ori.X; | ||
3549 | _orientation.Y = ori.Y; | ||
3550 | _orientation.Z = ori.Z; | ||
3551 | _orientation.W = ori.W; | ||
3552 | |||
3541 | if (_zeroFlag) | 3553 | if (_zeroFlag) |
3542 | { | 3554 | { |
3543 | if (lastZeroFlag) | 3555 | if (lastZeroFlag) |
@@ -3556,14 +3568,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3556 | return; | 3568 | return; |
3557 | } | 3569 | } |
3558 | 3570 | ||
3559 | _position.X = lpos.X; | ||
3560 | _position.Y = lpos.Y; | ||
3561 | _position.Z = lpos.Z; | ||
3562 | |||
3563 | _orientation.X = ori.X; | ||
3564 | _orientation.Y = ori.Y; | ||
3565 | _orientation.Z = ori.Z; | ||
3566 | _orientation.W = ori.W; | ||
3567 | base.RequestPhysicsterseUpdate(); | 3571 | base.RequestPhysicsterseUpdate(); |
3568 | m_lastUpdateSent = false; | 3572 | m_lastUpdateSent = false; |
3569 | } | 3573 | } |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs index 2923ccf..73ababa 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs | |||
@@ -680,4 +680,4 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
680 | public RayFilterFlags filter; | 680 | public RayFilterFlags filter; |
681 | public Quaternion orientation; | 681 | public Quaternion orientation; |
682 | } | 682 | } |
683 | } | 683 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs index 10d7d50..1f09dc7 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs | |||
@@ -1869,7 +1869,7 @@ namespace OdeAPI | |||
1869 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetCleanup"), SuppressUnmanagedCodeSecurity] | 1869 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetCleanup"), SuppressUnmanagedCodeSecurity] |
1870 | public static extern void SpaceSetCleanup(IntPtr space, bool mode); | 1870 | public static extern void SpaceSetCleanup(IntPtr space, bool mode); |
1871 | 1871 | ||
1872 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetSublevel"), SuppressUnmanagedCodeSecurity] | 1872 | [DllImport("ode.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetSublevel"), SuppressUnmanagedCodeSecurity] |
1873 | public static extern void SpaceSetSublevel(IntPtr space, int sublevel); | 1873 | public static extern void SpaceSetSublevel(IntPtr space, int sublevel); |
1874 | 1874 | ||
1875 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSweepAndPruneSpaceCreate"), SuppressUnmanagedCodeSecurity] | 1875 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSweepAndPruneSpaceCreate"), SuppressUnmanagedCodeSecurity] |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 754bc86..49dc03c 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | |||
@@ -25,6 +25,7 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | // Revision 2011/12/13 by Ubit Umarov | ||
28 | //#define SPAM | 29 | //#define SPAM |
29 | 30 | ||
30 | using System; | 31 | using System; |
@@ -43,25 +44,7 @@ using OpenMetaverse; | |||
43 | 44 | ||
44 | namespace OpenSim.Region.Physics.OdePlugin | 45 | namespace OpenSim.Region.Physics.OdePlugin |
45 | { | 46 | { |
46 | public enum StatusIndicators : int | 47 | // colision flags of things others can colide with |
47 | { | ||
48 | Generic = 0, | ||
49 | Start = 1, | ||
50 | End = 2 | ||
51 | } | ||
52 | |||
53 | public struct sCollisionData | ||
54 | { | ||
55 | public uint ColliderLocalId; | ||
56 | public uint CollidedWithLocalId; | ||
57 | public int NumberOfCollisions; | ||
58 | public int CollisionType; | ||
59 | public int StatusIndicator; | ||
60 | public int lastframe; | ||
61 | } | ||
62 | |||
63 | |||
64 | // colision flags of things others can colide with | ||
65 | // rays, sensors, probes removed since can't be colided with | 48 | // rays, sensors, probes removed since can't be colided with |
66 | // The top space where things are placed provided further selection | 49 | // The top space where things are placed provided further selection |
67 | // ie physical are in active space nonphysical in static | 50 | // ie physical are in active space nonphysical in static |
@@ -188,12 +171,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
188 | 171 | ||
189 | public bool OdeUbitLib = false; | 172 | public bool OdeUbitLib = false; |
190 | // private int threadid = 0; | 173 | // private int threadid = 0; |
191 | private Random fluidRandomizer = new Random(Environment.TickCount); | 174 | // private Random fluidRandomizer = new Random(Environment.TickCount); |
175 | |||
176 | // const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; | ||
192 | 177 | ||
193 | const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; | 178 | const d.ContactFlags comumContactFlags = d.ContactFlags.Bounce | d.ContactFlags.Approx1; |
194 | const float MaxERP = 0.8f; | 179 | const float comumContactERP = 0.7f; |
195 | const float minERP = 0.1f; | ||
196 | const float comumContactCFM = 0.0001f; | 180 | const float comumContactCFM = 0.0001f; |
181 | const float comumContactSLIP = 0.000001f; | ||
197 | 182 | ||
198 | float frictionMovementMult = 0.8f; | 183 | float frictionMovementMult = 0.8f; |
199 | 184 | ||
@@ -236,8 +221,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
236 | 221 | ||
237 | public float geomDefaultDensity = 10.000006836f; | 222 | public float geomDefaultDensity = 10.000006836f; |
238 | 223 | ||
239 | public int geomContactPointsStartthrottle = 3; | 224 | // public int geomContactPointsStartthrottle = 3; |
240 | public int geomUpdatesPerThrottledUpdate = 15; | 225 | // public int geomUpdatesPerThrottledUpdate = 15; |
241 | 226 | ||
242 | public float bodyPIDD = 35f; | 227 | public float bodyPIDD = 35f; |
243 | public float bodyPIDG = 25; | 228 | public float bodyPIDG = 25; |
@@ -246,7 +231,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
246 | 231 | ||
247 | public int bodyFramesAutoDisable = 5; | 232 | public int bodyFramesAutoDisable = 5; |
248 | 233 | ||
249 | |||
250 | private d.NearCallback nearCallback; | 234 | private d.NearCallback nearCallback; |
251 | 235 | ||
252 | private HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>(); | 236 | private HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>(); |
@@ -266,11 +250,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
266 | // public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); | 250 | // public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); |
267 | public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>(); | 251 | public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>(); |
268 | 252 | ||
269 | private float contactsurfacelayer = 0.002f; | 253 | private float contactsurfacelayer = 0.001f; |
270 | 254 | ||
271 | private int contactsPerCollision = 80; | 255 | private int contactsPerCollision = 80; |
272 | internal IntPtr ContactgeomsArray = IntPtr.Zero; | 256 | internal IntPtr ContactgeomsArray = IntPtr.Zero; |
273 | private IntPtr GlobalContactsArray = IntPtr.Zero; | 257 | private IntPtr GlobalContactsArray = IntPtr.Zero; |
258 | private d.Contact SharedTmpcontact = new d.Contact(); | ||
274 | 259 | ||
275 | const int maxContactsbeforedeath = 4000; | 260 | const int maxContactsbeforedeath = 4000; |
276 | private volatile int m_global_contactcount = 0; | 261 | private volatile int m_global_contactcount = 0; |
@@ -283,7 +268,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
283 | private Dictionary<IntPtr, float[]> TerrainHeightFieldHeights = new Dictionary<IntPtr, float[]>(); | 268 | private Dictionary<IntPtr, float[]> TerrainHeightFieldHeights = new Dictionary<IntPtr, float[]>(); |
284 | private Dictionary<IntPtr, GCHandle> TerrainHeightFieldHeightsHandlers = new Dictionary<IntPtr, GCHandle>(); | 269 | private Dictionary<IntPtr, GCHandle> TerrainHeightFieldHeightsHandlers = new Dictionary<IntPtr, GCHandle>(); |
285 | 270 | ||
286 | private int m_physicsiterations = 10; | 271 | private int m_physicsiterations = 15; |
287 | private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag | 272 | private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag |
288 | // private PhysicsActor PANull = new NullPhysicsActor(); | 273 | // private PhysicsActor PANull = new NullPhysicsActor(); |
289 | private float step_time = 0.0f; | 274 | private float step_time = 0.0f; |
@@ -303,8 +288,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
303 | public IntPtr StaticSpace; // space for the static things around | 288 | public IntPtr StaticSpace; // space for the static things around |
304 | public IntPtr GroundSpace; // space for ground | 289 | public IntPtr GroundSpace; // space for ground |
305 | 290 | ||
306 | public IntPtr SharedRay; | ||
307 | |||
308 | // some speedup variables | 291 | // some speedup variables |
309 | private int spaceGridMaxX; | 292 | private int spaceGridMaxX; |
310 | private int spaceGridMaxY; | 293 | private int spaceGridMaxY; |
@@ -431,8 +414,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
431 | contactgroup = d.JointGroupCreate(0); | 414 | contactgroup = d.JointGroupCreate(0); |
432 | //contactgroup | 415 | //contactgroup |
433 | 416 | ||
434 | SharedRay = d.CreateRay(TopSpace, 1.0f); | ||
435 | |||
436 | d.WorldSetAutoDisableFlag(world, false); | 417 | d.WorldSetAutoDisableFlag(world, false); |
437 | } | 418 | } |
438 | } | 419 | } |
@@ -481,10 +462,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
481 | 462 | ||
482 | metersInSpace = physicsconfig.GetFloat("meters_in_small_space", metersInSpace); | 463 | metersInSpace = physicsconfig.GetFloat("meters_in_small_space", metersInSpace); |
483 | 464 | ||
484 | contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer); | 465 | // contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer); |
485 | 466 | ||
486 | ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE); | 467 | ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE); |
487 | m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", m_physicsiterations); | 468 | // m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", m_physicsiterations); |
488 | 469 | ||
489 | avDensity = physicsconfig.GetFloat("av_density", avDensity); | 470 | avDensity = physicsconfig.GetFloat("av_density", avDensity); |
490 | avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk); | 471 | avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk); |
@@ -492,8 +473,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
492 | 473 | ||
493 | contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision); | 474 | contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision); |
494 | 475 | ||
495 | geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); | 476 | // geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); |
496 | geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); | 477 | // geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); |
497 | // geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); | 478 | // geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); |
498 | 479 | ||
499 | geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); | 480 | geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); |
@@ -508,6 +489,23 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
508 | } | 489 | } |
509 | } | 490 | } |
510 | 491 | ||
492 | |||
493 | d.WorldSetCFM(world, comumContactCFM); | ||
494 | d.WorldSetERP(world, comumContactERP); | ||
495 | |||
496 | d.WorldSetGravity(world, gravityx, gravityy, gravityz); | ||
497 | |||
498 | d.WorldSetLinearDamping(world, 0.002f); | ||
499 | d.WorldSetAngularDamping(world, 0.002f); | ||
500 | d.WorldSetAngularDampingThreshold(world, 0f); | ||
501 | d.WorldSetLinearDampingThreshold(world, 0f); | ||
502 | d.WorldSetMaxAngularSpeed(world, 100f); | ||
503 | |||
504 | d.WorldSetQuickStepNumIterations(world, m_physicsiterations); | ||
505 | |||
506 | d.WorldSetContactSurfaceLayer(world, contactsurfacelayer); | ||
507 | d.WorldSetContactMaxCorrectingVel(world, 60.0f); | ||
508 | |||
511 | m_meshWorker = new ODEMeshWorker(this, m_log, meshmerizer, physicsconfig); | 509 | m_meshWorker = new ODEMeshWorker(this, m_log, meshmerizer, physicsconfig); |
512 | 510 | ||
513 | HalfOdeStep = ODE_STEPSIZE * 0.5f; | 511 | HalfOdeStep = ODE_STEPSIZE * 0.5f; |
@@ -516,6 +514,20 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
516 | ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); | 514 | ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); |
517 | GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf); | 515 | GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf); |
518 | 516 | ||
517 | SharedTmpcontact.geom.g1 = IntPtr.Zero; | ||
518 | SharedTmpcontact.geom.g2 = IntPtr.Zero; | ||
519 | |||
520 | SharedTmpcontact.geom.side1 = -1; | ||
521 | SharedTmpcontact.geom.side2 = -1; | ||
522 | |||
523 | SharedTmpcontact.surface.mode = comumContactFlags; | ||
524 | SharedTmpcontact.surface.mu = 0; | ||
525 | SharedTmpcontact.surface.bounce = 0; | ||
526 | SharedTmpcontact.surface.soft_cfm = comumContactCFM; | ||
527 | SharedTmpcontact.surface.soft_erp = comumContactERP; | ||
528 | SharedTmpcontact.surface.slip1 = comumContactSLIP; | ||
529 | SharedTmpcontact.surface.slip2 = comumContactSLIP; | ||
530 | |||
519 | m_materialContactsData[(int)Material.Stone].mu = 0.8f; | 531 | m_materialContactsData[(int)Material.Stone].mu = 0.8f; |
520 | m_materialContactsData[(int)Material.Stone].bounce = 0.4f; | 532 | m_materialContactsData[(int)Material.Stone].bounce = 0.4f; |
521 | 533 | ||
@@ -540,27 +552,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
540 | m_materialContactsData[(int)Material.light].mu = 0.0f; | 552 | m_materialContactsData[(int)Material.light].mu = 0.0f; |
541 | m_materialContactsData[(int)Material.light].bounce = 0.0f; | 553 | m_materialContactsData[(int)Material.light].bounce = 0.0f; |
542 | 554 | ||
543 | // Set the gravity,, don't disable things automatically (we set it explicitly on some things) | ||
544 | |||
545 | d.WorldSetGravity(world, gravityx, gravityy, gravityz); | ||
546 | d.WorldSetContactSurfaceLayer(world, contactsurfacelayer); | ||
547 | |||
548 | d.WorldSetLinearDamping(world, 0.002f); | ||
549 | d.WorldSetAngularDamping(world, 0.002f); | ||
550 | d.WorldSetAngularDampingThreshold(world, 0f); | ||
551 | d.WorldSetLinearDampingThreshold(world, 0f); | ||
552 | d.WorldSetMaxAngularSpeed(world, 100f); | ||
553 | |||
554 | d.WorldSetCFM(world,1e-6f); // a bit harder than default | ||
555 | //d.WorldSetCFM(world, 1e-4f); // a bit harder than default | ||
556 | d.WorldSetERP(world, 0.6f); // higher than original | ||
557 | |||
558 | // Set how many steps we go without running collision testing | ||
559 | // This is in addition to the step size. | ||
560 | // Essentially Steps * m_physicsiterations | ||
561 | d.WorldSetQuickStepNumIterations(world, m_physicsiterations); | ||
562 | |||
563 | d.WorldSetContactMaxCorrectingVel(world, 60.0f); | ||
564 | 555 | ||
565 | spacesPerMeter = 1 / metersInSpace; | 556 | spacesPerMeter = 1 / metersInSpace; |
566 | spaceGridMaxX = (int)(WorldExtents.X * spacesPerMeter); | 557 | spaceGridMaxX = (int)(WorldExtents.X * spacesPerMeter); |
@@ -631,40 +622,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
631 | 622 | ||
632 | // sets a global contact for a joint for contactgeom , and base contact description) | 623 | // sets a global contact for a joint for contactgeom , and base contact description) |
633 | 624 | ||
634 | private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom, float mu, float bounce, float cfm, float erpscale, float dscale) | 625 | |
626 | |||
627 | private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom) | ||
635 | { | 628 | { |
636 | if (GlobalContactsArray == IntPtr.Zero || m_global_contactcount >= maxContactsbeforedeath) | 629 | if (m_global_contactcount >= maxContactsbeforedeath) |
637 | return IntPtr.Zero; | 630 | return IntPtr.Zero; |
638 | 631 | ||
639 | float erp = contactGeom.depth; | 632 | m_global_contactcount++; |
640 | erp *= erpscale; | 633 | |
641 | if (erp < minERP) | 634 | SharedTmpcontact.geom.depth = contactGeom.depth; |
642 | erp = minERP; | 635 | SharedTmpcontact.geom.pos = contactGeom.pos; |
643 | else if (erp > MaxERP) | 636 | SharedTmpcontact.geom.normal = contactGeom.normal; |
644 | erp = MaxERP; | ||
645 | |||
646 | float depth = contactGeom.depth * dscale; | ||
647 | if (depth > 0.5f) | ||
648 | depth = 0.5f; | ||
649 | |||
650 | d.Contact newcontact = new d.Contact(); | ||
651 | newcontact.geom.depth = depth; | ||
652 | newcontact.geom.g1 = contactGeom.g1; | ||
653 | newcontact.geom.g2 = contactGeom.g2; | ||
654 | newcontact.geom.pos = contactGeom.pos; | ||
655 | newcontact.geom.normal = contactGeom.normal; | ||
656 | newcontact.geom.side1 = contactGeom.side1; | ||
657 | newcontact.geom.side2 = contactGeom.side2; | ||
658 | |||
659 | // this needs bounce also | ||
660 | newcontact.surface.mode = comumContactFlags; | ||
661 | newcontact.surface.mu = mu; | ||
662 | newcontact.surface.bounce = bounce; | ||
663 | newcontact.surface.soft_cfm = cfm; | ||
664 | newcontact.surface.soft_erp = erp; | ||
665 | 637 | ||
666 | IntPtr contact = new IntPtr(GlobalContactsArray.ToInt64() + (Int64)(m_global_contactcount * d.Contact.unmanagedSizeOf)); | 638 | IntPtr contact = new IntPtr(GlobalContactsArray.ToInt64() + (Int64)(m_global_contactcount * d.Contact.unmanagedSizeOf)); |
667 | Marshal.StructureToPtr(newcontact, contact, true); | 639 | Marshal.StructureToPtr(SharedTmpcontact, contact, true); |
668 | return d.JointCreateContactPtr(world, contactgroup, contact); | 640 | return d.JointCreateContactPtr(world, contactgroup, contact); |
669 | } | 641 | } |
670 | 642 | ||
@@ -825,10 +797,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
825 | if (!GetCurContactGeom(0, ref curContact)) | 797 | if (!GetCurContactGeom(0, ref curContact)) |
826 | return; | 798 | return; |
827 | 799 | ||
800 | ContactPoint maxDepthContact = new ContactPoint(); | ||
801 | |||
828 | // do volume detection case | 802 | // do volume detection case |
829 | if ((p1.IsVolumeDtc || p2.IsVolumeDtc)) | 803 | if ((p1.IsVolumeDtc || p2.IsVolumeDtc)) |
830 | { | 804 | { |
831 | ContactPoint maxDepthContact = new ContactPoint( | 805 | maxDepthContact = new ContactPoint( |
832 | new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), | 806 | new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), |
833 | new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z), | 807 | new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z), |
834 | curContact.depth, false | 808 | curContact.depth, false |
@@ -842,10 +816,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
842 | 816 | ||
843 | float mu = 0; | 817 | float mu = 0; |
844 | float bounce = 0; | 818 | float bounce = 0; |
845 | float cfm = 0.0001f; | 819 | // bool IgnoreNegSides = false; |
846 | float erpscale = 1.0f; | ||
847 | float dscale = 1.0f; | ||
848 | bool IgnoreNegSides = false; | ||
849 | 820 | ||
850 | ContactData contactdata1 = new ContactData(0, 0, false); | 821 | ContactData contactdata1 = new ContactData(0, 0, false); |
851 | ContactData contactdata2 = new ContactData(0, 0, false); | 822 | ContactData contactdata2 = new ContactData(0, 0, false); |
@@ -890,7 +861,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
890 | break; | 861 | break; |
891 | 862 | ||
892 | case (int)ActorTypes.Prim: | 863 | case (int)ActorTypes.Prim: |
893 | if ((p1.Velocity - p2.Velocity).LengthSquared() > 0.0f) | 864 | Vector3 relV = p1.Velocity - p2.Velocity; |
865 | float relVlenSQ = relV.LengthSquared(); | ||
866 | if (relVlenSQ > 0.0001f) | ||
894 | { | 867 | { |
895 | p1.CollidingObj = true; | 868 | p1.CollidingObj = true; |
896 | p2.CollidingObj = true; | 869 | p2.CollidingObj = true; |
@@ -900,21 +873,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
900 | bounce = contactdata1.bounce * contactdata2.bounce; | 873 | bounce = contactdata1.bounce * contactdata2.bounce; |
901 | mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); | 874 | mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); |
902 | 875 | ||
903 | cfm = p1.Mass; | 876 | if (relVlenSQ > 0.01f) |
904 | if (cfm > p2.Mass) | ||
905 | cfm = p2.Mass; | ||
906 | dscale = 10 / cfm; | ||
907 | dscale = (float)Math.Sqrt(dscale); | ||
908 | if (dscale > 1.0f) | ||
909 | dscale = 1.0f; | ||
910 | erpscale = cfm * 0.01f; | ||
911 | cfm = 0.0001f / cfm; | ||
912 | if (cfm > 0.01f) | ||
913 | cfm = 0.01f; | ||
914 | else if (cfm < 0.00001f) | ||
915 | cfm = 0.00001f; | ||
916 | |||
917 | if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) | ||
918 | mu *= frictionMovementMult; | 877 | mu *= frictionMovementMult; |
919 | 878 | ||
920 | break; | 879 | break; |
@@ -923,27 +882,17 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
923 | p1.getContactData(ref contactdata1); | 882 | p1.getContactData(ref contactdata1); |
924 | bounce = contactdata1.bounce * TerrainBounce; | 883 | bounce = contactdata1.bounce * TerrainBounce; |
925 | mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); | 884 | mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); |
885 | |||
926 | if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) | 886 | if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) |
927 | mu *= frictionMovementMult; | 887 | mu *= frictionMovementMult; |
928 | p1.CollidingGround = true; | 888 | p1.CollidingGround = true; |
929 | 889 | /* | |
930 | cfm = p1.Mass; | ||
931 | dscale = 10 / cfm; | ||
932 | dscale = (float)Math.Sqrt(dscale); | ||
933 | if (dscale > 1.0f) | ||
934 | dscale = 1.0f; | ||
935 | erpscale = cfm * 0.01f; | ||
936 | cfm = 0.0001f / cfm; | ||
937 | if (cfm > 0.01f) | ||
938 | cfm = 0.01f; | ||
939 | else if (cfm < 0.00001f) | ||
940 | cfm = 0.00001f; | ||
941 | |||
942 | if (d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) | 890 | if (d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) |
943 | { | 891 | { |
944 | if (curContact.side1 > 0) | 892 | if (curContact.side1 > 0) |
945 | IgnoreNegSides = true; | 893 | IgnoreNegSides = true; |
946 | } | 894 | } |
895 | */ | ||
947 | break; | 896 | break; |
948 | 897 | ||
949 | case (int)ActorTypes.Water: | 898 | case (int)ActorTypes.Water: |
@@ -961,22 +910,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
961 | bounce = contactdata2.bounce * TerrainBounce; | 910 | bounce = contactdata2.bounce * TerrainBounce; |
962 | mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); | 911 | mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); |
963 | 912 | ||
964 | cfm = p2.Mass; | 913 | // if (curContact.side1 > 0) // should be 2 ? |
965 | dscale = 10 / cfm; | 914 | // IgnoreNegSides = true; |
966 | dscale = (float)Math.Sqrt(dscale); | ||
967 | |||
968 | if (dscale > 1.0f) | ||
969 | dscale = 1.0f; | ||
970 | |||
971 | erpscale = cfm * 0.01f; | ||
972 | cfm = 0.0001f / cfm; | ||
973 | if (cfm > 0.01f) | ||
974 | cfm = 0.01f; | ||
975 | else if (cfm < 0.00001f) | ||
976 | cfm = 0.00001f; | ||
977 | |||
978 | if (curContact.side1 > 0) // should be 2 ? | ||
979 | IgnoreNegSides = true; | ||
980 | 915 | ||
981 | if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f) | 916 | if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f) |
982 | mu *= frictionMovementMult; | 917 | mu *= frictionMovementMult; |
@@ -993,26 +928,24 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
993 | if (ignore) | 928 | if (ignore) |
994 | return; | 929 | return; |
995 | 930 | ||
996 | |||
997 | d.ContactGeom maxContact = curContact; | ||
998 | // if (IgnoreNegSides && curContact.side1 < 0) | ||
999 | // maxContact.depth = float.MinValue; | ||
1000 | |||
1001 | d.ContactGeom minContact = curContact; | ||
1002 | // if (IgnoreNegSides && curContact.side1 < 0) | ||
1003 | // minContact.depth = float.MaxValue; | ||
1004 | |||
1005 | IntPtr Joint; | 931 | IntPtr Joint; |
1006 | bool FeetCollision = false; | 932 | bool FeetCollision = false; |
1007 | int ncontacts = 0; | 933 | int ncontacts = 0; |
1008 | 934 | ||
1009 | |||
1010 | int i = 0; | 935 | int i = 0; |
1011 | 936 | ||
937 | maxDepthContact = new ContactPoint(); | ||
938 | maxDepthContact.PenetrationDepth = float.MinValue; | ||
939 | ContactPoint minDepthContact = new ContactPoint(); | ||
940 | minDepthContact.PenetrationDepth = float.MaxValue; | ||
941 | |||
942 | SharedTmpcontact.geom.depth = 0; | ||
943 | SharedTmpcontact.surface.mu = mu; | ||
944 | SharedTmpcontact.surface.bounce = bounce; | ||
945 | |||
1012 | while (true) | 946 | while (true) |
1013 | { | 947 | { |
1014 | 948 | // if (!(IgnoreNegSides && curContact.side1 < 0)) | |
1015 | // if (!(IgnoreNegSides && curContact.side1 < 0)) | ||
1016 | { | 949 | { |
1017 | bool noskip = true; | 950 | bool noskip = true; |
1018 | if (dop1ava) | 951 | if (dop1ava) |
@@ -1029,26 +962,32 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1029 | 962 | ||
1030 | if (noskip) | 963 | if (noskip) |
1031 | { | 964 | { |
1032 | m_global_contactcount++; | 965 | Joint = CreateContacJoint(ref curContact); |
1033 | if (m_global_contactcount >= maxContactsbeforedeath) | ||
1034 | break; | ||
1035 | |||
1036 | ncontacts++; | ||
1037 | |||
1038 | Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale); | ||
1039 | if (Joint == IntPtr.Zero) | 966 | if (Joint == IntPtr.Zero) |
1040 | break; | 967 | break; |
1041 | 968 | ||
1042 | d.JointAttach(Joint, b1, b2); | 969 | d.JointAttach(Joint, b1, b2); |
1043 | 970 | ||
1044 | if (curContact.depth > maxContact.depth) | 971 | ncontacts++; |
1045 | maxContact = curContact; | 972 | |
973 | if (curContact.depth > maxDepthContact.PenetrationDepth) | ||
974 | { | ||
975 | maxDepthContact.Position.X = curContact.pos.X; | ||
976 | maxDepthContact.Position.Y = curContact.pos.Y; | ||
977 | maxDepthContact.Position.Z = curContact.pos.Z; | ||
978 | maxDepthContact.PenetrationDepth = curContact.depth; | ||
979 | maxDepthContact.CharacterFeet = FeetCollision; | ||
980 | } | ||
1046 | 981 | ||
1047 | if (curContact.depth < minContact.depth) | 982 | if (curContact.depth < minDepthContact.PenetrationDepth) |
1048 | minContact = curContact; | 983 | { |
984 | minDepthContact.PenetrationDepth = curContact.depth; | ||
985 | minDepthContact.SurfaceNormal.X = curContact.normal.X; | ||
986 | minDepthContact.SurfaceNormal.Y = curContact.normal.Y; | ||
987 | minDepthContact.SurfaceNormal.Z = curContact.normal.Z; | ||
988 | } | ||
1049 | } | 989 | } |
1050 | } | 990 | } |
1051 | |||
1052 | if (++i >= count) | 991 | if (++i >= count) |
1053 | break; | 992 | break; |
1054 | 993 | ||
@@ -1058,11 +997,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1058 | 997 | ||
1059 | if (ncontacts > 0) | 998 | if (ncontacts > 0) |
1060 | { | 999 | { |
1061 | ContactPoint maxDepthContact = new ContactPoint( | 1000 | maxDepthContact.SurfaceNormal.X = minDepthContact.SurfaceNormal.X; |
1062 | new Vector3(maxContact.pos.X, maxContact.pos.Y, maxContact.pos.Z), | 1001 | maxDepthContact.SurfaceNormal.Y = minDepthContact.SurfaceNormal.Y; |
1063 | new Vector3(minContact.normal.X, minContact.normal.Y, minContact.normal.Z), | 1002 | maxDepthContact.SurfaceNormal.Z = minDepthContact.SurfaceNormal.Z; |
1064 | maxContact.depth, FeetCollision | 1003 | |
1065 | ); | ||
1066 | collision_accounting_events(p1, p2, maxDepthContact); | 1004 | collision_accounting_events(p1, p2, maxDepthContact); |
1067 | } | 1005 | } |
1068 | } | 1006 | } |
@@ -1629,16 +1567,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1629 | if (framecount < 0) | 1567 | if (framecount < 0) |
1630 | framecount = 0; | 1568 | framecount = 0; |
1631 | 1569 | ||
1632 | |||
1633 | framecount++; | 1570 | framecount++; |
1634 | 1571 | ||
1635 | int curphysiteractions; | 1572 | // int curphysiteractions; |
1636 | 1573 | ||
1637 | // if in trouble reduce step resolution | 1574 | // if in trouble reduce step resolution |
1638 | if (step_time >= m_SkipFramesAtms) | 1575 | // if (step_time >= m_SkipFramesAtms) |
1639 | curphysiteractions = m_physicsiterations / 2; | 1576 | // curphysiteractions = m_physicsiterations / 2; |
1640 | else | 1577 | // else |
1641 | curphysiteractions = m_physicsiterations; | 1578 | // curphysiteractions = m_physicsiterations; |
1642 | 1579 | ||
1643 | // checkThread(); | 1580 | // checkThread(); |
1644 | int nodeframes = 0; | 1581 | int nodeframes = 0; |
@@ -1653,14 +1590,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1653 | } | 1590 | } |
1654 | 1591 | ||
1655 | ODEchangeitem item; | 1592 | ODEchangeitem item; |
1656 | |||
1657 | |||
1658 | 1593 | ||
1659 | d.WorldSetQuickStepNumIterations(world, curphysiteractions); | 1594 | // d.WorldSetQuickStepNumIterations(world, curphysiteractions); |
1660 | 1595 | ||
1661 | int loopstartMS = Util.EnvironmentTickCount(); | 1596 | int loopstartMS = Util.EnvironmentTickCount(); |
1662 | int looptimeMS = 0; | 1597 | int looptimeMS = 0; |
1663 | 1598 | ||
1664 | 1599 | ||
1665 | while (step_time > HalfOdeStep) | 1600 | while (step_time > HalfOdeStep) |
1666 | { | 1601 | { |
@@ -1763,6 +1698,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1763 | 1698 | ||
1764 | // do a ode simulation step | 1699 | // do a ode simulation step |
1765 | d.WorldQuickStep(world, ODE_STEPSIZE); | 1700 | d.WorldQuickStep(world, ODE_STEPSIZE); |
1701 | // d.WorldStep(world, ODE_STEPSIZE); | ||
1766 | d.JointGroupEmpty(contactgroup); | 1702 | d.JointGroupEmpty(contactgroup); |
1767 | 1703 | ||
1768 | // update managed ideia of physical data and do updates to core | 1704 | // update managed ideia of physical data and do updates to core |
@@ -1789,7 +1725,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1789 | { | 1725 | { |
1790 | if (actor.IsPhysical) | 1726 | if (actor.IsPhysical) |
1791 | { | 1727 | { |
1792 | actor.UpdatePositionAndVelocity(); | 1728 | actor.UpdatePositionAndVelocity(framecount); |
1793 | } | 1729 | } |
1794 | } | 1730 | } |
1795 | } | 1731 | } |