diff options
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 13 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Manager/IMesher.cs | 1 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Manager/ZeroMesher.cs | 10 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 5 | ||||
-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/ODEDynamics.cs | 19 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs | 6 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 105 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 290 |
13 files changed, 591 insertions, 1191 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index d09ea3e..193a27b 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -359,13 +359,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
359 | { | 359 | { |
360 | CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); | 360 | CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); |
361 | Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); | 361 | Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); |
362 | // this possible is not needed if keyframes are saved | ||
363 | Dictionary<UUID, KeyframeMotion> originalKeyframes = new Dictionary<UUID, KeyframeMotion>(); | ||
362 | 364 | ||
363 | foreach (SceneObjectGroup objectGroup in objlist) | 365 | foreach (SceneObjectGroup objectGroup in objlist) |
364 | { | 366 | { |
365 | if (objectGroup.RootPart.KeyframeMotion != null) | 367 | if (objectGroup.RootPart.KeyframeMotion != null) |
366 | objectGroup.RootPart.KeyframeMotion.Stop(); | 368 | { |
369 | objectGroup.RootPart.KeyframeMotion.Suspend(); | ||
370 | } | ||
367 | objectGroup.RootPart.SetForce(Vector3.Zero); | 371 | objectGroup.RootPart.SetForce(Vector3.Zero); |
368 | objectGroup.RootPart.SetAngularImpulse(Vector3.Zero, false); | 372 | objectGroup.RootPart.SetAngularImpulse(Vector3.Zero, false); |
373 | |||
374 | originalKeyframes[objectGroup.UUID] = objectGroup.RootPart.KeyframeMotion; | ||
369 | objectGroup.RootPart.KeyframeMotion = null; | 375 | objectGroup.RootPart.KeyframeMotion = null; |
370 | 376 | ||
371 | Vector3 inventoryStoredPosition = new Vector3 | 377 | Vector3 inventoryStoredPosition = new Vector3 |
@@ -425,7 +431,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
425 | 431 | ||
426 | // Restore the position of each group now that it has been stored to inventory. | 432 | // Restore the position of each group now that it has been stored to inventory. |
427 | foreach (SceneObjectGroup objectGroup in objlist) | 433 | foreach (SceneObjectGroup objectGroup in objlist) |
434 | { | ||
428 | objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; | 435 | objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; |
436 | objectGroup.RootPart.KeyframeMotion = originalKeyframes[objectGroup.UUID]; | ||
437 | if (objectGroup.RootPart.KeyframeMotion != null) | ||
438 | objectGroup.RootPart.KeyframeMotion.Resume(); | ||
439 | } | ||
429 | 440 | ||
430 | InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); | 441 | InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); |
431 | 442 | ||
diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs index 5485eb7..e290dc9 100644 --- a/OpenSim/Region/Physics/Manager/IMesher.cs +++ b/OpenSim/Region/Physics/Manager/IMesher.cs | |||
@@ -37,6 +37,7 @@ namespace OpenSim.Region.Physics.Manager | |||
37 | { | 37 | { |
38 | IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod); | 38 | IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod); |
39 | IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); | 39 | IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); |
40 | IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde); | ||
40 | IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, bool convex, bool forOde); | 41 | IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, bool convex, bool forOde); |
41 | IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex); | 42 | IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex); |
42 | void ReleaseMesh(IMesh mesh); | 43 | void ReleaseMesh(IMesh mesh); |
diff --git a/OpenSim/Region/Physics/Manager/ZeroMesher.cs b/OpenSim/Region/Physics/Manager/ZeroMesher.cs index 80ecf66..890951f 100644 --- a/OpenSim/Region/Physics/Manager/ZeroMesher.cs +++ b/OpenSim/Region/Physics/Manager/ZeroMesher.cs | |||
@@ -64,20 +64,20 @@ namespace OpenSim.Region.Physics.Manager | |||
64 | { | 64 | { |
65 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) | 65 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) |
66 | { | 66 | { |
67 | return CreateMesh(primName, primShape, size, lod, false, false); | 67 | return CreateMesh(primName, primShape, size, lod, false); |
68 | } | 68 | } |
69 | 69 | ||
70 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, bool convex,bool forOde) | 70 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, bool convex, bool forOde) |
71 | { | 71 | { |
72 | return CreateMesh(primName, primShape, size, lod, false); | 72 | return CreateMesh(primName, primShape, size, lod, false); |
73 | } | 73 | } |
74 | 74 | ||
75 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) | 75 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex,bool forOde) |
76 | { | 76 | { |
77 | return CreateMesh(primName, primShape, size, lod, false, false); | 77 | return CreateMesh(primName, primShape, size, lod, false); |
78 | } | 78 | } |
79 | 79 | ||
80 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) | 80 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) |
81 | { | 81 | { |
82 | // Remove the reference to the encoded JPEG2000 data so it can be GCed | 82 | // Remove the reference to the encoded JPEG2000 data so it can be GCed |
83 | primShape.SculptData = OpenMetaverse.Utils.EmptyBytes; | 83 | primShape.SculptData = OpenMetaverse.Utils.EmptyBytes; |
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index d181b78..a32f401 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs | |||
@@ -715,6 +715,11 @@ namespace OpenSim.Region.Physics.Meshing | |||
715 | return CreateMesh(primName, primShape, size, lod, isPhysical, true); | 715 | return CreateMesh(primName, primShape, size, lod, isPhysical, true); |
716 | } | 716 | } |
717 | 717 | ||
718 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde) | ||
719 | { | ||
720 | return CreateMesh(primName, primShape, size, lod, isPhysical, true); | ||
721 | } | ||
722 | |||
718 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) | 723 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) |
719 | { | 724 | { |
720 | #if SPAM | 725 | #if SPAM |
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/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index a7dda7a..3c952ae 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs | |||
@@ -137,6 +137,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
137 | float m_amdampY; | 137 | float m_amdampY; |
138 | float m_amdampZ; | 138 | float m_amdampZ; |
139 | 139 | ||
140 | float m_gravmod; | ||
140 | 141 | ||
141 | public float FrictionFactor | 142 | public float FrictionFactor |
142 | { | 143 | { |
@@ -146,6 +147,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
146 | } | 147 | } |
147 | } | 148 | } |
148 | 149 | ||
150 | public float GravMod | ||
151 | { | ||
152 | set | ||
153 | { | ||
154 | m_gravmod = value; | ||
155 | } | ||
156 | } | ||
157 | |||
149 | 158 | ||
150 | public ODEDynamics(OdePrim rootp) | 159 | public ODEDynamics(OdePrim rootp) |
151 | { | 160 | { |
@@ -153,6 +162,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
153 | _pParentScene = rootPrim._parent_scene; | 162 | _pParentScene = rootPrim._parent_scene; |
154 | m_timestep = _pParentScene.ODE_STEPSIZE; | 163 | m_timestep = _pParentScene.ODE_STEPSIZE; |
155 | m_invtimestep = 1.0f / m_timestep; | 164 | m_invtimestep = 1.0f / m_timestep; |
165 | m_gravmod = rootPrim.GravModifier; | ||
156 | } | 166 | } |
157 | 167 | ||
158 | public void DoSetVehicle(VehicleData vd) | 168 | public void DoSetVehicle(VehicleData vd) |
@@ -816,7 +826,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
816 | m_lmEfect = 0; | 826 | m_lmEfect = 0; |
817 | m_ffactor = 1f; | 827 | m_ffactor = 1f; |
818 | } | 828 | } |
819 | 829 | ||
820 | // hover | 830 | // hover |
821 | if (m_VhoverTimescale < 300 && rootPrim.prim_geom != IntPtr.Zero) | 831 | if (m_VhoverTimescale < 300 && rootPrim.prim_geom != IntPtr.Zero) |
822 | { | 832 | { |
@@ -862,7 +872,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
862 | force.Z += perr; | 872 | force.Z += perr; |
863 | ldampZ *= -curVel.Z; | 873 | ldampZ *= -curVel.Z; |
864 | 874 | ||
865 | force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy); | 875 | force.Z += _pParentScene.gravityz * m_gravmod * (1f - m_VehicleBuoyancy); |
866 | } | 876 | } |
867 | else // no buoyancy | 877 | else // no buoyancy |
868 | force.Z += _pParentScene.gravityz; | 878 | force.Z += _pParentScene.gravityz; |
@@ -870,7 +880,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
870 | else | 880 | else |
871 | { | 881 | { |
872 | // default gravity and Buoyancy | 882 | // default gravity and Buoyancy |
873 | force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy); | 883 | force.Z += _pParentScene.gravityz * m_gravmod * (1f - m_VehicleBuoyancy); |
874 | } | 884 | } |
875 | 885 | ||
876 | // linear deflection | 886 | // linear deflection |
@@ -1063,8 +1073,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1063 | torque.Y -= curLocalAngVel.Y * m_amdampY; | 1073 | torque.Y -= curLocalAngVel.Y * m_amdampY; |
1064 | torque.Z -= curLocalAngVel.Z * m_amdampZ; | 1074 | torque.Z -= curLocalAngVel.Z * m_amdampZ; |
1065 | } | 1075 | } |
1066 | 1076 | ||
1067 | |||
1068 | 1077 | ||
1069 | if (force.X != 0 || force.Y != 0 || force.Z != 0) | 1078 | if (force.X != 0 || force.Y != 0 || force.Z != 0) |
1070 | { | 1079 | { |
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..4cac0aa 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 | */ |
@@ -115,7 +115,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
115 | 115 | ||
116 | private int body_autodisable_frames; | 116 | private int body_autodisable_frames; |
117 | public int bodydisablecontrol; | 117 | public int bodydisablecontrol; |
118 | 118 | private float m_gravmod = 1.0f; | |
119 | 119 | ||
120 | // Default we're a Geometry | 120 | // Default we're a Geometry |
121 | private CollisionCategories m_collisionCategories = (CollisionCategories.Geom); | 121 | private CollisionCategories m_collisionCategories = (CollisionCategories.Geom); |
@@ -914,6 +914,55 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
914 | bounce = _parent_scene.m_materialContactsData[pMaterial].bounce; | 914 | bounce = _parent_scene.m_materialContactsData[pMaterial].bounce; |
915 | } | 915 | } |
916 | 916 | ||
917 | public override float Density | ||
918 | { | ||
919 | get | ||
920 | { | ||
921 | return m_density * 100f; | ||
922 | } | ||
923 | set | ||
924 | { | ||
925 | m_density = value / 100f; | ||
926 | // for not prim mass is not updated since this implies full rebuild of body inertia TODO | ||
927 | } | ||
928 | } | ||
929 | public override float GravModifier | ||
930 | { | ||
931 | get | ||
932 | { | ||
933 | return m_gravmod; | ||
934 | } | ||
935 | set | ||
936 | { | ||
937 | m_gravmod = value; | ||
938 | if (m_vehicle != null) | ||
939 | m_vehicle.GravMod = m_gravmod; | ||
940 | } | ||
941 | } | ||
942 | public override float Friction | ||
943 | { | ||
944 | get | ||
945 | { | ||
946 | return mu; | ||
947 | } | ||
948 | set | ||
949 | { | ||
950 | mu = value; | ||
951 | } | ||
952 | } | ||
953 | |||
954 | public override float Restitution | ||
955 | { | ||
956 | get | ||
957 | { | ||
958 | return bounce; | ||
959 | } | ||
960 | set | ||
961 | { | ||
962 | bounce = value; | ||
963 | } | ||
964 | } | ||
965 | |||
917 | public void setPrimForRemoval() | 966 | public void setPrimForRemoval() |
918 | { | 967 | { |
919 | AddChange(changes.Remove, null); | 968 | AddChange(changes.Remove, null); |
@@ -1736,7 +1785,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1736 | 1785 | ||
1737 | d.BodySetAutoDisableFlag(Body, true); | 1786 | d.BodySetAutoDisableFlag(Body, true); |
1738 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); | 1787 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); |
1739 | d.BodySetDamping(Body, .005f, .005f); | 1788 | d.BodySetAutoDisableAngularThreshold(Body, 0.01f); |
1789 | d.BodySetAutoDisableLinearThreshold(Body, 0.01f); | ||
1790 | d.BodySetDamping(Body, .005f, .001f); | ||
1740 | 1791 | ||
1741 | if (m_targetSpace != IntPtr.Zero) | 1792 | if (m_targetSpace != IntPtr.Zero) |
1742 | { | 1793 | { |
@@ -2144,7 +2195,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2144 | 2195 | ||
2145 | _mass = primMass; // just in case | 2196 | _mass = primMass; // just in case |
2146 | 2197 | ||
2147 | d.MassSetBoxTotal(out primdMass, primMass, m_OBB.X, m_OBB.Y, m_OBB.Z); | 2198 | d.MassSetBoxTotal(out primdMass, primMass, 2.0f * m_OBB.X, 2.0f * m_OBB.Y, 2.0f * m_OBB.Z); |
2148 | 2199 | ||
2149 | d.MassTranslate(ref primdMass, | 2200 | d.MassTranslate(ref primdMass, |
2150 | m_OBBOffset.X, | 2201 | m_OBBOffset.X, |
@@ -2362,6 +2413,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2362 | MakeBody(); | 2413 | MakeBody(); |
2363 | } | 2414 | } |
2364 | 2415 | ||
2416 | |||
2365 | #region changes | 2417 | #region changes |
2366 | 2418 | ||
2367 | private void changeadd() | 2419 | private void changeadd() |
@@ -3213,7 +3265,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3213 | 3265 | ||
3214 | if (++bodydisablecontrol < 20) | 3266 | if (++bodydisablecontrol < 20) |
3215 | return; | 3267 | return; |
3216 | |||
3217 | 3268 | ||
3218 | d.BodyEnable(Body); | 3269 | d.BodyEnable(Body); |
3219 | } | 3270 | } |
@@ -3334,7 +3385,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3334 | } | 3385 | } |
3335 | else | 3386 | else |
3336 | { | 3387 | { |
3337 | float b = (1.0f - m_buoyancy); | 3388 | float b = (1.0f - m_buoyancy) * m_gravmod; |
3338 | fx = _parent_scene.gravityx * b; | 3389 | fx = _parent_scene.gravityx * b; |
3339 | fy = _parent_scene.gravityy * b; | 3390 | fy = _parent_scene.gravityy * b; |
3340 | fz = _parent_scene.gravityz * b; | 3391 | fz = _parent_scene.gravityz * b; |
@@ -3381,11 +3432,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3381 | } | 3432 | } |
3382 | } | 3433 | } |
3383 | 3434 | ||
3384 | public void UpdatePositionAndVelocity() | 3435 | public void UpdatePositionAndVelocity(int frame) |
3385 | { | 3436 | { |
3386 | if (_parent == null && !m_disabled && !m_building && !m_outbounds && Body != IntPtr.Zero) | 3437 | if (_parent == null && !m_disabled && !m_building && !m_outbounds && Body != IntPtr.Zero) |
3387 | { | 3438 | { |
3388 | if (d.BodyIsEnabled(Body) || !_zeroFlag) | 3439 | bool bodyenabled = d.BodyIsEnabled(Body); |
3440 | if (bodyenabled || !_zeroFlag) | ||
3389 | { | 3441 | { |
3390 | bool lastZeroFlag = _zeroFlag; | 3442 | bool lastZeroFlag = _zeroFlag; |
3391 | 3443 | ||
@@ -3478,13 +3530,13 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3478 | // tolerance values depende a lot on simulation noise... | 3530 | // tolerance values depende a lot on simulation noise... |
3479 | // use simple math.abs since we dont need to be exact | 3531 | // use simple math.abs since we dont need to be exact |
3480 | 3532 | ||
3481 | if ( | 3533 | if (!bodyenabled || |
3482 | (Math.Abs(_position.X - lpos.X) < 0.001f) | 3534 | (Math.Abs(_position.X - lpos.X) < 0.005f) |
3483 | && (Math.Abs(_position.Y - lpos.Y) < 0.001f) | 3535 | && (Math.Abs(_position.Y - lpos.Y) < 0.005f) |
3484 | && (Math.Abs(_position.Z - lpos.Z) < 0.001f) | 3536 | && (Math.Abs(_position.Z - lpos.Z) < 0.005f) |
3485 | && (Math.Abs(_orientation.X - ori.X) < 0.0001f) | 3537 | && (Math.Abs(_orientation.X - ori.X) < 0.0005f) |
3486 | && (Math.Abs(_orientation.Y - ori.Y) < 0.0001f) | 3538 | && (Math.Abs(_orientation.Y - ori.Y) < 0.0005f) |
3487 | && (Math.Abs(_orientation.Z - ori.Z) < 0.0001f) // ignore W | 3539 | && (Math.Abs(_orientation.Z - ori.Z) < 0.0005f) // ignore W |
3488 | ) | 3540 | ) |
3489 | { | 3541 | { |
3490 | _zeroFlag = true; | 3542 | _zeroFlag = true; |
@@ -3499,9 +3551,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3499 | 3551 | ||
3500 | _acceleration = _velocity; | 3552 | _acceleration = _velocity; |
3501 | 3553 | ||
3502 | if ((Math.Abs(vel.X) < 0.001f) && | 3554 | if ((Math.Abs(vel.X) < 0.005f) && |
3503 | (Math.Abs(vel.Y) < 0.001f) && | 3555 | (Math.Abs(vel.Y) < 0.005f) && |
3504 | (Math.Abs(vel.Z) < 0.001f)) | 3556 | (Math.Abs(vel.Z) < 0.005f)) |
3505 | { | 3557 | { |
3506 | _velocity = Vector3.Zero; | 3558 | _velocity = Vector3.Zero; |
3507 | float t = -m_invTimeStep; | 3559 | float t = -m_invTimeStep; |
@@ -3538,6 +3590,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3538 | } | 3590 | } |
3539 | } | 3591 | } |
3540 | 3592 | ||
3593 | _position.X = lpos.X; | ||
3594 | _position.Y = lpos.Y; | ||
3595 | _position.Z = lpos.Z; | ||
3596 | |||
3597 | _orientation.X = ori.X; | ||
3598 | _orientation.Y = ori.Y; | ||
3599 | _orientation.Z = ori.Z; | ||
3600 | _orientation.W = ori.W; | ||
3601 | |||
3541 | if (_zeroFlag) | 3602 | if (_zeroFlag) |
3542 | { | 3603 | { |
3543 | if (lastZeroFlag) | 3604 | if (lastZeroFlag) |
@@ -3556,14 +3617,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3556 | return; | 3617 | return; |
3557 | } | 3618 | } |
3558 | 3619 | ||
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(); | 3620 | base.RequestPhysicsterseUpdate(); |
3568 | m_lastUpdateSent = false; | 3621 | m_lastUpdateSent = false; |
3569 | } | 3622 | } |
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/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 754bc86..8abf6cf 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 | d.ContactFlags.Slip1 | d.ContactFlags.Slip2; |
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 = 0f; | ||
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; |
@@ -428,11 +411,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
428 | d.GeomSetCategoryBits(GroundSpace, (uint)(CollisionCategories.Land)); | 411 | d.GeomSetCategoryBits(GroundSpace, (uint)(CollisionCategories.Land)); |
429 | d.GeomSetCollideBits(GroundSpace, 0); | 412 | d.GeomSetCollideBits(GroundSpace, 0); |
430 | 413 | ||
431 | contactgroup = d.JointGroupCreate(0); | 414 | contactgroup = d.JointGroupCreate(maxContactsbeforedeath + 1); |
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 | } |