public void ComputeLinearHover(float pTimestep)
{
// m_VhoverEfficiency: 0=bouncy, 1=totally damped
// m_VhoverTimescale: time to achieve height
if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0 && (m_VhoverHeight > 0) && (m_VhoverTimescale < 300))
{
// We should hover, get the target height
if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
{
m_VhoverTargetHeight = GetWaterLevel(VehiclePosition) + m_VhoverHeight;
}
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
{
m_VhoverTargetHeight = GetTerrainHeight(VehiclePosition) + m_VhoverHeight;
}
if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
{
m_VhoverTargetHeight = m_VhoverHeight;
}
if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
{
// If body is already heigher, use its height as target height
if (VehiclePosition.Z > m_VhoverTargetHeight)
{
m_VhoverTargetHeight = VehiclePosition.Z;
// A 'misfeature' of this flag is that if the vehicle is above it's hover height,
// the vehicle's buoyancy goes away. This is an SL bug that got used by so many
// scripts that it could not be changed.
// So, if above the height, reapply gravity if buoyancy had it turned off.
if (m_VehicleBuoyancy != 0)
{
Vector3 appliedGravity = ControllingPrim.ComputeGravity(ControllingPrim.Buoyancy) * m_vehicleMass;
VehicleAddForce(appliedGravity);
}
}
}
if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
{
if (Math.Abs(VehiclePosition.Z - m_VhoverTargetHeight) > 0.2f)
{
Vector3 pos = VehiclePosition;
pos.Z = m_VhoverTargetHeight;
VehiclePosition = pos;
VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", ControllingPrim.LocalID, pos);
}
}
else
{
// Error is positive if below the target and negative if above.
Vector3 hpos = VehiclePosition;
float verticalError = m_VhoverTargetHeight - hpos.Z;
float verticalCorrection = verticalError / m_VhoverTimescale;
verticalCorrection *= m_VhoverEfficiency;
hpos.Z += verticalCorrection;
VehiclePosition = hpos;
// Since we are hovering, we need to do the opposite of falling -- get rid of world Z
Vector3 vel = VehicleVelocity;
vel.Z = 0f;
VehicleVelocity = vel;
/*
float verticalCorrectionVelocity = verticalError / m_VhoverTimescale;
Vector3 verticalCorrection = new Vector3(0f, 0f, verticalCorrectionVelocity);
verticalCorrection *= m_vehicleMass;
// TODO: implement m_VhoverEfficiency correctly
VehicleAddForceImpulse(verticalCorrection);
*/
VDetailLog(
"{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corr={7}",
ControllingPrim.LocalID, VehiclePosition, m_VhoverEfficiency,
m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight,
verticalError, verticalCorrection);
}
}
}