diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 94 |
1 files changed, 66 insertions, 28 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 159f79f..5f3f0d1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -94,7 +94,7 @@ public sealed class BSPrim : BSPhysObject | |||
94 | _size = size; | 94 | _size = size; |
95 | Scale = size; // prims are the size the user wants them to be (different for BSCharactes). | 95 | Scale = size; // prims are the size the user wants them to be (different for BSCharactes). |
96 | _orientation = rotation; | 96 | _orientation = rotation; |
97 | _buoyancy = 1f; | 97 | _buoyancy = 0f; |
98 | _velocity = OMV.Vector3.Zero; | 98 | _velocity = OMV.Vector3.Zero; |
99 | _rotationalVelocity = OMV.Vector3.Zero; | 99 | _rotationalVelocity = OMV.Vector3.Zero; |
100 | BaseShape = pbs; | 100 | BaseShape = pbs; |
@@ -408,12 +408,15 @@ public sealed class BSPrim : BSPhysObject | |||
408 | { | 408 | { |
409 | if (IsStatic) | 409 | if (IsStatic) |
410 | { | 410 | { |
411 | BulletSimAPI.SetGravity2(PhysBody.ptr, PhysicsScene.DefaultGravity); | ||
411 | Inertia = OMV.Vector3.Zero; | 412 | Inertia = OMV.Vector3.Zero; |
412 | BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia); | 413 | BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia); |
413 | BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); | 414 | BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); |
414 | } | 415 | } |
415 | else | 416 | else |
416 | { | 417 | { |
418 | OMV.Vector3 grav = ComputeGravity(); | ||
419 | |||
417 | if (inWorld) | 420 | if (inWorld) |
418 | { | 421 | { |
419 | // Changing interesting properties doesn't change proxy and collision cache | 422 | // Changing interesting properties doesn't change proxy and collision cache |
@@ -422,24 +425,41 @@ public sealed class BSPrim : BSPhysObject | |||
422 | BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); | 425 | BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); |
423 | } | 426 | } |
424 | 427 | ||
425 | float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); | 428 | // The computation of mass props requires gravity to be set on the object. |
426 | BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); | 429 | BulletSimAPI.SetGravity2(PhysBody.ptr, grav); |
427 | 430 | ||
428 | Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); | 431 | Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); |
429 | BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); | 432 | BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); |
430 | BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); | 433 | BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); |
434 | |||
431 | // center of mass is at the zero of the object | 435 | // center of mass is at the zero of the object |
432 | // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); | 436 | // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); |
433 | DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, Inertia); | 437 | DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}", LocalID, physMass, Inertia, grav, inWorld); |
434 | 438 | ||
435 | if (inWorld) | 439 | if (inWorld) |
436 | { | 440 | { |
437 | BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); | 441 | AddObjectToPhysicalWorld(); |
438 | } | 442 | } |
443 | |||
444 | // Must set gravity after it has been added to the world because, for unknown reasons, | ||
445 | // adding the object resets the object's gravity to world gravity | ||
446 | BulletSimAPI.SetGravity2(PhysBody.ptr, grav); | ||
447 | |||
439 | } | 448 | } |
440 | } | 449 | } |
441 | } | 450 | } |
442 | 451 | ||
452 | // Return what gravity should be set to this very moment | ||
453 | private OMV.Vector3 ComputeGravity() | ||
454 | { | ||
455 | OMV.Vector3 ret = PhysicsScene.DefaultGravity; | ||
456 | |||
457 | if (!IsStatic) | ||
458 | ret *= (1f - Buoyancy); | ||
459 | |||
460 | return ret; | ||
461 | } | ||
462 | |||
443 | // Is this used? | 463 | // Is this used? |
444 | public override OMV.Vector3 CenterOfMass | 464 | public override OMV.Vector3 CenterOfMass |
445 | { | 465 | { |
@@ -665,7 +685,7 @@ public sealed class BSPrim : BSPhysObject | |||
665 | _isPhysical = value; | 685 | _isPhysical = value; |
666 | PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate() | 686 | PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate() |
667 | { | 687 | { |
668 | // DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); | 688 | DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); |
669 | SetObjectDynamic(true); | 689 | SetObjectDynamic(true); |
670 | // whether phys-to-static or static-to-phys, the object is not moving. | 690 | // whether phys-to-static or static-to-phys, the object is not moving. |
671 | ZeroMotion(true); | 691 | ZeroMotion(true); |
@@ -720,22 +740,19 @@ public sealed class BSPrim : BSPhysObject | |||
720 | // Make solid or not (do things bounce off or pass through this object). | 740 | // Make solid or not (do things bounce off or pass through this object). |
721 | MakeSolid(IsSolid); | 741 | MakeSolid(IsSolid); |
722 | 742 | ||
723 | BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); | 743 | AddObjectToPhysicalWorld(); |
724 | 744 | ||
725 | // Rebuild its shape | 745 | // Rebuild its shape |
726 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); | 746 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); |
727 | 747 | ||
728 | // Collision filter can be set only when the object is in the world | ||
729 | PhysBody.ApplyCollisionMask(); | ||
730 | |||
731 | // Recompute any linkset parameters. | 748 | // Recompute any linkset parameters. |
732 | // When going from non-physical to physical, this re-enables the constraints that | 749 | // When going from non-physical to physical, this re-enables the constraints that |
733 | // had been automatically disabled when the mass was set to zero. | 750 | // had been automatically disabled when the mass was set to zero. |
734 | // For compound based linksets, this enables and disables interactions of the children. | 751 | // For compound based linksets, this enables and disables interactions of the children. |
735 | Linkset.Refresh(this); | 752 | Linkset.Refresh(this); |
736 | 753 | ||
737 | DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", | 754 | DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},cType={6},body={7},shape={8}", |
738 | LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape); | 755 | LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape); |
739 | } | 756 | } |
740 | 757 | ||
741 | // "Making dynamic" means changing to and from static. | 758 | // "Making dynamic" means changing to and from static. |
@@ -876,6 +893,28 @@ public sealed class BSPrim : BSPhysObject | |||
876 | } | 893 | } |
877 | } | 894 | } |
878 | 895 | ||
896 | // Add me to the physical world. | ||
897 | // Object MUST NOT already be in the world. | ||
898 | // This routine exists because some assorted properties get mangled by adding to the world. | ||
899 | internal void AddObjectToPhysicalWorld() | ||
900 | { | ||
901 | if (PhysBody.HasPhysicalBody) | ||
902 | { | ||
903 | BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); | ||
904 | |||
905 | // TODO: Fix this. Total kludge because adding object to world resets its gravity to default. | ||
906 | // Replace this when the new AddObjectToWorld function is complete. | ||
907 | BulletSimAPI.SetGravity2(PhysBody.ptr, ComputeGravity()); | ||
908 | |||
909 | // Collision filter can be set only when the object is in the world | ||
910 | if (!PhysBody.ApplyCollisionMask()) | ||
911 | { | ||
912 | m_log.ErrorFormat("{0} Failed setting object collision mask: id={1}", LogHeader, LocalID); | ||
913 | DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType); | ||
914 | } | ||
915 | } | ||
916 | } | ||
917 | |||
879 | // prims don't fly | 918 | // prims don't fly |
880 | public override bool Flying { | 919 | public override bool Flying { |
881 | get { return _flying; } | 920 | get { return _flying; } |
@@ -891,18 +930,6 @@ public sealed class BSPrim : BSPhysObject | |||
891 | get { return _throttleUpdates; } | 930 | get { return _throttleUpdates; } |
892 | set { _throttleUpdates = value; } | 931 | set { _throttleUpdates = value; } |
893 | } | 932 | } |
894 | public override bool IsColliding { | ||
895 | get { return (CollidingStep == PhysicsScene.SimulationStep); } | ||
896 | set { _isColliding = value; } | ||
897 | } | ||
898 | public override bool CollidingGround { | ||
899 | get { return (CollidingGroundStep == PhysicsScene.SimulationStep); } | ||
900 | set { _collidingGround = value; } | ||
901 | } | ||
902 | public override bool CollidingObj { | ||
903 | get { return _collidingObj; } | ||
904 | set { _collidingObj = value; } | ||
905 | } | ||
906 | public bool IsPhantom { | 933 | public bool IsPhantom { |
907 | get { | 934 | get { |
908 | // SceneObjectPart removes phantom objects from the physics scene | 935 | // SceneObjectPart removes phantom objects from the physics scene |
@@ -972,6 +999,7 @@ public sealed class BSPrim : BSPhysObject | |||
972 | _buoyancy = value; | 999 | _buoyancy = value; |
973 | // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | 1000 | // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); |
974 | // Force the recalculation of the various inertia,etc variables in the object | 1001 | // Force the recalculation of the various inertia,etc variables in the object |
1002 | DetailLog("{0},BSPrim.ForceBuoyancy,buoy={1},mass={2}", LocalID, _buoyancy, _mass); | ||
975 | UpdatePhysicalMassProperties(_mass, true); | 1003 | UpdatePhysicalMassProperties(_mass, true); |
976 | ActivateIfPhysical(false); | 1004 | ActivateIfPhysical(false); |
977 | } | 1005 | } |
@@ -981,12 +1009,12 @@ public sealed class BSPrim : BSPhysObject | |||
981 | public override OMV.Vector3 PIDTarget { | 1009 | public override OMV.Vector3 PIDTarget { |
982 | set { _PIDTarget = value; } | 1010 | set { _PIDTarget = value; } |
983 | } | 1011 | } |
984 | public override bool PIDActive { | ||
985 | set { _usePID = value; } | ||
986 | } | ||
987 | public override float PIDTau { | 1012 | public override float PIDTau { |
988 | set { _PIDTau = value; } | 1013 | set { _PIDTau = value; } |
989 | } | 1014 | } |
1015 | public override bool PIDActive { | ||
1016 | set { _usePID = value; } | ||
1017 | } | ||
990 | 1018 | ||
991 | // Used for llSetHoverHeight and maybe vehicle height | 1019 | // Used for llSetHoverHeight and maybe vehicle height |
992 | // Hover Height will override MoveTo target's Z | 1020 | // Hover Height will override MoveTo target's Z |
@@ -1010,7 +1038,9 @@ public sealed class BSPrim : BSPhysObject | |||
1010 | public override float APIDDamping { set { return; } } | 1038 | public override float APIDDamping { set { return; } } |
1011 | 1039 | ||
1012 | public override void AddForce(OMV.Vector3 force, bool pushforce) { | 1040 | public override void AddForce(OMV.Vector3 force, bool pushforce) { |
1013 | AddForce(force, pushforce, false); | 1041 | // Since this force is being applied in only one step, make this a force per second. |
1042 | OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep; | ||
1043 | AddForce(addForce, pushforce, false); | ||
1014 | } | 1044 | } |
1015 | // Applying a force just adds this to the total force on the object. | 1045 | // Applying a force just adds this to the total force on the object. |
1016 | // This added force will only last the next simulation tick. | 1046 | // This added force will only last the next simulation tick. |
@@ -1018,8 +1048,16 @@ public sealed class BSPrim : BSPhysObject | |||
1018 | // for an object, doesn't matter if force is a pushforce or not | 1048 | // for an object, doesn't matter if force is a pushforce or not |
1019 | if (force.IsFinite()) | 1049 | if (force.IsFinite()) |
1020 | { | 1050 | { |
1051 | float magnitude = force.Length(); | ||
1052 | if (magnitude > BSParam.MaxAddForceMagnitude) | ||
1053 | { | ||
1054 | // Force has a limit | ||
1055 | force = force / magnitude * BSParam.MaxAddForceMagnitude; | ||
1056 | } | ||
1057 | |||
1021 | OMV.Vector3 addForce = force; | 1058 | OMV.Vector3 addForce = force; |
1022 | DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); | 1059 | DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); |
1060 | |||
1023 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() | 1061 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() |
1024 | { | 1062 | { |
1025 | // Bullet adds this central force to the total force for this tick | 1063 | // Bullet adds this central force to the total force for this tick |