aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs15
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsActor.cs2
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs155
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs18
4 files changed, 85 insertions, 105 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index bacc9c9..f5d609d 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -3465,6 +3465,7 @@ namespace OpenSim.Region.Framework.Scenes
3465 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3465 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3466 } 3466 }
3467 3467
3468
3468 /// <summary> 3469 /// <summary>
3469 /// Event called by the physics plugin to tell the avatar about a collision. 3470 /// Event called by the physics plugin to tell the avatar about a collision.
3470 /// </summary> 3471 /// </summary>
@@ -3494,7 +3495,6 @@ namespace OpenSim.Region.Framework.Scenes
3494 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3495 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3495 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3496 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3496 3497
3497 CollisionPlane = Vector4.UnitW;
3498 3498
3499// // No collisions at all means we may be flying. Update always 3499// // No collisions at all means we may be flying. Update always
3500// // to make falling work 3500// // to make falling work
@@ -3504,6 +3504,8 @@ namespace OpenSim.Region.Framework.Scenes
3504// m_lastColCount = coldata.Count; 3504// m_lastColCount = coldata.Count;
3505// } 3505// }
3506 3506
3507 CollisionPlane = Vector4.UnitW;
3508
3507 if (coldata.Count != 0) 3509 if (coldata.Count != 0)
3508 { 3510 {
3509 switch (Animator.CurrentMovementAnimation) 3511 switch (Animator.CurrentMovementAnimation)
@@ -3517,17 +3519,22 @@ namespace OpenSim.Region.Framework.Scenes
3517 ContactPoint lowest; 3519 ContactPoint lowest;
3518 lowest.SurfaceNormal = Vector3.Zero; 3520 lowest.SurfaceNormal = Vector3.Zero;
3519 lowest.Position = Vector3.Zero; 3521 lowest.Position = Vector3.Zero;
3520 lowest.Position.Z = Single.NaN; 3522 lowest.Position.Z = float.MaxValue;
3521 3523
3522 foreach (ContactPoint contact in coldata.Values) 3524 foreach (ContactPoint contact in coldata.Values)
3523 { 3525 {
3524 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) 3526
3527 if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
3525 { 3528 {
3526 lowest = contact; 3529 lowest = contact;
3527 } 3530 }
3528 } 3531 }
3529 3532
3530 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); 3533 if (lowest.Position.Z != float.MaxValue)
3534 {
3535 lowest.SurfaceNormal = -lowest.SurfaceNormal;
3536 CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3537 }
3531 } 3538 }
3532 break; 3539 break;
3533 } 3540 }
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index 5af6373..e1168bd 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -61,6 +61,7 @@ namespace OpenSim.Region.Physics.Manager
61 public Vector3 SurfaceNormal; 61 public Vector3 SurfaceNormal;
62 public float PenetrationDepth; 62 public float PenetrationDepth;
63 public float RelativeSpeed; 63 public float RelativeSpeed;
64 public bool CharacterFeet;
64 65
65 public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth) 66 public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth)
66 { 67 {
@@ -68,6 +69,7 @@ namespace OpenSim.Region.Physics.Manager
68 SurfaceNormal = surfaceNormal; 69 SurfaceNormal = surfaceNormal;
69 PenetrationDepth = penetrationDepth; 70 PenetrationDepth = penetrationDepth;
70 RelativeSpeed = 0f; // for now let this one be set explicity 71 RelativeSpeed = 0f; // for now let this one be set explicity
72 CharacterFeet = true; // keep other plugins work as before
71 } 73 }
72 } 74 }
73 75
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;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 07987d1..2b4d368 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -224,9 +224,6 @@ namespace OpenSim.Region.Physics.OdePlugin
224// private IntPtr WaterHeightmapData = IntPtr.Zero; 224// private IntPtr WaterHeightmapData = IntPtr.Zero;
225// private GCHandle WaterMapHandler = new GCHandle(); 225// private GCHandle WaterMapHandler = new GCHandle();
226 226
227 public float avPIDD = 2200f; // make it visible
228 public float avPIDP = 900f; // make it visible
229 private float avCapRadius = 0.37f;
230 private float avDensity = 3f; 227 private float avDensity = 3f;
231 private float avMovementDivisorWalk = 1.3f; 228 private float avMovementDivisorWalk = 1.3f;
232 private float avMovementDivisorRun = 0.8f; 229 private float avMovementDivisorRun = 0.8f;
@@ -486,7 +483,6 @@ namespace OpenSim.Region.Physics.OdePlugin
486 avDensity = physicsconfig.GetFloat("av_density", avDensity); 483 avDensity = physicsconfig.GetFloat("av_density", avDensity);
487 avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk); 484 avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk);
488 avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun); 485 avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun);
489 avCapRadius = physicsconfig.GetFloat("av_capsule_radius", avCapRadius);
490 486
491 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision); 487 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision);
492 488
@@ -1040,6 +1036,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1040 1036
1041 IntPtr Joint; 1037 IntPtr Joint;
1042 1038
1039 bool FeetCollision = false;
1040
1043 int i = 0; 1041 int i = 0;
1044 int ncontacts = 0; 1042 int ncontacts = 0;
1045 while(true) 1043 while(true)
@@ -1058,7 +1056,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1058 { 1056 {
1059 if(dop1foot) 1057 if(dop1foot)
1060 { 1058 {
1061 if (!(((OdeCharacter)p1).Collide(g1,false, ref curContact))) 1059 if (!(((OdeCharacter)p1).Collide(g1, false, ref curContact, ref FeetCollision)))
1062 { 1060 {
1063 if (++i >= count) 1061 if (++i >= count)
1064 break; 1062 break;
@@ -1068,7 +1066,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1068 } 1066 }
1069 else if(dop2foot) 1067 else if(dop2foot)
1070 { 1068 {
1071 if(!(((OdeCharacter) p2).Collide(g2,true,ref curContact))) 1069 if (!(((OdeCharacter)p2).Collide(g2, true, ref curContact, ref FeetCollision)))
1072 { 1070 {
1073 if (++i >= count) 1071 if (++i >= count)
1074 break; 1072 break;
@@ -1177,9 +1175,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1177 } 1175 }
1178 } 1176 }
1179 1177
1180 if(ncontacts > 0) 1178 if (ncontacts > 0)
1179 {
1180 maxDepthContact.CharacterFeet = FeetCollision;
1181 collision_accounting_events(p1, p2, maxDepthContact); 1181 collision_accounting_events(p1, p2, maxDepthContact);
1182 1182 }
1183/* 1183/*
1184 if (notskipedcount > geomContactPointsStartthrottle) 1184 if (notskipedcount > geomContactPointsStartthrottle)
1185 { 1185 {
@@ -1393,7 +1393,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1393 pos.X = position.X; 1393 pos.X = position.X;
1394 pos.Y = position.Y; 1394 pos.Y = position.Y;
1395 pos.Z = position.Z; 1395 pos.Z = position.Z;
1396 OdeCharacter newAv = new OdeCharacter(avName, this, pos, size, avPIDD, avPIDP, avDensity, avMovementDivisorWalk, avMovementDivisorRun); 1396 OdeCharacter newAv = new OdeCharacter(avName, this, pos, size, avDensity, avMovementDivisorWalk, avMovementDivisorRun);
1397 newAv.Flying = isFlying; 1397 newAv.Flying = isFlying;
1398 newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset; 1398 newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset;
1399 1399