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