aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs136
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)