diff options
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 369 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 69 |
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 | ||