mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-23 07:40:14 +00:00
Fix WMO collision clipping in Stormwind
Relax swept collision hit threshold, expand spatial grid query range, enable WMO floor detection in first person, raise ramp rejection threshold, and snap Z after wall collision XY adjustment.
This commit is contained in:
parent
f6eaa2cf70
commit
387cc5ddf4
2 changed files with 12 additions and 9 deletions
|
|
@ -27,7 +27,7 @@ std::optional<float> selectReachableFloor(const std::optional<float>& terrainH,
|
|||
if (wmoH && *wmoH <= refZ + maxStepUp) reachWmo = wmoH;
|
||||
|
||||
// Avoid snapping up to higher WMO floors when entering buildings.
|
||||
if (reachTerrain && reachWmo && *reachWmo > refZ + 2.0f) {
|
||||
if (reachTerrain && reachWmo && *reachWmo > refZ + 3.5f) {
|
||||
return reachTerrain;
|
||||
}
|
||||
|
||||
|
|
@ -479,6 +479,11 @@ void CameraController::update(float deltaTime) {
|
|||
if (!walkable) {
|
||||
candidate.x = adjusted.x;
|
||||
candidate.y = adjusted.y;
|
||||
// Snap Z to floor at adjusted position to prevent fall-through
|
||||
auto adjFloor = wmoRenderer->getFloorHeight(adjusted.x, adjusted.y, feetZ + 2.5f);
|
||||
if (adjFloor && *adjFloor >= feetZ - 1.0f && *adjFloor <= feetZ + 1.6f) {
|
||||
candidate.z = *adjFloor;
|
||||
}
|
||||
} else if (floorH && *floorH > candidate.z) {
|
||||
// Snap Z to ramp surface so subsequent sweep
|
||||
// steps measure feetZ from the ramp, not the
|
||||
|
|
@ -611,8 +616,6 @@ void CameraController::update(float deltaTime) {
|
|||
// Skip entirely while swimming — the swim floor clamp handles vertical bounds.
|
||||
if (!swimming) {
|
||||
float stepUpBudget = grounded ? 1.6f : 1.2f;
|
||||
bool firstPerson = (!thirdPerson) || (currentDistance < 0.6f);
|
||||
|
||||
// 1. Center-only sample for terrain/WMO floor selection.
|
||||
// Using only the center prevents tunnel entrances from snapping
|
||||
// to terrain when offset samples miss the WMO floor geometry.
|
||||
|
|
@ -624,7 +627,7 @@ void CameraController::update(float deltaTime) {
|
|||
terrainH = terrainManager->getHeightAt(targetPos.x, targetPos.y);
|
||||
}
|
||||
float wmoProbeZ = std::max(targetPos.z, lastGroundZ) + stepUpBudget + 0.5f;
|
||||
if (wmoRenderer && !firstPerson) {
|
||||
if (wmoRenderer) {
|
||||
wmoH = wmoRenderer->getFloorHeight(targetPos.x, targetPos.y, wmoProbeZ);
|
||||
}
|
||||
groundH = selectReachableFloor(terrainH, wmoH, targetPos.z, stepUpBudget);
|
||||
|
|
|
|||
|
|
@ -1859,10 +1859,10 @@ bool WMORenderer::checkWallCollision(const glm::vec3& from, const glm::vec3& to,
|
|||
const auto& indices = group.collisionIndices;
|
||||
|
||||
// Use spatial grid: query range covering the movement segment + player radius
|
||||
float rangeMinX = std::min(localFrom.x, localTo.x) - PLAYER_RADIUS - 1.0f;
|
||||
float rangeMinY = std::min(localFrom.y, localTo.y) - PLAYER_RADIUS - 1.0f;
|
||||
float rangeMaxX = std::max(localFrom.x, localTo.x) + PLAYER_RADIUS + 1.0f;
|
||||
float rangeMaxY = std::max(localFrom.y, localTo.y) + PLAYER_RADIUS + 1.0f;
|
||||
float rangeMinX = std::min(localFrom.x, localTo.x) - PLAYER_RADIUS - 2.5f;
|
||||
float rangeMinY = std::min(localFrom.y, localTo.y) - PLAYER_RADIUS - 2.5f;
|
||||
float rangeMaxX = std::max(localFrom.x, localTo.x) + PLAYER_RADIUS + 2.5f;
|
||||
float rangeMaxY = std::max(localFrom.y, localTo.y) + PLAYER_RADIUS + 2.5f;
|
||||
group.getTrianglesInRange(rangeMinX, rangeMinY, rangeMaxX, rangeMaxY, wallTriScratch);
|
||||
|
||||
for (uint32_t triStart : wallTriScratch) {
|
||||
|
|
@ -1913,7 +1913,7 @@ bool WMORenderer::checkWallCollision(const glm::vec3& from, const glm::vec3& to,
|
|||
glm::vec3 hitPoint = localFrom + (localTo - localFrom) * tHit;
|
||||
glm::vec3 hitClosest = closestPointOnTriangle(hitPoint, v0, v1, v2);
|
||||
float hitErrSq = glm::dot(hitClosest - hitPoint, hitClosest - hitPoint);
|
||||
if (hitErrSq <= 0.04f * 0.04f) {
|
||||
if (hitErrSq <= 0.5f * 0.5f) {
|
||||
float side = fromDist > 0.0f ? 1.0f : -1.0f;
|
||||
glm::vec3 safeLocal = hitPoint + normal * side * (PLAYER_RADIUS + 0.05f);
|
||||
glm::vec3 safeWorld = glm::vec3(instance.modelMatrix * glm::vec4(safeLocal, 1.0f));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue