aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs67
1 files changed, 33 insertions, 34 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 500c84a..5d16bbf 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;
@@ -94,7 +93,7 @@ public sealed class BSPrim : BSPhysObject
94 _physicsActorType = (int)ActorTypes.Prim; 93 _physicsActorType = (int)ActorTypes.Prim;
95 _position = pos; 94 _position = pos;
96 _size = size; 95 _size = size;
97 Scale = new OMV.Vector3(1f, 1f, 1f); // the scale will be set by CreateGeom depending on object type 96 Scale = size; // the scale will be set by CreateGeom depending on object type
98 _orientation = rotation; 97 _orientation = rotation;
99 _buoyancy = 1f; 98 _buoyancy = 1f;
100 _velocity = OMV.Vector3.Zero; 99 _velocity = OMV.Vector3.Zero;
@@ -155,6 +154,8 @@ public sealed class BSPrim : BSPhysObject
155 public override OMV.Vector3 Size { 154 public override OMV.Vector3 Size {
156 get { return _size; } 155 get { return _size; }
157 set { 156 set {
157 // We presume the scale and size are the same. If scale must be changed for
158 // the physical shape, that is done when the geometry is built.
158 _size = value; 159 _size = value;
159 ForceBodyShapeRebuild(false); 160 ForceBodyShapeRebuild(false);
160 } 161 }
@@ -170,7 +171,7 @@ public sealed class BSPrim : BSPhysObject
170 } 171 }
171 } 172 }
172 // Whatever the linkset wants is what I want. 173 // Whatever the linkset wants is what I want.
173 public override ShapeData.PhysicsShapeType PreferredPhysicalShape 174 public override PhysicsShapeType PreferredPhysicalShape
174 { get { return Linkset.PreferredPhysicalShape(this); } } 175 { get { return Linkset.PreferredPhysicalShape(this); } }
175 176
176 public override bool ForceBodyShapeRebuild(bool inTaintTime) 177 public override bool ForceBodyShapeRebuild(bool inTaintTime)
@@ -274,19 +275,19 @@ public sealed class BSPrim : BSPhysObject
274 if (!Linkset.IsRoot(this)) 275 if (!Linkset.IsRoot(this))
275 _position = Linkset.Position(this); 276 _position = Linkset.Position(this);
276 277
277 // don't do the GetObjectPosition for root elements because this function is called a zillion times 278 // 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); 279 // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr);
279 return _position; 280 return _position;
280 } 281 }
281 set { 282 set {
282 // If you must push the position into the physics engine, use ForcePosition. 283 // If the position must be forced into the physics engine, use ForcePosition.
283 if (_position == value) 284 if (_position == value)
284 { 285 {
285 return; 286 return;
286 } 287 }
287 _position = value; 288 _position = value;
288 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? 289 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
289 PositionSanityCheck(); 290 PositionSanityCheck(false);
290 PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() 291 PhysicsScene.TaintedObject("BSPrim.setPosition", delegate()
291 { 292 {
292 // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 293 // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
@@ -302,7 +303,7 @@ public sealed class BSPrim : BSPhysObject
302 } 303 }
303 set { 304 set {
304 _position = value; 305 _position = value;
305 PositionSanityCheck(); 306 // PositionSanityCheck(); // Don't do this! Causes a loop and caller should know better.
306 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 307 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
307 ActivateIfPhysical(false); 308 ActivateIfPhysical(false);
308 } 309 }
@@ -311,52 +312,43 @@ public sealed class BSPrim : BSPhysObject
311 // Check that the current position is sane and, if not, modify the position to make it so. 312 // 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. 313 // Check for being below terrain and being out of bounds.
313 // Returns 'true' of the position was made sane by some action. 314 // Returns 'true' of the position was made sane by some action.
314 private bool PositionSanityCheck() 315 private bool PositionSanityCheck(bool inTaintTime)
315 { 316 {
316 bool ret = false; 317 bool ret = false;
317 318
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); 319 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position);
320 OMV.Vector3 upForce = OMV.Vector3.Zero;
322 if (Position.Z < terrainHeight) 321 if (Position.Z < terrainHeight)
323 { 322 {
324 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); 323 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
325 _position.Z = terrainHeight + 2.0f; 324 float targetHeight = terrainHeight + (Size.Z / 2f);
325 // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec.
326 upForce.Z = (terrainHeight - Position.Z) * 1f;
326 ret = true; 327 ret = true;
327 } 328 }
328 */ 329
329 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) 330 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
330 { 331 {
331 float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position); 332 float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position);
332 // TODO: a floating motor so object will bob in the water 333 // TODO: a floating motor so object will bob in the water
333 if (Position.Z < waterHeight) 334 if (Math.Abs(Position.Z - waterHeight) > 0.1f)
334 { 335 {
335 _position.Z = waterHeight; 336 // Upforce proportional to the distance away from the water. Correct the error in 1 sec.
337 upForce.Z = (waterHeight - Position.Z) * 1f;
336 ret = true; 338 ret = true;
337 } 339 }
338 } 340 }
339 341
340 // TODO: check for out of bounds 342 // TODO: check for out of bounds
341 return ret;
342 }
343 343
344 // A version of the sanity check that also makes sure a new position value is 344 // 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 345 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 { 346 {
352 // The new position value must be pushed into the physics engine but we can't 347 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 { 348 {
356 DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); 349 // Apply upforce and overcome gravity.
357 ForcePosition = _position; 350 ForceVelocity = ForceVelocity + upForce - PhysicsScene.DefaultGravity;
358 }); 351 });
359 ret = true;
360 } 352 }
361 return ret; 353 return ret;
362 } 354 }
@@ -940,6 +932,7 @@ public sealed class BSPrim : BSPhysObject
940 public override void AddForce(OMV.Vector3 force, bool pushforce) { 932 public override void AddForce(OMV.Vector3 force, bool pushforce) {
941 AddForce(force, pushforce, false); 933 AddForce(force, pushforce, false);
942 } 934 }
935 // Applying a force just adds this to the total force on the object.
943 public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { 936 public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
944 // for an object, doesn't matter if force is a pushforce or not 937 // for an object, doesn't matter if force is a pushforce or not
945 if (force.IsFinite()) 938 if (force.IsFinite())
@@ -971,6 +964,7 @@ public sealed class BSPrim : BSPhysObject
971 }); 964 });
972 } 965 }
973 966
967 // An impulse force is scaled by the mass of the object.
974 public void ApplyForceImpulse(OMV.Vector3 impulse, bool inTaintTime) 968 public void ApplyForceImpulse(OMV.Vector3 impulse, bool inTaintTime)
975 { 969 {
976 OMV.Vector3 applyImpulse = impulse; 970 OMV.Vector3 applyImpulse = impulse;
@@ -1423,7 +1417,7 @@ public sealed class BSPrim : BSPhysObject
1423 if (changed != 0) 1417 if (changed != 0)
1424 { 1418 {
1425 // Only update the position of single objects and linkset roots 1419 // Only update the position of single objects and linkset roots
1426 if (this._parentPrim == null) 1420 if (Linkset.IsRoot(this))
1427 { 1421 {
1428 base.RequestPhysicsterseUpdate(); 1422 base.RequestPhysicsterseUpdate();
1429 } 1423 }
@@ -1435,19 +1429,24 @@ public sealed class BSPrim : BSPhysObject
1435 // Updates only for individual prims and for the root object of a linkset. 1429 // Updates only for individual prims and for the root object of a linkset.
1436 if (Linkset.IsRoot(this)) 1430 if (Linkset.IsRoot(this))
1437 { 1431 {
1438 // Assign to the local variables so the normal set action does not happen 1432 // Assign directly to the local variables so the normal set action does not happen
1439 _position = entprop.Position; 1433 _position = entprop.Position;
1440 _orientation = entprop.Rotation; 1434 _orientation = entprop.Rotation;
1441 _velocity = entprop.Velocity; 1435 _velocity = entprop.Velocity;
1442 _acceleration = entprop.Acceleration; 1436 _acceleration = entprop.Acceleration;
1443 _rotationalVelocity = entprop.RotationalVelocity; 1437 _rotationalVelocity = entprop.RotationalVelocity;
1444 1438
1439 // The sanity check can change the velocity and/or position.
1440 if (PositionSanityCheck(true))
1441 {
1442 entprop.Position = _position;
1443 entprop.Velocity = _velocity;
1444 }
1445
1445 // remember the current and last set values 1446 // remember the current and last set values
1446 LastEntityProperties = CurrentEntityProperties; 1447 LastEntityProperties = CurrentEntityProperties;
1447 CurrentEntityProperties = entprop; 1448 CurrentEntityProperties = entprop;
1448 1449
1449 PositionSanityCheck(true);
1450
1451 OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; 1450 OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation;
1452 DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", 1451 DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}",
1453 LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); 1452 LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity);