using UnityEngine; using Unity.Jobs; using Unity.Collections; using System.Collections; using System.Collections.Generic; namespace Obi { public interface IComputeConstraintsImpl : IConstraints { void Initialize(float stepTime, float substepTime, int steps, float timeLeft); void Project(float stepTime, float substepTime, int substeps, float timeLeft); void Dispose(); IConstraintsBatchImpl CreateConstraintsBatch(); void RemoveBatch(IConstraintsBatchImpl batch); } public abstract class ComputeConstraintsImpl : IComputeConstraintsImpl where T : ComputeConstraintsBatchImpl { protected ComputeSolverImpl m_Solver; public List batches = new List(); protected Oni.ConstraintType m_ConstraintType; public Oni.ConstraintType constraintType { get { return m_ConstraintType; } } public ISolverImpl solver { get { return m_Solver; } } public ComputeConstraintsImpl(ComputeSolverImpl solver, Oni.ConstraintType constraintType) { this.m_ConstraintType = constraintType; this.m_Solver = solver; } public virtual void Dispose() { } public abstract IConstraintsBatchImpl CreateConstraintsBatch(); public abstract void RemoveBatch(IConstraintsBatchImpl batch); public virtual int GetConstraintCount() { int count = 0; if (batches == null) return count; foreach (T batch in batches) if (batch != null) count += batch.GetConstraintCount(); return count; } public void Initialize(float stepTime, float substepTime, int steps, float timeLeft) { // initialize all batches in parallel: if (batches.Count > 0) { for (int i = 0; i < batches.Count; ++i) if (batches[i].enabled) batches[i].Initialize(stepTime, substepTime, steps, timeLeft); } } public void Project(float stepTime, float substepTime, int substeps, float timeLeft) { UnityEngine.Profiling.Profiler.BeginSample("Project"); var parameters = m_Solver.abstraction.GetConstraintParameters(m_ConstraintType); switch(parameters.evaluationOrder) { case Oni.ConstraintParameters.EvaluationOrder.Sequential: EvaluateSequential(stepTime, substepTime, substeps, timeLeft); break; case Oni.ConstraintParameters.EvaluationOrder.Parallel: EvaluateParallel(stepTime, substepTime, substeps, timeLeft); break; } UnityEngine.Profiling.Profiler.EndSample(); } protected virtual void EvaluateSequential(float stepTime, float substepTime, int substeps, float timeLeft) { // evaluate and apply all batches: for (int i = 0; i < batches.Count; ++i) { if (batches[i].enabled) { batches[i].Evaluate(stepTime, substepTime, substeps, timeLeft); batches[i].Apply(substepTime); } } } protected virtual void EvaluateParallel(float stepTime, float substepTime, int substeps, float timeLeft) { // evaluate all batches: for (int i = 0; i < batches.Count; ++i) if (batches[i].enabled) { batches[i].Evaluate(stepTime, substepTime, substeps, timeLeft); } // then apply them: for (int i = 0; i < batches.Count; ++i) if (batches[i].enabled) { batches[i].Apply(substepTime); } } } }