Revert "Formatting pass"

This reverts commit 88a8ba24de.
This commit is contained in:
Sezz 2024-12-25 18:12:43 +11:00
parent 88a8ba24de
commit becd24da93
14 changed files with 209 additions and 199 deletions

View file

@ -461,8 +461,8 @@ static short NormalizeLookAroundTurnRate(short turnRate, short opticRange)
void HandlePlayerLookAround(ItemInfo& item, bool invertXAxis) void HandlePlayerLookAround(ItemInfo& item, bool invertXAxis)
{ {
constexpr auto TURN_RATE_MAX = ANGLE(4.0f); constexpr auto TURN_RATE_MAX = ANGLE(4.0f);
constexpr auto TURN_RATE_ACCEL = ANGLE(0.75f); constexpr auto TURN_RATE_ACCEL = ANGLE(0.75f);
auto& player = GetLaraInfo(item); auto& player = GetLaraInfo(item);

View file

@ -4,25 +4,20 @@
#include "Game/camera.h" #include "Game/camera.h"
#include "Game/control/los.h" #include "Game/control/los.h"
#include "Game/effects/effects.h" #include "Game/effects/effects.h"
#include "Game/items.h"
#include "Game/Lara/lara.h" #include "Game/Lara/lara.h"
#include "Game/Lara/lara_flare.h" #include "Game/Lara/lara_flare.h"
#include "Game/Lara/lara_helpers.h" #include "Game/Lara/lara_helpers.h"
#include "Game/Lara/lara_one_gun.h"
#include "Game/Lara/lara_struct.h" #include "Game/Lara/lara_struct.h"
#include "Game/Lara/lara_one_gun.h"
#include "Game/Lara/lara_two_guns.h" #include "Game/Lara/lara_two_guns.h"
#include "Specific/Input/Input.h"
#include "Game/Setup.h" #include "Game/Setup.h"
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Specific/Input/Input.h"
using namespace TEN::Input; using namespace TEN::Input;
static void HandlePlayerOpticZoom(ItemInfo& item) static void HandlePlayerOpticZoom(ItemInfo& item)
{ {
constexpr auto OPTICS_RANGE_MAX = ANGLE(8.5f);
constexpr auto OPTICS_RANGE_MIN = ANGLE(0.7f);
constexpr auto OPTICS_RANGE_RATE = ANGLE(0.35f);
auto& player = GetLaraInfo(item); auto& player = GetLaraInfo(item);
bool isSlow = IsHeld(In::Walk); bool isSlow = IsHeld(In::Walk);
@ -69,6 +64,7 @@ static void HandlePlayerOpticAnimations(ItemInfo& item)
return; return;
int animNumber = Objects[ID_LARA_BINOCULARS_MESH].loaded ? LA_BINOCULARS_IDLE : LA_STAND_IDLE; int animNumber = Objects[ID_LARA_BINOCULARS_MESH].loaded ? LA_BINOCULARS_IDLE : LA_STAND_IDLE;
if (player.Control.Look.IsUsingLasersight) if (player.Control.Look.IsUsingLasersight)
{ {
switch (player.Control.Weapon.GunType) switch (player.Control.Weapon.GunType)
@ -99,8 +95,7 @@ static void HandlePlayerOpticAnimations(ItemInfo& item)
player.Torch.IsLit = false; player.Torch.IsLit = false;
player.Flare.ControlLeft = false; player.Flare.ControlLeft = false;
player.Flare.Life = 0; player.Flare.Life = 0;
player.Control.Weapon.GunType = player.Control.Weapon.GunType = player.Control.Weapon.RequestGunType = player.Control.Weapon.LastGunType;
player.Control.Weapon.RequestGunType = player.Control.Weapon.LastGunType;
} }
else if (player.Control.Weapon.GunType != LaraWeaponType::None && else if (player.Control.Weapon.GunType != LaraWeaponType::None &&
player.Control.HandStatus != HandStatus::Free) player.Control.HandStatus != HandStatus::Free)
@ -129,14 +124,10 @@ static void HandlePlayerOpticAnimations(ItemInfo& item)
player.Control.HandStatus = HandStatus::Free; player.Control.HandStatus = HandStatus::Free;
} }
player.LeftArm.Locked = player.LeftArm.Locked = player.RightArm.Locked = false;
player.RightArm.Locked = false; player.LeftArm.FrameNumber = player.RightArm.FrameNumber = 0;
player.LeftArm.FrameNumber = player.LeftArm.AnimNumber = player.RightArm.AnimNumber = animNumber;
player.RightArm.FrameNumber = 0; player.LeftArm.FrameBase = player.RightArm.FrameBase = GetAnimData(animNumber).FramePtr;
player.LeftArm.AnimNumber =
player.RightArm.AnimNumber = animNumber;
player.LeftArm.FrameBase =
player.RightArm.FrameBase = GetAnimData(animNumber).FramePtr;
} }
static void ResetPlayerOpticAnimations(ItemInfo& item) static void ResetPlayerOpticAnimations(ItemInfo& item)
@ -145,14 +136,10 @@ static void ResetPlayerOpticAnimations(ItemInfo& item)
ResetPlayerFlex(&item); ResetPlayerFlex(&item);
player.LeftArm.Locked = player.LeftArm.Locked = player.RightArm.Locked = false;
player.RightArm.Locked = false; player.LeftArm.AnimNumber = player.RightArm.AnimNumber = 0;
player.LeftArm.AnimNumber = player.LeftArm.FrameNumber = player.RightArm.FrameNumber = 0;
player.RightArm.AnimNumber = 0; player.RightArm.FrameBase = player.LeftArm.FrameBase = GetAnimData(item).FramePtr;
player.LeftArm.FrameNumber =
player.RightArm.FrameNumber = 0;
player.RightArm.FrameBase =
player.LeftArm.FrameBase = GetAnimData(item).FramePtr;
player.Control.HandStatus = player.Control.Look.IsUsingLasersight ? HandStatus::WeaponReady : HandStatus::Free; player.Control.HandStatus = player.Control.Look.IsUsingLasersight ? HandStatus::WeaponReady : HandStatus::Free;
if (!player.Control.Look.IsUsingLasersight) if (!player.Control.Look.IsUsingLasersight)
@ -169,31 +156,32 @@ static void ResetPlayerOpticAnimations(ItemInfo& item)
SetScreenFadeIn(OPTICS_FADE_SPEED); SetScreenFadeIn(OPTICS_FADE_SPEED);
} }
static void DoOpticsHighlight(const ItemInfo& item, const Vector3i& origin, const Vector3i& target) static void DoOpticsHighlight(const ItemInfo& item, Vector3i* origin, Vector3i* target)
{ {
auto origin2 = GameVector(origin, item.RoomNumber); auto pos1 = GameVector(*origin, item.RoomNumber);
auto target2 = GameVector(target); auto pos2 = GameVector(*target);
const auto& binocularsColor = g_GameFlow->GetSettings()->Camera.BinocularLightColor; const auto& binocularColor = g_GameFlow->GetSettings()->Camera.BinocularLightColor;
const auto& lasersightColor = g_GameFlow->GetSettings()->Camera.LasersightLightColor; const auto& lasersightColor = g_GameFlow->GetSettings()->Camera.LasersightLightColor;
const auto& color = GetLaraInfo(item).Control.Look.IsUsingLasersight ? lasersightColor : binocularsColor; const auto& color = GetLaraInfo(item).Control.Look.IsUsingLasersight ? lasersightColor : binocularColor;
TriggerDynamicLight(origin2.x, origin2.y, origin2.z, 12, color.GetR(), color.GetG(), color.GetB()); TriggerDynamicLight(pos1.x, pos1.y, pos1.z, 12, color.GetR(), color.GetG(), color.GetB());
if (!LOS(&origin2, &target2)) if (!LOS(&pos1, &pos2))
{ {
int luma = sqrt(SQUARE(origin2.x - target2.x) + SQUARE(origin2.y - target2.y) + SQUARE(origin2.z - target2.z)) * CLICK(1); int l = sqrt(pow(pos1.x - pos2.x, 2) + pow(pos1.y - pos2.y, 2) + pow(pos1.z - pos2.z, 2)) * CLICK(1);
if ((luma + 8) > 31)
luma = 31;
auto dir = origin2.ToVector3() - target2.ToVector3(); if (l + 8 > 31)
l = 31;
auto dir = pos1.ToVector3() - pos2.ToVector3();
dir.Normalize(); dir.Normalize();
dir *= BLOCK(1); dir *= BLOCK(1);
byte r = std::max(0, color.GetR() - luma); byte r = std::max(0, color.GetR() - l);
byte g = std::max(0, color.GetG() - luma); byte g = std::max(0, color.GetG() - l);
byte b = std::max(0, color.GetB() - luma); byte b = std::max(0, color.GetB() - l);
TriggerDynamicLight(target2.x + dir.x, target2.y + dir.y, target2.z + dir.z, luma + 12, r, g, b); TriggerDynamicLight(pos2.x + dir.x, pos2.y + dir.y, pos2.z + dir.z, l + 12, r, g, b);
} }
} }
@ -269,7 +257,7 @@ bool HandlePlayerOptics(ItemInfo& item)
auto origin = Camera.pos.ToVector3i(); auto origin = Camera.pos.ToVector3i();
auto target = Camera.target.ToVector3i(); auto target = Camera.target.ToVector3i();
DoOpticsHighlight(item, origin, target); DoOpticsHighlight(item, &origin, &target);
} }
if (!breakOptics) if (!breakOptics)
@ -283,4 +271,4 @@ bool HandlePlayerOptics(ItemInfo& item)
ResetPlayerOpticAnimations(item); ResetPlayerOpticAnimations(item);
return false; return false;
} }
} }

View file

@ -1,10 +1,12 @@
#pragma once #pragma once
#include "Specific/clock.h" #include "Specific/clock.h"
struct ItemInfo; struct ItemInfo;
constexpr auto OPTICS_FADE_SPEED = 6.0f / FPS; constexpr auto OPTICS_FADE_SPEED = 6.0f / FPS;
constexpr auto OPTICS_RANGE_DEFAULT = ANGLE(0.7f); constexpr auto OPTICS_RANGE_DEFAULT = ANGLE(0.7f);
constexpr auto OPTICS_RANGE_MIN = ANGLE(0.7f);
constexpr auto OPTICS_RANGE_MAX = ANGLE(8.5f);
constexpr auto OPTICS_RANGE_RATE = ANGLE(0.35f);
bool HandlePlayerOptics(ItemInfo& item); bool HandlePlayerOptics(ItemInfo& item);

View file

@ -46,15 +46,15 @@ namespace TEN::Renderer
RenderViewCamera Camera; RenderViewCamera Camera;
D3D11_VIEWPORT Viewport; D3D11_VIEWPORT Viewport;
std::vector<RendererRoom*> RoomsToDraw = {}; std::vector<RendererRoom*> RoomsToDraw = {};
std::vector<RendererLight*> LightsToDraw = {}; std::vector<RendererLight*> LightsToDraw = {};
std::vector<RendererFogBulb> FogBulbsToDraw = {}; std::vector<RendererFogBulb> FogBulbsToDraw = {};
std::vector<RendererSpriteToDraw> SpritesToDraw = {}; std::vector<RendererSpriteToDraw> SpritesToDraw = {};
std::vector<RendererDisplaySpriteToDraw> DisplaySpritesToDraw = {}; std::vector<RendererDisplaySpriteToDraw> DisplaySpritesToDraw = {};
std::map<int, std::vector<RendererStatic*>> SortedStaticsToDraw = {}; std::map<int, std::vector<RendererStatic*>> SortedStaticsToDraw = {};
std::vector<RendererSortableObject> TransparentObjectsToDraw = {}; std::vector<RendererSortableObject> TransparentObjectsToDraw = {};
std::vector<RendererLensFlare> LensFlaresToDraw = {}; std::vector<RendererLensFlare> LensFlaresToDraw = {};
std::vector<RendererMirror> Mirrors = {}; std::vector<RendererMirror> Mirrors = {};
RenderView(CAMERA_INFO* cam, float roll, float fov, float nearPlane, float farPlane, int w, int h); RenderView(CAMERA_INFO* cam, float roll, float fov, float nearPlane, float farPlane, int w, int h);
RenderView(const Vector3& pos, const Vector3& dir, const Vector3& up, int w, int h, int room, float nearPlane, float farPlane, float fov); RenderView(const Vector3& pos, const Vector3& dir, const Vector3& up, int w, int h, int room, float nearPlane, float farPlane, float fov);

View file

@ -565,11 +565,11 @@ namespace TEN::Renderer
void CreateSSAONoiseTexture(); void CreateSSAONoiseTexture();
void InitializeSMAA(); void InitializeSMAA();
bool IsRoomReflected(RenderView& renderView, int roomNumber); bool RoomIsReflected(RenderView& renderView, int roomNumber);
inline bool IgnoreReflectionPassForRoom(int roomNumber) inline bool IgnoreReflectionPassForRoom(int room)
{ {
return (_currentMirror != nullptr && roomNumber != _currentMirror->RoomNumber); return (_currentMirror != nullptr && room != _currentMirror->RoomNumber);
} }
inline void ReflectVectorOptionally(Vector3& vector) inline void ReflectVectorOptionally(Vector3& vector)

View file

@ -561,9 +561,9 @@ namespace TEN::Renderer
if (rat->On) if (rat->On)
{ {
auto* mesh = GetMesh(Objects[ID_RATS_EMITTER].meshIndex + (rand() % 8)); RendererMesh* mesh = GetMesh(Objects[ID_RATS_EMITTER].meshIndex + (rand() % 8));
auto world = rat->Transform; Matrix world = rat->Transform;
ReflectMatrixOptionally(world); ReflectMatrixOptionally(world);
_stStatic.World = world; _stStatic.World = world;
@ -571,7 +571,9 @@ namespace TEN::Renderer
_stStatic.AmbientLight = _rooms[rat->RoomNumber].AmbientLight; _stStatic.AmbientLight = _rooms[rat->RoomNumber].AmbientLight;
if (rendererPass != RendererPass::GBuffer) if (rendererPass != RendererPass::GBuffer)
{
BindStaticLights(_rooms[rat->RoomNumber].LightsToDraw); BindStaticLights(_rooms[rat->RoomNumber].LightsToDraw);
}
_cbStatic.UpdateData(_stStatic, _context.Get()); _cbStatic.UpdateData(_stStatic, _context.Get());
@ -777,7 +779,7 @@ namespace TEN::Renderer
auto transformMatrix = Matrix::Lerp(bat.PrevTransform, bat.Transform, GetInterpolationFactor()); auto transformMatrix = Matrix::Lerp(bat.PrevTransform, bat.Transform, GetInterpolationFactor());
auto world = transformMatrix; Matrix world = transformMatrix;
ReflectMatrixOptionally(world); ReflectMatrixOptionally(world);
_stInstancedStaticMeshBuffer.StaticMeshes[batCount].World = world; _stInstancedStaticMeshBuffer.StaticMeshes[batCount].World = world;
@ -899,7 +901,7 @@ namespace TEN::Renderer
auto transformMatrix = Matrix::Lerp(beetle.PrevTransform, beetle.Transform, GetInterpolationFactor()); auto transformMatrix = Matrix::Lerp(beetle.PrevTransform, beetle.Transform, GetInterpolationFactor());
auto world = transformMatrix; Matrix world = transformMatrix;
ReflectMatrixOptionally(world); ReflectMatrixOptionally(world);
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].World = world; _stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].World = world;
@ -1056,7 +1058,7 @@ namespace TEN::Renderer
auto& mesh = *GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust.counter & 3)); auto& mesh = *GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust.counter & 3));
auto world = Matrix::Lerp(locust.PrevTransform, locust.Transform, GetInterpolationFactor()); Matrix world = Matrix::Lerp(locust.PrevTransform, locust.Transform, GetInterpolationFactor());
ReflectMatrixOptionally(world); ReflectMatrixOptionally(world);
_stStatic.World = world; _stStatic.World = world;
@ -1596,7 +1598,7 @@ namespace TEN::Renderer
if (_isLocked || g_GameFlow->LastFreezeMode != FreezeMode::None) if (_isLocked || g_GameFlow->LastFreezeMode != FreezeMode::None)
return; return;
auto dynamicLight = RendererLight{}; RendererLight dynamicLight = {};
dynamicLight.Color = Vector3(color.x, color.y, color.z); dynamicLight.Color = Vector3(color.x, color.y, color.z);
if (radius < BLOCK(2)) if (radius < BLOCK(2))
@ -1618,23 +1620,22 @@ namespace TEN::Renderer
void Renderer::PrepareDynamicLight(RendererLight& light) void Renderer::PrepareDynamicLight(RendererLight& light)
{ {
// If hash is provided, search for same light in previous buffer. // If hash is provided, search for same light in old buffer.
if (light.Hash != 0) if (light.Hash != 0)
{ {
// Determine previous buffer index. // Determine the previous buffer index.
const auto& prevList = _dynamicLights[1 - _dynamicLightList]; const auto& previousList = _dynamicLights[1 - _dynamicLightList];
// Find light in previous buffer with same hash. // Find a light in the previous buffer with the same Hash.
auto it = std::find_if( auto it = std::find_if(previousList.begin(), previousList.end(),
prevList.begin(), prevList.end(),
[&light](const auto& prevLight) [&light](const auto& prevLight)
{ {
return (prevLight.Hash == light.Hash); return prevLight.Hash == light.Hash;
}); });
if (it != prevList.end()) if (it != previousList.end())
{ {
// If matching light is found, copy it. // If a matching light is found, copy its data.
const auto& prevLight = *it; const auto& prevLight = *it;
light.PrevPosition = prevLight.Position; light.PrevPosition = prevLight.Position;
light.PrevDirection = prevLight.Direction; light.PrevDirection = prevLight.Direction;
@ -1644,17 +1645,16 @@ namespace TEN::Renderer
// Queue dynamic light. // Queue dynamic light.
_dynamicLights[_dynamicLightList].push_back(light); _dynamicLights[_dynamicLightList].push_back(light);
// Check if light is spawned in mirrored room and create reflection. // Check if light is spawned in a mirrored room, and create reflection.
for (const auto& mirror : g_Level.Mirrors) for (auto& mirror : g_Level.Mirrors)
{ {
if (!mirror.ReflectLights) if (!mirror.ReflectLights)
continue; continue;
// TODO: Avoid LaraItem global.
if ((Camera.pos.RoomNumber == mirror.RoomNumber || LaraItem->RoomNumber == mirror.RoomNumber) && if ((Camera.pos.RoomNumber == mirror.RoomNumber || LaraItem->RoomNumber == mirror.RoomNumber) &&
IsPointInRoom(light.Position, mirror.RoomNumber)) IsPointInRoom(light.Position, mirror.RoomNumber))
{ {
auto reflectedLight = light; RendererLight reflectedLight = light;
reflectedLight.Position = Vector3::Transform(light.Position, mirror.ReflectionMatrix); reflectedLight.Position = Vector3::Transform(light.Position, mirror.ReflectionMatrix);
reflectedLight.Direction = Vector3::Transform(light.Direction, mirror.ReflectionMatrix); reflectedLight.Direction = Vector3::Transform(light.Direction, mirror.ReflectionMatrix);
reflectedLight.Hash = 0; reflectedLight.Hash = 0;
@ -1886,7 +1886,7 @@ namespace TEN::Renderer
SortTransparentFaces(view); SortTransparentFaces(view);
DoRenderPass(RendererPass::Transparent, view, true); DoRenderPass(RendererPass::Transparent, view, true);
DoRenderPass(RendererPass::GunFlashes, view, true); // HACK: Gunflashes are drawn after everything because they are near camera. DoRenderPass(RendererPass::GunFlashes, view, true); // HACK: Gunflashes are drawn after everything because they are near the camera.
// Draw 3D debug lines and triangles. // Draw 3D debug lines and triangles.
DrawLines3D(view); DrawLines3D(view);
@ -2192,7 +2192,7 @@ namespace TEN::Renderer
SetCullMode(CullMode::CounterClockwise); SetCullMode(CullMode::CounterClockwise);
SetDepthState(DepthState::Write); SetDepthState(DepthState::Write);
// Draw room geometry first if applicable for a given pass. // Draw room geometry first, if applicable for a given pass.
if (pass != RendererPass::Transparent && pass != RendererPass::GunFlashes) if (pass != RendererPass::Transparent && pass != RendererPass::GunFlashes)
DrawRooms(view, pass); DrawRooms(view, pass);
@ -2206,10 +2206,9 @@ namespace TEN::Renderer
for (auto& mirror : view.Mirrors) for (auto& mirror : view.Mirrors)
{ {
_currentMirror = &mirror; _currentMirror = &mirror;
DrawObjects(pass, view, mirror.ReflectPlayer, mirror.ReflectMoveables, mirror.ReflectStatics, mirror.ReflectSprites); DrawObjects(pass, view, mirror.ReflectLara, mirror.ReflectMoveables, mirror.ReflectStatics, mirror.ReflectSprites);
_currentMirror = nullptr; _currentMirror = nullptr;
} }
SetCullMode(CullMode::CounterClockwise); SetCullMode(CullMode::CounterClockwise);
} }
} }
@ -2252,7 +2251,7 @@ namespace TEN::Renderer
DrawDebris(view, pass); // Debris mostly originate from shatter statics. DrawDebris(view, pass); // Debris mostly originate from shatter statics.
} }
// Sorted sprites already collected at beginning of frame. // Sorted sprites are already collected at the beginning of frame.
if (sprites && pass != RendererPass::CollectTransparentFaces) if (sprites && pass != RendererPass::CollectTransparentFaces)
DrawSprites(view, pass); DrawSprites(view, pass);
@ -2513,14 +2512,14 @@ namespace TEN::Renderer
for (auto it = view.SortedStaticsToDraw.begin(); it != view.SortedStaticsToDraw.end(); it++) for (auto it = view.SortedStaticsToDraw.begin(); it != view.SortedStaticsToDraw.end(); it++)
{ {
auto statics = it->second; std::vector<RendererStatic*> statics = it->second;
auto* refStatic = statics[0]; RendererStatic* refStatic = statics[0];
auto& refStaticObj = GetStaticRendererObject(refStatic->ObjectNumber); RendererObject& refStaticObj = GetStaticRendererObject(refStatic->ObjectNumber);
if (refStaticObj.ObjectMeshes.size() == 0) if (refStaticObj.ObjectMeshes.size() == 0)
continue; continue;
auto* refMesh = refStaticObj.ObjectMeshes[0]; RendererMesh* refMesh = refStaticObj.ObjectMeshes[0];
int staticsCount = (int)statics.size(); int staticsCount = (int)statics.size();
int bucketSize = INSTANCED_STATIC_MESH_BUCKET_SIZE; int bucketSize = INSTANCED_STATIC_MESH_BUCKET_SIZE;
@ -2533,13 +2532,13 @@ namespace TEN::Renderer
for (int s = baseStaticIndex; s < max; s++) for (int s = baseStaticIndex; s < max; s++)
{ {
auto* current = statics[s]; RendererStatic* current = statics[s];
auto* room = &_rooms[current->RoomNumber]; RendererRoom* room = &_rooms[current->RoomNumber];
if (IgnoreReflectionPassForRoom(current->RoomNumber)) if (IgnoreReflectionPassForRoom(current->RoomNumber))
continue; continue;
auto world = current->World; Matrix world = current->World;
ReflectMatrixOptionally(world); ReflectMatrixOptionally(world);
_stInstancedStaticMeshBuffer.StaticMeshes[instancesCount].World = world; _stInstancedStaticMeshBuffer.StaticMeshes[instancesCount].World = world;
@ -2548,7 +2547,9 @@ namespace TEN::Renderer
_stInstancedStaticMeshBuffer.StaticMeshes[instancesCount].LightMode = (int)refMesh->LightMode; _stInstancedStaticMeshBuffer.StaticMeshes[instancesCount].LightMode = (int)refMesh->LightMode;
if (rendererPass != RendererPass::GBuffer) if (rendererPass != RendererPass::GBuffer)
{
BindInstancedStaticLights(current->LightsToDraw, instancesCount); BindInstancedStaticLights(current->LightsToDraw, instancesCount);
}
instancesCount++; instancesCount++;
} }
@ -2559,16 +2560,21 @@ namespace TEN::Renderer
{ {
_cbInstancedStaticMeshBuffer.UpdateData(_stInstancedStaticMeshBuffer, _context.Get()); _cbInstancedStaticMeshBuffer.UpdateData(_stInstancedStaticMeshBuffer, _context.Get());
for (const auto& bucket : refMesh->Buckets) for (auto& bucket : refMesh->Buckets)
{ {
if (bucket.NumVertices == 0) if (bucket.NumVertices == 0)
{
continue; continue;
}
int passes = rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1; int passes = rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1;
for (int p = 0; p < passes; p++) for (int p = 0; p < passes; p++)
{ {
if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p)) if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p))
{
continue; continue;
}
BindTexture(TextureRegister::ColorMap, BindTexture(TextureRegister::ColorMap,
&std::get<0>(_staticTextures[bucket.Texture]), &std::get<0>(_staticTextures[bucket.Texture]),
@ -2588,17 +2594,18 @@ namespace TEN::Renderer
} }
else else
{ {
// Collect sorted blend modes faces ordered by room if doing transparent pass. // Collect sorted blend modes faces ordered by room, if transparent pass
for (auto it = view.SortedStaticsToDraw.begin(); it != view.SortedStaticsToDraw.end(); it++) for (auto it = view.SortedStaticsToDraw.begin(); it != view.SortedStaticsToDraw.end(); it++)
{ {
auto statics = it->second; std::vector<RendererStatic*> statics = it->second;
auto* refStatic = statics[0]; RendererStatic* refStatic = statics[0];
auto& refStaticObj = GetStaticRendererObject(refStatic->ObjectNumber); RendererObject& refStaticObj = GetStaticRendererObject(refStatic->ObjectNumber);
if (refStaticObj.ObjectMeshes.size() == 0) if (refStaticObj.ObjectMeshes.size() == 0)
continue; continue;
auto* refMesh = refStaticObj.ObjectMeshes[0]; RendererMesh* refMesh = refStaticObj.ObjectMeshes[0];
for (int i = 0; i < statics.size(); i++) for (int i = 0; i < statics.size(); i++)
{ {
@ -2607,13 +2614,15 @@ namespace TEN::Renderer
auto& bucket = refMesh->Buckets[j]; auto& bucket = refMesh->Buckets[j];
if (bucket.NumVertices == 0) if (bucket.NumVertices == 0)
{
continue; continue;
}
if (IsSortedBlendMode(bucket.BlendMode)) if (IsSortedBlendMode(bucket.BlendMode))
{ {
for (int p = 0; p < bucket.Polygons.size(); p++) for (int p = 0; p < bucket.Polygons.size(); p++)
{ {
auto object = RendererSortableObject{}; RendererSortableObject object;
object.ObjectType = RendererObjectType::Static; object.ObjectType = RendererObjectType::Static;
object.Bucket = &bucket; object.Bucket = &bucket;
@ -3292,8 +3301,8 @@ namespace TEN::Renderer
{ {
for (int i = 0; i < view.TransparentObjectsToDraw.size(); i++) for (int i = 0; i < view.TransparentObjectsToDraw.size(); i++)
{ {
auto* object = &view.TransparentObjectsToDraw[i]; RendererSortableObject* object = &view.TransparentObjectsToDraw[i];
auto lastObjectType = (i > 0 ? view.TransparentObjectsToDraw[i - 1].ObjectType : RendererObjectType::Unknown); RendererObjectType lastObjectType = (i > 0 ? view.TransparentObjectsToDraw[i - 1].ObjectType : RendererObjectType::Unknown);
_sortedPolygonsVertices.clear(); _sortedPolygonsVertices.clear();
_sortedPolygonsIndices.clear(); _sortedPolygonsIndices.clear();
@ -3310,7 +3319,7 @@ namespace TEN::Renderer
view.TransparentObjectsToDraw[i].Bucket->BlendMode == object->Bucket->BlendMode && view.TransparentObjectsToDraw[i].Bucket->BlendMode == object->Bucket->BlendMode &&
_sortedPolygonsIndices.size() + (view.TransparentObjectsToDraw[i].Polygon->Shape == 0 ? 6 : 3) < MAX_TRANSPARENT_VERTICES) _sortedPolygonsIndices.size() + (view.TransparentObjectsToDraw[i].Polygon->Shape == 0 ? 6 : 3) < MAX_TRANSPARENT_VERTICES)
{ {
auto* currentObject = &view.TransparentObjectsToDraw[i]; RendererSortableObject* currentObject = &view.TransparentObjectsToDraw[i];
_sortedPolygonsIndices.bulk_push_back( _sortedPolygonsIndices.bulk_push_back(
_roomsIndices.data(), _roomsIndices.data(),
currentObject->Polygon->BaseIndex, currentObject->Polygon->BaseIndex,
@ -3321,7 +3330,9 @@ namespace TEN::Renderer
DrawRoomSorted(object, lastObjectType, view); DrawRoomSorted(object, lastObjectType, view);
if (i == view.TransparentObjectsToDraw.size()) if (i == view.TransparentObjectsToDraw.size())
{
return; return;
}
i--; i--;
} }
@ -3334,7 +3345,7 @@ namespace TEN::Renderer
view.TransparentObjectsToDraw[i].Bucket->BlendMode == object->Bucket->BlendMode && view.TransparentObjectsToDraw[i].Bucket->BlendMode == object->Bucket->BlendMode &&
_sortedPolygonsIndices.size() + (view.TransparentObjectsToDraw[i].Polygon->Shape == 0 ? 6 : 3) < MAX_TRANSPARENT_VERTICES) _sortedPolygonsIndices.size() + (view.TransparentObjectsToDraw[i].Polygon->Shape == 0 ? 6 : 3) < MAX_TRANSPARENT_VERTICES)
{ {
auto* currentObject = &view.TransparentObjectsToDraw[i]; RendererSortableObject* currentObject = &view.TransparentObjectsToDraw[i];
_sortedPolygonsIndices.bulk_push_back( _sortedPolygonsIndices.bulk_push_back(
_moveablesIndices.data(), _moveablesIndices.data(),
currentObject->Polygon->BaseIndex, currentObject->Polygon->BaseIndex,
@ -3345,7 +3356,9 @@ namespace TEN::Renderer
DrawItemSorted(object, lastObjectType, view); DrawItemSorted(object, lastObjectType, view);
if (i == view.TransparentObjectsToDraw.size()) if (i == view.TransparentObjectsToDraw.size())
{
return; return;
}
i--; i--;
} }
@ -3359,7 +3372,7 @@ namespace TEN::Renderer
view.TransparentObjectsToDraw[i].Bucket->BlendMode == object->Bucket->BlendMode && view.TransparentObjectsToDraw[i].Bucket->BlendMode == object->Bucket->BlendMode &&
_sortedPolygonsIndices.size() + (view.TransparentObjectsToDraw[i].Polygon->Shape == 0 ? 6 : 3) < MAX_TRANSPARENT_VERTICES) _sortedPolygonsIndices.size() + (view.TransparentObjectsToDraw[i].Polygon->Shape == 0 ? 6 : 3) < MAX_TRANSPARENT_VERTICES)
{ {
auto* currentObject = &view.TransparentObjectsToDraw[i]; RendererSortableObject* currentObject = &view.TransparentObjectsToDraw[i];
_sortedPolygonsIndices.bulk_push_back( _sortedPolygonsIndices.bulk_push_back(
_staticsIndices.data(), _staticsIndices.data(),
currentObject->Polygon->BaseIndex, currentObject->Polygon->BaseIndex,
@ -3370,7 +3383,9 @@ namespace TEN::Renderer
DrawStaticSorted(object, lastObjectType, view); DrawStaticSorted(object, lastObjectType, view);
if (i == view.TransparentObjectsToDraw.size()) if (i == view.TransparentObjectsToDraw.size())
{
return; return;
}
i--; i--;
} }
@ -3383,7 +3398,7 @@ namespace TEN::Renderer
view.TransparentObjectsToDraw[i].Bucket->BlendMode == object->Bucket->BlendMode && view.TransparentObjectsToDraw[i].Bucket->BlendMode == object->Bucket->BlendMode &&
_sortedPolygonsIndices.size() + (view.TransparentObjectsToDraw[i].Polygon->Shape == 0 ? 6 : 3) < MAX_TRANSPARENT_VERTICES) _sortedPolygonsIndices.size() + (view.TransparentObjectsToDraw[i].Polygon->Shape == 0 ? 6 : 3) < MAX_TRANSPARENT_VERTICES)
{ {
auto* currentObject = &view.TransparentObjectsToDraw[i]; RendererSortableObject* currentObject = &view.TransparentObjectsToDraw[i];
_sortedPolygonsIndices.bulk_push_back( _sortedPolygonsIndices.bulk_push_back(
_staticsIndices.data(), _staticsIndices.data(),
currentObject->Polygon->BaseIndex, currentObject->Polygon->BaseIndex,
@ -3394,7 +3409,9 @@ namespace TEN::Renderer
DrawMoveableAsStaticSorted(object, lastObjectType, view); DrawMoveableAsStaticSorted(object, lastObjectType, view);
if (i == view.TransparentObjectsToDraw.size()) if (i == view.TransparentObjectsToDraw.size())
{
return; return;
}
i--; i--;
} }
@ -3443,7 +3460,7 @@ namespace TEN::Renderer
uv2 = spr->Sprite->UV[2]; uv2 = spr->Sprite->UV[2];
uv3 = spr->Sprite->UV[3]; uv3 = spr->Sprite->UV[3];
auto world = GetWorldMatrixForSprite(currentObject->Sprite, view); Matrix world = GetWorldMatrixForSprite(currentObject->Sprite, view);
Vertex v0; Vertex v0;
v0.Position = Vector3::Transform(p0t, world); v0.Position = Vector3::Transform(p0t, world);
@ -3620,7 +3637,7 @@ namespace TEN::Renderer
BindShader(_sStatics); BindShader(_sStatics);
auto world = objectInfo->Static->World; Matrix world = objectInfo->Static->World;
_stStatic.World = world; _stStatic.World = world;
_stStatic.Color = objectInfo->Static->Color; _stStatic.Color = objectInfo->Static->Color;
@ -3658,7 +3675,7 @@ namespace TEN::Renderer
BindShader(_sStatics); BindShader(_sStatics);
auto world = objectInfo->World; Matrix world = objectInfo->World;
_stStatic.World = world; _stStatic.World = world;
_stStatic.Color = Vector4::One; _stStatic.Color = Vector4::One;

View file

@ -1285,23 +1285,19 @@ namespace TEN::Renderer
auto spriteMatrix = Matrix::Identity; auto spriteMatrix = Matrix::Identity;
auto scaleMatrix = Matrix::CreateScale(sprite->Width * sprite->Scale, sprite->Height * sprite->Scale, sprite->Scale); auto scaleMatrix = Matrix::CreateScale(sprite->Width * sprite->Scale, sprite->Height * sprite->Scale, sprite->Scale);
auto spritePos = sprite->pos; Vector3 spritePosition = sprite->pos;
if (sprite->Type == SpriteType::ThreeD) if (sprite->Type == SpriteType::ThreeD)
{
ReflectMatrixOptionally(spriteMatrix); ReflectMatrixOptionally(spriteMatrix);
}
else else
{ ReflectVectorOptionally(spritePosition);
ReflectVectorOptionally(spritePos);
}
switch (sprite->Type) switch (sprite->Type)
{ {
case SpriteType::Billboard: case SpriteType::Billboard:
{ {
auto cameraUp = Vector3(view.Camera.View._12, view.Camera.View._22, view.Camera.View._32); auto cameraUp = Vector3(view.Camera.View._12, view.Camera.View._22, view.Camera.View._32);
spriteMatrix = scaleMatrix * Matrix::CreateRotationZ(sprite->Rotation) * Matrix::CreateBillboard(spritePos, Camera.pos.ToVector3(), cameraUp); spriteMatrix = scaleMatrix * Matrix::CreateRotationZ(sprite->Rotation) * Matrix::CreateBillboard(spritePosition, Camera.pos.ToVector3(), cameraUp);
} }
break; break;
@ -1310,7 +1306,7 @@ namespace TEN::Renderer
auto rotMatrix = Matrix::CreateRotationY(sprite->Rotation); auto rotMatrix = Matrix::CreateRotationY(sprite->Rotation);
auto quadForward = Vector3(0.0f, 0.0f, 1.0f); auto quadForward = Vector3(0.0f, 0.0f, 1.0f);
spriteMatrix = scaleMatrix * Matrix::CreateConstrainedBillboard( spriteMatrix = scaleMatrix * Matrix::CreateConstrainedBillboard(
spritePos, spritePosition,
Camera.pos.ToVector3(), Camera.pos.ToVector3(),
sprite->ConstrainAxis, sprite->ConstrainAxis,
nullptr, nullptr,
@ -1320,9 +1316,9 @@ namespace TEN::Renderer
case SpriteType::LookAtBillboard: case SpriteType::LookAtBillboard:
{ {
auto translationMatrix = Matrix::CreateTranslation(spritePos); auto tMatrix = Matrix::CreateTranslation(spritePosition);
auto rotMatrix = Matrix::CreateRotationZ(sprite->Rotation) * Matrix::CreateLookAt(Vector3::Zero, sprite->LookAtAxis, Vector3::UnitZ); auto rotMatrix = Matrix::CreateRotationZ(sprite->Rotation) * Matrix::CreateLookAt(Vector3::Zero, sprite->LookAtAxis, Vector3::UnitZ);
spriteMatrix = scaleMatrix * rotMatrix * translationMatrix; spriteMatrix = scaleMatrix * rotMatrix * tMatrix;
} }
break; break;
@ -1338,7 +1334,7 @@ namespace TEN::Renderer
{ {
const auto& room = _rooms[effect->RoomNumber]; const auto& room = _rooms[effect->RoomNumber];
auto world = effect->InterpolatedWorld; Matrix world = effect->InterpolatedWorld;
ReflectMatrixOptionally(world); ReflectMatrixOptionally(world);
_stStatic.World = world; _stStatic.World = world;

View file

@ -359,10 +359,9 @@ namespace TEN::Renderer
void Renderer::CollectMirrors(RenderView& renderView) void Renderer::CollectMirrors(RenderView& renderView)
{ {
// Collect mirrors first because they are needed while collecting moveables. // Collect mirrors first, because they are needed while collecting items
for (const auto& mirror : g_Level.Mirrors) for (auto& mirror : g_Level.Mirrors)
{ {
// TODO: Avoid LaraItem global.
if (mirror.RoomNumber != Camera.pos.RoomNumber && mirror.RoomNumber != LaraItem->RoomNumber) if (mirror.RoomNumber != Camera.pos.RoomNumber && mirror.RoomNumber != LaraItem->RoomNumber)
continue; continue;
@ -370,9 +369,10 @@ namespace TEN::Renderer
continue; continue;
auto& rendererMirror = renderView.Mirrors.emplace_back(); auto& rendererMirror = renderView.Mirrors.emplace_back();
rendererMirror.RoomNumber = mirror.RoomNumber; rendererMirror.RoomNumber = mirror.RoomNumber;
rendererMirror.ReflectionMatrix = mirror.ReflectionMatrix; rendererMirror.ReflectionMatrix = mirror.ReflectionMatrix;
rendererMirror.ReflectPlayer = mirror.ReflectPlayer; rendererMirror.ReflectLara = mirror.ReflectLara;
rendererMirror.ReflectMoveables = mirror.ReflectMoveables; rendererMirror.ReflectMoveables = mirror.ReflectMoveables;
rendererMirror.ReflectStatics = mirror.ReflectStatics; rendererMirror.ReflectStatics = mirror.ReflectStatics;
rendererMirror.ReflectSprites = mirror.ReflectSprites; rendererMirror.ReflectSprites = mirror.ReflectSprites;
@ -385,100 +385,98 @@ namespace TEN::Renderer
if (_rooms.size() < roomNumber) if (_rooms.size() < roomNumber)
return; return;
auto& rendererRoom = _rooms[roomNumber]; auto& room = _rooms[roomNumber];
const auto& room = g_Level.Rooms[rendererRoom.RoomNumber]; auto* r = &g_Level.Rooms[room.RoomNumber];
bool isRoomReflected = IsRoomReflected(renderView, roomNumber); bool roomIsReflected = RoomIsReflected(renderView, roomNumber);
short itemNumber = NO_VALUE; short itemNum = NO_VALUE;
for (itemNumber = room.itemNumber; itemNumber != NO_VALUE; itemNumber = g_Level.Items[itemNumber].NextItem) for (itemNum = r->itemNumber; itemNum != NO_VALUE; itemNum = g_Level.Items[itemNum].NextItem)
{ {
const auto& item = g_Level.Items[itemNumber]; auto* item = &g_Level.Items[itemNum];
if (item.ObjectNumber == ID_LARA && itemNumber == g_Level.Items[itemNumber].NextItem) if (item->ObjectNumber == ID_LARA && itemNum == g_Level.Items[itemNum].NextItem)
break; break;
if (item.Status == ITEM_INVISIBLE) if (item->Status == ITEM_INVISIBLE)
continue; continue;
if (item.ObjectNumber == ID_LARA && (SpotcamOverlay || SpotcamDontDrawLara)) if (item->ObjectNumber == ID_LARA && (SpotcamOverlay || SpotcamDontDrawLara))
continue; continue;
if (item.ObjectNumber == ID_LARA && CurrentLevel == 0 && !g_GameFlow->IsLaraInTitleEnabled()) if (item->ObjectNumber == ID_LARA && CurrentLevel == 0 && !g_GameFlow->IsLaraInTitleEnabled())
continue; continue;
if (!_moveableObjects[item.ObjectNumber].has_value()) if (!_moveableObjects[item->ObjectNumber].has_value())
continue; continue;
auto& obj = _moveableObjects[item.ObjectNumber].value(); auto& obj = _moveableObjects[item->ObjectNumber].value();
if (obj.DoNotDraw) if (obj.DoNotDraw)
continue; continue;
// Clip object by frustum only if it doesn't cast shadows and is not in mirror room, // Clip object by frustum only if it doesn't cast shadows and is not in the mirror room.
// otherwise disappearing shadows or reflections may be seen if object gets out of frustum. // Otherwise we may see disappearing shadows or reflections if object gets out of frustum.
if (!isRoomReflected && obj.ShadowType == ShadowMode::None) if (!roomIsReflected && obj.ShadowType == ShadowMode::None)
{ {
// Get all spheres and check if frustum intersects any of them. // Get all spheres and check if frustum intersects any of them.
auto spheres = GetSpheres(itemNumber); auto spheres = GetSpheres(itemNum);
bool inFrustum = false; bool inFrustum = false;
for (int i = 0; !inFrustum, i < spheres.size(); i++) for (int i = 0; !inFrustum, i < spheres.size(); i++)
{
// Blow up sphere radius by half for cases of too small calculated spheres. // Blow up sphere radius by half for cases of too small calculated spheres.
if (renderView.Camera.Frustum.SphereInFrustum(spheres[i].Center, spheres[i].Radius * 1.5f)) if (renderView.Camera.Frustum.SphereInFrustum(spheres[i].Center, spheres[i].Radius * 1.5f))
inFrustum = true; inFrustum = true;
}
if (!inFrustum) if (!inFrustum)
continue; continue;
} }
auto newItem = _items[itemNumber]; auto newItem = &_items[itemNum];
newItem.ItemNumber = itemNumber; newItem->ItemNumber = itemNum;
newItem.ObjectID = item.ObjectNumber; newItem->ObjectID = item->ObjectNumber;
newItem.Color = item.Model.Color; newItem->Color = item->Model.Color;
newItem.Position = item.Pose.Position.ToVector3(); newItem->Position = item->Pose.Position.ToVector3();
newItem.Translation = Matrix::CreateTranslation(newItem.Position.x, newItem.Position.y, newItem.Position.z); newItem->Translation = Matrix::CreateTranslation(newItem->Position.x, newItem->Position.y, newItem->Position.z);
newItem.Rotation = item.Pose.Orientation.ToRotationMatrix(); newItem->Rotation = item->Pose.Orientation.ToRotationMatrix();
newItem.Scale = Matrix::CreateScale(1.0f); newItem->Scale = Matrix::CreateScale(1.0f);
newItem.World = newItem.Rotation * newItem.Translation; newItem->World = newItem->Rotation * newItem->Translation;
// Disable interpolation either when renderer slot or item slot has flag. // Disable interpolation either when renderer slot or item slot has flag.
// Renderer slot has no interpolation flag set in case it is fetched for first time (e.g. item first time in frustum). // Renderer slot has no interpolation flag set in case it is fetched for the first time (e.g. item first time in frustum).
newItem.DisableInterpolation = item.DisableInterpolation || newItem.DisableInterpolation; newItem->DisableInterpolation = item->DisableInterpolation || newItem->DisableInterpolation;
if (newItem.DisableInterpolation) if (newItem->DisableInterpolation)
{ {
// NOTE: Interpolation always returns same result. // NOTE: Interpolation alwasy returns same result.
newItem.PrevPosition = newItem.Position; newItem->PrevPosition = newItem->Position;
newItem.PrevTranslation = newItem.Translation; newItem->PrevTranslation = newItem->Translation;
newItem.PrevRotation = newItem.Rotation; newItem->PrevRotation = newItem->Rotation;
newItem.PrevWorld = newItem.World; newItem->PrevWorld = newItem->World;
// Otherwise all frames until next ControlPhase will not be interpolated. // Otherwise all frames until the next ControlPhase will not be interpolated.
newItem.DisableInterpolation = false; newItem->DisableInterpolation = false;
for (int j = 0; j < MAX_BONES; j++) for (int j = 0; j < MAX_BONES; j++)
newItem.PrevAnimTransforms[j] = newItem.AnimTransforms[j]; newItem->PrevAnimTransforms[j] = newItem->AnimTransforms[j];
} }
// Force interpolation only for player in player freeze mode. // Force interpolation only for Lara in player freeze mode.
bool forceValue = g_GameFlow->CurrentFreezeMode == FreezeMode::Player && item.ObjectNumber == ID_LARA; bool forceValue = g_GameFlow->CurrentFreezeMode == FreezeMode::Player && item->ObjectNumber == ID_LARA;
newItem.InterpolatedPosition = Vector3::Lerp(newItem.PrevPosition, newItem.Position, GetInterpolationFactor(forceValue)); newItem->InterpolatedPosition = Vector3::Lerp(newItem->PrevPosition, newItem->Position, GetInterpolationFactor(forceValue));
newItem.InterpolatedTranslation = Matrix::Lerp(newItem.PrevTranslation, newItem.Translation, GetInterpolationFactor(forceValue)); newItem->InterpolatedTranslation = Matrix::Lerp(newItem->PrevTranslation, newItem->Translation, GetInterpolationFactor(forceValue));
newItem.InterpolatedRotation = Matrix::Lerp(newItem.InterpolatedRotation, newItem.Rotation, GetInterpolationFactor(forceValue)); newItem->InterpolatedRotation = Matrix::Lerp(newItem->InterpolatedRotation, newItem->Rotation, GetInterpolationFactor(forceValue));
newItem.InterpolatedWorld = Matrix::Lerp(newItem.PrevWorld, newItem.World, GetInterpolationFactor(forceValue)); newItem->InterpolatedWorld = Matrix::Lerp(newItem->PrevWorld, newItem->World, GetInterpolationFactor(forceValue));
for (int j = 0; j < MAX_BONES; j++) for (int j = 0; j < MAX_BONES; j++)
newItem.InterpolatedAnimTransforms[j] = Matrix::Lerp(newItem.PrevAnimTransforms[j], newItem.AnimTransforms[j], GetInterpolationFactor(forceValue)); newItem->InterpolatedAnimTransforms[j] = Matrix::Lerp(newItem->PrevAnimTransforms[j], newItem->AnimTransforms[j], GetInterpolationFactor(forceValue));
CalculateLightFades(&newItem); CalculateLightFades(newItem);
CollectLightsForItem(&newItem); CollectLightsForItem(newItem);
rendererRoom.ItemsToDraw.push_back(&newItem); room.ItemsToDraw.push_back(newItem);
} }
} }
@ -493,7 +491,7 @@ namespace TEN::Renderer
if (r->mesh.empty()) if (r->mesh.empty())
return; return;
bool roomIsReflected = IsRoomReflected(renderView, roomNumber); bool roomIsReflected = RoomIsReflected(renderView, roomNumber);
for (int i = 0; i < room.Statics.size(); i++) for (int i = 0; i < room.Statics.size(); i++)
{ {

View file

@ -600,11 +600,10 @@ namespace TEN::Renderer
return rendererItem->BoneOrientations[boneID]; return rendererItem->BoneOrientations[boneID];
} }
bool Renderer::IsRoomReflected(RenderView& renderView, int roomNumber) bool Renderer::RoomIsReflected(RenderView& renderView, int roomNumber)
{ {
for (const auto& mirror : renderView.Mirrors) for (auto& mirror : renderView.Mirrors)
{ {
// TODO: Avoid LaraItem global.
if (roomNumber == mirror.RoomNumber && (Camera.pos.RoomNumber == mirror.RoomNumber || LaraItem->RoomNumber == mirror.RoomNumber)) if (roomNumber == mirror.RoomNumber && (Camera.pos.RoomNumber == mirror.RoomNumber || LaraItem->RoomNumber == mirror.RoomNumber))
return true; return true;
} }

View file

@ -111,7 +111,7 @@ void Renderer::UpdateLaraAnimations(bool force)
auto frameData = GetFrameInterpData(*LaraItem); auto frameData = GetFrameInterpData(*LaraItem);
UpdateAnimation(&rItem, playerObject, frameData, mask); UpdateAnimation(&rItem, playerObject, frameData, mask);
auto gunType = Lara.Control.Weapon.GunType; auto gunType = Lara.Control.Weapon.GunType;
auto handStatus = Lara.Control.HandStatus; auto handStatus = Lara.Control.HandStatus;
// HACK: Treat binoculars as two-handed weapon. // HACK: Treat binoculars as two-handed weapon.
@ -138,7 +138,7 @@ void Renderer::UpdateLaraAnimations(bool force)
playerObject.LinearizedBones[LM_LINARM]->ExtraRotation = playerObject.LinearizedBones[LM_LINARM]->ExtraRotation =
playerObject.LinearizedBones[LM_RINARM]->ExtraRotation *= Lara.RightArm.Orientation.ToQuaternion(); playerObject.LinearizedBones[LM_RINARM]->ExtraRotation *= Lara.RightArm.Orientation.ToQuaternion();
} }
else else
{ {
playerObject.LinearizedBones[LM_LINARM]->ExtraRotation *= Lara.LeftArm.Orientation.ToQuaternion(); playerObject.LinearizedBones[LM_LINARM]->ExtraRotation *= Lara.LeftArm.Orientation.ToQuaternion();
playerObject.LinearizedBones[LM_RINARM]->ExtraRotation *= Lara.RightArm.Orientation.ToQuaternion(); playerObject.LinearizedBones[LM_RINARM]->ExtraRotation *= Lara.RightArm.Orientation.ToQuaternion();
@ -288,7 +288,6 @@ void Renderer::UpdateLaraAnimations(bool force)
void TEN::Renderer::Renderer::DrawLara(RenderView& view, RendererPass rendererPass) void TEN::Renderer::Renderer::DrawLara(RenderView& view, RendererPass rendererPass)
{ {
// TODO: Avoid Lara global.
// Don't draw player if using optics (but still draw reflections). // Don't draw player if using optics (but still draw reflections).
if (Lara.Control.Look.OpticRange != 0 && _currentMirror == nullptr) if (Lara.Control.Look.OpticRange != 0 && _currentMirror == nullptr)
return; return;

View file

@ -129,6 +129,7 @@ namespace TEN::Renderer
DrawTriangles(3, 0); DrawTriangles(3, 0);
_doingFullscreenPass = false; _doingFullscreenPass = false;
} }

View file

@ -1,17 +1,20 @@
#pragma once #pragma once
#include <SimpleMath.h>
namespace TEN::Renderer::Structures namespace TEN::Renderer::Structures
{ {
using namespace DirectX;
using namespace DirectX::SimpleMath;
struct RendererMirror struct RendererMirror
{ {
int RoomNumber = 0; short RoomNumber;
Plane Plane = SimpleMath::Plane(); Plane Plane;
Matrix ReflectionMatrix = Matrix::Identity; Matrix ReflectionMatrix;
bool ReflectLara;
bool ReflectPlayer = false; bool ReflectMoveables;
bool ReflectMoveables = false; bool ReflectStatics;
bool ReflectStatics = false; bool ReflectSprites;
bool ReflectSprites = false; bool ReflectLights;
bool ReflectLights = false;
}; };
} }

View file

@ -1522,6 +1522,7 @@ void LoadBoxes()
void LoadMirrors() void LoadMirrors()
{ {
int mirrorCount = ReadCount(); int mirrorCount = ReadCount();
TENLog("Mirror count: " + std::to_string(mirrorCount), LogLevel::Info); TENLog("Mirror count: " + std::to_string(mirrorCount), LogLevel::Info);
g_Level.Mirrors.reserve(mirrorCount); g_Level.Mirrors.reserve(mirrorCount);
@ -1529,20 +1530,27 @@ void LoadMirrors()
{ {
auto& mirror = g_Level.Mirrors.emplace_back(); auto& mirror = g_Level.Mirrors.emplace_back();
mirror.RoomNumber = ReadInt16(); // TODO: Write Int32 to level instead. Short isn't used for room numbers anymore. mirror.RoomNumber = ReadInt16();
mirror.Plane.x = ReadFloat(); mirror.Plane.x = ReadFloat();
mirror.Plane.y = ReadFloat(); mirror.Plane.y = ReadFloat();
mirror.Plane.z = ReadFloat(); mirror.Plane.z = ReadFloat();
mirror.Plane.w = ReadFloat(); mirror.Plane.w = ReadFloat();
mirror.ReflectPlayer = ReadBool(); mirror.ReflectLara = ReadBool();
mirror.ReflectMoveables = ReadBool(); mirror.ReflectMoveables = ReadBool();
mirror.ReflectStatics = ReadBool(); mirror.ReflectStatics = ReadBool();
mirror.ReflectSprites = ReadBool(); mirror.ReflectSprites = ReadBool();
mirror.ReflectLights = ReadBool(); mirror.ReflectLights = ReadBool();
mirror.Enabled = true; mirror.Enabled = true;
mirror.ReflectionMatrix = Matrix::CreateReflection(mirror.Plane); Plane plane = Plane(
Vector3(mirror.Plane.x,
mirror.Plane.y,
mirror.Plane.z),
mirror.Plane.w);
mirror.ReflectionMatrix = Matrix::CreateReflection(plane);
} }
} }

View file

@ -85,18 +85,17 @@ struct MESH
std::vector<BUCKET> buckets; std::vector<BUCKET> buckets;
}; };
struct MirrorData struct MirrorInfo
{ {
int RoomNumber = 0; short RoomNumber;
Plane Plane = SimpleMath::Plane(); Vector4 Plane;
Matrix ReflectionMatrix = Matrix::Identity; Matrix ReflectionMatrix;
bool ReflectLara;
bool Enabled = false; bool ReflectMoveables;
bool ReflectPlayer = false; bool ReflectStatics;
bool ReflectMoveables = false; bool ReflectLights;
bool ReflectStatics = false; bool ReflectSprites;
bool ReflectLights = false; bool Enabled;
bool ReflectSprites = false;
}; };
// LevelData // LevelData
@ -137,7 +136,7 @@ struct LEVEL
std::vector<int> LoopedEventSetIndices = {}; std::vector<int> LoopedEventSetIndices = {};
std::vector<AI_OBJECT> AIObjects = {}; std::vector<AI_OBJECT> AIObjects = {};
std::vector<SPRITE> Sprites = {}; std::vector<SPRITE> Sprites = {};
std::vector<MirrorData> Mirrors = {}; std::vector<MirrorInfo> Mirrors = {};
// Texture data // Texture data
TEXTURE SkyTexture = {}; TEXTURE SkyTexture = {};