diff options
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs')
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs | 296 |
1 files changed, 72 insertions, 224 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index 363cbef..6b323fb 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs | |||
@@ -629,36 +629,31 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
629 | 629 | ||
630 | Vector3 force = Vector3.Zero; // actually linear aceleration until mult by mass in world frame | 630 | Vector3 force = Vector3.Zero; // actually linear aceleration until mult by mass in world frame |
631 | Vector3 torque = Vector3.Zero;// actually angular aceleration until mult by Inertia in object frame | 631 | Vector3 torque = Vector3.Zero;// actually angular aceleration until mult by Inertia in object frame |
632 | d.Vector3 dtorque = new d.Vector3();// actually angular aceleration until mult by Inertia in object frame | 632 | d.Vector3 dtorque = new d.Vector3(); |
633 | |||
634 | bool doathing = false; | ||
635 | 633 | ||
636 | // linear motor | 634 | // linear motor |
637 | if (m_lmEfect > 0.01 && m_linearMotorTimescale < 1000) | 635 | if (m_lmEfect > 0.01 && m_linearMotorTimescale < 1000) |
638 | { | 636 | { |
639 | tmpV = m_linearMotorDirection - curLocalVel; // velocity error | 637 | tmpV = m_linearMotorDirection - curLocalVel; // velocity error |
640 | if (tmpV.LengthSquared() > 1e-6f) | 638 | tmpV *= m_lmEfect / m_linearMotorTimescale; // error to correct in this timestep |
641 | { | 639 | tmpV *= rotq; // to world |
642 | tmpV = tmpV * (m_lmEfect / m_linearMotorTimescale); // error to correct in this timestep | ||
643 | tmpV *= rotq; // to world | ||
644 | 640 | ||
645 | if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0) | 641 | if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0) |
646 | tmpV.Z = 0; | 642 | tmpV.Z = 0; |
647 | 643 | ||
648 | if (m_linearMotorOffset.X != 0 && m_linearMotorOffset.Y != 0 && m_linearMotorOffset.Z != 0) | 644 | if (m_linearMotorOffset.X != 0 || m_linearMotorOffset.Y != 0 || m_linearMotorOffset.Z != 0) |
649 | { | 645 | { |
650 | // have offset, do it now | 646 | // have offset, do it now |
651 | tmpV *= rootPrim.Mass; | 647 | tmpV *= rootPrim.Mass; |
652 | d.BodyAddForceAtRelPos(Body, tmpV.X, tmpV.Y, tmpV.Z, m_linearMotorOffset.X, m_linearMotorOffset.Y, m_linearMotorOffset.Z); | 648 | d.BodyAddForceAtRelPos(Body, tmpV.X, tmpV.Y, tmpV.Z, m_linearMotorOffset.X, m_linearMotorOffset.Y, m_linearMotorOffset.Z); |
653 | } | ||
654 | else | ||
655 | { | ||
656 | force.X += tmpV.X; | ||
657 | force.Y += tmpV.Y; | ||
658 | force.Z += tmpV.Z; | ||
659 | } | ||
660 | } | 649 | } |
661 | m_lmEfect *= (1 - 1.0f / m_linearMotorDecayTimescale); | 650 | else |
651 | { | ||
652 | force.X += tmpV.X; | ||
653 | force.Y += tmpV.Y; | ||
654 | force.Z += tmpV.Z; | ||
655 | } | ||
656 | m_lmEfect *= (1.0f - 1.0f / m_linearMotorDecayTimescale); | ||
662 | } | 657 | } |
663 | else | 658 | else |
664 | m_lmEfect = 0; | 659 | m_lmEfect = 0; |
@@ -719,30 +714,35 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
719 | if (m_linearDeflectionEfficiency > 0) | 714 | if (m_linearDeflectionEfficiency > 0) |
720 | { | 715 | { |
721 | float len = curVel.Length(); | 716 | float len = curVel.Length(); |
722 | Vector3 atAxis = refAtAxis; | 717 | Vector3 atAxis; |
723 | atAxis *= rotq; // at axis rotated to world | 718 | atAxis = Xrot(rotq); // where are we pointing to |
724 | atAxis = Xrot(rotq); | 719 | atAxis *= len; // make it same size as world velocity vector |
725 | tmpV = atAxis * len; | 720 | tmpV = -atAxis; // oposite direction |
726 | tmpV -= curVel; // velocity error | 721 | atAxis -= curVel; // error to one direction |
727 | tmpV *= (m_linearDeflectionEfficiency / m_linearDeflectionTimescale); // error to correct in this timestep | 722 | len = atAxis.LengthSquared(); |
728 | force.X += tmpV.X; | 723 | tmpV -= curVel; // error to oposite |
729 | force.Y += tmpV.Y; | 724 | float lens = tmpV.LengthSquared(); |
730 | if((m_flags & VehicleFlag.NO_DEFLECTION_UP) ==0) | 725 | if (len > 0.01 || lens > 0.01) // do nothing if close enougth |
731 | force.Z += tmpV.Z; | 726 | { |
727 | if (len < lens) | ||
728 | tmpV = atAxis; | ||
729 | |||
730 | tmpV *= (m_linearDeflectionEfficiency / m_linearDeflectionTimescale); // error to correct in this timestep | ||
731 | force.X += tmpV.X; | ||
732 | force.Y += tmpV.Y; | ||
733 | if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) == 0) | ||
734 | force.Z += tmpV.Z; | ||
735 | } | ||
732 | } | 736 | } |
733 | 737 | ||
734 | // angular motor | 738 | // angular motor |
735 | if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000) | 739 | if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000) |
736 | { | 740 | { |
737 | tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error | 741 | tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error |
738 | if (tmpV.LengthSquared() > 1e-6f) | 742 | tmpV *= m_amEfect / m_angularMotorTimescale; // error to correct in this timestep |
739 | { | 743 | torque.X += tmpV.X; |
740 | tmpV = tmpV * (m_amEfect / m_angularMotorTimescale); // error to correct in this timestep | 744 | torque.Y += tmpV.Y; |
741 | tmpV *= m_referenceFrame; // to object | 745 | torque.Z += tmpV.Z; |
742 | dtorque.X += tmpV.X; | ||
743 | dtorque.Y += tmpV.Y; | ||
744 | dtorque.Z += tmpV.Z; | ||
745 | } | ||
746 | m_amEfect *= (1 - 1.0f / m_angularMotorDecayTimescale); | 746 | m_amEfect *= (1 - 1.0f / m_angularMotorDecayTimescale); |
747 | } | 747 | } |
748 | else | 748 | else |
@@ -751,85 +751,64 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
751 | // angular friction | 751 | // angular friction |
752 | if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0) | 752 | if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0) |
753 | { | 753 | { |
754 | tmpV.X = -curLocalAngVel.X / m_angularFrictionTimescale.X; | 754 | torque.X -= curLocalAngVel.X / m_angularFrictionTimescale.X; |
755 | tmpV.Y = -curLocalAngVel.Y / m_angularFrictionTimescale.Y; | 755 | torque.Y -= curLocalAngVel.Y / m_angularFrictionTimescale.Y; |
756 | tmpV.Z = -curLocalAngVel.Z / m_angularFrictionTimescale.Z; | 756 | torque.Z -= curLocalAngVel.Z / m_angularFrictionTimescale.Z; |
757 | tmpV *= m_referenceFrame; // to object | ||
758 | dtorque.X += tmpV.X; | ||
759 | dtorque.Y += tmpV.Y; | ||
760 | dtorque.Z += tmpV.Z; | ||
761 | } | 757 | } |
762 | 758 | ||
763 | // angular deflection | 759 | // angular deflection |
764 | if (m_angularDeflectionEfficiency > 0) | 760 | if (m_angularDeflectionEfficiency > 0) |
765 | { | 761 | { |
766 | doathing = false; | 762 | Vector3 dirv; |
767 | float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale / m_angularDeflectionTimescale /_pParentScene.ODE_STEPSIZE; | 763 | |
768 | tmpV.X = 0; | 764 | if (curLocalVel.X > 0.01f) |
769 | if (Math.Abs(curLocalVel.Z) > 0.01) | 765 | dirv = curLocalVel; |
766 | else if (curLocalVel.X < -0.01f) | ||
767 | // use oposite | ||
768 | dirv = -curLocalVel; | ||
769 | else | ||
770 | { | 770 | { |
771 | tmpV.Y = -(float)Math.Atan2(curLocalVel.Z, curLocalVel.X) * ftmp; | 771 | // make it fall into small positive x case |
772 | doathing = true; | 772 | dirv.X = 0.01f; |
773 | dirv.Y = curLocalVel.Y; | ||
774 | dirv.Z = curLocalVel.Z; | ||
773 | } | 775 | } |
774 | else | 776 | |
775 | tmpV.Y = 0; | 777 | float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale; |
776 | if (Math.Abs(curLocalVel.Y) > 0.01) | 778 | |
779 | if (Math.Abs(dirv.Z) > 0.01) | ||
777 | { | 780 | { |
778 | tmpV.Z = (float)Math.Atan2(curLocalVel.Y, curLocalVel.X) * ftmp; | 781 | torque.Y += - (float)Math.Atan2(dirv.Z, dirv.X) * ftmp; |
779 | doathing = true; | ||
780 | } | 782 | } |
781 | else | ||
782 | tmpV.Z = 0; | ||
783 | 783 | ||
784 | if (doathing) | 784 | if (Math.Abs(dirv.Y) > 0.01) |
785 | { | 785 | { |
786 | tmpV *= m_referenceFrame; // to object | 786 | torque.Z += (float)Math.Atan2(dirv.Y, dirv.X) * ftmp; |
787 | dtorque.X += tmpV.X; | ||
788 | dtorque.Y += tmpV.Y; | ||
789 | dtorque.Z += tmpV.Z; | ||
790 | } | 787 | } |
791 | } | 788 | } |
792 | 789 | ||
793 | // vertical atractor | 790 | // vertical atractor |
794 | if (m_verticalAttractionTimescale < 300) | 791 | if (m_verticalAttractionTimescale < 300) |
795 | { | 792 | { |
796 | doathing = false; | ||
797 | float roll; | 793 | float roll; |
798 | float pitch; | 794 | float pitch; |
799 | 795 | ||
800 | GetRollPitch(rotq, out roll, out pitch); | 796 | GetRollPitch(rotq, out roll, out pitch); |
801 | 797 | ||
802 | |||
803 | float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE; | 798 | float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE; |
804 | float ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE; | 799 | float ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE; |
805 | 800 | ||
806 | if (Math.Abs(roll) > 0.01) // roll | 801 | if (Math.Abs(roll) > 0.01) // roll |
807 | { | 802 | { |
808 | tmpV.X = -roll * ftmp; | 803 | torque.X -= roll * ftmp + curLocalAngVel.X * ftmp2; |
809 | tmpV.X -= curLocalAngVel.X * ftmp2; | ||
810 | doathing = true; | ||
811 | } | ||
812 | else | ||
813 | { | ||
814 | tmpV.X = 0; | ||
815 | } | 804 | } |
816 | 805 | ||
817 | if (Math.Abs(pitch) > 0.01 && ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)) // pitch | 806 | if (Math.Abs(pitch) > 0.01 && ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)) // pitch |
818 | { | 807 | { |
819 | tmpV.Y = -pitch * ftmp; | 808 | torque.Y -= pitch * ftmp + curLocalAngVel.Y * ftmp2; |
820 | tmpV.Y -= curLocalAngVel.Y * ftmp2; | ||
821 | doathing = true; | ||
822 | } | ||
823 | else | ||
824 | { | ||
825 | tmpV.Y = 0; | ||
826 | } | 809 | } |
827 | 810 | ||
828 | tmpV.Z = 0; | 811 | if (m_bankingEfficiency != 0 && Math.Abs(roll) < 0.01) |
829 | |||
830 | if (m_bankingEfficiency == 0 || Math.Abs(roll) < 0.01) | ||
831 | tmpV.Z = 0; | ||
832 | else | ||
833 | { | 812 | { |
834 | float broll = -roll * m_bankingEfficiency; ; | 813 | float broll = -roll * m_bankingEfficiency; ; |
835 | if (m_bankingMix != 0) | 814 | if (m_bankingMix != 0) |
@@ -839,146 +818,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
839 | broll *= ((1 - m_bankingMix) + vfact); | 818 | broll *= ((1 - m_bankingMix) + vfact); |
840 | } | 819 | } |
841 | 820 | ||
842 | tmpV.Z = (broll - curLocalAngVel.Z) / m_bankingTimescale; | 821 | torque.Z += (broll - curLocalAngVel.Z) / m_bankingTimescale; |
843 | doathing = true; | ||
844 | } | ||
845 | |||
846 | if (doathing) | ||
847 | { | ||
848 | |||
849 | tmpV *= m_referenceFrame; // to object | ||
850 | dtorque.X += tmpV.X; | ||
851 | dtorque.Y += tmpV.Y; | ||
852 | dtorque.Z += tmpV.Z; | ||
853 | } | 822 | } |
854 | } | 823 | } |
855 | /* | ||
856 | d.Vector3 pos = d.BodyGetPosition(Body); | ||
857 | // 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); | ||
858 | Vector3 posChange = new Vector3(); | ||
859 | posChange.X = pos.X - m_lastPositionVector.X; | ||
860 | posChange.Y = pos.Y - m_lastPositionVector.Y; | ||
861 | posChange.Z = pos.Z - m_lastPositionVector.Z; | ||
862 | double Zchange = Math.Abs(posChange.Z); | ||
863 | if (m_BlockingEndPoint != Vector3.Zero) | ||
864 | { | ||
865 | if (pos.X >= (m_BlockingEndPoint.X - (float)1)) | ||
866 | { | ||
867 | pos.X -= posChange.X + 1; | ||
868 | d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); | ||
869 | } | ||
870 | if (pos.Y >= (m_BlockingEndPoint.Y - (float)1)) | ||
871 | { | ||
872 | pos.Y -= posChange.Y + 1; | ||
873 | d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); | ||
874 | } | ||
875 | if (pos.Z >= (m_BlockingEndPoint.Z - (float)1)) | ||
876 | { | ||
877 | pos.Z -= posChange.Z + 1; | ||
878 | d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); | ||
879 | } | ||
880 | if (pos.X <= 0) | ||
881 | { | ||
882 | pos.X += posChange.X + 1; | ||
883 | d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); | ||
884 | } | ||
885 | if (pos.Y <= 0) | ||
886 | { | ||
887 | pos.Y += posChange.Y + 1; | ||
888 | d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); | ||
889 | } | ||
890 | } | ||
891 | if (pos.Z < _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y)) | ||
892 | { | ||
893 | pos.Z = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + 2; | ||
894 | d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); | ||
895 | } | ||
896 | |||
897 | } | ||
898 | if ((m_flags & (VehicleFlag.NO_X)) != 0) | ||
899 | { | ||
900 | m_dir.X = 0; | ||
901 | } | ||
902 | if ((m_flags & (VehicleFlag.NO_Y)) != 0) | ||
903 | { | ||
904 | m_dir.Y = 0; | ||
905 | } | ||
906 | if ((m_flags & (VehicleFlag.NO_Z)) != 0) | ||
907 | { | ||
908 | m_dir.Z = 0; | ||
909 | } | ||
910 | |||
911 | |||
912 | */ | ||
913 | // angular part | ||
914 | /* | ||
915 | |||
916 | // Get what the body is doing, this includes 'external' influences | ||
917 | /* | ||
918 | Vector3 angularVelocity = Vector3.Zero; | ||
919 | |||
920 | // Vertical attractor section | ||
921 | Vector3 vertattr = Vector3.Zero; | ||
922 | |||
923 | if (m_verticalAttractionTimescale < 300) | ||
924 | { | ||
925 | float VAservo = 0.2f / m_verticalAttractionTimescale; | ||
926 | // get present body rotation | ||
927 | // make a vector pointing up | ||
928 | Vector3 verterr = Vector3.Zero; | ||
929 | verterr.Z = 1.0f; | ||
930 | // rotate it to Body Angle | ||
931 | verterr = verterr * rotq; | ||
932 | // verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. | ||
933 | // 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 | ||
934 | // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. | ||
935 | if (verterr.Z < 0.0f) | ||
936 | { | ||
937 | verterr.X = 2.0f - verterr.X; | ||
938 | verterr.Y = 2.0f - verterr.Y; | ||
939 | } | ||
940 | // Error is 0 (no error) to +/- 2 (max error) | ||
941 | // scale it by VAservo | ||
942 | verterr = verterr * VAservo; | ||
943 | //if (frcount == 0) Console.WriteLine("VAerr=" + verterr); | ||
944 | |||
945 | // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so | ||
946 | // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. | ||
947 | vertattr.X = verterr.Y; | ||
948 | vertattr.Y = - verterr.X; | ||
949 | vertattr.Z = 0f; | ||
950 | |||
951 | // scaling appears better usingsquare-law | ||
952 | float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); | ||
953 | vertattr.X += bounce * angularVelocity.X; | ||
954 | vertattr.Y += bounce * angularVelocity.Y; | ||
955 | |||
956 | } // else vertical attractor is off | ||
957 | |||
958 | // m_lastVertAttractor = vertattr; | ||
959 | |||
960 | // Bank section tba | ||
961 | // Deflection section tba | ||
962 | |||
963 | // Sum velocities | ||
964 | m_lastAngularVelocity = angularVelocity + vertattr; // + bank + deflection | ||
965 | 824 | ||
966 | if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) | ||
967 | { | ||
968 | m_lastAngularVelocity.X = 0; | ||
969 | m_lastAngularVelocity.Y = 0; | ||
970 | } | ||
971 | |||
972 | if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) | ||
973 | { | ||
974 | if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body); | ||
975 | } | ||
976 | else | ||
977 | { | ||
978 | m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. | ||
979 | } | ||
980 | */ | ||
981 | |||
982 | d.Mass dmass; | 825 | d.Mass dmass; |
983 | d.BodyGetMass(Body,out dmass); | 826 | d.BodyGetMass(Body,out dmass); |
984 | 827 | ||
@@ -988,8 +831,13 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
988 | d.BodySetForce(Body, force.X, force.Y, force.Z); | 831 | d.BodySetForce(Body, force.X, force.Y, force.Z); |
989 | } | 832 | } |
990 | 833 | ||
991 | if (dtorque.X != 0 || dtorque.Y != 0 || dtorque.Z != 0) | 834 | if (torque.X != 0 || torque.Y != 0 || torque.Z != 0) |
992 | { | 835 | { |
836 | torque *= m_referenceFrame; // to object frame | ||
837 | dtorque.X = torque.X; | ||
838 | dtorque.Y = torque.Y; | ||
839 | dtorque.Z = torque.Z; | ||
840 | |||
993 | d.MultiplyM3V3(out dvtmp, ref dmass.I, ref dtorque); | 841 | d.MultiplyM3V3(out dvtmp, ref dmass.I, ref dtorque); |
994 | d.BodyAddRelTorque(Body, dvtmp.X, dvtmp.Y, dvtmp.Z); // add torque in object frame | 842 | d.BodyAddRelTorque(Body, dvtmp.X, dvtmp.Y, dvtmp.Z); // add torque in object frame |
995 | } | 843 | } |