aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorRobert Adams2012-11-20 08:43:43 -0800
committerRobert Adams2012-11-21 16:42:42 -0800
commit4d29488216f3619455cda72aaf2d6ccf8f3e2402 (patch)
tree04075c27f863ba58bf5cfd22563c239382b5e86d
parentBulletSim: tweek avatar capsule parameters so avatar feet don't go below grou... (diff)
downloadopensim-SC-4d29488216f3619455cda72aaf2d6ccf8f3e2402.zip
opensim-SC-4d29488216f3619455cda72aaf2d6ccf8f3e2402.tar.gz
opensim-SC-4d29488216f3619455cda72aaf2d6ccf8f3e2402.tar.bz2
opensim-SC-4d29488216f3619455cda72aaf2d6ccf8f3e2402.tar.xz
BulletSim: change PositionSanityCheck to apply a force to correct position corrections (below ground and floating).
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs61
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs2
2 files changed, 30 insertions, 33 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 500c84a..b1b5846 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -47,7 +47,6 @@ public sealed class BSPrim : BSPhysObject
47 // _size is what the user passed. Scale is what we pass to the physics engine with the mesh. 47 // _size is what the user passed. Scale is what we pass to the physics engine with the mesh.
48 // Often Scale is unity because the meshmerizer will apply _size when creating the mesh. 48 // Often Scale is unity because the meshmerizer will apply _size when creating the mesh.
49 private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user 49 private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user
50 // private OMV.Vector3 _scale; // the multiplier for each mesh dimension for the mesh as created by the meshmerizer
51 50
52 private bool _grabbed; 51 private bool _grabbed;
53 private bool _isSelected; 52 private bool _isSelected;
@@ -274,19 +273,19 @@ public sealed class BSPrim : BSPhysObject
274 if (!Linkset.IsRoot(this)) 273 if (!Linkset.IsRoot(this))
275 _position = Linkset.Position(this); 274 _position = Linkset.Position(this);
276 275
277 // don't do the GetObjectPosition for root elements because this function is called a zillion times 276 // don't do the GetObjectPosition for root elements because this function is called a zillion times.
278 // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); 277 // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr);
279 return _position; 278 return _position;
280 } 279 }
281 set { 280 set {
282 // If you must push the position into the physics engine, use ForcePosition. 281 // If the position must be forced into the physics engine, use ForcePosition.
283 if (_position == value) 282 if (_position == value)
284 { 283 {
285 return; 284 return;
286 } 285 }
287 _position = value; 286 _position = value;
288 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? 287 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
289 PositionSanityCheck(); 288 PositionSanityCheck(false);
290 PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() 289 PhysicsScene.TaintedObject("BSPrim.setPosition", delegate()
291 { 290 {
292 // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 291 // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
@@ -302,7 +301,7 @@ public sealed class BSPrim : BSPhysObject
302 } 301 }
303 set { 302 set {
304 _position = value; 303 _position = value;
305 PositionSanityCheck(); 304 // PositionSanityCheck(); // Don't do this! Causes a loop and caller should know better.
306 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 305 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
307 ActivateIfPhysical(false); 306 ActivateIfPhysical(false);
308 } 307 }
@@ -311,52 +310,43 @@ public sealed class BSPrim : BSPhysObject
311 // Check that the current position is sane and, if not, modify the position to make it so. 310 // Check that the current position is sane and, if not, modify the position to make it so.
312 // Check for being below terrain and being out of bounds. 311 // Check for being below terrain and being out of bounds.
313 // Returns 'true' of the position was made sane by some action. 312 // Returns 'true' of the position was made sane by some action.
314 private bool PositionSanityCheck() 313 private bool PositionSanityCheck(bool inTaintTime)
315 { 314 {
316 bool ret = false; 315 bool ret = false;
317 316
318 // If totally below the ground, move the prim up
319 // TODO: figure out the right solution for this... only for dynamic objects?
320 /*
321 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); 317 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position);
318 OMV.Vector3 upForce = OMV.Vector3.Zero;
322 if (Position.Z < terrainHeight) 319 if (Position.Z < terrainHeight)
323 { 320 {
324 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); 321 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
325 _position.Z = terrainHeight + 2.0f; 322 float targetHeight = terrainHeight + (Size.Z / 2f);
323 // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec.
324 upForce.Z = (terrainHeight - Position.Z) * 1f;
326 ret = true; 325 ret = true;
327 } 326 }
328 */ 327
329 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) 328 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
330 { 329 {
331 float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position); 330 float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position);
332 // TODO: a floating motor so object will bob in the water 331 // TODO: a floating motor so object will bob in the water
333 if (Position.Z < waterHeight) 332 if (Math.Abs(Position.Z - waterHeight) > 0.1f)
334 { 333 {
335 _position.Z = waterHeight; 334 // Upforce proportional to the distance away from the water. Correct the error in 1 sec.
335 upForce.Z = (waterHeight - Position.Z) * 1f;
336 ret = true; 336 ret = true;
337 } 337 }
338 } 338 }
339 339
340 // TODO: check for out of bounds 340 // TODO: check for out of bounds
341 return ret;
342 }
343 341
344 // A version of the sanity check that also makes sure a new position value is 342 // The above code computes a force to apply to correct any out-of-bounds problems. Apply same.
345 // pushed to the physics engine. This routine would be used by anyone 343 if (ret)
346 // who is not already pushing the value.
347 private bool PositionSanityCheck(bool inTaintTime)
348 {
349 bool ret = false;
350 if (PositionSanityCheck())
351 { 344 {
352 // The new position value must be pushed into the physics engine but we can't 345 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.PositionSanityCheck:belowTerrain", delegate()
353 // just assign to "Position" because of potential call loops.
354 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.PositionSanityCheck", delegate()
355 { 346 {
356 DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); 347 // Apply upforce and overcome gravity.
357 ForcePosition = _position; 348 ForceVelocity = ForceVelocity + upForce - PhysicsScene.DefaultGravity;
358 }); 349 });
359 ret = true;
360 } 350 }
361 return ret; 351 return ret;
362 } 352 }
@@ -940,6 +930,7 @@ public sealed class BSPrim : BSPhysObject
940 public override void AddForce(OMV.Vector3 force, bool pushforce) { 930 public override void AddForce(OMV.Vector3 force, bool pushforce) {
941 AddForce(force, pushforce, false); 931 AddForce(force, pushforce, false);
942 } 932 }
933 // Applying a force just adds this to the total force on the object.
943 public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { 934 public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
944 // for an object, doesn't matter if force is a pushforce or not 935 // for an object, doesn't matter if force is a pushforce or not
945 if (force.IsFinite()) 936 if (force.IsFinite())
@@ -971,6 +962,7 @@ public sealed class BSPrim : BSPhysObject
971 }); 962 });
972 } 963 }
973 964
965 // An impulse force is scaled by the mass of the object.
974 public void ApplyForceImpulse(OMV.Vector3 impulse, bool inTaintTime) 966 public void ApplyForceImpulse(OMV.Vector3 impulse, bool inTaintTime)
975 { 967 {
976 OMV.Vector3 applyImpulse = impulse; 968 OMV.Vector3 applyImpulse = impulse;
@@ -1423,7 +1415,7 @@ public sealed class BSPrim : BSPhysObject
1423 if (changed != 0) 1415 if (changed != 0)
1424 { 1416 {
1425 // Only update the position of single objects and linkset roots 1417 // Only update the position of single objects and linkset roots
1426 if (this._parentPrim == null) 1418 if (Linkset.IsRoot(this))
1427 { 1419 {
1428 base.RequestPhysicsterseUpdate(); 1420 base.RequestPhysicsterseUpdate();
1429 } 1421 }
@@ -1435,19 +1427,24 @@ public sealed class BSPrim : BSPhysObject
1435 // Updates only for individual prims and for the root object of a linkset. 1427 // Updates only for individual prims and for the root object of a linkset.
1436 if (Linkset.IsRoot(this)) 1428 if (Linkset.IsRoot(this))
1437 { 1429 {
1438 // Assign to the local variables so the normal set action does not happen 1430 // Assign directly to the local variables so the normal set action does not happen
1439 _position = entprop.Position; 1431 _position = entprop.Position;
1440 _orientation = entprop.Rotation; 1432 _orientation = entprop.Rotation;
1441 _velocity = entprop.Velocity; 1433 _velocity = entprop.Velocity;
1442 _acceleration = entprop.Acceleration; 1434 _acceleration = entprop.Acceleration;
1443 _rotationalVelocity = entprop.RotationalVelocity; 1435 _rotationalVelocity = entprop.RotationalVelocity;
1444 1436
1437 // The sanity check can change the velocity and/or position.
1438 if (PositionSanityCheck(true))
1439 {
1440 entprop.Position = _position;
1441 entprop.Velocity = _velocity;
1442 }
1443
1445 // remember the current and last set values 1444 // remember the current and last set values
1446 LastEntityProperties = CurrentEntityProperties; 1445 LastEntityProperties = CurrentEntityProperties;
1447 CurrentEntityProperties = entprop; 1446 CurrentEntityProperties = entprop;
1448 1447
1449 PositionSanityCheck(true);
1450
1451 OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; 1448 OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation;
1452 DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", 1449 DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}",
1453 LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); 1450 LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index 29a23c0..7ef6429 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -940,7 +940,7 @@ public sealed class BSShapeCollection : IDisposable
940 else 940 else
941 { 941 {
942 bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, 942 bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr,
943 prim.LocalID, prim.ForcePosition, prim.ForceOrientation); 943 prim.LocalID, prim.RawPosition, prim.RawOrientation);
944 DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); 944 DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
945 } 945 }
946 aBody = new BulletBody(prim.LocalID, bodyPtr); 946 aBody = new BulletBody(prim.LocalID, bodyPtr);