mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-23 07:40:14 +00:00
Tighten WMO collision detection when inside buildings
When inside a WMO, use: - Smaller sweep step size (0.20 vs 0.35) for more frequent collision checks - Tighter player radius (0.45 vs 0.50) for less claustrophobic corridors - Stronger push response (0.12 vs 0.08 max) for more responsive walls Prevents clipping through walls in tight indoor spaces while keeping outdoor movement smooth.
This commit is contained in:
parent
d49b69a3a8
commit
b48802855b
3 changed files with 13 additions and 7 deletions
|
|
@ -201,9 +201,10 @@ public:
|
|||
* @param from Starting position
|
||||
* @param to Desired position
|
||||
* @param adjustedPos Output adjusted position (pushed away from walls)
|
||||
* @param insideWMO If true, use tighter collision for indoor precision
|
||||
* @return true if collision occurred
|
||||
*/
|
||||
bool checkWallCollision(const glm::vec3& from, const glm::vec3& to, glm::vec3& adjustedPos) const;
|
||||
bool checkWallCollision(const glm::vec3& from, const glm::vec3& to, glm::vec3& adjustedPos, bool insideWMO = false) const;
|
||||
|
||||
/**
|
||||
* Check if a position is inside any WMO
|
||||
|
|
|
|||
|
|
@ -444,13 +444,16 @@ void CameraController::update(float deltaTime) {
|
|||
|
||||
// Sweep collisions in small steps to reduce tunneling through thin walls/floors.
|
||||
// Skip entirely when stationary to avoid wasting collision calls.
|
||||
// Use tighter steps when inside WMO for more precise collision.
|
||||
{
|
||||
glm::vec3 startPos = *followTarget;
|
||||
glm::vec3 desiredPos = targetPos;
|
||||
float moveDist = glm::length(desiredPos - startPos);
|
||||
|
||||
if (moveDist > 0.01f) {
|
||||
int sweepSteps = std::max(1, std::min(5, static_cast<int>(std::ceil(moveDist / 0.35f))));
|
||||
// Smaller step size when inside buildings for tighter collision
|
||||
float stepSize = cachedInsideWMO ? 0.20f : 0.35f;
|
||||
int sweepSteps = std::max(1, std::min(8, static_cast<int>(std::ceil(moveDist / stepSize))));
|
||||
glm::vec3 stepPos = startPos;
|
||||
glm::vec3 stepDelta = (desiredPos - startPos) / static_cast<float>(sweepSteps);
|
||||
|
||||
|
|
@ -459,7 +462,7 @@ void CameraController::update(float deltaTime) {
|
|||
|
||||
if (wmoRenderer) {
|
||||
glm::vec3 adjusted;
|
||||
if (wmoRenderer->checkWallCollision(stepPos, candidate, adjusted)) {
|
||||
if (wmoRenderer->checkWallCollision(stepPos, candidate, adjusted, cachedInsideWMO)) {
|
||||
candidate.x = adjusted.x;
|
||||
candidate.y = adjusted.y;
|
||||
// Accept upward Z correction (ramps), reject downward
|
||||
|
|
|
|||
|
|
@ -1906,7 +1906,7 @@ std::optional<float> WMORenderer::getFloorHeight(float glX, float glY, float glZ
|
|||
return bestFloor;
|
||||
}
|
||||
|
||||
bool WMORenderer::checkWallCollision(const glm::vec3& from, const glm::vec3& to, glm::vec3& adjustedPos) const {
|
||||
bool WMORenderer::checkWallCollision(const glm::vec3& from, const glm::vec3& to, glm::vec3& adjustedPos, bool insideWMO) const {
|
||||
QueryTimer timer(&queryTimeMs, &queryCallCount);
|
||||
adjustedPos = to;
|
||||
bool blocked = false;
|
||||
|
|
@ -1916,7 +1916,8 @@ bool WMORenderer::checkWallCollision(const glm::vec3& from, const glm::vec3& to,
|
|||
if (moveDist < 0.001f) return false;
|
||||
|
||||
// Player collision parameters — WoW-style horizontal cylinder
|
||||
const float PLAYER_RADIUS = 0.50f; // Horizontal cylinder radius
|
||||
// Tighter radius when inside for more responsive indoor collision
|
||||
const float PLAYER_RADIUS = insideWMO ? 0.45f : 0.50f;
|
||||
const float PLAYER_HEIGHT = 2.0f; // Cylinder height for Z bounds
|
||||
const float MAX_STEP_HEIGHT = 1.0f; // Step-up threshold
|
||||
|
||||
|
|
@ -2067,8 +2068,9 @@ bool WMORenderer::checkWallCollision(const glm::vec3& from, const glm::vec3& to,
|
|||
float absNz = std::abs(normal.z);
|
||||
if (absNz >= 0.45f) continue;
|
||||
|
||||
const float SKIN = 0.005f; // small separation so we don’t re-collide immediately
|
||||
const float MAX_PUSH = 0.08f; // cap per triangle contact (tune 0.10–0.25)
|
||||
const float SKIN = 0.005f; // small separation so we don't re-collide immediately
|
||||
// Stronger push when inside WMO for more responsive indoor collision
|
||||
const float MAX_PUSH = insideWMO ? 0.12f : 0.08f;
|
||||
float penetration = (PLAYER_RADIUS - horizDist);
|
||||
float pushDist = glm::clamp(penetration + SKIN, 0.0f, MAX_PUSH);
|
||||
glm::vec2 pushDir2;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue