aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs30
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs143
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSMotors.cs26
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs32
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs13
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