diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 187 |
1 files changed, 127 insertions, 60 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index eb20eb3..c197e61 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -57,7 +57,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
57 | private int frcount = 0; // Used to limit dynamics debug output to | 57 | private int frcount = 0; // Used to limit dynamics debug output to |
58 | // every 100th frame | 58 | // every 100th frame |
59 | 59 | ||
60 | // private BSScene m_parentScene = null; | ||
61 | private BSPrim m_prim; // the prim this dynamic controller belongs to | 60 | private BSPrim m_prim; // the prim this dynamic controller belongs to |
62 | 61 | ||
63 | // Vehicle properties | 62 | // Vehicle properties |
@@ -131,8 +130,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
131 | m_type = Vehicle.TYPE_NONE; | 130 | m_type = Vehicle.TYPE_NONE; |
132 | } | 131 | } |
133 | 132 | ||
134 | internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) | 133 | internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep) |
135 | { | 134 | { |
135 | DetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); | ||
136 | switch (pParam) | 136 | switch (pParam) |
137 | { | 137 | { |
138 | case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: | 138 | case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: |
@@ -229,8 +229,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
229 | } | 229 | } |
230 | }//end ProcessFloatVehicleParam | 230 | }//end ProcessFloatVehicleParam |
231 | 231 | ||
232 | internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) | 232 | internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep) |
233 | { | 233 | { |
234 | DetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); | ||
234 | switch (pParam) | 235 | switch (pParam) |
235 | { | 236 | { |
236 | case Vehicle.ANGULAR_FRICTION_TIMESCALE: | 237 | case Vehicle.ANGULAR_FRICTION_TIMESCALE: |
@@ -265,6 +266,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
265 | 266 | ||
266 | internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) | 267 | internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) |
267 | { | 268 | { |
269 | DetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); | ||
268 | switch (pParam) | 270 | switch (pParam) |
269 | { | 271 | { |
270 | case Vehicle.REFERENCE_FRAME: | 272 | case Vehicle.REFERENCE_FRAME: |
@@ -278,6 +280,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
278 | 280 | ||
279 | internal void ProcessVehicleFlags(int pParam, bool remove) | 281 | internal void ProcessVehicleFlags(int pParam, bool remove) |
280 | { | 282 | { |
283 | DetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove); | ||
281 | if (remove) | 284 | if (remove) |
282 | { | 285 | { |
283 | if (pParam == -1) | 286 | if (pParam == -1) |
@@ -434,6 +437,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
434 | 437 | ||
435 | internal void ProcessTypeChange(Vehicle pType) | 438 | internal void ProcessTypeChange(Vehicle pType) |
436 | { | 439 | { |
440 | DetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType); | ||
437 | // Set Defaults For Type | 441 | // Set Defaults For Type |
438 | m_type = pType; | 442 | m_type = pType; |
439 | switch (pType) | 443 | switch (pType) |
@@ -594,11 +598,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
594 | m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); | 598 | m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); |
595 | m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); | 599 | m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); |
596 | break; | 600 | break; |
597 | |||
598 | } | 601 | } |
599 | }//end SetDefaultsForType | 602 | }//end SetDefaultsForType |
600 | 603 | ||
601 | internal void Step(float pTimestep, BSScene pParentScene) | 604 | internal void Step(float pTimestep) |
602 | { | 605 | { |
603 | if (m_type == Vehicle.TYPE_NONE) return; | 606 | if (m_type == Vehicle.TYPE_NONE) return; |
604 | 607 | ||
@@ -606,21 +609,34 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
606 | if (frcount > 100) | 609 | if (frcount > 100) |
607 | frcount = 0; | 610 | frcount = 0; |
608 | 611 | ||
609 | MoveLinear(pTimestep, pParentScene); | 612 | MoveLinear(pTimestep); |
610 | MoveAngular(pTimestep); | 613 | MoveAngular(pTimestep); |
611 | LimitRotation(pTimestep); | 614 | LimitRotation(pTimestep); |
615 | |||
616 | DetailLog("{0},Dynamics,done,pos={1},force={2},velocity={3},angvel={4}", | ||
617 | m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity); | ||
612 | }// end Step | 618 | }// end Step |
613 | 619 | ||
614 | private void MoveLinear(float pTimestep, BSScene _pParentScene) | 620 | private void MoveLinear(float pTimestep) |
615 | { | 621 | { |
616 | if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant | 622 | // requested m_linearMotorDirection is significant |
623 | // if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) | ||
624 | if (m_linearMotorDirection.LengthSquared() > 0.0001f) | ||
617 | { | 625 | { |
626 | Vector3 origDir = m_linearMotorDirection; | ||
627 | Vector3 origVel = m_lastLinearVelocityVector; | ||
628 | |||
618 | // add drive to body | 629 | // add drive to body |
619 | Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); | 630 | // Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); |
620 | m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector? | 631 | Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale); |
632 | // lastLinearVelocityVector is the current body velocity vector? | ||
633 | // RA: Not sure what the *10 is for. A correction for pTimestep? | ||
634 | // m_lastLinearVelocityVector += (addAmount*10); | ||
635 | m_lastLinearVelocityVector += addAmount; | ||
621 | 636 | ||
622 | // This will work temporarily, but we really need to compare speed on an axis | 637 | // This will work temporarily, but we really need to compare speed on an axis |
623 | // KF: Limit body velocity to applied velocity? | 638 | // KF: Limit body velocity to applied velocity? |
639 | // Limit the velocity vector to less than the last set linear motor direction | ||
624 | if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) | 640 | if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) |
625 | m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; | 641 | m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; |
626 | if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) | 642 | if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) |
@@ -630,76 +646,93 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
630 | 646 | ||
631 | // decay applied velocity | 647 | // decay applied velocity |
632 | Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); | 648 | Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); |
633 | //Console.WriteLine("decay: " + decayfraction); | ||
634 | m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f; | 649 | m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f; |
635 | //Console.WriteLine("actual: " + m_linearMotorDirection); | 650 | |
651 | /* | ||
652 | Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/m_linearMotorTimescale; | ||
653 | m_lastLinearVelocityVector += addAmount; | ||
654 | |||
655 | float decayfraction = (1.0f - 1.0f / m_linearMotorDecayTimescale); | ||
656 | m_linearMotorDirection *= decayfraction; | ||
657 | |||
658 | */ | ||
659 | |||
660 | DetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}", | ||
661 | m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector); | ||
636 | } | 662 | } |
637 | else | 663 | else |
638 | { // requested is not significant | 664 | { |
639 | // if what remains of applied is small, zero it. | 665 | // if what remains of applied is small, zero it. |
640 | if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f)) | 666 | // if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f)) |
641 | m_lastLinearVelocityVector = Vector3.Zero; | 667 | // m_lastLinearVelocityVector = Vector3.Zero; |
668 | m_linearMotorDirection = Vector3.Zero; | ||
669 | m_lastLinearVelocityVector = Vector3.Zero; | ||
642 | } | 670 | } |
643 | 671 | ||
644 | // convert requested object velocity to world-referenced vector | 672 | // convert requested object velocity to world-referenced vector |
645 | m_dir = m_lastLinearVelocityVector; | 673 | Quaternion rotq = m_prim.Orientation; |
646 | Quaternion rot = m_prim.Orientation; | 674 | m_dir = m_lastLinearVelocityVector * rotq; |
647 | Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object | 675 | |
648 | m_dir *= rotq; // apply obj rotation to velocity vector | 676 | // Add the various forces into m_dir which will be our new direction vector (velocity) |
649 | 677 | ||
650 | // add Gravity andBuoyancy | 678 | // add Gravity and Buoyancy |
651 | // KF: So far I have found no good method to combine a script-requested | 679 | // KF: So far I have found no good method to combine a script-requested |
652 | // .Z velocity and gravity. Therefore only 0g will used script-requested | 680 | // .Z velocity and gravity. Therefore only 0g will used script-requested |
653 | // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. | 681 | // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. |
654 | Vector3 grav = Vector3.Zero; | 682 | Vector3 grav = Vector3.Zero; |
655 | // There is some gravity, make a gravity force vector | 683 | // There is some gravity, make a gravity force vector that is applied after object velocity. |
656 | // that is applied after object velocity. | ||
657 | float objMass = m_prim.Mass; | ||
658 | // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; | 684 | // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; |
659 | grav.Z = _pParentScene.DefaultGravity.Z * objMass * (1f - m_VehicleBuoyancy); | 685 | grav.Z = m_prim.Scene.DefaultGravity.Z * m_prim.Mass * (1f - m_VehicleBuoyancy); |
660 | // Preserve the current Z velocity | 686 | // Preserve the current Z velocity |
661 | Vector3 vel_now = m_prim.Velocity; | 687 | Vector3 vel_now = m_prim.Velocity; |
662 | m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity | 688 | m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity |
663 | 689 | ||
664 | Vector3 pos = m_prim.Position; | 690 | Vector3 pos = m_prim.Position; |
691 | Vector3 posChange = pos; | ||
665 | // Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f); | 692 | // Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f); |
666 | Vector3 posChange = new Vector3(); | ||
667 | posChange.X = pos.X - m_lastPositionVector.X; | ||
668 | posChange.Y = pos.Y - m_lastPositionVector.Y; | ||
669 | posChange.Z = pos.Z - m_lastPositionVector.Z; | ||
670 | double Zchange = Math.Abs(posChange.Z); | 693 | double Zchange = Math.Abs(posChange.Z); |
671 | if (m_BlockingEndPoint != Vector3.Zero) | 694 | if (m_BlockingEndPoint != Vector3.Zero) |
672 | { | 695 | { |
696 | bool changed = false; | ||
673 | if (pos.X >= (m_BlockingEndPoint.X - (float)1)) | 697 | if (pos.X >= (m_BlockingEndPoint.X - (float)1)) |
674 | { | 698 | { |
675 | pos.X -= posChange.X + 1; | 699 | pos.X -= posChange.X + 1; |
676 | m_prim.Position = pos; | 700 | changed = true; |
677 | } | 701 | } |
678 | if (pos.Y >= (m_BlockingEndPoint.Y - (float)1)) | 702 | if (pos.Y >= (m_BlockingEndPoint.Y - (float)1)) |
679 | { | 703 | { |
680 | pos.Y -= posChange.Y + 1; | 704 | pos.Y -= posChange.Y + 1; |
681 | m_prim.Position = pos; | 705 | changed = true; |
682 | } | 706 | } |
683 | if (pos.Z >= (m_BlockingEndPoint.Z - (float)1)) | 707 | if (pos.Z >= (m_BlockingEndPoint.Z - (float)1)) |
684 | { | 708 | { |
685 | pos.Z -= posChange.Z + 1; | 709 | pos.Z -= posChange.Z + 1; |
686 | m_prim.Position = pos; | 710 | changed = true; |
687 | } | 711 | } |
688 | if (pos.X <= 0) | 712 | if (pos.X <= 0) |
689 | { | 713 | { |
690 | pos.X += posChange.X + 1; | 714 | pos.X += posChange.X + 1; |
691 | m_prim.Position = pos; | 715 | changed = true; |
692 | } | 716 | } |
693 | if (pos.Y <= 0) | 717 | if (pos.Y <= 0) |
694 | { | 718 | { |
695 | pos.Y += posChange.Y + 1; | 719 | pos.Y += posChange.Y + 1; |
720 | changed = true; | ||
721 | } | ||
722 | if (changed) | ||
723 | { | ||
696 | m_prim.Position = pos; | 724 | m_prim.Position = pos; |
725 | DetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", | ||
726 | m_prim.LocalID, m_BlockingEndPoint, posChange, pos); | ||
697 | } | 727 | } |
698 | } | 728 | } |
699 | if (pos.Z < _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y)) | 729 | |
730 | // If below the terrain, move us above the ground a little. | ||
731 | if (pos.Z < m_prim.Scene.GetTerrainHeightAtXYZ(pos)) | ||
700 | { | 732 | { |
701 | pos.Z = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + 2; | 733 | pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2; |
702 | m_prim.Position = pos; | 734 | m_prim.Position = pos; |
735 | DetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos); | ||
703 | } | 736 | } |
704 | 737 | ||
705 | // Check if hovering | 738 | // Check if hovering |
@@ -708,11 +741,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
708 | // We should hover, get the target height | 741 | // We should hover, get the target height |
709 | if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0) | 742 | if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0) |
710 | { | 743 | { |
711 | m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight; | 744 | m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight; |
712 | } | 745 | } |
713 | if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) | 746 | if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) |
714 | { | 747 | { |
715 | m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; | 748 | m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; |
716 | } | 749 | } |
717 | if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) | 750 | if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) |
718 | { | 751 | { |
@@ -746,6 +779,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
746 | } | 779 | } |
747 | } | 780 | } |
748 | 781 | ||
782 | DetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight); | ||
783 | |||
749 | // m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped | 784 | // m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped |
750 | // m_VhoverTimescale = 0f; // time to acheive height | 785 | // m_VhoverTimescale = 0f; // time to acheive height |
751 | // pTimestep is time since last frame,in secs | 786 | // pTimestep is time since last frame,in secs |
@@ -774,12 +809,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
774 | { | 809 | { |
775 | grav.Z = (float)(grav.Z * 1.125); | 810 | grav.Z = (float)(grav.Z * 1.125); |
776 | } | 811 | } |
777 | float terraintemp = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y); | 812 | float terraintemp = m_prim.Scene.GetTerrainHeightAtXYZ(pos); |
778 | float postemp = (pos.Z - terraintemp); | 813 | float postemp = (pos.Z - terraintemp); |
779 | if (postemp > 2.5f) | 814 | if (postemp > 2.5f) |
780 | { | 815 | { |
781 | grav.Z = (float)(grav.Z * 1.037125); | 816 | grav.Z = (float)(grav.Z * 1.037125); |
782 | } | 817 | } |
818 | DetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav); | ||
783 | //End Experimental Values | 819 | //End Experimental Values |
784 | } | 820 | } |
785 | if ((m_flags & (VehicleFlag.NO_X)) != 0) | 821 | if ((m_flags & (VehicleFlag.NO_X)) != 0) |
@@ -800,32 +836,39 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
800 | // Apply velocity | 836 | // Apply velocity |
801 | m_prim.Velocity = m_dir; | 837 | m_prim.Velocity = m_dir; |
802 | // apply gravity force | 838 | // apply gravity force |
803 | m_prim.Force = grav; | 839 | // Why is this set here? The physics engine already does gravity. |
804 | 840 | // m_prim.AddForce(grav, false); | |
841 | // m_prim.Force = grav; | ||
805 | 842 | ||
806 | // apply friction | 843 | // Apply friction |
807 | Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); | 844 | Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); |
808 | m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; | 845 | m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; |
846 | |||
847 | DetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}", | ||
848 | m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount); | ||
849 | |||
809 | } // end MoveLinear() | 850 | } // end MoveLinear() |
810 | 851 | ||
811 | private void MoveAngular(float pTimestep) | 852 | private void MoveAngular(float pTimestep) |
812 | { | 853 | { |
813 | /* | 854 | // m_angularMotorDirection // angular velocity requested by LSL motor |
814 | private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor | 855 | // m_angularMotorApply // application frame counter |
815 | private int m_angularMotorApply = 0; // application frame counter | 856 | // m_angularMotorVelocity // current angular motor velocity (ramps up and down) |
816 | private float m_angularMotorVelocity = 0; // current angular motor velocity (ramps up and down) | 857 | // m_angularMotorTimescale // motor angular velocity ramp up rate |
817 | private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate | 858 | // m_angularMotorDecayTimescale // motor angular velocity decay rate |
818 | private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate | 859 | // m_angularFrictionTimescale // body angular velocity decay rate |
819 | private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate | 860 | // m_lastAngularVelocity // what was last applied to body |
820 | private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body | ||
821 | */ | ||
822 | 861 | ||
823 | // Get what the body is doing, this includes 'external' influences | 862 | // Get what the body is doing, this includes 'external' influences |
824 | Vector3 angularVelocity = m_prim.RotationalVelocity; | 863 | Vector3 angularVelocity = m_prim.RotationalVelocity; |
825 | // Vector3 angularVelocity = Vector3.Zero; | ||
826 | 864 | ||
827 | if (m_angularMotorApply > 0) | 865 | if (m_angularMotorApply > 0) |
828 | { | 866 | { |
867 | // Rather than snapping the angular motor velocity from the old value to | ||
868 | // a newly set velocity, this routine steps the value from the previous | ||
869 | // value (m_angularMotorVelocity) to the requested value (m_angularMotorDirection). | ||
870 | // There are m_angularMotorApply steps. | ||
871 | Vector3 origAngularVelocity = m_angularMotorVelocity; | ||
829 | // ramp up to new value | 872 | // ramp up to new value |
830 | // current velocity += error / (time to get there / step interval) | 873 | // current velocity += error / (time to get there / step interval) |
831 | // requested speed - last motor speed | 874 | // requested speed - last motor speed |
@@ -833,23 +876,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
833 | m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); | 876 | m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); |
834 | m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); | 877 | m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); |
835 | 878 | ||
879 | DetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}", | ||
880 | m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity); | ||
881 | |||
836 | m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected | 882 | m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected |
837 | // velocity may still be acheived. | 883 | // velocity may still be acheived. |
838 | } | 884 | } |
839 | else | 885 | else |
840 | { | 886 | { |
841 | // no motor recently applied, keep the body velocity | 887 | // No motor recently applied, keep the body velocity |
842 | /* m_angularMotorVelocity.X = angularVelocity.X; | ||
843 | m_angularMotorVelocity.Y = angularVelocity.Y; | ||
844 | m_angularMotorVelocity.Z = angularVelocity.Z; */ | ||
845 | |||
846 | // and decay the velocity | 888 | // and decay the velocity |
847 | m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); | 889 | m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); |
848 | } // end motor section | 890 | } // end motor section |
849 | 891 | ||
850 | // Vertical attractor section | 892 | // Vertical attractor section |
851 | Vector3 vertattr = Vector3.Zero; | 893 | Vector3 vertattr = Vector3.Zero; |
852 | |||
853 | if (m_verticalAttractionTimescale < 300) | 894 | if (m_verticalAttractionTimescale < 300) |
854 | { | 895 | { |
855 | float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep); | 896 | float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep); |
@@ -871,7 +912,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
871 | // Error is 0 (no error) to +/- 2 (max error) | 912 | // Error is 0 (no error) to +/- 2 (max error) |
872 | // scale it by VAservo | 913 | // scale it by VAservo |
873 | verterr = verterr * VAservo; | 914 | verterr = verterr * VAservo; |
874 | //if (frcount == 0) Console.WriteLine("VAerr=" + verterr); | ||
875 | 915 | ||
876 | // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so | 916 | // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so |
877 | // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. | 917 | // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. |
@@ -884,11 +924,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
884 | vertattr.X += bounce * angularVelocity.X; | 924 | vertattr.X += bounce * angularVelocity.X; |
885 | vertattr.Y += bounce * angularVelocity.Y; | 925 | vertattr.Y += bounce * angularVelocity.Y; |
886 | 926 | ||
927 | DetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}", | ||
928 | m_prim.LocalID, verterr, bounce, vertattr); | ||
929 | |||
887 | } // else vertical attractor is off | 930 | } // else vertical attractor is off |
888 | 931 | ||
889 | // m_lastVertAttractor = vertattr; | 932 | // m_lastVertAttractor = vertattr; |
890 | 933 | ||
891 | // Bank section tba | 934 | // Bank section tba |
935 | |||
892 | // Deflection section tba | 936 | // Deflection section tba |
893 | 937 | ||
894 | // Sum velocities | 938 | // Sum velocities |
@@ -898,11 +942,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
898 | { | 942 | { |
899 | m_lastAngularVelocity.X = 0; | 943 | m_lastAngularVelocity.X = 0; |
900 | m_lastAngularVelocity.Y = 0; | 944 | m_lastAngularVelocity.Y = 0; |
945 | DetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); | ||
901 | } | 946 | } |
902 | 947 | ||
903 | if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) | 948 | if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) |
904 | { | 949 | { |
905 | m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. | 950 | m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. |
951 | DetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); | ||
906 | } | 952 | } |
907 | 953 | ||
908 | // apply friction | 954 | // apply friction |
@@ -912,10 +958,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
912 | // Apply to the body | 958 | // Apply to the body |
913 | m_prim.RotationalVelocity = m_lastAngularVelocity; | 959 | m_prim.RotationalVelocity = m_lastAngularVelocity; |
914 | 960 | ||
961 | DetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity); | ||
915 | } //end MoveAngular | 962 | } //end MoveAngular |
963 | |||
916 | internal void LimitRotation(float timestep) | 964 | internal void LimitRotation(float timestep) |
917 | { | 965 | { |
918 | Quaternion rotq = m_prim.Orientation; // rotq = rotation of object | 966 | Quaternion rotq = m_prim.Orientation; |
919 | Quaternion m_rot = rotq; | 967 | Quaternion m_rot = rotq; |
920 | bool changed = false; | 968 | bool changed = false; |
921 | if (m_RollreferenceFrame != Quaternion.Identity) | 969 | if (m_RollreferenceFrame != Quaternion.Identity) |
@@ -923,18 +971,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
923 | if (rotq.X >= m_RollreferenceFrame.X) | 971 | if (rotq.X >= m_RollreferenceFrame.X) |
924 | { | 972 | { |
925 | m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2); | 973 | m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2); |
974 | changed = true; | ||
926 | } | 975 | } |
927 | if (rotq.Y >= m_RollreferenceFrame.Y) | 976 | if (rotq.Y >= m_RollreferenceFrame.Y) |
928 | { | 977 | { |
929 | m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2); | 978 | m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2); |
979 | changed = true; | ||
930 | } | 980 | } |
931 | if (rotq.X <= -m_RollreferenceFrame.X) | 981 | if (rotq.X <= -m_RollreferenceFrame.X) |
932 | { | 982 | { |
933 | m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2); | 983 | m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2); |
984 | changed = true; | ||
934 | } | 985 | } |
935 | if (rotq.Y <= -m_RollreferenceFrame.Y) | 986 | if (rotq.Y <= -m_RollreferenceFrame.Y) |
936 | { | 987 | { |
937 | m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2); | 988 | m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2); |
989 | changed = true; | ||
938 | } | 990 | } |
939 | changed = true; | 991 | changed = true; |
940 | } | 992 | } |
@@ -944,8 +996,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
944 | m_rot.Y = 0; | 996 | m_rot.Y = 0; |
945 | changed = true; | 997 | changed = true; |
946 | } | 998 | } |
999 | if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0) | ||
1000 | { | ||
1001 | m_rot.X = 0; | ||
1002 | m_rot.Y = 0; | ||
1003 | changed = true; | ||
1004 | } | ||
947 | if (changed) | 1005 | if (changed) |
948 | m_prim.Orientation = m_rot; | 1006 | m_prim.Orientation = m_rot; |
1007 | |||
1008 | DetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot); | ||
1009 | } | ||
1010 | |||
1011 | // Invoke the detailed logger and output something if it's enabled. | ||
1012 | private void DetailLog(string msg, params Object[] args) | ||
1013 | { | ||
1014 | if (m_prim.Scene.VehicleLoggingEnabled) | ||
1015 | m_prim.Scene.PhysicsLogging.Write(msg, args); | ||
949 | } | 1016 | } |
950 | } | 1017 | } |
951 | } | 1018 | } |