_xiaofang/xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/ObiConstraints.cs

179 lines
4.6 KiB
C#
Raw Normal View History

2024-12-18 02:18:45 +08:00
using UnityEngine;
using System.Collections.Generic;
using System;
namespace Obi
{
public interface IObiConstraints
{
Oni.ConstraintType? GetConstraintType();
IObiConstraintsBatch GetBatch(int i);
int batchCount { get; }
void Clear();
bool AddToSolver(ObiSolver solver);
bool RemoveFromSolver();
int GetConstraintCount();
int GetActiveConstraintCount();
void ActivateAllConstraints();
void DeactivateAllConstraints();
void Merge(ObiActor actor, IObiConstraints other);
}
[Serializable]
public abstract class ObiConstraints<T> : IObiConstraints where T : class, IObiConstraintsBatch
{
[NonSerialized] protected ObiSolver m_Solver;
[HideInInspector] public List<T> batches = new List<T>();
public int batchCount { get => batches == null ? 0 : batches.Count; }
// merges constraints from a given actor with this one.
public void Merge(ObiActor actor, IObiConstraints other)
{
var others = other as ObiConstraints<T>;
if (others == null || !other.GetConstraintType().HasValue)
return;
int constraintType = (int)other.GetConstraintType().Value;
// clear batch offsets for this constraint type:
actor.solverBatchOffsets[constraintType].Clear();
// create new empty batches if needed:
int newBatches = Mathf.Max(0, others.batchCount - batchCount);
for (int i = 0; i < newBatches; ++i)
AddBatch(CreateBatch());
for (int i = 0; i < other.batchCount; ++i)
{
// store this batch's offset:
actor.solverBatchOffsets[constraintType].Add(batches[i].activeConstraintCount);
// merge both batches:
batches[i].Merge(actor, others.batches[i]);
}
}
public IObiConstraintsBatch GetBatch(int i)
{
if (batches != null && i >= 0 && i < batches.Count)
return (IObiConstraintsBatch) batches[i];
return null;
}
public int GetConstraintCount()
{
int count = 0;
if (batches == null) return count;
foreach (T batch in batches)
if (batch != null)
count += batch.constraintCount;
return count;
}
public int GetActiveConstraintCount()
{
int count = 0;
if (batches == null) return count;
foreach (T batch in batches)
if (batch != null)
count += batch.activeConstraintCount;
return count;
}
public void DeactivateAllConstraints()
{
if (batches != null)
foreach (T batch in batches)
if (batch != null)
batch.DeactivateAllConstraints();
}
public void ActivateAllConstraints()
{
if (batches != null)
foreach (T batch in batches)
if (batch != null)
batch.ActivateAllConstraints();
}
public T GetFirstBatch()
{
return (batches != null && batches.Count > 0) ? batches[0] : null;
}
public Oni.ConstraintType? GetConstraintType()
{
if (batches != null && batches.Count > 0)
return batches[0].constraintType;
else return null;
}
public void Clear()
{
RemoveFromSolver();
if (batches != null)
batches.Clear();
}
public virtual T CreateBatch(T source = null)
{
return null;
}
public void AddBatch(T batch)
{
if (batch != null)
batches.Add(batch);
}
public bool RemoveBatch(T batch)
{
if (batches == null || batch == null)
return false;
return batches.Remove(batch);
}
public bool AddToSolver(ObiSolver solver)
{
if (this.m_Solver != null || batches == null)
return false;
this.m_Solver = solver;
foreach (T batch in batches)
batch.AddToSolver(m_Solver);
return true;
}
public bool RemoveFromSolver()
{
if (this.m_Solver == null || batches == null)
return false;
foreach (T batch in batches)
batch.RemoveFromSolver(m_Solver);
this.m_Solver = null;
return true;
}
}
}