示例#1
0
    //----------------------------------------------------
    // run the physics for all the particles
    //----------------------------------------------------
    private void simulateParticlesCPU(float deltaTime)
    {
        if (_useMultithreading)
        {
            if (_parallelForeach == null)
            {
                _parallelForeach = new ParallelForeach((a, b) => particleSimulationLogic(a, b, deltaTime));
            }

            _parallelForeach.Dispatch(NUM_PARTICLES);
            _parallelForeach.Wait();
        }
        else
        {
            particleSimulationLogic(0, NUM_PARTICLES, deltaTime);
        }

        //----------------------------
        // swap back and front buffer
        //----------------------------
        var temp = _backBuffer;

        _backBuffer = _particles;
        _particles  = temp;
    }
示例#2
0
    protected virtual void Awake()
    {
        _stopwatch.Start();

        int cores = SystemInfo.processorCount;

        _integrationForeach       = new ParallelForeach(integrateParticles, cores);
        _resolveCollisionsForeach = new ParallelForeach(resolveCollisionsNaive, cores);

        _integrationForeach.OnComplete += () => {
            System.Array.Copy(_particlesFront, _particlesBack, _aliveParticles);
            _resolveCollisionsForeach.Dispatch(_aliveParticles);
        };

        ResetSimulation();

        _randomColors = new Color[maxParticles];
        for (int i = 0; i < maxParticles; i++)
        {
            _randomColors[i] = new Color(UnityEngine.Random.value, UnityEngine.Random.value, UnityEngine.Random.value);
        }
    }
示例#3
0
    protected virtual void Update()
    {
        _deltaTime = 1f / 5f;
        RuntimeGizmoManager.TryGetGizmoDrawer(out drawer);

        BeforeParticleUpdate();

        Array.Clear(collisionTimes, 0, collisionTimes.Length);
        for (int i = 0; i < _workerData.Length; i++)
        {
            _workerData[i].collisionChunkCounts.Clear();
            _workerData[i].socialChunkCounts.Clear();
        }

        using (new ProfilerSample("Destroy Particles")) {
            destroyParticles();
        }

        using (new ProfilerSample("Emit Particles")) {
            emitParticles();
        }

        if (_useMultithreading)
        {
            using (new ProfilerSample("Dispatch Simulation Jobs")) {
                _integrationForeach.Dispatch(_aliveParticles);
            }
        }
        else
        {
            using (new ProfilerSample("Integrate Particles")) {
                integrateParticles(0, 0, _aliveParticles);
            }
            Array.Copy(_particlesFront, _particlesBack, _aliveParticles);

            if (_useCollisionChunking)
            {
                using (new ProfilerSample("Accumulate And Sort")) {
                    sortIntoChunks(isCollision: true);
                }

                using (new ProfilerSample("Resolve Collisions")) {
                    resolveCollisionsChunked();
                }
            }
            else
            {
                using (new ProfilerSample("Resolve Collisions")) {
                    resolveCollisionsNaive(0, 0, _aliveParticles);
                }
            }

            if (_useSocialChunking)
            {
                using (new ProfilerSample("Accumulate And Sort")) {
                    sortIntoChunks(isCollision: false);
                }

                using (new ProfilerSample("Apply Forces")) {
                    doSocialForcesChunked();
                }
            }
            else
            {
                using (new ProfilerSample("Apply Forces")) {
                    doSocialForcesNaive(0, 0, _aliveParticles);
                }
            }

            using (new ProfilerSample("Apply Global Forces")) {
                applyGlobalForces(0, 0, _aliveParticles);
            }
        }

        if (Input.GetKeyDown(KeyCode.M))
        {
            useKMeans = true;
        }

        if (useKMeans)
        {
            int LEN = 20;
            if (_means == null)
            {
                _means  = new Vector3[LEN];
                _raddii = new float[LEN];
                for (int i = 0; i < LEN; i++)
                {
                    _means[i] = _particlesFront[UnityEngine.Random.Range(0, _aliveParticles)].position;
                }
            }

            var newMeans  = new Vector3[LEN];
            var newCounts = new int[LEN];

            _raddii = new float[LEN];

            for (int i = 0; i < _aliveParticles; i++)
            {
                Particle p = _particlesFront[i];

                float closestDist = float.MaxValue;
                int   index       = 0;
                for (int j = 0; j < LEN; j++)
                {
                    float dist = Vector3.Distance(p.position, _means[j]);
                    if (dist < closestDist)
                    {
                        closestDist = dist;
                        index       = j;
                    }
                }

                drawer.color = _randomColors[index];
                drawer.DrawWireSphere(p.position, 0.05f);

                newMeans[index]  += p.position;
                newCounts[index] += 1;
                _raddii[index]    = Mathf.Max(_raddii[index], closestDist);
            }

            for (int i = 0; i < LEN; i++)
            {
                if (newCounts[i] == 0)
                {
                    _means[i] = UnityEngine.Random.insideUnitSphere;
                }
                else
                {
                    _means[i] = newMeans[i] / newCounts[i];
                }

                drawer.color = _randomColors[i];
                drawer.DrawWireSphere(_means[i], _raddii[i]);
            }

            int totalInteractions = 0;
            for (int i = 0; i < _aliveParticles; i++)
            {
                Particle p = _particlesFront[i];

                float closestDist = float.MaxValue;
                int   index       = 0;
                for (int j = 0; j < LEN; j++)
                {
                    float dist = Vector3.Distance(p.position, _means[j]);
                    if (dist < closestDist)
                    {
                        closestDist = dist;
                        index       = j;
                    }
                }

                totalInteractions += newCounts[index];
                for (int j = 0; j < LEN; j++)
                {
                    if (j == index)
                    {
                        continue;
                    }

                    if (Vector3.Distance(p.position, _means[j]) < (0.5f + _raddii[j]))
                    {
                        totalInteractions += newCounts[j];
                    }
                }
            }

            Debug.Log(totalInteractions + " : " + (1024 * 1024));
        }
    }