aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorMelanie2013-01-31 02:53:11 +0000
committerMelanie2013-01-31 02:53:11 +0000
commit9a4de546fe92105c570d6861377ec47d32b4186e (patch)
treeedfb86074fc7c78126203a2c05a38e260c0d4076 /OpenSim/Region/Physics
parentMerge branch 'avination' into careminster (diff)
parentAdd JsonTestStore to determine if a JsonStore is associated with (diff)
downloadopensim-SC_OLD-9a4de546fe92105c570d6861377ec47d32b4186e.zip
opensim-SC_OLD-9a4de546fe92105c570d6861377ec47d32b4186e.tar.gz
opensim-SC_OLD-9a4de546fe92105c570d6861377ec47d32b4186e.tar.bz2
opensim-SC_OLD-9a4de546fe92105c570d6861377ec47d32b4186e.tar.xz
Merge branch 'master' into careminster
Conflicts: OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs28
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs13
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs72
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs41
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs108
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs48
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs23
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt13
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs150
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTests.cs56
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs95
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs4
13 files changed, 557 insertions, 98 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
index f25b447..abbd22c 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
@@ -87,7 +87,7 @@ public enum FixedShapeKey : ulong
87[StructLayout(LayoutKind.Sequential)] 87[StructLayout(LayoutKind.Sequential)]
88public struct ShapeData 88public struct ShapeData
89{ 89{
90 public uint ID; 90 public UInt32 ID;
91 public BSPhysicsShapeType Type; 91 public BSPhysicsShapeType Type;
92 public Vector3 Position; 92 public Vector3 Position;
93 public Quaternion Rotation; 93 public Quaternion Rotation;
@@ -111,7 +111,7 @@ public struct ShapeData
111[StructLayout(LayoutKind.Sequential)] 111[StructLayout(LayoutKind.Sequential)]
112public struct SweepHit 112public struct SweepHit
113{ 113{
114 public uint ID; 114 public UInt32 ID;
115 public float Fraction; 115 public float Fraction;
116 public Vector3 Normal; 116 public Vector3 Normal;
117 public Vector3 Point; 117 public Vector3 Point;
@@ -119,15 +119,15 @@ public struct SweepHit
119[StructLayout(LayoutKind.Sequential)] 119[StructLayout(LayoutKind.Sequential)]
120public struct RaycastHit 120public struct RaycastHit
121{ 121{
122 public uint ID; 122 public UInt32 ID;
123 public float Fraction; 123 public float Fraction;
124 public Vector3 Normal; 124 public Vector3 Normal;
125} 125}
126[StructLayout(LayoutKind.Sequential)] 126[StructLayout(LayoutKind.Sequential)]
127public struct CollisionDesc 127public struct CollisionDesc
128{ 128{
129 public uint aID; 129 public UInt32 aID;
130 public uint bID; 130 public UInt32 bID;
131 public Vector3 point; 131 public Vector3 point;
132 public Vector3 normal; 132 public Vector3 normal;
133 public float penetration; 133 public float penetration;
@@ -135,7 +135,7 @@ public struct CollisionDesc
135[StructLayout(LayoutKind.Sequential)] 135[StructLayout(LayoutKind.Sequential)]
136public struct EntityProperties 136public struct EntityProperties
137{ 137{
138 public uint ID; 138 public UInt32 ID;
139 public Vector3 Position; 139 public Vector3 Position;
140 public Quaternion Rotation; 140 public Quaternion Rotation;
141 public Vector3 Velocity; 141 public Vector3 Velocity;
@@ -325,7 +325,7 @@ public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParamet
325public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, 325public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep,
326 out int updatedEntityCount, out int collidersCount); 326 out int updatedEntityCount, out int collidersCount);
327 327
328public abstract bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); 328public abstract bool UpdateParameter(BulletWorld world, UInt32 localID, String parm, float value);
329 329
330public abstract void Shutdown(BulletWorld sim); 330public abstract void Shutdown(BulletWorld sim);
331 331
@@ -366,24 +366,24 @@ public abstract void UpdateChildTransform(BulletShape pShape, int childIndex, Ve
366 366
367public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); 367public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape);
368 368
369public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id); 369public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, UInt32 id);
370 370
371public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape); 371public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape);
372 372
373public abstract CollisionObjectTypes GetBodyType(BulletBody obj); 373public abstract CollisionObjectTypes GetBodyType(BulletBody obj);
374 374
375public abstract BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); 375public abstract BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
376 376
377public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, uint id, Vector3 pos, Quaternion rot); 377public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
378 378
379public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); 379public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
380 380
381public abstract void DestroyObject(BulletWorld sim, BulletBody obj); 381public abstract void DestroyObject(BulletWorld sim, BulletBody obj);
382 382
383// ===================================================================================== 383// =====================================================================================
384public abstract BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin); 384public abstract BulletShape CreateGroundPlaneShape(UInt32 id, float height, float collisionMargin);
385 385
386public abstract BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, 386public abstract BulletShape CreateTerrainShape(UInt32 id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
387 float scaleFactor, float collisionMargin); 387 float scaleFactor, float collisionMargin);
388 388
389// ===================================================================================== 389// =====================================================================================
@@ -629,7 +629,7 @@ public abstract BulletConstraint GetConstraintRef(BulletBody obj, int index);
629 629
630public abstract int GetNumConstraintRefs(BulletBody obj); 630public abstract int GetNumConstraintRefs(BulletBody obj);
631 631
632public abstract bool SetCollisionGroupMask(BulletBody body, uint filter, uint mask); 632public abstract bool SetCollisionGroupMask(BulletBody body, UInt32 filter, UInt32 mask);
633 633
634// ===================================================================================== 634// =====================================================================================
635// btCollisionShape entries 635// btCollisionShape entries
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 7603254..3884a5d 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -56,7 +56,6 @@ public sealed class BSCharacter : BSPhysObject
56 private int _physicsActorType; 56 private int _physicsActorType;
57 private bool _isPhysical; 57 private bool _isPhysical;
58 private bool _flying; 58 private bool _flying;
59 private bool _wasWalking; // 'true' if the avatar was walking/moving last frame
60 private bool _setAlwaysRun; 59 private bool _setAlwaysRun;
61 private bool _throttleUpdates; 60 private bool _throttleUpdates;
62 private bool _floatOnWater; 61 private bool _floatOnWater;
@@ -84,7 +83,6 @@ public sealed class BSCharacter : BSPhysObject
84 _position = pos; 83 _position = pos;
85 84
86 _flying = isFlying; 85 _flying = isFlying;
87 _wasWalking = true; // causes first step to initialize standing
88 _orientation = OMV.Quaternion.Identity; 86 _orientation = OMV.Quaternion.Identity;
89 _velocity = OMV.Vector3.Zero; 87 _velocity = OMV.Vector3.Zero;
90 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 88 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
@@ -220,7 +218,13 @@ public sealed class BSCharacter : BSPhysObject
220 { 218 {
221 // The avatar shouldn't be moving 219 // The avatar shouldn't be moving
222 _velocityMotor.Zero(); 220 _velocityMotor.Zero();
223 ZeroMotion(true /* inTaintTime */); 221
222 // If we are colliding with a stationary object, presume we're standing and don't move around
223 if (!ColliderIsMoving)
224 {
225 DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID);
226 ZeroMotion(true /* inTaintTime */);
227 }
224 228
225 // Standing has more friction on the ground 229 // Standing has more friction on the ground
226 if (_currentFriction != BSParam.AvatarStandingFriction) 230 if (_currentFriction != BSParam.AvatarStandingFriction)
@@ -229,8 +233,6 @@ public sealed class BSCharacter : BSPhysObject
229 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); 233 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
230 } 234 }
231 DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue); 235 DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue);
232
233 _wasWalking = false;
234 } 236 }
235 else 237 else
236 { 238 {
@@ -260,7 +262,6 @@ public sealed class BSCharacter : BSPhysObject
260 262
261 DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); 263 DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
262 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); 264 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce);
263 _wasWalking = true;
264 } 265 }
265 }); 266 });
266 } 267 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 7ad7c89..05ab180 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -125,9 +125,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
125 static readonly float PIOverTwo = ((float)Math.PI) / 2f; 125 static readonly float PIOverTwo = ((float)Math.PI) / 2f;
126 126
127 // For debugging, flags to turn on and off individual corrections. 127 // For debugging, flags to turn on and off individual corrections.
128 private bool enableAngularVerticalAttraction; 128 public bool enableAngularVerticalAttraction;
129 private bool enableAngularDeflection; 129 public bool enableAngularDeflection;
130 private bool enableAngularBanking; 130 public bool enableAngularBanking;
131 131
132 public BSDynamics(BSScene myScene, BSPrim myPrim) 132 public BSDynamics(BSScene myScene, BSPrim myPrim)
133 { 133 {
@@ -146,7 +146,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
146 enableAngularBanking = false; 146 enableAngularBanking = false;
147 if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse) 147 if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse)
148 { 148 {
149 enableAngularVerticalAttraction = false; 149 enableAngularVerticalAttraction = true;
150 enableAngularDeflection = false; 150 enableAngularDeflection = false;
151 enableAngularBanking = false; 151 enableAngularBanking = false;
152 } 152 }
@@ -165,7 +165,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
165 } 165 }
166 166
167 #region Vehicle parameter setting 167 #region Vehicle parameter setting
168 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) 168 public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
169 { 169 {
170 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); 170 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
171 switch (pParam) 171 switch (pParam)
@@ -591,14 +591,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
591 m_vehicleMass = Prim.Linkset.LinksetMass; 591 m_vehicleMass = Prim.Linkset.LinksetMass;
592 592
593 // Friction affects are handled by this vehicle code 593 // Friction affects are handled by this vehicle code
594 float friction = 0f; 594 PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction);
595 PhysicsScene.PE.SetFriction(Prim.PhysBody, friction); 595 PhysicsScene.PE.SetRestitution(Prim.PhysBody, BSParam.VehicleRestitution);
596 596
597 // Moderate angular movement introduced by Bullet. 597 // Moderate angular movement introduced by Bullet.
598 // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. 598 // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
599 // Maybe compute linear and angular factor and damping from params. 599 // Maybe compute linear and angular factor and damping from params.
600 float angularDamping = BSParam.VehicleAngularDamping; 600 PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, BSParam.VehicleAngularDamping);
601 PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, angularDamping); 601 PhysicsScene.PE.SetLinearFactor(Prim.PhysBody, BSParam.VehicleLinearFactorV);
602 PhysicsScene.PE.SetAngularFactorV(Prim.PhysBody, BSParam.VehicleAngularFactorV);
602 603
603 // Vehicles report collision events so we know when it's on the ground 604 // Vehicles report collision events so we know when it's on the ground
604 PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); 605 PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
@@ -613,8 +614,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
613 // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. 614 // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same.
614 PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero); 615 PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero);
615 616
616 VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}", 617 VDetailLog("{0},BSDynamics.Refresh,mass={1},inert={2},grav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}",
617 Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, m_VehicleGravity); 618 Prim.LocalID, m_vehicleMass, Prim.Inertia, m_VehicleGravity,
619 BSParam.VehicleAngularDamping, BSParam.VehicleFriction, BSParam.VehicleRestitution,
620 BSParam.VehicleLinearFactor, BSParam.VehicleAngularFactor
621 );
618 } 622 }
619 else 623 else
620 { 624 {
@@ -673,13 +677,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
673 private const int m_knownChangedWaterLevel = 1 << 9; 677 private const int m_knownChangedWaterLevel = 1 << 9;
674 private const int m_knownChangedForwardVelocity = 1 <<10; 678 private const int m_knownChangedForwardVelocity = 1 <<10;
675 679
676 private void ForgetKnownVehicleProperties() 680 public void ForgetKnownVehicleProperties()
677 { 681 {
678 m_knownHas = 0; 682 m_knownHas = 0;
679 m_knownChanged = 0; 683 m_knownChanged = 0;
680 } 684 }
681 // Push all the changed values back into the physics engine 685 // Push all the changed values back into the physics engine
682 private void PushKnownChanged() 686 public void PushKnownChanged()
683 { 687 {
684 if (m_knownChanged != 0) 688 if (m_knownChanged != 0)
685 { 689 {
@@ -799,7 +803,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
799 m_knownVelocity = Prim.ForceVelocity; 803 m_knownVelocity = Prim.ForceVelocity;
800 m_knownHas |= m_knownChangedVelocity; 804 m_knownHas |= m_knownChangedVelocity;
801 } 805 }
802 return (Vector3)m_knownVelocity; 806 return m_knownVelocity;
803 } 807 }
804 set 808 set
805 { 809 {
@@ -898,9 +902,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
898 { 902 {
899 if (!IsActive) return; 903 if (!IsActive) return;
900 904
901 if (PhysicsScene.VehiclePhysicalLoggingEnabled)
902 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
903
904 ForgetKnownVehicleProperties(); 905 ForgetKnownVehicleProperties();
905 906
906 MoveLinear(pTimestep); 907 MoveLinear(pTimestep);
@@ -922,6 +923,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
922 Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity); 923 Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity);
923 } 924 }
924 925
926 // Called after the simulation step
927 internal void PostStep(float pTimestep)
928 {
929 if (!IsActive) return;
930
931 if (PhysicsScene.VehiclePhysicalLoggingEnabled)
932 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
933 }
934
925 // Apply the effect of the linear motor and other linear motions (like hover and float). 935 // Apply the effect of the linear motor and other linear motions (like hover and float).
926 private void MoveLinear(float pTimestep) 936 private void MoveLinear(float pTimestep)
927 { 937 {
@@ -953,10 +963,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
953 // ================================================================== 963 // ==================================================================
954 // Clamp high or low velocities 964 // Clamp high or low velocities
955 float newVelocityLengthSq = VehicleVelocity.LengthSquared(); 965 float newVelocityLengthSq = VehicleVelocity.LengthSquared();
956 if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocity) 966 if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocitySq)
957 { 967 {
968 Vector3 origVelW = VehicleVelocity; // DEBUG DEBUG
958 VehicleVelocity /= VehicleVelocity.Length(); 969 VehicleVelocity /= VehicleVelocity.Length();
959 VehicleVelocity *= BSParam.VehicleMaxLinearVelocity; 970 VehicleVelocity *= BSParam.VehicleMaxLinearVelocity;
971 VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}",
972 Prim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySq, VehicleVelocity);
960 } 973 }
961 else if (newVelocityLengthSq < 0.001f) 974 else if (newVelocityLengthSq < 0.001f)
962 VehicleVelocity = Vector3.Zero; 975 VehicleVelocity = Vector3.Zero;
@@ -968,8 +981,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
968 public void ComputeLinearVelocity(float pTimestep) 981 public void ComputeLinearVelocity(float pTimestep)
969 { 982 {
970 // Step the motor from the current value. Get the correction needed this step. 983 // Step the motor from the current value. Get the correction needed this step.
971 Vector3 currentVel = VehicleVelocity * Quaternion.Inverse(VehicleOrientation); 984 Vector3 origVelW = VehicleVelocity; // DEBUG
972 Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVel); 985 Vector3 currentVelV = VehicleVelocity * Quaternion.Inverse(VehicleOrientation);
986 Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV);
973 987
974 // Motor is vehicle coordinates. Rotate it to world coordinates 988 // Motor is vehicle coordinates. Rotate it to world coordinates
975 Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation; 989 Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation;
@@ -984,8 +998,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
984 // Add this correction to the velocity to make it faster/slower. 998 // Add this correction to the velocity to make it faster/slower.
985 VehicleVelocity += linearMotorVelocityW; 999 VehicleVelocity += linearMotorVelocityW;
986 1000
987 VDetailLog("{0}, MoveLinear,velocity,vehVel={1},correction={2},force={3}", 1001 VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5}",
988 Prim.LocalID, VehicleVelocity, linearMotorCorrectionV, linearMotorVelocityW); 1002 Prim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, linearMotorVelocityW, VehicleVelocity);
989 } 1003 }
990 1004
991 public void ComputeLinearTerrainHeightCorrection(float pTimestep) 1005 public void ComputeLinearTerrainHeightCorrection(float pTimestep)
@@ -1185,12 +1199,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1185 1199
1186 // Hack to reduce downward force if the vehicle is probably sitting on the ground 1200 // Hack to reduce downward force if the vehicle is probably sitting on the ground
1187 if (Prim.IsColliding && IsGroundVehicle) 1201 if (Prim.IsColliding && IsGroundVehicle)
1188 appliedGravity *= 0.2f; 1202 appliedGravity *= BSParam.VehicleGroundGravityFudge;
1189 1203
1190 VehicleAddForce(appliedGravity); 1204 VehicleAddForce(appliedGravity);
1191 1205
1192 VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}", 1206 VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},appliedForce={3}",
1193 Prim.LocalID, m_VehicleGravity, appliedGravity); 1207 Prim.LocalID, m_VehicleGravity, Prim.IsColliding, appliedGravity);
1194 } 1208 }
1195 1209
1196 // ======================================================================= 1210 // =======================================================================
@@ -1292,6 +1306,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1292 if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1306 if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1293 { 1307 {
1294 Vector3 vertContributionV = Vector3.Zero; 1308 Vector3 vertContributionV = Vector3.Zero;
1309 Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG
1295 1310
1296 // Take a vector pointing up and convert it from world to vehicle relative coords. 1311 // Take a vector pointing up and convert it from world to vehicle relative coords.
1297 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; 1312 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
@@ -1319,13 +1334,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1319 1334
1320 // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. 1335 // 'vertContrbution' is now the necessary angular correction to correct tilt in one second.
1321 // Correction happens over a number of seconds. 1336 // Correction happens over a number of seconds.
1322 Vector3 unscaledContrib = vertContributionV; // DEBUG DEBUG 1337 Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG
1323 vertContributionV /= m_verticalAttractionTimescale; 1338 vertContributionV /= m_verticalAttractionTimescale;
1324 1339
1325 VehicleRotationalVelocity += vertContributionV * VehicleOrientation; 1340 VehicleRotationalVelocity += vertContributionV * VehicleOrientation;
1326 1341
1327 VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}", 1342 VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}",
1328 Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV); 1343 Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV,
1344 m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV);
1329 } 1345 }
1330 } 1346 }
1331 1347
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 2c8dd23..54dc458 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -232,7 +232,7 @@ public sealed class BSLinksetCompound : BSLinkset
232 newLsi.OffsetFromCenterOfMass, 232 newLsi.OffsetFromCenterOfMass,
233 newLsi.OffsetRot, 233 newLsi.OffsetRot,
234 true /* shouldRecalculateLocalAabb */); 234 true /* shouldRecalculateLocalAabb */);
235 DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1}newLsi={2}", 235 DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}",
236 updated.LocalID, whichUpdated, newLsi); 236 updated.LocalID, whichUpdated, newLsi);
237 updated.LinksetInfo = newLsi; 237 updated.LinksetInfo = newLsi;
238 updatedChild = true; 238 updatedChild = true;
@@ -377,7 +377,7 @@ public sealed class BSLinksetCompound : BSLinkset
377 // Constraint linksets are rebuilt every time. 377 // Constraint linksets are rebuilt every time.
378 // Note that this works for rebuilding just the root after a linkset is taken apart. 378 // Note that this works for rebuilding just the root after a linkset is taken apart.
379 // Called at taint time!! 379 // Called at taint time!!
380 private bool disableCOM = false; // disable until we get this debugged 380 private bool disableCOM = true; // disable until we get this debugged
381 private void RecomputeLinksetCompound() 381 private void RecomputeLinksetCompound()
382 { 382 {
383 try 383 try
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index 06186b0..8c098b2 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -82,9 +82,19 @@ public static class BSParam
82 public static float AvatarStepApproachFactor { get; private set; } 82 public static float AvatarStepApproachFactor { get; private set; }
83 public static float AvatarStepForceFactor { get; private set; } 83 public static float AvatarStepForceFactor { get; private set; }
84 84
85 // Vehicle parameters
85 public static float VehicleMaxLinearVelocity { get; private set; } 86 public static float VehicleMaxLinearVelocity { get; private set; }
87 public static float VehicleMaxLinearVelocitySq { get; private set; }
86 public static float VehicleMaxAngularVelocity { get; private set; } 88 public static float VehicleMaxAngularVelocity { get; private set; }
89 public static float VehicleMaxAngularVelocitySq { get; private set; }
87 public static float VehicleAngularDamping { get; private set; } 90 public static float VehicleAngularDamping { get; private set; }
91 public static float VehicleFriction { get; private set; }
92 public static float VehicleRestitution { get; private set; }
93 public static float VehicleLinearFactor { get; private set; }
94 public static Vector3 VehicleLinearFactorV { get; private set; }
95 public static float VehicleAngularFactor { get; private set; }
96 public static Vector3 VehicleAngularFactorV { get; private set; }
97 public static float VehicleGroundGravityFudge { get; private set; }
88 public static float VehicleDebuggingEnabled { get; private set; } 98 public static float VehicleDebuggingEnabled { get; private set; }
89 99
90 public static float LinksetImplementation { get; private set; } 100 public static float LinksetImplementation { get; private set; }
@@ -373,7 +383,7 @@ public static class BSParam
373 (s) => { return TerrainRestitution; }, 383 (s) => { return TerrainRestitution; },
374 (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ), 384 (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ),
375 new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , 385 new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" ,
376 0.04f, 386 0.08f,
377 (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); }, 387 (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); },
378 (s) => { return TerrainCollisionMargin; }, 388 (s) => { return TerrainCollisionMargin; },
379 (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ), 389 (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ),
@@ -443,17 +453,42 @@ public static class BSParam
443 1000.0f, 453 1000.0f,
444 (s,cf,p,v) => { VehicleMaxLinearVelocity = cf.GetFloat(p, v); }, 454 (s,cf,p,v) => { VehicleMaxLinearVelocity = cf.GetFloat(p, v); },
445 (s) => { return (float)VehicleMaxLinearVelocity; }, 455 (s) => { return (float)VehicleMaxLinearVelocity; },
446 (s,p,l,v) => { VehicleMaxLinearVelocity = v; } ), 456 (s,p,l,v) => { VehicleMaxLinearVelocity = v; VehicleMaxLinearVelocitySq = v * v; } ),
447 new ParameterDefn("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle", 457 new ParameterDefn("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle",
448 12.0f, 458 12.0f,
449 (s,cf,p,v) => { VehicleMaxAngularVelocity = cf.GetFloat(p, v); }, 459 (s,cf,p,v) => { VehicleMaxAngularVelocity = cf.GetFloat(p, v); },
450 (s) => { return (float)VehicleMaxAngularVelocity; }, 460 (s) => { return (float)VehicleMaxAngularVelocity; },
451 (s,p,l,v) => { VehicleMaxAngularVelocity = v; } ), 461 (s,p,l,v) => { VehicleMaxAngularVelocity = v; VehicleMaxAngularVelocitySq = v * v; } ),
452 new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", 462 new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)",
453 0.0f, 463 0.0f,
454 (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, 464 (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); },
455 (s) => { return VehicleAngularDamping; }, 465 (s) => { return VehicleAngularDamping; },
456 (s,p,l,v) => { VehicleAngularDamping = v; } ), 466 (s,p,l,v) => { VehicleAngularDamping = v; } ),
467 new ParameterDefn("VehicleLinearFactor", "Fraction of physical linear changes applied to vehicle (0.0 - 1.0)",
468 1.0f,
469 (s,cf,p,v) => { VehicleLinearFactor = cf.GetFloat(p, v); },
470 (s) => { return VehicleLinearFactor; },
471 (s,p,l,v) => { VehicleLinearFactor = v; VehicleLinearFactorV = new Vector3(v, v, v); } ),
472 new ParameterDefn("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (0.0 - 1.0)",
473 1.0f,
474 (s,cf,p,v) => { VehicleAngularFactor = cf.GetFloat(p, v); },
475 (s) => { return VehicleAngularFactor; },
476 (s,p,l,v) => { VehicleAngularFactor = v; VehicleAngularFactorV = new Vector3(v, v, v); } ),
477 new ParameterDefn("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)",
478 0.0f,
479 (s,cf,p,v) => { VehicleFriction = cf.GetFloat(p, v); },
480 (s) => { return VehicleFriction; },
481 (s,p,l,v) => { VehicleFriction = v; } ),
482 new ParameterDefn("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)",
483 0.0f,
484 (s,cf,p,v) => { VehicleRestitution = cf.GetFloat(p, v); },
485 (s) => { return VehicleRestitution; },
486 (s,p,l,v) => { VehicleRestitution = v; } ),
487 new ParameterDefn("VehicleGroundGravityFudge", "Factor to multiple gravity if a ground vehicle is probably on the ground (0.0 - 1.0)",
488 0.2f,
489 (s,cf,p,v) => { VehicleGroundGravityFudge = cf.GetFloat(p, v); },
490 (s) => { return VehicleGroundGravityFudge; },
491 (s,p,l,v) => { VehicleGroundGravityFudge = v; } ),
457 new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging", 492 new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging",
458 ConfigurationParameters.numericFalse, 493 ConfigurationParameters.numericFalse,
459 (s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, 494 (s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 027c786..a113530 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -95,12 +95,16 @@ public abstract class BSPhysObject : PhysicsActor
95 SubscribedEventsMs = 0; 95 SubscribedEventsMs = 0;
96 CollidingStep = 0; 96 CollidingStep = 0;
97 CollidingGroundStep = 0; 97 CollidingGroundStep = 0;
98 CollisionAccumulation = 0;
99 ColliderIsMoving = false;
100 CollisionScore = 0;
98 } 101 }
99 102
100 // Tell the object to clean up. 103 // Tell the object to clean up.
101 public virtual void Destroy() 104 public virtual void Destroy()
102 { 105 {
103 UnRegisterAllPreStepActions(); 106 UnRegisterAllPreStepActions();
107 UnRegisterAllPostStepActions();
104 } 108 }
105 109
106 public BSScene PhysicsScene { get; protected set; } 110 public BSScene PhysicsScene { get; protected set; }
@@ -174,13 +178,14 @@ public abstract class BSPhysObject : PhysicsActor
174 public abstract OMV.Vector3 RawPosition { get; set; } 178 public abstract OMV.Vector3 RawPosition { get; set; }
175 public abstract OMV.Vector3 ForcePosition { get; set; } 179 public abstract OMV.Vector3 ForcePosition { get; set; }
176 180
177 // Position is what the simulator thinks the positions of the prim is. 181 // 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is.
178 // Because Bullet needs the zero coordinate to be the center of mass of the linkset, 182 // Because Bullet needs the zero coordinate to be the center of mass of the linkset,
179 // sometimes it is necessary to displace the position the physics engine thinks 183 // sometimes it is necessary to displace the position the physics engine thinks
180 // the position is. PositionDisplacement must be added and removed from the 184 // the position is. PositionDisplacement must be added and removed from the
181 // position as the simulator position is stored and fetched from the physics 185 // position as the simulator position is stored and fetched from the physics
182 // engine. 186 // engine. Similar to OrientationDisplacement.
183 public virtual OMV.Vector3 PositionDisplacement { get; set; } 187 public virtual OMV.Vector3 PositionDisplacement { get; set; }
188 public virtual OMV.Quaternion OrientationDisplacement { get; set; }
184 189
185 public abstract OMV.Quaternion RawOrientation { get; set; } 190 public abstract OMV.Quaternion RawOrientation { get; set; }
186 public abstract OMV.Quaternion ForceOrientation { get; set; } 191 public abstract OMV.Quaternion ForceOrientation { get; set; }
@@ -237,6 +242,12 @@ public abstract class BSPhysObject : PhysicsActor
237 protected long CollidingObjectStep { get; set; } 242 protected long CollidingObjectStep { get; set; }
238 // The collision flags we think are set in Bullet 243 // The collision flags we think are set in Bullet
239 protected CollisionFlags CurrentCollisionFlags { get; set; } 244 protected CollisionFlags CurrentCollisionFlags { get; set; }
245 // On a collision, check the collider and remember if the last collider was moving
246 // Used to modify the standing of avatars (avatars on stationary things stand still)
247 protected bool ColliderIsMoving;
248
249 // Count of collisions for this object
250 protected long CollisionAccumulation { get; set; }
240 251
241 public override bool IsColliding { 252 public override bool IsColliding {
242 get { return (CollidingStep == PhysicsScene.SimulationStep); } 253 get { return (CollidingStep == PhysicsScene.SimulationStep); }
@@ -299,7 +310,12 @@ public abstract class BSPhysObject : PhysicsActor
299 return ret; 310 return ret;
300 } 311 }
301 312
302 // if someone has subscribed for collision events.... 313 CollisionAccumulation++;
314
315 // For movement tests, remember if we are colliding with an object that is moving.
316 ColliderIsMoving = collidee != null ? collidee.RawVelocity != OMV.Vector3.Zero : false;
317
318 // If someone has subscribed for collision events log the collision so it will be reported up
303 if (SubscribedEvents()) { 319 if (SubscribedEvents()) {
304 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 320 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
305 DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}", 321 DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}",
@@ -385,6 +401,17 @@ public abstract class BSPhysObject : PhysicsActor
385 public override bool SubscribedEvents() { 401 public override bool SubscribedEvents() {
386 return (SubscribedEventsMs > 0); 402 return (SubscribedEventsMs > 0);
387 } 403 }
404 // Because 'CollisionScore' is called many times while sorting, it should not be recomputed
405 // each time called. So this is built to be light weight for each collision and to do
406 // all the processing when the user asks for the info.
407 public void ComputeCollisionScore()
408 {
409 // Scale the collision count by the time since the last collision.
410 // The "+1" prevents dividing by zero.
411 long timeAgo = PhysicsScene.SimulationStep - CollidingStep + 1;
412 CollisionScore = CollisionAccumulation / timeAgo;
413 }
414 public override float CollisionScore { get; set; }
388 415
389 #endregion // Collisions 416 #endregion // Collisions
390 417
@@ -393,52 +420,103 @@ public abstract class BSPhysObject : PhysicsActor
393 // These actions are optional so, rather than scanning all the physical objects and asking them 420 // These actions are optional so, rather than scanning all the physical objects and asking them
394 // if they have anything to do, a physical object registers for an event call before the step is performed. 421 // if they have anything to do, a physical object registers for an event call before the step is performed.
395 // This bookkeeping makes it easy to add, remove and clean up after all these registrations. 422 // This bookkeeping makes it easy to add, remove and clean up after all these registrations.
396 private Dictionary<string, BSScene.PreStepAction> RegisteredActions = new Dictionary<string, BSScene.PreStepAction>(); 423 private Dictionary<string, BSScene.PreStepAction> RegisteredPrestepActions = new Dictionary<string, BSScene.PreStepAction>();
424 private Dictionary<string, BSScene.PostStepAction> RegisteredPoststepActions = new Dictionary<string, BSScene.PostStepAction>();
397 protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn) 425 protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn)
398 { 426 {
399 string identifier = op + "-" + id.ToString(); 427 string identifier = op + "-" + id.ToString();
400 428
401 lock (RegisteredActions) 429 lock (RegisteredPrestepActions)
402 { 430 {
403 // Clean out any existing action 431 // Clean out any existing action
404 UnRegisterPreStepAction(op, id); 432 UnRegisterPreStepAction(op, id);
405 433
406 RegisteredActions[identifier] = actn; 434 RegisteredPrestepActions[identifier] = actn;
435
436 PhysicsScene.BeforeStep += actn;
407 } 437 }
408 PhysicsScene.BeforeStep += actn;
409 DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); 438 DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
410 } 439 }
411 440
412 // Unregister a pre step action. Safe to call if the action has not been registered. 441 // Unregister a pre step action. Safe to call if the action has not been registered.
413 protected void UnRegisterPreStepAction(string op, uint id) 442 // Returns 'true' if an action was actually removed
443 protected bool UnRegisterPreStepAction(string op, uint id)
414 { 444 {
415 string identifier = op + "-" + id.ToString(); 445 string identifier = op + "-" + id.ToString();
416 bool removed = false; 446 bool removed = false;
417 lock (RegisteredActions) 447 lock (RegisteredPrestepActions)
418 { 448 {
419 if (RegisteredActions.ContainsKey(identifier)) 449 if (RegisteredPrestepActions.ContainsKey(identifier))
420 { 450 {
421 PhysicsScene.BeforeStep -= RegisteredActions[identifier]; 451 PhysicsScene.BeforeStep -= RegisteredPrestepActions[identifier];
422 RegisteredActions.Remove(identifier); 452 RegisteredPrestepActions.Remove(identifier);
423 removed = true; 453 removed = true;
424 } 454 }
425 } 455 }
426 DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed); 456 DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed);
457 return removed;
427 } 458 }
428 459
429 protected void UnRegisterAllPreStepActions() 460 protected void UnRegisterAllPreStepActions()
430 { 461 {
431 lock (RegisteredActions) 462 lock (RegisteredPrestepActions)
432 { 463 {
433 foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredActions) 464 foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredPrestepActions)
434 { 465 {
435 PhysicsScene.BeforeStep -= kvp.Value; 466 PhysicsScene.BeforeStep -= kvp.Value;
436 } 467 }
437 RegisteredActions.Clear(); 468 RegisteredPrestepActions.Clear();
438 } 469 }
439 DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID); 470 DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID);
440 } 471 }
472
473 protected void RegisterPostStepAction(string op, uint id, BSScene.PostStepAction actn)
474 {
475 string identifier = op + "-" + id.ToString();
441 476
477 lock (RegisteredPoststepActions)
478 {
479 // Clean out any existing action
480 UnRegisterPostStepAction(op, id);
481
482 RegisteredPoststepActions[identifier] = actn;
483
484 PhysicsScene.AfterStep += actn;
485 }
486 DetailLog("{0},BSPhysObject.RegisterPostStepAction,id={1}", LocalID, identifier);
487 }
488
489 // Unregister a pre step action. Safe to call if the action has not been registered.
490 // Returns 'true' if an action was actually removed.
491 protected bool UnRegisterPostStepAction(string op, uint id)
492 {
493 string identifier = op + "-" + id.ToString();
494 bool removed = false;
495 lock (RegisteredPoststepActions)
496 {
497 if (RegisteredPoststepActions.ContainsKey(identifier))
498 {
499 PhysicsScene.AfterStep -= RegisteredPoststepActions[identifier];
500 RegisteredPoststepActions.Remove(identifier);
501 removed = true;
502 }
503 }
504 DetailLog("{0},BSPhysObject.UnRegisterPostStepAction,id={1},removed={2}", LocalID, identifier, removed);
505 return removed;
506 }
507
508 protected void UnRegisterAllPostStepActions()
509 {
510 lock (RegisteredPoststepActions)
511 {
512 foreach (KeyValuePair<string, BSScene.PostStepAction> kvp in RegisteredPoststepActions)
513 {
514 PhysicsScene.AfterStep -= kvp.Value;
515 }
516 RegisteredPoststepActions.Clear();
517 }
518 DetailLog("{0},BSPhysObject.UnRegisterAllPostStepActions,", LocalID);
519 }
442 520
443 #endregion // Per Simulation Step actions 521 #endregion // Per Simulation Step actions
444 522
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 8b00a33..b5dd131 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -59,7 +59,6 @@ public sealed class BSPrim : BSPhysObject
59 private OMV.Vector3 _force; 59 private OMV.Vector3 _force;
60 private OMV.Vector3 _velocity; 60 private OMV.Vector3 _velocity;
61 private OMV.Vector3 _torque; 61 private OMV.Vector3 _torque;
62 private float _collisionScore;
63 private OMV.Vector3 _acceleration; 62 private OMV.Vector3 _acceleration;
64 private OMV.Quaternion _orientation; 63 private OMV.Quaternion _orientation;
65 private int _physicsActorType; 64 private int _physicsActorType;
@@ -74,7 +73,7 @@ public sealed class BSPrim : BSPhysObject
74 private bool _kinematic; 73 private bool _kinematic;
75 private float _buoyancy; 74 private float _buoyancy;
76 75
77 private BSDynamics _vehicle; 76 public BSDynamics VehicleController { get; private set; }
78 77
79 private BSVMotor _targetMotor; 78 private BSVMotor _targetMotor;
80 private OMV.Vector3 _PIDTarget; 79 private OMV.Vector3 _PIDTarget;
@@ -108,7 +107,7 @@ public sealed class BSPrim : BSPhysObject
108 _friction = PhysicsScene.Params.defaultFriction; 107 _friction = PhysicsScene.Params.defaultFriction;
109 _restitution = PhysicsScene.Params.defaultRestitution; 108 _restitution = PhysicsScene.Params.defaultRestitution;
110 109
111 _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness 110 VehicleController = new BSDynamics(PhysicsScene, this); // add vehicleness
112 111
113 _mass = CalculateMass(); 112 _mass = CalculateMass();
114 113
@@ -345,6 +344,10 @@ public sealed class BSPrim : BSPhysObject
345 { 344 {
346 bool ret = false; 345 bool ret = false;
347 346
347 // We don't care where non-physical items are placed
348 if (!IsPhysicallyActive)
349 return ret;
350
348 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) 351 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
349 { 352 {
350 // The physical object is out of the known/simulated area. 353 // The physical object is out of the known/simulated area.
@@ -513,7 +516,7 @@ public sealed class BSPrim : BSPhysObject
513 516
514 public override int VehicleType { 517 public override int VehicleType {
515 get { 518 get {
516 return (int)_vehicle.Type; // if we are a vehicle, return that type 519 return (int)VehicleController.Type; // if we are a vehicle, return that type
517 } 520 }
518 set { 521 set {
519 Vehicle type = (Vehicle)value; 522 Vehicle type = (Vehicle)value;
@@ -522,14 +525,20 @@ public sealed class BSPrim : BSPhysObject
522 { 525 {
523 // Done at taint time so we're sure the physics engine is not using the variables 526 // Done at taint time so we're sure the physics engine is not using the variables
524 // Vehicle code changes the parameters for this vehicle type. 527 // Vehicle code changes the parameters for this vehicle type.
525 _vehicle.ProcessTypeChange(type); 528 VehicleController.ProcessTypeChange(type);
526 ActivateIfPhysical(false); 529 ActivateIfPhysical(false);
527 530
528 // If an active vehicle, register the vehicle code to be called before each step 531 // If an active vehicle, register the vehicle code to be called before each step
529 if (_vehicle.Type == Vehicle.TYPE_NONE) 532 if (VehicleController.Type == Vehicle.TYPE_NONE)
533 {
530 UnRegisterPreStepAction("BSPrim.Vehicle", LocalID); 534 UnRegisterPreStepAction("BSPrim.Vehicle", LocalID);
535 PhysicsScene.AfterStep -= VehicleController.PostStep;
536 }
531 else 537 else
532 RegisterPreStepAction("BSPrim.Vehicle", LocalID, _vehicle.Step); 538 {
539 RegisterPreStepAction("BSPrim.Vehicle", LocalID, VehicleController.Step);
540 PhysicsScene.AfterStep += VehicleController.PostStep;
541 }
533 }); 542 });
534 } 543 }
535 } 544 }
@@ -537,7 +546,7 @@ public sealed class BSPrim : BSPhysObject
537 { 546 {
538 PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate() 547 PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
539 { 548 {
540 _vehicle.ProcessFloatVehicleParam((Vehicle)param, value); 549 VehicleController.ProcessFloatVehicleParam((Vehicle)param, value);
541 ActivateIfPhysical(false); 550 ActivateIfPhysical(false);
542 }); 551 });
543 } 552 }
@@ -545,7 +554,7 @@ public sealed class BSPrim : BSPhysObject
545 { 554 {
546 PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate() 555 PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
547 { 556 {
548 _vehicle.ProcessVectorVehicleParam((Vehicle)param, value); 557 VehicleController.ProcessVectorVehicleParam((Vehicle)param, value);
549 ActivateIfPhysical(false); 558 ActivateIfPhysical(false);
550 }); 559 });
551 } 560 }
@@ -553,7 +562,7 @@ public sealed class BSPrim : BSPhysObject
553 { 562 {
554 PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate() 563 PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
555 { 564 {
556 _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); 565 VehicleController.ProcessRotationVehicleParam((Vehicle)param, rotation);
557 ActivateIfPhysical(false); 566 ActivateIfPhysical(false);
558 }); 567 });
559 } 568 }
@@ -561,7 +570,7 @@ public sealed class BSPrim : BSPhysObject
561 { 570 {
562 PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate() 571 PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate()
563 { 572 {
564 _vehicle.ProcessVehicleFlags(param, remove); 573 VehicleController.ProcessVehicleFlags(param, remove);
565 }); 574 });
566 } 575 }
567 576
@@ -638,11 +647,6 @@ public sealed class BSPrim : BSPhysObject
638 // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); 647 // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
639 } 648 }
640 } 649 }
641 public override float CollisionScore {
642 get { return _collisionScore; }
643 set { _collisionScore = value;
644 }
645 }
646 public override OMV.Vector3 Acceleration { 650 public override OMV.Vector3 Acceleration {
647 get { return _acceleration; } 651 get { return _acceleration; }
648 set { _acceleration = value; } 652 set { _acceleration = value; }
@@ -747,7 +751,7 @@ public sealed class BSPrim : BSPhysObject
747 // isSolid: other objects bounce off of this object 751 // isSolid: other objects bounce off of this object
748 // isVolumeDetect: other objects pass through but can generate collisions 752 // isVolumeDetect: other objects pass through but can generate collisions
749 // collisionEvents: whether this object returns collision events 753 // collisionEvents: whether this object returns collision events
750 private void UpdatePhysicalParameters() 754 public void UpdatePhysicalParameters()
751 { 755 {
752 // DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape); 756 // DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape);
753 757
@@ -759,7 +763,7 @@ public sealed class BSPrim : BSPhysObject
759 MakeDynamic(IsStatic); 763 MakeDynamic(IsStatic);
760 764
761 // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters) 765 // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
762 _vehicle.Refresh(); 766 VehicleController.Refresh();
763 767
764 // Arrange for collision events if the simulator wants them 768 // Arrange for collision events if the simulator wants them
765 EnableCollisions(SubscribedEvents()); 769 EnableCollisions(SubscribedEvents());
@@ -1601,7 +1605,7 @@ public sealed class BSPrim : BSPhysObject
1601 // Remove all the physical dependencies on the old body. 1605 // Remove all the physical dependencies on the old body.
1602 // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...) 1606 // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
1603 Linkset.RemoveBodyDependencies(this); 1607 Linkset.RemoveBodyDependencies(this);
1604 _vehicle.RemoveBodyDependencies(this); 1608 VehicleController.RemoveBodyDependencies(this);
1605 }); 1609 });
1606 1610
1607 // Make sure the properties are set on the new object 1611 // Make sure the properties are set on the new object
@@ -1618,9 +1622,9 @@ public sealed class BSPrim : BSPhysObject
1618 { 1622 {
1619 // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet 1623 // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
1620 // TODO: handle physics introduced by Bullet with computed vehicle physics. 1624 // TODO: handle physics introduced by Bullet with computed vehicle physics.
1621 if (_vehicle.IsActive) 1625 if (VehicleController.IsActive)
1622 { 1626 {
1623 // entprop.RotationalVelocity = OMV.Vector3.Zero; 1627 entprop.RotationalVelocity = OMV.Vector3.Zero;
1624 } 1628 }
1625 1629
1626 // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG 1630 // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
@@ -1643,7 +1647,7 @@ public sealed class BSPrim : BSPhysObject
1643 // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG 1647 // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG
1644 1648
1645 // The sanity check can change the velocity and/or position. 1649 // The sanity check can change the velocity and/or position.
1646 if (IsPhysical && PositionSanityCheck(true /* inTaintTime */ )) 1650 if (PositionSanityCheck(true /* inTaintTime */ ))
1647 { 1651 {
1648 entprop.Position = _position; 1652 entprop.Position = _position;
1649 entprop.Velocity = _velocity; 1653 entprop.Velocity = _velocity;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index cb304b6..a4690ba 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Linq;
29using System.Reflection; 30using System.Reflection;
30using System.Runtime.InteropServices; 31using System.Runtime.InteropServices;
31using System.Text; 32using System.Text;
@@ -87,7 +88,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
87 public delegate void PreStepAction(float timeStep); 88 public delegate void PreStepAction(float timeStep);
88 public delegate void PostStepAction(float timeStep); 89 public delegate void PostStepAction(float timeStep);
89 public event PreStepAction BeforeStep; 90 public event PreStepAction BeforeStep;
90 public event PreStepAction AfterStep; 91 public event PostStepAction AfterStep;
91 92
92 // A value of the time now so all the collision and update routines do not have to get their own 93 // A value of the time now so all the collision and update routines do not have to get their own
93 // Set to 'now' just before all the prims and actors are called for collisions and updates 94 // Set to 'now' just before all the prims and actors are called for collisions and updates
@@ -697,7 +698,21 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
697 698
698 public override Dictionary<uint, float> GetTopColliders() 699 public override Dictionary<uint, float> GetTopColliders()
699 { 700 {
700 return new Dictionary<uint, float>(); 701 Dictionary<uint, float> topColliders;
702
703 lock (PhysObjects)
704 {
705 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
706 {
707 kvp.Value.ComputeCollisionScore();
708 }
709
710 List<BSPhysObject> orderedPrims = new List<BSPhysObject>(PhysObjects.Values);
711 orderedPrims.OrderByDescending(p => p.CollisionScore);
712 topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore);
713 }
714
715 return topColliders;
701 } 716 }
702 717
703 public override bool IsThreaded { get { return false; } } 718 public override bool IsThreaded { get { return false; } }
@@ -748,7 +763,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
748 763
749 private void TriggerPostStepEvent(float timeStep) 764 private void TriggerPostStepEvent(float timeStep)
750 { 765 {
751 PreStepAction actions = AfterStep; 766 PostStepAction actions = AfterStep;
752 if (actions != null) 767 if (actions != null)
753 actions(timeStep); 768 actions(timeStep);
754 769
@@ -840,7 +855,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
840 { 855 {
841 DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); 856 DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
842 m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); 857 m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
843 Util.PrintCallStack(DetailLog); 858 // Util.PrintCallStack(DetailLog);
844 } 859 }
845 return InTaintTime; 860 return InTaintTime;
846 } 861 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
index 801f690..a95e169 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
@@ -1,8 +1,11 @@
1CURRENT PRIORITIES 1CURRENT PRIORITIES
2================================================= 2=================================================
3One sided meshes? Should terrain be built into a closed shape?
4 When meshes get partially wedged into the terrain, they cannot push themselves out.
5 It is possible that Bullet processes collisions whether entering or leaving a mesh.
6 Ref: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4869
3Deleting a linkset while standing on the root will leave the physical shape of the root behind. 7Deleting a linkset while standing on the root will leave the physical shape of the root behind.
4 Not sure if it is because standing on it. Done with large prim linksets. 8 Not sure if it is because standing on it. Done with large prim linksets.
5Child movement in linkset (don't rebuild linkset)
6Vehicle angular vertical attraction 9Vehicle angular vertical attraction
7vehicle angular banking 10vehicle angular banking
8Center-of-gravity 11Center-of-gravity
@@ -12,6 +15,7 @@ when should angular and linear motor targets be zeroed? when selected?
12 Need a vehicle.clear()? Or an 'else' in prestep if not physical. 15 Need a vehicle.clear()? Or an 'else' in prestep if not physical.
13Teravus llMoveToTarget script debug 16Teravus llMoveToTarget script debug
14 Mixing of hover, buoyancy/gravity, moveToTarget, into one force 17 Mixing of hover, buoyancy/gravity, moveToTarget, into one force
18 Setting hover height to zero disables hover even if hover flags are on (from SL wiki)
15Nebadon vehicles turning funny in arena 19Nebadon vehicles turning funny in arena
16limitMotorUp calibration (more down?) 20limitMotorUp calibration (more down?)
17llRotLookAt 21llRotLookAt
@@ -72,7 +76,11 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl
72 76
73GENERAL TODO LIST: 77GENERAL TODO LIST:
74================================================= 78=================================================
79Avatar standing on a moving object should start to move with the object.
75llMoveToTarget objects are not effected by gravity until target is removed. 80llMoveToTarget objects are not effected by gravity until target is removed.
81Compute CCD parameters based on body size
82Can solver iterations be changed per body/shape? Can be for constraints but what
83 about regular vehicles?
76Implement llSetPhysicalMaterial. 84Implement llSetPhysicalMaterial.
77 extend it with Center-of-mass, rolling friction, density 85 extend it with Center-of-mass, rolling friction, density
78Implement llSetForceAndTorque. 86Implement llSetForceAndTorque.
@@ -321,4 +329,5 @@ Mantis 6040 script http://opensimulator.org/mantis/view.php?id=6040 (DONE)
321Boats float low in the water (DONE) 329Boats float low in the water (DONE)
322Boats floating at proper level (DONE) 330Boats floating at proper level (DONE)
323When is force introduced by SetForce removed? The prestep action could go forever. (DONE) 331When is force introduced by SetForce removed? The prestep action could go forever. (DONE)
324 (Resolution: setForce registers a prestep action which keeps applying the force) \ No newline at end of file 332 (Resolution: setForce registers a prestep action which keeps applying the force)
333Child movement in linkset (don't rebuild linkset) (DONE 20130122)) \ No newline at end of file
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs
new file mode 100755
index 0000000..33232bd
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs
@@ -0,0 +1,150 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32
33using NUnit.Framework;
34using log4net;
35
36using OpenSim.Framework;
37using OpenSim.Region.Physics.BulletSPlugin;
38using OpenSim.Region.Physics.Manager;
39using OpenSim.Tests.Common;
40
41using OpenMetaverse;
42
43namespace OpenSim.Region.Physics.BulletSPlugin.Tests
44{
45[TestFixture]
46public class BasicVehicles : OpenSimTestCase
47{
48 // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1
49 // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1
50
51 BSScene PhysicsScene { get; set; }
52 BSPrim TestVehicle { get; set; }
53 Vector3 TestVehicleInitPosition { get; set; }
54 float simulationTimeStep = 0.089f;
55
56 [TestFixtureSetUp]
57 public void Init()
58 {
59 Dictionary<string, string> engineParams = new Dictionary<string, string>();
60 PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams);
61
62 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere();
63 Vector3 pos = new Vector3(100.0f, 100.0f, 0f);
64 pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 2f;
65 TestVehicleInitPosition = pos;
66 Vector3 size = new Vector3(1f, 1f, 1f);
67 pbs.Scale = size;
68 Quaternion rot = Quaternion.Identity;
69 bool isPhys = false;
70 uint localID = 123;
71
72 PhysicsScene.AddPrimShape("testPrim", pbs, pos, size, rot, isPhys, localID);
73 TestVehicle = (BSPrim)PhysicsScene.PhysObjects[localID];
74 // The actual prim shape creation happens at taint time
75 PhysicsScene.ProcessTaints();
76
77 }
78
79 [TestFixtureTearDown]
80 public void TearDown()
81 {
82 if (PhysicsScene != null)
83 {
84 // The Dispose() will also free any physical objects in the scene
85 PhysicsScene.Dispose();
86 PhysicsScene = null;
87 }
88 }
89
90 [TestCase(2f, 0.2f, 0.25f, 0.25f, 0.25f)]
91 [TestCase(2f, 0.2f, -0.25f, 0.25f, 0.25f)]
92 [TestCase(2f, 0.2f, 0.25f, -0.25f, 0.25f)]
93 [TestCase(2f, 0.2f, -0.25f, -0.25f, 0.25f)]
94 // [TestCase(2f, 0.2f, 0.785f, 0.0f, 0.25f) /*, "Leaning 45 degrees to the side" */]
95 // [TestCase(2f, 0.2f, 1.650f, 0.0f, 0.25f) /*, "Leaning more than 90 degrees to the side" */]
96 // [TestCase(2f, 0.2f, 2.750f, 0.0f, 0.25f) /*, "Almost upside down, tipped right" */]
97 // [TestCase(2f, 0.2f,-2.750f, 0.0f, 0.25f) /*, "Almost upside down, tipped left" */]
98 // [TestCase(2f, 0.2f, 0.0f, 0.785f, 0.25f) /*, "Tipped back 45 degrees" */]
99 // [TestCase(2f, 0.2f, 0.0f, 1.650f, 0.25f) /*, "Tipped back more than 90 degrees" */]
100 // [TestCase(2f, 0.2f, 0.0f, 2.750f, 0.25f) /*, "Almost upside down, tipped back" */]
101 // [TestCase(2f, 0.2f, 0.0f,-2.750f, 0.25f) /*, "Almost upside down, tipped forward" */]
102 public void AngularVerticalAttraction(float timeScale, float efficiency, float initRoll, float initPitch, float initYaw)
103 {
104 // Enough simulation steps to cover the timescale the operation should take
105 int simSteps = (int)(timeScale / simulationTimeStep) + 1;
106
107 // Tip the vehicle
108 Quaternion initOrientation = Quaternion.CreateFromEulers(initRoll, initPitch, initYaw);
109 TestVehicle.Orientation = initOrientation;
110
111 TestVehicle.Position = TestVehicleInitPosition;
112
113 // The vehicle controller is not enabled directly (by setting a vehicle type).
114 // Instead the appropriate values are set and calls are made just the parts of the
115 // controller we want to exercise. Stepping the physics engine then applies
116 // the actions of that one feature.
117 TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency);
118 TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale);
119 TestVehicle.VehicleController.enableAngularVerticalAttraction = true;
120
121 TestVehicle.IsPhysical = true;
122 PhysicsScene.ProcessTaints();
123
124 // Step the simulator a bunch of times and vertical attraction should orient the vehicle up
125 for (int ii = 0; ii < simSteps; ii++)
126 {
127 TestVehicle.VehicleController.ForgetKnownVehicleProperties();
128 TestVehicle.VehicleController.ComputeAngularVerticalAttraction();
129 TestVehicle.VehicleController.PushKnownChanged();
130
131 PhysicsScene.Simulate(simulationTimeStep);
132 }
133
134 TestVehicle.IsPhysical = false;
135 PhysicsScene.ProcessTaints();
136
137 // After these steps, the vehicle should be upright
138 /*
139 float finalRoll, finalPitch, finalYaw;
140 TestVehicle.Orientation.GetEulerAngles(out finalRoll, out finalPitch, out finalYaw);
141 Assert.That(finalRoll, Is.InRange(-0.01f, 0.01f));
142 Assert.That(finalPitch, Is.InRange(-0.01f, 0.01f));
143 Assert.That(finalYaw, Is.InRange(initYaw - 0.1f, initYaw + 0.1f));
144 */
145
146 Vector3 upPointer = Vector3.UnitZ * TestVehicle.Orientation;
147 Assert.That(upPointer.Z, Is.GreaterThan(0.99f));
148 }
149}
150} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTests.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTests.cs
new file mode 100755
index 0000000..35cbc1d
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTests.cs
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32
33using NUnit.Framework;
34using log4net;
35
36using OpenSim.Tests.Common;
37
38namespace OpenSim.Region.Physics.BulletSPlugin.Tests
39{
40[TestFixture]
41public class BulletSimTests : OpenSimTestCase
42{
43 // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1
44 // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1
45
46 [TestFixtureSetUp]
47 public void Init()
48 {
49 }
50
51 [TestFixtureTearDown]
52 public void TearDown()
53 {
54 }
55}
56}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs
new file mode 100755
index 0000000..28207a4
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs
@@ -0,0 +1,95 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Collections.Generic;
31using System.Linq;
32using System.Text;
33
34using Nini.Config;
35
36using OpenSim.Framework;
37using OpenSim.Region.Physics.BulletSPlugin;
38using OpenSim.Region.Physics.Meshing;
39
40namespace OpenSim.Region.Physics.BulletSPlugin.Tests
41{
42// Utility functions for building up and tearing down the sample physics environments
43public static class BulletSimTestsUtil
44{
45 // 'engineName' is the Bullet engine to use. Either null (for unmanaged), "BulletUnmanaged" or "BulletXNA"
46 // 'params' is a set of keyValue pairs to set in the engine's configuration file (override defaults)
47 // May be 'null' if there are no overrides.
48 public static BSScene CreateBasicPhysicsEngine(Dictionary<string,string> paramOverrides)
49 {
50 IConfigSource openSimINI = new IniConfigSource();
51 IConfig startupConfig = openSimINI.AddConfig("Startup");
52 startupConfig.Set("physics", "BulletSim");
53 startupConfig.Set("meshing", "Meshmerizer");
54 startupConfig.Set("cacheSculptMaps", "false"); // meshmerizer shouldn't save maps
55
56 IConfig bulletSimConfig = openSimINI.AddConfig("BulletSim");
57 // If the caller cares, specify the bullet engine otherwise it will default to "BulletUnmanaged".
58 // bulletSimConfig.Set("BulletEngine", "BulletUnmanaged");
59 // bulletSimConfig.Set("BulletEngine", "BulletXNA");
60 bulletSimConfig.Set("MeshSculptedPrim", "false");
61 bulletSimConfig.Set("ForceSimplePrimMeshing", "true");
62 if (paramOverrides != null)
63 {
64 foreach (KeyValuePair<string, string> kvp in paramOverrides)
65 {
66 bulletSimConfig.Set(kvp.Key, kvp.Value);
67 }
68 }
69
70 // If a special directory exists, put detailed logging therein.
71 // This allows local testing/debugging without having to worry that the build engine will output logs.
72 if (Directory.Exists("physlogs"))
73 {
74 bulletSimConfig.Set("PhysicsLoggingDir","./physlogs");
75 bulletSimConfig.Set("PhysicsLoggingEnabled","True");
76 bulletSimConfig.Set("PhysicsLoggingDoFlush","True");
77 bulletSimConfig.Set("VehicleLoggingEnabled","True");
78 }
79
80 BSPlugin bsPlugin = new BSPlugin();
81
82 BSScene bsScene = (BSScene)bsPlugin.GetScene("BSTestRegion");
83
84 // Since the asset requestor is not initialized, any mesh or sculptie will be a cube.
85 // In the future, add a fake asset fetcher to get meshes and sculpts.
86 // bsScene.RequestAssetMethod = ???;
87
88 Meshing.Meshmerizer mesher = new Meshmerizer(openSimINI);
89 bsScene.Initialise(mesher, openSimINI);
90
91 return bsScene;
92 }
93
94}
95}
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 02a0b15..6d7f079 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -4096,8 +4096,8 @@ namespace OpenSim.Region.Physics.OdePlugin
4096 lock (_prims) 4096 lock (_prims)
4097 { 4097 {
4098 List<OdePrim> orderedPrims = new List<OdePrim>(_prims); 4098 List<OdePrim> orderedPrims = new List<OdePrim>(_prims);
4099 orderedPrims.OrderByDescending(p => p.CollisionScore).Take(25); 4099 orderedPrims.OrderByDescending(p => p.CollisionScore);
4100 topColliders = orderedPrims.ToDictionary(p => p.LocalID, p => p.CollisionScore); 4100 topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore);
4101 4101
4102 foreach (OdePrim p in _prims) 4102 foreach (OdePrim p in _prims)
4103 p.CollisionScore = 0; 4103 p.CollisionScore = 0;