-
Notifications
You must be signed in to change notification settings - Fork 28
Feature/shake #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Ne1gh-RR
wants to merge
3
commits into
develop
Choose a base branch
from
feature/shake
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Feature/shake #32
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| ///////////////////////////////////////////////////////////////////////////////////////////// | ||
| /// Original Unity version made by Ivan Pensionerov https://github.com/gasgiant/Camera-Shake | ||
| /// Ported and improved by Minkberry. | ||
| ///////////////////////////////////////////////////////////////////////////////////////////// | ||
| using Monofoxe.Engine.Shake.Utils; | ||
| using Microsoft.Xna.Framework; | ||
| using Monofoxe.Engine.Utils; | ||
|
|
||
| namespace Monofoxe.Engine.Shake | ||
| { | ||
| public class BounceShake : IShake | ||
| { | ||
| private readonly Params _pars; | ||
| private readonly Easing _moveCurve = Easing.EaseInOutCubic; | ||
| private readonly Vector2? _sourcePosition = null; | ||
|
|
||
| private float _attenuation = 1; | ||
| private Displacement _direction; | ||
| private Displacement _previousWaypoint; | ||
| private Displacement _currentWaypoint; | ||
| private int _bounceIndex; | ||
| private float _t; | ||
|
|
||
|
|
||
| /// <summary> | ||
| /// Creates an instance of BounceShake. | ||
| /// </summary> | ||
| /// <param name="parameters">Parameters of the shake.</param> | ||
| /// <param name="sourcePosition">World position of the source of the shake.</param> | ||
| public BounceShake(Params parameters, Vector2? sourcePosition = null) | ||
| { | ||
| _sourcePosition = sourcePosition; | ||
| _pars = parameters; | ||
| Displacement rnd = Displacement.InsideUnitSpheres(); | ||
| _direction = Displacement.Scale(rnd, _pars.AxesMultiplier).Normalized; | ||
| } | ||
|
|
||
|
|
||
| /// <summary> | ||
| /// Creates an instance of BounceShake. | ||
| /// </summary> | ||
| /// <param name="parameters">Parameters of the shake.</param> | ||
| /// <param name="initialDirection">Initial direction of the shake motion.</param> | ||
| /// <param name="sourcePosition">World position of the source of the shake.</param> | ||
| public BounceShake(Params parameters, Displacement initialDirection, Vector2? sourcePosition = null) | ||
| { | ||
| _sourcePosition = sourcePosition; | ||
| _pars = parameters; | ||
| _direction = Displacement.Scale(initialDirection, _pars.AxesMultiplier).Normalized; | ||
| } | ||
|
|
||
|
|
||
| public Displacement CurrentDisplacement { get; private set; } | ||
| public bool IsFinished { get; private set; } | ||
|
|
||
|
|
||
| public void Initialize(Vector2 cameraPosition, float cameraRotation) | ||
| { | ||
| _attenuation = _sourcePosition == null ? | ||
| 1 : _pars.Attenuation.Attenuate(_sourcePosition.Value, cameraPosition); | ||
| _currentWaypoint = _attenuation * _direction.ScaledBy(_pars.PositionStrength, _pars.RotationStrength); | ||
| } | ||
|
|
||
|
|
||
| public void Update(TimeKeeper time, Vector2 cameraPosition, float cameraRotation) | ||
| { | ||
| if (_t < 1) | ||
| { | ||
| _t += (float)time.Time() * _pars.Frequence; | ||
| if (_pars.Frequence == 0) _t = 1; | ||
|
|
||
| CurrentDisplacement = Displacement.Lerp(_previousWaypoint, _currentWaypoint, | ||
| _moveCurve.GetEasing(_t)); | ||
| } | ||
| else | ||
| { | ||
| _t = 0; | ||
| CurrentDisplacement = _currentWaypoint; | ||
| _previousWaypoint = _currentWaypoint; | ||
| _bounceIndex++; | ||
| if (_bounceIndex > _pars.NumBounces) | ||
| { | ||
| IsFinished = true; | ||
| return; | ||
| } | ||
|
|
||
| Displacement rnd = Displacement.InsideUnitSpheres(); | ||
| _direction = -_direction | ||
| + _pars.Randomness * Displacement.Scale(rnd, _pars.AxesMultiplier).Normalized; | ||
| _direction = _direction.Normalized; | ||
| float decayValue = 1 - (float)_bounceIndex / _pars.NumBounces; | ||
| _currentWaypoint = decayValue * decayValue * _attenuation | ||
| * _direction.ScaledBy(_pars.PositionStrength, _pars.RotationStrength); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| public class Params | ||
| { | ||
| /// <summary> | ||
| /// Strength of the shake for positional axes. | ||
| /// </summary> | ||
| public float PositionStrength = 0.05f; | ||
|
|
||
| /// <summary> | ||
| /// Strength of the shake for rotational axes. | ||
| /// </summary> | ||
| public float RotationStrength = 0.1f; | ||
|
|
||
| /// <summary> | ||
| /// Preferred direction of shaking. | ||
| /// </summary> | ||
| public Displacement AxesMultiplier = new Displacement(Vector2.One, 0); | ||
|
|
||
| /// <summary> | ||
| /// Frequency of shaking. | ||
| /// </summary> | ||
| public float Frequence = 25; | ||
|
|
||
| /// <summary> | ||
| /// Number of vibrations before stop. | ||
| /// </summary> | ||
| public int NumBounces = 5; | ||
|
|
||
| /// <summary> | ||
| /// Randomness of motion. | ||
| /// </summary> | ||
| public float Randomness = 0.5f; | ||
|
|
||
| /// <summary> | ||
| /// How strength falls with distance from the shake source. | ||
| /// </summary> | ||
| public Attenuation Attenuation = new Attenuation(); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| ///////////////////////////////////////////////////////////////////////////////////////////// | ||
| /// Original Unity version made by Ivan Pensionerov https://github.com/gasgiant/Camera-Shake | ||
| /// Ported and improved by Minkberry. | ||
| ///////////////////////////////////////////////////////////////////////////////////////////// | ||
| using Monofoxe.Engine.Shake.Utils; | ||
| using Microsoft.Xna.Framework; | ||
| using Monofoxe.Engine.Utils; | ||
|
|
||
| namespace Monofoxe.Engine.Shake | ||
| { | ||
| public interface IShake | ||
| { | ||
| /// <summary> | ||
| /// Represents current position and rotation of the camera according to the shake. | ||
| /// </summary> | ||
| Displacement CurrentDisplacement { get; } | ||
|
|
||
| /// <summary> | ||
| /// Shake system will dispose the shake on the first frame when this is true. | ||
| /// </summary> | ||
| bool IsFinished { get; } | ||
|
|
||
| /// <summary> | ||
| /// Shaker calls this when the shake is added to the list of active shakes. | ||
| /// </summary> | ||
| void Initialize(Vector2 cameraPosition, float cameraRotation); | ||
|
|
||
| /// <summary> | ||
| /// Shaker calls this every frame on active shakes. | ||
| /// </summary> | ||
| void Update(TimeKeeper time, Vector2 cameraPosition, float cameraRotation); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| ///////////////////////////////////////////////////////////////////////////////////////////// | ||
| /// Original Unity version made by Ivan Pensionerov https://github.com/gasgiant/Camera-Shake | ||
| /// Ported and improved by Minkberry. | ||
| ///////////////////////////////////////////////////////////////////////////////////////////// | ||
| using Microsoft.Xna.Framework; | ||
| using Monofoxe.Engine.Utils; | ||
| using Monofoxe.Engine.Shake.Utils; | ||
|
|
||
| namespace Monofoxe.Engine.Shake | ||
| { | ||
| public class PerlinShake : IShake | ||
| { | ||
| private readonly Params _pars; | ||
| private readonly Envelope _envelope; | ||
|
|
||
| public IAmplitudeController AmplitudeController; | ||
|
|
||
| private Vector2[] _seeds; | ||
| private float _t; | ||
| private Vector2? _sourcePosition; | ||
| private float _norm; | ||
|
|
||
| /// <summary> | ||
| /// Creates an instance of PerlinShake. | ||
| /// </summary> | ||
| /// <param name="parameters">Parameters of the shake.</param> | ||
| /// <param name="maxAmplitude">Maximum amplitude of the shake.</param> | ||
| /// <param name="sourcePosition">World position of the source of the shake.</param> | ||
| /// <param name="manualStrengthControl">Pass true if you want to control amplitude manually.</param> | ||
| public PerlinShake( | ||
| Params parameters, | ||
| float maxAmplitude = 1, | ||
| Vector2? sourcePosition = null, | ||
| bool manualStrengthControl = false | ||
| ) | ||
| { | ||
| _pars = parameters; | ||
| _envelope = new Envelope(_pars.Envelope, maxAmplitude, | ||
| manualStrengthControl ? | ||
| Envelope.EnvelopeControlMode.Manual : Envelope.EnvelopeControlMode.Auto); | ||
| AmplitudeController = _envelope; | ||
| _sourcePosition = sourcePosition; | ||
| } | ||
|
|
||
|
|
||
| public Displacement CurrentDisplacement { get; private set; } | ||
| public bool IsFinished { get; private set; } | ||
|
|
||
|
|
||
| public void Initialize(Vector2 cameraPosition, float cameraRotation) | ||
| { | ||
| _seeds = new Vector2[_pars.NoiseModes.Length]; | ||
| _norm = 0; | ||
| for (int i = 0; i < _seeds.Length; i++) | ||
| { | ||
| _seeds[i] = RandomExt.Global.NextInsideUnitCircle() * 20; | ||
| _norm += _pars.NoiseModes[i].Amplitude; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| public void Update(TimeKeeper time, Vector2 cameraPosition, float cameraRotation) | ||
| { | ||
| if (_envelope.IsFinished) | ||
| { | ||
| IsFinished = true; | ||
| return; | ||
| } | ||
| _t += (float)time.Time(); | ||
| _envelope.Update((float)time.Time()); | ||
|
|
||
| Displacement disp = Displacement.Zero; | ||
| for (int i = 0; i < _pars.NoiseModes.Length; i++) | ||
| { | ||
| disp += _pars.NoiseModes[i].Amplitude / _norm | ||
| * SampleNoise(_seeds[i], _pars.NoiseModes[i].Frequence); | ||
| } | ||
|
|
||
| CurrentDisplacement = _envelope.Intensity * Displacement.Scale(disp, _pars.Strength); | ||
| if (_sourcePosition != null) | ||
| { | ||
| CurrentDisplacement *= _pars.Attenuation.Attenuate(_sourcePosition.Value, cameraPosition); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| private Displacement SampleNoise(Vector2 seed, float freq) | ||
| { | ||
| var position = new Vector2( | ||
| PerlinNoise.CarmodyNoise(seed.X + _t * freq, seed.Y), | ||
| PerlinNoise.CarmodyNoise(seed.X, seed.Y + _t * freq) | ||
| ); | ||
| position -= Vector2.One * 0.5f; | ||
|
|
||
| var rotation = PerlinNoise.CarmodyNoise(-seed.X - _t * freq, -seed.Y - _t * freq); | ||
| rotation -= 0.5f; | ||
|
|
||
| return new Displacement(position, rotation); | ||
| } | ||
|
|
||
|
|
||
| public class Params | ||
| { | ||
| /// <summary> | ||
| /// Strength of the shake for each axis. | ||
| /// </summary> | ||
| public Displacement Strength = new Displacement(Vector2.Zero, 0.8f); | ||
|
|
||
| /// <summary> | ||
| /// Layers of perlin noise with different frequencies. | ||
| /// </summary> | ||
| public NoiseMode[] NoiseModes = { new NoiseMode(12, 1) }; | ||
|
|
||
| /// <summary> | ||
| /// Strength over time. | ||
| /// </summary> | ||
| public Envelope.EnvelopeParams Envelope; | ||
|
|
||
| /// <summary> | ||
| /// How strength falls with distance from the shake source. | ||
| /// </summary> | ||
| public Attenuation Attenuation = new Attenuation(); | ||
| } | ||
|
|
||
|
|
||
| public struct NoiseMode | ||
| { | ||
| public NoiseMode(float freq, float amplitude) | ||
| { | ||
| Frequence = freq; | ||
| Amplitude = amplitude; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Frequency multiplier for the noise. | ||
| /// </summary> | ||
| public float Frequence; | ||
|
|
||
| /// <summary> | ||
| /// Amplitude of the mode. Ranges from 0 to 1. | ||
| /// </summary> | ||
| public float Amplitude; | ||
| } | ||
| } | ||
| } |
43 changes: 43 additions & 0 deletions
43
Monofoxe/Monofoxe.Engine/Shake/Presets/DirectionalShakePreset.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| ///////////////////////////////////////////////////////////////////////////////////////////// | ||
| /// Original Unity version made by Ivan Pensionerov https://github.com/gasgiant/Camera-Shake | ||
| /// Ported and improved by Minkberry. | ||
| ///////////////////////////////////////////////////////////////////////////////////////////// | ||
| using Monofoxe.Engine.Shake.Utils; | ||
| using Microsoft.Xna.Framework; | ||
|
|
||
| namespace Monofoxe.Engine.Shake.Presets | ||
| { | ||
| /// <summary> | ||
| /// Preset for bounce shake. | ||
| /// Suitable for short and snappy shakes. Moves camera in X and Y axes and rotates it in Z axis. | ||
| /// </summary> | ||
| public class DirectionalShakePreset : ShakePreset | ||
| { | ||
| public float PositionStrength = 10f; | ||
| public float RotationStrength = 0.02f; | ||
|
|
||
| public float Frequency = 25; | ||
|
|
||
| /// <summary> | ||
| /// Number of vibrations before stop. | ||
| /// </summary> | ||
| public int BounceCount = 5; | ||
|
|
||
| public Vector2 Direction = Vector2.UnitX; | ||
|
|
||
|
|
||
| public override IShake CreateShake() | ||
| { | ||
| var pars = new BounceShake.Params | ||
| { | ||
| PositionStrength = PositionStrength, | ||
| RotationStrength = RotationStrength, | ||
| Frequence = Frequency, | ||
| NumBounces = BounceCount, | ||
| Attenuation = Attenuation | ||
| }; | ||
|
|
||
| return new BounceShake(pars, new Displacement(Direction), UsesAttenuation ? (Vector2?)SourcePosition : null); | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove