diff options
Merge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs')
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 155 |
1 files changed, 63 insertions, 92 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 925900f..fd6b8aa 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | |||
@@ -84,18 +84,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
84 | private float m_mass = 80f; | 84 | private float m_mass = 80f; |
85 | public float m_density = 60f; | 85 | public float m_density = 60f; |
86 | private bool m_pidControllerActive = true; | 86 | private bool m_pidControllerActive = true; |
87 | public float PID_D = 800.0f; | ||
88 | public float PID_P = 900.0f; | ||
89 | //private static float POSTURE_SERVO = 10000.0f; | ||
90 | 87 | ||
91 | 88 | const float basePID_D = 0.55f; // scaled for unit mass unit time (2200 /(50*80)) | |
92 | private float m_invElipSizeX; | 89 | const float basePID_P = 0.225f; // scaled for unit mass unit time (900 /(50*80)) |
93 | private float m_invElipSizeY; | 90 | public float PID_D; |
91 | public float PID_P; | ||
94 | 92 | ||
95 | private float feetOff = 0; | 93 | private float feetOff = 0; |
96 | private float feetSZ = 0.5f; | 94 | private float feetSZ = 0.5f; |
97 | const float feetScale = 0.9f; | 95 | const float feetScale = 0.8f; |
98 | const float invFeetScale = 1.0f / 0.9f; | ||
99 | const float sizeZAdjust = 0.18f; | 96 | const float sizeZAdjust = 0.18f; |
100 | private float boneOff = 0; | 97 | private float boneOff = 0; |
101 | 98 | ||
@@ -160,7 +157,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
160 | 157 | ||
161 | 158 | ||
162 | 159 | ||
163 | public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float pid_d, float pid_p, float density, float walk_divisor, float rundivisor) | 160 | public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float density, float walk_divisor, float rundivisor) |
164 | { | 161 | { |
165 | m_uuid = UUID.Random(); | 162 | m_uuid = UUID.Random(); |
166 | 163 | ||
@@ -184,8 +181,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
184 | 181 | ||
185 | _parent_scene = parent_scene; | 182 | _parent_scene = parent_scene; |
186 | 183 | ||
187 | PID_D = pid_d; | ||
188 | PID_P = pid_p; | ||
189 | 184 | ||
190 | m_size.X = pSize.X; | 185 | m_size.X = pSize.X; |
191 | m_size.Y = pSize.Y; | 186 | m_size.Y = pSize.Y; |
@@ -204,6 +199,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
204 | // force lower density for testing | 199 | // force lower density for testing |
205 | m_density = 3.0f; | 200 | m_density = 3.0f; |
206 | 201 | ||
202 | m_density *= 1.4f; // scale to have mass similar to capsule | ||
203 | |||
207 | mu = parent_scene.AvatarFriction; | 204 | mu = parent_scene.AvatarFriction; |
208 | 205 | ||
209 | walkDivisor = walk_divisor; | 206 | walkDivisor = walk_divisor; |
@@ -211,6 +208,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
211 | 208 | ||
212 | m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default | 209 | m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default |
213 | 210 | ||
211 | PID_D = basePID_D * m_mass / parent_scene.ODE_STEPSIZE; | ||
212 | PID_P = basePID_P * m_mass / parent_scene.ODE_STEPSIZE; | ||
213 | |||
214 | m_isPhysical = false; // current status: no ODE information exists | 214 | m_isPhysical = false; // current status: no ODE information exists |
215 | 215 | ||
216 | Name = avName; | 216 | Name = avName; |
@@ -491,7 +491,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
491 | { | 491 | { |
492 | get | 492 | get |
493 | { | 493 | { |
494 | return m_density * m_size.X * m_size.Y * m_size.Z; | 494 | return m_mass; |
495 | } | 495 | } |
496 | } | 496 | } |
497 | public override void link(PhysicsActor obj) | 497 | public override void link(PhysicsActor obj) |
@@ -671,23 +671,22 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
671 | private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) | 671 | private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) |
672 | { | 672 | { |
673 | // sizes one day should came from visual parameters | 673 | // sizes one day should came from visual parameters |
674 | float sx = m_size.X; | ||
675 | float sy = m_size.Y; | ||
674 | float sz = m_size.Z + sizeZAdjust; | 676 | float sz = m_size.Z + sizeZAdjust; |
675 | 677 | ||
676 | m_invElipSizeX = 1.0f / m_size.X; | 678 | float topsx = sx * 0.9f; |
677 | m_invElipSizeY = 1.0f / m_size.Y; | 679 | float midsx = sx; |
680 | float feetsx = sx * feetScale; | ||
681 | float bonesx = sx * 0.2f; | ||
678 | 682 | ||
679 | float topsx = m_size.X * 0.9f; | 683 | float topsy = sy * 0.4f; |
680 | float midsx = m_size.X; | 684 | float midsy = sy; |
681 | float feetsx = m_size.X * feetScale; | 685 | float feetsy = sy * feetScale * 0.8f; |
682 | float bonesx = feetsx * 0.2f; | ||
683 | |||
684 | float topsy = m_size.Y * 0.4f; | ||
685 | float midsy = m_size.Y; | ||
686 | float feetsy = m_size.Y * feetScale; | ||
687 | float bonesy = feetsy * 0.2f; | 686 | float bonesy = feetsy * 0.2f; |
688 | 687 | ||
689 | float topsz = sz * 0.15f; | 688 | float topsz = sz * 0.15f; |
690 | float feetsz = sz * 0.3f; | 689 | float feetsz = sz * 0.45f; |
691 | if (feetsz > 0.6f) | 690 | if (feetsz > 0.6f) |
692 | feetsz = 0.6f; | 691 | feetsz = 0.6f; |
693 | 692 | ||
@@ -726,22 +725,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
726 | d.GeomSetCategoryBits(bonebox, (uint)m_collisionCategories); | 725 | d.GeomSetCategoryBits(bonebox, (uint)m_collisionCategories); |
727 | d.GeomSetCollideBits(bonebox, (uint)m_collisionFlags); | 726 | d.GeomSetCollideBits(bonebox, (uint)m_collisionFlags); |
728 | 727 | ||
729 | d.MassSetBox(out ShellMass, m_density, m_size.X , m_size.Y, m_size.Z); | 728 | m_mass = m_density * m_size.X * m_size.Y * m_size.Z; // update mass |
730 | |||
731 | m_mass = ShellMass.mass; // update mass | ||
732 | |||
733 | // rescale PID parameters | ||
734 | PID_D = _parent_scene.avPIDD; | ||
735 | PID_P = _parent_scene.avPIDP; | ||
736 | 729 | ||
737 | // rescale PID parameters so that this aren't affected by mass | 730 | d.MassSetBoxTotal(out ShellMass, m_mass, m_size.X, m_size.Y, m_size.Z); |
738 | // and so don't get unstable for some masses | ||
739 | // also scale by ode time step so you don't need to refix them | ||
740 | 731 | ||
741 | PID_D /= 50 * 80; //scale to original mass of around 80 and 50 ODE fps | 732 | PID_D = basePID_D * m_mass / _parent_scene.ODE_STEPSIZE; |
742 | PID_D *= m_mass / _parent_scene.ODE_STEPSIZE; | 733 | PID_P = basePID_P * m_mass / _parent_scene.ODE_STEPSIZE; |
743 | PID_P /= 50 * 80; | ||
744 | PID_P *= m_mass / _parent_scene.ODE_STEPSIZE; | ||
745 | 734 | ||
746 | Body = d.BodyCreate(_parent_scene.world); | 735 | Body = d.BodyCreate(_parent_scene.world); |
747 | 736 | ||
@@ -857,8 +846,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
857 | 846 | ||
858 | } | 847 | } |
859 | 848 | ||
860 | public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact) | 849 | public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact, ref bool feetcollision) |
861 | { | 850 | { |
851 | feetcollision = false; | ||
862 | 852 | ||
863 | if (me == bonebox) // inner bone | 853 | if (me == bonebox) // inner bone |
864 | { | 854 | { |
@@ -870,44 +860,13 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
870 | if (me == topbox) // keep a box head | 860 | if (me == topbox) // keep a box head |
871 | return true; | 861 | return true; |
872 | 862 | ||
873 | // rotate elipsoide assuming only rotation around Z | 863 | float t; |
874 | float ca = m_orientation.W * m_orientation.W - m_orientation.Z * m_orientation.Z; | ||
875 | float sa = 2 * m_orientation.W * m_orientation.Z; | ||
876 | |||
877 | float isx; | ||
878 | float isy; | ||
879 | |||
880 | if (me == feetbox) // feet have narrow bounds | ||
881 | { | ||
882 | |||
883 | isx = m_invElipSizeX * invFeetScale; | ||
884 | isy = m_invElipSizeY * invFeetScale; | ||
885 | } | ||
886 | else | ||
887 | { | ||
888 | isx = m_invElipSizeX; | ||
889 | isy = m_invElipSizeY; | ||
890 | } | ||
891 | |||
892 | float a = isx * ca - isy * sa; | ||
893 | float b = isx * sa + isy * ca; | ||
894 | |||
895 | float offx = contact.pos.X - _position.X; | 864 | float offx = contact.pos.X - _position.X; |
896 | float er = offx * a; | ||
897 | er *= er; | ||
898 | |||
899 | float offy = contact.pos.Y - _position.Y; | 865 | float offy = contact.pos.Y - _position.Y; |
900 | float ty = offy * b; | ||
901 | er += ty * ty; | ||
902 | 866 | ||
903 | if (me == midbox) | 867 | if (me == midbox) |
904 | { | 868 | { |
905 | if (er > 4.0f) // no collision | 869 | t = offx * offx + offy * offy; |
906 | return false; | ||
907 | if (er < 0.2f) | ||
908 | return true; | ||
909 | |||
910 | float t = offx * offx + offy * offy; | ||
911 | t = (float)Math.Sqrt(t); | 870 | t = (float)Math.Sqrt(t); |
912 | t = 1 / t; | 871 | t = 1 / t; |
913 | offx *= t; | 872 | offx *= t; |
@@ -930,40 +889,51 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
930 | 889 | ||
931 | else if (me == feetbox) | 890 | else if (me == feetbox) |
932 | { | 891 | { |
933 | float c = feetSZ * 2; | ||
934 | float h = contact.pos.Z - _position.Z; | 892 | float h = contact.pos.Z - _position.Z; |
935 | float offz = h - feetOff; // distance from top of feetbox | ||
936 | 893 | ||
937 | float tz = offz / c; | 894 | if (Math.Abs(contact.normal.Z) > 0.95f) |
938 | er += tz * tz; | 895 | { |
896 | feetcollision = true; | ||
897 | if (h < boneOff) | ||
898 | IsColliding = true; | ||
899 | return true; | ||
900 | } | ||
901 | |||
902 | float offz = h - feetOff; // distance from top of feetbox | ||
939 | 903 | ||
940 | if (er > 4.0f) // no collision | 904 | if (offz > 0) |
941 | return false; | 905 | return false; |
942 | 906 | ||
943 | if (er > 0.2f) | 907 | if (offz > -0.01) |
908 | { | ||
909 | offx = 0; | ||
910 | offy = 0; | ||
911 | offz = -1.0f; | ||
912 | } | ||
913 | else | ||
944 | { | 914 | { |
945 | float t = offx * offx + offy * offy + offz * offz; | 915 | t = offx * offx + offy * offy + offz * offz; |
946 | t = (float)Math.Sqrt(t); | 916 | t = (float)Math.Sqrt(t); |
947 | t = 1 / t; | 917 | t = 1 / t; |
948 | offx *= t; | 918 | offx *= t; |
949 | offy *= t; | 919 | offy *= t; |
950 | offz *= t; | 920 | offz *= t; |
951 | |||
952 | if (reverse) | ||
953 | { | ||
954 | contact.normal.X = offx; | ||
955 | contact.normal.Y = offy; | ||
956 | contact.normal.Z = offz; | ||
957 | } | ||
958 | else | ||
959 | { | ||
960 | contact.normal.X = -offx; | ||
961 | contact.normal.Y = -offy; | ||
962 | contact.normal.Z = -offz; | ||
963 | } | ||
964 | } | 921 | } |
965 | 922 | ||
966 | if(h < boneOff) | 923 | if (reverse) |
924 | { | ||
925 | contact.normal.X = offx; | ||
926 | contact.normal.Y = offy; | ||
927 | contact.normal.Z = offz; | ||
928 | } | ||
929 | else | ||
930 | { | ||
931 | contact.normal.X = -offx; | ||
932 | contact.normal.Y = -offy; | ||
933 | contact.normal.Z = -offz; | ||
934 | } | ||
935 | feetcollision = true; | ||
936 | if (h < boneOff) | ||
967 | IsColliding = true; | 937 | IsColliding = true; |
968 | } | 938 | } |
969 | else | 939 | else |
@@ -1105,6 +1075,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1105 | contact.SurfaceNormal.Y = 0f; | 1075 | contact.SurfaceNormal.Y = 0f; |
1106 | contact.SurfaceNormal.Z = -1f; | 1076 | contact.SurfaceNormal.Z = -1f; |
1107 | contact.RelativeSpeed = -vel.Z; | 1077 | contact.RelativeSpeed = -vel.Z; |
1078 | contact.CharacterFeet = true; | ||
1108 | AddCollisionEvent(0, contact); | 1079 | AddCollisionEvent(0, contact); |
1109 | 1080 | ||
1110 | vec.Z *= 0.5f; | 1081 | vec.Z *= 0.5f; |