Code: Select all
protected override void CalculateImpulse(Entity e, float dt, out Vector3 impulse)
{
Vector3 position = Position;
Vector3 entityPosition = e.Position;
float entityHeight = Vector3.Dot(Axis, entityPosition - position + Axis * (Height * 0.5f));
if (entityHeight < 0 || entityHeight > Height)
{
impulse = Vector3.Zero;
}
else
{
Vector3 closestPoint;
Vector3 endpointA = position + Axis * Height * 0.5f;
Vector3 endpointB = position - Axis * Height * 0.5f;
Toolbox.GetClosestPointOnSegmentToPoint(ref endpointA, ref endpointB, ref entityPosition, out closestPoint);
float entityDistanceFromTornado;
Vector3.Distance(ref entityPosition, ref closestPoint, out entityDistanceFromTornado);
//Compute the axis to the
Vector3 posClosest;
float forceMultiplier;
if (entityDistanceFromTornado > Radius)
{
//outside tornado
forceMultiplier = Radius / entityDistanceFromTornado;
posClosest = (closestPoint - entityPosition) / entityDistanceFromTornado;
}
else if (entityDistanceFromTornado > Toolbox.Epsilon)
{
//inside tornado
forceMultiplier = .5f + .5f * entityDistanceFromTornado / Radius;
posClosest = (closestPoint - entityPosition) / entityDistanceFromTornado;
}
else
{
forceMultiplier = .5f;
posClosest = Toolbox.ZeroVector;
}
// Don't need to normalize the direction.
// Axis and posClosest are perpendicular and each normal, so the result is normal.
Vector3 tangentialForceVector;
Vector3 tangentDirection;
if (SpinClockwise)
{
Vector3.Cross(ref Axis, ref posClosest, out tangentDirection);
}
else
{
Vector3.Cross(ref posClosest, ref Axis, out tangentDirection);
}
//Current velocity along the tangent direction.
float dot = Vector3.Dot(e.LinearVelocity, tangentDirection);
//Compute the velocity difference between the current and the maximum
dot = HorizontalWindSpeed - dot;
//Compute the force needed to reach the maximum, but clamp it to the amount of force that the tornado can apply
dot = MathHelper.Clamp(dot * e.Mass, 0, HorizontalForce * dt);
Vector3.Multiply(ref tangentDirection, dot, out tangentialForceVector);
Vector3 inwardForceVector;
dot = Vector3.Dot(e.LinearVelocity, posClosest);
dot = InwardSuctionSpeed - dot;
dot = MathHelper.Clamp(dot * e.Mass, 0, InwardForce * dt);
Vector3.Multiply(ref posClosest, dot, out inwardForceVector);
impulse = forceMultiplier * (tangentialForceVector + inwardForceVector);
}
}
I've tried adjusting the inward suction speed and force but it makes little difference:
Code: Select all
circularWind = new CircularWind(
this,
new BoundingBoxForceFieldShape(new BoundingBox(position - extents, position + extents)),
position,
Vector3.UnitY,
5f,
true,
10f, // Horizontal wind speed
1000f, // Inward suction speed
10f, // Horizontal force
1000f, // Inward force
5f,
space.BroadPhase.QueryAccelerator
);