Fix M2 interior lighting and carpet sliding

- M2 interior darkening now uses global player-inside-WMO flag instead
  of per-instance queries that were unreliable
- Fix carpet/rug sliding by skipping lateral collision push when player
  is standing on top of any stepable low object, not just platforms
This commit is contained in:
Kelsi 2026-02-07 17:05:30 -08:00
parent 84c3d1bf32
commit 2d2b9cc1fc
4 changed files with 10 additions and 17 deletions

View file

@ -64,6 +64,7 @@ public:
bool isRightMouseHeld() const { return rightMouseDown; }
bool isSitting() const { return sitting; }
bool isSwimming() const { return swimming; }
bool isInsideWMO() const { return cachedInsideWMO; }
const glm::vec3* getFollowTarget() const { return followTarget; }
glm::vec3* getFollowTargetMutable() { return followTarget; }

View file

@ -22,7 +22,6 @@ namespace rendering {
class Shader;
class Camera;
class WMORenderer;
/**
* GPU representation of an M2 model
@ -277,10 +276,10 @@ public:
}
void clearShadowMap() { shadowEnabled = false; }
void setWMORenderer(WMORenderer* wmo) { wmoRenderer = wmo; }
void setInsideInterior(bool inside) { insideInterior = inside; }
private:
WMORenderer* wmoRenderer = nullptr;
bool insideInterior = false;
pipeline::AssetManager* assetManager = nullptr;
std::unique_ptr<Shader> shader;

View file

@ -1,5 +1,4 @@
#include "rendering/m2_renderer.hpp"
#include "rendering/wmo_renderer.hpp"
#include "rendering/texture.hpp"
#include "rendering/shader.hpp"
#include "rendering/camera.hpp"
@ -1495,14 +1494,7 @@ void M2Renderer::render(const Camera& camera, const glm::mat4& view, const glm::
shader->setUniform("uModel", instance.modelMatrix);
shader->setUniform("uFadeAlpha", fadeAlpha);
// Dim M2 objects inside WMO interiors
bool interior = false;
if (wmoRenderer && entry.distSq < 200.0f * 200.0f) {
interior = wmoRenderer->isInsideInteriorWMO(
instance.position.x, instance.position.y, instance.position.z);
}
shader->setUniform("uInteriorDarken", interior);
shader->setUniform("uInteriorDarken", insideInterior);
// Upload bone matrices if model has skeletal animation
bool useBones = model.hasAnimation && !model.disableAnimation && !instance.boneMatrices.empty();
@ -2406,9 +2398,9 @@ bool M2Renderer::checkCollision(const glm::vec3& from, const glm::vec3& to,
if (allowEscapeRelax) {
continue;
}
if ((model.collisionSteppedLowPlatform || model.collisionSteppedFountain) && stepableLowObject) {
if (stepableLowObject && nearTop) {
// Already on/near top surface: don't apply lateral push that ejects
// the player from the object when landing.
// the player from the object (carpets, platforms, etc).
continue;
}
// Gentle fallback push for overlapping cases.

View file

@ -185,9 +185,6 @@ bool Renderer::initialize(core::Window* win) {
// Create M2 renderer (for doodads)
m2Renderer = std::make_unique<M2Renderer>();
if (wmoRenderer) {
m2Renderer->setWMORenderer(wmoRenderer.get());
}
// Note: M2 renderer needs asset manager, will be initialized when terrain loads
// Create zone manager
@ -1301,6 +1298,10 @@ void Renderer::renderWorld(game::World* world) {
// Render M2 doodads (trees, rocks, etc.)
if (m2Renderer && camera) {
// Dim M2 lighting when player is inside a WMO
if (cameraController) {
m2Renderer->setInsideInterior(cameraController->isInsideWMO());
}
auto m2Start = std::chrono::steady_clock::now();
m2Renderer->render(*camera, view, projection);
m2Renderer->renderSmokeParticles(*camera, view, projection);