mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Optimize collision queries with spatial grid and improve movement CCD
This commit is contained in:
parent
a3f351f395
commit
baca09828e
9 changed files with 627 additions and 15 deletions
|
|
@ -94,6 +94,8 @@ private:
|
|||
static constexpr float PIVOT_HEIGHT = 1.8f; // Pivot at head height
|
||||
static constexpr float CAM_SPHERE_RADIUS = 0.32f; // Keep camera farther from geometry to avoid clipping-through surfaces
|
||||
static constexpr float CAM_EPSILON = 0.22f; // Extra wall offset to avoid near-plane clipping artifacts
|
||||
static constexpr float COLLISION_FOCUS_RADIUS_THIRD_PERSON = 90.0f;
|
||||
static constexpr float COLLISION_FOCUS_RADIUS_FREE_FLY = 70.0f;
|
||||
static constexpr float MIN_PITCH = -88.0f; // Look almost straight down
|
||||
static constexpr float MAX_PITCH = 35.0f; // Limited upward look
|
||||
glm::vec3* followTarget = nullptr;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
|
@ -58,6 +59,8 @@ struct M2Instance {
|
|||
float scale;
|
||||
glm::mat4 modelMatrix;
|
||||
glm::mat4 invModelMatrix;
|
||||
glm::vec3 worldBoundsMin;
|
||||
glm::vec3 worldBoundsMax;
|
||||
|
||||
// Animation state
|
||||
float animTime = 0.0f; // Current animation time
|
||||
|
|
@ -163,6 +166,16 @@ public:
|
|||
*/
|
||||
float raycastBoundingBoxes(const glm::vec3& origin, const glm::vec3& direction, float maxDistance) const;
|
||||
|
||||
/**
|
||||
* Limit expensive collision/raycast queries to objects near a focus point.
|
||||
*/
|
||||
void setCollisionFocus(const glm::vec3& worldPos, float radius);
|
||||
void clearCollisionFocus();
|
||||
|
||||
void resetQueryStats();
|
||||
double getQueryTimeMs() const { return queryTimeMs; }
|
||||
uint32_t getQueryCallCount() const { return queryCallCount; }
|
||||
|
||||
// Stats
|
||||
uint32_t getModelCount() const { return static_cast<uint32_t>(models.size()); }
|
||||
uint32_t getInstanceCount() const { return static_cast<uint32_t>(instances.size()); }
|
||||
|
|
@ -186,6 +199,42 @@ private:
|
|||
// Lighting uniforms
|
||||
glm::vec3 lightDir = glm::vec3(0.5f, 0.5f, 1.0f);
|
||||
glm::vec3 ambientColor = glm::vec3(0.4f, 0.4f, 0.45f);
|
||||
|
||||
// Optional query-space culling for collision/raycast hot paths.
|
||||
bool collisionFocusEnabled = false;
|
||||
glm::vec3 collisionFocusPos = glm::vec3(0.0f);
|
||||
float collisionFocusRadius = 0.0f;
|
||||
float collisionFocusRadiusSq = 0.0f;
|
||||
|
||||
struct GridCell {
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
bool operator==(const GridCell& other) const {
|
||||
return x == other.x && y == other.y && z == other.z;
|
||||
}
|
||||
};
|
||||
struct GridCellHash {
|
||||
size_t operator()(const GridCell& c) const {
|
||||
size_t h1 = std::hash<int>()(c.x);
|
||||
size_t h2 = std::hash<int>()(c.y);
|
||||
size_t h3 = std::hash<int>()(c.z);
|
||||
return h1 ^ (h2 * 0x9e3779b9u) ^ (h3 * 0x85ebca6bu);
|
||||
}
|
||||
};
|
||||
GridCell toCell(const glm::vec3& p) const;
|
||||
void rebuildSpatialIndex();
|
||||
void gatherCandidates(const glm::vec3& queryMin, const glm::vec3& queryMax, std::vector<size_t>& outIndices) const;
|
||||
|
||||
static constexpr float SPATIAL_CELL_SIZE = 64.0f;
|
||||
std::unordered_map<GridCell, std::vector<uint32_t>, GridCellHash> spatialGrid;
|
||||
std::unordered_map<uint32_t, size_t> instanceIndexById;
|
||||
mutable std::vector<size_t> candidateScratch;
|
||||
mutable std::unordered_set<uint32_t> candidateIdScratch;
|
||||
|
||||
// Collision query profiling (per frame).
|
||||
mutable double queryTimeMs = 0.0;
|
||||
mutable uint32_t queryCallCount = 0;
|
||||
};
|
||||
|
||||
} // namespace rendering
|
||||
|
|
|
|||
|
|
@ -121,6 +121,14 @@ public:
|
|||
void setTargetPosition(const glm::vec3* pos);
|
||||
bool isMoving() const;
|
||||
|
||||
// CPU timing stats (milliseconds, last frame).
|
||||
double getLastUpdateMs() const { return lastUpdateMs; }
|
||||
double getLastRenderMs() const { return lastRenderMs; }
|
||||
double getLastCameraUpdateMs() const { return lastCameraUpdateMs; }
|
||||
double getLastTerrainRenderMs() const { return lastTerrainRenderMs; }
|
||||
double getLastWMORenderMs() const { return lastWMORenderMs; }
|
||||
double getLastM2RenderMs() const { return lastM2RenderMs; }
|
||||
|
||||
private:
|
||||
core::Window* window = nullptr;
|
||||
std::unique_ptr<Camera> camera;
|
||||
|
|
@ -177,6 +185,14 @@ private:
|
|||
|
||||
bool terrainEnabled = true;
|
||||
bool terrainLoaded = false;
|
||||
|
||||
// CPU timing stats (last frame/update).
|
||||
double lastUpdateMs = 0.0;
|
||||
double lastRenderMs = 0.0;
|
||||
double lastCameraUpdateMs = 0.0;
|
||||
double lastTerrainRenderMs = 0.0;
|
||||
double lastWMORenderMs = 0.0;
|
||||
double lastM2RenderMs = 0.0;
|
||||
};
|
||||
|
||||
} // namespace rendering
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
|
@ -158,6 +159,16 @@ public:
|
|||
*/
|
||||
float raycastBoundingBoxes(const glm::vec3& origin, const glm::vec3& direction, float maxDistance) const;
|
||||
|
||||
/**
|
||||
* Limit expensive collision/raycast queries to objects near a focus point.
|
||||
*/
|
||||
void setCollisionFocus(const glm::vec3& worldPos, float radius);
|
||||
void clearCollisionFocus();
|
||||
|
||||
void resetQueryStats();
|
||||
double getQueryTimeMs() const { return queryTimeMs; }
|
||||
uint32_t getQueryCallCount() const { return queryCallCount; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* WMO group GPU resources
|
||||
|
|
@ -222,6 +233,8 @@ private:
|
|||
float scale;
|
||||
glm::mat4 modelMatrix;
|
||||
glm::mat4 invModelMatrix; // Cached inverse for collision
|
||||
glm::vec3 worldBoundsMin;
|
||||
glm::vec3 worldBoundsMax;
|
||||
|
||||
void updateModelMatrix();
|
||||
};
|
||||
|
|
@ -249,6 +262,27 @@ private:
|
|||
*/
|
||||
GLuint loadTexture(const std::string& path);
|
||||
|
||||
struct GridCell {
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
bool operator==(const GridCell& other) const {
|
||||
return x == other.x && y == other.y && z == other.z;
|
||||
}
|
||||
};
|
||||
struct GridCellHash {
|
||||
size_t operator()(const GridCell& c) const {
|
||||
size_t h1 = std::hash<int>()(c.x);
|
||||
size_t h2 = std::hash<int>()(c.y);
|
||||
size_t h3 = std::hash<int>()(c.z);
|
||||
return h1 ^ (h2 * 0x9e3779b9u) ^ (h3 * 0x85ebca6bu);
|
||||
}
|
||||
};
|
||||
|
||||
GridCell toCell(const glm::vec3& p) const;
|
||||
void rebuildSpatialIndex();
|
||||
void gatherCandidates(const glm::vec3& queryMin, const glm::vec3& queryMax, std::vector<size_t>& outIndices) const;
|
||||
|
||||
// Shader
|
||||
std::unique_ptr<Shader> shader;
|
||||
|
||||
|
|
@ -272,6 +306,23 @@ private:
|
|||
bool wireframeMode = false;
|
||||
bool frustumCulling = true;
|
||||
uint32_t lastDrawCalls = 0;
|
||||
|
||||
// Optional query-space culling for collision/raycast hot paths.
|
||||
bool collisionFocusEnabled = false;
|
||||
glm::vec3 collisionFocusPos = glm::vec3(0.0f);
|
||||
float collisionFocusRadius = 0.0f;
|
||||
float collisionFocusRadiusSq = 0.0f;
|
||||
|
||||
// Uniform grid for fast local collision queries.
|
||||
static constexpr float SPATIAL_CELL_SIZE = 64.0f;
|
||||
std::unordered_map<GridCell, std::vector<uint32_t>, GridCellHash> spatialGrid;
|
||||
std::unordered_map<uint32_t, size_t> instanceIndexById;
|
||||
mutable std::vector<size_t> candidateScratch;
|
||||
mutable std::unordered_set<uint32_t> candidateIdScratch;
|
||||
|
||||
// Collision query profiling (per frame).
|
||||
mutable double queryTimeMs = 0.0;
|
||||
mutable uint32_t queryCallCount = 0;
|
||||
};
|
||||
|
||||
} // namespace rendering
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue