aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/WebUtil.cs28
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs40
-rw-r--r--OpenSim/Region/Physics/Manager/IMesher.cs4
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs2
-rw-r--r--OpenSim/Region/Physics/Manager/ZeroMesher.cs6
-rw-r--r--OpenSim/Region/Physics/Meshing/Mesh.cs6
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs10
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs90
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs11
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs41
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Mesh.cs84
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs104
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs1
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs916
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs823
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs321
18 files changed, 1523 insertions, 970 deletions
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs
index 8094b6d..30a8c28 100644
--- a/OpenSim/Framework/WebUtil.cs
+++ b/OpenSim/Framework/WebUtil.cs
@@ -706,9 +706,10 @@ namespace OpenSim.Framework
706 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); 706 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
707 707
708 int tickstart = Util.EnvironmentTickCount(); 708 int tickstart = Util.EnvironmentTickCount();
709 int tickdata = 0; 709// int tickdata = 0;
710 int tickdiff = 0;
710 711
711 // m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl); 712// m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl);
712 713
713 Type type = typeof(TRequest); 714 Type type = typeof(TRequest);
714 715
@@ -751,8 +752,8 @@ namespace OpenSim.Framework
751 requestStream.Close(); 752 requestStream.Close();
752 753
753 // capture how much time was spent writing 754 // capture how much time was spent writing
754 tickdata = Util.EnvironmentTickCountSubtract(tickstart); 755 // useless in this async
755 756// tickdata = Util.EnvironmentTickCountSubtract(tickstart);
756 request.BeginGetResponse(delegate(IAsyncResult ar) 757 request.BeginGetResponse(delegate(IAsyncResult ar)
757 { 758 {
758 response = request.EndGetResponse(ar); 759 response = request.EndGetResponse(ar);
@@ -769,7 +770,8 @@ namespace OpenSim.Framework
769 finally 770 finally
770 { 771 {
771 // Let's not close this 772 // Let's not close this
772 //buffer.Close(); 773 // yes do close it
774 buffer.Close();
773 respStream.Close(); 775 respStream.Close();
774 response.Close(); 776 response.Close();
775 } 777 }
@@ -837,7 +839,6 @@ namespace OpenSim.Framework
837 } 839 }
838 840
839 // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); 841 // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
840
841 try 842 try
842 { 843 {
843 action(deserial); 844 action(deserial);
@@ -852,9 +853,10 @@ namespace OpenSim.Framework
852 }, null); 853 }, null);
853 } 854 }
854 855
855 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); 856 tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
856 if (tickdiff > WebUtil.LongCallTime) 857 if (tickdiff > WebUtil.LongCallTime)
857 { 858 {
859/*
858 string originalRequest = null; 860 string originalRequest = null;
859 861
860 if (buffer != null) 862 if (buffer != null)
@@ -873,6 +875,13 @@ namespace OpenSim.Framework
873 tickdiff, 875 tickdiff,
874 tickdata, 876 tickdata,
875 originalRequest); 877 originalRequest);
878*/
879 m_log.InfoFormat(
880 "[ASYNC REQUEST]: Slow WebRequest SETUP <{0}> {1} {2} took {3}ms",
881 reqnum,
882 verb,
883 requestUrl,
884 tickdiff);
876 } 885 }
877 } 886 }
878 } 887 }
@@ -903,6 +912,8 @@ namespace OpenSim.Framework
903 request.Method = verb; 912 request.Method = verb;
904 string respstring = String.Empty; 913 string respstring = String.Empty;
905 914
915 int tickset = Util.EnvironmentTickCountSubtract(tickstart);
916
906 using (MemoryStream buffer = new MemoryStream()) 917 using (MemoryStream buffer = new MemoryStream())
907 { 918 {
908 if ((verb == "POST") || (verb == "PUT")) 919 if ((verb == "POST") || (verb == "PUT"))
@@ -979,11 +990,12 @@ namespace OpenSim.Framework
979 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); 990 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
980 if (tickdiff > WebUtil.LongCallTime) 991 if (tickdiff > WebUtil.LongCallTime)
981 m_log.InfoFormat( 992 m_log.InfoFormat(
982 "[FORMS]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", 993 "[FORMS]: Slow request to <{0}> {1} {2} took {3}ms {4}ms writing {5}",
983 reqnum, 994 reqnum,
984 verb, 995 verb,
985 requestUrl, 996 requestUrl,
986 tickdiff, 997 tickdiff,
998 tickset,
987 tickdata, 999 tickdata,
988 obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj); 1000 obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
989 1001
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index bd7bd82..4cb4370 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -525,7 +525,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
525 { 525 {
526 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 526 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
527 { 527 {
528 for (int j = 0; j < appearance.Wearables[j].Count; j++) 528 for (int j = 0; j < appearance.Wearables[i].Count; j++)
529 { 529 {
530 if (appearance.Wearables[i][j].ItemID == UUID.Zero) 530 if (appearance.Wearables[i][j].ItemID == UUID.Zero)
531 continue; 531 continue;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 4798481..4b22ebe 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -4299,8 +4299,8 @@ namespace OpenSim.Region.Framework.Scenes
4299 4299
4300 SceneObjectPart[] parts = m_parts.GetArray(); 4300 SceneObjectPart[] parts = m_parts.GetArray();
4301 4301
4302 for (int i = 0; i < parts.Length; i++) 4302// for (int i = 0; i < parts.Length; i++)
4303 parts[i].CheckSculptAndLoad(); 4303// parts[i].CheckSculptAndLoad();
4304 } 4304 }
4305 4305
4306 /// <summary> 4306 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index e6ad89c..633cd3b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1095,9 +1095,9 @@ namespace OpenSim.Region.Framework.Scenes
1095 { 1095 {
1096 actor.Size = m_shape.Scale; 1096 actor.Size = m_shape.Scale;
1097 1097
1098 if (Shape.SculptEntry) 1098// if (Shape.SculptEntry)
1099 CheckSculptAndLoad(); 1099// CheckSculptAndLoad();
1100 else 1100// else
1101 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 1101 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
1102 } 1102 }
1103 } 1103 }
@@ -1654,8 +1654,8 @@ namespace OpenSim.Region.Framework.Scenes
1654 else 1654 else
1655 { 1655 {
1656 PhysActor.PhysicsShapeType = m_physicsShapeType; 1656 PhysActor.PhysicsShapeType = m_physicsShapeType;
1657 if (Shape.SculptEntry) 1657// if (Shape.SculptEntry)
1658 CheckSculptAndLoad(); 1658// CheckSculptAndLoad();
1659 } 1659 }
1660 1660
1661 if (ParentGroup != null) 1661 if (ParentGroup != null)
@@ -2115,12 +2115,13 @@ namespace OpenSim.Region.Framework.Scenes
2115 2115
2116 if (userExposed) 2116 if (userExposed)
2117 { 2117 {
2118/*
2118 if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero) 2119 if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero)
2119 { 2120 {
2120 ParentGroup.Scene.AssetService.Get( 2121 ParentGroup.Scene.AssetService.Get(
2121 dupe.m_shape.SculptTexture.ToString(), dupe, dupe.AssetReceived); 2122 dupe.m_shape.SculptTexture.ToString(), dupe, dupe.AssetReceived);
2122 } 2123 }
2123 2124*/
2124 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 2125 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
2125 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 2126 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
2126// dupe.UpdatePhysicsSubscribedEvents(); // not sure... 2127// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
@@ -2142,6 +2143,7 @@ namespace OpenSim.Region.Framework.Scenes
2142 /// <param name="id">ID of asset received</param> 2143 /// <param name="id">ID of asset received</param>
2143 /// <param name="sender">Register</param> 2144 /// <param name="sender">Register</param>
2144 /// <param name="asset"></param> 2145 /// <param name="asset"></param>
2146/*
2145 protected void AssetReceived(string id, Object sender, AssetBase asset) 2147 protected void AssetReceived(string id, Object sender, AssetBase asset)
2146 { 2148 {
2147 if (asset != null) 2149 if (asset != null)
@@ -2151,7 +2153,7 @@ namespace OpenSim.Region.Framework.Scenes
2151// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", 2153// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
2152// Name, UUID, id); 2154// Name, UUID, id);
2153 } 2155 }
2154 2156*/
2155 /// <summary> 2157 /// <summary>
2156 /// Do a physics property update for a NINJA joint. 2158 /// Do a physics property update for a NINJA joint.
2157 /// </summary> 2159 /// </summary>
@@ -2341,9 +2343,9 @@ namespace OpenSim.Region.Framework.Scenes
2341 2343
2342 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2344 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
2343 // mesh data. 2345 // mesh data.
2344 if (Shape.SculptEntry) 2346// if (Shape.SculptEntry)
2345 CheckSculptAndLoad(); 2347// CheckSculptAndLoad();
2346 else 2348// else
2347 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); 2349 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
2348 } 2350 }
2349 } 2351 }
@@ -3125,6 +3127,7 @@ namespace OpenSim.Region.Framework.Scenes
3125 /// Set sculpt and mesh data, and tell the physics engine to process the change. 3127 /// Set sculpt and mesh data, and tell the physics engine to process the change.
3126 /// </summary> 3128 /// </summary>
3127 /// <param name="texture">The mesh itself.</param> 3129 /// <param name="texture">The mesh itself.</param>
3130/*
3128 public void SculptTextureCallback(AssetBase texture) 3131 public void SculptTextureCallback(AssetBase texture)
3129 { 3132 {
3130 if (m_shape.SculptEntry) 3133 if (m_shape.SculptEntry)
@@ -3152,7 +3155,7 @@ namespace OpenSim.Region.Framework.Scenes
3152 } 3155 }
3153 } 3156 }
3154 } 3157 }
3155 3158*/
3156 /// <summary> 3159 /// <summary>
3157 /// Send a full update to the client for the given part 3160 /// Send a full update to the client for the given part
3158 /// </summary> 3161 /// </summary>
@@ -4377,7 +4380,7 @@ namespace OpenSim.Region.Framework.Scenes
4377 public void UpdateExtraParam(ushort type, bool inUse, byte[] data) 4380 public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
4378 { 4381 {
4379 m_shape.ReadInUpdateExtraParam(type, inUse, data); 4382 m_shape.ReadInUpdateExtraParam(type, inUse, data);
4380 4383/*
4381 if (type == 0x30) 4384 if (type == 0x30)
4382 { 4385 {
4383 if (m_shape.SculptEntry && m_shape.SculptTexture != UUID.Zero) 4386 if (m_shape.SculptEntry && m_shape.SculptTexture != UUID.Zero)
@@ -4385,7 +4388,7 @@ namespace OpenSim.Region.Framework.Scenes
4385 ParentGroup.Scene.AssetService.Get(m_shape.SculptTexture.ToString(), this, AssetReceived); 4388 ParentGroup.Scene.AssetService.Get(m_shape.SculptTexture.ToString(), this, AssetReceived);
4386 } 4389 }
4387 } 4390 }
4388 4391*/
4389 if (ParentGroup != null) 4392 if (ParentGroup != null)
4390 { 4393 {
4391 ParentGroup.HasGroupChanged = true; 4394 ParentGroup.HasGroupChanged = true;
@@ -4793,9 +4796,9 @@ namespace OpenSim.Region.Framework.Scenes
4793 } 4796 }
4794 } 4797 }
4795 4798
4796 if (Shape.SculptEntry) 4799// if (Shape.SculptEntry)
4797 CheckSculptAndLoad(); 4800// CheckSculptAndLoad();
4798 else 4801// else
4799 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); 4802 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4800 4803
4801 if (!building) 4804 if (!building)
@@ -4898,10 +4901,13 @@ namespace OpenSim.Region.Framework.Scenes
4898 /// <remarks> 4901 /// <remarks>
4899 /// When the physics engine has finished with it, the sculpt data is discarded to save memory. 4902 /// When the physics engine has finished with it, the sculpt data is discarded to save memory.
4900 /// </remarks> 4903 /// </remarks>
4904/*
4901 public void CheckSculptAndLoad() 4905 public void CheckSculptAndLoad()
4902 { 4906 {
4903// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4907// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4904 4908
4909 return;
4910
4905 if (ParentGroup.IsDeleted) 4911 if (ParentGroup.IsDeleted)
4906 return; 4912 return;
4907 4913
@@ -4923,7 +4929,7 @@ namespace OpenSim.Region.Framework.Scenes
4923 } 4929 }
4924 } 4930 }
4925 } 4931 }
4926 4932*/
4927 /// <summary> 4933 /// <summary>
4928 /// Update the texture entry for this part. 4934 /// Update the texture entry for this part.
4929 /// </summary> 4935 /// </summary>
diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs
index a8c99f7..460b48e 100644
--- a/OpenSim/Region/Physics/Manager/IMesher.cs
+++ b/OpenSim/Region/Physics/Manager/IMesher.cs
@@ -37,7 +37,8 @@ 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); 40 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex);
41 IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex);
41 void ReleaseMesh(IMesh mesh); 42 void ReleaseMesh(IMesh mesh);
42 void ExpireReleaseMeshs(); 43 void ExpireReleaseMeshs();
43 } 44 }
@@ -81,5 +82,6 @@ namespace OpenSim.Region.Physics.Manager
81 void Append(IMesh newMesh); 82 void Append(IMesh newMesh);
82 void TransformLinear(float[,] matrix, float[] offset); 83 void TransformLinear(float[,] matrix, float[] offset);
83 Vector3 GetCentroid(); 84 Vector3 GetCentroid();
85 Vector3 GetOBB();
84 } 86 }
85} 87}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 5274f3b..46bfa59 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -106,7 +106,7 @@ namespace OpenSim.Region.Physics.Manager
106 get { return new NullPhysicsScene(); } 106 get { return new NullPhysicsScene(); }
107 } 107 }
108 108
109 public RequestAssetDelegate RequestAssetMethod { private get; set; } 109 public RequestAssetDelegate RequestAssetMethod { get; set; }
110 110
111 public virtual void TriggerPhysicsBasedRestart() 111 public virtual void TriggerPhysicsBasedRestart()
112 { 112 {
diff --git a/OpenSim/Region/Physics/Manager/ZeroMesher.cs b/OpenSim/Region/Physics/Manager/ZeroMesher.cs
index f555cb9..61da9f3 100644
--- a/OpenSim/Region/Physics/Manager/ZeroMesher.cs
+++ b/OpenSim/Region/Physics/Manager/ZeroMesher.cs
@@ -79,6 +79,12 @@ namespace OpenSim.Region.Physics.Manager
79 79
80 return null; 80 return null;
81 } 81 }
82
83 public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
84 {
85 return null;
86 }
87
82 public void ReleaseMesh(IMesh mesh) { } 88 public void ReleaseMesh(IMesh mesh) { }
83 public void ExpireReleaseMeshs() { } 89 public void ExpireReleaseMeshs() { }
84 } 90 }
diff --git a/OpenSim/Region/Physics/Meshing/Mesh.cs b/OpenSim/Region/Physics/Meshing/Mesh.cs
index c715642..c03f18b 100644
--- a/OpenSim/Region/Physics/Meshing/Mesh.cs
+++ b/OpenSim/Region/Physics/Meshing/Mesh.cs
@@ -148,6 +148,12 @@ namespace OpenSim.Region.Physics.Meshing
148 return Vector3.Zero; 148 return Vector3.Zero;
149 } 149 }
150 150
151 // not functional
152 public Vector3 GetOBB()
153 {
154 return new Vector3(0.5f, 0.5f, 0.5f);
155 }
156
151 public void CalcNormals() 157 public void CalcNormals()
152 { 158 {
153 int iTriangles = m_triangles.Count; 159 int iTriangles = m_triangles.Count;
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 236adb0..7a3f343 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -743,5 +743,15 @@ namespace OpenSim.Region.Physics.Meshing
743 743
744 return mesh; 744 return mesh;
745 } 745 }
746<<<<<<< HEAD
747 public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
748 {
749 return null;
750 }
751
752 public void ReleaseMesh(IMesh imesh) { }
753 public void ExpireReleaseMeshs() { }
754=======
755>>>>>>> avination
746 } 756 }
747} 757}
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index a41c856..b2c2d8a 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -63,6 +63,9 @@ namespace OpenSim.Region.Physics.OdePlugin
63 63
64 private bool m_isphysical; 64 private bool m_isphysical;
65 65
66 public int ExpectedCollisionContacts { get { return m_expectedCollisionContacts; } }
67 private int m_expectedCollisionContacts = 0;
68
66 /// <summary> 69 /// <summary>
67 /// Is this prim subject to physics? Even if not, it's still solid for collision purposes. 70 /// Is this prim subject to physics? Even if not, it's still solid for collision purposes.
68 /// </summary> 71 /// </summary>
@@ -97,6 +100,9 @@ namespace OpenSim.Region.Physics.OdePlugin
97 private Vector3 m_taintAngularLock = Vector3.One; 100 private Vector3 m_taintAngularLock = Vector3.One;
98 private IntPtr Amotor = IntPtr.Zero; 101 private IntPtr Amotor = IntPtr.Zero;
99 102
103 private object m_assetsLock = new object();
104 private bool m_assetFailed = false;
105
100 private Vector3 m_PIDTarget; 106 private Vector3 m_PIDTarget;
101 private float m_PIDTau; 107 private float m_PIDTau;
102 private float PID_D = 35f; 108 private float PID_D = 35f;
@@ -279,6 +285,7 @@ namespace OpenSim.Region.Physics.OdePlugin
279 } 285 }
280 286
281 m_taintadd = true; 287 m_taintadd = true;
288 m_assetFailed = false;
282 _parent_scene.AddPhysicsActorTaint(this); 289 _parent_scene.AddPhysicsActorTaint(this);
283 } 290 }
284 291
@@ -601,8 +608,8 @@ namespace OpenSim.Region.Physics.OdePlugin
601 break; 608 break;
602 609
603 case HollowShape.Circle: 610 case HollowShape.Circle:
604 // Hollow shape is a perfect cylinder in respect to the cube's scale 611 // Hollow shape is a perfect cyllinder in respect to the cube's scale
605 // Cylinder hollow volume calculation 612 // Cyllinder hollow volume calculation
606 613
607 hollowVolume *= 0.1963495f * 3.07920140172638f; 614 hollowVolume *= 0.1963495f * 3.07920140172638f;
608 break; 615 break;
@@ -840,7 +847,7 @@ namespace OpenSim.Region.Physics.OdePlugin
840 int vertexStride, triStride; 847 int vertexStride, triStride;
841 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap 848 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap
842 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage 849 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
843 850 m_expectedCollisionContacts = indexCount;
844 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory 851 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
845 852
846 // We must lock here since m_MeshToTriMeshMap is static and multiple scene threads may call this method at 853 // We must lock here since m_MeshToTriMeshMap is static and multiple scene threads may call this method at
@@ -1377,6 +1384,7 @@ Console.WriteLine("CreateGeom:");
1377 { 1384 {
1378//Console.WriteLine(" CreateGeom 1"); 1385//Console.WriteLine(" CreateGeom 1");
1379 SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2)); 1386 SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
1387 m_expectedCollisionContacts = 3;
1380 } 1388 }
1381 catch (AccessViolationException) 1389 catch (AccessViolationException)
1382 { 1390 {
@@ -1391,6 +1399,7 @@ Console.WriteLine("CreateGeom:");
1391 { 1399 {
1392//Console.WriteLine(" CreateGeom 2"); 1400//Console.WriteLine(" CreateGeom 2");
1393 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); 1401 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1402 m_expectedCollisionContacts = 4;
1394 } 1403 }
1395 catch (AccessViolationException) 1404 catch (AccessViolationException)
1396 { 1405 {
@@ -1406,6 +1415,7 @@ Console.WriteLine("CreateGeom:");
1406 { 1415 {
1407//Console.WriteLine(" CreateGeom 3"); 1416//Console.WriteLine(" CreateGeom 3");
1408 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); 1417 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1418 m_expectedCollisionContacts = 4;
1409 } 1419 }
1410 catch (AccessViolationException) 1420 catch (AccessViolationException)
1411 { 1421 {
@@ -1421,6 +1431,7 @@ Console.WriteLine("CreateGeom:");
1421 { 1431 {
1422//Console.WriteLine(" CreateGeom 4"); 1432//Console.WriteLine(" CreateGeom 4");
1423 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); 1433 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1434 m_expectedCollisionContacts = 4;
1424 } 1435 }
1425 catch (AccessViolationException) 1436 catch (AccessViolationException)
1426 { 1437 {
@@ -1446,11 +1457,13 @@ Console.WriteLine("CreateGeom:");
1446 _parent_scene.geom_name_map.Remove(prim_geom); 1457 _parent_scene.geom_name_map.Remove(prim_geom);
1447 _parent_scene.actor_name_map.Remove(prim_geom); 1458 _parent_scene.actor_name_map.Remove(prim_geom);
1448 d.GeomDestroy(prim_geom); 1459 d.GeomDestroy(prim_geom);
1460 m_expectedCollisionContacts = 0;
1449 prim_geom = IntPtr.Zero; 1461 prim_geom = IntPtr.Zero;
1450 } 1462 }
1451 catch (System.AccessViolationException) 1463 catch (System.AccessViolationException)
1452 { 1464 {
1453 prim_geom = IntPtr.Zero; 1465 prim_geom = IntPtr.Zero;
1466 m_expectedCollisionContacts = 0;
1454 m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); 1467 m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name);
1455 1468
1456 return false; 1469 return false;
@@ -1489,6 +1502,8 @@ Console.WriteLine("CreateGeom:");
1489 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); 1502 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
1490 // createmesh returns null when it's a shape that isn't a cube. 1503 // createmesh returns null when it's a shape that isn't a cube.
1491 // m_log.Debug(m_localID); 1504 // m_log.Debug(m_localID);
1505 if (mesh == null)
1506 CheckMeshAsset();
1492 } 1507 }
1493 1508
1494#if SPAM 1509#if SPAM
@@ -1988,7 +2003,12 @@ Console.WriteLine(" JointCreateFixed");
1988 // Don't need to re-enable body.. it's done in SetMesh 2003 // Don't need to re-enable body.. it's done in SetMesh
1989 2004
1990 if (_parent_scene.needsMeshing(_pbs)) 2005 if (_parent_scene.needsMeshing(_pbs))
2006 {
1991 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical); 2007 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical);
2008 if (mesh == null)
2009 CheckMeshAsset();
2010 }
2011
1992 } 2012 }
1993 2013
1994 CreateGeom(m_targetSpace, mesh); 2014 CreateGeom(m_targetSpace, mesh);
@@ -2048,6 +2068,8 @@ Console.WriteLine(" JointCreateFixed");
2048 /// </summary> 2068 /// </summary>
2049 private void changeshape() 2069 private void changeshape()
2050 { 2070 {
2071 m_taintshape = false;
2072
2051 // Cleanup of old prim geometry and Bodies 2073 // Cleanup of old prim geometry and Bodies
2052 if (IsPhysical && Body != IntPtr.Zero) 2074 if (IsPhysical && Body != IntPtr.Zero)
2053 { 2075 {
@@ -2075,6 +2097,7 @@ Console.WriteLine(" JointCreateFixed");
2075 2097
2076 IMesh mesh = null; 2098 IMesh mesh = null;
2077 2099
2100
2078 if (_parent_scene.needsMeshing(_pbs)) 2101 if (_parent_scene.needsMeshing(_pbs))
2079 { 2102 {
2080 // Don't need to re-enable body.. it's done in CreateMesh 2103 // Don't need to re-enable body.. it's done in CreateMesh
@@ -2085,6 +2108,8 @@ Console.WriteLine(" JointCreateFixed");
2085 2108
2086 // createmesh returns null when it doesn't mesh. 2109 // createmesh returns null when it doesn't mesh.
2087 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical); 2110 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical);
2111 if (mesh == null)
2112 CheckMeshAsset();
2088 } 2113 }
2089 2114
2090 CreateGeom(m_targetSpace, mesh); 2115 CreateGeom(m_targetSpace, mesh);
@@ -2121,7 +2146,7 @@ Console.WriteLine(" JointCreateFixed");
2121 } 2146 }
2122 2147
2123 resetCollisionAccounting(); 2148 resetCollisionAccounting();
2124 m_taintshape = false; 2149// m_taintshape = false;
2125 } 2150 }
2126 2151
2127 /// <summary> 2152 /// <summary>
@@ -2387,6 +2412,7 @@ Console.WriteLine(" JointCreateFixed");
2387 set 2412 set
2388 { 2413 {
2389 _pbs = value; 2414 _pbs = value;
2415 m_assetFailed = false;
2390 m_taintshape = true; 2416 m_taintshape = true;
2391 } 2417 }
2392 } 2418 }
@@ -2395,15 +2421,15 @@ Console.WriteLine(" JointCreateFixed");
2395 { 2421 {
2396 get 2422 get
2397 { 2423 {
2398 // Averate previous velocity with the new one so 2424 // Average previous velocity with the new one so
2399 // client object interpolation works a 'little' better 2425 // client object interpolation works a 'little' better
2400 if (_zeroFlag) 2426 if (_zeroFlag)
2401 return Vector3.Zero; 2427 return Vector3.Zero;
2402 2428
2403 Vector3 returnVelocity = Vector3.Zero; 2429 Vector3 returnVelocity = Vector3.Zero;
2404 returnVelocity.X = (m_lastVelocity.X + _velocity.X)/2; 2430 returnVelocity.X = (m_lastVelocity.X + _velocity.X) * 0.5f; // 0.5f is mathematically equiv to '/ 2'
2405 returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y)/2; 2431 returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y) * 0.5f;
2406 returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z)/2; 2432 returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z) * 0.5f;
2407 return returnVelocity; 2433 return returnVelocity;
2408 } 2434 }
2409 set 2435 set
@@ -2600,6 +2626,7 @@ Console.WriteLine(" JointCreateFixed");
2600 { 2626 {
2601 Vector3 pv = Vector3.Zero; 2627 Vector3 pv = Vector3.Zero;
2602 bool lastZeroFlag = _zeroFlag; 2628 bool lastZeroFlag = _zeroFlag;
2629 float m_minvelocity = 0;
2603 if (Body != (IntPtr)0) // FIXME -> or if it is a joint 2630 if (Body != (IntPtr)0) // FIXME -> or if it is a joint
2604 { 2631 {
2605 d.Vector3 vec = d.BodyGetPosition(Body); 2632 d.Vector3 vec = d.BodyGetPosition(Body);
@@ -2752,8 +2779,21 @@ Console.WriteLine(" JointCreateFixed");
2752 _acceleration = ((_velocity - m_lastVelocity) / 0.1f); 2779 _acceleration = ((_velocity - m_lastVelocity) / 0.1f);
2753 _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f, _velocity.Z - m_lastVelocity.Z / 0.1f); 2780 _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f, _velocity.Z - m_lastVelocity.Z / 0.1f);
2754 //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString()); 2781 //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString());
2782
2783 // Note here that linearvelocity is affecting angular velocity... so I'm guessing this is a vehicle specific thing...
2784 // it does make sense to do this for tiny little instabilities with physical prim, however 0.5m/frame is fairly large.
2785 // reducing this to 0.02m/frame seems to help the angular rubberbanding quite a bit, however, to make sure it doesn't affect elevators and vehicles
2786 // adding these logical exclusion situations to maintain this where I think it was intended to be.
2787 if (m_throttleUpdates || m_usePID || (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) || (Amotor != IntPtr.Zero))
2788 {
2789 m_minvelocity = 0.5f;
2790 }
2791 else
2792 {
2793 m_minvelocity = 0.02f;
2794 }
2755 2795
2756 if (_velocity.ApproxEquals(pv, 0.5f)) 2796 if (_velocity.ApproxEquals(pv, m_minvelocity))
2757 { 2797 {
2758 m_rotationalVelocity = pv; 2798 m_rotationalVelocity = pv;
2759 } 2799 }
@@ -3211,5 +3251,37 @@ Console.WriteLine(" JointCreateFixed");
3211 { 3251 {
3212 m_material = pMaterial; 3252 m_material = pMaterial;
3213 } 3253 }
3254
3255
3256 private void CheckMeshAsset()
3257 {
3258 if (_pbs.SculptEntry && !m_assetFailed && _pbs.SculptTexture != UUID.Zero)
3259 {
3260 m_assetFailed = true;
3261 Util.FireAndForget(delegate
3262 {
3263 RequestAssetDelegate assetProvider = _parent_scene.RequestAssetMethod;
3264 if (assetProvider != null)
3265 assetProvider(_pbs.SculptTexture, MeshAssetReveived);
3266 });
3267 }
3268 }
3269
3270 void MeshAssetReveived(AssetBase asset)
3271 {
3272 if (asset.Data != null && asset.Data.Length > 0)
3273 {
3274 if (!_pbs.SculptEntry)
3275 return;
3276 if (_pbs.SculptTexture.ToString() != asset.ID)
3277 return;
3278
3279 _pbs.SculptData = new byte[asset.Data.Length];
3280 asset.Data.CopyTo(_pbs.SculptData, 0);
3281 m_assetFailed = false;
3282 m_taintshape = true;
3283 _parent_scene.AddPhysicsActorTaint(this);
3284 }
3285 }
3214 } 3286 }
3215} \ No newline at end of file 3287} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
index 7e3ec63..8d7d3b3 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
@@ -137,15 +137,8 @@ namespace OpenSim.Region.Physics.OdePlugin
137 ODERayCastRequest[] reqs = m_PendingRequests.ToArray(); 137 ODERayCastRequest[] reqs = m_PendingRequests.ToArray();
138 for (int i = 0; i < reqs.Length; i++) 138 for (int i = 0; i < reqs.Length; i++)
139 { 139 {
140 try 140 if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast
141 { 141 RayCast(reqs[i]); // if there isn't anyone to send results
142 if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast
143 RayCast(reqs[i]); // if there isn't anyone to send results
144 }
145 catch
146 {
147 //Fail silently
148 }
149 } 142 }
150 143
151 m_PendingRequests.Clear(); 144 m_PendingRequests.Clear();
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 929b019..7a50c4c 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -336,6 +336,7 @@ namespace OpenSim.Region.Physics.OdePlugin
336 336
337 public int geomContactPointsStartthrottle = 3; 337 public int geomContactPointsStartthrottle = 3;
338 public int geomUpdatesPerThrottledUpdate = 15; 338 public int geomUpdatesPerThrottledUpdate = 15;
339 private const int avatarExpectedContacts = 3;
339 340
340 public float bodyPIDD = 35f; 341 public float bodyPIDD = 35f;
341 public float bodyPIDG = 25; 342 public float bodyPIDG = 25;
@@ -474,6 +475,8 @@ namespace OpenSim.Region.Physics.OdePlugin
474 private OdePrim cp1; 475 private OdePrim cp1;
475 private OdeCharacter cc2; 476 private OdeCharacter cc2;
476 private OdePrim cp2; 477 private OdePrim cp2;
478 private int p1ExpectedPoints = 0;
479 private int p2ExpectedPoints = 0;
477 //private int cStartStop = 0; 480 //private int cStartStop = 0;
478 //private string cDictKey = ""; 481 //private string cDictKey = "";
479 482
@@ -498,6 +501,7 @@ namespace OpenSim.Region.Physics.OdePlugin
498 public int physics_logging_interval = 0; 501 public int physics_logging_interval = 0;
499 public bool physics_logging_append_existing_logfile = false; 502 public bool physics_logging_append_existing_logfile = false;
500 503
504
501 public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f); 505 public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f);
502 public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f); 506 public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f);
503 507
@@ -644,7 +648,7 @@ namespace OpenSim.Region.Physics.OdePlugin
644 648
645 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); 649 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80);
646 650
647 geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); 651 geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 5);
648 geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); 652 geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15);
649 geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); 653 geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5);
650 654
@@ -1064,7 +1068,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1064 1068
1065 PhysicsActor p1; 1069 PhysicsActor p1;
1066 PhysicsActor p2; 1070 PhysicsActor p2;
1067 1071
1072 p1ExpectedPoints = 0;
1073 p2ExpectedPoints = 0;
1074
1068 if (!actor_name_map.TryGetValue(g1, out p1)) 1075 if (!actor_name_map.TryGetValue(g1, out p1))
1069 { 1076 {
1070 p1 = PANull; 1077 p1 = PANull;
@@ -1121,9 +1128,13 @@ namespace OpenSim.Region.Physics.OdePlugin
1121 switch (p1.PhysicsActorType) 1128 switch (p1.PhysicsActorType)
1122 { 1129 {
1123 case (int)ActorTypes.Agent: 1130 case (int)ActorTypes.Agent:
1131 p1ExpectedPoints = avatarExpectedContacts;
1124 p2.CollidingObj = true; 1132 p2.CollidingObj = true;
1125 break; 1133 break;
1126 case (int)ActorTypes.Prim: 1134 case (int)ActorTypes.Prim:
1135 if (p1 != null && p1 is OdePrim)
1136 p1ExpectedPoints = ((OdePrim) p1).ExpectedCollisionContacts;
1137
1127 if (p2.Velocity.LengthSquared() > 0.0f) 1138 if (p2.Velocity.LengthSquared() > 0.0f)
1128 p2.CollidingObj = true; 1139 p2.CollidingObj = true;
1129 break; 1140 break;
@@ -1319,6 +1330,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1319 if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && 1330 if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
1320 (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) 1331 (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
1321 { 1332 {
1333 p2ExpectedPoints = avatarExpectedContacts;
1322 // Avatar is moving on terrain, use the movement terrain contact 1334 // Avatar is moving on terrain, use the movement terrain contact
1323 AvatarMovementTerrainContact.geom = curContact; 1335 AvatarMovementTerrainContact.geom = curContact;
1324 1336
@@ -1332,6 +1344,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1332 { 1344 {
1333 if (p2.PhysicsActorType == (int)ActorTypes.Agent) 1345 if (p2.PhysicsActorType == (int)ActorTypes.Agent)
1334 { 1346 {
1347 p2ExpectedPoints = avatarExpectedContacts;
1335 // Avatar is standing on terrain, use the non moving terrain contact 1348 // Avatar is standing on terrain, use the non moving terrain contact
1336 TerrainContact.geom = curContact; 1349 TerrainContact.geom = curContact;
1337 1350
@@ -1356,9 +1369,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1356 } 1369 }
1357 1370
1358 if (p2 is OdePrim) 1371 if (p2 is OdePrim)
1359 material = ((OdePrim)p2).m_material; 1372 {
1360 1373 material = ((OdePrim) p2).m_material;
1374 p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
1375 }
1376
1377 // Unnessesary because p1 is defined above
1378 //if (p1 is OdePrim)
1379 // {
1380 // p1ExpectedPoints = ((OdePrim)p1).ExpectedCollisionContacts;
1381 // }
1361 //m_log.DebugFormat("Material: {0}", material); 1382 //m_log.DebugFormat("Material: {0}", material);
1383
1362 m_materialContacts[material, movintYN].geom = curContact; 1384 m_materialContacts[material, movintYN].geom = curContact;
1363 1385
1364 if (m_global_contactcount < maxContactsbeforedeath) 1386 if (m_global_contactcount < maxContactsbeforedeath)
@@ -1379,7 +1401,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1379 int material = (int)Material.Wood; 1401 int material = (int)Material.Wood;
1380 1402
1381 if (p2 is OdePrim) 1403 if (p2 is OdePrim)
1404 {
1382 material = ((OdePrim)p2).m_material; 1405 material = ((OdePrim)p2).m_material;
1406 p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
1407 }
1383 1408
1384 //m_log.DebugFormat("Material: {0}", material); 1409 //m_log.DebugFormat("Material: {0}", material);
1385 m_materialContacts[material, movintYN].geom = curContact; 1410 m_materialContacts[material, movintYN].geom = curContact;
@@ -1429,6 +1454,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1429 { 1454 {
1430 if ((p2.PhysicsActorType == (int)ActorTypes.Agent)) 1455 if ((p2.PhysicsActorType == (int)ActorTypes.Agent))
1431 { 1456 {
1457 p2ExpectedPoints = avatarExpectedContacts;
1432 if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) 1458 if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
1433 { 1459 {
1434 // Avatar is moving on a prim, use the Movement prim contact 1460 // Avatar is moving on a prim, use the Movement prim contact
@@ -1458,7 +1484,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1458 int material = (int)Material.Wood; 1484 int material = (int)Material.Wood;
1459 1485
1460 if (p2 is OdePrim) 1486 if (p2 is OdePrim)
1487 {
1461 material = ((OdePrim)p2).m_material; 1488 material = ((OdePrim)p2).m_material;
1489 p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
1490 }
1462 1491
1463 //m_log.DebugFormat("Material: {0}", material); 1492 //m_log.DebugFormat("Material: {0}", material);
1464 m_materialContacts[material, 0].geom = curContact; 1493 m_materialContacts[material, 0].geom = curContact;
@@ -1479,8 +1508,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1479 } 1508 }
1480 1509
1481 collision_accounting_events(p1, p2, maxDepthContact); 1510 collision_accounting_events(p1, p2, maxDepthContact);
1482 1511
1483 if (count > geomContactPointsStartthrottle) 1512 if (count > ((p1ExpectedPoints + p2ExpectedPoints) * 0.25) + (geomContactPointsStartthrottle))
1484 { 1513 {
1485 // If there are more then 3 contact points, it's likely 1514 // If there are more then 3 contact points, it's likely
1486 // that we've got a pile of objects, so ... 1515 // that we've got a pile of objects, so ...
diff --git a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs
index 98c0f0b..c31ec08 100644
--- a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs
@@ -48,8 +48,14 @@ namespace OpenSim.Region.Physics.Meshing
48 int m_indexCount = 0; 48 int m_indexCount = 0;
49 public float[] m_normals; 49 public float[] m_normals;
50 Vector3 m_centroid; 50 Vector3 m_centroid;
51 int m_centroidDiv; 51 float m_obbXmin;
52 float m_obbXmax;
53 float m_obbYmin;
54 float m_obbYmax;
55 float m_obbZmin;
56 float m_obbZmax;
52 57
58 int m_centroidDiv;
53 59
54 private class vertexcomp : IEqualityComparer<Vertex> 60 private class vertexcomp : IEqualityComparer<Vertex>
55 { 61 {
@@ -77,6 +83,12 @@ namespace OpenSim.Region.Physics.Meshing
77 m_triangles = new List<Triangle>(); 83 m_triangles = new List<Triangle>();
78 m_centroid = Vector3.Zero; 84 m_centroid = Vector3.Zero;
79 m_centroidDiv = 0; 85 m_centroidDiv = 0;
86 m_obbXmin = float.MaxValue;
87 m_obbXmax = float.MinValue;
88 m_obbYmin = float.MaxValue;
89 m_obbYmax = float.MinValue;
90 m_obbZmin = float.MaxValue;
91 m_obbZmax = float.MinValue;
80 } 92 }
81 93
82 public int RefCount { get; set; } 94 public int RefCount { get; set; }
@@ -85,8 +97,6 @@ namespace OpenSim.Region.Physics.Meshing
85 97
86 public void Scale(Vector3 scale) 98 public void Scale(Vector3 scale)
87 { 99 {
88
89
90 } 100 }
91 101
92 public Mesh Clone() 102 public Mesh Clone()
@@ -99,9 +109,44 @@ namespace OpenSim.Region.Physics.Meshing
99 } 109 }
100 result.m_centroid = m_centroid; 110 result.m_centroid = m_centroid;
101 result.m_centroidDiv = m_centroidDiv; 111 result.m_centroidDiv = m_centroidDiv;
112 result.m_obbXmin = m_obbXmin;
113 result.m_obbXmax = m_obbXmax;
114 result.m_obbYmin = m_obbYmin;
115 result.m_obbYmax = m_obbYmax;
116 result.m_obbZmin = m_obbZmin;
117 result.m_obbZmax = m_obbZmax;
102 return result; 118 return result;
103 } 119 }
104 120
121 public void addVertexLStats(Vertex v)
122 {
123 float x = v.X;
124 float y = v.Y;
125 float z = v.Z;
126
127 m_centroid.X += x;
128 m_centroid.Y += y;
129 m_centroid.Z += z;
130 m_centroidDiv++;
131
132 if (x > m_obbXmax)
133 m_obbXmax = x;
134 else if (x < m_obbXmin)
135 m_obbXmin = x;
136
137 if (y > m_obbYmax)
138 m_obbYmax = y;
139 else if (y < m_obbYmin)
140 m_obbYmin = y;
141
142 if (z > m_obbZmax)
143 m_obbZmax = z;
144 else if (z < m_obbZmin)
145 m_obbZmin = z;
146
147 }
148
149
105 public void Add(Triangle triangle) 150 public void Add(Triangle triangle)
106 { 151 {
107 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) 152 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
@@ -127,26 +172,17 @@ namespace OpenSim.Region.Physics.Meshing
127 if (!m_vertices.ContainsKey(triangle.v1)) 172 if (!m_vertices.ContainsKey(triangle.v1))
128 { 173 {
129 m_vertices[triangle.v1] = m_vertices.Count; 174 m_vertices[triangle.v1] = m_vertices.Count;
130 m_centroid.X += triangle.v1.X; 175 addVertexLStats(triangle.v1);
131 m_centroid.Y += triangle.v1.Y;
132 m_centroid.Z += triangle.v1.Z;
133 m_centroidDiv++;
134 } 176 }
135 if (!m_vertices.ContainsKey(triangle.v2)) 177 if (!m_vertices.ContainsKey(triangle.v2))
136 { 178 {
137 m_vertices[triangle.v2] = m_vertices.Count; 179 m_vertices[triangle.v2] = m_vertices.Count;
138 m_centroid.X += triangle.v2.X; 180 addVertexLStats(triangle.v2);
139 m_centroid.Y += triangle.v2.Y;
140 m_centroid.Z += triangle.v2.Z;
141 m_centroidDiv++;
142 } 181 }
143 if (!m_vertices.ContainsKey(triangle.v3)) 182 if (!m_vertices.ContainsKey(triangle.v3))
144 { 183 {
145 m_vertices[triangle.v3] = m_vertices.Count; 184 m_vertices[triangle.v3] = m_vertices.Count;
146 m_centroid.X += triangle.v3.X; 185 addVertexLStats(triangle.v3);
147 m_centroid.Y += triangle.v3.Y;
148 m_centroid.Z += triangle.v3.Z;
149 m_centroidDiv++;
150 } 186 }
151 m_triangles.Add(triangle); 187 m_triangles.Add(triangle);
152 } 188 }
@@ -159,6 +195,24 @@ namespace OpenSim.Region.Physics.Meshing
159 return Vector3.Zero; 195 return Vector3.Zero;
160 } 196 }
161 197
198 public Vector3 GetOBB()
199 {
200 float x, y, z;
201 if (m_centroidDiv > 0)
202 {
203 x = (m_obbXmax - m_obbXmin) * 0.5f;
204 y = (m_obbYmax - m_obbYmin) * 0.5f;
205 z = (m_obbZmax - m_obbZmin) * 0.5f;
206 }
207 else // ??
208 {
209 x = 0.5f;
210 y = 0.5f;
211 z = 0.5f;
212 }
213 return new Vector3(x, y, z);
214 }
215
162 public void CalcNormals() 216 public void CalcNormals()
163 { 217 {
164 int iTriangles = m_triangles.Count; 218 int iTriangles = m_triangles.Count;
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
index 4c40175..2933d86 100644
--- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
@@ -74,10 +74,6 @@ namespace OpenSim.Region.Physics.Meshing
74 private const string baseDir = null; //"rawFiles"; 74 private const string baseDir = null; //"rawFiles";
75#endif 75#endif
76 76
77 private bool cacheSculptMaps = true;
78 private bool cacheSculptAlphaMaps = true;
79
80 private string decodedSculptMapPath = null;
81 private bool useMeshiesPhysicsMesh = false; 77 private bool useMeshiesPhysicsMesh = false;
82 78
83 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 79 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
@@ -92,29 +88,9 @@ namespace OpenSim.Region.Physics.Meshing
92 IConfig start_config = config.Configs["Startup"]; 88 IConfig start_config = config.Configs["Startup"];
93 IConfig mesh_config = config.Configs["Mesh"]; 89 IConfig mesh_config = config.Configs["Mesh"];
94 90
95 decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
96
97 cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
98
99 if (Environment.OSVersion.Platform == PlatformID.Unix)
100 {
101 cacheSculptAlphaMaps = false;
102 }
103 else
104 cacheSculptAlphaMaps = cacheSculptMaps;
105
106 if(mesh_config != null) 91 if(mesh_config != null)
107 useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); 92 useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
108 93
109 try
110 {
111 if (!Directory.Exists(decodedSculptMapPath))
112 Directory.CreateDirectory(decodedSculptMapPath);
113 }
114 catch (Exception e)
115 {
116 m_log.WarnFormat("[SCULPT]: Unable to create {0} directory: ", decodedSculptMapPath, e.Message);
117 }
118 } 94 }
119 95
120 /// <summary> 96 /// <summary>
@@ -444,7 +420,7 @@ namespace OpenSim.Region.Physics.Meshing
444 // physics_shape is an array of OSDMaps, one for each submesh 420 // physics_shape is an array of OSDMaps, one for each submesh
445 if (decodedMeshOsd is OSDArray) 421 if (decodedMeshOsd is OSDArray)
446 { 422 {
447 // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); 423// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
448 424
449 decodedMeshOsdArray = (OSDArray)decodedMeshOsd; 425 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
450 foreach (OSD subMeshOsd in decodedMeshOsdArray) 426 foreach (OSD subMeshOsd in decodedMeshOsdArray)
@@ -717,29 +693,7 @@ namespace OpenSim.Region.Physics.Meshing
717 faces = new List<Face>(); 693 faces = new List<Face>();
718 PrimMesher.SculptMesh sculptMesh; 694 PrimMesher.SculptMesh sculptMesh;
719 Image idata = null; 695 Image idata = null;
720 string decodedSculptFileName = "";
721 696
722 if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)
723 {
724 decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString());
725 try
726 {
727 if (File.Exists(decodedSculptFileName))
728 {
729 idata = Image.FromFile(decodedSculptFileName);
730 }
731 }
732 catch (Exception e)
733 {
734 m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message);
735
736 }
737 //if (idata != null)
738 // m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString());
739 }
740
741 if (idata == null)
742 {
743 if (primShape.SculptData == null || primShape.SculptData.Length == 0) 697 if (primShape.SculptData == null || primShape.SculptData.Length == 0)
744 return false; 698 return false;
745 699
@@ -748,25 +702,15 @@ namespace OpenSim.Region.Physics.Meshing
748 OpenMetaverse.Imaging.ManagedImage unusedData; 702 OpenMetaverse.Imaging.ManagedImage unusedData;
749 OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata); 703 OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata);
750 704
705 unusedData = null;
706
751 if (idata == null) 707 if (idata == null)
752 { 708 {
753 // In some cases it seems that the decode can return a null bitmap without throwing 709 // In some cases it seems that the decode can return a null bitmap without throwing
754 // an exception 710 // an exception
755 m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName); 711 m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName);
756
757 return false; 712 return false;
758 } 713 }
759
760 unusedData = null;
761
762 //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
763
764 if (cacheSculptMaps && (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) ==0)))
765 // don't cache images with alpha channel in linux since mono can't load them correctly)
766 {
767 try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
768 catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
769 }
770 } 714 }
771 catch (DllNotFoundException) 715 catch (DllNotFoundException)
772 { 716 {
@@ -783,7 +727,6 @@ namespace OpenSim.Region.Physics.Meshing
783 m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message); 727 m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message);
784 return false; 728 return false;
785 } 729 }
786 }
787 730
788 PrimMesher.SculptMesh.SculptType sculptType; 731 PrimMesher.SculptMesh.SculptType sculptType;
789 // remove mirror and invert bits 732 // remove mirror and invert bits
@@ -1048,7 +991,6 @@ namespace OpenSim.Region.Physics.Meshing
1048 return ((hash << 5) + hash) + (ulong)(c >> 8); 991 return ((hash << 5) + hash) + (ulong)(c >> 8);
1049 } 992 }
1050 993
1051
1052 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 994 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
1053 { 995 {
1054 return CreateMesh(primName, primShape, size, lod, false,false); 996 return CreateMesh(primName, primShape, size, lod, false,false);
@@ -1061,6 +1003,42 @@ namespace OpenSim.Region.Physics.Meshing
1061 1003
1062 private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f); 1004 private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f);
1063 1005
1006 public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
1007 {
1008 Mesh mesh = null;
1009
1010 if (size.X < 0.01f) size.X = 0.01f;
1011 if (size.Y < 0.01f) size.Y = 0.01f;
1012 if (size.Z < 0.01f) size.Z = 0.01f;
1013
1014 AMeshKey key = GetMeshUniqueKey(primShape, size, (byte)lod, convex);
1015 lock (m_uniqueMeshes)
1016 {
1017 m_uniqueMeshes.TryGetValue(key, out mesh);
1018
1019 if (mesh != null)
1020 {
1021 mesh.RefCount++;
1022 return mesh;
1023 }
1024 }
1025
1026 // try to find a identical mesh on meshs recently released
1027 lock (m_uniqueReleasedMeshes)
1028 {
1029 m_uniqueReleasedMeshes.TryGetValue(key, out mesh);
1030 if (mesh != null)
1031 {
1032 m_uniqueReleasedMeshes.Remove(key);
1033 lock (m_uniqueMeshes)
1034 m_uniqueMeshes.Add(key, mesh);
1035 mesh.RefCount = 1;
1036 return mesh;
1037 }
1038 }
1039 return null;
1040 }
1041
1064 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) 1042 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
1065 { 1043 {
1066#if SPAM 1044#if SPAM
@@ -1068,15 +1046,13 @@ namespace OpenSim.Region.Physics.Meshing
1068#endif 1046#endif
1069 1047
1070 Mesh mesh = null; 1048 Mesh mesh = null;
1071// ulong key = 0;
1072
1073 1049
1074 if (size.X < 0.01f) size.X = 0.01f; 1050 if (size.X < 0.01f) size.X = 0.01f;
1075 if (size.Y < 0.01f) size.Y = 0.01f; 1051 if (size.Y < 0.01f) size.Y = 0.01f;
1076 if (size.Z < 0.01f) size.Z = 0.01f; 1052 if (size.Z < 0.01f) size.Z = 0.01f;
1077 1053
1078 // try to find a identical mesh on meshs in use 1054 // try to find a identical mesh on meshs in use
1079// key = primShape.GetMeshKey(size, lod, convex); 1055
1080 AMeshKey key = GetMeshUniqueKey(primShape,size,(byte)lod, convex); 1056 AMeshKey key = GetMeshUniqueKey(primShape,size,(byte)lod, convex);
1081 1057
1082 lock (m_uniqueMeshes) 1058 lock (m_uniqueMeshes)
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index c363310..f5bf05d 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -172,7 +172,6 @@ namespace OpenSim.Region.Physics.OdePlugin
172 // force lower density for testing 172 // force lower density for testing
173 m_density = 3.0f; 173 m_density = 3.0f;
174 174
175
176 mu = parent_scene.AvatarFriction; 175 mu = parent_scene.AvatarFriction;
177 176
178 walkDivisor = walk_divisor; 177 walkDivisor = walk_divisor;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
new file mode 100644
index 0000000..3fcbb1b
--- /dev/null
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
@@ -0,0 +1,916 @@
1/*
2 * AJLDuarte 2012
3 */
4
5using System;
6using System.Threading;
7using System.Collections.Generic;
8using System.IO;
9using System.Reflection;
10using System.Runtime.InteropServices;
11using System.Text;
12using OpenSim.Framework;
13using OpenSim.Region.Physics.Manager;
14using OdeAPI;
15using log4net;
16using Nini.Config;
17using OpenMetaverse;
18
19namespace OpenSim.Region.Physics.OdePlugin
20{
21 public enum meshWorkerCmnds : byte
22 {
23 nop = 0,
24 addnew,
25 changefull,
26 changesize,
27 changeshapetype,
28 getmesh,
29 }
30
31 public class ODEPhysRepData
32 {
33 public PhysicsActor actor;
34 public PrimitiveBaseShape pbs;
35 public IMesh mesh;
36
37 public Vector3 size;
38 public Vector3 OBB;
39 public Vector3 OBBOffset;
40
41 public float volume;
42
43 public float physCost;
44 public float streamCost;
45 public byte shapetype;
46 public bool hasOBB;
47 public bool hasMeshVolume;
48 public AssetState assetState;
49 public UUID? assetID;
50 public meshWorkerCmnds comand;
51 }
52
53
54
55 public class ODEMeshWorker
56 {
57
58 private ILog m_log;
59 private OdeScene m_scene;
60 private IMesher m_mesher;
61
62 public bool meshSculptedPrim = true;
63 public bool forceSimplePrimMeshing = false;
64 public float meshSculptLOD = 32;
65 public float MeshSculptphysicalLOD = 32;
66
67
68 private OpenSim.Framework.BlockingQueue<ODEPhysRepData> createqueue = new OpenSim.Framework.BlockingQueue<ODEPhysRepData>();
69 private bool m_running;
70
71 private Thread m_thread;
72
73 public ODEMeshWorker(OdeScene pScene, ILog pLog, IMesher pMesher, IConfig pConfig)
74 {
75 m_scene = pScene;
76 m_log = pLog;
77 m_mesher = pMesher;
78
79 if (pConfig != null)
80 {
81 forceSimplePrimMeshing = pConfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing);
82 meshSculptedPrim = pConfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim);
83 meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD);
84 MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
85 }
86 m_running = true;
87 m_thread = new Thread(DoWork);
88 m_thread.Start();
89 }
90
91 private void DoWork()
92 {
93 while(m_running)
94 {
95 ODEPhysRepData nextRep = createqueue.Dequeue();
96 if(!m_running)
97 return;
98 if (nextRep == null)
99 continue;
100 if (m_scene.haveActor(nextRep.actor))
101 {
102 switch (nextRep.comand)
103 {
104 case meshWorkerCmnds.changefull:
105 case meshWorkerCmnds.changeshapetype:
106 case meshWorkerCmnds.changesize:
107 if (CreateActorPhysRep(nextRep) && m_scene.haveActor(nextRep.actor))
108 m_scene.AddChange(nextRep.actor, changes.PhysRepData, nextRep);
109 break;
110 case meshWorkerCmnds.addnew:
111 if (CreateActorPhysRep(nextRep))
112 m_scene.AddChange(nextRep.actor, changes.AddPhysRep, nextRep);
113 break;
114 case meshWorkerCmnds.getmesh:
115 DoRepDataGetMesh(nextRep);
116 break;
117 }
118 }
119 }
120 }
121
122 public void Stop()
123 {
124 m_running = false;
125 m_thread.Abort();
126 }
127
128 public void ChangeActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs,
129 Vector3 size, byte shapetype)
130 {
131 ODEPhysRepData repData = new ODEPhysRepData();
132 repData.actor = actor;
133 repData.pbs = pbs;
134 repData.size = size;
135 repData.shapetype = shapetype;
136
137 // if (CheckMeshDone(repData))
138 {
139 CheckMeshDone(repData);
140 CalcVolumeData(repData);
141 m_scene.AddChange(actor, changes.PhysRepData, repData);
142 return;
143 }
144
145// repData.comand = meshWorkerCmnds.changefull;
146// createqueue.Enqueue(repData);
147 }
148
149 public void NewActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs,
150 Vector3 size, byte shapetype)
151 {
152 ODEPhysRepData repData = new ODEPhysRepData();
153 repData.actor = actor;
154 repData.pbs = pbs;
155 repData.size = size;
156 repData.shapetype = shapetype;
157
158 // bool done = CheckMeshDone(repData);
159
160 CheckMeshDone(repData);
161 CalcVolumeData(repData);
162 m_scene.AddChange(actor, changes.AddPhysRep, repData);
163// if (done)
164 return;
165
166// repData.comand = meshWorkerCmnds.addnew;
167// createqueue.Enqueue(repData);
168 }
169
170 public void RequestMeshAsset(ODEPhysRepData repData)
171 {
172 if (repData.assetState != AssetState.needAsset)
173 return;
174
175 if (repData.assetID == null || repData.assetID == UUID.Zero)
176 return;
177
178 repData.mesh = null;
179
180 repData.assetState = AssetState.loadingAsset;
181
182 repData.comand = meshWorkerCmnds.getmesh;
183 createqueue.Enqueue(repData);
184 }
185
186 public bool CreateActorPhysRep(ODEPhysRepData repData)
187 {
188 getMesh(repData);
189 IMesh mesh = repData.mesh;
190
191 if (mesh != null)
192 {
193 IntPtr vertices, indices;
194 int vertexCount, indexCount;
195 int vertexStride, triStride;
196
197 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount);
198 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount);
199
200 if (vertexCount == 0 || indexCount == 0)
201 {
202 m_log.WarnFormat("[PHYSICS]: Invalid mesh data on prim {0} mesh UUID {1}",
203 repData.actor.Name, repData.pbs.SculptTexture.ToString());
204 repData.assetState = AssetState.AssetFailed;
205 repData.hasOBB = false;
206 repData.mesh = null;
207 m_scene.mesher.ReleaseMesh(mesh);
208 }
209 else
210 {
211 repData.OBBOffset = mesh.GetCentroid();
212 repData.OBB = mesh.GetOBB();
213 repData.hasOBB = true;
214 repData.physCost = 0.0013f * (float)indexCount;
215 // todo
216 repData.streamCost = 1.0f;
217 mesh.releaseSourceMeshData();
218 }
219 }
220 CalcVolumeData(repData);
221 return true;
222 }
223
224 public void AssetLoaded(ODEPhysRepData repData)
225 {
226 if (m_scene.haveActor(repData.actor))
227 {
228 if (needsMeshing(repData.pbs)) // no need for pbs now?
229 {
230 repData.comand = meshWorkerCmnds.changefull;
231 createqueue.Enqueue(repData);
232 }
233 }
234 }
235
236 public void DoRepDataGetMesh(ODEPhysRepData repData)
237 {
238 if (!repData.pbs.SculptEntry)
239 return;
240
241 if (repData.assetState != AssetState.loadingAsset)
242 return;
243
244 if (repData.assetID == null || repData.assetID == UUID.Zero)
245 return;
246
247 if (repData.assetID != repData.pbs.SculptTexture)
248 return;
249
250 RequestAssetDelegate assetProvider = m_scene.RequestAssetMethod;
251 if (assetProvider == null)
252 return;
253 ODEAssetRequest asr = new ODEAssetRequest(this, assetProvider, repData, m_log);
254 }
255
256
257 /// <summary>
258 /// Routine to figure out if we need to mesh this prim with our mesher
259 /// </summary>
260 /// <param name="pbs"></param>
261 /// <returns></returns>
262 public bool needsMeshing(PrimitiveBaseShape pbs)
263 {
264 // check sculpts or meshs
265 if (pbs.SculptEntry)
266 {
267 if (meshSculptedPrim)
268 return true;
269
270 if (pbs.SculptType == (byte)SculptType.Mesh) // always do meshs
271 return true;
272
273 return false;
274 }
275
276 if (forceSimplePrimMeshing)
277 return true;
278
279 // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim
280
281 if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
282 || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
283 && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z))
284 {
285
286 if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
287 && pbs.ProfileHollow == 0
288 && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
289 && pbs.PathBegin == 0 && pbs.PathEnd == 0
290 && pbs.PathTaperX == 0 && pbs.PathTaperY == 0
291 && pbs.PathScaleX == 100 && pbs.PathScaleY == 100
292 && pbs.PathShearX == 0 && pbs.PathShearY == 0)
293 {
294 return false;
295 }
296 }
297
298 // following code doesn't give meshs to boxes and spheres ever
299 // and it's odd.. so for now just return true if asked to force meshs
300 // hopefully mesher will fail if doesn't suport so things still get basic boxes
301
302 int iPropertiesNotSupportedDefault = 0;
303
304 if (pbs.ProfileHollow != 0)
305 iPropertiesNotSupportedDefault++;
306
307 if ((pbs.PathBegin != 0) || pbs.PathEnd != 0)
308 iPropertiesNotSupportedDefault++;
309
310 if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
311 iPropertiesNotSupportedDefault++;
312
313 if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
314 iPropertiesNotSupportedDefault++;
315
316 if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
317 iPropertiesNotSupportedDefault++;
318
319 if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
320 iPropertiesNotSupportedDefault++;
321
322 if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
323 iPropertiesNotSupportedDefault++;
324
325 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X))
326 iPropertiesNotSupportedDefault++;
327
328 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1)
329 iPropertiesNotSupportedDefault++;
330
331 // test for torus
332 if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
333 {
334 if (pbs.PathCurve == (byte)Extrusion.Curve1)
335 {
336 iPropertiesNotSupportedDefault++;
337 }
338 }
339 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
340 {
341 if (pbs.PathCurve == (byte)Extrusion.Straight)
342 {
343 iPropertiesNotSupportedDefault++;
344 }
345
346 // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
347 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
348 {
349 iPropertiesNotSupportedDefault++;
350 }
351 }
352 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
353 {
354 if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2)
355 {
356 iPropertiesNotSupportedDefault++;
357 }
358 }
359 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
360 {
361 if (pbs.PathCurve == (byte)Extrusion.Straight)
362 {
363 iPropertiesNotSupportedDefault++;
364 }
365 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
366 {
367 iPropertiesNotSupportedDefault++;
368 }
369 }
370
371 if (iPropertiesNotSupportedDefault == 0)
372 {
373 return false;
374 }
375 return true;
376 }
377
378 public bool CheckMeshDone(ODEPhysRepData repData)
379 {
380 PhysicsActor actor = repData.actor;
381 PrimitiveBaseShape pbs = repData.pbs;
382
383 repData.mesh = null;
384 repData.hasOBB = false;
385
386 if (!needsMeshing(pbs))
387 {
388 repData.assetState = AssetState.noNeedAsset;
389 return true;
390 }
391
392 if (pbs.SculptEntry)
393 {
394 if (repData.assetState == AssetState.AssetFailed)
395 {
396 if (pbs.SculptTexture == repData.assetID)
397 return true;
398 }
399 }
400 else
401 {
402 repData.assetState = AssetState.noNeedAsset;
403 repData.assetID = null;
404 }
405
406 IMesh mesh = null;
407
408 Vector3 size = repData.size;
409 byte shapetype = repData.shapetype;
410
411 bool convex;
412
413 int clod = (int)LevelOfDetail.High;
414 if (shapetype == 0)
415 convex = false;
416 else
417 {
418 convex = true;
419 if (pbs.SculptType != (byte)SculptType.Mesh)
420 clod = (int)LevelOfDetail.Low;
421 }
422 mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);
423 if (mesh == null)
424 {
425 if (pbs.SculptEntry)
426 {
427 if (pbs.SculptTexture != null && pbs.SculptTexture != UUID.Zero)
428 {
429 repData.assetID = pbs.SculptTexture;
430 repData.assetState = AssetState.needAsset;
431 }
432 else
433 repData.assetState = AssetState.AssetFailed;
434 }
435 return false;
436 }
437
438 repData.mesh = mesh;
439 if (pbs.SculptEntry)
440 {
441 repData.assetState = AssetState.AssetOK;
442 repData.assetID = pbs.SculptTexture;
443 pbs.SculptData = Utils.EmptyBytes;
444 }
445 return true;
446 }
447
448
449 public bool getMesh(ODEPhysRepData repData)
450 {
451 PhysicsActor actor = repData.actor;
452
453 PrimitiveBaseShape pbs = repData.pbs;
454
455 repData.mesh = null;
456 repData.hasOBB = false;
457
458 if (!needsMeshing(pbs))
459 return false;
460
461 if (pbs.SculptEntry)
462 {
463 if (repData.assetState == AssetState.AssetFailed)
464 {
465 if (pbs.SculptTexture == repData.assetID)
466 return true;
467 }
468 }
469
470 repData.assetState = AssetState.noNeedAsset;
471
472 IMesh mesh = null;
473 Vector3 size = repData.size;
474 byte shapetype = repData.shapetype;
475
476 bool convex;
477 int clod = (int)LevelOfDetail.High;
478 if (shapetype == 0)
479 convex = false;
480 else
481 {
482 convex = true;
483 if (pbs.SculptType != (byte)SculptType.Mesh)
484 clod = (int)LevelOfDetail.Low;
485 }
486 mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);
487 if (mesh == null)
488 {
489 if (pbs.SculptEntry)
490 {
491 if (pbs.SculptTexture == UUID.Zero)
492 return false;
493
494 repData.assetID = pbs.SculptTexture;
495 repData.assetState = AssetState.AssetOK;
496
497 if (pbs.SculptData == null || pbs.SculptData.Length == 0)
498 {
499 repData.assetState = AssetState.needAsset;
500 return false;
501 }
502 }
503
504 mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
505
506 }
507
508 repData.mesh = mesh;
509 repData.pbs.SculptData = Utils.EmptyBytes;
510
511 if (mesh == null)
512 {
513 if (pbs.SculptEntry)
514 repData.assetState = AssetState.AssetFailed;
515
516 return false;
517 }
518
519 if (pbs.SculptEntry)
520 repData.assetState = AssetState.AssetOK;
521
522 return true;
523 }
524
525 private void CalculateBasicPrimVolume(ODEPhysRepData repData)
526 {
527 PrimitiveBaseShape _pbs = repData.pbs;
528 Vector3 _size = repData.size;
529
530 float volume = _size.X * _size.Y * _size.Z; // default
531 float tmp;
532
533 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
534 float hollowVolume = hollowAmount * hollowAmount;
535
536 switch (_pbs.ProfileShape)
537 {
538 case ProfileShape.Square:
539 // default box
540
541 if (_pbs.PathCurve == (byte)Extrusion.Straight)
542 {
543 if (hollowAmount > 0.0)
544 {
545 switch (_pbs.HollowShape)
546 {
547 case HollowShape.Square:
548 case HollowShape.Same:
549 break;
550
551 case HollowShape.Circle:
552
553 hollowVolume *= 0.78539816339f;
554 break;
555
556 case HollowShape.Triangle:
557
558 hollowVolume *= (0.5f * .5f);
559 break;
560
561 default:
562 hollowVolume = 0;
563 break;
564 }
565 volume *= (1.0f - hollowVolume);
566 }
567 }
568
569 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
570 {
571 //a tube
572
573 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX);
574 tmp = 1.0f - 2.0e-2f * (float)(200 - _pbs.PathScaleY);
575 volume -= volume * tmp * tmp;
576
577 if (hollowAmount > 0.0)
578 {
579 hollowVolume *= hollowAmount;
580
581 switch (_pbs.HollowShape)
582 {
583 case HollowShape.Square:
584 case HollowShape.Same:
585 break;
586
587 case HollowShape.Circle:
588 hollowVolume *= 0.78539816339f;
589 break;
590
591 case HollowShape.Triangle:
592 hollowVolume *= 0.5f * 0.5f;
593 break;
594 default:
595 hollowVolume = 0;
596 break;
597 }
598 volume *= (1.0f - hollowVolume);
599 }
600 }
601
602 break;
603
604 case ProfileShape.Circle:
605
606 if (_pbs.PathCurve == (byte)Extrusion.Straight)
607 {
608 volume *= 0.78539816339f; // elipse base
609
610 if (hollowAmount > 0.0)
611 {
612 switch (_pbs.HollowShape)
613 {
614 case HollowShape.Same:
615 case HollowShape.Circle:
616 break;
617
618 case HollowShape.Square:
619 hollowVolume *= 0.5f * 2.5984480504799f;
620 break;
621
622 case HollowShape.Triangle:
623 hollowVolume *= .5f * 1.27323954473516f;
624 break;
625
626 default:
627 hollowVolume = 0;
628 break;
629 }
630 volume *= (1.0f - hollowVolume);
631 }
632 }
633
634 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
635 {
636 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX);
637 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
638 volume *= (1.0f - tmp * tmp);
639
640 if (hollowAmount > 0.0)
641 {
642
643 // calculate the hollow volume by it's shape compared to the prim shape
644 hollowVolume *= hollowAmount;
645
646 switch (_pbs.HollowShape)
647 {
648 case HollowShape.Same:
649 case HollowShape.Circle:
650 break;
651
652 case HollowShape.Square:
653 hollowVolume *= 0.5f * 2.5984480504799f;
654 break;
655
656 case HollowShape.Triangle:
657 hollowVolume *= .5f * 1.27323954473516f;
658 break;
659
660 default:
661 hollowVolume = 0;
662 break;
663 }
664 volume *= (1.0f - hollowVolume);
665 }
666 }
667 break;
668
669 case ProfileShape.HalfCircle:
670 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
671 {
672 volume *= 0.5236f;
673
674 if (hollowAmount > 0.0)
675 {
676 hollowVolume *= hollowAmount;
677
678 switch (_pbs.HollowShape)
679 {
680 case HollowShape.Circle:
681 case HollowShape.Triangle: // diference in sl is minor and odd
682 case HollowShape.Same:
683 break;
684
685 case HollowShape.Square:
686 hollowVolume *= 0.909f;
687 break;
688
689 // case HollowShape.Triangle:
690 // hollowVolume *= .827f;
691 // break;
692 default:
693 hollowVolume = 0;
694 break;
695 }
696 volume *= (1.0f - hollowVolume);
697 }
698
699 }
700 break;
701
702 case ProfileShape.EquilateralTriangle:
703
704 if (_pbs.PathCurve == (byte)Extrusion.Straight)
705 {
706 volume *= 0.32475953f;
707
708 if (hollowAmount > 0.0)
709 {
710
711 // calculate the hollow volume by it's shape compared to the prim shape
712 switch (_pbs.HollowShape)
713 {
714 case HollowShape.Same:
715 case HollowShape.Triangle:
716 hollowVolume *= .25f;
717 break;
718
719 case HollowShape.Square:
720 hollowVolume *= 0.499849f * 3.07920140172638f;
721 break;
722
723 case HollowShape.Circle:
724 // Hollow shape is a perfect cyllinder in respect to the cube's scale
725 // Cyllinder hollow volume calculation
726
727 hollowVolume *= 0.1963495f * 3.07920140172638f;
728 break;
729
730 default:
731 hollowVolume = 0;
732 break;
733 }
734 volume *= (1.0f - hollowVolume);
735 }
736 }
737 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
738 {
739 volume *= 0.32475953f;
740 volume *= 0.01f * (float)(200 - _pbs.PathScaleX);
741 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
742 volume *= (1.0f - tmp * tmp);
743
744 if (hollowAmount > 0.0)
745 {
746
747 hollowVolume *= hollowAmount;
748
749 switch (_pbs.HollowShape)
750 {
751 case HollowShape.Same:
752 case HollowShape.Triangle:
753 hollowVolume *= .25f;
754 break;
755
756 case HollowShape.Square:
757 hollowVolume *= 0.499849f * 3.07920140172638f;
758 break;
759
760 case HollowShape.Circle:
761
762 hollowVolume *= 0.1963495f * 3.07920140172638f;
763 break;
764
765 default:
766 hollowVolume = 0;
767 break;
768 }
769 volume *= (1.0f - hollowVolume);
770 }
771 }
772 break;
773
774 default:
775 break;
776 }
777
778 float taperX1;
779 float taperY1;
780 float taperX;
781 float taperY;
782 float pathBegin;
783 float pathEnd;
784 float profileBegin;
785 float profileEnd;
786
787 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible)
788 {
789 taperX1 = _pbs.PathScaleX * 0.01f;
790 if (taperX1 > 1.0f)
791 taperX1 = 2.0f - taperX1;
792 taperX = 1.0f - taperX1;
793
794 taperY1 = _pbs.PathScaleY * 0.01f;
795 if (taperY1 > 1.0f)
796 taperY1 = 2.0f - taperY1;
797 taperY = 1.0f - taperY1;
798 }
799 else
800 {
801 taperX = _pbs.PathTaperX * 0.01f;
802 if (taperX < 0.0f)
803 taperX = -taperX;
804 taperX1 = 1.0f - taperX;
805
806 taperY = _pbs.PathTaperY * 0.01f;
807 if (taperY < 0.0f)
808 taperY = -taperY;
809 taperY1 = 1.0f - taperY;
810 }
811
812 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
813
814 pathBegin = (float)_pbs.PathBegin * 2.0e-5f;
815 pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f;
816 volume *= (pathEnd - pathBegin);
817
818 // this is crude aproximation
819 profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f;
820 profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f;
821 volume *= (profileEnd - profileBegin);
822
823 repData.volume = volume;
824 }
825
826 private void CalcVolumeData(ODEPhysRepData repData)
827 {
828 if (repData.hasOBB)
829 {
830 Vector3 OBB = repData.OBB;
831 float pc = repData.physCost;
832 float psf = OBB.X * (OBB.Y + OBB.Z) + OBB.Y * OBB.Z;
833 psf *= 1.33f * .2f;
834 pc *= psf;
835 if (pc < 0.1f)
836 pc = 0.1f;
837
838 repData.physCost = pc;
839 }
840 else
841 {
842 Vector3 OBB = repData.size;
843 OBB.X *= 0.5f;
844 OBB.Y *= 0.5f;
845 OBB.Z *= 0.5f;
846
847 repData.OBB = OBB;
848 repData.OBBOffset = Vector3.Zero;
849
850 repData.physCost = 0.1f;
851 repData.streamCost = 1.0f;
852 }
853
854 CalculateBasicPrimVolume(repData);
855 }
856 }
857
858 public class ODEAssetRequest
859 {
860 ODEMeshWorker m_worker;
861 private ILog m_log;
862 ODEPhysRepData repData;
863
864 public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider,
865 ODEPhysRepData pRepData, ILog plog)
866 {
867 m_worker = pWorker;
868 m_log = plog;
869 repData = pRepData;
870
871 repData.assetState = AssetState.AssetFailed;
872 if (provider == null)
873 return;
874
875 if (repData.assetID == null)
876 return;
877
878 UUID assetID = (UUID) repData.assetID;
879 if (assetID == UUID.Zero)
880 return;
881
882 repData.assetState = AssetState.loadingAsset;
883 provider(assetID, ODEassetReceived);
884 }
885
886 void ODEassetReceived(AssetBase asset)
887 {
888 repData.assetState = AssetState.AssetFailed;
889 if (asset != null)
890 {
891 if (asset.Data != null && asset.Data.Length > 0)
892 {
893 if (!repData.pbs.SculptEntry)
894 return;
895 if (repData.pbs.SculptTexture != repData.assetID)
896 return;
897
898 // asset get may return a pointer to the same asset data
899 // for similar prims and we destroy with it
900 // so waste a lot of time stressing gc and hoping it clears things
901 // TODO avoid this
902 repData.pbs.SculptData = new byte[asset.Data.Length];
903 asset.Data.CopyTo(repData.pbs.SculptData,0);
904 repData.assetState = AssetState.AssetOK;
905 m_worker.AssetLoaded(repData);
906 }
907 else
908 m_log.WarnFormat("[PHYSICS]: asset provider returned invalid mesh data for prim {0} asset UUID {1}.",
909 repData.actor.Name, asset.ID.ToString());
910 }
911 else
912 m_log.WarnFormat("[PHYSICS]: asset provider returned null asset fo mesh of prim {0}.",
913 repData.actor.Name);
914 }
915 }
916} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index f2f4725..cbe129a 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -79,7 +79,7 @@ namespace OpenSim.Region.Physics.OdePlugin
79 private bool m_lastdoneSelected; 79 private bool m_lastdoneSelected;
80 internal bool m_outbounds; 80 internal bool m_outbounds;
81 81
82 private Quaternion m_lastorientation = new Quaternion(); 82 private Quaternion m_lastorientation;
83 private Quaternion _orientation; 83 private Quaternion _orientation;
84 84
85 private Vector3 _position; 85 private Vector3 _position;
@@ -91,33 +91,30 @@ namespace OpenSim.Region.Physics.OdePlugin
91 private Vector3 _size; 91 private Vector3 _size;
92 private Vector3 _acceleration; 92 private Vector3 _acceleration;
93 private Vector3 m_angularlock = Vector3.One; 93 private Vector3 m_angularlock = Vector3.One;
94 private IntPtr Amotor = IntPtr.Zero; 94 private IntPtr Amotor;
95 95
96 private Vector3 m_force; 96 private Vector3 m_force;
97 private Vector3 m_forceacc; 97 private Vector3 m_forceacc;
98 private Vector3 m_angularForceacc; 98 private Vector3 m_angularForceacc;
99 99
100 private float m_invTimeStep = 50.0f; 100 private float m_invTimeStep;
101 private float m_timeStep = .02f; 101 private float m_timeStep;
102 102
103 private Vector3 m_PIDTarget; 103 private Vector3 m_PIDTarget;
104 private float m_PIDTau; 104 private float m_PIDTau;
105 private bool m_usePID; 105 private bool m_usePID;
106 106
107 // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau),
108 // and are for non-VEHICLES only.
109
110 private float m_PIDHoverHeight; 107 private float m_PIDHoverHeight;
111 private float m_PIDHoverTau; 108 private float m_PIDHoverTau;
112 private bool m_useHoverPID; 109 private bool m_useHoverPID;
113 private PIDHoverType m_PIDHoverType = PIDHoverType.Ground; 110 private PIDHoverType m_PIDHoverType;
114 private float m_targetHoverHeight; 111 private float m_targetHoverHeight;
115 private float m_groundHeight; 112 private float m_groundHeight;
116 private float m_waterHeight; 113 private float m_waterHeight;
117 private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. 114 private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle.
118 115
119 private int body_autodisable_frames = 5; 116 private int body_autodisable_frames;
120 public int bodydisablecontrol = 0; 117 public int bodydisablecontrol;
121 118
122 119
123 // Default we're a Geometry 120 // Default we're a Geometry
@@ -147,12 +144,16 @@ namespace OpenSim.Region.Physics.OdePlugin
147 private IMesh m_mesh; 144 private IMesh m_mesh;
148 private object m_meshlock = new object(); 145 private object m_meshlock = new object();
149 private PrimitiveBaseShape _pbs; 146 private PrimitiveBaseShape _pbs;
147
148 private UUID? m_assetID;
149 private AssetState m_assetState;
150
150 public OdeScene _parent_scene; 151 public OdeScene _parent_scene;
151 152
152 /// <summary> 153 /// <summary>
153 /// The physics space which contains prim geometry 154 /// The physics space which contains prim geometry
154 /// </summary> 155 /// </summary>
155 public IntPtr m_targetSpace = IntPtr.Zero; 156 public IntPtr m_targetSpace;
156 157
157 public IntPtr prim_geom; 158 public IntPtr prim_geom;
158 public IntPtr _triMeshData; 159 public IntPtr _triMeshData;
@@ -166,27 +167,32 @@ namespace OpenSim.Region.Physics.OdePlugin
166 167
167 public IntPtr collide_geom; // for objects: geom if single prim space it linkset 168 public IntPtr collide_geom; // for objects: geom if single prim space it linkset
168 169
169 private float m_density = 10.000006836f; // Aluminum g/cm3; 170 private float m_density;
170 private byte m_shapetype; 171 private byte m_shapetype;
171 public bool _zeroFlag; 172 public bool _zeroFlag;
172 private bool m_lastUpdateSent; 173 private bool m_lastUpdateSent;
173 174
174 public IntPtr Body = IntPtr.Zero; 175 public IntPtr Body;
175 176
176 private Vector3 _target_velocity; 177 private Vector3 _target_velocity;
177 178
178 public Vector3 primOOBsize; // prim real dimensions from mesh 179 public Vector3 m_OBBOffset;
179 public Vector3 primOOBoffset; // its centroid out of mesh or rest aabb 180 public Vector3 m_OBB;
180 public float primOOBradiusSQ; 181 public float primOOBradiusSQ;
182
183 private bool m_hasOBB = true;
184
185 private float m_physCost;
186 private float m_streamCost;
187
181 public d.Mass primdMass; // prim inertia information on it's own referencial 188 public d.Mass primdMass; // prim inertia information on it's own referencial
182 float primMass; // prim own mass 189 float primMass; // prim own mass
183 float primVolume; // prim own volume; 190 float primVolume; // prim own volume;
184 float _mass; // object mass acording to case 191 float _mass; // object mass acording to case
185 private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb
186 192
187 public int givefakepos = 0; 193 public int givefakepos;
188 private Vector3 fakepos; 194 private Vector3 fakepos;
189 public int givefakeori = 0; 195 public int givefakeori;
190 private Quaternion fakeori; 196 private Quaternion fakeori;
191 197
192 private int m_eventsubscription; 198 private int m_eventsubscription;
@@ -394,7 +400,7 @@ namespace OpenSim.Region.Physics.OdePlugin
394 { 400 {
395 if (value.IsFinite()) 401 if (value.IsFinite())
396 { 402 {
397 AddChange(changes.Size, value); 403 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, value, m_shapetype);
398 } 404 }
399 else 405 else
400 { 406 {
@@ -464,7 +470,7 @@ namespace OpenSim.Region.Physics.OdePlugin
464 q.Z = dq.Z; 470 q.Z = dq.Z;
465 q.W = dq.W; 471 q.W = dq.W;
466 472
467 Vector3 Ptot = primOOBoffset * q; 473 Vector3 Ptot = m_OBBOffset * q;
468 dtmp = d.GeomGetPosition(prim_geom); 474 dtmp = d.GeomGetPosition(prim_geom);
469 Ptot.X += dtmp.X; 475 Ptot.X += dtmp.X;
470 Ptot.Y += dtmp.Y; 476 Ptot.Y += dtmp.Y;
@@ -504,7 +510,7 @@ namespace OpenSim.Region.Physics.OdePlugin
504 { 510 {
505 get 511 get
506 { 512 {
507 return primOOBsize; 513 return m_OBB;
508 } 514 }
509 } 515 }
510 516
@@ -512,7 +518,7 @@ namespace OpenSim.Region.Physics.OdePlugin
512 { 518 {
513 get 519 get
514 { 520 {
515 return primOOBoffset; 521 return m_OBBOffset;
516 } 522 }
517 } 523 }
518 524
@@ -528,7 +534,8 @@ namespace OpenSim.Region.Physics.OdePlugin
528 { 534 {
529 set 535 set
530 { 536 {
531 AddChange(changes.Shape, value); 537// AddChange(changes.Shape, value);
538 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, value, _size, m_shapetype);
532 } 539 }
533 } 540 }
534 541
@@ -541,11 +548,10 @@ namespace OpenSim.Region.Physics.OdePlugin
541 set 548 set
542 { 549 {
543 m_shapetype = value; 550 m_shapetype = value;
544 AddChange(changes.Shape, null); 551 _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, _size, value);
545 } 552 }
546 } 553 }
547 554
548
549 public override Vector3 Velocity 555 public override Vector3 Velocity
550 { 556 {
551 get 557 get
@@ -1012,7 +1018,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1012 m_invTimeStep = 1f / m_timeStep; 1018 m_invTimeStep = 1f / m_timeStep;
1013 1019
1014 m_density = parent_scene.geomDefaultDensity; 1020 m_density = parent_scene.geomDefaultDensity;
1015 // m_tensor = parent_scene.bodyMotorJointMaxforceTensor;
1016 body_autodisable_frames = parent_scene.bodyFramesAutoDisable; 1021 body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
1017 1022
1018 prim_geom = IntPtr.Zero; 1023 prim_geom = IntPtr.Zero;
@@ -1064,7 +1069,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1064 m_colliderfilter = 0; 1069 m_colliderfilter = 0;
1065 m_NoColide = false; 1070 m_NoColide = false;
1066 1071
1067 hasOOBoffsetFromMesh = false;
1068 _triMeshData = IntPtr.Zero; 1072 _triMeshData = IntPtr.Zero;
1069 1073
1070 m_shapetype = _shapeType; 1074 m_shapetype = _shapeType;
@@ -1079,27 +1083,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1079 mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; 1083 mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu;
1080 bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; 1084 bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce;
1081 1085
1082 CalcPrimBodyData();
1083
1084 m_mesh = null;
1085 if (_parent_scene.needsMeshing(pbs) && (pbs.SculptData.Length > 0))
1086 {
1087 bool convex;
1088 int clod = (int)LevelOfDetail.High;
1089 if (m_shapetype == 0)
1090 convex = false;
1091 else
1092 {
1093 convex = true;
1094 if (_pbs.SculptType != (byte)SculptType.Mesh)
1095 clod = (int)LevelOfDetail.Low;
1096 }
1097 m_mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex);
1098 }
1099
1100 m_building = true; // control must set this to false when done 1086 m_building = true; // control must set this to false when done
1101 1087
1102 AddChange(changes.Add, null); 1088 _parent_scene.m_meshWorker.NewActorPhysRep(this, _pbs, _size, m_shapetype);
1103 } 1089 }
1104 1090
1105 private void resetCollisionAccounting() 1091 private void resetCollisionAccounting()
@@ -1323,80 +1309,34 @@ namespace OpenSim.Region.Physics.OdePlugin
1323 } 1309 }
1324 } 1310 }
1325 1311
1326 private bool setMesh(OdeScene parent_scene) 1312 private bool GetMeshGeom()
1327 { 1313 {
1328 IntPtr vertices, indices; 1314 IntPtr vertices, indices;
1329 int vertexCount, indexCount; 1315 int vertexCount, indexCount;
1330 int vertexStride, triStride; 1316 int vertexStride, triStride;
1331 1317
1332 if (Body != IntPtr.Zero) 1318 IMesh mesh = m_mesh;
1333 {
1334 if (childPrim)
1335 {
1336 if (_parent != null)
1337 {
1338 OdePrim parent = (OdePrim)_parent;
1339 parent.ChildDelink(this, false);
1340 }
1341 }
1342 else
1343 {
1344 DestroyBody();
1345 }
1346 }
1347
1348 IMesh mesh = null;
1349
1350 lock (m_meshlock)
1351 {
1352 if (m_mesh == null)
1353 {
1354 bool convex;
1355 int clod = (int)LevelOfDetail.High;
1356
1357 if (m_shapetype == 0)
1358 convex = false;
1359 else
1360 {
1361 convex = true;
1362 if (_pbs.SculptType != (byte)SculptType.Mesh)
1363 clod = (int)LevelOfDetail.Low;
1364 }
1365
1366 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex);
1367 }
1368 else
1369 {
1370 mesh = m_mesh;
1371 }
1372
1373 if (mesh == null)
1374 {
1375 m_log.WarnFormat("[PHYSICS]: CreateMesh Failed on prim {0} at <{1},{2},{3}>.", Name, _position.X, _position.Y, _position.Z);
1376 return false;
1377 }
1378
1379
1380 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap
1381 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
1382 1319
1383 if (vertexCount == 0 || indexCount == 0) 1320 if (mesh == null)
1384 { 1321 return false;
1385 m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}",
1386 Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString());
1387 mesh.releaseSourceMeshData();
1388 return false;
1389 }
1390 1322
1391 primOOBoffset = mesh.GetCentroid(); 1323 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount);
1392 hasOOBoffsetFromMesh = true; 1324 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount);
1393 1325
1394 mesh.releaseSourceMeshData(); 1326 if (vertexCount == 0 || indexCount == 0)
1395 m_mesh = mesh; 1327 {
1328 m_log.WarnFormat("[PHYSICS]: Invalid mesh data on OdePrim {0} mesh UUID {1}",
1329 Name, _pbs.SculptTexture.ToString());
1330 m_hasOBB = false;
1331 m_OBBOffset = Vector3.Zero;
1332 m_OBB = _size * 0.5f;
1333 m_physCost = 0.1f;
1334 m_streamCost = 1.0f;
1335 _parent_scene.mesher.ReleaseMesh(mesh);
1336 m_assetState = AssetState.AssetFailed;
1337 m_mesh = null;
1338 return false;
1396 } 1339 }
1397
1398 IntPtr geo = IntPtr.Zero;
1399
1400 try 1340 try
1401 { 1341 {
1402 _triMeshData = d.GeomTriMeshDataCreate(); 1342 _triMeshData = d.GeomTriMeshDataCreate();
@@ -1404,8 +1344,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1404 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); 1344 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
1405 d.GeomTriMeshDataPreprocess(_triMeshData); 1345 d.GeomTriMeshDataPreprocess(_triMeshData);
1406 1346
1407 _parent_scene.waitForSpaceUnlock(m_targetSpace); 1347 prim_geom = d.CreateTriMesh(IntPtr.Zero, _triMeshData, null, null, null);
1408 geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null);
1409 } 1348 }
1410 1349
1411 catch (Exception e) 1350 catch (Exception e)
@@ -1413,85 +1352,56 @@ namespace OpenSim.Region.Physics.OdePlugin
1413 m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, e); 1352 m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, e);
1414 if (_triMeshData != IntPtr.Zero) 1353 if (_triMeshData != IntPtr.Zero)
1415 { 1354 {
1416 d.GeomTriMeshDataDestroy(_triMeshData); 1355 try
1417 _triMeshData = IntPtr.Zero;
1418 }
1419 return false;
1420 }
1421
1422 SetGeom(geo);
1423 return true;
1424 }
1425
1426 private void SetGeom(IntPtr geom)
1427 {
1428 prim_geom = geom;
1429 //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name);
1430 if (prim_geom != IntPtr.Zero)
1431 {
1432
1433 if (m_NoColide)
1434 {
1435 d.GeomSetCategoryBits(prim_geom, 0);
1436 if (m_isphysical)
1437 { 1356 {
1438 d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land); 1357 d.GeomTriMeshDataDestroy(_triMeshData);
1439 } 1358 }
1440 else 1359 catch
1441 { 1360 {
1442 d.GeomSetCollideBits(prim_geom, 0);
1443 d.GeomDisable(prim_geom);
1444 } 1361 }
1445 } 1362 }
1446 else 1363 _triMeshData = IntPtr.Zero;
1447 { 1364 prim_geom = IntPtr.Zero;
1448 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1449 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1450 }
1451
1452 CalcPrimBodyData();
1453
1454 _parent_scene.actor_name_map[prim_geom] = this;
1455 1365
1366 m_hasOBB = false;
1367 m_OBBOffset = Vector3.Zero;
1368 m_OBB = _size * 0.5f;
1369 m_physCost = 0.1f;
1370 m_streamCost = 1.0f;
1371 _parent_scene.mesher.ReleaseMesh(mesh);
1372 m_assetState = AssetState.AssetFailed;
1373 m_mesh = null;
1374 return false;
1456 } 1375 }
1457 else 1376 return true;
1458 m_log.Warn("Setting bad Geom");
1459 } 1377 }
1460 1378
1461
1462 /// <summary>
1463 /// Create a geometry for the given mesh in the given target space.
1464 /// </summary>
1465 /// <param name="m_targetSpace"></param>
1466 /// <param name="mesh">If null, then a mesh is used that is based on the profile shape data.</param>
1467 private void CreateGeom() 1379 private void CreateGeom()
1468 { 1380 {
1469 if (_triMeshData != IntPtr.Zero) 1381 IntPtr geo = IntPtr.Zero;
1470 { 1382 bool hasMesh = false;
1471 d.GeomTriMeshDataDestroy(_triMeshData);
1472 _triMeshData = IntPtr.Zero;
1473 }
1474 1383
1475 bool haveMesh = false;
1476 hasOOBoffsetFromMesh = false;
1477 m_NoColide = false; 1384 m_NoColide = false;
1478 1385
1479 if (_parent_scene.needsMeshing(_pbs)) 1386 if (m_assetState == AssetState.AssetFailed)
1387 m_NoColide = true;
1388
1389 else if (m_mesh != null)
1480 { 1390 {
1481 haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims 1391 if (GetMeshGeom())
1482 if (!haveMesh) 1392 hasMesh = true;
1393 else
1483 m_NoColide = true; 1394 m_NoColide = true;
1484 } 1395 }
1485 1396
1486 if (!haveMesh) 1397 if (!hasMesh)
1487 { 1398 {
1488 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1 1399 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1
1489 && _size.X == _size.Y && _size.Y == _size.Z) 1400 && _size.X == _size.Y && _size.Y == _size.Z)
1490 { // it's a sphere 1401 { // it's a sphere
1491 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1492 try 1402 try
1493 { 1403 {
1494 SetGeom(d.CreateSphere(m_targetSpace, _size.X * 0.5f)); 1404 geo = d.CreateSphere(IntPtr.Zero, _size.X * 0.5f);
1495 } 1405 }
1496 catch (Exception e) 1406 catch (Exception e)
1497 { 1407 {
@@ -1501,11 +1411,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1501 } 1411 }
1502 else 1412 else
1503 {// do it as a box 1413 {// do it as a box
1504 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1505 try 1414 try
1506 { 1415 {
1507 //Console.WriteLine(" CreateGeom 4"); 1416 geo = d.CreateBox(IntPtr.Zero, _size.X, _size.Y, _size.Z);
1508 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1509 } 1417 }
1510 catch (Exception e) 1418 catch (Exception e)
1511 { 1419 {
@@ -1513,19 +1421,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1513 return; 1421 return;
1514 } 1422 }
1515 } 1423 }
1424 m_physCost = 0.1f;
1425 m_streamCost = 1.0f;
1426 prim_geom = geo;
1516 } 1427 }
1517 } 1428 }
1518 1429
1519 /// <summary>
1520 /// Set a new geometry for this prim.
1521 /// </summary>
1522 /// <param name="geom"></param>
1523 private void RemoveGeom() 1430 private void RemoveGeom()
1524 { 1431 {
1525 if (prim_geom != IntPtr.Zero) 1432 if (prim_geom != IntPtr.Zero)
1526 { 1433 {
1527// _parent_scene.geom_name_map.Remove(prim_geom);
1528 _parent_scene.actor_name_map.Remove(prim_geom); 1434 _parent_scene.actor_name_map.Remove(prim_geom);
1435
1529 try 1436 try
1530 { 1437 {
1531 d.GeomDestroy(prim_geom); 1438 d.GeomDestroy(prim_geom);
@@ -1534,11 +1441,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1534 d.GeomTriMeshDataDestroy(_triMeshData); 1441 d.GeomTriMeshDataDestroy(_triMeshData);
1535 _triMeshData = IntPtr.Zero; 1442 _triMeshData = IntPtr.Zero;
1536 } 1443 }
1537
1538 } 1444 }
1539
1540
1541 // catch (System.AccessViolationException)
1542 catch (Exception e) 1445 catch (Exception e)
1543 { 1446 {
1544 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name, e); 1447 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name, e);
@@ -1546,29 +1449,26 @@ namespace OpenSim.Region.Physics.OdePlugin
1546 1449
1547 prim_geom = IntPtr.Zero; 1450 prim_geom = IntPtr.Zero;
1548 collide_geom = IntPtr.Zero; 1451 collide_geom = IntPtr.Zero;
1452 m_targetSpace = IntPtr.Zero;
1549 } 1453 }
1550 else 1454 else
1551 { 1455 {
1552 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name); 1456 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name);
1553 } 1457 }
1554 1458
1555 if (m_mesh != null) 1459 lock (m_meshlock)
1556 { 1460 {
1557 _parent_scene.mesher.ReleaseMesh(m_mesh); 1461 if (m_mesh != null)
1558 m_mesh = null; 1462 {
1463 _parent_scene.mesher.ReleaseMesh(m_mesh);
1464 m_mesh = null;
1465 }
1559 } 1466 }
1560 1467
1561 Body = IntPtr.Zero; 1468 Body = IntPtr.Zero;
1562 hasOOBoffsetFromMesh = false; 1469 m_hasOBB = false;
1563 } 1470 }
1564/* 1471
1565 private void ChildSetGeom(OdePrim odePrim)
1566 {
1567 // well..
1568 DestroyBody();
1569 MakeBody();
1570 }
1571*/
1572 //sets non physical prim m_targetSpace to right space in spaces grid for static prims 1472 //sets non physical prim m_targetSpace to right space in spaces grid for static prims
1573 // should only be called for non physical prims unless they are becoming non physical 1473 // should only be called for non physical prims unless they are becoming non physical
1574 private void SetInStaticSpace(OdePrim prim) 1474 private void SetInStaticSpace(OdePrim prim)
@@ -1631,9 +1531,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1631 1531
1632 if (Body != IntPtr.Zero) 1532 if (Body != IntPtr.Zero)
1633 { 1533 {
1634// d.BodyDestroy(Body);
1635// Body = IntPtr.Zero;
1636 // do a more complet destruction
1637 DestroyBody(); 1534 DestroyBody();
1638 m_log.Warn("[PHYSICS]: MakeBody called having a body"); 1535 m_log.Warn("[PHYSICS]: MakeBody called having a body");
1639 } 1536 }
@@ -2143,339 +2040,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2143 2040
2144 #region Mass Calculation 2041 #region Mass Calculation
2145 2042
2146 private float CalculatePrimVolume() 2043 private void UpdatePrimBodyData()
2147 {
2148 float volume = _size.X * _size.Y * _size.Z; // default
2149 float tmp;
2150
2151 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
2152 float hollowVolume = hollowAmount * hollowAmount;
2153
2154 switch (_pbs.ProfileShape)
2155 {
2156 case ProfileShape.Square:
2157 // default box
2158
2159 if (_pbs.PathCurve == (byte)Extrusion.Straight)
2160 {
2161 if (hollowAmount > 0.0)
2162 {
2163 switch (_pbs.HollowShape)
2164 {
2165 case HollowShape.Square:
2166 case HollowShape.Same:
2167 break;
2168
2169 case HollowShape.Circle:
2170
2171 hollowVolume *= 0.78539816339f;
2172 break;
2173
2174 case HollowShape.Triangle:
2175
2176 hollowVolume *= (0.5f * .5f);
2177 break;
2178
2179 default:
2180 hollowVolume = 0;
2181 break;
2182 }
2183 volume *= (1.0f - hollowVolume);
2184 }
2185 }
2186
2187 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
2188 {
2189 //a tube
2190
2191 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX);
2192 tmp = 1.0f - 2.0e-2f * (float)(200 - _pbs.PathScaleY);
2193 volume -= volume * tmp * tmp;
2194
2195 if (hollowAmount > 0.0)
2196 {
2197 hollowVolume *= hollowAmount;
2198
2199 switch (_pbs.HollowShape)
2200 {
2201 case HollowShape.Square:
2202 case HollowShape.Same:
2203 break;
2204
2205 case HollowShape.Circle:
2206 hollowVolume *= 0.78539816339f;
2207 break;
2208
2209 case HollowShape.Triangle:
2210 hollowVolume *= 0.5f * 0.5f;
2211 break;
2212 default:
2213 hollowVolume = 0;
2214 break;
2215 }
2216 volume *= (1.0f - hollowVolume);
2217 }
2218 }
2219
2220 break;
2221
2222 case ProfileShape.Circle:
2223
2224 if (_pbs.PathCurve == (byte)Extrusion.Straight)
2225 {
2226 volume *= 0.78539816339f; // elipse base
2227
2228 if (hollowAmount > 0.0)
2229 {
2230 switch (_pbs.HollowShape)
2231 {
2232 case HollowShape.Same:
2233 case HollowShape.Circle:
2234 break;
2235
2236 case HollowShape.Square:
2237 hollowVolume *= 0.5f * 2.5984480504799f;
2238 break;
2239
2240 case HollowShape.Triangle:
2241 hollowVolume *= .5f * 1.27323954473516f;
2242 break;
2243
2244 default:
2245 hollowVolume = 0;
2246 break;
2247 }
2248 volume *= (1.0f - hollowVolume);
2249 }
2250 }
2251
2252 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
2253 {
2254 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX);
2255 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
2256 volume *= (1.0f - tmp * tmp);
2257
2258 if (hollowAmount > 0.0)
2259 {
2260
2261 // calculate the hollow volume by it's shape compared to the prim shape
2262 hollowVolume *= hollowAmount;
2263
2264 switch (_pbs.HollowShape)
2265 {
2266 case HollowShape.Same:
2267 case HollowShape.Circle:
2268 break;
2269
2270 case HollowShape.Square:
2271 hollowVolume *= 0.5f * 2.5984480504799f;
2272 break;
2273
2274 case HollowShape.Triangle:
2275 hollowVolume *= .5f * 1.27323954473516f;
2276 break;
2277
2278 default:
2279 hollowVolume = 0;
2280 break;
2281 }
2282 volume *= (1.0f - hollowVolume);
2283 }
2284 }
2285 break;
2286
2287 case ProfileShape.HalfCircle:
2288 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
2289 {
2290 volume *= 0.5236f;
2291
2292 if (hollowAmount > 0.0)
2293 {
2294 hollowVolume *= hollowAmount;
2295
2296 switch (_pbs.HollowShape)
2297 {
2298 case HollowShape.Circle:
2299 case HollowShape.Triangle: // diference in sl is minor and odd
2300 case HollowShape.Same:
2301 break;
2302
2303 case HollowShape.Square:
2304 hollowVolume *= 0.909f;
2305 break;
2306
2307 // case HollowShape.Triangle:
2308 // hollowVolume *= .827f;
2309 // break;
2310 default:
2311 hollowVolume = 0;
2312 break;
2313 }
2314 volume *= (1.0f - hollowVolume);
2315 }
2316
2317 }
2318 break;
2319
2320 case ProfileShape.EquilateralTriangle:
2321
2322 if (_pbs.PathCurve == (byte)Extrusion.Straight)
2323 {
2324 volume *= 0.32475953f;
2325
2326 if (hollowAmount > 0.0)
2327 {
2328
2329 // calculate the hollow volume by it's shape compared to the prim shape
2330 switch (_pbs.HollowShape)
2331 {
2332 case HollowShape.Same:
2333 case HollowShape.Triangle:
2334 hollowVolume *= .25f;
2335 break;
2336
2337 case HollowShape.Square:
2338 hollowVolume *= 0.499849f * 3.07920140172638f;
2339 break;
2340
2341 case HollowShape.Circle:
2342 // Hollow shape is a perfect cyllinder in respect to the cube's scale
2343 // Cyllinder hollow volume calculation
2344
2345 hollowVolume *= 0.1963495f * 3.07920140172638f;
2346 break;
2347
2348 default:
2349 hollowVolume = 0;
2350 break;
2351 }
2352 volume *= (1.0f - hollowVolume);
2353 }
2354 }
2355 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
2356 {
2357 volume *= 0.32475953f;
2358 volume *= 0.01f * (float)(200 - _pbs.PathScaleX);
2359 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
2360 volume *= (1.0f - tmp * tmp);
2361
2362 if (hollowAmount > 0.0)
2363 {
2364
2365 hollowVolume *= hollowAmount;
2366
2367 switch (_pbs.HollowShape)
2368 {
2369 case HollowShape.Same:
2370 case HollowShape.Triangle:
2371 hollowVolume *= .25f;
2372 break;
2373
2374 case HollowShape.Square:
2375 hollowVolume *= 0.499849f * 3.07920140172638f;
2376 break;
2377
2378 case HollowShape.Circle:
2379
2380 hollowVolume *= 0.1963495f * 3.07920140172638f;
2381 break;
2382
2383 default:
2384 hollowVolume = 0;
2385 break;
2386 }
2387 volume *= (1.0f - hollowVolume);
2388 }
2389 }
2390 break;
2391
2392 default:
2393 break;
2394 }
2395
2396 float taperX1;
2397 float taperY1;
2398 float taperX;
2399 float taperY;
2400 float pathBegin;
2401 float pathEnd;
2402 float profileBegin;
2403 float profileEnd;
2404
2405 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible)
2406 {
2407 taperX1 = _pbs.PathScaleX * 0.01f;
2408 if (taperX1 > 1.0f)
2409 taperX1 = 2.0f - taperX1;
2410 taperX = 1.0f - taperX1;
2411
2412 taperY1 = _pbs.PathScaleY * 0.01f;
2413 if (taperY1 > 1.0f)
2414 taperY1 = 2.0f - taperY1;
2415 taperY = 1.0f - taperY1;
2416 }
2417 else
2418 {
2419 taperX = _pbs.PathTaperX * 0.01f;
2420 if (taperX < 0.0f)
2421 taperX = -taperX;
2422 taperX1 = 1.0f - taperX;
2423
2424 taperY = _pbs.PathTaperY * 0.01f;
2425 if (taperY < 0.0f)
2426 taperY = -taperY;
2427 taperY1 = 1.0f - taperY;
2428 }
2429
2430 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
2431
2432 pathBegin = (float)_pbs.PathBegin * 2.0e-5f;
2433 pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f;
2434 volume *= (pathEnd - pathBegin);
2435
2436 // this is crude aproximation
2437 profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f;
2438 profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f;
2439 volume *= (profileEnd - profileBegin);
2440
2441 return volume;
2442 }
2443
2444
2445 private void CalcPrimBodyData()
2446 { 2044 {
2447 float volume; 2045 primMass = m_density * primVolume;
2448
2449 if (prim_geom == IntPtr.Zero)
2450 {
2451 // Ubit let's have a initial basic OOB
2452 primOOBsize.X = _size.X;
2453 primOOBsize.Y = _size.Y;
2454 primOOBsize.Z = _size.Z;
2455 primOOBoffset = Vector3.Zero;
2456 }
2457 else
2458 {
2459 d.AABB AABB;
2460 d.GeomGetAABB(prim_geom, out AABB); // get the AABB from engine geom
2461
2462 primOOBsize.X = (AABB.MaxX - AABB.MinX);
2463 primOOBsize.Y = (AABB.MaxY - AABB.MinY);
2464 primOOBsize.Z = (AABB.MaxZ - AABB.MinZ);
2465 if (!hasOOBoffsetFromMesh)
2466 {
2467 primOOBoffset.X = (AABB.MaxX + AABB.MinX) * 0.5f;
2468 primOOBoffset.Y = (AABB.MaxY + AABB.MinY) * 0.5f;
2469 primOOBoffset.Z = (AABB.MaxZ + AABB.MinZ) * 0.5f;
2470 }
2471 }
2472
2473 // also its own inertia and mass
2474 // keep using basic shape mass for now
2475 volume = CalculatePrimVolume();
2476
2477 primVolume = volume;
2478 primMass = m_density * volume;
2479 2046
2480 if (primMass <= 0) 2047 if (primMass <= 0)
2481 primMass = 0.0001f;//ckrinke: Mass must be greater then zero. 2048 primMass = 0.0001f;//ckrinke: Mass must be greater then zero.
@@ -2484,18 +2051,16 @@ namespace OpenSim.Region.Physics.OdePlugin
2484 2051
2485 _mass = primMass; // just in case 2052 _mass = primMass; // just in case
2486 2053
2487 d.MassSetBoxTotal(out primdMass, primMass, primOOBsize.X, primOOBsize.Y, primOOBsize.Z); 2054 d.MassSetBoxTotal(out primdMass, primMass, m_OBB.X, m_OBB.Y, m_OBB.Z);
2488 2055
2489 d.MassTranslate(ref primdMass, 2056 d.MassTranslate(ref primdMass,
2490 primOOBoffset.X, 2057 m_OBBOffset.X,
2491 primOOBoffset.Y, 2058 m_OBBOffset.Y,
2492 primOOBoffset.Z); 2059 m_OBBOffset.Z);
2493 2060
2494 primOOBsize *= 0.5f; // let obb size be a corner coords 2061 primOOBradiusSQ = m_OBBOffset.LengthSquared();
2495 primOOBradiusSQ = primOOBsize.LengthSquared();
2496 } 2062 }
2497 2063
2498
2499 #endregion 2064 #endregion
2500 2065
2501 2066
@@ -2684,27 +2249,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2684 2249
2685 private void changeadd() 2250 private void changeadd()
2686 { 2251 {
2687 CreateGeom();
2688
2689 if (prim_geom != IntPtr.Zero)
2690 {
2691 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2692 d.Quaternion myrot = new d.Quaternion();
2693 myrot.X = _orientation.X;
2694 myrot.Y = _orientation.Y;
2695 myrot.Z = _orientation.Z;
2696 myrot.W = _orientation.W;
2697 d.GeomSetQuaternion(prim_geom, ref myrot);
2698
2699 if (!m_isphysical)
2700 {
2701 SetInStaticSpace(this);
2702 UpdateCollisionCatFlags();
2703 ApplyCollisionCatFlags();
2704 }
2705 else
2706 MakeBody();
2707 }
2708 } 2252 }
2709 2253
2710 private void changeAngularLock(Vector3 newLock) 2254 private void changeAngularLock(Vector3 newLock)
@@ -3148,7 +2692,73 @@ namespace OpenSim.Region.Physics.OdePlugin
3148 resetCollisionAccounting(); 2692 resetCollisionAccounting();
3149 } 2693 }
3150 2694
3151 private void changeprimsizeshape() 2695 private void changeSize(Vector3 newSize)
2696 {
2697 }
2698
2699 private void changeShape(PrimitiveBaseShape newShape)
2700 {
2701 }
2702
2703
2704
2705 private void changeAddPhysRep(ODEPhysRepData repData)
2706 {
2707 _size = repData.size; //??
2708 _pbs = repData.pbs;
2709 m_shapetype = repData.shapetype;
2710
2711 m_mesh = repData.mesh;
2712
2713 m_assetID = repData.assetID;
2714 m_assetState = repData.assetState;
2715
2716 m_hasOBB = repData.hasOBB;
2717 m_OBBOffset = repData.OBBOffset;
2718 m_OBB = repData.OBB;
2719
2720// m_NoColide = repData.NoColide;
2721 m_physCost = repData.physCost;
2722 m_streamCost = repData.streamCost;
2723
2724 primVolume = repData.volume;
2725
2726 CreateGeom();
2727
2728 if (prim_geom != IntPtr.Zero)
2729 {
2730 UpdatePrimBodyData();
2731
2732 _parent_scene.actor_name_map[prim_geom] = this;
2733
2734 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2735 d.Quaternion myrot = new d.Quaternion();
2736 myrot.X = _orientation.X;
2737 myrot.Y = _orientation.Y;
2738 myrot.Z = _orientation.Z;
2739 myrot.W = _orientation.W;
2740 d.GeomSetQuaternion(prim_geom, ref myrot);
2741
2742 if (!m_isphysical)
2743 {
2744 SetInStaticSpace(this);
2745 UpdateCollisionCatFlags();
2746 ApplyCollisionCatFlags();
2747 }
2748 else
2749 MakeBody();
2750
2751 if (m_assetState == AssetState.needAsset)
2752 {
2753 repData.size = _size;
2754 repData.pbs = _pbs;
2755 repData.shapetype = m_shapetype;
2756 _parent_scene.m_meshWorker.RequestMeshAsset(repData);
2757 }
2758 }
2759 }
2760
2761 private void changePhysRepData(ODEPhysRepData repData)
3152 { 2762 {
3153 CheckDelaySelect(); 2763 CheckDelaySelect();
3154 2764
@@ -3170,19 +2780,41 @@ namespace OpenSim.Region.Physics.OdePlugin
3170 2780
3171 RemoveGeom(); 2781 RemoveGeom();
3172 2782
3173 // we don't need to do space calculation because the client sends a position update also. 2783 _size = repData.size;
3174 if (_size.X <= 0) 2784 _pbs = repData.pbs;
3175 _size.X = 0.01f; 2785 m_shapetype = repData.shapetype;
3176 if (_size.Y <= 0) 2786
3177 _size.Y = 0.01f; 2787 m_mesh = repData.mesh;
3178 if (_size.Z <= 0) 2788
3179 _size.Z = 0.01f; 2789 m_assetID = repData.assetID;
3180 // Construction of new prim 2790 m_assetState = repData.assetState;
2791
2792 m_hasOBB = repData.hasOBB;
2793 m_OBBOffset = repData.OBBOffset;
2794 m_OBB = repData.OBB;
2795
2796 m_physCost = repData.physCost;
2797 m_streamCost = repData.streamCost;
2798
2799 primVolume = repData.volume;
3181 2800
3182 CreateGeom(); 2801 CreateGeom();
3183 2802
3184 if (prim_geom != IntPtr.Zero) 2803 if (prim_geom != IntPtr.Zero)
3185 { 2804 {
2805 m_targetSpace = IntPtr.Zero;
2806
2807 UpdatePrimBodyData();
2808
2809 try
2810 {
2811 _parent_scene.actor_name_map[prim_geom] = this;
2812 }
2813 catch
2814 {
2815
2816 }
2817
3186 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 2818 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
3187 d.Quaternion myrot = new d.Quaternion(); 2819 d.Quaternion myrot = new d.Quaternion();
3188 myrot.X = _orientation.X; 2820 myrot.X = _orientation.X;
@@ -3190,41 +2822,37 @@ namespace OpenSim.Region.Physics.OdePlugin
3190 myrot.Z = _orientation.Z; 2822 myrot.Z = _orientation.Z;
3191 myrot.W = _orientation.W; 2823 myrot.W = _orientation.W;
3192 d.GeomSetQuaternion(prim_geom, ref myrot); 2824 d.GeomSetQuaternion(prim_geom, ref myrot);
3193 }
3194 2825
3195 if (m_isphysical) 2826
3196 { 2827 if (m_isphysical)
3197 if (chp)
3198 { 2828 {
3199 if (parent != null) 2829 if (chp)
3200 { 2830 {
3201 parent.MakeBody(); 2831 if (parent != null)
2832 {
2833 parent.MakeBody();
2834 }
3202 } 2835 }
2836 else
2837 MakeBody();
3203 } 2838 }
2839
3204 else 2840 else
3205 MakeBody(); 2841 {
3206 } 2842 SetInStaticSpace(this);
2843 UpdateCollisionCatFlags();
2844 ApplyCollisionCatFlags();
2845 }
3207 2846
3208 else 2847 resetCollisionAccounting();
3209 { 2848 if (m_assetState == AssetState.needAsset)
3210 UpdateCollisionCatFlags(); 2849 {
3211 ApplyCollisionCatFlags(); 2850 repData.size = _size;
2851 repData.pbs = _pbs;
2852 repData.shapetype = m_shapetype;
2853 _parent_scene.m_meshWorker.RequestMeshAsset(repData);
2854 }
3212 } 2855 }
3213
3214 resetCollisionAccounting();
3215 }
3216
3217 private void changeSize(Vector3 newSize)
3218 {
3219 _size = newSize;
3220 changeprimsizeshape();
3221 }
3222
3223 private void changeShape(PrimitiveBaseShape newShape)
3224 {
3225 if(newShape != null)
3226 _pbs = newShape;
3227 changeprimsizeshape();
3228 } 2856 }
3229 2857
3230 private void changeFloatOnWater(bool newval) 2858 private void changeFloatOnWater(bool newval)
@@ -3891,7 +3519,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3891 3519
3892 public bool DoAChange(changes what, object arg) 3520 public bool DoAChange(changes what, object arg)
3893 { 3521 {
3894 if (prim_geom == IntPtr.Zero && what != changes.Add && what != changes.Remove) 3522 if (prim_geom == IntPtr.Zero && what != changes.Add && what != changes.AddPhysRep && what != changes.Remove)
3895 { 3523 {
3896 return false; 3524 return false;
3897 } 3525 }
@@ -3902,6 +3530,11 @@ namespace OpenSim.Region.Physics.OdePlugin
3902 case changes.Add: 3530 case changes.Add:
3903 changeadd(); 3531 changeadd();
3904 break; 3532 break;
3533
3534 case changes.AddPhysRep:
3535 changeAddPhysRep((ODEPhysRepData)arg);
3536 break;
3537
3905 case changes.Remove: 3538 case changes.Remove:
3906 //If its being removed, we don't want to rebuild the physical rep at all, so ignore this stuff... 3539 //If its being removed, we don't want to rebuild the physical rep at all, so ignore this stuff...
3907 //When we return true, it destroys all of the prims in the linkset anyway 3540 //When we return true, it destroys all of the prims in the linkset anyway
@@ -3984,6 +3617,10 @@ namespace OpenSim.Region.Physics.OdePlugin
3984 changeShape((PrimitiveBaseShape)arg); 3617 changeShape((PrimitiveBaseShape)arg);
3985 break; 3618 break;
3986 3619
3620 case changes.PhysRepData:
3621 changePhysRepData((ODEPhysRepData) arg);
3622 break;
3623
3987 case changes.CollidesWater: 3624 case changes.CollidesWater:
3988 changeFloatOnWater((bool)arg); 3625 changeFloatOnWater((bool)arg);
3989 break; 3626 break;
@@ -4072,6 +3709,8 @@ namespace OpenSim.Region.Physics.OdePlugin
4072 donullchange(); 3709 donullchange();
4073 break; 3710 break;
4074 3711
3712
3713
4075 default: 3714 default:
4076 donullchange(); 3715 donullchange();
4077 break; 3716 break;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index f126644..5e4c2a5 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -60,6 +60,7 @@ namespace OpenSim.Region.Physics.OdePlugin
60 public int lastframe; 60 public int lastframe;
61 } 61 }
62 62
63
63 // colision flags of things others can colide with 64 // colision flags of things others can colide with
64 // rays, sensors, probes removed since can't be colided with 65 // rays, sensors, probes removed since can't be colided with
65 // The top space where things are placed provided further selection 66 // The top space where things are placed provided further selection
@@ -109,6 +110,17 @@ namespace OpenSim.Region.Physics.OdePlugin
109 110
110 light = 7 // compatibility with old viewers 111 light = 7 // compatibility with old viewers
111 } 112 }
113
114 public enum AssetState : byte
115 {
116 noNeedAsset = 0,
117 needAsset = 1,
118 loadingAsset = 2,
119 procAsset = 3,
120 AssetOK = 4,
121
122 AssetFailed = 0xff
123 }
112 124
113 public enum changes : int 125 public enum changes : int
114 { 126 {
@@ -147,6 +159,8 @@ namespace OpenSim.Region.Physics.OdePlugin
147 159
148 Size, 160 Size,
149 Shape, 161 Shape,
162 PhysRepData,
163 AddPhysRep,
150 164
151 CollidesWater, 165 CollidesWater,
152 VolumeDtc, 166 VolumeDtc,
@@ -230,11 +244,6 @@ namespace OpenSim.Region.Physics.OdePlugin
230 private float minimumGroundFlightOffset = 3f; 244 private float minimumGroundFlightOffset = 3f;
231 public float maximumMassObject = 10000.01f; 245 public float maximumMassObject = 10000.01f;
232 246
233 public bool meshSculptedPrim = true;
234 public bool forceSimplePrimMeshing = false;
235
236 public float meshSculptLOD = 32;
237 public float MeshSculptphysicalLOD = 32;
238 247
239 public float geomDefaultDensity = 10.000006836f; 248 public float geomDefaultDensity = 10.000006836f;
240 249
@@ -313,7 +322,7 @@ namespace OpenSim.Region.Physics.OdePlugin
313 private IntPtr[] staticPrimspaceOffRegion; 322 private IntPtr[] staticPrimspaceOffRegion;
314 323
315 public Object OdeLock; 324 public Object OdeLock;
316 private static Object SimulationLock; 325 public static Object SimulationLock;
317 326
318 public IMesher mesher; 327 public IMesher mesher;
319 328
@@ -328,7 +337,7 @@ namespace OpenSim.Region.Physics.OdePlugin
328 private PhysicsScene m_parentScene = null; 337 private PhysicsScene m_parentScene = null;
329 338
330 private ODERayCastRequestManager m_rayCastManager; 339 private ODERayCastRequestManager m_rayCastManager;
331 340 public ODEMeshWorker m_meshWorker;
332 341
333/* maybe needed if ode uses tls 342/* maybe needed if ode uses tls
334 private void checkThread() 343 private void checkThread()
@@ -361,6 +370,8 @@ namespace OpenSim.Region.Physics.OdePlugin
361 nearCallback = near; 370 nearCallback = near;
362 371
363 m_rayCastManager = new ODERayCastRequestManager(this); 372 m_rayCastManager = new ODERayCastRequestManager(this);
373
374
364 lock (OdeLock) 375 lock (OdeLock)
365 { 376 {
366 // Create the world and the first space 377 // Create the world and the first space
@@ -402,6 +413,7 @@ namespace OpenSim.Region.Physics.OdePlugin
402 )); 413 ));
403 d.GeomSetCollideBits(StaticSpace, 0); 414 d.GeomSetCollideBits(StaticSpace, 0);
404 415
416
405 contactgroup = d.JointGroupCreate(0); 417 contactgroup = d.JointGroupCreate(0);
406 //contactgroup 418 //contactgroup
407 419
@@ -440,9 +452,11 @@ namespace OpenSim.Region.Physics.OdePlugin
440 452
441 int contactsPerCollision = 80; 453 int contactsPerCollision = 80;
442 454
455 IConfig physicsconfig = null;
456
443 if (m_config != null) 457 if (m_config != null)
444 { 458 {
445 IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; 459 physicsconfig = m_config.Configs["ODEPhysicsSettings"];
446 if (physicsconfig != null) 460 if (physicsconfig != null)
447 { 461 {
448 gravityx = physicsconfig.GetFloat("world_gravityx", gravityx); 462 gravityx = physicsconfig.GetFloat("world_gravityx", gravityx);
@@ -469,27 +483,7 @@ namespace OpenSim.Region.Physics.OdePlugin
469 483
470 geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); 484 geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity);
471 bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable); 485 bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable);
472/* 486
473 bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", bodyPIDD);
474 bodyPIDG = physicsconfig.GetFloat("body_pid_gain", bodyPIDG);
475*/
476 forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing);
477 meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim);
478 meshSculptLOD = physicsconfig.GetFloat("mesh_lod", meshSculptLOD);
479 MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
480/*
481 if (Environment.OSVersion.Platform == PlatformID.Unix)
482 {
483 avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", avPIDD);
484 avPIDP = physicsconfig.GetFloat("av_pid_proportional_linux", avPIDP);
485 }
486 else
487 {
488
489 avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", avPIDD);
490 avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", avPIDP);
491 }
492*/
493 physics_logging = physicsconfig.GetBoolean("physics_logging", false); 487 physics_logging = physicsconfig.GetBoolean("physics_logging", false);
494 physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); 488 physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0);
495 physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); 489 physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false);
@@ -499,6 +493,8 @@ namespace OpenSim.Region.Physics.OdePlugin
499 } 493 }
500 } 494 }
501 495
496 m_meshWorker = new ODEMeshWorker(this, m_log, meshmerizer, physicsconfig);
497
502 HalfOdeStep = ODE_STEPSIZE * 0.5f; 498 HalfOdeStep = ODE_STEPSIZE * 0.5f;
503 odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f); 499 odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f);
504 500
@@ -1295,6 +1291,15 @@ namespace OpenSim.Region.Physics.OdePlugin
1295 _collisionEventPrimRemove.Add(obj); 1291 _collisionEventPrimRemove.Add(obj);
1296 } 1292 }
1297 1293
1294 public override float TimeDilation
1295 {
1296 get { return m_timeDilation; }
1297 }
1298
1299 public override bool SupportsNINJAJoints
1300 {
1301 get { return false; }
1302 }
1298 1303
1299 #region Add/Remove Entities 1304 #region Add/Remove Entities
1300 1305
@@ -1350,117 +1355,59 @@ namespace OpenSim.Region.Physics.OdePlugin
1350 ((OdeCharacter) actor).Destroy(); 1355 ((OdeCharacter) actor).Destroy();
1351 } 1356 }
1352 1357
1353 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
1354 PrimitiveBaseShape pbs, bool isphysical, uint localID)
1355 {
1356 Vector3 pos = position;
1357 Vector3 siz = size;
1358 Quaternion rot = rotation;
1359 1358
1360 OdePrim newPrim; 1359 public void addActivePrim(OdePrim activatePrim)
1361 lock (OdeLock) 1360 {
1361 // adds active prim..
1362 lock (_activeprims)
1362 { 1363 {
1363 newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical,false,0,localID); 1364 if (!_activeprims.Contains(activatePrim))
1364 1365 _activeprims.Add(activatePrim);
1365 lock (_prims)
1366 _prims.Add(newPrim);
1367 } 1366 }
1368 return newPrim;
1369 } 1367 }
1370 1368
1371 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, 1369 public void addActiveGroups(OdePrim activatePrim)
1372 PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, uint localID)
1373 { 1370 {
1374 Vector3 pos = position; 1371 lock (_activegroups)
1375 Vector3 siz = size;
1376 Quaternion rot = rotation;
1377
1378 OdePrim newPrim;
1379 lock (OdeLock)
1380 { 1372 {
1381 newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical, isPhantom, 0, localID); 1373 if (!_activegroups.Contains(activatePrim))
1382 1374 _activegroups.Add(activatePrim);
1383 lock (_prims)
1384 _prims.Add(newPrim);
1385 } 1375 }
1386 return newPrim;
1387 } 1376 }
1388 1377
1389 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, 1378 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
1390 PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, byte shapeType, uint localID) 1379 PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, byte shapeType, uint localID)
1391 { 1380 {
1392 Vector3 pos = position;
1393 Vector3 siz = size;
1394 Quaternion rot = rotation;
1395
1396 OdePrim newPrim; 1381 OdePrim newPrim;
1397 lock (OdeLock) 1382 lock (OdeLock)
1398 { 1383 {
1399 newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical, isPhantom, shapeType, localID); 1384 newPrim = new OdePrim(name, this, position, size, rotation, pbs, isphysical, isPhantom, shapeType, localID);
1400
1401 lock (_prims) 1385 lock (_prims)
1402 _prims.Add(newPrim); 1386 _prims.Add(newPrim);
1403 } 1387 }
1404 return newPrim; 1388 return newPrim;
1405 } 1389 }
1406 1390
1407 public void addActivePrim(OdePrim activatePrim)
1408 {
1409 // adds active prim..
1410 lock (_activeprims)
1411 {
1412 if (!_activeprims.Contains(activatePrim))
1413 _activeprims.Add(activatePrim);
1414 }
1415 }
1416
1417 public void addActiveGroups(OdePrim activatePrim)
1418 {
1419 lock (_activegroups)
1420 {
1421 if (!_activegroups.Contains(activatePrim))
1422 _activegroups.Add(activatePrim);
1423 }
1424 }
1425
1426 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 1391 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
1427 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, uint localid) 1392 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, uint localid)
1428 { 1393 {
1429 return AddPrim(primName, position, size, rotation, pbs, isPhysical, isPhantom, localid); 1394 return AddPrim(primName, position, size, rotation, pbs, isPhysical, isPhantom, 0 , localid);
1430 } 1395 }
1431 1396
1432 1397
1433 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 1398 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
1434 Vector3 size, Quaternion rotation, bool isPhysical, uint localid) 1399 Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
1435 { 1400 {
1436#if SPAM 1401 return AddPrim(primName, position, size, rotation, pbs, isPhysical,false, 0, localid);
1437 m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName);
1438#endif
1439
1440 return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid);
1441 } 1402 }
1442 1403
1443 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 1404 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
1444 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapeType, uint localid) 1405 Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapeType, uint localid)
1445 { 1406 {
1446#if SPAM
1447 m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName);
1448#endif
1449 1407
1450 return AddPrim(primName, position, size, rotation, pbs, isPhysical,isPhantom, shapeType, localid); 1408 return AddPrim(primName, position, size, rotation, pbs, isPhysical,isPhantom, shapeType, localid);
1451 } 1409 }
1452 1410
1453 public override float TimeDilation
1454 {
1455 get { return m_timeDilation; }
1456 }
1457
1458 public override bool SupportsNINJAJoints
1459 {
1460 get { return false; }
1461 }
1462
1463
1464 public void remActivePrim(OdePrim deactivatePrim) 1411 public void remActivePrim(OdePrim deactivatePrim)
1465 { 1412 {
1466 lock (_activeprims) 1413 lock (_activeprims)
@@ -1513,6 +1460,28 @@ namespace OpenSim.Region.Physics.OdePlugin
1513 } 1460 }
1514 1461
1515 } 1462 }
1463
1464 public bool havePrim(OdePrim prm)
1465 {
1466 lock (_prims)
1467 return _prims.Contains(prm);
1468 }
1469
1470 public bool haveActor(PhysicsActor actor)
1471 {
1472 if (actor is OdePrim)
1473 {
1474 lock (_prims)
1475 return _prims.Contains((OdePrim)actor);
1476 }
1477 else if (actor is OdeCharacter)
1478 {
1479 lock (_characters)
1480 return _characters.Contains((OdeCharacter)actor);
1481 }
1482 return false;
1483 }
1484
1516 #endregion 1485 #endregion
1517 1486
1518 #region Space Separation Calculation 1487 #region Space Separation Calculation
@@ -1615,135 +1584,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1615 1584
1616 #endregion 1585 #endregion
1617 1586
1618 /// <summary>
1619 /// Routine to figure out if we need to mesh this prim with our mesher
1620 /// </summary>
1621 /// <param name="pbs"></param>
1622 /// <returns></returns>
1623 public bool needsMeshing(PrimitiveBaseShape pbs)
1624 {
1625 // check sculpts or meshs
1626 if (pbs.SculptEntry)
1627 {
1628 if (meshSculptedPrim)
1629 return true;
1630
1631 if (pbs.SculptType == (byte)SculptType.Mesh) // always do meshs
1632 return true;
1633
1634 return false;
1635 }
1636
1637 if (forceSimplePrimMeshing)
1638 return true;
1639
1640 // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim
1641
1642 if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
1643 || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
1644 && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z))
1645 {
1646
1647 if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
1648 && pbs.ProfileHollow == 0
1649 && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
1650 && pbs.PathBegin == 0 && pbs.PathEnd == 0
1651 && pbs.PathTaperX == 0 && pbs.PathTaperY == 0
1652 && pbs.PathScaleX == 100 && pbs.PathScaleY == 100
1653 && pbs.PathShearX == 0 && pbs.PathShearY == 0)
1654 {
1655#if SPAM
1656 m_log.Warn("NonMesh");
1657#endif
1658 return false;
1659 }
1660 }
1661
1662 // following code doesn't give meshs to boxes and spheres ever
1663 // and it's odd.. so for now just return true if asked to force meshs
1664 // hopefully mesher will fail if doesn't suport so things still get basic boxes
1665
1666 int iPropertiesNotSupportedDefault = 0;
1667
1668 if (pbs.ProfileHollow != 0)
1669 iPropertiesNotSupportedDefault++;
1670
1671 if ((pbs.PathBegin != 0) || pbs.PathEnd != 0)
1672 iPropertiesNotSupportedDefault++;
1673
1674 if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
1675 iPropertiesNotSupportedDefault++;
1676
1677 if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
1678 iPropertiesNotSupportedDefault++;
1679
1680 if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
1681 iPropertiesNotSupportedDefault++;
1682
1683 if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
1684 iPropertiesNotSupportedDefault++;
1685
1686 if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
1687 iPropertiesNotSupportedDefault++;
1688
1689 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X))
1690 iPropertiesNotSupportedDefault++;
1691
1692 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1)
1693 iPropertiesNotSupportedDefault++;
1694
1695 // test for torus
1696 if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
1697 {
1698 if (pbs.PathCurve == (byte)Extrusion.Curve1)
1699 {
1700 iPropertiesNotSupportedDefault++;
1701 }
1702 }
1703 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
1704 {
1705 if (pbs.PathCurve == (byte)Extrusion.Straight)
1706 {
1707 iPropertiesNotSupportedDefault++;
1708 }
1709
1710 // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
1711 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
1712 {
1713 iPropertiesNotSupportedDefault++;
1714 }
1715 }
1716 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
1717 {
1718 if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2)
1719 {
1720 iPropertiesNotSupportedDefault++;
1721 }
1722 }
1723 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
1724 {
1725 if (pbs.PathCurve == (byte)Extrusion.Straight)
1726 {
1727 iPropertiesNotSupportedDefault++;
1728 }
1729 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
1730 {
1731 iPropertiesNotSupportedDefault++;
1732 }
1733 }
1734
1735 if (iPropertiesNotSupportedDefault == 0)
1736 {
1737#if SPAM
1738 m_log.Warn("NonMesh");
1739#endif
1740 return false;
1741 }
1742#if SPAM
1743 m_log.Debug("Mesh");
1744#endif
1745 return true;
1746 }
1747 1587
1748 /// <summary> 1588 /// <summary>
1749 /// Called to queue a change to a actor 1589 /// Called to queue a change to a actor
@@ -1814,20 +1654,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1814 { 1654 {
1815 if (world == IntPtr.Zero) 1655 if (world == IntPtr.Zero)
1816 return 0; 1656 return 0;
1657
1658 d.WorldSetQuickStepNumIterations(world, curphysiteractions);
1817 1659
1818 // adjust number of iterations per step
1819
1820// try
1821// {
1822 d.WorldSetQuickStepNumIterations(world, curphysiteractions);
1823/* }
1824 catch (StackOverflowException)
1825 {
1826 m_log.Error("[PHYSICS]: The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim.");
1827// ode.drelease(world);
1828 base.TriggerPhysicsBasedRestart();
1829 }
1830*/
1831 while (step_time > HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever 1660 while (step_time > HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever
1832 { 1661 {
1833 try 1662 try
@@ -1855,8 +1684,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1855 } 1684 }
1856 catch 1685 catch
1857 { 1686 {
1858 m_log.Warn("[PHYSICS]: doChange failed for a actor"); 1687 m_log.WarnFormat("[PHYSICS]: doChange failed for a actor {0} {1}",
1859 }; 1688 item.actor.Name, item.what.ToString());
1689 }
1860 } 1690 }
1861 ttmp = Util.EnvironmentTickCountSubtract(ttmpstart); 1691 ttmp = Util.EnvironmentTickCountSubtract(ttmpstart);
1862 if (ttmp > 20) 1692 if (ttmp > 20)
@@ -2599,6 +2429,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2599*/ 2429*/
2600 public override void Dispose() 2430 public override void Dispose()
2601 { 2431 {
2432 if (m_meshWorker != null)
2433 m_meshWorker.Stop();
2434
2602 lock (OdeLock) 2435 lock (OdeLock)
2603 { 2436 {
2604 m_rayCastManager.Dispose(); 2437 m_rayCastManager.Dispose();