using UnityEngine; using System.Collections; using System.Collections.Generic; using System; namespace Obi { [Serializable] public class ObiSkinConstraintsBatch : ObiConstraintsBatch { protected ISkinConstraintsBatchImpl m_BatchImpl; /// /// skin constraint anchor points, in solver space. /// [HideInInspector] public ObiNativeVector4List skinPoints = new ObiNativeVector4List(); /// /// normal vector for each skin constraint, in solver space. /// [HideInInspector] public ObiNativeVector4List skinNormals = new ObiNativeVector4List(); /// /// 3 floats per constraint: skin radius, backstop sphere radius, and backstop sphere distance. /// [HideInInspector] public ObiNativeFloatList skinRadiiBackstop = new ObiNativeFloatList(); /// /// one compliance value per skin constraint. /// [HideInInspector] public ObiNativeFloatList skinCompliance = new ObiNativeFloatList(); public override Oni.ConstraintType constraintType { get { return Oni.ConstraintType.Skin; } } public override IConstraintsBatchImpl implementation { get { return m_BatchImpl; } } public ObiSkinConstraintsBatch(ObiSkinConstraintsData constraints = null) : base() { } public void AddConstraint(int index, Vector4 point, Vector4 normal, float radius, float collisionRadius, float backstop, float stiffness) { RegisterConstraint(); particleIndices.Add(index); skinPoints.Add(point); skinNormals.Add(normal); skinRadiiBackstop.Add(radius); skinRadiiBackstop.Add(collisionRadius); skinRadiiBackstop.Add(backstop); skinCompliance.Add(stiffness); } public override void Clear() { base.Clear(); particleIndices.Clear(); skinPoints.Clear(); skinNormals.Clear(); skinRadiiBackstop.Clear(); skinCompliance.Clear(); } public override void GetParticlesInvolved(int index, List particles) { particles.Add(particleIndices[index]); } protected override void SwapConstraints(int sourceIndex, int destIndex) { particleIndices.Swap(sourceIndex, destIndex); skinPoints.Swap(sourceIndex, destIndex); skinNormals.Swap(sourceIndex, destIndex); skinRadiiBackstop.Swap(sourceIndex * 3, destIndex * 3); skinRadiiBackstop.Swap(sourceIndex * 3+1, destIndex * 3+1); skinRadiiBackstop.Swap(sourceIndex * 3+2, destIndex * 3+2); skinCompliance.Swap(sourceIndex, destIndex); } public override void Merge(ObiActor actor, IObiConstraintsBatch other) { var batch = other as ObiSkinConstraintsBatch; var user = actor as ISkinConstraintsUser; if (batch != null && user != null) { if (!user.skinConstraintsEnabled) return; particleIndices.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); skinPoints.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); skinNormals.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); skinRadiiBackstop.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 3); skinCompliance.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); lambdas.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount); skinPoints.CopyFrom(batch.skinPoints, 0, m_ActiveConstraintCount, batch.activeConstraintCount); skinNormals.CopyFrom(batch.skinNormals, 0, m_ActiveConstraintCount, batch.activeConstraintCount); for (int i = 0; i < batch.activeConstraintCount; ++i) { var radiiBackstop = user.GetSkinRadiiBackstop(batch, i); skinRadiiBackstop[(m_ActiveConstraintCount + i) * 3] = radiiBackstop.x; skinRadiiBackstop[(m_ActiveConstraintCount + i) * 3 + 1] = radiiBackstop.y; skinRadiiBackstop[(m_ActiveConstraintCount + i) * 3 + 2] = radiiBackstop.z; skinCompliance[m_ActiveConstraintCount + i] = user.GetSkinCompliance(batch, i); } for (int i = 0; i < batch.activeConstraintCount; ++i) particleIndices[m_ActiveConstraintCount + i] = actor.solverIndices[batch.particleIndices[i]]; base.Merge(actor, other); } } public override void AddToSolver(ObiSolver solver) { // Create distance constraints batch directly. m_BatchImpl = solver.implementation.CreateConstraintsBatch(constraintType) as ISkinConstraintsBatchImpl; if (m_BatchImpl != null) m_BatchImpl.SetSkinConstraints(particleIndices, skinPoints, skinNormals, skinRadiiBackstop, skinCompliance, lambdas, m_ActiveConstraintCount); } public override void RemoveFromSolver(ObiSolver solver) { //Remove batch: solver.implementation.DestroyConstraintsBatch(m_BatchImpl as IConstraintsBatchImpl); } } }