diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 377 |
1 files changed, 295 insertions, 82 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 | } |