去掉obi,使用自写绳索
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e272b09fdfb9d401aa0514e09d3eb842
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12f3679c3b69b41b68f65afab6db4c56
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f23dea5b75e2c432282b0f62513267ed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7aacef50ee7794d0c9d6c77ef761d142
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d642dbf4a869c4761b38ce3f65e22f05
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4c68760109fb4c9a9fe6cd000123940
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f82b39fc2deaa46d9bbec616c2e7aaf5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1c1bcd52cdf746fc8f62059ba5bb9e9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e2e8e3c3251694dcfbb9aabbd5ed1a4a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 33365683dad7c4ad395bce89c5381081
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 782174d96bf484b98b0dbb103eeb2d1c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7a2147b44dc24d59a5b57314325ae6c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: caeaf013c17424e0884d22017414ee1c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d275158a9006411cb1a69f84653efcb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0bb567aa0489c4b38bf7e6f9b43d953f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8ae3ab8eafd74991858032375e5444f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10997226d34c34554a17c69f27627e5d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 55945e863f03047c18b48088708c2935
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef958cf590b69495999edd2bbdd290f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 553bc976d8dc04e3fa4a38926a713231
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1 +0,0 @@
|
||||
using System;
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9fd5c54becb84484b9b524f897fa9f23
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a20734f05b7e41d89888f99cc0e88f2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 775ad4994fda946d1a5936c7e2dfc785
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user