diff options
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin')
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 377 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 12 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 69 |
3 files changed, 350 insertions, 108 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index f5bf05d..3d5be3e 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | |||
@@ -79,14 +79,27 @@ 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; |
85 | public float PID_D = 800.0f; | 87 | public float PID_D = 800.0f; |
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 | public float CAPSULE_RADIUS = 0.37f; | 90 | |
89 | public float CAPSULE_LENGTH = 2.140599f; | 91 | |
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 | |||
102 | |||
90 | public float walkDivisor = 1.3f; | 103 | public float walkDivisor = 1.3f; |
91 | public float runDivisor = 0.8f; | 104 | public float runDivisor = 0.8f; |
92 | private bool flying = false; | 105 | private bool flying = false; |
@@ -123,10 +136,16 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
123 | // we do land collisions not ode | CollisionCategories.Land); | 136 | // we do land collisions not ode | CollisionCategories.Land); |
124 | public IntPtr Body = IntPtr.Zero; | 137 | public IntPtr Body = IntPtr.Zero; |
125 | private OdeScene _parent_scene; | 138 | private OdeScene _parent_scene; |
126 | 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 | |||
127 | public IntPtr Amotor = IntPtr.Zero; | 144 | public IntPtr Amotor = IntPtr.Zero; |
145 | |||
128 | public d.Mass ShellMass; | 146 | public d.Mass ShellMass; |
129 | // public bool collidelock = false; | 147 | |
148 | |||
130 | 149 | ||
131 | public int m_eventsubscription = 0; | 150 | public int m_eventsubscription = 0; |
132 | private int m_cureventsubscription = 0; | 151 | private int m_cureventsubscription = 0; |
@@ -139,7 +158,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
139 | 158 | ||
140 | float mu; | 159 | float mu; |
141 | 160 | ||
142 | 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) | 161 | |
162 | |||
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) | ||
143 | { | 164 | { |
144 | m_uuid = UUID.Random(); | 165 | m_uuid = UUID.Random(); |
145 | 166 | ||
@@ -165,9 +186,20 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
165 | 186 | ||
166 | PID_D = pid_d; | 187 | PID_D = pid_d; |
167 | PID_P = pid_p; | 188 | PID_P = pid_p; |
168 | 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; | ||
169 | m_density = density; | 202 | m_density = density; |
170 | m_mass = 80f; // sure we have a default | ||
171 | 203 | ||
172 | // force lower density for testing | 204 | // force lower density for testing |
173 | m_density = 3.0f; | 205 | m_density = 3.0f; |
@@ -177,8 +209,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
177 | walkDivisor = walk_divisor; | 209 | walkDivisor = walk_divisor; |
178 | runDivisor = rundivisor; | 210 | runDivisor = rundivisor; |
179 | 211 | ||
180 | CAPSULE_LENGTH = size.Z * 1.15f - CAPSULE_RADIUS * 2.0f; | 212 | m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default |
181 | //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); | ||
182 | 213 | ||
183 | m_isPhysical = false; // current status: no ODE information exists | 214 | m_isPhysical = false; // current status: no ODE information exists |
184 | 215 | ||
@@ -420,13 +451,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
420 | /// </summary> | 451 | /// </summary> |
421 | public override Vector3 Size | 452 | public override Vector3 Size |
422 | { | 453 | { |
423 | get { | 454 | get |
424 | float d = CAPSULE_RADIUS * 2; | 455 | { |
425 | return new Vector3(d, d, (CAPSULE_LENGTH +d)/1.15f); } | 456 | return m_size; |
457 | } | ||
426 | set | 458 | set |
427 | { | 459 | { |
428 | if (value.IsFinite()) | 460 | if (value.IsFinite()) |
429 | { | 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 | |||
430 | AddChange(changes.Size, value); | 469 | AddChange(changes.Size, value); |
431 | } | 470 | } |
432 | else | 471 | else |
@@ -452,8 +491,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
452 | { | 491 | { |
453 | get | 492 | get |
454 | { | 493 | { |
455 | 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; |
456 | return m_density * AVvolume; | ||
457 | } | 495 | } |
458 | } | 496 | } |
459 | public override void link(PhysicsActor obj) | 497 | public override void link(PhysicsActor obj) |
@@ -571,9 +609,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
571 | 609 | ||
572 | public override Quaternion Orientation | 610 | public override Quaternion Orientation |
573 | { | 611 | { |
574 | get { return Quaternion.Identity; } | 612 | get { return m_orientation; } |
575 | set | 613 | set |
576 | { | 614 | { |
615 | // fakeori = value; | ||
616 | // givefakeori++; | ||
617 | |||
618 | value.Normalize(); | ||
619 | AddChange(changes.Orientation, value); | ||
577 | } | 620 | } |
578 | } | 621 | } |
579 | 622 | ||
@@ -625,32 +668,65 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
625 | AddChange(changes.Momentum, momentum); | 668 | AddChange(changes.Momentum, momentum); |
626 | } | 669 | } |
627 | 670 | ||
628 | |||
629 | // WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access | ||
630 | // to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only | ||
631 | // place that is safe to call this routine AvatarGeomAndBodyCreation. | ||
632 | private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) | 671 | private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) |
633 | { | 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 | |||
634 | _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); | 711 | _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); |
635 | if (CAPSULE_LENGTH <= 0) | ||
636 | { | ||
637 | m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); | ||
638 | CAPSULE_LENGTH = 0.01f; | ||
639 | 712 | ||
640 | } | 713 | feetbox = d.CreateBox(_parent_scene.ActiveSpace, feetsx, feetsy, feetsz); |
714 | d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories); | ||
715 | d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags); | ||
641 | 716 | ||
642 | if (CAPSULE_RADIUS <= 0) | 717 | midbox = d.CreateBox(_parent_scene.ActiveSpace, midsx, midsy, midsz); |
643 | { | 718 | d.GeomSetCategoryBits(midbox, (uint)m_collisionCategories); |
644 | 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); |
645 | CAPSULE_RADIUS = 0.01f; | ||
646 | 720 | ||
647 | } | 721 | topbox = d.CreateBox(_parent_scene.ActiveSpace, topsx, topsy, topsz); |
648 | Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH); | 722 | d.GeomSetCategoryBits(topbox, (uint)m_collisionCategories); |
723 | d.GeomSetCollideBits(topbox, (uint)m_collisionFlags); | ||
649 | 724 | ||
650 | d.GeomSetCategoryBits(Shell, (uint)m_collisionCategories); | 725 | bonebox = d.CreateBox(_parent_scene.ActiveSpace, bonesx, bonesy, bonesz); |
651 | d.GeomSetCollideBits(Shell, (uint)m_collisionFlags); | 726 | d.GeomSetCategoryBits(bonebox, (uint)m_collisionCategories); |
727 | d.GeomSetCollideBits(bonebox, (uint)m_collisionFlags); | ||
652 | 728 | ||
653 | 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); |
654 | 730 | ||
655 | m_mass = ShellMass.mass; // update mass | 731 | m_mass = ShellMass.mass; // update mass |
656 | 732 | ||
@@ -681,7 +757,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
681 | _position.Z = npositionZ; | 757 | _position.Z = npositionZ; |
682 | 758 | ||
683 | d.BodySetMass(Body, ref ShellMass); | 759 | d.BodySetMass(Body, ref ShellMass); |
684 | 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); | ||
685 | 768 | ||
686 | // 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 |
687 | // surrogate from rotating while moving | 770 | // surrogate from rotating while moving |
@@ -741,15 +824,152 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
741 | Body = IntPtr.Zero; | 824 | Body = IntPtr.Zero; |
742 | } | 825 | } |
743 | 826 | ||
744 | //kill the Geometry | 827 | //kill the Geoms |
745 | if (Shell != IntPtr.Zero) | 828 | if (topbox != IntPtr.Zero) |
829 | { | ||
830 | _parent_scene.actor_name_map.Remove(topbox); | ||
831 | _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); | ||
832 | d.GeomDestroy(topbox); | ||
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) | ||
746 | { | 851 | { |
747 | // _parent_scene.geom_name_map.Remove(Shell); | 852 | _parent_scene.actor_name_map.Remove(bonebox); |
748 | _parent_scene.actor_name_map.Remove(Shell); | ||
749 | _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); | 853 | _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); |
750 | d.GeomDestroy(Shell); | 854 | d.GeomDestroy(bonebox); |
751 | Shell = IntPtr.Zero; | 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; | ||
752 | } | 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; | ||
968 | } | ||
969 | else | ||
970 | return false; | ||
971 | |||
972 | return true; | ||
753 | } | 973 | } |
754 | 974 | ||
755 | /// <summary> | 975 | /// <summary> |
@@ -769,10 +989,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
769 | // so force it back to identity | 989 | // so force it back to identity |
770 | 990 | ||
771 | d.Quaternion qtmp; | 991 | d.Quaternion qtmp; |
772 | qtmp.W = 1; | 992 | qtmp.W = m_orientation.W; |
773 | qtmp.X = 0; | 993 | qtmp.X = m_orientation.X; |
774 | qtmp.Y = 0; | 994 | qtmp.Y = m_orientation.Y; |
775 | qtmp.Z = 0; | 995 | qtmp.Z = m_orientation.Z; |
776 | d.BodySetQuaternion(Body, ref qtmp); | 996 | d.BodySetQuaternion(Body, ref qtmp); |
777 | 997 | ||
778 | if (m_pidControllerActive == false) | 998 | if (m_pidControllerActive == false) |
@@ -836,9 +1056,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
836 | //****************************************** | 1056 | //****************************************** |
837 | // colide with land | 1057 | // colide with land |
838 | d.AABB aabb; | 1058 | d.AABB aabb; |
839 | d.GeomGetAABB(Shell, out aabb); | 1059 | d.GeomGetAABB(feetbox, out aabb); |
840 | float chrminZ = aabb.MinZ; | 1060 | float chrminZ = aabb.MinZ - 0.04f; // move up a bit |
841 | |||
842 | Vector3 posch = localpos; | 1061 | Vector3 posch = localpos; |
843 | 1062 | ||
844 | float ftmp; | 1063 | float ftmp; |
@@ -1176,20 +1395,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1176 | { | 1395 | { |
1177 | if (NewStatus) | 1396 | if (NewStatus) |
1178 | { | 1397 | { |
1179 | // Create avatar capsule and related ODE data | 1398 | AvatarGeomAndBodyDestroy(); |
1180 | if ((Shell != IntPtr.Zero)) | ||
1181 | { | ||
1182 | // a lost shell ? | ||
1183 | m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - " | ||
1184 | + (Shell != IntPtr.Zero ? "Shell " : "") | ||
1185 | + (Body != IntPtr.Zero ? "Body " : "") | ||
1186 | + (Amotor != IntPtr.Zero ? "Amotor " : "")); | ||
1187 | AvatarGeomAndBodyDestroy(); | ||
1188 | } | ||
1189 | 1399 | ||
1190 | AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z); | 1400 | AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z); |
1191 | 1401 | ||
1192 | _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; | ||
1193 | _parent_scene.AddCharacter(this); | 1406 | _parent_scene.AddCharacter(this); |
1194 | } | 1407 | } |
1195 | else | 1408 | else |
@@ -1218,37 +1431,29 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1218 | { | 1431 | { |
1219 | } | 1432 | } |
1220 | 1433 | ||
1221 | private void changeSize(Vector3 Size) | 1434 | private void changeSize(Vector3 pSize) |
1222 | { | 1435 | { |
1223 | if (Size.IsFinite()) | 1436 | if (pSize.IsFinite()) |
1224 | { | 1437 | { |
1225 | 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(); | ||
1226 | 1442 | ||
1227 | caplen = caplen * 1.15f - CAPSULE_RADIUS * 2.0f; | ||
1228 | 1443 | ||
1229 | if (caplen != CAPSULE_LENGTH) | 1444 | float oldsz = m_size.Z; |
1230 | { | 1445 | m_size = pSize; |
1231 | if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) | ||
1232 | { | ||
1233 | AvatarGeomAndBodyDestroy(); | ||
1234 | 1446 | ||
1235 | float prevCapsule = CAPSULE_LENGTH; | ||
1236 | CAPSULE_LENGTH = caplen; | ||
1237 | 1447 | ||
1238 | AvatarGeomAndBodyCreation(_position.X, _position.Y, | 1448 | AvatarGeomAndBodyCreation(_position.X, _position.Y, |
1239 | _position.Z + (CAPSULE_LENGTH - prevCapsule) * 0.5f); | 1449 | _position.Z + (m_size.Z - oldsz) * 0.5f); |
1240 | 1450 | ||
1241 | Velocity = Vector3.Zero; | 1451 | Velocity = Vector3.Zero; |
1242 | 1452 | ||
1243 | _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; | 1453 | _parent_scene.actor_name_map[topbox] = (PhysicsActor)this; |
1244 | } | 1454 | _parent_scene.actor_name_map[midbox] = (PhysicsActor)this; |
1245 | else | 1455 | _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this; |
1246 | { | 1456 | _parent_scene.actor_name_map[bonebox] = (PhysicsActor)this; |
1247 | m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - " | ||
1248 | + (Shell == IntPtr.Zero ? "Shell " : "") | ||
1249 | + (Body == IntPtr.Zero ? "Body " : "") | ||
1250 | + (Amotor == IntPtr.Zero ? "Amotor " : "")); | ||
1251 | } | ||
1252 | } | 1457 | } |
1253 | m_freemove = false; | 1458 | m_freemove = false; |
1254 | m_pidControllerActive = true; | 1459 | m_pidControllerActive = true; |
@@ -1270,6 +1475,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1270 | 1475 | ||
1271 | private void changeOrientation(Quaternion newOri) | 1476 | private void changeOrientation(Quaternion newOri) |
1272 | { | 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; | ||
1273 | } | 1486 | } |
1274 | 1487 | ||
1275 | private void changeVelocity(Vector3 newVel) | 1488 | private void changeVelocity(Vector3 newVel) |
@@ -1359,7 +1572,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1359 | 1572 | ||
1360 | public bool DoAChange(changes what, object arg) | 1573 | public bool DoAChange(changes what, object arg) |
1361 | { | 1574 | { |
1362 | if (Shell == IntPtr.Zero && what != changes.Add && what != changes.Remove) | 1575 | if (topbox == IntPtr.Zero && what != changes.Add && what != changes.Remove) |
1363 | { | 1576 | { |
1364 | return false; | 1577 | return false; |
1365 | } | 1578 | } |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index dc247a9..7dddab6 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | |||
@@ -84,7 +84,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
84 | 84 | ||
85 | private Vector3 _position; | 85 | private Vector3 _position; |
86 | private Vector3 _velocity; | 86 | private Vector3 _velocity; |
87 | private Vector3 _torque; | 87 | private Vector3 m_torque; |
88 | private Vector3 m_lastVelocity; | 88 | private Vector3 m_lastVelocity; |
89 | private Vector3 m_lastposition; | 89 | private Vector3 m_lastposition; |
90 | private Vector3 m_rotationalVelocity; | 90 | private Vector3 m_rotationalVelocity; |
@@ -597,7 +597,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
597 | if (!IsPhysical || Body == IntPtr.Zero) | 597 | if (!IsPhysical || Body == IntPtr.Zero) |
598 | return Vector3.Zero; | 598 | return Vector3.Zero; |
599 | 599 | ||
600 | return _torque; | 600 | return m_torque; |
601 | } | 601 | } |
602 | 602 | ||
603 | set | 603 | set |
@@ -2425,10 +2425,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2425 | { | 2425 | { |
2426 | if (!childPrim) | 2426 | if (!childPrim) |
2427 | { | 2427 | { |
2428 | m_force = Vector3.Zero; | 2428 | // m_force = Vector3.Zero; |
2429 | m_forceacc = Vector3.Zero; | 2429 | m_forceacc = Vector3.Zero; |
2430 | m_angularForceacc = Vector3.Zero; | 2430 | m_angularForceacc = Vector3.Zero; |
2431 | _torque = Vector3.Zero; | 2431 | // m_torque = Vector3.Zero; |
2432 | _velocity = Vector3.Zero; | 2432 | _velocity = Vector3.Zero; |
2433 | _acceleration = Vector3.Zero; | 2433 | _acceleration = Vector3.Zero; |
2434 | m_rotationalVelocity = Vector3.Zero; | 2434 | m_rotationalVelocity = Vector3.Zero; |
@@ -2968,7 +2968,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2968 | d.BodyEnable(Body); | 2968 | d.BodyEnable(Body); |
2969 | 2969 | ||
2970 | } | 2970 | } |
2971 | _torque = newtorque; | 2971 | m_torque = newtorque; |
2972 | } | 2972 | } |
2973 | } | 2973 | } |
2974 | 2974 | ||
@@ -3364,7 +3364,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3364 | 3364 | ||
3365 | Vector3 trq; | 3365 | Vector3 trq; |
3366 | 3366 | ||
3367 | trq = _torque; | 3367 | trq = m_torque; |
3368 | trq += m_angularForceacc; | 3368 | trq += m_angularForceacc; |
3369 | m_angularForceacc = Vector3.Zero; | 3369 | m_angularForceacc = Vector3.Zero; |
3370 | if (trq.X != 0 || trq.Y != 0 || trq.Z != 0) | 3370 | if (trq.X != 0 || trq.Y != 0 || trq.Z != 0) |
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 | ||