aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-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.cs5
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Mesh.cs84
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs40
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs762
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs149
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs206
10 files changed, 1062 insertions, 202 deletions
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 3c4f737..143648e 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -763,6 +763,11 @@ namespace OpenSim.Region.Physics.Meshing
763 763
764 return mesh; 764 return mesh;
765 } 765 }
766 public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
767 {
768 return null;
769 }
770
766 public void ReleaseMesh(IMesh imesh) { } 771 public void ReleaseMesh(IMesh imesh) { }
767 public void ExpireReleaseMeshs() { } 772 public void ExpireReleaseMeshs() { }
768 } 773 }
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..44c8972 100644
--- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
@@ -1061,6 +1061,42 @@ namespace OpenSim.Region.Physics.Meshing
1061 1061
1062 private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f); 1062 private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f);
1063 1063
1064 public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
1065 {
1066 Mesh mesh = null;
1067
1068 if (size.X < 0.01f) size.X = 0.01f;
1069 if (size.Y < 0.01f) size.Y = 0.01f;
1070 if (size.Z < 0.01f) size.Z = 0.01f;
1071
1072 AMeshKey key = GetMeshUniqueKey(primShape, size, (byte)lod, convex);
1073 lock (m_uniqueMeshes)
1074 {
1075 m_uniqueMeshes.TryGetValue(key, out mesh);
1076
1077 if (mesh != null)
1078 {
1079 mesh.RefCount++;
1080 return mesh;
1081 }
1082 }
1083
1084 // try to find a identical mesh on meshs recently released
1085 lock (m_uniqueReleasedMeshes)
1086 {
1087 m_uniqueReleasedMeshes.TryGetValue(key, out mesh);
1088 if (mesh != null)
1089 {
1090 m_uniqueReleasedMeshes.Remove(key);
1091 lock (m_uniqueMeshes)
1092 m_uniqueMeshes.Add(key, mesh);
1093 mesh.RefCount = 1;
1094 return mesh;
1095 }
1096 }
1097 return null;
1098 }
1099
1064 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) 1100 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
1065 { 1101 {
1066#if SPAM 1102#if SPAM
@@ -1068,15 +1104,13 @@ namespace OpenSim.Region.Physics.Meshing
1068#endif 1104#endif
1069 1105
1070 Mesh mesh = null; 1106 Mesh mesh = null;
1071// ulong key = 0;
1072
1073 1107
1074 if (size.X < 0.01f) size.X = 0.01f; 1108 if (size.X < 0.01f) size.X = 0.01f;
1075 if (size.Y < 0.01f) size.Y = 0.01f; 1109 if (size.Y < 0.01f) size.Y = 0.01f;
1076 if (size.Z < 0.01f) size.Z = 0.01f; 1110 if (size.Z < 0.01f) size.Z = 0.01f;
1077 1111
1078 // try to find a identical mesh on meshs in use 1112 // try to find a identical mesh on meshs in use
1079// key = primShape.GetMeshKey(size, lod, convex); 1113
1080 AMeshKey key = GetMeshUniqueKey(primShape,size,(byte)lod, convex); 1114 AMeshKey key = GetMeshUniqueKey(primShape,size,(byte)lod, convex);
1081 1115
1082 lock (m_uniqueMeshes) 1116 lock (m_uniqueMeshes)
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
new file mode 100644
index 0000000..702c336
--- /dev/null
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
@@ -0,0 +1,762 @@
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 class ODEMeshWorker
22 {
23 private ILog m_log;
24 private OdeScene m_scene;
25 private IMesher m_mesher;
26
27
28 public bool meshSculptedPrim = true;
29 public bool forceSimplePrimMeshing = false;
30 public float meshSculptLOD = 32;
31 public float MeshSculptphysicalLOD = 32;
32
33 private IntPtr m_workODEspace = IntPtr.Zero;
34
35 public ODEMeshWorker(OdeScene pScene, ILog pLog, IMesher pMesher, IntPtr pWorkSpace, IConfig pConfig)
36 {
37 m_scene = pScene;
38 m_log = pLog;
39 m_mesher = pMesher;
40 m_workODEspace = pWorkSpace;
41
42 if (pConfig != null)
43 {
44 forceSimplePrimMeshing = pConfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing);
45 meshSculptedPrim = pConfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim);
46 meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD);
47 MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
48 }
49 }
50
51 /// <summary>
52 /// Routine to figure out if we need to mesh this prim with our mesher
53 /// </summary>
54 /// <param name="pbs"></param>
55 /// <returns></returns>
56 public bool needsMeshing(PrimitiveBaseShape pbs)
57 {
58 // check sculpts or meshs
59 if (pbs.SculptEntry)
60 {
61 if (meshSculptedPrim)
62 return true;
63
64 if (pbs.SculptType == (byte)SculptType.Mesh) // always do meshs
65 return true;
66
67 return false;
68 }
69
70 if (forceSimplePrimMeshing)
71 return true;
72
73 // 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
74
75 if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
76 || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
77 && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z))
78 {
79
80 if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
81 && pbs.ProfileHollow == 0
82 && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
83 && pbs.PathBegin == 0 && pbs.PathEnd == 0
84 && pbs.PathTaperX == 0 && pbs.PathTaperY == 0
85 && pbs.PathScaleX == 100 && pbs.PathScaleY == 100
86 && pbs.PathShearX == 0 && pbs.PathShearY == 0)
87 {
88 return false;
89 }
90 }
91
92 // following code doesn't give meshs to boxes and spheres ever
93 // and it's odd.. so for now just return true if asked to force meshs
94 // hopefully mesher will fail if doesn't suport so things still get basic boxes
95
96 int iPropertiesNotSupportedDefault = 0;
97
98 if (pbs.ProfileHollow != 0)
99 iPropertiesNotSupportedDefault++;
100
101 if ((pbs.PathBegin != 0) || pbs.PathEnd != 0)
102 iPropertiesNotSupportedDefault++;
103
104 if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
105 iPropertiesNotSupportedDefault++;
106
107 if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
108 iPropertiesNotSupportedDefault++;
109
110 if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
111 iPropertiesNotSupportedDefault++;
112
113 if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
114 iPropertiesNotSupportedDefault++;
115
116 if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
117 iPropertiesNotSupportedDefault++;
118
119 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))
120 iPropertiesNotSupportedDefault++;
121
122 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1)
123 iPropertiesNotSupportedDefault++;
124
125 // test for torus
126 if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
127 {
128 if (pbs.PathCurve == (byte)Extrusion.Curve1)
129 {
130 iPropertiesNotSupportedDefault++;
131 }
132 }
133 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
134 {
135 if (pbs.PathCurve == (byte)Extrusion.Straight)
136 {
137 iPropertiesNotSupportedDefault++;
138 }
139
140 // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
141 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
142 {
143 iPropertiesNotSupportedDefault++;
144 }
145 }
146 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
147 {
148 if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2)
149 {
150 iPropertiesNotSupportedDefault++;
151 }
152 }
153 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
154 {
155 if (pbs.PathCurve == (byte)Extrusion.Straight)
156 {
157 iPropertiesNotSupportedDefault++;
158 }
159 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
160 {
161 iPropertiesNotSupportedDefault++;
162 }
163 }
164
165 if (iPropertiesNotSupportedDefault == 0)
166 {
167 return false;
168 }
169 return true;
170 }
171
172 public IMesh getMesh(PhysicsActor actor, PrimitiveBaseShape ppbs, Vector3 psize, byte pshapetype)
173 {
174 if (!(actor is OdePrim))
175 return null;
176
177 IMesh mesh = null;
178 PrimitiveBaseShape pbs = ppbs;
179 Vector3 size = psize;
180 byte shapetype = pshapetype;
181
182 if (needsMeshing(pbs))
183 {
184 bool convex;
185 int clod = (int)LevelOfDetail.High;
186 if (shapetype == 0)
187 convex = false;
188 else
189 {
190 convex = true;
191 if (pbs.SculptType != (byte)SculptType.Mesh)
192 clod = (int)LevelOfDetail.Low;
193 }
194 mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);
195 if (mesh == null)
196 {
197 if (!pbs.SculptEntry)
198 return m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
199
200 if (pbs.SculptTexture == UUID.Zero)
201 return null;
202
203 if (pbs.SculptType != (byte)SculptType.Mesh)
204 { // check for sculpt decoded image on cache)
205 if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + pbs.SculptTexture.ToString())))
206 return m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
207 }
208
209 if (pbs.SculptData != null && pbs.SculptData.Length > 0)
210 return m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
211
212 ODEAssetRequest asr;
213 RequestAssetDelegate assetProvider = m_scene.RequestAssetMethod;
214 if (assetProvider != null)
215 asr = new ODEAssetRequest(this, assetProvider, actor, pbs, m_log);
216
217 return null;
218 }
219 }
220 return mesh;
221 }
222
223 private bool GetTriMeshGeo(ODEPhysRepData repData)
224 {
225 IntPtr vertices, indices;
226 IntPtr triMeshData = IntPtr.Zero;
227 IntPtr geo = IntPtr.Zero;
228 int vertexCount, indexCount;
229 int vertexStride, triStride;
230
231 PhysicsActor actor = repData.actor;
232
233 IMesh mesh = repData.mesh;
234
235 if (mesh == null)
236 {
237 mesh = getMesh(repData.actor, repData.pbs, repData.size, repData.shapetype);
238 }
239
240 if (mesh == null)
241 return false;
242
243 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap
244 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
245
246 if (vertexCount == 0 || indexCount == 0)
247 {
248 m_log.WarnFormat("[PHYSICS]: Invalid mesh data on prim {0} mesh UUID {1}",
249 actor.Name, repData.pbs.SculptTexture.ToString());
250 mesh.releaseSourceMeshData();
251 return false;
252 }
253
254 repData.OBBOffset = mesh.GetCentroid();
255 repData.OBB = mesh.GetOBB();
256 repData.hasOBB = true;
257 repData.physCost = 0.0013f * (float)indexCount;
258
259 mesh.releaseSourceMeshData();
260
261 try
262 {
263 triMeshData = d.GeomTriMeshDataCreate();
264
265 d.GeomTriMeshDataBuildSimple(triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
266 d.GeomTriMeshDataPreprocess(triMeshData);
267
268 m_scene.waitForSpaceUnlock(m_workODEspace);
269 geo = d.CreateTriMesh(m_workODEspace, triMeshData, null, null, null);
270 }
271
272 catch (Exception e)
273 {
274 m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", actor.Name, e);
275 if (triMeshData != IntPtr.Zero)
276 {
277 d.GeomTriMeshDataDestroy(triMeshData);
278 repData.triMeshData = IntPtr.Zero;
279 }
280 repData.geo = IntPtr.Zero;
281 return false;
282 }
283
284 repData.geo = geo;
285 repData.triMeshData = triMeshData;
286 repData.curSpace = m_workODEspace;
287 return true;
288 }
289
290 public ODEPhysRepData CreateActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs, IMesh pMesh, Vector3 size, byte shapetype)
291 {
292 ODEPhysRepData repData = new ODEPhysRepData();
293
294 repData.actor = actor;
295 repData.pbs = pbs;
296 repData.mesh = pMesh;
297 repData.size = size;
298 repData.shapetype = shapetype;
299
300 IntPtr geo = IntPtr.Zero;
301 bool hasMesh = false;
302 if (needsMeshing(pbs))
303 {
304 if (GetTriMeshGeo(repData))
305 hasMesh = true;
306 else
307 repData.NoColide = true;
308 }
309
310 if (!hasMesh)
311 {
312 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
313 && size.X == size.Y && size.Y == size.Z)
314 { // it's a sphere
315 m_scene.waitForSpaceUnlock(m_workODEspace);
316 try
317 {
318 geo = d.CreateSphere(m_workODEspace, size.X * 0.5f);
319 }
320 catch (Exception e)
321 {
322 m_log.WarnFormat("[PHYSICS]: Create sphere failed: {0}", e);
323 return null;
324 }
325 }
326 else
327 {// do it as a box
328 m_scene.waitForSpaceUnlock(m_workODEspace);
329 try
330 {
331 //Console.WriteLine(" CreateGeom 4");
332 geo = d.CreateBox(m_workODEspace, size.X, size.Y, size.Z);
333 }
334 catch (Exception e)
335 {
336 m_log.Warn("[PHYSICS]: Create box failed: {0}", e);
337 return null;
338 }
339 }
340
341 repData.physCost = 0.1f;
342 repData.streamCost = 1.0f;
343 repData.geo = geo;
344 }
345
346 repData.curSpace = m_workODEspace;
347
348 CalcVolumeData(repData);
349
350 return repData;
351 }
352
353 public void ChangeActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs,
354 Vector3 size, byte shapetype, MeshWorkerChange what)
355 {
356 ODEPhysRepData repData = CreateActorPhysRep(actor, pbs, null, size, shapetype);
357 repData.changed |= what;
358 if (repData != null && actor != null)
359 ((OdePrim)actor).AddChange(changes.PhysRepData, repData);
360 }
361
362 private void CalculateBasicPrimVolume(ODEPhysRepData repData)
363 {
364 PrimitiveBaseShape _pbs = repData.pbs;
365 Vector3 _size = repData.size;
366
367 float volume = _size.X * _size.Y * _size.Z; // default
368 float tmp;
369
370 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
371 float hollowVolume = hollowAmount * hollowAmount;
372
373 switch (_pbs.ProfileShape)
374 {
375 case ProfileShape.Square:
376 // default box
377
378 if (_pbs.PathCurve == (byte)Extrusion.Straight)
379 {
380 if (hollowAmount > 0.0)
381 {
382 switch (_pbs.HollowShape)
383 {
384 case HollowShape.Square:
385 case HollowShape.Same:
386 break;
387
388 case HollowShape.Circle:
389
390 hollowVolume *= 0.78539816339f;
391 break;
392
393 case HollowShape.Triangle:
394
395 hollowVolume *= (0.5f * .5f);
396 break;
397
398 default:
399 hollowVolume = 0;
400 break;
401 }
402 volume *= (1.0f - hollowVolume);
403 }
404 }
405
406 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
407 {
408 //a tube
409
410 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX);
411 tmp = 1.0f - 2.0e-2f * (float)(200 - _pbs.PathScaleY);
412 volume -= volume * tmp * tmp;
413
414 if (hollowAmount > 0.0)
415 {
416 hollowVolume *= hollowAmount;
417
418 switch (_pbs.HollowShape)
419 {
420 case HollowShape.Square:
421 case HollowShape.Same:
422 break;
423
424 case HollowShape.Circle:
425 hollowVolume *= 0.78539816339f;
426 break;
427
428 case HollowShape.Triangle:
429 hollowVolume *= 0.5f * 0.5f;
430 break;
431 default:
432 hollowVolume = 0;
433 break;
434 }
435 volume *= (1.0f - hollowVolume);
436 }
437 }
438
439 break;
440
441 case ProfileShape.Circle:
442
443 if (_pbs.PathCurve == (byte)Extrusion.Straight)
444 {
445 volume *= 0.78539816339f; // elipse base
446
447 if (hollowAmount > 0.0)
448 {
449 switch (_pbs.HollowShape)
450 {
451 case HollowShape.Same:
452 case HollowShape.Circle:
453 break;
454
455 case HollowShape.Square:
456 hollowVolume *= 0.5f * 2.5984480504799f;
457 break;
458
459 case HollowShape.Triangle:
460 hollowVolume *= .5f * 1.27323954473516f;
461 break;
462
463 default:
464 hollowVolume = 0;
465 break;
466 }
467 volume *= (1.0f - hollowVolume);
468 }
469 }
470
471 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
472 {
473 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX);
474 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
475 volume *= (1.0f - tmp * tmp);
476
477 if (hollowAmount > 0.0)
478 {
479
480 // calculate the hollow volume by it's shape compared to the prim shape
481 hollowVolume *= hollowAmount;
482
483 switch (_pbs.HollowShape)
484 {
485 case HollowShape.Same:
486 case HollowShape.Circle:
487 break;
488
489 case HollowShape.Square:
490 hollowVolume *= 0.5f * 2.5984480504799f;
491 break;
492
493 case HollowShape.Triangle:
494 hollowVolume *= .5f * 1.27323954473516f;
495 break;
496
497 default:
498 hollowVolume = 0;
499 break;
500 }
501 volume *= (1.0f - hollowVolume);
502 }
503 }
504 break;
505
506 case ProfileShape.HalfCircle:
507 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
508 {
509 volume *= 0.5236f;
510
511 if (hollowAmount > 0.0)
512 {
513 hollowVolume *= hollowAmount;
514
515 switch (_pbs.HollowShape)
516 {
517 case HollowShape.Circle:
518 case HollowShape.Triangle: // diference in sl is minor and odd
519 case HollowShape.Same:
520 break;
521
522 case HollowShape.Square:
523 hollowVolume *= 0.909f;
524 break;
525
526 // case HollowShape.Triangle:
527 // hollowVolume *= .827f;
528 // break;
529 default:
530 hollowVolume = 0;
531 break;
532 }
533 volume *= (1.0f - hollowVolume);
534 }
535
536 }
537 break;
538
539 case ProfileShape.EquilateralTriangle:
540
541 if (_pbs.PathCurve == (byte)Extrusion.Straight)
542 {
543 volume *= 0.32475953f;
544
545 if (hollowAmount > 0.0)
546 {
547
548 // calculate the hollow volume by it's shape compared to the prim shape
549 switch (_pbs.HollowShape)
550 {
551 case HollowShape.Same:
552 case HollowShape.Triangle:
553 hollowVolume *= .25f;
554 break;
555
556 case HollowShape.Square:
557 hollowVolume *= 0.499849f * 3.07920140172638f;
558 break;
559
560 case HollowShape.Circle:
561 // Hollow shape is a perfect cyllinder in respect to the cube's scale
562 // Cyllinder hollow volume calculation
563
564 hollowVolume *= 0.1963495f * 3.07920140172638f;
565 break;
566
567 default:
568 hollowVolume = 0;
569 break;
570 }
571 volume *= (1.0f - hollowVolume);
572 }
573 }
574 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
575 {
576 volume *= 0.32475953f;
577 volume *= 0.01f * (float)(200 - _pbs.PathScaleX);
578 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
579 volume *= (1.0f - tmp * tmp);
580
581 if (hollowAmount > 0.0)
582 {
583
584 hollowVolume *= hollowAmount;
585
586 switch (_pbs.HollowShape)
587 {
588 case HollowShape.Same:
589 case HollowShape.Triangle:
590 hollowVolume *= .25f;
591 break;
592
593 case HollowShape.Square:
594 hollowVolume *= 0.499849f * 3.07920140172638f;
595 break;
596
597 case HollowShape.Circle:
598
599 hollowVolume *= 0.1963495f * 3.07920140172638f;
600 break;
601
602 default:
603 hollowVolume = 0;
604 break;
605 }
606 volume *= (1.0f - hollowVolume);
607 }
608 }
609 break;
610
611 default:
612 break;
613 }
614
615 float taperX1;
616 float taperY1;
617 float taperX;
618 float taperY;
619 float pathBegin;
620 float pathEnd;
621 float profileBegin;
622 float profileEnd;
623
624 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible)
625 {
626 taperX1 = _pbs.PathScaleX * 0.01f;
627 if (taperX1 > 1.0f)
628 taperX1 = 2.0f - taperX1;
629 taperX = 1.0f - taperX1;
630
631 taperY1 = _pbs.PathScaleY * 0.01f;
632 if (taperY1 > 1.0f)
633 taperY1 = 2.0f - taperY1;
634 taperY = 1.0f - taperY1;
635 }
636 else
637 {
638 taperX = _pbs.PathTaperX * 0.01f;
639 if (taperX < 0.0f)
640 taperX = -taperX;
641 taperX1 = 1.0f - taperX;
642
643 taperY = _pbs.PathTaperY * 0.01f;
644 if (taperY < 0.0f)
645 taperY = -taperY;
646 taperY1 = 1.0f - taperY;
647 }
648
649 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
650
651 pathBegin = (float)_pbs.PathBegin * 2.0e-5f;
652 pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f;
653 volume *= (pathEnd - pathBegin);
654
655 // this is crude aproximation
656 profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f;
657 profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f;
658 volume *= (profileEnd - profileBegin);
659
660 repData.volume = volume;
661 }
662
663 private void CalcVolumeData(ODEPhysRepData repData)
664 {
665 float volume;
666 Vector3 OBB = repData.size;
667 Vector3 OBBoffset;
668 IntPtr geo = repData.geo;
669
670 if (geo == IntPtr.Zero || repData.triMeshData == IntPtr.Zero)
671 {
672 OBB.X *= 0.5f;
673 OBB.Y *= 0.5f;
674 OBB.Z *= 0.5f;
675
676 repData.OBB = OBB;
677 repData.OBBOffset = Vector3.Zero;
678 }
679 else if (!repData.hasOBB) // should this happen?
680 {
681 d.AABB AABB;
682 d.GeomGetAABB(geo, out AABB); // get the AABB from engine geom
683
684 OBB.X = (AABB.MaxX - AABB.MinX) * 0.5f;
685 OBB.Y = (AABB.MaxY - AABB.MinY) * 0.5f;
686 OBB.Z = (AABB.MaxZ - AABB.MinZ) * 0.5f;
687 repData.OBB = OBB;
688 OBBoffset.X = (AABB.MaxX + AABB.MinX) * 0.5f;
689 OBBoffset.Y = (AABB.MaxY + AABB.MinY) * 0.5f;
690 OBBoffset.Z = (AABB.MaxZ + AABB.MinZ) * 0.5f;
691 repData.OBBOffset = Vector3.Zero;
692 }
693
694 // also its own inertia and mass
695 // keep using basic shape mass for now
696 CalculateBasicPrimVolume(repData);
697
698 if (repData.hasOBB)
699 {
700 OBB = repData.OBB;
701 float pc = repData.physCost;
702 float psf = OBB.X * (OBB.Y + OBB.Z) + OBB.Y * OBB.Z;
703 psf *= 1.33f * .2f;
704
705 pc *= psf;
706 if (pc < 0.1f)
707 pc = 0.1f;
708
709 repData.physCost = pc;
710 }
711 else
712 repData.physCost = 0.1f;
713 }
714 }
715
716 public class ODEAssetRequest
717 {
718 PhysicsActor m_actor;
719 ODEMeshWorker m_worker;
720 PrimitiveBaseShape m_pbs;
721 private ILog m_log;
722
723 public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider,
724 PhysicsActor pActor, PrimitiveBaseShape ppbs, ILog plog)
725 {
726 m_actor = pActor;
727 m_worker = pWorker;
728 m_pbs = ppbs;
729 m_log = plog;
730
731 if (provider == null)
732 return;
733
734 UUID assetID = m_pbs.SculptTexture;
735 if (assetID == UUID.Zero)
736 return;
737
738 provider(assetID, ODEassetReceived);
739 }
740
741 void ODEassetReceived(AssetBase asset)
742 {
743 if (m_actor != null && m_pbs != null)
744 {
745 if (asset != null)
746 {
747 if (asset.Data != null && asset.Data.Length > 0)
748 {
749 m_pbs.SculptData = asset.Data;
750 m_actor.Shape = m_pbs;
751 }
752 else
753 m_log.WarnFormat("[PHYSICS]: asset provider returned invalid mesh data for prim {0} asset UUID {1}.",
754 m_actor.Name, asset.ID.ToString());
755 }
756 else
757 m_log.WarnFormat("[PHYSICS]: asset provider returned null asset fo mesh of prim {0}.",
758 m_actor.Name);
759 }
760 }
761 }
762} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index f2f4725..7650571 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -104,9 +104,6 @@ namespace OpenSim.Region.Physics.OdePlugin
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;
@@ -395,6 +392,8 @@ namespace OpenSim.Region.Physics.OdePlugin
395 if (value.IsFinite()) 392 if (value.IsFinite())
396 { 393 {
397 AddChange(changes.Size, value); 394 AddChange(changes.Size, value);
395
396// _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, value, m_shapetype, MeshWorkerChange.size);
398 } 397 }
399 else 398 else
400 { 399 {
@@ -529,6 +528,7 @@ namespace OpenSim.Region.Physics.OdePlugin
529 set 528 set
530 { 529 {
531 AddChange(changes.Shape, value); 530 AddChange(changes.Shape, value);
531// _parent_scene.m_meshWorker.ChangeActorPhysRep(this, value, _size, m_shapetype, MeshWorkerChange.shape);
532 } 532 }
533 } 533 }
534 534
@@ -542,10 +542,10 @@ namespace OpenSim.Region.Physics.OdePlugin
542 { 542 {
543 m_shapetype = value; 543 m_shapetype = value;
544 AddChange(changes.Shape, null); 544 AddChange(changes.Shape, null);
545// _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, _size, value, MeshWorkerChange.shapetype);
545 } 546 }
546 } 547 }
547 548
548
549 public override Vector3 Velocity 549 public override Vector3 Velocity
550 { 550 {
551 get 551 get
@@ -1080,7 +1080,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1080 bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; 1080 bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce;
1081 1081
1082 CalcPrimBodyData(); 1082 CalcPrimBodyData();
1083 1083/*
1084 m_mesh = null; 1084 m_mesh = null;
1085 if (_parent_scene.needsMeshing(pbs) && (pbs.SculptData.Length > 0)) 1085 if (_parent_scene.needsMeshing(pbs) && (pbs.SculptData.Length > 0))
1086 { 1086 {
@@ -1096,6 +1096,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1096 } 1096 }
1097 m_mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex); 1097 m_mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex);
1098 } 1098 }
1099*/
1100 m_mesh = _parent_scene.m_meshWorker.getMesh(this, pbs, _size, m_shapetype);
1099 1101
1100 m_building = true; // control must set this to false when done 1102 m_building = true; // control must set this to false when done
1101 1103
@@ -1351,6 +1353,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1351 { 1353 {
1352 if (m_mesh == null) 1354 if (m_mesh == null)
1353 { 1355 {
1356/*
1354 bool convex; 1357 bool convex;
1355 int clod = (int)LevelOfDetail.High; 1358 int clod = (int)LevelOfDetail.High;
1356 1359
@@ -1364,6 +1367,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1364 } 1367 }
1365 1368
1366 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex); 1369 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex);
1370*/
1371 mesh = _parent_scene.m_meshWorker.getMesh(this, _pbs, _size, m_shapetype);
1367 } 1372 }
1368 else 1373 else
1369 { 1374 {
@@ -1476,7 +1481,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1476 hasOOBoffsetFromMesh = false; 1481 hasOOBoffsetFromMesh = false;
1477 m_NoColide = false; 1482 m_NoColide = false;
1478 1483
1479 if (_parent_scene.needsMeshing(_pbs)) 1484 if (_parent_scene.m_meshWorker.needsMeshing(_pbs))
1480 { 1485 {
1481 haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims 1486 haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims
1482 if (!haveMesh) 1487 if (!haveMesh)
@@ -1524,7 +1529,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1524 { 1529 {
1525 if (prim_geom != IntPtr.Zero) 1530 if (prim_geom != IntPtr.Zero)
1526 { 1531 {
1527// _parent_scene.geom_name_map.Remove(prim_geom);
1528 _parent_scene.actor_name_map.Remove(prim_geom); 1532 _parent_scene.actor_name_map.Remove(prim_geom);
1529 try 1533 try
1530 { 1534 {
@@ -1534,11 +1538,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1534 d.GeomTriMeshDataDestroy(_triMeshData); 1538 d.GeomTriMeshDataDestroy(_triMeshData);
1535 _triMeshData = IntPtr.Zero; 1539 _triMeshData = IntPtr.Zero;
1536 } 1540 }
1537
1538 } 1541 }
1539
1540
1541 // catch (System.AccessViolationException)
1542 catch (Exception e) 1542 catch (Exception e)
1543 { 1543 {
1544 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name, e); 1544 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name, e);
@@ -1552,23 +1552,19 @@ namespace OpenSim.Region.Physics.OdePlugin
1552 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name); 1552 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name);
1553 } 1553 }
1554 1554
1555 if (m_mesh != null) 1555 lock (m_meshlock)
1556 { 1556 {
1557 _parent_scene.mesher.ReleaseMesh(m_mesh); 1557 if (m_mesh != null)
1558 m_mesh = null; 1558 {
1559 _parent_scene.mesher.ReleaseMesh(m_mesh);
1560 m_mesh = null;
1561 }
1559 } 1562 }
1560 1563
1561 Body = IntPtr.Zero; 1564 Body = IntPtr.Zero;
1562 hasOOBoffsetFromMesh = false; 1565 hasOOBoffsetFromMesh = false;
1563 } 1566 }
1564/* 1567
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 1568 //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 1569 // should only be called for non physical prims unless they are becoming non physical
1574 private void SetInStaticSpace(OdePrim prim) 1570 private void SetInStaticSpace(OdePrim prim)
@@ -1631,9 +1627,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1631 1627
1632 if (Body != IntPtr.Zero) 1628 if (Body != IntPtr.Zero)
1633 { 1629 {
1634// d.BodyDestroy(Body);
1635// Body = IntPtr.Zero;
1636 // do a more complet destruction
1637 DestroyBody(); 1630 DestroyBody();
1638 m_log.Warn("[PHYSICS]: MakeBody called having a body"); 1631 m_log.Warn("[PHYSICS]: MakeBody called having a body");
1639 } 1632 }
@@ -2495,6 +2488,26 @@ namespace OpenSim.Region.Physics.OdePlugin
2495 primOOBradiusSQ = primOOBsize.LengthSquared(); 2488 primOOBradiusSQ = primOOBsize.LengthSquared();
2496 } 2489 }
2497 2490
2491 private void UpdatePrimBodyData()
2492 {
2493 primMass = m_density * primVolume;
2494
2495 if (primMass <= 0)
2496 primMass = 0.0001f;//ckrinke: Mass must be greater then zero.
2497 if (primMass > _parent_scene.maximumMassObject)
2498 primMass = _parent_scene.maximumMassObject;
2499
2500 _mass = primMass; // just in case
2501
2502 d.MassSetBoxTotal(out primdMass, primMass, primOOBsize.X, primOOBsize.Y, primOOBsize.Z);
2503
2504 d.MassTranslate(ref primdMass,
2505 primOOBoffset.X,
2506 primOOBoffset.Y,
2507 primOOBoffset.Z);
2508
2509 primOOBradiusSQ = primOOBsize.LengthSquared();
2510 }
2498 2511
2499 #endregion 2512 #endregion
2500 2513
@@ -3227,6 +3240,86 @@ namespace OpenSim.Region.Physics.OdePlugin
3227 changeprimsizeshape(); 3240 changeprimsizeshape();
3228 } 3241 }
3229 3242
3243
3244 private void changePhysRepData(ODEPhysRepData repData)
3245 {
3246 CheckDelaySelect();
3247
3248 OdePrim parent = (OdePrim)_parent;
3249
3250 bool chp = childPrim;
3251
3252 if (chp)
3253 {
3254 if (parent != null)
3255 {
3256 parent.DestroyBody();
3257 }
3258 }
3259 else
3260 {
3261 DestroyBody();
3262 }
3263
3264 RemoveGeom();
3265
3266 prim_geom = repData.geo;
3267 _triMeshData = repData.triMeshData;
3268 _size = repData.size;
3269 _pbs = repData.pbs;
3270 m_mesh = repData.mesh;
3271 m_shapetype = repData.shapetype;
3272
3273 hasOOBoffsetFromMesh = repData.hasOBB;
3274 primOOBoffset = repData.OBBOffset;
3275 primOOBsize = repData.OBB;
3276
3277 m_NoColide = repData.NoColide;
3278// m_physCost = repData.physCost;
3279// m_streamCost = repData.streamCost;
3280
3281 primVolume = repData.volume;
3282 m_targetSpace = repData.curSpace;
3283
3284 UpdatePrimBodyData();
3285
3286 _parent_scene.actor_name_map[prim_geom] = this;
3287
3288 if (prim_geom != IntPtr.Zero)
3289 {
3290 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
3291 d.Quaternion myrot = new d.Quaternion();
3292 myrot.X = _orientation.X;
3293 myrot.Y = _orientation.Y;
3294 myrot.Z = _orientation.Z;
3295 myrot.W = _orientation.W;
3296 d.GeomSetQuaternion(prim_geom, ref myrot);
3297 }
3298
3299 if (m_isphysical)
3300 {
3301 if (chp)
3302 {
3303 if (parent != null)
3304 {
3305 parent.MakeBody();
3306 }
3307 }
3308 else
3309 MakeBody();
3310 }
3311
3312 else
3313 {
3314 SetInStaticSpace(this);
3315 UpdateCollisionCatFlags();
3316 ApplyCollisionCatFlags();
3317 }
3318
3319 resetCollisionAccounting();
3320 }
3321
3322
3230 private void changeFloatOnWater(bool newval) 3323 private void changeFloatOnWater(bool newval)
3231 { 3324 {
3232 m_collidesWater = newval; 3325 m_collidesWater = newval;
@@ -3984,6 +4077,10 @@ namespace OpenSim.Region.Physics.OdePlugin
3984 changeShape((PrimitiveBaseShape)arg); 4077 changeShape((PrimitiveBaseShape)arg);
3985 break; 4078 break;
3986 4079
4080 case changes.PhysRepData:
4081 changePhysRepData((ODEPhysRepData) arg);
4082 break;
4083
3987 case changes.CollidesWater: 4084 case changes.CollidesWater:
3988 changeFloatOnWater((bool)arg); 4085 changeFloatOnWater((bool)arg);
3989 break; 4086 break;
@@ -4072,6 +4169,8 @@ namespace OpenSim.Region.Physics.OdePlugin
4072 donullchange(); 4169 donullchange();
4073 break; 4170 break;
4074 4171
4172
4173
4075 default: 4174 default:
4076 donullchange(); 4175 donullchange();
4077 break; 4176 break;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index f126644..d758c85 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -60,6 +60,30 @@ namespace OpenSim.Region.Physics.OdePlugin
60 public int lastframe; 60 public int lastframe;
61 } 61 }
62 62
63 public class ODEPhysRepData
64 {
65 public PhysicsActor actor;
66 public IntPtr geo = IntPtr.Zero;
67 public IntPtr triMeshData = IntPtr.Zero;
68 public IMesh mesh;
69 public IntPtr curSpace = IntPtr.Zero;
70 public PrimitiveBaseShape pbs;
71
72 public Vector3 size = Vector3.Zero;
73 public Vector3 OBB = Vector3.Zero;
74 public Vector3 OBBOffset = Vector3.Zero;
75
76 public float volume;
77
78 public float physCost = 0.0f;
79 public float streamCost = 0;
80 public MeshWorkerChange changed;
81 public byte shapetype = 0;
82 public bool NoColide = false;
83 public bool hasOBB = false;
84 public bool hasMeshVolume = false;
85 }
86
63 // colision flags of things others can colide with 87 // colision flags of things others can colide with
64 // rays, sensors, probes removed since can't be colided with 88 // rays, sensors, probes removed since can't be colided with
65 // The top space where things are placed provided further selection 89 // The top space where things are placed provided further selection
@@ -109,6 +133,14 @@ namespace OpenSim.Region.Physics.OdePlugin
109 133
110 light = 7 // compatibility with old viewers 134 light = 7 // compatibility with old viewers
111 } 135 }
136 [Flags]
137 public enum MeshWorkerChange : uint
138 {
139 none = 0,
140 size = 1,
141 shape = 2,
142 shapetype = 3,
143 }
112 144
113 public enum changes : int 145 public enum changes : int
114 { 146 {
@@ -147,6 +179,7 @@ namespace OpenSim.Region.Physics.OdePlugin
147 179
148 Size, 180 Size,
149 Shape, 181 Shape,
182 PhysRepData,
150 183
151 CollidesWater, 184 CollidesWater,
152 VolumeDtc, 185 VolumeDtc,
@@ -230,11 +263,6 @@ namespace OpenSim.Region.Physics.OdePlugin
230 private float minimumGroundFlightOffset = 3f; 263 private float minimumGroundFlightOffset = 3f;
231 public float maximumMassObject = 10000.01f; 264 public float maximumMassObject = 10000.01f;
232 265
233 public bool meshSculptedPrim = true;
234 public bool forceSimplePrimMeshing = false;
235
236 public float meshSculptLOD = 32;
237 public float MeshSculptphysicalLOD = 32;
238 266
239 public float geomDefaultDensity = 10.000006836f; 267 public float geomDefaultDensity = 10.000006836f;
240 268
@@ -302,6 +330,7 @@ namespace OpenSim.Region.Physics.OdePlugin
302 public IntPtr TopSpace; // the global space 330 public IntPtr TopSpace; // the global space
303 public IntPtr ActiveSpace; // space for active prims 331 public IntPtr ActiveSpace; // space for active prims
304 public IntPtr StaticSpace; // space for the static things around 332 public IntPtr StaticSpace; // space for the static things around
333 public IntPtr WorkSpace; // no collisions work space
305 334
306 // some speedup variables 335 // some speedup variables
307 private int spaceGridMaxX; 336 private int spaceGridMaxX;
@@ -328,7 +357,7 @@ namespace OpenSim.Region.Physics.OdePlugin
328 private PhysicsScene m_parentScene = null; 357 private PhysicsScene m_parentScene = null;
329 358
330 private ODERayCastRequestManager m_rayCastManager; 359 private ODERayCastRequestManager m_rayCastManager;
331 360 public ODEMeshWorker m_meshWorker;
332 361
333/* maybe needed if ode uses tls 362/* maybe needed if ode uses tls
334 private void checkThread() 363 private void checkThread()
@@ -361,6 +390,8 @@ namespace OpenSim.Region.Physics.OdePlugin
361 nearCallback = near; 390 nearCallback = near;
362 391
363 m_rayCastManager = new ODERayCastRequestManager(this); 392 m_rayCastManager = new ODERayCastRequestManager(this);
393
394
364 lock (OdeLock) 395 lock (OdeLock)
365 { 396 {
366 // Create the world and the first space 397 // Create the world and the first space
@@ -372,6 +403,7 @@ namespace OpenSim.Region.Physics.OdePlugin
372 // now the major subspaces 403 // now the major subspaces
373 ActiveSpace = d.HashSpaceCreate(TopSpace); 404 ActiveSpace = d.HashSpaceCreate(TopSpace);
374 StaticSpace = d.HashSpaceCreate(TopSpace); 405 StaticSpace = d.HashSpaceCreate(TopSpace);
406 WorkSpace = d.HashSpaceCreate(TopSpace);
375 } 407 }
376 catch 408 catch
377 { 409 {
@@ -381,10 +413,12 @@ namespace OpenSim.Region.Physics.OdePlugin
381 d.HashSpaceSetLevels(TopSpace, -2, 8); 413 d.HashSpaceSetLevels(TopSpace, -2, 8);
382 d.HashSpaceSetLevels(ActiveSpace, -2, 8); 414 d.HashSpaceSetLevels(ActiveSpace, -2, 8);
383 d.HashSpaceSetLevels(StaticSpace, -2, 8); 415 d.HashSpaceSetLevels(StaticSpace, -2, 8);
416 d.HashSpaceSetLevels(WorkSpace, -2, 8);
384 417
385 // demote to second level 418 // demote to second level
386 d.SpaceSetSublevel(ActiveSpace, 1); 419 d.SpaceSetSublevel(ActiveSpace, 1);
387 d.SpaceSetSublevel(StaticSpace, 1); 420 d.SpaceSetSublevel(StaticSpace, 1);
421 d.SpaceSetSublevel(WorkSpace, 1);
388 422
389 d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space | 423 d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space |
390 CollisionCategories.Geom | 424 CollisionCategories.Geom |
@@ -402,6 +436,9 @@ namespace OpenSim.Region.Physics.OdePlugin
402 )); 436 ));
403 d.GeomSetCollideBits(StaticSpace, 0); 437 d.GeomSetCollideBits(StaticSpace, 0);
404 438
439 d.GeomSetCategoryBits(WorkSpace, 0);
440 d.GeomSetCollideBits(WorkSpace, 0);
441
405 contactgroup = d.JointGroupCreate(0); 442 contactgroup = d.JointGroupCreate(0);
406 //contactgroup 443 //contactgroup
407 444
@@ -440,9 +477,11 @@ namespace OpenSim.Region.Physics.OdePlugin
440 477
441 int contactsPerCollision = 80; 478 int contactsPerCollision = 80;
442 479
480 IConfig physicsconfig = null;
481
443 if (m_config != null) 482 if (m_config != null)
444 { 483 {
445 IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; 484 physicsconfig = m_config.Configs["ODEPhysicsSettings"];
446 if (physicsconfig != null) 485 if (physicsconfig != null)
447 { 486 {
448 gravityx = physicsconfig.GetFloat("world_gravityx", gravityx); 487 gravityx = physicsconfig.GetFloat("world_gravityx", gravityx);
@@ -469,27 +508,7 @@ namespace OpenSim.Region.Physics.OdePlugin
469 508
470 geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); 509 geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity);
471 bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable); 510 bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable);
472/* 511
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); 512 physics_logging = physicsconfig.GetBoolean("physics_logging", false);
494 physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); 513 physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0);
495 physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); 514 physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false);
@@ -499,6 +518,8 @@ namespace OpenSim.Region.Physics.OdePlugin
499 } 518 }
500 } 519 }
501 520
521 m_meshWorker = new ODEMeshWorker(this, m_log, meshmerizer, WorkSpace, physicsconfig);
522
502 HalfOdeStep = ODE_STEPSIZE * 0.5f; 523 HalfOdeStep = ODE_STEPSIZE * 0.5f;
503 odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f); 524 odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f);
504 525
@@ -1615,135 +1636,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1615 1636
1616 #endregion 1637 #endregion
1617 1638
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 1639
1748 /// <summary> 1640 /// <summary>
1749 /// Called to queue a change to a actor 1641 /// Called to queue a change to a actor