/// <summary>
        /// Creates a new LineCirclePattern, duplicating an existing one
        /// </summary>
        /// <param name="CopyTarget">The LineCirclePattern to duplicate</param>
        public LineCirclePattern(LineCirclePattern CopyTarget)
        {
            Count                  = CopyTarget.Count;
            LineCount              = CopyTarget.LineCount;
            LineScaleMultiplier    = CopyTarget.LineScaleMultiplier;
            LineRotationMultiplier = CopyTarget.LineRotationMultiplier;
            SphericalCoordinates   = CopyTarget.SphericalCoordinates;
            LineInterval           = CopyTarget.LineInterval;
            AutoScaleLines         = CopyTarget.AutoScaleLines;

            TimeStep   = CopyTarget.TimeStep;
            TimeSpan   = CopyTarget.TimeSpan;
            TimeOffset = CopyTarget.TimeOffset;

            DrawLines = CopyTarget.DrawLines;
            DrawFill  = CopyTarget.DrawFill;
            LineColor = CopyTarget.LineColor;
            FillColor = CopyTarget.FillColor;

            SrcMode = CopyTarget.SrcMode;
            DstMode = CopyTarget.DstMode;

            Oscillators = new Oscillator[CopyTarget.Oscillators.Length];
            for (int i = 0; i < Oscillators.Length; i++)
            {
                Oscillators[i] = new Oscillator(CopyTarget.Oscillators[i]);
            }

            TimeToZ = CopyTarget.TimeToZ;
            ZFade   = CopyTarget.ZFade;
        }
        /// <summary>
        /// Initialises a new LineCirclePattern which is the interpolation of two other LineCirclePatterns
        /// </summary>
        /// <param name="PatternA"></param>
        /// <param name="PatternB"></param>
        /// <param name="LerpFactor"></param>
        public LineCirclePattern(LineCirclePattern PatternA, LineCirclePattern PatternB, float LerpFactor)
        {
            Count                  = Mathf.RoundToInt(Mathf.Lerp(PatternA.Count, PatternB.Count, LerpFactor));
            LineCount              = Mathf.RoundToInt(Mathf.Lerp(PatternA.LineCount, PatternB.LineCount, LerpFactor));
            LineScaleMultiplier    = Mathf.Lerp(PatternA.LineScaleMultiplier, PatternB.LineScaleMultiplier, LerpFactor);
            LineRotationMultiplier = Mathf.Lerp(PatternA.LineRotationMultiplier, PatternB.LineRotationMultiplier, LerpFactor);
            SphericalCoordinates   = LerpFactor < 0.5f ? PatternA.SphericalCoordinates : PatternB.SphericalCoordinates;
            LineInterval           = Mathf.RoundToInt(Mathf.Lerp(PatternA.LineInterval, PatternB.LineInterval, LerpFactor));
            AutoScaleLines         = LerpFactor < 0.5f ? PatternA.AutoScaleLines : PatternB.AutoScaleLines;

            TimeStep   = Mathf.Lerp(PatternA.TimeStep, PatternB.TimeStep, LerpFactor);
            TimeSpan   = Mathf.Lerp(PatternA.TimeSpan, PatternB.TimeSpan, LerpFactor);
            TimeOffset = Mathf.Lerp(PatternA.TimeOffset, PatternB.TimeOffset, LerpFactor);

            DrawLines = LerpFactor < 0.5f ? PatternA.DrawLines : PatternB.DrawLines;
            DrawFill  = LerpFactor < 0.5f ? PatternA.DrawFill : PatternB.DrawFill;
            LineColor = Color.Lerp(PatternA.LineColor, PatternB.LineColor, LerpFactor);
            FillColor = Color.Lerp(PatternA.FillColor, PatternB.FillColor, LerpFactor);

            SrcMode = LerpFactor < 0.5f ? PatternA.SrcMode : PatternB.SrcMode;
            DstMode = LerpFactor < 0.5f ? PatternA.DstMode : PatternB.DstMode;

            Oscillators = new Oscillator[PatternA.Oscillators.Length];
            for (int i = 0; i < Oscillators.Length; i++)
            {
                Oscillators[i] = new Oscillator(PatternA.Oscillators[i], PatternB.Oscillators[i], LerpFactor);
            }

            TimeToZ = LerpFactor < 0.5f ? PatternA.TimeToZ : PatternB.TimeToZ;
            ZFade   = LerpFactor < 0.5f ? PatternA.ZFade : PatternB.ZFade;
        }
Exemplo n.º 3
0
        /// <summary>
        /// Reusable code snippet to shuffle a given oscillator (used for angular oscillators that can be a sawtooth wave)
        /// </summary>
        /// <param name="index">Index of oscillator shuffler to target</param>
        /// <param name="pattern">Pattern to be mutated by this shuffle operation</param>
        private void RollShufflerLoopable(int index, ref LineCirclePattern pattern)
        {
            //check to see if we should be a sawtooth
            pattern.Oscillators[index].Type = Roll(SawtoothChance)
                                ? OscillatorShape.Sawtooth
                                : OscillatorShape.Sine;

            //do normal stuff
            RollShuffler(index, ref pattern);

            //if sawtooth, make sure we go from 0 to 2 pi (so one full revolution)
            if (pattern.Oscillators[index].Type != OscillatorShape.Sawtooth)
            {
                return;
            }

            OscillatorShuffler.EnforceTwoPi(ref pattern.Oscillators[index]);

            //Once we've done all this enforcing, we need to do one more pass on ensuring that the frequency isn't too high
            if (Shufflers[index].OverrideFrequency)
            {
                Shufflers[index].RandomiseFrequency(ref pattern.Oscillators[index]);
            }
            else
            {
                OscillatorShuffler.RandomiseFrequency(ref pattern.Oscillators[index],
                                                      GlobalMinimumFrequency, GlobalMaximumFrequency);
            }
            Shufflers[index].EnforceMaxFrequency(ref pattern.Oscillators[index]);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Reusable code snippet to shuffle a given oscillator
        /// </summary>
        /// <param name="index">Index of oscillator shuffler to target</param>
        /// <param name="pattern">Pattern to be mutated by this shuffle operation</param>
        private void RollShuffler(int index, ref LineCirclePattern pattern)
        {
            //check whether we should shuffle at all
            if (!Roll(GlobalShuffleChance))
            {
                return;
            }

            //check whether we should freeze
            if (Roll(FreezeChance))
            {
                Shufflers[index].RandomiseCenter(ref pattern.Oscillators[index]);
                pattern.Oscillators[index].Amplitude = 0;
            }
            else
            {
                Shufflers[index].RandomiseRange(ref pattern.Oscillators[index]);
                OscillatorShuffler.RandomisePhase(ref pattern.Oscillators[index]);

                //check whether we should use override frequency values
                if (Shufflers[index].OverrideFrequency)
                {
                    Shufflers[index].RandomiseFrequency(ref pattern.Oscillators[index]);
                }
                else
                {
                    OscillatorShuffler.RandomiseFrequency(ref pattern.Oscillators[index],
                                                          GlobalMinimumFrequency, GlobalMaximumFrequency);
                }
            }

            Shufflers[index].EnforceMaxFrequency(ref pattern.Oscillators[index]);
        }
        public void SetPattern(LineCirclePattern pattern)
        {
            Pattern = pattern;
            ResetBounds();
            _maxPossibleBounds = Pattern.GetMaxPossibleBounds();

            OnPatternChanged?.Invoke(this, new EventArgs());
            if (pattern.Count != _setCount)
            {
                SetCount(pattern.Count);
            }
        }
        /// <summary>
        /// Assign all Pattern values to the GPU to update its simulation
        /// </summary>
        /// <param name="pattern">The LineCirclePattern to push to the GPU</param>
        private void SetComputeValues(LineCirclePattern pattern)
        {
            //each of these has _type, _center, _amplitude, _period and _phase appended
            //just saves me writing tons of code!
            var prefixes = new[]
            {
                "circlePos_x", "circlePos_y", "circlePos_z",
                "circleRot_x", "circleRot_y", "circleRot_z",
                "circleRad",
                "lineRot_x", "lineRot_y", "lineRot_z",
                "lineLength",
                "colorRange", "colorOffset"
            };

            for (var i = 0; i < pattern.Oscillators.Length; i++)
            {
                _snapshotCompute.SetInt(prefixes[i] + "_type", (int)pattern.Oscillators[i].Type);
                _snapshotCompute.SetFloat(prefixes[i] + "_center", pattern.Oscillators[i].Center);
                _snapshotCompute.SetFloat(prefixes[i] + "_amplitude", pattern.Oscillators[i].Amplitude);
                _snapshotCompute.SetFloat(prefixes[i] + "_period", pattern.Oscillators[i].Period);
                _snapshotCompute.SetFloat(prefixes[i] + "_phase", pattern.Oscillators[i].Phase);
            }

            _snapshotCompute.SetInt("_BufferCount", pattern.Count);
            _snapshotCompute.SetFloat("_TimeStep", pattern.TimeStep);
            _snapshotCompute.SetFloat("_TimeOffset", pattern.TimeOffset);
            _snapshotCompute.SetInt("_TimeSpan", (int)(pattern.TimeSpan / pattern.TimeStep));
            _snapshotCompute.SetInt("_AutoScaleLines", pattern.AutoScaleLines ? 1 : 0);
            _snapshotCompute.SetInt("_IntervalOffset", (int)(pattern.TimeOffset / pattern.TimeStep));
            _snapshotCompute.SetInt("_LineInterval", pattern.LineInterval);

            _vertexCompute.SetInt("_LineCount", pattern.LineCount);
            _vertexCompute.SetFloat("_TimeSpan", pattern.TimeSpan);
            _vertexCompute.SetInt("_Spherical", pattern.SphericalCoordinates ? 1 : 0);
            _vertexCompute.SetInt("_FirstIndex", (int)(pattern.TimeSpan / pattern.TimeStep));
            _vertexCompute.SetFloat("_LineScaleMultiplier", pattern.LineScaleMultiplier);
            _vertexCompute.SetFloat("_LineRotationMultiplier", pattern.LineRotationMultiplier);

            _lineMat.SetInt("_LineCount", pattern.LineCount);
            _lineMat.SetFloat("_Alpha", pattern.LineColor.a * AlphaMultiplier);
            _lineMat.SetMatrix("_LocalToWorld", transform.localToWorldMatrix);
            _lineMat.SetMatrix("_WorldToLocal", transform.worldToLocalMatrix);
            _lineMat.SetFloat("_TimeToZ", pattern.TimeToZ);
            _lineMat.SetFloat("_ZFade", pattern.ZFade);

            _fillMat.SetInt("_LineCount", pattern.LineCount);
            _fillMat.SetFloat("_Alpha", pattern.FillColor.a * AlphaMultiplier);
            _fillMat.SetMatrix("_LocalToWorld", transform.localToWorldMatrix);
            _fillMat.SetMatrix("_WorldToLocal", transform.worldToLocalMatrix);
            _fillMat.SetFloat("_TimeToZ", pattern.TimeToZ);
            _fillMat.SetFloat("_ZFade", pattern.ZFade);


//		_lineMat.SetInt("_Spherical", pattern.SphericalCoordinates ? 1 : 0);
//		_lineMat.SetInt("_LineCount", pattern.LineCount);
//		_lineMat.SetColor("_Color", pattern.LineColor);
//        _lineMat.SetInt("_LineInterval", pattern.LineInterval);
//        _lineMat.SetInt("_IntervalOffset", (int)(pattern.TimeOffset / pattern.TimeStep));
//        _lineMat.SetInt("_TimeSpan", (int)(pattern.TimeSpan / pattern.TimeStep));
//
//		_lineMat.SetVector("_Position", new Vector4(transform.position.x, transform.position.y, transform.position.z, 0));
//		_lineMat.SetVector("_Rotation", new Vector4(transform.eulerAngles.x * Mathf.Deg2Rad, transform.eulerAngles.y * Mathf.Deg2Rad, transform.eulerAngles.z * Mathf.Deg2Rad, 0));
//		_lineMat.SetVector("_Scale", new Vector4(transform.localScale.x, transform.localScale.y, transform.localScale.z, 0));
//
//		_lineMat.SetInt("_SrcMode", (int)pattern.SrcMode);
//		_lineMat.SetInt("_DstMode", (int)pattern.DstMode);
//
//		_fillMat.SetInt("_Spherical", pattern.SphericalCoordinates ? 1 : 0);
//		_fillMat.SetInt("_LineCount", pattern.LineCount);
//		_fillMat.SetColor("_Color", pattern.FillColor);
//        _fillMat.SetInt("_TimeSpan", (int)(pattern.TimeSpan / pattern.TimeStep));
//
//		_fillMat.SetVector("_Position", new Vector4(transform.position.x, transform.position.y, transform.position.z, 0));
//		_fillMat.SetVector("_Rotation", new Vector4(transform.eulerAngles.x * Mathf.Deg2Rad, transform.eulerAngles.y * Mathf.Deg2Rad, transform.eulerAngles.z * Mathf.Deg2Rad, 0));
//		_fillMat.SetVector("_Scale", new Vector4(transform.localScale.x, transform.localScale.y, transform.localScale.z, 0));
//
//		_fillMat.SetInt("_SrcMode", (int)pattern.SrcMode);
//		_fillMat.SetInt("_DstMode", (int)pattern.DstMode);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Generates a new LineCircle pattern, shuffling parameters of a previous pattern
        /// </summary>
        /// <param name="previousPattern">Previous pattern to use as shuffle base</param>
        /// <returns>A shuffled version of the previous pattern</returns>
        public LineCirclePattern GenerateNewPattern(LineCirclePattern previousPattern)
        {
            var newPattern = new LineCirclePattern(previousPattern);

            //first we decide whether we should be spherical or cartesian
            if (Roll(SphericalSwapChance))
            {
                newPattern.SphericalCoordinates = true;

                //Shuffle X (aka radius)
                RollShuffler(ID.CirclePosX, ref newPattern);

                //Shuffle Y (aka theta) if in 3D mode
                if (!RestrictThirdDimension)
                {
                    RollShufflerLoopable(ID.CirclePosY, ref newPattern);
                }
                else
                {
                    //reset to make sure everything is in 2D
                    var savedName = newPattern.Oscillators[ID.CirclePosY].Name;
                    newPattern.Oscillators[ID.CirclePosY] = new Oscillator("CirclePosY", 0, 0, 0, 1, 0)
                    {
                        Name = savedName
                    };
                }

                //Shuffle Z (aka phi)
                RollShufflerLoopable(ID.CirclePosZ, ref newPattern);
            }
            else
            {
                newPattern.SphericalCoordinates = false;

                //Shuffle X and Y
                RollShuffler(ID.CirclePosX, ref newPattern);
                RollShuffler(ID.CirclePosY, ref newPattern);

                //Shuffle Z if in 3D mode
                if (!RestrictThirdDimension)
                {
                    RollShuffler(ID.CirclePosZ, ref newPattern);
                }
                else
                {
                    //reset to make sure everything is in 2D
                    var savedName = newPattern.Oscillators[ID.CirclePosZ].Name;
                    newPattern.Oscillators[ID.CirclePosZ] = new Oscillator("CirclePosZ", 0, 0, 0, 1, 0)
                    {
                        Name = savedName
                    };
                }
            }

            //Shuffle rotation about X and Y axes if in 3D mode
            if (!RestrictThirdDimension)
            {
                RollShufflerLoopable(ID.CircleRotX, ref newPattern);
                RollShufflerLoopable(ID.CircleRotY, ref newPattern);
            }
            else
            {
                //reset to make sure everything is in 2D
                var savedName = newPattern.Oscillators[ID.CircleRotX].Name;
                newPattern.Oscillators[ID.CircleRotX] = new Oscillator("CircleRotX", 0, 0, 0, 1, 0)
                {
                    Name = savedName
                };

                savedName = newPattern.Oscillators[ID.CircleRotY].Name;
                newPattern.Oscillators[ID.CircleRotY] = new Oscillator("CircleRotY", 0, 0, 0, 1, 0)
                {
                    Name = savedName
                };
            }

            //Shuffle rotation about Z axis
            RollShufflerLoopable(ID.CircleRotZ, ref newPattern);

            //Shuffle radius
            RollShuffler(ID.CircleRad, ref newPattern);

            //Shuffle offset about X and Y axes if in 3D mode
            if (!RestrictThirdDimension)
            {
                RollShufflerLoopable(ID.LineRotX, ref newPattern);
                RollShufflerLoopable(ID.LineRotY, ref newPattern);
            }
            else
            {
                //reset to make sure everything is in 2D
                var savedName = newPattern.Oscillators[ID.LineRotX].Name;
                newPattern.Oscillators[ID.LineRotX] = new Oscillator("LineRotX", 0, 0, 0, 1, 0)
                {
                    Name = savedName
                };

                savedName = newPattern.Oscillators[ID.LineRotY].Name;
                newPattern.Oscillators[ID.LineRotY] = new Oscillator("LineRotY", 0, 0, 0, 1, 0)
                {
                    Name = savedName
                };
            }

            //Shuffle offset about Z axis
            RollShufflerLoopable(ID.LineRotZ, ref newPattern);

            //custom - line length and colors

            //for line length we only randomise the total length
            if (Roll(GlobalShuffleChance))
            {
                newPattern.Oscillators[ID.LineLength] = new Oscillator("LineLength", 0,
                                                                       Random.Range(Shufflers[ID.LineLength].AbsoluteMin, Shufflers[ID.LineLength].AbsoluteMax), 0, 1, 0)
                {
                    Name = "Line Length"
                };
            }


            //we keep amplitude for both color values at zero because otherwise the pattern is just a rainbow mess
            //mmm...rainbow mess
            if (Roll(GlobalShuffleChance))
            {
                newPattern.Oscillators[ID.ColorRange].Amplitude = 0f;
                newPattern.Oscillators[ID.ColorRange].Center    = Random.Range(0f, 1f);
            }

            if (Roll(GlobalShuffleChance))
            {
                newPattern.Oscillators[ID.ColorOffset].Amplitude = 0f;
                newPattern.Oscillators[ID.ColorOffset].Center    = Random.Range(0f, 1f);
            }

            //Shuffle line count
            if (Roll(GlobalShuffleChance))
            {
                newPattern.LineCount = Random.Range(3, MaxLineCount + 1);
            }

            return(newPattern);
        }