aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs155
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;