aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs2
-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.cs78
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs40
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs753
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs9
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs196
11 files changed, 924 insertions, 177 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index e6ad89c..1bddf22 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -4902,6 +4902,8 @@ namespace OpenSim.Region.Framework.Scenes
4902 { 4902 {
4903// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4903// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4904 4904
4905 return;
4906
4905 if (ParentGroup.IsDeleted) 4907 if (ParentGroup.IsDeleted)
4906 return; 4908 return;
4907 4909
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..47e0cf4 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,14 @@ 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;
92
93
80 } 94 }
81 95
82 public int RefCount { get; set; } 96 public int RefCount { get; set; }
@@ -102,6 +116,35 @@ namespace OpenSim.Region.Physics.Meshing
102 return result; 116 return result;
103 } 117 }
104 118
119 public void addVertexLStats(Vertex v)
120 {
121 float x = v.X;
122 float y = v.Y;
123 float z = v.Z;
124
125 m_centroid.X += x;
126 m_centroid.Y += y;
127 m_centroid.Z += z;
128 m_centroidDiv++;
129
130 if (x > m_obbXmax)
131 m_obbXmax = x;
132 else if (x < m_obbXmin)
133 m_obbXmin = x;
134
135 if (y > m_obbYmax)
136 m_obbYmax = y;
137 else if (y < m_obbYmin)
138 m_obbYmin = y;
139
140 if (z > m_obbZmax)
141 m_obbZmax = z;
142 else if (z < m_obbZmin)
143 m_obbZmin = z;
144
145 }
146
147
105 public void Add(Triangle triangle) 148 public void Add(Triangle triangle)
106 { 149 {
107 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) 150 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
@@ -127,26 +170,17 @@ namespace OpenSim.Region.Physics.Meshing
127 if (!m_vertices.ContainsKey(triangle.v1)) 170 if (!m_vertices.ContainsKey(triangle.v1))
128 { 171 {
129 m_vertices[triangle.v1] = m_vertices.Count; 172 m_vertices[triangle.v1] = m_vertices.Count;
130 m_centroid.X += triangle.v1.X; 173 addVertexLStats(triangle.v1);
131 m_centroid.Y += triangle.v1.Y;
132 m_centroid.Z += triangle.v1.Z;
133 m_centroidDiv++;
134 } 174 }
135 if (!m_vertices.ContainsKey(triangle.v2)) 175 if (!m_vertices.ContainsKey(triangle.v2))
136 { 176 {
137 m_vertices[triangle.v2] = m_vertices.Count; 177 m_vertices[triangle.v2] = m_vertices.Count;
138 m_centroid.X += triangle.v2.X; 178 addVertexLStats(triangle.v2);
139 m_centroid.Y += triangle.v2.Y;
140 m_centroid.Z += triangle.v2.Z;
141 m_centroidDiv++;
142 } 179 }
143 if (!m_vertices.ContainsKey(triangle.v3)) 180 if (!m_vertices.ContainsKey(triangle.v3))
144 { 181 {
145 m_vertices[triangle.v3] = m_vertices.Count; 182 m_vertices[triangle.v3] = m_vertices.Count;
146 m_centroid.X += triangle.v3.X; 183 addVertexLStats(triangle.v3);
147 m_centroid.Y += triangle.v3.Y;
148 m_centroid.Z += triangle.v3.Z;
149 m_centroidDiv++;
150 } 184 }
151 m_triangles.Add(triangle); 185 m_triangles.Add(triangle);
152 } 186 }
@@ -159,6 +193,24 @@ namespace OpenSim.Region.Physics.Meshing
159 return Vector3.Zero; 193 return Vector3.Zero;
160 } 194 }
161 195
196 public Vector3 GetOBB()
197 {
198 float x, y, z;
199 if (m_centroidDiv > 0)
200 {
201 x = (m_obbXmax - m_obbXmin) * 0.5f;
202 y = (m_obbYmax - m_obbYmin) * 0.5f;
203 z = (m_obbZmax - m_obbZmin) * 0.5f;
204 }
205 else // ??
206 {
207 x = 0.5f;
208 y = 0.5f;
209 z = 0.5f;
210 }
211 return new Vector3(x, y, z);
212 }
213
162 public void CalcNormals() 214 public void CalcNormals()
163 { 215 {
164 int iTriangles = m_triangles.Count; 216 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..9bf3667
--- /dev/null
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
@@ -0,0 +1,753 @@
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.canColide = false;
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 private void CalculateBasicPrimVolume(ODEPhysRepData repData)
354 {
355 PrimitiveBaseShape _pbs = repData.pbs;
356 Vector3 _size = repData.size;
357
358 float volume = _size.X * _size.Y * _size.Z; // default
359 float tmp;
360
361 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
362 float hollowVolume = hollowAmount * hollowAmount;
363
364 switch (_pbs.ProfileShape)
365 {
366 case ProfileShape.Square:
367 // default box
368
369 if (_pbs.PathCurve == (byte)Extrusion.Straight)
370 {
371 if (hollowAmount > 0.0)
372 {
373 switch (_pbs.HollowShape)
374 {
375 case HollowShape.Square:
376 case HollowShape.Same:
377 break;
378
379 case HollowShape.Circle:
380
381 hollowVolume *= 0.78539816339f;
382 break;
383
384 case HollowShape.Triangle:
385
386 hollowVolume *= (0.5f * .5f);
387 break;
388
389 default:
390 hollowVolume = 0;
391 break;
392 }
393 volume *= (1.0f - hollowVolume);
394 }
395 }
396
397 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
398 {
399 //a tube
400
401 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX);
402 tmp = 1.0f - 2.0e-2f * (float)(200 - _pbs.PathScaleY);
403 volume -= volume * tmp * tmp;
404
405 if (hollowAmount > 0.0)
406 {
407 hollowVolume *= hollowAmount;
408
409 switch (_pbs.HollowShape)
410 {
411 case HollowShape.Square:
412 case HollowShape.Same:
413 break;
414
415 case HollowShape.Circle:
416 hollowVolume *= 0.78539816339f;
417 break;
418
419 case HollowShape.Triangle:
420 hollowVolume *= 0.5f * 0.5f;
421 break;
422 default:
423 hollowVolume = 0;
424 break;
425 }
426 volume *= (1.0f - hollowVolume);
427 }
428 }
429
430 break;
431
432 case ProfileShape.Circle:
433
434 if (_pbs.PathCurve == (byte)Extrusion.Straight)
435 {
436 volume *= 0.78539816339f; // elipse base
437
438 if (hollowAmount > 0.0)
439 {
440 switch (_pbs.HollowShape)
441 {
442 case HollowShape.Same:
443 case HollowShape.Circle:
444 break;
445
446 case HollowShape.Square:
447 hollowVolume *= 0.5f * 2.5984480504799f;
448 break;
449
450 case HollowShape.Triangle:
451 hollowVolume *= .5f * 1.27323954473516f;
452 break;
453
454 default:
455 hollowVolume = 0;
456 break;
457 }
458 volume *= (1.0f - hollowVolume);
459 }
460 }
461
462 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
463 {
464 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX);
465 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
466 volume *= (1.0f - tmp * tmp);
467
468 if (hollowAmount > 0.0)
469 {
470
471 // calculate the hollow volume by it's shape compared to the prim shape
472 hollowVolume *= hollowAmount;
473
474 switch (_pbs.HollowShape)
475 {
476 case HollowShape.Same:
477 case HollowShape.Circle:
478 break;
479
480 case HollowShape.Square:
481 hollowVolume *= 0.5f * 2.5984480504799f;
482 break;
483
484 case HollowShape.Triangle:
485 hollowVolume *= .5f * 1.27323954473516f;
486 break;
487
488 default:
489 hollowVolume = 0;
490 break;
491 }
492 volume *= (1.0f - hollowVolume);
493 }
494 }
495 break;
496
497 case ProfileShape.HalfCircle:
498 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
499 {
500 volume *= 0.5236f;
501
502 if (hollowAmount > 0.0)
503 {
504 hollowVolume *= hollowAmount;
505
506 switch (_pbs.HollowShape)
507 {
508 case HollowShape.Circle:
509 case HollowShape.Triangle: // diference in sl is minor and odd
510 case HollowShape.Same:
511 break;
512
513 case HollowShape.Square:
514 hollowVolume *= 0.909f;
515 break;
516
517 // case HollowShape.Triangle:
518 // hollowVolume *= .827f;
519 // break;
520 default:
521 hollowVolume = 0;
522 break;
523 }
524 volume *= (1.0f - hollowVolume);
525 }
526
527 }
528 break;
529
530 case ProfileShape.EquilateralTriangle:
531
532 if (_pbs.PathCurve == (byte)Extrusion.Straight)
533 {
534 volume *= 0.32475953f;
535
536 if (hollowAmount > 0.0)
537 {
538
539 // calculate the hollow volume by it's shape compared to the prim shape
540 switch (_pbs.HollowShape)
541 {
542 case HollowShape.Same:
543 case HollowShape.Triangle:
544 hollowVolume *= .25f;
545 break;
546
547 case HollowShape.Square:
548 hollowVolume *= 0.499849f * 3.07920140172638f;
549 break;
550
551 case HollowShape.Circle:
552 // Hollow shape is a perfect cyllinder in respect to the cube's scale
553 // Cyllinder hollow volume calculation
554
555 hollowVolume *= 0.1963495f * 3.07920140172638f;
556 break;
557
558 default:
559 hollowVolume = 0;
560 break;
561 }
562 volume *= (1.0f - hollowVolume);
563 }
564 }
565 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
566 {
567 volume *= 0.32475953f;
568 volume *= 0.01f * (float)(200 - _pbs.PathScaleX);
569 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
570 volume *= (1.0f - tmp * tmp);
571
572 if (hollowAmount > 0.0)
573 {
574
575 hollowVolume *= hollowAmount;
576
577 switch (_pbs.HollowShape)
578 {
579 case HollowShape.Same:
580 case HollowShape.Triangle:
581 hollowVolume *= .25f;
582 break;
583
584 case HollowShape.Square:
585 hollowVolume *= 0.499849f * 3.07920140172638f;
586 break;
587
588 case HollowShape.Circle:
589
590 hollowVolume *= 0.1963495f * 3.07920140172638f;
591 break;
592
593 default:
594 hollowVolume = 0;
595 break;
596 }
597 volume *= (1.0f - hollowVolume);
598 }
599 }
600 break;
601
602 default:
603 break;
604 }
605
606 float taperX1;
607 float taperY1;
608 float taperX;
609 float taperY;
610 float pathBegin;
611 float pathEnd;
612 float profileBegin;
613 float profileEnd;
614
615 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible)
616 {
617 taperX1 = _pbs.PathScaleX * 0.01f;
618 if (taperX1 > 1.0f)
619 taperX1 = 2.0f - taperX1;
620 taperX = 1.0f - taperX1;
621
622 taperY1 = _pbs.PathScaleY * 0.01f;
623 if (taperY1 > 1.0f)
624 taperY1 = 2.0f - taperY1;
625 taperY = 1.0f - taperY1;
626 }
627 else
628 {
629 taperX = _pbs.PathTaperX * 0.01f;
630 if (taperX < 0.0f)
631 taperX = -taperX;
632 taperX1 = 1.0f - taperX;
633
634 taperY = _pbs.PathTaperY * 0.01f;
635 if (taperY < 0.0f)
636 taperY = -taperY;
637 taperY1 = 1.0f - taperY;
638 }
639
640 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
641
642 pathBegin = (float)_pbs.PathBegin * 2.0e-5f;
643 pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f;
644 volume *= (pathEnd - pathBegin);
645
646 // this is crude aproximation
647 profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f;
648 profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f;
649 volume *= (profileEnd - profileBegin);
650
651 repData.volume = volume;
652 }
653
654 private void CalcVolumeData(ODEPhysRepData repData)
655 {
656 float volume;
657 Vector3 OBB = repData.size;
658 Vector3 OBBoffset;
659 IntPtr geo = repData.geo;
660
661 if (geo == IntPtr.Zero || repData.triMeshData == IntPtr.Zero)
662 {
663 OBB.X *= 0.5f;
664 OBB.Y *= 0.5f;
665 OBB.Z *= 0.5f;
666
667 repData.OBB = OBB;
668 repData.OBBOffset = Vector3.Zero;
669 }
670 else if (!repData.hasOBB) // should this happen?
671 {
672 d.AABB AABB;
673 d.GeomGetAABB(geo, out AABB); // get the AABB from engine geom
674
675 OBB.X = (AABB.MaxX - AABB.MinX) * 0.5f;
676 OBB.Y = (AABB.MaxY - AABB.MinY) * 0.5f;
677 OBB.Z = (AABB.MaxZ - AABB.MinZ) * 0.5f;
678 repData.OBB = OBB;
679 OBBoffset.X = (AABB.MaxX + AABB.MinX) * 0.5f;
680 OBBoffset.Y = (AABB.MaxY + AABB.MinY) * 0.5f;
681 OBBoffset.Z = (AABB.MaxZ + AABB.MinZ) * 0.5f;
682 repData.OBBOffset = Vector3.Zero;
683 }
684
685 // also its own inertia and mass
686 // keep using basic shape mass for now
687 CalculateBasicPrimVolume(repData);
688
689 if (repData.hasOBB)
690 {
691 OBB = repData.OBB;
692 float pc = repData.physCost;
693 float psf = OBB.X * (OBB.Y + OBB.Z) + OBB.Y * OBB.Z;
694 psf *= 1.33f * .2f;
695
696 pc *= psf;
697 if (pc < 0.1f)
698 pc = 0.1f;
699
700 repData.physCost = pc;
701 }
702 else
703 repData.physCost = 0.1f;
704 }
705 }
706
707 public class ODEAssetRequest
708 {
709 PhysicsActor m_actor;
710 ODEMeshWorker m_worker;
711 PrimitiveBaseShape m_pbs;
712 private ILog m_log;
713
714 public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider,
715 PhysicsActor pActor, PrimitiveBaseShape ppbs, ILog plog)
716 {
717 m_actor = pActor;
718 m_worker = pWorker;
719 m_pbs = ppbs;
720 m_log = plog;
721
722 if (provider == null)
723 return;
724
725 UUID assetID = m_pbs.SculptTexture;
726 if (assetID == UUID.Zero)
727 return;
728
729 provider(assetID, ODEassetReceived);
730 }
731
732 void ODEassetReceived(AssetBase asset)
733 {
734 if (m_actor != null && m_pbs != null)
735 {
736 if (asset != null)
737 {
738 if (asset.Data != null && asset.Data.Length > 0)
739 {
740 m_pbs.SculptData = asset.Data;
741 m_actor.Shape = m_pbs;
742 }
743 else
744 m_log.WarnFormat("[PHYSICS]: asset provider returned invalid mesh data for prim {0} asset UUID {1}.",
745 m_actor.Name, asset.ID.ToString());
746 }
747 else
748 m_log.WarnFormat("[PHYSICS]: asset provider returned null asset fo mesh of prim {0}.",
749 m_actor.Name);
750 }
751 }
752 }
753} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index f2f4725..f328066 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -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)
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index f126644..d426112 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -60,6 +60,29 @@ 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 byte shapetype = 0;
81 public bool canColide = true;
82 public bool hasOBB = false;
83 public bool hasMeshVolume = false;
84 }
85
63 // colision flags of things others can colide with 86 // colision flags of things others can colide with
64 // rays, sensors, probes removed since can't be colided with 87 // rays, sensors, probes removed since can't be colided with
65 // The top space where things are placed provided further selection 88 // The top space where things are placed provided further selection
@@ -230,11 +253,6 @@ namespace OpenSim.Region.Physics.OdePlugin
230 private float minimumGroundFlightOffset = 3f; 253 private float minimumGroundFlightOffset = 3f;
231 public float maximumMassObject = 10000.01f; 254 public float maximumMassObject = 10000.01f;
232 255
233 public bool meshSculptedPrim = true;
234 public bool forceSimplePrimMeshing = false;
235
236 public float meshSculptLOD = 32;
237 public float MeshSculptphysicalLOD = 32;
238 256
239 public float geomDefaultDensity = 10.000006836f; 257 public float geomDefaultDensity = 10.000006836f;
240 258
@@ -302,6 +320,7 @@ namespace OpenSim.Region.Physics.OdePlugin
302 public IntPtr TopSpace; // the global space 320 public IntPtr TopSpace; // the global space
303 public IntPtr ActiveSpace; // space for active prims 321 public IntPtr ActiveSpace; // space for active prims
304 public IntPtr StaticSpace; // space for the static things around 322 public IntPtr StaticSpace; // space for the static things around
323 public IntPtr WorkSpace; // no collisions work space
305 324
306 // some speedup variables 325 // some speedup variables
307 private int spaceGridMaxX; 326 private int spaceGridMaxX;
@@ -328,7 +347,7 @@ namespace OpenSim.Region.Physics.OdePlugin
328 private PhysicsScene m_parentScene = null; 347 private PhysicsScene m_parentScene = null;
329 348
330 private ODERayCastRequestManager m_rayCastManager; 349 private ODERayCastRequestManager m_rayCastManager;
331 350 public ODEMeshWorker m_meshWorker;
332 351
333/* maybe needed if ode uses tls 352/* maybe needed if ode uses tls
334 private void checkThread() 353 private void checkThread()
@@ -361,6 +380,8 @@ namespace OpenSim.Region.Physics.OdePlugin
361 nearCallback = near; 380 nearCallback = near;
362 381
363 m_rayCastManager = new ODERayCastRequestManager(this); 382 m_rayCastManager = new ODERayCastRequestManager(this);
383
384
364 lock (OdeLock) 385 lock (OdeLock)
365 { 386 {
366 // Create the world and the first space 387 // Create the world and the first space
@@ -372,6 +393,7 @@ namespace OpenSim.Region.Physics.OdePlugin
372 // now the major subspaces 393 // now the major subspaces
373 ActiveSpace = d.HashSpaceCreate(TopSpace); 394 ActiveSpace = d.HashSpaceCreate(TopSpace);
374 StaticSpace = d.HashSpaceCreate(TopSpace); 395 StaticSpace = d.HashSpaceCreate(TopSpace);
396 WorkSpace = d.HashSpaceCreate(TopSpace);
375 } 397 }
376 catch 398 catch
377 { 399 {
@@ -381,10 +403,12 @@ namespace OpenSim.Region.Physics.OdePlugin
381 d.HashSpaceSetLevels(TopSpace, -2, 8); 403 d.HashSpaceSetLevels(TopSpace, -2, 8);
382 d.HashSpaceSetLevels(ActiveSpace, -2, 8); 404 d.HashSpaceSetLevels(ActiveSpace, -2, 8);
383 d.HashSpaceSetLevels(StaticSpace, -2, 8); 405 d.HashSpaceSetLevels(StaticSpace, -2, 8);
406 d.HashSpaceSetLevels(WorkSpace, -2, 8);
384 407
385 // demote to second level 408 // demote to second level
386 d.SpaceSetSublevel(ActiveSpace, 1); 409 d.SpaceSetSublevel(ActiveSpace, 1);
387 d.SpaceSetSublevel(StaticSpace, 1); 410 d.SpaceSetSublevel(StaticSpace, 1);
411 d.SpaceSetSublevel(WorkSpace, 1);
388 412
389 d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space | 413 d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space |
390 CollisionCategories.Geom | 414 CollisionCategories.Geom |
@@ -402,6 +426,9 @@ namespace OpenSim.Region.Physics.OdePlugin
402 )); 426 ));
403 d.GeomSetCollideBits(StaticSpace, 0); 427 d.GeomSetCollideBits(StaticSpace, 0);
404 428
429 d.GeomSetCategoryBits(WorkSpace, 0);
430 d.GeomSetCollideBits(WorkSpace, 0);
431
405 contactgroup = d.JointGroupCreate(0); 432 contactgroup = d.JointGroupCreate(0);
406 //contactgroup 433 //contactgroup
407 434
@@ -440,9 +467,11 @@ namespace OpenSim.Region.Physics.OdePlugin
440 467
441 int contactsPerCollision = 80; 468 int contactsPerCollision = 80;
442 469
470 IConfig physicsconfig = null;
471
443 if (m_config != null) 472 if (m_config != null)
444 { 473 {
445 IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; 474 physicsconfig = m_config.Configs["ODEPhysicsSettings"];
446 if (physicsconfig != null) 475 if (physicsconfig != null)
447 { 476 {
448 gravityx = physicsconfig.GetFloat("world_gravityx", gravityx); 477 gravityx = physicsconfig.GetFloat("world_gravityx", gravityx);
@@ -469,27 +498,7 @@ namespace OpenSim.Region.Physics.OdePlugin
469 498
470 geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); 499 geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity);
471 bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable); 500 bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable);
472/* 501
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); 502 physics_logging = physicsconfig.GetBoolean("physics_logging", false);
494 physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); 503 physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0);
495 physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); 504 physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false);
@@ -499,6 +508,8 @@ namespace OpenSim.Region.Physics.OdePlugin
499 } 508 }
500 } 509 }
501 510
511 m_meshWorker = new ODEMeshWorker(this, m_log, meshmerizer, WorkSpace, physicsconfig);
512
502 HalfOdeStep = ODE_STEPSIZE * 0.5f; 513 HalfOdeStep = ODE_STEPSIZE * 0.5f;
503 odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f); 514 odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f);
504 515
@@ -1615,135 +1626,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1615 1626
1616 #endregion 1627 #endregion
1617 1628
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 1629
1748 /// <summary> 1630 /// <summary>
1749 /// Called to queue a change to a actor 1631 /// Called to queue a change to a actor