Advertisement
JontePonte

Slow sim gravity

Nov 10th, 2024
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.12 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using TMPro;
  5. using Unity.VisualScripting;
  6. using UnityEngine;
  7. using UnityEngine.Profiling;
  8. using UnityEngine.Serialization;
  9. using Debug = UnityEngine.Debug;
  10. using Random = UnityEngine.Random;
  11.  
  12. public class Simulation : MonoBehaviour
  13. {
  14.    public struct Particle
  15.    {
  16.       public Vector2 position, velocity;
  17.       public float mass;
  18.    }
  19.    public int particleCount;
  20.    public float radius;
  21.    public float mass;
  22.    public float timeScale;
  23.    
  24.    [Header("Quad Tree")]
  25.    public float approximationThreshold;
  26.    public int capacity;
  27.    public int maxDepth;
  28.    
  29.    [Header("")]
  30.    public bool centerAttraction;
  31.    public float centerMass;
  32.  
  33.    public float particleForce;
  34.    
  35.    public Material material;
  36.  
  37.    Particle[] particles;
  38.    QuadTree quadTree;
  39.    new ParticleRenderer renderer;
  40.    Particle center;
  41.    TextMeshProUGUI latency;
  42.  
  43.    const int HalfScreenSize = 5;
  44.  
  45.    void Start()
  46.    {
  47.       center = new Particle
  48.       {
  49.          position = Vector2.zero,
  50.          velocity = Vector2.zero,
  51.          mass = centerMass
  52.       };
  53.       particles = new Particle[particleCount];
  54.       for (int i = 0; i < particleCount; i++)
  55.       {
  56.          float posX = Random.Range(-HalfScreenSize + radius, HalfScreenSize - radius);
  57.          float posY = Random.Range(-HalfScreenSize + radius, HalfScreenSize - radius);
  58.  
  59.          float centerDist = new Vector2(posX, posY).magnitude;
  60.          float force = Mathf.Sqrt(centerMass / centerDist);
  61.          Vector2 direction = new Vector2(posY, posX).normalized;
  62.          Vector2 velocity = new Vector2(direction.x, -direction.y) * force * particleForce;
  63.          
  64.          particles[i] = new()
  65.          {
  66.             position = new Vector2(posX, posY),
  67.             velocity = Vector2.zero,
  68.             mass = mass
  69.          };
  70.       }
  71.  
  72.       latency = GameObject.Find("Latency").GetComponent<TextMeshProUGUI>();
  73.       renderer = new(particles, material, radius);
  74.       RebuildQuadTree();
  75.    }
  76.  
  77.    void FixedUpdate()
  78.    {
  79.       Stopwatch watch = new();
  80.       watch.Start();
  81.      
  82.       Profiler.BeginSample("UpdateVelocities");
  83.       UpdateVelocities(Time.fixedDeltaTime * timeScale);
  84.       Profiler.EndSample();
  85.       Profiler.BeginSample("UpdatePositions");
  86.       UpdatePositions(Time.fixedDeltaTime * timeScale);
  87.       Profiler.EndSample();
  88.       Profiler.BeginSample("RebuildQuadTree");
  89.       RebuildQuadTree();
  90.       Profiler.EndSample();
  91.      
  92.       watch.Stop();
  93.       latency.text = watch.ElapsedMilliseconds + " ms";
  94.    }
  95.  
  96.    void Update()
  97.    {
  98.       renderer.Render(particles);
  99.       quadTree.DrawTree();
  100.    }
  101.    void OnDestroy()
  102.    {
  103.       renderer.ReleaseBuffers();
  104.    }
  105.  
  106.    void UpdateVelocities(float timeStep)
  107.    {
  108.       for (int i = 0; i < particleCount; i++)
  109.       {
  110.          List<Particle> targets = quadTree.UpdateVelocity(particles[i], timeStep);
  111.          Particle thisParticle = particles[i];
  112.          int count = targets.Count;
  113.          Debug.Log(targets.Count);
  114.          for (int j = 0; j < count; j++)
  115.          {
  116.             thisParticle.velocity += CalculateAcceleration(thisParticle, targets[j]) * timeStep;
  117.          }
  118.  
  119.          particles[i] = thisParticle;
  120.          //particles[i] = quadTree.UpdateVelocity(particles[i], timeStep);
  121.       }  
  122.    }
  123.    
  124.    Vector2 CalculateAcceleration(Particle p1, Particle p2)
  125.    {
  126.       Vector2 diff = p2.position - p1.position;
  127.       Vector2 forceDir = diff.normalized;
  128.       float sqrDst = Mathf.Max(diff.sqrMagnitude, 0.05f);
  129.       Vector2 force = forceDir * (p1.mass * p2.mass) / sqrDst;
  130.       Vector2 acceleration = force / p1.mass;
  131.  
  132.       return acceleration;
  133.    }
  134.  
  135.    void UpdatePositions(float timeStep)
  136.    {
  137.       float minPosX = -HalfScreenSize + radius;
  138.       float maxPosX = HalfScreenSize - radius;
  139.       float minPosY = -HalfScreenSize + radius;
  140.       float maxPosY = HalfScreenSize - radius;
  141.      
  142.       for (int i = 0; i < particleCount; i++)
  143.       {
  144.          Particle particle = particles[i];
  145.          particle.position += particle.velocity * timeStep;
  146.          
  147.          Vector2 absPos = new(Mathf.Abs(particle.position.x), Mathf.Abs(particle.position.y));
  148.          if (absPos.x < minPosX || absPos.x > maxPosX || absPos.y < minPosY || absPos.y > maxPosY)
  149.          {
  150.             float posX = Random.Range(minPosX, maxPosX);
  151.             float posY = Random.Range(minPosY, maxPosY);
  152.             particle.position = new Vector2(posX, posY);
  153.          }
  154.            
  155.          particles[i] = particle;
  156.       }
  157.    }
  158.  
  159.    void RebuildQuadTree()
  160.    {
  161.       AABB boundary = new()
  162.       {
  163.          position = new Vector2(-5f, -5f),
  164.          size = 10
  165.       };
  166.       quadTree = new(boundary);
  167.       QuadTree.OverlapTolerance = radius;
  168.       QuadTree.ApproximationThreshold = approximationThreshold;
  169.       QuadTree.Capacity = capacity;
  170.       QuadTree.MaxDepth = maxDepth;
  171.       QuadTree.OriginalSize = HalfScreenSize * 2;
  172.  
  173.       for (int i = 0; i < particles.Length; i++)
  174.       {
  175.          quadTree.Insert(particles[i]);
  176.       }
  177.      
  178.       quadTree.CalculateMassAndCenterOfMass();
  179.    }
  180. }
  181.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement