Redo husk particle physics using LerpQuadratic.

This commit is contained in:
Paul Chote
2013-07-07 13:13:36 +12:00
parent 5976913c73
commit 4fbed810dc

View File

@@ -22,14 +22,20 @@ namespace OpenRA.Mods.RA
[Desc("Initial position relative to body")] [Desc("Initial position relative to body")]
public readonly WVec Offset = WVec.Zero; public readonly WVec Offset = WVec.Zero;
[Desc("Minimum distance to throw the particle")]
public readonly WRange MinThrowRange = new WRange(256);
[Desc("Maximum distance to throw the particle")] [Desc("Maximum distance to throw the particle")]
public readonly WRange ThrowRange = new WRange(768); public readonly WRange MaxThrowRange = new WRange(768);
[Desc("Maximum height to throw the particle")] [Desc("Minimum angle to throw the particle")]
public readonly WRange ThrowHeight = new WRange(256); public readonly WAngle MinThrowAngle = WAngle.FromDegrees(30);
[Desc("Number of ticks to animate")] [Desc("Maximum angle to throw the particle")]
public readonly int Length = 15; public readonly WAngle MaxThrowAngle = WAngle.FromDegrees(60);
[Desc("Speed to throw the particle (horizontal WPos/tick)")]
public readonly int Velocity = 75;
[Desc("Maximum rotation rate")] [Desc("Maximum rotation rate")]
public readonly float ROT = 15; public readonly float ROT = 15;
@@ -39,19 +45,19 @@ namespace OpenRA.Mods.RA
class ThrowsParticle : ITick class ThrowsParticle : ITick
{ {
ThrowsParticleInfo info;
WVec pos; WVec pos;
WVec initialPos; WVec initialPos;
WVec finalPos; WVec finalPos;
WAngle angle;
int tick = 0; int tick = 0;
int length;
float facing; float facing;
float rotation; float rotation;
public ThrowsParticle(ActorInitializer init, ThrowsParticleInfo info) public ThrowsParticle(ActorInitializer init, ThrowsParticleInfo info)
{ {
this.info = info;
var self = init.self; var self = init.self;
var rs = self.Trait<RenderSimple>(); var rs = self.Trait<RenderSimple>();
var body = self.Trait<IBodyOrientation>(); var body = self.Trait<IBodyOrientation>();
@@ -62,10 +68,12 @@ namespace OpenRA.Mods.RA
// Calculate final position // Calculate final position
var throwRotation = WRot.FromFacing(Game.CosmeticRandom.Next(1024)); var throwRotation = WRot.FromFacing(Game.CosmeticRandom.Next(1024));
var throwOffset = new WVec((int)(Game.CosmeticRandom.Gauss1D(1)*info.ThrowRange.Range), 0, 0).Rotate(throwRotation); var throwDistance = Game.CosmeticRandom.Next(info.MinThrowRange.Range, info.MaxThrowRange.Range);
initialPos = pos = info.Offset.Rotate(body.QuantizeOrientation(self, WRot.FromFacing(bodyFacing))); initialPos = pos = info.Offset.Rotate(body.QuantizeOrientation(self, WRot.FromFacing(bodyFacing)));
finalPos = initialPos + throwOffset; finalPos = initialPos + new WVec(throwDistance, 0, 0).Rotate(throwRotation);
angle = new WAngle(Game.CosmeticRandom.Next(info.MinThrowAngle.Angle, info.MaxThrowAngle.Angle));
length = (finalPos - initialPos).Length / info.Velocity;
// Facing rotation // Facing rotation
rotation = Game.CosmeticRandom.Gauss1D(2) * info.ROT; rotation = Game.CosmeticRandom.Gauss1D(2) * info.ROT;
@@ -77,15 +85,10 @@ namespace OpenRA.Mods.RA
public void Tick(Actor self) public void Tick(Actor self)
{ {
if (tick == info.Length) if (tick == length)
return; return;
tick++;
// Lerp position horizontally and height along a sinusoid using a cubic ease pos = WVec.LerpQuadratic(initialPos, finalPos, angle, tick++, length);
var t = (tick*tick*tick / (info.Length*info.Length) - 3*tick*tick / info.Length + 3*tick);
var tp = WVec.Lerp(initialPos, finalPos, t, info.Length);
var th = new WAngle(512*(info.Length - t) / info.Length).Sin()*info.ThrowHeight.Range / 1024;
pos = new WVec(tp.X, tp.Y, th);
// Spin the particle // Spin the particle
facing += rotation; facing += rotation;