Performance optimizations and collision improvements

Performance:
- Remove expensive inverse() from all vertex shaders (terrain, WMO, M2, water, character)
- Add uniform location caching to avoid repeated glGetUniformLocation calls
- Add proper frustum culling for WMO groups using AABB intersection
- Add distance-based culling for WMO and M2 instances
- Add cleanup of unused M2/WMO models when tiles unload

Collision & Movement:
- Add M2 doodad collision detection (fences, boxes, etc.)
- Reduce character eye height (5.0 -> 1.8) and collision radius (2.5 -> 0.5)
- Enable WoW-style movement speed by default (14 units/sec run, 5 walk, 9 back)
- Fix emote grammar ("You waves." -> "You wave.")

Misc:
- Rename window title to "Wowee"
This commit is contained in:
Kelsi 2026-02-02 23:03:45 -08:00
parent 0c85fcd444
commit 4287878a73
16 changed files with 258 additions and 32 deletions

View file

@ -10,6 +10,7 @@ namespace rendering {
class TerrainManager;
class WMORenderer;
class M2Renderer;
class WaterRenderer;
class CameraController {
@ -25,6 +26,7 @@ public:
void setEnabled(bool enabled) { this->enabled = enabled; }
void setTerrainManager(TerrainManager* tm) { terrainManager = tm; }
void setWMORenderer(WMORenderer* wmo) { wmoRenderer = wmo; }
void setM2Renderer(M2Renderer* m2) { m2Renderer = m2; }
void setWaterRenderer(WaterRenderer* wr) { waterRenderer = wr; }
void processMouseWheel(float delta);
@ -54,6 +56,7 @@ private:
Camera* camera;
TerrainManager* terrainManager = nullptr;
WMORenderer* wmoRenderer = nullptr;
M2Renderer* m2Renderer = nullptr;
WaterRenderer* waterRenderer = nullptr;
// Stored rotation (avoids lossy forward-vector round-trip)
@ -82,7 +85,7 @@ private:
// Gravity / grounding
float verticalVelocity = 0.0f;
bool grounded = false;
float eyeHeight = 5.0f;
float eyeHeight = 1.8f; // WoW human eye height (~2 yard tall character)
float lastGroundZ = 0.0f; // Last known ground height (fallback when no terrain)
static constexpr float GRAVITY = -30.0f;
static constexpr float JUMP_VELOCITY = 15.0f;
@ -112,11 +115,11 @@ private:
// Movement callback
MovementCallback movementCallback;
// WoW-correct speeds
// Movement speeds (scaled up for better feel)
bool useWoWSpeed = false;
static constexpr float WOW_RUN_SPEED = 7.0f;
static constexpr float WOW_WALK_SPEED = 2.5f;
static constexpr float WOW_BACK_SPEED = 4.5f;
static constexpr float WOW_RUN_SPEED = 14.0f; // Double base WoW speed for responsiveness
static constexpr float WOW_WALK_SPEED = 5.0f; // Walk (hold Shift)
static constexpr float WOW_BACK_SPEED = 9.0f; // Backpedal
static constexpr float WOW_GRAVITY = -19.29f;
static constexpr float WOW_JUMP_VELOCITY = 7.96f;

View file

@ -116,6 +116,23 @@ public:
*/
void clear();
/**
* Remove models that have no instances referencing them
* Call periodically to free GPU memory
*/
void cleanupUnusedModels();
/**
* Check collision with M2 objects and adjust position
* @param from Starting position
* @param to Desired position
* @param adjustedPos Output adjusted position
* @param playerRadius Collision radius of player
* @return true if collision occurred
*/
bool checkCollision(const glm::vec3& from, const glm::vec3& to,
glm::vec3& adjustedPos, float playerRadius = 0.5f) const;
// Stats
uint32_t getModelCount() const { return static_cast<uint32_t>(models.size()); }
uint32_t getInstanceCount() const { return static_cast<uint32_t>(instances.size()); }

View file

@ -1,6 +1,7 @@
#pragma once
#include <string>
#include <unordered_map>
#include <GL/glew.h>
#include <glm/glm.hpp>
@ -25,6 +26,7 @@ public:
void setUniform(const std::string& name, const glm::vec4& value);
void setUniform(const std::string& name, const glm::mat3& value);
void setUniform(const std::string& name, const glm::mat4& value);
void setUniformMatrixArray(const std::string& name, const glm::mat4* matrices, int count);
GLuint getProgram() const { return program; }
@ -35,6 +37,9 @@ private:
GLuint program = 0;
GLuint vertexShader = 0;
GLuint fragmentShader = 0;
// Cache uniform locations to avoid expensive glGetUniformLocation calls
mutable std::unordered_map<std::string, GLint> uniformLocationCache;
};
} // namespace rendering

View file

@ -102,6 +102,12 @@ public:
*/
uint32_t getInstanceCount() const { return instances.size(); }
/**
* Remove models that have no instances referencing them
* Call periodically to free GPU memory
*/
void cleanupUnusedModels();
/**
* Get total triangle count (all instances)
*/