aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
diff options
context:
space:
mode:
authorRobert Adams2013-01-20 22:35:42 -0800
committerRobert Adams2013-01-20 23:09:54 -0800
commit52b341e2e24384395fddc7d32fd66358f5062468 (patch)
treea0b28ec5b79004b1a556db78d835e486b8040632 /OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
parentBulletSim: fix problem of avatar sliding very slowly occasionally after stopp... (diff)
downloadopensim-SC-52b341e2e24384395fddc7d32fd66358f5062468.zip
opensim-SC-52b341e2e24384395fddc7d32fd66358f5062468.tar.gz
opensim-SC-52b341e2e24384395fddc7d32fd66358f5062468.tar.bz2
opensim-SC-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.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs143
1 files changed, 71 insertions, 72 deletions
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.