aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
diff options
context:
space:
mode:
authorRobert Adams2013-07-08 16:21:10 -0700
committerRobert Adams2013-07-08 16:24:31 -0700
commitfad4241e4ea898b0dca0176cc9b428d03ba44d1c (patch)
treec9786d6ee34555025448ebadcf4f500657259b65 /OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
parentminor: remove mono compiler warnings from HGSuitcaseInventoryService (diff)
downloadopensim-SC_OLD-fad4241e4ea898b0dca0176cc9b428d03ba44d1c.zip
opensim-SC_OLD-fad4241e4ea898b0dca0176cc9b428d03ba44d1c.tar.gz
opensim-SC_OLD-fad4241e4ea898b0dca0176cc9b428d03ba44d1c.tar.bz2
opensim-SC_OLD-fad4241e4ea898b0dca0176cc9b428d03ba44d1c.tar.xz
BulletSim: make all the different angularVerticalAttraction algorithms
selectable from configuration paramters. Changed default algorithm to "1" from previous default as it seems to handle Y axis correction a little better. Add config file independent enablement of vehicle angular forces to make debugging easier (independent testing of forces).
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs261
1 files changed, 129 insertions, 132 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 82fe267..a5f2e98 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -125,33 +125,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
125 static readonly float PIOverFour = ((float)Math.PI) / 4f; 125 static readonly float PIOverFour = ((float)Math.PI) / 4f;
126 static readonly float PIOverTwo = ((float)Math.PI) / 2f; 126 static readonly float PIOverTwo = ((float)Math.PI) / 2f;
127 127
128 // For debugging, flags to turn on and off individual corrections.
129 public bool enableAngularVerticalAttraction;
130 public bool enableAngularDeflection;
131 public bool enableAngularBanking;
132
133 public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName) 128 public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName)
134 : base(myScene, myPrim, actorName) 129 : base(myScene, myPrim, actorName)
135 { 130 {
136 ControllingPrim = myPrim; 131 ControllingPrim = myPrim;
137 Type = Vehicle.TYPE_NONE; 132 Type = Vehicle.TYPE_NONE;
138 m_haveRegisteredForSceneEvents = false; 133 m_haveRegisteredForSceneEvents = false;
139 SetupVehicleDebugging();
140 }
141
142 // Stopgap debugging enablement. Allows source level debugging but still checking
143 // in changes by making enablement of debugging flags from INI file.
144 public void SetupVehicleDebugging()
145 {
146 enableAngularVerticalAttraction = true;
147 enableAngularDeflection = true;
148 enableAngularBanking = true;
149 if (BSParam.VehicleDebuggingEnable)
150 {
151 enableAngularVerticalAttraction = true;
152 enableAngularDeflection = false;
153 enableAngularBanking = false;
154 }
155 } 134 }
156 135
157 // Return 'true' if this vehicle is doing vehicle things 136 // Return 'true' if this vehicle is doing vehicle things
@@ -556,10 +535,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
556 } 535 }
557 536
558 m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, m_linearMotorDecayTimescale, 1f); 537 m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, m_linearMotorDecayTimescale, 1f);
559 m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) 538 // m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
560 539
561 m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, m_angularMotorDecayTimescale, 1f); 540 m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, m_angularMotorDecayTimescale, 1f);
562 m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) 541 // m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
563 542
564 /* Not implemented 543 /* Not implemented
565 m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, 544 m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale,
@@ -1393,116 +1372,134 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1393 { 1372 {
1394 1373
1395 // If vertical attaction timescale is reasonable 1374 // If vertical attaction timescale is reasonable
1396 if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1375 if (BSParam.VehicleEnableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1397 { 1376 {
1398 //Another formula to try got from : 1377 Vector3 vehicleUpAxis = Vector3.UnitZ * VehicleOrientation;
1399 //http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html 1378 switch (BSParam.VehicleAngularVerticalAttractionAlgorithm)
1400
1401 Vector3 VehicleUpAxis = Vector3.UnitZ * VehicleOrientation;
1402
1403 // Flipping what was originally a timescale into a speed variable and then multiplying it by 2
1404 // since only computing half the distance between the angles.
1405 float VerticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f;
1406
1407 // Make a prediction of where the up axis will be when this is applied rather then where it is now as
1408 // this makes for a smoother adjustment and less fighting between the various forces.
1409 Vector3 predictedUp = VehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
1410
1411 // This is only half the distance to the target so it will take 2 seconds to complete the turn.
1412 Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
1413
1414 // Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared
1415 Vector3 vertContributionV = torqueVector * VerticalAttractionSpeed * VerticalAttractionSpeed;
1416
1417 VehicleRotationalVelocity += vertContributionV;
1418
1419 VDetailLog("{0}, MoveAngular,verticalAttraction,UpAxis={1},PredictedUp={2},torqueVector={3},contrib={4}",
1420 ControllingPrim.LocalID,
1421 VehicleUpAxis,
1422 predictedUp,
1423 torqueVector,
1424 vertContributionV);
1425 //=====================================================================
1426 /*
1427 // Possible solution derived from a discussion at:
1428 // http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no
1429
1430 // Create a rotation that is only the vehicle's rotation around Z
1431 Vector3 currentEuler = Vector3.Zero;
1432 VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z);
1433 Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z);
1434
1435 // Create the axis that is perpendicular to the up vector and the rotated up vector.
1436 Vector3 differenceAxis = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation);
1437 // Compute the angle between those to vectors.
1438 double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation)));
1439 // 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical
1440
1441 // Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied.
1442 // TODO: add 'efficiency'.
1443 differenceAngle /= m_verticalAttractionTimescale;
1444
1445 // Create the quaterian representing the correction angle
1446 Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle);
1447
1448 // Turn that quaternion into Euler values to make it into velocities to apply.
1449 Vector3 vertContributionV = Vector3.Zero;
1450 correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z);
1451 vertContributionV *= -1f;
1452
1453 VehicleRotationalVelocity += vertContributionV;
1454
1455 VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}",
1456 ControllingPrim.LocalID,
1457 differenceAxis,
1458 differenceAngle,
1459 correctionRotation,
1460 vertContributionV);
1461 */
1462
1463 // ===================================================================
1464 /*
1465 Vector3 vertContributionV = Vector3.Zero;
1466 Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG
1467
1468 // Take a vector pointing up and convert it from world to vehicle relative coords.
1469 Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation);
1470
1471 // If vertical attraction correction is needed, the vector that was pointing up (UnitZ)
1472 // is now:
1473 // leaning to one side: rotated around the X axis with the Y value going
1474 // from zero (nearly straight up) to one (completely to the side)) or
1475 // leaning front-to-back: rotated around the Y axis with the value of X being between
1476 // zero and one.
1477 // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees.
1478
1479 // Y error means needed rotation around X axis and visa versa.
1480 // Since the error goes from zero to one, the asin is the corresponding angle.
1481 vertContributionV.X = (float)Math.Asin(verticalError.Y);
1482 // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.)
1483 vertContributionV.Y = -(float)Math.Asin(verticalError.X);
1484
1485 // If verticalError.Z is negative, the vehicle is upside down. Add additional push.
1486 if (verticalError.Z < 0f)
1487 { 1379 {
1488 vertContributionV.X += Math.Sign(vertContributionV.X) * PIOverFour; 1380 case 0:
1489 // vertContribution.Y -= PIOverFour; 1381 {
1382 //Another formula to try got from :
1383 //http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html
1384
1385 // Flipping what was originally a timescale into a speed variable and then multiplying it by 2
1386 // since only computing half the distance between the angles.
1387 float VerticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f;
1388
1389 // Make a prediction of where the up axis will be when this is applied rather then where it is now as
1390 // this makes for a smoother adjustment and less fighting between the various forces.
1391 Vector3 predictedUp = vehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
1392
1393 // This is only half the distance to the target so it will take 2 seconds to complete the turn.
1394 Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
1395
1396 // Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared
1397 Vector3 vertContributionV = torqueVector * VerticalAttractionSpeed * VerticalAttractionSpeed;
1398
1399 VehicleRotationalVelocity += vertContributionV;
1400
1401 VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},PredictedUp={2},torqueVector={3},contrib={4}",
1402 ControllingPrim.LocalID,
1403 vehicleUpAxis,
1404 predictedUp,
1405 torqueVector,
1406 vertContributionV);
1407 break;
1408 }
1409 case 1:
1410 {
1411 // Possible solution derived from a discussion at:
1412 // http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no
1413
1414 // Create a rotation that is only the vehicle's rotation around Z
1415 Vector3 currentEuler = Vector3.Zero;
1416 VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z);
1417 Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z);
1418
1419 // Create the axis that is perpendicular to the up vector and the rotated up vector.
1420 Vector3 differenceAxis = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation);
1421 // Compute the angle between those to vectors.
1422 double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation)));
1423 // 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical
1424
1425 // Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied.
1426 // TODO: add 'efficiency'.
1427 differenceAngle /= m_verticalAttractionTimescale;
1428
1429 // Create the quaterian representing the correction angle
1430 Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle);
1431
1432 // Turn that quaternion into Euler values to make it into velocities to apply.
1433 Vector3 vertContributionV = Vector3.Zero;
1434 correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z);
1435 vertContributionV *= -1f;
1436
1437 VehicleRotationalVelocity += vertContributionV;
1438
1439 VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},diffAxis={2},diffAng={3},corrRot={4},contrib={5}",
1440 ControllingPrim.LocalID,
1441 vehicleUpAxis,
1442 differenceAxis,
1443 differenceAngle,
1444 correctionRotation,
1445 vertContributionV);
1446 break;
1447 }
1448 case 2:
1449 {
1450 Vector3 vertContributionV = Vector3.Zero;
1451 Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG
1452
1453 // Take a vector pointing up and convert it from world to vehicle relative coords.
1454 Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation);
1455
1456 // If vertical attraction correction is needed, the vector that was pointing up (UnitZ)
1457 // is now:
1458 // leaning to one side: rotated around the X axis with the Y value going
1459 // from zero (nearly straight up) to one (completely to the side)) or
1460 // leaning front-to-back: rotated around the Y axis with the value of X being between
1461 // zero and one.
1462 // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees.
1463
1464 // Y error means needed rotation around X axis and visa versa.
1465 // Since the error goes from zero to one, the asin is the corresponding angle.
1466 vertContributionV.X = (float)Math.Asin(verticalError.Y);
1467 // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.)
1468 vertContributionV.Y = -(float)Math.Asin(verticalError.X);
1469
1470 // If verticalError.Z is negative, the vehicle is upside down. Add additional push.
1471 if (verticalError.Z < 0f)
1472 {
1473 vertContributionV.X += Math.Sign(vertContributionV.X) * PIOverFour;
1474 // vertContribution.Y -= PIOverFour;
1475 }
1476
1477 // 'vertContrbution' is now the necessary angular correction to correct tilt in one second.
1478 // Correction happens over a number of seconds.
1479 Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG
1480
1481 // The correction happens over the user's time period
1482 vertContributionV /= m_verticalAttractionTimescale;
1483
1484 // Rotate the vehicle rotation to the world coordinates.
1485 VehicleRotationalVelocity += (vertContributionV * VehicleOrientation);
1486
1487 VDetailLog("{0}, MoveAngular,verticalAttraction,,upAxis={1},origRotVW={2},vertError={3},unscaledV={4},eff={5},ts={6},vertContribV={7}",
1488 ControllingPrim.LocalID,
1489 vehicleUpAxis,
1490 origRotVelW,
1491 verticalError,
1492 unscaledContribVerticalErrorV,
1493 m_verticalAttractionEfficiency,
1494 m_verticalAttractionTimescale,
1495 vertContributionV);
1496 break;
1497 }
1498 default:
1499 {
1500 break;
1501 }
1490 } 1502 }
1491
1492 // 'vertContrbution' is now the necessary angular correction to correct tilt in one second.
1493 // Correction happens over a number of seconds.
1494 Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG
1495
1496 // The correction happens over the user's time period
1497 vertContributionV /= m_verticalAttractionTimescale;
1498
1499 // Rotate the vehicle rotation to the world coordinates.
1500 VehicleRotationalVelocity += (vertContributionV * VehicleOrientation);
1501
1502 VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}",
1503 Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV,
1504 m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV);
1505 */
1506 } 1503 }
1507 } 1504 }
1508 1505
@@ -1514,7 +1511,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1514 public void ComputeAngularDeflection() 1511 public void ComputeAngularDeflection()
1515 { 1512 {
1516 1513
1517 if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) 1514 if (BSParam.VehicleEnableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
1518 { 1515 {
1519 Vector3 deflectContributionV = Vector3.Zero; 1516 Vector3 deflectContributionV = Vector3.Zero;
1520 1517
@@ -1593,7 +1590,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1593 // make a sluggish vehicle by giving it a timescale of several seconds. 1590 // make a sluggish vehicle by giving it a timescale of several seconds.
1594 public void ComputeAngularBanking() 1591 public void ComputeAngularBanking()
1595 { 1592 {
1596 if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1593 if (BSParam.VehicleEnableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1597 { 1594 {
1598 Vector3 bankingContributionV = Vector3.Zero; 1595 Vector3 bankingContributionV = Vector3.Zero;
1599 1596