aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs30
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs57
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs16
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSMotors.cs170
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs28
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs4
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs138
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs1
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt20
10 files changed, 372 insertions, 96 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs
index 8c6e7d6..14de2eb 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs
@@ -530,12 +530,12 @@ public override void SetForceUpdateAllAabbs(BulletWorld world, bool force)
530// btDynamicsWorld entries 530// btDynamicsWorld entries
531public override bool AddObjectToWorld(BulletWorld world, BulletBody obj) 531public override bool AddObjectToWorld(BulletWorld world, BulletBody obj)
532{ 532{
533 // Bullet resets several variables when an object is added to the world.
534 // Gravity is reset to world default depending on the static/dynamic
535 // type. Of course, the collision flags in the broadphase proxy are initialized to default.
536 BulletWorldUnman worldu = world as BulletWorldUnman; 533 BulletWorldUnman worldu = world as BulletWorldUnman;
537 BulletBodyUnman bodyu = obj as BulletBodyUnman; 534 BulletBodyUnman bodyu = obj as BulletBodyUnman;
538 535
536 // Bullet resets several variables when an object is added to the world.
537 // Gravity is reset to world default depending on the static/dynamic
538 // type. Of course, the collision flags in the broadphase proxy are initialized to default.
539 Vector3 origGrav = BSAPICPP.GetGravity2(bodyu.ptr); 539 Vector3 origGrav = BSAPICPP.GetGravity2(bodyu.ptr);
540 540
541 bool ret = BSAPICPP.AddObjectToWorld2(worldu.ptr, bodyu.ptr); 541 bool ret = BSAPICPP.AddObjectToWorld2(worldu.ptr, bodyu.ptr);
@@ -921,6 +921,7 @@ public override void SetCenterOfMassByPosRot(BulletBody obj, Vector3 pos, Quater
921} 921}
922 922
923// Add a force to the object as if its mass is one. 923// Add a force to the object as if its mass is one.
924// Deep down in Bullet: m_totalForce += force*m_linearFactor;
924public override void ApplyCentralForce(BulletBody obj, Vector3 force) 925public override void ApplyCentralForce(BulletBody obj, Vector3 force)
925{ 926{
926 BulletBodyUnman bodyu = obj as BulletBodyUnman; 927 BulletBodyUnman bodyu = obj as BulletBodyUnman;
@@ -964,6 +965,7 @@ public override void SetSleepingThresholds(BulletBody obj, float lin_threshold,
964 BSAPICPP.SetSleepingThresholds2(bodyu.ptr, lin_threshold, ang_threshold); 965 BSAPICPP.SetSleepingThresholds2(bodyu.ptr, lin_threshold, ang_threshold);
965} 966}
966 967
968// Deep down in Bullet: m_totalTorque += torque*m_angularFactor;
967public override void ApplyTorque(BulletBody obj, Vector3 torque) 969public override void ApplyTorque(BulletBody obj, Vector3 torque)
968{ 970{
969 BulletBodyUnman bodyu = obj as BulletBodyUnman; 971 BulletBodyUnman bodyu = obj as BulletBodyUnman;
@@ -971,6 +973,8 @@ public override void ApplyTorque(BulletBody obj, Vector3 torque)
971} 973}
972 974
973// Apply force at the given point. Will add torque to the object. 975// Apply force at the given point. Will add torque to the object.
976// Deep down in Bullet: applyCentralForce(force);
977// applyTorque(rel_pos.cross(force*m_linearFactor));
974public override void ApplyForce(BulletBody obj, Vector3 force, Vector3 pos) 978public override void ApplyForce(BulletBody obj, Vector3 force, Vector3 pos)
975{ 979{
976 BulletBodyUnman bodyu = obj as BulletBodyUnman; 980 BulletBodyUnman bodyu = obj as BulletBodyUnman;
@@ -978,6 +982,7 @@ public override void ApplyForce(BulletBody obj, Vector3 force, Vector3 pos)
978} 982}
979 983
980// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass. 984// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass.
985// Deep down in Bullet: m_linearVelocity += impulse *m_linearFactor * m_inverseMass;
981public override void ApplyCentralImpulse(BulletBody obj, Vector3 imp) 986public override void ApplyCentralImpulse(BulletBody obj, Vector3 imp)
982{ 987{
983 BulletBodyUnman bodyu = obj as BulletBodyUnman; 988 BulletBodyUnman bodyu = obj as BulletBodyUnman;
@@ -985,6 +990,7 @@ public override void ApplyCentralImpulse(BulletBody obj, Vector3 imp)
985} 990}
986 991
987// Apply impulse to the object's torque. Force is scaled by object's mass. 992// Apply impulse to the object's torque. Force is scaled by object's mass.
993// Deep down in Bullet: m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
988public override void ApplyTorqueImpulse(BulletBody obj, Vector3 imp) 994public override void ApplyTorqueImpulse(BulletBody obj, Vector3 imp)
989{ 995{
990 BulletBodyUnman bodyu = obj as BulletBodyUnman; 996 BulletBodyUnman bodyu = obj as BulletBodyUnman;
@@ -992,6 +998,8 @@ public override void ApplyTorqueImpulse(BulletBody obj, Vector3 imp)
992} 998}
993 999
994// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces. 1000// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces.
1001// Deep down in Bullet: applyCentralImpulse(impulse);
1002// applyTorqueImpulse(rel_pos.cross(impulse*m_linearFactor));
995public override void ApplyImpulse(BulletBody obj, Vector3 imp, Vector3 pos) 1003public override void ApplyImpulse(BulletBody obj, Vector3 imp, Vector3 pos)
996{ 1004{
997 BulletBodyUnman bodyu = obj as BulletBodyUnman; 1005 BulletBodyUnman bodyu = obj as BulletBodyUnman;
@@ -1259,6 +1267,16 @@ public override void DumpPhysicsStatistics(BulletWorld world)
1259 BulletWorldUnman worldu = world as BulletWorldUnman; 1267 BulletWorldUnman worldu = world as BulletWorldUnman;
1260 BSAPICPP.DumpPhysicsStatistics2(worldu.ptr); 1268 BSAPICPP.DumpPhysicsStatistics2(worldu.ptr);
1261} 1269}
1270public override void ResetBroadphasePool(BulletWorld world)
1271{
1272 BulletWorldUnman worldu = world as BulletWorldUnman;
1273 BSAPICPP.ResetBroadphasePool(worldu.ptr);
1274}
1275public override void ResetConstraintSolver(BulletWorld world)
1276{
1277 BulletWorldUnman worldu = world as BulletWorldUnman;
1278 BSAPICPP.ResetConstraintSolver(worldu.ptr);
1279}
1262 1280
1263// ===================================================================================== 1281// =====================================================================================
1264// ===================================================================================== 1282// =====================================================================================
@@ -1832,6 +1850,12 @@ public static extern void DumpAllInfo2(IntPtr sim);
1832[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1850[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1833public static extern void DumpPhysicsStatistics2(IntPtr sim); 1851public static extern void DumpPhysicsStatistics2(IntPtr sim);
1834 1852
1853[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1854public static extern void ResetBroadphasePool(IntPtr sim);
1855
1856[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1857public static extern void ResetConstraintSolver(IntPtr sim);
1858
1835} 1859}
1836 1860
1837} 1861}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
index 30a7bee..0c7f315 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
@@ -232,21 +232,25 @@ private sealed class BulletConstraintXNA : BulletConstraint
232 232
233 public override bool AddObjectToWorld(BulletWorld pWorld, BulletBody pBody) 233 public override bool AddObjectToWorld(BulletWorld pWorld, BulletBody pBody)
234 { 234 {
235 DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
236 CollisionObject cbody = ((BulletBodyXNA)pBody).body;
237 RigidBody rbody = cbody as RigidBody;
238
235 // Bullet resets several variables when an object is added to the world. In particular, 239 // Bullet resets several variables when an object is added to the world. In particular,
236 // BulletXNA resets position and rotation. Gravity is also reset depending on the static/dynamic 240 // BulletXNA resets position and rotation. Gravity is also reset depending on the static/dynamic
237 // type. Of course, the collision flags in the broadphase proxy are initialized to default. 241 // type. Of course, the collision flags in the broadphase proxy are initialized to default.
238 DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; 242 IndexedMatrix origPos = cbody.GetWorldTransform();
239 RigidBody body = ((BulletBodyXNA)pBody).rigidBody; 243 if (rbody != null)
240 244 {
241 IndexedMatrix origPos = body.GetWorldTransform(); 245 IndexedVector3 origGrav = rbody.GetGravity();
242 IndexedVector3 origGrav = body.GetGravity(); 246 world.AddRigidBody(rbody);
243 247 rbody.SetGravity(origGrav);
244 //if (!(body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE && body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE)) 248 }
245 249 else
246 world.AddRigidBody(body); 250 {
247 251 world.AddCollisionObject(rbody);
248 body.SetWorldTransform(origPos); 252 }
249 body.SetGravity(origGrav); 253 cbody.SetWorldTransform(origPos);
250 254
251 pBody.ApplyCollisionMask(pWorld.physicsScene); 255 pBody.ApplyCollisionMask(pWorld.physicsScene);
252 256
@@ -773,35 +777,6 @@ private sealed class BulletConstraintXNA : BulletConstraint
773 body.ApplyTorqueImpulse(ref fSum); 777 body.ApplyTorqueImpulse(ref fSum);
774 } 778 }
775 779
776 public override void DumpRigidBody(BulletWorld p, BulletBody p_2)
777 {
778 //TODO:
779 }
780
781 public override void DumpCollisionShape(BulletWorld p, BulletShape p_2)
782 {
783 //TODO:
784 }
785 public override void DumpConstraint(BulletWorld world, BulletConstraint constrain)
786 {
787 //TODO:
788 }
789
790 public override void DumpActivationInfo(BulletWorld world)
791 {
792 //TODO:
793 }
794
795 public override void DumpAllInfo(BulletWorld world)
796 {
797 //TODO:
798 }
799
800 public override void DumpPhysicsStatistics(BulletWorld world)
801 {
802 //TODO:
803 }
804
805 public override void DestroyObject(BulletWorld p, BulletBody p_2) 780 public override void DestroyObject(BulletWorld p, BulletBody p_2)
806 { 781 {
807 //TODO: 782 //TODO:
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
index 8ad78ca..befb076 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
@@ -646,17 +646,21 @@ public abstract float GetMargin(BulletShape shape);
646 646
647// ===================================================================================== 647// =====================================================================================
648// Debugging 648// Debugging
649public abstract void DumpRigidBody(BulletWorld sim, BulletBody collisionObject); 649public virtual void DumpRigidBody(BulletWorld sim, BulletBody collisionObject) { }
650 650
651public abstract void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape); 651public virtual void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape) { }
652 652
653public abstract void DumpConstraint(BulletWorld sim, BulletConstraint constrain); 653public virtual void DumpConstraint(BulletWorld sim, BulletConstraint constrain) { }
654 654
655public abstract void DumpActivationInfo(BulletWorld sim); 655public virtual void DumpActivationInfo(BulletWorld sim) { }
656 656
657public abstract void DumpAllInfo(BulletWorld sim); 657public virtual void DumpAllInfo(BulletWorld sim) { }
658 658
659public abstract void DumpPhysicsStatistics(BulletWorld sim); 659public virtual void DumpPhysicsStatistics(BulletWorld sim) { }
660
661public virtual void ResetBroadphasePool(BulletWorld sim) { }
662
663public virtual void ResetConstraintSolver(BulletWorld sim) { }
660 664
661}; 665};
662} 666}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 103d8fc..c215e3a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -214,7 +214,7 @@ public sealed class BSCharacter : BSPhysObject
214 } 214 }
215 215
216 // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. 216 // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
217 OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass / PhysicsScene.LastTimeStep; 217 OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass;
218 218
219 /* 219 /*
220 // If moveForce is very small, zero things so we don't keep sending microscopic updates to the user 220 // If moveForce is very small, zero things so we don't keep sending microscopic updates to the user
@@ -231,7 +231,7 @@ public sealed class BSCharacter : BSPhysObject
231 } 231 }
232 */ 232 */
233 // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); 233 // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
234 AddForce(moveForce, false, true); 234 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce);
235 }); 235 });
236 } 236 }
237 237
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs
index 817a5f7..6d0db2e 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs
@@ -59,10 +59,7 @@ public abstract class BSMotor
59 { 59 {
60 if (PhysicsScene != null) 60 if (PhysicsScene != null)
61 { 61 {
62 if (PhysicsScene.VehicleLoggingEnabled) 62 PhysicsScene.DetailLog(msg, parms);
63 {
64 PhysicsScene.DetailLog(msg, parms);
65 }
66 } 63 }
67 } 64 }
68} 65}
@@ -100,10 +97,13 @@ public class BSVMotor : BSMotor
100 public virtual Vector3 CurrentValue { get; protected set; } 97 public virtual Vector3 CurrentValue { get; protected set; }
101 public virtual Vector3 LastError { get; protected set; } 98 public virtual Vector3 LastError { get; protected set; }
102 99
103 public virtual bool ErrorIsZero 100 public virtual bool ErrorIsZero()
104 { get { 101 {
105 return (LastError == Vector3.Zero || LastError.LengthSquared() <= ErrorZeroThreshold); 102 return ErrorIsZero(LastError);
106 } 103 }
104 public virtual bool ErrorIsZero(Vector3 err)
105 {
106 return (err == Vector3.Zero || err.ApproxEquals(Vector3.Zero, ErrorZeroThreshold));
107 } 107 }
108 108
109 public BSVMotor(string useName) 109 public BSVMotor(string useName)
@@ -148,7 +148,7 @@ public class BSVMotor : BSMotor
148 148
149 Vector3 correction = Vector3.Zero; 149 Vector3 correction = Vector3.Zero;
150 Vector3 error = TargetValue - CurrentValue; 150 Vector3 error = TargetValue - CurrentValue;
151 if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) 151 if (!ErrorIsZero(error))
152 { 152 {
153 correction = Step(timeStep, error); 153 correction = Step(timeStep, error);
154 154
@@ -200,7 +200,7 @@ public class BSVMotor : BSMotor
200 200
201 LastError = error; 201 LastError = error;
202 Vector3 returnCorrection = Vector3.Zero; 202 Vector3 returnCorrection = Vector3.Zero;
203 if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) 203 if (!ErrorIsZero())
204 { 204 {
205 // correction = error / secondsItShouldTakeToCorrect 205 // correction = error / secondsItShouldTakeToCorrect
206 Vector3 correctionAmount; 206 Vector3 correctionAmount;
@@ -246,32 +246,139 @@ public class BSVMotor : BSMotor
246 } 246 }
247} 247}
248 248
249// ============================================================================
250// ============================================================================
249public class BSFMotor : BSMotor 251public class BSFMotor : BSMotor
250{ 252{
251 public float TimeScale { get; set; } 253 public virtual float TimeScale { get; set; }
252 public float DecayTimeScale { get; set; } 254 public virtual float TargetValueDecayTimeScale { get; set; }
253 public float Friction { get; set; } 255 public virtual float FrictionTimescale { get; set; }
254 public float Efficiency { get; set; } 256 public virtual float Efficiency { get; set; }
257
258 public virtual float ErrorZeroThreshold { get; set; }
255 259
256 public float Target { get; private set; } 260 public virtual float TargetValue { get; protected set; }
257 public float CurrentValue { get; private set; } 261 public virtual float CurrentValue { get; protected set; }
262 public virtual float LastError { get; protected set; }
263
264 public virtual bool ErrorIsZero()
265 {
266 return ErrorIsZero(LastError);
267 }
268 public virtual bool ErrorIsZero(float err)
269 {
270 return (err >= -ErrorZeroThreshold && err <= ErrorZeroThreshold);
271 }
258 272
259 public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency) 273 public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency)
260 : base(useName) 274 : base(useName)
261 { 275 {
276 TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite;
277 Efficiency = 1f;
278 FrictionTimescale = BSMotor.Infinite;
279 CurrentValue = TargetValue = 0f;
280 ErrorZeroThreshold = 0.01f;
262 } 281 }
263 public void SetCurrent(float target) 282 public void SetCurrent(float current)
264 { 283 {
284 CurrentValue = current;
265 } 285 }
266 public void SetTarget(float target) 286 public void SetTarget(float target)
267 { 287 {
288 TargetValue = target;
268 } 289 }
290 public override void Zero()
291 {
292 base.Zero();
293 CurrentValue = TargetValue = 0f;
294 }
295
269 public virtual float Step(float timeStep) 296 public virtual float Step(float timeStep)
270 { 297 {
271 return 0f; 298 if (!Enabled) return TargetValue;
299
300 float origTarget = TargetValue; // DEBUG
301 float origCurrVal = CurrentValue; // DEBUG
302
303 float correction = 0f;
304 float error = TargetValue - CurrentValue;
305 if (!ErrorIsZero(error))
306 {
307 correction = Step(timeStep, error);
308
309 CurrentValue += correction;
310
311 // The desired value reduces to zero which also reduces the difference with current.
312 // If the decay time is infinite, don't decay at all.
313 float decayFactor = 0f;
314 if (TargetValueDecayTimeScale != BSMotor.Infinite)
315 {
316 decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep;
317 TargetValue *= (1f - decayFactor);
318 }
319
320 // The amount we can correct the error is reduced by the friction
321 float frictionFactor = 0f;
322 if (FrictionTimescale != BSMotor.Infinite)
323 {
324 // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep;
325 // Individual friction components can be 'infinite' so compute each separately.
326 frictionFactor = 1f / FrictionTimescale;
327 frictionFactor *= timeStep;
328 CurrentValue *= (1f - frictionFactor);
329 }
330
331 MDetailLog("{0}, BSFMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}",
332 BSScene.DetailLogZero, UseName, origCurrVal, origTarget,
333 timeStep, error, correction);
334 MDetailLog("{0}, BSFMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},frictTS={4},frictFact={5},tgt={6},curr={7}",
335 BSScene.DetailLogZero, UseName,
336 TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor,
337 TargetValue, CurrentValue);
338 }
339 else
340 {
341 // Difference between what we have and target is small. Motor is done.
342 CurrentValue = TargetValue;
343 MDetailLog("{0}, BSFMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}",
344 BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue);
345 }
346
347 return CurrentValue;
348 }
349
350 public virtual float Step(float timeStep, float error)
351 {
352 if (!Enabled) return 0f;
353
354 LastError = error;
355 float returnCorrection = 0f;
356 if (!ErrorIsZero())
357 {
358 // correction = error / secondsItShouldTakeToCorrect
359 float correctionAmount;
360 if (TimeScale == 0f || TimeScale == BSMotor.Infinite)
361 correctionAmount = error * timeStep;
362 else
363 correctionAmount = error / TimeScale * timeStep;
364
365 returnCorrection = correctionAmount;
366 MDetailLog("{0}, BSFMotor.Step,nonZero,{1},timeStep={2},timeScale={3},err={4},corr={5}",
367 BSScene.DetailLogZero, UseName, timeStep, TimeScale, error, correctionAmount);
368 }
369 return returnCorrection;
370 }
371
372 public override string ToString()
373 {
374 return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4},frictTS={5}>",
375 UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale, FrictionTimescale);
272 } 376 }
377
273} 378}
274 379
380// ============================================================================
381// ============================================================================
275// Proportional, Integral, Derivitive Motor 382// Proportional, Integral, Derivitive Motor
276// Good description at http://www.answers.com/topic/pid-controller . Includes processes for choosing p, i and d factors. 383// Good description at http://www.answers.com/topic/pid-controller . Includes processes for choosing p, i and d factors.
277public class BSPIDVMotor : BSVMotor 384public class BSPIDVMotor : BSVMotor
@@ -281,6 +388,12 @@ public class BSPIDVMotor : BSVMotor
281 public Vector3 integralFactor { get; set; } 388 public Vector3 integralFactor { get; set; }
282 public Vector3 derivFactor { get; set; } 389 public Vector3 derivFactor { get; set; }
283 390
391 // The factors are vectors for the three dimensions. This is the proportional of each
392 // that is applied. This could be multiplied through the actual factors but it
393 // is sometimes easier to manipulate the factors and their mix separately.
394 // to
395 public Vector3 FactorMix;
396
284 // Arbritrary factor range. 397 // Arbritrary factor range.
285 // EfficiencyHigh means move quickly to the correct number. EfficiencyLow means might over correct. 398 // EfficiencyHigh means move quickly to the correct number. EfficiencyLow means might over correct.
286 public float EfficiencyHigh = 0.4f; 399 public float EfficiencyHigh = 0.4f;
@@ -295,6 +408,7 @@ public class BSPIDVMotor : BSVMotor
295 proportionFactor = new Vector3(1.00f, 1.00f, 1.00f); 408 proportionFactor = new Vector3(1.00f, 1.00f, 1.00f);
296 integralFactor = new Vector3(1.00f, 1.00f, 1.00f); 409 integralFactor = new Vector3(1.00f, 1.00f, 1.00f);
297 derivFactor = new Vector3(1.00f, 1.00f, 1.00f); 410 derivFactor = new Vector3(1.00f, 1.00f, 1.00f);
411 FactorMix = new Vector3(0.5f, 0.25f, 0.25f);
298 RunningIntegration = Vector3.Zero; 412 RunningIntegration = Vector3.Zero;
299 LastError = Vector3.Zero; 413 LastError = Vector3.Zero;
300 } 414 }
@@ -310,15 +424,19 @@ public class BSPIDVMotor : BSVMotor
310 set 424 set
311 { 425 {
312 base.Efficiency = Util.Clamp(value, 0f, 1f); 426 base.Efficiency = Util.Clamp(value, 0f, 1f);
427
313 // Compute factors based on efficiency. 428 // Compute factors based on efficiency.
314 // If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot. 429 // If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot.
315 // If efficiency is low (0f), use a factor value that overcorrects. 430 // If efficiency is low (0f), use a factor value that overcorrects.
316 // TODO: might want to vary contribution of different factor depending on efficiency. 431 // TODO: might want to vary contribution of different factor depending on efficiency.
317 float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f; 432 float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f;
318 // float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow; 433 // float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow;
434
319 proportionFactor = new Vector3(factor, factor, factor); 435 proportionFactor = new Vector3(factor, factor, factor);
320 integralFactor = new Vector3(factor, factor, factor); 436 integralFactor = new Vector3(factor, factor, factor);
321 derivFactor = new Vector3(factor, factor, factor); 437 derivFactor = new Vector3(factor, factor, factor);
438
439 MDetailLog("{0},BSPIDVMotor.setEfficiency,eff={1},factor={2}", BSScene.DetailLogZero, Efficiency, factor);
322 } 440 }
323 } 441 }
324 442
@@ -331,15 +449,17 @@ public class BSPIDVMotor : BSVMotor
331 RunningIntegration += error * timeStep; 449 RunningIntegration += error * timeStep;
332 450
333 // A simple derivitive is the rate of change from the last error. 451 // A simple derivitive is the rate of change from the last error.
334 Vector3 derivFactor = (error - LastError) * timeStep; 452 Vector3 derivitive = (error - LastError) * timeStep;
335 LastError = error; 453 LastError = error;
336 454
337 // Correction = -(proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError) 455 // Correction = (proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError)
338 Vector3 ret = -( 456 Vector3 ret = error * timeStep * proportionFactor * FactorMix.X
339 error * proportionFactor 457 + RunningIntegration * integralFactor * FactorMix.Y
340 + RunningIntegration * integralFactor 458 + derivitive * derivFactor * FactorMix.Z
341 + derivFactor * derivFactor 459 ;
342 ); 460
461 MDetailLog("{0},BSPIDVMotor.step,ts={1},err={2},runnInt={3},deriv={4},ret={5}",
462 BSScene.DetailLogZero, timeStep, error, RunningIntegration, derivitive, ret);
343 463
344 return ret; 464 return ret;
345 } 465 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index 69ac8cd..b9bd0bf 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -497,6 +497,16 @@ public static class BSParam
497 (s,cf,p,v) => { s.PhysicsMetricDumpFrames = cf.GetFloat(p, (int)v); }, 497 (s,cf,p,v) => { s.PhysicsMetricDumpFrames = cf.GetFloat(p, (int)v); },
498 (s) => { return (float)s.PhysicsMetricDumpFrames; }, 498 (s) => { return (float)s.PhysicsMetricDumpFrames; },
499 (s,p,l,v) => { s.PhysicsMetricDumpFrames = (int)v; } ), 499 (s,p,l,v) => { s.PhysicsMetricDumpFrames = (int)v; } ),
500 new ParameterDefn("ResetBroadphasePool", "Setting this is any value resets the broadphase collision pool",
501 0f,
502 (s,cf,p,v) => { ; },
503 (s) => { return 0f; },
504 (s,p,l,v) => { BSParam.ResetBroadphasePoolTainted(s, v); } ),
505 new ParameterDefn("ResetConstraintSolver", "Setting this is any value resets the constraint solver",
506 0f,
507 (s,cf,p,v) => { ; },
508 (s) => { return 0f; },
509 (s,p,l,v) => { BSParam.ResetConstraintSolverTainted(s, v); } ),
500 }; 510 };
501 511
502 // Convert a boolean to our numeric true and false values 512 // Convert a boolean to our numeric true and false values
@@ -511,6 +521,24 @@ public static class BSParam
511 return (b == ConfigurationParameters.numericTrue ? true : false); 521 return (b == ConfigurationParameters.numericTrue ? true : false);
512 } 522 }
513 523
524 private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v)
525 {
526 BSScene physScene = pPhysScene;
527 physScene.TaintedObject("BSParam.ResetBroadphasePoolTainted", delegate()
528 {
529 physScene.PE.ResetBroadphasePool(physScene.World);
530 });
531 }
532
533 private static void ResetConstraintSolverTainted(BSScene pPhysScene, float v)
534 {
535 BSScene physScene = pPhysScene;
536 physScene.TaintedObject("BSParam.ResetConstraintSolver", delegate()
537 {
538 physScene.PE.ResetConstraintSolver(physScene.World);
539 });
540 }
541
514 // Search through the parameter definitions and return the matching 542 // Search through the parameter definitions and return the matching
515 // ParameterDefn structure. 543 // ParameterDefn structure.
516 // Case does not matter as names are compared after converting to lower case. 544 // Case does not matter as names are compared after converting to lower case.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index e7cb3e0..534f929 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -343,6 +343,10 @@ public abstract class BSPhysObject : PhysicsActor
343 protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn) 343 protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn)
344 { 344 {
345 string identifier = op + "-" + id.ToString(); 345 string identifier = op + "-" + id.ToString();
346
347 // Clean out any existing action
348 UnRegisterPreStepAction(op, id);
349
346 RegisteredActions[identifier] = actn; 350 RegisteredActions[identifier] = actn;
347 PhysicsScene.BeforeStep += actn; 351 PhysicsScene.BeforeStep += actn;
348 DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); 352 DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 826261c..94b63e5 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -66,9 +66,6 @@ public sealed class BSPrim : BSPhysObject
66 private float _restitution; 66 private float _restitution;
67 private bool _setAlwaysRun; 67 private bool _setAlwaysRun;
68 private bool _throttleUpdates; 68 private bool _throttleUpdates;
69 private bool _isColliding;
70 private bool _collidingGround;
71 private bool _collidingObj;
72 private bool _floatOnWater; 69 private bool _floatOnWater;
73 private OMV.Vector3 _rotationalVelocity; 70 private OMV.Vector3 _rotationalVelocity;
74 private bool _kinematic; 71 private bool _kinematic;
@@ -76,13 +73,14 @@ public sealed class BSPrim : BSPhysObject
76 73
77 private BSDynamics _vehicle; 74 private BSDynamics _vehicle;
78 75
76 private BSVMotor _targetMotor;
79 private OMV.Vector3 _PIDTarget; 77 private OMV.Vector3 _PIDTarget;
80 private bool _usePID;
81 private float _PIDTau; 78 private float _PIDTau;
82 private bool _useHoverPID; 79
80 private BSFMotor _hoverMotor;
83 private float _PIDHoverHeight; 81 private float _PIDHoverHeight;
84 private PIDHoverType _PIDHoverType; 82 private PIDHoverType _PIDHoverType;
85 private float _PIDHoverTao; 83 private float _PIDHoverTau;
86 84
87 public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, 85 public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
88 OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) 86 OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
@@ -564,6 +562,11 @@ public sealed class BSPrim : BSPhysObject
564 } 562 }
565 return; 563 return;
566 } 564 }
565 public OMV.Vector3 RawVelocity
566 {
567 get { return _velocity; }
568 set { _velocity = value; }
569 }
567 public override OMV.Vector3 Velocity { 570 public override OMV.Vector3 Velocity {
568 get { return _velocity; } 571 get { return _velocity; }
569 set { 572 set {
@@ -1004,13 +1007,99 @@ public sealed class BSPrim : BSPhysObject
1004 set { _PIDTau = value; } 1007 set { _PIDTau = value; }
1005 } 1008 }
1006 public override bool PIDActive { 1009 public override bool PIDActive {
1007 set { _usePID = value; } 1010 set {
1011 if (value)
1012 {
1013 // We're taking over after this.
1014 ZeroMotion(true);
1015
1016 _targetMotor = new BSVMotor("BSPrim.PIDTarget",
1017 _PIDTau, // timeScale
1018 BSMotor.Infinite, // decay time scale
1019 BSMotor.InfiniteVector, // friction timescale
1020 1f // efficiency
1021 );
1022 _targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
1023 _targetMotor.SetTarget(_PIDTarget);
1024 _targetMotor.SetCurrent(RawPosition);
1025 /*
1026 _targetMotor = new BSPIDVMotor("BSPrim.PIDTarget");
1027 _targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
1028
1029 _targetMotor.SetTarget(_PIDTarget);
1030 _targetMotor.SetCurrent(RawPosition);
1031 _targetMotor.TimeScale = _PIDTau;
1032 _targetMotor.Efficiency = 1f;
1033 */
1034
1035 RegisterPreStepAction("BSPrim.PIDTarget", LocalID, delegate(float timeStep)
1036 {
1037 OMV.Vector3 origPosition = RawPosition; // DEBUG DEBUG (for printout below)
1038
1039 // 'movePosition' is where we'd like the prim to be at this moment.
1040 OMV.Vector3 movePosition = _targetMotor.Step(timeStep);
1041
1042 // If we are very close to our target, turn off the movement motor.
1043 if (_targetMotor.ErrorIsZero())
1044 {
1045 DetailLog("{0},BSPrim.PIDTarget,zeroMovement,movePos={1},pos={2},mass={3}",
1046 LocalID, movePosition, RawPosition, Mass);
1047 ForcePosition = _targetMotor.TargetValue;
1048 _targetMotor.Enabled = false;
1049 }
1050 else
1051 {
1052 ForcePosition = movePosition;
1053 }
1054 DetailLog("{0},BSPrim.PIDTarget,move,fromPos={1},movePos={2}", LocalID, origPosition, movePosition);
1055 });
1056 }
1057 else
1058 {
1059 // Stop any targetting
1060 UnRegisterPreStepAction("BSPrim.PIDTarget", LocalID);
1061 }
1062 }
1008 } 1063 }
1009 1064
1010 // Used for llSetHoverHeight and maybe vehicle height 1065 // Used for llSetHoverHeight and maybe vehicle height
1011 // Hover Height will override MoveTo target's Z 1066 // Hover Height will override MoveTo target's Z
1012 public override bool PIDHoverActive { 1067 public override bool PIDHoverActive {
1013 set { _useHoverPID = value; } 1068 set {
1069 if (value)
1070 {
1071 // Turning the target on
1072 _hoverMotor = new BSFMotor("BSPrim.Hover",
1073 _PIDHoverTau, // timeScale
1074 BSMotor.Infinite, // decay time scale
1075 BSMotor.Infinite, // friction timescale
1076 1f // efficiency
1077 );
1078 _hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight());
1079 _hoverMotor.SetCurrent(RawPosition.Z);
1080 _hoverMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
1081
1082 RegisterPreStepAction("BSPrim.Hover", LocalID, delegate(float timeStep)
1083 {
1084 _hoverMotor.SetCurrent(RawPosition.Z);
1085 _hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight());
1086 float targetHeight = _hoverMotor.Step(timeStep);
1087
1088 // 'targetHeight' is where we'd like the Z of the prim to be at this moment.
1089 // Compute the amount of force to push us there.
1090 float moveForce = (targetHeight - RawPosition.Z) * Mass;
1091 // Undo anything the object thinks it's doing at the moment
1092 moveForce = -RawVelocity.Z * Mass;
1093
1094 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, new OMV.Vector3(0f, 0f, moveForce));
1095 DetailLog("{0},BSPrim.Hover,move,targHt={1},moveForce={2},mass={3}", LocalID, targetHeight, moveForce, Mass);
1096 });
1097 }
1098 else
1099 {
1100 UnRegisterPreStepAction("BSPrim.Hover", LocalID);
1101 }
1102 }
1014 } 1103 }
1015 public override float PIDHoverHeight { 1104 public override float PIDHoverHeight {
1016 set { _PIDHoverHeight = value; } 1105 set { _PIDHoverHeight = value; }
@@ -1019,8 +1108,35 @@ public sealed class BSPrim : BSPhysObject
1019 set { _PIDHoverType = value; } 1108 set { _PIDHoverType = value; }
1020 } 1109 }
1021 public override float PIDHoverTau { 1110 public override float PIDHoverTau {
1022 set { _PIDHoverTao = value; } 1111 set { _PIDHoverTau = value; }
1023 } 1112 }
1113 // Based on current position, determine what we should be hovering at now.
1114 // Must recompute often. What if we walked offa cliff>
1115 private float ComputeCurrentPIDHoverHeight()
1116 {
1117 float ret = _PIDHoverHeight;
1118 float groundHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
1119
1120 switch (_PIDHoverType)
1121 {
1122 case PIDHoverType.Ground:
1123 ret = groundHeight + _PIDHoverHeight;
1124 break;
1125 case PIDHoverType.GroundAndWater:
1126 float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(RawPosition);
1127 if (groundHeight > waterHeight)
1128 {
1129 ret = groundHeight + _PIDHoverHeight;
1130 }
1131 else
1132 {
1133 ret = waterHeight + _PIDHoverHeight;
1134 }
1135 break;
1136 }
1137 return ret;
1138 }
1139
1024 1140
1025 // For RotLookAt 1141 // For RotLookAt
1026 public override OMV.Quaternion APIDTarget { set { return; } } 1142 public override OMV.Quaternion APIDTarget { set { return; } }
@@ -1037,7 +1153,7 @@ public sealed class BSPrim : BSPhysObject
1037 // This added force will only last the next simulation tick. 1153 // This added force will only last the next simulation tick.
1038 public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { 1154 public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
1039 // for an object, doesn't matter if force is a pushforce or not 1155 // for an object, doesn't matter if force is a pushforce or not
1040 if (force.IsFinite()) 1156 if (!IsStatic && force.IsFinite())
1041 { 1157 {
1042 float magnitude = force.Length(); 1158 float magnitude = force.Length();
1043 if (magnitude > BSParam.MaxAddForceMagnitude) 1159 if (magnitude > BSParam.MaxAddForceMagnitude)
@@ -1047,7 +1163,7 @@ public sealed class BSPrim : BSPhysObject
1047 } 1163 }
1048 1164
1049 OMV.Vector3 addForce = force; 1165 OMV.Vector3 addForce = force;
1050 DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); 1166 // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce);
1051 1167
1052 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() 1168 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate()
1053 { 1169 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index a7855f0..b4f764b 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -453,6 +453,7 @@ public sealed class BSShapeCollection : IDisposable
453 // If the prim attributes are simple, this could be a simple Bullet native shape 453 // If the prim attributes are simple, this could be a simple Bullet native shape
454 if (!haveShape 454 if (!haveShape
455 && pbs != null 455 && pbs != null
456 && !pbs.SculptEntry
456 && nativeShapePossible 457 && nativeShapePossible
457 && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) 458 && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim)
458 || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 459 || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
index a8a4ff5..facf720 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
@@ -1,22 +1,26 @@
1CURRENT PRIORITIES 1CURRENT PRIORITIES
2================================================= 2=================================================
3Redo BulletSimAPI to allow native C# implementation of Bullet option. 3Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE)
4Meshes rendering as bounding boxes
5llMoveToTarget
6Vehicle movement on terrain smoothness
7limitMotorUp calibration (more down?)
8Preferred orientatino angular correction fix
9Surfboard go wonky when turning
10 Angular motor direction is global coordinates rather than local coordinates?
11Boats float low in the water
4Avatar movement 12Avatar movement
5 flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle 13 flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE)
6 walking up stairs is not calibrated correctly (stairs out of Kepler cabin) 14 walking up stairs is not calibrated correctly (stairs out of Kepler cabin)
7 avatar capsule rotation completed 15 avatar capsule rotation completed (NOT DONE - Bullet's capsule shape is not the solution)
8llMoveToTarget
9Enable vehicle border crossings (at least as poorly as ODE) 16Enable vehicle border crossings (at least as poorly as ODE)
10 Terrain skirts 17 Terrain skirts
11 Avatar created in previous region and not new region when crossing border 18 Avatar created in previous region and not new region when crossing border
12 Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) 19 Vehicle recreated in new sim at small Z value (offset from root value?) (DONE)
13Vehicle movement on terrain smoothness
14Vehicle script tuning/debugging 20Vehicle script tuning/debugging
15 Avanti speed script 21 Avanti speed script
16 Weapon shooter script 22 Weapon shooter script
17limitMotorUp calibration (more down?) 23Add material densities to the material types
18Boats float low in the water
19Add material densities to the material types.
20 24
21CRASHES 25CRASHES
22================================================= 26=================================================