This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| 4rpl:commands:signalgenerator [2019/04/21 20:04] – external edit 127.0.0.1 | 4rpl:commands:signalgenerator [2025/09/03 16:43] (current) – [Sine wave in any direction without gaps] kalli | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ~~NOTOC~~ | + | < |
| + | < | ||
| ====== SignalGenerator ====== | ====== SignalGenerator ====== | ||
| - | SignalGenerator(< | + | SignalGenerator(< |
| ===== Description ===== | ===== Description ===== | ||
| Computes the value for a given signal waveform and pushes it to the stack. | Computes the value for a given signal waveform and pushes it to the stack. | ||
| - | A function to derive the y-coordinate for a given x-co-ordiante | + | A function to derive the y-coordinate for a given x-coordinate |
| - | Arguments and type in order: 1: Integer. the X coordinate in the waveform | + | Useful to animate an object or to produce a pattern over time. For instance, could be used to vary the strength of an emitter over time, or to " |
| - | 2: Float. Frequency of the waveform \\\ | + | |
| - | 3: Float. PhaseShift | + | |
| - | 4: Bool. invert the waveform \ 5: Integer. Signal type (0 to 6 in types, below) \ | + | |
| - | Signal types. 0 = NONE < | + | Arguments and type in order: |
| + | * time: (float) Current step in the waveform. For a wave duration of 10.0, a step of 2.5 is a quarter of the way into a pattern. | ||
| + | * frequency: (float) The frequency dictates the duration of each repeating pattern. A duration of 10.0 must set the frequency to 0.1 (1/10.0) | ||
| + | * phaseShift: (float) A starting offset, between 0 and 1, where 0 will start the pattern at the beginning, and 1 will start it at the end. For sine wave, 0.25 will begin the wave at the peak, and 0.75 will begin at the valley. | ||
| + | * invert: (0/1) inverts the waveform | ||
| + | * signalType: (0 to 6) | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| - | ===== Examples | + | The resulting variable sigValue contains a float value between -1 and 1 which represents the current state of the wave at the provided step (time) given its provided frequency and other factors. |
| + | |||
| + | ===== Example | ||
| + | To create a sine wave that should start at its peak and run for 80 frames until it repeats, we should set the frequency to (1.0/80.0), phase shift to 0.25, start the time value at 0 and add 1 to it every frame. | ||
| + | |||
| + | Play the following example in the editor console to spawn a continuous stream of creeper using the sine wave at the bottom of the map. | ||
| + | <code 4RPL> | ||
| + | $time:0 | ||
| + | $duration: | ||
| + | $phaseShift: | ||
| + | $invert:0 | ||
| + | $signalType: | ||
| + | |||
| + | SignalGenerator(< | ||
| + | <-time 1 add ->time | ||
| + | |||
| + | #Let's use the result to spawn some creeper in a range of cells: | ||
| + | AddCreeper(< | ||
| + | |||
| + | :Once | ||
| + | 1.0 < | ||
| + | | ||
| + | </ | ||
| + | |||
| + | ===== Patterns ===== | ||
| + | [{{cw4_signalgenerator_1.png|1 - SINE, Pattern repeated every 60 cells}}] \\ | ||
| + | [{{cw4_signalgenerator_2.png|2 - SQUARE, Pattern repeated every 60 cells}}] | ||
| + | [{{cw4_signalgenerator_3.png|3 - TRIANGLE, Pattern repeated every 60 cells}}] \\ | ||
| + | [{{cw4_signalgenerator_4.png|4 - SAW-TOOTH, Pattern repeated every 60 cells}}] | ||
| + | [{{cw4_signalgenerator_5.png|5 - RANDOM, Pattern repeated every 5 cells}}] \\ | ||
| + | |||
| + | ===== Extra Notes ===== | ||
| + | This is how each wave is produced in the game's source code: | ||
| + | ==== Sine wave function ==== | ||
| + | <code C#> | ||
| + | float t = frequency * time + phase; | ||
| + | value = (float)Mathf.Sin(2f * Mathf.PI * t); | ||
| + | </ | ||
| + | ==== Square wave function ==== | ||
| + | <code c#> | ||
| + | value = Mathf.Sign(Mathf.Sin(2f * Mathf.PI * t)); | ||
| + | </ | ||
| + | ==== For triangle wave function ==== | ||
| + | <code c#> | ||
| + | value = 1f - 4f * (float)Mathf.Abs(Mathf.Round(t - 0.25f) - (t - 0.25f)); | ||
| + | </ | ||
| + | ==== Saw-tooth wave function ==== | ||
| + | <code c#> | ||
| + | value = 2f * (t - (float)Mathf.Floor(t + 0.5f)); | ||
| + | </ | ||
| + | ==== Random wave function ==== | ||
| + | The function will output the same number for a given interval. | ||
| + | |||
| + | <code c#> | ||
| + | float interval = 1 / frequency; | ||
| + | int slot = (int)(time / interval) ; | ||
| + | slot = (slot * 1431655781) + (slot * 1183186591) + (slot * 622729787) + (slot * 338294347); | ||
| + | if (slot < 0) slot = -slot; | ||
| + | value = (float)GameSpace.instance.RandDoubleInput(randSeed + slot)*2-1; | ||
| + | </ | ||
| + | |||
| + | ===== Extra examples ===== | ||
| + | ==== Sine Wave Creeper on Terrain | ||
| <code 4rpl> | <code 4rpl> | ||
| - | # On a map with terrain of 200 in X direction and at least 150 in Z direction (3D coordinates) | + | # On a map with terrain of 200 in X direction and at least 150 in Z direction (3D coordinates) |
| # generate a sine wave of creeper across the map. | # generate a sine wave of creeper across the map. | ||
| - | 200 -> | + | # On a map with terrain of 200 in X direction and at least 150 in Z direction (3D coordinates) |
| - | | + | # generate a sine wave of creeper across the map. |
| - | 0 | + | |
| + | 180 -> | ||
| + | 1 < | ||
| + | 0 -> | ||
| false ->invert | false ->invert | ||
| - | 1 | + | 1 -> |
| - | do (< | + | do (< |
| - | SignalGenerator(I < | + | SignalGenerator(I < |
| - | | + | |
| - | | + | |
| - | SetCreeper(I 75 add (< | + | SetCreeper(I 75 add(< |
| loop | loop | ||
| </ | </ | ||
| + | The above command generated this sinusoidal creeper pattern on a map | ||
| + | |||
| + | {{sine_creeper.png? | ||
| + | |||
| + | ==== Make a Unit Move or " | ||
| + | |||
| + | <code 4RPL> | ||
| + | # Oscillate | ||
| + | $UID:1 | ||
| + | |||
| + | GetUnitMoveCell(< | ||
| + | if (< | ||
| + | SignalGenerator(< | ||
| + | <-time 1 + ->time | ||
| + | < | ||
| + | GetUnitPosition(< | ||
| + | GetExactTerrain(< | ||
| + | SetUnitPosition(< | ||
| + | # SetObjPosition(2 | ||
| + | else | ||
| + | 0 ->time | ||
| + | endIf | ||
| + | |||
| + | :Once | ||
| + | # Parameters for SignalGenerator | ||
| + | 1.0 180 / -> | ||
| + | 0.0 -> | ||
| + | false ->invert # Invert the waveform | ||
| + | 1 -> | ||
| + | 0.5 -> | ||
| + | </ | ||
| + | |||
| + | ==== Sine wave in any direction without gaps ==== | ||
| + | {{ : | ||
| + | |||
| + | <code 4RPL> | ||
| + | 30 30 v2 165 91 v2 15 4.5 0 @getSinusoidCells ->list | ||
| + | <-list 0 do | ||
| + | < | ||
| + | loop | ||
| + | |||
| + | : | ||
| + | ->cell1 | ||
| + | ->cell0 | ||
| + | <-cell1 <-cell0 sub ->dir | ||
| + | <-dir.0 abs <-dir.1 abs max ->length | ||
| + | < | ||
| + | <-cell0 | ||
| + | < | ||
| + | dup <-dirL add | ||
| + | loop | ||
| + | < | ||
| + | |||
| + | : | ||
| + | ->shift # FLOAT between 0 and 1 that will shift the signal from signalgenerator. | ||
| + | -> | ||
| + | ->ampl | ||
| + | ->cell1 | ||
| + | ->cell0 | ||
| + | |||
| + | clearstack | ||
| + | <-cell0 <-cell1 @getSingleLineCells dup -> | ||
| + | < | ||
| + | |||
| + | <-cell1 <-cell0 sub normalize ->dir | ||
| + | <-dir.1 <-dir.0 neg v2 <-ampl mul ->dirP | ||
| + | |||
| + | <-cell0 | ||
| + | < | ||
| + | i <-freq <-shift 0 1 signalgenerator <-dirP mul < | ||
| + | loop | ||
| + | list | ||
| + | |||
| + | </ | ||
| + | |||
| + | < | ||