aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs')
-rw-r--r--OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs571
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;