Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Unity.Burst;
- using Unity.Collections;
- using Unity.Collections.LowLevel.Unsafe;
- using Unity.Jobs;
- using Unity.Mathematics;
- using UnityEngine;
- using Particle = Simulation.Particle;
- [BurstCompile]
- struct UpdateParticlesJob : IJobParallelFor
- {
- public NativeArray<Particle> particles;
- [ReadOnly] public NativeArray<Color> gradient;
- [ReadOnly] public int gradientResolution;
- [ReadOnly] public float deltaTime;
- [ReadOnly] public float minPosX;
- [ReadOnly] public float maxPosX;
- [ReadOnly] public float minPosY;
- [ReadOnly] public float maxPosY;
- [ReadOnly] public Unity.Mathematics.Random rng;
- public void Execute(int i)
- {
- Particle particle = particles[i];
- particle.position += particle.velocity * deltaTime;
- // float len = math.lengthsq(particle.velocity) / 5000f;
- // int gradientIndex = math.clamp((int)(len * gradientResolution), 0, gradientResolution - 1);
- // particle.color = gradient[gradientIndex];
- Vector2 absPos = new(Mathf.Abs(particle.position.x), Mathf.Abs(particle.position.y));
- if (absPos.x < minPosX || absPos.x > maxPosX || absPos.y < minPosY || absPos.y > maxPosY)
- {
- float posX = rng.NextFloat(minPosX, maxPosX);
- float posY = rng.NextFloat(minPosY, maxPosY);
- particle.position = new Vector2(posX, posY);
- particle.velocity = Vector2.zero;
- }
- particles[i] = particle;
- }
- }
- [BurstCompile]
- struct AccelerationJob : IJobParallelFor
- {
- [ReadOnly] public NativeArray<UnsafeList<Node>> nodes;
- public NativeArray<Particle> particles;
- [ReadOnly] public float theta;
- [ReadOnly] public float epsilon;
- [ReadOnly] public float deltaTime;
- public void Execute(int i)
- {
- float2 acceleration = new();
- float thetaSqr = theta * theta;
- float epsilonSqr = epsilon * epsilon;
- for (int j = 0; j < nodes.Length; j++)
- {
- int nodeIndex = 0;
- while (true)
- {
- Node node = nodes[j][nodeIndex];
- float2 diff = node.centerOfMass - particles[i].position;
- float sqrDst = math.max(math.lengthsq(diff), 0.05f);
- if (node.childIndex == 0 || node.boundary.size * node.boundary.size < sqrDst * thetaSqr)
- {
- float denom = (sqrDst + epsilonSqr) * math.sqrt(sqrDst);
- acceleration += diff * node.mass / denom * deltaTime;
- if (node.next == 0) break;
- nodeIndex = node.next;
- }
- else nodeIndex = node.childIndex;
- }
- }
- Particle particle = particles[i];
- particles[i] = new Particle
- {
- position = particle.position,
- velocity = particle.velocity + acceleration,
- mass = particle.mass,
- color = particle.color
- };
- }
- }
- [BurstCompile]
- struct InsertJob : IJob
- {
- [ReadOnly] public NativeArray<Particle> particles;
- public NativeList<Node> nodes;
- public void Execute()
- {
- int count = particles.Length;
- for (int i = 0; i < count; i++)
- {
- Insert(particles[i]);
- }
- }
- void Insert(Particle particle)
- {
- int nodeIndex = 0;
- Node node = nodes[0];
- while (node.childIndex != 0)
- {
- int quad = node.boundary.FindNode(particle.position);
- nodeIndex = quad + node.childIndex;
- node = nodes[nodeIndex];
- }
- if (node.mass == 0)
- {
- node.centerOfMass = particle.position;
- node.mass = particle.mass;
- nodes[nodeIndex] = node;
- return;
- }
- if (math.all(node.centerOfMass == particle.position))
- {
- node.mass += particle.mass;
- nodes[nodeIndex] = node;
- return;
- }
- Vector2 nodePos = node.centerOfMass;
- float nodeMass = node.mass;
- while (true)
- {
- Subdivide(nodeIndex);
- node = nodes[nodeIndex];
- int childIndex = node.childIndex;
- int q1 = node.boundary.FindNode(nodePos);
- int q2 = node.boundary.FindNode(particle.position);
- if (q1 == q2)
- {
- nodeIndex = q1 + childIndex;
- }
- else
- {
- int n1 = q1 + childIndex;
- int n2 = q2 + childIndex;
- nodes[n1] = new Node
- {
- centerOfMass = nodePos,
- mass = nodeMass,
- boundary = nodes[n1].boundary,
- next = nodes[n1].next
- };
- nodes[n2] = new Node
- {
- centerOfMass = particle.position,
- mass = particle.mass,
- boundary = nodes[n2].boundary,
- next = nodes[n2].next
- };
- return;
- }
- }
- }
- void Subdivide(int parentIndex)
- {
- Node parent = nodes[parentIndex];
- parent.childIndex = nodes.Length;
- nodes[parentIndex] = parent;
- float2 parentPos = parent.boundary.position;
- float halfSize = parent.boundary.size / 2;
- float2 nwPosition = new float2(parentPos.x, parentPos.y + halfSize);
- float2 nePosition = new float2(parentPos.x + halfSize, parentPos.y + halfSize);
- float2 swPosition = new float2(parentPos.x, parentPos.y);
- float2 sePosition = new float2(parentPos.x + halfSize, parentPos.y);
- Node nw = new Node
- {
- boundary = new Quad { position = nwPosition, size = halfSize },
- next = parent.childIndex + 1
- };
- Node ne = new Node
- {
- boundary = new Quad { position = nePosition, size = halfSize },
- next = parent.childIndex + 2
- };
- Node sw = new Node
- {
- boundary = new Quad { position = swPosition, size = halfSize },
- next = parent.childIndex + 3
- };
- Node se = new Node
- {
- boundary = new Quad { position = sePosition, size = halfSize },
- next = parent.next
- };
- nodes.Add(nw);
- nodes.Add(ne);
- nodes.Add(sw);
- nodes.Add(se);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement