示例#1
0
    private void stepSimulation()
    {
        float deltaTime = timescale / REFERENCE_FRAMERATE;

        simulationTime += deltaTime;
        while (mainState->time < simulationTime)
        {
            //Simulate black holes
            {
                NBodyC.CopyGalaxy(mainState, prevState);
                NBodyC.StepGalaxy(mainState);
            }

            //Update trails
            {
                // When the mainState matches a trail entry, we can remove that trail entry
                // (These are _future_ trails, not past trails :P)
                foreach (var pair in _trails)
                {
                    if (mainState->frames > pair.Value.startFrame && pair.Value.queue.Count > 0)
                    {
                        pair.Value.queue.PopFront();
                    }
                }
            }

            //Simulate stars
            {
                updateShaderConstants();

                nextPos.DiscardContents();
                Graphics.Blit(null, nextPos, simulateMat, 0);

                var tmp = prevPos;
                prevPos = currPos;
                currPos = nextPos;
                nextPos = tmp;

                simulateMat.SetTexture("_PrevPositions", prevPos);
                simulateMat.SetTexture("_CurrPositions", currPos);
            }

            if (_limitStepsPerFrame)
            {
                if (mainState->time < simulationTime)
                {
                    simulationTime = mainState->time;
                }
                break;
            }
        }

        if (OnStep != null)
        {
            OnStep();
        }
    }
示例#2
0
    private void Update()
    {
        if (Input.GetKeyDown(resetKeycode))
        {
            ResetSimulation();
        }

        if ((loop && mainState->time > loopTime) || respawnMode)
        {
            ResetSimulation();
            return;
        }

        Random.InitState(Time.frameCount);
        _seed = Random.Range(int.MinValue, int.MaxValue);

        if (simulate)
        {
            stepSimulation();
        }

        if (_enableTrails)
        {
            using (new ProfilerSample("Simulate Trails")) {
                if (_profileTrails)
                {
                    var stopwatch = new System.Diagnostics.Stopwatch();
                    stopwatch.Reset();
                    stopwatch.Start();
                    const int FRAMES_TO_TEST = 1000;
                    for (int i = 0; i < FRAMES_TO_TEST; i++)
                    {
                        NBodyC.StepGalaxy(_trailState);
                    }
                    double seconds         = stopwatch.ElapsedTicks / (double)System.Diagnostics.Stopwatch.Frequency;
                    double framesPerSecond = FRAMES_TO_TEST / seconds;
                    _trailFramerate = framesPerSecond;
                    Debug.Log("#####: " + _trailFramerate);
                }
                else
                {
                    int simTime = 0;
                    while (_trailState->frames < mainState->frames + _maxTrailLength)
                    {
                        NBodyC.StepGalaxy(_trailState);

                        unsafe {
                            BlackHole * src = _trailState->blackHoles;
                            TrailRecord trail;
                            for (int j = 0; j < _trailState->numBlackHoles; j++, src++)
                            {
                                if (!_trails.TryGetValue(src->id, out trail))
                                {
                                    trail = new TrailRecord()
                                    {
                                        startFrame = _trailState->frames
                                    };
                                    _trails[src->id] = trail;
                                }

                                trail.queue.PushBack(src->position);
                            }
                        }

                        simTime++;
                        if (simTime >= _trailUpdateRate)
                        {
                            break;
                        }
                    }
                }
            }

            //Build and display trail mesh
            //but only if it's already reached its max length
            if (_trailState->frames - mainState->frames >= _trailShowLength)
            {
                using (new ProfilerSample("Display Trails")) {
                    _trailVerts.Clear();
                    _trailIndices.Clear();

                    using (new ProfilerSample("Build Vertex List")) {
                        foreach (var pair in _trails)
                        {
                            for (int i = 0; i < pair.Value.queue.Count; i++)
                            {
                                if (i != 0)
                                {
                                    _trailIndices.Add(_trailVerts.Count);
                                    _trailIndices.Add(_trailVerts.Count - 1);
                                }

                                _trailVerts.Add(pair.Value.queue[i]);
                            }
                        }
                    }

                    int[] indexArray;
                    using (new ProfilerSample("Build Index Array")) {
                        indexArray = ArrayPool <int> .Spawn(_trailIndices.Count);

                        for (int i = 0; i < _trailIndices.Count; i++)
                        {
                            indexArray[i] = _trailIndices[i];
                        }

                        for (int i = _trailIndices.Count; i < indexArray.Length; i++)
                        {
                            indexArray[i] = 0;
                        }
                    }

                    using (new ProfilerSample("Upload Mesh")) {
                        _trailMesh.Clear();
                        _trailMesh.SetVertices(_trailVerts);
                        _trailMesh.SetIndices(indexArray, MeshTopology.Lines, 0);

                        ArrayPool <int> .Recycle(indexArray);

                        indexArray = null;
                    }

                    if (_trailResetQueued)
                    {
                        ResetTrails(forceReset: true);
                    }
                }
            }

            _trailPropertyBlock.SetColor("_Color", _trailColor);
            Graphics.DrawMesh(_trailMesh, galaxyRenderer.displayAnchor.localToWorldMatrix, _trailMaterial, 0, null, 0, _trailPropertyBlock);
        }

        //Render the black holes themselves
        unsafe {
            BlackHole *prevSrc  = prevState->blackHoles;
            BlackHole *mainSrc  = mainState->blackHoles;
            float      fraction = Mathf.InverseLerp(prevState->time, mainState->time, simulationTime);
            for (int j = 0; j < mainState->numBlackHoles; j++, prevSrc++, mainSrc++)
            {
                Vector3 position = Vector3.Lerp(prevSrc->position, mainSrc->position, fraction);
                galaxyRenderer.DrawBlackHole(position);
            }
        }
    }