diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 136 |
1 files changed, 52 insertions, 84 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 4981007..5c61774 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -511,21 +511,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
511 | // Do any updating needed for a vehicle | 511 | // Do any updating needed for a vehicle |
512 | public void Refresh() | 512 | public void Refresh() |
513 | { | 513 | { |
514 | /* | ||
515 | * Doesnt work unless BSDynamics senses and corrects for all collisions | ||
516 | if (IsActive) | ||
517 | BulletSimAPI.AddToCollisionFlags2(Prim.BSBody.ptr, CollisionFlags.CF_KINEMATIC_OBJECT); | ||
518 | else | ||
519 | BulletSimAPI.RemoveFromCollisionFlags2(Prim.BSBody.ptr, CollisionFlags.CF_KINEMATIC_OBJECT); | ||
520 | */ | ||
521 | /* | ||
522 | * Doesn't work because with zero inertia, Bullet will not apply any forces to the object. | ||
523 | if (IsActive) | ||
524 | { | ||
525 | BulletSimAPI.SetMassProps2(Prim.BSBody.ptr, Prim.MassRaw, Vector3.Zero); | ||
526 | BulletSimAPI.UpdateInertiaTensor2(Prim.BSBody.ptr); | ||
527 | } | ||
528 | */ | ||
529 | if (IsActive) | 514 | if (IsActive) |
530 | { | 515 | { |
531 | // Friction effects are handled by this vehicle code | 516 | // Friction effects are handled by this vehicle code |
@@ -539,29 +524,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
539 | { | 524 | { |
540 | if (!IsActive) return; | 525 | if (!IsActive) return; |
541 | 526 | ||
542 | m_lastAngularVelocity = Prim.ForceRotationalVelocity; // DEBUG: account for what Bullet did last time | 527 | // DEBUG |
528 | // Because Bullet does apply forces to the vehicle, our last computed | ||
529 | // linear and angular velocities are not what is happening now. | ||
530 | // Vector3 externalAngularVelocity = Prim.ForceRotationalVelocity - m_lastAngularVelocity; | ||
531 | // m_lastAngularVelocity += (externalAngularVelocity * 0.5f) * pTimestep; | ||
532 | // m_lastAngularVelocity = Prim.ForceRotationalVelocity; // DEBUG: account for what Bullet did last time | ||
533 | // m_lastLinearVelocityVector = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG: | ||
534 | // END DEBUG | ||
543 | 535 | ||
544 | MoveLinear(pTimestep); | 536 | MoveLinear(pTimestep); |
545 | MoveAngular(pTimestep); | 537 | MoveAngular(pTimestep); |
546 | LimitRotation(pTimestep); | 538 | LimitRotation(pTimestep); |
547 | 539 | ||
548 | /* Experimental | ||
549 | // Wonder if Bullet could handle collision penetration while this applies the forces. | ||
550 | // Apply the computed forces on the vehicle | ||
551 | Prim.ForcePosition += Prim.ForceVelocity * Prim.MassRaw * pTimestep; | ||
552 | |||
553 | if (Prim.ForceRotationalVelocity != Vector3.Zero) | ||
554 | { | ||
555 | Quaternion newOrientation = Prim.ForceOrientation; | ||
556 | newOrientation.Normalize(); | ||
557 | Quaternion appliedRotation = new Quaternion((Prim.ForceRotationalVelocity * pTimestep), 0f); | ||
558 | newOrientation += (appliedRotation * newOrientation) * 0.5f; | ||
559 | newOrientation.Normalize(); | ||
560 | Prim.ForceOrientation = newOrientation; | ||
561 | } | ||
562 | */ | ||
563 | // DEBUG: Trying to figure out why Bullet goes crazy when the root prim is moved. | 540 | // DEBUG: Trying to figure out why Bullet goes crazy when the root prim is moved. |
564 | BulletSimAPI.SetInterpolationVelocity2(Prim.BSBody.ptr, m_newVelocity, m_lastAngularVelocity); // DEBUG DEBUG DEBUG | 541 | // BulletSimAPI.SetInterpolationVelocity2(Prim.BSBody.ptr, m_newVelocity, m_lastAngularVelocity); // DEBUG DEBUG DEBUG |
565 | 542 | ||
566 | // remember the position so next step we can limit absolute movement effects | 543 | // remember the position so next step we can limit absolute movement effects |
567 | m_lastPositionVector = Prim.ForcePosition; | 544 | m_lastPositionVector = Prim.ForcePosition; |
@@ -583,7 +560,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
583 | Vector3 vehicleVelocity = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG | 560 | Vector3 vehicleVelocity = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG |
584 | 561 | ||
585 | // add drive to body | 562 | // add drive to body |
586 | Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale / pTimestep); | 563 | Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale) * pTimestep; |
587 | // lastLinearVelocityVector is the current body velocity vector | 564 | // lastLinearVelocityVector is the current body velocity vector |
588 | m_lastLinearVelocityVector += addAmount; | 565 | m_lastLinearVelocityVector += addAmount; |
589 | 566 | ||
@@ -593,11 +570,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
593 | Vector3 frictionFactor = (Vector3.One / m_linearFrictionTimescale) * pTimestep; | 570 | Vector3 frictionFactor = (Vector3.One / m_linearFrictionTimescale) * pTimestep; |
594 | m_lastLinearVelocityVector *= (Vector3.One - frictionFactor); | 571 | m_lastLinearVelocityVector *= (Vector3.One - frictionFactor); |
595 | 572 | ||
596 | VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},vehVel={3},add={4},decay={5},lmDir={6},lmVel={7}", | 573 | // Rotate new object velocity from vehicle relative to world coordinates |
597 | Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, m_linearMotorDirection, m_lastLinearVelocityVector); | ||
598 | |||
599 | // convert requested object velocity to object relative vector | ||
600 | m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation; | 574 | m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation; |
575 | |||
576 | VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},vehVel={3},add={4},decay={5},frict={6},lmDir={7},lmVel={8},newVel={9}", | ||
577 | Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, frictionFactor, | ||
578 | m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity); | ||
601 | } | 579 | } |
602 | else | 580 | else |
603 | { | 581 | { |
@@ -609,18 +587,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
609 | VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID); | 587 | VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID); |
610 | } | 588 | } |
611 | 589 | ||
612 | // m_newVelocity is velocity computed from linear motor | 590 | // m_newVelocity is velocity computed from linear motor in world coordinates |
613 | 591 | ||
614 | // Add the various forces into m_dir which will be our new direction vector (velocity) | 592 | // Gravity and Buoyancy |
615 | |||
616 | // add Gravity and Buoyancy | ||
617 | // There is some gravity, make a gravity force vector that is applied after object velocity. | 593 | // There is some gravity, make a gravity force vector that is applied after object velocity. |
618 | // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; | 594 | // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; |
619 | // Vector3 grav = Prim.PhysicsScene.DefaultGravity * (Prim.Linkset.LinksetMass * (1f - m_VehicleBuoyancy)); | ||
620 | Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); | 595 | Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); |
621 | 596 | ||
622 | /* | 597 | /* |
623 | * RA: Not sure why one would do this | 598 | * RA: Not sure why one would do this unless we are hoping external forces are doing gravity, ... |
624 | // Preserve the current Z velocity | 599 | // Preserve the current Z velocity |
625 | Vector3 vel_now = m_prim.Velocity; | 600 | Vector3 vel_now = m_prim.Velocity; |
626 | m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity | 601 | m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity |
@@ -676,7 +651,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
676 | else | 651 | else |
677 | { | 652 | { |
678 | float verticalError = pos.Z - m_VhoverTargetHeight; | 653 | float verticalError = pos.Z - m_VhoverTargetHeight; |
679 | // RA: where does the 50 come from> | 654 | // RA: where does the 50 come from? |
680 | float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale); | 655 | float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale); |
681 | // Replace Vertical speed with correction figure if significant | 656 | // Replace Vertical speed with correction figure if significant |
682 | if (Math.Abs(verticalError) > 0.01f) | 657 | if (Math.Abs(verticalError) > 0.01f) |
@@ -784,37 +759,24 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
784 | // m_angularFrictionTimescale // body angular velocity decay rate | 759 | // m_angularFrictionTimescale // body angular velocity decay rate |
785 | // m_lastAngularVelocity // what was last applied to body | 760 | // m_lastAngularVelocity // what was last applied to body |
786 | 761 | ||
787 | // Get what the body is doing, this includes 'external' influences | 762 | if (m_angularMotorDirection.LengthSquared() > 0.0001) |
788 | Vector3 angularVelocity = Prim.ForceRotationalVelocity; | ||
789 | |||
790 | if (m_angularMotorApply > 0) | ||
791 | { | 763 | { |
792 | // Rather than snapping the angular motor velocity from the old value to | ||
793 | // a newly set velocity, this routine steps the value from the previous | ||
794 | // value (m_angularMotorVelocity) to the requested value (m_angularMotorDirection). | ||
795 | // There are m_angularMotorApply steps. | ||
796 | Vector3 origVel = m_angularMotorVelocity; | 764 | Vector3 origVel = m_angularMotorVelocity; |
797 | Vector3 origDir = m_angularMotorDirection; | 765 | Vector3 origDir = m_angularMotorDirection; |
798 | 766 | ||
799 | // ramp up to new value | ||
800 | // new velocity += error / ( time to get there / step interval) | 767 | // new velocity += error / ( time to get there / step interval) |
801 | // requested speed - last motor speed | 768 | // requested speed - last motor speed |
802 | m_angularMotorVelocity += (m_angularMotorDirection - m_angularMotorVelocity) / (m_angularMotorTimescale / pTimestep); | 769 | m_angularMotorVelocity += (m_angularMotorDirection - m_angularMotorVelocity) / (m_angularMotorTimescale / pTimestep); |
770 | // decay requested direction | ||
771 | m_angularMotorDirection *= (1.0f - (pTimestep * 1.0f/m_angularMotorDecayTimescale)); | ||
803 | 772 | ||
804 | VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},angTScale={2},timeStep={3},origvel={4},origDir={5},vel={6}", | 773 | VDetailLog("{0},MoveAngular,angularMotorApply,angTScale={1},timeStep={2},origvel={3},origDir={4},vel={5}", |
805 | Prim.LocalID, m_angularMotorApply, m_angularMotorTimescale, pTimestep, origVel, origDir, m_angularMotorVelocity); | 774 | Prim.LocalID, m_angularMotorTimescale, pTimestep, origVel, origDir, m_angularMotorVelocity); |
806 | |||
807 | m_angularMotorApply--; | ||
808 | } | 775 | } |
809 | else | 776 | else |
810 | { | 777 | { |
811 | // No motor recently applied, keep the body velocity | 778 | m_angularMotorVelocity = Vector3.Zero; |
812 | // and decay the velocity | 779 | } |
813 | if (m_angularMotorVelocity.LengthSquared() < 0.0001) | ||
814 | m_angularMotorVelocity = Vector3.Zero; | ||
815 | else | ||
816 | m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); | ||
817 | } // end motor section | ||
818 | 780 | ||
819 | #region Vertical attactor | 781 | #region Vertical attactor |
820 | 782 | ||
@@ -824,22 +786,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
824 | 786 | ||
825 | if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) | 787 | if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) |
826 | { | 788 | { |
827 | float VAservo = 0.2f; | 789 | float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale; |
828 | if (Prim.Linkset.LinksetIsColliding) | 790 | if (Prim.Linkset.LinksetIsColliding) |
829 | VAservo = 0.05f / (m_verticalAttractionTimescale / pTimestep); | 791 | VAservo = pTimestep * 0.05f / (m_verticalAttractionTimescale); |
830 | 792 | ||
831 | VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); | 793 | VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); |
832 | 794 | ||
833 | // get present body rotation | 795 | // Create a vector of the vehicle "up" in world coordinates |
834 | Quaternion rotq = Prim.ForceOrientation; | 796 | Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; |
835 | // vector pointing up | 797 | // verticalError.X and .Y are the World error amounts. They are 0 when there is no |
836 | Vector3 verticalError = Vector3.UnitZ; | 798 | // error (Vehicle Body is 'vertical'), and .Z will be 1. As the body leans to its |
837 | 799 | // side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall | |
838 | // rotate it to Body Angle | 800 | // and .Z will go // negative. Similar for tilt and |.Y|. .X and .Y must be |
839 | verticalError = verticalError * rotq; | 801 | // modulated to prevent a stable inverted body. |
840 | // verticalError.X and .Y are the World error amounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. | ||
841 | // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go | ||
842 | // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. | ||
843 | 802 | ||
844 | // Error is 0 (no error) to +/- 2 (max error) | 803 | // Error is 0 (no error) to +/- 2 (max error) |
845 | if (verticalError.Z < 0.0f) | 804 | if (verticalError.Z < 0.0f) |
@@ -850,13 +809,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
850 | // scale it by VAservo | 809 | // scale it by VAservo |
851 | verticalError = verticalError * VAservo; | 810 | verticalError = verticalError * VAservo; |
852 | 811 | ||
853 | // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y then .X increases, so | 812 | // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y |
854 | // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. | 813 | // then .X increases, so change Body angular velocity X based on Y, and Y based on X. |
814 | // Z is not changed. | ||
855 | vertattr.X = verticalError.Y; | 815 | vertattr.X = verticalError.Y; |
856 | vertattr.Y = - verticalError.X; | 816 | vertattr.Y = - verticalError.X; |
857 | vertattr.Z = 0f; | 817 | vertattr.Z = 0f; |
858 | 818 | ||
859 | // scaling appears better usingsquare-law | 819 | // scaling appears better usingsquare-law |
820 | Vector3 angularVelocity = Prim.ForceRotationalVelocity; | ||
860 | float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); | 821 | float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); |
861 | vertattr.X += bounce * angularVelocity.X; | 822 | vertattr.X += bounce * angularVelocity.X; |
862 | vertattr.Y += bounce * angularVelocity.Y; | 823 | vertattr.Y += bounce * angularVelocity.Y; |
@@ -956,15 +917,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
956 | VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); | 917 | VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); |
957 | } | 918 | } |
958 | 919 | ||
959 | // apply friction | ||
960 | Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep); | ||
961 | m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; | ||
962 | |||
963 | // Apply to the body | 920 | // Apply to the body |
964 | // The above calculates the absolute angular velocity needed | 921 | // The above calculates the absolute angular velocity needed |
965 | Prim.ForceRotationalVelocity = m_lastAngularVelocity; | 922 | // Prim.ForceRotationalVelocity = m_lastAngularVelocity; |
923 | |||
924 | // Apply a force to overcome current angular velocity | ||
925 | Vector3 applyAngularForce = (m_lastAngularVelocity - Prim.ForceRotationalVelocity) * Prim.Linkset.LinksetMass; | ||
926 | // Vector3 applyAngularForce = (m_lastAngularVelocity - Prim.ForceRotationalVelocity); | ||
927 | // Prim.AddAngularForce(applyAngularForce, false); | ||
928 | Prim.ApplyTorqueImpulse(applyAngularForce, false); | ||
929 | |||
930 | // Apply friction for next time | ||
931 | Vector3 decayamount = (Vector3.One / m_angularFrictionTimescale) * pTimestep; | ||
932 | m_lastAngularVelocity *= Vector3.One - decayamount; | ||
966 | 933 | ||
967 | VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", Prim.LocalID, decayamount, m_lastAngularVelocity); | 934 | VDetailLog("{0},MoveAngular,done,applyAForce={1},decay={2},lastAngular={3}", |
935 | Prim.LocalID, applyAngularForce, decayamount, m_lastAngularVelocity); | ||
968 | } //end MoveAngular | 936 | } //end MoveAngular |
969 | 937 | ||
970 | internal void LimitRotation(float timestep) | 938 | internal void LimitRotation(float timestep) |