bool PositionSanityCheck(bool inTaintTime)
{
bool ret = false;
// We don't care where non-physical items are placed
if (!IsPhysicallyActive)
return ret;
if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
{
// The physical object is out of the known/simulated area.
// Upper levels of code will handle the transition to other areas so, for
// the time, we just ignore the position.
return ret;
}
float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
OMV.Vector3 upForce = OMV.Vector3.Zero;
float approxSize = Math.Max(Size.X, Math.Max(Size.Y, Size.Z));
if ((RawPosition.Z + approxSize / 2f) < terrainHeight)
{
DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, RawPosition,
terrainHeight);
float targetHeight = terrainHeight + (Size.Z / 2f);
// If the object is below ground it just has to be moved up because pushing will
// not get it through the terrain
//_position = new OMV.Vector3(_position.X, _position.Y, targetHeight);
_position.Z = targetHeight;
if (inTaintTime)
{
ForcePosition = _position;
}
// If we are throwing the object around, zero its other forces
ZeroMotion(inTaintTime);
ret = true;
}
if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
{
float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position);
// TODO: a floating motor so object will bob in the water
if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f)
{
// Upforce proportional to the distance away from the water. Correct the error in 1 sec.
upForce.Z = (waterHeight - RawPosition.Z) * 1f;
// Apply upforce and overcome gravity.
OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity;
DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}",
LocalID, _position, upForce, correctionForce);
AddForce(correctionForce, false, inTaintTime);
ret = true;
}
}
return ret;
}