添加插件
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1816ef976b3b64da7bf7a71a91e97d0f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeBox
|
||||
{
|
||||
private ComputeShader shader;
|
||||
private int kernel;
|
||||
|
||||
public ComputeBox()
|
||||
{
|
||||
shader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/BoxShape"));
|
||||
kernel = shader.FindKernel("GenerateContacts");
|
||||
}
|
||||
|
||||
public void GenerateContacts(ComputeSolverImpl solver, ComputeColliderWorld world)
|
||||
{
|
||||
shader.SetInt("maxContacts", ComputeColliderWorld.maxContacts);
|
||||
shader.SetInt("pointCount", solver.simplexCounts.pointCount);
|
||||
shader.SetInt("edgeCount", solver.simplexCounts.edgeCount);
|
||||
shader.SetInt("triangleCount", solver.simplexCounts.triangleCount);
|
||||
shader.SetInt("surfaceCollisionIterations", solver.abstraction.parameters.surfaceCollisionIterations);
|
||||
shader.SetFloat("surfaceCollisionTolerance", solver.abstraction.parameters.surfaceCollisionTolerance);
|
||||
shader.SetFloat("collisionMargin", solver.abstraction.parameters.collisionMargin);
|
||||
|
||||
shader.SetBuffer(kernel, "worldToSolver", solver.worldToSolverBuffer);
|
||||
shader.SetBuffer(kernel, "simplices", solver.simplices);
|
||||
shader.SetBuffer(kernel, "positions", solver.positionsBuffer);
|
||||
shader.SetBuffer(kernel, "orientations", solver.orientationsBuffer);
|
||||
shader.SetBuffer(kernel, "velocities", solver.velocitiesBuffer);
|
||||
shader.SetBuffer(kernel, "principalRadii", solver.principalRadiiBuffer);
|
||||
shader.SetBuffer(kernel, "transforms", world.transformsBuffer);
|
||||
shader.SetBuffer(kernel, "shapes", world.shapesBuffer);
|
||||
shader.SetBuffer(kernel, "contactPairs", world.contactPairs);
|
||||
shader.SetBuffer(kernel, "contactOffsetsPerType", world.contactOffsetsPerType);
|
||||
shader.SetBuffer(kernel, "contacts", solver.abstraction.colliderContacts.computeBuffer);
|
||||
shader.SetBuffer(kernel, "dispatchBuffer", world.dispatchBuffer);
|
||||
shader.DispatchIndirect(kernel, world.dispatchBuffer, 32 + 16 * (int)Oni.ShapeType.Box);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 669f5cb47192b4a08864250bd4ba3872
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeCapsule
|
||||
{
|
||||
private ComputeShader shader;
|
||||
private int kernel;
|
||||
|
||||
public ComputeCapsule()
|
||||
{
|
||||
shader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/CapsuleShape"));
|
||||
kernel = shader.FindKernel("GenerateContacts");
|
||||
}
|
||||
|
||||
public void GenerateContacts(ComputeSolverImpl solver, ComputeColliderWorld world)
|
||||
{
|
||||
shader.SetInt("maxContacts", ComputeColliderWorld.maxContacts);
|
||||
shader.SetInt("pointCount", solver.simplexCounts.pointCount);
|
||||
shader.SetInt("edgeCount", solver.simplexCounts.edgeCount);
|
||||
shader.SetInt("triangleCount", solver.simplexCounts.triangleCount);
|
||||
shader.SetInt("surfaceCollisionIterations", solver.abstraction.parameters.surfaceCollisionIterations);
|
||||
shader.SetFloat("surfaceCollisionTolerance", solver.abstraction.parameters.surfaceCollisionTolerance);
|
||||
shader.SetFloat("collisionMargin", solver.abstraction.parameters.collisionMargin);
|
||||
|
||||
shader.SetBuffer(kernel, "worldToSolver", solver.worldToSolverBuffer);
|
||||
shader.SetBuffer(kernel, "simplices", solver.simplices);
|
||||
shader.SetBuffer(kernel, "positions", solver.positionsBuffer);
|
||||
shader.SetBuffer(kernel, "orientations", solver.orientationsBuffer);
|
||||
shader.SetBuffer(kernel, "velocities", solver.velocitiesBuffer);
|
||||
shader.SetBuffer(kernel, "principalRadii", solver.principalRadiiBuffer);
|
||||
shader.SetBuffer(kernel, "transforms", world.transformsBuffer);
|
||||
shader.SetBuffer(kernel, "shapes", world.shapesBuffer);
|
||||
shader.SetBuffer(kernel, "contactPairs", world.contactPairs);
|
||||
shader.SetBuffer(kernel, "contactOffsetsPerType", world.contactOffsetsPerType);
|
||||
shader.SetBuffer(kernel, "contacts", solver.abstraction.colliderContacts.computeBuffer);
|
||||
shader.SetBuffer(kernel, "dispatchBuffer", world.dispatchBuffer);
|
||||
shader.DispatchIndirect(kernel, world.dispatchBuffer, 32 + 16 * (int)Oni.ShapeType.Capsule);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8577fc7696f14a5bad666ce7bdbd424
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,479 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeColliderWorld : MonoBehaviour, IColliderWorldImpl
|
||||
{
|
||||
public int referenceCount { get; private set; } = 0;
|
||||
|
||||
public int colliderCount { get; private set; } = 0;
|
||||
public int rigidbodyCount { get; private set; } = -1; // make sure the buffer is created even if there's 0.
|
||||
public int forceZoneCount { get; private set; } = -1; // make sure the buffer is created even if there's 0.
|
||||
public int materialCount { get; private set; } = -1; // make sure the buffer is created even if there's 0.
|
||||
|
||||
public int triangleMeshCount { get; private set; } = -1;
|
||||
public int edgeMeshCount { get; private set; } = -1;
|
||||
public int distanceFieldCount { get; private set; } = -1;
|
||||
public int heightFieldCount { get; private set; } = -1;
|
||||
|
||||
private ComputePrefixSum prefixSum;
|
||||
|
||||
private ComputeShader gridShader;
|
||||
private int buildKernel;
|
||||
private int gridPopulationKernel;
|
||||
private int sortKernel;
|
||||
private int contactsKernel;
|
||||
private int clearKernel;
|
||||
private int prefixSumPairsKernel;
|
||||
private int sortPairsKernel;
|
||||
private int applyForceZonesKernel;
|
||||
private int writeForceZoneResultsKernel;
|
||||
|
||||
public GraphicsBuffer materialsBuffer;
|
||||
public GraphicsBuffer aabbsBuffer;
|
||||
public GraphicsBuffer transformsBuffer;
|
||||
public GraphicsBuffer shapesBuffer;
|
||||
public GraphicsBuffer forceZonesBuffer;
|
||||
public GraphicsBuffer rigidbodiesBuffer;
|
||||
public GraphicsBuffer sortedColliderIndicesBuffer;
|
||||
|
||||
public GraphicsBuffer cellIndicesBuffer; //for each collider, the IDs of the 8 cells it covers.
|
||||
public GraphicsBuffer cellOffsetsBuffer; //for each cell, start offset in the sorted span indices buffer.
|
||||
|
||||
public GraphicsBuffer cellCountsBuffer; // for each cell, how many colliders in it.
|
||||
public GraphicsBuffer offsetInCells; // for each collider, its offset in each of the 8 cells.
|
||||
public GraphicsBuffer levelPopulation; // buffer storing amount of entries in each grid level
|
||||
|
||||
private GraphicsBuffer colliderTypeCounts; // amount of contacts against each collider type.
|
||||
public GraphicsBuffer unsortedContactPairs; // unsorted contact pairs.
|
||||
public GraphicsBuffer contactPairs; // list of contact pairs.
|
||||
public GraphicsBuffer contactOffsetsPerType; // offset in the contact pairs array for each collider type.
|
||||
|
||||
public GraphicsBuffer dispatchBuffer; // dispatch info for iterating trough contacts.
|
||||
|
||||
public GraphicsBuffer heightFieldHeaders;
|
||||
public GraphicsBuffer heightFieldSamples;
|
||||
|
||||
public GraphicsBuffer distanceFieldHeaders;
|
||||
public GraphicsBuffer dfNodes;
|
||||
|
||||
public GraphicsBuffer edgeMeshHeaders;
|
||||
public GraphicsBuffer edgeBihNodes;
|
||||
public GraphicsBuffer edges;
|
||||
public GraphicsBuffer edgeVertices;
|
||||
|
||||
public GraphicsBuffer triangleMeshHeaders;
|
||||
public GraphicsBuffer bihNodes;
|
||||
public GraphicsBuffer triangles;
|
||||
public GraphicsBuffer vertices;
|
||||
|
||||
public const int maxContacts = 512 * 512;
|
||||
public const int maxCells = 512 * 512;
|
||||
public const int cellsPerCollider = 8;
|
||||
private const int maxGridLevels = 24;
|
||||
private uint[] colliderCountClear = new uint[Oni.ColliderShapeTypeCount];
|
||||
private uint[] dispatchClear = { 0, 1, 1, 0, // contacts
|
||||
0, 1, 1, 0, // pairs
|
||||
0, 1, 1, 0, // spheres
|
||||
0, 1, 1, 0, // boxes
|
||||
0, 1, 1, 0, // capsules
|
||||
0, 1, 1, 0, // heighmaps
|
||||
0, 1, 1, 0, // tri mesh
|
||||
0, 1, 1, 0, // edge mesh
|
||||
0, 1, 1, 0, // distance field
|
||||
};
|
||||
|
||||
private ComputeSphere spheres;
|
||||
private ComputeBox boxes;
|
||||
private ComputeCapsule capsules;
|
||||
private ComputeTriangleMesh triangleMeshes;
|
||||
private ComputeEdgeMesh edgeMeshes;
|
||||
private ComputeDistanceField distanceFields;
|
||||
private ComputeHeightField heightFields;
|
||||
|
||||
// for each particle in parallel:
|
||||
// determine its cell span in the collider grid.
|
||||
// iterate over all of them, generating contacts.
|
||||
|
||||
// we just need to get collider indices from each cell.
|
||||
// sort by cell, store offset for each cell.
|
||||
|
||||
// each collider keeps track of 8 uints: IDs of the cells it overlaps. unused are invalid.
|
||||
// each collider must know offset within each cell: another 8 units per collider.
|
||||
// we can keep using the same system as we did with particles.
|
||||
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
ObiColliderWorld.GetInstance().RegisterImplementation(this);
|
||||
|
||||
prefixSum = new ComputePrefixSum(maxCells);
|
||||
|
||||
gridShader = Resources.Load<ComputeShader>("Compute/ColliderGrid");
|
||||
buildKernel = gridShader.FindKernel("BuildUnsortedList");
|
||||
gridPopulationKernel = gridShader.FindKernel("FindPopulatedLevels");
|
||||
sortKernel = gridShader.FindKernel("SortList");
|
||||
contactsKernel = gridShader.FindKernel("BuildContactList");
|
||||
clearKernel = gridShader.FindKernel("Clear");
|
||||
prefixSumPairsKernel = gridShader.FindKernel("PrefixSumColliderCounts");
|
||||
sortPairsKernel = gridShader.FindKernel("SortContactPairs");
|
||||
applyForceZonesKernel = gridShader.FindKernel("ApplyForceZones");
|
||||
writeForceZoneResultsKernel = gridShader.FindKernel("WriteForceZoneResults");
|
||||
|
||||
gridShader.SetInt("shapeTypeCount", Oni.ColliderShapeTypeCount);
|
||||
gridShader.SetInt("maxContacts", maxContacts);
|
||||
gridShader.SetInt("colliderCount", colliderCount);
|
||||
gridShader.SetInt("cellsPerCollider", cellsPerCollider);
|
||||
gridShader.SetInt("maxCells", maxCells);
|
||||
|
||||
cellOffsetsBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, maxCells, 4);
|
||||
cellCountsBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, maxCells, 4);
|
||||
|
||||
// first entry is amount of non-empty levels in the grid.
|
||||
// next maxGridLevels entries hold the indices of the non-empty levels.
|
||||
// final maxGridLevels entries hold the population of each level.
|
||||
levelPopulation = new GraphicsBuffer(GraphicsBuffer.Target.Structured, maxGridLevels + 1, 4);
|
||||
|
||||
colliderTypeCounts = new GraphicsBuffer(GraphicsBuffer.Target.Structured, Oni.ColliderShapeTypeCount, 4);
|
||||
contactOffsetsPerType = new GraphicsBuffer(GraphicsBuffer.Target.Structured, Oni.ColliderShapeTypeCount + 1, 4);
|
||||
unsortedContactPairs = new GraphicsBuffer(GraphicsBuffer.Target.Structured, maxContacts, 8);
|
||||
|
||||
contactPairs = new GraphicsBuffer(GraphicsBuffer.Target.Structured, maxContacts, 8);
|
||||
dispatchBuffer = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, dispatchClear.Length, sizeof(uint));
|
||||
|
||||
spheres = new ComputeSphere();
|
||||
boxes = new ComputeBox();
|
||||
capsules = new ComputeCapsule();
|
||||
triangleMeshes = new ComputeTriangleMesh();
|
||||
edgeMeshes = new ComputeEdgeMesh();
|
||||
distanceFields = new ComputeDistanceField();
|
||||
heightFields = new ComputeHeightField();
|
||||
}
|
||||
|
||||
public void OnDestroy()
|
||||
{
|
||||
ObiColliderWorld.GetInstance().UnregisterImplementation(this);
|
||||
|
||||
prefixSum.Dispose();
|
||||
|
||||
cellOffsetsBuffer.Dispose();
|
||||
cellCountsBuffer.Dispose();
|
||||
levelPopulation.Dispose();
|
||||
|
||||
contactPairs.Dispose();
|
||||
dispatchBuffer.Dispose();
|
||||
|
||||
colliderTypeCounts.Dispose();
|
||||
contactOffsetsPerType.Dispose();
|
||||
unsortedContactPairs.Dispose();
|
||||
|
||||
if (cellIndicesBuffer != null)
|
||||
cellIndicesBuffer.Dispose();
|
||||
if (offsetInCells != null)
|
||||
offsetInCells.Dispose();
|
||||
if (sortedColliderIndicesBuffer != null)
|
||||
sortedColliderIndicesBuffer.Dispose();
|
||||
}
|
||||
|
||||
public void IncreaseReferenceCount()
|
||||
{
|
||||
referenceCount++;
|
||||
}
|
||||
public void DecreaseReferenceCount()
|
||||
{
|
||||
if (--referenceCount <= 0 && gameObject != null)
|
||||
DestroyImmediate(gameObject);
|
||||
}
|
||||
|
||||
public void SetColliders(ObiNativeColliderShapeList shapes, ObiNativeAabbList bounds, ObiNativeAffineTransformList transforms)
|
||||
{
|
||||
if (colliderCount != shapes.count || aabbsBuffer == null || !aabbsBuffer.IsValid())
|
||||
aabbsBuffer = bounds.AsComputeBuffer<Aabb>();
|
||||
else
|
||||
bounds.Upload();
|
||||
|
||||
if (colliderCount != shapes.count || shapesBuffer == null || !shapesBuffer.IsValid())
|
||||
shapesBuffer = shapes.AsComputeBuffer<ColliderShape>();
|
||||
else
|
||||
shapes.Upload();
|
||||
|
||||
if (colliderCount != shapes.count || transformsBuffer == null || !transformsBuffer.IsValid())
|
||||
transformsBuffer = transforms.AsComputeBuffer<AffineTransform>();
|
||||
else
|
||||
transforms.Upload();
|
||||
|
||||
// Only update in case the amount of colliders has changed:
|
||||
if (colliderCount != shapes.count)
|
||||
{
|
||||
colliderCount = shapes.count;
|
||||
gridShader.SetInt("colliderCount", colliderCount);
|
||||
|
||||
if (cellIndicesBuffer != null)
|
||||
{
|
||||
cellIndicesBuffer.Release();
|
||||
cellIndicesBuffer = null;
|
||||
}
|
||||
if (offsetInCells != null)
|
||||
{
|
||||
offsetInCells.Release();
|
||||
offsetInCells = null;
|
||||
}
|
||||
if (sortedColliderIndicesBuffer != null)
|
||||
{
|
||||
sortedColliderIndicesBuffer.Release();
|
||||
sortedColliderIndicesBuffer = null;
|
||||
}
|
||||
|
||||
if (colliderCount > 0)
|
||||
{
|
||||
cellIndicesBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, colliderCount * cellsPerCollider, 4);
|
||||
offsetInCells = new GraphicsBuffer(GraphicsBuffer.Target.Structured, colliderCount * cellsPerCollider, 4);
|
||||
sortedColliderIndicesBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, colliderCount * cellsPerCollider, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetForceZones(ObiNativeForceZoneList forceZones)
|
||||
{
|
||||
// Changing the count of a NativeList should not invalidate compute buffer. Only need to invalidate if *capacity* changes, it's up to the user to
|
||||
// regenerate the compute buffer in case it is needed, or Uplodad() the new data in case it is not (because our compute buffer maps full capacity, instead of only up to count)
|
||||
if (forceZoneCount != forceZones.count || forceZonesBuffer == null || !forceZonesBuffer.IsValid())
|
||||
{
|
||||
forceZoneCount = forceZones.count;
|
||||
forceZonesBuffer = forceZones.SafeAsComputeBuffer<ForceZone>();
|
||||
}
|
||||
else
|
||||
forceZones.Upload();
|
||||
}
|
||||
|
||||
public void SetRigidbodies(ObiNativeRigidbodyList rigidbody)
|
||||
{
|
||||
if (rigidbodyCount != rigidbody.count || rigidbodiesBuffer == null || !rigidbodiesBuffer.IsValid())
|
||||
{
|
||||
rigidbodyCount = rigidbody.count;
|
||||
rigidbodiesBuffer = rigidbody.SafeAsComputeBuffer<ColliderRigidbody>();
|
||||
}
|
||||
else
|
||||
rigidbody.Upload();
|
||||
}
|
||||
|
||||
public void SetCollisionMaterials(ObiNativeCollisionMaterialList materials)
|
||||
{
|
||||
if (materialCount != materials.count || materialsBuffer == null || !materialsBuffer.IsValid())
|
||||
{
|
||||
materialCount = materials.count;
|
||||
materialsBuffer = materials.SafeAsComputeBuffer<CollisionMaterial>();
|
||||
}
|
||||
else
|
||||
materials.Upload();
|
||||
}
|
||||
|
||||
public void SetTriangleMeshData(ObiNativeTriangleMeshHeaderList headers, ObiNativeBIHNodeList nodes, ObiNativeTriangleList triangles, ObiNativeVector3List vertices)
|
||||
{
|
||||
if (triangleMeshCount != headers.count || triangleMeshHeaders == null || !triangleMeshHeaders.IsValid())
|
||||
{
|
||||
triangleMeshCount = headers.count;
|
||||
triangleMeshHeaders = headers.SafeAsComputeBuffer<TriangleMeshHeader>();
|
||||
bihNodes = nodes.SafeAsComputeBuffer<BIHNode>();
|
||||
this.triangles = triangles.SafeAsComputeBuffer<Triangle>();
|
||||
this.vertices = vertices.SafeAsComputeBuffer<Vector3>();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetEdgeMeshData(ObiNativeEdgeMeshHeaderList headers, ObiNativeBIHNodeList nodes, ObiNativeEdgeList edges, ObiNativeVector2List vertices)
|
||||
{
|
||||
if (edgeMeshCount != headers.count || edgeMeshHeaders == null || !edgeMeshHeaders.IsValid())
|
||||
{
|
||||
edgeMeshCount = headers.count;
|
||||
edgeMeshHeaders = headers.SafeAsComputeBuffer<EdgeMeshHeader>();
|
||||
edgeBihNodes = nodes.SafeAsComputeBuffer<BIHNode>();
|
||||
this.edges = edges.SafeAsComputeBuffer<Edge>();
|
||||
edgeVertices = vertices.SafeAsComputeBuffer<Vector2>();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDistanceFieldData(ObiNativeDistanceFieldHeaderList headers, ObiNativeDFNodeList nodes)
|
||||
{
|
||||
if (distanceFieldCount != headers.count || distanceFieldHeaders == null || !distanceFieldHeaders.IsValid())
|
||||
{
|
||||
distanceFieldCount = headers.count;
|
||||
distanceFieldHeaders = headers.SafeAsComputeBuffer<DistanceFieldHeader>();
|
||||
dfNodes = nodes.SafeAsComputeBuffer<DFNode>();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetHeightFieldData(ObiNativeHeightFieldHeaderList headers, ObiNativeFloatList samples)
|
||||
{
|
||||
if (heightFieldCount != headers.count || heightFieldHeaders == null || !heightFieldHeaders.IsValid())
|
||||
{
|
||||
heightFieldCount = headers.count;
|
||||
heightFieldHeaders = headers.SafeAsComputeBuffer<HeightFieldHeader>();
|
||||
heightFieldSamples = samples.SafeAsComputeBuffer<float>();
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateWorld(float deltaTime)
|
||||
{
|
||||
if (colliderCount > 0)
|
||||
{
|
||||
|
||||
int colliderThreadGroups = ComputeMath.ThreadGroupCount(colliderCount, 128);
|
||||
int capacityThreadGroups = ComputeMath.ThreadGroupCount(colliderCount * 8, 128);
|
||||
int cellThreadGroups = ComputeMath.ThreadGroupCount(maxCells, 128);
|
||||
|
||||
// clear grid:
|
||||
gridShader.SetBuffer(clearKernel, "cellOffsets", cellOffsetsBuffer);
|
||||
gridShader.SetBuffer(clearKernel, "cellIndices", cellIndicesBuffer);
|
||||
gridShader.SetBuffer(clearKernel, "cellCounts", cellCountsBuffer);
|
||||
gridShader.SetBuffer(clearKernel, "levelPopulation", levelPopulation);
|
||||
gridShader.Dispatch(clearKernel, Mathf.Max(cellThreadGroups, capacityThreadGroups), 1, 1);
|
||||
|
||||
// build cell list:
|
||||
gridShader.SetBuffer(buildKernel, "aabbs", aabbsBuffer);
|
||||
gridShader.SetBuffer(buildKernel, "shapes", shapesBuffer);
|
||||
gridShader.SetBuffer(buildKernel, "rigidbodies", rigidbodiesBuffer);
|
||||
gridShader.SetBuffer(buildKernel, "collisionMaterials", materialsBuffer);
|
||||
gridShader.SetBuffer(buildKernel, "cellIndices", cellIndicesBuffer);
|
||||
gridShader.SetBuffer(buildKernel, "cellCounts", cellCountsBuffer);
|
||||
gridShader.SetBuffer(buildKernel, "offsetInCells", offsetInCells);
|
||||
gridShader.SetBuffer(buildKernel, "levelPopulation", levelPopulation);
|
||||
gridShader.Dispatch(buildKernel, colliderThreadGroups, 1, 1);
|
||||
|
||||
// find populated grid levels:
|
||||
gridShader.SetBuffer(gridPopulationKernel, "levelPopulation", levelPopulation);
|
||||
gridShader.Dispatch(gridPopulationKernel, 1, 1, 1);
|
||||
|
||||
// prefix sum:
|
||||
prefixSum.Sum(cellCountsBuffer, cellOffsetsBuffer);
|
||||
|
||||
// sort particle indices:
|
||||
gridShader.SetBuffer(sortKernel, "sortedColliderIndices", sortedColliderIndicesBuffer);
|
||||
gridShader.SetBuffer(sortKernel, "offsetInCells", offsetInCells);
|
||||
gridShader.SetBuffer(sortKernel, "cellIndices", cellIndicesBuffer);
|
||||
gridShader.SetBuffer(sortKernel, "cellOffsets", cellOffsetsBuffer);
|
||||
gridShader.Dispatch(sortKernel, capacityThreadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyForceZones(ComputeSolverImpl solver, float deltaTime)
|
||||
{
|
||||
if (colliderCount > 0)
|
||||
{
|
||||
if (solver.activeParticlesBuffer != null && solver.simplices != null && forceZonesBuffer != null)
|
||||
{
|
||||
gridShader.SetInt("pointCount", solver.simplexCounts.pointCount);
|
||||
gridShader.SetInt("edgeCount", solver.simplexCounts.edgeCount);
|
||||
gridShader.SetInt("triangleCount", solver.simplexCounts.triangleCount);
|
||||
gridShader.SetFloat("deltaTime", deltaTime);
|
||||
|
||||
gridShader.SetBuffer(applyForceZonesKernel, "contacts", solver.abstraction.colliderContacts.computeBuffer);
|
||||
gridShader.SetBuffer(applyForceZonesKernel, "dispatchBuffer", dispatchBuffer);
|
||||
|
||||
gridShader.SetBuffer(applyForceZonesKernel, "simplices", solver.simplices);
|
||||
gridShader.SetBuffer(applyForceZonesKernel, "positions", solver.positionsBuffer);
|
||||
gridShader.SetBuffer(applyForceZonesKernel, "velocities", solver.velocitiesBuffer);
|
||||
gridShader.SetBuffer(applyForceZonesKernel, "colors", solver.colorsBuffer);
|
||||
gridShader.SetBuffer(applyForceZonesKernel, "invMasses", solver.invMassesBuffer);
|
||||
|
||||
gridShader.SetBuffer(applyForceZonesKernel, "transforms", transformsBuffer);
|
||||
gridShader.SetBuffer(applyForceZonesKernel, "shapes", shapesBuffer);
|
||||
gridShader.SetBuffer(applyForceZonesKernel, "forceZones", forceZonesBuffer);
|
||||
gridShader.SetBuffer(applyForceZonesKernel, "deltasAsInt", solver.positionDeltasIntBuffer);
|
||||
gridShader.SetBuffer(applyForceZonesKernel, "orientationDeltasAsInt", solver.orientationDeltasIntBuffer);
|
||||
gridShader.SetBuffer(applyForceZonesKernel, "worldToSolver", solver.worldToSolverBuffer);
|
||||
|
||||
gridShader.DispatchIndirect(applyForceZonesKernel, dispatchBuffer);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(solver.activeParticleCount, 128);
|
||||
gridShader.SetInt("particleCount", solver.activeParticleCount);
|
||||
|
||||
gridShader.SetBuffer(writeForceZoneResultsKernel, "activeParticles", solver.activeParticlesBuffer);
|
||||
gridShader.SetBuffer(writeForceZoneResultsKernel, "externalForces", solver.externalForcesBuffer);
|
||||
gridShader.SetBuffer(writeForceZoneResultsKernel, "life", solver.lifeBuffer);
|
||||
gridShader.SetBuffer(writeForceZoneResultsKernel, "wind", solver.windBuffer);
|
||||
gridShader.SetBuffer(writeForceZoneResultsKernel, "deltasAsInt", solver.positionDeltasIntBuffer);
|
||||
gridShader.SetBuffer(writeForceZoneResultsKernel, "orientationDeltasAsInt", solver.orientationDeltasIntBuffer);
|
||||
|
||||
gridShader.Dispatch(writeForceZoneResultsKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void GenerateContacts(ComputeSolverImpl solver, float deltaTime)
|
||||
{
|
||||
if (colliderCount > 0)
|
||||
{
|
||||
int particleThreadGroups = ComputeMath.ThreadGroupCount(solver.simplexCounts.simplexCount, 128);
|
||||
|
||||
colliderTypeCounts.SetData(colliderCountClear);
|
||||
dispatchBuffer.SetData(dispatchClear);
|
||||
|
||||
if (solver.activeParticlesBuffer != null && solver.simplices != null)
|
||||
{
|
||||
solver.abstraction.colliderContacts.computeBuffer.SetCounterValue(0);
|
||||
|
||||
gridShader.SetInt("pointCount", solver.simplexCounts.pointCount);
|
||||
gridShader.SetInt("edgeCount", solver.simplexCounts.edgeCount);
|
||||
gridShader.SetInt("triangleCount", solver.simplexCounts.triangleCount);
|
||||
|
||||
gridShader.SetFloat("colliderCCD", solver.abstraction.parameters.colliderCCD);
|
||||
gridShader.SetInt("surfaceCollisionIterations", solver.abstraction.parameters.surfaceCollisionIterations);
|
||||
gridShader.SetFloat("surfaceCollisionTolerance", solver.abstraction.parameters.surfaceCollisionTolerance);
|
||||
gridShader.SetInt("mode", (int)solver.abstraction.parameters.mode);
|
||||
gridShader.SetFloat("deltaTime", deltaTime);
|
||||
|
||||
gridShader.SetBuffer(contactsKernel, "simplices", solver.simplices);
|
||||
gridShader.SetBuffer(contactsKernel, "simplexBounds", solver.simplexBounds);
|
||||
gridShader.SetBuffer(contactsKernel, "positions", solver.positionsBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "orientations", solver.orientationsBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "principalRadii", solver.principalRadiiBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "filters", solver.filtersBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "sortedColliderIndices", sortedColliderIndicesBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "aabbs", aabbsBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "transforms", transformsBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "shapes", shapesBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "rigidbodies", rigidbodiesBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "collisionMaterials", materialsBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "collisionMaterialIndices", solver.collisionMaterialIndexBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "cellIndices", cellIndicesBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "cellOffsets", cellOffsetsBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "cellCounts", cellCountsBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "levelPopulation", levelPopulation);
|
||||
|
||||
gridShader.SetBuffer(contactsKernel, "solverToWorld", solver.solverToWorldBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "colliderTypeCounts", colliderTypeCounts);
|
||||
gridShader.SetBuffer(contactsKernel, "unsortedContactPairs", unsortedContactPairs);
|
||||
gridShader.SetBuffer(contactsKernel, "dispatchBuffer", dispatchBuffer);
|
||||
|
||||
gridShader.Dispatch(contactsKernel, particleThreadGroups, 1, 1);
|
||||
|
||||
gridShader.SetBuffer(prefixSumPairsKernel, "colliderTypeCounts", colliderTypeCounts);
|
||||
gridShader.SetBuffer(prefixSumPairsKernel, "contactOffsetsPerType", contactOffsetsPerType);
|
||||
gridShader.SetBuffer(prefixSumPairsKernel, "dispatchBuffer", dispatchBuffer);
|
||||
|
||||
gridShader.Dispatch(prefixSumPairsKernel, 1, 1, 1);
|
||||
|
||||
gridShader.SetBuffer(sortPairsKernel, "shapes", shapesBuffer);
|
||||
gridShader.SetBuffer(sortPairsKernel, "unsortedContactPairs", unsortedContactPairs);
|
||||
gridShader.SetBuffer(sortPairsKernel, "contactPairs", contactPairs);
|
||||
gridShader.SetBuffer(sortPairsKernel, "colliderTypeCounts", colliderTypeCounts);
|
||||
gridShader.SetBuffer(sortPairsKernel, "contactOffsetsPerType", contactOffsetsPerType);
|
||||
gridShader.SetBuffer(sortPairsKernel, "dispatchBuffer", dispatchBuffer);
|
||||
|
||||
gridShader.DispatchIndirect(sortPairsKernel, dispatchBuffer, 16);
|
||||
|
||||
boxes.GenerateContacts(solver, this);
|
||||
spheres.GenerateContacts(solver, this);
|
||||
capsules.GenerateContacts(solver, this);
|
||||
triangleMeshes.GenerateContacts(solver, this, deltaTime);
|
||||
edgeMeshes.GenerateContacts(solver, this, deltaTime);
|
||||
distanceFields.GenerateContacts(solver, this, deltaTime);
|
||||
heightFields.GenerateContacts(solver, this, deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce0ddc77554954cd78643d83b0505396
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeDistanceField
|
||||
{
|
||||
private ComputeShader shader;
|
||||
private int kernel;
|
||||
|
||||
public ComputeDistanceField()
|
||||
{
|
||||
shader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/DistanceFieldShape"));
|
||||
kernel = shader.FindKernel("GenerateContacts");
|
||||
}
|
||||
|
||||
public void GenerateContacts(ComputeSolverImpl solver, ComputeColliderWorld world, float deltaTime)
|
||||
{
|
||||
if (world.distanceFieldHeaders != null)
|
||||
{
|
||||
shader.SetInt("maxContacts", ComputeColliderWorld.maxContacts);
|
||||
shader.SetInt("pointCount", solver.simplexCounts.pointCount);
|
||||
shader.SetInt("edgeCount", solver.simplexCounts.edgeCount);
|
||||
shader.SetInt("triangleCount", solver.simplexCounts.triangleCount);
|
||||
shader.SetInt("surfaceCollisionIterations", solver.abstraction.parameters.surfaceCollisionIterations);
|
||||
shader.SetFloat("surfaceCollisionTolerance", solver.abstraction.parameters.surfaceCollisionTolerance);
|
||||
shader.SetFloat("collisionMargin", solver.abstraction.parameters.collisionMargin);
|
||||
shader.SetFloat("deltaTime", deltaTime);
|
||||
|
||||
shader.SetBuffer(kernel, "worldToSolver", solver.worldToSolverBuffer);
|
||||
shader.SetBuffer(kernel, "simplices", solver.simplices);
|
||||
shader.SetBuffer(kernel, "positions", solver.positionsBuffer);
|
||||
shader.SetBuffer(kernel, "orientations", solver.orientationsBuffer);
|
||||
shader.SetBuffer(kernel, "velocities", solver.velocitiesBuffer);
|
||||
shader.SetBuffer(kernel, "principalRadii", solver.principalRadiiBuffer);
|
||||
shader.SetBuffer(kernel, "transforms", world.transformsBuffer);
|
||||
shader.SetBuffer(kernel, "shapes", world.shapesBuffer);
|
||||
shader.SetBuffer(kernel, "contactPairs", world.contactPairs);
|
||||
shader.SetBuffer(kernel, "contactOffsetsPerType", world.contactOffsetsPerType);
|
||||
shader.SetBuffer(kernel, "contacts", solver.abstraction.colliderContacts.computeBuffer);
|
||||
shader.SetBuffer(kernel, "dispatchBuffer", world.dispatchBuffer);
|
||||
|
||||
shader.SetBuffer(kernel, "distanceFieldHeaders", world.distanceFieldHeaders);
|
||||
shader.SetBuffer(kernel, "dfNodes", world.dfNodes);
|
||||
|
||||
shader.DispatchIndirect(kernel, world.dispatchBuffer, 32 + 16 * (int)Oni.ShapeType.SignedDistanceField);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e43826d84a91b447c88f6d65a6e329ac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeEdgeMesh
|
||||
{
|
||||
private ComputeShader shader;
|
||||
private int kernel;
|
||||
|
||||
public ComputeEdgeMesh()
|
||||
{
|
||||
shader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/EdgeMeshShape"));
|
||||
kernel = shader.FindKernel("GenerateContacts");
|
||||
}
|
||||
|
||||
public void GenerateContacts(ComputeSolverImpl solver, ComputeColliderWorld world, float deltaTime)
|
||||
{
|
||||
if (world.edgeMeshHeaders != null)
|
||||
{
|
||||
shader.SetInt("maxContacts", ComputeColliderWorld.maxContacts);
|
||||
shader.SetInt("pointCount", solver.simplexCounts.pointCount);
|
||||
shader.SetInt("edgeCount", solver.simplexCounts.edgeCount);
|
||||
shader.SetInt("triangleCount", solver.simplexCounts.triangleCount);
|
||||
shader.SetInt("surfaceCollisionIterations", solver.abstraction.parameters.surfaceCollisionIterations);
|
||||
shader.SetFloat("surfaceCollisionTolerance", solver.abstraction.parameters.surfaceCollisionTolerance);
|
||||
shader.SetFloat("collisionMargin", solver.abstraction.parameters.collisionMargin);
|
||||
shader.SetFloat("deltaTime", deltaTime);
|
||||
|
||||
shader.SetBuffer(kernel, "worldToSolver", solver.worldToSolverBuffer);
|
||||
shader.SetBuffer(kernel, "simplices", solver.simplices);
|
||||
shader.SetBuffer(kernel, "simplexBounds", solver.simplexBounds);
|
||||
shader.SetBuffer(kernel, "positions", solver.positionsBuffer);
|
||||
shader.SetBuffer(kernel, "orientations", solver.orientationsBuffer);
|
||||
shader.SetBuffer(kernel, "velocities", solver.velocitiesBuffer);
|
||||
shader.SetBuffer(kernel, "principalRadii", solver.principalRadiiBuffer);
|
||||
shader.SetBuffer(kernel, "transforms", world.transformsBuffer);
|
||||
shader.SetBuffer(kernel, "shapes", world.shapesBuffer);
|
||||
shader.SetBuffer(kernel, "contactPairs", world.contactPairs);
|
||||
shader.SetBuffer(kernel, "contactOffsetsPerType", world.contactOffsetsPerType);
|
||||
shader.SetBuffer(kernel, "contacts", solver.abstraction.colliderContacts.computeBuffer);
|
||||
shader.SetBuffer(kernel, "dispatchBuffer", world.dispatchBuffer);
|
||||
|
||||
shader.SetBuffer(kernel, "edgeMeshHeaders", world.edgeMeshHeaders);
|
||||
shader.SetBuffer(kernel, "edgeBihNodes", world.edgeBihNodes);
|
||||
shader.SetBuffer(kernel, "edges", world.edges);
|
||||
shader.SetBuffer(kernel, "edgeVertices", world.edgeVertices);
|
||||
|
||||
shader.DispatchIndirect(kernel, world.dispatchBuffer, 32 + 16 * (int)Oni.ShapeType.EdgeMesh);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6191dad6170694a7c8f9eca0cd733e7a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,51 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeHeightField
|
||||
{
|
||||
private ComputeShader shader;
|
||||
private int kernel;
|
||||
|
||||
public ComputeHeightField()
|
||||
{
|
||||
shader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/HeightfieldShape"));
|
||||
kernel = shader.FindKernel("GenerateContacts");
|
||||
}
|
||||
|
||||
public void GenerateContacts(ComputeSolverImpl solver, ComputeColliderWorld world, float deltaTime)
|
||||
{
|
||||
if (world.heightFieldHeaders != null)
|
||||
{
|
||||
shader.SetInt("maxContacts", ComputeColliderWorld.maxContacts);
|
||||
shader.SetInt("pointCount", solver.simplexCounts.pointCount);
|
||||
shader.SetInt("edgeCount", solver.simplexCounts.edgeCount);
|
||||
shader.SetInt("triangleCount", solver.simplexCounts.triangleCount);
|
||||
shader.SetInt("surfaceCollisionIterations", solver.abstraction.parameters.surfaceCollisionIterations);
|
||||
shader.SetFloat("surfaceCollisionTolerance", solver.abstraction.parameters.surfaceCollisionTolerance);
|
||||
shader.SetFloat("collisionMargin", solver.abstraction.parameters.collisionMargin);
|
||||
shader.SetFloat("deltaTime", deltaTime);
|
||||
|
||||
shader.SetBuffer(kernel, "worldToSolver", solver.worldToSolverBuffer);
|
||||
shader.SetBuffer(kernel, "simplices", solver.simplices);
|
||||
shader.SetBuffer(kernel, "simplexBounds", solver.simplexBounds);
|
||||
shader.SetBuffer(kernel, "positions", solver.positionsBuffer);
|
||||
shader.SetBuffer(kernel, "orientations", solver.orientationsBuffer);
|
||||
shader.SetBuffer(kernel, "velocities", solver.velocitiesBuffer);
|
||||
shader.SetBuffer(kernel, "principalRadii", solver.principalRadiiBuffer);
|
||||
shader.SetBuffer(kernel, "transforms", world.transformsBuffer);
|
||||
shader.SetBuffer(kernel, "shapes", world.shapesBuffer);
|
||||
shader.SetBuffer(kernel, "contactPairs", world.contactPairs);
|
||||
shader.SetBuffer(kernel, "contactOffsetsPerType", world.contactOffsetsPerType);
|
||||
shader.SetBuffer(kernel, "contacts", solver.abstraction.colliderContacts.computeBuffer);
|
||||
shader.SetBuffer(kernel, "dispatchBuffer", world.dispatchBuffer);
|
||||
|
||||
shader.SetBuffer(kernel, "heightFieldHeaders", world.heightFieldHeaders);
|
||||
shader.SetBuffer(kernel, "heightFieldSamples", world.heightFieldSamples);
|
||||
|
||||
shader.DispatchIndirect(kernel, world.dispatchBuffer, 32 + 16 * (int)Oni.ShapeType.Heightmap);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c209374faec0f47adacedb911e8582fd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeSphere
|
||||
{
|
||||
private ComputeShader shader;
|
||||
private int kernel;
|
||||
|
||||
public ComputeSphere()
|
||||
{
|
||||
shader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/SphereShape"));
|
||||
kernel = shader.FindKernel("GenerateContacts");
|
||||
}
|
||||
|
||||
public void GenerateContacts(ComputeSolverImpl solver, ComputeColliderWorld world)
|
||||
{
|
||||
shader.SetInt("maxContacts", ComputeColliderWorld.maxContacts);
|
||||
shader.SetInt("pointCount", solver.simplexCounts.pointCount);
|
||||
shader.SetInt("edgeCount", solver.simplexCounts.edgeCount);
|
||||
shader.SetInt("triangleCount", solver.simplexCounts.triangleCount);
|
||||
shader.SetInt("surfaceCollisionIterations", solver.abstraction.parameters.surfaceCollisionIterations);
|
||||
shader.SetFloat("surfaceCollisionTolerance", solver.abstraction.parameters.surfaceCollisionTolerance);
|
||||
shader.SetFloat("collisionMargin", solver.abstraction.parameters.collisionMargin);
|
||||
|
||||
shader.SetBuffer(kernel, "worldToSolver", solver.worldToSolverBuffer);
|
||||
shader.SetBuffer(kernel, "simplices", solver.simplices);
|
||||
shader.SetBuffer(kernel, "positions", solver.positionsBuffer);
|
||||
shader.SetBuffer(kernel, "orientations", solver.orientationsBuffer);
|
||||
shader.SetBuffer(kernel, "velocities", solver.velocitiesBuffer);
|
||||
shader.SetBuffer(kernel, "principalRadii", solver.principalRadiiBuffer);
|
||||
shader.SetBuffer(kernel, "transforms", world.transformsBuffer);
|
||||
shader.SetBuffer(kernel, "shapes", world.shapesBuffer);
|
||||
shader.SetBuffer(kernel, "contactPairs", world.contactPairs);
|
||||
shader.SetBuffer(kernel, "contactOffsetsPerType", world.contactOffsetsPerType);
|
||||
shader.SetBuffer(kernel, "contacts", solver.abstraction.colliderContacts.computeBuffer);
|
||||
shader.SetBuffer(kernel, "dispatchBuffer", world.dispatchBuffer);
|
||||
shader.DispatchIndirect(kernel, world.dispatchBuffer, 32 + 16 * (int)Oni.ShapeType.Sphere);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8994093c1331f405b92c10a6401791d3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeTriangleMesh
|
||||
{
|
||||
private ComputeShader shader;
|
||||
private int kernel;
|
||||
|
||||
public ComputeTriangleMesh()
|
||||
{
|
||||
shader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/TriangleMeshShape"));
|
||||
kernel = shader.FindKernel("GenerateContacts");
|
||||
}
|
||||
|
||||
public void GenerateContacts(ComputeSolverImpl solver, ComputeColliderWorld world, float deltaTime)
|
||||
{
|
||||
if (world.triangleMeshHeaders != null)
|
||||
{
|
||||
shader.SetInt("maxContacts", ComputeColliderWorld.maxContacts);
|
||||
shader.SetInt("pointCount", solver.simplexCounts.pointCount);
|
||||
shader.SetInt("edgeCount", solver.simplexCounts.edgeCount);
|
||||
shader.SetInt("triangleCount", solver.simplexCounts.triangleCount);
|
||||
shader.SetInt("surfaceCollisionIterations", solver.abstraction.parameters.surfaceCollisionIterations);
|
||||
shader.SetFloat("surfaceCollisionTolerance", solver.abstraction.parameters.surfaceCollisionTolerance);
|
||||
shader.SetFloat("collisionMargin", solver.abstraction.parameters.collisionMargin);
|
||||
shader.SetFloat("deltaTime", deltaTime);
|
||||
|
||||
shader.SetBuffer(kernel, "worldToSolver", solver.worldToSolverBuffer);
|
||||
shader.SetBuffer(kernel, "simplices", solver.simplices);
|
||||
shader.SetBuffer(kernel, "simplexBounds", solver.simplexBounds);
|
||||
shader.SetBuffer(kernel, "positions", solver.positionsBuffer);
|
||||
shader.SetBuffer(kernel, "orientations", solver.orientationsBuffer);
|
||||
shader.SetBuffer(kernel, "velocities", solver.velocitiesBuffer);
|
||||
shader.SetBuffer(kernel, "principalRadii", solver.principalRadiiBuffer);
|
||||
shader.SetBuffer(kernel, "transforms", world.transformsBuffer);
|
||||
shader.SetBuffer(kernel, "shapes", world.shapesBuffer);
|
||||
shader.SetBuffer(kernel, "contactPairs", world.contactPairs);
|
||||
shader.SetBuffer(kernel, "contactOffsetsPerType", world.contactOffsetsPerType);
|
||||
shader.SetBuffer(kernel, "contacts", solver.abstraction.colliderContacts.computeBuffer);
|
||||
shader.SetBuffer(kernel, "dispatchBuffer", world.dispatchBuffer);
|
||||
|
||||
shader.SetBuffer(kernel, "triangleMeshHeaders", world.triangleMeshHeaders);
|
||||
shader.SetBuffer(kernel, "bihNodes", world.bihNodes);
|
||||
shader.SetBuffer(kernel, "triangles", world.triangles);
|
||||
shader.SetBuffer(kernel, "vertices", world.vertices);
|
||||
|
||||
shader.DispatchIndirect(kernel, world.dispatchBuffer, 32 + 16 * (int)Oni.ShapeType.TriangleMesh);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f52cda7e406964ef4bf980e6ff1f91ec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,245 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
|
||||
public class SpatialQueries
|
||||
{
|
||||
private ComputePrefixSum prefixSum;
|
||||
|
||||
private ComputeShader gridShader;
|
||||
private int buildKernel;
|
||||
private int gridPopulationKernel;
|
||||
private int sortKernel;
|
||||
private int contactsKernel;
|
||||
private int clearKernel;
|
||||
private int prefixSumPairsKernel;
|
||||
private int sortPairsKernel;
|
||||
|
||||
public GraphicsBuffer sortedShapeIndicesBuffer;
|
||||
|
||||
public GraphicsBuffer cellIndicesBuffer; //for each collider, the IDs of the 8 cells it covers.
|
||||
public GraphicsBuffer cellOffsetsBuffer; //for each cell, start offset in the sorted span indices buffer.
|
||||
|
||||
public GraphicsBuffer cellCountsBuffer; // for each cell, how many colliders in it.
|
||||
public GraphicsBuffer offsetInCells; // for each collider, its offset in each of the 8 cells.
|
||||
public GraphicsBuffer levelPopulation; // buffer storing the lowest and highest populated level.
|
||||
|
||||
private GraphicsBuffer queryTypeCounts; // amount of contacts against each collider type.
|
||||
public GraphicsBuffer unsortedContactPairs; // unsorted contact pairs.
|
||||
public GraphicsBuffer contactPairs; // list of contact pairs.
|
||||
public GraphicsBuffer contactOffsetsPerType; // offset in the contact pairs array for each collider type.
|
||||
|
||||
public GraphicsBuffer dispatchBuffer; // dispatch info for iterating trough contacts.
|
||||
|
||||
private const int maxCells = 512 * 512;
|
||||
private const int cellsPerShape = 8;
|
||||
private const int maxGridLevels = 24;
|
||||
private uint[] queryCountClear = new uint[Oni.QueryTypeCount];
|
||||
private uint[] dispatchClear = { 0, 1, 1, 0, // contacts
|
||||
0, 1, 1, 0, // pairs
|
||||
0, 1, 1, 0, // spheres
|
||||
0, 1, 1, 0, // boxes
|
||||
0, 1, 1, 0 // rays
|
||||
};
|
||||
|
||||
private ComputeSphereQuery spheres;
|
||||
private ComputeBoxQuery boxes;
|
||||
private ComputeRayQuery rays;
|
||||
|
||||
public SpatialQueries(uint capacity)
|
||||
{
|
||||
gridShader = Resources.Load<ComputeShader>("Compute/SpatialQueries");
|
||||
buildKernel = gridShader.FindKernel("BuildUnsortedList");
|
||||
gridPopulationKernel = gridShader.FindKernel("FindPopulatedLevels");
|
||||
sortKernel = gridShader.FindKernel("SortList");
|
||||
contactsKernel = gridShader.FindKernel("BuildContactList");
|
||||
clearKernel = gridShader.FindKernel("Clear");
|
||||
prefixSumPairsKernel = gridShader.FindKernel("PrefixSumColliderCounts");
|
||||
sortPairsKernel = gridShader.FindKernel("SortContactPairs");
|
||||
|
||||
gridShader.SetInt("shapeTypeCount", Oni.QueryTypeCount);
|
||||
gridShader.SetInt("cellsPerShape", cellsPerShape);
|
||||
gridShader.SetInt("maxCells", (int)maxCells);
|
||||
|
||||
cellOffsetsBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, maxCells, 4);
|
||||
cellCountsBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, maxCells, 4);
|
||||
levelPopulation = new GraphicsBuffer(GraphicsBuffer.Target.Structured, maxGridLevels + 1, 4);
|
||||
dispatchBuffer = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, dispatchClear.Length, sizeof(uint));
|
||||
|
||||
queryTypeCounts = new GraphicsBuffer(GraphicsBuffer.Target.Structured, Oni.QueryTypeCount, 4);
|
||||
contactOffsetsPerType = new GraphicsBuffer(GraphicsBuffer.Target.Structured, Oni.QueryTypeCount + 1, 4);
|
||||
|
||||
prefixSum = new ComputePrefixSum(maxCells);
|
||||
spheres = new ComputeSphereQuery();
|
||||
boxes = new ComputeBoxQuery();
|
||||
rays = new ComputeRayQuery();
|
||||
|
||||
SetCapacity(capacity);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
prefixSum?.Dispose();
|
||||
|
||||
cellOffsetsBuffer?.Dispose();
|
||||
cellCountsBuffer?.Dispose();
|
||||
levelPopulation?.Dispose();
|
||||
dispatchBuffer?.Dispose();
|
||||
|
||||
queryTypeCounts?.Dispose();
|
||||
contactOffsetsPerType?.Dispose();
|
||||
|
||||
DisposeOfResultsData();
|
||||
DisposeOfQueryData();
|
||||
}
|
||||
|
||||
private void DisposeOfResultsData()
|
||||
{
|
||||
contactPairs?.Dispose();
|
||||
unsortedContactPairs?.Dispose();
|
||||
}
|
||||
|
||||
private void DisposeOfQueryData()
|
||||
{
|
||||
cellIndicesBuffer?.Dispose();
|
||||
offsetInCells?.Dispose();
|
||||
sortedShapeIndicesBuffer?.Dispose();
|
||||
}
|
||||
|
||||
private void SetCapacity(uint capacity)
|
||||
{
|
||||
DisposeOfResultsData();
|
||||
|
||||
gridShader.SetInt("maxResults", (int)capacity);
|
||||
|
||||
if (capacity > 0)
|
||||
{
|
||||
unsortedContactPairs = new GraphicsBuffer(GraphicsBuffer.Target.Structured, (int)capacity, 8);
|
||||
contactPairs = new GraphicsBuffer(GraphicsBuffer.Target.Structured, (int)capacity, 8);
|
||||
}
|
||||
}
|
||||
|
||||
public void SpatialQuery(ComputeSolverImpl solver,
|
||||
GraphicsBuffer shapes,
|
||||
GraphicsBuffer transforms,
|
||||
GraphicsBuffer results)
|
||||
{
|
||||
results.SetCounterValue(0);
|
||||
|
||||
if (solver.activeParticlesBuffer == null || solver.simplices == null)
|
||||
return;
|
||||
|
||||
// If the maximum amount of query results has changed, set capacity:
|
||||
if (contactPairs == null || !contactPairs.IsValid() || contactPairs.count != solver.abstraction.maxQueryResults)
|
||||
SetCapacity(solver.abstraction.maxQueryResults);
|
||||
|
||||
// In case we still have zero capacity, just bail out.
|
||||
if (contactPairs == null || !contactPairs.IsValid())
|
||||
return;
|
||||
|
||||
// Check whether we need to reallocate space for queries:
|
||||
if (cellIndicesBuffer == null || !cellIndicesBuffer.IsValid() || shapes.count * cellsPerShape >= cellIndicesBuffer.count)
|
||||
{
|
||||
DisposeOfQueryData();
|
||||
|
||||
cellIndicesBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, shapes.count * cellsPerShape * 2, 4);
|
||||
offsetInCells = new GraphicsBuffer(GraphicsBuffer.Target.Structured, shapes.count * cellsPerShape * 2, 4);
|
||||
sortedShapeIndicesBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, shapes.count * cellsPerShape * 2, 4);
|
||||
}
|
||||
|
||||
gridShader.SetInt("queryCount", shapes.count);
|
||||
|
||||
int particleThreadGroups = ComputeMath.ThreadGroupCount(solver.simplexCounts.simplexCount, 128);
|
||||
int shapeThreadGroups = ComputeMath.ThreadGroupCount(shapes.count, 128);
|
||||
int capacityThreadGroups = ComputeMath.ThreadGroupCount(shapes.count * 8, 128);
|
||||
int cellThreadGroups = ComputeMath.ThreadGroupCount(maxCells, 128);
|
||||
|
||||
queryTypeCounts.SetData(queryCountClear);
|
||||
dispatchBuffer.SetData(dispatchClear);
|
||||
|
||||
// clear grid:
|
||||
gridShader.SetBuffer(clearKernel, "cellOffsets", cellOffsetsBuffer);
|
||||
gridShader.SetBuffer(clearKernel, "cellIndices", cellIndicesBuffer);
|
||||
gridShader.SetBuffer(clearKernel, "cellCounts", cellCountsBuffer);
|
||||
gridShader.SetBuffer(clearKernel, "levelPopulation", levelPopulation);
|
||||
gridShader.Dispatch(clearKernel, Mathf.Max(cellThreadGroups, capacityThreadGroups), 1, 1);
|
||||
|
||||
// build cell list:
|
||||
gridShader.SetBuffer(buildKernel, "shapes", shapes);
|
||||
gridShader.SetBuffer(buildKernel, "transforms", transforms);
|
||||
gridShader.SetBuffer(buildKernel, "cellIndices", cellIndicesBuffer);
|
||||
gridShader.SetBuffer(buildKernel, "cellCounts", cellCountsBuffer);
|
||||
gridShader.SetBuffer(buildKernel, "offsetInCells", offsetInCells);
|
||||
gridShader.SetBuffer(buildKernel, "levelPopulation", levelPopulation);
|
||||
gridShader.SetBuffer(buildKernel, "worldToSolver", solver.worldToSolverBuffer);
|
||||
gridShader.Dispatch(buildKernel, shapeThreadGroups, 1, 1);
|
||||
|
||||
// find populated grid levels:
|
||||
gridShader.SetBuffer(gridPopulationKernel, "levelPopulation", levelPopulation);
|
||||
gridShader.Dispatch(gridPopulationKernel, 1, 1, 1);
|
||||
|
||||
// prefix sum:
|
||||
prefixSum.Sum(cellCountsBuffer, cellOffsetsBuffer);
|
||||
|
||||
// sort query indices:
|
||||
gridShader.SetBuffer(sortKernel, "sortedColliderIndices", sortedShapeIndicesBuffer);
|
||||
gridShader.SetBuffer(sortKernel, "offsetInCells", offsetInCells);
|
||||
gridShader.SetBuffer(sortKernel, "cellIndices", cellIndicesBuffer);
|
||||
gridShader.SetBuffer(sortKernel, "cellOffsets", cellOffsetsBuffer);
|
||||
gridShader.Dispatch(sortKernel, capacityThreadGroups, 1, 1);
|
||||
|
||||
|
||||
gridShader.SetInt("pointCount", solver.simplexCounts.pointCount);
|
||||
gridShader.SetInt("edgeCount", solver.simplexCounts.edgeCount);
|
||||
gridShader.SetInt("triangleCount", solver.simplexCounts.triangleCount);
|
||||
gridShader.SetInt("surfaceCollisionIterations", solver.abstraction.parameters.surfaceCollisionIterations);
|
||||
gridShader.SetFloat("surfaceCollisionTolerance", solver.abstraction.parameters.surfaceCollisionTolerance);
|
||||
gridShader.SetInt("mode", (int)solver.abstraction.parameters.mode);
|
||||
|
||||
gridShader.SetBuffer(contactsKernel, "simplices", solver.simplices);
|
||||
gridShader.SetBuffer(contactsKernel, "simplexBounds", solver.simplexBounds);
|
||||
gridShader.SetBuffer(contactsKernel, "positions", solver.positionsBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "orientations", solver.orientationsBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "principalRadii", solver.principalRadiiBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "filters", solver.filtersBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "sortedColliderIndices", sortedShapeIndicesBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "transforms", transforms);
|
||||
gridShader.SetBuffer(contactsKernel, "shapes", shapes);
|
||||
gridShader.SetBuffer(contactsKernel, "collisionMaterialIndices", solver.collisionMaterialIndexBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "cellIndices", cellIndicesBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "cellOffsets", cellOffsetsBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "cellCounts", cellCountsBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "levelPopulation", levelPopulation);
|
||||
|
||||
gridShader.SetBuffer(contactsKernel, "solverToWorld", solver.solverToWorldBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "worldToSolver", solver.worldToSolverBuffer);
|
||||
gridShader.SetBuffer(contactsKernel, "colliderTypeCounts", queryTypeCounts);
|
||||
gridShader.SetBuffer(contactsKernel, "unsortedContactPairs", unsortedContactPairs);
|
||||
gridShader.SetBuffer(contactsKernel, "dispatchBuffer", dispatchBuffer);
|
||||
|
||||
gridShader.Dispatch(contactsKernel, particleThreadGroups, 1, 1);
|
||||
|
||||
gridShader.SetBuffer(prefixSumPairsKernel, "colliderTypeCounts", queryTypeCounts);
|
||||
gridShader.SetBuffer(prefixSumPairsKernel, "contactOffsetsPerType", contactOffsetsPerType);
|
||||
gridShader.SetBuffer(prefixSumPairsKernel, "dispatchBuffer", dispatchBuffer);
|
||||
|
||||
gridShader.Dispatch(prefixSumPairsKernel, 1, 1, 1);
|
||||
|
||||
gridShader.SetBuffer(sortPairsKernel, "shapes", shapes);
|
||||
gridShader.SetBuffer(sortPairsKernel, "unsortedContactPairs", unsortedContactPairs);
|
||||
gridShader.SetBuffer(sortPairsKernel, "contactPairs", contactPairs);
|
||||
gridShader.SetBuffer(sortPairsKernel, "colliderTypeCounts", queryTypeCounts);
|
||||
gridShader.SetBuffer(sortPairsKernel, "contactOffsetsPerType", contactOffsetsPerType);
|
||||
gridShader.SetBuffer(sortPairsKernel, "dispatchBuffer", dispatchBuffer);
|
||||
|
||||
gridShader.DispatchIndirect(sortPairsKernel, dispatchBuffer, 16);
|
||||
|
||||
boxes.GetResults(solver, this, transforms, shapes, results);
|
||||
spheres.GetResults(solver, this, transforms, shapes, results);
|
||||
rays.GetResults(solver, this, transforms, shapes, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01c4905e2f6964e7b91a3262bbd54229
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
17
Assets/Obi/Scripts/Common/Backends/Compute/ComputeBackend.cs
Normal file
17
Assets/Obi/Scripts/Common/Backends/Compute/ComputeBackend.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeBackend : IObiBackend
|
||||
{
|
||||
#region Solver
|
||||
public ISolverImpl CreateSolver(ObiSolver solver, int capacity)
|
||||
{
|
||||
return new ComputeSolverImpl(solver);
|
||||
}
|
||||
public void DestroySolver(ISolverImpl solver)
|
||||
{
|
||||
if (solver != null)
|
||||
solver.Destroy();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c68d8c4a741f459ea53d69f8eddbfef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeJobHandle : IObiJobHandle
|
||||
{
|
||||
public void Complete()
|
||||
{
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4dc5d7005f3f2458bbdc5c1756153cac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
16
Assets/Obi/Scripts/Common/Backends/Compute/ComputeMath.cs
Normal file
16
Assets/Obi/Scripts/Common/Backends/Compute/ComputeMath.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public static class ComputeMath
|
||||
{
|
||||
public static int ThreadGroupCount(int elements, int numThreads)
|
||||
{
|
||||
return elements / numThreads + 1;
|
||||
}
|
||||
|
||||
public static int NextMultiple(int baseNumber, int number)
|
||||
{
|
||||
return ((baseNumber / number) + 1) * number;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0df3a211b1614ebbb0f5144e868546e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0040fe7f7368047d29f179b7d7bf4d1a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b92b6684fbd249cd9732bf9b3303e03
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeAerodynamicConstraints : ComputeConstraintsImpl<ComputeAerodynamicConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int projectKernel;
|
||||
|
||||
public ComputeAerodynamicConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.Aerodynamics)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/AerodynamicConstraints"));
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputeAerodynamicConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputeAerodynamicConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5bb44136361b4a2d948bf85825e53b9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,52 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeAerodynamicConstraintsBatch : ComputeConstraintsBatchImpl, IAerodynamicConstraintsBatchImpl
|
||||
{
|
||||
GraphicsBuffer aerodynamicCoeffs;
|
||||
|
||||
public ComputeAerodynamicConstraintsBatch(ComputeAerodynamicConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.Aerodynamics;
|
||||
}
|
||||
|
||||
public void SetAerodynamicConstraints(ObiNativeIntList particleIndices, ObiNativeFloatList aerodynamicCoeffs, int count)
|
||||
{
|
||||
this.particleIndices = particleIndices.AsComputeBuffer<int>();
|
||||
this.aerodynamicCoeffs = aerodynamicCoeffs.AsComputeBuffer<float>();
|
||||
|
||||
m_ConstraintCount = count;
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var shader = ((ComputeAerodynamicConstraints)m_Constraints).constraintsShader;
|
||||
int projectKernel = ((ComputeAerodynamicConstraints)m_Constraints).projectKernel;
|
||||
|
||||
shader.SetBuffer(projectKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(projectKernel, "aerodynamicCoeffs", aerodynamicCoeffs);
|
||||
|
||||
shader.SetBuffer(projectKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "normals", solverImplementation.normalsBuffer);
|
||||
shader.SetBuffer(projectKernel, "wind", solverImplementation.windBuffer);
|
||||
shader.SetBuffer(projectKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(projectKernel, "velocities", solverImplementation.velocitiesBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("deltaTime", substepTime);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(projectKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(float substepTime)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84f8c85144ba84d59bdf603d907ae5fb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d16c953a082614e88bd02d0f99035c3a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeBendConstraints : ComputeConstraintsImpl<ComputeBendConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int projectKernel;
|
||||
public int applyKernel;
|
||||
|
||||
public ComputeBendConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.Bending)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/BendConstraints"));
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputeBendConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputeBendConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac9c52f073f794c47a6cbb7b41cf023c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,75 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeBendConstraintsBatch : ComputeConstraintsBatchImpl, IBendConstraintsBatchImpl
|
||||
{
|
||||
GraphicsBuffer restBends;
|
||||
GraphicsBuffer stiffnesses;
|
||||
|
||||
public ComputeBendConstraintsBatch(ComputeBendConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.Bending;
|
||||
}
|
||||
|
||||
public void SetBendConstraints(ObiNativeIntList particleIndices, ObiNativeFloatList restBends, ObiNativeVector2List bendingStiffnesses, ObiNativeVector2List plasticity, ObiNativeFloatList lambdas, int count)
|
||||
{
|
||||
this.particleIndices = particleIndices.AsComputeBuffer<int>();
|
||||
this.restBends = restBends.AsComputeBuffer<float>();
|
||||
this.stiffnesses = bendingStiffnesses.AsComputeBuffer<Vector2>();
|
||||
this.lambdas = lambdas.AsComputeBuffer<float>();
|
||||
this.lambdasList = lambdas;
|
||||
|
||||
m_ConstraintCount = count;
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var shader = ((ComputeBendConstraints)m_Constraints).constraintsShader;
|
||||
int projectKernel = ((ComputeBendConstraints)m_Constraints).projectKernel;
|
||||
|
||||
shader.SetBuffer(projectKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(projectKernel, "restBends", restBends);
|
||||
shader.SetBuffer(projectKernel, "stiffnesses", stiffnesses);
|
||||
shader.SetBuffer(projectKernel, "lambdas", lambdas);
|
||||
|
||||
shader.SetBuffer(projectKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(projectKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("deltaTime", substepTime);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(projectKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(float deltaTime)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var parameters = solverAbstraction.GetConstraintParameters(m_ConstraintType);
|
||||
|
||||
var shader = ((ComputeBendConstraints)m_Constraints).constraintsShader;
|
||||
int applyKernel = ((ComputeBendConstraints)m_Constraints).applyKernel;
|
||||
|
||||
shader.SetBuffer(applyKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(applyKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(applyKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(applyKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("sorFactor", parameters.SORFactor);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(applyKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49d201b7a15f44e17b27019b972e9844
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 253f34729aa7d4bbabe8eca30fdb88af
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeBendTwistConstraints : ComputeConstraintsImpl<ComputeBendTwistConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int projectKernel;
|
||||
public int applyKernel;
|
||||
|
||||
public ComputeBendTwistConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.BendTwist)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/BendTwistConstraints"));
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputeBendTwistConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputeBendTwistConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 442edc2bc0aec4bf181b4332f0c8dd46
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,81 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeBendTwistConstraintsBatch : ComputeConstraintsBatchImpl, IBendTwistConstraintsBatchImpl
|
||||
{
|
||||
GraphicsBuffer orientationIndices;
|
||||
GraphicsBuffer restDarboux;
|
||||
GraphicsBuffer stiffnesses;
|
||||
GraphicsBuffer plasticity;
|
||||
|
||||
public ComputeBendTwistConstraintsBatch(ComputeBendTwistConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.BendTwist;
|
||||
}
|
||||
|
||||
public void SetBendTwistConstraints(ObiNativeIntList orientationIndices, ObiNativeQuaternionList restDarboux, ObiNativeVector3List stiffnesses, ObiNativeVector2List plasticity, ObiNativeFloatList lambdas, int count)
|
||||
{
|
||||
this.orientationIndices = orientationIndices.AsComputeBuffer<int>();
|
||||
this.restDarboux = restDarboux.AsComputeBuffer<Quaternion>();
|
||||
this.stiffnesses = stiffnesses.AsComputeBuffer<Vector3>();
|
||||
this.plasticity = plasticity.AsComputeBuffer<Vector2>();
|
||||
this.lambdas = lambdas.AsComputeBuffer<float>();
|
||||
this.lambdasList = lambdas;
|
||||
|
||||
m_ConstraintCount = count;
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var shader = ((ComputeBendTwistConstraints)m_Constraints).constraintsShader;
|
||||
int projectKernel = ((ComputeBendTwistConstraints)m_Constraints).projectKernel;
|
||||
|
||||
shader.SetBuffer(projectKernel, "orientationIndices", orientationIndices);
|
||||
shader.SetBuffer(projectKernel, "restDarboux", restDarboux);
|
||||
shader.SetBuffer(projectKernel, "stiffnesses", stiffnesses);
|
||||
shader.SetBuffer(projectKernel, "plasticity", plasticity);
|
||||
shader.SetBuffer(projectKernel, "lambdas", lambdas);
|
||||
|
||||
shader.SetBuffer(projectKernel, "orientations", solverImplementation.orientationsBuffer);
|
||||
shader.SetBuffer(projectKernel, "invRotationalMasses", solverImplementation.invRotationalMassesBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "orientationDeltasAsInt", solverImplementation.orientationDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientationConstraintCounts", solverImplementation.orientationConstraintCountBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("deltaTime", substepTime);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(projectKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(float substepTime)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var parameters = solverAbstraction.GetConstraintParameters(m_ConstraintType);
|
||||
|
||||
var shader = ((ComputeBendTwistConstraints)m_Constraints).constraintsShader;
|
||||
int applyKernel = ((ComputeBendTwistConstraints)m_Constraints).applyKernel;
|
||||
|
||||
shader.SetBuffer(applyKernel, "orientationIndices", orientationIndices);
|
||||
shader.SetBuffer(applyKernel, "orientations", solverImplementation.orientationsBuffer);
|
||||
|
||||
shader.SetBuffer(applyKernel, "orientationDeltasAsInt", solverImplementation.orientationDeltasIntBuffer);
|
||||
shader.SetBuffer(applyKernel, "orientationConstraintCounts", solverImplementation.orientationConstraintCountBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("sorFactor", parameters.SORFactor);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(applyKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5806beebf896460d87156df3e045b57
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 06d157d45e7fd46f08b501d67d3d632b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeChainConstraints : ComputeConstraintsImpl<ComputeChainConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int projectKernel;
|
||||
public int applyKernel;
|
||||
|
||||
public ComputeChainConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.Chain)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/ChainConstraints"));
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputeChainConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputeChainConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c28cd2bd740f4bebb4c8559b395ed0e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,97 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeChainConstraintsBatch : ComputeConstraintsBatchImpl, IChainConstraintsBatchImpl
|
||||
{
|
||||
GraphicsBuffer firstIndex;
|
||||
GraphicsBuffer numIndices;
|
||||
GraphicsBuffer restLengths;
|
||||
|
||||
GraphicsBuffer ni;
|
||||
GraphicsBuffer diagonals;
|
||||
|
||||
public ComputeChainConstraintsBatch(ComputeChainConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.Chain;
|
||||
}
|
||||
|
||||
public void SetChainConstraints(ObiNativeIntList particleIndices, ObiNativeVector2List restLengths, ObiNativeIntList firstIndex, ObiNativeIntList numIndex, int count)
|
||||
{
|
||||
this.particleIndices = particleIndices.AsComputeBuffer<int>();
|
||||
this.firstIndex = firstIndex.AsComputeBuffer<int>();
|
||||
this.numIndices = numIndex.AsComputeBuffer<int>();
|
||||
this.restLengths = restLengths.AsComputeBuffer<Vector2>();
|
||||
|
||||
int numEdges = 0;
|
||||
for (int i = 0; i < numIndex.count; ++i)
|
||||
numEdges += numIndex[i] - 1;
|
||||
|
||||
ni = new GraphicsBuffer(GraphicsBuffer.Target.Structured, numEdges, 16);
|
||||
diagonals = new GraphicsBuffer(GraphicsBuffer.Target.Structured, numEdges, 12);
|
||||
|
||||
m_ConstraintCount = count;
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
ni.Dispose();
|
||||
diagonals.Dispose();
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var shader = ((ComputeChainConstraints)m_Constraints).constraintsShader;
|
||||
int projectKernel = ((ComputeChainConstraints)m_Constraints).projectKernel;
|
||||
|
||||
shader.SetBuffer(projectKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(projectKernel, "firstIndex", firstIndex);
|
||||
shader.SetBuffer(projectKernel, "numIndices", numIndices);
|
||||
shader.SetBuffer(projectKernel, "restLengths", restLengths);
|
||||
|
||||
shader.SetBuffer(projectKernel, "ni", ni);
|
||||
shader.SetBuffer(projectKernel, "diagonals", diagonals);
|
||||
|
||||
shader.SetBuffer(projectKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(projectKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("deltaTime", substepTime);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(projectKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(float substepTime)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var parameters = solverAbstraction.GetConstraintParameters(m_ConstraintType);
|
||||
|
||||
var shader = ((ComputeChainConstraints)m_Constraints).constraintsShader;
|
||||
int applyKernel = ((ComputeChainConstraints)m_Constraints).applyKernel;
|
||||
|
||||
shader.SetBuffer(applyKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(applyKernel, "firstIndex", firstIndex);
|
||||
shader.SetBuffer(applyKernel, "numIndices", numIndices);
|
||||
|
||||
shader.SetBuffer(applyKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(applyKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(applyKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("sorFactor", parameters.SORFactor);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(applyKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d067c1d8b1e94c51bbb85f0f81754ad
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff5938de5299c42278caf6e3181426ed
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeColliderCollisionConstraints : ComputeConstraintsImpl<ComputeColliderCollisionConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int clearKernel;
|
||||
public int initializeKernel;
|
||||
public int projectKernel;
|
||||
public int applyKernel;
|
||||
|
||||
public ComputeColliderCollisionConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.Collision)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/ColliderCollisionConstraints"));
|
||||
clearKernel = constraintsShader.FindKernel("Clear");
|
||||
initializeKernel = constraintsShader.FindKernel("Initialize");
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputeColliderCollisionConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputeColliderCollisionConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a86d11bb25f6409a95e22186e98474c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,126 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeColliderCollisionConstraintsBatch : ComputeConstraintsBatchImpl, IColliderCollisionConstraintsBatchImpl
|
||||
{
|
||||
|
||||
public ComputeColliderCollisionConstraintsBatch(ComputeColliderCollisionConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.Collision;
|
||||
}
|
||||
|
||||
public override void Initialize(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (solverAbstraction.simplexCounts.simplexCount > 0 && solverImplementation.colliderGrid.colliderCount > 0)
|
||||
{
|
||||
var shader = ((ComputeColliderCollisionConstraints)m_Constraints).constraintsShader;
|
||||
int initializeKernel = ((ComputeColliderCollisionConstraints)m_Constraints).initializeKernel;
|
||||
int clearKernel = ((ComputeColliderCollisionConstraints)m_Constraints).clearKernel;
|
||||
|
||||
shader.SetInt("pointCount", solverAbstraction.simplexCounts.pointCount);
|
||||
shader.SetInt("edgeCount", solverAbstraction.simplexCounts.edgeCount);
|
||||
shader.SetInt("triangleCount", solverAbstraction.simplexCounts.triangleCount);
|
||||
|
||||
shader.SetBuffer(clearKernel, "contacts", solverAbstraction.colliderContacts.computeBuffer);
|
||||
shader.SetBuffer(clearKernel, "shapes", this.solverImplementation.colliderGrid.shapesBuffer);
|
||||
shader.SetBuffer(clearKernel, "RW_rigidbodies", this.solverImplementation.colliderGrid.rigidbodiesBuffer);
|
||||
shader.SetBuffer(clearKernel, "dispatchBuffer", this.solverImplementation.colliderGrid.dispatchBuffer);
|
||||
|
||||
shader.SetBuffer(initializeKernel, "contacts", solverAbstraction.colliderContacts.computeBuffer);
|
||||
shader.SetBuffer(initializeKernel, "effectiveMasses", solverAbstraction.contactEffectiveMasses.computeBuffer);
|
||||
shader.SetBuffer(initializeKernel, "dispatchBuffer", this.solverImplementation.colliderGrid.dispatchBuffer);
|
||||
shader.SetBuffer(initializeKernel, "collisionMaterials", this.solverImplementation.colliderGrid.materialsBuffer);
|
||||
|
||||
shader.SetBuffer(initializeKernel, "simplices", this.solverImplementation.simplices);
|
||||
shader.SetBuffer(initializeKernel, "transforms", this.solverImplementation.colliderGrid.transformsBuffer);
|
||||
shader.SetBuffer(initializeKernel, "shapes", this.solverImplementation.colliderGrid.shapesBuffer);
|
||||
shader.SetBuffer(initializeKernel, "RW_rigidbodies", this.solverImplementation.colliderGrid.rigidbodiesBuffer);
|
||||
shader.SetBuffer(initializeKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(initializeKernel, "orientations", solverImplementation.orientationsBuffer);
|
||||
shader.SetBuffer(initializeKernel, "prevPositions", solverImplementation.prevPositionsBuffer);
|
||||
shader.SetBuffer(initializeKernel, "prevOrientations", solverImplementation.prevOrientationsBuffer);
|
||||
shader.SetBuffer(initializeKernel, "velocities", solverImplementation.velocitiesBuffer);
|
||||
shader.SetBuffer(initializeKernel, "principalRadii", solverImplementation.principalRadiiBuffer);
|
||||
shader.SetBuffer(initializeKernel, "collisionMaterialIndices", solverImplementation.collisionMaterialIndexBuffer);
|
||||
shader.SetBuffer(initializeKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(initializeKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(initializeKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(initializeKernel, "invRotationalMasses", solverImplementation.invRotationalMassesBuffer);
|
||||
|
||||
shader.SetBuffer(initializeKernel, "linearDeltasAsInt", solverImplementation.rigidbodyLinearDeltasIntBuffer);
|
||||
shader.SetBuffer(initializeKernel, "angularDeltasAsInt", solverImplementation.rigidbodyAngularDeltasIntBuffer);
|
||||
|
||||
shader.SetBuffer(initializeKernel, "inertialSolverFrame", solverImplementation.inertialFrameBuffer);
|
||||
|
||||
shader.SetFloat("substepTime", substepTime);
|
||||
|
||||
shader.DispatchIndirect(clearKernel, this.solverImplementation.colliderGrid.dispatchBuffer);
|
||||
shader.DispatchIndirect(initializeKernel, this.solverImplementation.colliderGrid.dispatchBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (solverAbstraction.simplexCounts.simplexCount > 0 && solverImplementation.colliderGrid.colliderCount > 0)
|
||||
{
|
||||
var shader = ((ComputeColliderCollisionConstraints)m_Constraints).constraintsShader;
|
||||
int projectKernel = ((ComputeColliderCollisionConstraints)m_Constraints).projectKernel;
|
||||
|
||||
shader.SetBuffer(projectKernel, "contacts", solverAbstraction.colliderContacts.computeBuffer);
|
||||
shader.SetBuffer(projectKernel, "effectiveMasses", this.solverAbstraction.contactEffectiveMasses.computeBuffer);
|
||||
shader.SetBuffer(projectKernel, "dispatchBuffer", this.solverImplementation.colliderGrid.dispatchBuffer);
|
||||
shader.SetBuffer(projectKernel, "collisionMaterials", this.solverImplementation.colliderGrid.materialsBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "simplices", this.solverImplementation.simplices);
|
||||
shader.SetBuffer(projectKernel, "transforms", this.solverImplementation.colliderGrid.transformsBuffer);
|
||||
shader.SetBuffer(projectKernel, "shapes", this.solverImplementation.colliderGrid.shapesBuffer);
|
||||
shader.SetBuffer(projectKernel, "rigidbodies", this.solverImplementation.colliderGrid.rigidbodiesBuffer);
|
||||
shader.SetBuffer(projectKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "prevPositions", solverImplementation.prevPositionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientations", solverImplementation.orientationsBuffer);
|
||||
shader.SetBuffer(projectKernel, "prevOrientations", solverImplementation.prevOrientationsBuffer);
|
||||
shader.SetBuffer(projectKernel, "principalRadii", solverImplementation.principalRadiiBuffer);
|
||||
shader.SetBuffer(projectKernel, "collisionMaterialIndices", solverImplementation.collisionMaterialIndexBuffer);
|
||||
shader.SetBuffer(projectKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(projectKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "linearDeltasAsInt", solverImplementation.rigidbodyLinearDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "angularDeltasAsInt", solverImplementation.rigidbodyAngularDeltasIntBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "inertialSolverFrame", solverImplementation.inertialFrameBuffer);
|
||||
shader.SetFloat("substepTime", substepTime);
|
||||
shader.SetFloat("stepTime", stepTime);
|
||||
shader.SetInt("steps", steps);
|
||||
shader.SetFloat("timeLeft", timeLeft);
|
||||
shader.SetFloat("maxDepenetration", solverAbstraction.parameters.maxDepenetration);
|
||||
|
||||
shader.DispatchIndirect(projectKernel, this.solverImplementation.colliderGrid.dispatchBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(float substepTime)
|
||||
{
|
||||
var shader = ((ComputeColliderCollisionConstraints)m_Constraints).constraintsShader;
|
||||
int applyKernel = ((ComputeColliderCollisionConstraints)m_Constraints).applyKernel;
|
||||
|
||||
if (solverImplementation.activeParticleCount > 0)
|
||||
{
|
||||
var parameters = solverAbstraction.GetConstraintParameters(m_ConstraintType);
|
||||
|
||||
shader.SetBuffer(applyKernel, "particleIndices", this.solverImplementation.activeParticlesBuffer);
|
||||
shader.SetBuffer(applyKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(applyKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(applyKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
|
||||
shader.SetInt("particleCount", this.solverAbstraction.activeParticleCount);
|
||||
shader.SetFloat("sorFactor", parameters.SORFactor);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(this.solverAbstraction.activeParticleCount, 128);
|
||||
shader.Dispatch(applyKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d33af332861d148229253e82497aa0df
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeColliderFrictionConstraints : ComputeConstraintsImpl<ComputeColliderFrictionConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int projectKernel;
|
||||
public int applyKernel;
|
||||
|
||||
public ComputeColliderFrictionConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.Friction)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/ColliderFrictionConstraints"));
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputeColliderFrictionConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputeColliderFrictionConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b15312c6313124df298754c7654b62bc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,86 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeColliderFrictionConstraintsBatch : ComputeConstraintsBatchImpl, IColliderCollisionConstraintsBatchImpl
|
||||
{
|
||||
|
||||
public ComputeColliderFrictionConstraintsBatch(ComputeColliderFrictionConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.Friction;
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (solverAbstraction.simplexCounts.simplexCount > 0 && solverImplementation.colliderGrid.colliderCount > 0)
|
||||
{
|
||||
var shader = ((ComputeColliderFrictionConstraints)m_Constraints).constraintsShader;
|
||||
int projectKernel = ((ComputeColliderFrictionConstraints)m_Constraints).projectKernel;
|
||||
|
||||
shader.SetInt("pointCount", solverAbstraction.simplexCounts.pointCount);
|
||||
shader.SetInt("edgeCount", solverAbstraction.simplexCounts.edgeCount);
|
||||
shader.SetInt("triangleCount", solverAbstraction.simplexCounts.triangleCount);
|
||||
|
||||
shader.SetBuffer(projectKernel, "contacts", solverAbstraction.colliderContacts.computeBuffer);
|
||||
shader.SetBuffer(projectKernel, "effectiveMasses", solverAbstraction.contactEffectiveMasses.computeBuffer);
|
||||
shader.SetBuffer(projectKernel, "dispatchBuffer", this.solverImplementation.colliderGrid.dispatchBuffer);
|
||||
shader.SetBuffer(projectKernel, "collisionMaterials", this.solverImplementation.colliderGrid.materialsBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "simplices", this.solverImplementation.simplices);
|
||||
shader.SetBuffer(projectKernel, "transforms", this.solverImplementation.colliderGrid.transformsBuffer);
|
||||
shader.SetBuffer(projectKernel, "shapes", this.solverImplementation.colliderGrid.shapesBuffer);
|
||||
shader.SetBuffer(projectKernel, "rigidbodies", this.solverImplementation.colliderGrid.rigidbodiesBuffer);
|
||||
shader.SetBuffer(projectKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "collisionMaterialIndices", solverImplementation.collisionMaterialIndexBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientations", solverImplementation.orientationsBuffer);
|
||||
shader.SetBuffer(projectKernel, "prevPositions", solverImplementation.prevPositionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "prevOrientations", solverImplementation.prevOrientationsBuffer);
|
||||
shader.SetBuffer(projectKernel, "principalRadii", solverImplementation.principalRadiiBuffer);
|
||||
shader.SetBuffer(projectKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(projectKernel, "invRotationalMasses", solverImplementation.invRotationalMassesBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(projectKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientationConstraintCounts", solverImplementation.orientationConstraintCountBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientationDeltasAsInt", solverImplementation.orientationDeltasIntBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "linearDeltasAsInt", solverImplementation.rigidbodyLinearDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "angularDeltasAsInt", solverImplementation.rigidbodyAngularDeltasIntBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "solverToWorld", solverImplementation.solverToWorldBuffer);
|
||||
shader.SetBuffer(projectKernel, "inertialSolverFrame", solverImplementation.inertialFrameBuffer);
|
||||
shader.SetFloat("stepTime", stepTime);
|
||||
shader.SetFloat("substepTime", substepTime);
|
||||
|
||||
shader.DispatchIndirect(projectKernel, this.solverImplementation.colliderGrid.dispatchBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(float substepTime)
|
||||
{
|
||||
var shader = ((ComputeColliderFrictionConstraints)m_Constraints).constraintsShader;
|
||||
int applyKernel = ((ComputeColliderFrictionConstraints)m_Constraints).applyKernel;
|
||||
|
||||
if (solverImplementation.activeParticleCount > 0)
|
||||
{
|
||||
var parameters = solverAbstraction.GetConstraintParameters(m_ConstraintType);
|
||||
|
||||
shader.SetBuffer(applyKernel, "particleIndices", this.solverImplementation.activeParticlesBuffer);
|
||||
shader.SetBuffer(applyKernel, "RW_positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(applyKernel, "RW_orientations", solverImplementation.orientationsBuffer);
|
||||
shader.SetBuffer(applyKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(applyKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(applyKernel, "orientationConstraintCounts", solverImplementation.orientationConstraintCountBuffer);
|
||||
shader.SetBuffer(applyKernel, "orientationDeltasAsInt", solverImplementation.orientationDeltasIntBuffer);
|
||||
|
||||
shader.SetInt("particleCount", this.solverAbstraction.activeParticleCount);
|
||||
shader.SetFloat("sorFactor", parameters.SORFactor);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(this.solverAbstraction.activeParticleCount, 128);
|
||||
shader.Dispatch(applyKernel, threadGroups, 1, 1);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24cfbad987ca74ec696ec132558f6103
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,82 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public abstract class ComputeConstraintsBatchImpl : IConstraintsBatchImpl
|
||||
{
|
||||
protected IComputeConstraintsImpl m_Constraints;
|
||||
protected Oni.ConstraintType m_ConstraintType;
|
||||
|
||||
protected bool m_Enabled = true;
|
||||
protected int m_ConstraintCount = 0;
|
||||
|
||||
public Oni.ConstraintType constraintType
|
||||
{
|
||||
get { return m_ConstraintType; }
|
||||
}
|
||||
|
||||
public bool enabled
|
||||
{
|
||||
set
|
||||
{
|
||||
if (m_Enabled != value)
|
||||
m_Enabled = value;
|
||||
}
|
||||
get { return m_Enabled; }
|
||||
}
|
||||
|
||||
public IConstraints constraints
|
||||
{
|
||||
get { return m_Constraints; }
|
||||
}
|
||||
|
||||
public ObiSolver solverAbstraction
|
||||
{
|
||||
get { return ((ComputeSolverImpl)m_Constraints.solver).abstraction; }
|
||||
}
|
||||
|
||||
public ComputeSolverImpl solverImplementation
|
||||
{
|
||||
get { return (ComputeSolverImpl)m_Constraints.solver; }
|
||||
}
|
||||
|
||||
protected GraphicsBuffer particleIndices;
|
||||
protected GraphicsBuffer lambdas;
|
||||
|
||||
protected ObiNativeFloatList lambdasList;
|
||||
|
||||
public virtual void Initialize(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (lambdasList != null)
|
||||
{
|
||||
lambdasList.WipeToZero();
|
||||
lambdasList.Upload();
|
||||
}
|
||||
}
|
||||
|
||||
// implemented by concrete constraint subclasses.
|
||||
public abstract void Evaluate(float stepTime, float substepTime, int steps, float timeLeft);
|
||||
public abstract void Apply(float substepTime);
|
||||
|
||||
public ComputeConstraintsBatchImpl() { }
|
||||
|
||||
public virtual void Destroy()
|
||||
{
|
||||
// clean resources allocated by the batch, no need for a default implementation.
|
||||
}
|
||||
|
||||
public void SetDependency(IConstraintsBatchImpl batch)
|
||||
{
|
||||
// no need to implement.
|
||||
}
|
||||
|
||||
public void SetConstraintCount(int constraintCount)
|
||||
{
|
||||
m_ConstraintCount = constraintCount;
|
||||
}
|
||||
public int GetConstraintCount()
|
||||
{
|
||||
return m_ConstraintCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01e582f7ad8544beca43dac2f3af8b37
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,126 @@
|
||||
using UnityEngine;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public interface IComputeConstraintsImpl : IConstraints
|
||||
{
|
||||
void Initialize(float stepTime, float substepTime, int steps, float timeLeft);
|
||||
void Project(float stepTime, float substepTime, int substeps, float timeLeft);
|
||||
void Dispose();
|
||||
|
||||
IConstraintsBatchImpl CreateConstraintsBatch();
|
||||
void RemoveBatch(IConstraintsBatchImpl batch);
|
||||
}
|
||||
|
||||
public abstract class ComputeConstraintsImpl<T> : IComputeConstraintsImpl where T : ComputeConstraintsBatchImpl
|
||||
{
|
||||
protected ComputeSolverImpl m_Solver;
|
||||
public List<T> batches = new List<T>();
|
||||
|
||||
protected Oni.ConstraintType m_ConstraintType;
|
||||
|
||||
public Oni.ConstraintType constraintType
|
||||
{
|
||||
get { return m_ConstraintType; }
|
||||
}
|
||||
|
||||
public ISolverImpl solver
|
||||
{
|
||||
get { return m_Solver; }
|
||||
}
|
||||
|
||||
public ComputeConstraintsImpl(ComputeSolverImpl solver, Oni.ConstraintType constraintType)
|
||||
{
|
||||
this.m_ConstraintType = constraintType;
|
||||
this.m_Solver = solver;
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public abstract IConstraintsBatchImpl CreateConstraintsBatch();
|
||||
|
||||
public abstract void RemoveBatch(IConstraintsBatchImpl batch);
|
||||
|
||||
public virtual int GetConstraintCount()
|
||||
{
|
||||
int count = 0;
|
||||
if (batches == null) return count;
|
||||
|
||||
foreach (T batch in batches)
|
||||
if (batch != null)
|
||||
count += batch.GetConstraintCount();
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public void Initialize(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
// initialize all batches in parallel:
|
||||
if (batches.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < batches.Count; ++i)
|
||||
if (batches[i].enabled) batches[i].Initialize(stepTime, substepTime, steps, timeLeft);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Project(float stepTime, float substepTime, int substeps, float timeLeft)
|
||||
{
|
||||
UnityEngine.Profiling.Profiler.BeginSample("Project");
|
||||
|
||||
var parameters = m_Solver.abstraction.GetConstraintParameters(m_ConstraintType);
|
||||
|
||||
switch(parameters.evaluationOrder)
|
||||
{
|
||||
case Oni.ConstraintParameters.EvaluationOrder.Sequential:
|
||||
EvaluateSequential(stepTime, substepTime, substeps, timeLeft);
|
||||
break;
|
||||
|
||||
case Oni.ConstraintParameters.EvaluationOrder.Parallel:
|
||||
EvaluateParallel(stepTime, substepTime, substeps, timeLeft);
|
||||
break;
|
||||
}
|
||||
|
||||
UnityEngine.Profiling.Profiler.EndSample();
|
||||
|
||||
}
|
||||
|
||||
protected virtual void EvaluateSequential(float stepTime, float substepTime, int substeps, float timeLeft)
|
||||
{
|
||||
// evaluate and apply all batches:
|
||||
for (int i = 0; i < batches.Count; ++i)
|
||||
{
|
||||
if (batches[i].enabled)
|
||||
{
|
||||
batches[i].Evaluate(stepTime, substepTime, substeps, timeLeft);
|
||||
batches[i].Apply(substepTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void EvaluateParallel(float stepTime, float substepTime, int substeps, float timeLeft)
|
||||
{
|
||||
// evaluate all batches:
|
||||
for (int i = 0; i < batches.Count; ++i)
|
||||
if (batches[i].enabled)
|
||||
{
|
||||
batches[i].Evaluate(stepTime, substepTime, substeps, timeLeft);
|
||||
}
|
||||
|
||||
// then apply them:
|
||||
for (int i = 0; i < batches.Count; ++i)
|
||||
if (batches[i].enabled)
|
||||
{
|
||||
batches[i].Apply(substepTime);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36bc3e2333033489782d3f9f7781f967
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6f9b81a4e3934d66a7268e686756750
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeDensityConstraints : ComputeConstraintsImpl<ComputeDensityConstraintsBatch>
|
||||
{
|
||||
public ComputeShader sortParticlesShader;
|
||||
public int sortDataKernel;
|
||||
|
||||
public ComputeShader constraintsShader;
|
||||
public int updateDensitiesKernel;
|
||||
public int applyKernel;
|
||||
public int applyPositionDeltaKernel;
|
||||
public int calculateAtmosphereKernel;
|
||||
public int applyAtmosphereKernel;
|
||||
|
||||
public int accumSmoothPositionsKernel;
|
||||
public int accumAnisotropyKernel;
|
||||
public int averageAnisotropyKernel;
|
||||
|
||||
public ComputeDensityConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.Density)
|
||||
{
|
||||
sortParticlesShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/SortParticleData"));
|
||||
sortDataKernel = sortParticlesShader.FindKernel("SortData");
|
||||
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/DensityConstraints"));
|
||||
updateDensitiesKernel = constraintsShader.FindKernel("UpdateDensities");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
applyPositionDeltaKernel = constraintsShader.FindKernel("ApplyPositionDeltas");
|
||||
calculateAtmosphereKernel = constraintsShader.FindKernel("CalculateAtmosphere");
|
||||
applyAtmosphereKernel = constraintsShader.FindKernel("ApplyAtmosphere");
|
||||
|
||||
accumSmoothPositionsKernel = constraintsShader.FindKernel("AccumulateSmoothPositions");
|
||||
accumAnisotropyKernel = constraintsShader.FindKernel("AccumulateAnisotropy");
|
||||
averageAnisotropyKernel = constraintsShader.FindKernel("AverageAnisotropy");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputeDensityConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputeDensityConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
|
||||
public void CopyDataInSortedOrder(bool renderable = false)
|
||||
{
|
||||
sortParticlesShader.SetBuffer(sortDataKernel, "sortedToOriginal", m_Solver.particleGrid.sortedFluidIndices);
|
||||
|
||||
if (renderable)
|
||||
{
|
||||
sortParticlesShader.SetBuffer(sortDataKernel, "positions", m_Solver.renderablePositionsBuffer);
|
||||
sortParticlesShader.SetBuffer(sortDataKernel, "principalRadii", m_Solver.renderableRadiiBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
sortParticlesShader.SetBuffer(sortDataKernel, "positions", m_Solver.positionsBuffer);
|
||||
sortParticlesShader.SetBuffer(sortDataKernel, "principalRadii", m_Solver.principalRadiiBuffer);
|
||||
}
|
||||
|
||||
sortParticlesShader.SetBuffer(sortDataKernel, "prevPositions", m_Solver.prevPositionsBuffer);
|
||||
sortParticlesShader.SetBuffer(sortDataKernel, "userData", m_Solver.userDataBuffer);
|
||||
|
||||
sortParticlesShader.SetBuffer(sortDataKernel, "sortedPositions", m_Solver.particleGrid.sortedPositions);
|
||||
sortParticlesShader.SetBuffer(sortDataKernel, "sortedPrincipalRadii", m_Solver.particleGrid.sortedPrincipalRadii);
|
||||
sortParticlesShader.SetBuffer(sortDataKernel, "sortedPrevPositions", m_Solver.particleGrid.sortedPrevPosOrientations);
|
||||
sortParticlesShader.SetBuffer(sortDataKernel, "sortedUserData", m_Solver.particleGrid.sortedUserDataColor);
|
||||
|
||||
sortParticlesShader.SetBuffer(sortDataKernel, "dispatchBuffer", m_Solver.fluidDispatchBuffer);
|
||||
sortParticlesShader.DispatchIndirect(sortDataKernel, m_Solver.fluidDispatchBuffer);
|
||||
}
|
||||
|
||||
public void CalculateVelocityCorrections(float deltaTime)
|
||||
{
|
||||
if (m_Solver.particleGrid.sortedFluidIndices != null && m_Solver.cellCoordsBuffer != null)
|
||||
{
|
||||
constraintsShader.SetFloat("deltaTime", deltaTime);
|
||||
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "neighborCounts", m_Solver.particleGrid.neighborCounts);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "neighbors", m_Solver.particleGrid.neighbors);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "sortedToOriginal", m_Solver.particleGrid.sortedFluidIndices);
|
||||
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "invMasses", m_Solver.invMassesBuffer);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "velocities_RO", m_Solver.velocitiesBuffer);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "angularVelocities_RO", m_Solver.angularVelocitiesBuffer);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "vorticity_RO", m_Solver.restOrientationsBuffer); // restOrientations are unused for fluid particles, so we reuse them here.
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "vorticityAccelerations", m_Solver.orientationDeltasIntBuffer); // restPositions are unused for fluid particles, so we reuse them here.
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "linearAccelerations", m_Solver.positionDeltasIntBuffer);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "angularDiffusion", m_Solver.anisotropiesBuffer);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "linearFromAngular", m_Solver.restPositionsBuffer);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "normals", m_Solver.normalsBuffer);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "userData", m_Solver.userDataBuffer);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "sortedPositions", m_Solver.particleGrid.sortedPositions);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "sortedFluidData_RO", m_Solver.particleGrid.sortedFluidData);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "sortedPrincipalRadii", m_Solver.particleGrid.sortedPrincipalRadii);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "sortedFluidMaterials", m_Solver.particleGrid.sortedFluidMaterials);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "sortedFluidInterface", m_Solver.particleGrid.sortedFluidInterface);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "sortedUserData", m_Solver.particleGrid.sortedUserDataColor);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "fluidData", m_Solver.fluidDataBuffer);
|
||||
constraintsShader.SetBuffer(calculateAtmosphereKernel, "dispatchBuffer", m_Solver.fluidDispatchBuffer);
|
||||
|
||||
constraintsShader.DispatchIndirect(calculateAtmosphereKernel, m_Solver.fluidDispatchBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyVelocityCorrections(float deltaTime)
|
||||
{
|
||||
if (m_Solver.particleGrid.sortedFluidIndices != null && m_Solver.cellCoordsBuffer != null)
|
||||
{
|
||||
constraintsShader.SetFloat("deltaTime", deltaTime);
|
||||
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "positions", m_Solver.positionsBuffer);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "prevPositions", m_Solver.prevPositionsBuffer);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "wind", m_Solver.windBuffer);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "normals_RO", m_Solver.normalsBuffer);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "fluidMaterials2", m_Solver.fluidMaterials2Buffer);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "sortedPrincipalRadii", m_Solver.particleGrid.sortedPrincipalRadii);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "sortedFluidInterface", m_Solver.particleGrid.sortedFluidInterface);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "fluidData_RO", m_Solver.fluidDataBuffer);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "linearAccelerations", m_Solver.positionDeltasIntBuffer);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "angularDiffusion", m_Solver.anisotropiesBuffer);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "vorticity", m_Solver.restOrientationsBuffer);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "vorticityAccelerations", m_Solver.orientationDeltasIntBuffer);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "linearFromAngular_RO", m_Solver.restPositionsBuffer);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "velocities", m_Solver.velocitiesBuffer);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "angularVelocities", m_Solver.angularVelocitiesBuffer);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "sortedToOriginal", m_Solver.particleGrid.sortedFluidIndices);
|
||||
constraintsShader.SetBuffer(applyAtmosphereKernel, "dispatchBuffer", m_Solver.fluidDispatchBuffer);
|
||||
|
||||
constraintsShader.DispatchIndirect(applyAtmosphereKernel, m_Solver.fluidDispatchBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void CalculateAnisotropyLaplacianSmoothing()
|
||||
{
|
||||
int pcount = ((ComputeSolverImpl)solver).particleCount;
|
||||
if (pcount > 0 && m_Solver.particleGrid.sortedFluidIndices != null && m_Solver.cellCoordsBuffer != null)
|
||||
{
|
||||
if (m_Solver.abstraction.parameters.maxAnisotropy <= 1)
|
||||
return;
|
||||
|
||||
constraintsShader.SetFloat("maxAnisotropy", m_Solver.abstraction.parameters.maxAnisotropy);
|
||||
constraintsShader.SetInt("simplexCount", m_Solver.simplexCounts.simplexCount);
|
||||
|
||||
// copy render data (renderablePositions / radii) in sorted order:
|
||||
CopyDataInSortedOrder(true);
|
||||
|
||||
// accumulate smoothed positions:
|
||||
constraintsShader.SetBuffer(accumSmoothPositionsKernel, "neighborCounts", m_Solver.particleGrid.neighborCounts);
|
||||
constraintsShader.SetBuffer(accumSmoothPositionsKernel, "neighbors", m_Solver.particleGrid.neighbors);
|
||||
constraintsShader.SetBuffer(accumSmoothPositionsKernel, "sortedFluidMaterials", m_Solver.particleGrid.sortedFluidMaterials);
|
||||
constraintsShader.SetBuffer(accumSmoothPositionsKernel, "renderablePositions", m_Solver.particleGrid.sortedPositions);
|
||||
constraintsShader.SetBuffer(accumSmoothPositionsKernel, "anisotropies", m_Solver.anisotropiesBuffer);
|
||||
constraintsShader.SetBuffer(accumSmoothPositionsKernel, "dispatchBuffer", m_Solver.fluidDispatchBuffer);
|
||||
constraintsShader.DispatchIndirect(accumSmoothPositionsKernel, m_Solver.fluidDispatchBuffer);
|
||||
|
||||
// accumulate anisotropy:
|
||||
constraintsShader.SetBuffer(accumAnisotropyKernel, "neighborCounts", m_Solver.particleGrid.neighborCounts);
|
||||
constraintsShader.SetBuffer(accumAnisotropyKernel, "neighbors", m_Solver.particleGrid.neighbors);
|
||||
constraintsShader.SetBuffer(accumAnisotropyKernel, "anisotropies", m_Solver.anisotropiesBuffer);
|
||||
constraintsShader.SetBuffer(accumAnisotropyKernel, "renderablePositions", m_Solver.particleGrid.sortedPositions);
|
||||
constraintsShader.SetBuffer(accumAnisotropyKernel, "sortedFluidMaterials", m_Solver.particleGrid.sortedFluidMaterials);
|
||||
constraintsShader.SetBuffer(accumAnisotropyKernel, "dispatchBuffer", m_Solver.fluidDispatchBuffer);
|
||||
constraintsShader.DispatchIndirect(accumAnisotropyKernel, m_Solver.fluidDispatchBuffer);
|
||||
|
||||
// average anisotropies:
|
||||
constraintsShader.SetBuffer(averageAnisotropyKernel, "sortedToOriginal", m_Solver.particleGrid.sortedFluidIndices);
|
||||
constraintsShader.SetBuffer(averageAnisotropyKernel, "anisotropies", m_Solver.anisotropiesBuffer);
|
||||
constraintsShader.SetBuffer(averageAnisotropyKernel, "renderablePositions", m_Solver.renderablePositionsBuffer);
|
||||
constraintsShader.SetBuffer(averageAnisotropyKernel, "renderableOrientations", m_Solver.renderableOrientationsBuffer);
|
||||
constraintsShader.SetBuffer(averageAnisotropyKernel, "renderableRadii", m_Solver.renderableRadiiBuffer);
|
||||
constraintsShader.SetBuffer(averageAnisotropyKernel, "sortedPrincipalRadii", m_Solver.particleGrid.sortedPrincipalRadii);
|
||||
constraintsShader.SetBuffer(averageAnisotropyKernel, "fluidData", m_Solver.fluidDataBuffer);
|
||||
constraintsShader.SetBuffer(averageAnisotropyKernel, "dispatchBuffer", m_Solver.fluidDispatchBuffer);
|
||||
constraintsShader.SetBuffer(averageAnisotropyKernel, "life", m_Solver.lifeBuffer);
|
||||
constraintsShader.DispatchIndirect(averageAnisotropyKernel, m_Solver.fluidDispatchBuffer);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e1927f3839c94d8e806b2ba446e2797
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,93 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeDensityConstraintsBatch : ComputeConstraintsBatchImpl, IDensityConstraintsBatchImpl
|
||||
{
|
||||
|
||||
public ComputeDensityConstraintsBatch(ComputeDensityConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.Density;
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (solverImplementation.particleGrid.sortedFluidIndices != null && solverImplementation.cellCoordsBuffer != null)
|
||||
{
|
||||
var shader = ((ComputeDensityConstraints)m_Constraints).constraintsShader;
|
||||
int densitiesKernel = ((ComputeDensityConstraints)m_Constraints).updateDensitiesKernel;
|
||||
|
||||
// Need to do this at least every simulation step, since fluid meshing reuses sorted arrays.
|
||||
((ComputeDensityConstraints)m_Constraints).CopyDataInSortedOrder();
|
||||
|
||||
shader.SetInt("maxNeighbors", solverImplementation.particleGrid.maxParticleNeighbors);
|
||||
shader.SetInt("mode", (int)solverImplementation.abstraction.parameters.mode);
|
||||
shader.SetFloat("deltaTime", substepTime);
|
||||
shader.SetVector("diffusionMask", solverAbstraction.parameters.diffusionMask);
|
||||
|
||||
// calculate densities:
|
||||
shader.SetBuffer(densitiesKernel, "neighborCounts", this.solverImplementation.particleGrid.neighborCounts);
|
||||
shader.SetBuffer(densitiesKernel, "neighbors", this.solverImplementation.particleGrid.neighbors);
|
||||
|
||||
shader.SetBuffer(densitiesKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(densitiesKernel, "sortedFluidData", solverImplementation.particleGrid.sortedFluidData);
|
||||
shader.SetBuffer(densitiesKernel, "sortedPositions", solverImplementation.particleGrid.sortedPositions);
|
||||
shader.SetBuffer(densitiesKernel, "sortedPrevPositions", solverImplementation.particleGrid.sortedPrevPosOrientations);
|
||||
shader.SetBuffer(densitiesKernel, "sortedFluidMaterials", solverImplementation.particleGrid.sortedFluidMaterials);
|
||||
shader.SetBuffer(densitiesKernel, "sortedPrincipalRadii", solverImplementation.particleGrid.sortedPrincipalRadii);
|
||||
shader.SetBuffer(densitiesKernel, "renderableOrientations", solverImplementation.orientationDeltasIntBuffer);
|
||||
shader.SetBuffer(densitiesKernel, "prevPositions", solverImplementation.prevPositionsBuffer);
|
||||
shader.SetBuffer(densitiesKernel, "massCenters", solverImplementation.normalsBuffer);
|
||||
shader.SetBuffer(densitiesKernel, "prevMassCenters", solverImplementation.renderablePositionsBuffer);
|
||||
shader.SetBuffer(densitiesKernel, "dispatchBuffer", solverImplementation.fluidDispatchBuffer);
|
||||
|
||||
shader.DispatchIndirect(densitiesKernel, solverImplementation.fluidDispatchBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(float substepTime)
|
||||
{
|
||||
if (solverImplementation.particleGrid.sortedFluidIndices != null && solverImplementation.cellCoordsBuffer != null)
|
||||
{
|
||||
var shader = ((ComputeDensityConstraints)m_Constraints).constraintsShader;
|
||||
var applyPositionDeltaKernel = ((ComputeDensityConstraints)m_Constraints).applyPositionDeltaKernel;
|
||||
var applyKernel = ((ComputeDensityConstraints)m_Constraints).applyKernel;
|
||||
|
||||
// calculate deltas:
|
||||
shader.SetBuffer(applyKernel, "neighborCounts", this.solverImplementation.particleGrid.neighborCounts);
|
||||
shader.SetBuffer(applyKernel, "neighbors", this.solverImplementation.particleGrid.neighbors);
|
||||
|
||||
shader.SetBuffer(applyKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(applyKernel, "sortedPositions", solverImplementation.particleGrid.sortedPositions);
|
||||
shader.SetBuffer(applyKernel, "sortedPrevPositions", solverImplementation.particleGrid.sortedPrevPosOrientations);
|
||||
shader.SetBuffer(applyKernel, "sortedFluidMaterials", solverImplementation.particleGrid.sortedFluidMaterials);
|
||||
shader.SetBuffer(applyKernel, "sortedPrincipalRadii", solverImplementation.particleGrid.sortedPrincipalRadii);
|
||||
shader.SetBuffer(applyKernel, "renderableOrientations", solverImplementation.orientationDeltasIntBuffer);
|
||||
shader.SetBuffer(applyKernel, "prevPositions", solverImplementation.prevPositionsBuffer);
|
||||
shader.SetBuffer(applyKernel, "massCenters", solverImplementation.normalsBuffer);
|
||||
shader.SetBuffer(applyKernel, "prevMassCenters", solverImplementation.renderablePositionsBuffer);
|
||||
shader.SetBuffer(applyKernel, "sortedFluidData", solverImplementation.particleGrid.sortedFluidData);
|
||||
shader.SetBuffer(applyKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(applyKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(applyKernel, "sortedToOriginal", solverImplementation.particleGrid.sortedFluidIndices);
|
||||
shader.SetBuffer(applyKernel, "dispatchBuffer", solverImplementation.fluidDispatchBuffer);
|
||||
|
||||
shader.DispatchIndirect(applyKernel, solverImplementation.fluidDispatchBuffer);
|
||||
|
||||
// apply position deltas
|
||||
shader.SetBuffer(applyPositionDeltaKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(applyPositionDeltaKernel, "fluidData", solverImplementation.fluidDataBuffer);
|
||||
shader.SetBuffer(applyPositionDeltaKernel, "sortedFluidData", solverImplementation.particleGrid.sortedFluidData);
|
||||
shader.SetBuffer(applyPositionDeltaKernel, "renderableOrientations", solverImplementation.orientationDeltasIntBuffer);
|
||||
shader.SetBuffer(applyPositionDeltaKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(applyPositionDeltaKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(applyPositionDeltaKernel, "sortedToOriginal", solverImplementation.particleGrid.sortedFluidIndices);
|
||||
shader.SetBuffer(applyPositionDeltaKernel, "dispatchBuffer", solverImplementation.fluidDispatchBuffer);
|
||||
|
||||
shader.DispatchIndirect(applyPositionDeltaKernel, solverImplementation.fluidDispatchBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 277bb45dfcd314cdd8e9d917bcc05955
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: beca9bcaa99b64d8188c2ac127314259
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeDistanceConstraints : ComputeConstraintsImpl<ComputeDistanceConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int projectKernel;
|
||||
public int applyKernel;
|
||||
|
||||
public ComputeDistanceConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.Distance)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/DistanceConstraints"));
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputeDistanceConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputeDistanceConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
|
||||
public void RequestDataReadback()
|
||||
{
|
||||
foreach (var batch in batches)
|
||||
batch.RequestDataReadback();
|
||||
}
|
||||
|
||||
public void WaitForReadback()
|
||||
{
|
||||
foreach (var batch in batches)
|
||||
batch.WaitForReadback();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c56c65d479be44432ba437d871d4892d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,85 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeDistanceConstraintsBatch : ComputeConstraintsBatchImpl, IDistanceConstraintsBatchImpl
|
||||
{
|
||||
|
||||
GraphicsBuffer restLengthsBuffer;
|
||||
GraphicsBuffer stiffnessesBuffer;
|
||||
|
||||
public ComputeDistanceConstraintsBatch(ComputeDistanceConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.Distance;
|
||||
}
|
||||
|
||||
public void SetDistanceConstraints(ObiNativeIntList particleIndices, ObiNativeFloatList restLengths, ObiNativeVector2List stiffnesses, ObiNativeFloatList lambdas, int count)
|
||||
{
|
||||
this.particleIndices = particleIndices.AsComputeBuffer<int>();
|
||||
this.restLengthsBuffer = restLengths.AsComputeBuffer<float>();
|
||||
this.stiffnessesBuffer = stiffnesses.AsComputeBuffer<Vector2>();
|
||||
this.lambdas = lambdas.AsComputeBuffer<float>();
|
||||
this.lambdasList = lambdas;
|
||||
|
||||
m_ConstraintCount = count;
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var shader = ((ComputeDistanceConstraints)m_Constraints).constraintsShader;
|
||||
int projectKernel = ((ComputeDistanceConstraints)m_Constraints).projectKernel;
|
||||
|
||||
shader.SetBuffer(projectKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(projectKernel, "restLengths", restLengthsBuffer);
|
||||
shader.SetBuffer(projectKernel, "stiffnesses", stiffnessesBuffer);
|
||||
shader.SetBuffer(projectKernel, "lambdas", lambdas);
|
||||
|
||||
shader.SetBuffer(projectKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(projectKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("deltaTime", substepTime);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(projectKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(float deltaTime)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var parameters = solverAbstraction.GetConstraintParameters(m_ConstraintType);
|
||||
|
||||
var shader = ((ComputeDistanceConstraints)m_Constraints).constraintsShader;
|
||||
int applyKernel = ((ComputeDistanceConstraints)m_Constraints).applyKernel;
|
||||
|
||||
shader.SetBuffer(applyKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(applyKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(applyKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(applyKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("sorFactor", parameters.SORFactor);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(applyKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void RequestDataReadback()
|
||||
{
|
||||
lambdasList.Readback();
|
||||
}
|
||||
|
||||
public void WaitForReadback()
|
||||
{
|
||||
lambdasList.WaitForReadback();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e197e97b0c8b94a84bce0a448e62e5fb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da310e9f3c6a84350b6e00bda41d8a90
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeParticleCollisionConstraints : ComputeConstraintsImpl<ComputeParticleCollisionConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int initializeKernel;
|
||||
public int projectKernel;
|
||||
public int applyKernel;
|
||||
|
||||
public ComputeParticleCollisionConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.ParticleCollision)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/ParticleCollisionConstraints"));
|
||||
initializeKernel = constraintsShader.FindKernel("Initialize");
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputeParticleCollisionConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputeParticleCollisionConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0039bc61ce4bc4aaa952b7bf1463c8b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,112 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeParticleCollisionConstraintsBatch : ComputeConstraintsBatchImpl, IParticleCollisionConstraintsBatchImpl
|
||||
{
|
||||
|
||||
public ComputeParticleCollisionConstraintsBatch(ComputeParticleCollisionConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.ParticleCollision;
|
||||
}
|
||||
|
||||
public override void Initialize(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
var shader = ((ComputeParticleCollisionConstraints)m_Constraints).constraintsShader;
|
||||
int initializeKernel = ((ComputeParticleCollisionConstraints)m_Constraints).initializeKernel;
|
||||
|
||||
if (solverImplementation.simplexCounts.simplexCount > 0)
|
||||
{
|
||||
shader.SetInt("pointCount", solverAbstraction.simplexCounts.pointCount);
|
||||
shader.SetInt("edgeCount", solverAbstraction.simplexCounts.edgeCount);
|
||||
shader.SetInt("triangleCount", solverAbstraction.simplexCounts.triangleCount);
|
||||
shader.SetFloat("shockPropagation", solverAbstraction.parameters.shockPropagation);
|
||||
shader.SetVector("gravity", solverAbstraction.parameters.gravity);
|
||||
|
||||
shader.SetBuffer(initializeKernel, "simplices", this.solverImplementation.simplices);
|
||||
shader.SetBuffer(initializeKernel, "particleContacts", solverAbstraction.particleContacts.computeBuffer);
|
||||
shader.SetBuffer(initializeKernel, "effectiveMasses", solverAbstraction.particleContactEffectiveMasses.computeBuffer);
|
||||
shader.SetBuffer(initializeKernel, "dispatchBuffer", this.solverImplementation.particleGrid.dispatchBuffer);
|
||||
shader.SetBuffer(initializeKernel, "collisionMaterials", this.solverImplementation.colliderGrid.materialsBuffer);
|
||||
|
||||
shader.SetBuffer(initializeKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(initializeKernel, "prevPositions", solverImplementation.prevPositionsBuffer);
|
||||
shader.SetBuffer(initializeKernel, "orientations", solverImplementation.orientationsBuffer);
|
||||
shader.SetBuffer(initializeKernel, "prevOrientations", solverImplementation.prevOrientationsBuffer);
|
||||
shader.SetBuffer(initializeKernel, "principalRadii", solverImplementation.principalRadiiBuffer);
|
||||
shader.SetBuffer(initializeKernel, "velocities", solverImplementation.velocitiesBuffer);
|
||||
shader.SetBuffer(initializeKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(initializeKernel, "collisionMaterialIndices", solverImplementation.collisionMaterialIndexBuffer);
|
||||
shader.SetBuffer(initializeKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(initializeKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(initializeKernel, "invRotationalMasses", solverImplementation.invMassesBuffer);
|
||||
|
||||
shader.SetFloat("substepTime", substepTime);
|
||||
|
||||
shader.DispatchIndirect(initializeKernel, this.solverImplementation.particleGrid.dispatchBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (solverImplementation.simplexCounts.simplexCount > 0)
|
||||
{
|
||||
var shader = ((ComputeParticleCollisionConstraints)m_Constraints).constraintsShader;
|
||||
int projectKernel = ((ComputeParticleCollisionConstraints)m_Constraints).projectKernel;
|
||||
|
||||
shader.SetBuffer(projectKernel, "particleContacts", solverAbstraction.particleContacts.computeBuffer);
|
||||
shader.SetBuffer(projectKernel, "effectiveMasses", solverAbstraction.particleContactEffectiveMasses.computeBuffer);
|
||||
shader.SetBuffer(projectKernel, "dispatchBuffer", this.solverImplementation.particleGrid.dispatchBuffer);
|
||||
shader.SetBuffer(projectKernel, "collisionMaterials", this.solverImplementation.colliderGrid.materialsBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "simplices", this.solverImplementation.simplices);
|
||||
shader.SetBuffer(projectKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "prevPositions", solverImplementation.prevPositionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientations", solverImplementation.orientationsBuffer);
|
||||
shader.SetBuffer(projectKernel, "prevOrientations", solverImplementation.prevOrientationsBuffer);
|
||||
shader.SetBuffer(projectKernel, "principalRadii", solverImplementation.principalRadiiBuffer);
|
||||
shader.SetBuffer(projectKernel, "fluidInterface", solverImplementation.fluidInterfaceBuffer);
|
||||
shader.SetBuffer(projectKernel, "userData", solverImplementation.userDataBuffer);
|
||||
shader.SetBuffer(projectKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientationConstraintCounts", solverImplementation.orientationConstraintCountBuffer);
|
||||
shader.SetBuffer(projectKernel, "collisionMaterialIndices", solverImplementation.collisionMaterialIndexBuffer);
|
||||
shader.SetBuffer(projectKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientationDeltasAsInt", solverImplementation.orientationDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
|
||||
shader.SetFloat("maxDepenetration", solverAbstraction.parameters.maxDepenetration);
|
||||
shader.SetFloat("collisionMargin", solverAbstraction.parameters.collisionMargin);
|
||||
shader.SetVector("diffusionMask", solverAbstraction.parameters.diffusionMask);
|
||||
shader.SetFloat("substepTime", substepTime);
|
||||
|
||||
shader.DispatchIndirect(projectKernel, this.solverImplementation.particleGrid.dispatchBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(float substepTime)
|
||||
{
|
||||
var shader = ((ComputeParticleCollisionConstraints)m_Constraints).constraintsShader;
|
||||
int applyKernel = ((ComputeParticleCollisionConstraints)m_Constraints).applyKernel;
|
||||
|
||||
if (solverImplementation.activeParticleCount > 0)
|
||||
{
|
||||
var parameters = solverAbstraction.GetConstraintParameters(m_ConstraintType);
|
||||
|
||||
shader.SetBuffer(applyKernel, "particleIndices", this.solverImplementation.activeParticlesBuffer);
|
||||
shader.SetBuffer(applyKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(applyKernel, "userData", solverImplementation.userDataBuffer);
|
||||
shader.SetBuffer(applyKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(applyKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(applyKernel, "orientationConstraintCounts", solverImplementation.orientationConstraintCountBuffer);
|
||||
shader.SetBuffer(applyKernel, "orientationDeltasAsInt", solverImplementation.orientationDeltasIntBuffer);
|
||||
|
||||
shader.SetInt("particleCount", this.solverAbstraction.activeParticleCount);
|
||||
shader.SetFloat("sorFactor", parameters.SORFactor);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(this.solverAbstraction.activeParticleCount, 128);
|
||||
shader.Dispatch(applyKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 425e2aa73a5f746039203ce1c0ac3a00
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeParticleFrictionConstraints : ComputeConstraintsImpl<ComputeParticleFrictionConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int projectKernel;
|
||||
public int applyKernel;
|
||||
|
||||
public ComputeParticleFrictionConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.ParticleFriction)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/ParticleFrictionConstraints"));
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputeParticleFrictionConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputeParticleFrictionConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41b95f7aa768148b38a09f35bee8efce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,79 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeParticleFrictionConstraintsBatch : ComputeConstraintsBatchImpl, IParticleCollisionConstraintsBatchImpl
|
||||
{
|
||||
|
||||
public ComputeParticleFrictionConstraintsBatch(ComputeParticleFrictionConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.ParticleFriction;
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
//if (m_ConstraintCount > 0)
|
||||
if (solverImplementation.simplexCounts.simplexCount > 0 && solverImplementation.activeParticleCount > 0)
|
||||
{
|
||||
var shader = ((ComputeParticleFrictionConstraints)m_Constraints).constraintsShader;
|
||||
int projectKernel = ((ComputeParticleFrictionConstraints)m_Constraints).projectKernel;
|
||||
|
||||
shader.SetInt("pointCount", solverAbstraction.simplexCounts.pointCount);
|
||||
shader.SetInt("edgeCount", solverAbstraction.simplexCounts.edgeCount);
|
||||
shader.SetInt("triangleCount", solverAbstraction.simplexCounts.triangleCount);
|
||||
|
||||
shader.SetBuffer(projectKernel, "particleContacts", solverAbstraction.particleContacts.computeBuffer);
|
||||
shader.SetBuffer(projectKernel, "effectiveMasses", solverAbstraction.particleContactEffectiveMasses.computeBuffer);
|
||||
shader.SetBuffer(projectKernel, "dispatchBuffer", solverImplementation.particleGrid.dispatchBuffer);
|
||||
shader.SetBuffer(projectKernel, "collisionMaterials", solverImplementation.colliderGrid.materialsBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "simplices", solverImplementation.simplices);
|
||||
shader.SetBuffer(projectKernel, "collisionMaterialIndices", solverImplementation.collisionMaterialIndexBuffer);
|
||||
shader.SetBuffer(projectKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientations", solverImplementation.orientationsBuffer);
|
||||
shader.SetBuffer(projectKernel, "prevPositions", solverImplementation.prevPositionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "prevOrientations", solverImplementation.prevOrientationsBuffer);
|
||||
shader.SetBuffer(projectKernel, "principalRadii", solverImplementation.principalRadiiBuffer);
|
||||
shader.SetBuffer(projectKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(projectKernel, "invRotationalMasses", solverImplementation.invRotationalMassesBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(projectKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientationConstraintCounts", solverImplementation.orientationConstraintCountBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientationDeltasAsInt", solverImplementation.orientationDeltasIntBuffer);
|
||||
|
||||
shader.SetFloat("stepTime", stepTime);
|
||||
shader.SetFloat("substepTime", substepTime);
|
||||
|
||||
shader.DispatchIndirect(projectKernel, this.solverImplementation.particleGrid.dispatchBuffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void Apply(float substepTime)
|
||||
{
|
||||
var shader = ((ComputeParticleFrictionConstraints)m_Constraints).constraintsShader;
|
||||
int applyKernel = ((ComputeParticleFrictionConstraints)m_Constraints).applyKernel;
|
||||
|
||||
if (solverImplementation.activeParticleCount > 0)
|
||||
{
|
||||
var parameters = solverAbstraction.GetConstraintParameters(m_ConstraintType);
|
||||
|
||||
shader.SetBuffer(applyKernel, "particleIndices", this.solverImplementation.activeParticlesBuffer);
|
||||
shader.SetBuffer(applyKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(applyKernel, "orientations", solverImplementation.orientationsBuffer);
|
||||
shader.SetBuffer(applyKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(applyKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(applyKernel, "orientationConstraintCounts", solverImplementation.orientationConstraintCountBuffer);
|
||||
shader.SetBuffer(applyKernel, "orientationDeltasAsInt", solverImplementation.orientationDeltasIntBuffer);
|
||||
|
||||
shader.SetInt("particleCount", this.solverAbstraction.activeParticleCount);
|
||||
shader.SetFloat("sorFactor", parameters.SORFactor);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(this.solverAbstraction.activeParticleCount, 128);
|
||||
shader.Dispatch(applyKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12275bbeff9604bb393a365d8442161a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b03d5abd353fb4064bf5677d949196a1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputePinConstraints : ComputeConstraintsImpl<ComputePinConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int clearKernel;
|
||||
public int initializeKernel;
|
||||
public int projectKernel;
|
||||
public int applyKernel;
|
||||
public int projectRenderableKernel;
|
||||
|
||||
public ComputePinConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.Pin)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/PinConstraints"));
|
||||
clearKernel = constraintsShader.FindKernel("Clear");
|
||||
initializeKernel = constraintsShader.FindKernel("Initialize");
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
projectRenderableKernel = constraintsShader.FindKernel("ProjectRenderable");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputePinConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputePinConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
|
||||
public void RequestDataReadback()
|
||||
{
|
||||
foreach (var batch in batches)
|
||||
batch.RequestDataReadback();
|
||||
}
|
||||
|
||||
public void WaitForReadback()
|
||||
{
|
||||
foreach (var batch in batches)
|
||||
batch.WaitForReadback();
|
||||
}
|
||||
|
||||
public void ProjectRenderablePositions()
|
||||
{
|
||||
for (int i = 0; i < batches.Count; ++i)
|
||||
{
|
||||
if (batches[i].enabled)
|
||||
{
|
||||
batches[i].ProjectRenderablePositions();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0fcd123efb9af486783fa2eca750d731
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,167 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputePinConstraintsBatch : ComputeConstraintsBatchImpl, IPinConstraintsBatchImpl
|
||||
{
|
||||
GraphicsBuffer colliderIndices;
|
||||
GraphicsBuffer offsets;
|
||||
GraphicsBuffer restDarboux;
|
||||
GraphicsBuffer stiffnesses;
|
||||
|
||||
public ComputePinConstraintsBatch(ComputePinConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.Pin;
|
||||
}
|
||||
|
||||
public void SetPinConstraints(ObiNativeIntList particleIndices, ObiNativeIntList colliderIndices, ObiNativeVector4List offsets, ObiNativeQuaternionList restDarbouxVectors, ObiNativeFloatList stiffnesses, ObiNativeFloatList lambdas, int count)
|
||||
{
|
||||
this.particleIndices = particleIndices.AsComputeBuffer<int>();
|
||||
this.colliderIndices = colliderIndices.AsComputeBuffer<int>();
|
||||
this.offsets = offsets.AsComputeBuffer<Vector4>();
|
||||
this.restDarboux = restDarbouxVectors.AsComputeBuffer<Quaternion>();
|
||||
this.stiffnesses = stiffnesses.AsComputeBuffer<Vector2>();
|
||||
this.lambdas = lambdas.AsComputeBuffer<Vector4>();
|
||||
this.lambdasList = lambdas;
|
||||
|
||||
m_ConstraintCount = count;
|
||||
}
|
||||
|
||||
public override void Initialize(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var shader = ((ComputePinConstraints)m_Constraints).constraintsShader;
|
||||
int clearKernel = ((ComputePinConstraints)m_Constraints).clearKernel;
|
||||
int initializeKernel = ((ComputePinConstraints)m_Constraints).initializeKernel;
|
||||
|
||||
shader.SetBuffer(clearKernel, "colliderIndices", colliderIndices);
|
||||
shader.SetBuffer(clearKernel, "shapes", this.solverImplementation.colliderGrid.shapesBuffer);
|
||||
shader.SetBuffer(clearKernel, "RW_rigidbodies", this.solverImplementation.colliderGrid.rigidbodiesBuffer);
|
||||
|
||||
shader.SetBuffer(initializeKernel, "colliderIndices", colliderIndices);
|
||||
shader.SetBuffer(initializeKernel, "shapes", this.solverImplementation.colliderGrid.shapesBuffer);
|
||||
shader.SetBuffer(initializeKernel, "RW_rigidbodies", this.solverImplementation.colliderGrid.rigidbodiesBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(clearKernel, threadGroups, 1, 1);
|
||||
shader.Dispatch(initializeKernel, threadGroups, 1, 1);
|
||||
}
|
||||
|
||||
// clear lambdas:
|
||||
base.Initialize(stepTime, substepTime, steps, timeLeft);
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var shader = ((ComputePinConstraints)m_Constraints).constraintsShader;
|
||||
int projectKernel = ((ComputePinConstraints)m_Constraints).projectKernel;
|
||||
|
||||
shader.SetBuffer(projectKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(projectKernel, "colliderIndices", colliderIndices);
|
||||
shader.SetBuffer(projectKernel, "offsets", offsets);
|
||||
shader.SetBuffer(projectKernel, "restDarboux", restDarboux);
|
||||
shader.SetBuffer(projectKernel, "stiffnesses", stiffnesses);
|
||||
shader.SetBuffer(projectKernel, "lambdas", lambdas);
|
||||
|
||||
shader.SetBuffer(projectKernel, "transforms", this.solverImplementation.colliderGrid.transformsBuffer);
|
||||
shader.SetBuffer(projectKernel, "shapes", this.solverImplementation.colliderGrid.shapesBuffer);
|
||||
shader.SetBuffer(projectKernel, "rigidbodies", this.solverImplementation.colliderGrid.rigidbodiesBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "prevPositions", solverImplementation.prevPositionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientations", solverImplementation.orientationsBuffer);
|
||||
shader.SetBuffer(projectKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(projectKernel, "invRotationalMasses", solverImplementation.invRotationalMassesBuffer);
|
||||
shader.SetBuffer(projectKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientationDeltasAsInt", solverImplementation.orientationDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientationConstraintCounts", solverImplementation.orientationConstraintCountBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "linearDeltasAsInt", solverImplementation.rigidbodyLinearDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "angularDeltasAsInt", solverImplementation.rigidbodyAngularDeltasIntBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "inertialSolverFrame", solverImplementation.inertialFrameBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("stepTime", stepTime);
|
||||
shader.SetFloat("substepTime", substepTime);
|
||||
shader.SetInt("steps", steps);
|
||||
shader.SetFloat("timeLeft", timeLeft);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(projectKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(float substepTime)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var parameters = solverAbstraction.GetConstraintParameters(m_ConstraintType);
|
||||
|
||||
var shader = ((ComputePinConstraints)m_Constraints).constraintsShader;
|
||||
int applyKernel = ((ComputePinConstraints)m_Constraints).applyKernel;
|
||||
|
||||
shader.SetBuffer(applyKernel, "particleIndices", particleIndices);
|
||||
|
||||
shader.SetBuffer(applyKernel, "RW_positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(applyKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(applyKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
|
||||
shader.SetBuffer(applyKernel, "RW_orientations", solverImplementation.orientationsBuffer);
|
||||
shader.SetBuffer(applyKernel, "orientationDeltasAsInt", solverImplementation.orientationDeltasIntBuffer);
|
||||
shader.SetBuffer(applyKernel, "orientationConstraintCounts", solverImplementation.orientationConstraintCountBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("sorFactor", parameters.SORFactor);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(applyKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void ProjectRenderablePositions()
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var shader = ((ComputePinConstraints)m_Constraints).constraintsShader;
|
||||
int projectRenderableKernel = ((ComputePinConstraints)m_Constraints).projectRenderableKernel;
|
||||
|
||||
shader.SetBuffer(projectRenderableKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(projectRenderableKernel, "colliderIndices", colliderIndices);
|
||||
shader.SetBuffer(projectRenderableKernel, "offsets", offsets);
|
||||
shader.SetBuffer(projectRenderableKernel, "restDarboux", restDarboux);
|
||||
shader.SetBuffer(projectRenderableKernel, "stiffnesses", stiffnesses);
|
||||
|
||||
shader.SetBuffer(projectRenderableKernel, "transforms", this.solverImplementation.colliderGrid.transformsBuffer);
|
||||
|
||||
shader.SetBuffer(projectRenderableKernel, "RW_positions", solverImplementation.renderablePositionsBuffer);
|
||||
shader.SetBuffer(projectRenderableKernel, "RW_orientations", solverImplementation.renderableOrientationsBuffer);
|
||||
|
||||
shader.SetBuffer(projectRenderableKernel, "inertialSolverFrame", solverImplementation.inertialFrameBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(projectRenderableKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void RequestDataReadback()
|
||||
{
|
||||
lambdasList.Readback();
|
||||
}
|
||||
|
||||
public void WaitForReadback()
|
||||
{
|
||||
lambdasList.WaitForReadback();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf8b3fc4b0e8f4ab3ab1f4418e053a8f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67d3689a6a1a94c8b88ec9d27a88963f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputePinholeConstraints : ComputeConstraintsImpl<ComputePinholeConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int clearKernel;
|
||||
public int initializeKernel;
|
||||
public int projectKernel;
|
||||
public int applyKernel;
|
||||
|
||||
public ComputePinholeConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.Pinhole)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/PinholeConstraints"));
|
||||
clearKernel = constraintsShader.FindKernel("Clear");
|
||||
initializeKernel = constraintsShader.FindKernel("Initialize");
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputePinholeConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputePinholeConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
|
||||
public void RequestDataReadback()
|
||||
{
|
||||
foreach (var batch in batches)
|
||||
batch.RequestDataReadback();
|
||||
}
|
||||
|
||||
public void WaitForReadback()
|
||||
{
|
||||
foreach (var batch in batches)
|
||||
batch.WaitForReadback();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac5087fe6e43f4ffc8b73089fd3f96b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,165 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputePinholeConstraintsBatch : ComputeConstraintsBatchImpl, IPinholeConstraintsBatchImpl
|
||||
{
|
||||
GraphicsBuffer colliderIndices;
|
||||
GraphicsBuffer offsets;
|
||||
GraphicsBuffer edgeMus;
|
||||
GraphicsBuffer edgeRanges;
|
||||
GraphicsBuffer edgeRangeMus;
|
||||
GraphicsBuffer relativeVelocities;
|
||||
GraphicsBuffer parameters;
|
||||
|
||||
public ComputePinholeConstraintsBatch(ComputePinholeConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.Pinhole;
|
||||
}
|
||||
|
||||
public void SetPinholeConstraints(ObiNativeIntList particleIndices, ObiNativeIntList colliderIndices, ObiNativeVector4List offsets, ObiNativeFloatList edgeMus, ObiNativeIntList edgeRanges, ObiNativeFloatList edgeRangeMus, ObiNativeFloatList parameters, ObiNativeFloatList relativeVelocities, ObiNativeFloatList lambdas, int count)
|
||||
{
|
||||
this.particleIndices = particleIndices.AsComputeBuffer<int>();
|
||||
this.colliderIndices = colliderIndices.AsComputeBuffer<int>();
|
||||
this.offsets = offsets.AsComputeBuffer<Vector4>();
|
||||
this.edgeMus = edgeMus.AsComputeBuffer<float>();
|
||||
this.edgeRanges = edgeRanges.AsComputeBuffer<Vector2Int>();
|
||||
this.edgeRangeMus = edgeRangeMus.AsComputeBuffer<Vector2>();
|
||||
this.parameters = parameters.AsComputeBuffer<float>();
|
||||
this.lambdas = lambdas.AsComputeBuffer<float>();
|
||||
this.relativeVelocities = relativeVelocities.AsComputeBuffer<float>();
|
||||
this.lambdasList = lambdas;
|
||||
|
||||
m_ConstraintCount = count;
|
||||
}
|
||||
|
||||
public override void Initialize(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var shader = ((ComputePinholeConstraints)m_Constraints).constraintsShader;
|
||||
int clearKernel = ((ComputePinholeConstraints)m_Constraints).clearKernel;
|
||||
int initializeKernel = ((ComputePinholeConstraints)m_Constraints).initializeKernel;
|
||||
|
||||
shader.SetBuffer(clearKernel, "colliderIndices", colliderIndices);
|
||||
shader.SetBuffer(clearKernel, "shapes", this.solverImplementation.colliderGrid.shapesBuffer);
|
||||
shader.SetBuffer(clearKernel, "RW_rigidbodies", this.solverImplementation.colliderGrid.rigidbodiesBuffer);
|
||||
|
||||
shader.SetBuffer(initializeKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(initializeKernel, "colliderIndices", colliderIndices);
|
||||
shader.SetBuffer(initializeKernel, "offsets", offsets);
|
||||
shader.SetBuffer(initializeKernel, "edgeMus", edgeMus);
|
||||
shader.SetBuffer(initializeKernel, "edgeRanges", edgeRanges);
|
||||
shader.SetBuffer(initializeKernel, "edgeRangeMus", edgeRangeMus);
|
||||
shader.SetBuffer(initializeKernel, "relativeVelocities", relativeVelocities);
|
||||
shader.SetBuffer(initializeKernel, "parameters", parameters);
|
||||
|
||||
shader.SetBuffer(initializeKernel, "deformableEdges", solverImplementation.deformableEdgesBuffer);
|
||||
shader.SetBuffer(initializeKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(initializeKernel, "prevPositions", solverImplementation.prevPositionsBuffer);
|
||||
shader.SetBuffer(initializeKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
|
||||
shader.SetBuffer(initializeKernel, "colliderIndices", colliderIndices);
|
||||
shader.SetBuffer(initializeKernel, "transforms", this.solverImplementation.colliderGrid.transformsBuffer);
|
||||
shader.SetBuffer(initializeKernel, "shapes", this.solverImplementation.colliderGrid.shapesBuffer);
|
||||
shader.SetBuffer(initializeKernel, "rigidbodies", this.solverImplementation.colliderGrid.rigidbodiesBuffer);
|
||||
shader.SetBuffer(initializeKernel, "RW_rigidbodies", this.solverImplementation.colliderGrid.rigidbodiesBuffer);
|
||||
|
||||
shader.SetBuffer(initializeKernel, "linearDeltasAsInt", solverImplementation.rigidbodyLinearDeltasIntBuffer);
|
||||
shader.SetBuffer(initializeKernel, "angularDeltasAsInt", solverImplementation.rigidbodyAngularDeltasIntBuffer);
|
||||
|
||||
shader.SetBuffer(initializeKernel, "inertialSolverFrame", solverImplementation.inertialFrameBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("stepTime", stepTime);
|
||||
shader.SetFloat("substepTime", substepTime);
|
||||
shader.SetInt("steps", steps);
|
||||
shader.SetFloat("timeLeft", timeLeft);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(clearKernel, threadGroups, 1, 1);
|
||||
shader.Dispatch(initializeKernel, threadGroups, 1, 1);
|
||||
}
|
||||
|
||||
// clear lambdas:
|
||||
base.Initialize(stepTime, substepTime, steps, timeLeft);
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var shader = ((ComputePinholeConstraints)m_Constraints).constraintsShader;
|
||||
int projectKernel = ((ComputePinholeConstraints)m_Constraints).projectKernel;
|
||||
|
||||
shader.SetBuffer(projectKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(projectKernel, "colliderIndices", colliderIndices);
|
||||
shader.SetBuffer(projectKernel, "offsets", offsets);
|
||||
shader.SetBuffer(projectKernel, "edgeMus", edgeMus);
|
||||
shader.SetBuffer(projectKernel, "parameters", parameters);
|
||||
shader.SetBuffer(projectKernel, "lambdas", lambdas);
|
||||
|
||||
shader.SetBuffer(projectKernel, "transforms", this.solverImplementation.colliderGrid.transformsBuffer);
|
||||
shader.SetBuffer(projectKernel, "shapes", this.solverImplementation.colliderGrid.shapesBuffer);
|
||||
shader.SetBuffer(projectKernel, "rigidbodies", this.solverImplementation.colliderGrid.rigidbodiesBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "deformableEdges", solverImplementation.deformableEdgesBuffer);
|
||||
shader.SetBuffer(projectKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "prevPositions", solverImplementation.prevPositionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(projectKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "linearDeltasAsInt", solverImplementation.rigidbodyLinearDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "angularDeltasAsInt", solverImplementation.rigidbodyAngularDeltasIntBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "inertialSolverFrame", solverImplementation.inertialFrameBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("stepTime", stepTime);
|
||||
shader.SetFloat("substepTime", substepTime);
|
||||
shader.SetInt("steps", steps);
|
||||
shader.SetFloat("timeLeft", timeLeft);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(projectKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(float substepTime)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var param = solverAbstraction.GetConstraintParameters(m_ConstraintType);
|
||||
|
||||
var shader = ((ComputePinholeConstraints)m_Constraints).constraintsShader;
|
||||
int applyKernel = ((ComputePinholeConstraints)m_Constraints).applyKernel;
|
||||
|
||||
shader.SetBuffer(applyKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(applyKernel, "deformableEdges", solverImplementation.deformableEdgesBuffer);
|
||||
|
||||
shader.SetBuffer(applyKernel, "RW_positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(applyKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(applyKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("sorFactor", param.SORFactor);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(applyKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void RequestDataReadback()
|
||||
{
|
||||
lambdasList.Readback();
|
||||
}
|
||||
|
||||
public void WaitForReadback()
|
||||
{
|
||||
lambdasList.WaitForReadback();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 262e3b75b5b53406b92eaed391db8114
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21c4f0318a4dd4112aeb7065a1251e2a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeShapeMatchingConstraints : ComputeConstraintsImpl<ComputeShapeMatchingConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int projectKernel;
|
||||
public int plasticityKernel;
|
||||
public int restStateKernel;
|
||||
public int applyKernel;
|
||||
|
||||
public ComputeShapeMatchingConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.ShapeMatching)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/ShapeMatchingConstraints"));
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
plasticityKernel = constraintsShader.FindKernel("PlasticDeformation");
|
||||
restStateKernel = constraintsShader.FindKernel("CalculateRestShapeMatching");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputeShapeMatchingConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputeShapeMatchingConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
|
||||
public void RequestDataReadback()
|
||||
{
|
||||
foreach(var batch in batches)
|
||||
batch.RequestDataReadback();
|
||||
}
|
||||
|
||||
public void WaitForReadback()
|
||||
{
|
||||
foreach (var batch in batches)
|
||||
batch.WaitForReadback();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2c02ccc8463d4650b854a7a374ac0d3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,204 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeShapeMatchingConstraintsBatch : ComputeConstraintsBatchImpl, IShapeMatchingConstraintsBatchImpl
|
||||
{
|
||||
private GraphicsBuffer firstIndexBuffer;
|
||||
private GraphicsBuffer numIndicesBuffer;
|
||||
private GraphicsBuffer explicitGroupBuffer;
|
||||
private GraphicsBuffer shapeMaterialParametersBuffer;
|
||||
private GraphicsBuffer restComsBuffer;
|
||||
private GraphicsBuffer comsBuffer;
|
||||
private GraphicsBuffer constraintOrientationsBuffer;
|
||||
|
||||
private GraphicsBuffer AqqBuffer;
|
||||
private GraphicsBuffer linearTransformsBuffer;
|
||||
private GraphicsBuffer plasticDeformationsBuffer;
|
||||
|
||||
private ObiNativeVector4List m_RestComs;
|
||||
private ObiNativeVector4List m_Coms;
|
||||
private ObiNativeQuaternionList m_ConstraintOrientations;
|
||||
|
||||
private bool m_RecalculateRestShape = false;
|
||||
public ComputeShapeMatchingConstraintsBatch(ComputeShapeMatchingConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.ShapeMatching;
|
||||
}
|
||||
|
||||
public void SetShapeMatchingConstraints(ObiNativeIntList particleIndices,
|
||||
ObiNativeIntList firstIndex,
|
||||
ObiNativeIntList numIndices,
|
||||
ObiNativeIntList explicitGroup,
|
||||
ObiNativeFloatList shapeMaterialParameters,
|
||||
ObiNativeVector4List restComs,
|
||||
ObiNativeVector4List coms,
|
||||
ObiNativeQuaternionList constraintOrientations,
|
||||
ObiNativeMatrix4x4List linearTransforms,
|
||||
ObiNativeMatrix4x4List plasticDeformations,
|
||||
ObiNativeFloatList lambdas,
|
||||
int count)
|
||||
{
|
||||
this.particleIndices = particleIndices.AsComputeBuffer<int>();
|
||||
this.firstIndexBuffer = firstIndex.AsComputeBuffer<int>();
|
||||
this.numIndicesBuffer = numIndices.AsComputeBuffer<int>();
|
||||
this.explicitGroupBuffer = explicitGroup.AsComputeBuffer<int>();
|
||||
this.shapeMaterialParametersBuffer = shapeMaterialParameters.AsComputeBuffer<float>();
|
||||
this.restComsBuffer = restComs.AsComputeBuffer<Vector4>();
|
||||
this.comsBuffer = coms.AsComputeBuffer<Vector4>();
|
||||
this.constraintOrientationsBuffer = constraintOrientations.AsComputeBuffer<Quaternion>();
|
||||
this.linearTransformsBuffer = linearTransforms.AsComputeBuffer<Matrix4x4>();
|
||||
this.plasticDeformationsBuffer = plasticDeformations.AsComputeBuffer<Matrix4x4>();
|
||||
|
||||
if (AqqBuffer != null)
|
||||
AqqBuffer.Dispose();
|
||||
|
||||
AqqBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, count, 64); // float4x4
|
||||
|
||||
m_RestComs = restComs;
|
||||
m_Coms = coms;
|
||||
m_ConstraintOrientations = constraintOrientations;
|
||||
|
||||
m_ConstraintCount = count;
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
if (AqqBuffer != null)
|
||||
AqqBuffer.Dispose();
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var shader = ((ComputeShapeMatchingConstraints)m_Constraints).constraintsShader;
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("deltaTime", substepTime);
|
||||
|
||||
if (m_RecalculateRestShape)
|
||||
{
|
||||
m_RecalculateRestShape = false;
|
||||
|
||||
int restKernel = ((ComputeShapeMatchingConstraints)m_Constraints).restStateKernel;
|
||||
|
||||
shader.SetBuffer(restKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(restKernel, "firstIndex", firstIndexBuffer);
|
||||
shader.SetBuffer(restKernel, "numIndices", numIndicesBuffer);
|
||||
shader.SetBuffer(restKernel, "RW_restComs", restComsBuffer);
|
||||
|
||||
shader.SetBuffer(restKernel, "RW_Aqq", AqqBuffer);
|
||||
shader.SetBuffer(restKernel, "RW_deformation", plasticDeformationsBuffer);
|
||||
|
||||
shader.SetBuffer(restKernel, "restPositions", solverImplementation.restPositionsBuffer);
|
||||
shader.SetBuffer(restKernel, "restOrientations", solverImplementation.restOrientationsBuffer);
|
||||
shader.SetBuffer(restKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(restKernel, "invRotationalMasses", solverImplementation.invRotationalMassesBuffer);
|
||||
shader.SetBuffer(restKernel, "principalRadii", solverImplementation.principalRadiiBuffer);
|
||||
|
||||
shader.Dispatch(restKernel, threadGroups, 1, 1);
|
||||
|
||||
m_RestComs.Readback();
|
||||
m_RestComs.WaitForReadback();
|
||||
}
|
||||
|
||||
//var shader = ((ComputeShapeMatchingConstraints)m_Constraints).constraintsShader;
|
||||
int projectKernel = ((ComputeShapeMatchingConstraints)m_Constraints).projectKernel;
|
||||
int plasticityKernel = ((ComputeShapeMatchingConstraints)m_Constraints).plasticityKernel;
|
||||
|
||||
shader.SetBuffer(projectKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(projectKernel, "firstIndex", firstIndexBuffer);
|
||||
shader.SetBuffer(projectKernel, "numIndices", numIndicesBuffer);
|
||||
shader.SetBuffer(projectKernel, "explicitGroup", explicitGroupBuffer);
|
||||
shader.SetBuffer(projectKernel, "shapeMaterialParameters", shapeMaterialParametersBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "restComs", restComsBuffer);
|
||||
shader.SetBuffer(projectKernel, "coms", comsBuffer);
|
||||
shader.SetBuffer(projectKernel, "constraintOrientations", constraintOrientationsBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "Aqq", AqqBuffer);
|
||||
shader.SetBuffer(projectKernel, "RW_linearTransforms", linearTransformsBuffer);
|
||||
shader.SetBuffer(projectKernel, "deformation", plasticDeformationsBuffer);
|
||||
|
||||
shader.SetBuffer(projectKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "restPositions", solverImplementation.restPositionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "orientations", solverImplementation.orientationsBuffer);
|
||||
shader.SetBuffer(projectKernel, "restOrientations", solverImplementation.restOrientationsBuffer);
|
||||
shader.SetBuffer(projectKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(projectKernel, "invRotationalMasses", solverImplementation.invRotationalMassesBuffer);
|
||||
shader.SetBuffer(projectKernel, "principalRadii", solverImplementation.principalRadiiBuffer);
|
||||
shader.SetBuffer(projectKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
|
||||
shader.Dispatch(projectKernel, threadGroups, 1, 1);
|
||||
|
||||
shader.SetBuffer(plasticityKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(plasticityKernel, "firstIndex", firstIndexBuffer);
|
||||
shader.SetBuffer(plasticityKernel, "numIndices", numIndicesBuffer);
|
||||
shader.SetBuffer(plasticityKernel, "shapeMaterialParameters", shapeMaterialParametersBuffer);
|
||||
|
||||
shader.SetBuffer(plasticityKernel, "RW_restComs", restComsBuffer);
|
||||
shader.SetBuffer(plasticityKernel, "constraintOrientations", constraintOrientationsBuffer);
|
||||
|
||||
shader.SetBuffer(plasticityKernel, "RW_Aqq", AqqBuffer);
|
||||
shader.SetBuffer(plasticityKernel, "linearTransforms", linearTransformsBuffer);
|
||||
shader.SetBuffer(plasticityKernel, "RW_deformation", plasticDeformationsBuffer);
|
||||
|
||||
shader.SetBuffer(plasticityKernel, "restPositions", solverImplementation.restPositionsBuffer);
|
||||
shader.SetBuffer(plasticityKernel, "restOrientations", solverImplementation.restOrientationsBuffer);
|
||||
shader.SetBuffer(plasticityKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(plasticityKernel, "invRotationalMasses", solverImplementation.invRotationalMassesBuffer);
|
||||
shader.SetBuffer(plasticityKernel, "principalRadii", solverImplementation.principalRadiiBuffer);
|
||||
|
||||
shader.Dispatch(plasticityKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(float substepTime)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var parameters = solverAbstraction.GetConstraintParameters(m_ConstraintType);
|
||||
|
||||
var shader = ((ComputeShapeMatchingConstraints)m_Constraints).constraintsShader;
|
||||
int applyKernel = ((ComputeShapeMatchingConstraints)m_Constraints).applyKernel;
|
||||
|
||||
shader.SetBuffer(applyKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(applyKernel, "firstIndex", firstIndexBuffer);
|
||||
shader.SetBuffer(applyKernel, "numIndices", numIndicesBuffer);
|
||||
shader.SetBuffer(applyKernel, "RW_positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(applyKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
shader.SetBuffer(applyKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("sorFactor", parameters.SORFactor);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(applyKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void CalculateRestShapeMatching()
|
||||
{
|
||||
// just set a flag and do the actual calculation at the start of Evaluate().
|
||||
// This ensures GPu data of both particles and constraints is up to date when calculating the rest shape.
|
||||
m_RecalculateRestShape = true;
|
||||
}
|
||||
|
||||
public void RequestDataReadback()
|
||||
{
|
||||
m_Coms.Readback();
|
||||
m_ConstraintOrientations.Readback();
|
||||
}
|
||||
|
||||
public void WaitForReadback()
|
||||
{
|
||||
m_Coms.WaitForReadback();
|
||||
m_ConstraintOrientations.WaitForReadback();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efcebc6a8ed1446fe8216d7656fe7462
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3f96b782e06d47d699bad2fbd4712e1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeSkinConstraints : ComputeConstraintsImpl<ComputeSkinConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int projectKernel;
|
||||
public int applyKernel;
|
||||
|
||||
public ComputeSkinConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.Skin)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/SkinConstraints"));
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputeSkinConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputeSkinConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df84869cc78e04bb895be2db5e398cc3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,81 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeSkinConstraintsBatch : ComputeConstraintsBatchImpl, ISkinConstraintsBatchImpl
|
||||
{
|
||||
GraphicsBuffer skinPoints;
|
||||
GraphicsBuffer skinNormalsBuffer;
|
||||
GraphicsBuffer skinRadiiBackstopBuffer;
|
||||
GraphicsBuffer skinComplianceBuffer;
|
||||
|
||||
public ComputeSkinConstraintsBatch(ComputeSkinConstraints constraints)
|
||||
{
|
||||
m_Constraints = constraints;
|
||||
m_ConstraintType = Oni.ConstraintType.Skin;
|
||||
}
|
||||
|
||||
public void SetSkinConstraints(ObiNativeIntList particleIndices, ObiNativeVector4List skinPoints, ObiNativeVector4List skinNormals, ObiNativeFloatList skinRadiiBackstop, ObiNativeFloatList skinCompliance, ObiNativeFloatList lambdas, int count)
|
||||
{
|
||||
this.particleIndices = particleIndices.AsComputeBuffer<int>();
|
||||
this.skinPoints = skinPoints.AsComputeBuffer<Vector4>();
|
||||
this.skinNormalsBuffer = skinNormals.AsComputeBuffer<Vector4>();
|
||||
this.skinRadiiBackstopBuffer = skinRadiiBackstop.AsComputeBuffer<float>();
|
||||
this.skinComplianceBuffer = skinCompliance.AsComputeBuffer<float>();
|
||||
this.lambdas = lambdas.AsComputeBuffer<float>();
|
||||
this.lambdasList = lambdas;
|
||||
|
||||
m_ConstraintCount = count;
|
||||
}
|
||||
|
||||
public override void Evaluate(float stepTime, float substepTime, int steps, float timeLeft)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var shader = ((ComputeSkinConstraints)m_Constraints).constraintsShader;
|
||||
int projectKernel = ((ComputeSkinConstraints)m_Constraints).projectKernel;
|
||||
|
||||
shader.SetBuffer(projectKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(projectKernel, "skinPoints", skinPoints);
|
||||
shader.SetBuffer(projectKernel, "skinNormals", skinNormalsBuffer);
|
||||
shader.SetBuffer(projectKernel, "skinRadiiBackstop", skinRadiiBackstopBuffer);
|
||||
shader.SetBuffer(projectKernel, "skinCompliance", skinComplianceBuffer);
|
||||
shader.SetBuffer(projectKernel, "lambdas", lambdas);
|
||||
|
||||
shader.SetBuffer(projectKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(projectKernel, "invMasses", solverImplementation.invMassesBuffer);
|
||||
shader.SetBuffer(projectKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(projectKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("deltaTime", substepTime);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(projectKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(float substepTime)
|
||||
{
|
||||
if (m_ConstraintCount > 0)
|
||||
{
|
||||
var parameters = solverAbstraction.GetConstraintParameters(m_ConstraintType);
|
||||
|
||||
var shader = ((ComputeSkinConstraints)m_Constraints).constraintsShader;
|
||||
int applyKernel = ((ComputeSkinConstraints)m_Constraints).applyKernel;
|
||||
|
||||
shader.SetBuffer(applyKernel, "particleIndices", particleIndices);
|
||||
shader.SetBuffer(applyKernel, "positions", solverImplementation.positionsBuffer);
|
||||
shader.SetBuffer(applyKernel, "deltasAsInt", solverImplementation.positionDeltasIntBuffer);
|
||||
shader.SetBuffer(applyKernel, "positionConstraintCounts", solverImplementation.positionConstraintCountBuffer);
|
||||
|
||||
shader.SetInt("activeConstraintCount", m_ConstraintCount);
|
||||
shader.SetFloat("sorFactor", parameters.SORFactor);
|
||||
|
||||
int threadGroups = ComputeMath.ThreadGroupCount(m_ConstraintCount, 128);
|
||||
shader.Dispatch(applyKernel, threadGroups, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 935a9038a35be4d21aa06057f83040a9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fd1b55deaf68449f9fc2f037f032b4c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public class ComputeStitchConstraints : ComputeConstraintsImpl<ComputeStitchConstraintsBatch>
|
||||
{
|
||||
public ComputeShader constraintsShader;
|
||||
public int projectKernel;
|
||||
public int applyKernel;
|
||||
|
||||
public ComputeStitchConstraints(ComputeSolverImpl solver) : base(solver, Oni.ConstraintType.Stitch)
|
||||
{
|
||||
constraintsShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/StitchConstraints"));
|
||||
projectKernel = constraintsShader.FindKernel("Project");
|
||||
applyKernel = constraintsShader.FindKernel("Apply");
|
||||
}
|
||||
|
||||
public override IConstraintsBatchImpl CreateConstraintsBatch()
|
||||
{
|
||||
var dataBatch = new ComputeStitchConstraintsBatch(this);
|
||||
batches.Add(dataBatch);
|
||||
return dataBatch;
|
||||
}
|
||||
|
||||
public override void RemoveBatch(IConstraintsBatchImpl batch)
|
||||
{
|
||||
batches.Remove(batch as ComputeStitchConstraintsBatch);
|
||||
batch.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user