去掉obi,使用自写绳索

This commit is contained in:
2026-02-23 20:51:03 +08:00
parent cb636f862d
commit 91e2309eeb
2011 changed files with 2593 additions and 190578 deletions

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: e272b09fdfb9d401aa0514e09d3eb842
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 12f3679c3b69b41b68f65afab6db4c56
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,13 +0,0 @@
using UnityEngine;
using System.Collections;
namespace Obi
{
public interface IStructuralConstraintBatch
{
float GetRestLength(int index);
void SetRestLength(int index, float restLength);
ParticlePair GetParticleIndices(int index);
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f23dea5b75e2c432282b0f62513267ed
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,107 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Obi
{
[Serializable]
public class ObiAerodynamicConstraintsBatch : ObiConstraintsBatch
{
protected IAerodynamicConstraintsBatchImpl m_BatchImpl;
/// <summary>
/// 3 floats per constraint: surface area, drag and lift.
/// </summary>
[HideInInspector] public ObiNativeFloatList aerodynamicCoeffs = new ObiNativeFloatList();
public override Oni.ConstraintType constraintType
{
get { return Oni.ConstraintType.Aerodynamics; }
}
public override IConstraintsBatchImpl implementation
{
get { return m_BatchImpl; }
}
public ObiAerodynamicConstraintsBatch(ObiAerodynamicConstraintsData constraints = null) : base()
{
}
public void AddConstraint(int index, float area, float drag, float lift)
{
RegisterConstraint();
particleIndices.Add(index);
aerodynamicCoeffs.Add(area);
aerodynamicCoeffs.Add(drag);
aerodynamicCoeffs.Add(lift);
}
public override void GetParticlesInvolved(int index, List<int> particles)
{
particles.Add(particleIndices[index]);
}
public override void Clear()
{
base.Clear();
particleIndices.Clear();
aerodynamicCoeffs.Clear();
}
protected override void SwapConstraints(int sourceIndex, int destIndex)
{
particleIndices.Swap(sourceIndex, destIndex);
aerodynamicCoeffs.Swap(sourceIndex * 3, destIndex * 3);
aerodynamicCoeffs.Swap(sourceIndex * 3 + 1, destIndex * 3 + 1);
aerodynamicCoeffs.Swap(sourceIndex * 3 + 2, destIndex * 3 + 2);
}
public override void Merge(ObiActor actor, IObiConstraintsBatch other)
{
var batch = other as ObiAerodynamicConstraintsBatch;
var user = actor as IAerodynamicConstraintsUser;
if (batch != null && user != null)
{
if (!user.aerodynamicsEnabled)
return;
particleIndices.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
aerodynamicCoeffs.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 3);
for (int i = 0; i < batch.activeConstraintCount; ++i)
{
particleIndices[m_ActiveConstraintCount + i] = actor.solverIndices[batch.particleIndices[i]];
aerodynamicCoeffs[(m_ActiveConstraintCount + i) * 3] = batch.aerodynamicCoeffs[i*3];
aerodynamicCoeffs[(m_ActiveConstraintCount + i) * 3 + 1] = user.GetDrag(batch, i);
aerodynamicCoeffs[(m_ActiveConstraintCount + i) * 3 + 2] = user.GetLift(batch, i);
}
base.Merge(actor, other);
}
}
public override void AddToSolver(ObiSolver solver)
{
// Create distance constraints batch directly.
m_BatchImpl = solver.implementation.CreateConstraintsBatch(constraintType) as IAerodynamicConstraintsBatchImpl;
if (m_BatchImpl != null)
m_BatchImpl.SetAerodynamicConstraints(particleIndices, aerodynamicCoeffs, m_ActiveConstraintCount);
}
public override void RemoveFromSolver(ObiSolver solver)
{
base.RemoveFromSolver(solver);
aerodynamicCoeffs.Dispose();
//Remove batch:
solver.implementation.DestroyConstraintsBatch(m_BatchImpl as IConstraintsBatchImpl);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 679cceabc60a345df8d9c3e0ac00eca3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 8626b43f419d1466a9dc1c1509308b13, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,128 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Obi
{
[Serializable]
public class ObiBendConstraintsBatch : ObiConstraintsBatch
{
protected IBendConstraintsBatchImpl m_BatchImpl;
/// <summary>
/// one float per constraint: the rest bend distance.
/// </summary>
[HideInInspector] public ObiNativeFloatList restBends = new ObiNativeFloatList();
/// <summary>
/// two floats per constraint: max bending and compliance.
/// </summary>
[HideInInspector] public ObiNativeVector2List bendingStiffnesses = new ObiNativeVector2List();
/// <summary>
/// two floats per constraint: plastic yield and creep.
/// </summary>
[HideInInspector] public ObiNativeVector2List plasticity = new ObiNativeVector2List();
public override Oni.ConstraintType constraintType
{
get { return Oni.ConstraintType.Bending; }
}
public override IConstraintsBatchImpl implementation
{
get { return m_BatchImpl; }
}
public ObiBendConstraintsBatch(ObiBendConstraintsData constraints = null) : base()
{
}
public override void Merge(ObiActor actor, IObiConstraintsBatch other)
{
var batch = other as ObiBendConstraintsBatch;
var user = actor as IBendConstraintsUser;
if (batch != null && user != null)
{
if (!user.bendConstraintsEnabled)
return;
particleIndices.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 3);
restBends.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
bendingStiffnesses.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
plasticity.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
lambdas.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
restBends.CopyFrom(batch.restBends, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
bendingStiffnesses.CopyReplicate(new Vector2(user.maxBending, user.bendCompliance), m_ActiveConstraintCount, batch.activeConstraintCount);
plasticity.CopyReplicate(new Vector2(user.plasticYield, user.plasticCreep), m_ActiveConstraintCount, batch.activeConstraintCount);
for (int i = 0; i < batch.activeConstraintCount * 3; ++i)
particleIndices[m_ActiveConstraintCount * 3 + i] = actor.solverIndices[batch.particleIndices[i]];
base.Merge(actor, other);
}
}
public void AddConstraint(Vector3Int indices, float restBend)
{
RegisterConstraint();
particleIndices.Add(indices[0]);
particleIndices.Add(indices[1]);
particleIndices.Add(indices[2]);
restBends.Add(restBend);
bendingStiffnesses.Add(Vector2.zero);
plasticity.Add(Vector2.zero);
}
public override void Clear()
{
base.Clear();
restBends.Clear();
bendingStiffnesses.Clear();
plasticity.Clear();
}
public override void GetParticlesInvolved(int index, List<int> particles)
{
particles.Add(particleIndices[index * 3]);
particles.Add(particleIndices[index * 3 + 1]);
particles.Add(particleIndices[index * 3 + 2]);
}
protected override void SwapConstraints(int sourceIndex, int destIndex)
{
particleIndices.Swap(sourceIndex * 3, destIndex * 3);
particleIndices.Swap(sourceIndex * 3 + 1 , destIndex * 3 + 1);
particleIndices.Swap(sourceIndex * 3 + 2, destIndex * 3 + 2);
restBends.Swap(sourceIndex, destIndex);
bendingStiffnesses.Swap(sourceIndex, destIndex);
plasticity.Swap(sourceIndex, destIndex);
}
public override void AddToSolver(ObiSolver solver)
{
// Create distance constraints batch directly.
m_BatchImpl = solver.implementation.CreateConstraintsBatch(constraintType) as IBendConstraintsBatchImpl;
if (m_BatchImpl != null)
m_BatchImpl.SetBendConstraints(particleIndices, restBends, bendingStiffnesses, plasticity, lambdas, m_ActiveConstraintCount);
}
public override void RemoveFromSolver(ObiSolver solver)
{
base.RemoveFromSolver(solver);
restBends.Dispose();
bendingStiffnesses.Dispose();
plasticity.Dispose();
//Remove batch:
solver.implementation.DestroyConstraintsBatch(m_BatchImpl as IConstraintsBatchImpl);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 2d25c1516f81f44b190e2ef893151ea0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: f9aac3aba3ca7456d807e7fab120eb8a, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,129 +0,0 @@
using UnityEngine;
using System.Collections.Generic;
using System;
namespace Obi
{
[Serializable]
public class ObiBendTwistConstraintsBatch : ObiConstraintsBatch
{
protected IBendTwistConstraintsBatchImpl m_BatchImpl;
/// <summary>
/// Rest darboux vector for each constraint.
/// </summary>
[HideInInspector] public ObiNativeQuaternionList restDarbouxVectors = new ObiNativeQuaternionList();
/// <summary>
/// 3 compliance values for each constraint, one for each local axis (x,y,z)
/// </summary>
[HideInInspector] public ObiNativeVector3List stiffnesses = new ObiNativeVector3List();
/// <summary>
/// two floats per constraint: plastic yield and creep.
/// </summary>
[HideInInspector] public ObiNativeVector2List plasticity = new ObiNativeVector2List();
public override Oni.ConstraintType constraintType
{
get { return Oni.ConstraintType.BendTwist; }
}
public override IConstraintsBatchImpl implementation
{
get { return m_BatchImpl; }
}
public ObiBendTwistConstraintsBatch(ObiBendTwistConstraintsData constraints = null) : base()
{
}
public void AddConstraint(Vector2Int indices, Quaternion restDarboux)
{
RegisterConstraint();
this.particleIndices.Add(indices[0]);
this.particleIndices.Add(indices[1]);
this.restDarbouxVectors.Add(restDarboux);
this.stiffnesses.Add(Vector3.zero);
this.plasticity.Add(Vector2.zero);
}
public override void Clear()
{
base.Clear();
particleIndices.Clear();
restDarbouxVectors.Clear();
stiffnesses.Clear();
plasticity.Clear();
}
public override void GetParticlesInvolved(int index, List<int> particles)
{
particles.Add(particleIndices[index * 2]);
particles.Add(particleIndices[index * 2 + 1]);
}
protected override void SwapConstraints(int sourceIndex, int destIndex)
{
particleIndices.Swap(sourceIndex * 2, destIndex * 2);
particleIndices.Swap(sourceIndex * 2 + 1, destIndex * 2 + 1);
restDarbouxVectors.Swap(sourceIndex, destIndex);
stiffnesses.Swap(sourceIndex, destIndex);
plasticity.Swap(sourceIndex, destIndex);
}
public override void Merge(ObiActor actor, IObiConstraintsBatch other)
{
var batch = other as ObiBendTwistConstraintsBatch;
var user = actor as IBendTwistConstraintsUser;
if (batch != null && user != null)
{
if (!user.bendTwistConstraintsEnabled)
return;
particleIndices.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 2);
restDarbouxVectors.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
stiffnesses.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
plasticity.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
lambdas.ResizeInitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 3);
restDarbouxVectors.CopyFrom(batch.restDarbouxVectors, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
for (int i = 0; i < batch.activeConstraintCount; ++i)
{
stiffnesses[m_ActiveConstraintCount + i] = user.GetBendTwistCompliance(batch, i);
plasticity[m_ActiveConstraintCount + i] = user.GetBendTwistPlasticity(batch, i);
}
for (int i = 0; i < batch.activeConstraintCount * 2; ++i)
particleIndices[m_ActiveConstraintCount * 2 + 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 IBendTwistConstraintsBatchImpl;
if (m_BatchImpl != null)
m_BatchImpl.SetBendTwistConstraints(particleIndices, restDarbouxVectors, stiffnesses, plasticity, lambdas, m_ActiveConstraintCount);
}
public override void RemoveFromSolver(ObiSolver solver)
{
base.RemoveFromSolver(solver);
restDarbouxVectors.Dispose();
plasticity.Dispose();
stiffnesses.Dispose();
//Remove batch:
solver.implementation.DestroyConstraintsBatch(m_BatchImpl as IConstraintsBatchImpl);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: fd870f7d936fb46178a58eed5f6d4f7e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 91de8d14a7b7a42d88d336323c428b20, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,133 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Obi
{
[Serializable]
public class ObiChainConstraintsBatch : ObiConstraintsBatch
{
protected IChainConstraintsBatchImpl m_BatchImpl;
/// <summary>
/// index of the first particle for each constraint.
/// </summary>
[HideInInspector] public ObiNativeIntList firstParticle = new ObiNativeIntList();
/// <summary>
/// number of particles for each constraint.
/// </summary>
[HideInInspector] public ObiNativeIntList numParticles = new ObiNativeIntList();
/// <summary>
/// min/max lenghts for each constraint.
/// </summary>
[HideInInspector] public ObiNativeVector2List lengths = new ObiNativeVector2List();
public override Oni.ConstraintType constraintType
{
get { return Oni.ConstraintType.Chain; }
}
public override IConstraintsBatchImpl implementation
{
get { return m_BatchImpl; }
}
public ObiChainConstraintsBatch(ObiChainConstraintsData constraints = null) : base()
{
}
public void AddConstraint(int[] indices, float restLength, float stretchStiffness, float compressionStiffness)
{
RegisterConstraint();
firstParticle.Add((int)particleIndices.count);
numParticles.Add((int)indices.Length);
particleIndices.AddRange(indices);
lengths.Add(new Vector2(restLength, restLength));
}
public override void Clear()
{
base.Clear();
particleIndices.Clear();
firstParticle.Clear();
numParticles.Clear();
lengths.Clear();
}
public override void GetParticlesInvolved(int index, List<int> particles)
{
//TODO.
}
protected override void SwapConstraints(int sourceIndex, int destIndex)
{
firstParticle.Swap(sourceIndex, destIndex);
numParticles.Swap(sourceIndex, destIndex);
lengths.Swap(sourceIndex, destIndex);
}
public override void Merge(ObiActor actor, IObiConstraintsBatch other)
{
var batch = other as ObiChainConstraintsBatch;
var user = actor as IChainConstraintsUser;
if (batch != null && user != null)
{
if (!user.chainConstraintsEnabled)
return;
int initialIndexCount = particleIndices.count;
int numActiveIndices = 0;
for (int i = 0; i < batch.activeConstraintCount; ++i)
numActiveIndices += batch.numParticles[i];
particleIndices.ResizeUninitialized(initialIndexCount + numActiveIndices);
firstParticle.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
numParticles.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
lengths.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
lambdas.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
numParticles.CopyFrom(batch.numParticles, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
for (int i = 0; i < numActiveIndices; ++i)
particleIndices[initialIndexCount + i] = actor.solverIndices[batch.particleIndices[i]];
for (int i = 0; i < batch.activeConstraintCount; ++i)
{
firstParticle[m_ActiveConstraintCount + i] = batch.firstParticle[i] + initialIndexCount;
lengths[m_ActiveConstraintCount + i] = new Vector2(batch.lengths[i].y * user.tightness, batch.lengths[i].y);
}
base.Merge(actor, other);
}
}
public override void AddToSolver(ObiSolver solver)
{
// Create distance constraints batch directly.
m_BatchImpl = solver.implementation.CreateConstraintsBatch(constraintType) as IChainConstraintsBatchImpl;
if (m_BatchImpl != null)
m_BatchImpl.SetChainConstraints(particleIndices, lengths, firstParticle, numParticles, m_ActiveConstraintCount);
}
public override void RemoveFromSolver(ObiSolver solver)
{
base.RemoveFromSolver(solver);
firstParticle.Dispose();
numParticles.Dispose();
lengths.Dispose();
//Remove batch:
solver.implementation.DestroyConstraintsBatch(m_BatchImpl as IConstraintsBatchImpl);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 4a957d8a661ad464085e9f64cfc57406
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 1a42905220c3544c99b3ec98f88b080b, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,212 +0,0 @@
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 ActivateAllConstraints();
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 virtual void AddToSolver(ObiSolver solver) { }
public virtual void RemoveFromSolver(ObiSolver solver) {
particleIndices.Dispose();
lambdas.Dispose();
}
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;
}
public void ActivateAllConstraints()
{
m_ActiveConstraintCount = m_ConstraintCount;
}
// 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;
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 7aacef50ee7794d0c9d6c77ef761d142
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,148 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Obi
{
[Serializable]
public class ObiDistanceConstraintsBatch : ObiConstraintsBatch, IStructuralConstraintBatch
{
[NonSerialized] protected IDistanceConstraintsBatchImpl m_BatchImpl;
/// <summary>
/// Rest distance for each individual constraint.
/// </summary>
[HideInInspector] public ObiNativeFloatList restLengths = new ObiNativeFloatList();
/// <summary>
/// 2 values for each constraint: compliance and slack.
/// </summary>
[HideInInspector] public ObiNativeVector2List stiffnesses = new ObiNativeVector2List();
public override Oni.ConstraintType constraintType
{
get { return Oni.ConstraintType.Distance; }
}
public override IConstraintsBatchImpl implementation
{
get { return m_BatchImpl; }
}
public ObiDistanceConstraintsBatch(ObiDistanceConstraintsData constraints = null) : base()
{
}
public void AddConstraint(Vector2Int indices, float restLength)
{
RegisterConstraint();
particleIndices.Add(indices[0]);
particleIndices.Add(indices[1]);
restLengths.Add(restLength);
stiffnesses.Add(Vector2.zero);
}
public override void Clear()
{
base.Clear();
restLengths.Clear();
stiffnesses.Clear();
}
public float GetRestLength(int index)
{
return restLengths[index];
}
public void SetRestLength(int index, float restLength)
{
restLengths[index] = restLength;
}
public ParticlePair GetParticleIndices(int index)
{
return new ParticlePair(particleIndices[index * 2],particleIndices[index * 2 + 1]);
}
public override void GetParticlesInvolved(int index, List<int> particles)
{
particles.Add(particleIndices[index * 2]);
particles.Add(particleIndices[index * 2 + 1]);
}
protected override void CopyConstraint(ObiConstraintsBatch batch, int constraintIndex)
{
if (batch is ObiDistanceConstraintsBatch)
{
var db = batch as ObiDistanceConstraintsBatch;
RegisterConstraint();
particleIndices.Add(batch.particleIndices[constraintIndex * 2]);
particleIndices.Add(batch.particleIndices[constraintIndex * 2 + 1]);
restLengths.Add(db.restLengths[constraintIndex]);
stiffnesses.Add(db.stiffnesses[constraintIndex]);
ActivateConstraint(constraintCount - 1);
}
}
protected override void SwapConstraints(int sourceIndex, int destIndex)
{
particleIndices.Swap(sourceIndex * 2, destIndex * 2);
particleIndices.Swap(sourceIndex * 2 + 1, destIndex * 2 + 1);
restLengths.Swap(sourceIndex, destIndex);
stiffnesses.Swap(sourceIndex, destIndex);
}
public override void Merge(ObiActor actor, IObiConstraintsBatch other)
{
var batch = other as ObiDistanceConstraintsBatch;
var user = actor as IDistanceConstraintsUser;
if (batch != null && user != null)
{
if (!user.distanceConstraintsEnabled)
return;
particleIndices.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 2);
restLengths.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
stiffnesses.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
lambdas.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
for (int i = 0; i < batch.activeConstraintCount * 2; ++i)
particleIndices[m_ActiveConstraintCount * 2 + i] = actor.solverIndices[batch.particleIndices[i]];
for (int i = 0; i < batch.activeConstraintCount; ++i)
{
float restLength = batch.restLengths[i] * user.stretchingScale;
restLengths[m_ActiveConstraintCount + i] = restLength; // TODO: use nativelist methods?
stiffnesses[m_ActiveConstraintCount + i] = new Vector2(user.stretchCompliance, user.maxCompression * restLength);
}
base.Merge(actor, other);
}
}
public override void AddToSolver(ObiSolver solver)
{
// Create distance constraints batch directly.
m_BatchImpl = solver.implementation.CreateConstraintsBatch(constraintType) as IDistanceConstraintsBatchImpl;
if (m_BatchImpl != null)
m_BatchImpl.SetDistanceConstraints(particleIndices, restLengths, stiffnesses, lambdas, m_ActiveConstraintCount);
}
public override void RemoveFromSolver(ObiSolver solver)
{
base.RemoveFromSolver(solver);
restLengths.Dispose();
stiffnesses.Dispose();
//Remove batch:
solver.implementation.DestroyConstraintsBatch(m_BatchImpl as IConstraintsBatchImpl);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 6b0df8a8dbd9143dca2d51705e597db4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 8be685232a6ad41508d8bbe9d003a892, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,146 +0,0 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
namespace Obi
{
[Serializable]
public class ObiPinConstraintsBatch : ObiConstraintsBatch
{
protected IPinConstraintsBatchImpl m_BatchImpl;
/// <summary>
/// for each constraint, handle of the pinned collider.
/// </summary>
[HideInInspector] public List<ObiColliderHandle> pinBodies = new List<ObiColliderHandle>();
/// <summary>
/// index of the pinned collider in the collider world.
/// </summary>
[HideInInspector] public ObiNativeIntList colliderIndices = new ObiNativeIntList();
/// <summary>
/// Pin position expressed in the attachment's local space.
/// </summary>
[HideInInspector] public ObiNativeVector4List offsets = new ObiNativeVector4List();
/// <summary>
/// Rest Darboux vector for each constraint.
/// </summary>
[HideInInspector] public ObiNativeQuaternionList restDarbouxVectors = new ObiNativeQuaternionList();
/// <summary>
/// Compliances of pin constraits. 2 float per constraint (positional and rotational compliance).
/// </summary>
[HideInInspector] public ObiNativeFloatList stiffnesses = new ObiNativeFloatList();
public override Oni.ConstraintType constraintType
{
get { return Oni.ConstraintType.Pin; }
}
public override IConstraintsBatchImpl implementation
{
get { return m_BatchImpl; }
}
public ObiPinConstraintsBatch(ObiPinConstraintsData constraints = null) : base()
{
}
public void AddConstraint(int solverIndex, ObiColliderBase body, Vector3 offset, Quaternion restDarboux, float linearCompliance, float rotationalCompliance, bool projectRenderable = false)
{
RegisterConstraint();
particleIndices.Add(solverIndex);
pinBodies.Add(body != null ? body.Handle : new ObiColliderHandle());
colliderIndices.Add(body != null ? body.Handle.index : -1);
offsets.Add(new Vector4(offset.x, offset.y, offset.z, projectRenderable ? 1:0));
restDarbouxVectors.Add(restDarboux);
stiffnesses.Add(linearCompliance);
stiffnesses.Add(rotationalCompliance);
}
public override void Clear()
{
base.Clear();
particleIndices.Clear();
pinBodies.Clear();
colliderIndices.Clear();
offsets.Clear();
restDarbouxVectors.Clear();
stiffnesses.Clear();
}
public override void GetParticlesInvolved(int index, List<int> particles)
{
particles.Add(particleIndices[index]);
}
protected override void SwapConstraints(int sourceIndex, int destIndex)
{
particleIndices.Swap(sourceIndex, destIndex);
pinBodies.Swap(sourceIndex, destIndex);
colliderIndices.Swap(sourceIndex, destIndex);
offsets.Swap(sourceIndex, destIndex);
restDarbouxVectors.Swap(sourceIndex, destIndex);
stiffnesses.Swap(sourceIndex * 2, destIndex * 2);
stiffnesses.Swap(sourceIndex * 2 + 1, destIndex * 2 + 1);
}
public override void Merge(ObiActor actor, IObiConstraintsBatch other)
{
var batch = other as ObiPinConstraintsBatch;
if (batch != null)
{
particleIndices.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
colliderIndices.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
offsets.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
restDarbouxVectors.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
stiffnesses.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 2);
lambdas.ResizeInitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 4);
offsets.CopyFrom(batch.offsets, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
restDarbouxVectors.CopyFrom(batch.restDarbouxVectors, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
stiffnesses.CopyFrom(batch.stiffnesses, 0, m_ActiveConstraintCount * 2, batch.activeConstraintCount * 2);
for (int i = 0; i < batch.activeConstraintCount; ++i)
{
particleIndices[m_ActiveConstraintCount + i] = batch.particleIndices[i];
colliderIndices[m_ActiveConstraintCount + i] = batch.pinBodies[i] != null ? batch.pinBodies[i].index : -1;
}
base.Merge(actor, other);
}
}
public override void AddToSolver(ObiSolver solver)
{
if (solver != null && solver.implementation != null)
{
m_BatchImpl = solver.implementation.CreateConstraintsBatch(constraintType) as IPinConstraintsBatchImpl;
if (m_BatchImpl != null)
m_BatchImpl.SetPinConstraints(particleIndices, colliderIndices, offsets, restDarbouxVectors, stiffnesses, lambdas, m_ActiveConstraintCount);
}
}
public override void RemoveFromSolver(ObiSolver solver)
{
base.RemoveFromSolver(solver);
restDarbouxVectors.Dispose();
colliderIndices.Dispose();
offsets.Dispose();
stiffnesses.Dispose();
if (solver != null && solver.implementation != null)
solver.implementation.DestroyConstraintsBatch(m_BatchImpl as IConstraintsBatchImpl);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c2de2f97e7edf4bedb38202be59122ae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 85e4f507907784b9eb4637afe5c2e3a4, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,220 +0,0 @@
using UnityEngine;
using System;
using System.Collections.Generic;
namespace Obi
{
[Serializable]
public class ObiPinholeConstraintsBatch : ObiConstraintsBatch
{
[Serializable]
public struct PinholeEdge
{
public int edgeIndex;
public float coordinate;
public PinholeEdge(int edgeIndex, float coordinate)
{
this.edgeIndex = edgeIndex;
this.coordinate = coordinate;
}
public float GetRopeCoordinate(ObiActor actor)
{
int edgeCount = actor.GetDeformableEdgeCount();
return edgeCount > 0 ? Mathf.Clamp01((edgeIndex + coordinate) / edgeCount) : 0;
}
}
protected IPinholeConstraintsBatchImpl m_BatchImpl;
/// <summary>
/// for each constraint, handle of the pinned collider.
/// </summary>
[HideInInspector] public List<ObiColliderHandle> pinBodies = new List<ObiColliderHandle>();
/// <summary>
/// for each constraint, reference to the actor pinned.
/// </summary>
[HideInInspector] public List<ObiActor> pinActors = new List<ObiActor>();
/// <summary>
/// index of the pinned collider in the collider world.
/// </summary>
[HideInInspector] public ObiNativeIntList colliderIndices = new ObiNativeIntList();
/// <summary>
/// Pinhole position expressed in the attachment's local space.
/// </summary>
[HideInInspector] public ObiNativeVector4List offsets = new ObiNativeVector4List();
/// <summary>
// Normalized coordinate along current edge.
/// </summary>
[HideInInspector] public ObiNativeFloatList edgeMus = new ObiNativeFloatList();
/// <summary>
/// Edge range as 2 ints (first edge, last edge) for each constraint.
/// </summary>
[HideInInspector] public ObiNativeIntList edgeRanges = new ObiNativeIntList();
/// <summary>
/// Min/max cooridnate in each of the first and last edges as 2 floats for each constraint.
/// </summary>
[HideInInspector] public ObiNativeFloatList edgeRangeMus = new ObiNativeFloatList();
/// <summary>
/// Parameters of pinhole constraints. 5 floats per constraint (compliance, friction, motor speed, motor force and normalized coordinate along edge).
/// </summary>
[HideInInspector] public ObiNativeFloatList parameters = new ObiNativeFloatList();
/// <summary>
/// Relative velocities between rope and pinhole.
/// </summary>
[HideInInspector] public ObiNativeFloatList relativeVelocities = new ObiNativeFloatList();
public override Oni.ConstraintType constraintType
{
get { return Oni.ConstraintType.Pinhole; }
}
public override IConstraintsBatchImpl implementation
{
get { return m_BatchImpl; }
}
public ObiPinholeConstraintsBatch(ObiPinholeConstraintsData constraints = null) : base()
{
}
public void AddConstraint(PinholeEdge edge, PinholeEdge firstEdge, PinholeEdge lastEdge, ObiActor actor, ObiColliderBase body, Vector3 offset, float compliance, float friction, float motorSpeed, float motorForce, bool clampAtEnds)
{
RegisterConstraint();
particleIndices.Add(edge.edgeIndex);
edgeMus.Add(edge.coordinate);
edgeRanges.Add(firstEdge.edgeIndex);
edgeRanges.Add(lastEdge.edgeIndex);
edgeRangeMus.Add(firstEdge.coordinate);
edgeRangeMus.Add(lastEdge.coordinate);
pinBodies.Add(body != null ? body.Handle : new ObiColliderHandle());
pinActors.Add(actor);
colliderIndices.Add(body != null ? body.Handle.index : -1);
offsets.Add(offset);
parameters.Add(compliance);
parameters.Add(friction);
parameters.Add(motorSpeed);
parameters.Add(motorForce);
parameters.Add(clampAtEnds ? 1 : 0);
relativeVelocities.Add(0);
}
public override void Clear()
{
base.Clear();
particleIndices.Clear();
pinBodies.Clear();
colliderIndices.Clear();
offsets.Clear();
edgeMus.Clear();
edgeRanges.Clear();
edgeRangeMus.Clear();
parameters.Clear();
relativeVelocities.Clear();
}
public override void GetParticlesInvolved(int index, List<int> particles)
{
particles.Add(particleIndices[index]);
}
protected override void SwapConstraints(int sourceIndex, int destIndex)
{
particleIndices.Swap(sourceIndex, destIndex);
pinBodies.Swap(sourceIndex, destIndex);
colliderIndices.Swap(sourceIndex, destIndex);
offsets.Swap(sourceIndex, destIndex);
edgeMus.Swap(sourceIndex, destIndex);
edgeRanges.Swap(sourceIndex * 2, destIndex * 2);
edgeRanges.Swap(sourceIndex * 2 + 1, destIndex * 2 + 1);
edgeRangeMus.Swap(sourceIndex * 2, destIndex * 2);
edgeRangeMus.Swap(sourceIndex * 2 + 1, destIndex * 2 + 1);
for (int i = 0; i < 5; ++i)
parameters.Swap(sourceIndex * 5 + i, destIndex * 5 + i);
relativeVelocities.Swap(sourceIndex, destIndex);
}
public override void Merge(ObiActor actor, IObiConstraintsBatch other)
{
var batch = other as ObiPinholeConstraintsBatch;
if (batch != null)
{
particleIndices.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
colliderIndices.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
offsets.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
edgeRanges.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 2);
edgeRangeMus.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 2);
edgeMus.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
parameters.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 5);
relativeVelocities.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
lambdas.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
edgeMus.CopyFrom(batch.edgeMus, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
edgeRangeMus.CopyFrom(batch.edgeRangeMus, 0, m_ActiveConstraintCount * 2, batch.activeConstraintCount * 2);
offsets.CopyFrom(batch.offsets, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
relativeVelocities.CopyFrom(batch.relativeVelocities, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
parameters.CopyFrom(batch.parameters, 0, m_ActiveConstraintCount * 5, batch.activeConstraintCount * 5);
for (int i = 0; i < batch.activeConstraintCount; ++i)
{
int currentEdge = -1, firstEdge = -1, lastEdge = -1;
if (batch.pinActors[i] != null)
{
currentEdge = batch.pinActors[i].deformableEdgesOffset + batch.particleIndices[i];
firstEdge = batch.pinActors[i].deformableEdgesOffset + batch.edgeRanges[i * 2];
lastEdge = batch.pinActors[i].deformableEdgesOffset + batch.edgeRanges[i * 2 + 1];
}
edgeRanges[(m_ActiveConstraintCount + i) * 2] = firstEdge;
edgeRanges[(m_ActiveConstraintCount + i) * 2 + 1] = lastEdge;
particleIndices[m_ActiveConstraintCount + i] = Mathf.Clamp(currentEdge, firstEdge, lastEdge);
colliderIndices[m_ActiveConstraintCount + i] = batch.pinBodies[i] != null ? batch.pinBodies[i].index : -1;
}
base.Merge(actor, other);
}
}
public override void AddToSolver(ObiSolver solver)
{
if (solver != null && solver.implementation != null)
{
m_BatchImpl = solver.implementation.CreateConstraintsBatch(constraintType) as IPinholeConstraintsBatchImpl;
if (m_BatchImpl != null)
m_BatchImpl.SetPinholeConstraints(particleIndices, colliderIndices, offsets, edgeMus, edgeRanges, edgeRangeMus, parameters, relativeVelocities, lambdas, m_ActiveConstraintCount);
}
}
public override void RemoveFromSolver(ObiSolver solver)
{
base.RemoveFromSolver(solver);
edgeRanges.Dispose();
colliderIndices.Dispose();
offsets.Dispose();
parameters.Dispose();
if (solver != null && solver.implementation != null)
solver.implementation.DestroyConstraintsBatch(m_BatchImpl as IConstraintsBatchImpl);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d642dbf4a869c4761b38ce3f65e22f05
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,235 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Obi
{
[Serializable]
public class ObiShapeMatchingConstraintsBatch : ObiConstraintsBatch
{
protected IShapeMatchingConstraintsBatchImpl m_BatchImpl;
/// <summary>
/// index of the first particle in each constraint.
/// </summary>
public ObiNativeIntList firstIndex = new ObiNativeIntList();
/// <summary>
/// amount of particles in each constraint.
/// </summary>
public ObiNativeIntList numIndices = new ObiNativeIntList();
/// <summary>
/// whether the constraint is implicit (0) or explicit (>0).
/// </summary>
public ObiNativeIntList explicitGroup = new ObiNativeIntList();
/// <summary>
/// 5 floats per constraint: stiffness, plastic yield, creep, recovery and max deformation.
/// </summary>
public ObiNativeFloatList materialParameters = new ObiNativeFloatList();
/// <summary>
/// rest center of mass for each constraint.
/// </summary>
public ObiNativeVector4List restComs = new ObiNativeVector4List();
/// <summary>
/// current center of mass for each constraint.
/// </summary>
public ObiNativeVector4List coms = new ObiNativeVector4List();
/// <summary>
/// current best-match orientation for each constraint.
/// </summary>
public ObiNativeQuaternionList orientations = new ObiNativeQuaternionList();
/// <summary>
/// current best-match linear transform for each constraint.
/// </summary>
public ObiNativeMatrix4x4List linearTransforms = new ObiNativeMatrix4x4List();
/// <summary>
/// current plastic deformation for each constraint.
/// </summary>
public ObiNativeMatrix4x4List plasticDeformations = new ObiNativeMatrix4x4List();
public override Oni.ConstraintType constraintType
{
get { return Oni.ConstraintType.ShapeMatching; }
}
public override IConstraintsBatchImpl implementation
{
get { return m_BatchImpl; }
}
public ObiShapeMatchingConstraintsBatch(ObiShapeMatchingConstraintsData constraints = null) : base()
{
}
public void AddConstraint(int[] indices, bool isExplicit)
{
RegisterConstraint();
firstIndex.Add((int)particleIndices.count);
numIndices.Add((int)indices.Length);
explicitGroup.Add(isExplicit ? 1 : 0);
particleIndices.AddRange(indices);
materialParameters.AddRange(new float[] { 1, 1, 1, 1, 1 });
}
public override void Clear()
{
base.Clear();
firstIndex.Clear();
numIndices.Clear();
explicitGroup.Clear();
particleIndices.Clear();
materialParameters.Clear();
}
public override void GetParticlesInvolved(int index, List<int> particles)
{
int first = firstIndex[index];
int num = numIndices[index];
for (int i = first; i < first + num; ++i)
particles.Add(particleIndices[i]);
}
public void RemoveParticleFromConstraint(int constraintIndex, int particleIndex)
{
int first = firstIndex[constraintIndex];
int num = numIndices[constraintIndex];
int found = 0;
for (int i = first + num - 1; i >= first; --i)
{
if (particleIndices[i] == particleIndex)
{
found++;
particleIndices.RemoveAt(i);
}
}
// update num indices of the current constraint:
numIndices[constraintIndex] -= found;
// update firstIndex of following constraints:
for (int i = constraintIndex + 1; i < constraintCount; ++i)
firstIndex[i] -= found;
}
protected override void SwapConstraints(int sourceIndex, int destIndex)
{
firstIndex.Swap(sourceIndex, destIndex);
numIndices.Swap(sourceIndex, destIndex);
explicitGroup.Swap(sourceIndex, destIndex);
for (int i = 0; i < 5; ++i)
materialParameters.Swap(sourceIndex * 5 + i, destIndex * 5 + i);
restComs.Swap(sourceIndex, destIndex);
coms.Swap(sourceIndex, destIndex);
orientations.Swap(sourceIndex, destIndex);
linearTransforms.Swap(sourceIndex, destIndex);
plasticDeformations.Swap(sourceIndex, destIndex);
}
public override void Merge(ObiActor actor, IObiConstraintsBatch other)
{
var batch = other as ObiShapeMatchingConstraintsBatch;
var user = actor as IShapeMatchingConstraintsUser;
if (batch != null && user != null)
{
if (!user.shapeMatchingConstraintsEnabled)
return;
int initialIndexCount = particleIndices.count;
// shape matching constraint particle indices are not reordered when deactivating constraints,
// so instead of using batch.activeConstraintCount, batch.constraintCount. We need all of them.
int numActiveIndices = 0;
for (int i = 0; i < batch.constraintCount; ++i)
numActiveIndices += batch.numIndices[i];
particleIndices.ResizeUninitialized(initialIndexCount + numActiveIndices);
firstIndex.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
numIndices.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
explicitGroup.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
materialParameters.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 5);
restComs.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
coms.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
orientations.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
linearTransforms.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
plasticDeformations.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount, Matrix4x4.identity);
lambdas.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
numIndices.CopyFrom(batch.numIndices, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
explicitGroup.CopyFrom(batch.explicitGroup, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
orientations.CopyReplicate(actor.actorLocalToSolverMatrix.rotation, m_ActiveConstraintCount, batch.activeConstraintCount);
for (int i = 0; i < numActiveIndices; ++i)
particleIndices[initialIndexCount + i] = actor.solverIndices[batch.particleIndices[i]];
for (int i = 0; i < batch.activeConstraintCount; ++i)
{
firstIndex[m_ActiveConstraintCount + i] = batch.firstIndex[i] + initialIndexCount;
materialParameters[(m_ActiveConstraintCount + i) * 5] = batch.materialParameters[i * 5] * user.deformationResistance;
materialParameters[(m_ActiveConstraintCount + i) * 5 + 1] = batch.materialParameters[i * 5 + 1] * user.plasticYield;
materialParameters[(m_ActiveConstraintCount + i) * 5 + 2] = batch.materialParameters[i * 5 + 2] * user.plasticCreep;
materialParameters[(m_ActiveConstraintCount + i) * 5 + 3] = batch.materialParameters[i * 5 + 3] * user.plasticRecovery;
materialParameters[(m_ActiveConstraintCount + i) * 5 + 4] = batch.materialParameters[i * 5 + 4] * user.maxDeformation;
}
base.Merge(actor, other);
}
}
public override void AddToSolver(ObiSolver solver)
{
// Create distance constraints batch directly.
m_BatchImpl = solver.implementation.CreateConstraintsBatch(constraintType) as IShapeMatchingConstraintsBatchImpl;
if (m_BatchImpl != null)
{
m_BatchImpl.SetShapeMatchingConstraints(particleIndices, firstIndex, numIndices, explicitGroup,
materialParameters, restComs, coms, orientations, linearTransforms, plasticDeformations,
lambdas, m_ActiveConstraintCount);
m_BatchImpl.CalculateRestShapeMatching();
}
}
public override void RemoveFromSolver(ObiSolver solver)
{
base.RemoveFromSolver(solver);
firstIndex.Dispose();
numIndices.Dispose();
explicitGroup.Dispose();
materialParameters.Dispose();
restComs.Dispose();
coms.Dispose();
orientations.Dispose();
linearTransforms.Dispose();
plasticDeformations.Dispose();
//Remove batch:
solver.implementation.DestroyConstraintsBatch(m_BatchImpl as IConstraintsBatchImpl);
}
public void RecalculateRestShapeMatching()
{
if (m_BatchImpl != null)
m_BatchImpl.CalculateRestShapeMatching();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 7b626d541fade4c159a4373343c8f0bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: a2686776a1c104bfd8868f056a5cd335, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,146 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Obi
{
[Serializable]
public class ObiSkinConstraintsBatch : ObiConstraintsBatch
{
protected ISkinConstraintsBatchImpl m_BatchImpl;
/// <summary>
/// skin constraint anchor points, in solver space.
/// </summary>
[HideInInspector] public ObiNativeVector4List skinPoints = new ObiNativeVector4List();
/// <summary>
/// normal vector for each skin constraint, in solver space.
/// </summary>
[HideInInspector] public ObiNativeVector4List skinNormals = new ObiNativeVector4List();
/// <summary>
/// 3 floats per constraint: skin radius, backstop sphere radius, and backstop sphere distance.
/// </summary>
[HideInInspector] public ObiNativeFloatList skinRadiiBackstop = new ObiNativeFloatList();
/// <summary>
/// one compliance value per skin constraint.
/// </summary>
[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<int> 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)
{
base.RemoveFromSolver(solver);
skinPoints.Dispose();
skinNormals.Dispose();
skinRadiiBackstop.Dispose();
skinCompliance.Dispose();
//Remove batch:
solver.implementation.DestroyConstraintsBatch(m_BatchImpl as IConstraintsBatchImpl);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: a7643c39396894308b222447b842c2b5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: e58e2a3c37c7547a8a791a56e0a1ace6, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,156 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Obi
{
[Serializable]
public class ObiStretchShearConstraintsBatch : ObiConstraintsBatch, IStructuralConstraintBatch
{
protected IStretchShearConstraintsBatchImpl m_BatchImpl;
/// <summary>
/// index of particle orientation for each constraint.
/// </summary>
[HideInInspector] public ObiNativeIntList orientationIndices = new ObiNativeIntList();
/// <summary>
/// rest distance for each constraint.
/// </summary>
[HideInInspector] public ObiNativeFloatList restLengths = new ObiNativeFloatList();
/// <summary>
/// rest orientation for each constraint.
/// </summary>
[HideInInspector] public ObiNativeQuaternionList restOrientations = new ObiNativeQuaternionList();
/// <summary>
/// 3 compliance values per constraint, one for each local axis (x,y,z).
/// </summary>
[HideInInspector] public ObiNativeVector3List stiffnesses = new ObiNativeVector3List();
public override Oni.ConstraintType constraintType
{
get { return Oni.ConstraintType.StretchShear; }
}
public override IConstraintsBatchImpl implementation
{
get { return m_BatchImpl; }
}
public ObiStretchShearConstraintsBatch(ObiStretchShearConstraintsData constraints = null) : base()
{
}
public void AddConstraint(Vector2Int indices, int orientationIndex, float restLength, Quaternion restOrientation)
{
RegisterConstraint();
particleIndices.Add(indices[0]);
particleIndices.Add(indices[1]);
orientationIndices.Add(orientationIndex);
restLengths.Add(restLength);
restOrientations.Add(restOrientation);
stiffnesses.Add(Vector3.zero);
}
public override void Clear()
{
base.Clear();
particleIndices.Clear();
orientationIndices.Clear();
restLengths.Clear();
restOrientations.Clear();
stiffnesses.Clear();
}
public float GetRestLength(int index)
{
return restLengths[index];
}
public void SetRestLength(int index, float restLength)
{
restLengths[index] = restLength;
}
public ParticlePair GetParticleIndices(int index)
{
return new ParticlePair(particleIndices[index * 2], particleIndices[index * 2 + 1]);
}
public override void GetParticlesInvolved(int index, List<int> particles)
{
particles.Add(particleIndices[index * 2]);
particles.Add(particleIndices[index * 2 + 1]);
}
protected override void SwapConstraints(int sourceIndex, int destIndex)
{
particleIndices.Swap(sourceIndex * 2 , destIndex * 2);
particleIndices.Swap(sourceIndex * 2 + 1, destIndex * 2 + 1);
orientationIndices.Swap(sourceIndex, destIndex);
restLengths.Swap(sourceIndex, destIndex);
restOrientations.Swap(sourceIndex, destIndex);
stiffnesses.Swap(sourceIndex, destIndex);
}
public override void Merge(ObiActor actor, IObiConstraintsBatch other)
{
var batch = other as ObiStretchShearConstraintsBatch;
var user = actor as IStretchShearConstraintsUser;
if (batch != null && user != null)
{
if (!user.stretchShearConstraintsEnabled)
return;
particleIndices.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 2);
orientationIndices.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
restLengths.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
restOrientations.ResizeUninitialized(lambdas.count + batch.activeConstraintCount);
stiffnesses.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
lambdas.ResizeInitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 3);
restLengths.CopyFrom(batch.restLengths, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
restOrientations.CopyFrom(batch.restOrientations, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
for (int i = 0; i < batch.activeConstraintCount; ++i)
stiffnesses[m_ActiveConstraintCount + i] = user.GetStretchShearCompliance(batch, i);
for (int i = 0; i < batch.activeConstraintCount * 2; ++i)
particleIndices[m_ActiveConstraintCount * 2 + i] = actor.solverIndices[batch.particleIndices[i]];
for (int i = 0; i < batch.activeConstraintCount; ++i)
orientationIndices[m_ActiveConstraintCount + i] = actor.solverIndices[batch.orientationIndices[i]];
base.Merge(actor, other);
}
}
public override void AddToSolver(ObiSolver solver)
{
// Create distance constraints batch directly.
m_BatchImpl = solver.implementation.CreateConstraintsBatch(constraintType) as IStretchShearConstraintsBatchImpl;
if (m_BatchImpl != null)
m_BatchImpl.SetStretchShearConstraints(particleIndices, orientationIndices, restLengths, restOrientations, stiffnesses, lambdas, m_ActiveConstraintCount);
}
public override void RemoveFromSolver(ObiSolver solver)
{
base.RemoveFromSolver(solver);
orientationIndices.Dispose();
restLengths.Dispose();
restOrientations.Dispose();
stiffnesses.Dispose();
//Remove batch:
solver.implementation.DestroyConstraintsBatch(m_BatchImpl as IConstraintsBatchImpl);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 915edc2d24cba477e8a942210f7ea8a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: b3583331769a946aab1e4c59859547b2, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,156 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Obi
{
[Serializable]
public class ObiTetherConstraintsBatch : ObiConstraintsBatch
{
protected ITetherConstraintsBatchImpl m_BatchImpl;
/// <summary>
/// 2 floats per constraint: maximum length and tether scale.
/// </summary>
[HideInInspector] public ObiNativeVector2List maxLengthsScales = new ObiNativeVector2List();
/// <summary>
/// compliance value for each constraint.
/// </summary>
[HideInInspector] public ObiNativeFloatList stiffnesses = new ObiNativeFloatList();
public override Oni.ConstraintType constraintType
{
get { return Oni.ConstraintType.Tether; }
}
public override IConstraintsBatchImpl implementation
{
get { return m_BatchImpl; }
}
public ObiTetherConstraintsBatch(ObiTetherConstraintsData constraints = null) : base()
{
}
public void AddConstraint(Vector2Int indices, float maxLength, float scale)
{
RegisterConstraint();
particleIndices.Add(indices[0]);
particleIndices.Add(indices[1]);
maxLengthsScales.Add(new Vector2(maxLength, scale));
stiffnesses.Add(0);
}
public override void Clear()
{
base.Clear();
particleIndices.Clear();
maxLengthsScales.Clear();
stiffnesses.Clear();
}
public override void GetParticlesInvolved(int index, List<int> particles)
{
particles.Add(particleIndices[index * 2]);
particles.Add(particleIndices[index * 2 + 1]);
}
protected override void SwapConstraints(int sourceIndex, int destIndex)
{
particleIndices.Swap(sourceIndex * 2, destIndex * 2);
particleIndices.Swap(sourceIndex * 2 + 1, destIndex * 2 + 1);
maxLengthsScales.Swap(sourceIndex, destIndex);
stiffnesses.Swap(sourceIndex, destIndex);
}
public override void Merge(ObiActor actor, IObiConstraintsBatch other)
{
var batch = other as ObiTetherConstraintsBatch;
var user = actor as ITetherConstraintsUser;
if (batch != null && user != null)
{
if (!user.tetherConstraintsEnabled)
return;
particleIndices.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 2);
maxLengthsScales.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
stiffnesses.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
lambdas.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
stiffnesses.CopyReplicate(user.tetherCompliance, m_ActiveConstraintCount, batch.activeConstraintCount);
for (int i = 0; i < batch.activeConstraintCount * 2; ++i)
particleIndices[m_ActiveConstraintCount * 2 + i] = actor.solverIndices[batch.particleIndices[i]];
for (int i = 0; i < batch.activeConstraintCount; ++i)
maxLengthsScales[m_ActiveConstraintCount + i] = new Vector2(batch.maxLengthsScales[i].x, user.tetherScale);
base.Merge(actor, other);
}
}
public override void AddToSolver(ObiSolver solver)
{
// Create distance constraints batch directly.
m_BatchImpl = solver.implementation.CreateConstraintsBatch(constraintType) as ITetherConstraintsBatchImpl;
if (m_BatchImpl != null)
m_BatchImpl.SetTetherConstraints(particleIndices, maxLengthsScales, stiffnesses, lambdas, m_ActiveConstraintCount);
}
public override void RemoveFromSolver(ObiSolver solver)
{
base.RemoveFromSolver(solver);
maxLengthsScales.Dispose();
stiffnesses.Dispose();
//Remove batch:
solver.implementation.DestroyConstraintsBatch(m_BatchImpl as IConstraintsBatchImpl);
}
/*public override void AddToSolver(ObiSolver solver)
{
// create and add the implementation:
if (m_Constraints != null && m_Constraints.implementation != null)
{
m_BatchImpl = m_Constraints.implementation.CreateConstraintsBatch();
}
if (m_BatchImpl != null)
{
lambdas.Clear();
for (int i = 0; i < stiffnesses.count; i++)
{
//particleIndices[i * 2] = constraints.GetActor().solverIndices[m_Source.particleIndices[i * 2]];
//particleIndices[i * 2 + 1] = constraints.GetActor().solverIndices[m_Source.particleIndices[i * 2 + 1]];
lambdas.Add(0);
}
m_BatchImpl.SetTetherConstraints(particleIndices, maxLengthsScales, stiffnesses, lambdas, m_ConstraintCount);
m_BatchImpl.SetActiveConstraints(m_ActiveConstraintCount);
}
}
public override void RemoveFromSolver(ObiSolver solver)
{
if (m_Constraints != null && m_Constraints.implementation != null)
m_Constraints.implementation.RemoveBatch(m_BatchImpl);
}*/
public void SetParameters(float compliance, float scale)
{
for (int i = 0; i < stiffnesses.count; i++)
{
stiffnesses[i] = compliance;
maxLengthsScales[i] = new Vector2(maxLengthsScales[i].x, scale);
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 6cf16f1dcc0c34dbd816110ce4b29ed9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 45a4a839cd07d49f698be261ce71ee3c, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,147 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Obi
{
[Serializable]
public class ObiVolumeConstraintsBatch : ObiConstraintsBatch
{
protected IVolumeConstraintsBatchImpl m_BatchImpl;
/// <summary>
/// index of the first triangle for each constraint (exclusive prefix sum).
/// </summary>
[HideInInspector] public ObiNativeIntList firstTriangle = new ObiNativeIntList();
/// <summary>
/// number of triangles for each constraint.
/// </summary>
[HideInInspector] public ObiNativeIntList numTriangles = new ObiNativeIntList();
/// <summary>
/// rest volume for each constraint.
/// </summary>
[HideInInspector] public ObiNativeFloatList restVolumes = new ObiNativeFloatList();
/// <summary>
/// 2 floats per constraint: pressure and stiffness.
/// </summary>
[HideInInspector] public ObiNativeVector2List pressureStiffness = new ObiNativeVector2List();
public override Oni.ConstraintType constraintType
{
get { return Oni.ConstraintType.Volume; }
}
public override IConstraintsBatchImpl implementation
{
get { return m_BatchImpl; }
}
public ObiVolumeConstraintsBatch(ObiVolumeConstraintsData constraints = null) : base()
{
}
public void AddConstraint(int[] triangles, float restVolume)
{
RegisterConstraint();
firstTriangle.Add((int)particleIndices.count / 3);
numTriangles.Add((int)triangles.Length / 3);
restVolumes.Add(restVolume);
pressureStiffness.Add(new Vector2(1,0));
particleIndices.AddRange(triangles);
}
public override void Clear()
{
base.Clear();
particleIndices.Clear();
firstTriangle.Clear();
numTriangles.Clear();
restVolumes.Clear();
pressureStiffness.Clear();
}
public override void GetParticlesInvolved(int index, List<int> particles)
{
//TODO.
}
protected override void SwapConstraints(int sourceIndex, int destIndex)
{
firstTriangle.Swap(sourceIndex, destIndex);
numTriangles.Swap(sourceIndex, destIndex);
restVolumes.Swap(sourceIndex, destIndex);
pressureStiffness.Swap(sourceIndex, destIndex);
}
public override void Merge(ObiActor actor, IObiConstraintsBatch other)
{
var batch = other as ObiVolumeConstraintsBatch;
var user = actor as IVolumeConstraintsUser;
if (batch != null && user != null)
{
if (!user.volumeConstraintsEnabled)
return;
int initialIndexCount = particleIndices.count;
int numActiveTriangles = 0;
for (int i = 0; i < batch.constraintCount; ++i)
numActiveTriangles += batch.numTriangles[i];
particleIndices.ResizeUninitialized(initialIndexCount + numActiveTriangles * 3);
firstTriangle.ResizeUninitialized(firstTriangle.count + batch.activeConstraintCount);
numTriangles.ResizeUninitialized(numTriangles.count + batch.activeConstraintCount);
restVolumes.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
pressureStiffness.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
lambdas.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount);
numTriangles.CopyFrom(batch.numTriangles, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
restVolumes.CopyFrom(batch.restVolumes, 0, m_ActiveConstraintCount, batch.activeConstraintCount);
pressureStiffness.CopyReplicate(new Vector2(user.pressure, user.compressionCompliance), m_ActiveConstraintCount, batch.activeConstraintCount);
for (int i = 0; i < numActiveTriangles * 3; ++i)
particleIndices[initialIndexCount + i] = actor.solverIndices[batch.particleIndices[i]];
for (int i = 0; i < batch.activeConstraintCount + 1; ++i)
firstTriangle[m_ActiveConstraintCount + i] = initialIndexCount/3 + batch.firstTriangle[i];
base.Merge(actor, other);
}
}
public override void AddToSolver(ObiSolver solver)
{
// Create distance constraints batch directly.
m_BatchImpl = solver.implementation.CreateConstraintsBatch(constraintType) as IVolumeConstraintsBatchImpl;
if (m_BatchImpl != null)
m_BatchImpl.SetVolumeConstraints(particleIndices, firstTriangle, numTriangles, restVolumes, pressureStiffness, lambdas, m_ActiveConstraintCount);
}
public override void RemoveFromSolver(ObiSolver solver)
{
base.RemoveFromSolver(solver);
firstTriangle.Dispose();
numTriangles.Dispose();
restVolumes.Dispose();
pressureStiffness.Dispose();
//Remove batch:
solver.implementation.DestroyConstraintsBatch(m_BatchImpl as IConstraintsBatchImpl);
}
public void SetParameters(float compliance, float pressure)
{
Vector2 p = new Vector2(pressure, compliance);
for (int i = 0; i < pressureStiffness.count; i++)
pressureStiffness[i] = p;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 38adc52900fa64209829b6db86f4fd40
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: d9d3ddf824bd449e5b405439ee034b12, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: a4c68760109fb4c9a9fe6cd000123940
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,28 +0,0 @@
using UnityEngine;
using System.Collections;
using System;
namespace Obi
{
public interface IAerodynamicConstraintsUser
{
bool aerodynamicsEnabled
{
get;
set;
}
float GetDrag(ObiAerodynamicConstraintsBatch batch, int constraintIndex);
float GetLift(ObiAerodynamicConstraintsBatch batch, int constraintIndex);
}
[Serializable]
public class ObiAerodynamicConstraintsData : ObiConstraints<ObiAerodynamicConstraintsBatch>
{
public override ObiAerodynamicConstraintsBatch CreateBatch(ObiAerodynamicConstraintsBatch source = null)
{
return new ObiAerodynamicConstraintsBatch();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f82b39fc2deaa46d9bbec616c2e7aaf5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,49 +0,0 @@
using UnityEngine;
using System.Collections;
using System;
namespace Obi
{
public interface IBendConstraintsUser
{
bool bendConstraintsEnabled
{
get;
set;
}
float bendCompliance
{
get;
set;
}
float maxBending
{
get;
set;
}
float plasticYield
{
get;
set;
}
float plasticCreep
{
get;
set;
}
}
[Serializable]
public class ObiBendConstraintsData : ObiConstraints<ObiBendConstraintsBatch>
{
public override ObiBendConstraintsBatch CreateBatch(ObiBendConstraintsBatch source = null)
{
return new ObiBendConstraintsBatch();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: b1c1bcd52cdf746fc8f62059ba5bb9e9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,28 +0,0 @@
using UnityEngine;
using System;
namespace Obi
{
public interface IBendTwistConstraintsUser
{
bool bendTwistConstraintsEnabled
{
get;
set;
}
Vector3 GetBendTwistCompliance(ObiBendTwistConstraintsBatch batch, int constraintIndex);
Vector2 GetBendTwistPlasticity(ObiBendTwistConstraintsBatch batch, int constraintIndex);
}
[Serializable]
public class ObiBendTwistConstraintsData : ObiConstraints<ObiBendTwistConstraintsBatch>
{
public override ObiBendTwistConstraintsBatch CreateBatch(ObiBendTwistConstraintsBatch source = null)
{
return new ObiBendTwistConstraintsBatch();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: e2e8e3c3251694dcfbb9aabbd5ed1a4a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,32 +0,0 @@
using UnityEngine;
using System.Collections;
using System;
namespace Obi
{
public interface IChainConstraintsUser
{
bool chainConstraintsEnabled
{
get;
set;
}
float tightness
{
get;
set;
}
}
[Serializable]
public class ObiChainConstraintsData : ObiConstraints<ObiChainConstraintsBatch>
{
public override ObiChainConstraintsBatch CreateBatch(ObiChainConstraintsBatch source = null)
{
return new ObiChainConstraintsBatch();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 33365683dad7c4ad395bce89c5381081
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,43 +0,0 @@
using UnityEngine;
using System.Collections;
using System;
namespace Obi
{
public interface IDistanceConstraintsUser
{
bool distanceConstraintsEnabled
{
get;
set;
}
float stretchingScale
{
get;
set;
}
float stretchCompliance
{
get;
set;
}
float maxCompression
{
get;
set;
}
}
[Serializable]
public class ObiDistanceConstraintsData : ObiConstraints<ObiDistanceConstraintsBatch>
{
public override ObiDistanceConstraintsBatch CreateBatch(ObiDistanceConstraintsBatch source = null)
{
return new ObiDistanceConstraintsBatch();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 782174d96bf484b98b0dbb103eeb2d1c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,16 +0,0 @@
using UnityEngine;
using System.Collections;
using System;
namespace Obi
{
[Serializable]
public class ObiPinConstraintsData : ObiConstraints<ObiPinConstraintsBatch>
{
public override ObiPinConstraintsBatch CreateBatch(ObiPinConstraintsBatch source = null)
{
return new ObiPinConstraintsBatch();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: b7a2147b44dc24d59a5b57314325ae6c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,16 +0,0 @@
using UnityEngine;
using System.Collections;
using System;
namespace Obi
{
[Serializable]
public class ObiPinholeConstraintsData : ObiConstraints<ObiPinholeConstraintsBatch>
{
public override ObiPinholeConstraintsBatch CreateBatch(ObiPinholeConstraintsBatch source = null)
{
return new ObiPinholeConstraintsBatch();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: caeaf013c17424e0884d22017414ee1c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,55 +0,0 @@
using UnityEngine;
using System.Collections;
using System;
namespace Obi
{
public interface IShapeMatchingConstraintsUser
{
bool shapeMatchingConstraintsEnabled
{
get;
set;
}
float deformationResistance
{
get;
set;
}
float maxDeformation
{
get;
set;
}
float plasticYield
{
get;
set;
}
float plasticCreep
{
get;
set;
}
float plasticRecovery
{
get;
set;
}
}
[Serializable]
public class ObiShapeMatchingConstraintsData : ObiConstraints<ObiShapeMatchingConstraintsBatch>
{
public override ObiShapeMatchingConstraintsBatch CreateBatch(ObiShapeMatchingConstraintsBatch source = null)
{
return new ObiShapeMatchingConstraintsBatch();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 0d275158a9006411cb1a69f84653efcb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,26 +0,0 @@
using UnityEngine;
using System;
namespace Obi
{
public interface ISkinConstraintsUser
{
bool skinConstraintsEnabled
{
get;
set;
}
Vector3 GetSkinRadiiBackstop(ObiSkinConstraintsBatch batch, int constraintIndex);
float GetSkinCompliance(ObiSkinConstraintsBatch batch, int constraintIndex);
}
[Serializable]
public class ObiSkinConstraintsData : ObiConstraints<ObiSkinConstraintsBatch>
{
public override ObiSkinConstraintsBatch CreateBatch(ObiSkinConstraintsBatch source = null)
{
return new ObiSkinConstraintsBatch();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 0bb567aa0489c4b38bf7e6f9b43d953f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,28 +0,0 @@
using UnityEngine;
using System.Collections;
using System;
namespace Obi
{
public interface IStretchShearConstraintsUser
{
bool stretchShearConstraintsEnabled
{
get;
set;
}
Vector3 GetStretchShearCompliance(ObiStretchShearConstraintsBatch batch, int constraintIndex);
}
[Serializable]
public class ObiStretchShearConstraintsData : ObiConstraints<ObiStretchShearConstraintsBatch>
{
public override ObiStretchShearConstraintsBatch CreateBatch(ObiStretchShearConstraintsBatch source = null)
{
return new ObiStretchShearConstraintsBatch();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f8ae3ab8eafd74991858032375e5444f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,38 +0,0 @@
using UnityEngine;
using System.Collections;
using System;
namespace Obi
{
public interface ITetherConstraintsUser
{
bool tetherConstraintsEnabled
{
get;
set;
}
float tetherCompliance
{
get;
set;
}
float tetherScale
{
get;
set;
}
}
[Serializable]
public class ObiTetherConstraintsData : ObiConstraints<ObiTetherConstraintsBatch>
{
public override ObiTetherConstraintsBatch CreateBatch(ObiTetherConstraintsBatch source = null)
{
return new ObiTetherConstraintsBatch();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 10997226d34c34554a17c69f27627e5d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,37 +0,0 @@
using UnityEngine;
using System.Collections;
using System;
namespace Obi
{
public interface IVolumeConstraintsUser
{
bool volumeConstraintsEnabled
{
get;
set;
}
float compressionCompliance
{
get;
set;
}
float pressure
{
get;
set;
}
}
[Serializable]
public class ObiVolumeConstraintsData : ObiConstraints<ObiVolumeConstraintsBatch>
{
public override ObiVolumeConstraintsBatch CreateBatch(ObiVolumeConstraintsBatch source = null)
{
return new ObiVolumeConstraintsBatch();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 55945e863f03047c18b48088708c2935
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,178 +0,0 @@
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;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ef958cf590b69495999edd2bbdd290f7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,37 +0,0 @@
using UnityEngine;
using System.Collections;
namespace Obi
{
public struct StructuralConstraint
{
public IStructuralConstraintBatch batchIndex;
public int constraintIndex;
public float force;
public float restLength
{
get
{
if (batchIndex == null)
return -1;
return batchIndex.GetRestLength(constraintIndex);
}
set
{
if (batchIndex != null)
{
batchIndex.SetRestLength(constraintIndex, value);
}
}
}
public StructuralConstraint(IStructuralConstraintBatch batchIndex, int constraintIndex, float force)
{
this.batchIndex = batchIndex;
this.constraintIndex = constraintIndex;
this.force = force;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 553bc976d8dc04e3fa4a38926a713231
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1 +0,0 @@
using System;

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 9fd5c54becb84484b9b524f897fa9f23
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,706 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using System.IO;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Obi
{
public abstract class ObiActorBlueprint : ScriptableObject, IObiParticleCollection
{
public delegate void BlueprintCallback(ObiActorBlueprint blueprint);
public event BlueprintCallback OnBlueprintGenerate;
[HideInInspector] [SerializeField] protected uint m_Checksum;
[HideInInspector] [SerializeField] protected bool m_Empty = true;
[HideInInspector] [SerializeField] protected bool m_Edited = false; /**< Whether there's been any modifications to blueprint data since generating it. This is used to tell whether it can be re-generated without data loss.*/
[HideInInspector] [SerializeField] protected int m_ActiveParticleCount = 0;
[HideInInspector] [SerializeField] protected int m_InitialActiveParticleCount = 0;
[HideInInspector] [SerializeField] protected Bounds _bounds = new Bounds();
/**Particle components*/
[HideInInspector] public Vector3[] positions = null; /**< Particle positions.*/
[HideInInspector] public Vector4[] restPositions = null; /**< Particle rest positions, used to filter collisions.*/
[HideInInspector] public Vector4[] restNormals = null; /**< Particle local-space normal in xyz, SDF in w. Used for softbody collisions.*/
[HideInInspector] public Quaternion[] orientations = null; /**< Particle orientations.*/
[HideInInspector] public Quaternion[] restOrientations = null; /**< Particle rest orientations.*/
[HideInInspector] public Vector3[] velocities = null; /**< Particle velocities.*/
[HideInInspector] public Vector3[] angularVelocities = null; /**< Particle angular velocities.*/
[HideInInspector] public float[] invMasses = null; /**< Particle inverse masses*/
[HideInInspector] public float[] invRotationalMasses = null;
[FormerlySerializedAs("phases")]
[HideInInspector] public int[] filters = null; /**< Particle filters*/
[HideInInspector] public Vector3[] principalRadii = null; /**< Particle ellipsoid principal radii. These are the ellipsoid radius in each axis.*/
[HideInInspector] public Color[] colors = null; /**< Particle colors (not used by all actors, can be null)*/
/** Simplices **/
[HideInInspector] public int[] points = null;
[HideInInspector] public int[] edges = null;
[HideInInspector] public int[] triangles = null;
/** Constraint components. Each constraint type contains a list of constraint batches.*/
[HideInInspector] public ObiDistanceConstraintsData distanceConstraintsData = null;
[HideInInspector] public ObiBendConstraintsData bendConstraintsData = null;
[HideInInspector] public ObiSkinConstraintsData skinConstraintsData = null;
[HideInInspector] public ObiTetherConstraintsData tetherConstraintsData = null;
[HideInInspector] public ObiStretchShearConstraintsData stretchShearConstraintsData = null;
[HideInInspector] public ObiBendTwistConstraintsData bendTwistConstraintsData = null;
[HideInInspector] public ObiShapeMatchingConstraintsData shapeMatchingConstraintsData = null;
[HideInInspector] public ObiAerodynamicConstraintsData aerodynamicConstraintsData = null;
[HideInInspector] public ObiChainConstraintsData chainConstraintsData = null;
[HideInInspector] public ObiVolumeConstraintsData volumeConstraintsData = null;
/** Particle groups.*/
[HideInInspector] public List<ObiParticleGroup> groups = new List<ObiParticleGroup>();
/**
* Checksum value generated from particle positions and orientations.
*/
public uint checksum
{
get { return m_Checksum; }
}
/**
* Returns the amount of particles used by this blueprint.
*/
public int particleCount
{
get { return positions != null ? positions.Length : 0; }
}
public int activeParticleCount
{
get { return m_ActiveParticleCount; }
}
public Oni.SimplexType simplexTypes
{
get
{
return Oni.SimplexType.Point | // points (single particles) are always available.
(edges != null ? Oni.SimplexType.Edge : 0) |
(triangles != null ? Oni.SimplexType.Triangle : 0);
}
}
/**
* Returns whether this group uses oriented particles.
*/
public bool usesOrientedParticles
{
get
{
return invRotationalMasses != null && invRotationalMasses.Length > 0 &&
orientations != null && orientations.Length > 0;
}
}
public virtual bool usesTethers
{
get { return false; }
}
public bool IsParticleActive(int index)
{
return index < m_ActiveParticleCount;
}
protected virtual void SwapWithFirstInactiveParticle(int index)
{
positions.Swap(index, m_ActiveParticleCount);
restPositions.Swap(index, m_ActiveParticleCount);
restNormals.Swap(index, m_ActiveParticleCount);
orientations.Swap(index, m_ActiveParticleCount);
restOrientations.Swap(index, m_ActiveParticleCount);
velocities.Swap(index, m_ActiveParticleCount);
angularVelocities.Swap(index, m_ActiveParticleCount);
invMasses.Swap(index, m_ActiveParticleCount);
invRotationalMasses.Swap(index, m_ActiveParticleCount);
filters.Swap(index, m_ActiveParticleCount);
principalRadii.Swap(index, m_ActiveParticleCount);
colors.Swap(index, m_ActiveParticleCount);
m_Edited = true;
}
public bool edited
{
get { return m_Edited; }
set { m_Edited = value; }
}
/**
* Activates one particle. This operation preserves the relative order of all particles.
*/
public bool ActivateParticle(int index)
{
if (IsParticleActive(index))
return false;
SwapWithFirstInactiveParticle(index);
m_ActiveParticleCount++;
return true;
}
/**
* Deactivates one particle. This operation does not preserve the relative order of other particles, because the last active particle will
* swap positions with the particle being deactivated.
*/
public bool DeactivateParticle(int index)
{
if (!IsParticleActive(index))
return false;
m_ActiveParticleCount--;
SwapWithFirstInactiveParticle(index);
return true;
}
public bool empty
{
get { return m_Empty; }
}
public void RecalculateBounds()
{
if (positions.Length > 0)
{
_bounds = new Bounds(positions[0], Vector3.zero);
for (int i = 1; i < positions.Length; ++i)
_bounds.Encapsulate(positions[i]);
}
else
_bounds = new Bounds();
}
public Bounds bounds
{
get { return _bounds; }
}
protected void GenerateChecksum()
{
using (MemoryStream ms = new MemoryStream())
{
if (positions != null)
foreach (var p in positions) ms.Concatenate(p);
if (orientations != null)
foreach (var o in orientations) ms.Concatenate(o);
ms.Flush();
m_Checksum = ObiUtils.Adler32(ms.ToArray());
}
}
public IEnumerable<IObiConstraints> GetConstraints()
{
if (distanceConstraintsData != null && distanceConstraintsData.batchCount > 0)
yield return distanceConstraintsData;
if (bendConstraintsData != null && bendConstraintsData.batchCount > 0)
yield return bendConstraintsData;
if (skinConstraintsData != null && skinConstraintsData.batchCount > 0)
yield return skinConstraintsData;
if (tetherConstraintsData != null && tetherConstraintsData.batchCount > 0)
yield return tetherConstraintsData;
if (stretchShearConstraintsData != null && stretchShearConstraintsData.batchCount > 0)
yield return stretchShearConstraintsData;
if (bendTwistConstraintsData != null && bendTwistConstraintsData.batchCount > 0)
yield return bendTwistConstraintsData;
if (shapeMatchingConstraintsData != null && shapeMatchingConstraintsData.batchCount > 0)
yield return shapeMatchingConstraintsData;
if (aerodynamicConstraintsData != null && aerodynamicConstraintsData.batchCount > 0)
yield return aerodynamicConstraintsData;
if (chainConstraintsData != null && chainConstraintsData.batchCount > 0)
yield return chainConstraintsData;
if (volumeConstraintsData != null && volumeConstraintsData.batchCount > 0)
yield return volumeConstraintsData;
}
public IObiConstraints GetConstraintsByType(Oni.ConstraintType type)
{
switch (type)
{
case Oni.ConstraintType.Distance: return distanceConstraintsData;
case Oni.ConstraintType.Bending: return bendConstraintsData;
case Oni.ConstraintType.Skin: return skinConstraintsData;
case Oni.ConstraintType.Tether: return tetherConstraintsData;
case Oni.ConstraintType.BendTwist: return bendTwistConstraintsData;
case Oni.ConstraintType.StretchShear: return stretchShearConstraintsData;
case Oni.ConstraintType.ShapeMatching: return shapeMatchingConstraintsData;
case Oni.ConstraintType.Aerodynamics: return aerodynamicConstraintsData;
case Oni.ConstraintType.Chain: return chainConstraintsData;
case Oni.ConstraintType.Volume: return volumeConstraintsData;
default: return null;
}
}
public int GetParticleRuntimeIndex(int blueprintIndex)
{
return blueprintIndex;
}
public Vector3 GetParticlePosition(int index)
{
if (positions != null && index < positions.Length)
{
return positions[index];
}
return Vector3.zero;
}
public Quaternion GetParticleOrientation(int index)
{
if (orientations != null && index < orientations.Length)
{
return orientations[index];
}
return Quaternion.identity;
}
public Vector3 GetParticleRestPosition(int index)
{
if (restPositions != null && index < restPositions.Length)
{
return restPositions[index];
}
return Vector3.zero;
}
public Quaternion GetParticleRestOrientation(int index)
{
if (restOrientations != null && index < restOrientations.Length)
{
return restOrientations[index];
}
return Quaternion.identity;
}
public void GetParticleAnisotropy(int index, ref Vector4 b1, ref Vector4 b2, ref Vector4 b3)
{
if (orientations != null && index < orientations.Length)
{
Quaternion orientation = orientations[index];
b1 = orientation * Vector3.right;
b2 = orientation * Vector3.up;
b3 = orientation * Vector3.forward;
b1[3] = principalRadii[index][0];
b2[3] = principalRadii[index][1];
b3[3] = principalRadii[index][2];
}
else
{
b1[3] = b2[3] = b3[3] = principalRadii[index][0];
}
}
public float GetParticleMaxRadius(int index)
{
if (principalRadii != null && index < principalRadii.Length)
{
return principalRadii[index][0];
}
return 0;
}
public Color GetParticleColor(int index)
{
if (colors != null && index < colors.Length)
{
return colors[index];
}
else
return Color.white;
}
public void GenerateImmediate()
{
var g = Generate();
while (g.MoveNext()) { }
}
public IEnumerator Generate()
{
Clear();
IEnumerator g = Initialize();
while (g.MoveNext())
yield return g.Current;
RecalculateBounds();
m_Empty = false;
m_InitialActiveParticleCount = m_ActiveParticleCount;
foreach (IObiConstraints constraints in GetConstraints())
for (int i = 0; i < constraints.batchCount; ++i)
constraints.GetBatch(i).initialActiveConstraintCount = constraints.GetBatch(i).activeConstraintCount;
CommitBlueprintChanges();
#if UNITY_EDITOR
if (!Application.isPlaying)
{
EditorUtility.SetDirty(this);
}
#endif
OnBlueprintGenerate?.Invoke(this);
}
// Called at the end of blueprint generation. Also automatically called when exiting blueprint editor.
// This generates a checksum for the blueprint, and in some case extra data (such as default skinmaps for cloth and softbodies).
public virtual void CommitBlueprintChanges()
{
GenerateChecksum();
}
public void Clear()
{
m_Empty = true;
edited = false;
m_ActiveParticleCount = 0;
positions = null;
restPositions = null;
restNormals = null;
orientations = null;
restOrientations = null;
velocities = null;
angularVelocities = null;
invMasses = null;
invRotationalMasses = null;
filters = null;
principalRadii = null;
colors = null;
points = null;
edges = null;
triangles = null;
distanceConstraintsData = null;
bendConstraintsData = null;
skinConstraintsData = null;
tetherConstraintsData = null;
bendTwistConstraintsData = null;
stretchShearConstraintsData = null;
shapeMatchingConstraintsData = null;
aerodynamicConstraintsData = null;
chainConstraintsData = null;
volumeConstraintsData = null;
}
public ObiParticleGroup InsertNewParticleGroup(string name, int index, bool saveImmediately = true)
{
if (index >= 0 && index <= groups.Count)
{
ObiParticleGroup group = ScriptableObject.CreateInstance<ObiParticleGroup>();
group.SetSourceBlueprint(this);
group.name = name;
#if UNITY_EDITOR
if (!Application.isPlaying)
{
AssetDatabase.AddObjectToAsset(group, this);
Undo.RegisterCreatedObjectUndo(group, "Insert particle group");
Undo.RecordObject(this, "Insert particle group");
groups.Insert(index, group);
if (EditorUtility.IsPersistent(this))
{
EditorUtility.SetDirty(this);
if (saveImmediately)
AssetDatabase.SaveAssetIfDirty(this);
}
}
else
#endif
{
groups.Insert(index, group);
}
edited = true;
return group;
}
return null;
}
public ObiParticleGroup AppendNewParticleGroup(string name, bool saveImmediately = true)
{
return InsertNewParticleGroup(name, groups.Count, saveImmediately);
}
public bool RemoveParticleGroupAt(int index, bool saveImmediately = true)
{
if (index >= 0 && index < groups.Count)
{
#if UNITY_EDITOR
if (!Application.isPlaying)
{
Undo.RecordObject(this, "Remove particle group");
var group = groups[index];
groups.RemoveAt(index);
if (group != null)
Undo.DestroyObjectImmediate(group);
if (EditorUtility.IsPersistent(this))
{
EditorUtility.SetDirty(this);
if (saveImmediately)
AssetDatabase.SaveAssetIfDirty(this);
}
}
else
#endif
{
var group = groups[index];
groups.RemoveAt(index);
if (group != null)
DestroyImmediate(group, true);
}
edited = true;
return true;
}
return false;
}
public bool SetParticleGroupName(int index, string name, bool saveImmediately = true)
{
if (index >= 0 && index < groups.Count)
{
#if UNITY_EDITOR
if (!Application.isPlaying)
{
Undo.RecordObject(this, "Set particle group name");
groups[index].name = name;
if (EditorUtility.IsPersistent(this))
{
EditorUtility.SetDirty(this);
if (saveImmediately)
AssetDatabase.SaveAssetIfDirty(this);
}
}
else
#endif
{
groups[index].name = name;
}
edited = true;
return true;
}
return false;
}
public void ClearParticleGroups(bool registerUndo = true, bool saveImmediately = true)
{
if (groups.Count == 0) return;
#if UNITY_EDITOR
if (!Application.isPlaying)
{
if (registerUndo)
{
Undo.RecordObject(this, "Clear particle groups");
for (int i = 0; i < groups.Count; ++i)
if (groups[i] != null)
Undo.DestroyObjectImmediate(groups[i]);
}
else
{
for (int i = 0; i < groups.Count; ++i)
if (groups[i] != null)
DestroyImmediate(groups[i], true);
}
if (EditorUtility.IsPersistent(this))
{
EditorUtility.SetDirty(this);
if (saveImmediately)
AssetDatabase.SaveAssetIfDirty(this);
}
}
else
#endif
{
for (int i = 0; i < groups.Count; ++i)
if (groups[i] != null)
DestroyImmediate(groups[i], true);
}
groups.Clear();
}
private bool IsParticleSharedInConstraint(int index, List<int> particles, bool[] selected)
{
bool containsCurrent = false;
bool containsUnselected = false;
for (int k = 0; k < particles.Count; ++k)
{
containsCurrent |= particles[k] == index;
containsUnselected |= !selected[particles[k]];
if (containsCurrent && containsUnselected)
{
return true;
}
}
return false;
}
private bool DoesParticleShareConstraints(IObiConstraints constraints, int index, List<int> particles, bool[] selected)
{
bool shared = false;
for (int i = 0; i < constraints.batchCount; ++i)
{
var batch = constraints.GetBatch(i);
for (int j = 0; j < batch.activeConstraintCount; ++j)
{
particles.Clear();
batch.GetParticlesInvolved(j, particles);
if (shared |= IsParticleSharedInConstraint(index, particles, selected))
break;
}
if (shared)
break;
}
return shared;
}
private void DeactivateConstraintsWithInactiveParticles(IObiConstraints constraints, List<int> particles)
{
for (int j = 0; j < constraints.batchCount; ++j)
{
var batch = constraints.GetBatch(j);
for (int i = batch.activeConstraintCount - 1; i >= 0; --i)
{
particles.Clear();
batch.GetParticlesInvolved(i, particles);
for (int k = 0; k < particles.Count; ++k)
{
if (!IsParticleActive(particles[k]))
{
batch.DeactivateConstraint(i);
break;
}
}
}
}
edited = true;
}
private void ParticlesSwappedInGroups(int index, int newIndex)
{
// Update groups:
foreach (ObiParticleGroup group in groups)
{
for (int i = 0; i < group.particleIndices.Count; ++i)
{
if (group.particleIndices[i] == newIndex)
group.particleIndices[i] = index;
else if (group.particleIndices[i] == index)
group.particleIndices[i] = newIndex;
}
}
edited = true;
}
public virtual void RemoveSelectedParticles(ref bool[] selected, bool optimize = true)
{
List<int> particles = new List<int>();
// iterate over all particles and get those selected ones that are only constrained to other selected ones.
for (int i = activeParticleCount - 1; i >= 0; --i)
{
// if the particle is not selected for optimization, skip it.
if (!selected[i])
continue;
// look if the particle shares distance or shape matching constraints with an unselected particle.
bool shared = false;
if (optimize)
{
shared |= DoesParticleShareConstraints(distanceConstraintsData, i, particles, selected);
shared |= DoesParticleShareConstraints(bendConstraintsData, i, particles, selected);
shared |= DoesParticleShareConstraints(shapeMatchingConstraintsData, i, particles, selected);
}
if (!shared)
{
if (DeactivateParticle(i))
{
selected.Swap(i, m_ActiveParticleCount);
// Update constraints:
foreach (IObiConstraints constraints in GetConstraints())
for (int j = 0; j < constraints.batchCount; ++j)
constraints.GetBatch(j).ParticlesSwapped(i, m_ActiveParticleCount);
// Update groups:
ParticlesSwappedInGroups(i, m_ActiveParticleCount);
}
}
}
// deactivate all constraints that reference inactive particles:
foreach (IObiConstraints constraints in GetConstraints())
DeactivateConstraintsWithInactiveParticles(constraints, particles);
CommitBlueprintChanges();
edited = true;
}
public void RestoreRemovedParticles()
{
m_ActiveParticleCount = m_InitialActiveParticleCount;
foreach (IObiConstraints constraints in GetConstraints())
for (int j = 0; j < constraints.batchCount; ++j)
constraints.GetBatch(j).activeConstraintCount = constraints.GetBatch(j).initialActiveConstraintCount;
CommitBlueprintChanges();
}
public virtual void GenerateTethers(bool[] selected) { }
public virtual void ClearTethers() { }
protected abstract IEnumerator Initialize();
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: e041cee7fba0844ba933278f278090ce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: d0123218ec6144d0983c099fc7339924, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,13 +0,0 @@
using UnityEngine;
using System.Collections;
namespace Obi
{
public abstract class ObiMeshBasedActorBlueprint : ObiActorBlueprint
{
public Mesh inputMesh; /**< Mesh used to generate the blueprint.*/
public Vector3 scale = Vector3.one;
public Quaternion rotation = Quaternion.identity;
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 5a20734f05b7e41d89888f99cc0e88f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,35 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Obi
{
[Serializable]
public class ObiParticleGroup : ScriptableObject
{
public List<int> particleIndices = new List<int>() { };
public ObiActorBlueprint m_Blueprint = null;
public ObiActorBlueprint blueprint
{
get { return m_Blueprint; }
}
public void SetSourceBlueprint(ObiActorBlueprint blueprint)
{
this.m_Blueprint = blueprint;
}
public int Count
{
get { return particleIndices.Count; }
}
public bool ContainsParticle(int index)
{
return particleIndices.Contains(index);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 775ad4994fda946d1a5936c7e2dfc785
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: