aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs374
1 files changed, 0 insertions, 374 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 17ba85a..e65e42b 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -27,8 +27,6 @@
27 27
28// Uncomment this it enable code to do all shape an body memory management 28// Uncomment this it enable code to do all shape an body memory management
29// in the C# code. 29// in the C# code.
30#define CSHARP_BODY_MANAGEMENT
31
32using System; 30using System;
33using System.Reflection; 31using System.Reflection;
34using System.Collections.Generic; 32using System.Collections.Generic;
@@ -474,14 +472,8 @@ public sealed class BSPrim : BSPhysObject
474 // Called at taint-time!! 472 // Called at taint-time!!
475 private void SetObjectDynamic(bool forceRebuild) 473 private void SetObjectDynamic(bool forceRebuild)
476 { 474 {
477#if CSHARP_BODY_MANAGEMENT
478 // Recreate the physical object if necessary 475 // Recreate the physical object if necessary
479 CreateGeomAndObject(forceRebuild); 476 CreateGeomAndObject(forceRebuild);
480#else
481 // If it's becoming dynamic, it will need hullness
482 VerifyCorrectPhysicalShape();
483 UpdatePhysicalParameters();
484#endif // CSHARP_BODY_MANAGEMENT
485 } 477 }
486 478
487 // Convert the simulator's physical properties into settings on BulletSim objects. 479 // Convert the simulator's physical properties into settings on BulletSim objects.
@@ -498,11 +490,6 @@ public sealed class BSPrim : BSPhysObject
498 // This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found). 490 // This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found).
499 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, BSBody.ptr); 491 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, BSBody.ptr);
500 492
501#if !CSHARP_BODY_MANAGEMENT
502 // Make solid or not (do things bounce off or pass through this object)
503 // This is done first because it can change the collisionObject type.
504 MakeSolid(IsSolid);
505#endif // !CSHARP_BODY_MANAGEMENT
506 493
507 // Set up the object physicalness (does gravity and collisions move this object) 494 // Set up the object physicalness (does gravity and collisions move this object)
508 MakeDynamic(IsStatic); 495 MakeDynamic(IsStatic);
@@ -513,10 +500,8 @@ public sealed class BSPrim : BSPhysObject
513 // Arrange for collision events if the simulator wants them 500 // Arrange for collision events if the simulator wants them
514 EnableCollisions(SubscribedEvents()); 501 EnableCollisions(SubscribedEvents());
515 502
516#if CSHARP_BODY_MANAGEMENT
517 // Make solid or not (do things bounce off or pass through this object). 503 // Make solid or not (do things bounce off or pass through this object).
518 MakeSolid(IsSolid); 504 MakeSolid(IsSolid);
519#endif // CSHARP_BODY_MANAGEMENT
520 505
521 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr); 506 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr);
522 507
@@ -609,7 +594,6 @@ public sealed class BSPrim : BSPhysObject
609 // the functions after this one set up the state of a possibly newly created collision body. 594 // the functions after this one set up the state of a possibly newly created collision body.
610 private void MakeSolid(bool makeSolid) 595 private void MakeSolid(bool makeSolid)
611 { 596 {
612#if CSHARP_BODY_MANAGEMENT
613 CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(BSBody.ptr); 597 CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(BSBody.ptr);
614 if (makeSolid) 598 if (makeSolid)
615 { 599 {
@@ -630,49 +614,6 @@ public sealed class BSPrim : BSPhysObject
630 BSBody.collisionFilter = CollisionFilterGroups.VolumeDetectFilter; 614 BSBody.collisionFilter = CollisionFilterGroups.VolumeDetectFilter;
631 BSBody.collisionMask = CollisionFilterGroups.VolumeDetectMask; 615 BSBody.collisionMask = CollisionFilterGroups.VolumeDetectMask;
632 } 616 }
633#else
634 // If doing the body management in C#, all this logic is in CSShapeCollection.CreateObject().
635 CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(BSBody.ptr);
636 if (makeSolid)
637 {
638 if ((bodyType & CollisionObjectTypes.CO_RIGID_BODY) == 0)
639 {
640 // Solid things are made out of rigid bodies. Remove this old body from the world
641 // and use this shape in a new rigid body.
642 BulletBody oldBody = BSBody;
643 // Zero out the pointer to the shape in the old body so the shape will not get freed
644 BSShape.Ptr = BulletSimAPI.GetCollisionShape2(oldBody.Ptr);
645 BulletSimAPI.SetCollisionShape2(PhysicsScene.World.Ptr, oldBody.Ptr, IntPtr.Zero);
646 // Get rid of the old body and remove it from BulletSim's object list
647 BulletSimAPI.DestroyObject(PhysicsScene.WorldID, LocalID);
648
649 // Create the new body with the shape
650 BSBody = new BulletBody(LocalID, BulletSimAPI.CreateBodyFromShape2(PhysicsScene.World.Ptr, BSShape.Ptr, _position, _orientation));
651 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
652 DetailLog("{0},BSPrim.MakeSolid:rigidBody,body={1},shape={2}", LocalID, BSBody, BSShape);
653 }
654 }
655 else
656 {
657 if ((bodyType & CollisionObjectTypes.CO_GHOST_OBJECT) == 0)
658 {
659 // Non-solid things are made out of ghost objects. Remove this old body from the world
660 // and use this shape in a new rigid body.
661 BulletBody oldBody = BSBody;
662
663 // Zero out the pointer to the shape in the old body so the shape will not get freed
664 BSShape.Ptr = BulletSimAPI.GetCollisionShape2(oldBody.Ptr);
665 BulletSimAPI.SetCollisionShape2(PhysicsScene.World.Ptr, oldBody.Ptr, IntPtr.Zero);
666 // Get rid of the old body and remove it from BulletSim's object list
667 BulletSimAPI.DestroyObject(PhysicsScene.WorldID, LocalID);
668
669 BSBody = new BulletBody(LocalID,
670 BulletSimAPI.CreateGhostFromShape2(PhysicsScene.World.Ptr, BSShape.Ptr, _position, _orientation));
671 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
672 DetailLog("{0},BSPrim.MakeGhostBody,body={1},shape={2}", LocalID, BSBody, BSShape);
673 }
674 }
675#endif
676 } 617 }
677 618
678 // Turn on or off the flag controlling whether collision events are returned to the simulator. 619 // Turn on or off the flag controlling whether collision events are returned to the simulator.
@@ -1139,300 +1080,6 @@ public sealed class BSPrim : BSPhysObject
1139 }// end CalculateMass 1080 }// end CalculateMass
1140 #endregion Mass Calculation 1081 #endregion Mass Calculation
1141 1082
1142#if !CSHARP_BODY_MANAGEMENT
1143 // Create the geometry information in Bullet for later use.
1144 // The objects needs a hull if it's physical otherwise a mesh is enough.
1145 // No locking here because this is done when we know physics is not simulating.
1146 // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used.
1147 // Returns 'true' if the geometry was rebuilt.
1148 // Called at taint-time!
1149 private bool CreateGeom(bool forceRebuild)
1150 {
1151 bool ret = false;
1152 bool haveShape = false;
1153
1154 // If the prim attributes are simple, this could be a simple Bullet native shape
1155 if (
1156 // if the basic shape is a cube or a sphere...
1157 ((_pbs.ProfileShape == ProfileShape.Square && _pbs.PathCurve == (byte)Extrusion.Straight)
1158 || (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1
1159 /* && _pbs.Scale.X == _pbs.Scale.Y && _pbs.Scale.Y == _pbs.Scale.Z */ ))
1160 // ... and we are not doing sculpty meshes...
1161 && (_pbs.SculptEntry && !PhysicsScene.ShouldMeshSculptedPrim)
1162 // ... or this is a 'simple' shape...
1163 || (_pbs.ProfileBegin == 0 && _pbs.ProfileEnd == 0
1164 && _pbs.ProfileHollow == 0
1165 && _pbs.PathTwist == 0 && _pbs.PathTwistBegin == 0
1166 && _pbs.PathBegin == 0 && _pbs.PathEnd == 0
1167 && _pbs.PathTaperX == 0 && _pbs.PathTaperY == 0
1168 && _pbs.PathScaleX == 100 && _pbs.PathScaleY == 100
1169 && _pbs.PathShearX == 0 && _pbs.PathShearY == 0) )
1170 // ... then this might be representable as a native Bullet collision shape
1171 {
1172 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
1173 {
1174 haveShape = true;
1175 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
1176 {
1177 DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
1178 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
1179 _meshKey = (ulong)ShapeData.FixedShapeKey.KEY_SPHERE;
1180 // Bullet native objects are scaled by the Bullet engine so pass the size in
1181 _scale = _size;
1182 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
1183 ret = true;
1184 }
1185 }
1186 else
1187 {
1188 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
1189 haveShape = true;
1190 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
1191 {
1192 DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
1193 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
1194 _meshKey = (ulong)ShapeData.FixedShapeKey.KEY_BOX;
1195 _scale = _size;
1196 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
1197 ret = true;
1198 }
1199 }
1200 }
1201 // If a simple shape isn't happening, create a mesh and possibly a hull
1202 if (!haveShape)
1203 {
1204 if (IsPhysical)
1205 {
1206 if (forceRebuild || _hullKey == 0)
1207 {
1208 // physical objects require a hull for interaction.
1209 // This also creates the mesh if it doesn't already exist
1210 ret = CreateGeomHull();
1211 }
1212 }
1213 else
1214 {
1215 if (forceRebuild || _meshKey == 0)
1216 {
1217 // Static (non-physical) objects only need a mesh for bumping into
1218 ret = CreateGeomMesh();
1219 }
1220 }
1221 }
1222
1223 return ret;
1224 }
1225
1226 // No locking here because this is done when we know physics is not simulating
1227 // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs).
1228 // Called at taint-time!
1229 private bool CreateGeomMesh()
1230 {
1231 // level of detail based on size and type of the object
1232 float lod = PhysicsScene.MeshLOD;
1233 if (_pbs.SculptEntry)
1234 lod = PhysicsScene.SculptLOD;
1235 float maxAxis = Math.Max(_size.X, Math.Max(_size.Y, _size.Z));
1236 if (maxAxis > PhysicsScene.MeshMegaPrimThreshold)
1237 lod = PhysicsScene.MeshMegaPrimLOD;
1238
1239 ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod);
1240 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, LocalID, _meshKey, newMeshKey);
1241
1242 // if this new shape is the same as last time, don't recreate the mesh
1243 if (_meshKey == newMeshKey) return false;
1244
1245 DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
1246 // Since we're recreating new, get rid of any previously generated shape
1247 if (_meshKey != 0)
1248 {
1249 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, LocalID, _meshKey);
1250 DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
1251 BulletSimAPI.DestroyMesh(PhysicsScene.WorldID, _meshKey);
1252 _mesh = null;
1253 _meshKey = 0;
1254 }
1255
1256 _meshKey = newMeshKey;
1257 // always pass false for physicalness as this creates some sort of bounding box which we don't need
1258 _mesh = PhysicsScene.mesher.CreateMesh(PhysObjectName, _pbs, _size, lod, false);
1259
1260 int[] indices = _mesh.getIndexListAsInt();
1261 List<OMV.Vector3> vertices = _mesh.getVertexList();
1262
1263 float[] verticesAsFloats = new float[vertices.Count * 3];
1264 int vi = 0;
1265 foreach (OMV.Vector3 vv in vertices)
1266 {
1267 verticesAsFloats[vi++] = vv.X;
1268 verticesAsFloats[vi++] = vv.Y;
1269 verticesAsFloats[vi++] = vv.Z;
1270 }
1271
1272 // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}",
1273 // LogHeader, LocalID, _meshKey, indices.Length, vertices.Count);
1274 BulletSimAPI.CreateMesh(PhysicsScene.WorldID, _meshKey, indices.GetLength(0), indices,
1275 vertices.Count, verticesAsFloats);
1276
1277 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
1278 // meshes are already scaled by the meshmerizer
1279 _scale = new OMV.Vector3(1f, 1f, 1f);
1280 return true;
1281 }
1282
1283 // No locking here because this is done when we know physics is not simulating
1284 // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs).
1285 private bool CreateGeomHull()
1286 {
1287 float lod = _pbs.SculptEntry ? PhysicsScene.SculptLOD : PhysicsScene.MeshLOD;
1288 ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod);
1289 // m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, LocalID, _hullKey, newHullKey);
1290
1291 // if the hull hasn't changed, don't rebuild it
1292 if (newHullKey == _hullKey) return false;
1293
1294 DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
1295
1296 // Since we're recreating new, get rid of any previously generated shape
1297 if (_hullKey != 0)
1298 {
1299 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
1300 DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey);
1301 BulletSimAPI.DestroyHull(PhysicsScene.WorldID, _hullKey);
1302 _hullKey = 0;
1303 }
1304
1305 _hullKey = newHullKey;
1306
1307 // Make sure the underlying mesh exists and is correct
1308 CreateGeomMesh();
1309
1310 int[] indices = _mesh.getIndexListAsInt();
1311 List<OMV.Vector3> vertices = _mesh.getVertexList();
1312
1313 //format conversion from IMesh format to DecompDesc format
1314 List<int> convIndices = new List<int>();
1315 List<float3> convVertices = new List<float3>();
1316 for (int ii = 0; ii < indices.GetLength(0); ii++)
1317 {
1318 convIndices.Add(indices[ii]);
1319 }
1320 foreach (OMV.Vector3 vv in vertices)
1321 {
1322 convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
1323 }
1324
1325 // setup and do convex hull conversion
1326 _hulls = new List<ConvexResult>();
1327 DecompDesc dcomp = new DecompDesc();
1328 dcomp.mIndices = convIndices;
1329 dcomp.mVertices = convVertices;
1330 ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
1331 // create the hull into the _hulls variable
1332 convexBuilder.process(dcomp);
1333
1334 // Convert the vertices and indices for passing to unmanaged.
1335 // The hull information is passed as a large floating point array.
1336 // The format is:
1337 // convHulls[0] = number of hulls
1338 // convHulls[1] = number of vertices in first hull
1339 // convHulls[2] = hull centroid X coordinate
1340 // convHulls[3] = hull centroid Y coordinate
1341 // convHulls[4] = hull centroid Z coordinate
1342 // convHulls[5] = first hull vertex X
1343 // convHulls[6] = first hull vertex Y
1344 // convHulls[7] = first hull vertex Z
1345 // convHulls[8] = second hull vertex X
1346 // ...
1347 // convHulls[n] = number of vertices in second hull
1348 // convHulls[n+1] = second hull centroid X coordinate
1349 // ...
1350 //
1351 // TODO: is is very inefficient. Someday change the convex hull generator to return
1352 // data structures that do not need to be converted in order to pass to Bullet.
1353 // And maybe put the values directly into pinned memory rather than marshaling.
1354 int hullCount = _hulls.Count;
1355 int totalVertices = 1; // include one for the count of the hulls
1356 foreach (ConvexResult cr in _hulls)
1357 {
1358 totalVertices += 4; // add four for the vertex count and centroid
1359 totalVertices += cr.HullIndices.Count * 3; // we pass just triangles
1360 }
1361 float[] convHulls = new float[totalVertices];
1362
1363 convHulls[0] = (float)hullCount;
1364 int jj = 1;
1365 foreach (ConvexResult cr in _hulls)
1366 {
1367 // copy vertices for index access
1368 float3[] verts = new float3[cr.HullVertices.Count];
1369 int kk = 0;
1370 foreach (float3 ff in cr.HullVertices)
1371 {
1372 verts[kk++] = ff;
1373 }
1374
1375 // add to the array one hull's worth of data
1376 convHulls[jj++] = cr.HullIndices.Count;
1377 convHulls[jj++] = 0f; // centroid x,y,z
1378 convHulls[jj++] = 0f;
1379 convHulls[jj++] = 0f;
1380 foreach (int ind in cr.HullIndices)
1381 {
1382 convHulls[jj++] = verts[ind].x;
1383 convHulls[jj++] = verts[ind].y;
1384 convHulls[jj++] = verts[ind].z;
1385 }
1386 }
1387
1388 // create the hull definition in Bullet
1389 // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, LocalID, _hullKey, hullCount);
1390 BulletSimAPI.CreateHull(PhysicsScene.WorldID, _hullKey, hullCount, convHulls);
1391 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
1392 // meshes are already scaled by the meshmerizer
1393 _scale = new OMV.Vector3(1f, 1f, 1f);
1394 DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
1395 return true;
1396 }
1397
1398 // Callback from convex hull creater with a newly created hull.
1399 // Just add it to the collection of hulls for this shape.
1400 private void HullReturn(ConvexResult result)
1401 {
1402 _hulls.Add(result);
1403 return;
1404 }
1405
1406 private void VerifyCorrectPhysicalShape()
1407 {
1408 if (!IsStatic)
1409 {
1410 // if not static, it will need a hull to efficiently collide with things
1411 if (_hullKey == 0)
1412 {
1413 CreateGeomAndObject(false);
1414 }
1415
1416 }
1417 }
1418
1419 // Create an object in Bullet if it has not already been created
1420 // No locking here because this is done when the physics engine is not simulating
1421 // Returns 'true' if an object was actually created.
1422 private bool CreateObject()
1423 {
1424 // this routine is called when objects are rebuilt.
1425
1426 // the mesh or hull must have already been created in Bullet
1427 ShapeData shape;
1428 FillShapeInfo(out shape);
1429 // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, LocalID, shape.Type);
1430 bool ret = BulletSimAPI.CreateObject(PhysicsScene.WorldID, shape);
1431
1432 return ret;
1433 }
1434#endif // !CSHARP_BODY_MANAGEMENT
1435
1436 // Copy prim's info into the BulletSim shape description structure 1083 // Copy prim's info into the BulletSim shape description structure
1437 public void FillShapeInfo(out ShapeData shape) 1084 public void FillShapeInfo(out ShapeData shape)
1438 { 1085 {
@@ -1458,7 +1105,6 @@ public sealed class BSPrim : BSPhysObject
1458 // Called at taint-time!!! 1105 // Called at taint-time!!!
1459 private void CreateGeomAndObject(bool forceRebuild) 1106 private void CreateGeomAndObject(bool forceRebuild)
1460 { 1107 {
1461#if CSHARP_BODY_MANAGEMENT
1462 ShapeData shapeData; 1108 ShapeData shapeData;
1463 FillShapeInfo(out shapeData); 1109 FillShapeInfo(out shapeData);
1464 1110
@@ -1475,26 +1121,6 @@ public sealed class BSPrim : BSPhysObject
1475 1121
1476 // Make sure the properties are set on the new object 1122 // Make sure the properties are set on the new object
1477 UpdatePhysicalParameters(); 1123 UpdatePhysicalParameters();
1478#else
1479 // m_log.DebugFormat("{0}: CreateGeomAndObject. lID={1}, force={2}", LogHeader, LocalID, forceRebuild);
1480 // Create the geometry that will make up the object
1481 if (CreateGeom(forceRebuild))
1482 {
1483 // Create the object and place it into the world
1484 CreateObject();
1485
1486 // the CreateObject() may have recreated the rigid body. Make sure we have the latest address.
1487 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.Ptr, LocalID));
1488 BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr), _shapeType);
1489 BSShape.shapeKey = _meshKey;
1490 DetailLog("{0},BSPrim.CreateGeomAndObject,body={1},shape={2}", LocalID, BSBody, BSShape);
1491
1492 // Make sure the properties are set on the new object
1493 UpdatePhysicalParameters();
1494 }
1495
1496
1497#endif // CSHARP_BODY_MANAGEMENT
1498 return; 1124 return;
1499 } 1125 }
1500 1126