fix(Core/Grid): Address bugs and performance issues introduced by visibility notifier implementation (#17480)

* Bug fixes

- Corrected std::chrono from seconds to milliseconds
- Got rid of leftover code that caused objects to not show up on time

* Removed logic to set gameobject as active

- More alignement with TC.
- Reduces CPU usage drastically

* Revert back to using time_t instead of std chrono

* Invoke SetNoCreate() method to reduce CPU usage drastically

* Remove setActive from static and motion transports

* Fix performance issues

* Added SetFarVisible to WG and some dungeon scripts

- Also removed setActive(true) from creatures in Wintergrasp. As for gameobjects they are set to active upon being damaged/destroyed and removed from active on rebuild (reset)

* Removed comments related to VISIBILITY_COMPENSATION

* Fix log

* Deleted unused files + corrected a check

* Added missing header

* Removed unused parameter

* Removed another unsued parameter

* Changed vector to set for i_visibleNow

- Changed vector to set for i_visibleNow in VisibleNotifer
- Adjusted HaveAtClient to accept Object*
- Adjusted SendUpdateToPlayer to send createobject packet only if not known to client
This commit is contained in:
AG
2023-10-23 10:37:11 +02:00
committed by GitHub
parent a56a224bd7
commit 60e27511c5
53 changed files with 509 additions and 586 deletions
+40 -6
View File
@@ -125,14 +125,13 @@ namespace Movement
if (args.flags.cyclic)
{
uint32 cyclic_point = 0;
// MoveSplineFlag::Enter_Cycle support dropped
//if (splineflags & SPLINEFLAG_ENTER_CYCLE)
//cyclic_point = 1; // shouldn't be modified, came from client
spline.init_cyclic_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()], cyclic_point);
if (splineflags.enter_cycle)
cyclic_point = 1; // shouldn't be modified, came from client
spline.init_cyclic_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()], cyclic_point, args.initialOrientation);
}
else
{
spline.init_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()]);
spline.init_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()], args.initialOrientation);
}
// init spline timestamps
@@ -204,7 +203,7 @@ namespace Movement
if (!(exp)) \
{ \
if (unit) \
LOG_ERROR("misc.movesplineinitargs", "MoveSplineInitArgs::Validate: expression '{}' failed for {}", #exp, unit->GetGUID().ToString()); \
LOG_ERROR("misc.movesplineinitargs", "MoveSplineInitArgs::Validate: expression '{}' failed for GUID: {} Entry: {}", #exp, unit->GetGUID().ToString().c_str(), unit->GetEntry());\
else \
LOG_ERROR("misc.movesplineinitargs", "MoveSplineInitArgs::Validate: expression '{}' failed for cyclic spline continuation", #exp); \
return false;\
@@ -273,6 +272,41 @@ namespace Movement
point_Idx = spline.first();
time_passed = time_passed % Duration();
result = Movement::MoveSpline::UpdateResult(Result_NextCycle | Result_JustArrived);
// Remove first point from the path after one full cycle.
// That point was the position of the unit prior to entering the cycle and it shouldn't be repeated with continuous cycles.
if (splineflags.enter_cycle)
{
splineflags.enter_cycle = false;
MoveSplineInitArgs args{ (size_t)spline.getPointCount() };
args.path.assign(spline.getPoints().begin() + spline.first() + 1, spline.getPoints().begin() + spline.last());
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(nullptr))
{
// 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;
tempSpline.Initialize(args);
args.velocity = (float)tempSpline.Duration() / Duration();
if (args.Validate(nullptr))
init_spline(args);
}
}
}
else
{
@@ -87,6 +87,7 @@ namespace Movement
// corrent first vertex
args.path[0] = real_position;
args.initialOrientation = real_position.orientation;
args.flags.enter_cycle = args.flags.cyclic;
move_spline.onTransport = transport;
uint32 moveFlags = unit->m_movementInfo.GetMovementFlags();
@@ -67,10 +67,6 @@ namespace Movement
break;
}
// add fake Enter_Cycle flag - needed for client-side cyclic movement (client will erase first spline vertex after first cycle done)
// Xinef: this flag breaks cycle for ground movement, client teleports npc between last and first point instead of using smooth movement
if (splineflags & MoveSplineFlag::Flying)
splineflags.enter_cycle = move_spline.isCyclic();
data << uint32(splineflags & uint32(~MoveSplineFlag::Mask_No_Monster_Move));
if (splineflags.animation)
@@ -123,20 +119,11 @@ namespace Movement
data.append<Vector3>(&spline.getPoint(2), count);
}
void WriteCatmullRomCyclicPath(const Spline<int32>& spline, ByteBuffer& data, bool flying)
void WriteCatmullRomCyclicPath(const Spline<int32>& spline, ByteBuffer& data)
{
uint32 count = spline.getPointCount() - 3;
data << uint32(count + 1);
if (flying)
{
data << spline.getPoint(1); // fake point, client will erase it from the spline after first cycle done
data.append<Vector3>(&spline.getPoint(2), count);
}
else
{
data.append<Vector3>(&spline.getPoint(2), count);
data << Vector3::zero(); //Xinef: fake point
}
uint32 count = spline.getPointCount() - 4;
data << count;
data.append<Vector3>(&spline.getPoint(2), count);
}
void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, ByteBuffer& data)
@@ -148,7 +135,7 @@ namespace Movement
if (splineflags & MoveSplineFlag::Mask_CatmullRom)
{
if (splineflags.cyclic)
WriteCatmullRomCyclicPath(spline, data, splineflags & MoveSplineFlag::Flying);
WriteCatmullRomCyclicPath(spline, data);
else
WriteCatmullRomPath(spline, data);
}
@@ -199,4 +186,8 @@ namespace Movement
data << (move_spline.isCyclic() ? Vector3::zero() : move_spline.FinalDestination());
}
}
void PacketBuilder::WriteSplineSync(MoveSpline const& move_spline, ByteBuffer& data)
{
data << (float)move_spline.timePassed() / move_spline.Duration();
}
}
@@ -38,6 +38,7 @@ namespace Movement
static void WriteMonsterMove(const MoveSpline& mov, ByteBuffer& data);
static void WriteStopMovement(Vector3 const& loc, uint32 splineId, ByteBuffer& data);
static void WriteCreate(const MoveSpline& mov, ByteBuffer& data);
static void WriteSplineSync(MoveSpline const& mov, ByteBuffer& data);
};
}
#endif // AC_PACKET_BUILDER_H
+11 -9
View File
@@ -199,23 +199,25 @@ namespace Movement
return length;
}
void SplineBase::init_spline(const Vector3* controls, index_type count, EvaluationMode m)
void SplineBase::init_spline(const Vector3* controls, index_type count, EvaluationMode m, float orientation)
{
m_mode = m;
cyclic = false;
initialOrientation = orientation;
(this->*initializers[m_mode])(controls, count, cyclic, 0);
(this->*initializers[m_mode])(controls, count, 0);
}
void SplineBase::init_cyclic_spline(const Vector3* controls, index_type count, EvaluationMode m, index_type cyclic_point)
void SplineBase::init_cyclic_spline(const Vector3* controls, index_type count, EvaluationMode m, index_type cyclic_point, float orientation)
{
m_mode = m;
cyclic = true;
initialOrientation = orientation;
(this->*initializers[m_mode])(controls, count, cyclic, cyclic_point);
(this->*initializers[m_mode])(controls, count, cyclic_point);
}
void SplineBase::InitLinear(const Vector3* controls, index_type count, bool cyclic, index_type cyclic_point)
void SplineBase::InitLinear(const Vector3* controls, index_type count, index_type cyclic_point)
{
ASSERT(count >= 2);
const int real_size = count + 1;
@@ -235,7 +237,7 @@ namespace Movement
index_hi = cyclic ? count : (count - 1);
}
void SplineBase::InitCatmullRom(const Vector3* controls, index_type count, bool cyclic, index_type cyclic_point)
void SplineBase::InitCatmullRom(const Vector3* controls, index_type count, index_type cyclic_point)
{
const int real_size = count + (cyclic ? (1 + 2) : (1 + 1));
@@ -253,14 +255,14 @@ namespace Movement
if (cyclic_point == 0)
points[0] = controls[count - 1];
else
points[0] = controls[0].lerp(controls[1], -1);
points[0] = controls[0] - G3D::Vector3{ std::cos(initialOrientation), std::sin(initialOrientation), 0.0f };
points[high_index + 1] = controls[cyclic_point];
points[high_index + 2] = controls[cyclic_point + 1];
}
else
{
points[0] = controls[0].lerp(controls[1], -1);
points[0] = controls[0] - G3D::Vector3{ std::cos(initialOrientation), std::sin(initialOrientation), 0.0f };
points[high_index + 1] = controls[count - 1];
}
@@ -268,7 +270,7 @@ namespace Movement
index_hi = high_index + (cyclic ? 1 : 0);
}
void SplineBase::InitBezier3(const Vector3* controls, index_type count, bool /*cyclic*/, index_type /*cyclic_point*/)
void SplineBase::InitBezier3(const Vector3* controls, index_type count, index_type /*cyclic_point*/)
{
index_type c = count / 3u * 3u;
index_type t = c / 3u;
+11 -10
View File
@@ -48,6 +48,7 @@ namespace Movement
uint8 m_mode{UninitializedMode};
bool cyclic{false};
float initialOrientation;
enum
{
@@ -77,15 +78,15 @@ namespace Movement
typedef float (SplineBase::*SegLenghtMethtod)(index_type) const;
static SegLenghtMethtod seglengths[ModesEnd];
void InitLinear(const Vector3*, index_type, bool, index_type);
void InitCatmullRom(const Vector3*, index_type, bool, index_type);
void InitBezier3(const Vector3*, index_type, bool, index_type);
typedef void (SplineBase::*InitMethtod)(const Vector3*, index_type, bool, index_type);
void InitLinear(const Vector3*, index_type, index_type);
void InitCatmullRom(const Vector3*, index_type, index_type);
void InitBezier3(const Vector3*, index_type, index_type);
typedef void (SplineBase::*InitMethtod)(const Vector3*, index_type, index_type);
static InitMethtod initializers[ModesEnd];
void UninitializedSplineEvaluationMethod(index_type, float, Vector3&) const { ABORT(); }
[[nodiscard]] float UninitializedSplineSegLenghtMethod(index_type) const { ABORT(); }
void UninitializedSplineInitMethod(Vector3 const*, index_type, bool, index_type) { ABORT(); }
[[nodiscard]] float UninitializedSplineSegLenghtMethod(index_type) const { ABORT(); return 0.0f; }
void UninitializedSplineInitMethod(Vector3 const*, index_type, index_type) { ABORT(); }
public:
explicit SplineBase() = default;
@@ -116,8 +117,8 @@ namespace Movement
[[nodiscard]] const Vector3& getPoint(index_type i) const { return points[i];}
/** Initializes spline. Don't call other methods while spline not initialized. */
void init_spline(const Vector3* controls, index_type count, EvaluationMode m);
void init_cyclic_spline(const Vector3* controls, index_type count, EvaluationMode m, index_type cyclic_point);
void init_spline(const Vector3* controls, index_type count, EvaluationMode m, float orientation);
void init_cyclic_spline(const Vector3* controls, index_type count, EvaluationMode m, index_type cyclic_point, float orientation);
/** As i can see there are a lot of ways how spline can be initialized
would be no harm to have some custom initializers. */
@@ -170,8 +171,8 @@ namespace Movement
void computeIndex(float t, index_type& out_idx, float& out_u) const;
/** Initializes spline. Don't call other methods while spline not initialized. */
void init_spline(const Vector3* controls, index_type count, EvaluationMode m) { SplineBase::init_spline(controls, count, m);}
void init_cyclic_spline(const Vector3* controls, index_type count, EvaluationMode m, index_type cyclic_point) { SplineBase::init_cyclic_spline(controls, count, m, cyclic_point);}
void init_spline(const Vector3* controls, index_type count, EvaluationMode m, float orientation = 0) { SplineBase::init_spline(controls, count, m, orientation);}
void init_cyclic_spline(const Vector3* controls, index_type count, EvaluationMode m, index_type cyclic_point, float orientation = 0) { SplineBase::init_cyclic_spline(controls, count, m, cyclic_point, orientation);}
/** Initializes lengths with SplineBase::SegLength method. */
void initLengths();