aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs234
-rw-r--r--OpenSim/Region/Physics/Meshing/Mesh.cs87
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs69
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs17
4 files changed, 217 insertions, 190 deletions
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
index 7ab8b98..f22ea71 100644
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
+++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
@@ -204,7 +204,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
204 tempAngularVelocity2 = new btVector3(0, 0, 0); 204 tempAngularVelocity2 = new btVector3(0, 0, 0);
205 tempInertia1 = new btVector3(0, 0, 0); 205 tempInertia1 = new btVector3(0, 0, 0);
206 tempInertia2 = new btVector3(0, 0, 0); 206 tempInertia2 = new btVector3(0, 0, 0);
207 tempOrientation1 = new btQuaternion(0,0,0,1); 207 tempOrientation1 = new btQuaternion(0, 0, 0, 1);
208 tempOrientation2 = new btQuaternion(0, 0, 0, 1); 208 tempOrientation2 = new btQuaternion(0, 0, 0, 1);
209 _parent_scene = parent_scene; 209 _parent_scene = parent_scene;
210 tempTransform1 = new btTransform(_parent_scene.QuatIdentity, _parent_scene.VectorZero); 210 tempTransform1 = new btTransform(_parent_scene.QuatIdentity, _parent_scene.VectorZero);
@@ -216,10 +216,10 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
216 tempMotionState2 = new btDefaultMotionState(_parent_scene.TransZero); 216 tempMotionState2 = new btDefaultMotionState(_parent_scene.TransZero);
217 tempMotionState3 = new btDefaultMotionState(_parent_scene.TransZero); 217 tempMotionState3 = new btDefaultMotionState(_parent_scene.TransZero);
218 218
219 219
220 AxisLockLinearLow = new btVector3(-1 * (int)Constants.RegionSize, -1 * (int)Constants.RegionSize, -1 * (int)Constants.RegionSize); 220 AxisLockLinearLow = new btVector3(-1 * (int)Constants.RegionSize, -1 * (int)Constants.RegionSize, -1 * (int)Constants.RegionSize);
221 int regionsize = (int) Constants.RegionSize; 221 int regionsize = (int)Constants.RegionSize;
222 222
223 if (regionsize == 256) 223 if (regionsize == 256)
224 regionsize = 512; 224 regionsize = 512;
225 225
@@ -611,7 +611,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
611 DisableAxisMotor(); 611 DisableAxisMotor();
612 DisposeOfBody(); 612 DisposeOfBody();
613 SetCollisionShape(null); 613 SetCollisionShape(null);
614 614
615 if (tempMotionState3 != null && tempMotionState3.Handle != IntPtr.Zero) 615 if (tempMotionState3 != null && tempMotionState3.Handle != IntPtr.Zero)
616 { 616 {
617 tempMotionState3.Dispose(); 617 tempMotionState3.Dispose();
@@ -677,8 +677,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
677 tempInertia2.Dispose(); 677 tempInertia2.Dispose();
678 tempInertia1 = null; 678 tempInertia1 = null;
679 } 679 }
680 680
681 681
682 if (tempAngularVelocity2 != null && tempAngularVelocity2.Handle != IntPtr.Zero) 682 if (tempAngularVelocity2 != null && tempAngularVelocity2.Handle != IntPtr.Zero)
683 { 683 {
684 tempAngularVelocity2.Dispose(); 684 tempAngularVelocity2.Dispose();
@@ -802,7 +802,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
802 changesize(timestep); 802 changesize(timestep);
803 } 803 }
804 804
805 // 805 //
806 806
807 if (m_taintshape) 807 if (m_taintshape)
808 { 808 {
@@ -1001,7 +1001,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1001 else 1001 else
1002 SetBody(0); 1002 SetBody(0);
1003 changeSelectedStatus(timestep); 1003 changeSelectedStatus(timestep);
1004 1004
1005 resetCollisionAccounting(); 1005 resetCollisionAccounting();
1006 m_taintPhysics = m_isphysical; 1006 m_taintPhysics = m_isphysical;
1007 } 1007 }
@@ -1012,7 +1012,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1012 { 1012 {
1013 if (_parent_scene.needsMeshing(_pbs)) 1013 if (_parent_scene.needsMeshing(_pbs))
1014 { 1014 {
1015 ProcessGeomCreationAsTriMesh(PhysicsVector.Zero,Quaternion.Identity); 1015 ProcessGeomCreationAsTriMesh(PhysicsVector.Zero, Quaternion.Identity);
1016 // createmesh returns null when it doesn't mesh. 1016 // createmesh returns null when it doesn't mesh.
1017 CreateGeom(IntPtr.Zero, _mesh); 1017 CreateGeom(IntPtr.Zero, _mesh);
1018 } 1018 }
@@ -1038,32 +1038,32 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1038 meshlod = _parent_scene.MeshSculptphysicalLOD; 1038 meshlod = _parent_scene.MeshSculptphysicalLOD;
1039 1039
1040 IMesh mesh = _parent_scene.mesher.CreateMesh(SOPName, _pbs, _size, meshlod, IsPhysical); 1040 IMesh mesh = _parent_scene.mesher.CreateMesh(SOPName, _pbs, _size, meshlod, IsPhysical);
1041 if (!positionOffset.IsIdentical(PhysicsVector.Zero,0.001f) || orientation != Quaternion.Identity) 1041 if (!positionOffset.IsIdentical(PhysicsVector.Zero, 0.001f) || orientation != Quaternion.Identity)
1042 { 1042 {
1043 1043
1044 float[] xyz = new float[3]; 1044 float[] xyz = new float[3];
1045 xyz[0] = positionOffset.X; 1045 xyz[0] = positionOffset.X;
1046 xyz[1] = positionOffset.Y; 1046 xyz[1] = positionOffset.Y;
1047 xyz[2] = positionOffset.Z; 1047 xyz[2] = positionOffset.Z;
1048 1048
1049 Matrix4 m4 = Matrix4.CreateFromQuaternion(orientation); 1049 Matrix4 m4 = Matrix4.CreateFromQuaternion(orientation);
1050 1050
1051 float[,] matrix = new float[3,3]; 1051 float[,] matrix = new float[3, 3];
1052 1052
1053 matrix[0, 0] = m4.M11; 1053 matrix[0, 0] = m4.M11;
1054 matrix[0, 1] = m4.M12; 1054 matrix[0, 1] = m4.M12;
1055 matrix[0, 2] = m4.M13; 1055 matrix[0, 2] = m4.M13;
1056 matrix[1, 0] = m4.M21; 1056 matrix[1, 0] = m4.M21;
1057 matrix[1, 1] = m4.M22; 1057 matrix[1, 1] = m4.M22;
1058 matrix[1, 2] = m4.M23; 1058 matrix[1, 2] = m4.M23;
1059 matrix[2, 0] = m4.M31; 1059 matrix[2, 0] = m4.M31;
1060 matrix[2, 1] = m4.M32; 1060 matrix[2, 1] = m4.M32;
1061 matrix[2, 2] = m4.M33; 1061 matrix[2, 2] = m4.M33;
1062 1062
1063 1063
1064 mesh.TransformLinear(matrix, xyz); 1064 mesh.TransformLinear(matrix, xyz);
1065 1065
1066 1066
1067 1067
1068 } 1068 }
1069 1069
@@ -1088,12 +1088,12 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1088 SetCollisionShape(null); 1088 SetCollisionShape(null);
1089 // Construction of new prim 1089 // Construction of new prim
1090 ProcessGeomCreation(); 1090 ProcessGeomCreation();
1091 1091
1092 if (IsPhysical) 1092 if (IsPhysical)
1093 SetBody(Mass); 1093 SetBody(Mass);
1094 else 1094 else
1095 SetBody(0); 1095 SetBody(0);
1096 1096
1097 m_taintsize = _size; 1097 m_taintsize = _size;
1098 1098
1099 } 1099 }
@@ -1136,7 +1136,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1136 //prim_geom = IntPtr.Zero; 1136 //prim_geom = IntPtr.Zero;
1137 m_log.Error("[PHYSICS]: PrimGeom dead"); 1137 m_log.Error("[PHYSICS]: PrimGeom dead");
1138 } 1138 }
1139 1139
1140 // we don't need to do space calculation because the client sends a position update also. 1140 // we don't need to do space calculation because the client sends a position update also.
1141 if (_size.X <= 0) _size.X = 0.01f; 1141 if (_size.X <= 0) _size.X = 0.01f;
1142 if (_size.Y <= 0) _size.Y = 0.01f; 1142 if (_size.Y <= 0) _size.Y = 0.01f;
@@ -1153,8 +1153,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1153 tempTransform1.Dispose(); 1153 tempTransform1.Dispose();
1154 tempTransform1 = new btTransform(tempOrientation1, tempPosition1); 1154 tempTransform1 = new btTransform(tempOrientation1, tempPosition1);
1155 1155
1156 1156
1157 1157
1158 1158
1159 //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); 1159 //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
1160 if (IsPhysical) 1160 if (IsPhysical)
@@ -1162,7 +1162,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1162 SetBody(Mass); 1162 SetBody(Mass);
1163 // Re creates body on size. 1163 // Re creates body on size.
1164 // EnableBody also does setMass() 1164 // EnableBody also does setMass()
1165 1165
1166 } 1166 }
1167 else 1167 else
1168 { 1168 {
@@ -1179,7 +1179,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1179 } 1179 }
1180 } 1180 }
1181 resetCollisionAccounting(); 1181 resetCollisionAccounting();
1182 1182
1183 m_taintshape = false; 1183 m_taintshape = false;
1184 } 1184 }
1185 1185
@@ -1291,7 +1291,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1291 { 1291 {
1292 Body.setCollisionFlags((int)ContactFlags.CF_NO_CONTACT_RESPONSE); 1292 Body.setCollisionFlags((int)ContactFlags.CF_NO_CONTACT_RESPONSE);
1293 disableBodySoft(); 1293 disableBodySoft();
1294 1294
1295 } 1295 }
1296 else 1296 else
1297 { 1297 {
@@ -1299,7 +1299,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1299 enableBodySoft(); 1299 enableBodySoft();
1300 } 1300 }
1301 m_isSelected = m_taintselected; 1301 m_isSelected = m_taintselected;
1302 1302
1303 } 1303 }
1304 1304
1305 private void changevelocity(float timestep) 1305 private void changevelocity(float timestep)
@@ -1368,7 +1368,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1368 _parent = m_taintparent; 1368 _parent = m_taintparent;
1369 1369
1370 m_taintPhysics = m_isphysical; 1370 m_taintPhysics = m_isphysical;
1371 1371
1372 } 1372 }
1373 1373
1374 private void changefloatonwater(float timestep) 1374 private void changefloatonwater(float timestep)
@@ -1627,7 +1627,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1627 { 1627 {
1628 if (m_zeroPosition == null) 1628 if (m_zeroPosition == null)
1629 m_zeroPosition = new PhysicsVector(0, 0, 0); 1629 m_zeroPosition = new PhysicsVector(0, 0, 0);
1630 m_zeroPosition.setValues(_position.X,_position.Y,_position.Z); 1630 m_zeroPosition.setValues(_position.X, _position.Y, _position.Z);
1631 return; 1631 return;
1632 } 1632 }
1633 } 1633 }
@@ -1981,7 +1981,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1981 //_mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); 1981 //_mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
1982 _mesh = p_mesh; 1982 _mesh = p_mesh;
1983 setMesh(_parent_scene, _mesh); 1983 setMesh(_parent_scene, _mesh);
1984 1984
1985 } 1985 }
1986 else 1986 else
1987 { 1987 {
@@ -1994,15 +1994,15 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1994 //SetGeom to a Regular Sphere 1994 //SetGeom to a Regular Sphere
1995 if (tempSize1 == null) 1995 if (tempSize1 == null)
1996 tempSize1 = new btVector3(0, 0, 0); 1996 tempSize1 = new btVector3(0, 0, 0);
1997 tempSize1.setValue(_size.X * 0.5f,_size.Y * 0.5f, _size.Z * 0.5f); 1997 tempSize1.setValue(_size.X * 0.5f, _size.Y * 0.5f, _size.Z * 0.5f);
1998 SetCollisionShape(new btSphereShape(_size.X*0.5f)); 1998 SetCollisionShape(new btSphereShape(_size.X * 0.5f));
1999 } 1999 }
2000 else 2000 else
2001 { 2001 {
2002 // uses halfextents 2002 // uses halfextents
2003 if (tempSize1 == null) 2003 if (tempSize1 == null)
2004 tempSize1 = new btVector3(0, 0, 0); 2004 tempSize1 = new btVector3(0, 0, 0);
2005 tempSize1.setValue(_size.X*0.5f, _size.Y*0.5f, _size.Z*0.5f); 2005 tempSize1.setValue(_size.X * 0.5f, _size.Y * 0.5f, _size.Z * 0.5f);
2006 SetCollisionShape(new btBoxShape(tempSize1)); 2006 SetCollisionShape(new btBoxShape(tempSize1));
2007 } 2007 }
2008 } 2008 }
@@ -2052,14 +2052,24 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2052 } 2052 }
2053 } 2053 }
2054 2054
2055 //IMesh oldMesh = primMesh;
2056
2057 //primMesh = mesh;
2058
2059 //float[] vertexList = primMesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
2060 //int[] indexList = primMesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
2061 ////Array.Reverse(indexList);
2062 //primMesh.releaseSourceMeshData(); // free up the original mesh data to save memory
2063
2055 IMesh oldMesh = primMesh; 2064 IMesh oldMesh = primMesh;
2056 2065
2057 primMesh = mesh; 2066 primMesh = mesh;
2058 2067
2059 float[] vertexList = primMesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory 2068 float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
2060 int[] indexList = primMesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage 2069 int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
2061 //Array.Reverse(indexList); 2070 //Array.Reverse(indexList);
2062 primMesh.releaseSourceMeshData(); // free up the original mesh data to save memory 2071 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
2072
2063 2073
2064 int VertexCount = vertexList.GetLength(0) / 3; 2074 int VertexCount = vertexList.GetLength(0) / 3;
2065 int IndexCount = indexList.GetLength(0); 2075 int IndexCount = indexList.GetLength(0);
@@ -2068,17 +2078,17 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2068 btshapeArray.Dispose(); 2078 btshapeArray.Dispose();
2069 //Array.Reverse(indexList); 2079 //Array.Reverse(indexList);
2070 btshapeArray = new btTriangleIndexVertexArray(IndexCount / 3, indexList, (3 * sizeof(int)), 2080 btshapeArray = new btTriangleIndexVertexArray(IndexCount / 3, indexList, (3 * sizeof(int)),
2071 VertexCount, vertexList, 3*sizeof (float)); 2081 VertexCount, vertexList, 3 * sizeof(float));
2072 SetCollisionShape(new btGImpactMeshShape(btshapeArray)); 2082 SetCollisionShape(new btGImpactMeshShape(btshapeArray));
2073 //((btGImpactMeshShape) prim_geom).updateBound(); 2083 //((btGImpactMeshShape) prim_geom).updateBound();
2074 ((btGImpactMeshShape)prim_geom).setLocalScaling(new btVector3(1,1, 1)); 2084 ((btGImpactMeshShape)prim_geom).setLocalScaling(new btVector3(1, 1, 1));
2075 ((btGImpactMeshShape)prim_geom).updateBound(); 2085 ((btGImpactMeshShape)prim_geom).updateBound();
2076 _parent_scene.SetUsingGImpact(); 2086 _parent_scene.SetUsingGImpact();
2077 if (oldMesh != null) 2087 //if (oldMesh != null)
2078 { 2088 //{
2079 oldMesh.releasePinned(); 2089 // oldMesh.releasePinned();
2080 oldMesh = null; 2090 // oldMesh = null;
2081 } 2091 //}
2082 2092
2083 } 2093 }
2084 2094
@@ -2102,7 +2112,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2102 } 2112 }
2103 */ 2113 */
2104 prim_geom = shape; 2114 prim_geom = shape;
2105 2115
2106 //Body.set 2116 //Body.set
2107 } 2117 }
2108 2118
@@ -2143,8 +2153,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2143 2153
2144 if (prim_geom is btGImpactMeshShape) 2154 if (prim_geom is btGImpactMeshShape)
2145 { 2155 {
2146 ((btGImpactMeshShape) prim_geom).setLocalScaling(new btVector3(1, 1, 1)); 2156 ((btGImpactMeshShape)prim_geom).setLocalScaling(new btVector3(1, 1, 1));
2147 ((btGImpactMeshShape) prim_geom).updateBound(); 2157 ((btGImpactMeshShape)prim_geom).updateBound();
2148 } 2158 }
2149 //Body.setCollisionFlags(Body.getCollisionFlags() | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK); 2159 //Body.setCollisionFlags(Body.getCollisionFlags() | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK);
2150 //Body.setUserPointer((IntPtr) (int)m_localID); 2160 //Body.setUserPointer((IntPtr) (int)m_localID);
@@ -2159,7 +2169,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2159 { 2169 {
2160 if (chld == null) 2170 if (chld == null)
2161 continue; 2171 continue;
2162 2172
2163 // if (chld.NeedsMeshing()) 2173 // if (chld.NeedsMeshing())
2164 // hasTrimesh = true; 2174 // hasTrimesh = true;
2165 } 2175 }
@@ -2167,40 +2177,40 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2167 2177
2168 //if (hasTrimesh) 2178 //if (hasTrimesh)
2169 //{ 2179 //{
2170 ProcessGeomCreationAsTriMesh(PhysicsVector.Zero, Quaternion.Identity); 2180 ProcessGeomCreationAsTriMesh(PhysicsVector.Zero, Quaternion.Identity);
2171 // createmesh returns null when it doesn't mesh. 2181 // createmesh returns null when it doesn't mesh.
2172
2173 /*
2174 if (_mesh is Mesh)
2175 {
2176 }
2177 else
2178 {
2179 m_log.Warn("[PHYSICS]: Can't link a OpenSim.Region.Physics.Meshing.Mesh object");
2180 return;
2181 }
2182 */
2183 2182
2184 2183 /*
2185 2184 if (_mesh is Mesh)
2186 foreach (BulletDotNETPrim chld in childrenPrim) 2185 {
2187 { 2186 }
2188 if (chld == null) 2187 else
2189 continue; 2188 {
2190 PhysicsVector offset = chld.Position - Position; 2189 m_log.Warn("[PHYSICS]: Can't link a OpenSim.Region.Physics.Meshing.Mesh object");
2191 Vector3 pos = new Vector3(offset.X, offset.Y, offset.Z); 2190 return;
2192 pos *= Quaternion.Inverse(Orientation); 2191 }
2193 //pos *= Orientation; 2192 */
2194 offset.setValues(pos.X, pos.Y, pos.Z);
2195 chld.ProcessGeomCreationAsTriMesh(offset, chld.Orientation);
2196
2197 _mesh.Append(chld._mesh);
2198
2199 2193
2200 } 2194
2201 setMesh(_parent_scene, _mesh); 2195
2202 2196 foreach (BulletDotNETPrim chld in childrenPrim)
2203 //} 2197 {
2198 if (chld == null)
2199 continue;
2200 PhysicsVector offset = chld.Position - Position;
2201 Vector3 pos = new Vector3(offset.X, offset.Y, offset.Z);
2202 pos *= Quaternion.Inverse(Orientation);
2203 //pos *= Orientation;
2204 offset.setValues(pos.X, pos.Y, pos.Z);
2205 chld.ProcessGeomCreationAsTriMesh(offset, chld.Orientation);
2206
2207 _mesh.Append(chld._mesh);
2208
2209
2210 }
2211 setMesh(_parent_scene, _mesh);
2212
2213 //}
2204 2214
2205 if (tempMotionState1 != null && tempMotionState1.Handle != IntPtr.Zero) 2215 if (tempMotionState1 != null && tempMotionState1.Handle != IntPtr.Zero)
2206 tempMotionState1.Dispose(); 2216 tempMotionState1.Dispose();
@@ -2238,7 +2248,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2238 ((btGImpactMeshShape)prim_geom).updateBound(); 2248 ((btGImpactMeshShape)prim_geom).updateBound();
2239 } 2249 }
2240 _parent_scene.AddPrimToScene(this); 2250 _parent_scene.AddPrimToScene(this);
2241 2251
2242 } 2252 }
2243 2253
2244 if (IsPhysical) 2254 if (IsPhysical)
@@ -2252,7 +2262,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2252 if (Body.Handle != IntPtr.Zero) 2262 if (Body.Handle != IntPtr.Zero)
2253 { 2263 {
2254 DisableAxisMotor(); 2264 DisableAxisMotor();
2255 _parent_scene.removeFromWorld(this,Body); 2265 _parent_scene.removeFromWorld(this, Body);
2256 Body.Dispose(); 2266 Body.Dispose();
2257 } 2267 }
2258 Body = null; 2268 Body = null;
@@ -2305,7 +2315,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2305 return; 2315 return;
2306 2316
2307 2317
2308 2318
2309 lock (childrenPrim) 2319 lock (childrenPrim)
2310 { 2320 {
2311 if (!childrenPrim.Contains(prm)) 2321 if (!childrenPrim.Contains(prm))
@@ -2313,8 +2323,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2313 childrenPrim.Add(prm); 2323 childrenPrim.Add(prm);
2314 } 2324 }
2315 } 2325 }
2316 2326
2317 2327
2318 } 2328 }
2319 2329
2320 public void disableBody() 2330 public void disableBody()
@@ -2386,7 +2396,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2386 { 2396 {
2387 Body.clearForces(); 2397 Body.clearForces();
2388 Body.forceActivationState(0); 2398 Body.forceActivationState(0);
2389 2399
2390 } 2400 }
2391 2401
2392 } 2402 }
@@ -2400,7 +2410,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2400 Body.clearForces(); 2410 Body.clearForces();
2401 Body.forceActivationState(4); 2411 Body.forceActivationState(4);
2402 forceenable = true; 2412 forceenable = true;
2403 2413
2404 } 2414 }
2405 m_disabled = false; 2415 m_disabled = false;
2406 } 2416 }
@@ -2415,7 +2425,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2415 SetBody(Mass); 2425 SetBody(Mass);
2416 else 2426 else
2417 SetBody(0); 2427 SetBody(0);
2418 2428
2419 // TODO: Set Collision Category Bits and Flags 2429 // TODO: Set Collision Category Bits and Flags
2420 // TODO: Set Auto Disable data 2430 // TODO: Set Auto Disable data
2421 2431
@@ -2587,10 +2597,10 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2587 _velocity.Y = tempLinearVelocity1.getY(); 2597 _velocity.Y = tempLinearVelocity1.getY();
2588 _velocity.Z = tempLinearVelocity1.getZ(); 2598 _velocity.Z = tempLinearVelocity1.getZ();
2589 2599
2590 _acceleration = ((_velocity - m_lastVelocity)/0.1f); 2600 _acceleration = ((_velocity - m_lastVelocity) / 0.1f);
2591 _acceleration = new PhysicsVector(_velocity.X - m_lastVelocity.X/0.1f, 2601 _acceleration = new PhysicsVector(_velocity.X - m_lastVelocity.X / 0.1f,
2592 _velocity.Y - m_lastVelocity.Y/0.1f, 2602 _velocity.Y - m_lastVelocity.Y / 0.1f,
2593 _velocity.Z - m_lastVelocity.Z/0.1f); 2603 _velocity.Z - m_lastVelocity.Z / 0.1f);
2594 //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString()); 2604 //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString());
2595 2605
2596 if (_velocity.IsIdentical(pv, 0.5f)) 2606 if (_velocity.IsIdentical(pv, 0.5f))
@@ -2669,7 +2679,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2669 if (AxisLockAngleHigh != null && AxisLockAngleHigh.Handle != IntPtr.Zero) 2679 if (AxisLockAngleHigh != null && AxisLockAngleHigh.Handle != IntPtr.Zero)
2670 AxisLockAngleHigh.Dispose(); 2680 AxisLockAngleHigh.Dispose();
2671 2681
2672 2682
2673 2683
2674 m_aMotor = new btGeneric6DofConstraint(Body, _parent_scene.TerrainBody, _parent_scene.TransZero, 2684 m_aMotor = new btGeneric6DofConstraint(Body, _parent_scene.TerrainBody, _parent_scene.TransZero,
2675 _parent_scene.TransZero, false); 2685 _parent_scene.TransZero, false);
@@ -2683,7 +2693,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2683 m_aMotor.setLinearUpperLimit(AxisLockLinearHigh); 2693 m_aMotor.setLinearUpperLimit(AxisLockLinearHigh);
2684 _parent_scene.getBulletWorld().addConstraint((btTypedConstraint)m_aMotor); 2694 _parent_scene.getBulletWorld().addConstraint((btTypedConstraint)m_aMotor);
2685 //m_aMotor. 2695 //m_aMotor.
2686 2696
2687 2697
2688 } 2698 }
2689 internal void DisableAxisMotor() 2699 internal void DisableAxisMotor()
@@ -2698,4 +2708,4 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2698 2708
2699 } 2709 }
2700} 2710}
2701 2711
diff --git a/OpenSim/Region/Physics/Meshing/Mesh.cs b/OpenSim/Region/Physics/Meshing/Mesh.cs
index ceafaad..7567556 100644
--- a/OpenSim/Region/Physics/Meshing/Mesh.cs
+++ b/OpenSim/Region/Physics/Meshing/Mesh.cs
@@ -40,7 +40,6 @@ namespace OpenSim.Region.Physics.Meshing
40 private List<Triangle> triangles; 40 private List<Triangle> triangles;
41 GCHandle pinnedVirtexes; 41 GCHandle pinnedVirtexes;
42 GCHandle pinnedIndex; 42 GCHandle pinnedIndex;
43 public PrimMesh primMesh = null;
44 public float[] normals; 43 public float[] normals;
45 44
46 public Mesh() 45 public Mesh()
@@ -63,6 +62,8 @@ namespace OpenSim.Region.Physics.Meshing
63 62
64 public void Add(Triangle triangle) 63 public void Add(Triangle triangle)
65 { 64 {
65 if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated)
66 throw new NotSupportedException("Attempt to Add to a pinned Mesh");
66 // If a vertex of the triangle is not yet in the vertices list, 67 // If a vertex of the triangle is not yet in the vertices list,
67 // add it and set its index to the current index count 68 // add it and set its index to the current index count
68 if (!vertices.ContainsKey(triangle.v1)) 69 if (!vertices.ContainsKey(triangle.v1))
@@ -148,40 +149,22 @@ namespace OpenSim.Region.Physics.Meshing
148 149
149 public float[] getVertexListAsFloatLocked() 150 public float[] getVertexListAsFloatLocked()
150 { 151 {
152 if( pinnedVirtexes.IsAllocated )
153 return (float[])(pinnedVirtexes.Target);
151 float[] result; 154 float[] result;
152 155
153 if (primMesh == null) 156 //m_log.WarnFormat("vertices.Count = {0}", vertices.Count);
157 result = new float[vertices.Count * 3];
158 foreach (KeyValuePair<Vertex, int> kvp in vertices)
154 { 159 {
155 //m_log.WarnFormat("vertices.Count = {0}", vertices.Count); 160 Vertex v = kvp.Key;
156 result = new float[vertices.Count * 3]; 161 int i = kvp.Value;
157 foreach (KeyValuePair<Vertex, int> kvp in vertices) 162 //m_log.WarnFormat("kvp.Value = {0}", i);
158 { 163 result[3 * i + 0] = v.X;
159 Vertex v = kvp.Key; 164 result[3 * i + 1] = v.Y;
160 int i = kvp.Value; 165 result[3 * i + 2] = v.Z;
161 //m_log.WarnFormat("kvp.Value = {0}", i);
162 result[3 * i + 0] = v.X;
163 result[3 * i + 1] = v.Y;
164 result[3 * i + 2] = v.Z;
165 }
166 pinnedVirtexes = GCHandle.Alloc(result, GCHandleType.Pinned);
167 }
168 else
169 {
170 int count = primMesh.coords.Count;
171 result = new float[count * 3];
172 for (int i = 0; i < count; i++)
173 {
174 Coord c = primMesh.coords[i];
175 {
176 int resultIndex = 3 * i;
177 result[resultIndex] = c.X;
178 result[resultIndex + 1] = c.Y;
179 result[resultIndex + 2] = c.Z;
180 }
181
182 }
183 pinnedVirtexes = GCHandle.Alloc(result, GCHandleType.Pinned);
184 } 166 }
167 pinnedVirtexes = GCHandle.Alloc(result, GCHandleType.Pinned);
185 return result; 168 return result;
186 } 169 }
187 170
@@ -189,33 +172,13 @@ namespace OpenSim.Region.Physics.Meshing
189 { 172 {
190 int[] result; 173 int[] result;
191 174
192 if (primMesh == null) 175 result = new int[triangles.Count * 3];
193 { 176 for (int i = 0; i < triangles.Count; i++)
194 result = new int[triangles.Count * 3];
195 for (int i = 0; i < triangles.Count; i++)
196 {
197 Triangle t = triangles[i];
198 result[3 * i + 0] = vertices[t.v1];
199 result[3 * i + 1] = vertices[t.v2];
200 result[3 * i + 2] = vertices[t.v3];
201 }
202 }
203 else
204 { 177 {
205 int numFaces = primMesh.faces.Count; 178 Triangle t = triangles[i];
206 result = new int[numFaces * 3]; 179 result[3 * i + 0] = vertices[t.v1];
207 for (int i = 0; i < numFaces; i++) 180 result[3 * i + 1] = vertices[t.v2];
208 { 181 result[3 * i + 2] = vertices[t.v3];
209 Face f = primMesh.faces[i];
210// Coord c1 = primMesh.coords[f.v1];
211// Coord c2 = primMesh.coords[f.v2];
212// Coord c3 = primMesh.coords[f.v3];
213
214 int resultIndex = i * 3;
215 result[resultIndex] = f.v1;
216 result[resultIndex + 1] = f.v2;
217 result[resultIndex + 2] = f.v3;
218 }
219 } 182 }
220 return result; 183 return result;
221 } 184 }
@@ -226,6 +189,9 @@ namespace OpenSim.Region.Physics.Meshing
226 /// <returns></returns> 189 /// <returns></returns>
227 public int[] getIndexListAsIntLocked() 190 public int[] getIndexListAsIntLocked()
228 { 191 {
192 if (pinnedIndex.IsAllocated)
193 return (int[])(pinnedIndex.Target);
194
229 int[] result = getIndexListAsInt(); 195 int[] result = getIndexListAsInt();
230 pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned); 196 pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned);
231 197
@@ -245,11 +211,13 @@ namespace OpenSim.Region.Physics.Meshing
245 { 211 {
246 triangles = null; 212 triangles = null;
247 vertices = null; 213 vertices = null;
248 primMesh = null;
249 } 214 }
250 215
251 public void Append(IMesh newMesh) 216 public void Append(IMesh newMesh)
252 { 217 {
218 if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated)
219 throw new NotSupportedException("Attempt to Append to a pinned Mesh");
220
253 if (!(newMesh is Mesh)) 221 if (!(newMesh is Mesh))
254 return; 222 return;
255 223
@@ -260,6 +228,9 @@ namespace OpenSim.Region.Physics.Meshing
260 // Do a linear transformation of mesh. 228 // Do a linear transformation of mesh.
261 public void TransformLinear(float[,] matrix, float[] offset) 229 public void TransformLinear(float[,] matrix, float[] offset)
262 { 230 {
231 if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated)
232 throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh");
233
263 foreach (Vertex v in vertices.Keys) 234 foreach (Vertex v in vertices.Keys)
264 { 235 {
265 if (v == null) 236 if (v == null)
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index f469ad6..0873035 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -76,6 +76,7 @@ namespace OpenSim.Region.Physics.Meshing
76 76
77 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 77 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
78 78
79 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
79 80
80 /// <summary> 81 /// <summary>
81 /// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may 82 /// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may
@@ -170,9 +171,62 @@ namespace OpenSim.Region.Physics.Meshing
170 171
171 } 172 }
172 173
173 public Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod) 174 private ulong GetMeshKey( PrimitiveBaseShape pbs, PhysicsVector size, float lod )
175 {
176 ulong hash = 5381;
177
178 hash = djb2(hash, pbs.PathCurve);
179 hash = djb2(hash, (byte)((byte)pbs.HollowShape | (byte)pbs.ProfileShape));
180 hash = djb2(hash, pbs.PathBegin);
181 hash = djb2(hash, pbs.PathEnd);
182 hash = djb2(hash, pbs.PathScaleX);
183 hash = djb2(hash, pbs.PathScaleY);
184 hash = djb2(hash, pbs.PathShearX);
185 hash = djb2(hash, pbs.PathShearY);
186 hash = djb2(hash, (byte)pbs.PathTwist);
187 hash = djb2(hash, (byte)pbs.PathTwistBegin);
188 hash = djb2(hash, (byte)pbs.PathRadiusOffset);
189 hash = djb2(hash, (byte)pbs.PathTaperX);
190 hash = djb2(hash, (byte)pbs.PathTaperY);
191 hash = djb2(hash, pbs.PathRevolutions);
192 hash = djb2(hash, (byte)pbs.PathSkew);
193 hash = djb2(hash, pbs.ProfileBegin);
194 hash = djb2(hash, pbs.ProfileEnd);
195 hash = djb2(hash, pbs.ProfileHollow);
196
197 // TODO: Separate scale out from the primitive shape data (after
198 // scaling is supported at the physics engine level)
199 byte[] scaleBytes = size.GetBytes();
200 for (int i = 0; i < scaleBytes.Length; i++)
201 hash = djb2(hash, scaleBytes[i]);
202
203 // Include LOD in hash, accounting for endianness
204 byte[] lodBytes = new byte[4];
205 Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4);
206 if (!BitConverter.IsLittleEndian)
207 {
208 Array.Reverse(lodBytes, 0, 4);
209 }
210 for (int i = 0; i < lodBytes.Length; i++)
211 hash = djb2(hash, lodBytes[i]);
212
213 return hash;
214 }
215
216 private ulong djb2(ulong hash, byte c)
217 {
218 return ((hash << 5) + hash) + (ulong)c;
219 }
220
221 private ulong djb2(ulong hash, ushort c)
222 {
223 hash = ((hash << 5) + hash) + (ulong)((byte)c);
224 return ((hash << 5) + hash) + (ulong)(c >> 8);
225 }
226
227
228 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod)
174 { 229 {
175 Mesh mesh = new Mesh();
176 PrimMesh primMesh; 230 PrimMesh primMesh;
177 PrimMesher.SculptMesh sculptMesh; 231 PrimMesher.SculptMesh sculptMesh;
178 232
@@ -385,8 +439,6 @@ namespace OpenSim.Region.Physics.Meshing
385 439
386 coords = primMesh.coords; 440 coords = primMesh.coords;
387 faces = primMesh.faces; 441 faces = primMesh.faces;
388
389
390 } 442 }
391 443
392 444
@@ -401,13 +453,13 @@ namespace OpenSim.Region.Physics.Meshing
401 vertices.Add(new Vertex(c.X, c.Y, c.Z)); 453 vertices.Add(new Vertex(c.X, c.Y, c.Z));
402 } 454 }
403 455
456 Mesh mesh = new Mesh();
404 // Add the corresponding triangles to the mesh 457 // Add the corresponding triangles to the mesh
405 for (int i = 0; i < numFaces; i++) 458 for (int i = 0; i < numFaces; i++)
406 { 459 {
407 Face f = faces[i]; 460 Face f = faces[i];
408 mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3])); 461 mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
409 } 462 }
410
411 return mesh; 463 return mesh;
412 } 464 }
413 465
@@ -418,7 +470,12 @@ namespace OpenSim.Region.Physics.Meshing
418 470
419 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod, bool isPhysical) 471 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod, bool isPhysical)
420 { 472 {
473 // If this mesh has been created already, return it instead of creating another copy
474 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory
475 ulong key = GetMeshKey(primShape, size, lod);
421 Mesh mesh = null; 476 Mesh mesh = null;
477 if (m_uniqueMeshes.TryGetValue(key, out mesh))
478 return mesh;
422 479
423 if (size.X < 0.01f) size.X = 0.01f; 480 if (size.X < 0.01f) size.X = 0.01f;
424 if (size.Y < 0.01f) size.Y = 0.01f; 481 if (size.Y < 0.01f) size.Y = 0.01f;
@@ -441,7 +498,7 @@ namespace OpenSim.Region.Physics.Meshing
441 // trim the vertex and triangle lists to free up memory 498 // trim the vertex and triangle lists to free up memory
442 mesh.TrimExcess(); 499 mesh.TrimExcess();
443 } 500 }
444 501 m_uniqueMeshes.Add(key, mesh);
445 return mesh; 502 return mesh;
446 } 503 }
447 } 504 }
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 673ae39..032b5df 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -82,7 +82,6 @@ namespace OpenSim.Region.Physics.OdePlugin
82 82
83 // private float m_tensor = 5f; 83 // private float m_tensor = 5f;
84 private int body_autodisable_frames = 20; 84 private int body_autodisable_frames = 20;
85 private IMesh primMesh = null;
86 85
87 86
88 private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom 87 private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom
@@ -814,14 +813,10 @@ namespace OpenSim.Region.Physics.OdePlugin
814 } 813 }
815 } 814 }
816 815
817 IMesh oldMesh = primMesh; 816 float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
817 int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
818 818
819 primMesh = mesh; 819 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
820
821 float[] vertexList = primMesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
822 int[] indexList = primMesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
823
824 primMesh.releaseSourceMeshData(); // free up the original mesh data to save memory
825 820
826 int VertexCount = vertexList.GetLength(0)/3; 821 int VertexCount = vertexList.GetLength(0)/3;
827 int IndexCount = indexList.GetLength(0); 822 int IndexCount = indexList.GetLength(0);
@@ -847,12 +842,6 @@ namespace OpenSim.Region.Physics.OdePlugin
847 return; 842 return;
848 } 843 }
849 844
850 if (oldMesh != null)
851 {
852 oldMesh.releasePinned();
853 oldMesh = null;
854 }
855
856 // if (IsPhysical && Body == (IntPtr) 0) 845 // if (IsPhysical && Body == (IntPtr) 0)
857 // { 846 // {
858 // Recreate the body 847 // Recreate the body