Fix taxi mount orientation and eliminate tile loading hitches

Fixes two critical taxi flight issues:

1. Mount orientation now correctly faces flight direction:
   - Prevent camera controller from updating facingYaw during taxi (externalFollow_ check)
   - Taxi orientation callback system updates mount rotation from spline tangent
   - Initial orientation set when flight starts
   - Smooth Catmull-Rom spline interpolation for natural curved paths

2. Eliminate frame hitches from tile loading during flight:
   - New taxiFlightStartCallback uploads ALL precached tiles to GPU before flight begins
   - Previously tiles loaded async during 3s mount delay but uploaded 1/frame during flight
   - Now processAllReadyTiles() blocks briefly after mount delay to batch upload everything
   - Combined with 2.0s terrain update interval and aggressive culling for smooth flight

Additional optimizations:
   - Aggressive taxi culling: skip models <15 units, all foliage/trees, underwater objects
   - Max render distance reduced to 150 units during taxi
   - Movement heartbeat packets disabled during taxi (server controls position)
   - Reduced taxi speed from 32 to 18 units/sec to prevent streaming overload
This commit is contained in:
Kelsi 2026-02-08 22:00:33 -08:00
parent 536b3cea48
commit 2e0a7e0039
7 changed files with 119 additions and 21 deletions

View file

@ -501,6 +501,14 @@ public:
using TaxiPrecacheCallback = std::function<void(const std::vector<glm::vec3>&)>;
void setTaxiPrecacheCallback(TaxiPrecacheCallback cb) { taxiPrecacheCallback_ = std::move(cb); }
// Taxi orientation callback (for mount rotation)
using TaxiOrientationCallback = std::function<void(float orientationRadians)>;
void setTaxiOrientationCallback(TaxiOrientationCallback cb) { taxiOrientationCallback_ = std::move(cb); }
// Callback for when taxi flight is about to start (after mounting delay, before movement begins)
using TaxiFlightStartCallback = std::function<void()>;
void setTaxiFlightStartCallback(TaxiFlightStartCallback cb) { taxiFlightStartCallback_ = std::move(cb); }
bool isMounted() const { return currentMountDisplayId_ != 0; }
bool isHostileAttacker(uint64_t guid) const { return hostileAttackers_.count(guid) > 0; }
float getServerRunSpeed() const { return serverRunSpeed_; }
@ -959,7 +967,7 @@ private:
bool taxiClientActive_ = false;
size_t taxiClientIndex_ = 0;
std::vector<glm::vec3> taxiClientPath_;
float taxiClientSpeed_ = 32.0f;
float taxiClientSpeed_ = 18.0f; // Reduced from 32 to prevent loading hitches
float taxiClientSegmentProgress_ = 0.0f;
bool taxiMountingDelay_ = false; // Delay before flight starts (terrain precache time)
float taxiMountingTimer_ = 0.0f;
@ -1023,6 +1031,8 @@ private:
NpcSwingCallback npcSwingCallback_;
MountCallback mountCallback_;
TaxiPrecacheCallback taxiPrecacheCallback_;
TaxiOrientationCallback taxiOrientationCallback_;
TaxiFlightStartCallback taxiFlightStartCallback_;
uint32_t currentMountDisplayId_ = 0;
float serverRunSpeed_ = 7.0f;
bool playerDead_ = false;