From 72e26d6b21d02a3f3459b1bdc6b50022d323a16e Mon Sep 17 00:00:00 2001 From: XProger Date: Wed, 30 Jan 2019 01:54:50 +0300 Subject: [PATCH] fix shadow intensity --- src/controller.h | 26 ++------------------------ src/format.h | 35 +++++++++++++++++++++++++++++++++++ src/level.h | 9 +++++++-- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/controller.h b/src/controller.h index 13168f3..60dff73 100644 --- a/src/controller.h +++ b/src/controller.h @@ -1271,40 +1271,18 @@ struct Controller { const TR::Room &room = getLightRoom(); targetLight = NULL; - int ambient = room.ambient; if (getEntity().intensity == -1) { + int ambient = room.ambient; if (room.lightsCount && getModel()) { - ambient = 0x1FFF - ambient; - int maxValue = 0; - vec3 center = getBoundingBox().center(); int x = int(center.x); int y = int(center.y); int z = int(center.z); - for (int i = 0; i < room.lightsCount; i++) { - TR::Room::Light &light = room.lights[i]; - - int dx = x - light.x; - int dy = y - light.y; - int dz = z - light.z; - - int D = (SQR(dx) + SQR(dy) + SQR(dz)) >> 12; - int R = SQR(light.radius >> 1) >> 12; - - int value = (light.intensity * R) / (D + R) + ambient; - - if (maxValue < value) { - targetLight = &room.lights[i]; - maxValue = value; - } - } - - ambient = (maxValue + ambient) / 2; - ambient = 0x1FFF - ambient; + ambient = room.getAmbient(x, y, z, &targetLight); } intensity = intensityf(ambient); diff --git a/src/format.h b/src/format.h index 80413a5..5c2cf81 100644 --- a/src/format.h +++ b/src/format.h @@ -1363,6 +1363,10 @@ namespace TR { return vec3(float(info.x), 0.0f, float(info.z)); } + vec3 getCenter() const { + return vec3(info.x + xSectors * 512.0f, (info.yBottom + info.yTop) * 0.5f, info.z + zSectors * 512.0f); + } + Sector* getSector(int sx, int sz) { if (sz <= 0 || sz >= zSectors - 1) { sz = clamp(sz, 0, zSectors - 1); @@ -1408,6 +1412,37 @@ namespace TR { break; } } + + int getAmbient(int x, int y, int z, Light **nearLight = NULL) const { + if (!lightsCount) { + return ambient; + } + + int ambientInv = 0x1FFF - ambient; + int maxValue = 0; + + for (int i = 0; i < lightsCount; i++) { + Light &light = lights[i]; + + int dx = x - light.x; + int dy = y - light.y; + int dz = z - light.z; + + int D = (SQR(dx) + SQR(dy) + SQR(dz)) >> 12; + int R = SQR(light.radius >> 1) >> 12; + + int value = (light.intensity * R) / (D + R) + ambientInv; + + if (maxValue < value) { + if (nearLight) { + *nearLight = &light; + } + maxValue = value; + } + } + + return 0x1FFF - (maxValue + ambientInv) / 2; + } }; union FloorData { diff --git a/src/level.h b/src/level.h index bd9de0c..c09e7a0 100644 --- a/src/level.h +++ b/src/level.h @@ -1584,9 +1584,14 @@ struct Level : IGame { continue; } - setRoomParams(roomIndex, Shader::ROOM, 1.0f, intensityf(level.rooms[roomIndex].ambient), 0.0f, 1.0f, transp == 1); + const TR::Room &room = level.rooms[roomIndex]; - basis.pos = level.rooms[roomIndex].getOffset(); + vec3 center = room.getCenter(); + int ambient = room.getAmbient(int(center.x), int(center.y), int(center.z)); + + setRoomParams(roomIndex, Shader::ROOM, 1.0f, intensityf(ambient), 0.0f, 1.0f, transp == 1); + + basis.pos = room.getOffset(); Core::setBasis(&basis, 1); Core::mModel.setPos(basis.pos);