diff options
author | Robert Adams | 2013-01-20 22:35:42 -0800 |
---|---|---|
committer | Robert Adams | 2013-01-20 23:09:54 -0800 |
commit | 52b341e2e24384395fddc7d32fd66358f5062468 (patch) | |
tree | a0b28ec5b79004b1a556db78d835e486b8040632 | |
parent | BulletSim: fix problem of avatar sliding very slowly occasionally after stopp... (diff) | |
download | opensim-SC_OLD-52b341e2e24384395fddc7d32fd66358f5062468.zip opensim-SC_OLD-52b341e2e24384395fddc7d32fd66358f5062468.tar.gz opensim-SC_OLD-52b341e2e24384395fddc7d32fd66358f5062468.tar.bz2 opensim-SC_OLD-52b341e2e24384395fddc7d32fd66358f5062468.tar.xz |
BulletSim: More aggressive as setting character velocity to zero
when should be standing.
Modify angular force routines to be the same pattern as linear force routines.
BulletSim vehicle turning is scaled like SL and is DIFFERENT THAN ODE!!
Fix some bugs in BSMotor dealing with the motor going to zero.
Add a bunch of parameters: MaxLinearVelocity, MaxAngularVelocity,
MaxAddForceMagnitude, VehicleMaxLinearVelocity, VehicleMaxAngularVelocity,
and most of the values are defaulted to values that are larger
than in SL.
Use the new parameters in BSPrim, BSCharacter and BSDynamic.
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 30 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 143 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 26 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 32 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 13 |
5 files changed, 153 insertions, 91 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index cd279e3..a9e16e6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -200,20 +200,36 @@ public sealed class BSCharacter : BSPhysObject | |||
200 | // TODO: Decide if the step parameters should be changed depending on the avatar's | 200 | // TODO: Decide if the step parameters should be changed depending on the avatar's |
201 | // state (flying, colliding, ...). There is code in ODE to do this. | 201 | // state (flying, colliding, ...). There is code in ODE to do this. |
202 | 202 | ||
203 | // COMMENTARY: when the user is making the avatar walk, except for falling, the velocity | ||
204 | // specified for the avatar is the one that should be used. For falling, if the avatar | ||
205 | // is not flying and is not colliding then it is presumed to be falling and the Z | ||
206 | // component is not fooled with (thus allowing gravity to do its thing). | ||
207 | // When the avatar is standing, though, the user has specified a velocity of zero and | ||
208 | // the avatar should be standing. But if the avatar is pushed by something in the world | ||
209 | // (raising elevator platform, moving vehicle, ...) the avatar should be allowed to | ||
210 | // move. Thus, the velocity cannot be forced to zero. The problem is that small velocity | ||
211 | // errors can creap in and the avatar will slowly float off in some direction. | ||
212 | // So, the problem is that, when an avatar is standing, we cannot tell creaping error | ||
213 | // from real pushing.OMV.Vector3.Zero; | ||
214 | // The code below keeps setting the velocity to zero hoping the world will keep pushing. | ||
215 | |||
203 | _velocityMotor.Step(timeStep); | 216 | _velocityMotor.Step(timeStep); |
204 | 217 | ||
205 | // If we're not supposed to be moving, make sure things are zero. | 218 | // If we're not supposed to be moving, make sure things are zero. |
206 | if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f)) | 219 | if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero && IsColliding) |
207 | { | 220 | { |
208 | if (_wasWalking) | 221 | // The avatar shouldn't be moving |
222 | _velocityMotor.Zero(); | ||
223 | ZeroMotion(true /* inTaintTime */); | ||
224 | |||
225 | // Standing has more friction on the ground | ||
226 | if (_currentFriction != BSParam.AvatarStandingFriction) | ||
209 | { | 227 | { |
210 | _velocityMotor.Zero(); | ||
211 | _velocity = OMV.Vector3.Zero; | ||
212 | PhysicsScene.PE.SetLinearVelocity(PhysBody, OMV.Vector3.Zero); | ||
213 | _currentFriction = BSParam.AvatarStandingFriction; | 228 | _currentFriction = BSParam.AvatarStandingFriction; |
214 | PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); | 229 | PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); |
215 | // DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue); | ||
216 | } | 230 | } |
231 | DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue); | ||
232 | |||
217 | _wasWalking = false; | 233 | _wasWalking = false; |
218 | } | 234 | } |
219 | else | 235 | else |
@@ -242,7 +258,7 @@ public sealed class BSCharacter : BSPhysObject | |||
242 | // Add special movement force to allow avatars to walk up stepped surfaces. | 258 | // Add special movement force to allow avatars to walk up stepped surfaces. |
243 | moveForce += WalkUpStairs(); | 259 | moveForce += WalkUpStairs(); |
244 | 260 | ||
245 | // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); | 261 | DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); |
246 | PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); | 262 | PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); |
247 | _wasWalking = true; | 263 | _wasWalking = true; |
248 | } | 264 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 388d4f9..f8fc3de 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -231,6 +231,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
231 | break; | 231 | break; |
232 | case Vehicle.ANGULAR_MOTOR_DIRECTION: | 232 | case Vehicle.ANGULAR_MOTOR_DIRECTION: |
233 | m_angularMotorDirection = new Vector3(pValue, pValue, pValue); | 233 | m_angularMotorDirection = new Vector3(pValue, pValue, pValue); |
234 | m_angularMotor.Zero(); | ||
234 | m_angularMotor.SetTarget(m_angularMotorDirection); | 235 | m_angularMotor.SetTarget(m_angularMotorDirection); |
235 | break; | 236 | break; |
236 | case Vehicle.LINEAR_FRICTION_TIMESCALE: | 237 | case Vehicle.LINEAR_FRICTION_TIMESCALE: |
@@ -264,6 +265,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
264 | pValue.Y = ClampInRange(-12.56f, pValue.Y, 12.56f); | 265 | pValue.Y = ClampInRange(-12.56f, pValue.Y, 12.56f); |
265 | pValue.Z = ClampInRange(-12.56f, pValue.Z, 12.56f); | 266 | pValue.Z = ClampInRange(-12.56f, pValue.Z, 12.56f); |
266 | m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); | 267 | m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); |
268 | m_angularMotor.Zero(); | ||
267 | m_angularMotor.SetTarget(m_angularMotorDirection); | 269 | m_angularMotor.SetTarget(m_angularMotorDirection); |
268 | break; | 270 | break; |
269 | case Vehicle.LINEAR_FRICTION_TIMESCALE: | 271 | case Vehicle.LINEAR_FRICTION_TIMESCALE: |
@@ -945,10 +947,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
945 | // ================================================================== | 947 | // ================================================================== |
946 | // Clamp high or low velocities | 948 | // Clamp high or low velocities |
947 | float newVelocityLengthSq = VehicleVelocity.LengthSquared(); | 949 | float newVelocityLengthSq = VehicleVelocity.LengthSquared(); |
948 | if (newVelocityLengthSq > 1000f) | 950 | if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocity) |
949 | { | 951 | { |
950 | VehicleVelocity /= VehicleVelocity.Length(); | 952 | VehicleVelocity /= VehicleVelocity.Length(); |
951 | VehicleVelocity *= 1000f; | 953 | VehicleVelocity *= BSParam.VehicleMaxLinearVelocity; |
952 | } | 954 | } |
953 | else if (newVelocityLengthSq < 0.001f) | 955 | else if (newVelocityLengthSq < 0.001f) |
954 | VehicleVelocity = Vector3.Zero; | 956 | VehicleVelocity = Vector3.Zero; |
@@ -1190,63 +1192,33 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1190 | // set directly on the vehicle. | 1192 | // set directly on the vehicle. |
1191 | private void MoveAngular(float pTimestep) | 1193 | private void MoveAngular(float pTimestep) |
1192 | { | 1194 | { |
1193 | // The user wants this many radians per second angular change? | 1195 | VehicleRotationalVelocity = Vector3.Zero; |
1194 | Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); | ||
1195 | angularMotorContribution = m_angularMotor.CurrentValue; | ||
1196 | 1196 | ||
1197 | // ================================================================== | 1197 | ComputeAngularTurning(pTimestep); |
1198 | // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : | ||
1199 | // This flag prevents linear deflection parallel to world z-axis. This is useful | ||
1200 | // for preventing ground vehicles with large linear deflection, like bumper cars, | ||
1201 | // from climbing their linear deflection into the sky. | ||
1202 | // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement | ||
1203 | // TODO: This is here because this is where ODE put it but documentation says it | ||
1204 | // is a linear effect. Where should this check go? | ||
1205 | if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) | ||
1206 | { | ||
1207 | angularMotorContribution.X = 0f; | ||
1208 | angularMotorContribution.Y = 0f; | ||
1209 | VDetailLog("{0}, MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); | ||
1210 | } | ||
1211 | 1198 | ||
1212 | Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction(); | 1199 | ComputeAngularVerticalAttraction(); |
1213 | 1200 | ||
1214 | Vector3 deflectionContribution = ComputeAngularDeflection(); | 1201 | ComputeAngularDeflection(); |
1215 | 1202 | ||
1216 | Vector3 bankingContribution = ComputeAngularBanking(); | 1203 | ComputeAngularBanking(); |
1217 | 1204 | ||
1218 | // ================================================================== | 1205 | // ================================================================== |
1219 | m_lastVertAttractor = verticalAttractionContribution; | ||
1220 | |||
1221 | m_lastAngularVelocity = angularMotorContribution | ||
1222 | + verticalAttractionContribution | ||
1223 | + deflectionContribution | ||
1224 | + bankingContribution; | ||
1225 | |||
1226 | // All of the above computation are made relative to vehicle coordinates. | 1206 | // All of the above computation are made relative to vehicle coordinates. |
1227 | // Convert to world coordinates. | 1207 | // Convert to world coordinates. |
1228 | m_lastAngularVelocity *= VehicleOrientation; | 1208 | // TODO: Should this be applied as an angular force (torque)? |
1209 | VehicleRotationalVelocity *= VehicleOrientation; | ||
1229 | 1210 | ||
1230 | // ================================================================== | 1211 | // ================================================================== |
1231 | // Apply the correction velocity. | 1212 | if (VehicleRotationalVelocity.ApproxEquals(Vector3.Zero, 0.01f)) |
1232 | // TODO: Should this be applied as an angular force (torque)? | ||
1233 | if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) | ||
1234 | { | ||
1235 | VehicleRotationalVelocity = m_lastAngularVelocity; | ||
1236 | |||
1237 | VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5}", | ||
1238 | Prim.LocalID, | ||
1239 | angularMotorContribution, verticalAttractionContribution, | ||
1240 | bankingContribution, deflectionContribution, | ||
1241 | m_lastAngularVelocity | ||
1242 | ); | ||
1243 | } | ||
1244 | else | ||
1245 | { | 1213 | { |
1246 | // The vehicle is not adding anything angular wise. | 1214 | // The vehicle is not adding anything angular wise. |
1247 | VehicleRotationalVelocity = Vector3.Zero; | 1215 | VehicleRotationalVelocity = Vector3.Zero; |
1248 | VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); | 1216 | VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); |
1249 | } | 1217 | } |
1218 | else | ||
1219 | { | ||
1220 | VDetailLog("{0}, MoveAngular,done,nonZero,angVel={1}", Prim.LocalID, VehicleRotationalVelocity); | ||
1221 | } | ||
1250 | 1222 | ||
1251 | // ================================================================== | 1223 | // ================================================================== |
1252 | //Offset section | 1224 | //Offset section |
@@ -1280,6 +1252,30 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1280 | } | 1252 | } |
1281 | 1253 | ||
1282 | } | 1254 | } |
1255 | |||
1256 | private void ComputeAngularTurning(float pTimestep) | ||
1257 | { | ||
1258 | // The user wants this many radians per second angular change? | ||
1259 | Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); | ||
1260 | |||
1261 | // ================================================================== | ||
1262 | // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : | ||
1263 | // This flag prevents linear deflection parallel to world z-axis. This is useful | ||
1264 | // for preventing ground vehicles with large linear deflection, like bumper cars, | ||
1265 | // from climbing their linear deflection into the sky. | ||
1266 | // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement | ||
1267 | // TODO: This is here because this is where ODE put it but documentation says it | ||
1268 | // is a linear effect. Where should this check go? | ||
1269 | if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) | ||
1270 | { | ||
1271 | angularMotorContribution.X = 0f; | ||
1272 | angularMotorContribution.Y = 0f; | ||
1273 | } | ||
1274 | |||
1275 | VehicleRotationalVelocity += angularMotorContribution; | ||
1276 | VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); | ||
1277 | } | ||
1278 | |||
1283 | // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: | 1279 | // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: |
1284 | // Some vehicles, like boats, should always keep their up-side up. This can be done by | 1280 | // Some vehicles, like boats, should always keep their up-side up. This can be done by |
1285 | // enabling the "vertical attractor" behavior that springs the vehicle's local z-axis to | 1281 | // enabling the "vertical attractor" behavior that springs the vehicle's local z-axis to |
@@ -1288,13 +1284,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1288 | // and then set the VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY to control the damping. An | 1284 | // and then set the VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY to control the damping. An |
1289 | // efficiency of 0.0 will cause the spring to wobble around its equilibrium, while an | 1285 | // efficiency of 0.0 will cause the spring to wobble around its equilibrium, while an |
1290 | // efficiency of 1.0 will cause the spring to reach its equilibrium with exponential decay. | 1286 | // efficiency of 1.0 will cause the spring to reach its equilibrium with exponential decay. |
1291 | public Vector3 ComputeAngularVerticalAttraction() | 1287 | public void ComputeAngularVerticalAttraction() |
1292 | { | 1288 | { |
1293 | Vector3 ret = Vector3.Zero; | ||
1294 | |||
1295 | // If vertical attaction timescale is reasonable | 1289 | // If vertical attaction timescale is reasonable |
1296 | if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) | 1290 | if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) |
1297 | { | 1291 | { |
1292 | Vector3 vertContribution = Vector3.Zero; | ||
1293 | |||
1298 | // Take a vector pointing up and convert it from world to vehicle relative coords. | 1294 | // Take a vector pointing up and convert it from world to vehicle relative coords. |
1299 | Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; | 1295 | Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; |
1300 | 1296 | ||
@@ -1308,37 +1304,36 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1308 | 1304 | ||
1309 | // Y error means needed rotation around X axis and visa versa. | 1305 | // Y error means needed rotation around X axis and visa versa. |
1310 | // Since the error goes from zero to one, the asin is the corresponding angle. | 1306 | // Since the error goes from zero to one, the asin is the corresponding angle. |
1311 | ret.X = (float)Math.Asin(verticalError.Y); | 1307 | vertContribution.X = (float)Math.Asin(verticalError.Y); |
1312 | // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) | 1308 | // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) |
1313 | ret.Y = -(float)Math.Asin(verticalError.X); | 1309 | vertContribution.Y = -(float)Math.Asin(verticalError.X); |
1314 | 1310 | ||
1315 | // If verticalError.Z is negative, the vehicle is upside down. Add additional push. | 1311 | // If verticalError.Z is negative, the vehicle is upside down. Add additional push. |
1316 | if (verticalError.Z < 0f) | 1312 | if (verticalError.Z < 0f) |
1317 | { | 1313 | { |
1318 | ret.X += PIOverFour; | 1314 | vertContribution.X += PIOverFour; |
1319 | ret.Y += PIOverFour; | 1315 | vertContribution.Y += PIOverFour; |
1320 | } | 1316 | } |
1321 | 1317 | ||
1322 | // 'ret' is now the necessary velocity to correct tilt in one second. | 1318 | // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. |
1323 | // Correction happens over a number of seconds. | 1319 | // Correction happens over a number of seconds. |
1324 | Vector3 unscaledContrib = ret; | 1320 | Vector3 unscaledContrib = vertContribution; // DEBUG DEBUG |
1325 | ret /= m_verticalAttractionTimescale; | 1321 | vertContribution /= m_verticalAttractionTimescale; |
1322 | |||
1323 | VehicleRotationalVelocity += vertContribution; | ||
1326 | 1324 | ||
1327 | VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}", | 1325 | VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}", |
1328 | Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, ret); | 1326 | Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContribution); |
1329 | } | 1327 | } |
1330 | return ret; | ||
1331 | } | 1328 | } |
1332 | 1329 | ||
1333 | // Return the angular correction to correct the direction the vehicle is pointing to be | 1330 | // Angular correction to correct the direction the vehicle is pointing to be |
1334 | // the direction is should want to be pointing. | 1331 | // the direction is should want to be pointing. |
1335 | // The vehicle is moving in some direction and correct its orientation to it is pointing | 1332 | // The vehicle is moving in some direction and correct its orientation to it is pointing |
1336 | // in that direction. | 1333 | // in that direction. |
1337 | // TODO: implement reference frame. | 1334 | // TODO: implement reference frame. |
1338 | public Vector3 ComputeAngularDeflection() | 1335 | public void ComputeAngularDeflection() |
1339 | { | 1336 | { |
1340 | Vector3 ret = Vector3.Zero; | ||
1341 | |||
1342 | // Since angularMotorUp and angularDeflection are computed independently, they will calculate | 1337 | // Since angularMotorUp and angularDeflection are computed independently, they will calculate |
1343 | // approximately the same X or Y correction. When added together (when contributions are combined) | 1338 | // approximately the same X or Y correction. When added together (when contributions are combined) |
1344 | // this creates an over-correction and then wabbling as the target is overshot. | 1339 | // this creates an over-correction and then wabbling as the target is overshot. |
@@ -1346,6 +1341,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1346 | 1341 | ||
1347 | if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) | 1342 | if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) |
1348 | { | 1343 | { |
1344 | Vector3 deflectContribution = Vector3.Zero; | ||
1345 | |||
1349 | // The direction the vehicle is moving | 1346 | // The direction the vehicle is moving |
1350 | Vector3 movingDirection = VehicleVelocity; | 1347 | Vector3 movingDirection = VehicleVelocity; |
1351 | movingDirection.Normalize(); | 1348 | movingDirection.Normalize(); |
@@ -1371,18 +1368,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1371 | // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError); | 1368 | // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError); |
1372 | 1369 | ||
1373 | // Scale the correction by recovery timescale and efficiency | 1370 | // Scale the correction by recovery timescale and efficiency |
1374 | ret = (-deflectionError) * m_angularDeflectionEfficiency; | 1371 | deflectContribution = (-deflectionError) * m_angularDeflectionEfficiency; |
1375 | ret /= m_angularDeflectionTimescale; | 1372 | deflectContribution /= m_angularDeflectionTimescale; |
1373 | |||
1374 | VehicleRotationalVelocity += deflectContribution; | ||
1376 | 1375 | ||
1377 | VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", | 1376 | VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", |
1378 | Prim.LocalID, movingDirection, pointingDirection, deflectionError, ret); | 1377 | Prim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContribution); |
1379 | VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", | 1378 | VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", |
1380 | Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); | 1379 | Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); |
1381 | } | 1380 | } |
1382 | return ret; | ||
1383 | } | 1381 | } |
1384 | 1382 | ||
1385 | // Return an angular change to rotate the vehicle around the Z axis when the vehicle | 1383 | // Angular change to rotate the vehicle around the Z axis when the vehicle |
1386 | // is tipped around the X axis. | 1384 | // is tipped around the X axis. |
1387 | // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: | 1385 | // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: |
1388 | // The vertical attractor feature must be enabled in order for the banking behavior to | 1386 | // The vertical attractor feature must be enabled in order for the banking behavior to |
@@ -1413,12 +1411,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1413 | // world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to | 1411 | // world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to |
1414 | // bank quickly then give it a banking timescale of about a second or less, otherwise you can | 1412 | // bank quickly then give it a banking timescale of about a second or less, otherwise you can |
1415 | // make a sluggish vehicle by giving it a timescale of several seconds. | 1413 | // make a sluggish vehicle by giving it a timescale of several seconds. |
1416 | public Vector3 ComputeAngularBanking() | 1414 | public void ComputeAngularBanking() |
1417 | { | 1415 | { |
1418 | Vector3 ret = Vector3.Zero; | ||
1419 | |||
1420 | if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) | 1416 | if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) |
1421 | { | 1417 | { |
1418 | Vector3 bankingContribution = Vector3.Zero; | ||
1419 | |||
1422 | // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. | 1420 | // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. |
1423 | // As the vehicle rolls to the right or left, the Y value will increase from | 1421 | // As the vehicle rolls to the right or left, the Y value will increase from |
1424 | // zero (straight up) to 1 or -1 (full tilt right or left) | 1422 | // zero (straight up) to 1 or -1 (full tilt right or left) |
@@ -1435,15 +1433,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1435 | mixedYawAngle = ClampInRange(-20f, mixedYawAngle, 20f); | 1433 | mixedYawAngle = ClampInRange(-20f, mixedYawAngle, 20f); |
1436 | 1434 | ||
1437 | // Build the force vector to change rotation from what it is to what it should be | 1435 | // Build the force vector to change rotation from what it is to what it should be |
1438 | ret.Z = -mixedYawAngle; | 1436 | bankingContribution.Z = -mixedYawAngle; |
1439 | 1437 | ||
1440 | // Don't do it all at once. | 1438 | // Don't do it all at once. |
1441 | ret /= m_bankingTimescale; | 1439 | bankingContribution /= m_bankingTimescale; |
1440 | |||
1441 | VehicleRotationalVelocity += bankingContribution; | ||
1442 | 1442 | ||
1443 | VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", | 1443 | VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", |
1444 | Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, ret); | 1444 | Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContribution); |
1445 | } | 1445 | } |
1446 | return ret; | ||
1447 | } | 1446 | } |
1448 | 1447 | ||
1449 | // This is from previous instantiations of XXXDynamics.cs. | 1448 | // This is from previous instantiations of XXXDynamics.cs. |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 82fd2d2..9501e2d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | |||
@@ -149,6 +149,7 @@ public class BSVMotor : BSMotor | |||
149 | 149 | ||
150 | Vector3 correction = Vector3.Zero; | 150 | Vector3 correction = Vector3.Zero; |
151 | Vector3 error = TargetValue - CurrentValue; | 151 | Vector3 error = TargetValue - CurrentValue; |
152 | LastError = error; | ||
152 | if (!ErrorIsZero(error)) | 153 | if (!ErrorIsZero(error)) |
153 | { | 154 | { |
154 | correction = StepError(timeStep, error); | 155 | correction = StepError(timeStep, error); |
@@ -188,9 +189,15 @@ public class BSVMotor : BSMotor | |||
188 | else | 189 | else |
189 | { | 190 | { |
190 | // Difference between what we have and target is small. Motor is done. | 191 | // Difference between what we have and target is small. Motor is done. |
191 | CurrentValue = TargetValue = Vector3.Zero; | 192 | if (TargetValue.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) |
192 | MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}", | 193 | { |
193 | BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue); | 194 | // The target can step down to nearly zero but not get there. If close to zero |
195 | // it is really zero. | ||
196 | TargetValue = Vector3.Zero; | ||
197 | } | ||
198 | CurrentValue = TargetValue; | ||
199 | MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},currTgt={4},currCurr={5}", | ||
200 | BSScene.DetailLogZero, UseName, origCurrVal, origTarget, TargetValue, CurrentValue); | ||
194 | } | 201 | } |
195 | 202 | ||
196 | return correction; | 203 | return correction; |
@@ -205,9 +212,8 @@ public class BSVMotor : BSMotor | |||
205 | { | 212 | { |
206 | if (!Enabled) return Vector3.Zero; | 213 | if (!Enabled) return Vector3.Zero; |
207 | 214 | ||
208 | LastError = error; | ||
209 | Vector3 returnCorrection = Vector3.Zero; | 215 | Vector3 returnCorrection = Vector3.Zero; |
210 | if (!ErrorIsZero()) | 216 | if (!ErrorIsZero(error)) |
211 | { | 217 | { |
212 | // correction = error / secondsItShouldTakeToCorrect | 218 | // correction = error / secondsItShouldTakeToCorrect |
213 | Vector3 correctionAmount; | 219 | Vector3 correctionAmount; |
@@ -309,6 +315,7 @@ public class BSFMotor : BSMotor | |||
309 | 315 | ||
310 | float correction = 0f; | 316 | float correction = 0f; |
311 | float error = TargetValue - CurrentValue; | 317 | float error = TargetValue - CurrentValue; |
318 | LastError = error; | ||
312 | if (!ErrorIsZero(error)) | 319 | if (!ErrorIsZero(error)) |
313 | { | 320 | { |
314 | correction = StepError(timeStep, error); | 321 | correction = StepError(timeStep, error); |
@@ -346,6 +353,12 @@ public class BSFMotor : BSMotor | |||
346 | else | 353 | else |
347 | { | 354 | { |
348 | // Difference between what we have and target is small. Motor is done. | 355 | // Difference between what we have and target is small. Motor is done. |
356 | if (Util.InRange<float>(TargetValue, -ErrorZeroThreshold, ErrorZeroThreshold)) | ||
357 | { | ||
358 | // The target can step down to nearly zero but not get there. If close to zero | ||
359 | // it is really zero. | ||
360 | TargetValue = 0f; | ||
361 | } | ||
349 | CurrentValue = TargetValue; | 362 | CurrentValue = TargetValue; |
350 | MDetailLog("{0}, BSFMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}", | 363 | MDetailLog("{0}, BSFMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}", |
351 | BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue); | 364 | BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue); |
@@ -358,9 +371,8 @@ public class BSFMotor : BSMotor | |||
358 | { | 371 | { |
359 | if (!Enabled) return 0f; | 372 | if (!Enabled) return 0f; |
360 | 373 | ||
361 | LastError = error; | ||
362 | float returnCorrection = 0f; | 374 | float returnCorrection = 0f; |
363 | if (!ErrorIsZero()) | 375 | if (!ErrorIsZero(error)) |
364 | { | 376 | { |
365 | // correction = error / secondsItShouldTakeToCorrect | 377 | // correction = error / secondsItShouldTakeToCorrect |
366 | float correctionAmount; | 378 | float correctionAmount; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 3e80aa4..6a92365 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -45,6 +45,9 @@ public static class BSParam | |||
45 | 45 | ||
46 | public static float MinimumObjectMass { get; private set; } | 46 | public static float MinimumObjectMass { get; private set; } |
47 | public static float MaximumObjectMass { get; private set; } | 47 | public static float MaximumObjectMass { get; private set; } |
48 | public static float MaxLinearVelocity { get; private set; } | ||
49 | public static float MaxAngularVelocity { get; private set; } | ||
50 | public static float MaxAddForceMagnitude { get; private set; } | ||
48 | 51 | ||
49 | public static float LinearDamping { get; private set; } | 52 | public static float LinearDamping { get; private set; } |
50 | public static float AngularDamping { get; private set; } | 53 | public static float AngularDamping { get; private set; } |
@@ -79,6 +82,8 @@ public static class BSParam | |||
79 | public static float AvatarStepApproachFactor { get; private set; } | 82 | public static float AvatarStepApproachFactor { get; private set; } |
80 | public static float AvatarStepForceFactor { get; private set; } | 83 | public static float AvatarStepForceFactor { get; private set; } |
81 | 84 | ||
85 | public static float VehicleMaxLinearVelocity { get; private set; } | ||
86 | public static float VehicleMaxAngularVelocity { get; private set; } | ||
82 | public static float VehicleAngularDamping { get; private set; } | 87 | public static float VehicleAngularDamping { get; private set; } |
83 | public static float VehicleDebuggingEnabled { get; private set; } | 88 | public static float VehicleDebuggingEnabled { get; private set; } |
84 | 89 | ||
@@ -103,7 +108,6 @@ public static class BSParam | |||
103 | public const float MaxDensity = 22587f; | 108 | public const float MaxDensity = 22587f; |
104 | public const float MinRestitution = 0f; | 109 | public const float MinRestitution = 0f; |
105 | public const float MaxRestitution = 1f; | 110 | public const float MaxRestitution = 1f; |
106 | public const float MaxAddForceMagnitude = 20f; | ||
107 | 111 | ||
108 | // =========================================================================== | 112 | // =========================================================================== |
109 | public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); | 113 | public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); |
@@ -247,6 +251,22 @@ public static class BSParam | |||
247 | (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); }, | 251 | (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); }, |
248 | (s) => { return (float)MaximumObjectMass; }, | 252 | (s) => { return (float)MaximumObjectMass; }, |
249 | (s,p,l,v) => { MaximumObjectMass = v; } ), | 253 | (s,p,l,v) => { MaximumObjectMass = v; } ), |
254 | new ParameterDefn("MaxLinearVelocity", "Maximum velocity magnitude that can be assigned to an object", | ||
255 | 1000.0f, | ||
256 | (s,cf,p,v) => { MaxLinearVelocity = cf.GetFloat(p, v); }, | ||
257 | (s) => { return (float)MaxLinearVelocity; }, | ||
258 | (s,p,l,v) => { MaxLinearVelocity = v; } ), | ||
259 | new ParameterDefn("MaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to an object", | ||
260 | 1000.0f, | ||
261 | (s,cf,p,v) => { MaxAngularVelocity = cf.GetFloat(p, v); }, | ||
262 | (s) => { return (float)MaxAngularVelocity; }, | ||
263 | (s,p,l,v) => { MaxAngularVelocity = v; } ), | ||
264 | // LL documentation says thie number should be 20f | ||
265 | new ParameterDefn("MaxAddForceMagnitude", "Maximum force that can be applied by llApplyImpulse (SL says 20f)", | ||
266 | 200.0f, | ||
267 | (s,cf,p,v) => { MaxAddForceMagnitude = cf.GetFloat(p, v); }, | ||
268 | (s) => { return (float)MaxAddForceMagnitude; }, | ||
269 | (s,p,l,v) => { MaxAddForceMagnitude = v; } ), | ||
250 | 270 | ||
251 | new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", | 271 | new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", |
252 | 2200f, | 272 | 2200f, |
@@ -423,6 +443,16 @@ public static class BSParam | |||
423 | (s) => { return AvatarStepForceFactor; }, | 443 | (s) => { return AvatarStepForceFactor; }, |
424 | (s,p,l,v) => { AvatarStepForceFactor = v; } ), | 444 | (s,p,l,v) => { AvatarStepForceFactor = v; } ), |
425 | 445 | ||
446 | new ParameterDefn("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle", | ||
447 | 1000.0f, | ||
448 | (s,cf,p,v) => { VehicleMaxLinearVelocity = cf.GetFloat(p, v); }, | ||
449 | (s) => { return (float)VehicleMaxLinearVelocity; }, | ||
450 | (s,p,l,v) => { VehicleMaxLinearVelocity = v; } ), | ||
451 | new ParameterDefn("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle", | ||
452 | 12.0f, | ||
453 | (s,cf,p,v) => { VehicleMaxAngularVelocity = cf.GetFloat(p, v); }, | ||
454 | (s) => { return (float)VehicleMaxAngularVelocity; }, | ||
455 | (s,p,l,v) => { VehicleMaxAngularVelocity = v; } ), | ||
426 | new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", | 456 | new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", |
427 | 0.95f, | 457 | 0.95f, |
428 | (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, | 458 | (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 22afdc9..b63523c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -989,10 +989,10 @@ public sealed class BSPrim : BSPhysObject | |||
989 | } | 989 | } |
990 | set { | 990 | set { |
991 | _rotationalVelocity = value; | 991 | _rotationalVelocity = value; |
992 | Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity); | ||
992 | // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); | 993 | // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); |
993 | PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() | 994 | PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() |
994 | { | 995 | { |
995 | DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); | ||
996 | ForceRotationalVelocity = _rotationalVelocity; | 996 | ForceRotationalVelocity = _rotationalVelocity; |
997 | }); | 997 | }); |
998 | } | 998 | } |
@@ -1005,6 +1005,7 @@ public sealed class BSPrim : BSPhysObject | |||
1005 | _rotationalVelocity = value; | 1005 | _rotationalVelocity = value; |
1006 | if (PhysBody.HasPhysicalBody) | 1006 | if (PhysBody.HasPhysicalBody) |
1007 | { | 1007 | { |
1008 | DetailLog("{0},BSPrim.ForceRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); | ||
1008 | PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity); | 1009 | PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity); |
1009 | ActivateIfPhysical(false); | 1010 | ActivateIfPhysical(false); |
1010 | } | 1011 | } |
@@ -1193,10 +1194,14 @@ public sealed class BSPrim : BSPhysObject | |||
1193 | public override float APIDDamping { set { return; } } | 1194 | public override float APIDDamping { set { return; } } |
1194 | 1195 | ||
1195 | public override void AddForce(OMV.Vector3 force, bool pushforce) { | 1196 | public override void AddForce(OMV.Vector3 force, bool pushforce) { |
1197 | // Per documentation, max force is limited. | ||
1198 | OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); | ||
1199 | |||
1196 | // Since this force is being applied in only one step, make this a force per second. | 1200 | // Since this force is being applied in only one step, make this a force per second. |
1197 | OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep; | 1201 | addForce /= PhysicsScene.LastTimeStep; |
1198 | AddForce(addForce, pushforce, false); | 1202 | AddForce(addForce, pushforce, false /* inTaintTime */); |
1199 | } | 1203 | } |
1204 | |||
1200 | // Applying a force just adds this to the total force on the object. | 1205 | // Applying a force just adds this to the total force on the object. |
1201 | // This added force will only last the next simulation tick. | 1206 | // This added force will only last the next simulation tick. |
1202 | public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { | 1207 | public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { |
@@ -1205,9 +1210,9 @@ public sealed class BSPrim : BSPhysObject | |||
1205 | { | 1210 | { |
1206 | if (force.IsFinite()) | 1211 | if (force.IsFinite()) |
1207 | { | 1212 | { |
1208 | OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); | ||
1209 | // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); | 1213 | // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); |
1210 | 1214 | ||
1215 | OMV.Vector3 addForce = force; | ||
1211 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() | 1216 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() |
1212 | { | 1217 | { |
1213 | // Bullet adds this central force to the total force for this tick | 1218 | // Bullet adds this central force to the total force for this tick |