ace/Source/ACE.Server/Physics/Particles/Particle.cs
Mag-nus 12c138cb80
ThreadSafeRandom Cleanup (#2428)
This fixes the namespace for ThreadSafeRandom, from ACE -> ACE.Common.

It also adds better Summary descriptions.

The rest of the file changes are simply adding ACE.Common references.

This is mainly commenting and namespace preparation for adding a non-thread safe random class, in effort to reduce lock contention.
2019-11-21 07:22:20 -06:00

182 lines
6.7 KiB
C#

using System;
using System.Numerics;
using ACE.Common;
using ACE.Entity.Enum;
using ACE.Server.Physics.Animation;
using ACE.Server.Physics.Common;
namespace ACE.Server.Physics
{
public class Particle
{
// union?
public double Birthtime { get => LastUpdateTime; set => LastUpdateTime = value; }
public double LastUpdateTime;
public double Lifespan;
public double Lifetime;
public AFrame StartFrame;
public Vector3 Offset;
public Vector3 A;
public Vector3 B;
public Vector3 C;
public float StartScale;
public float FinalScale;
public float StartTrans;
public float FinalTrans;
public PhysicsObj Owner;
public bool Init(ParticleEmitterInfo info, PhysicsObj parent, int partIdx, AFrame pFrame, PhysicsPart part, Vector3 _offset, bool persistent, Vector3 a, Vector3 b, Vector3 c)
{
var currentTime = PhysicsTimer.CurrentTime;
LastUpdateTime = currentTime;
Birthtime = currentTime;
Lifetime = 0;
Lifespan = info.GetRandomLifespan();
if (partIdx == -1)
StartFrame = new AFrame(parent.Position.Frame);
else
StartFrame = new AFrame(parent.PartArray.Parts[partIdx].Pos.Frame);
Offset = StartFrame.LocalToGlobalVec(pFrame.Origin + _offset);
switch (info.ParticleType)
{
case ParticleType.Still:
break;
case ParticleType.LocalVelocity:
A = StartFrame.LocalToGlobalVec(a);
break;
case ParticleType.ParabolicLVGA:
B = StartFrame.LocalToGlobalVec(b);
break;
case ParticleType.ParabolicLVGAGR:
C = StartFrame.LocalToGlobalVec(c);
break;
case ParticleType.Swarm:
A = StartFrame.LocalToGlobalVec(a);
B = b;
C = c;
break;
case ParticleType.Explode:
A = a;
B = b;
var ra = ThreadSafeRandom.Next(-(float)Math.PI, (float)Math.PI);
var po = ThreadSafeRandom.Next(-(float)Math.PI, (float)Math.PI);
var rb = Math.Cos(po);
C.X = (float)(Math.Cos(ra) * c.X * rb);
C.Y = (float)(Math.Sin(ra) * c.Y * rb);
C.Z = (float)(Math.Sin(po) * c.Z * rb);
if (Vec.NormalizeCheckSmall(ref C))
C = Vector3.Zero;
break;
case ParticleType.Implode:
A = a;
B = b;
Offset *= c;
C = Offset;
break;
case ParticleType.ParabolicLVLA:
A = StartFrame.LocalToGlobalVec(a);
B = StartFrame.LocalToGlobalVec(b);
break;
case ParticleType.ParabolicLVLALR:
C = StartFrame.LocalToGlobalVec(c);
break;
case ParticleType.ParabolicGVGA:
B = b;
break;
case ParticleType.ParabolicGVGAGR:
C = c;
break;
case ParticleType.GlobalVelocity:
A = a;
break;
default:
A = a;
B = b;
C = c;
break;
}
StartScale = info.StartScale;
FinalScale = info.FinalScale;
StartTrans = info.StartTrans;
FinalTrans = info.FinalTrans;
part.GfxObjScale = new Vector3(StartScale, StartScale, StartScale);
part.SetTranslucency(StartTrans);
Update(info.ParticleType, persistent, part, pFrame);
return false;
}
public void Update(ParticleType particleType, bool persistent, PhysicsPart part, AFrame parent)
{
var currentTime = PhysicsTimer.CurrentTime;
var elapsedTime = currentTime - LastUpdateTime;
if (persistent)
{
Lifetime += elapsedTime;
LastUpdateTime = currentTime;
}
else
Lifetime = elapsedTime;
var lifetime = (float)Lifetime;
switch (particleType)
{
case ParticleType.Still:
part.Pos.Frame.Origin = parent.Origin + Offset;
break;
case ParticleType.LocalVelocity:
case ParticleType.GlobalVelocity:
part.Pos.Frame.Origin = (lifetime * A) + parent.Origin + Offset;
break;
case ParticleType.ParabolicLVGA:
case ParticleType.ParabolicLVLA:
case ParticleType.ParabolicGVGA:
part.Pos.Frame.Origin += (lifetime * lifetime * B / 2.0f) + (lifetime * A) + Offset;
break;
case ParticleType.ParabolicLVGAGR:
case ParticleType.ParabolicLVLALR:
case ParticleType.ParabolicGVGAGR:
part.Pos.Frame = new AFrame(parent);
part.Pos.Frame.Origin += (lifetime * lifetime * B / 2.0f) + (lifetime * A) + Offset;
part.Pos.Frame.Rotate(lifetime * C);
break;
case ParticleType.Swarm:
var swarm = (lifetime * A) + C + parent.Origin + Offset;
part.Pos.Frame.Origin.X = (float)Math.Cos(lifetime * B.X) + swarm.X;
part.Pos.Frame.Origin.Y = (float)Math.Sin(lifetime * B.Y) + swarm.Y;
part.Pos.Frame.Origin.Z = (float)Math.Cos(lifetime * B.Z) + swarm.Z;
break;
case ParticleType.Explode:
part.Pos.Frame.Origin = (lifetime * B + C * A.X) * lifetime + Offset + parent.Origin;
break;
case ParticleType.Implode:
part.Pos.Frame.Origin = ((float)Math.Cos(A.X * lifetime) * C) + (lifetime * lifetime * B) + parent.Origin + Offset;
break;
}
var interval = Math.Min(Lifetime / Lifespan, 1.0f);
var currentScale = StartScale + (FinalScale - StartScale) * interval;
var currentTrans = StartTrans + (FinalTrans - StartTrans) * interval;
part.GfxObjScale = new Vector3((float)currentScale);
part.SetTranslucency((float)currentTrans);
}
}
}