添加插件
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using UnityEngine;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Burst;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
[BurstCompile]
|
||||
struct ApplyInertialForcesJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<int> activeParticles;
|
||||
[ReadOnly] public NativeArray<float4> positions;
|
||||
[ReadOnly] public NativeArray<float> invMasses;
|
||||
|
||||
[ReadOnly] public float4 angularVel;
|
||||
[ReadOnly] public float4 inertialAccel;
|
||||
[ReadOnly] public float4 eulerAccel;
|
||||
|
||||
[ReadOnly] public float worldLinearInertiaScale;
|
||||
[ReadOnly] public float worldAngularInertiaScale;
|
||||
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> velocities;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> wind;
|
||||
|
||||
[ReadOnly] public float deltaTime;
|
||||
[ReadOnly] public float4 ambientWind;
|
||||
[ReadOnly] public BurstInertialFrame inertialFrame;
|
||||
[ReadOnly] public bool inertialWind;
|
||||
|
||||
public void Execute(int index)
|
||||
{
|
||||
int i = activeParticles[index];
|
||||
|
||||
if (invMasses[i] > 0)
|
||||
{
|
||||
float4 euler = new float4(math.cross(eulerAccel.xyz, positions[i].xyz), 0);
|
||||
float4 centrifugal = new float4(math.cross(angularVel.xyz, math.cross(angularVel.xyz, positions[i].xyz)), 0);
|
||||
float4 coriolis = 2 * new float4(math.cross(angularVel.xyz, velocities[i].xyz), 0);
|
||||
float4 angularAccel = euler + coriolis + centrifugal;
|
||||
|
||||
velocities[i] -= (inertialAccel * worldLinearInertiaScale + angularAccel * worldAngularInertiaScale) * deltaTime;
|
||||
}
|
||||
|
||||
wind[i] = ambientWind;
|
||||
|
||||
if (inertialWind)
|
||||
{
|
||||
float4 wsPos = inertialFrame.frame.TransformPoint(positions[i]);
|
||||
wind[i] -= inertialFrame.frame.InverseTransformVector(inertialFrame.VelocityAtPoint(wsPos));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9583eea8cf2234362a59c97e3f908a85
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,87 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using UnityEngine;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Burst;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
[BurstCompile]
|
||||
struct CalculateSimplexBoundsJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<float4> radii;
|
||||
[ReadOnly] public NativeArray<float4> fluidMaterials;
|
||||
[ReadOnly] public NativeArray<float4> positions;
|
||||
[ReadOnly] public NativeArray<float4> velocities;
|
||||
|
||||
// simplex arrays:
|
||||
[ReadOnly] public NativeArray<int> simplices;
|
||||
[ReadOnly] public SimplexCounts simplexCounts;
|
||||
|
||||
[ReadOnly] public NativeArray<int> particleMaterialIndices;
|
||||
[ReadOnly] public NativeArray<BurstCollisionMaterial> collisionMaterials;
|
||||
public NativeArray<BurstAabb> simplexBounds;
|
||||
public NativeArray<BurstAabb> reducedBounds;
|
||||
|
||||
[ReadOnly] public Oni.SolverParameters parameters;
|
||||
[ReadOnly] public float dt;
|
||||
|
||||
public void Execute(int i)
|
||||
{
|
||||
int simplexStart = simplexCounts.GetSimplexStartAndSize(i, out int simplexSize);
|
||||
|
||||
var sxBounds = new BurstAabb(float.MaxValue, float.MinValue);
|
||||
var soBounds = new BurstAabb(float.MaxValue, float.MinValue);
|
||||
|
||||
for (int j = 0; j < simplexSize; ++j)
|
||||
{
|
||||
int p = simplices[simplexStart + j];
|
||||
|
||||
int m = particleMaterialIndices[p];
|
||||
float solidRadius = radii[p].x + (m >= 0 ? collisionMaterials[m].stickDistance : 0);
|
||||
|
||||
// Expand simplex bounds, using both the particle's original position and its velocity.
|
||||
// Add collision margin for both fluid neighborhood too (prevents explosions at high pressures due to neighborhood deficiency)
|
||||
sxBounds.EncapsulateParticle(positions[p],
|
||||
BurstIntegration.IntegrateLinear(positions[p], velocities[p], dt * parameters.particleCCD),
|
||||
math.max(solidRadius, fluidMaterials[p].x * 0.5f) + parameters.collisionMargin);
|
||||
|
||||
soBounds.EncapsulateParticle(positions[p],
|
||||
BurstIntegration.IntegrateLinear(positions[p], velocities[p], dt),
|
||||
solidRadius);
|
||||
}
|
||||
|
||||
simplexBounds[i] = sxBounds;
|
||||
reducedBounds[i] = soBounds;
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
struct BoundsReductionJob : IJobParallelFor
|
||||
{
|
||||
[NativeDisableParallelForRestriction] public NativeArray<BurstAabb> bounds; // the length of bounds must be a multiple of size.
|
||||
[ReadOnly] public int stride;
|
||||
[ReadOnly] public int size;
|
||||
|
||||
public void Execute(int first)
|
||||
{
|
||||
int baseIndex = first * size;
|
||||
for (int i = 1; i < size; ++i)
|
||||
{
|
||||
int dest = baseIndex * stride;
|
||||
int source = (baseIndex + i) * stride;
|
||||
|
||||
if (source < bounds.Length)
|
||||
{
|
||||
var v = bounds[dest];
|
||||
v.EncapsulateBounds(bounds[source]);
|
||||
bounds[dest] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31e84cee4b2444511a44d1c8ff0c8cd1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d37e8b7fe851346debbbd28e17c1e593
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using Unity.Burst;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
[BurstCompile]
|
||||
public struct DequeueIntoArrayJob<T> : IJob where T : unmanaged
|
||||
{
|
||||
public int StartIndex;
|
||||
public NativeQueue<T> InputQueue;
|
||||
[WriteOnly] public NativeArray<T> OutputArray;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
int queueCount = InputQueue.Count;
|
||||
|
||||
for (int i = StartIndex; i < StartIndex + queueCount; i++)
|
||||
{
|
||||
OutputArray[i] = InputQueue.Dequeue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e9889084567047d389e79cf39fc3391
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Burst;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
[BurstCompile]
|
||||
struct EnforceLimitsJob : IJobParallelFor
|
||||
{
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> positions;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> prevPositions;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float> life;
|
||||
[ReadOnly] public NativeArray<int> phases;
|
||||
|
||||
[ReadOnly] public NativeArray<int> activeParticles;
|
||||
[ReadOnly] public bool killOffLimits;
|
||||
|
||||
[ReadOnly] public BurstAabb boundaryLimits;
|
||||
|
||||
public void Execute(int index)
|
||||
{
|
||||
int i = activeParticles[index];
|
||||
|
||||
float4 pos = positions[i];
|
||||
float4 prevPos = prevPositions[i];
|
||||
|
||||
bool outside = math.any(math.step(pos, boundaryLimits.min).xyz + math.step(boundaryLimits.max, pos).xyz);
|
||||
|
||||
if ((phases[i] & (int)ObiUtils.ParticleFlags.Isolated) != 0)
|
||||
life[i] = outside && killOffLimits ? 0 : life[i];
|
||||
|
||||
pos.xyz = math.clamp(pos, boundaryLimits.min, boundaryLimits.max).xyz;
|
||||
prevPos.xyz = math.clamp(prevPos, boundaryLimits.min, boundaryLimits.max).xyz;
|
||||
|
||||
positions[i] = pos;
|
||||
prevPositions[i] = prevPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 354e2117ba6e94ad8afbfe95160a553b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using UnityEngine;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Burst;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
[BurstCompile]
|
||||
struct FindFluidParticlesJob : IJob
|
||||
{
|
||||
[ReadOnly] public NativeArray<int> activeParticles;
|
||||
[ReadOnly] public NativeArray<int> phases;
|
||||
|
||||
public NativeList<int> fluidParticles;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
fluidParticles.Clear();
|
||||
|
||||
for (int i = 0; i < activeParticles.Length; ++i)
|
||||
{
|
||||
int p = activeParticles[i];
|
||||
if ((phases[p] & (int)ObiUtils.ParticleFlags.Fluid) != 0)
|
||||
fluidParticles.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 58485b95b70f24a809a8f9509faabdad
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,361 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Burst;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using System.Threading;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
[BurstCompile]
|
||||
unsafe struct EmitParticlesJob : IJobParallelFor
|
||||
{
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputPositions;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputVelocities;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputColors;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputAttributes;
|
||||
|
||||
[NativeDisableParallelForRestriction] public NativeArray<int> dispatchBuffer;
|
||||
|
||||
public uint emitterShape;
|
||||
public float4 emitterPosition;
|
||||
public quaternion emitterRotation;
|
||||
public float4 emitterSize;
|
||||
|
||||
public float lifetime;
|
||||
public float lifetimeRandom;
|
||||
public float particleSize;
|
||||
public float sizeRandom;
|
||||
public float buoyancy;
|
||||
public float drag;
|
||||
public float airdrag;
|
||||
public float airAging;
|
||||
public float isosurface;
|
||||
public float4 foamColor;
|
||||
|
||||
public float randomSeed;
|
||||
public float deltaTime;
|
||||
|
||||
public void Execute(int i)
|
||||
{
|
||||
int* dispatch = (int*)dispatchBuffer.GetUnsafePtr();
|
||||
|
||||
// atomically increment alive particle counter:
|
||||
int count = Interlocked.Add(ref dispatch[3], 1) - 1;
|
||||
|
||||
if (count < outputPositions.Length)
|
||||
{
|
||||
// initialize foam particle in a random position inside the cylinder spawned by fluid particle:
|
||||
float3 radialVelocity;
|
||||
float4 pos;
|
||||
|
||||
if (emitterShape == 0)
|
||||
BurstMath.RandomInCylinder(randomSeed + i, -new float4(0, 1, 0, 0) * emitterSize.y * 0.5f, new float4(0, 1, 0, 0), emitterSize.y, math.max(emitterSize.x, emitterSize.z) * 0.5f, out pos, out radialVelocity);
|
||||
else
|
||||
BurstMath.RandomInBox(randomSeed + i, float4.zero, emitterSize, out pos, out radialVelocity);
|
||||
|
||||
float2 random = BurstMath.Hash21(randomSeed - i);
|
||||
|
||||
// calculate initial life/size/color:
|
||||
float initialLife = math.max (0, lifetime - lifetime * random.x * lifetimeRandom);
|
||||
float initialSize = particleSize - particleSize * random.y * sizeRandom;
|
||||
|
||||
outputPositions[count] = new float4(emitterPosition.xyz + math.rotate(emitterRotation, pos.xyz), 0);
|
||||
outputVelocities[count] = new float4(0,0,0, buoyancy);
|
||||
outputColors[count] = foamColor;
|
||||
outputAttributes[count] = new float4(1, 1 / initialLife, initialSize, BurstMath.PackFloatRGBA(new float4(airAging / 50.0f, airdrag, drag, isosurface)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
unsafe struct GenerateParticlesJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] [DeallocateOnJobCompletion] public NativeArray<int> activeParticles;
|
||||
[ReadOnly] public NativeArray<float4> positions;
|
||||
[ReadOnly] public NativeArray<float4> velocities;
|
||||
[ReadOnly] public NativeArray<float4> principalRadii;
|
||||
[ReadOnly] public NativeArray<float4> fluidData;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> angularVelocities;
|
||||
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputPositions;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputVelocities;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputColors;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputAttributes;
|
||||
|
||||
[NativeDisableParallelForRestriction] public NativeArray<int> dispatchBuffer;
|
||||
|
||||
public float2 vorticityRange;
|
||||
public float2 velocityRange;
|
||||
public float potentialIncrease;
|
||||
public float potentialDiffusion;
|
||||
public float foamGenerationRate;
|
||||
|
||||
public float lifetime;
|
||||
public float lifetimeRandom;
|
||||
public float particleSize;
|
||||
public float sizeRandom;
|
||||
public float buoyancy;
|
||||
public float drag;
|
||||
public float airdrag;
|
||||
public float airAging;
|
||||
public float isosurface;
|
||||
public float4 foamColor;
|
||||
|
||||
public float randomSeed;
|
||||
public float deltaTime;
|
||||
|
||||
public void Execute(int i)
|
||||
{
|
||||
int* dispatch = (int*)dispatchBuffer.GetUnsafePtr();
|
||||
|
||||
int p = activeParticles[i];
|
||||
|
||||
float4 angVel = angularVelocities[p];
|
||||
float2 potential = BurstMath.UnpackFloatRG(angVel.w);
|
||||
|
||||
// calculate foam potential increase:
|
||||
float vorticityPotential = BurstMath.Remap01(fluidData[p].z, vorticityRange.x, vorticityRange.y);
|
||||
float velocityPotential = BurstMath.Remap01(math.length(velocities[p].xyz), velocityRange.x, velocityRange.y);
|
||||
float potentialDelta = velocityPotential * vorticityPotential * deltaTime * potentialIncrease;
|
||||
|
||||
// update foam potential:
|
||||
potential.y = math.saturate(potential.y * potentialDiffusion + potentialDelta);
|
||||
|
||||
// calculate amount of emitted particles
|
||||
potential.x += foamGenerationRate * potential.y * deltaTime;
|
||||
int emitCount = (int)potential.x;
|
||||
potential.x -= emitCount;
|
||||
|
||||
for (int j = 0; j < emitCount; ++j)
|
||||
{
|
||||
// atomically increment alive particle counter:
|
||||
int count = Interlocked.Add(ref dispatch[3], 1) - 1;
|
||||
|
||||
if (count < outputPositions.Length)
|
||||
{
|
||||
// initialize foam particle in a random position inside the cylinder spawned by fluid particle:
|
||||
float3 radialVelocity;
|
||||
float4 pos;
|
||||
BurstMath.RandomInCylinder(randomSeed + p + j, positions[p], math.normalizesafe(velocities[p]), math.length(velocities[p]) * deltaTime, principalRadii[p].x, out pos, out radialVelocity);
|
||||
|
||||
float2 random = BurstMath.Hash21(randomSeed - p - j);
|
||||
|
||||
// calculate initial life/size/color:
|
||||
float initialLife = velocityPotential * (lifetime - lifetime * random.x * lifetimeRandom);
|
||||
float initialSize = particleSize - particleSize * random.y * sizeRandom;
|
||||
|
||||
outputPositions[count] = pos;
|
||||
outputVelocities[count] = velocities[p] + new float4(radialVelocity, buoyancy);
|
||||
outputColors[count] = foamColor;
|
||||
outputAttributes[count] = new float4(1, 1/initialLife, initialSize, BurstMath.PackFloatRGBA(new float4(airAging/50.0f, airdrag, drag, isosurface)));
|
||||
}
|
||||
}
|
||||
|
||||
angVel.w = BurstMath.PackFloatRG(potential);
|
||||
angularVelocities[p] = angVel;
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
unsafe struct UpdateParticlesJob : IJobParallelForDefer
|
||||
{
|
||||
[ReadOnly] public NativeArray<float4> positions;
|
||||
[ReadOnly] public NativeArray<quaternion> orientations;
|
||||
[ReadOnly] public NativeArray<float4> velocities;
|
||||
[ReadOnly] public NativeArray<float4> angularVelocities;
|
||||
[ReadOnly] public NativeArray<float4> principalRadii;
|
||||
[ReadOnly] public NativeArray<float4> fluidData;
|
||||
[ReadOnly] public NativeArray<float4> fluidMaterial;
|
||||
|
||||
[ReadOnly] public NativeArray<int> simplices;
|
||||
[ReadOnly] public SimplexCounts simplexCounts;
|
||||
|
||||
[ReadOnly] public NativeMultilevelGrid<int> grid;
|
||||
[DeallocateOnJobCompletion]
|
||||
[ReadOnly] public NativeArray<int> gridLevels;
|
||||
|
||||
[ReadOnly] public Poly6Kernel densityKernel;
|
||||
|
||||
[ReadOnly] public NativeArray<float4> inputPositions;
|
||||
[ReadOnly] public NativeArray<float4> inputVelocities;
|
||||
[ReadOnly] public NativeArray<float4> inputColors;
|
||||
[ReadOnly] public NativeArray<float4> inputAttributes;
|
||||
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputPositions;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputVelocities;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputColors;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputAttributes;
|
||||
|
||||
[NativeDisableParallelForRestriction] public NativeArray<int> dispatchBuffer;
|
||||
|
||||
[ReadOnly] public Oni.SolverParameters parameters;
|
||||
|
||||
public float3 agingOverPopulation;
|
||||
public int minFluidNeighbors;
|
||||
public float deltaTime;
|
||||
public int currentAliveParticles;
|
||||
|
||||
static readonly int4[] offsets =
|
||||
{
|
||||
new int4(0, 0, 0, 1),
|
||||
new int4(1, 0, 0, 1),
|
||||
new int4(0, 1, 0, 1),
|
||||
new int4(1, 1, 0, 1),
|
||||
new int4(0, 0, 1, 1),
|
||||
new int4(1, 0, 1, 1),
|
||||
new int4(0, 1, 1, 1),
|
||||
new int4(1, 1, 1, 1)
|
||||
};
|
||||
|
||||
public void Execute(int i)
|
||||
{
|
||||
int* dispatch = (int*)dispatchBuffer.GetUnsafePtr();
|
||||
int count = Interlocked.Add(ref dispatch[3], -1);
|
||||
|
||||
if (count < inputPositions.Length && inputAttributes[count].x > 0)
|
||||
{
|
||||
int aliveCount = Interlocked.Add(ref dispatch[7], 1) - 1;
|
||||
|
||||
float4 attributes = inputAttributes[count];
|
||||
float4 packedData = BurstMath.UnpackFloatRGBA(attributes.w);
|
||||
|
||||
int offsetCount = ((int)parameters.mode == 1) ? 4 : 8;
|
||||
float4 advectedVelocity = float4.zero;
|
||||
float4 advectedAngVelocity = float4.zero;
|
||||
float kernelSum = -packedData.w;
|
||||
uint neighbourCount = 0;
|
||||
|
||||
float4 diffusePos = inputPositions[count];
|
||||
|
||||
for (int k = 0; k < gridLevels.Length; ++k)
|
||||
{
|
||||
int l = gridLevels[k];
|
||||
float radius = NativeMultilevelGrid<int>.CellSizeOfLevel(l);
|
||||
float interactionDist = radius * 0.5f;
|
||||
|
||||
float4 cellCoords = math.floor(diffusePos / radius);
|
||||
|
||||
cellCoords[3] = 0;
|
||||
if ((int)parameters.mode == 1)
|
||||
cellCoords[2] = 0;
|
||||
|
||||
float4 posInCell = diffusePos - (cellCoords * radius + new float4(interactionDist));
|
||||
int4 quadrant = (int4)math.sign(posInCell);
|
||||
|
||||
quadrant[3] = l;
|
||||
|
||||
for (int o = 0; o < offsetCount; ++o)
|
||||
{
|
||||
int cellIndex;
|
||||
if (grid.TryGetCellIndex((int4)cellCoords + offsets[o] * quadrant, out cellIndex))
|
||||
{
|
||||
var cell = grid.usedCells[cellIndex];
|
||||
for (int n = 0; n < cell.Length; ++n)
|
||||
{
|
||||
int simplexStart = simplexCounts.GetSimplexStartAndSize(cell[n], out int simplexSize);
|
||||
|
||||
for (int a = 0; a < simplexSize; ++a)
|
||||
{
|
||||
int p = simplices[simplexStart + a];
|
||||
float4 normal = diffusePos - positions[p];
|
||||
|
||||
normal[3] = 0;
|
||||
if ((int)parameters.mode == 1)
|
||||
normal[2] = 0;
|
||||
|
||||
float d = math.length(normal);
|
||||
if (d <= interactionDist)
|
||||
{
|
||||
float3 radii = fluidMaterial[p].x * (principalRadii[p].xyz / principalRadii[p].x);
|
||||
|
||||
float4 angVel = new float4(math.cross(angularVelocities[p].xyz, normal.xyz), 0);
|
||||
advectedAngVelocity += angVel * densityKernel.W(d, radii.x) / densityKernel.W(0, radii.x);
|
||||
|
||||
normal.xyz = math.mul(math.conjugate(orientations[p]), normal.xyz) / radii;
|
||||
d = math.length(normal) * radii.x;
|
||||
|
||||
// scale by volume (* 1 / normalized density)
|
||||
float w = densityKernel.W(d, radii.x) / fluidData[p].x;
|
||||
|
||||
kernelSum += w;
|
||||
advectedVelocity += velocities[p] * w;
|
||||
neighbourCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float4 forces = float4.zero;
|
||||
float velocityScale = 1;
|
||||
float agingScale = 1 + BurstMath.Remap01(currentAliveParticles / (float)inputPositions.Length, agingOverPopulation.x, agingOverPopulation.y) * (agingOverPopulation.z - 1);
|
||||
|
||||
// foam/bubble particle:
|
||||
if (kernelSum > BurstMath.epsilon && neighbourCount >= minFluidNeighbors)
|
||||
{
|
||||
// advection:
|
||||
forces = packedData.z / deltaTime * (advectedVelocity / (kernelSum + packedData.w) + advectedAngVelocity - inputVelocities[count]);
|
||||
|
||||
// buoyancy:
|
||||
forces -= new float4(parameters.gravity * parameters.foamGravityScale * inputVelocities[count].w * math.saturate(kernelSum), 0);
|
||||
|
||||
}
|
||||
else // ballistic:
|
||||
{
|
||||
// gravity:
|
||||
forces += new float4(parameters.gravity * parameters.foamGravityScale, 0);
|
||||
|
||||
// atmospheric drag/aging:
|
||||
velocityScale = packedData.y;
|
||||
agingScale *= packedData.x * 50;
|
||||
}
|
||||
|
||||
// don't change 4th component, as its used to store buoyancy control parameter.
|
||||
forces[3] = 0;
|
||||
|
||||
// update particle data:
|
||||
attributes.x -= attributes.y * deltaTime * agingScale;
|
||||
outputAttributes[aliveCount] = attributes;
|
||||
outputColors[aliveCount] = inputColors[count];
|
||||
|
||||
// integrate:
|
||||
outputVelocities[aliveCount] = (inputVelocities[count] + forces * deltaTime) * velocityScale;
|
||||
outputPositions[aliveCount] = new float4((inputPositions[count] + outputVelocities[aliveCount] * deltaTime).xyz,neighbourCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
unsafe struct CopyJob : IJobParallelForDefer
|
||||
{
|
||||
[ReadOnly] public NativeArray<float4> inputPositions;
|
||||
[ReadOnly] public NativeArray<float4> inputVelocities;
|
||||
[ReadOnly] public NativeArray<float4> inputColors;
|
||||
[ReadOnly] public NativeArray<float4> inputAttributes;
|
||||
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputPositions;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputVelocities;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputColors;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> outputAttributes;
|
||||
|
||||
[NativeDisableParallelForRestriction] public NativeArray<int> dispatchBuffer;
|
||||
|
||||
public void Execute(int i)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
dispatchBuffer[3] = dispatchBuffer[7];
|
||||
dispatchBuffer[7] = 0;
|
||||
}
|
||||
|
||||
outputPositions[i] = inputPositions[i];
|
||||
outputVelocities[i] = inputVelocities[i];
|
||||
outputColors[i] = inputColors[i];
|
||||
outputAttributes[i] = inputAttributes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54f132d8cdea34935be3c33b0d1ca4d1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Burst;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
[BurstCompile]
|
||||
struct InterpolationJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<float4> positions;
|
||||
[ReadOnly] public NativeArray<float4> startPositions;
|
||||
[ReadOnly] public NativeArray<float4> endPositions;
|
||||
[WriteOnly] public NativeArray<float4> renderablePositions;
|
||||
|
||||
[ReadOnly] public NativeArray<quaternion> orientations;
|
||||
[ReadOnly] public NativeArray<quaternion> startOrientations;
|
||||
[ReadOnly] public NativeArray<quaternion> endOrientations;
|
||||
[WriteOnly] public NativeArray<quaternion> renderableOrientations;
|
||||
|
||||
[ReadOnly] public NativeArray<float4> principalRadii;
|
||||
[WriteOnly] public NativeArray<float4> renderableRadii;
|
||||
|
||||
[ReadOnly] public float blendFactor;
|
||||
[ReadOnly] public Oni.SolverParameters.Interpolation interpolationMode;
|
||||
|
||||
// The code actually running on the job
|
||||
public void Execute(int i)
|
||||
{
|
||||
if (interpolationMode == Oni.SolverParameters.Interpolation.Interpolate)
|
||||
{
|
||||
renderablePositions[i] = math.lerp(startPositions[i], endPositions[i], blendFactor);
|
||||
renderableOrientations[i] = math.normalize(math.slerp(startOrientations[i], endOrientations[i], blendFactor));
|
||||
renderableRadii[i] = principalRadii[i];
|
||||
}
|
||||
else if (interpolationMode == Oni.SolverParameters.Interpolation.Extrapolate)
|
||||
{
|
||||
renderablePositions[i] = math.lerp(endPositions[i], positions[i], blendFactor);
|
||||
renderableOrientations[i] = math.normalize(math.slerp(endOrientations[i], orientations[i], blendFactor));
|
||||
renderableRadii[i] = principalRadii[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
renderablePositions[i] = endPositions[i];
|
||||
renderableOrientations[i] = math.normalize(endOrientations[i]);
|
||||
renderableRadii[i] = principalRadii[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8928e13e186424d31a319347de871c16
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,82 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using UnityEngine;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Burst;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
[BurstCompile]
|
||||
struct PredictPositionsJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<int> activeParticles;
|
||||
[ReadOnly] public NativeArray<int> phases;
|
||||
[ReadOnly] public NativeArray<float4> buoyancies;
|
||||
|
||||
// linear/position properties:
|
||||
[ReadOnly] public NativeArray<float4> externalForces;
|
||||
[ReadOnly] public NativeArray<float> inverseMasses;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> previousPositions;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> positions;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> velocities;
|
||||
|
||||
// angular/orientation properties:
|
||||
[ReadOnly] public NativeArray<float4> externalTorques;
|
||||
[ReadOnly] public NativeArray<float> inverseRotationalMasses;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<quaternion> previousOrientations;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<quaternion> orientations;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> angularVelocities;
|
||||
|
||||
[ReadOnly] public float4 gravity;
|
||||
[ReadOnly] public float deltaTime;
|
||||
[ReadOnly] public bool is2D;
|
||||
|
||||
public void Execute(int index)
|
||||
{
|
||||
int i = activeParticles[index];
|
||||
|
||||
// the previous position/orientation is the current position/orientation at the start of the step.
|
||||
previousPositions[i] = positions[i];
|
||||
previousOrientations[i] = orientations[i];
|
||||
|
||||
if (inverseMasses[i] > 0)
|
||||
{
|
||||
float4 effectiveGravity = gravity;
|
||||
|
||||
// Adjust gravity for buoyant fluid particles:
|
||||
if ((phases[i] & (int)ObiUtils.ParticleFlags.Fluid) != 0)
|
||||
effectiveGravity *= -buoyancies[i].z;
|
||||
|
||||
// apply external forces and gravity:
|
||||
float4 vel = velocities[i] + (inverseMasses[i] * externalForces[i] + effectiveGravity) * deltaTime;
|
||||
|
||||
// project velocity to 2D plane if needed:
|
||||
if (is2D)
|
||||
vel[3] = 0;
|
||||
|
||||
velocities[i] = vel;
|
||||
}
|
||||
|
||||
if (inverseRotationalMasses[i] > 0)
|
||||
{
|
||||
// apply external torques (simplification: we don't use full inertia tensor here)
|
||||
float3 angularVel = angularVelocities[i].xyz + inverseRotationalMasses[i] * externalTorques[i].xyz * deltaTime;
|
||||
|
||||
// project angular velocity to 2D plane normal if needed:
|
||||
if (is2D)
|
||||
angularVel = angularVel.project(new float3(0, 0, 1));
|
||||
|
||||
angularVelocities[i] = new float4(angularVel, angularVelocities[i].w);
|
||||
}
|
||||
|
||||
// integrate velocities:
|
||||
positions[i] = BurstIntegration.IntegrateLinear(positions[i], velocities[i], deltaTime);
|
||||
orientations[i] = BurstIntegration.IntegrateAngular(orientations[i], angularVelocities[i], deltaTime);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fcd4a6f15c3844229a95fa41f283d408
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,122 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Burst;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
|
||||
[BurstCompile]
|
||||
struct ResetNormals : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<int> phases;
|
||||
public NativeArray<float4> normals;
|
||||
[WriteOnly] public NativeArray<float4> tangents;
|
||||
|
||||
public void Execute(int i)
|
||||
{
|
||||
// leave fluid and softbody normals intact.
|
||||
if ((phases[i] & (int)ObiUtils.ParticleFlags.Fluid) == 0 && normals[i].w >= 0)
|
||||
{
|
||||
normals[i] = float4.zero;
|
||||
tangents[i] = float4.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
unsafe struct UpdateTriangleNormalsJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<int> deformableTriangles;
|
||||
[ReadOnly] public NativeArray<float2> deformableTriangleUVs;
|
||||
[ReadOnly] public NativeArray<float4> renderPositions;
|
||||
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> normals;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> tangents;
|
||||
|
||||
public void Execute(int i)
|
||||
{
|
||||
int p1 = deformableTriangles[i*3];
|
||||
int p2 = deformableTriangles[i*3 + 1];
|
||||
int p3 = deformableTriangles[i*3 + 2];
|
||||
|
||||
float3 m1 = (renderPositions[p2] - renderPositions[p1]).xyz;
|
||||
float3 m2 = (renderPositions[p3] - renderPositions[p1]).xyz;
|
||||
|
||||
float2 s = deformableTriangleUVs[i * 3 + 1] - deformableTriangleUVs[i * 3];
|
||||
float2 t = deformableTriangleUVs[i * 3 + 2] - deformableTriangleUVs[i * 3];
|
||||
|
||||
float4 normal = new float4(math.cross(m1, m2), 0);
|
||||
float4 tangent = float4.zero;
|
||||
|
||||
float area = s.x * t.y - t.x * s.y;
|
||||
|
||||
if (math.abs(area) > BurstMath.epsilon)
|
||||
{
|
||||
tangent = new float4(t.y * m1.x - s.y * m2.x,
|
||||
t.y * m1.y - s.y * m2.y,
|
||||
t.y * m1.z - s.y * m2.z, 0) / area;
|
||||
}
|
||||
|
||||
BurstMath.AtomicAdd(normals, p1, normal);
|
||||
BurstMath.AtomicAdd(normals, p2, normal);
|
||||
BurstMath.AtomicAdd(normals, p3, normal);
|
||||
|
||||
BurstMath.AtomicAdd(tangents, p1, tangent);
|
||||
BurstMath.AtomicAdd(tangents, p2, tangent);
|
||||
BurstMath.AtomicAdd(tangents, p3, tangent);
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
unsafe struct UpdateEdgeNormalsJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<int> deformableEdges;
|
||||
[ReadOnly] public NativeArray<float4> velocities;
|
||||
[ReadOnly] public NativeArray<float4> wind;
|
||||
[ReadOnly] public NativeArray<float4> renderPositions;
|
||||
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> normals;
|
||||
|
||||
public void Execute(int i)
|
||||
{
|
||||
int p1 = deformableEdges[i * 2];
|
||||
int p2 = deformableEdges[i * 2 + 1];
|
||||
|
||||
float4 edge = renderPositions[p2] - renderPositions[p1];
|
||||
float4 avgWind = (velocities[p1] + velocities[p2]) * 0.5f - (wind[p1] + wind[p2]) * 0.5f;
|
||||
float4 normal = avgWind - math.projectsafe(avgWind, edge);
|
||||
|
||||
BurstMath.AtomicAdd(normals, p1, normal);
|
||||
BurstMath.AtomicAdd(normals, p2, normal);
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
struct RenderableOrientationFromNormals : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<int> phases;
|
||||
|
||||
public NativeArray<float4> normals;
|
||||
public NativeArray<float4> tangents;
|
||||
|
||||
[WriteOnly] public NativeArray<quaternion> renderableOrientations;
|
||||
|
||||
public void Execute(int i)
|
||||
{
|
||||
if (((phases[i] & (int)ObiUtils.ParticleFlags.Fluid) == 0 && normals[i].w >= 0) && // not fluid or softbody (no SDF stored)
|
||||
math.lengthsq(normals[i]) > BurstMath.epsilon &&
|
||||
math.lengthsq(tangents[i]) > BurstMath.epsilon)
|
||||
{
|
||||
normals[i] = math.normalizesafe(normals[i]);
|
||||
tangents[i] = math.normalizesafe(tangents[i]);
|
||||
|
||||
// particle orientation from normal/tangent:
|
||||
renderableOrientations[i] = quaternion.LookRotation(normals[i].xyz, tangents[i].xyz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c46e86e164afb414fbc171972a53eb91
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,41 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using UnityEngine;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Burst;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Threading;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
[BurstCompile]
|
||||
unsafe struct UpdateParticleLifetimesJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<int> activeParticles;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float> life;
|
||||
|
||||
[NativeDisableParallelForRestriction] public NativeArray<int> deadParticles;
|
||||
[NativeDisableContainerSafetyRestriction] public NativeReference<int> deadParticleCount;
|
||||
|
||||
[ReadOnly] public float dt;
|
||||
|
||||
public void Execute(int i)
|
||||
{
|
||||
int p = activeParticles[i];
|
||||
|
||||
life[p] -= dt;
|
||||
|
||||
if (life[p] <= 0)
|
||||
{
|
||||
int* countRef = (int*)deadParticleCount.GetUnsafePtr();
|
||||
int count = Interlocked.Increment(ref countRef[0]) - 1;
|
||||
deadParticles[count] = p;
|
||||
life[p] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e2ac6f480787440e7bd2610e4545bd9e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using UnityEngine;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Burst;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
[BurstCompile]
|
||||
struct UpdatePositionsJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<int> activeParticles;
|
||||
|
||||
// linear/position properties:
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> positions;
|
||||
[ReadOnly] public NativeArray<float4> previousPositions;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> velocities;
|
||||
|
||||
// angular/orientation properties:
|
||||
[NativeDisableParallelForRestriction] public NativeArray<quaternion> orientations;
|
||||
[ReadOnly] public NativeArray<quaternion> previousOrientations;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> angularVelocities;
|
||||
|
||||
[ReadOnly] public float velocityScale;
|
||||
[ReadOnly] public float sleepThreshold;
|
||||
[ReadOnly] public float maxVelocity;
|
||||
[ReadOnly] public float maxAngularVelocity;
|
||||
|
||||
// The code actually running on the job
|
||||
public void Execute(int index)
|
||||
{
|
||||
int i = activeParticles[index];
|
||||
|
||||
float4 velocity = velocities[i];
|
||||
float4 angVelocity = angularVelocities[i];
|
||||
|
||||
// damp velocities:
|
||||
velocity *= velocityScale;
|
||||
angVelocity.xyz *= velocityScale;
|
||||
|
||||
// clamp velocities:
|
||||
float velMagnitude = math.length(velocity);
|
||||
float angularVelMagnitude = math.length(angVelocity.xyz);
|
||||
|
||||
if (velMagnitude > BurstMath.epsilon)
|
||||
velocity *= math.min(maxVelocity, velMagnitude) / velMagnitude;
|
||||
|
||||
if (angularVelMagnitude > BurstMath.epsilon)
|
||||
angVelocity.xyz *= math.min(maxAngularVelocity, angularVelMagnitude) / angularVelMagnitude;
|
||||
|
||||
// if the kinetic energy is below the sleep threshold, keep the particle at its previous position.
|
||||
if (velMagnitude * velMagnitude * 0.5f + angularVelMagnitude * angularVelMagnitude * 0.5f <= sleepThreshold)
|
||||
{
|
||||
positions[i] = previousPositions[i];
|
||||
orientations[i] = previousOrientations[i];
|
||||
velocity = float4.zero;
|
||||
angVelocity.xyz = float3.zero;
|
||||
}
|
||||
|
||||
velocities[i] = velocity;
|
||||
angularVelocities[i] = angVelocity;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a41d3897adb37457da8385a46e6f0bb6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,58 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using UnityEngine;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Burst;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
[BurstCompile]
|
||||
struct UpdateVelocitiesJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<int> activeParticles;
|
||||
|
||||
// linear/position properties:
|
||||
[ReadOnly] public NativeArray<float> inverseMasses;
|
||||
[ReadOnly] public NativeArray<float4> previousPositions;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> positions;
|
||||
[NativeDisableParallelForRestriction] [WriteOnly] public NativeArray<float4> velocities;
|
||||
|
||||
// angular/orientation properties:
|
||||
[ReadOnly] public NativeArray<float> inverseRotationalMasses;
|
||||
[ReadOnly] public NativeArray<quaternion> previousOrientations;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<quaternion> orientations;
|
||||
[NativeDisableParallelForRestriction] public NativeArray<float4> angularVelocities;
|
||||
|
||||
[ReadOnly] public float deltaTime;
|
||||
[ReadOnly] public bool is2D;
|
||||
|
||||
// The code actually running on the job
|
||||
public void Execute(int index)
|
||||
{
|
||||
int i = activeParticles[index];
|
||||
|
||||
// Project particles on the XY plane if we are in 2D mode:
|
||||
if (is2D)
|
||||
{
|
||||
// restrict position to the 2D plane
|
||||
float4 pos = positions[i];
|
||||
pos[2] = previousPositions[i][2];
|
||||
positions[i] = pos;
|
||||
}
|
||||
|
||||
if (inverseMasses[i] > 0)
|
||||
velocities[i] = BurstIntegration.DifferentiateLinear(positions[i], previousPositions[i], deltaTime);
|
||||
else
|
||||
velocities[i] = float4.zero;
|
||||
|
||||
if (inverseRotationalMasses[i] > 0)
|
||||
angularVelocities[i] = new float4(BurstIntegration.DifferentiateAngular(orientations[i], previousOrientations[i], deltaTime).xyz, angularVelocities[i].w);
|
||||
else
|
||||
angularVelocities[i] = float4.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d10fd506f9f2645ecbf2d61a4634a5ba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user