aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs7
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs13
-rw-r--r--OpenSim/Region/Physics/Manager/IMesher.cs1
-rw-r--r--OpenSim/Region/Physics/Manager/ZeroMesher.cs10
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs5
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs4
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Mesh.cs33
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs64
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs1230
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs19
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs6
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs105
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs2
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs290
14 files changed, 597 insertions, 1192 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index b7a0adf..a34c85f 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -1626,7 +1626,12 @@ namespace OpenSim.Framework
1626 BREAST_PHYSICS_LEFTRIGHT_MAX_EFFECT = 247, 1626 BREAST_PHYSICS_LEFTRIGHT_MAX_EFFECT = 247,
1627 BREAST_PHYSICS_LEFTRIGHT_SPRING= 248, 1627 BREAST_PHYSICS_LEFTRIGHT_SPRING= 248,
1628 BREAST_PHYSICS_LEFTRIGHT_GAIN = 249, 1628 BREAST_PHYSICS_LEFTRIGHT_GAIN = 249,
1629 BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250 1629 BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250,
1630
1631 // Ubit: 07/96/2013 new parameters
1632 _APPEARANCEMESSAGE_VERSION = 251, //ID 11000
1633
1634 SHAPE_HOVER = 252, //ID 11001
1630 } 1635 }
1631 #endregion 1636 #endregion
1632 } 1637 }
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 4c11135..a606d76 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
30using System; 31using System;
@@ -43,25 +44,7 @@ using OpenMetaverse;
43 44
44namespace OpenSim.Region.Physics.OdePlugin 45namespace 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 }