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).cpu-performance
parent
76b2b20f7e
commit
fad4241e4e
|
@ -125,33 +125,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
static readonly float PIOverFour = ((float)Math.PI) / 4f;
|
||||
static readonly float PIOverTwo = ((float)Math.PI) / 2f;
|
||||
|
||||
// For debugging, flags to turn on and off individual corrections.
|
||||
public bool enableAngularVerticalAttraction;
|
||||
public bool enableAngularDeflection;
|
||||
public bool enableAngularBanking;
|
||||
|
||||
public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName)
|
||||
: base(myScene, myPrim, actorName)
|
||||
{
|
||||
ControllingPrim = myPrim;
|
||||
Type = Vehicle.TYPE_NONE;
|
||||
m_haveRegisteredForSceneEvents = false;
|
||||
SetupVehicleDebugging();
|
||||
}
|
||||
|
||||
// Stopgap debugging enablement. Allows source level debugging but still checking
|
||||
// in changes by making enablement of debugging flags from INI file.
|
||||
public void SetupVehicleDebugging()
|
||||
{
|
||||
enableAngularVerticalAttraction = true;
|
||||
enableAngularDeflection = true;
|
||||
enableAngularBanking = true;
|
||||
if (BSParam.VehicleDebuggingEnable)
|
||||
{
|
||||
enableAngularVerticalAttraction = true;
|
||||
enableAngularDeflection = false;
|
||||
enableAngularBanking = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Return 'true' if this vehicle is doing vehicle things
|
||||
|
@ -556,10 +535,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
}
|
||||
|
||||
m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, m_linearMotorDecayTimescale, 1f);
|
||||
m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||
// m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||
|
||||
m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, m_angularMotorDecayTimescale, 1f);
|
||||
m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||
// m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||
|
||||
/* Not implemented
|
||||
m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale,
|
||||
|
@ -1393,116 +1372,134 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
{
|
||||
|
||||
// If vertical attaction timescale is reasonable
|
||||
if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
|
||||
if (BSParam.VehicleEnableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
|
||||
{
|
||||
//Another formula to try got from :
|
||||
//http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html
|
||||
|
||||
Vector3 VehicleUpAxis = Vector3.UnitZ * VehicleOrientation;
|
||||
|
||||
// Flipping what was originally a timescale into a speed variable and then multiplying it by 2
|
||||
// since only computing half the distance between the angles.
|
||||
float VerticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f;
|
||||
|
||||
// Make a prediction of where the up axis will be when this is applied rather then where it is now as
|
||||
// this makes for a smoother adjustment and less fighting between the various forces.
|
||||
Vector3 predictedUp = VehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
|
||||
|
||||
// This is only half the distance to the target so it will take 2 seconds to complete the turn.
|
||||
Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
|
||||
|
||||
// Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared
|
||||
Vector3 vertContributionV = torqueVector * VerticalAttractionSpeed * VerticalAttractionSpeed;
|
||||
|
||||
VehicleRotationalVelocity += vertContributionV;
|
||||
|
||||
VDetailLog("{0}, MoveAngular,verticalAttraction,UpAxis={1},PredictedUp={2},torqueVector={3},contrib={4}",
|
||||
ControllingPrim.LocalID,
|
||||
VehicleUpAxis,
|
||||
predictedUp,
|
||||
torqueVector,
|
||||
vertContributionV);
|
||||
//=====================================================================
|
||||
/*
|
||||
// Possible solution derived from a discussion at:
|
||||
// http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no
|
||||
|
||||
// Create a rotation that is only the vehicle's rotation around Z
|
||||
Vector3 currentEuler = Vector3.Zero;
|
||||
VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z);
|
||||
Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z);
|
||||
|
||||
// Create the axis that is perpendicular to the up vector and the rotated up vector.
|
||||
Vector3 differenceAxis = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation);
|
||||
// Compute the angle between those to vectors.
|
||||
double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation)));
|
||||
// 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical
|
||||
|
||||
// Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied.
|
||||
// TODO: add 'efficiency'.
|
||||
differenceAngle /= m_verticalAttractionTimescale;
|
||||
|
||||
// Create the quaterian representing the correction angle
|
||||
Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle);
|
||||
|
||||
// Turn that quaternion into Euler values to make it into velocities to apply.
|
||||
Vector3 vertContributionV = Vector3.Zero;
|
||||
correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z);
|
||||
vertContributionV *= -1f;
|
||||
|
||||
VehicleRotationalVelocity += vertContributionV;
|
||||
|
||||
VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}",
|
||||
ControllingPrim.LocalID,
|
||||
differenceAxis,
|
||||
differenceAngle,
|
||||
correctionRotation,
|
||||
vertContributionV);
|
||||
*/
|
||||
|
||||
// ===================================================================
|
||||
/*
|
||||
Vector3 vertContributionV = Vector3.Zero;
|
||||
Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG
|
||||
|
||||
// Take a vector pointing up and convert it from world to vehicle relative coords.
|
||||
Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation);
|
||||
|
||||
// If vertical attraction correction is needed, the vector that was pointing up (UnitZ)
|
||||
// is now:
|
||||
// leaning to one side: rotated around the X axis with the Y value going
|
||||
// from zero (nearly straight up) to one (completely to the side)) or
|
||||
// leaning front-to-back: rotated around the Y axis with the value of X being between
|
||||
// zero and one.
|
||||
// The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees.
|
||||
|
||||
// Y error means needed rotation around X axis and visa versa.
|
||||
// Since the error goes from zero to one, the asin is the corresponding angle.
|
||||
vertContributionV.X = (float)Math.Asin(verticalError.Y);
|
||||
// (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.)
|
||||
vertContributionV.Y = -(float)Math.Asin(verticalError.X);
|
||||
|
||||
// If verticalError.Z is negative, the vehicle is upside down. Add additional push.
|
||||
if (verticalError.Z < 0f)
|
||||
Vector3 vehicleUpAxis = Vector3.UnitZ * VehicleOrientation;
|
||||
switch (BSParam.VehicleAngularVerticalAttractionAlgorithm)
|
||||
{
|
||||
vertContributionV.X += Math.Sign(vertContributionV.X) * PIOverFour;
|
||||
// vertContribution.Y -= PIOverFour;
|
||||
case 0:
|
||||
{
|
||||
//Another formula to try got from :
|
||||
//http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html
|
||||
|
||||
// Flipping what was originally a timescale into a speed variable and then multiplying it by 2
|
||||
// since only computing half the distance between the angles.
|
||||
float VerticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f;
|
||||
|
||||
// Make a prediction of where the up axis will be when this is applied rather then where it is now as
|
||||
// this makes for a smoother adjustment and less fighting between the various forces.
|
||||
Vector3 predictedUp = vehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
|
||||
|
||||
// This is only half the distance to the target so it will take 2 seconds to complete the turn.
|
||||
Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
|
||||
|
||||
// Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared
|
||||
Vector3 vertContributionV = torqueVector * VerticalAttractionSpeed * VerticalAttractionSpeed;
|
||||
|
||||
VehicleRotationalVelocity += vertContributionV;
|
||||
|
||||
VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},PredictedUp={2},torqueVector={3},contrib={4}",
|
||||
ControllingPrim.LocalID,
|
||||
vehicleUpAxis,
|
||||
predictedUp,
|
||||
torqueVector,
|
||||
vertContributionV);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// Possible solution derived from a discussion at:
|
||||
// http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no
|
||||
|
||||
// Create a rotation that is only the vehicle's rotation around Z
|
||||
Vector3 currentEuler = Vector3.Zero;
|
||||
VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z);
|
||||
Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z);
|
||||
|
||||
// Create the axis that is perpendicular to the up vector and the rotated up vector.
|
||||
Vector3 differenceAxis = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation);
|
||||
// Compute the angle between those to vectors.
|
||||
double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation)));
|
||||
// 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical
|
||||
|
||||
// Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied.
|
||||
// TODO: add 'efficiency'.
|
||||
differenceAngle /= m_verticalAttractionTimescale;
|
||||
|
||||
// Create the quaterian representing the correction angle
|
||||
Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle);
|
||||
|
||||
// Turn that quaternion into Euler values to make it into velocities to apply.
|
||||
Vector3 vertContributionV = Vector3.Zero;
|
||||
correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z);
|
||||
vertContributionV *= -1f;
|
||||
|
||||
VehicleRotationalVelocity += vertContributionV;
|
||||
|
||||
VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},diffAxis={2},diffAng={3},corrRot={4},contrib={5}",
|
||||
ControllingPrim.LocalID,
|
||||
vehicleUpAxis,
|
||||
differenceAxis,
|
||||
differenceAngle,
|
||||
correctionRotation,
|
||||
vertContributionV);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
Vector3 vertContributionV = Vector3.Zero;
|
||||
Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG
|
||||
|
||||
// Take a vector pointing up and convert it from world to vehicle relative coords.
|
||||
Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation);
|
||||
|
||||
// If vertical attraction correction is needed, the vector that was pointing up (UnitZ)
|
||||
// is now:
|
||||
// leaning to one side: rotated around the X axis with the Y value going
|
||||
// from zero (nearly straight up) to one (completely to the side)) or
|
||||
// leaning front-to-back: rotated around the Y axis with the value of X being between
|
||||
// zero and one.
|
||||
// The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees.
|
||||
|
||||
// Y error means needed rotation around X axis and visa versa.
|
||||
// Since the error goes from zero to one, the asin is the corresponding angle.
|
||||
vertContributionV.X = (float)Math.Asin(verticalError.Y);
|
||||
// (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.)
|
||||
vertContributionV.Y = -(float)Math.Asin(verticalError.X);
|
||||
|
||||
// If verticalError.Z is negative, the vehicle is upside down. Add additional push.
|
||||
if (verticalError.Z < 0f)
|
||||
{
|
||||
vertContributionV.X += Math.Sign(vertContributionV.X) * PIOverFour;
|
||||
// vertContribution.Y -= PIOverFour;
|
||||
}
|
||||
|
||||
// 'vertContrbution' is now the necessary angular correction to correct tilt in one second.
|
||||
// Correction happens over a number of seconds.
|
||||
Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG
|
||||
|
||||
// The correction happens over the user's time period
|
||||
vertContributionV /= m_verticalAttractionTimescale;
|
||||
|
||||
// Rotate the vehicle rotation to the world coordinates.
|
||||
VehicleRotationalVelocity += (vertContributionV * VehicleOrientation);
|
||||
|
||||
VDetailLog("{0}, MoveAngular,verticalAttraction,,upAxis={1},origRotVW={2},vertError={3},unscaledV={4},eff={5},ts={6},vertContribV={7}",
|
||||
ControllingPrim.LocalID,
|
||||
vehicleUpAxis,
|
||||
origRotVelW,
|
||||
verticalError,
|
||||
unscaledContribVerticalErrorV,
|
||||
m_verticalAttractionEfficiency,
|
||||
m_verticalAttractionTimescale,
|
||||
vertContributionV);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 'vertContrbution' is now the necessary angular correction to correct tilt in one second.
|
||||
// Correction happens over a number of seconds.
|
||||
Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG
|
||||
|
||||
// The correction happens over the user's time period
|
||||
vertContributionV /= m_verticalAttractionTimescale;
|
||||
|
||||
// Rotate the vehicle rotation to the world coordinates.
|
||||
VehicleRotationalVelocity += (vertContributionV * VehicleOrientation);
|
||||
|
||||
VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}",
|
||||
Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV,
|
||||
m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1514,7 +1511,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
public void ComputeAngularDeflection()
|
||||
{
|
||||
|
||||
if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
|
||||
if (BSParam.VehicleEnableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
|
||||
{
|
||||
Vector3 deflectContributionV = Vector3.Zero;
|
||||
|
||||
|
@ -1593,7 +1590,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// make a sluggish vehicle by giving it a timescale of several seconds.
|
||||
public void ComputeAngularBanking()
|
||||
{
|
||||
if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
|
||||
if (BSParam.VehicleEnableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
|
||||
{
|
||||
Vector3 bankingContributionV = Vector3.Zero;
|
||||
|
||||
|
|
|
@ -155,7 +155,10 @@ public static class BSParam
|
|||
public static Vector3 VehicleInertiaFactor { get; private set; }
|
||||
public static float VehicleGroundGravityFudge { get; private set; }
|
||||
public static float VehicleAngularBankingTimescaleFudge { get; private set; }
|
||||
public static bool VehicleDebuggingEnable { get; private set; }
|
||||
public static bool VehicleEnableAngularVerticalAttraction { get; private set; }
|
||||
public static int VehicleAngularVerticalAttractionAlgorithm { get; private set; }
|
||||
public static bool VehicleEnableAngularDeflection { get; private set; }
|
||||
public static bool VehicleEnableAngularBanking { get; private set; }
|
||||
|
||||
// Convex Hulls
|
||||
public static int CSHullMaxDepthSplit { get; private set; }
|
||||
|
@ -606,8 +609,14 @@ public static class BSParam
|
|||
0.2f ),
|
||||
new ParameterDefn<float>("VehicleAngularBankingTimescaleFudge", "Factor to multiple angular banking timescale. Tune to increase realism.",
|
||||
60.0f ),
|
||||
new ParameterDefn<bool>("VehicleDebuggingEnable", "Turn on/off vehicle debugging",
|
||||
false ),
|
||||
new ParameterDefn<bool>("VehicleEnableAngularVerticalAttraction", "Turn on/off vehicle angular vertical attraction effect",
|
||||
true ),
|
||||
new ParameterDefn<int>("VehicleAngularVerticalAttractionAlgorithm", "Select vertical attraction algo. You need to look at the source.",
|
||||
1 ),
|
||||
new ParameterDefn<bool>("VehicleEnableAngularDeflection", "Turn on/off vehicle angular deflection effect",
|
||||
true ),
|
||||
new ParameterDefn<bool>("VehicleEnableAngularBanking", "Turn on/off vehicle angular banking effect",
|
||||
true ),
|
||||
|
||||
new ParameterDefn<float>("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
|
||||
0f,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
@ -648,7 +648,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
simTime = Util.EnvironmentTickCountSubtract(beforeTime);
|
||||
if (PhysicsLogging.Enabled)
|
||||
{
|
||||
DetailLog("{0},DoPhysicsStep,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}",
|
||||
DetailLog("{0},DoPhysicsStep,complete,frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}",
|
||||
DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps,
|
||||
updatedEntityCount, collidersCount, ObjectsWithCollisions.Count);
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@ public class BasicVehicles : OpenSimTestCase
|
|||
public void Init()
|
||||
{
|
||||
Dictionary<string, string> engineParams = new Dictionary<string, string>();
|
||||
engineParams.Add("VehicleEnableAngularVerticalAttraction", "true");
|
||||
engineParams.Add("VehicleAngularVerticalAttractionAlgorithm", "1");
|
||||
PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams);
|
||||
|
||||
PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere();
|
||||
|
@ -119,7 +121,7 @@ public class BasicVehicles : OpenSimTestCase
|
|||
{
|
||||
vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency);
|
||||
vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale);
|
||||
vehicleActor.enableAngularVerticalAttraction = true;
|
||||
// vehicleActor.enableAngularVerticalAttraction = true;
|
||||
|
||||
TestVehicle.IsPhysical = true;
|
||||
PhysicsScene.ProcessTaints();
|
||||
|
|
Loading…
Reference in New Issue