Files
HauntedBloodlines/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiConstraintsBatch.cs
2025-05-29 22:31:40 +03:00

203 lines
6.5 KiB
C#

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
namespace Obi
{
public interface IObiConstraintsBatch
{
int constraintCount
{
get;
}
int activeConstraintCount
{
get;
set;
}
int initialActiveConstraintCount
{
get;
set;
}
Oni.ConstraintType constraintType
{
get;
}
IConstraintsBatchImpl implementation
{
get;
}
void AddToSolver(ObiSolver solver);
void RemoveFromSolver(ObiSolver solver);
void Merge(ObiActor actor, IObiConstraintsBatch other);
bool DeactivateConstraint(int constraintIndex);
bool ActivateConstraint(int constraintIndex);
void DeactivateAllConstraints();
void Clear();
void GetParticlesInvolved(int index, List<int> particles);
void ParticlesSwapped(int index, int newIndex);
}
public abstract class ObiConstraintsBatch : IObiConstraintsBatch
{
[HideInInspector] [SerializeField] protected List<int> m_IDs = new List<int>();
[HideInInspector] [SerializeField] protected List<int> m_IDToIndex = new List<int>(); /**< maps from constraint ID to constraint index. When activating/deactivating constraints, their order changes. That makes this
map necessary. All active constraints are at the beginning of the constraint arrays, in the 0, activeConstraintCount index range.*/
[HideInInspector] [SerializeField] protected int m_ConstraintCount = 0;
[HideInInspector] [SerializeField] protected int m_ActiveConstraintCount = 0;
[HideInInspector] [SerializeField] protected int m_InitialActiveConstraintCount = 0;
[HideInInspector] public ObiNativeIntList particleIndices = new ObiNativeIntList(); /**< particle indices, amount of them per constraint can be variable. */
[HideInInspector] public ObiNativeFloatList lambdas = new ObiNativeFloatList(); /**< constraint lambdas */
public int constraintCount
{
get { return m_ConstraintCount; }
}
public int activeConstraintCount
{
get { return m_ActiveConstraintCount; }
set { m_ActiveConstraintCount = value; }
}
public virtual int initialActiveConstraintCount
{
get { return m_InitialActiveConstraintCount; }
set { m_InitialActiveConstraintCount = value; }
}
public abstract Oni.ConstraintType constraintType
{
get;
}
public abstract IConstraintsBatchImpl implementation
{
get;
}
// Merges a batch from a given actor with this one.
public virtual void Merge(ObiActor actor, IObiConstraintsBatch other)
{
m_ConstraintCount += other.constraintCount;
m_ActiveConstraintCount += other.activeConstraintCount;
m_InitialActiveConstraintCount += other.initialActiveConstraintCount;
}
protected abstract void SwapConstraints(int sourceIndex, int destIndex);
public abstract void GetParticlesInvolved(int index, List<int> particles);
public abstract void AddToSolver(ObiSolver solver);
public abstract void RemoveFromSolver(ObiSolver solver);
protected virtual void CopyConstraint(ObiConstraintsBatch batch, int constraintIndex) { }
private void InnerSwapConstraints(int sourceIndex, int destIndex)
{
m_IDToIndex[m_IDs[sourceIndex]] = destIndex;
m_IDToIndex[m_IDs[destIndex]] = sourceIndex;
m_IDs.Swap(sourceIndex, destIndex);
SwapConstraints(sourceIndex, destIndex);
}
/**
* Registers a new constraint. Call this before adding a new contraint to the batch, so that the constraint is given an ID
* and the amount of constraints increased.
*/
protected void RegisterConstraint()
{
m_IDs.Add(m_ConstraintCount);
m_IDToIndex.Add(m_ConstraintCount);
m_ConstraintCount++;
}
public virtual void Clear()
{
m_ConstraintCount = 0;
m_ActiveConstraintCount = 0;
m_IDs.Clear();
m_IDToIndex.Clear();
particleIndices.Clear();
lambdas.Clear();
}
/**
* Given the id of a constraint, return its index in the constraint data arrays. Will return -1 if the constraint does not exist.
*/
public int GetConstraintIndex(int constraintId)
{
if (constraintId < 0 || constraintId >= constraintCount)
return -1;
return m_IDToIndex[constraintId];
}
public bool IsConstraintActive(int index)
{
return index < m_ActiveConstraintCount;
}
public bool ActivateConstraint(int constraintIndex)
{
if (constraintIndex < m_ActiveConstraintCount)
return false;
InnerSwapConstraints(constraintIndex, m_ActiveConstraintCount);
m_ActiveConstraintCount++;
return true;
}
public bool DeactivateConstraint(int constraintIndex)
{
if (constraintIndex >= m_ActiveConstraintCount)
return false;
m_ActiveConstraintCount--;
InnerSwapConstraints(constraintIndex, m_ActiveConstraintCount);
return true;
}
public void DeactivateAllConstraints()
{
m_ActiveConstraintCount = 0;
}
// Swaps the constraint with the last one and reduces the amount of constraints by one.
public void RemoveConstraint(int constraintIndex)
{
SwapConstraints(constraintIndex, constraintCount - 1);
m_IDs.RemoveAt(constraintCount - 1);
m_IDToIndex.RemoveAt(constraintCount - 1);
m_ConstraintCount--;
m_ActiveConstraintCount = Mathf.Min(m_ActiveConstraintCount, m_ConstraintCount);
}
public void ParticlesSwapped(int index, int newIndex)
{
for (int i = 0; i < particleIndices.count; ++i)
{
if (particleIndices[i] == newIndex)
particleIndices[i] = index;
else if (particleIndices[i] == index)
particleIndices[i] = newIndex;
}
}
}
}