diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs | 571 |
1 files changed, 194 insertions, 377 deletions
diff --git a/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs b/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs index 0b9c45f..908b266 100644 --- a/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs +++ b/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs | |||
@@ -83,8 +83,15 @@ namespace OpenSim.Region.PhysicsModule.ODE | |||
83 | set | 83 | set |
84 | { | 84 | { |
85 | m_isphysical = value; | 85 | m_isphysical = value; |
86 | if (!m_isphysical) // Zero the remembered last velocity | 86 | if (!m_isphysical) |
87 | { | ||
88 | _zeroFlag = true; // Zero the remembered last velocity | ||
87 | m_lastVelocity = Vector3.Zero; | 89 | m_lastVelocity = Vector3.Zero; |
90 | _acceleration = Vector3.Zero; | ||
91 | _velocity = Vector3.Zero; | ||
92 | m_taintVelocity = Vector3.Zero; | ||
93 | m_rotationalVelocity = Vector3.Zero; | ||
94 | } | ||
88 | } | 95 | } |
89 | } | 96 | } |
90 | 97 | ||
@@ -104,10 +111,12 @@ namespace OpenSim.Region.PhysicsModule.ODE | |||
104 | private Vector3 m_taintVelocity; | 111 | private Vector3 m_taintVelocity; |
105 | private Vector3 m_taintTorque; | 112 | private Vector3 m_taintTorque; |
106 | private Quaternion m_taintrot; | 113 | private Quaternion m_taintrot; |
107 | private Vector3 m_angularlock = Vector3.One; | 114 | |
108 | private Vector3 m_taintAngularLock = Vector3.One; | ||
109 | private IntPtr Amotor = IntPtr.Zero; | 115 | private IntPtr Amotor = IntPtr.Zero; |
110 | 116 | ||
117 | private byte m_taintAngularLock = 0; | ||
118 | private byte m_angularlock = 0; | ||
119 | |||
111 | private bool m_assetFailed = false; | 120 | private bool m_assetFailed = false; |
112 | 121 | ||
113 | private Vector3 m_PIDTarget; | 122 | private Vector3 m_PIDTarget; |
@@ -445,7 +454,7 @@ namespace OpenSim.Region.PhysicsModule.ODE | |||
445 | m_disabled = false; | 454 | m_disabled = false; |
446 | 455 | ||
447 | // The body doesn't already have a finite rotation mode set here | 456 | // The body doesn't already have a finite rotation mode set here |
448 | if ((!m_angularlock.ApproxEquals(Vector3.One, 0.0f)) && _parent == null) | 457 | if (m_angularlock != 0 && _parent == null) |
449 | { | 458 | { |
450 | createAMotor(m_angularlock); | 459 | createAMotor(m_angularlock); |
451 | } | 460 | } |
@@ -919,7 +928,7 @@ namespace OpenSim.Region.PhysicsModule.ODE | |||
919 | // _parent_scene.waitForSpaceUnlock(m_targetSpace); | 928 | // _parent_scene.waitForSpaceUnlock(m_targetSpace); |
920 | try | 929 | try |
921 | { | 930 | { |
922 | SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); | 931 | SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null)); |
923 | } | 932 | } |
924 | catch (AccessViolationException) | 933 | catch (AccessViolationException) |
925 | { | 934 | { |
@@ -1001,7 +1010,7 @@ Console.WriteLine("ZProcessTaints for " + Name); | |||
1001 | if (m_taintCollidesWater != m_collidesWater) | 1010 | if (m_taintCollidesWater != m_collidesWater) |
1002 | changefloatonwater(); | 1011 | changefloatonwater(); |
1003 | 1012 | ||
1004 | if (!m_angularlock.ApproxEquals(m_taintAngularLock,0f)) | 1013 | if (m_taintAngularLock != m_angularlock) |
1005 | changeAngularLock(); | 1014 | changeAngularLock(); |
1006 | } | 1015 | } |
1007 | 1016 | ||
@@ -1017,10 +1026,8 @@ Console.WriteLine("ZProcessTaints for " + Name); | |||
1017 | //If we have a parent then we're not authorative here | 1026 | //If we have a parent then we're not authorative here |
1018 | if (_parent == null) | 1027 | if (_parent == null) |
1019 | { | 1028 | { |
1020 | if (!m_taintAngularLock.ApproxEquals(Vector3.One, 0f)) | 1029 | if (m_taintAngularLock != 0) |
1021 | { | 1030 | { |
1022 | //d.BodySetFiniteRotationMode(Body, 0); | ||
1023 | //d.BodySetFiniteRotationAxis(Body,m_taintAngularLock.X,m_taintAngularLock.Y,m_taintAngularLock.Z); | ||
1024 | createAMotor(m_taintAngularLock); | 1031 | createAMotor(m_taintAngularLock); |
1025 | } | 1032 | } |
1026 | else | 1033 | else |
@@ -1034,7 +1041,6 @@ Console.WriteLine("ZProcessTaints for " + Name); | |||
1034 | } | 1041 | } |
1035 | } | 1042 | } |
1036 | 1043 | ||
1037 | // Store this for later in case we get turned into a separate body | ||
1038 | m_angularlock = m_taintAngularLock; | 1044 | m_angularlock = m_taintAngularLock; |
1039 | } | 1045 | } |
1040 | 1046 | ||
@@ -1230,7 +1236,8 @@ Console.WriteLine("ZProcessTaints for " + Name); | |||
1230 | m_disabled = false; | 1236 | m_disabled = false; |
1231 | 1237 | ||
1232 | // The body doesn't already have a finite rotation mode set here | 1238 | // The body doesn't already have a finite rotation mode set here |
1233 | if ((!m_angularlock.ApproxEquals(Vector3.One, 0f)) && _parent == null) | 1239 | // or remove |
1240 | if (_parent == null) | ||
1234 | { | 1241 | { |
1235 | createAMotor(m_angularlock); | 1242 | createAMotor(m_angularlock); |
1236 | } | 1243 | } |
@@ -1686,6 +1693,9 @@ Console.WriteLine(" JointCreateFixed"); | |||
1686 | float fy = 0; | 1693 | float fy = 0; |
1687 | float fz = 0; | 1694 | float fz = 0; |
1688 | 1695 | ||
1696 | if (outofBounds) | ||
1697 | return; | ||
1698 | |||
1689 | if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. | 1699 | if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. |
1690 | { | 1700 | { |
1691 | if (m_vehicle.Type != Vehicle.TYPE_NONE) | 1701 | if (m_vehicle.Type != Vehicle.TYPE_NONE) |
@@ -1697,21 +1707,6 @@ Console.WriteLine(" JointCreateFixed"); | |||
1697 | { | 1707 | { |
1698 | //Console.WriteLine("Move " + Name); | 1708 | //Console.WriteLine("Move " + Name); |
1699 | if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 | 1709 | if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 |
1700 | // NON-'VEHICLES' are dealt with here | ||
1701 | // if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f)) | ||
1702 | // { | ||
1703 | // d.Vector3 avel2 = d.BodyGetAngularVel(Body); | ||
1704 | // /* | ||
1705 | // if (m_angularlock.X == 1) | ||
1706 | // avel2.X = 0; | ||
1707 | // if (m_angularlock.Y == 1) | ||
1708 | // avel2.Y = 0; | ||
1709 | // if (m_angularlock.Z == 1) | ||
1710 | // avel2.Z = 0; | ||
1711 | // d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z); | ||
1712 | // */ | ||
1713 | // } | ||
1714 | //float PID_P = 900.0f; | ||
1715 | 1710 | ||
1716 | float m_mass = CalculateMass(); | 1711 | float m_mass = CalculateMass(); |
1717 | 1712 | ||
@@ -1940,8 +1935,8 @@ Console.WriteLine(" JointCreateFixed"); | |||
1940 | d.BodySetQuaternion(Body, ref myrot); | 1935 | d.BodySetQuaternion(Body, ref myrot); |
1941 | if (IsPhysical) | 1936 | if (IsPhysical) |
1942 | { | 1937 | { |
1943 | if (!m_angularlock.ApproxEquals(Vector3.One, 0f)) | 1938 | // create or remove locks |
1944 | createAMotor(m_angularlock); | 1939 | createAMotor(m_angularlock); |
1945 | } | 1940 | } |
1946 | } | 1941 | } |
1947 | else | 1942 | else |
@@ -2659,16 +2654,38 @@ Console.WriteLine(" JointCreateFixed"); | |||
2659 | 2654 | ||
2660 | public override void CrossingFailure() | 2655 | public override void CrossingFailure() |
2661 | { | 2656 | { |
2662 | m_crossingfailures++; | 2657 | /* |
2663 | if (m_crossingfailures > _parent_scene.geomCrossingFailuresBeforeOutofbounds) | 2658 | m_crossingfailures++; |
2664 | { | 2659 | if (m_crossingfailures > _parent_scene.geomCrossingFailuresBeforeOutofbounds) |
2665 | base.RaiseOutOfBounds(_position); | 2660 | { |
2666 | return; | 2661 | base.RaiseOutOfBounds(_position); |
2667 | } | 2662 | return; |
2668 | else if (m_crossingfailures == _parent_scene.geomCrossingFailuresBeforeOutofbounds) | 2663 | } |
2664 | else if (m_crossingfailures == _parent_scene.geomCrossingFailuresBeforeOutofbounds) | ||
2665 | { | ||
2666 | m_log.Warn("[PHYSICS]: Too many crossing failures for: " + Name); | ||
2667 | } | ||
2668 | */ | ||
2669 | _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f); | ||
2670 | _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f); | ||
2671 | _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f); | ||
2672 | |||
2673 | m_lastposition = _position; | ||
2674 | _velocity.X = 0; | ||
2675 | _velocity.Y = 0; | ||
2676 | _velocity.Z = 0; | ||
2677 | |||
2678 | m_lastVelocity = _velocity; | ||
2679 | |||
2680 | if (Body != IntPtr.Zero) | ||
2669 | { | 2681 | { |
2670 | m_log.Warn("[PHYSICS]: Too many crossing failures for: " + Name); | 2682 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it |
2683 | d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); | ||
2671 | } | 2684 | } |
2685 | |||
2686 | outofBounds = false; | ||
2687 | base.RequestPhysicsterseUpdate(); | ||
2688 | |||
2672 | } | 2689 | } |
2673 | 2690 | ||
2674 | public override float Buoyancy | 2691 | public override float Buoyancy |
@@ -2687,32 +2704,23 @@ Console.WriteLine(" JointCreateFixed"); | |||
2687 | m_taintparent = null; | 2704 | m_taintparent = null; |
2688 | } | 2705 | } |
2689 | 2706 | ||
2690 | public override void LockAngularMotion(Vector3 axis) | 2707 | public override void LockAngularMotion(byte axislocks) |
2691 | { | 2708 | { |
2692 | // reverse the zero/non zero values for ODE. | 2709 | // m_log.DebugFormat("[axislocks]: {0}", axislocks); |
2693 | if (axis.IsFinite()) | 2710 | m_taintAngularLock = axislocks; |
2694 | { | ||
2695 | axis.X = (axis.X > 0) ? 1f : 0f; | ||
2696 | axis.Y = (axis.Y > 0) ? 1f : 0f; | ||
2697 | axis.Z = (axis.Z > 0) ? 1f : 0f; | ||
2698 | m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z); | ||
2699 | m_taintAngularLock = axis; | ||
2700 | } | ||
2701 | else | ||
2702 | { | ||
2703 | m_log.WarnFormat("[PHYSICS]: Got NaN locking axis from Scene on Object {0}", Name); | ||
2704 | } | ||
2705 | } | 2711 | } |
2706 | 2712 | ||
2707 | internal void UpdatePositionAndVelocity() | 2713 | internal void UpdatePositionAndVelocity() |
2708 | { | 2714 | { |
2709 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! | 2715 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! |
2716 | if (outofBounds) | ||
2717 | return; | ||
2710 | if (_parent == null) | 2718 | if (_parent == null) |
2711 | { | 2719 | { |
2712 | Vector3 pv = Vector3.Zero; | 2720 | Vector3 pv = Vector3.Zero; |
2713 | bool lastZeroFlag = _zeroFlag; | 2721 | bool lastZeroFlag = _zeroFlag; |
2714 | float m_minvelocity = 0; | 2722 | float m_minvelocity = 0; |
2715 | if (Body != (IntPtr)0) // FIXME -> or if it is a joint | 2723 | if (Body != IntPtr.Zero) // FIXME -> or if it is a joint |
2716 | { | 2724 | { |
2717 | d.Vector3 vec = d.BodyGetPosition(Body); | 2725 | d.Vector3 vec = d.BodyGetPosition(Body); |
2718 | d.Quaternion ori = d.BodyGetQuaternion(Body); | 2726 | d.Quaternion ori = d.BodyGetQuaternion(Body); |
@@ -2723,12 +2731,6 @@ Console.WriteLine(" JointCreateFixed"); | |||
2723 | Vector3 l_position = Vector3.Zero; | 2731 | Vector3 l_position = Vector3.Zero; |
2724 | Quaternion l_orientation = Quaternion.Identity; | 2732 | Quaternion l_orientation = Quaternion.Identity; |
2725 | 2733 | ||
2726 | // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) | ||
2727 | //if (vec.X < 0.0f) { vec.X = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
2728 | //if (vec.Y < 0.0f) { vec.Y = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
2729 | //if (vec.X > 255.95f) { vec.X = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
2730 | //if (vec.Y > 255.95f) { vec.Y = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
2731 | |||
2732 | m_lastposition = _position; | 2734 | m_lastposition = _position; |
2733 | m_lastorientation = _orientation; | 2735 | m_lastorientation = _orientation; |
2734 | 2736 | ||
@@ -2740,26 +2742,6 @@ Console.WriteLine(" JointCreateFixed"); | |||
2740 | l_orientation.Z = ori.Z; | 2742 | l_orientation.Z = ori.Z; |
2741 | l_orientation.W = ori.W; | 2743 | l_orientation.W = ori.W; |
2742 | 2744 | ||
2743 | if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f) | ||
2744 | { | ||
2745 | //base.RaiseOutOfBounds(l_position); | ||
2746 | |||
2747 | if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds) | ||
2748 | { | ||
2749 | _position = l_position; | ||
2750 | //_parent_scene.remActivePrim(this); | ||
2751 | if (_parent == null) | ||
2752 | base.RequestPhysicsterseUpdate(); | ||
2753 | return; | ||
2754 | } | ||
2755 | else | ||
2756 | { | ||
2757 | if (_parent == null) | ||
2758 | base.RaiseOutOfBounds(l_position); | ||
2759 | return; | ||
2760 | } | ||
2761 | } | ||
2762 | |||
2763 | if (l_position.Z < 0) | 2745 | if (l_position.Z < 0) |
2764 | { | 2746 | { |
2765 | // This is so prim that get lost underground don't fall forever and suck up | 2747 | // This is so prim that get lost underground don't fall forever and suck up |
@@ -2769,8 +2751,6 @@ Console.WriteLine(" JointCreateFixed"); | |||
2769 | // It's a hack and will generate a console message if it fails. | 2751 | // It's a hack and will generate a console message if it fails. |
2770 | 2752 | ||
2771 | //IsPhysical = false; | 2753 | //IsPhysical = false; |
2772 | if (_parent == null) | ||
2773 | base.RaiseOutOfBounds(_position); | ||
2774 | 2754 | ||
2775 | _acceleration.X = 0; | 2755 | _acceleration.X = 0; |
2776 | _acceleration.Y = 0; | 2756 | _acceleration.Y = 0; |
@@ -2784,16 +2764,64 @@ Console.WriteLine(" JointCreateFixed"); | |||
2784 | m_rotationalVelocity.Z = 0; | 2764 | m_rotationalVelocity.Z = 0; |
2785 | 2765 | ||
2786 | if (_parent == null) | 2766 | if (_parent == null) |
2767 | base.RaiseOutOfBounds(_position); | ||
2768 | |||
2769 | if (_parent == null) | ||
2787 | base.RequestPhysicsterseUpdate(); | 2770 | base.RequestPhysicsterseUpdate(); |
2788 | 2771 | ||
2789 | m_throttleUpdates = false; | 2772 | m_throttleUpdates = false; |
2790 | throttleCounter = 0; | 2773 | throttleCounter = 0; |
2791 | _zeroFlag = true; | 2774 | _zeroFlag = true; |
2792 | //outofBounds = true; | 2775 | //outofBounds = true; |
2776 | return; | ||
2777 | } | ||
2778 | |||
2779 | if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f) | ||
2780 | { | ||
2781 | //base.RaiseOutOfBounds(l_position); | ||
2782 | /* | ||
2783 | if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds) | ||
2784 | { | ||
2785 | _position = l_position; | ||
2786 | //_parent_scene.remActivePrim(this); | ||
2787 | if (_parent == null) | ||
2788 | base.RequestPhysicsterseUpdate(); | ||
2789 | return; | ||
2790 | } | ||
2791 | else | ||
2792 | { | ||
2793 | if (_parent == null) | ||
2794 | base.RaiseOutOfBounds(l_position); | ||
2795 | return; | ||
2796 | } | ||
2797 | */ | ||
2798 | outofBounds = true; | ||
2799 | // part near the border on outside | ||
2800 | if (l_position.X < 0) | ||
2801 | Util.Clamp(l_position.X, -0.1f, -2f); | ||
2802 | else | ||
2803 | Util.Clamp(l_position.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f); | ||
2804 | if (l_position.Y < 0) | ||
2805 | Util.Clamp(l_position.Y, -0.1f, -2f); | ||
2806 | else | ||
2807 | Util.Clamp(l_position.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f); | ||
2808 | |||
2809 | d.BodySetPosition(Body, l_position.X, l_position.Y, l_position.Z); | ||
2810 | |||
2811 | // stop it | ||
2812 | d.BodySetAngularVel(Body, 0, 0, 0); | ||
2813 | d.BodySetLinearVel(Body, 0, 0, 0); | ||
2814 | disableBodySoft(); | ||
2815 | |||
2816 | // tell framework to fix it | ||
2817 | if (_parent == null) | ||
2818 | base.RequestPhysicsterseUpdate(); | ||
2819 | return; | ||
2793 | } | 2820 | } |
2794 | 2821 | ||
2822 | |||
2795 | //float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); | 2823 | //float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); |
2796 | //Console.WriteLine("Adiff " + Name + " = " + Adiff); | 2824 | //Console.WriteLine("Adiff " + Name + " = " + Adiff); |
2797 | if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) | 2825 | if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) |
2798 | && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) | 2826 | && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) |
2799 | && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) | 2827 | && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) |
@@ -2950,11 +2978,12 @@ Console.WriteLine(" JointCreateFixed"); | |||
2950 | m_log.WarnFormat("[PHYSICS]: Got NaN PIDTarget from Scene on Object {0}", Name); | 2978 | m_log.WarnFormat("[PHYSICS]: Got NaN PIDTarget from Scene on Object {0}", Name); |
2951 | } | 2979 | } |
2952 | } | 2980 | } |
2981 | |||
2953 | public override bool PIDActive { get; set; } | 2982 | public override bool PIDActive { get; set; } |
2954 | public override float PIDTau { set { m_PIDTau = value; } } | 2983 | public override float PIDTau { set { m_PIDTau = value; } } |
2955 | 2984 | ||
2956 | public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } | 2985 | public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } |
2957 | public override bool PIDHoverActive { set { m_useHoverPID = value; } } | 2986 | public override bool PIDHoverActive { get { return m_useHoverPID;} set { m_useHoverPID = value; } } |
2958 | public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } } | 2987 | public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } } |
2959 | public override float PIDHoverTau { set { m_PIDHoverTau = value; } } | 2988 | public override float PIDHoverTau { set { m_PIDHoverTau = value; } } |
2960 | 2989 | ||
@@ -2966,7 +2995,7 @@ Console.WriteLine(" JointCreateFixed"); | |||
2966 | 2995 | ||
2967 | public override float APIDDamping{ set { return; } } | 2996 | public override float APIDDamping{ set { return; } } |
2968 | 2997 | ||
2969 | private void createAMotor(Vector3 axis) | 2998 | private void createAMotor(byte axislock) |
2970 | { | 2999 | { |
2971 | if (Body == IntPtr.Zero) | 3000 | if (Body == IntPtr.Zero) |
2972 | return; | 3001 | return; |
@@ -2977,150 +3006,105 @@ Console.WriteLine(" JointCreateFixed"); | |||
2977 | Amotor = IntPtr.Zero; | 3006 | Amotor = IntPtr.Zero; |
2978 | } | 3007 | } |
2979 | 3008 | ||
2980 | float axisnum = 3; | 3009 | if(axislock == 0) |
2981 | 3010 | return; | |
2982 | axisnum = (axisnum - (axis.X + axis.Y + axis.Z)); | ||
2983 | |||
2984 | // PhysicsVector totalSize = new PhysicsVector(_size.X, _size.Y, _size.Z); | ||
2985 | |||
2986 | |||
2987 | // Inverse Inertia Matrix, set the X, Y, and/r Z inertia to 0 then invert it again. | ||
2988 | d.Mass objMass; | ||
2989 | d.MassSetZero(out objMass); | ||
2990 | DMassCopy(ref pMass, ref objMass); | ||
2991 | |||
2992 | //m_log.DebugFormat("1-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", objMass.I.M00, objMass.I.M01, objMass.I.M02, objMass.I.M10, objMass.I.M11, objMass.I.M12, objMass.I.M20, objMass.I.M21, objMass.I.M22); | ||
2993 | |||
2994 | Matrix4 dMassMat = FromDMass(objMass); | ||
2995 | |||
2996 | Matrix4 mathmat = Inverse(dMassMat); | ||
2997 | |||
2998 | /* | ||
2999 | //m_log.DebugFormat("2-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", mathmat[0, 0], mathmat[0, 1], mathmat[0, 2], mathmat[1, 0], mathmat[1, 1], mathmat[1, 2], mathmat[2, 0], mathmat[2, 1], mathmat[2, 2]); | ||
3000 | |||
3001 | mathmat = Inverse(mathmat); | ||
3002 | |||
3003 | |||
3004 | objMass = FromMatrix4(mathmat, ref objMass); | ||
3005 | //m_log.DebugFormat("3-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", objMass.I.M00, objMass.I.M01, objMass.I.M02, objMass.I.M10, objMass.I.M11, objMass.I.M12, objMass.I.M20, objMass.I.M21, objMass.I.M22); | ||
3006 | |||
3007 | mathmat = Inverse(mathmat); | ||
3008 | */ | ||
3009 | if (axis.X == 0) | ||
3010 | { | ||
3011 | mathmat.M33 = 50.0000001f; | ||
3012 | //objMass.I.M22 = 0; | ||
3013 | } | ||
3014 | if (axis.Y == 0) | ||
3015 | { | ||
3016 | mathmat.M22 = 50.0000001f; | ||
3017 | //objMass.I.M11 = 0; | ||
3018 | } | ||
3019 | if (axis.Z == 0) | ||
3020 | { | ||
3021 | mathmat.M11 = 50.0000001f; | ||
3022 | //objMass.I.M00 = 0; | ||
3023 | } | ||
3024 | |||
3025 | |||
3026 | 3011 | ||
3027 | mathmat = Inverse(mathmat); | 3012 | int axisnum = 0; |
3028 | objMass = FromMatrix4(mathmat, ref objMass); | 3013 | bool axisX = false; |
3029 | //m_log.DebugFormat("4-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", objMass.I.M00, objMass.I.M01, objMass.I.M02, objMass.I.M10, objMass.I.M11, objMass.I.M12, objMass.I.M20, objMass.I.M21, objMass.I.M22); | 3014 | bool axisY = false; |
3030 | 3015 | bool axisZ = false; | |
3031 | //return; | 3016 | if((axislock & 0x02) != 0) |
3032 | if (d.MassCheck(ref objMass)) | 3017 | { |
3033 | { | 3018 | axisnum++; |
3034 | d.BodySetMass(Body, ref objMass); | 3019 | axisX = true; |
3035 | } | 3020 | } |
3036 | else | 3021 | if((axislock & 0x04) != 0) |
3037 | { | 3022 | { |
3038 | //m_log.Debug("[PHYSICS]: Mass invalid, ignoring"); | 3023 | axisnum++; |
3039 | } | 3024 | axisY = true; |
3025 | } | ||
3026 | if((axislock & 0x08) != 0) | ||
3027 | { | ||
3028 | axisnum++; | ||
3029 | axisZ = true; | ||
3030 | } | ||
3040 | 3031 | ||
3041 | if (axisnum <= 0) | 3032 | if(axisnum == 0) |
3042 | return; | 3033 | return; |
3043 | // int dAMotorEuler = 1; | 3034 | // stop it |
3035 | d.BodySetTorque(Body, 0, 0, 0); | ||
3036 | d.BodySetAngularVel(Body, 0, 0, 0); | ||
3044 | 3037 | ||
3045 | Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); | 3038 | Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); |
3046 | d.JointAttach(Amotor, Body, IntPtr.Zero); | 3039 | d.JointAttach(Amotor, Body, IntPtr.Zero); |
3040 | |||
3047 | d.JointSetAMotorMode(Amotor, 0); | 3041 | d.JointSetAMotorMode(Amotor, 0); |
3048 | 3042 | ||
3049 | d.JointSetAMotorNumAxes(Amotor,(int)axisnum); | 3043 | d.JointSetAMotorNumAxes(Amotor, axisnum); |
3050 | int i = 0; | ||
3051 | 3044 | ||
3052 | if (axis.X == 0) | 3045 | // get current orientation to lock |
3053 | { | ||
3054 | d.JointSetAMotorAxis(Amotor, i, 0, 1, 0, 0); | ||
3055 | i++; | ||
3056 | } | ||
3057 | 3046 | ||
3058 | if (axis.Y == 0) | 3047 | d.Quaternion dcur = d.BodyGetQuaternion(Body); |
3059 | { | 3048 | Quaternion curr; // crap convertion between identical things |
3060 | d.JointSetAMotorAxis(Amotor, i, 0, 0, 1, 0); | 3049 | curr.X = dcur.X; |
3061 | i++; | 3050 | curr.Y = dcur.Y; |
3062 | } | 3051 | curr.Z = dcur.Z; |
3052 | curr.W = dcur.W; | ||
3053 | Vector3 ax; | ||
3063 | 3054 | ||
3064 | if (axis.Z == 0) | 3055 | int i = 0; |
3065 | { | 3056 | int j = 0; |
3066 | d.JointSetAMotorAxis(Amotor, i, 0, 0, 0, 1); | 3057 | if (axisX) |
3058 | { | ||
3059 | ax = (new Vector3(1, 0, 0)) * curr; // rotate world X to current local X | ||
3060 | d.JointSetAMotorAxis(Amotor, 0, 0, ax.X, ax.Y, ax.Z); | ||
3061 | d.JointSetAMotorAngle(Amotor, 0, 0); | ||
3062 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.LoStop, 0f); | ||
3063 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.HiStop, 0f); | ||
3064 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0); | ||
3065 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f); | ||
3066 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f); | ||
3067 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.CFM, 0f); | ||
3068 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f); | ||
3069 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopCFM, 0f); | ||
3070 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopERP, 0.8f); | ||
3071 | i++; | ||
3072 | j = 256; // move to next axis set | ||
3073 | } | ||
3074 | |||
3075 | if (axisY) | ||
3076 | { | ||
3077 | ax = (new Vector3(0, 1, 0)) * curr; | ||
3078 | d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); | ||
3079 | d.JointSetAMotorAngle(Amotor, i, 0); | ||
3080 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, 0f); | ||
3081 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0f); | ||
3082 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0); | ||
3083 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); | ||
3084 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); | ||
3085 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.CFM, 0f); | ||
3086 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); | ||
3087 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); | ||
3088 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); | ||
3067 | i++; | 3089 | i++; |
3090 | j += 256; | ||
3068 | } | 3091 | } |
3069 | 3092 | ||
3070 | for (int j = 0; j < (int)axisnum; j++) | 3093 | if (axisZ) |
3071 | { | 3094 | { |
3072 | //d.JointSetAMotorAngle(Amotor, j, 0); | 3095 | ax = (new Vector3(0, 0, 1)) * curr; |
3096 | d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); | ||
3097 | d.JointSetAMotorAngle(Amotor, i, 0); | ||
3098 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, 0f); | ||
3099 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0f); | ||
3100 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0); | ||
3101 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); | ||
3102 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); | ||
3103 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.CFM, 0f); | ||
3104 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); | ||
3105 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); | ||
3106 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); | ||
3073 | } | 3107 | } |
3074 | |||
3075 | //d.JointSetAMotorAngle(Amotor, 1, 0); | ||
3076 | //d.JointSetAMotorAngle(Amotor, 2, 0); | ||
3077 | |||
3078 | // These lowstops and high stops are effectively (no wiggle room) | ||
3079 | d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0f); | ||
3080 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f); | ||
3081 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0f); | ||
3082 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0f); | ||
3083 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); | ||
3084 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0f); | ||
3085 | //d.JointSetAMotorParam(Amotor, (int) dParam.Vel, 9000f); | ||
3086 | d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f); | ||
3087 | d.JointSetAMotorParam(Amotor, (int)dParam.FMax, Mass * 50f);// | ||
3088 | } | ||
3089 | |||
3090 | private Matrix4 FromDMass(d.Mass pMass) | ||
3091 | { | ||
3092 | Matrix4 obj; | ||
3093 | obj.M11 = pMass.I.M00; | ||
3094 | obj.M12 = pMass.I.M01; | ||
3095 | obj.M13 = pMass.I.M02; | ||
3096 | obj.M14 = 0; | ||
3097 | obj.M21 = pMass.I.M10; | ||
3098 | obj.M22 = pMass.I.M11; | ||
3099 | obj.M23 = pMass.I.M12; | ||
3100 | obj.M24 = 0; | ||
3101 | obj.M31 = pMass.I.M20; | ||
3102 | obj.M32 = pMass.I.M21; | ||
3103 | obj.M33 = pMass.I.M22; | ||
3104 | obj.M34 = 0; | ||
3105 | obj.M41 = 0; | ||
3106 | obj.M42 = 0; | ||
3107 | obj.M43 = 0; | ||
3108 | obj.M44 = 1; | ||
3109 | return obj; | ||
3110 | } | ||
3111 | |||
3112 | private d.Mass FromMatrix4(Matrix4 pMat, ref d.Mass obj) | ||
3113 | { | ||
3114 | obj.I.M00 = pMat[0, 0]; | ||
3115 | obj.I.M01 = pMat[0, 1]; | ||
3116 | obj.I.M02 = pMat[0, 2]; | ||
3117 | obj.I.M10 = pMat[1, 0]; | ||
3118 | obj.I.M11 = pMat[1, 1]; | ||
3119 | obj.I.M12 = pMat[1, 2]; | ||
3120 | obj.I.M20 = pMat[2, 0]; | ||
3121 | obj.I.M21 = pMat[2, 1]; | ||
3122 | obj.I.M22 = pMat[2, 2]; | ||
3123 | return obj; | ||
3124 | } | 3108 | } |
3125 | 3109 | ||
3126 | public override void SubscribeEvents(int ms) | 3110 | public override void SubscribeEvents(int ms) |
@@ -3165,173 +3149,6 @@ Console.WriteLine(" JointCreateFixed"); | |||
3165 | return false; | 3149 | return false; |
3166 | } | 3150 | } |
3167 | 3151 | ||
3168 | public static Matrix4 Inverse(Matrix4 pMat) | ||
3169 | { | ||
3170 | if (determinant3x3(pMat) == 0) | ||
3171 | { | ||
3172 | return Matrix4.Identity; // should probably throw an error. singluar matrix inverse not possible | ||
3173 | } | ||
3174 | |||
3175 | return (Adjoint(pMat) / determinant3x3(pMat)); | ||
3176 | } | ||
3177 | |||
3178 | public static Matrix4 Adjoint(Matrix4 pMat) | ||
3179 | { | ||
3180 | Matrix4 adjointMatrix = new Matrix4(); | ||
3181 | for (int i=0; i<4; i++) | ||
3182 | { | ||
3183 | for (int j=0; j<4; j++) | ||
3184 | { | ||
3185 | Matrix4SetValue(ref adjointMatrix, i, j, (float)(Math.Pow(-1, i + j) * (determinant3x3(Minor(pMat, i, j))))); | ||
3186 | } | ||
3187 | } | ||
3188 | |||
3189 | adjointMatrix = Transpose(adjointMatrix); | ||
3190 | return adjointMatrix; | ||
3191 | } | ||
3192 | |||
3193 | public static Matrix4 Minor(Matrix4 matrix, int iRow, int iCol) | ||
3194 | { | ||
3195 | Matrix4 minor = new Matrix4(); | ||
3196 | int m = 0, n = 0; | ||
3197 | for (int i = 0; i < 4; i++) | ||
3198 | { | ||
3199 | if (i == iRow) | ||
3200 | continue; | ||
3201 | n = 0; | ||
3202 | for (int j = 0; j < 4; j++) | ||
3203 | { | ||
3204 | if (j == iCol) | ||
3205 | continue; | ||
3206 | Matrix4SetValue(ref minor, m,n, matrix[i, j]); | ||
3207 | n++; | ||
3208 | } | ||
3209 | m++; | ||
3210 | } | ||
3211 | |||
3212 | return minor; | ||
3213 | } | ||
3214 | |||
3215 | public static Matrix4 Transpose(Matrix4 pMat) | ||
3216 | { | ||
3217 | Matrix4 transposeMatrix = new Matrix4(); | ||
3218 | for (int i = 0; i < 4; i++) | ||
3219 | for (int j = 0; j < 4; j++) | ||
3220 | Matrix4SetValue(ref transposeMatrix, i, j, pMat[j, i]); | ||
3221 | return transposeMatrix; | ||
3222 | } | ||
3223 | |||
3224 | public static void Matrix4SetValue(ref Matrix4 pMat, int r, int c, float val) | ||
3225 | { | ||
3226 | switch (r) | ||
3227 | { | ||
3228 | case 0: | ||
3229 | switch (c) | ||
3230 | { | ||
3231 | case 0: | ||
3232 | pMat.M11 = val; | ||
3233 | break; | ||
3234 | case 1: | ||
3235 | pMat.M12 = val; | ||
3236 | break; | ||
3237 | case 2: | ||
3238 | pMat.M13 = val; | ||
3239 | break; | ||
3240 | case 3: | ||
3241 | pMat.M14 = val; | ||
3242 | break; | ||
3243 | } | ||
3244 | |||
3245 | break; | ||
3246 | case 1: | ||
3247 | switch (c) | ||
3248 | { | ||
3249 | case 0: | ||
3250 | pMat.M21 = val; | ||
3251 | break; | ||
3252 | case 1: | ||
3253 | pMat.M22 = val; | ||
3254 | break; | ||
3255 | case 2: | ||
3256 | pMat.M23 = val; | ||
3257 | break; | ||
3258 | case 3: | ||
3259 | pMat.M24 = val; | ||
3260 | break; | ||
3261 | } | ||
3262 | |||
3263 | break; | ||
3264 | case 2: | ||
3265 | switch (c) | ||
3266 | { | ||
3267 | case 0: | ||
3268 | pMat.M31 = val; | ||
3269 | break; | ||
3270 | case 1: | ||
3271 | pMat.M32 = val; | ||
3272 | break; | ||
3273 | case 2: | ||
3274 | pMat.M33 = val; | ||
3275 | break; | ||
3276 | case 3: | ||
3277 | pMat.M34 = val; | ||
3278 | break; | ||
3279 | } | ||
3280 | |||
3281 | break; | ||
3282 | case 3: | ||
3283 | switch (c) | ||
3284 | { | ||
3285 | case 0: | ||
3286 | pMat.M41 = val; | ||
3287 | break; | ||
3288 | case 1: | ||
3289 | pMat.M42 = val; | ||
3290 | break; | ||
3291 | case 2: | ||
3292 | pMat.M43 = val; | ||
3293 | break; | ||
3294 | case 3: | ||
3295 | pMat.M44 = val; | ||
3296 | break; | ||
3297 | } | ||
3298 | |||
3299 | break; | ||
3300 | } | ||
3301 | } | ||
3302 | |||
3303 | private static float determinant3x3(Matrix4 pMat) | ||
3304 | { | ||
3305 | float det = 0; | ||
3306 | float diag1 = pMat[0, 0]*pMat[1, 1]*pMat[2, 2]; | ||
3307 | float diag2 = pMat[0, 1]*pMat[2, 1]*pMat[2, 0]; | ||
3308 | float diag3 = pMat[0, 2]*pMat[1, 0]*pMat[2, 1]; | ||
3309 | float diag4 = pMat[2, 0]*pMat[1, 1]*pMat[0, 2]; | ||
3310 | float diag5 = pMat[2, 1]*pMat[1, 2]*pMat[0, 0]; | ||
3311 | float diag6 = pMat[2, 2]*pMat[1, 0]*pMat[0, 1]; | ||
3312 | |||
3313 | det = diag1 + diag2 + diag3 - (diag4 + diag5 + diag6); | ||
3314 | return det; | ||
3315 | } | ||
3316 | |||
3317 | private static void DMassCopy(ref d.Mass src, ref d.Mass dst) | ||
3318 | { | ||
3319 | dst.c.W = src.c.W; | ||
3320 | dst.c.X = src.c.X; | ||
3321 | dst.c.Y = src.c.Y; | ||
3322 | dst.c.Z = src.c.Z; | ||
3323 | dst.mass = src.mass; | ||
3324 | dst.I.M00 = src.I.M00; | ||
3325 | dst.I.M01 = src.I.M01; | ||
3326 | dst.I.M02 = src.I.M02; | ||
3327 | dst.I.M10 = src.I.M10; | ||
3328 | dst.I.M11 = src.I.M11; | ||
3329 | dst.I.M12 = src.I.M12; | ||
3330 | dst.I.M20 = src.I.M20; | ||
3331 | dst.I.M21 = src.I.M21; | ||
3332 | dst.I.M22 = src.I.M22; | ||
3333 | } | ||
3334 | |||
3335 | public override void SetMaterial(int pMaterial) | 3152 | public override void SetMaterial(int pMaterial) |
3336 | { | 3153 | { |
3337 | m_material = pMaterial; | 3154 | m_material = pMaterial; |