aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorRobert Adams2012-11-06 18:10:06 -0800
committerRobert Adams2012-11-06 18:16:47 -0800
commitee00c5c8851dd364acef858f3fd9f5164797fc1e (patch)
treece43c7624d1f4b85db821346425dd9c51da6146a /OpenSim
parentBulletSim: Add ZeroAngularMotion method to physical objects. Add inTaint flag... (diff)
downloadopensim-SC-ee00c5c8851dd364acef858f3fd9f5164797fc1e.zip
opensim-SC-ee00c5c8851dd364acef858f3fd9f5164797fc1e.tar.gz
opensim-SC-ee00c5c8851dd364acef858f3fd9f5164797fc1e.tar.bz2
opensim-SC-ee00c5c8851dd364acef858f3fd9f5164797fc1e.tar.xz
BulletSim: many changes to tune vehicles for BulletSim.
The problem left is that the vehicle sitting on something needs to press down for gravity and what its sitting on pushes up so the vehicle does not penetrate. The effect is Bullet calculates a lot of random angular motion for the vehicle. Various schemes of damping and zeroing has not resolved the problem.
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs224
1 files changed, 161 insertions, 63 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 819635a..dbc9039 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -54,10 +54,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
54{ 54{
55 public sealed class BSDynamics 55 public sealed class BSDynamics
56 { 56 {
57 private static string LogHeader = "[BULLETSIM VEHICLE]";
58
57 private BSScene PhysicsScene { get; set; } 59 private BSScene PhysicsScene { get; set; }
58 // the prim this dynamic controller belongs to 60 // the prim this dynamic controller belongs to
59 private BSPrim Prim { get; set; } 61 private BSPrim Prim { get; set; }
60 62
63 // mass of the vehicle fetched each time we're calles
64 private float m_vehicleMass;
65
61 // Vehicle properties 66 // Vehicle properties
62 public Vehicle Type { get; set; } 67 public Vehicle Type { get; set; }
63 68
@@ -516,7 +521,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin
516 // Friction effects are handled by this vehicle code 521 // Friction effects are handled by this vehicle code
517 BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, 0f); 522 BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, 0f);
518 BulletSimAPI.SetHitFraction2(Prim.PhysBody.ptr, 0f); 523 BulletSimAPI.SetHitFraction2(Prim.PhysBody.ptr, 0f);
524
525 // BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, 0.8f);
526
527 VDetailLog("{0},BSDynamics.Refresh,zeroingFriction and adding damping", Prim.LocalID);
528 }
529 }
530
531 public bool RemoveBodyDependencies(BSPhysObject prim)
532 {
533 // If active, we need to add our properties back when the body is rebuilt.
534 return IsActive;
535 }
536
537 public void RestoreBodyDependencies(BSPhysObject prim)
538 {
539 if (Prim.LocalID != prim.LocalID)
540 {
541 // The call should be on us by our prim. Error if not.
542 PhysicsScene.Logger.ErrorFormat("{0} RestoreBodyDependencies: called by not my prim. passedLocalID={1}, vehiclePrimLocalID={2}",
543 LogHeader, prim.LocalID, Prim.LocalID);
544 return;
519 } 545 }
546 Refresh();
520 } 547 }
521 548
522 // One step of the vehicle properties for the next 'pTimestep' seconds. 549 // One step of the vehicle properties for the next 'pTimestep' seconds.
@@ -533,16 +560,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
533 // m_lastLinearVelocityVector = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG: 560 // m_lastLinearVelocityVector = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG:
534 // END DEBUG 561 // END DEBUG
535 562
563 m_vehicleMass = Prim.Linkset.LinksetMass;
564
536 MoveLinear(pTimestep); 565 MoveLinear(pTimestep);
566 // Commented out for debug
537 MoveAngular(pTimestep); 567 MoveAngular(pTimestep);
538 LimitRotation(pTimestep); 568 // Prim.ApplyTorqueImpulse(-Prim.RotationalVelocity * m_vehicleMass, false); // DEBUG DEBUG
569 // Prim.ForceRotationalVelocity = -Prim.RotationalVelocity; // DEBUG DEBUG
539 570
540 // DEBUG: Trying to figure out why Bullet goes crazy when the root prim is moved. 571 LimitRotation(pTimestep);
541 // BulletSimAPI.SetInterpolationVelocity2(Prim.BSBody.ptr, m_newVelocity, m_lastAngularVelocity); // DEBUG DEBUG DEBUG
542 572
543 // remember the position so next step we can limit absolute movement effects 573 // remember the position so next step we can limit absolute movement effects
544 m_lastPositionVector = Prim.ForcePosition; 574 m_lastPositionVector = Prim.ForcePosition;
545 575
576 VDetailLog("{0},BSDynamics.Step,frict={1},grav={2},inertia={3},mass={4}", // DEBUG DEBUG
577 Prim.LocalID,
578 BulletSimAPI.GetFriction2(Prim.PhysBody.ptr),
579 BulletSimAPI.GetGravity2(Prim.PhysBody.ptr),
580 Prim.Inertia,
581 m_vehicleMass
582 );
546 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", 583 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
547 Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); 584 Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity);
548 }// end Step 585 }// end Step
@@ -555,25 +592,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
555 // m_lastLinearVelocityVector is the current speed we are moving in that direction 592 // m_lastLinearVelocityVector is the current speed we are moving in that direction
556 if (m_linearMotorDirection.LengthSquared() > 0.001f) 593 if (m_linearMotorDirection.LengthSquared() > 0.001f)
557 { 594 {
558 Vector3 origDir = m_linearMotorDirection; 595 Vector3 origDir = m_linearMotorDirection; // DEBUG
559 Vector3 origVel = m_lastLinearVelocityVector; 596 Vector3 origVel = m_lastLinearVelocityVector; // DEBUG
597 // DEBUG: the vehicle velocity rotated to be relative to vehicle coordinates for comparison
560 Vector3 vehicleVelocity = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG 598 Vector3 vehicleVelocity = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG
561 599
562 // add drive to body 600 // Add (desiredVelocity - lastAppliedVelocity) / howLongItShouldTakeToComplete
563 Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale) * pTimestep; 601 Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale) * pTimestep;
564 // lastLinearVelocityVector is the current body velocity vector
565 m_lastLinearVelocityVector += addAmount; 602 m_lastLinearVelocityVector += addAmount;
566 603
567 float decayFactor = (1.0f / m_linearMotorDecayTimescale) * pTimestep; 604 float decayFactor = (1.0f / m_linearMotorDecayTimescale) * pTimestep;
568 m_linearMotorDirection *= (1f - decayFactor); 605 m_linearMotorDirection *= (1f - decayFactor);
569 606
570 Vector3 frictionFactor = (Vector3.One / m_linearFrictionTimescale) * pTimestep;
571 m_lastLinearVelocityVector *= (Vector3.One - frictionFactor);
572
573 // Rotate new object velocity from vehicle relative to world coordinates 607 // Rotate new object velocity from vehicle relative to world coordinates
574 m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation; 608 m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation;
575 609
576 VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},vehVel={3},add={4},decay={5},frict={6},lmDir={7},lmVel={8},newVel={9}", 610 // Apply friction for next time
611 Vector3 frictionFactor = (Vector3.One / m_linearFrictionTimescale) * pTimestep;
612 m_lastLinearVelocityVector *= (Vector3.One - frictionFactor);
613
614 VDetailLog("{0},MoveLinear,nonZero,origlmDir={1},origlvVel={2},vehVel={3},add={4},decay={5},frict={6},lmDir={7},lvVec={8},newVel={9}",
577 Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, frictionFactor, 615 Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, frictionFactor,
578 m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity); 616 m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity);
579 } 617 }
@@ -607,7 +645,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
607 // If below the terrain, move us above the ground a little. 645 // If below the terrain, move us above the ground a little.
608 float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); 646 float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
609 // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. 647 // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset.
610 // Need to add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass. 648 // TODO: Add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass.
611 // Vector3 rotatedSize = m_prim.Size * m_prim.ForceOrientation; 649 // Vector3 rotatedSize = m_prim.Size * m_prim.ForceOrientation;
612 // if (rotatedSize.Z < terrainHeight) 650 // if (rotatedSize.Z < terrainHeight)
613 if (pos.Z < terrainHeight) 651 if (pos.Z < terrainHeight)
@@ -638,13 +676,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
638 676
639 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) 677 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
640 { 678 {
641 // If body is aready heigher, use its height as target height 679 // If body is already heigher, use its height as target height
642 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; 680 if (pos.Z > m_VhoverTargetHeight)
681 m_VhoverTargetHeight = pos.Z;
643 } 682 }
644 if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) 683 if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
645 { 684 {
646 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2) 685 if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f)
647 { 686 {
687 pos.Z = m_VhoverTargetHeight;
648 Prim.ForcePosition = pos; 688 Prim.ForcePosition = pos;
649 } 689 }
650 } 690 }
@@ -709,25 +749,28 @@ namespace OpenSim.Region.Physics.BulletSPlugin
709 } 749 }
710 } 750 }
711 751
712 // Limit absolute vertical change 752 #region downForce
713 float Zchange = Math.Abs(posChange.Z); 753 Vector3 downForce = Vector3.Zero;
754
714 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) 755 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
715 { 756 {
716 if (Zchange > .3) 757 // If the vehicle is motoring into the sky, get it going back down.
717 grav.Z = (float)(grav.Z * 3); 758 // Is this an angular force or both linear and angular??
718 if (Zchange > .15) 759 float distanceAboveGround = pos.Z - terrainHeight;
719 grav.Z = (float)(grav.Z * 2); 760 if (distanceAboveGround > 2f)
720 if (Zchange > .75) 761 {
721 grav.Z = (float)(grav.Z * 1.5); 762 // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep);
722 if (Zchange > .05) 763 // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
723 grav.Z = (float)(grav.Z * 1.25); 764 downForce = new Vector3(0, 0, -distanceAboveGround);
724 if (Zchange > .025) 765 }
725 grav.Z = (float)(grav.Z * 1.125); 766 // TODO: this calculation is all wrong. From the description at
726 float postemp = (pos.Z - terrainHeight); 767 // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce
727 if (postemp > 2.5f) 768 // has a decay factor. This says this force should
728 grav.Z = (float)(grav.Z * 1.037125); 769 // be computed with a motor.
729 VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", Prim.LocalID, grav); 770 VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}",
771 Prim.LocalID, distanceAboveGround, downForce);
730 } 772 }
773 #endregion // downForce
731 774
732 // If not changing some axis, reduce out velocity 775 // If not changing some axis, reduce out velocity
733 if ((m_flags & (VehicleFlag.NO_X)) != 0) 776 if ((m_flags & (VehicleFlag.NO_X)) != 0)
@@ -737,13 +780,28 @@ namespace OpenSim.Region.Physics.BulletSPlugin
737 if ((m_flags & (VehicleFlag.NO_Z)) != 0) 780 if ((m_flags & (VehicleFlag.NO_Z)) != 0)
738 m_newVelocity.Z = 0; 781 m_newVelocity.Z = 0;
739 782
740 // Apply velocity 783 // Clamp REALLY high or low velocities
784 if (m_newVelocity.LengthSquared() > 1e6f)
785 {
786 m_newVelocity /= m_newVelocity.Length();
787 m_newVelocity *= 1000f;
788 }
789 else if (m_newVelocity.LengthSquared() < 1e-6f)
790 m_newVelocity = Vector3.Zero;
791
792 // Stuff new linear velocity into the vehicle
741 Prim.ForceVelocity = m_newVelocity; 793 Prim.ForceVelocity = m_newVelocity;
742 // Prim.AddForce(m_newVelocity * Prim.Linkset.LinksetMass, false); 794 // Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG
743 Prim.AddForce(grav * Prim.Linkset.LinksetMass, false);
744 795
745 VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4}", 796 Vector3 totalDownForce = downForce + grav;
746 Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav); 797 if (totalDownForce != Vector3.Zero)
798 {
799 Prim.AddForce(totalDownForce * m_vehicleMass, false);
800 // Prim.ApplyForceImpulse(totalDownForce * m_vehicleMass, false);
801 }
802
803 VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}",
804 Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, Prim.Velocity, totalDownForce);
747 805
748 } // end MoveLinear() 806 } // end MoveLinear()
749 807
@@ -765,7 +823,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
765 Vector3 origDir = m_angularMotorDirection; 823 Vector3 origDir = m_angularMotorDirection;
766 824
767 // new velocity += error / ( time to get there / step interval) 825 // new velocity += error / ( time to get there / step interval)
768 // requested speed - last motor speed 826 // requested direction - current vehicle direction
769 m_angularMotorVelocity += (m_angularMotorDirection - m_angularMotorVelocity) / (m_angularMotorTimescale / pTimestep); 827 m_angularMotorVelocity += (m_angularMotorDirection - m_angularMotorVelocity) / (m_angularMotorTimescale / pTimestep);
770 // decay requested direction 828 // decay requested direction
771 m_angularMotorDirection *= (1.0f - (pTimestep * 1.0f/m_angularMotorDecayTimescale)); 829 m_angularMotorDirection *= (1.0f - (pTimestep * 1.0f/m_angularMotorDecayTimescale));
@@ -784,10 +842,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
784 Vector3 deflection = Vector3.Zero; 842 Vector3 deflection = Vector3.Zero;
785 Vector3 banking = Vector3.Zero; 843 Vector3 banking = Vector3.Zero;
786 844
845 // If vertical attaction timescale is reasonable and we applied an angular force last time...
787 if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) 846 if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero)
788 { 847 {
789 float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale; 848 float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale;
790 if (Prim.Linkset.LinksetIsColliding) 849 if (Prim.IsColliding)
791 VAservo = pTimestep * 0.05f / (m_verticalAttractionTimescale); 850 VAservo = pTimestep * 0.05f / (m_verticalAttractionTimescale);
792 851
793 VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); 852 VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
@@ -806,7 +865,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
806 verticalError.X = 2.0f - verticalError.X; 865 verticalError.X = 2.0f - verticalError.X;
807 verticalError.Y = 2.0f - verticalError.Y; 866 verticalError.Y = 2.0f - verticalError.Y;
808 } 867 }
809 // scale it by VAservo 868 // scale it by VAservo (timestep and timescale)
810 verticalError = verticalError * VAservo; 869 verticalError = verticalError * VAservo;
811 870
812 // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y 871 // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y
@@ -822,25 +881,30 @@ namespace OpenSim.Region.Physics.BulletSPlugin
822 vertattr.X += bounce * angularVelocity.X; 881 vertattr.X += bounce * angularVelocity.X;
823 vertattr.Y += bounce * angularVelocity.Y; 882 vertattr.Y += bounce * angularVelocity.Y;
824 883
825 VDetailLog("{0},MoveAngular,verticalAttraction,verticalError={1},bounce={2},vertattr={3}", 884 VDetailLog("{0},MoveAngular,verticalAttraction,VAservo={1},effic={2},verticalError={3},bounce={4},vertattr={5}",
826 Prim.LocalID, verticalError, bounce, vertattr); 885 Prim.LocalID, VAservo, m_verticalAttractionEfficiency, verticalError, bounce, vertattr);
827 886
828 } 887 }
829 #endregion // Vertical attactor 888 #endregion // Vertical attactor
830 889
831 #region Deflection 890 #region Deflection
832 891
833 //Forward is the prefered direction, but if the reference frame has changed, we need to take this into account as well
834 if (m_angularDeflectionEfficiency != 0) 892 if (m_angularDeflectionEfficiency != 0)
835 { 893 {
836 Vector3 preferredAxisOfMotion = 894 // Compute a scaled vector that points in the preferred axis (X direction)
895 Vector3 scaledDefaultDirection =
837 new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0); 896 new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0);
838 preferredAxisOfMotion *= Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); 897 // Adding the current vehicle orientation and reference frame displaces the orientation to the frame.
898 // Rotate the scaled default axix relative to the actual vehicle direction giving where it should point.
899 Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame);
839 900
901 // Scale by efficiency and timescale
840 deflection = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; 902 deflection = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep;
841 903
842 VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", 904 VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}",
843 Prim.LocalID, preferredAxisOfMotion, deflection); 905 Prim.LocalID, preferredAxisOfMotion, deflection);
906 // This deflection computation is not correct.
907 deflection = Vector3.Zero;
844 } 908 }
845 909
846 #endregion 910 #endregion
@@ -875,7 +939,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
875 } 939 }
876 else 940 else
877 banking.Z += (effSquared*(mult*mix))*(m_angularMotorVelocity.X) * 4; 941 banking.Z += (effSquared*(mult*mix))*(m_angularMotorVelocity.X) * 4;
878 if (!Prim.Linkset.LinksetIsColliding && Math.Abs(m_angularMotorVelocity.X) > mix) 942 if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix)
879 //If they are colliding, we probably shouldn't shove the prim around... probably 943 //If they are colliding, we probably shouldn't shove the prim around... probably
880 { 944 {
881 float angVelZ = m_angularMotorVelocity.X*-1; 945 float angVelZ = m_angularMotorVelocity.X*-1;
@@ -904,6 +968,40 @@ namespace OpenSim.Region.Physics.BulletSPlugin
904 // Sum velocities 968 // Sum velocities
905 m_lastAngularVelocity = m_angularMotorVelocity + vertattr + banking + deflection; 969 m_lastAngularVelocity = m_angularMotorVelocity + vertattr + banking + deflection;
906 970
971 #region Linear Motor Offset
972
973 //Offset section
974 if (m_linearMotorOffset != Vector3.Zero)
975 {
976 //Offset of linear velocity doesn't change the linear velocity,
977 // but causes a torque to be applied, for example...
978 //
979 // IIIII >>> IIIII
980 // IIIII >>> IIIII
981 // IIIII >>> IIIII
982 // ^
983 // | Applying a force at the arrow will cause the object to move forward, but also rotate
984 //
985 //
986 // The torque created is the linear velocity crossed with the offset
987
988 // NOTE: this computation does should be in the linear section
989 // because there we know the impulse being applied.
990 Vector3 torqueFromOffset = Vector3.Zero;
991 // torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse);
992 if (float.IsNaN(torqueFromOffset.X))
993 torqueFromOffset.X = 0;
994 if (float.IsNaN(torqueFromOffset.Y))
995 torqueFromOffset.Y = 0;
996 if (float.IsNaN(torqueFromOffset.Z))
997 torqueFromOffset.Z = 0;
998 torqueFromOffset *= m_vehicleMass;
999 Prim.ApplyTorqueImpulse(torqueFromOffset, true);
1000 VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset);
1001 }
1002
1003 #endregion
1004
907 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) 1005 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
908 { 1006 {
909 m_lastAngularVelocity.X = 0; 1007 m_lastAngularVelocity.X = 0;
@@ -914,25 +1012,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin
914 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) 1012 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
915 { 1013 {
916 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. 1014 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
917 VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); 1015 Prim.ZeroAngularMotion(true);
1016 VDetailLog("{0},MoveAngular,zeroAngularMotion,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
1017 }
1018 else
1019 {
1020 // Apply to the body.
1021 // The above calculates the absolute angular velocity needed. Angular velocity is massless.
1022 // Since we are stuffing the angular velocity directly into the object, the computed
1023 // velocity needs to be scaled by the timestep.
1024 Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - Prim.ForceRotationalVelocity);
1025 Prim.ForceRotationalVelocity = applyAngularForce;
1026
1027 // Decay the angular movement for next time
1028 Vector3 decayamount = (Vector3.One / m_angularFrictionTimescale) * pTimestep;
1029 m_lastAngularVelocity *= Vector3.One - decayamount;
1030
1031 VDetailLog("{0},MoveAngular,done,newRotVel={1},decay={2},lastAngular={3}",
1032 Prim.LocalID, applyAngularForce, decayamount, m_lastAngularVelocity);
918 } 1033 }
919
920 // Apply to the body
921 // The above calculates the absolute angular velocity needed
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;
933
934 VDetailLog("{0},MoveAngular,done,applyAForce={1},decay={2},lastAngular={3}",
935 Prim.LocalID, applyAngularForce, decayamount, m_lastAngularVelocity);
936 } //end MoveAngular 1034 } //end MoveAngular
937 1035
938 internal void LimitRotation(float timestep) 1036 internal void LimitRotation(float timestep)