aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-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)