示例#1
0
    public void ResetTrails(bool forceReset = false)
    {
        if (!forceReset && _onlyResetWhenComplete)
        {
            _trailResetQueued = true;
        }
        else
        {
            _trailResetQueued = false;

            if (_trailState != null)
            {
                NBodyC.DestroyGalaxy(_trailState);
                _trailState = null;
            }

            _trailState = NBodyC.Clone(mainState);

            _trails.Clear();
            unsafe {
                BlackHole *src = mainState->blackHoles;
                for (int i = 0; i < mainState->numBlackHoles; i++, src++)
                {
                    _trails[src->id] = new TrailRecord();
                }
            }
        }
    }
示例#2
0
    private unsafe void updateShaderConstants()
    {
        simulateMat.SetFloat("_MinDiscRadius", minDiscRadius);
        simulateMat.SetFloat("_MaxDiscRadius", maxDiscRadius);
        simulateMat.SetFloat("_MaxDiscHeight", maxDiscHeight);

        {
            BlackHole *src = mainState->blackHoles;
            for (int i = 0; i < mainState->numBlackHoles; i++, src++)
            {
                Vector4 planet = src->position;
                planet.w        = src->mass;
                _vectorArray[i] = planet;
            }
            simulateMat.SetVectorArray("_Planets", _vectorArray);
        }

        {
            BlackHole *src = mainState->blackHoles;
            for (int i = 0; i < mainState->numBlackHoles; i++, src++)
            {
                _matrixArray[i] = Matrix4x4.Rotate(src->rotation);
            }
            simulateMat.SetMatrixArray("_PlanetRotations", _matrixArray);
        }

        simulateMat.SetInt("_PlanetCount", mainState->numBlackHoles);

        simulateMat.SetFloat("_Force", starGravConstant);
        simulateMat.SetFloat("_FuzzValue", fuzzValue);
    }
示例#3
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);
            }
        }
    }
示例#4
0
    public unsafe void ResetSimulation()
    {
        if (mainState != null)
        {
            NBodyC.DestroyGalaxy(mainState);
            mainState = null;
        }

        if (prevState != null)
        {
            NBodyC.DestroyGalaxy(prevState);
            prevState = null;
        }

        if (_trailState != null)
        {
            NBodyC.DestroyGalaxy(_trailState);
            _trailState = null;
        }

        _trails.Clear();
        _trailMesh.Clear();

        simulationTime         = 0;
        mainState              = NBodyC.CreateGalaxy(blackHoleCount);
        mainState->time        = 0;
        mainState->frames      = 0;
        _initialBlackHoleCount = blackHoleCount;

        {
            Random.InitState(_seed);
            BlackHole *dst = mainState->blackHoles;

            int nextId = 1;
            for (int i = 0; i < blackHoleCount; i++, dst++)
            {
                Vector3 position = Random.onUnitSphere * blackHoleSpawnRadius;

                *dst = new BlackHole()
                {
                    position = position,
                    velocity = Vector3.Slerp(Vector3.zero - position, Random.onUnitSphere, initialDirVariance).normalized *blackHoleVelocity,
                    mass     = Random.Range(1 - blackHoleMassVariance, 1 + blackHoleMassVariance),
                    id       = nextId,
                    rotation = Random.rotationUniform
                };

                nextId = nextId << 1;
            }
        }

        Texture2D tex = new Texture2D(2048, 1, TextureFormat.RFloat, mipmap: false, linear: true);

        for (int i = 0; i < tex.width; i++)
        {
            float t = 1 - i / 2047f;
            t = Mathf.Pow(t, pow);

            tex.SetPixel(i, 0, new Color(t, 0, 0, 0));
            //tex.SetPixel(i, 0, new Color(radiusDistribution.Evaluate(i / 2048.0f), 0, 0, 0));
        }
        tex.Apply();
        tex.filterMode = FilterMode.Bilinear;
        tex.wrapMode   = TextureWrapMode.Clamp;
        simulateMat.SetTexture("_RadiusDistribution", tex);

        updateShaderConstants();

        {
            BlackHole *src = mainState->blackHoles;
            for (int i = 0; i < mainState->numBlackHoles; i++, src++)
            {
                _vectorArray[i] = src->velocity;
            }
            simulateMat.SetVectorArray("_PlanetVelocities", _vectorArray);
        }

        {
            BlackHole *src = mainState->blackHoles;
            _floatArray.Fill(0);
            for (int i = 0; i < mainState->numBlackHoles; i++, src++)
            {
                _floatArray[i] = Mathf.Lerp(1, src->mass, blackHoleMassAffectsDensity);
            }
            simulateMat.SetFloatArray("_PlanetDensities", _floatArray);
            simulateMat.SetFloat("_TotalDensity", _floatArray.Query().Fold((a, b) => a + b));
        }

        {
            BlackHole *src = mainState->blackHoles;
            for (int i = 0; i < mainState->numBlackHoles; i++, src++)
            {
                _floatArray[i] = Mathf.Lerp(1, src->mass, blackHoleMassAffectsSize);
            }
            simulateMat.SetFloatArray("_PlanetSizes", _floatArray);
        }

        GL.LoadPixelMatrix(0, 1, 0, 1);

        prevPos.DiscardContents();
        currPos.DiscardContents();

        RenderBuffer[] buffer = new RenderBuffer[2];
        buffer[0] = prevPos.colorBuffer;
        buffer[1] = currPos.colorBuffer;
        Graphics.SetRenderTarget(buffer, prevPos.depthBuffer);

        simulateMat.SetPass(1);

        GL.Begin(GL.QUADS);
        GL.TexCoord2(0, 0);
        GL.Vertex3(0, 0, 0);
        GL.TexCoord2(1, 0);
        GL.Vertex3(1, 0, 0);
        GL.TexCoord2(1, 1);
        GL.Vertex3(1, 1, 0);
        GL.TexCoord2(0, 1);
        GL.Vertex3(0, 1, 0);
        GL.End();

        prevState       = NBodyC.Clone(mainState);
        prevState->time = mainState->time - 1.0f / REFERENCE_FRAMERATE;

        ResetTrails(forceReset: true);

        if (OnReset != null)
        {
            OnReset();
        }
    }