mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-28 15:57:59 +03:00
Merge branch 'develop' into implement_willard
This commit is contained in:
commit
eaf61ad60d
25 changed files with 124 additions and 127 deletions
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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).
|
||||||
|
|
|
@ -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).
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue