using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Azimuth;
namespace Lodestone
{
///
/// Basically all bodies which are directly or indirectly constrained
/// to each other (eg: touching each other) form an island.
///
/// The purpose of an island is to allow all simultaneous collisions to be
/// solved jointly, efficiently, and without jitter.
///
public class Island
{
public IList Constraints { get; protected set; }
public IList Bodies { get; protected set; }
///
/// The center of mass of the island. Barring external forces, this should obey a ballistic trajectory.
///
public Vector CenterOfMass { get; protected set; }
private ulong _currentTimeUnits = 0;
private Scalar _currentTimeFraction = 0;
private void UpdateSimulationTime(Scalar deltaTime)
{
Scalar units = Math.Floor(deltaTime);
// This should be safe except for very very very large deltaTime where 1.0 is not representable in the epsilon.
Scalar fraction = deltaTime - units;
_currentTimeFraction += fraction;
while (_currentTimeFraction.Value >= 1.0) // we want an exact check
{
_currentTimeFraction--;
units++;
}
// This should always be safe
_currentTimeUnits += (ulong)units;
}
///
/// Steps the motion of the island forward by deltaTime.
///
public void Step(Scalar deltaTime, Solvers.Solver solver, Scalar stepSize)
{
if (deltaTime < 0)
{
throw new Exception("Negative timesteps are not presently supported.");
}
if (deltaTime == 0)
{
throw new Exception("Trying to step the island with a timestep that is " +
"indistinguishable from 0.");
}
UpdateSimulationTime(deltaTime);
ConstrainAndIntegrateAcceleraton(solver);
//Solver.SolveAndIntegrateIsland(this,
}
public void ConstrainAndIntegrateAcceleraton(Solvers.Solver solver)
{
// Flush all the accumulated forces to accumulated accelerations.
IList deltaLinearVelocity;
IList deltaAngularVelocity;
// Now solve for delta velocities
solver.SolveIsland(
Bodies, Constraints, Lodestone.Solvers.SolverLevel.ACCELERATION,
out deltaLinearVelocity, out deltaAngularVelocity);
// Now update
for (int i = 0; i < Bodies.Count; ++i)
{
//Bodies[i].ResetAccumulatedForcesAndTorques();
Bodies[i].Motion.Velocity += deltaLinearVelocity[i];
Bodies[i].Motion.AngularVelocity += deltaAngularVelocity[i];
}
}
public void ConstrainVelocity(Scalar deltaTime,
IList deltaLinearVelocity,
IList deltaAngularVelocity,
out IList newLinearVelocity,
out IList newAngularVelocity)
{
newLinearVelocity = new List(deltaLinearVelocity.Count);
newAngularVelocity = new List(deltaAngularVelocity.Count);
}
/////
///// Will split the given island into smaller child islands
///// if it's possible to do so.
/////
//public static IList SplitIslandIfPossible(Island island)
//{
// var childIslands = new List();
// while (island.Collisions.Count > 0)
// {
// List next = new List();
// next.Add(collisions.First());
// collisions.RemoveAt(0);
// for (int i = 0; i < next.Count && collisions.Count > 0; i++)
// {
// for (int x = collisions.Count - 1; x >= 0 && collisions.Count > 0; x--)
// {
// if(next[i].Related(collisions[x]))
// {
// next.Add(collisions[x]);
// collisions.RemoveAt(x);
// }
// }
// }
// islands.Add(next);
// }
// Island[] value = new Island[islands.Count];
// for (int i = 0; i < value.Length; i++)
// {
// value[i] = new Island(islands[i]);
// }
// return value;
//}
///
/// Will solve the constraints in the island.
///
/// NOTE! This is very very slow.
///
//public void SolveIslandConstraints()
//{
// if(Constrain
// //Do collisions here
// //Only changes velocity, not position
// //Directly modifies the bodies
// if (Count < 1)
// {
// return;
// }
// //simple collision
// if (Count == 1)
// {
// CollisionPhysics.SimpleCollision(this);
// }
// else//Multiple collision
// {
// CollisionPhysics.MultipleCollision(this);
// }
//}
internal int GetIndexOfBody(Body body)
{
throw new NotImplementedException();
}
}
}