BulletSim: distribute vehicle physical settings to all members of
a linkset. Enables constraint based linksets. Rename some internal variables to clarify whether values world or vehicle relative.TeleportWork
parent
6ad577d32b
commit
0d189165a8
|
@ -589,10 +589,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_vehicleMass = ControllingPrim.TotalMass;
|
m_vehicleMass = ControllingPrim.TotalMass;
|
||||||
|
|
||||||
// Friction affects are handled by this vehicle code
|
// Friction affects are handled by this vehicle code
|
||||||
m_physicsScene.PE.SetFriction(ControllingPrim.PhysBody, BSParam.VehicleFriction);
|
// m_physicsScene.PE.SetFriction(ControllingPrim.PhysBody, BSParam.VehicleFriction);
|
||||||
m_physicsScene.PE.SetRestitution(ControllingPrim.PhysBody, BSParam.VehicleRestitution);
|
// m_physicsScene.PE.SetRestitution(ControllingPrim.PhysBody, BSParam.VehicleRestitution);
|
||||||
// ControllingPrim.Linkset.SetPhysicalFriction(BSParam.VehicleFriction);
|
ControllingPrim.Linkset.SetPhysicalFriction(BSParam.VehicleFriction);
|
||||||
// ControllingPrim.Linkset.SetPhysicalRestitution(BSParam.VehicleRestitution);
|
ControllingPrim.Linkset.SetPhysicalRestitution(BSParam.VehicleRestitution);
|
||||||
|
|
||||||
// Moderate angular movement introduced by Bullet.
|
// Moderate angular movement introduced by Bullet.
|
||||||
// TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
|
// TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
|
||||||
|
@ -602,21 +602,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_physicsScene.PE.SetAngularFactorV(ControllingPrim.PhysBody, BSParam.VehicleAngularFactor);
|
m_physicsScene.PE.SetAngularFactorV(ControllingPrim.PhysBody, BSParam.VehicleAngularFactor);
|
||||||
|
|
||||||
// Vehicles report collision events so we know when it's on the ground
|
// Vehicles report collision events so we know when it's on the ground
|
||||||
m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
// m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
||||||
// ControllingPrim.Linkset.SetPhysicalCollisionFlags(CollisionFlags.BS_VEHICLE_COLLISIONS);
|
ControllingPrim.Linkset.AddToPhysicalCollisionFlags(CollisionFlags.BS_VEHICLE_COLLISIONS);
|
||||||
|
|
||||||
Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass);
|
// Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass);
|
||||||
ControllingPrim.Inertia = inertia * BSParam.VehicleInertiaFactor;
|
// ControllingPrim.Inertia = inertia * BSParam.VehicleInertiaFactor;
|
||||||
m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia);
|
// m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia);
|
||||||
m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody);
|
// m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody);
|
||||||
// ControllingPrim.Linkset.ComputeLocalInertia(BSParam.VehicleInertiaFactor);
|
ControllingPrim.Linkset.ComputeAndSetLocalInertia(BSParam.VehicleInertiaFactor, m_vehicleMass);
|
||||||
|
|
||||||
// Set the gravity for the vehicle depending on the buoyancy
|
// Set the gravity for the vehicle depending on the buoyancy
|
||||||
// TODO: what should be done if prim and vehicle buoyancy differ?
|
// TODO: what should be done if prim and vehicle buoyancy differ?
|
||||||
m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy);
|
m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy);
|
||||||
// The actual vehicle gravity is set to zero in Bullet so we can do all the application of same.
|
// The actual vehicle gravity is set to zero in Bullet so we can do all the application of same.
|
||||||
m_physicsScene.PE.SetGravity(ControllingPrim.PhysBody, Vector3.Zero);
|
// m_physicsScene.PE.SetGravity(ControllingPrim.PhysBody, Vector3.Zero);
|
||||||
// ControllingPrim.Linkset.SetPhysicalGravity(Vector3.Zero);
|
ControllingPrim.Linkset.SetPhysicalGravity(Vector3.Zero);
|
||||||
|
|
||||||
VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}",
|
VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}",
|
||||||
ControllingPrim.LocalID, m_vehicleMass, ControllingPrim.Inertia, m_VehicleGravity,
|
ControllingPrim.LocalID, m_vehicleMass, ControllingPrim.Inertia, m_VehicleGravity,
|
||||||
|
@ -1121,7 +1121,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
m_VhoverTargetHeight = m_VhoverHeight;
|
m_VhoverTargetHeight = m_VhoverHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
|
if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
|
||||||
{
|
{
|
||||||
// If body is already heigher, use its height as target height
|
// If body is already heigher, use its height as target height
|
||||||
|
@ -1170,7 +1169,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight,
|
m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight,
|
||||||
verticalError, verticalCorrection);
|
verticalError, verticalCorrection);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1357,6 +1355,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
private void ComputeAngularTurning(float pTimestep)
|
private void ComputeAngularTurning(float pTimestep)
|
||||||
{
|
{
|
||||||
// The user wants this many radians per second angular change?
|
// The user wants this many radians per second angular change?
|
||||||
|
Vector3 origVehicleRotationalVelocity = VehicleRotationalVelocity; // DEBUG DEBUG
|
||||||
Vector3 currentAngularV = VehicleRotationalVelocity * Quaternion.Inverse(VehicleOrientation);
|
Vector3 currentAngularV = VehicleRotationalVelocity * Quaternion.Inverse(VehicleOrientation);
|
||||||
Vector3 angularMotorContributionV = m_angularMotor.Step(pTimestep, currentAngularV);
|
Vector3 angularMotorContributionV = m_angularMotor.Step(pTimestep, currentAngularV);
|
||||||
|
|
||||||
|
@ -1369,20 +1368,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// TODO: This is here because this is where ODE put it but documentation says it
|
// TODO: This is here because this is where ODE put it but documentation says it
|
||||||
// is a linear effect. Where should this check go?
|
// is a linear effect. Where should this check go?
|
||||||
//if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
|
//if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
|
||||||
// {
|
// {
|
||||||
// angularMotorContributionV.X = 0f;
|
// angularMotorContributionV.X = 0f;
|
||||||
// angularMotorContributionV.Y = 0f;
|
// angularMotorContributionV.Y = 0f;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// Reduce any velocity by friction.
|
// Reduce any velocity by friction.
|
||||||
Vector3 frictionFactorW = ComputeFrictionFactor(m_angularFrictionTimescale, pTimestep);
|
Vector3 frictionFactorW = ComputeFrictionFactor(m_angularFrictionTimescale, pTimestep);
|
||||||
angularMotorContributionV -= (currentAngularV * frictionFactorW);
|
angularMotorContributionV -= (currentAngularV * frictionFactorW);
|
||||||
|
|
||||||
VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation;
|
Vector3 angularMotorContributionW = angularMotorContributionV * VehicleOrientation;
|
||||||
|
VehicleRotationalVelocity += angularMotorContributionW;
|
||||||
|
|
||||||
|
VDetailLog("{0}, MoveAngular,angularTurning,curAngVelV={1},origVehRotVel={2},vehRotVel={3},frictFact={4}, angContribV={5},angContribW={6}",
|
||||||
|
ControllingPrim.LocalID, currentAngularV, origVehicleRotationalVelocity, VehicleRotationalVelocity, frictionFactorW, angularMotorContributionV, angularMotorContributionW);
|
||||||
VDetailLog("{0}, MoveAngular,angularTurning,angContribV={1}", ControllingPrim.LocalID, angularMotorContributionV);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial:
|
// From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial:
|
||||||
|
@ -1409,7 +1408,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
|
||||||
// Flipping what was originally a timescale into a speed variable and then multiplying it by 2
|
// 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.
|
// since only computing half the distance between the angles.
|
||||||
float VerticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f;
|
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
|
// 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.
|
// this makes for a smoother adjustment and less fighting between the various forces.
|
||||||
|
@ -1419,12 +1418,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
|
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
|
// 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;
|
Vector3 vertContributionV = torqueVector * verticalAttractionSpeed * verticalAttractionSpeed;
|
||||||
|
|
||||||
VehicleRotationalVelocity += vertContributionV;
|
VehicleRotationalVelocity += vertContributionV;
|
||||||
|
|
||||||
VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},PredictedUp={2},torqueVector={3},contrib={4}",
|
VDetailLog("{0}, MoveAngular,verticalAttraction,vertAttrSpeed={1},upAxis={2},PredictedUp={3},torqueVector={4},contrib={5}",
|
||||||
ControllingPrim.LocalID,
|
ControllingPrim.LocalID,
|
||||||
|
verticalAttractionSpeed,
|
||||||
vehicleUpAxis,
|
vehicleUpAxis,
|
||||||
predictedUp,
|
predictedUp,
|
||||||
torqueVector,
|
torqueVector,
|
||||||
|
@ -1437,37 +1437,38 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no
|
// 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
|
// Create a rotation that is only the vehicle's rotation around Z
|
||||||
Vector3 currentEuler = Vector3.Zero;
|
Vector3 currentEulerW = Vector3.Zero;
|
||||||
VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z);
|
VehicleOrientation.GetEulerAngles(out currentEulerW.X, out currentEulerW.Y, out currentEulerW.Z);
|
||||||
Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z);
|
Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEulerW.Z);
|
||||||
|
|
||||||
// Create the axis that is perpendicular to the up vector and the rotated up vector.
|
// 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);
|
Vector3 differenceAxisW = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation);
|
||||||
// Compute the angle between those to vectors.
|
// Compute the angle between those to vectors.
|
||||||
double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation)));
|
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
|
// '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.
|
// Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied.
|
||||||
// TODO: add 'efficiency'.
|
// TODO: add 'efficiency'.
|
||||||
differenceAngle /= m_verticalAttractionTimescale;
|
// differenceAngle /= m_verticalAttractionTimescale;
|
||||||
|
|
||||||
// Create the quaterian representing the correction angle
|
// Create the quaterian representing the correction angle
|
||||||
Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle);
|
Quaternion correctionRotationW = Quaternion.CreateFromAxisAngle(differenceAxisW, (float)differenceAngle);
|
||||||
|
|
||||||
// Turn that quaternion into Euler values to make it into velocities to apply.
|
// Turn that quaternion into Euler values to make it into velocities to apply.
|
||||||
Vector3 vertContributionV = Vector3.Zero;
|
Vector3 vertContributionW = Vector3.Zero;
|
||||||
correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z);
|
correctionRotationW.GetEulerAngles(out vertContributionW.X, out vertContributionW.Y, out vertContributionW.Z);
|
||||||
vertContributionV *= -1f;
|
vertContributionW *= -1f;
|
||||||
|
vertContributionW /= m_verticalAttractionTimescale;
|
||||||
|
|
||||||
VehicleRotationalVelocity += vertContributionV;
|
VehicleRotationalVelocity += vertContributionW;
|
||||||
|
|
||||||
VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},diffAxis={2},diffAng={3},corrRot={4},contrib={5}",
|
VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},diffAxis={2},diffAng={3},corrRot={4},contrib={5}",
|
||||||
ControllingPrim.LocalID,
|
ControllingPrim.LocalID,
|
||||||
vehicleUpAxis,
|
vehicleUpAxis,
|
||||||
differenceAxis,
|
differenceAxisW,
|
||||||
differenceAngle,
|
differenceAngle,
|
||||||
correctionRotation,
|
correctionRotationW,
|
||||||
vertContributionV);
|
vertContributionW);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
|
|
|
@ -309,16 +309,18 @@ public abstract class BSLinkset
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public virtual void ComputeLocalInertia(OMV.Vector3 inertiaFactor)
|
public virtual void ComputeAndSetLocalInertia(OMV.Vector3 inertiaFactor, float linksetMass)
|
||||||
{
|
{
|
||||||
ForEachMember((member) =>
|
ForEachMember((member) =>
|
||||||
{
|
{
|
||||||
if (member.PhysBody.HasPhysicalBody)
|
if (member.PhysBody.HasPhysicalBody)
|
||||||
{
|
{
|
||||||
OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(member.PhysShape.physShapeInfo, member.Mass);
|
OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(member.PhysShape.physShapeInfo, linksetMass);
|
||||||
member.Inertia = inertia * inertiaFactor;
|
member.Inertia = inertia * inertiaFactor;
|
||||||
m_physicsScene.PE.SetMassProps(member.PhysBody, member.Mass, member.Inertia);
|
m_physicsScene.PE.SetMassProps(member.PhysBody, linksetMass, member.Inertia);
|
||||||
m_physicsScene.PE.UpdateInertiaTensor(member.PhysBody);
|
m_physicsScene.PE.UpdateInertiaTensor(member.PhysBody);
|
||||||
|
DetailLog("{0},BSLinkset.ComputeAndSetLocalInertia,m.mass={1}, inertia={2}", member.LocalID, linksetMass, member.Inertia);
|
||||||
|
|
||||||
}
|
}
|
||||||
return false; // 'false' says to continue looping
|
return false; // 'false' says to continue looping
|
||||||
}
|
}
|
||||||
|
@ -334,6 +336,16 @@ public abstract class BSLinkset
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
public virtual void AddToPhysicalCollisionFlags(CollisionFlags collFlags)
|
||||||
|
{
|
||||||
|
ForEachMember((member) =>
|
||||||
|
{
|
||||||
|
if (member.PhysBody.HasPhysicalBody)
|
||||||
|
m_physicsScene.PE.AddToCollisionFlags(member.PhysBody, collFlags);
|
||||||
|
return false; // 'false' says to continue looping
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
public virtual void RemoveFromPhysicalCollisionFlags(CollisionFlags collFlags)
|
public virtual void RemoveFromPhysicalCollisionFlags(CollisionFlags collFlags)
|
||||||
{
|
{
|
||||||
ForEachMember((member) =>
|
ForEachMember((member) =>
|
||||||
|
|
|
@ -61,11 +61,11 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
if (LinksetRoot.PhysBody.HasPhysicalBody)
|
if (LinksetRoot.PhysBody.HasPhysicalBody)
|
||||||
m_physicsScene.PE.SetGravity(LinksetRoot.PhysBody, gravity);
|
m_physicsScene.PE.SetGravity(LinksetRoot.PhysBody, gravity);
|
||||||
}
|
}
|
||||||
public override void ComputeLocalInertia(OMV.Vector3 inertiaFactor)
|
public override void ComputeAndSetLocalInertia(OMV.Vector3 inertiaFactor, float linksetMass)
|
||||||
{
|
{
|
||||||
OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(LinksetRoot.PhysShape.physShapeInfo, LinksetRoot.Mass);
|
OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(LinksetRoot.PhysShape.physShapeInfo, linksetMass);
|
||||||
LinksetRoot.Inertia = inertia * inertiaFactor;
|
LinksetRoot.Inertia = inertia * inertiaFactor;
|
||||||
m_physicsScene.PE.SetMassProps(LinksetRoot.PhysBody, LinksetRoot.Mass, LinksetRoot.Inertia);
|
m_physicsScene.PE.SetMassProps(LinksetRoot.PhysBody, linksetMass, LinksetRoot.Inertia);
|
||||||
m_physicsScene.PE.UpdateInertiaTensor(LinksetRoot.PhysBody);
|
m_physicsScene.PE.UpdateInertiaTensor(LinksetRoot.PhysBody);
|
||||||
}
|
}
|
||||||
public override void SetPhysicalCollisionFlags(CollisionFlags collFlags)
|
public override void SetPhysicalCollisionFlags(CollisionFlags collFlags)
|
||||||
|
@ -73,6 +73,11 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
if (LinksetRoot.PhysBody.HasPhysicalBody)
|
if (LinksetRoot.PhysBody.HasPhysicalBody)
|
||||||
m_physicsScene.PE.SetCollisionFlags(LinksetRoot.PhysBody, collFlags);
|
m_physicsScene.PE.SetCollisionFlags(LinksetRoot.PhysBody, collFlags);
|
||||||
}
|
}
|
||||||
|
public override void AddToPhysicalCollisionFlags(CollisionFlags collFlags)
|
||||||
|
{
|
||||||
|
if (LinksetRoot.PhysBody.HasPhysicalBody)
|
||||||
|
m_physicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, collFlags);
|
||||||
|
}
|
||||||
public override void RemoveFromPhysicalCollisionFlags(CollisionFlags collFlags)
|
public override void RemoveFromPhysicalCollisionFlags(CollisionFlags collFlags)
|
||||||
{
|
{
|
||||||
if (LinksetRoot.PhysBody.HasPhysicalBody)
|
if (LinksetRoot.PhysBody.HasPhysicalBody)
|
||||||
|
|
Loading…
Reference in New Issue