aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs369
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs69
2 files changed, 337 insertions, 101 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index 94ed663..3d5be3e 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -79,6 +79,8 @@ namespace OpenSim.Region.Physics.OdePlugin
79 private Vector3 _target_velocity; 79 private Vector3 _target_velocity;
80 private Vector3 _acceleration; 80 private Vector3 _acceleration;
81 private Vector3 m_rotationalVelocity; 81 private Vector3 m_rotationalVelocity;
82 private Vector3 m_size;
83 private Quaternion m_orientation;
82 private float m_mass = 80f; 84 private float m_mass = 80f;
83 public float m_density = 60f; 85 public float m_density = 60f;
84 private bool m_pidControllerActive = true; 86 private bool m_pidControllerActive = true;
@@ -86,10 +88,17 @@ namespace OpenSim.Region.Physics.OdePlugin
86 public float PID_P = 900.0f; 88 public float PID_P = 900.0f;
87 //private static float POSTURE_SERVO = 10000.0f; 89 //private static float POSTURE_SERVO = 10000.0f;
88 90
89 public float CAPSULE_RADIUS = 0.37f;
90 public float CAPSULE_LENGTH = 2.140599f;
91 91
92 const float CAP_OFFSET = -.2f; // compensation of SL size offset plus spheric collision shape bottom 92 private float m_invElipSizeX;
93 private float m_invElipSizeY;
94
95 private float feetOff = 0;
96 private float feetSZ = 0.5f;
97 const float feetScale = 0.9f;
98 const float invFeetScale = 1.0f / 0.9f;
99 const float sizeZAdjust = 0.15f;
100 private float boneOff = 0;
101
93 102
94 public float walkDivisor = 1.3f; 103 public float walkDivisor = 1.3f;
95 public float runDivisor = 0.8f; 104 public float runDivisor = 0.8f;
@@ -127,10 +136,16 @@ namespace OpenSim.Region.Physics.OdePlugin
127 // we do land collisions not ode | CollisionCategories.Land); 136 // we do land collisions not ode | CollisionCategories.Land);
128 public IntPtr Body = IntPtr.Zero; 137 public IntPtr Body = IntPtr.Zero;
129 private OdeScene _parent_scene; 138 private OdeScene _parent_scene;
130 public IntPtr Shell = IntPtr.Zero; 139 public IntPtr topbox = IntPtr.Zero;
140 public IntPtr midbox = IntPtr.Zero;
141 public IntPtr feetbox = IntPtr.Zero;
142 public IntPtr bonebox = IntPtr.Zero;
143
131 public IntPtr Amotor = IntPtr.Zero; 144 public IntPtr Amotor = IntPtr.Zero;
145
132 public d.Mass ShellMass; 146 public d.Mass ShellMass;
133// public bool collidelock = false; 147
148
134 149
135 public int m_eventsubscription = 0; 150 public int m_eventsubscription = 0;
136 private int m_cureventsubscription = 0; 151 private int m_cureventsubscription = 0;
@@ -145,7 +160,7 @@ namespace OpenSim.Region.Physics.OdePlugin
145 160
146 161
147 162
148 public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float density, float walk_divisor, float rundivisor) 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)
149 { 164 {
150 m_uuid = UUID.Random(); 165 m_uuid = UUID.Random();
151 166
@@ -171,9 +186,20 @@ namespace OpenSim.Region.Physics.OdePlugin
171 186
172 PID_D = pid_d; 187 PID_D = pid_d;
173 PID_P = pid_p; 188 PID_P = pid_p;
174 CAPSULE_RADIUS = capsule_radius; 189
190 m_size.X = pSize.X;
191 m_size.Y = pSize.Y;
192 m_size.Z = pSize.Z;
193
194 if(m_size.X <0.01f)
195 m_size.X = 0.01f;
196 if(m_size.Y <0.01f)
197 m_size.Y = 0.01f;
198 if(m_size.Z <0.01f)
199 m_size.Z = 0.01f;
200
201 m_orientation = Quaternion.Identity;
175 m_density = density; 202 m_density = density;
176 m_mass = 80f; // sure we have a default
177 203
178 // force lower density for testing 204 // force lower density for testing
179 m_density = 3.0f; 205 m_density = 3.0f;
@@ -183,8 +209,7 @@ namespace OpenSim.Region.Physics.OdePlugin
183 walkDivisor = walk_divisor; 209 walkDivisor = walk_divisor;
184 runDivisor = rundivisor; 210 runDivisor = rundivisor;
185 211
186 CAPSULE_LENGTH = size.Z - CAPSULE_RADIUS + CAP_OFFSET; 212 m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default
187 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
188 213
189 m_isPhysical = false; // current status: no ODE information exists 214 m_isPhysical = false; // current status: no ODE information exists
190 215
@@ -426,14 +451,21 @@ namespace OpenSim.Region.Physics.OdePlugin
426 /// </summary> 451 /// </summary>
427 public override Vector3 Size 452 public override Vector3 Size
428 { 453 {
429 get { 454 get
430 float d = CAPSULE_RADIUS * 2; 455 {
431 return new Vector3(d, d, (CAPSULE_LENGTH + CAPSULE_RADIUS - CAP_OFFSET)); 456 return m_size;
432 } 457 }
433 set 458 set
434 { 459 {
435 if (value.IsFinite()) 460 if (value.IsFinite())
436 { 461 {
462 if(value.X <0.01f)
463 value.X = 0.01f;
464 if(value.Y <0.01f)
465 value.Y = 0.01f;
466 if(value.Z <0.01f)
467 value.Z = 0.01f;
468
437 AddChange(changes.Size, value); 469 AddChange(changes.Size, value);
438 } 470 }
439 else 471 else
@@ -459,8 +491,7 @@ namespace OpenSim.Region.Physics.OdePlugin
459 { 491 {
460 get 492 get
461 { 493 {
462 float AVvolume = (float)(Math.PI * CAPSULE_RADIUS * CAPSULE_RADIUS * (1.3333333333f * CAPSULE_RADIUS + CAPSULE_LENGTH)); 494 return m_density * m_size.X * m_size.Y * m_size.Z;
463 return m_density * AVvolume;
464 } 495 }
465 } 496 }
466 public override void link(PhysicsActor obj) 497 public override void link(PhysicsActor obj)
@@ -578,9 +609,14 @@ namespace OpenSim.Region.Physics.OdePlugin
578 609
579 public override Quaternion Orientation 610 public override Quaternion Orientation
580 { 611 {
581 get { return Quaternion.Identity; } 612 get { return m_orientation; }
582 set 613 set
583 { 614 {
615 // fakeori = value;
616 // givefakeori++;
617
618 value.Normalize();
619 AddChange(changes.Orientation, value);
584 } 620 }
585 } 621 }
586 622
@@ -632,32 +668,65 @@ namespace OpenSim.Region.Physics.OdePlugin
632 AddChange(changes.Momentum, momentum); 668 AddChange(changes.Momentum, momentum);
633 } 669 }
634 670
635
636 // WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access
637 // to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only
638 // place that is safe to call this routine AvatarGeomAndBodyCreation.
639 private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) 671 private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
640 { 672 {
673 // sizes one day should came from visual parameters
674 float sz = m_size.Z + sizeZAdjust;
675
676 m_invElipSizeX = 1.0f / m_size.X;
677 m_invElipSizeY = 1.0f / m_size.Y;
678
679 float topsx = m_size.X;
680 float midsx = m_size.X;
681 float feetsx = m_size.X * feetScale;
682 float bonesx = feetsx * 0.2f;
683
684 float topsy = m_size.Y * 0.5f;
685 float midsy = m_size.Y;
686 float feetsy = m_size.Y * feetScale;
687 float bonesy = feetsy * 0.2f;
688
689 float topsz = sz * 0.15f;
690 float feetsz = sz * 0.3f;
691 if (feetsz > 0.6f)
692 feetsz = 0.6f;
693
694 float midsz = sz - topsz - feetsz;
695 float bonesz = sz;
696
697 float bot = -sz * 0.5f;
698
699 boneOff = bot + 0.3f;
700
701 float feetz = bot + feetsz * 0.5f;
702 bot += feetsz;
703
704 feetOff = bot;
705 feetSZ = feetsz;
706
707 float midz = bot + midsz * 0.5f;
708 bot += midsz;
709 float topz = bot + topsz * 0.5f;
710
641 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); 711 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
642 if (CAPSULE_LENGTH <= 0)
643 {
644 m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
645 CAPSULE_LENGTH = 0.01f;
646 712
647 } 713 feetbox = d.CreateBox(_parent_scene.ActiveSpace, feetsx, feetsy, feetsz);
714 d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories);
715 d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags);
648 716
649 if (CAPSULE_RADIUS <= 0) 717 midbox = d.CreateBox(_parent_scene.ActiveSpace, midsx, midsy, midsz);
650 { 718 d.GeomSetCategoryBits(midbox, (uint)m_collisionCategories);
651 m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); 719 d.GeomSetCollideBits(midbox, (uint)m_collisionFlags);
652 CAPSULE_RADIUS = 0.01f;
653 720
654 } 721 topbox = d.CreateBox(_parent_scene.ActiveSpace, topsx, topsy, topsz);
655 Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH); 722 d.GeomSetCategoryBits(topbox, (uint)m_collisionCategories);
723 d.GeomSetCollideBits(topbox, (uint)m_collisionFlags);
656 724
657 d.GeomSetCategoryBits(Shell, (uint)m_collisionCategories); 725 bonebox = d.CreateBox(_parent_scene.ActiveSpace, bonesx, bonesy, bonesz);
658 d.GeomSetCollideBits(Shell, (uint)m_collisionFlags); 726 d.GeomSetCategoryBits(bonebox, (uint)m_collisionCategories);
727 d.GeomSetCollideBits(bonebox, (uint)m_collisionFlags);
659 728
660 d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH); 729 d.MassSetBox(out ShellMass, m_density, m_size.X , m_size.Y, m_size.Z);
661 730
662 m_mass = ShellMass.mass; // update mass 731 m_mass = ShellMass.mass; // update mass
663 732
@@ -688,7 +757,14 @@ namespace OpenSim.Region.Physics.OdePlugin
688 _position.Z = npositionZ; 757 _position.Z = npositionZ;
689 758
690 d.BodySetMass(Body, ref ShellMass); 759 d.BodySetMass(Body, ref ShellMass);
691 d.GeomSetBody(Shell, Body); 760 d.GeomSetBody(feetbox, Body);
761 d.GeomSetBody(midbox, Body);
762 d.GeomSetBody(topbox, Body);
763 d.GeomSetBody(bonebox, Body);
764
765 d.GeomSetOffsetPosition(feetbox, 0, 0, feetz);
766 d.GeomSetOffsetPosition(midbox, 0, 0, midz);
767 d.GeomSetOffsetPosition(topbox, 0, 0, topz);
692 768
693 // The purpose of the AMotor here is to keep the avatar's physical 769 // The purpose of the AMotor here is to keep the avatar's physical
694 // surrogate from rotating while moving 770 // surrogate from rotating while moving
@@ -748,15 +824,152 @@ namespace OpenSim.Region.Physics.OdePlugin
748 Body = IntPtr.Zero; 824 Body = IntPtr.Zero;
749 } 825 }
750 826
751 //kill the Geometry 827 //kill the Geoms
752 if (Shell != IntPtr.Zero) 828 if (topbox != IntPtr.Zero)
753 { 829 {
754// _parent_scene.geom_name_map.Remove(Shell); 830 _parent_scene.actor_name_map.Remove(topbox);
755 _parent_scene.actor_name_map.Remove(Shell);
756 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); 831 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
757 d.GeomDestroy(Shell); 832 d.GeomDestroy(topbox);
758 Shell = IntPtr.Zero; 833 topbox = IntPtr.Zero;
834 }
835 if (midbox != IntPtr.Zero)
836 {
837 _parent_scene.actor_name_map.Remove(midbox);
838 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
839 d.GeomDestroy(midbox);
840 midbox = IntPtr.Zero;
841 }
842 if (feetbox != IntPtr.Zero)
843 {
844 _parent_scene.actor_name_map.Remove(feetbox);
845 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
846 d.GeomDestroy(feetbox);
847 feetbox = IntPtr.Zero;
848 }
849
850 if (bonebox != IntPtr.Zero)
851 {
852 _parent_scene.actor_name_map.Remove(bonebox);
853 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
854 d.GeomDestroy(bonebox);
855 bonebox = IntPtr.Zero;
856 }
857
858 }
859
860 public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact)
861 {
862
863 if (me == bonebox) // inner bone
864 {
865 if (contact.pos.Z - _position.Z < boneOff)
866 IsColliding = true;
867 return true;
868 }
869
870 if (me == topbox) // keep a box head
871 return true;
872
873 // rotate elipsoide assuming only rotation around Z
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;
896 float er = offx * a;
897 er *= er;
898
899 float offy = contact.pos.Y - _position.Y;
900 float ty = offy * b;
901 er += ty * ty;
902
903 if (me == midbox)
904 {
905 if (er > 4.0f) // no collision
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);
912 t = 1 / t;
913 offx *= t;
914 offy *= t;
915
916 if (reverse)
917 {
918 contact.normal.X = offx;
919 contact.normal.Y = offy;
920 }
921 else
922 {
923 contact.normal.X = -offx;
924 contact.normal.Y = -offy;
925 }
926
927 contact.normal.Z = 0;
928 return true;
929 }
930
931 else if (me == feetbox)
932 {
933 float c = feetSZ * 2;
934 float h = contact.pos.Z - _position.Z;
935 float offz = h - feetOff; // distance from top of feetbox
936
937 float tz = offz / c;
938 er += tz * tz;
939
940 if (er > 4.0f) // no collision
941 return false;
942
943 if (er > 0.2f)
944 {
945 float t = offx * offx + offy * offy + offz * offz;
946 t = (float)Math.Sqrt(t);
947 t = 1 / t;
948 offx *= t;
949 offy *= t;
950 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 }
965
966 if(h < boneOff)
967 IsColliding = true;
759 } 968 }
969 else
970 return false;
971
972 return true;
760 } 973 }
761 974
762 /// <summary> 975 /// <summary>
@@ -776,10 +989,10 @@ namespace OpenSim.Region.Physics.OdePlugin
776 // so force it back to identity 989 // so force it back to identity
777 990
778 d.Quaternion qtmp; 991 d.Quaternion qtmp;
779 qtmp.W = 1; 992 qtmp.W = m_orientation.W;
780 qtmp.X = 0; 993 qtmp.X = m_orientation.X;
781 qtmp.Y = 0; 994 qtmp.Y = m_orientation.Y;
782 qtmp.Z = 0; 995 qtmp.Z = m_orientation.Z;
783 d.BodySetQuaternion(Body, ref qtmp); 996 d.BodySetQuaternion(Body, ref qtmp);
784 997
785 if (m_pidControllerActive == false) 998 if (m_pidControllerActive == false)
@@ -843,7 +1056,7 @@ namespace OpenSim.Region.Physics.OdePlugin
843 //****************************************** 1056 //******************************************
844 // colide with land 1057 // colide with land
845 d.AABB aabb; 1058 d.AABB aabb;
846 d.GeomGetAABB(Shell, out aabb); 1059 d.GeomGetAABB(feetbox, out aabb);
847 float chrminZ = aabb.MinZ - 0.04f; // move up a bit 1060 float chrminZ = aabb.MinZ - 0.04f; // move up a bit
848 Vector3 posch = localpos; 1061 Vector3 posch = localpos;
849 1062
@@ -1182,20 +1395,14 @@ namespace OpenSim.Region.Physics.OdePlugin
1182 { 1395 {
1183 if (NewStatus) 1396 if (NewStatus)
1184 { 1397 {
1185 // Create avatar capsule and related ODE data 1398 AvatarGeomAndBodyDestroy();
1186 if ((Shell != IntPtr.Zero))
1187 {
1188 // a lost shell ?
1189 m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - "
1190 + (Shell != IntPtr.Zero ? "Shell " : "")
1191 + (Body != IntPtr.Zero ? "Body " : "")
1192 + (Amotor != IntPtr.Zero ? "Amotor " : ""));
1193 AvatarGeomAndBodyDestroy();
1194 }
1195 1399
1196 AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z); 1400 AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z);
1197 1401
1198 _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; 1402 _parent_scene.actor_name_map[topbox] = (PhysicsActor)this;
1403 _parent_scene.actor_name_map[midbox] = (PhysicsActor)this;
1404 _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this;
1405 _parent_scene.actor_name_map[bonebox] = (PhysicsActor)this;
1199 _parent_scene.AddCharacter(this); 1406 _parent_scene.AddCharacter(this);
1200 } 1407 }
1201 else 1408 else
@@ -1224,37 +1431,29 @@ namespace OpenSim.Region.Physics.OdePlugin
1224 { 1431 {
1225 } 1432 }
1226 1433
1227 private void changeSize(Vector3 Size) 1434 private void changeSize(Vector3 pSize)
1228 { 1435 {
1229 if (Size.IsFinite()) 1436 if (pSize.IsFinite())
1230 { 1437 {
1231 float caplen = Size.Z; 1438 // for now only look to Z changes since viewers also don't change X and Y
1439 if (pSize.Z != m_size.Z)
1440 {
1441 AvatarGeomAndBodyDestroy();
1232 1442
1233 caplen = caplen - CAPSULE_RADIUS + CAP_OFFSET;
1234 1443
1235 if (caplen != CAPSULE_LENGTH) 1444 float oldsz = m_size.Z;
1236 { 1445 m_size = pSize;
1237 if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
1238 {
1239 AvatarGeomAndBodyDestroy();
1240 1446
1241 float prevCapsule = CAPSULE_LENGTH;
1242 CAPSULE_LENGTH = caplen;
1243 1447
1244 AvatarGeomAndBodyCreation(_position.X, _position.Y, 1448 AvatarGeomAndBodyCreation(_position.X, _position.Y,
1245 _position.Z + (CAPSULE_LENGTH - prevCapsule) * 0.5f); 1449 _position.Z + (m_size.Z - oldsz) * 0.5f);
1246 1450
1247 Velocity = Vector3.Zero; 1451 Velocity = Vector3.Zero;
1248 1452
1249 _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; 1453 _parent_scene.actor_name_map[topbox] = (PhysicsActor)this;
1250 } 1454 _parent_scene.actor_name_map[midbox] = (PhysicsActor)this;
1251 else 1455 _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this;
1252 { 1456 _parent_scene.actor_name_map[bonebox] = (PhysicsActor)this;
1253 m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - "
1254 + (Shell == IntPtr.Zero ? "Shell " : "")
1255 + (Body == IntPtr.Zero ? "Body " : "")
1256 + (Amotor == IntPtr.Zero ? "Amotor " : ""));
1257 }
1258 } 1457 }
1259 m_freemove = false; 1458 m_freemove = false;
1260 m_pidControllerActive = true; 1459 m_pidControllerActive = true;
@@ -1276,6 +1475,14 @@ namespace OpenSim.Region.Physics.OdePlugin
1276 1475
1277 private void changeOrientation(Quaternion newOri) 1476 private void changeOrientation(Quaternion newOri)
1278 { 1477 {
1478 d.Quaternion myrot = new d.Quaternion();
1479 myrot.X = newOri.X;
1480 myrot.Y = newOri.Y;
1481 myrot.Z = newOri.Z;
1482 myrot.W = newOri.W;
1483 float t = d.JointGetAMotorAngle(Amotor, 2);
1484 d.BodySetQuaternion(Body,ref myrot);
1485 m_orientation = newOri;
1279 } 1486 }
1280 1487
1281 private void changeVelocity(Vector3 newVel) 1488 private void changeVelocity(Vector3 newVel)
@@ -1365,7 +1572,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1365 1572
1366 public bool DoAChange(changes what, object arg) 1573 public bool DoAChange(changes what, object arg)
1367 { 1574 {
1368 if (Shell == IntPtr.Zero && what != changes.Add && what != changes.Remove) 1575 if (topbox == IntPtr.Zero && what != changes.Add && what != changes.Remove)
1369 { 1576 {
1370 return false; 1577 return false;
1371 } 1578 }
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 54bc29f..003a91c 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -840,6 +840,8 @@ namespace OpenSim.Region.Physics.OdePlugin
840 { 840 {
841 case (int)ActorTypes.Agent: 841 case (int)ActorTypes.Agent:
842 { 842 {
843 dop1foot = true;
844
843 AvanormOverride = true; 845 AvanormOverride = true;
844 Vector3 tmp = p2.Position - p1.Position; 846 Vector3 tmp = p2.Position - p1.Position;
845 normoverride = p2.Velocity - p1.Velocity; 847 normoverride = p2.Velocity - p1.Velocity;
@@ -883,6 +885,10 @@ namespace OpenSim.Region.Physics.OdePlugin
883 switch (p2.PhysicsActorType) 885 switch (p2.PhysicsActorType)
884 { 886 {
885 case (int)ActorTypes.Agent: 887 case (int)ActorTypes.Agent:
888
889
890 dop2foot = true;
891
886 AvanormOverride = true; 892 AvanormOverride = true;
887 893
888 Vector3 tmp = p2.Position - p1.Position; 894 Vector3 tmp = p2.Position - p1.Position;
@@ -1017,6 +1023,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1017 IntPtr Joint; 1023 IntPtr Joint;
1018 1024
1019 int i = 0; 1025 int i = 0;
1026 int ncontacts = 0;
1020 while(true) 1027 while(true)
1021 { 1028 {
1022 1029
@@ -1031,7 +1038,28 @@ namespace OpenSim.Region.Physics.OdePlugin
1031 else 1038 else
1032 1039
1033 { 1040 {
1041 if(dop1foot)
1042 {
1043 if (!(((OdeCharacter)p1).Collide(g1,false, ref curContact)))
1044 {
1045 if (++i >= count)
1046 break;
1047 else
1048 continue;
1049 }
1050 }
1051 else if(dop2foot)
1052 {
1053 if(!(((OdeCharacter) p2).Collide(g2,true,ref curContact)))
1054 {
1055 if (++i >= count)
1056 break;
1057 else
1058 continue;
1059 }
1060 }
1034 1061
1062/*
1035 if (AvanormOverride) 1063 if (AvanormOverride)
1036 { 1064 {
1037 if (curContact.depth > 0.3f) 1065 if (curContact.depth > 0.3f)
@@ -1081,34 +1109,31 @@ namespace OpenSim.Region.Physics.OdePlugin
1081 { 1109 {
1082 float sz = p2.Size.Z; 1110 float sz = p2.Size.Z;
1083 Vector3 vtmp = p2.Position; 1111 Vector3 vtmp = p2.Position;
1084 float ppos = curContact.pos.Z - vtmp.Z + (sz - avCapRadius) * 0.5f; 1112 vtmp.Z -= sz * 0.5f;
1113 vtmp.Z += 0.5f;
1114 float ppos = vtmp.Z - curContact.pos.Z;
1085 if (ppos > 0f) 1115 if (ppos > 0f)
1086 { 1116 {
1087 if (!p2.Flying) 1117 if (!p2.Flying)
1088 { 1118 {
1089 d.AABB aabb;
1090 d.GeomGetAABB(g1, out aabb);
1091 float tmp = vtmp.Z - sz * .18f; 1119 float tmp = vtmp.Z - sz * .18f;
1092 1120 vtmp.X = curContact.pos.X - vtmp.X;
1093 if (aabb.MaxZ < tmp) 1121 vtmp.Y = curContact.pos.Y - vtmp.Y;
1094 { 1122 vtmp.Z = curContact.pos.Z - vtmp.Z;
1095 vtmp.X = curContact.pos.X - vtmp.X; 1123 vtmp.Normalize();
1096 vtmp.Y = curContact.pos.Y - vtmp.Y; 1124 curContact.normal.X = vtmp.X;
1097 vtmp.Z = -0.2f; 1125 curContact.normal.Y = vtmp.Y;
1098 vtmp.Normalize(); 1126 curContact.normal.Z = vtmp.Z;
1099 curContact.normal.X = vtmp.X;
1100 curContact.normal.Y = vtmp.Y;
1101 curContact.normal.Z = vtmp.Z;
1102 }
1103 } 1127 }
1104 } 1128 }
1105 else 1129// else
1106 p2.IsColliding = true; 1130 p2.IsColliding = true;
1107 1131
1108 } 1132 }
1109 } 1133 }
1110 } 1134 }
1111 1135*/
1136 ncontacts++;
1112 Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale); 1137 Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale);
1113 d.JointAttach(Joint, b1, b2); 1138 d.JointAttach(Joint, b1, b2);
1114 1139
@@ -1134,7 +1159,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1134 } 1159 }
1135 } 1160 }
1136 1161
1137 collision_accounting_events(p1, p2, maxDepthContact); 1162 if(ncontacts > 0)
1163 collision_accounting_events(p1, p2, maxDepthContact);
1138 1164
1139/* 1165/*
1140 if (notskipedcount > geomContactPointsStartthrottle) 1166 if (notskipedcount > geomContactPointsStartthrottle)
@@ -1234,14 +1260,17 @@ namespace OpenSim.Region.Physics.OdePlugin
1234 { 1260 {
1235 foreach (OdeCharacter chr in _characters) 1261 foreach (OdeCharacter chr in _characters)
1236 { 1262 {
1237 if (chr == null || chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero) 1263 if (chr == null || chr.Body == IntPtr.Zero)
1238 continue; 1264 continue;
1239 1265
1240 chr.IsColliding = false; 1266 chr.IsColliding = false;
1241 // chr.CollidingGround = false; not done here 1267 // chr.CollidingGround = false; not done here
1242 chr.CollidingObj = false; 1268 chr.CollidingObj = false;
1243 // do colisions with static space 1269 // do colisions with static space
1244 d.SpaceCollide2(StaticSpace, chr.Shell, IntPtr.Zero, nearCallback); 1270 d.SpaceCollide2(StaticSpace, chr.topbox, IntPtr.Zero, nearCallback);
1271 d.SpaceCollide2(StaticSpace, chr.midbox, IntPtr.Zero, nearCallback);
1272 d.SpaceCollide2(StaticSpace, chr.feetbox, IntPtr.Zero, nearCallback);
1273 d.SpaceCollide2(StaticSpace, chr.bonebox, IntPtr.Zero, nearCallback);
1245 // no coll with gnd 1274 // no coll with gnd
1246 } 1275 }
1247 } 1276 }
@@ -1334,7 +1363,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1334 pos.X = position.X; 1363 pos.X = position.X;
1335 pos.Y = position.Y; 1364 pos.Y = position.Y;
1336 pos.Z = position.Z; 1365 pos.Z = position.Z;
1337 OdeCharacter newAv = new OdeCharacter(avName, this, pos, size, avPIDD, avPIDP, avCapRadius, avDensity, avMovementDivisorWalk, avMovementDivisorRun); 1366 OdeCharacter newAv = new OdeCharacter(avName, this, pos, size, avPIDD, avPIDP, avDensity, avMovementDivisorWalk, avMovementDivisorRun);
1338 newAv.Flying = isFlying; 1367 newAv.Flying = isFlying;
1339 newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset; 1368 newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset;
1340 1369