diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 133 |
1 files changed, 111 insertions, 22 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index a0e627e..f7b68ba 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -46,19 +46,13 @@ public sealed class BSPrim : BSPhysObject | |||
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
47 | private static readonly string LogHeader = "[BULLETS PRIM]"; | 47 | private static readonly string LogHeader = "[BULLETS PRIM]"; |
48 | 48 | ||
49 | private IMesh _mesh; | ||
50 | private PrimitiveBaseShape _pbs; | 49 | private PrimitiveBaseShape _pbs; |
51 | private ShapeData.PhysicsShapeType _shapeType; | ||
52 | private ulong _meshKey; | ||
53 | private ulong _hullKey; | ||
54 | private List<ConvexResult> _hulls; | ||
55 | 50 | ||
56 | // _size is what the user passed. _scale is what we pass to the physics engine with the mesh. | 51 | // _size is what the user passed. _scale is what we pass to the physics engine with the mesh. |
57 | // Often _scale is unity because the meshmerizer will apply _size when creating the mesh. | 52 | // Often _scale is unity because the meshmerizer will apply _size when creating the mesh. |
58 | private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user | 53 | private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user |
59 | private OMV.Vector3 _scale; // the multiplier for each mesh dimension for the mesh as created by the meshmerizer | 54 | private OMV.Vector3 _scale; // the multiplier for each mesh dimension for the mesh as created by the meshmerizer |
60 | 55 | ||
61 | private bool _stopped; | ||
62 | private bool _grabbed; | 56 | private bool _grabbed; |
63 | private bool _isSelected; | 57 | private bool _isSelected; |
64 | private bool _isVolumeDetect; | 58 | private bool _isVolumeDetect; |
@@ -109,8 +103,6 @@ public sealed class BSPrim : BSPhysObject | |||
109 | _buoyancy = 1f; | 103 | _buoyancy = 1f; |
110 | _velocity = OMV.Vector3.Zero; | 104 | _velocity = OMV.Vector3.Zero; |
111 | _rotationalVelocity = OMV.Vector3.Zero; | 105 | _rotationalVelocity = OMV.Vector3.Zero; |
112 | _hullKey = 0; | ||
113 | _meshKey = 0; | ||
114 | _pbs = pbs; | 106 | _pbs = pbs; |
115 | _isPhysical = pisPhysical; | 107 | _isPhysical = pisPhysical; |
116 | _isVolumeDetect = false; | 108 | _isVolumeDetect = false; |
@@ -160,8 +152,9 @@ public sealed class BSPrim : BSPhysObject | |||
160 | }); | 152 | }); |
161 | } | 153 | } |
162 | 154 | ||
155 | // No one uses this property. | ||
163 | public override bool Stopped { | 156 | public override bool Stopped { |
164 | get { return _stopped; } | 157 | get { return false; } |
165 | } | 158 | } |
166 | public override OMV.Vector3 Size { | 159 | public override OMV.Vector3 Size { |
167 | get { return _size; } | 160 | get { return _size; } |
@@ -274,6 +267,7 @@ public sealed class BSPrim : BSPhysObject | |||
274 | set { | 267 | set { |
275 | _position = value; | 268 | _position = value; |
276 | // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? | 269 | // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? |
270 | PositionSanityCheck(); | ||
277 | PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() | 271 | PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() |
278 | { | 272 | { |
279 | // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 273 | // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
@@ -281,6 +275,74 @@ public sealed class BSPrim : BSPhysObject | |||
281 | }); | 275 | }); |
282 | } | 276 | } |
283 | } | 277 | } |
278 | public override OMV.Vector3 ForcePosition { | ||
279 | get { | ||
280 | _position = BulletSimAPI.GetPosition2(BSBody.ptr); | ||
281 | return _position; | ||
282 | } | ||
283 | set { | ||
284 | _position = value; | ||
285 | PositionSanityCheck(); | ||
286 | BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); | ||
287 | } | ||
288 | } | ||
289 | |||
290 | // Check that the current position is sane and, if not, modify the position to make it so. | ||
291 | // Check for being below terrain and being out of bounds. | ||
292 | // Returns 'true' of the position was made sane by some action. | ||
293 | private bool PositionSanityCheck() | ||
294 | { | ||
295 | bool ret = false; | ||
296 | |||
297 | // If totally below the ground, move the prim up | ||
298 | // TODO: figure out the right solution for this... only for dynamic objects? | ||
299 | /* | ||
300 | float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); | ||
301 | if (Position.Z < terrainHeight) | ||
302 | { | ||
303 | DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); | ||
304 | _position.Z = terrainHeight + 2.0f; | ||
305 | ret = true; | ||
306 | } | ||
307 | */ | ||
308 | if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) | ||
309 | { | ||
310 | float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position); | ||
311 | if (Position.Z < waterHeight) | ||
312 | { | ||
313 | _position.Z = waterHeight; | ||
314 | ret = true; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | // TODO: check for out of bounds | ||
319 | return ret; | ||
320 | } | ||
321 | |||
322 | // A version of the sanity check that also makes sure a new position value is | ||
323 | // pushed back to the physics engine. This routine would be used by anyone | ||
324 | // who is not already pushing the value. | ||
325 | private bool PositionSanityCheck2(bool atTaintTime) | ||
326 | { | ||
327 | bool ret = false; | ||
328 | if (PositionSanityCheck()) | ||
329 | { | ||
330 | // The new position value must be pushed into the physics engine but we can't | ||
331 | // just assign to "Position" because of potential call loops. | ||
332 | BSScene.TaintCallback sanityOperation = delegate() | ||
333 | { | ||
334 | DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); | ||
335 | BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation); | ||
336 | }; | ||
337 | if (atTaintTime) | ||
338 | sanityOperation(); | ||
339 | else | ||
340 | PhysicsScene.TaintedObject("BSPrim.PositionSanityCheck", sanityOperation); | ||
341 | |||
342 | ret = true; | ||
343 | } | ||
344 | return ret; | ||
345 | } | ||
284 | 346 | ||
285 | // Return the effective mass of the object. | 347 | // Return the effective mass of the object. |
286 | // If there are multiple items in the linkset, add them together for the root | 348 | // If there are multiple items in the linkset, add them together for the root |
@@ -326,14 +388,15 @@ public sealed class BSPrim : BSPhysObject | |||
326 | } | 388 | } |
327 | set { | 389 | set { |
328 | Vehicle type = (Vehicle)value; | 390 | Vehicle type = (Vehicle)value; |
329 | BSPrim vehiclePrim = this; | 391 | |
392 | // Tell the scene about the vehicle so it will get processing each frame. | ||
393 | PhysicsScene.VehicleInSceneTypeChanged(this, type); | ||
394 | |||
330 | PhysicsScene.TaintedObject("setVehicleType", delegate() | 395 | PhysicsScene.TaintedObject("setVehicleType", delegate() |
331 | { | 396 | { |
332 | // Done at taint time so we're sure the physics engine is not using the variables | 397 | // Done at taint time so we're sure the physics engine is not using the variables |
333 | // Vehicle code changes the parameters for this vehicle type. | 398 | // Vehicle code changes the parameters for this vehicle type. |
334 | _vehicle.ProcessTypeChange(type); | 399 | this._vehicle.ProcessTypeChange(type); |
335 | // Tell the scene about the vehicle so it will get processing each frame. | ||
336 | PhysicsScene.VehicleInSceneTypeChanged(this, type); | ||
337 | }); | 400 | }); |
338 | } | 401 | } |
339 | } | 402 | } |
@@ -371,7 +434,9 @@ public sealed class BSPrim : BSPhysObject | |||
371 | public override void StepVehicle(float timeStep) | 434 | public override void StepVehicle(float timeStep) |
372 | { | 435 | { |
373 | if (IsPhysical) | 436 | if (IsPhysical) |
437 | { | ||
374 | _vehicle.Step(timeStep); | 438 | _vehicle.Step(timeStep); |
439 | } | ||
375 | } | 440 | } |
376 | 441 | ||
377 | // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more | 442 | // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more |
@@ -435,6 +500,20 @@ public sealed class BSPrim : BSPhysObject | |||
435 | }); | 500 | }); |
436 | } | 501 | } |
437 | } | 502 | } |
503 | // Go directly to Bullet to get/set the value. | ||
504 | public override OMV.Quaternion ForceOrientation | ||
505 | { | ||
506 | get | ||
507 | { | ||
508 | _orientation = BulletSimAPI.GetOrientation2(BSBody.ptr); | ||
509 | return _orientation; | ||
510 | } | ||
511 | set | ||
512 | { | ||
513 | _orientation = value; | ||
514 | BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); | ||
515 | } | ||
516 | } | ||
438 | public override int PhysicsActorType { | 517 | public override int PhysicsActorType { |
439 | get { return _physicsActorType; } | 518 | get { return _physicsActorType; } |
440 | set { _physicsActorType = value; } | 519 | set { _physicsActorType = value; } |
@@ -488,11 +567,10 @@ public sealed class BSPrim : BSPhysObject | |||
488 | // This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found). | 567 | // This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found). |
489 | BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, BSBody.ptr); | 568 | BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, BSBody.ptr); |
490 | 569 | ||
491 | |||
492 | // Set up the object physicalness (does gravity and collisions move this object) | 570 | // Set up the object physicalness (does gravity and collisions move this object) |
493 | MakeDynamic(IsStatic); | 571 | MakeDynamic(IsStatic); |
494 | 572 | ||
495 | // Do any vehicle stuff | 573 | // Update vehicle specific parameters |
496 | _vehicle.Refresh(); | 574 | _vehicle.Refresh(); |
497 | 575 | ||
498 | // Arrange for collision events if the simulator wants them | 576 | // Arrange for collision events if the simulator wants them |
@@ -563,7 +641,6 @@ public sealed class BSPrim : BSPhysObject | |||
563 | // A dynamic object has mass | 641 | // A dynamic object has mass |
564 | IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.ptr); | 642 | IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.ptr); |
565 | OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Mass); | 643 | OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Mass); |
566 | // OMV.Vector3 inertia = OMV.Vector3.Zero; | ||
567 | BulletSimAPI.SetMassProps2(BSBody.ptr, _mass, inertia); | 644 | BulletSimAPI.SetMassProps2(BSBody.ptr, _mass, inertia); |
568 | BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); | 645 | BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); |
569 | 646 | ||
@@ -573,7 +650,7 @@ public sealed class BSPrim : BSPhysObject | |||
573 | BulletSimAPI.SetSleepingThresholds2(BSBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); | 650 | BulletSimAPI.SetSleepingThresholds2(BSBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); |
574 | BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold); | 651 | BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold); |
575 | 652 | ||
576 | // There can be special things needed for implementing linksets. | 653 | // There might be special things needed for implementing linksets. |
577 | Linkset.MakeDynamic(this); | 654 | Linkset.MakeDynamic(this); |
578 | 655 | ||
579 | // Force activation of the object so Bullet will act on it. | 656 | // Force activation of the object so Bullet will act on it. |
@@ -663,7 +740,16 @@ public sealed class BSPrim : BSPhysObject | |||
663 | } | 740 | } |
664 | } | 741 | } |
665 | public override bool FloatOnWater { | 742 | public override bool FloatOnWater { |
666 | set { _floatOnWater = value; } | 743 | set { |
744 | _floatOnWater = value; | ||
745 | PhysicsScene.TaintedObject("BSPrim.setFloatOnWater", delegate() | ||
746 | { | ||
747 | if (_floatOnWater) | ||
748 | CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); | ||
749 | else | ||
750 | CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); | ||
751 | }); | ||
752 | } | ||
667 | } | 753 | } |
668 | public override OMV.Vector3 RotationalVelocity { | 754 | public override OMV.Vector3 RotationalVelocity { |
669 | get { | 755 | get { |
@@ -1082,15 +1168,15 @@ public sealed class BSPrim : BSPhysObject | |||
1082 | public void FillShapeInfo(out ShapeData shape) | 1168 | public void FillShapeInfo(out ShapeData shape) |
1083 | { | 1169 | { |
1084 | shape.ID = LocalID; | 1170 | shape.ID = LocalID; |
1085 | shape.Type = _shapeType; | 1171 | shape.Type = ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; |
1086 | shape.Position = _position; | 1172 | shape.Position = _position; |
1087 | shape.Rotation = _orientation; | 1173 | shape.Rotation = _orientation; |
1088 | shape.Velocity = _velocity; | 1174 | shape.Velocity = _velocity; |
1089 | shape.Scale = _scale; | 1175 | shape.Scale = _scale; |
1090 | shape.Mass = _isPhysical ? _mass : 0f; | 1176 | shape.Mass = _isPhysical ? _mass : 0f; |
1091 | shape.Buoyancy = _buoyancy; | 1177 | shape.Buoyancy = _buoyancy; |
1092 | shape.HullKey = _hullKey; | 1178 | shape.HullKey = 0; |
1093 | shape.MeshKey = _meshKey; | 1179 | shape.MeshKey = 0; |
1094 | shape.Friction = _friction; | 1180 | shape.Friction = _friction; |
1095 | shape.Restitution = _restitution; | 1181 | shape.Restitution = _restitution; |
1096 | shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse; | 1182 | shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse; |
@@ -1112,7 +1198,8 @@ public sealed class BSPrim : BSPhysObject | |||
1112 | 1198 | ||
1113 | // Create the correct physical representation for this type of object. | 1199 | // Create the correct physical representation for this type of object. |
1114 | // Updates BSBody and BSShape with the new information. | 1200 | // Updates BSBody and BSShape with the new information. |
1115 | PhysicsScene.Shapes.GetBodyAndShape(forceRebuild, PhysicsScene.World, this, shapeData, _pbs, | 1201 | // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. |
1202 | PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, shapeData, _pbs, | ||
1116 | null, delegate(BulletBody dBody) | 1203 | null, delegate(BulletBody dBody) |
1117 | { | 1204 | { |
1118 | // Called if the current prim body is about to be destroyed. | 1205 | // Called if the current prim body is about to be destroyed. |
@@ -1205,6 +1292,8 @@ public sealed class BSPrim : BSPhysObject | |||
1205 | _acceleration = entprop.Acceleration; | 1292 | _acceleration = entprop.Acceleration; |
1206 | _rotationalVelocity = entprop.RotationalVelocity; | 1293 | _rotationalVelocity = entprop.RotationalVelocity; |
1207 | 1294 | ||
1295 | PositionSanityCheck2(true); | ||
1296 | |||
1208 | DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", | 1297 | DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", |
1209 | LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); | 1298 | LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); |
1210 | 1299 | ||