diff options
author | kitto | 2010-04-04 22:57:32 -0400 |
---|---|---|
committer | kitto | 2010-04-04 22:57:32 -0400 |
commit | e2a521742a737aa54e43dd934c0a0d5f2e380e8f (patch) | |
tree | 8259c800deb55b3e42faac9760cf2bcd3d6b27af /OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | |
parent | Update acceleration to 0 on no tphysical. (diff) | |
download | opensim-SC-e2a521742a737aa54e43dd934c0a0d5f2e380e8f.zip opensim-SC-e2a521742a737aa54e43dd934c0a0d5f2e380e8f.tar.gz opensim-SC-e2a521742a737aa54e43dd934c0a0d5f2e380e8f.tar.bz2 opensim-SC-e2a521742a737aa54e43dd934c0a0d5f2e380e8f.tar.xz |
ChODE Only: Corrected Heightmap load to iliminate crack at 255M. Added 'fence' option to prevent physical objects crossing region border.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 202 |
1 files changed, 112 insertions, 90 deletions
diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index e8894f7..67f8af5 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | |||
@@ -180,6 +180,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
180 | internal int m_material = (int)Material.Wood; | 180 | internal int m_material = (int)Material.Wood; |
181 | 181 | ||
182 | private int frcount = 0; // Used to limit dynamics debug output to | 182 | private int frcount = 0; // Used to limit dynamics debug output to |
183 | private int revcount = 0; // Reverse motion while > 0 | ||
183 | 184 | ||
184 | private IntPtr m_body = IntPtr.Zero; | 185 | private IntPtr m_body = IntPtr.Zero; |
185 | 186 | ||
@@ -1888,22 +1889,19 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1888 | 1889 | ||
1889 | public void changemove(float timestep) | 1890 | public void changemove(float timestep) |
1890 | { | 1891 | { |
1891 | //Console.WriteLine("changemove for {0}", m_primName ); | 1892 | //Console.WriteLine("changemove sing/root {0} to {1}", m_primName, _position ); |
1892 | |||
1893 | if (m_isphysical) | 1893 | if (m_isphysical) |
1894 | { | 1894 | { |
1895 | //Console.WriteLine("phys {0} {1} {2}", m_disabled, m_taintremove, childPrim); | 1895 | //Console.WriteLine("phys {0} {1} {2}", m_disabled, m_taintremove, childPrim); |
1896 | // if (!m_disabled && !m_taintremove && !childPrim) After one edit m_disabled is sometimes set, disabling further edits! | 1896 | // if (!m_disabled && !m_taintremove && !childPrim) After one edit m_disabled is sometimes set, disabling further edits! |
1897 | if (!m_taintremove && !childPrim) | 1897 | if (!m_taintremove && !childPrim) |
1898 | { | 1898 | { |
1899 | //Console.WriteLine("physOK"); | ||
1900 | if (Body == IntPtr.Zero) | 1899 | if (Body == IntPtr.Zero) |
1901 | enableBody(); | 1900 | enableBody(); |
1902 | //Prim auto disable after 20 frames, | 1901 | //Prim auto disable after 20 frames, |
1903 | //if you move it, re-enable the prim manually. | 1902 | //if you move it, re-enable the prim manually. |
1904 | if (_parent != null) | 1903 | if (_parent != null) |
1905 | { | 1904 | { |
1906 | //Console.WriteLine("physChild"); | ||
1907 | if (m_linkJoint != IntPtr.Zero) | 1905 | if (m_linkJoint != IntPtr.Zero) |
1908 | { | 1906 | { |
1909 | d.JointDestroy(m_linkJoint); | 1907 | d.JointDestroy(m_linkJoint); |
@@ -1912,7 +1910,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1912 | } | 1910 | } |
1913 | if (Body != IntPtr.Zero) | 1911 | if (Body != IntPtr.Zero) |
1914 | { | 1912 | { |
1915 | //Console.WriteLine("physNotIPZ"); | ||
1916 | d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); | 1913 | d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); |
1917 | 1914 | ||
1918 | if (_parent != null) | 1915 | if (_parent != null) |
@@ -1945,7 +1942,6 @@ Console.WriteLine(" JointCreateFixed"); | |||
1945 | } | 1942 | } |
1946 | else | 1943 | else |
1947 | { | 1944 | { |
1948 | //Console.WriteLine("NONphys"); | ||
1949 | // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); | 1945 | // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); |
1950 | // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); | 1946 | // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); |
1951 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1947 | _parent_scene.waitForSpaceUnlock(m_targetSpace); |
@@ -2382,9 +2378,7 @@ Console.WriteLine(" JointCreateFixed"); | |||
2382 | if (IsPhysical) | 2378 | if (IsPhysical) |
2383 | { | 2379 | { |
2384 | if (Body != IntPtr.Zero) | 2380 | if (Body != IntPtr.Zero) |
2385 | { | ||
2386 | d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z); | 2381 | d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z); |
2387 | } | ||
2388 | } | 2382 | } |
2389 | 2383 | ||
2390 | //resetCollisionAccounting(); | 2384 | //resetCollisionAccounting(); |
@@ -2394,31 +2388,9 @@ Console.WriteLine(" JointCreateFixed"); | |||
2394 | 2388 | ||
2395 | public void UpdatePositionAndVelocity() | 2389 | public void UpdatePositionAndVelocity() |
2396 | { | 2390 | { |
2397 | return; // moved to the Move() method | 2391 | return; // moved to the Move () method |
2398 | } | ||
2399 | /* No one uses this? | ||
2400 | public Matrix4 FromDMass(d.Mass pMass) | ||
2401 | { | ||
2402 | Matrix4 obj; | ||
2403 | obj.M11 = pMass.I.M00; | ||
2404 | obj.M12 = pMass.I.M01; | ||
2405 | obj.M13 = pMass.I.M02; | ||
2406 | obj.M14 = 0; | ||
2407 | obj.M21 = pMass.I.M10; | ||
2408 | obj.M22 = pMass.I.M11; | ||
2409 | obj.M23 = pMass.I.M12; | ||
2410 | obj.M24 = 0; | ||
2411 | obj.M31 = pMass.I.M20; | ||
2412 | obj.M32 = pMass.I.M21; | ||
2413 | obj.M33 = pMass.I.M22; | ||
2414 | obj.M34 = 0; | ||
2415 | obj.M41 = 0; | ||
2416 | obj.M42 = 0; | ||
2417 | obj.M43 = 0; | ||
2418 | obj.M44 = 1; | ||
2419 | return obj; | ||
2420 | } | 2392 | } |
2421 | */ | 2393 | |
2422 | public d.Mass FromMatrix4(Matrix4 pMat, ref d.Mass obj) | 2394 | public d.Mass FromMatrix4(Matrix4 pMat, ref d.Mass obj) |
2423 | { | 2395 | { |
2424 | obj.I.M00 = pMat[0, 0]; | 2396 | obj.I.M00 = pMat[0, 0]; |
@@ -2996,44 +2968,114 @@ Console.WriteLine(" JointCreateFixed"); | |||
2996 | float fx = 0; | 2968 | float fx = 0; |
2997 | float fy = 0; | 2969 | float fy = 0; |
2998 | float fz = 0; | 2970 | float fz = 0; |
2971 | Vector3 linvel; // velocity applied, including any reversal | ||
2972 | int outside = 0; | ||
2973 | |||
2974 | // If geomCrossingFailuresBeforeOutofbounds is set to 0 in OpenSim.ini then phys objects bounce off region borders. | ||
2975 | // This is a temp patch until proper region crossing is developed. | ||
2976 | |||
2977 | int failureLimit = _parent_scene.geomCrossingFailuresBeforeOutofbounds; | ||
2978 | int fence = _parent_scene.geomRegionFence; | ||
2979 | |||
2980 | float border_limit = 0.05f; // original limit | ||
2981 | if (fence == 1) border_limit = 0.5f; // bounce point | ||
2999 | 2982 | ||
3000 | frcount++; // used to limit debug comment output | 2983 | frcount++; // used to limit debug comment output |
3001 | if (frcount > 100) | 2984 | if (frcount > 100) |
3002 | frcount = 0; | 2985 | frcount = 0; |
3003 | 2986 | ||
3004 | if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. | 2987 | if(revcount > 0) revcount--; |
2988 | |||
2989 | if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // Only move root prims. | ||
3005 | { | 2990 | { |
3006 | 2991 | // Old public void UpdatePositionAndVelocity(), more accuratley calculated here | |
3007 | // Old public void UpdatePositionAndVelocity(), more accuratley calculated here | ||
3008 | bool lastZeroFlag = _zeroFlag; // was it stopped | 2992 | bool lastZeroFlag = _zeroFlag; // was it stopped |
2993 | |||
3009 | d.Vector3 vec = d.BodyGetPosition(Body); | 2994 | d.Vector3 vec = d.BodyGetPosition(Body); |
3010 | d.Quaternion ori = d.BodyGetQuaternion(Body); | ||
3011 | d.Vector3 vel = d.BodyGetLinearVel(Body); | ||
3012 | // d.Vector3 rotvel = d.BodyGetAngularVel(Body); | ||
3013 | d.Vector3 torque = d.BodyGetTorque(Body); | ||
3014 | _torque = new Vector3(torque.X, torque.Y, torque.Z); | ||
3015 | Vector3 l_position = Vector3.Zero; | 2995 | Vector3 l_position = Vector3.Zero; |
3016 | Quaternion l_orientation = Quaternion.Identity; | ||
3017 | |||
3018 | m_lastposition = _position; | ||
3019 | m_lastorientation = _orientation; | ||
3020 | |||
3021 | l_position.X = vec.X; | 2996 | l_position.X = vec.X; |
3022 | l_position.Y = vec.Y; | 2997 | l_position.Y = vec.Y; |
3023 | l_position.Z = vec.Z; | 2998 | l_position.Z = vec.Z; |
3024 | l_orientation.X = ori.X; | 2999 | m_lastposition = _position; |
3025 | l_orientation.Y = ori.Y; | 3000 | _position = l_position; |
3026 | l_orientation.Z = ori.Z; | 3001 | |
3027 | l_orientation.W = ori.W; | 3002 | d.Quaternion ori = d.BodyGetQuaternion(Body); |
3003 | // Quaternion l_orientation = Quaternion.Identity; | ||
3004 | _orientation.X = ori.X; | ||
3005 | _orientation.Y = ori.Y; | ||
3006 | _orientation.Z = ori.Z; | ||
3007 | _orientation.W = ori.W; | ||
3008 | m_lastorientation = _orientation; | ||
3009 | |||
3010 | d.Vector3 vel = d.BodyGetLinearVel(Body); | ||
3011 | m_lastVelocity = _velocity; | ||
3012 | _velocity.X = vel.X; | ||
3013 | _velocity.Y = vel.Y; | ||
3014 | _velocity.Z = vel.Z; | ||
3015 | _acceleration = ((_velocity - m_lastVelocity) / timestep); | ||
3016 | |||
3017 | d.Vector3 torque = d.BodyGetTorque(Body); | ||
3018 | _torque = new Vector3(torque.X, torque.Y, torque.Z); | ||
3019 | |||
3020 | base.RequestPhysicsterseUpdate(); | ||
3021 | |||
3028 | //Console.WriteLine("Move {0} at {1}", m_primName, l_position); | 3022 | //Console.WriteLine("Move {0} at {1}", m_primName, l_position); |
3029 | 3023 | ||
3030 | // Check if outside region horizontally | 3024 | // Check if outside region |
3031 | if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || | 3025 | // In Scene.cs/CrossPrimGroupIntoNewRegion the object is checked for 0.1M from border! |
3032 | l_position.X < 0f || | 3026 | if (l_position.X > ((float)_parent_scene.WorldExtents.X - border_limit)) |
3033 | l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || | 3027 | { |
3034 | l_position.Y < 0f) | 3028 | l_position.X = ((float)_parent_scene.WorldExtents.X - border_limit); |
3029 | outside = 1; | ||
3030 | } | ||
3031 | |||
3032 | if (l_position.X < border_limit) | ||
3033 | { | ||
3034 | l_position.X = border_limit; | ||
3035 | outside = 2; | ||
3036 | } | ||
3037 | if (l_position.Y > ((float)_parent_scene.WorldExtents.Y - border_limit)) | ||
3038 | { | ||
3039 | l_position.Y = ((float)_parent_scene.WorldExtents.Y - border_limit); | ||
3040 | outside = 3; | ||
3041 | } | ||
3042 | |||
3043 | if (l_position.Y < border_limit) | ||
3044 | { | ||
3045 | l_position.Y = border_limit; | ||
3046 | outside = 4; | ||
3047 | } | ||
3048 | |||
3049 | if (outside > 0) | ||
3035 | { | 3050 | { |
3036 | if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds) | 3051 | //Console.WriteLine(" fence = {0}",fence); |
3052 | |||
3053 | //Console.WriteLine("Border {0}", l_position); | ||
3054 | if (fence == 1) // bounce object off boundary | ||
3055 | { | ||
3056 | if (revcount == 0) | ||
3057 | { | ||
3058 | if (outside < 3) | ||
3059 | { | ||
3060 | _velocity.X = -_velocity.X; | ||
3061 | } | ||
3062 | else | ||
3063 | { | ||
3064 | _velocity.Y = -_velocity.Y; | ||
3065 | } | ||
3066 | if (m_type != Vehicle.TYPE_NONE) Halt(); | ||
3067 | _position = l_position; | ||
3068 | m_taintposition = _position; | ||
3069 | m_lastVelocity = _velocity; | ||
3070 | _acceleration = Vector3.Zero; | ||
3071 | d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); | ||
3072 | d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); | ||
3073 | base.RequestPhysicsterseUpdate(); | ||
3074 | |||
3075 | revcount = 25; // wait for object to move away from border | ||
3076 | } | ||
3077 | } // else old crossing mode | ||
3078 | else if (m_crossingfailures < failureLimit) | ||
3037 | { // keep trying to cross? | 3079 | { // keep trying to cross? |
3038 | _position = l_position; | 3080 | _position = l_position; |
3039 | //_parent_scene.remActivePrim(this); | 3081 | //_parent_scene.remActivePrim(this); |
@@ -3043,9 +3085,12 @@ Console.WriteLine(" JointCreateFixed"); | |||
3043 | else | 3085 | else |
3044 | { // Too many tries | 3086 | { // Too many tries |
3045 | if (_parent == null) base.RaiseOutOfBounds(l_position); | 3087 | if (_parent == null) base.RaiseOutOfBounds(l_position); |
3088 | //Console.WriteLine("ROOB 2"); | ||
3089 | |||
3046 | return; // Dont process any other motion? | 3090 | return; // Dont process any other motion? |
3047 | } | 3091 | } // end various methods |
3048 | } // end outside region horizontally | 3092 | } // end outside region horizontally |
3093 | |||
3049 | 3094 | ||
3050 | if (l_position.Z < 0) | 3095 | if (l_position.Z < 0) |
3051 | { | 3096 | { |
@@ -3057,6 +3102,8 @@ Console.WriteLine(" JointCreateFixed"); | |||
3057 | 3102 | ||
3058 | //IsPhysical = false; | 3103 | //IsPhysical = false; |
3059 | if (_parent == null) base.RaiseOutOfBounds(_position); | 3104 | if (_parent == null) base.RaiseOutOfBounds(_position); |
3105 | //Console.WriteLine("ROOB 3"); | ||
3106 | |||
3060 | 3107 | ||
3061 | _acceleration.X = 0; // This stuff may stop client display but it has no | 3108 | _acceleration.X = 0; // This stuff may stop client display but it has no |
3062 | _acceleration.Y = 0; // effect on the object in phys engine! | 3109 | _acceleration.Y = 0; // effect on the object in phys engine! |
@@ -3081,10 +3128,9 @@ Console.WriteLine(" JointCreateFixed"); | |||
3081 | if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) | 3128 | if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) |
3082 | && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) | 3129 | && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) |
3083 | && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) | 3130 | && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) |
3084 | && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.0001)) // KF 0.01 is far to large | 3131 | && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, _orientation)) < 0.0001)) // KF 0.01 is far to large |
3085 | { | 3132 | { |
3086 | _zeroFlag = true; | 3133 | _zeroFlag = true; |
3087 | //Console.WriteLine("ZFT 2"); | ||
3088 | m_throttleUpdates = false; | 3134 | m_throttleUpdates = false; |
3089 | } | 3135 | } |
3090 | else | 3136 | else |
@@ -3104,10 +3150,7 @@ Console.WriteLine(" JointCreateFixed"); | |||
3104 | _acceleration.X = 0; | 3150 | _acceleration.X = 0; |
3105 | _acceleration.Y = 0; | 3151 | _acceleration.Y = 0; |
3106 | _acceleration.Z = 0; | 3152 | _acceleration.Z = 0; |
3107 | //_orientation.w = 0f; | 3153 | |
3108 | //_orientation.X = 0f; | ||
3109 | //_orientation.Y = 0f; | ||
3110 | //_orientation.Z = 0f; | ||
3111 | m_rotationalVelocity.X = 0; | 3154 | m_rotationalVelocity.X = 0; |
3112 | m_rotationalVelocity.Y = 0; | 3155 | m_rotationalVelocity.Y = 0; |
3113 | m_rotationalVelocity.Z = 0; | 3156 | m_rotationalVelocity.Z = 0; |
@@ -3132,26 +3175,6 @@ Console.WriteLine(" JointCreateFixed"); | |||
3132 | base.RequestPhysicsterseUpdate(); | 3175 | base.RequestPhysicsterseUpdate(); |
3133 | } | 3176 | } |
3134 | } | 3177 | } |
3135 | |||
3136 | m_lastVelocity = _velocity; | ||
3137 | |||
3138 | _position = l_position; | ||
3139 | |||
3140 | _velocity.X = vel.X; | ||
3141 | _velocity.Y = vel.Y; | ||
3142 | _velocity.Z = vel.Z; | ||
3143 | // Why 2 calcs??? | ||
3144 | // _acceleration = ((_velocity - m_lastVelocity) / 0.1f); | ||
3145 | // _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, | ||
3146 | // _velocity.Y - m_lastVelocity.Y / 0.1f, | ||
3147 | // _velocity.Z - m_lastVelocity.Z / 0.1f); | ||
3148 | |||
3149 | _acceleration = ((_velocity - m_lastVelocity) / timestep); | ||
3150 | |||
3151 | _orientation.X = ori.X; | ||
3152 | _orientation.Y = ori.Y; | ||
3153 | _orientation.Z = ori.Z; | ||
3154 | _orientation.W = ori.W; | ||
3155 | m_lastUpdateSent = false; | 3178 | m_lastUpdateSent = false; |
3156 | if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate) | 3179 | if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate) |
3157 | { | 3180 | { |
@@ -3167,11 +3190,8 @@ Console.WriteLine(" JointCreateFixed"); | |||
3167 | } | 3190 | } |
3168 | m_lastposition = l_position; | 3191 | m_lastposition = l_position; |
3169 | 3192 | ||
3170 | /// End of old UpdatePositionAndVelocity insert | 3193 | /// End UpdatePositionAndVelocity insert |
3171 | 3194 | ||
3172 | //if (!Acceleration.ApproxEquals(Vector3.Zero, 0.01f)) Console.WriteLine("Move " + m_primName + " Accel=" + Acceleration); | ||
3173 | // if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_type + | ||
3174 | // " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID); | ||
3175 | if (m_type != Vehicle.TYPE_NONE) | 3195 | if (m_type != Vehicle.TYPE_NONE) |
3176 | { | 3196 | { |
3177 | // get body attitude | 3197 | // get body attitude |
@@ -3299,11 +3319,12 @@ Console.WriteLine(" JointCreateFixed"); | |||
3299 | { // not hovering, Gravity rules | 3319 | { // not hovering, Gravity rules |
3300 | m_wLinObjectVel.Z = vel_now.Z; | 3320 | m_wLinObjectVel.Z = vel_now.Z; |
3301 | } | 3321 | } |
3302 | 3322 | linvel = m_wLinObjectVel; | |
3303 | 3323 | ||
3304 | // Vehicle Linear Motion done ======================================= | 3324 | // Vehicle Linear Motion done ======================================= |
3305 | // Apply velocity | 3325 | // Apply velocity |
3306 | d.BodySetLinearVel(Body, m_wLinObjectVel.X, m_wLinObjectVel.Y, m_wLinObjectVel.Z); | 3326 | //if(frcount == 0) Console.WriteLine("LV {0}", linvel); |
3327 | d.BodySetLinearVel(Body, linvel.X, linvel.Y, linvel.Z); | ||
3307 | // apply gravity force | 3328 | // apply gravity force |
3308 | d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); | 3329 | d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); |
3309 | //if(frcount == 0) Console.WriteLine("Grav {0}", grav); | 3330 | //if(frcount == 0) Console.WriteLine("Grav {0}", grav); |
@@ -3626,9 +3647,10 @@ Console.WriteLine(" JointCreateFixed"); | |||
3626 | // react to the physics scene by moving it's position. | 3647 | // react to the physics scene by moving it's position. |
3627 | // Avatar to Avatar collisions | 3648 | // Avatar to Avatar collisions |
3628 | // Prim to avatar collisions | 3649 | // Prim to avatar collisions |
3650 | d.Vector3 dlinvel = vel; | ||
3629 | 3651 | ||
3630 | d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); | 3652 | d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); |
3631 | d.BodySetLinearVel(Body, vel.X, vel.Y, 0); | 3653 | d.BodySetLinearVel(Body, dlinvel.X, dlinvel.Y, dlinvel.Z); |
3632 | d.BodyAddForce(Body, 0, 0, fz); | 3654 | d.BodyAddForce(Body, 0, 0, fz); |
3633 | //KF this prevents furthur motions return; | 3655 | //KF this prevents furthur motions return; |
3634 | } | 3656 | } |