using UnityEngine; using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace Obi{ /** * Holds information about distance constraints for an actor. */ [Serializable] public class ObiTetherConstraintBatch : ObiConstraintBatch { [HideInInspector] public List tetherIndices = new List(); /**< Tether constraint indices.*/ [HideInInspector] public List maxLengthsScales = new List(); /**< Max distance and scale for each tether.*/ [HideInInspector] public List stiffnesses = new List(); /**< Stiffnesses of distance constraits.*/ int[] solverIndices = new int[0]; public ObiTetherConstraintBatch(bool cooked, bool sharesParticles) : base(cooked,sharesParticles){ } public ObiTetherConstraintBatch(bool cooked, bool sharesParticles, float minYoungModulus, float maxYoungModulus) : base(cooked,sharesParticles,minYoungModulus,maxYoungModulus){ } public override Oni.ConstraintType GetConstraintType(){ return Oni.ConstraintType.Tether; } public override void Clear(){ activeConstraints.Clear(); tetherIndices.Clear(); maxLengthsScales.Clear(); stiffnesses.Clear(); constraintCount = 0; } public void AddConstraint(int index1, int index2, float maxLength, float scale, float stiffness){ activeConstraints.Add(constraintCount); tetherIndices.Add(index1); tetherIndices.Add(index2); maxLengthsScales.Add(new Vector2(maxLength,scale)); stiffnesses.Add(stiffness); constraintCount++; } public void RemoveConstraint(int index){ if (index < 0 || index >= ConstraintCount) return; activeConstraints.Remove(index); for(int i = 0; i < activeConstraints.Count; ++i) if (activeConstraints[i] > index) activeConstraints[i]--; tetherIndices.RemoveRange(index*2,2); maxLengthsScales.RemoveAt(index); stiffnesses.RemoveAt(index); constraintCount--; } public override List GetConstraintsInvolvingParticle(int particleIndex){ List constraints = new List(4); for (int i = 0; i < ConstraintCount; i++){ if (tetherIndices[i*2] == particleIndex || tetherIndices[i*2+1] == particleIndex) constraints.Add(i); } return constraints; } public override void Cook() { batch = Oni.CreateBatch((int)Oni.ConstraintType.Tether,true); // Send initial data to batch: Oni.SetTetherConstraints(batch,tetherIndices.ToArray(),maxLengthsScales.ToArray(),stiffnesses.ToArray(),ConstraintCount); // cook the batch and retrieve new sorted data: if (Oni.CookBatch(batch)) { constraintCount = Oni.GetBatchConstraintCount(batch); activeConstraints = Enumerable.Range(0, constraintCount).ToList(); int[] cookedIndices = new int[constraintCount*2]; Vector2[] cookedRestLengths = new Vector2[constraintCount]; float[] cookedStiffnesses = new float[constraintCount]; Oni.GetTetherConstraints(batch,cookedIndices,cookedRestLengths,cookedStiffnesses); tetherIndices = new List(cookedIndices); maxLengthsScales = new List(cookedRestLengths); stiffnesses = new List(cookedStiffnesses); int phaseCount = Oni.GetBatchPhaseCount(batch); int[] phases = new int[phaseCount]; Oni.GetBatchPhaseSizes(batch,phases); this.phaseSizes = new List(phases); } Oni.DestroyBatch(batch); batch = IntPtr.Zero; } protected override void OnAddToSolver(ObiBatchedConstraints constraints){ // Set solver constraint data: solverIndices = new int[tetherIndices.Count]; for (int i = 0; i < ConstraintCount; i++) { solverIndices[i*2] = constraints.Actor.particleIndices[tetherIndices[i*2]]; solverIndices[i*2+1] = constraints.Actor.particleIndices[tetherIndices[i*2+1]]; } } protected override void OnRemoveFromSolver(ObiBatchedConstraints constraints){ } public override void PushDataToSolver(ObiBatchedConstraints constraints){ if (constraints == null || constraints.Actor == null || !constraints.Actor.InSolver) return; ObiTetherConstraints tc = (ObiTetherConstraints) constraints; for (int i = 0; i < ConstraintCount; i++){ maxLengthsScales[i] = new Vector2(maxLengthsScales[i].x, tc.tetherScale); stiffnesses[i] = StiffnessToCompliance(tc.stiffness); } Oni.SetTetherConstraints(batch,solverIndices,maxLengthsScales.ToArray(),stiffnesses.ToArray(),ConstraintCount); Oni.SetBatchPhaseSizes(batch,phaseSizes.ToArray(),phaseSizes.Count); } public override void PullDataFromSolver(ObiBatchedConstraints constraints){ } } }