System3.
상속: opentk.Scene.ParticleSystem.ParticleSystemBase
예제 #1
0
 protected override Vector3 NewPosition(System3 system, int bundleFirstItem, int i)
 {
     var dir = (Vector3) MathHelper2.RandomVector3(1);
     var l = dir.Length;
     var k = (float) MathHelper2.GetThreadLocalRandom().NextDouble();
     return dir * BoxOuterSize * k + dir * BoxInnerSize * (1 - k);
 }
예제 #2
0
        void ISimulationScheme.Simulate(System3 system, DateTime simulationTime, long simulationStep)
        {
            m_MapModeComputed &= simulationStep == m_PrevSimulStep + 1;
            m_PrevSimulStep = simulationStep;

            var position = system.Position;
            var dimension = system.Dimension;
            var meta = system.Meta;
            var color = system.Color;
            var dt = (float)system.DT;

            var fun = system.ChaoticMap.Map;
            m_SpeedUpperBound = Math.Max(m_SpeedUpperBound * 0.75f, 1);

            var step = 150;
            var meta0 = meta[0];
            var ld = (meta0.Leader + 1) % step;
            meta0.Leader = ld;
            meta[0] = meta0;

            //prepare seed points
            if (!m_MapModeComputed)
            {
                for (int i = 0; i < step; i++)
                {
                    position[i] = new Vector4 ((float)(MathHelper2.GetThreadLocalRandom().NextDouble () * 0.01), 0, 0, 1);
                    dimension[i] = Vector4.Zero;
                }
                m_MapModeComputed = true;
            }

            //iterate the seed values
            ld += step;
            for (int i = ld; i < position.Length; i += step)
            {
                var posi = position[i];
                var posis = position[i - step];
                fun (ref posis, ref posi );
                posi.W = 1;
                position[i] = posi;
                dimension[i] = new Vector4(meta[i].Size);

                switch (ColorScheme)
                {
                case ColorSchemeType.Distance:
                    var speed = (position[i] - position[i - step]).LengthFast / dt;
                    var A = MathHelper2.Clamp (2 * speed / m_SpeedUpperBound, 0, 1);
                    m_SpeedUpperBound = m_SpeedUpperBound < speed? speed: m_SpeedUpperBound;

                    color[i] = (new Vector4 (1, 0.2f, 0.2f, 1) * A + new Vector4 (0.2f, 1, 0.2f, 1) * (1 - A));
                    break;
                case ColorSchemeType.Color:
                    color[i] = new Vector4 (0.2f, 1, 0.2f, 1);
                    break;
                default:
                    break;
                }
            }
        }
예제 #3
0
        protected override Vector3 NewPosition(System3 system, int bundleFirstItem, int i)
        {
            var pcount = system.PARTICLES_COUNT;
            var amount = Math.Max (AmountX * AmountY * AmountZ, float.Epsilon);
            var gridCount = (int)Math.Floor (Math.Pow (pcount / amount, 1 / 3.0));

            var gcx = (int)Math.Max(gridCount * AmountY * gridCount * AmountZ, 1);
            var gcy = (int)Math.Max(gridCount * AmountZ, 1);

            int ix = i / gcx;
            int iy = (i - gcx * ix) / gcy;
            int iz = i - gcx * ix - gcy * iy;

            return
                Vector3.Multiply (new Vector3 (ix, iy, iz), new Vector3 (StepX, StepY, StepZ)) -
                Vector3.Multiply (new Vector3 (gridCount * StepX, gridCount * StepY, gridCount * StepZ), new Vector3 (AmountX, AmountY, AmountZ)) / 2;
        }
예제 #4
0
        void IGenerationScheme.Generate(System3 system, DateTime simulationTime, long simulationStep)
        {
            var trailSize = Math.Max (system.TrailSize, 1);
            var trailCount = (system.Position.Length + trailSize - 1) / trailSize;
            var trailBundleSize = Math.Max (system.SimulationScheme is ParticlesWithTrails ? ((ParticlesWithTrails)system.SimulationScheme).TrailBundleSize : 1, 1);
            var trailBundleCount = (trailCount + trailBundleSize - 1) / trailBundleSize;

            var fun = system.ChaoticMap.Map;
            var position = system.Position;
            var dimension = system.Dimension;
            var meta = system.Meta;
            var rotation = system.Rotation;
            var attribute1 = system.Color;

            var particleCount = position.Length;
            var particleScale = system.ParticleScaleFactor;
            var dt = (float)system.DT;

            for (int bundleIndex = 0; bundleIndex < trailBundleCount; bundleIndex++)
            {
                var firsttrail = bundleIndex * trailBundleSize * trailSize;
                var lasttrail = Math.Min (firsttrail + trailBundleSize, particleCount);

                for (int j = 0; j < trailSize; j++) {
                    for (int i = firsttrail; i < lasttrail; i++) {
                        //i is the trail's first element
                        var ii = i + j * trailBundleSize;
                        if (ii >= particleCount) {
                            break;
                        }

                        if(j != 0 || trailSize == 1)
                            meta[ii].Size = Math.Max (system.ParticleGenerator.UpdateSize (system, i, ii), float.Epsilon);

                        if (j == trailSize - 1) {
                            if (meta [i].LifeLen <= 0) {
                                system.ParticleGenerator.NewBundle (system, i);
                            } else
                                meta [i].LifeLen--;
                        }
                    }
                }
            }
        }
예제 #5
0
        void IGenerationScheme.Generate(System3 system, DateTime simulationTime, long simulationStep)
        {
            m_MapModeComputed &= simulationStep == m_PrevSimulStep + 1;
            m_PrevSimulStep = simulationStep;

            var Position = system.Position;
            var Meta = system.Meta;
            var Color = system.Color;
            var dt = (float)system.DT;

            //prepare seed points
            if (!m_MapModeComputed)
            {
                for (int i = 0; i < Meta.Length; i++) {
                    system.ParticleGenerator.MakeBubble (system, 0, i);
                }
                m_MapModeComputed = true;
            }
        }
예제 #6
0
 protected virtual Vector3 NewPosition(System3 system, int bundleFirstItem, int i)
 {
     return (Vector3)MathHelper2.RandomVector3(12);
 }
예제 #7
0
 public float UpdateSize(System3 system, int bundleFirstItem, int i)
 {
     var Meta = system.Meta;
     var r = (float)MathHelper2.GetThreadLocalRandom().NextDouble();
     return Math.Max((1 - SizeRandomness * r) * Meta [bundleFirstItem].Size, ScaleRatioMaxDifference * SizeScaleRatio);
 }
예제 #8
0
        public void NewBundle(System3 system, int bundleFirstItem)
        {
            var Meta = system.Meta;

            Meta [bundleFirstItem] = new MetaInformation {
            Size = (float)Math.Pow (MathHelper2.GetThreadLocalRandom().NextDouble (), SizeScalePower) * SizeScaleRatio,
            LifeLen = MathHelper2.GetThreadLocalRandom().Next (LifeLengthMin, LifeLengthMax),
            Leader = Meta[bundleFirstItem].Leader };

            MakeBubble(system, bundleFirstItem, Meta [bundleFirstItem].Leader + bundleFirstItem);
            return;
        }
예제 #9
0
        public void MakeBubble(System3 system, int bundleFirstItem, int i)
        {
            var Position = system.Position;
            var Dimension = system.Dimension;
            var Rotation = system.Rotation;
            var Color = system.Color;

            if (PreferStableOrbits)
            {
                var map = system.ChaoticMap;
                var lp = map.LyapunovExponent(Position [i], StableOrbitsCount);

                if (lp.Item1 > StableOrbitsLMin && lp.Item1 < StableOrbitsLMax)
                    return;

                if (lp.Item2.Length < StableOrbitsMaxDist)
                    return;
            }

            var size = UpdateSize(system, bundleFirstItem, i);
            var newpos = NewPosition(system, bundleFirstItem, i);

            Dimension [i] = new Vector4(size, size, size, size);
            Position [i] = new Vector4(newpos.X, newpos.Y, newpos.Z, 1);
            Color [i] = new Vector4(0, 1, 0, 1);
            Rotation [i] = Matrix4.Identity;
        }
예제 #10
0
        void IGenerationScheme.Generate(System3 system, DateTime simulationTime, long simulationStep)
        {
            var trailBundleSize = Math.Max (system.SimulationScheme is ParticlesWithTrails ? ((ParticlesWithTrails)system.SimulationScheme).TrailBundleSize : 1, 1);
            var dt = (float)system.DT;

            m_GIndices = m_GIndices ?? GenerationIndices(system).GetEnumerator();
            var sw = new System.Diagnostics.Stopwatch();

            sw.Start();
            while(m_GIndices.MoveNext())
            {
                var pack = m_GIndices.Current;
                var i = (int)(pack >> 32);
                var j = (int)(pack);

                var ii = i + j * trailBundleSize;
                if (ii >= system.Position.Length) {
                    break;
                }

                var _i = i;
                var metai = system.Meta.MapReadWrite(ref _i);
                if(j == 0)
                {
                    if (m_Length != system.Position.Length)
                    {
                        system.ParticleGenerator.NewBundle (system, i);
                    }
                    else if (metai[_i].LifeLen <= 0) {
                        system.ParticleGenerator.NewBundle (system, i);
                    }
                    else
                    {
                        metai[_i].LifeLen--;
                        metai[_i].Size = Math.Max (system.ParticleGenerator.UpdateSize (system, i, i), float.Epsilon);
                    }
                }
                else
                {
                    var _ii = ii;
                    system.Meta.MapReadWrite(ref _ii)[_ii].Size = Math.Max (system.ParticleGenerator.UpdateSize (system, i, ii), float.Epsilon);
                }

                if(m_Length == system.Position.Length)
                    if(sw.Elapsed > TimeSpan.FromMilliseconds(50))
                        return;
            }

            m_GIndices.Dispose ();
            m_GIndices = null;
            m_Length = system.Position.Length;
        }
예제 #11
0
        IEnumerable<long> GenerationIndices(System3 system)
        {
            var trailSize = Math.Max (system.TrailSize, 1);
            var trailCount = (system.Position.Length + trailSize - 1) / trailSize;
            var trailBundleSize = Math.Max (system.SimulationScheme is ParticlesWithTrails ? ((ParticlesWithTrails)system.SimulationScheme).TrailBundleSize : 1, 1);
            var trailBundleCount = (trailCount + trailBundleSize - 1) / trailBundleSize;

            var position = system.Position;
            for (int bundleIndex = 0; bundleIndex < trailBundleCount; bundleIndex++)
            {
                var firsttrail = bundleIndex * trailBundleSize * trailSize;
                var lasttrail = Math.Min (firsttrail + trailBundleSize, system.Position.Length);

                for (int j = 0; j < trailSize; j++) {
                    for (int i = firsttrail; i < lasttrail; i++) {
                        //i is the trail's first element
                        var ii = i + j * trailBundleSize;
                        if (ii >= system.Position.Length) {
                            yield break;
                        }

                        yield return (long)i << 32 | (uint)j;
                    }
                }
            }
        }
        void ISimulationScheme.Simulate(System3 system, DateTime simulationTime, long simulationStep)
        {
            var trailBundleSize = Math.Max(TrailBundleSize, 1);

            if (m_State == null) {
                //create program from resources filtered by namespace and name
                var program = new Program ("SimulationScheme")
                {
                    RenderPass.GetShaders ("System3", "ParticlesWithTrails"),
                    RenderPass.GetShaders ("System3", "PWTSub")
                };
                m_Parameters = new BufferObjectCompact<float>(sizeof(float), 0) { Name = "map_parameters_buffer", Usage = BufferUsageHint.DynamicDraw };

                m_State =
                    new State (null)
                    {
                      program,
                      new ShaderStorageSet
                      {
                            {"Position", system.PositionBuffer},
                          {"Rotation", system.RotationBuffer},
                          {"MapParameters", m_Parameters},
                          {"Dimension", system.DimensionBuffer},
                          {"Attribute1", system.ColorBuffer},
                          {"Meta", system.MetaBuffer},
                      },
                      new UniformState
                      {
                          {"u_Dt", () => (float)system.DT },
                          {"u_TrailSize", () => system.TrailSize },
                          {"u_TrailBundleSize", () => TrailBundleSize },
                          {"u_StepsPerFrame", () => system.StepsPerFrame },
                          {"u_ParticleScale", () => (float)system.ParticleScaleFactor },
                          {"u_Map", (ShaderType)ShaderTypeExt.ComputeShader, () => system.ChaoticMap.Name },
                      }
                    };
            }

            system.MetaBuffer.Publish();
            system.PositionBuffer.Publish();
            system.DimensionBuffer.Publish();
            system.RotationBuffer.Publish();
            system.ColorBuffer.Publish();
            system.RotationLocalBuffer.Publish();

            m_Parameters.Length = system.ChaoticMap.a.Length;
            m_Parameters.CopyFrom(system.ChaoticMap.a, 0);
            m_Parameters.Publish();

            m_State.Activate ();
            GLExtensions.DispatchCompute (system.PARTICLES_COUNT/(8 * trailBundleSize)  + 1, 1, 1);

            //system.MetaBuffer.Readout();
            //system.PositionBuffer.Readout();
            //system.RotationBuffer.Readout();
            //system.DimensionBuffer.Readout();
            //system.ColorBuffer.Readout();
        }
예제 #13
0
        void ISimulationScheme.Simulate(System3 system, DateTime simulationTime, long simulationStep)
        {
            m_MapModeComputed &= simulationStep == m_PrevSimulStep + 1;
            m_PrevSimulStep = simulationStep;

            var position = system.Position;
            var fun = system.ChaoticMap.Map;
            m_SpeedUpperBound = Math.Max(m_SpeedUpperBound * 0.75f, 1);

            //prepare seed points
            if (!m_MapModeComputed)
            {
                for (int i = 0; i < position.Length; i++)
                {
                    system.ParticleGenerator.MakeBubble(system, i, i);
                    fun (ref position[i], ref position[i]);
                    position[i].W = 1;
                }
                m_MapModeComputed = true;
            }
        }
예제 #14
0
        void ISimulationScheme.Simulate(System3 system, DateTime simulationTime, long simulationStep)
        {
            m_SpeedUpperBound = Math.Max(m_SpeedUpperBound * 0.75f, 0.01f);

            var trailSize = Math.Max(system.TrailSize, 1);
            var trailCount = (system.Position.Length + trailSize - 1) / trailSize;
            var trailBundleSize = Math.Max(TrailBundleSize, 1);
            var trailBundleCount = (trailCount + trailBundleSize - 1) / trailBundleSize;

            var stepsPerFrame = Math.Max(system.StepsPerFrame, 1);
            var fun = system.ChaoticMap.Map;
            var position = system.Position;
            var dimension = system.Dimension;
            var meta = system.Meta;
            var rotation = system.Rotation;
            var attribute1 = system.Color;

            var particleCount = position.Length;
            var particleScale = system.ParticleScaleFactor;
            var dt = (float)system.DT;

            Parallel.For (0, trailBundleCount,
            bundleIndex =>
            {
                var firsttrail = bundleIndex * trailBundleSize * trailSize;
                var lasttrail = Math.Min(firsttrail + trailBundleSize , particleCount);
                var speedBound = m_SpeedUpperBound;
                var dp = Vector4.Zero;
                var dpA = Vector4.Zero;
                var dpB = Vector4.Zero;
                var delta2 = Vector4.Zero;
                var size = 0f;
                var middlepoint = Vector4.Zero;
                var endpoint = Vector4.Zero;

                for (int j = 0; j < stepsPerFrame; j++)
                {
                    for (int i = firsttrail ; i < lasttrail ; i += 1)
                    {
                        //i is the trail's first element
                        var pi = i + meta[i].Leader;
                        var K = dt;

                        size = Math.Max(meta[pi].Size, float.Epsilon);

                        if(MapMode == MapModeType.ForceField)
                        {
                            dp = new Vector4 (meta[i].Velocity, 0);
                            fun (ref position[pi], ref delta2);
                            meta[i].Velocity += delta2.Xyz * dt;
                        }
                        else
                        {
                            fun (ref position[pi], ref dp);
                        }

                        //
                        var b0 = new Vector4( dp.Xyz, 0);
                        var b2 = new Vector4( Vector3.Cross( b0.Xyz, rotation[pi].Row1.Xyz), 0);
                        var b1 = new Vector4( Vector3.Cross( b2.Xyz, b0.Xyz), 0);

                        b0.Normalize();
                        b1.Normalize();
                        b2.Normalize();

                        //
                        if(IntegrationStep == IntegrationStepType.LimitDelta)
                        {
                            K *= Math.Min(1, 10 * (size * particleScale)/ (dp.Length * dt));
                        }

                        if(Interpolation == InterpolationType.Cubic)
                            K *= 0.5f;

                        dp *= K;

                        //
                        var localCount = (float)Math.Ceiling(dp.Length / (size * particleScale));
                        localCount = Math.Min(localCount, trailSize);
                        if(Interpolation == InterpolationType.Cubic)
                        {
                            dpA = 2 * dp;
                            middlepoint = position[pi] + dp;
                            fun (ref middlepoint, ref dpB);
                            dpB *= K;
                            endpoint = middlepoint + dpB;

                            fun (ref endpoint, ref dpB);
                            dpB *= 2 * K;
                        }

                        for(int li = 0; li < localCount; li++)
                        {
                            meta[i].Leader = (meta[i].Leader + trailBundleSize) % (trailSize * trailBundleSize);

                            var ii = i + meta[i].Leader;
                            if (ii >= particleCount)
                            {
                                ii = i;
                                meta[i].Leader = 0;
                            }

                            if(Interpolation == InterpolationType.Cubic)
                            {
                                var t = (1 + li) / localCount;
                                var p1 = 2*t*t*t - 3*t*t + 1;
                                var p2 = t*t*t - 2*t*t + t;
                                var p3 = -p1 + 1;
                                var p4 = p2 + t*t - t;

                                position[ii] =
                                    p1 *  position[pi] +
                                    p2 * dpA +
                                    p3 * endpoint +
                                    p4 * dpB;

                                dimension[ii] = new Vector4 (size, size, size, size);
                                rotation[ii] = new Matrix4(b0, b1, b2, new Vector4(0,0,0,1));
                            }
                            else
                            {
                                position[ii] = position[pi] + ((1 + li) / localCount) * dp;
                                dimension[ii] = new Vector4 (size, size, size, size);
                                rotation[ii] = new Matrix4(b0, b1, b2, new Vector4(0,0,0,1));
                            }

                            switch (ComputeMetadataMode) {
                            case ComputeMetadata.Speed:
                                attribute1[ii] = dp;
                            break;
                            case ComputeMetadata.Tangent:
                                attribute1[ii] = b0;
                            break;
                            default:
                            break;
                            }
                        }
                    }
                }

                var orig = m_SpeedUpperBound;
                var help = orig;
                while(
                    speedBound > orig &&
                    (help = Interlocked.CompareExchange(ref m_SpeedUpperBound, speedBound, orig)) != orig)
                    orig = help;
            });
        }
예제 #15
0
 protected override ParticleSystem GetInstanceInternal(GameWindow win)
 {
     var result = new System3
     {
         PARTICLES_COUNT = 260000,
         VIEWPORT_WIDTH = 324,
         NEAR = 1,
         FAR = 10240,
         DT = 1,
         Fov = 0.9,
         PublishMethod = PublishMethod.Never,
         ParticleScaleFactor = 600,
         SimulationScheme = new ParticlesWithTrailsGpuSimulationScheme(),
         GenerationScheme = new ParticlesWithTrailsGenerationScheme(),
         ParticleGenerator = new GridGenerator { AmountX = 1, AmountY = 1, AmountZ = 0.001f, StepX = 0.1f, StepY = 0.1f },
         ChaoticMap = new Swirl2DMap()
     };
     return result;
 }