添加插件

This commit is contained in:
2025-11-10 00:08:26 +08:00
parent 4059c207c0
commit 76f80db694
2814 changed files with 436400 additions and 178 deletions

View File

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

View File

@@ -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);
}
}
}

View File

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

View File

@@ -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);
}
}
}

View File

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

View File

@@ -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);
}
}
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

@@ -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);
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

@@ -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);
}
}
}

View File

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

View 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
}
}

View File

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

View File

@@ -0,0 +1,15 @@
using System;
namespace Obi
{
public class ComputeJobHandle : IObiJobHandle
{
public void Complete()
{
}
public void Release()
{
}
}
}

View File

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

View 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;
}
}
}

View File

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

View File

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

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

@@ -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)
{
}
}
}

View File

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

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

@@ -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;
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

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

View File

@@ -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();
}
}
}
}
}

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

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

View File

@@ -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();
}
}
}

View File

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

View File

@@ -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);
}
}
}
}

View File

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

View File

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

View File

@@ -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