Core/Movement: Spline code cleanup
Port From (https://github.com/TrinityCore/TrinityCore/commit/e02e8a474244c229cc34c4efb987e24b6dd417f5)
This commit is contained in:
@@ -63,7 +63,7 @@ namespace Game.Movement
|
|||||||
MoveSplineInit init = new(owner);
|
MoveSplineInit init = new(owner);
|
||||||
// Providing a starting vertex since the taxi paths do not provide such
|
// Providing a starting vertex since the taxi paths do not provide such
|
||||||
init.Path().Add(new Vector3(owner.GetPositionX(), owner.GetPositionY(), owner.GetPositionZ()));
|
init.Path().Add(new Vector3(owner.GetPositionX(), owner.GetPositionY(), owner.GetPositionZ()));
|
||||||
for (int i = (int)currentNodeId; i != (uint)end; ++i)
|
for (int i = (int)currentNodeId; i != end; ++i)
|
||||||
{
|
{
|
||||||
Vector3 vertice = new(_path[i].Loc.X, _path[i].Loc.Y, _path[i].Loc.Z);
|
Vector3 vertice = new(_path[i].Loc.X, _path[i].Loc.Y, _path[i].Loc.Z);
|
||||||
init.Path().Add(vertice);
|
init.Path().Add(vertice);
|
||||||
|
|||||||
@@ -77,17 +77,17 @@ namespace Game.Movement
|
|||||||
|
|
||||||
void InitSpline(MoveSplineInitArgs args)
|
void InitSpline(MoveSplineInitArgs args)
|
||||||
{
|
{
|
||||||
EvaluationMode[] modes = new EvaluationMode[2] { EvaluationMode.Linear, EvaluationMode.Catmullrom };
|
EvaluationMode mode = args.flags.IsSmooth() ? EvaluationMode.Catmullrom : EvaluationMode.Linear;
|
||||||
if (args.flags.HasFlag(MoveSplineFlagEnum.Cyclic))
|
if (args.flags.HasFlag(MoveSplineFlagEnum.Cyclic))
|
||||||
{
|
{
|
||||||
int cyclic_point = 0;
|
int cyclic_point = 0;
|
||||||
if (splineflags.HasFlag(MoveSplineFlagEnum.EnterCycle))
|
if (splineflags.HasFlag(MoveSplineFlagEnum.EnterCycle))
|
||||||
cyclic_point = 1; // shouldn't be modified, came from client
|
cyclic_point = 1; // shouldn't be modified, came from client
|
||||||
spline.InitCyclicSpline(args.path.ToArray(), args.path.Count, modes[Convert.ToInt32(args.flags.IsSmooth())], cyclic_point, args.initialOrientation);
|
spline.InitCyclicSpline(args.path.ToArray(), args.path.Count, mode, cyclic_point, args.initialOrientation);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
spline.InitSpline(args.path.ToArray(), args.path.Count, modes[Convert.ToInt32(args.flags.IsSmooth())], args.initialOrientation);
|
spline.InitSpline(args.path.ToArray(), args.path.Count, mode, args.initialOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// init spline timestamps
|
// init spline timestamps
|
||||||
@@ -290,34 +290,7 @@ namespace Game.Movement
|
|||||||
if (splineflags.HasFlag(MoveSplineFlagEnum.EnterCycle))
|
if (splineflags.HasFlag(MoveSplineFlagEnum.EnterCycle))
|
||||||
{
|
{
|
||||||
splineflags.SetUnsetFlag(MoveSplineFlagEnum.EnterCycle, false);
|
splineflags.SetUnsetFlag(MoveSplineFlagEnum.EnterCycle, false);
|
||||||
|
reinit_spline_for_next_cycle();
|
||||||
MoveSplineInitArgs args = new(spline.GetPointCount());
|
|
||||||
args.path.AddRange(spline.GetPoints().AsSpan().Slice(spline.First() + 1, spline.Last()).ToArray());
|
|
||||||
args.facing = facing;
|
|
||||||
args.flags = splineflags;
|
|
||||||
args.path_Idx_offset = point_Idx_offset;
|
|
||||||
// MoveSplineFlag::Parabolic | MoveSplineFlag::Animation not supported currently
|
|
||||||
//args.parabolic_amplitude = ?;
|
|
||||||
//args.time_perc = ?;
|
|
||||||
args.splineId = m_Id;
|
|
||||||
args.initialOrientation = initialOrientation;
|
|
||||||
args.velocity = 1.0f; // Calculated below
|
|
||||||
args.HasVelocity = true;
|
|
||||||
args.TransformForTransport = onTransport;
|
|
||||||
if (args.Validate(null))
|
|
||||||
{
|
|
||||||
// New cycle should preserve previous cycle's duration for some weird reason, even though
|
|
||||||
// the path is really different now. Blizzard is weird. Or this was just a simple oversight.
|
|
||||||
// Since our splines precalculate length with velocity in mind, if we want to find the desired
|
|
||||||
// velocity, we have to make a fake spline, calculate its duration and then compare it to the
|
|
||||||
// desired duration, thus finding out how much the velocity has to be increased for them to match.
|
|
||||||
MoveSpline tempSpline = new();
|
|
||||||
tempSpline.Initialize(args);
|
|
||||||
args.velocity = (float)tempSpline.Duration() / Duration();
|
|
||||||
|
|
||||||
if (args.Validate(null))
|
|
||||||
InitSpline(args);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -331,6 +304,38 @@ namespace Game.Movement
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reinit_spline_for_next_cycle()
|
||||||
|
{
|
||||||
|
MoveSplineInitArgs args = new(spline.GetPointCount());
|
||||||
|
args.path.AddRange(spline.GetPoints().AsSpan().Slice(spline.First() + 1, spline.Last()).ToArray());
|
||||||
|
args.facing = facing;
|
||||||
|
args.flags = splineflags;
|
||||||
|
args.path_Idx_offset = point_Idx_offset;
|
||||||
|
// MoveSplineFlag::Parabolic | MoveSplineFlag::Animation not supported currently
|
||||||
|
//args.parabolic_amplitude = ?;
|
||||||
|
//args.time_perc = ?;
|
||||||
|
args.splineId = m_Id;
|
||||||
|
args.initialOrientation = initialOrientation;
|
||||||
|
args.velocity = 1.0f; // Calculated below
|
||||||
|
args.HasVelocity = true;
|
||||||
|
args.TransformForTransport = onTransport;
|
||||||
|
if (args.Validate(null))
|
||||||
|
{
|
||||||
|
// New cycle should preserve previous cycle's duration for some weird reason, even though
|
||||||
|
// the path is really different now. Blizzard is weird. Or this was just a simple oversight.
|
||||||
|
// Since our splines precalculate length with velocity in mind, if we want to find the desired
|
||||||
|
// velocity, we have to make a fake spline, calculate its duration and then compare it to the
|
||||||
|
// desired duration, thus finding out how much the velocity has to be increased for them to match.
|
||||||
|
MoveSpline tempSpline = new();
|
||||||
|
tempSpline.Initialize(args);
|
||||||
|
args.velocity = (float)tempSpline.Duration() / Duration();
|
||||||
|
|
||||||
|
if (args.Validate(null))
|
||||||
|
InitSpline(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int NextTimestamp() { return spline.Length(point_Idx + 1); }
|
int NextTimestamp() { return spline.Length(point_Idx + 1); }
|
||||||
int SegmentTimeElapsed() { return NextTimestamp() - time_passed; }
|
int SegmentTimeElapsed() { return NextTimestamp() - time_passed; }
|
||||||
public bool IsCyclic() { return splineflags.HasFlag(MoveSplineFlagEnum.Cyclic); }
|
public bool IsCyclic() { return splineflags.HasFlag(MoveSplineFlagEnum.Cyclic); }
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ namespace Game.Movement
|
|||||||
return 50.0f;
|
return 50.0f;
|
||||||
|
|
||||||
return Math.Max(28.0f, unit.GetSpeed(UnitMoveType.Run) * 4.0f);
|
return Math.Max(28.0f, unit.GetSpeed(UnitMoveType.Run) * 4.0f);
|
||||||
};
|
}
|
||||||
|
|
||||||
args.velocity = Math.Min(args.velocity, speedLimit());
|
args.velocity = Math.Min(args.velocity, speedLimit());
|
||||||
|
|
||||||
@@ -218,20 +218,8 @@ namespace Game.Movement
|
|||||||
|
|
||||||
public void SetFacing(float angle)
|
public void SetFacing(float angle)
|
||||||
{
|
{
|
||||||
if (args.TransformForTransport)
|
TransportPathTransform transform = new(unit, args.TransformForTransport);
|
||||||
{
|
args.facing.angle = Position.NormalizeOrientation(transform.Calc(angle));
|
||||||
Unit vehicle = unit.GetVehicleBase();
|
|
||||||
if (vehicle != null)
|
|
||||||
angle -= vehicle.GetOrientation();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ITransport transport = unit.GetTransport();
|
|
||||||
if (transport != null)
|
|
||||||
angle -= transport.GetTransportOrientation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
args.facing.angle = MathFunctions.wrap(angle, 0.0f, MathFunctions.TwoPi);
|
|
||||||
args.facing.type = MonsterMoveType.FacingAngle;
|
args.facing.type = MonsterMoveType.FacingAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,12 +276,12 @@ namespace Game.Movement
|
|||||||
|
|
||||||
public void SetUnlimitedSpeed() { args.flags.SetUnsetFlag(MoveSplineFlagEnum.UnlimitedSpeed, true); }
|
public void SetUnlimitedSpeed() { args.flags.SetUnsetFlag(MoveSplineFlagEnum.UnlimitedSpeed, true); }
|
||||||
|
|
||||||
public void MovebyPath(Vector3[] controls, int path_offset = 0)
|
public void MovebyPath(Vector3[] path, int pointId = 0)
|
||||||
{
|
{
|
||||||
args.path_Idx_offset = path_offset;
|
args.path_Idx_offset = pointId;
|
||||||
TransportPathTransform transform = new(unit, args.TransformForTransport);
|
TransportPathTransform transform = new(unit, args.TransformForTransport);
|
||||||
for (var i = 0; i < controls.Length; i++)
|
for (var i = 0; i < path.Length; i++)
|
||||||
args.path.Add(transform.Calc(controls[i]));
|
args.path.Add(transform.Calc(path[i]));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,17 +290,17 @@ namespace Game.Movement
|
|||||||
MoveTo(new Vector3(x, y, z), generatePath, forceDest);
|
MoveTo(new Vector3(x, y, z), generatePath, forceDest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetParabolic(float amplitude, float time_shift)
|
public void SetParabolic(float amplitude, float start_time)
|
||||||
{
|
{
|
||||||
args.effect_start_time_percent = time_shift;
|
args.effect_start_time_percent = start_time;
|
||||||
args.parabolic_amplitude = amplitude;
|
args.parabolic_amplitude = amplitude;
|
||||||
args.vertical_acceleration = 0.0f;
|
args.vertical_acceleration = 0.0f;
|
||||||
args.flags.EnableParabolic();
|
args.flags.EnableParabolic();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetParabolicVerticalAcceleration(float vertical_acceleration, float time_shift)
|
public void SetParabolicVerticalAcceleration(float vertical_acceleration, float start_time)
|
||||||
{
|
{
|
||||||
args.effect_start_time_percent = time_shift;
|
args.effect_start_time_percent = start_time;
|
||||||
args.parabolic_amplitude = 0.0f;
|
args.parabolic_amplitude = 0.0f;
|
||||||
args.vertical_acceleration = vertical_acceleration;
|
args.vertical_acceleration = vertical_acceleration;
|
||||||
args.flags.EnableParabolic();
|
args.flags.EnableParabolic();
|
||||||
@@ -345,30 +333,28 @@ namespace Game.Movement
|
|||||||
// Transforms coordinates from global to transport offsets
|
// Transforms coordinates from global to transport offsets
|
||||||
public class TransportPathTransform
|
public class TransportPathTransform
|
||||||
{
|
{
|
||||||
|
ITransport _transport;
|
||||||
|
|
||||||
public TransportPathTransform(Unit owner, bool transformForTransport)
|
public TransportPathTransform(Unit owner, bool transformForTransport)
|
||||||
{
|
{
|
||||||
_owner = owner;
|
_transport = transformForTransport ? owner.GetDirectTransport() : null;
|
||||||
_transformForTransport = transformForTransport;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 Calc(Vector3 input)
|
public Vector3 Calc(Vector3 input)
|
||||||
{
|
{
|
||||||
float x = input.X;
|
float o = 0;
|
||||||
float y = input.Y;
|
if (_transport != null)
|
||||||
float z = input.Z;
|
_transport.CalculatePassengerOffset(ref input.X, ref input.Y, ref input.Z, ref o);
|
||||||
if (_transformForTransport)
|
|
||||||
{
|
return input;
|
||||||
ITransport transport = _owner.GetDirectTransport();
|
|
||||||
if (transport != null)
|
|
||||||
{
|
|
||||||
float unused = 0.0f; // need reference
|
|
||||||
transport.CalculatePassengerOffset(ref x, ref y, ref z, ref unused);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Vector3(x, y, z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit _owner;
|
public float Calc(float input)
|
||||||
bool _transformForTransport;
|
{
|
||||||
|
if (_transport != null)
|
||||||
|
input -= _transport.GetTransportOrientation();
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user