aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs')
-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.