aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authornlin2009-09-18 11:26:52 +0900
committernlin2009-09-18 11:39:08 +0900
commit56edbe9b60e5ed5f1388e2d1d4d2a0d82cdeaf6d (patch)
tree0695c869ccdd523470a68c3462e0b96dbd910f7f
parentRemove the methods for full inventory fetch from the connector. Remove tests (diff)
downloadopensim-SC-56edbe9b60e5ed5f1388e2d1d4d2a0d82cdeaf6d.zip
opensim-SC-56edbe9b60e5ed5f1388e2d1d4d2a0d82cdeaf6d.tar.gz
opensim-SC-56edbe9b60e5ed5f1388e2d1d4d2a0d82cdeaf6d.tar.bz2
opensim-SC-56edbe9b60e5ed5f1388e2d1d4d2a0d82cdeaf6d.tar.xz
Alternate algorithm for fixing avatar capsule tilt (Mantis #2905)
Eliminate dynamic capsule wobble. Instead introduce a small, fixed tilt, and allow the tilt to rotate with the avatar while moving; the tilt always faces away from the direction of avatar movement. The rotation while moving should eliminate direction-dependent behavior (e.g. only being able to climb on top of prims from certain directions). Falling animation is still too frequently invoked. Ideally the tilt should be completely eliminated, but doing so currently causes the avatar to fall through the terrain.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs2
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs132
2 files changed, 73 insertions, 61 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 23fe2d3..6772f75 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2269,7 +2269,7 @@ namespace OpenSim.Region.Framework.Scenes
2269 { 2269 {
2270 //Record the time we enter this state so we know whether to "land" or not 2270 //Record the time we enter this state so we know whether to "land" or not
2271 m_animPersistUntil = DateTime.Now.Ticks; 2271 m_animPersistUntil = DateTime.Now.Ticks;
2272 return "FALLDOWN"; 2272 return "FALLDOWN"; // this falling animation is invoked too frequently when capsule tilt correction is used - why?
2273 } 2273 }
2274 } 2274 }
2275 } 2275 }
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index dd58a4e..a00ba11 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -107,6 +107,7 @@ namespace OpenSim.Region.Physics.OdePlugin
107 public float MinimumGroundFlightOffset = 3f; 107 public float MinimumGroundFlightOffset = 3f;
108 108
109 private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes. 109 private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes.
110 private float m_tiltMagnitudeWhenProjectedOnXYPlane = 0.1131371f; // used to introduce a fixed tilt because a straight-up capsule falls through terrain, probably a bug in terrain collider
110 111
111 112
112 private float m_buoyancy = 0f; 113 private float m_buoyancy = 0f;
@@ -477,7 +478,71 @@ namespace OpenSim.Region.Physics.OdePlugin
477 } 478 }
478 } 479 }
479 } 480 }
480 481
482 private void AlignAvatarTiltWithCurrentDirectionOfMovement(PhysicsVector movementVector)
483 {
484 movementVector.Z = 0f;
485 float magnitude = (float)Math.Sqrt((double)(movementVector.X * movementVector.X + movementVector.Y * movementVector.Y));
486 if (magnitude < 0.1f) return;
487
488 // normalize the velocity vector
489 float invMagnitude = 1.0f / magnitude;
490 movementVector.X *= invMagnitude;
491 movementVector.Y *= invMagnitude;
492
493 // if we change the capsule heading too often, the capsule can fall down
494 // therefore we snap movement vector to just 1 of 4 predefined directions (ne, nw, se, sw),
495 // meaning only 4 possible capsule tilt orientations
496 if (movementVector.X > 0)
497 {
498 // east
499 if (movementVector.Y > 0)
500 {
501 // northeast
502 movementVector.X = (float)Math.Sqrt(2.0);
503 movementVector.Y = (float)Math.Sqrt(2.0);
504 }
505 else
506 {
507 // southeast
508 movementVector.X = (float)Math.Sqrt(2.0);
509 movementVector.Y = -(float)Math.Sqrt(2.0);
510 }
511 }
512 else
513 {
514 // west
515 if (movementVector.Y > 0)
516 {
517 // northwest
518 movementVector.X = -(float)Math.Sqrt(2.0);
519 movementVector.Y = (float)Math.Sqrt(2.0);
520 }
521 else
522 {
523 // southwest
524 movementVector.X = -(float)Math.Sqrt(2.0);
525 movementVector.Y = -(float)Math.Sqrt(2.0);
526 }
527 }
528
529
530 // movementVector.Z is zero
531
532 // calculate tilt components based on desired amount of tilt and current (snapped) heading.
533 // the "-" sign is to force the tilt to be OPPOSITE the direction of movement.
534 float xTiltComponent = -movementVector.X * m_tiltMagnitudeWhenProjectedOnXYPlane;
535 float yTiltComponent = -movementVector.Y * m_tiltMagnitudeWhenProjectedOnXYPlane;
536
537 //m_log.Debug("[PHYSICS] changing avatar tilt");
538 d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, xTiltComponent);
539 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, xTiltComponent); // must be same as lowstop, else a different, spurious tilt is introduced
540 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, yTiltComponent);
541 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, yTiltComponent); // same as lowstop
542 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, 0f);
543 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop
544 }
545
481 /// <summary> 546 /// <summary>
482 /// This creates the Avatar's physical Surrogate at the position supplied 547 /// This creates the Avatar's physical Surrogate at the position supplied
483 /// </summary> 548 /// </summary>
@@ -576,71 +641,13 @@ namespace OpenSim.Region.Physics.OdePlugin
576 // (with -0..0 motor stops) falls into the terrain for reasons yet 641 // (with -0..0 motor stops) falls into the terrain for reasons yet
577 // to be comprehended in their entirety. 642 // to be comprehended in their entirety.
578 #endregion 643 #endregion
644 AlignAvatarTiltWithCurrentDirectionOfMovement(new PhysicsVector(0,0,0));
579 d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f); 645 d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f);
580 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f); 646 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f);
581 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f); 647 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f);
582 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.08f); // must be same as lowstop, else a different, spurious tilt is introduced 648 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.08f); // must be same as lowstop, else a different, spurious tilt is introduced
583 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop 649 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop
584 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop 650 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop
585 #region Documentation of capsule motor StopERP and StopCFM parameters
586 // In addition to the above tilt, we allow a dynamic tilt, or
587 // wobble, to emerge as the capsule is pushed around the environment.
588 // We do this with an experimentally determined combination of
589 // StopERP and StopCFM which make the above motor stops soft.
590 // The softness of the stops should be tweaked according to two
591 // requirements:
592 //
593 // 1. Motor stops should be weak enough to allow enough wobble such
594 // that the capsule can tilt slightly more when moving, to allow
595 // "gliding" over obstacles:
596 //
597 //
598 // .-.
599 // / /
600 // / /
601 // _ / / _
602 // / \ .-. / / / \
603 // | | ----> / / / / | |
604 // | | / / `-' | |
605 // | | / / +------+ | |
606 // | | / / | | | |
607 // | | / / | | | |
608 // \_/ `-' +------+ \_/
609 // ----------------------------------------------------------
610 //
611 // Note that requirement 1 is made complicated by the ever-present
612 // slight avatar tilt (assigned in the above code to prevent avatar
613 // from falling through terrain), which introduces a direction-dependent
614 // bias into the wobble (wobbling against the existing tilt is harder
615 // than wobbling with the tilt), which makes it easier to walk over
616 // prims from some directions. I have tried to minimize this effect by
617 // minimizing the avatar tilt to the minimum that prevents the avatar from
618 // falling through the terrain.
619 //
620 // 2. Motor stops should be strong enough to prevent the capsule
621 // from being forced all the way to the ground; otherwise the
622 // capsule could slip underneath obstacles like this:
623 // _ _
624 // / \ +------+ / \
625 // | | ----> | | | |
626 // | | | | | |
627 // | | .--.___ +------+ | |
628 // | | `--.__`--.__ | |
629 // | | `--.__`--. | |
630 // \_/ `--' \_/
631 // ----------------------------------------------------------
632 //
633 //
634 // It is strongly recommended you enable USE_DRAWSTUFF if you want to
635 // tweak these values, to see how the capsule is reacting in various
636 // situations.
637 #endregion
638 d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0.0035f);
639 d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0.0035f);
640 d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0.0035f);
641 d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f);
642 d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f);
643 d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f);
644 } 651 }
645 652
646 // Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the 653 // Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the
@@ -939,6 +946,7 @@ namespace OpenSim.Region.Physics.OdePlugin
939 946
940 PhysicsVector vec = new PhysicsVector(); 947 PhysicsVector vec = new PhysicsVector();
941 d.Vector3 vel = d.BodyGetLinearVel(Body); 948 d.Vector3 vel = d.BodyGetLinearVel(Body);
949
942 float movementdivisor = 1f; 950 float movementdivisor = 1f;
943 951
944 if (!m_alwaysRun) 952 if (!m_alwaysRun)
@@ -1052,6 +1060,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1052 if (PhysicsVector.isFinite(vec)) 1060 if (PhysicsVector.isFinite(vec))
1053 { 1061 {
1054 doForce(vec); 1062 doForce(vec);
1063 if (!_zeroFlag)
1064 {
1065 AlignAvatarTiltWithCurrentDirectionOfMovement(new PhysicsVector(vec.X, vec.Y, vec.Z));
1066 }
1055 } 1067 }
1056 else 1068 else
1057 { 1069 {