GQ_Communicate/GQ_TongXin/Assets/Obi/Scripts/Constraints/ConstraintBatches/ObiConstraintBatch.cs

142 lines
5.0 KiB
C#

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Obi
{
/**
* ObiConstraintBatch are groups of constraints of the same type that are added/removed together from the solver.
* Batches can be of two main types:
*
* - Cooked: cooked batches reorder their constraints for better data locality and to enable the vectorized code path.
* Once the cooking proccess has finished constraints can't be added or removed, only activated/deactivated,
* but they yield very good performance.
*
* - Raw: raw batches allow for efficient addition/removal of constraints on the fly, and very efficient activation/deactivation.
* They do not require cooking but perform worse than cooked batches, as they don't do anyhting special regarding
* vectorization or improving cache data locality.
*
* ObiBatchedConstraints hold parameters for a group of batches of the same type.
*/
[Serializable]
public abstract class ObiConstraintBatch
{
protected IntPtr batch; /**< pointer to constraint batch in the solver.*/
public float maxYoungModulus = 0.02f; /**< default value of max stiffness (N/m2)*/
public float minYoungModulus = 0.0001f; /**< default value of min stiffness (N/m2)*/
[SerializeField][HideInInspector] protected int constraintCount = 0; /**< amount of constraints in this batch*/
[SerializeField][HideInInspector] protected bool cooked = false; /**< returns whether this batch supports cooking or not.*/
[SerializeField][HideInInspector] protected bool sharesParticles = false; /**< returns whether this batch must be done serially or can benefit from multithreading.*/
[SerializeField][HideInInspector] protected List<int> activeConstraints = new List<int>(); /**< list of active constraint indices.*/
[SerializeField][HideInInspector] protected List<int> phaseSizes = new List<int>(); /**< phase sizes for cooked batches.*/
public IntPtr OniBatch{
get{return batch;}
}
public int ConstraintCount{
get{return constraintCount;}
}
public bool IsCooked{
get{return cooked;}
}
public bool SharesParticles{
get{return sharesParticles;}
}
public IEnumerable<int> ActiveConstraints
{
get{return activeConstraints.AsReadOnly();}
}
// Implement this method to provide info about the batch type:
public abstract Oni.ConstraintType GetConstraintType();
// Implement these method to provide a custom clearing/cooking/swapping implementation.
public abstract void Clear();
public virtual void Cook(){}
// Implement these methods to perform custom actions when adding/removing the batch from the solver.
protected abstract void OnAddToSolver(ObiBatchedConstraints constraints);
protected abstract void OnRemoveFromSolver(ObiBatchedConstraints constraints);
// Implement these methods to push/pull constraint data to/from the solver.
public abstract void PushDataToSolver(ObiBatchedConstraints constraints);
public abstract void PullDataFromSolver(ObiBatchedConstraints constraints);
public abstract List<int> GetConstraintsInvolvingParticle(int particleIndex);
protected float StiffnessToCompliance(float stiffness){
float minCompliance = 1.0f/Mathf.Max(minYoungModulus,0.00001f);
float maxCompliance = 1.0f/Mathf.Max(maxYoungModulus,minYoungModulus);
return Mathf.Lerp(minCompliance,maxCompliance,stiffness);
}
public void ActivateConstraint(int index){
if (!activeConstraints.Contains(index))
activeConstraints.Add(index);
}
public void DeactivateConstraint(int index){
activeConstraints.Remove(index);
}
public ObiConstraintBatch(bool cooked, bool sharesParticles){
this.cooked = cooked;
this.sharesParticles = sharesParticles;
}
/**
* This constructor allows to override min/max young modulus, used to map a stiffness range of (0,1) to physical compliance values.
*/
public ObiConstraintBatch(bool cooked, bool sharesParticles, float minYoungModulus, float maxYoungModulus){
this.cooked = cooked;
this.sharesParticles = sharesParticles;
this.maxYoungModulus = maxYoungModulus;
this.minYoungModulus = minYoungModulus;
}
public void AddToSolver(ObiBatchedConstraints constraints){
// create a constraint batch:
batch = Oni.CreateBatch((int)GetConstraintType(),cooked);
Oni.AddBatch(constraints.Actor.Solver.OniSolver,batch,sharesParticles);
// custom stuff:
OnAddToSolver(constraints);
}
public void RemoveFromSolver(ObiBatchedConstraints constraints){
// custom stuff:
OnRemoveFromSolver(constraints);
// remove the constraint batch from the solver
// (no need to destroy it as its destruction is managed by the solver)
Oni.RemoveBatch(constraints.Actor.Solver.OniSolver,batch);
// important: set the batch pointer to null, as it could be destroyed by the solver.
batch = IntPtr.Zero;
}
public void SetActiveConstraints(){
Oni.SetActiveConstraints(batch,activeConstraints.ToArray(),activeConstraints.Count);
}
public void Enable(){
Oni.EnableBatch(batch,true);
}
public void Disable(){
Oni.EnableBatch(batch,false);
}
}
}