diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 67 |
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); |