aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitOdePlugin
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs325
1 files changed, 28 insertions, 297 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index e912997..ecd5474 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -95,10 +95,7 @@ namespace OpenSim.Region.Physics.OdePlugin
95 95
96 private float m_feetOffset = 0; 96 private float m_feetOffset = 0;
97 private float feetOff = 0; 97 private float feetOff = 0;
98 private float feetSZ = 0.5f;
99 const float feetScale = 0.8f;
100 private float boneOff = 0; 98 private float boneOff = 0;
101 private float m_lastVelocitySqr = 0;
102 99
103 public float walkDivisor = 1.3f; 100 public float walkDivisor = 1.3f;
104 public float runDivisor = 0.8f; 101 public float runDivisor = 0.8f;
@@ -110,7 +107,6 @@ namespace OpenSim.Region.Physics.OdePlugin
110 107
111 private bool _zeroFlag = false; 108 private bool _zeroFlag = false;
112 109
113 private int m_requestedUpdateFrequency = 0;
114 private uint m_localID = 0; 110 private uint m_localID = 0;
115 public bool m_returnCollisions = false; 111 public bool m_returnCollisions = false;
116 // taints and their non-tainted counterparts 112 // taints and their non-tainted counterparts
@@ -127,7 +123,6 @@ namespace OpenSim.Region.Physics.OdePlugin
127 int m_colliderfilter = 0; 123 int m_colliderfilter = 0;
128 int m_colliderGroundfilter = 0; 124 int m_colliderGroundfilter = 0;
129 int m_colliderObjectfilter = 0; 125 int m_colliderObjectfilter = 0;
130 bool m_collisionException = false;
131 126
132 // Default we're a Character 127 // Default we're a Character
133 private CollisionCategories m_collisionCategories = (CollisionCategories.Character); 128 private CollisionCategories m_collisionCategories = (CollisionCategories.Character);
@@ -140,9 +135,7 @@ namespace OpenSim.Region.Physics.OdePlugin
140 // we do land collisions not ode | CollisionCategories.Land); 135 // we do land collisions not ode | CollisionCategories.Land);
141 public IntPtr Body = IntPtr.Zero; 136 public IntPtr Body = IntPtr.Zero;
142 private OdeScene _parent_scene; 137 private OdeScene _parent_scene;
143 private IntPtr topbox = IntPtr.Zero; 138 private IntPtr capsule = IntPtr.Zero;
144 private IntPtr midbox = IntPtr.Zero;
145 private IntPtr feetbox = IntPtr.Zero;
146 private IntPtr bbox = IntPtr.Zero; 139 private IntPtr bbox = IntPtr.Zero;
147 public IntPtr collider = IntPtr.Zero; 140 public IntPtr collider = IntPtr.Zero;
148 141
@@ -150,9 +143,6 @@ namespace OpenSim.Region.Physics.OdePlugin
150 143
151 public d.Mass ShellMass; 144 public d.Mass ShellMass;
152 145
153
154
155
156 public int m_eventsubscription = 0; 146 public int m_eventsubscription = 0;
157 private int m_cureventsubscription = 0; 147 private int m_cureventsubscription = 0;
158 private CollisionEventUpdate CollisionEventsThisFrame = null; 148 private CollisionEventUpdate CollisionEventsThisFrame = null;
@@ -214,8 +204,6 @@ namespace OpenSim.Region.Physics.OdePlugin
214 // force lower density for testing 204 // force lower density for testing
215 m_density = 3.0f; 205 m_density = 3.0f;
216 206
217 m_density *= 1.4f; // scale to have mass similar to capsule
218
219 mu = parent_scene.AvatarFriction; 207 mu = parent_scene.AvatarFriction;
220 208
221 walkDivisor = walk_divisor; 209 walkDivisor = walk_divisor;
@@ -704,58 +692,6 @@ namespace OpenSim.Region.Physics.OdePlugin
704 AddChange(changes.Momentum, momentum); 692 AddChange(changes.Momentum, momentum);
705 } 693 }
706 694
707 private void ajustCollider()
708 {
709 float vq = _velocity.LengthSquared();
710 if (m_lastVelocitySqr != vq)
711 {
712 m_lastVelocitySqr = vq;
713 if (vq > 100.0f)
714 {
715 Vector3 off = _velocity;
716 float t = 0.5f * timeStep;
717 off = off * t;
718 d.Quaternion qtmp;
719 d.GeomCopyQuaternion(bbox, out qtmp);
720 Quaternion q;
721 q.X = qtmp.X;
722 q.Y = qtmp.Y;
723 q.Z = qtmp.Z;
724 q.W = qtmp.W;
725 off *= Quaternion.Conjugate(q);
726
727 d.GeomSetOffsetPosition(bbox, off.X, off.Y, off.Z);
728
729 off.X = 2.0f * (m_size.X + Math.Abs(off.X));
730 off.Y = 2.0f * (m_size.Y + Math.Abs(off.Y));
731 off.Z = m_size.Z + 2.0f * Math.Abs(off.Z);
732 d.GeomBoxSetLengths(bbox, off.X, off.Y, off.Z);
733
734 d.GeomSetCategoryBits(bbox, (uint)m_collisionCategories);
735 d.GeomSetCollideBits(bbox, (uint)m_collisionFlags);
736 d.GeomSetCategoryBits(topbox, 0);
737 d.GeomSetCollideBits(topbox, 0);
738 d.GeomSetCategoryBits(midbox, 0);
739 d.GeomSetCollideBits(midbox, 0);
740 d.GeomSetCategoryBits(feetbox, 0);
741 d.GeomSetCollideBits(feetbox, 0);
742 }
743 else
744 {
745 d.GeomSetCategoryBits(bbox, 0);
746 d.GeomSetCollideBits(bbox, 0);
747 d.GeomSetCategoryBits(topbox, (uint)m_collisionCategories);
748 d.GeomSetCollideBits(topbox, (uint)m_collisionFlags);
749 d.GeomSetCategoryBits(midbox, (uint)m_collisionCategories);
750 d.GeomSetCollideBits(midbox, (uint)m_collisionFlags);
751 d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories);
752 d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags);
753 }
754 uint cat1 = d.GeomGetCategoryBits(bbox);
755 uint col1 = d.GeomGetCollideBits(bbox);
756
757 }
758 }
759 695
760 private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) 696 private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
761 { 697 {
@@ -764,37 +700,14 @@ namespace OpenSim.Region.Physics.OdePlugin
764 float sy = m_size.Y; 700 float sy = m_size.Y;
765 float sz = m_size.Z; 701 float sz = m_size.Z;
766 702
767 float topsx = sx * 0.9f; 703 float bot = -sz * 0.5f + m_feetOffset;
768 float midsx = sx; 704 boneOff = bot + 0.3f;
769 float feetsx = sx * feetScale;
770 float bonesx = sx * 0.2f;
771
772 float topsy = sy * 0.4f;
773 float midsy = sy;
774 float feetsy = sy * feetScale * 0.8f;
775 float bonesy = feetsy * 0.2f;
776 705
777 float topsz = sz * 0.15f;
778 float feetsz = sz * 0.45f; 706 float feetsz = sz * 0.45f;
779 if (feetsz > 0.6f) 707 if (feetsz > 0.6f)
780 feetsz = 0.6f; 708 feetsz = 0.6f;
781 709
782 float midsz = sz - topsz - feetsz; 710 feetOff = bot + feetsz;
783 float bonesz = sz;
784
785 float bot = -sz * 0.5f + m_feetOffset;
786
787 boneOff = bot + 0.3f;
788
789 float feetz = bot + feetsz * 0.5f;
790 bot += feetsz;
791
792 feetOff = bot;
793 feetSZ = feetsz;
794
795 float midz = bot + midsz * 0.5f;
796 bot += midsz;
797 float topz = bot + topsz * 0.5f;
798 711
799 _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); 712 _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace);
800 713
@@ -805,9 +718,13 @@ namespace OpenSim.Region.Physics.OdePlugin
805 d.GeomSetCategoryBits(collider, (uint)m_collisionCategories); 718 d.GeomSetCategoryBits(collider, (uint)m_collisionCategories);
806 d.GeomSetCollideBits(collider, (uint)m_collisionFlags); 719 d.GeomSetCollideBits(collider, (uint)m_collisionFlags);
807 720
808 feetbox = d.CreateBox(collider, feetsx, feetsy, feetsz); 721 float r = m_size.X;
809 midbox = d.CreateBox(collider, midsx, midsy, midsz); 722 if (m_size.Y > r)
810 topbox = d.CreateBox(collider, topsx, topsy, topsz); 723 r = m_size.Y;
724 float l = m_size.Z - r;
725 r *= 0.5f;
726 capsule = d.CreateCapsule(collider, r, l);
727
811 bbox = d.CreateBox(collider, m_size.X, m_size.Y, m_size.Z); 728 bbox = d.CreateBox(collider, m_size.X, m_size.Y, m_size.Z);
812 729
813 m_mass = m_density * m_size.X * m_size.Y * m_size.Z; // update mass 730 m_mass = m_density * m_size.X * m_size.Y * m_size.Z; // update mass
@@ -820,12 +737,10 @@ namespace OpenSim.Region.Physics.OdePlugin
820 Body = d.BodyCreate(_parent_scene.world); 737 Body = d.BodyCreate(_parent_scene.world);
821 738
822 _zeroFlag = false; 739 _zeroFlag = false;
823 m_collisionException = false;
824 m_pidControllerActive = true; 740 m_pidControllerActive = true;
825 m_freemove = false; 741 m_freemove = false;
826 742
827 _velocity = Vector3.Zero; 743 _velocity = Vector3.Zero;
828 m_lastVelocitySqr = 0;
829 744
830 d.BodySetAutoDisableFlag(Body, false); 745 d.BodySetAutoDisableFlag(Body, false);
831 d.BodySetPosition(Body, npositionX, npositionY, npositionZ); 746 d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
@@ -835,17 +750,9 @@ namespace OpenSim.Region.Physics.OdePlugin
835 _position.Z = npositionZ; 750 _position.Z = npositionZ;
836 751
837 d.BodySetMass(Body, ref ShellMass); 752 d.BodySetMass(Body, ref ShellMass);
838 d.GeomSetBody(feetbox, Body);
839 d.GeomSetBody(midbox, Body);
840 d.GeomSetBody(topbox, Body);
841 d.GeomSetBody(bbox, Body);
842
843 d.GeomSetOffsetPosition(feetbox, 0, 0, feetz);
844 d.GeomSetOffsetPosition(midbox, 0, 0, midz);
845 d.GeomSetOffsetPosition(topbox, 0, 0, topz);
846
847 ajustCollider();
848 753
754 d.GeomSetBody(bbox, Body);
755 d.GeomSetBody(capsule, Body);
849 756
850 // The purpose of the AMotor here is to keep the avatar's physical 757 // The purpose of the AMotor here is to keep the avatar's physical
851 // surrogate from rotating while moving 758 // surrogate from rotating while moving
@@ -906,26 +813,12 @@ namespace OpenSim.Region.Physics.OdePlugin
906 } 813 }
907 814
908 //kill the Geoms 815 //kill the Geoms
909 if (topbox != IntPtr.Zero) 816 if (capsule != IntPtr.Zero)
910 { 817 {
911 _parent_scene.actor_name_map.Remove(topbox); 818 _parent_scene.actor_name_map.Remove(capsule);
912 _parent_scene.waitForSpaceUnlock(collider); 819 _parent_scene.waitForSpaceUnlock(collider);
913 d.GeomDestroy(topbox); 820 d.GeomDestroy(capsule);
914 topbox = IntPtr.Zero; 821 capsule = IntPtr.Zero;
915 }
916 if (midbox != IntPtr.Zero)
917 {
918 _parent_scene.actor_name_map.Remove(midbox);
919 _parent_scene.waitForSpaceUnlock(collider);
920 d.GeomDestroy(midbox);
921 midbox = IntPtr.Zero;
922 }
923 if (feetbox != IntPtr.Zero)
924 {
925 _parent_scene.actor_name_map.Remove(feetbox);
926 _parent_scene.waitForSpaceUnlock(collider);
927 d.GeomDestroy(feetbox);
928 feetbox = IntPtr.Zero;
929 } 822 }
930 823
931 if (bbox != IntPtr.Zero) 824 if (bbox != IntPtr.Zero)
@@ -981,163 +874,21 @@ namespace OpenSim.Region.Physics.OdePlugin
981 public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact, ref bool feetcollision) 874 public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact, ref bool feetcollision)
982 { 875 {
983 feetcollision = false; 876 feetcollision = false;
984 if (m_collisionException)
985 return false;
986 877
987 Vector3 offset; 878 Vector3 offset;
988 879
989 if (me == bbox) // if moving fast
990 {
991 // force a full inelastic collision
992 m_collisionException = true;
993
994 offset = m_size * m_orientation2D;
995
996 offset.X = (float)Math.Abs(offset.X) * 0.5f + contact.depth;
997 offset.Y = (float)Math.Abs(offset.Y) * 0.5f + contact.depth;
998 offset.Z = (float)Math.Abs(offset.Z) * 0.5f + contact.depth;
999
1000 if (reverse)
1001 {
1002 offset.X *= -contact.normal.X;
1003 offset.Y *= -contact.normal.Y;
1004 offset.Z *= -contact.normal.Z;
1005 }
1006 else
1007 {
1008 offset.X *= contact.normal.X;
1009 offset.Y *= contact.normal.Y;
1010 offset.Z *= contact.normal.Z;
1011 }
1012
1013 offset.X += contact.pos.X;
1014 offset.Y += contact.pos.Y;
1015 offset.Z += contact.pos.Z;
1016
1017 //_position = offset;
1018 //return false;
1019 }
1020
1021 offset.X = contact.pos.X - _position.X; 880 offset.X = contact.pos.X - _position.X;
1022 offset.Y = contact.pos.Y - _position.Y; 881 offset.Y = contact.pos.Y - _position.Y;
1023 882
1024 if (me == topbox) 883 if (me == capsule)
1025 {
1026 offset.Z = contact.pos.Z - _position.Z;
1027
1028 offset.Normalize();
1029
1030 if (reverse)
1031 {
1032 contact.normal.X = offset.X;
1033 contact.normal.Y = offset.Y;
1034 contact.normal.Z = offset.Z;
1035 }
1036 else
1037 {
1038 contact.normal.X = -offset.X;
1039 contact.normal.Y = -offset.Y;
1040 contact.normal.Z = -offset.Z;
1041 }
1042 return true;
1043 }
1044
1045 if (me == midbox)
1046 {
1047 if (Math.Abs(contact.normal.Z) > 0.95f)
1048 {
1049 offset.Z = contact.pos.Z - _position.Z;
1050 offset.X = (float)Math.Abs(offset.X) * 0.5f + contact.depth;
1051 offset.Y = (float)Math.Abs(offset.Y) * 0.5f + contact.depth;
1052 offset.Z = (float)Math.Abs(offset.Z) * 0.5f + contact.depth;
1053
1054 if (reverse)
1055 {
1056 offset.X *= -contact.normal.X;
1057 offset.Y *= -contact.normal.Y;
1058 offset.Z *= -contact.normal.Z;
1059 }
1060 else
1061 {
1062 offset.X *= contact.normal.X;
1063 offset.Y *= contact.normal.Y;
1064 offset.Z *= contact.normal.Z;
1065 }
1066
1067 offset.X += contact.pos.X;
1068 offset.Y += contact.pos.Y;
1069 offset.Z += contact.pos.Z;
1070 _position = offset;
1071 return true;
1072 }
1073 else
1074 offset.Z = contact.normal.Z;
1075
1076 offset.Normalize();
1077
1078 /*
1079 if (reverse)
1080 {
1081 contact.normal.X = offset.X;
1082 contact.normal.Y = offset.Y;
1083 contact.normal.Z = offset.Z;
1084 }
1085 else
1086 {
1087 contact.normal.X = -offset.X;
1088 contact.normal.Y = -offset.Y;
1089 contact.normal.Z = -offset.Z;
1090 }
1091 */
1092 //_position.Z = offset.Z;
1093 return true;
1094 }
1095
1096 else if (me == feetbox)
1097 { 884 {
1098 float h = contact.pos.Z - _position.Z; 885 float h = contact.pos.Z - _position.Z;
1099 886 offset.Z = h - feetOff;
1100 // Only do this if the normal is sufficiently pointing in the 'up' direction
1101 if (Math.Abs(contact.normal.Z) > 0.95f)
1102 {
1103 // We Only want to do this if we're sunk into the object a bit and we're stuck and we're trying to move and feetcollision is false
1104 if ((contact.depth > 0.0010f && _velocity.X == 0f && _velocity.Y == 0 && _velocity.Z == 0)
1105 && (_target_velocity.X > 0 || _target_velocity.Y > 0 || _target_velocity.Z > 0)
1106 && (!feetcollision) )
1107 {
1108 m_collisionException = true; // Stop looping, do this only once not X times Contacts
1109 _position.Z += contact.depth + 0.01f; // Move us Up the amount that we sank in, and add 0.01 meters to gently lift avatar up.
1110
1111 return true;
1112 }
1113
1114 if (contact.normal.Z > 0)
1115 contact.normal.Z = 1.0f;
1116 else
1117 contact.normal.Z = -1.0f;
1118 contact.normal.X = 0.0f;
1119 contact.normal.Y = 0.0f;
1120 feetcollision = true;
1121 if (h < boneOff)
1122 IsColliding = true;
1123 return true;
1124 }
1125
1126 offset.Z = h - feetOff; // distance from top of feetbox
1127 887
1128 if (offset.Z > 0) 888 if (offset.Z > 0)
1129 return false; 889 return true;
1130 890
1131 if (offset.Z > -0.01) 891 offset.Normalize();
1132 {
1133 offset.X = 0;
1134 offset.Y = 0;
1135 offset.Z = -1.0f;
1136 }
1137 else
1138 {
1139 offset.Normalize();
1140 }
1141 892
1142 if (reverse) 893 if (reverse)
1143 { 894 {
@@ -1171,23 +922,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1171 if (Body == IntPtr.Zero) 922 if (Body == IntPtr.Zero)
1172 return; 923 return;
1173 924
1174 if (m_collisionException)
1175 {
1176 d.BodySetPosition(Body,_position.X, _position.Y, _position.Z);
1177 d.BodySetLinearVel(Body, 0, 0, 0);
1178
1179 float v = _velocity.Length();
1180 if (v != 0)
1181 {
1182 v = 5.0f / v;
1183 _velocity = _velocity * v;
1184 d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z);
1185 }
1186 ajustCollider();
1187 m_collisionException = false;
1188 return;
1189 }
1190
1191 d.Vector3 dtmp = d.BodyGetPosition(Body); 925 d.Vector3 dtmp = d.BodyGetPosition(Body);
1192 Vector3 localpos = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); 926 Vector3 localpos = new Vector3(dtmp.X, dtmp.Y, dtmp.Z);
1193 927
@@ -1263,7 +997,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1263 // colide with land 997 // colide with land
1264 998
1265 d.AABB aabb; 999 d.AABB aabb;
1266 d.GeomGetAABB(feetbox, out aabb); 1000// d.GeomGetAABB(feetbox, out aabb);
1001 d.GeomGetAABB(capsule, out aabb);
1267 float chrminZ = aabb.MinZ; ; // move up a bit 1002 float chrminZ = aabb.MinZ; ; // move up a bit
1268 Vector3 posch = localpos; 1003 Vector3 posch = localpos;
1269 1004
@@ -1489,7 +1224,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1489 m_rotationalVelocity.Z = dtmp.Z; 1224 m_rotationalVelocity.Z = dtmp.Z;
1490 Math.Round(m_rotationalVelocity.Z,3); 1225 Math.Round(m_rotationalVelocity.Z,3);
1491 } 1226 }
1492 ajustCollider();
1493 } 1227 }
1494 1228
1495 public void round(ref Vector3 v, int digits) 1229 public void round(ref Vector3 v, int digits)
@@ -1655,10 +1389,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1655 AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z); 1389 AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z);
1656 1390
1657 _parent_scene.actor_name_map[collider] = (PhysicsActor)this; 1391 _parent_scene.actor_name_map[collider] = (PhysicsActor)this;
1658 _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this; 1392// _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this;
1659 _parent_scene.actor_name_map[midbox] = (PhysicsActor)this; 1393// _parent_scene.actor_name_map[midbox] = (PhysicsActor)this;
1660 _parent_scene.actor_name_map[topbox] = (PhysicsActor)this; 1394// _parent_scene.actor_name_map[topbox] = (PhysicsActor)this;
1661 _parent_scene.actor_name_map[bbox] = (PhysicsActor)this; 1395 _parent_scene.actor_name_map[bbox] = (PhysicsActor)this;
1396 _parent_scene.actor_name_map[capsule] = (PhysicsActor)this;
1662 _parent_scene.AddCharacter(this); 1397 _parent_scene.AddCharacter(this);
1663 } 1398 }
1664 else 1399 else
@@ -1714,13 +1449,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1714 1449
1715 1450
1716 _parent_scene.actor_name_map[collider] = (PhysicsActor)this; 1451 _parent_scene.actor_name_map[collider] = (PhysicsActor)this;
1717 _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this;
1718 _parent_scene.actor_name_map[midbox] = (PhysicsActor)this;
1719 _parent_scene.actor_name_map[topbox] = (PhysicsActor)this;
1720 _parent_scene.actor_name_map[bbox] = (PhysicsActor)this; 1452 _parent_scene.actor_name_map[bbox] = (PhysicsActor)this;
1453 _parent_scene.actor_name_map[capsule] = (PhysicsActor)this;
1721 } 1454 }
1722 m_freemove = false; 1455 m_freemove = false;
1723 m_collisionException = false;
1724 m_pidControllerActive = true; 1456 m_pidControllerActive = true;
1725 } 1457 }
1726 else 1458 else
@@ -1851,7 +1583,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1851 1583
1852 if (Body != IntPtr.Zero) 1584 if (Body != IntPtr.Zero)
1853 d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z); 1585 d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z);
1854 ajustCollider();
1855 } 1586 }
1856 1587
1857 private void donullchange() 1588 private void donullchange()