#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 activeParticles; // linear/position properties: [NativeDisableParallelForRestriction] public NativeArray positions; [ReadOnly] public NativeArray previousPositions; [NativeDisableParallelForRestriction] public NativeArray velocities; // angular/orientation properties: [NativeDisableParallelForRestriction] public NativeArray orientations; [ReadOnly] public NativeArray previousOrientations; [NativeDisableParallelForRestriction] public NativeArray 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