Merge branch 'develop' into implement_willard

This commit is contained in:
Stranger1992 2024-10-28 23:41:56 +00:00
commit eaf61ad60d
25 changed files with 124 additions and 127 deletions

View file

@ -19,6 +19,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
* Fixed several binocular bugs. * Fixed several binocular bugs.
* Fixed incorrect climbing out of water on bridge objects. * Fixed incorrect climbing out of water on bridge objects.
* Fixed faulty death sectors. * Fixed faulty death sectors.
* Fixed water climbouts in front of static meshes.
* Fixed incorrect diving animation when swandiving from a high place. * Fixed incorrect diving animation when swandiving from a high place.
* Fixed camera rotating with the player's hips when climbing out of water. * Fixed camera rotating with the player's hips when climbing out of water.
* Fixed AI for TR2 skidoo driver and worker with shotgun. * Fixed AI for TR2 skidoo driver and worker with shotgun.
@ -45,6 +46,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
* Added the ability to display "Lara's Home" entry in the main menu. * Added the ability to display "Lara's Home" entry in the main menu.
* Added the ability to change pickup item count by modifying item hit points. * Added the ability to change pickup item count by modifying item hit points.
* Added F12 as alternative to PrtSc for screenshots. * Added F12 as alternative to PrtSc for screenshots.
* Added visible mouse pointer in windowed mode.
* Added new sound conditions: Quicksand and Underwater. * Added new sound conditions: Quicksand and Underwater.
- Quicksand - sound effect plays when a moveable is in quicksand. - Quicksand - sound effect plays when a moveable is in quicksand.
- Underwater - sound plays when the camera is submerged. - Underwater - sound plays when the camera is submerged.

View file

@ -507,7 +507,6 @@ void LaraSurfaceCollision(ItemInfo* item, CollisionInfo* coll)
} }
} }
void LaraDefaultCollision(ItemInfo* item, CollisionInfo* coll) void LaraDefaultCollision(ItemInfo* item, CollisionInfo* coll)
{ {
auto& player = GetLaraInfo(*item); auto& player = GetLaraInfo(*item);

View file

@ -924,12 +924,29 @@ bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll)
if (coll->Middle.Ceiling > -STEPUP_HEIGHT) if (coll->Middle.Ceiling > -STEPUP_HEIGHT)
return false; return false;
int frontFloor = coll->Front.Floor + LARA_HEIGHT_TREAD; // HACK: Probe at incremetal height steps to account for room stacks. -- Sezz 2024.10.28
if (coll->Front.Bridge == NO_VALUE && int frontFloor = NO_HEIGHT;
(frontFloor <= -CLICK(2) || if (coll->Front.Bridge != NO_VALUE)
frontFloor > CLICK(1.25f) - 4))
{ {
return false; auto pointColl = GetPointCollision(*item, item->Pose.Orientation.y, BLOCK(0.5f), -BLOCK(0.5f));
frontFloor = (pointColl.GetFloorHeight() - item->Pose.Position.y);
}
else
{
int yOffset = CLICK(1.25f);
while (yOffset > -CLICK(2))
{
auto pointColl = GetPointCollision(*item, item->Pose.Orientation.y, BLOCK(0.5f), yOffset);
frontFloor = pointColl.GetFloorHeight() - item->Pose.Position.y;
if (frontFloor > -CLICK(2) &&
frontFloor <= (CLICK(1.25f) - 4))
{
break;
}
yOffset -= CLICK(0.5f);
}
} }
// Extra bridge check. // Extra bridge check.

View file

@ -234,6 +234,13 @@ CollidedObjectData GetCollidedObjects(ItemInfo& collidingItem, bool onlyVisible,
if (!Geometry::CircleIntersects(circle, collidingCircle)) if (!Geometry::CircleIntersects(circle, collidingCircle))
continue; continue;
// Skip if either bounding box has any zero extent (not a collidable volume).
if (bounds.GetExtents().Length() > 0)
continue;
if (collidingBounds.GetExtents().Length() > 0)
continue;
auto box0 = bounds.ToBoundingOrientedBox(staticObj.pos.Position); auto box0 = bounds.ToBoundingOrientedBox(staticObj.pos.Position);
auto box1 = collidingBounds.ToBoundingOrientedBox(collidingItem.Pose); auto box1 = collidingBounds.ToBoundingOrientedBox(collidingItem.Pose);
@ -283,7 +290,8 @@ bool TestWithGlobalCollisionBounds(ItemInfo* item, ItemInfo* laraItem, Collision
void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll) void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll)
{ {
int height = GameBoundingBox(item).GetHeight(); auto bbox = GameBoundingBox(item).ToBoundingOrientedBox(item->Pose);
auto height = (bbox.Center - bbox.Extents).y - CLICK(1);
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
@ -292,8 +300,9 @@ void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll)
auto origin = Vector3( auto origin = Vector3(
item->Pose.Position.x + (sinHeading * (coll->Setup.Radius)), item->Pose.Position.x + (sinHeading * (coll->Setup.Radius)),
item->Pose.Position.y - (height + CLICK(1)), height,
item->Pose.Position.z + (cosHeading * (coll->Setup.Radius))); item->Pose.Position.z + (cosHeading * (coll->Setup.Radius)));
auto mxR = Matrix::CreateFromYawPitchRoll(TO_RAD(coll->Setup.ForwardAngle), 0.0f, 0.0f); auto mxR = Matrix::CreateFromYawPitchRoll(TO_RAD(coll->Setup.ForwardAngle), 0.0f, 0.0f);
auto direction = (Matrix::CreateTranslation(Vector3::UnitZ) * mxR).Translation(); auto direction = (Matrix::CreateTranslation(Vector3::UnitZ) * mxR).Translation();

View file

@ -593,8 +593,8 @@ void EndGameLoop(int levelIndex, GameStatus reason)
void SetupInterpolation() void SetupInterpolation()
{ {
for (int i = 0; i < g_Level.Items.size(); i++) for (auto& item : g_Level.Items)
g_Level.Items[i].DisableInterpolation = false; item.DisableInterpolation = false;
} }
void HandleControls(bool isTitle) void HandleControls(bool isTitle)

View file

@ -408,6 +408,7 @@ void Trigger(short const value, short const flags)
} }
item->Status = ITEM_ACTIVE; item->Status = ITEM_ACTIVE;
item->DisableInterpolation = true;
} }
} }
@ -866,11 +867,12 @@ void TestTriggers(int x, int y, int z, short roomNumber, bool heavy, int heavyFl
void ProcessSectorFlags(ItemInfo* item) void ProcessSectorFlags(ItemInfo* item)
{ {
auto pointColl = GetPointCollision(*item);
auto& sector = GetPointCollision(*item).GetBottomSector();
bool isPlayer = item->IsLara(); bool isPlayer = item->IsLara();
// HACK: because of L-shaped portal configurations, we need to fetch room number from Location struct for player.
auto pointColl = isPlayer ? GetPointCollision(item->Pose.Position, item->Location.RoomNumber) : GetPointCollision(*item);
auto& sector = pointColl.GetBottomSector();
// Set monkeyswing and wall climb statuses for player. // Set monkeyswing and wall climb statuses for player.
if (isPlayer) if (isPlayer)
{ {

View file

@ -109,7 +109,7 @@ struct ItemInfo
int Index = 0; // ItemNumber // TODO: Make int. int Index = 0; // ItemNumber // TODO: Make int.
GAME_OBJECT_ID ObjectNumber = ID_NO_OBJECT; // ObjectID GAME_OBJECT_ID ObjectNumber = ID_NO_OBJECT; // ObjectID
/*ItemStatus*/int Status = ITEM_NOT_ACTIVE; ItemStatus Status = ITEM_NOT_ACTIVE;
bool Active = false; bool Active = false;
// TODO: Refactor linked list. // TODO: Refactor linked list.

View file

@ -258,7 +258,7 @@ void AnimatingControl(short itemNumber)
else if (item.TriggerFlags == 2) //Make the animating dissapear when anti-triggered. else if (item.TriggerFlags == 2) //Make the animating dissapear when anti-triggered.
{ {
RemoveActiveItem(itemNumber); RemoveActiveItem(itemNumber);
item.Status |= ITEM_INVISIBLE; item.Status = ITEM_INVISIBLE;
} }
// TODO: ID_SHOOT_SWITCH2 is probably the bell in Trajan Markets, use Lua for that. // TODO: ID_SHOOT_SWITCH2 is probably the bell in Trajan Markets, use Lua for that.

View file

@ -77,7 +77,7 @@ namespace TEN::Entities::Creatures::TR1
AddActiveItem(skateItemNumber); AddActiveItem(skateItemNumber);
skate.Active = false; skate.Active = false;
skate.Status |= ITEM_INVISIBLE; skate.Status = ITEM_INVISIBLE;
item.ItemFlags[0] = skateItemNumber; item.ItemFlags[0] = skateItemNumber;
} }

View file

@ -81,13 +81,9 @@ namespace TEN::Entities::Creatures::TR2
auto& item = g_Level.Items[itemNumber]; auto& item = g_Level.Items[itemNumber];
if (item.Flags & IFLAG_REVERSE) if (item.Flags & IFLAG_REVERSE)
{ item.Status = ITEM_NOT_ACTIVE;
item.Status &= ~ITEM_INVISIBLE;
}
else else
{
item.Status = ITEM_INVISIBLE; item.Status = ITEM_INVISIBLE;
}
} }
void SkidooManCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) void SkidooManCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)

View file

@ -195,7 +195,7 @@ namespace TEN::Entities::Creatures::TR2
InitializeCreature(itemNumber); InitializeCreature(itemNumber);
SetAnimation(&item, SPEAR_GUARDIAN_ANIM_AWAKE); SetAnimation(&item, SPEAR_GUARDIAN_ANIM_AWAKE);
item.Status &= ~ITEM_INVISIBLE; item.Status = ITEM_NOT_ACTIVE;
item.ItemFlags[0] = 0; // Joint index for mesh swap. item.ItemFlags[0] = 0; // Joint index for mesh swap.
item.ItemFlags[1] = 1; // Immune state (bool). item.ItemFlags[1] = 1; // Immune state (bool).

View file

@ -174,7 +174,7 @@ namespace TEN::Entities::Creatures::TR2
InitializeCreature(itemNumber); InitializeCreature(itemNumber);
SetAnimation(&item, SWORD_GUARDIAN_ANIM_AWAKE); SetAnimation(&item, SWORD_GUARDIAN_ANIM_AWAKE);
item.Status &= ~ITEM_INVISIBLE; item.Status = ITEM_NOT_ACTIVE;
item.ItemFlags[0] = 0; // Joint index for mesh swap. item.ItemFlags[0] = 0; // Joint index for mesh swap.
item.ItemFlags[1] = 1; // Immune state (bool). item.ItemFlags[1] = 1; // Immune state (bool).

View file

@ -254,7 +254,7 @@ namespace TEN::Entities::Creatures::TR3
void InitializeShiva(short itemNumber) void InitializeShiva(short itemNumber)
{ {
auto& item = g_Level.Items[itemNumber]; auto& item = g_Level.Items[itemNumber];
item.Status &= ~ITEM_INVISIBLE; // Draw the statue from the start. item.Status = ITEM_NOT_ACTIVE; // Draw the statue from the start.
InitializeCreature(itemNumber); InitializeCreature(itemNumber);
SetAnimation(&item, SHIVA_ANIM_INACTIVE); SetAnimation(&item, SHIVA_ANIM_INACTIVE);

View file

@ -81,7 +81,7 @@ namespace TEN::Entities::TR4
if (item->TriggerFlags) if (item->TriggerFlags)
{ {
SetAnimation(item, DOG_ANIM_AWAKEN); SetAnimation(item, DOG_ANIM_AWAKEN);
item->Status -= ITEM_INVISIBLE; item->Status = ITEM_NOT_ACTIVE;
} }
else else
SetAnimation(item, DOG_ANIM_IDLE); SetAnimation(item, DOG_ANIM_IDLE);

View file

@ -81,7 +81,7 @@ namespace TEN::Entities::TR4
if (item->TriggerFlags == 2) if (item->TriggerFlags == 2)
{ {
SetAnimation(item, MUMMY_ANIM_COLLAPSE_END); SetAnimation(item, MUMMY_ANIM_COLLAPSE_END);
item->Status -= ITEM_INVISIBLE; item->Status = ITEM_NOT_ACTIVE;
} }
else else
{ {

View file

@ -136,7 +136,7 @@ namespace TEN::Entities::TR4
case 3: case 3:
SetAnimation(item, SKELETON_ANIM_STANDING_UP); SetAnimation(item, SKELETON_ANIM_STANDING_UP);
item->Status -= ITEM_INVISIBLE; item->Status = ITEM_NOT_ACTIVE;
break; break;
} }
} }

View file

@ -19,12 +19,12 @@ namespace TEN::Entities::Traps
if (TriggerActive(&item)) if (TriggerActive(&item))
{ {
item.Status = ITEM_ACTIVE; item.Status = ITEM_ACTIVE;
AnimateItem(&item); AnimateItem(&item);
} }
else if (item.TriggerFlags == 2) else if (item.TriggerFlags == 2)
{ {
item.Status |= ITEM_INVISIBLE; item.Status = ITEM_INVISIBLE;
} }
} }

View file

@ -18,6 +18,8 @@ using namespace TEN::Math;
namespace TEN::Entities::Creatures::TR5 namespace TEN::Entities::Creatures::TR5
{ {
constexpr auto LARSON_ALERT_RANGE = SQUARE(BLOCK(2));
#define STATE_TR5_LARSON_STOP 1 #define STATE_TR5_LARSON_STOP 1
#define STATE_TR5_LARSON_WALK 2 #define STATE_TR5_LARSON_WALK 2
#define STATE_TR5_LARSON_RUN 3 #define STATE_TR5_LARSON_RUN 3
@ -58,6 +60,8 @@ namespace TEN::Entities::Creatures::TR5
item->Pose.Position.z += STEPUP_HEIGHT; item->Pose.Position.z += STEPUP_HEIGHT;
} }
// TODO: Make larson 1:1 from TOMB5 code. TokyoSU: 10/27/2024
// This code is a mess...
void LarsonControl(short itemNumber) void LarsonControl(short itemNumber)
{ {
if (!CreatureActive(itemNumber)) if (!CreatureActive(itemNumber))
@ -73,15 +77,14 @@ namespace TEN::Entities::Creatures::TR5
short joint2 = 0; short joint2 = 0;
// TODO: When Larson's HP is below 40, he runs away in Streets of Rome. Keeping block commented for reference. // TODO: When Larson's HP is below 40, he runs away in Streets of Rome. Keeping block commented for reference.
/*if (item->HitPoints <= TR5_LARSON_MIN_HP && !(item->flags & IFLAG_INVISIBLE)) if (item->HitPoints <= TR5_LARSON_MIN_HP && !(item->Flags & IFLAG_INVISIBLE))
{ {
item->HitPoints = TR5_LARSON_MIN_HP; item->HitPoints = TR5_LARSON_MIN_HP;
creature->flags++; creature->Flags++;
}*/ }
if (creature->MuzzleFlash[0].Delay != 0) if (creature->MuzzleFlash[0].Delay != 0)
creature->MuzzleFlash[0].Delay--; creature->MuzzleFlash[0].Delay--;
if (creature->MuzzleFlash[1].Delay != 0) if (creature->MuzzleFlash[1].Delay != 0)
creature->MuzzleFlash[1].Delay--; creature->MuzzleFlash[1].Delay--;
@ -89,20 +92,13 @@ namespace TEN::Entities::Creatures::TR5
{ {
if (CurrentLevel == 2) if (CurrentLevel == 2)
{ {
item->Animation.IsAirborne = false; item->AIBits = AMBUSH;
item->Status = ITEM_DEACTIVATED;
item->Collidable = false;
item->HitStatus = false;
item->ItemFlags[3] = 1; item->ItemFlags[3] = 1;
} }
else else
{ {
item->Animation.IsAirborne = false; item->AIBits = GUARD;
item->Status = ITEM_ACTIVE;
item->Collidable = false;
item->HitStatus = false;
} }
item->TriggerFlags = 0; item->TriggerFlags = 0;
} }
@ -120,25 +116,23 @@ namespace TEN::Entities::Creatures::TR5
joint2 = AI.angle; joint2 = AI.angle;
// FIXME: This should make Larson run away, but it doesn't work. // FIXME: This should make Larson run away, but it doesn't work.
/*if (creature->flags) // FIXME: 10/27/2024 - TokyoSU: Implemented TOMB5 way, should work now but need test.
if (creature->Flags)
{ {
item->HitPoints = 60; item->HitPoints = 60;
item->IsAirborne = false; item->AIBits = AMBUSH;
item->HitStatus = false;
item->Collidable = false;
item->Status = ITEM_DESACTIVATED;
creature->Flags = 0; creature->Flags = 0;
}*/ }
GetCreatureMood(item, &AI, true); GetCreatureMood(item, &AI, true);
CreatureMood(item, &AI, true); CreatureMood(item, &AI, true);
if (AI.distance < SQUARE(BLOCK(2)) && if (AI.distance < LARSON_ALERT_RANGE &&
LaraItem->Animation.Velocity.z > 20.0f || LaraItem->Animation.Velocity.z > 20.0f ||
item->HitStatus || item->HitStatus ||
TargetVisible(item, &AI) != 0) TargetVisible(item, &AI) != 0)
{ {
item->Status &= ~ITEM_ACTIVE; item->AIBits &= ~GUARD;
creature->Alerted = true; creature->Alerted = true;
} }

View file

@ -51,6 +51,7 @@ namespace TEN::Renderer
for (auto& item : _items) for (auto& item : _items)
{ {
item.DisableInterpolation = true;
item.PrevRoomNumber = NO_VALUE; item.PrevRoomNumber = NO_VALUE;
item.RoomNumber = NO_VALUE; item.RoomNumber = NO_VALUE;
item.ItemNumber = NO_VALUE; item.ItemNumber = NO_VALUE;

View file

@ -507,6 +507,7 @@ namespace TEN::Renderer
void ResetScissor(); void ResetScissor();
void ResetDebugVariables(); void ResetDebugVariables();
float CalculateFrameRate(); float CalculateFrameRate();
void InterpolateCamera(float interpFactor);
void CopyRenderTarget(RenderTarget2D* source, RenderTarget2D* dest, RenderView& view); void CopyRenderTarget(RenderTarget2D* source, RenderTarget2D* dest, RenderView& view);
void AddSpriteBillboard(RendererSprite* sprite, const Vector3& pos, const Vector4& color, float orient2D, float scale, void AddSpriteBillboard(RendererSprite* sprite, const Vector3& pos, const Vector4& color, float orient2D, float scale,

View file

@ -3023,35 +3023,7 @@ namespace TEN::Renderer
void Renderer::Render(float interpFactor) void Renderer::Render(float interpFactor)
{ {
_interpolationFactor = interpFactor; InterpolateCamera(interpFactor);
// Interpolate camera.
if (!Camera.DisableInterpolation)
{
_gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpFactor);
_gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpFactor);
_gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpFactor);
_gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpFactor);
_gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection;
_gameCamera.Camera.FOV = Lerp(_oldGameCamera.Camera.FOV, _currentGameCamera.Camera.FOV,interpFactor);
_gameCamera.Camera.Frustum.Update(_gameCamera.Camera.View, _gameCamera.Camera.Projection);
}
else
{
_gameCamera.Camera.WorldPosition = _currentGameCamera.Camera.WorldPosition;
_gameCamera.Camera.WorldDirection = _currentGameCamera.Camera.WorldDirection;
_gameCamera.Camera.View = _currentGameCamera.Camera.View;
_gameCamera.Camera.Projection = _currentGameCamera.Camera.Projection;
_gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection;
_gameCamera.Camera.FOV = _currentGameCamera.Camera.FOV;
_gameCamera.Camera.Frustum = _currentGameCamera.Camera.Frustum;
}
_gameCamera.Camera.ViewSize = _currentGameCamera.Camera.ViewSize;
_gameCamera.Camera.InvViewSize = _currentGameCamera.Camera.InvViewSize;
_gameCamera.Camera.NearPlane = _currentGameCamera.Camera.NearPlane;
_gameCamera.Camera.FarPlane = _currentGameCamera.Camera.FarPlane;
RenderScene(&_backBuffer, true, _gameCamera); RenderScene(&_backBuffer, true, _gameCamera);
_context->ClearState(); _context->ClearState();
@ -3679,4 +3651,36 @@ namespace TEN::Renderer
DrawTriangles(3, 0); DrawTriangles(3, 0);
} }
void Renderer::InterpolateCamera(float interpFactor)
{
_interpolationFactor = interpFactor;
// Interpolate camera.
if (!Camera.DisableInterpolation)
{
_gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpFactor);
_gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpFactor);
_gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpFactor);
_gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpFactor);
_gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection;
_gameCamera.Camera.FOV = Lerp(_oldGameCamera.Camera.FOV, _currentGameCamera.Camera.FOV, interpFactor);
_gameCamera.Camera.Frustum.Update(_gameCamera.Camera.View, _gameCamera.Camera.Projection);
}
else
{
_gameCamera.Camera.WorldPosition = _currentGameCamera.Camera.WorldPosition;
_gameCamera.Camera.WorldDirection = _currentGameCamera.Camera.WorldDirection;
_gameCamera.Camera.View = _currentGameCamera.Camera.View;
_gameCamera.Camera.Projection = _currentGameCamera.Camera.Projection;
_gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection;
_gameCamera.Camera.FOV = _currentGameCamera.Camera.FOV;
_gameCamera.Camera.Frustum = _currentGameCamera.Camera.Frustum;
}
_gameCamera.Camera.ViewSize = _currentGameCamera.Camera.ViewSize;
_gameCamera.Camera.InvViewSize = _currentGameCamera.Camera.InvViewSize;
_gameCamera.Camera.NearPlane = _currentGameCamera.Camera.NearPlane;
_gameCamera.Camera.FarPlane = _currentGameCamera.Camera.FarPlane;
}
} }

View file

@ -1148,35 +1148,6 @@ namespace TEN::Renderer
void Renderer::RenderTitle(float interpFactor) void Renderer::RenderTitle(float interpFactor)
{ {
_interpolationFactor = interpFactor;
// Interpolate camera.
if (!Camera.DisableInterpolation)
{
_gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpFactor);
_gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpFactor);
_gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpFactor);
_gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpFactor);
_gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection;
_gameCamera.Camera.FOV = Lerp(_oldGameCamera.Camera.FOV, _currentGameCamera.Camera.FOV, interpFactor);
_gameCamera.Camera.Frustum.Update(_gameCamera.Camera.View, _gameCamera.Camera.Projection);
}
else
{
_gameCamera.Camera.WorldPosition = _currentGameCamera.Camera.WorldPosition;
_gameCamera.Camera.WorldDirection = _currentGameCamera.Camera.WorldDirection;
_gameCamera.Camera.View = _currentGameCamera.Camera.View;
_gameCamera.Camera.Projection = _currentGameCamera.Camera.Projection;
_gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection;
_gameCamera.Camera.FOV = _currentGameCamera.Camera.FOV;
_gameCamera.Camera.Frustum = _currentGameCamera.Camera.Frustum;
}
_gameCamera.Camera.ViewSize = _currentGameCamera.Camera.ViewSize;
_gameCamera.Camera.InvViewSize = _currentGameCamera.Camera.InvViewSize;
_gameCamera.Camera.NearPlane = _currentGameCamera.Camera.NearPlane;
_gameCamera.Camera.FarPlane = _currentGameCamera.Camera.FarPlane;
_stringsToDraw.clear(); _stringsToDraw.clear();
_isLocked = false; _isLocked = false;
@ -1185,6 +1156,7 @@ namespace TEN::Renderer
_context->ClearDepthStencilView(_backBuffer.DepthStencilView.Get(), D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0); _context->ClearDepthStencilView(_backBuffer.DepthStencilView.Get(), D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0);
_context->ClearRenderTargetView(_backBuffer.RenderTargetView.Get(), Colors::Black); _context->ClearRenderTargetView(_backBuffer.RenderTargetView.Get(), Colors::Black);
InterpolateCamera(interpFactor);
RenderInventoryScene(&_backBuffer, &_dumpScreenRenderTarget, 1.0f); RenderInventoryScene(&_backBuffer, &_dumpScreenRenderTarget, 1.0f);
_swapChain->Present(1, 0); _swapChain->Present(1, 0);
@ -1293,7 +1265,7 @@ namespace TEN::Renderer
PrintDebugMessage("Orientation: %d, %d, %d", LaraItem->Pose.Orientation.x, LaraItem->Pose.Orientation.y, LaraItem->Pose.Orientation.z); PrintDebugMessage("Orientation: %d, %d, %d", LaraItem->Pose.Orientation.x, LaraItem->Pose.Orientation.y, LaraItem->Pose.Orientation.z);
PrintDebugMessage("RoomNumber: %d", LaraItem->RoomNumber); PrintDebugMessage("RoomNumber: %d", LaraItem->RoomNumber);
PrintDebugMessage("PathfindingBoxID: %d", LaraItem->BoxNumber); PrintDebugMessage("PathfindingBoxID: %d", LaraItem->BoxNumber);
PrintDebugMessage("WaterSurfaceDist: %d", Lara.Context.WaterSurfaceDist); PrintDebugMessage((Lara.Context.WaterSurfaceDist == -NO_HEIGHT ? "WaterSurfaceDist: N/A" : "WaterSurfaceDist: %d"), Lara.Context.WaterSurfaceDist);
PrintDebugMessage("Room Position: %d, %d, %d, %d", room.Position.z, room.Position.z, room.Position.z + BLOCK(room.XSize), room.Position.z + BLOCK(room.ZSize)); PrintDebugMessage("Room Position: %d, %d, %d, %d", room.Position.z, room.Position.z, room.Position.z + BLOCK(room.XSize), room.Position.z + BLOCK(room.ZSize));
PrintDebugMessage("Room.y, minFloor, maxCeiling: %d, %d, %d ", room.Position.y, room.BottomHeight, room.TopHeight); PrintDebugMessage("Room.y, minFloor, maxCeiling: %d, %d, %d ", room.Position.y, room.BottomHeight, room.TopHeight);
PrintDebugMessage("Camera Position: %d, %d, %d", Camera.pos.x, Camera.pos.y, Camera.pos.z); PrintDebugMessage("Camera Position: %d, %d, %d", Camera.pos.x, Camera.pos.y, Camera.pos.z);

View file

@ -417,7 +417,11 @@ namespace TEN::Renderer
newItem->Scale = Matrix::CreateScale(1.0f); newItem->Scale = Matrix::CreateScale(1.0f);
newItem->World = newItem->Rotation * newItem->Translation; newItem->World = newItem->Rotation * newItem->Translation;
if (item->DisableInterpolation) // Disable interpolation either when renderer slot or item slot has flag.
// 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;
if (newItem->DisableInterpolation)
{ {
// NOTE: Interpolation alwasy returns same result. // NOTE: Interpolation alwasy returns same result.
newItem->PrevPosition = newItem->Position; newItem->PrevPosition = newItem->Position;
@ -425,9 +429,8 @@ namespace TEN::Renderer
newItem->PrevRotation = newItem->Rotation; newItem->PrevRotation = newItem->Rotation;
newItem->PrevWorld = newItem->World; newItem->PrevWorld = newItem->World;
// Otherwise all frames until the next ControlPhase will not // Otherwise all frames until the next ControlPhase will not be interpolated.
// be interpolated newItem->DisableInterpolation = false;
item->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];

View file

@ -29,6 +29,7 @@ namespace TEN::Renderer::Structures
float LightFade = 0.0f; float LightFade = 0.0f;
bool DoneAnimations = false; bool DoneAnimations = false;
bool DisableInterpolation = true;
Vector3 InterpolatedPosition = Vector3::Zero; Vector3 InterpolatedPosition = Vector3::Zero;
Matrix InterpolatedWorld = Matrix::Identity; Matrix InterpolatedWorld = Matrix::Identity;

View file

@ -156,17 +156,6 @@ void CALLBACK HandleWmCommand(unsigned short wParam)
SuspendThread((HANDLE)ThreadHandle); SuspendThread((HANDLE)ThreadHandle);
g_Renderer.ToggleFullScreen(); g_Renderer.ToggleFullScreen();
ResumeThread((HANDLE)ThreadHandle); ResumeThread((HANDLE)ThreadHandle);
if (g_Renderer.IsFullsScreen())
{
SetCursor(nullptr);
ShowCursor(false);
}
else
{
SetCursor(LoadCursorA(App.hInstance, (LPCSTR)0x68));
ShowCursor(true);
}
} }
} }
} }
@ -180,6 +169,15 @@ LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ {
return 0; return 0;
} }
if (msg == WM_SETCURSOR)
{
if (LOWORD(lParam) == HTCLIENT)
{
SetCursor(g_Renderer.IsFullsScreen() ? nullptr : App.WindowClass.hCursor);
return 1;
}
}
if (msg == WM_ACTIVATEAPP) if (msg == WM_ACTIVATEAPP)
{ {
@ -370,7 +368,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
App.WindowClass.lpfnWndProc = WinAppProc; App.WindowClass.lpfnWndProc = WinAppProc;
App.WindowClass.cbClsExtra = 0; App.WindowClass.cbClsExtra = 0;
App.WindowClass.cbWndExtra = 0; App.WindowClass.cbWndExtra = 0;
App.WindowClass.hCursor = LoadCursor(App.hInstance, IDC_ARROW); App.WindowClass.hCursor = LoadCursorA(NULL, IDC_ARROW);
// Register main window. // Register main window.
if (!RegisterClass(&App.WindowClass)) if (!RegisterClass(&App.WindowClass))
@ -461,8 +459,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
UpdateWindow(WindowsHandle); UpdateWindow(WindowsHandle);
ShowWindow(WindowsHandle, nShowCmd); ShowWindow(WindowsHandle, nShowCmd);
SetCursor(NULL);
ShowCursor(FALSE);
hAccTable = LoadAccelerators(hInstance, (LPCSTR)0x65); hAccTable = LoadAccelerators(hInstance, (LPCSTR)0x65);
} }
catch (std::exception& ex) catch (std::exception& ex)