mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-11 04:56:49 +03:00
Merge branch 'ten_beta' into lua_funcs
This commit is contained in:
commit
be4b98dc41
80 changed files with 1272 additions and 1173 deletions
|
@ -1,39 +0,0 @@
|
|||
ANIM.C
|
||||
X BOX.C
|
||||
CAMERA.C
|
||||
* COLLIDE.C
|
||||
* CONTROL.C
|
||||
* DEBRIS.C
|
||||
X DOOR.C
|
||||
* DRAW.C
|
||||
X EFFECT2.C
|
||||
X EFFECTS.C
|
||||
FLMTRCH.C
|
||||
GUARDIAN.C
|
||||
HAIR.C
|
||||
X HEALTH.C
|
||||
HYDRA.C
|
||||
X ITEMS.C
|
||||
* LARA.C
|
||||
X LARA1GUN.C
|
||||
X LARA2GUN.C
|
||||
X LARASURF.C
|
||||
* LARACLMB.C
|
||||
X LARAFIRE.C
|
||||
X LARAFLAR.C
|
||||
X LARAMISC.C
|
||||
X LARASWIM.C
|
||||
X LION.C
|
||||
X LOT.C
|
||||
X MAFIA2.C
|
||||
MISSILE.C
|
||||
X OBJECTS.C
|
||||
X PEOPLE.C
|
||||
X PICKUP.C
|
||||
RAT.C
|
||||
* ROPE.C
|
||||
X SPHERE.C
|
||||
X SWITCH.C
|
||||
* TOMB4FX.C
|
||||
* TRAPS.C
|
||||
TWOGUN.C
|
|
@ -462,6 +462,8 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
|
|||
bool isWater = TestEnvironment(ENV_FLAG_WATER, item);
|
||||
bool isSwamp = TestEnvironment(ENV_FLAG_SWAMP, item);
|
||||
|
||||
bool isWaterOnHeadspace = false;
|
||||
|
||||
int waterDepth = GetWaterDepth(item);
|
||||
int waterHeight = GetWaterHeight(item);
|
||||
|
||||
|
@ -475,7 +477,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
|
|||
if (lara->Vehicle == NO_ITEM)
|
||||
WadeSplash(item, waterHeight, waterDepth);
|
||||
|
||||
if (lara->Vehicle == NO_ITEM && lara->ExtraAnim == -1)
|
||||
if (lara->Vehicle == NO_ITEM && lara->ExtraAnim == NO_ITEM)
|
||||
{
|
||||
switch (lara->Control.WaterStatus)
|
||||
{
|
||||
|
@ -553,14 +555,15 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
|
|||
break;
|
||||
|
||||
case WaterStatus::Underwater:
|
||||
if (isWater ||
|
||||
waterDepth == DEEP_WATER || abs(heightFromWater) >= CLICK(1) ||
|
||||
item->Animation.AnimNumber == LA_UNDERWATER_RESURFACE ||
|
||||
item->Animation.AnimNumber == LA_ONWATER_DIVE)
|
||||
isWaterOnHeadspace = TestEnvironment(ENV_FLAG_WATER, item->Pose.Position.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z,
|
||||
GetCollision(item->Pose.Position.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z, item->RoomNumber).RoomNumber);
|
||||
|
||||
if (waterDepth == NO_HEIGHT || abs(heightFromWater) >= CLICK(1) || isWaterOnHeadspace ||
|
||||
item->Animation.AnimNumber == LA_UNDERWATER_RESURFACE || item->Animation.AnimNumber == LA_ONWATER_DIVE)
|
||||
{
|
||||
if (!isWater)
|
||||
{
|
||||
if (waterDepth == DEEP_WATER || abs(heightFromWater) >= CLICK(1))
|
||||
if (waterDepth == NO_HEIGHT || abs(heightFromWater) >= CLICK(1))
|
||||
{
|
||||
SetAnimation(item, LA_FALL_START);
|
||||
ResetLaraLean(item);
|
||||
|
@ -779,7 +782,7 @@ void LaraAboveWater(ItemInfo* item, CollisionInfo* coll)
|
|||
|
||||
AnimateLara(item);
|
||||
|
||||
if (lara->ExtraAnim == -1)
|
||||
if (lara->ExtraAnim == NO_ITEM)
|
||||
{
|
||||
// Check for collision with items.
|
||||
DoObjectCollision(item, coll);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "ScriptInterfaceGame.h"
|
||||
#include "Objects/ScriptInterfaceObjectsHandler.h"
|
||||
#include "Game/Lara/lara_tests.h"
|
||||
|
||||
using namespace TEN::Entities::Generic;
|
||||
using namespace TEN::Input;
|
||||
|
@ -261,8 +262,8 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
}
|
||||
};
|
||||
|
||||
// States in which Lara will hold the flare out in front.
|
||||
int HoldStates[] =
|
||||
// States in which Lara will hold a flare out in front.
|
||||
const std::vector<LaraState> FlarePoseStates =
|
||||
{
|
||||
LS_WALK_FORWARD,
|
||||
LS_RUN_FORWARD,
|
||||
|
@ -281,29 +282,8 @@ int HoldStates[] =
|
|||
LS_CROUCH_IDLE,
|
||||
LS_CROUCH_TURN_LEFT,
|
||||
LS_CROUCH_TURN_RIGHT,
|
||||
LS_SOFT_SPLAT,
|
||||
-1
|
||||
LS_SOFT_SPLAT
|
||||
};
|
||||
|
||||
bool CheckForHoldingState(LaraState state)
|
||||
{
|
||||
#if 0
|
||||
if (lara->ExtraAnim != NO_ITEM)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
int* holdState = HoldStates;
|
||||
while (*holdState >= 0)
|
||||
{
|
||||
if (state == *holdState)
|
||||
return true;
|
||||
|
||||
holdState++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
GAME_OBJECT_ID WeaponObject(LaraWeaponType weaponType)
|
||||
{
|
||||
switch (weaponType)
|
||||
|
@ -623,7 +603,7 @@ void LaraGun(ItemInfo* laraItem)
|
|||
if (lara->Control.Weapon.GunType == LaraWeaponType::Flare)
|
||||
{
|
||||
if (lara->Vehicle != NO_ITEM ||
|
||||
CheckForHoldingState((LaraState)laraItem->Animation.ActiveState))
|
||||
CheckLaraState((LaraState)laraItem->Animation.ActiveState, FlarePoseStates))
|
||||
{
|
||||
if (lara->Flare.ControlLeft)
|
||||
{
|
||||
|
@ -653,7 +633,7 @@ void LaraGun(ItemInfo* laraItem)
|
|||
{
|
||||
if (lara->MeshPtrs[LM_LHAND] == Objects[ID_LARA_FLARE_ANIM].meshIndex + LM_LHAND)
|
||||
{
|
||||
lara->Flare.ControlLeft = (lara->Vehicle != NO_ITEM || CheckForHoldingState((LaraState)laraItem->Animation.ActiveState));
|
||||
lara->Flare.ControlLeft = (lara->Vehicle != NO_ITEM || CheckLaraState((LaraState)laraItem->Animation.ActiveState, FlarePoseStates));
|
||||
DoFlareInHand(laraItem, lara->Flare.Life);
|
||||
SetFlareArm(laraItem, lara->LeftArm.FrameNumber);
|
||||
}
|
||||
|
|
|
@ -57,6 +57,5 @@ void HitTarget(ItemInfo* laraItem, ItemInfo* target, GameVector* hitPos, int dam
|
|||
FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo* target, ItemInfo* src, Vector3Shrt armOrient);
|
||||
void FindTargetPoint(ItemInfo* laraItem, GameVector* target);
|
||||
void LaraTargetInfo(ItemInfo* laraItem, WeaponInfo* weaponInfo);
|
||||
bool CheckForHoldingState(LaraState state);
|
||||
void LaraGetNewTarget(ItemInfo* laraItem, WeaponInfo* weaponInfo);
|
||||
HolsterSlot HolsterSlotForWeapon(LaraWeaponType weaponType);
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
using namespace TEN::Math::Random;
|
||||
|
||||
constexpr auto FlareMainColor = Vector3(0.8f, 0.42947f, 0.2921f);
|
||||
constexpr auto FLARE_MAIN_COLOR = Vector3(0.8f, 0.42947f, 0.2921f);
|
||||
constexpr auto FLARE_LIFE_MAX = 60 * FPS; // 60 * 30 frames = 60 seconds.
|
||||
|
||||
void FlareControl(short itemNumber)
|
||||
{
|
||||
|
@ -409,9 +410,9 @@ int DoFlareLight(Vector3Int* pos, int flareLife)
|
|||
{
|
||||
int falloff = 6 * (1.0f - (flareLife / FLARE_LIFE_MAX));
|
||||
|
||||
int r = FlareMainColor.x * 255;
|
||||
int g = FlareMainColor.y * 255;
|
||||
int b = FlareMainColor.z * 255;
|
||||
int r = FLARE_MAIN_COLOR.x * 255;
|
||||
int g = FLARE_MAIN_COLOR.y * 255;
|
||||
int b = FLARE_MAIN_COLOR.z * 255;
|
||||
|
||||
TriggerDynamicLight(x, y, z, falloff, r, g, b);
|
||||
|
||||
|
@ -422,9 +423,9 @@ int DoFlareLight(Vector3Int* pos, int flareLife)
|
|||
float multiplier = GenerateFloat(0.05f, 1.0f);
|
||||
int falloff = 8 * multiplier;
|
||||
|
||||
int r = FlareMainColor.x * 255 * multiplier;
|
||||
int g = FlareMainColor.y * 255 * multiplier;
|
||||
int b = FlareMainColor.z * 255 * multiplier;
|
||||
int r = FLARE_MAIN_COLOR.x * 255 * multiplier;
|
||||
int g = FLARE_MAIN_COLOR.y * 255 * multiplier;
|
||||
int b = FLARE_MAIN_COLOR.z * 255 * multiplier;
|
||||
TriggerDynamicLight(x, y, z, falloff, r, g, b);
|
||||
|
||||
result = (random < 0.4f);
|
||||
|
@ -434,9 +435,9 @@ int DoFlareLight(Vector3Int* pos, int flareLife)
|
|||
float multiplier = GenerateFloat(0.6f, 0.8f);
|
||||
int falloff = 8 * (1.0f - (flareLife / FLARE_LIFE_MAX));
|
||||
|
||||
int r = FlareMainColor.x * 255 * multiplier;
|
||||
int g = FlareMainColor.y * 255 * multiplier;
|
||||
int b = FlareMainColor.z * 255 * multiplier;
|
||||
int r = FLARE_MAIN_COLOR.x * 255 * multiplier;
|
||||
int g = FLARE_MAIN_COLOR.y * 255 * multiplier;
|
||||
int b = FLARE_MAIN_COLOR.z * 255 * multiplier;
|
||||
TriggerDynamicLight(x, y, z, falloff, r, g, b);
|
||||
|
||||
result = (random < 0.3f);
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
#pragma once
|
||||
#include "Game/control/control.h"
|
||||
|
||||
struct ItemInfo;
|
||||
struct CollisionInfo;
|
||||
struct ItemInfo;
|
||||
struct Vector3Int;
|
||||
enum GAME_OBJECT_ID : short;
|
||||
|
||||
constexpr auto FLARE_LIFE_MAX = 60 * FPS; // 60 * 30 frames = 60 seconds.
|
||||
|
||||
void FlareControl(short itemNumber);
|
||||
void ReadyFlare(ItemInfo* laraItem);
|
||||
void UndrawFlareMeshes(ItemInfo* laraItem);
|
||||
|
|
|
@ -345,7 +345,7 @@ short ModulateLaraTurnRate(short turnRate, short accelRate, short minTurnRate, s
|
|||
|
||||
short newTurnRate = (turnRate + (accelRate * sign)) * sign;
|
||||
newTurnRate = std::clamp(newTurnRate, minTurnRateNormalized, maxTurnRateNormalized);
|
||||
return newTurnRate * sign;
|
||||
return (newTurnRate * sign);
|
||||
}
|
||||
|
||||
// TODO: Make these two functions methods of LaraInfo someday. @Sezz 2022.06.26
|
||||
|
|
|
@ -21,18 +21,12 @@ void InitialiseLara(int restore)
|
|||
LaraItem->Location.roomNumber = LaraItem->RoomNumber;
|
||||
LaraItem->Location.yNumber = LaraItem->Pose.Position.y;
|
||||
|
||||
LaraInfo backup = {};
|
||||
|
||||
if (restore)
|
||||
{
|
||||
LaraInfo backup;
|
||||
memcpy(&backup, &Lara, sizeof(LaraInfo));
|
||||
ZeroMemory(&Lara, sizeof(LaraInfo));
|
||||
}
|
||||
else
|
||||
{
|
||||
ZeroMemory(&Lara, sizeof(LaraInfo));
|
||||
Lara.ExtraAnim = NO_ITEM;
|
||||
Lara.Vehicle = NO_ITEM;
|
||||
}
|
||||
|
||||
ZeroMemory(&Lara, sizeof(LaraInfo));
|
||||
|
||||
Lara.Control.CanLook = true;
|
||||
Lara.ItemNumber = itemNumber;
|
||||
|
@ -40,11 +34,11 @@ void InitialiseLara(int restore)
|
|||
Lara.SprintEnergy = LARA_SPRINT_ENERGY_MAX;
|
||||
Lara.Air = LARA_AIR_MAX;
|
||||
Lara.Control.Weapon.WeaponItem = NO_ITEM;
|
||||
PoisonFlag = 0;
|
||||
Lara.PoisonPotency = 0;
|
||||
Lara.WaterSurfaceDist = 100;
|
||||
|
||||
Lara.Vehicle = -1;
|
||||
Lara.ExtraAnim = NO_ITEM;
|
||||
Lara.Vehicle = NO_ITEM;
|
||||
Lara.Location = -1;
|
||||
Lara.HighestLocation = -1;
|
||||
Lara.Control.Rope.Ptr = -1;
|
||||
|
|
|
@ -130,6 +130,8 @@ void lara_as_freefall(ItemInfo* item, CollisionInfo* coll)
|
|||
{
|
||||
item->Animation.Velocity = item->Animation.Velocity * 0.95f;
|
||||
|
||||
ModulateLaraTurnRateY(item, 0, 0, 0);
|
||||
|
||||
if (item->Animation.VerticalVelocity == LARA_DEATH_VELOCITY &&
|
||||
item->HitPoints > 0)
|
||||
{
|
||||
|
@ -804,6 +806,8 @@ void lara_as_freefall_dive(ItemInfo* item, CollisionInfo* coll)
|
|||
coll->Setup.EnableObjectPush = true;
|
||||
coll->Setup.EnableSpasm = false;
|
||||
|
||||
ModulateLaraTurnRateY(item, 0, 0, 0);
|
||||
|
||||
if (item->HitPoints <= 0)
|
||||
{
|
||||
if (TestLaraLand(item, coll))
|
||||
|
|
|
@ -743,7 +743,7 @@ void lara_as_pole_idle(ItemInfo* item, CollisionInfo* coll)
|
|||
if (item->Animation.ActiveState == LA_POLE_IDLE) // HACK.
|
||||
{
|
||||
if (TrInput & (IN_LEFT | IN_RIGHT))
|
||||
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX);
|
||||
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX, true);
|
||||
}
|
||||
|
||||
// TODO: Add forward jump.
|
||||
|
@ -834,7 +834,7 @@ void lara_as_pole_up(ItemInfo* item, CollisionInfo* coll)
|
|||
if (TrInput & IN_ACTION)
|
||||
{
|
||||
if (TrInput & (IN_LEFT | IN_RIGHT))
|
||||
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX);
|
||||
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX, true);
|
||||
|
||||
if (TrInput & IN_JUMP)
|
||||
{
|
||||
|
@ -883,7 +883,7 @@ void lara_as_pole_down(ItemInfo* item, CollisionInfo* coll)
|
|||
if (TrInput & IN_ACTION)
|
||||
{
|
||||
if (TrInput & (IN_LEFT | IN_RIGHT))
|
||||
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX);
|
||||
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX, true);
|
||||
|
||||
if (TrInput & IN_JUMP)
|
||||
{
|
||||
|
@ -973,7 +973,7 @@ void lara_as_pole_turn_clockwise(ItemInfo* item, CollisionInfo* coll)
|
|||
if (TrInput & IN_LEFT)
|
||||
{
|
||||
item->Animation.TargetState = LS_POLE_TURN_CLOCKWISE;
|
||||
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX);
|
||||
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1025,7 +1025,7 @@ void lara_as_pole_turn_counter_clockwise(ItemInfo* item, CollisionInfo* coll)
|
|||
if (TrInput & IN_RIGHT)
|
||||
{
|
||||
item->Animation.TargetState = LS_POLE_TURN_COUNTER_CLOCKWISE;
|
||||
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX);
|
||||
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -541,7 +541,10 @@ void HarpoonBoltControl(short itemNumber)
|
|||
if (item->HitPoints > 0)
|
||||
item->HitPoints--;
|
||||
else
|
||||
{
|
||||
ExplodeItemNode(item, 0, 0, BODY_EXPLODE);
|
||||
KillItem(itemNumber);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -447,7 +447,7 @@ bool TestLaraNearClimbableWall(ItemInfo* item, FloorInfo* floor)
|
|||
if (floor == nullptr)
|
||||
floor = GetCollision(item).BottomBlock;
|
||||
|
||||
return ((1 << (GetQuadrant(item->Pose.Orientation.y) + 8)) & GetClimbFlags(floor));
|
||||
return ((256 << (GetQuadrant(item->Pose.Orientation.y))) & GetClimbFlags(floor));
|
||||
}
|
||||
|
||||
bool TestLaraHangOnClimbableWall(ItemInfo* item, CollisionInfo* coll)
|
||||
|
@ -1111,86 +1111,106 @@ void GetTightropeFallOff(ItemInfo* item, int regularity)
|
|||
}
|
||||
#endif
|
||||
|
||||
bool IsStandingWeapon(ItemInfo* item, LaraWeaponType weaponType)
|
||||
// TODO: Organise all of this properly. -- Sezz 2022.07.28
|
||||
bool CheckLaraState(LaraState state, std::vector<LaraState> stateList)
|
||||
{
|
||||
auto* lara = GetLaraInfo(item);
|
||||
|
||||
if (weaponType == LaraWeaponType::Shotgun ||
|
||||
weaponType == LaraWeaponType::HK ||
|
||||
weaponType == LaraWeaponType::Crossbow ||
|
||||
weaponType == LaraWeaponType::Torch ||
|
||||
weaponType == LaraWeaponType::GrenadeLauncher ||
|
||||
weaponType == LaraWeaponType::HarpoonGun ||
|
||||
weaponType == LaraWeaponType::RocketLauncher||
|
||||
weaponType == LaraWeaponType::Snowmobile ||
|
||||
lara->Weapons[(int)weaponType].HasLasersight)
|
||||
for (auto listedState : stateList)
|
||||
{
|
||||
return true;
|
||||
if (state == listedState)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckLaraWeaponType(LaraWeaponType weaponType, std::vector<LaraWeaponType> weaponTypeList)
|
||||
{
|
||||
for (auto listedWeaponType : weaponTypeList)
|
||||
{
|
||||
if (weaponType == listedWeaponType)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static std::vector<LaraWeaponType> StandingWeaponTypes
|
||||
{
|
||||
LaraWeaponType::Shotgun,
|
||||
LaraWeaponType::HK,
|
||||
LaraWeaponType::Crossbow,
|
||||
LaraWeaponType::Torch,
|
||||
LaraWeaponType::GrenadeLauncher,
|
||||
LaraWeaponType::HarpoonGun,
|
||||
LaraWeaponType::RocketLauncher,
|
||||
LaraWeaponType::Snowmobile
|
||||
};
|
||||
|
||||
bool IsStandingWeapon(ItemInfo* item, LaraWeaponType weaponType)
|
||||
{
|
||||
return (CheckLaraWeaponType(weaponType, StandingWeaponTypes) || GetLaraInfo(item)->Weapons[(int)weaponType].HasLasersight);
|
||||
}
|
||||
|
||||
static std::vector<LaraState> VaultStates
|
||||
{
|
||||
LS_VAULT,
|
||||
LS_VAULT_2_STEPS,
|
||||
LS_VAULT_3_STEPS,
|
||||
LS_VAULT_1_STEP_CROUCH,
|
||||
LS_VAULT_2_STEPS_CROUCH,
|
||||
LS_VAULT_3_STEPS_CROUCH,
|
||||
LS_AUTO_JUMP
|
||||
};
|
||||
|
||||
bool IsVaultState(LaraState state)
|
||||
{
|
||||
if (state == LS_VAULT ||
|
||||
state == LS_VAULT_2_STEPS ||
|
||||
state == LS_VAULT_3_STEPS ||
|
||||
state == LS_VAULT_1_STEP_CROUCH ||
|
||||
state == LS_VAULT_2_STEPS_CROUCH ||
|
||||
state == LS_VAULT_3_STEPS_CROUCH ||
|
||||
state == LS_AUTO_JUMP)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return CheckLaraState(state, VaultStates);
|
||||
}
|
||||
|
||||
static std::vector<LaraState> JumpStates
|
||||
{
|
||||
LS_JUMP_FORWARD,
|
||||
LS_JUMP_BACK,
|
||||
LS_JUMP_LEFT,
|
||||
LS_JUMP_RIGHT,
|
||||
LS_JUMP_UP,
|
||||
LS_FALL_BACK,
|
||||
LS_REACH,
|
||||
LS_SWAN_DIVE,
|
||||
LS_FREEFALL_DIVE,
|
||||
LS_FREEFALL
|
||||
};
|
||||
|
||||
bool IsJumpState(LaraState state)
|
||||
{
|
||||
if (state == LS_JUMP_FORWARD ||
|
||||
state == LS_JUMP_BACK ||
|
||||
state == LS_JUMP_LEFT ||
|
||||
state == LS_JUMP_RIGHT ||
|
||||
state == LS_JUMP_UP ||
|
||||
state == LS_FALL_BACK ||
|
||||
state == LS_REACH ||
|
||||
state == LS_SWAN_DIVE ||
|
||||
state == LS_FREEFALL_DIVE ||
|
||||
state == LS_FREEFALL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return CheckLaraState(state, JumpStates);
|
||||
}
|
||||
|
||||
static std::vector<LaraState> RunningJumpQueuableStates
|
||||
{
|
||||
LS_RUN_FORWARD,
|
||||
LS_SPRINT,
|
||||
LS_STEP_UP,
|
||||
LS_STEP_DOWN
|
||||
};
|
||||
|
||||
bool IsRunJumpQueueableState(LaraState state)
|
||||
{
|
||||
if (state == LS_RUN_FORWARD ||
|
||||
state == LS_SPRINT ||
|
||||
state == LS_STEP_UP ||
|
||||
state == LS_STEP_DOWN)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return CheckLaraState(state, RunningJumpQueuableStates);
|
||||
}
|
||||
|
||||
static std::vector<LaraState> RunningJumpTimerStates
|
||||
{
|
||||
LS_WALK_FORWARD,
|
||||
LS_RUN_FORWARD,
|
||||
LS_SPRINT,
|
||||
LS_SPRINT_DIVE,
|
||||
LS_JUMP_FORWARD
|
||||
};
|
||||
|
||||
bool IsRunJumpCountableState(LaraState state)
|
||||
{
|
||||
if (state == LS_WALK_FORWARD ||
|
||||
state == LS_RUN_FORWARD ||
|
||||
state == LS_SPRINT ||
|
||||
state == LS_SPRINT_DIVE ||
|
||||
state == LS_JUMP_FORWARD)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return CheckLaraState(state, RunningJumpTimerStates);
|
||||
}
|
||||
|
||||
bool TestLaraPose(ItemInfo* item, CollisionInfo* coll)
|
||||
|
@ -1224,12 +1244,31 @@ bool TestLaraKeepLow(ItemInfo* item, CollisionInfo* coll)
|
|||
|
||||
auto probeFront = GetCollision(item, item->Pose.Orientation.y, radius, -coll->Setup.Height);
|
||||
auto probeBack = GetCollision(item, item->Pose.Orientation.y + ANGLE(180.0f), radius, -coll->Setup.Height);
|
||||
auto probeMiddle = GetCollision(item);
|
||||
auto probeMiddle = GetCollision(item, 0.0f, 0.0f, -LARA_HEIGHT / 2);
|
||||
|
||||
if (abs(probeFront.Position.Ceiling - probeFront.Position.Floor) < LARA_HEIGHT || // Front is not a clamp.
|
||||
abs(probeBack.Position.Ceiling - probeBack.Position.Floor) < LARA_HEIGHT || // Back is not a clamp.
|
||||
abs(probeMiddle.Position.Ceiling - probeMiddle.Position.Floor) < LARA_HEIGHT || // Middle is not a clamp.
|
||||
abs(coll->Middle.Ceiling - LARA_HEIGHT_CRAWL) < LARA_HEIGHT) // TEMP: Consider statics overhead detected by GetCollisionInfo().
|
||||
// Assess middle.
|
||||
if (abs(probeMiddle.Position.Ceiling - probeMiddle.Position.Floor) < LARA_HEIGHT || // Middle space is low enough.
|
||||
abs(coll->Middle.Ceiling - LARA_HEIGHT_CRAWL) < LARA_HEIGHT) // Consider statics overhead detected by GetCollisionInfo().
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Check whether < or <= and > or >=.
|
||||
|
||||
// Assess front.
|
||||
if (abs(probeFront.Position.Ceiling - probeFront.Position.Floor) < LARA_HEIGHT && // Front space is low enough.
|
||||
abs(probeFront.Position.Ceiling - probeFront.Position.Floor) > LARA_HEIGHT_CRAWL && // Front space not a clamp.
|
||||
abs(probeFront.Position.Floor - probeMiddle.Position.Floor) <= (CLICK(1) - 1) && // Front is withing upper/lower floor bounds.
|
||||
probeFront.Position.Floor != NO_HEIGHT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Assess back.
|
||||
if (abs(probeBack.Position.Ceiling - probeBack.Position.Floor) < LARA_HEIGHT && // Back space is low enough.
|
||||
abs(probeBack.Position.Ceiling - probeBack.Position.Floor) > LARA_HEIGHT_CRAWL && // Back space not a clamp.
|
||||
abs(probeBack.Position.Floor - probeMiddle.Position.Floor) <= (CLICK(1) - 1) && // Back is withing upper/lower floor bounds.
|
||||
probeBack.Position.Floor != NO_HEIGHT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ void TestLaraWaterDepth(ItemInfo* item, CollisionInfo* coll);
|
|||
void GetTightropeFallOff(ItemInfo* item, int regularity);
|
||||
#endif
|
||||
|
||||
bool CheckLaraState(LaraState state, std::vector<LaraState> stateList);
|
||||
bool IsStandingWeapon(ItemInfo* item, LaraWeaponType weaponType);
|
||||
bool IsVaultState(LaraState state);
|
||||
bool IsJumpState(LaraState state);
|
||||
|
|
|
@ -95,7 +95,10 @@ void LookAt(CAMERA_INFO* cam, short roll)
|
|||
float fov = TO_RAD(CurrentFOV / 1.333333f);
|
||||
float r = TO_RAD(roll);
|
||||
|
||||
g_Renderer.UpdateCameraMatrices(cam, r, fov);
|
||||
float gameFarView = g_GameFlow->GetGameFarView() * float(SECTOR(1));
|
||||
float levelFarView = g_GameFlow->GetLevel(CurrentLevel)->GetFarView() * float(SECTOR(1));
|
||||
|
||||
g_Renderer.UpdateCameraMatrices(cam, r, fov, std::min(gameFarView, levelFarView));
|
||||
}
|
||||
|
||||
void AlterFOV(int value)
|
||||
|
|
|
@ -408,7 +408,7 @@ bool TestLaraPosition(OBJECT_COLLISION_BOUNDS* bounds, ItemInfo* item, ItemInfo*
|
|||
return true;
|
||||
}
|
||||
|
||||
void AlignLaraPosition(Vector3Int* vec, ItemInfo* item, ItemInfo* laraItem)
|
||||
bool AlignLaraPosition(Vector3Int* vec, ItemInfo* item, ItemInfo* laraItem)
|
||||
{
|
||||
laraItem->Pose.Orientation = item->Pose.Orientation;
|
||||
|
||||
|
@ -419,10 +419,25 @@ void AlignLaraPosition(Vector3Int* vec, ItemInfo* item, ItemInfo* laraItem)
|
|||
);
|
||||
|
||||
Vector3 pos = Vector3::Transform(Vector3(vec->x, vec->y, vec->z), matrix);
|
||||
Vector3 newPos = item->Pose.Position.ToVector3() + pos;
|
||||
|
||||
laraItem->Pose.Position.x = item->Pose.Position.x + pos.x;
|
||||
laraItem->Pose.Position.y = item->Pose.Position.y + pos.y;
|
||||
laraItem->Pose.Position.z = item->Pose.Position.z + pos.z;
|
||||
int height = GetCollision(newPos.x, newPos.y, newPos.z, laraItem->RoomNumber).Position.Floor;
|
||||
if (abs(height - laraItem->Pose.Position.y) <= CLICK(2))
|
||||
{
|
||||
laraItem->Pose.Position.x = newPos.x;
|
||||
laraItem->Pose.Position.y = newPos.y;
|
||||
laraItem->Pose.Position.z = newPos.z;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
if (lara->Control.IsMoving)
|
||||
{
|
||||
lara->Control.IsMoving = false;
|
||||
lara->Control.HandStatus = HandStatus::Free;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MoveLaraPosition(Vector3Int* vec, ItemInfo* item, ItemInfo* laraItem)
|
||||
|
@ -856,8 +871,8 @@ void CollideSolidStatics(ItemInfo* item, CollisionInfo* coll)
|
|||
{
|
||||
if (phd_Distance(&item->Pose, &mesh->pos) < COLLISION_CHECK_DISTANCE)
|
||||
{
|
||||
auto staticInfo = StaticObjects[mesh->staticNumber];
|
||||
if (CollideSolidBounds(item, staticInfo.collisionBox, mesh->pos, coll))
|
||||
auto staticInfo = &StaticObjects[mesh->staticNumber];
|
||||
if (CollideSolidBounds(item, staticInfo->collisionBox, mesh->pos, coll))
|
||||
coll->HitStatic = true;
|
||||
}
|
||||
}
|
||||
|
@ -910,9 +925,13 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX box, PHD_3DPOS pos, Collisi
|
|||
}
|
||||
|
||||
// Get and test DX item coll bounds
|
||||
auto collBounds = TO_DX_BBOX(PHD_3DPOS(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z), &collBox);
|
||||
auto collBounds = TO_DX_BBOX(PHD_3DPOS(item->Pose.Position), &collBox);
|
||||
bool intersects = staticBounds.Intersects(collBounds);
|
||||
|
||||
// Check if previous item horizontal position intersects bounds
|
||||
auto oldCollBounds = TO_DX_BBOX(PHD_3DPOS(coll->Setup.OldPosition.x, item->Pose.Position.y, coll->Setup.OldPosition.z), &collBox);
|
||||
bool oldHorIntersects = staticBounds.Intersects(oldCollBounds);
|
||||
|
||||
// Draw item coll bounds
|
||||
g_Renderer.AddDebugBox(collBounds, intersects ? Vector4(1, 0, 0, 1) : Vector4(0, 1, 0, 1), RENDERER_DEBUG_PAGE::LOGIC_STATS);
|
||||
|
||||
|
@ -973,7 +992,7 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX box, PHD_3DPOS pos, Collisi
|
|||
auto distanceToVerticalPlane = height / 2 - yPoint;
|
||||
|
||||
// Correct position according to top/bottom bounds, if collided and plane is nearby
|
||||
if (intersects && minDistance < height)
|
||||
if (intersects && oldHorIntersects && minDistance < height)
|
||||
{
|
||||
if (bottom)
|
||||
{
|
||||
|
@ -1180,6 +1199,11 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
|
|||
auto oldCollResult = GetCollision(x, y, z, item->RoomNumber);
|
||||
auto collResult = GetCollision(item);
|
||||
|
||||
auto* bounds = GetBoundsAccurate(item);
|
||||
int radius = abs(bounds->Y2 - bounds->Y1);
|
||||
|
||||
item->Pose.Position.y += radius;
|
||||
|
||||
if (item->Pose.Position.y >= collResult.Position.Floor)
|
||||
{
|
||||
bs = 0;
|
||||
|
@ -1670,8 +1694,16 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
|
|||
}
|
||||
|
||||
collResult = GetCollision(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber);
|
||||
|
||||
if (collResult.RoomNumber != item->RoomNumber)
|
||||
{
|
||||
if (item->ObjectNumber == ID_GRENADE && TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, collResult.RoomNumber))
|
||||
Splash(item);
|
||||
|
||||
ItemNewRoom(itemNumber, collResult.RoomNumber);
|
||||
}
|
||||
|
||||
item->Pose.Position.y -= radius;
|
||||
}
|
||||
|
||||
void DoObjectCollision(ItemInfo* laraItem, CollisionInfo* coll)
|
||||
|
@ -1844,42 +1876,43 @@ void CreatureCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll
|
|||
{
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
if (item->ObjectNumber != ID_HITMAN || item->Animation.ActiveState != LS_INSERT_PUZZLE)
|
||||
if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius))
|
||||
return;
|
||||
|
||||
if (!TestCollision(item, laraItem))
|
||||
return;
|
||||
|
||||
bool playerCollision = laraItem->IsLara();
|
||||
bool waterPlayerCollision = playerCollision && GetLaraInfo(laraItem)->Control.WaterStatus >= WaterStatus::TreadWater;
|
||||
|
||||
if (waterPlayerCollision || coll->Setup.EnableObjectPush)
|
||||
{
|
||||
if (TestBoundsCollide(item, laraItem, coll->Setup.Radius))
|
||||
ItemPushItem(item, laraItem, coll, coll->Setup.EnableSpasm, 0);
|
||||
}
|
||||
else if (playerCollision && coll->Setup.EnableSpasm)
|
||||
{
|
||||
int x = laraItem->Pose.Position.x - item->Pose.Position.x;
|
||||
int z = laraItem->Pose.Position.z - item->Pose.Position.z;
|
||||
|
||||
float sinY = phd_sin(item->Pose.Orientation.y);
|
||||
float cosY = phd_cos(item->Pose.Orientation.y);
|
||||
|
||||
auto* frame = GetBestFrame(item);
|
||||
int rx = (frame->boundingBox.X1 + frame->boundingBox.X2) / 2;
|
||||
int rz = (frame->boundingBox.X2 + frame->boundingBox.Z2) / 2;
|
||||
|
||||
if (frame->boundingBox.Y2 - frame->boundingBox.Y1 > STEP_SIZE)
|
||||
{
|
||||
if (TestCollision(item, laraItem))
|
||||
{
|
||||
if (coll->Setup.EnableObjectPush ||
|
||||
Lara.Control.WaterStatus == WaterStatus::Underwater ||
|
||||
Lara.Control.WaterStatus == WaterStatus::TreadWater)
|
||||
{
|
||||
ItemPushItem(item, laraItem, coll, coll->Setup.EnableSpasm, 0);
|
||||
}
|
||||
else if (coll->Setup.EnableSpasm)
|
||||
{
|
||||
int x = laraItem->Pose.Position.x - item->Pose.Position.x;
|
||||
int z = laraItem->Pose.Position.z - item->Pose.Position.z;
|
||||
int angle = (laraItem->Pose.Orientation.y - phd_atan(z - cosY * rx - sinY * rz, x - cosY * rx + sinY * rz) - ANGLE(135.0f)) / ANGLE(90.0f);
|
||||
|
||||
float sinY = phd_sin(item->Pose.Orientation.y);
|
||||
float cosY = phd_cos(item->Pose.Orientation.y);
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
|
||||
auto* frame = GetBestFrame(item);
|
||||
int rx = (frame->boundingBox.X1 + frame->boundingBox.X2) / 2;
|
||||
int rz = (frame->boundingBox.X2 + frame->boundingBox.Z2) / 2;
|
||||
lara->HitDirection = (short)angle;
|
||||
|
||||
if (frame->boundingBox.Y2 - frame->boundingBox.Y1 > STEP_SIZE)
|
||||
{
|
||||
int angle = (laraItem->Pose.Orientation.y - phd_atan(z - cosY * rx - sinY * rz, x - cosY * rx + sinY * rz) - ANGLE(135.0f)) / ANGLE(90.0f);
|
||||
Lara.HitDirection = (short)angle;
|
||||
// TODO: check if a second Lara.hitFrame++; is required there !
|
||||
|
||||
Lara.HitFrame++;
|
||||
if (Lara.HitFrame > 30)
|
||||
Lara.HitFrame = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: check if a second Lara.hitFrame++; is required there !
|
||||
lara->HitFrame++;
|
||||
if (lara->HitFrame > 30)
|
||||
lara->HitFrame = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ bool TestWithGlobalCollisionBounds(ItemInfo* item, ItemInfo* laraItem, Collision
|
|||
void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll);
|
||||
|
||||
bool TestLaraPosition(OBJECT_COLLISION_BOUNDS* bounds, ItemInfo* item, ItemInfo* laraItem);
|
||||
void AlignLaraPosition(Vector3Int* vec, ItemInfo* item, ItemInfo* laraItem);
|
||||
bool AlignLaraPosition(Vector3Int* vec, ItemInfo* item, ItemInfo* laraItem);
|
||||
bool MoveLaraPosition(Vector3Int* pos, ItemInfo* item, ItemInfo* laraItem);
|
||||
|
||||
bool ItemNearLara(PHD_3DPOS* pos, int radius);
|
||||
|
|
|
@ -954,6 +954,11 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
|
|||
auto floorHeight = GetFloorHeight(ROOM_VECTOR{ block->Room, y }, ffpX, ffpZ).value_or(NO_HEIGHT);
|
||||
auto ceilingHeight = GetCeilingHeight(ROOM_VECTOR{ block->Room, y }, ffpX, ffpZ).value_or(NO_HEIGHT);
|
||||
|
||||
// If probe landed inside wall (i.e. both floor/ceiling heights are NO_HEIGHT), make a fake
|
||||
// ledge for algorithm to further succeed.
|
||||
if (floorHeight == NO_HEIGHT && ceilingHeight == NO_HEIGHT)
|
||||
floorHeight = y - CLICK(4);
|
||||
|
||||
// If ceiling height tests lower than Y value, it means ceiling
|
||||
// ledge is in front and we should use it instead of floor.
|
||||
bool useCeilingLedge = ceilingHeight > y;
|
||||
|
@ -1306,6 +1311,7 @@ int GetWaterDepth(int x, int y, int z, short roomNumber)
|
|||
while (floor->RoomBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
|
||||
{
|
||||
room = &g_Level.Rooms[floor->RoomBelow(x, y, z).value_or(floor->Room)];
|
||||
|
||||
if (TestEnvironment(ENV_FLAG_WATER, room) ||
|
||||
TestEnvironment(ENV_FLAG_SWAMP, room))
|
||||
{
|
||||
|
|
|
@ -11,14 +11,10 @@ void InitTENLog()
|
|||
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("Logs/TENLog.txt", true);
|
||||
|
||||
std::shared_ptr<spdlog::logger> logger;
|
||||
if constexpr (DebugBuild)
|
||||
{
|
||||
// Set the file and console log targets
|
||||
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
||||
logger = std::make_shared<spdlog::logger>(std::string{ "multi_sink" }, spdlog::sinks_init_list{file_sink, console_sink });
|
||||
}
|
||||
else
|
||||
logger = std::make_shared<spdlog::logger>(std::string{ "multi_sink" }, file_sink);
|
||||
|
||||
// Set the file and console log targets
|
||||
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
||||
logger = std::make_shared<spdlog::logger>(std::string{ "multi_sink" }, spdlog::sinks_init_list{ file_sink, console_sink });
|
||||
|
||||
spdlog::initialize_logger(logger);
|
||||
logger->set_level(spdlog::level::info);
|
||||
|
|
|
@ -33,7 +33,8 @@ public:
|
|||
|
||||
inline void assertion(const bool& expr, const char* msg)
|
||||
{
|
||||
if constexpr (DebugBuild) {
|
||||
if constexpr (DebugBuild)
|
||||
{
|
||||
if (!expr)
|
||||
{
|
||||
TENLog(msg, LogLevel::Error);
|
||||
|
|
|
@ -99,8 +99,17 @@ void TriggerChaffEffects(ItemInfo* item, Vector3Int* pos, Vector3Int* vel, int s
|
|||
}
|
||||
}
|
||||
|
||||
auto cond = TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item);
|
||||
SoundEffect(cond ? SFX_TR4_FLARE_BURN_UNDERWATER : SFX_TR4_FLARE_BURN_DRY, & item->Pose, cond ? SoundEnvironment::Water : SoundEnvironment::Always, 1.0f, 0.5f);
|
||||
PHD_3DPOS position = item->Pose;
|
||||
if (item->IsLara())
|
||||
{
|
||||
Vector3Int handPos = {};
|
||||
GetJointAbsPosition(item, &handPos, LM_RHAND);
|
||||
position.Position = handPos;
|
||||
position.Position.y -= 64;
|
||||
}
|
||||
|
||||
auto cond = TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, position.Position.x, position.Position.y, position.Position.z, item->RoomNumber);
|
||||
SoundEffect(cond ? SFX_TR4_FLARE_BURN_UNDERWATER : SFX_TR4_FLARE_BURN_DRY, &position, SoundEnvironment::Always, 1.0f, 0.5f);
|
||||
}
|
||||
|
||||
void TriggerChaffSparkles(Vector3Int* pos, Vector3Int* vel, CVECTOR* color, int age, ItemInfo* item)
|
||||
|
|
|
@ -162,6 +162,7 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num, short roomNumbe
|
|||
fragment->velocity = CalculateFragmentImpactVelocity(fragment->worldPosition, ShatterImpactData.impactDirection, ShatterImpactData.impactLocation);
|
||||
fragment->roomNumber = roomNumber;
|
||||
fragment->numBounces = 0;
|
||||
fragment->color = isStatic ? mesh->color : Vector4::One; // FIXME: SHATTER_ITEM must be refactored! -- Lwmte, 15.07.22
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ struct DebrisFragment
|
|||
float angularDrag;
|
||||
float friction;
|
||||
float restitution;
|
||||
Vector4 color;
|
||||
uint32_t roomNumber;
|
||||
uint32_t numBounces;
|
||||
bool active;
|
||||
|
|
|
@ -285,7 +285,7 @@ namespace TEN::Effects::Lightning
|
|||
}*/
|
||||
}
|
||||
|
||||
long LSpline(int x, int* knots, int nk)
|
||||
int LSpline(int x, int* knots, int nk)
|
||||
{
|
||||
int* k;
|
||||
int c1, c2, c3, ret, span;
|
||||
|
@ -299,11 +299,12 @@ namespace TEN::Effects::Lightning
|
|||
x -= 65536 * span;
|
||||
k = &knots[3 * span];
|
||||
c1 = k[3] + (k[3] >> 1) - (k[6] >> 1) - k[6] + (k[9] >> 1) + ((-k[0] - 1) >> 1);
|
||||
ret = (long long) c1 * x >> 16;
|
||||
ret = (long long)c1 * x >> 16;
|
||||
c2 = ret + 2 * k[6] - 2 * k[3] - (k[3] >> 1) - (k[9] >> 1) + k[0];
|
||||
ret = (long long) c2 * x >> 16;
|
||||
ret = (long long)c2 * x >> 16;
|
||||
c3 = ret + (k[6] >> 1) + ((-k[0] - 1) >> 1);
|
||||
ret = (long long) c3 * x >> 16;
|
||||
ret = (long long)c3 * x >> 16;
|
||||
|
||||
return ret + k[3];
|
||||
}
|
||||
|
||||
|
|
|
@ -569,7 +569,8 @@ void GuiController::DoDebouncedInput()
|
|||
{
|
||||
if (!dbSelect)
|
||||
{
|
||||
goSelect = (TrInput & IN_OPTION || TrInput & IN_DESELECT) ? 0 : 1;
|
||||
goSelect = ((TrInput & IN_OPTION) || (TrInput & IN_DESELECT) ||
|
||||
g_Gui.GetEnterInventory() != NO_ITEM) ? 0 : 1;
|
||||
dbSelect = !goSelect;
|
||||
}
|
||||
}
|
||||
|
@ -1091,7 +1092,7 @@ void GuiController::HandleOtherSettingsInput(bool pause)
|
|||
}
|
||||
}
|
||||
|
||||
if (goLeft)
|
||||
if (dbLeft)
|
||||
{
|
||||
switch (selected_option)
|
||||
{
|
||||
|
@ -1129,7 +1130,7 @@ void GuiController::HandleOtherSettingsInput(bool pause)
|
|||
}
|
||||
}
|
||||
|
||||
if (goRight)
|
||||
if (dbRight)
|
||||
{
|
||||
switch (selected_option)
|
||||
{
|
||||
|
@ -1951,8 +1952,6 @@ void GuiController::InitialiseInventory()
|
|||
{
|
||||
if (IsObjectInInventory(enterInventory))
|
||||
SetupObjectListStartPosition2(enterInventory);
|
||||
|
||||
enterInventory = NO_ITEM;
|
||||
}
|
||||
|
||||
ammo_selector_fade_val = 0;
|
||||
|
@ -3014,11 +3013,11 @@ void GuiController::DrawCurrentObjectList(int ringnum)
|
|||
nummeup = count;
|
||||
break;
|
||||
|
||||
case ID_ROCKET_LAUNCHER_ITEM:
|
||||
case ID_ROCKET_LAUNCHER_AMMO_ITEM:
|
||||
nummeup = Lara.Weapons[(int)LaraWeaponType::RocketLauncher].Ammo[(int)WeaponAmmoType::Ammo1].getCount();
|
||||
break;
|
||||
|
||||
case ID_HARPOON_ITEM:
|
||||
case ID_HARPOON_AMMO_ITEM:
|
||||
nummeup = Lara.Weapons[(int)LaraWeaponType::HarpoonGun].Ammo[(int)WeaponAmmoType::Ammo1].getCount();
|
||||
break;
|
||||
|
||||
|
@ -3284,6 +3283,8 @@ bool GuiController::CallInventory(bool reset_mode)
|
|||
if (useItem && !TrInput)
|
||||
exitLoop = true;
|
||||
|
||||
SetEnterInventory(NO_ITEM);
|
||||
|
||||
Camera.numberFrames = g_Renderer.SyncRenderer();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ float HealthBar = OldHitPoints;
|
|||
float MutateAmount = 0;
|
||||
int FlashState = 0;
|
||||
int FlashCount = 0;
|
||||
int PoisonFlag = 0;
|
||||
extern RendererHUDBar* g_HealthBar;
|
||||
extern RendererHUDBar* g_DashBar;
|
||||
extern RendererHUDBar* g_AirBar;
|
||||
|
@ -145,9 +144,6 @@ void UpdateHealthBar(ItemInfo* item, int flash)
|
|||
else
|
||||
DrawHealthBarOverlay(item, HealthBar / LARA_HEALTH_MAX);
|
||||
}
|
||||
|
||||
if (PoisonFlag)
|
||||
PoisonFlag--;
|
||||
}
|
||||
|
||||
void DrawAirBar(float value)
|
||||
|
|
|
@ -34,6 +34,5 @@ extern int HealthBarTimer;
|
|||
extern float HealthBar;
|
||||
extern float MutateAmount;
|
||||
extern int FlashState;
|
||||
extern int PoisonFlag;
|
||||
|
||||
extern bool EnableSmoothHealthBar;
|
||||
|
|
|
@ -612,7 +612,8 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
if (item->ObjectNumber == ID_BURNING_TORCH_ITEM)
|
||||
break;
|
||||
|
||||
AlignLaraPosition(&PickUpPosition, item, laraItem);
|
||||
if (!AlignLaraPosition(&PickUpPosition, item, laraItem))
|
||||
break;
|
||||
|
||||
if (item->ObjectNumber == ID_FLARE_ITEM)
|
||||
{
|
||||
|
@ -634,7 +635,8 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
if (item->ObjectNumber == ID_BURNING_TORCH_ITEM)
|
||||
break;
|
||||
|
||||
AlignLaraPosition(&PickUpPosition, item, laraItem);
|
||||
if (!AlignLaraPosition(&PickUpPosition, item, laraItem))
|
||||
break;
|
||||
|
||||
if (item->ObjectNumber == ID_FLARE_ITEM)
|
||||
{
|
||||
|
|
|
@ -242,7 +242,7 @@ namespace TEN::Entities::Generic
|
|||
if (GetCollidedObjects(item, 0, true, CollidedItems, CollidedMeshes, true))
|
||||
{
|
||||
LaraCollision.Setup.EnableObjectPush = true;
|
||||
if (CollidedItems)
|
||||
if (CollidedItems[0])
|
||||
{
|
||||
if (!Objects[CollidedItems[0]->ObjectNumber].intelligent &&
|
||||
CollidedItems[0]->ObjectNumber != ID_LARA)
|
||||
|
@ -250,10 +250,12 @@ namespace TEN::Entities::Generic
|
|||
ObjectCollision(CollidedItems[0] - g_Level.Items.data(), item, &LaraCollision);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (CollidedMeshes[0])
|
||||
{
|
||||
ItemPushStatic(item, CollidedMeshes[0], &LaraCollision);
|
||||
}
|
||||
|
||||
item->Animation.Velocity /= 2;
|
||||
item->Animation.Velocity = -int(item->Animation.Velocity / 1.5f);
|
||||
}
|
||||
|
||||
if (item->ItemFlags[3])
|
||||
|
|
|
@ -44,14 +44,15 @@ namespace TEN::Entities::Vehicles
|
|||
|
||||
constexpr auto MINECART_VELOCITY_DECEL = 6 * VEHICLE_VELOCITY_SCALE;
|
||||
|
||||
constexpr auto MINECART_SPEED_MIN = 10 * VEHICLE_VELOCITY_SCALE; // TODO: These two have confusing names. @Sezz
|
||||
constexpr auto MINECART_VELOCITY_MIN = 32;
|
||||
constexpr auto MINECART_FRICTION_VELOCITY_MIN = 70;
|
||||
constexpr auto MINECART_STOP_VELOCITY_MAX = 240;
|
||||
constexpr auto MINECART_VELOCITY_MIN = 10 * VEHICLE_VELOCITY_SCALE;
|
||||
constexpr auto MINECART_FRICTION_VELOCITY_MIN = 70 * VEHICLE_VELOCITY_SCALE;
|
||||
constexpr auto MINECART_STOP_VELOCITY_MIN = 1 * VEHICLE_VELOCITY_SCALE;
|
||||
constexpr auto MINECART_STOP_VELOCITY_MAX = 240 * VEHICLE_VELOCITY_SCALE;
|
||||
constexpr auto MINECART_VERTICAL_VELOCITY_MAX = 63 * VEHICLE_VELOCITY_SCALE;
|
||||
|
||||
constexpr auto MINECART_JUMP_VERTICAL_VELOCITY = 252 * VEHICLE_VELOCITY_SCALE;
|
||||
constexpr auto MINECART_TURN_DEATH_VELOCITY = 128;
|
||||
|
||||
constexpr auto MINECART_ANIM_VELOCITY_MIN = 32;
|
||||
constexpr auto MINECART_TURN_DEATH_ANIM_VELOCITY = 128;
|
||||
|
||||
constexpr auto MINECART_FORWARD_GRADIENT = -CLICK(0.5f);
|
||||
constexpr auto MINECART_BACK_GRADIENT = CLICK(0.5f);
|
||||
|
@ -244,14 +245,14 @@ namespace TEN::Entities::Vehicles
|
|||
}
|
||||
}
|
||||
|
||||
static short GetMinecartCollision(ItemInfo* minecartItem, short angle, int distance)
|
||||
static int GetMinecartCollision(ItemInfo* minecartItem, short angle, int distance)
|
||||
{
|
||||
auto probe = GetCollision(minecartItem, angle, distance, -LARA_HEIGHT);
|
||||
|
||||
if (probe.Position.Floor != NO_HEIGHT)
|
||||
probe.Position.Floor -= minecartItem->Pose.Position.y;
|
||||
|
||||
return (short)probe.Position.Floor;
|
||||
return probe.Position.Floor;
|
||||
}
|
||||
|
||||
static bool TestMinecartDismount(ItemInfo* laraItem, int direction)
|
||||
|
@ -446,15 +447,15 @@ namespace TEN::Entities::Vehicles
|
|||
minecart->Flags |= flags.MinecartLeft() ? MINECART_FLAG_TURNING_LEFT : MINECART_FLAG_TURNING_RIGHT;
|
||||
}
|
||||
|
||||
if (minecart->Velocity < MINECART_SPEED_MIN)
|
||||
minecart->Velocity = MINECART_SPEED_MIN;
|
||||
if (minecart->Velocity < MINECART_VELOCITY_MIN)
|
||||
minecart->Velocity = MINECART_VELOCITY_MIN;
|
||||
|
||||
minecart->Velocity -= minecart->Gradient * 4;
|
||||
minecartItem->Animation.Velocity = minecart->Velocity / VEHICLE_VELOCITY_SCALE;
|
||||
|
||||
if (minecartItem->Animation.Velocity < MINECART_VELOCITY_MIN)
|
||||
if (minecartItem->Animation.Velocity < MINECART_ANIM_VELOCITY_MIN)
|
||||
{
|
||||
minecartItem->Animation.Velocity = MINECART_VELOCITY_MIN;
|
||||
minecartItem->Animation.Velocity = MINECART_ANIM_VELOCITY_MIN;
|
||||
StopSoundEffect(SFX_TR3_VEHICLE_MINECART_TRACK_LOOP);
|
||||
|
||||
if (minecart->VerticalVelocity)
|
||||
|
@ -531,7 +532,7 @@ namespace TEN::Entities::Vehicles
|
|||
minecartItem->Pose.Position.x = minecart->TurnX + x * 3584;
|
||||
minecartItem->Pose.Position.z = minecart->TurnZ + z * 3584;
|
||||
|
||||
if (minecartItem->Animation.Velocity > MINECART_FRICTION_VELOCITY_MIN)
|
||||
if (minecart->Velocity > MINECART_FRICTION_VELOCITY_MIN)
|
||||
{
|
||||
SoundEffect(SFX_TR3_VEHICLE_MINECART_BRAKE, &minecartItem->Pose, SoundEnvironment::Always);
|
||||
TriggerWheelSparkles(minecartItem, (minecart->Flags & MINECART_FLAG_TURNING_RIGHT) != 0);
|
||||
|
@ -588,7 +589,7 @@ namespace TEN::Entities::Vehicles
|
|||
auto* minecart = GetMinecartInfo(minecartItem);
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
|
||||
short floorHeight;
|
||||
int floorHeight;
|
||||
|
||||
switch (laraItem->Animation.ActiveState)
|
||||
{
|
||||
|
@ -599,7 +600,7 @@ namespace TEN::Entities::Vehicles
|
|||
laraItem->Animation.TargetState = MINECART_STATE_DUCK;
|
||||
else if (TrInput & (VEHICLE_IN_BRAKE | VEHICLE_IN_SLOW))
|
||||
laraItem->Animation.TargetState = MINECART_STATE_BRAKE;
|
||||
else if (minecart->Velocity == MINECART_VELOCITY_MIN || minecart->Flags & MINECART_FLAG_STOPPED)
|
||||
else if (minecart->Velocity <= MINECART_STOP_VELOCITY_MIN || minecart->Flags & MINECART_FLAG_STOPPED)
|
||||
laraItem->Animation.TargetState = MINECART_STATE_IDLE;
|
||||
else if (minecart->Gradient < MINECART_FORWARD_GRADIENT)
|
||||
laraItem->Animation.TargetState = MINECART_STATE_FORWARD;
|
||||
|
@ -684,7 +685,7 @@ namespace TEN::Entities::Vehicles
|
|||
}
|
||||
}
|
||||
|
||||
if (minecart->Velocity > MINECART_VELOCITY_MIN)
|
||||
if (minecart->Velocity >= MINECART_VELOCITY_MIN)
|
||||
{
|
||||
if (TrInput & MINECART_IN_DUCK)
|
||||
laraItem->Animation.TargetState = MINECART_STATE_DUCK;
|
||||
|
@ -724,7 +725,7 @@ namespace TEN::Entities::Vehicles
|
|||
minecart->Velocity -= MINECART_VELOCITY_DECEL;
|
||||
SoundEffect(SFX_TR3_VEHICLE_MINECART_BRAKE, &laraItem->Pose, SoundEnvironment::Always);
|
||||
|
||||
if (minecartItem->Animation.Velocity > MINECART_FRICTION_VELOCITY_MIN)
|
||||
if (minecart->Velocity > MINECART_FRICTION_VELOCITY_MIN)
|
||||
{
|
||||
TriggerWheelSparkles(minecartItem, false);
|
||||
TriggerWheelSparkles(minecartItem, true);
|
||||
|
@ -819,7 +820,7 @@ namespace TEN::Entities::Vehicles
|
|||
if ((Wibble & 7) == 0)
|
||||
SoundEffect(SFX_TR3_VEHICLE_QUADBIKE_FRONT_IMPACT, &minecartItem->Pose, SoundEnvironment::Always);
|
||||
|
||||
TranslateItem(minecartItem, minecartItem->Pose.Orientation.y, MINECART_TURN_DEATH_VELOCITY);
|
||||
TranslateItem(minecartItem, minecartItem->Pose.Orientation.y, MINECART_TURN_DEATH_ANIM_VELOCITY);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1215,6 +1215,7 @@ namespace TEN::Entities::Vehicles
|
|||
else
|
||||
{
|
||||
motorbikeItem->ClearBits(JointBitType::Mesh, MotorbikeHeadLightJoints);
|
||||
motorbikeItem->ClearBits(JointBitType::Mesh, MotorbikeBrakeLightJoints);
|
||||
|
||||
drive = -1;
|
||||
collide = 0;
|
||||
|
|
|
@ -131,6 +131,8 @@ void ControlBodyPart(short fxNumber)
|
|||
fx->pos.Position.y + GenerateInt( 16, 32),
|
||||
fx->pos.Position.z + GenerateInt(-16, 16), fx->roomNumber);
|
||||
}
|
||||
|
||||
ExplodeFX(fx, -1, 32);
|
||||
KillEffect(fxNumber);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -258,8 +258,8 @@ void RollingBallControl(short itemNumber)
|
|||
SplashSetup.y = waterHeight - 1;
|
||||
SplashSetup.x = item->Pose.Position.x;
|
||||
SplashSetup.z = item->Pose.Position.z;
|
||||
SplashSetup.splashPower = item->Animation.VerticalVelocity * 2;
|
||||
SplashSetup.innerRadius = 96;
|
||||
SplashSetup.splashPower = item->Animation.VerticalVelocity * 4;
|
||||
SplashSetup.innerRadius = 160;
|
||||
SetupSplash(&SplashSetup, roomNumber);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
struct alignas(16) CItemBuffer
|
||||
{
|
||||
Matrix World;
|
||||
Matrix BonesMatrices[32];
|
||||
Matrix BonesMatrices[MAX_BONES];
|
||||
Vector4 Position;
|
||||
Vector4 AmbientLight;
|
||||
int BoneLightModes[MAX_BONES];
|
||||
};
|
||||
|
|
|
@ -6,5 +6,4 @@ struct alignas(16) CLightBuffer
|
|||
{
|
||||
ShaderLight Lights[NUM_LIGHTS_PER_BUFFER];
|
||||
int NumLights;
|
||||
Vector3 CameraPosition;
|
||||
};
|
||||
|
|
|
@ -4,5 +4,5 @@
|
|||
struct alignas(16) CRoomBuffer
|
||||
{
|
||||
DirectX::SimpleMath::Vector4 AmbientColor;
|
||||
int Water;
|
||||
unsigned int Water;
|
||||
};
|
||||
|
|
|
@ -3,13 +3,14 @@
|
|||
struct alignas(16) ShaderLight
|
||||
{
|
||||
Vector3 Position;
|
||||
int Type;
|
||||
unsigned int Type;
|
||||
Vector3 Color;
|
||||
int LocalIntensity;
|
||||
Vector3 Direction;
|
||||
float Distance;
|
||||
float Intensity;
|
||||
Vector3 Direction;
|
||||
float In;
|
||||
float Out;
|
||||
float Range;
|
||||
float InRange;
|
||||
float OutRange;
|
||||
|
||||
float padding;
|
||||
};
|
||||
|
|
|
@ -5,4 +5,5 @@ struct alignas(16) CStaticBuffer
|
|||
Matrix World;
|
||||
Vector4 Position;
|
||||
Vector4 Color;
|
||||
int LightMode;
|
||||
};
|
||||
|
|
|
@ -43,10 +43,11 @@ namespace TEN::Renderer
|
|||
m_spritesTextures.resize(0);
|
||||
m_animatedTextures.resize(0);
|
||||
m_animatedTextureSets.resize(0);
|
||||
for (auto& mesh : m_meshes) {
|
||||
|
||||
for (auto& mesh : m_meshes)
|
||||
delete mesh;
|
||||
}
|
||||
m_meshes.resize(0);
|
||||
|
||||
for (auto& item : m_items)
|
||||
{
|
||||
item.PreviousRoomNumber = NO_ROOM;
|
||||
|
@ -315,6 +316,16 @@ namespace TEN::Renderer
|
|||
m_context->PSSetSamplers(registerType, 1, &samplerState);
|
||||
}
|
||||
|
||||
void Renderer11::BindLights(std::vector<RendererLight*>& lights)
|
||||
{
|
||||
m_stLights.NumLights = lights.size();
|
||||
for (int j = 0; j < lights.size(); j++)
|
||||
memcpy(&m_stLights.Lights[j], lights[j], sizeof(ShaderLight));
|
||||
m_cbLights.updateData(m_stLights, m_context.Get());
|
||||
BindConstantBufferPS(CB_LIGHTS, m_cbLights.get());
|
||||
BindConstantBufferVS(CB_LIGHTS, m_cbLights.get());
|
||||
}
|
||||
|
||||
void Renderer11::BindConstantBufferVS(CONSTANT_BUFFERS constantBufferType, ID3D11Buffer** buffer)
|
||||
{
|
||||
m_context->VSSetConstantBuffers(static_cast<UINT>(constantBufferType), 1, buffer);
|
||||
|
|
|
@ -81,9 +81,10 @@ namespace TEN::Renderer
|
|||
struct RendererStatic
|
||||
{
|
||||
int Id;
|
||||
short RoomIndex;
|
||||
MESH_INFO* Mesh;
|
||||
int RoomIndex;
|
||||
Matrix World;
|
||||
Vector4 AmbientLight;
|
||||
std::vector<RendererLight*> LightsToDraw;
|
||||
};
|
||||
|
||||
struct RendererRoomNode
|
||||
|
@ -95,7 +96,7 @@ namespace TEN::Renderer
|
|||
|
||||
struct RendererItem
|
||||
{
|
||||
short ItemNumber;
|
||||
int ItemNumber;
|
||||
bool DoneAnimations;
|
||||
Matrix World;
|
||||
Matrix Translation;
|
||||
|
@ -111,8 +112,9 @@ namespace TEN::Renderer
|
|||
|
||||
struct RendererMesh
|
||||
{
|
||||
LIGHT_MODES LightMode;
|
||||
BoundingSphere Sphere;
|
||||
std::vector<RendererBucket> buckets;
|
||||
std::vector<RendererBucket> Buckets;
|
||||
std::vector<Vector3> Positions;
|
||||
};
|
||||
|
||||
|
@ -122,7 +124,7 @@ namespace TEN::Renderer
|
|||
FX_INFO* Effect;
|
||||
Matrix World;
|
||||
RendererMesh* Mesh;
|
||||
std::vector<RendererLight*> Lights;
|
||||
std::vector<RendererLight*> LightsToDraw;
|
||||
};
|
||||
|
||||
struct RendererObject
|
||||
|
@ -194,9 +196,9 @@ namespace TEN::Renderer
|
|||
|
||||
struct RendererLine3D
|
||||
{
|
||||
Vector3 start;
|
||||
Vector3 end;
|
||||
Vector4 color;
|
||||
Vector3 Start;
|
||||
Vector3 End;
|
||||
Vector4 Color;
|
||||
};
|
||||
|
||||
struct RendererLine2D
|
||||
|
@ -421,6 +423,7 @@ namespace TEN::Renderer
|
|||
|
||||
// Private functions
|
||||
void BindTexture(TEXTURE_REGISTERS registerType, TextureBase* texture, SAMPLER_STATES samplerType);
|
||||
void BindLights(std::vector<RendererLight*>& lights);
|
||||
void BindRenderTargetAsTexture(TEXTURE_REGISTERS registerType, RenderTarget2D* target, SAMPLER_STATES samplerType);
|
||||
void BindConstantBufferVS(CONSTANT_BUFFERS constantBufferType, ID3D11Buffer** buffer);
|
||||
void BindConstantBufferPS(CONSTANT_BUFFERS constantBufferType, ID3D11Buffer** buffer);
|
||||
|
@ -434,11 +437,13 @@ namespace TEN::Renderer
|
|||
void SetRoomBounds(ROOM_DOOR* door, short parentRoomNumber, RenderView& renderView);
|
||||
void CollectRooms(RenderView& renderView, bool onlyRooms);
|
||||
void CollectItems(short roomNumber, RenderView& renderView);
|
||||
void CollectStatics(short roomNumber, RenderView& renderView);
|
||||
void CollectLightsForEffect(short roomNumber, RendererEffect* effect, RenderView& renderView);
|
||||
void CollectLightsForItem(short roomNumber, RendererItem* item, RenderView& renderView);
|
||||
void CollectStatics(short roomNumber);
|
||||
void CollectLights(Vector3Int position, int roomNumber, bool collectShadowLight, std::vector<RendererLight*>& lights);
|
||||
void CollectLightsForItem(short roomNumber, RendererItem* item, bool collectShadowLight);
|
||||
void CollectLightsForEffect(short roomNumber, RendererEffect* effect);
|
||||
void CollectLightsForRoom(short roomNumber, RenderView& renderView);
|
||||
void CollectEffects(short roomNumber, RenderView& renderView);
|
||||
void CalculateAmbientLight(RendererItem* item);
|
||||
void CollectEffects(short roomNumber);
|
||||
void ClearScene();
|
||||
void ClearSceneItems();
|
||||
void ClearDynamicLights();
|
||||
|
@ -585,7 +590,7 @@ namespace TEN::Renderer
|
|||
void Initialise(int w, int h, bool windowed, HWND handle);
|
||||
void Draw();
|
||||
bool PrepareDataForTheRenderer();
|
||||
void UpdateCameraMatrices(CAMERA_INFO* cam, float roll, float fov);
|
||||
void UpdateCameraMatrices(CAMERA_INFO* cam, float roll, float fov, float farView);
|
||||
void RenderSimpleScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, RenderView& view);
|
||||
void DumpGameScene();
|
||||
void RenderInventory();
|
||||
|
@ -602,7 +607,7 @@ namespace TEN::Renderer
|
|||
void RenderLoadingScreen(float percentage);
|
||||
void UpdateProgress(float value);
|
||||
void GetLaraBonePosition(Vector3* pos, int bone);
|
||||
void ToggleFullScreen();
|
||||
void ToggleFullScreen(bool force = false);
|
||||
bool IsFullsScreen();
|
||||
void RenderTitleImage();
|
||||
void AddLine2D(int x1, int y1, int x2, int y2, byte r, byte g, byte b, byte a);
|
||||
|
|
|
@ -165,9 +165,7 @@ namespace TEN::Renderer
|
|||
r->TransparentFacesToDraw.reserve(MAX_TRANSPARENT_FACES_PER_ROOM);
|
||||
|
||||
if (room.mesh.size() > 0)
|
||||
{
|
||||
r->StaticsToDraw.reserve(room.mesh.size());
|
||||
}
|
||||
|
||||
if (room.positions.size() == 0)
|
||||
continue;
|
||||
|
@ -218,13 +216,13 @@ namespace TEN::Renderer
|
|||
vertex->UV = poly.textureCoordinates[k];
|
||||
vertex->Color = Vector4(room.colors[index].x, room.colors[index].y, room.colors[index].z, 1.0f);
|
||||
vertex->Tangent = poly.tangents[k];
|
||||
vertex->BiTangent = poly.bitangents[k];
|
||||
vertex->AnimationFrameOffset = poly.animatedFrame;
|
||||
vertex->IndexInPoly = k;
|
||||
vertex->OriginalIndex = index;
|
||||
vertex->Effects = Vector4(room.effects[index].x, room.effects[index].y, room.effects[index].z, 0);
|
||||
|
||||
const unsigned long long primes[]{ 73856093ULL, 19349663ULL, 83492791ULL };
|
||||
vertex->hash = std::hash<float>{}((vertex->Position.x)* primes[0]) ^ (std::hash<float>{}(vertex->Position.y)* primes[1]) ^ std::hash<float>{}(vertex->Position.z) * primes[2];
|
||||
vertex->Hash = std::hash<float>{}((vertex->Position.x)* primes[0]) ^ (std::hash<float>{}(vertex->Position.y)* primes[1]) ^ std::hash<float>{}(vertex->Position.z) * primes[2];
|
||||
vertex->Bone = 0;
|
||||
|
||||
lastVertex++;
|
||||
|
@ -269,12 +267,14 @@ namespace TEN::Renderer
|
|||
RendererLight* light = &r->Lights[l];
|
||||
ROOM_LIGHT* oldLight = &room.lights[l];
|
||||
|
||||
// Monty's temp variables for sorting
|
||||
light->LocalIntensity = 0;
|
||||
light->Distance = 0;
|
||||
|
||||
if (oldLight->type == LIGHT_TYPES::LIGHT_TYPE_SUN)
|
||||
{
|
||||
light->Color = Vector3(oldLight->r, oldLight->g, oldLight->b) * oldLight->intensity;
|
||||
light->Intensity = 1.0f;
|
||||
light->LocalIntensity = 0;
|
||||
light->Distance = 0;
|
||||
light->Intensity = oldLight->intensity;
|
||||
light->Direction = Vector3(oldLight->dx, oldLight->dy, oldLight->dz);
|
||||
light->CastShadows = oldLight->castShadows;
|
||||
light->Type = LIGHT_TYPES::LIGHT_TYPE_SUN;
|
||||
|
@ -283,9 +283,7 @@ namespace TEN::Renderer
|
|||
{
|
||||
light->Position = Vector3(oldLight->x, oldLight->y, oldLight->z);
|
||||
light->Color = Vector3(oldLight->r, oldLight->g, oldLight->b) * oldLight->intensity;
|
||||
light->Intensity = 1.0f;
|
||||
light->LocalIntensity = 0;
|
||||
light->Distance = 0;
|
||||
light->Intensity = oldLight->intensity;
|
||||
light->In = oldLight->in;
|
||||
light->Out = oldLight->out;
|
||||
light->CastShadows = oldLight->castShadows;
|
||||
|
@ -295,25 +293,22 @@ namespace TEN::Renderer
|
|||
{
|
||||
light->Position = Vector3(oldLight->x, oldLight->y, oldLight->z);
|
||||
light->Color = Vector3(oldLight->r, oldLight->g, oldLight->b) * oldLight->intensity;
|
||||
light->Intensity = 1.0f;
|
||||
light->LocalIntensity = 0;
|
||||
light->Distance = 0;
|
||||
light->Intensity = oldLight->intensity;
|
||||
light->In = oldLight->in;
|
||||
light->Out = oldLight->out;
|
||||
light->CastShadows = false;
|
||||
light->Type = LIGHT_TYPE_SHADOW;
|
||||
light->Intensity = 1.0f;
|
||||
}
|
||||
else if (oldLight->type == LIGHT_TYPE_SPOT)
|
||||
{
|
||||
light->Position = Vector3(oldLight->x, oldLight->y, oldLight->z);
|
||||
light->Color = Vector3(oldLight->r, oldLight->g, oldLight->b) * oldLight->intensity;
|
||||
light->Intensity = 1.0f;
|
||||
light->LocalIntensity = 0;
|
||||
light->Distance = 0;
|
||||
light->Intensity = oldLight->intensity;
|
||||
light->Direction = Vector3(oldLight->dx, oldLight->dy, oldLight->dz);
|
||||
light->In = oldLight->in;
|
||||
light->Out = oldLight->out;
|
||||
light->Range = oldLight->length;
|
||||
light->In = oldLight->length;
|
||||
light->Out = oldLight->cutoff;
|
||||
light->InRange = oldLight->in;
|
||||
light->OutRange = oldLight->out;
|
||||
light->CastShadows = oldLight->castShadows;
|
||||
light->Type = LIGHT_TYPE_SPOT;
|
||||
}
|
||||
|
@ -503,9 +498,9 @@ namespace TEN::Renderer
|
|||
BonesToCheck[0] = jointBone->Parent->Index;
|
||||
BonesToCheck[1] = j;
|
||||
|
||||
for (int b1 = 0; b1 < jointMesh->buckets.size(); b1++)
|
||||
for (int b1 = 0; b1 < jointMesh->Buckets.size(); b1++)
|
||||
{
|
||||
RendererBucket *jointBucket = &jointMesh->buckets[b1];
|
||||
RendererBucket *jointBucket = &jointMesh->Buckets[b1];
|
||||
|
||||
for (int v1 = 0; v1 < jointBucket->NumVertices; v1++)
|
||||
{
|
||||
|
@ -518,9 +513,9 @@ namespace TEN::Renderer
|
|||
RendererMesh *skinMesh = objSkin.ObjectMeshes[BonesToCheck[k]];
|
||||
RendererBone *skinBone = objSkin.LinearizedBones[BonesToCheck[k]];
|
||||
|
||||
for (int b2 = 0; b2 < skinMesh->buckets.size(); b2++)
|
||||
for (int b2 = 0; b2 < skinMesh->Buckets.size(); b2++)
|
||||
{
|
||||
RendererBucket *skinBucket = &skinMesh->buckets[b2];
|
||||
RendererBucket *skinBucket = &skinMesh->Buckets[b2];
|
||||
for (int v2 = 0; v2 < skinBucket->NumVertices; v2++)
|
||||
{
|
||||
RendererVertex *skinVertex = &moveablesVertices[skinBucket->StartVertex + v2];
|
||||
|
@ -565,9 +560,9 @@ namespace TEN::Renderer
|
|||
RendererMesh* currentMesh = moveable.ObjectMeshes[j];
|
||||
RendererBone* currentBone = moveable.LinearizedBones[j];
|
||||
|
||||
for (int b1 = 0; b1 < currentMesh->buckets.size(); b1++)
|
||||
for (int b1 = 0; b1 < currentMesh->Buckets.size(); b1++)
|
||||
{
|
||||
RendererBucket* currentBucket = ¤tMesh->buckets[b1];
|
||||
RendererBucket* currentBucket = ¤tMesh->Buckets[b1];
|
||||
|
||||
for (int v1 = 0; v1 < currentBucket->NumVertices; v1++)
|
||||
{
|
||||
|
@ -585,9 +580,9 @@ namespace TEN::Renderer
|
|||
|
||||
if (currentVertex->OriginalIndex < 4)
|
||||
{
|
||||
for (int b2 = 0; b2 < parentMesh->buckets.size(); b2++)
|
||||
for (int b2 = 0; b2 < parentMesh->Buckets.size(); b2++)
|
||||
{
|
||||
RendererBucket* parentBucket = &parentMesh->buckets[b2];
|
||||
RendererBucket* parentBucket = &parentMesh->Buckets[b2];
|
||||
for (int v2 = 0; v2 < parentBucket->NumVertices; v2++)
|
||||
{
|
||||
RendererVertex* parentVertex = &moveablesVertices[parentBucket->StartVertex + v2];
|
||||
|
@ -608,9 +603,9 @@ namespace TEN::Renderer
|
|||
RendererMesh* parentMesh = moveable.ObjectMeshes[j - 1];
|
||||
RendererBone* parentBone = moveable.LinearizedBones[j - 1];
|
||||
|
||||
for (int b2 = 0; b2 < parentMesh->buckets.size(); b2++)
|
||||
for (int b2 = 0; b2 < parentMesh->Buckets.size(); b2++)
|
||||
{
|
||||
RendererBucket* parentBucket = &parentMesh->buckets[b2];
|
||||
RendererBucket* parentBucket = &parentMesh->Buckets[b2];
|
||||
for (int v2 = 0; v2 < parentBucket->NumVertices; v2++)
|
||||
{
|
||||
RendererVertex* parentVertex = &moveablesVertices[parentBucket->StartVertex + v2];
|
||||
|
@ -628,7 +623,7 @@ namespace TEN::Renderer
|
|||
currentVertex->Bone = j;
|
||||
currentVertex->Position = parentVertex->Position;
|
||||
currentVertex->Normal = parentVertex->Normal;
|
||||
currentVertex->BiTangent = parentVertex->BiTangent;
|
||||
currentVertex->AnimationFrameOffset = parentVertex->AnimationFrameOffset;
|
||||
currentVertex->Tangent = parentVertex->Tangent;
|
||||
break;
|
||||
}
|
||||
|
@ -753,6 +748,7 @@ namespace TEN::Renderer
|
|||
RendererMesh* mesh = new RendererMesh();
|
||||
|
||||
mesh->Sphere = meshPtr->sphere;
|
||||
mesh->LightMode = LIGHT_MODES(meshPtr->lightMode);
|
||||
|
||||
if (meshPtr->positions.size() == 0)
|
||||
return mesh;
|
||||
|
@ -811,7 +807,7 @@ namespace TEN::Renderer
|
|||
vertex.OriginalIndex = v;
|
||||
|
||||
vertex.Effects = Vector4(meshPtr->effects[v].x, meshPtr->effects[v].y, meshPtr->effects[v].z, poly->shineStrength);
|
||||
vertex.hash = std::hash<float>{}(vertex.Position.x) ^ std::hash<float>{}(vertex.Position.y) ^ std::hash<float>{}(vertex.Position.z);
|
||||
vertex.Hash = std::hash<float>{}(vertex.Position.x) ^ std::hash<float>{}(vertex.Position.y) ^ std::hash<float>{}(vertex.Position.z);
|
||||
|
||||
if (obj->Type == 0)
|
||||
moveablesVertices[*lastVertex] = vertex;
|
||||
|
@ -869,7 +865,7 @@ namespace TEN::Renderer
|
|||
bucket.Polygons.push_back(newPoly);
|
||||
}
|
||||
|
||||
mesh->buckets.push_back(bucket);
|
||||
mesh->Buckets.push_back(bucket);
|
||||
}
|
||||
|
||||
m_meshes.push_back(mesh);
|
||||
|
|
|
@ -182,20 +182,19 @@ namespace TEN::Renderer
|
|||
if (shadowLight->Type == LIGHT_TYPE_POINT)
|
||||
{
|
||||
view = Matrix::CreateLookAt(lightPos, lightPos +
|
||||
RenderTargetCube::forwardVectors[step]*10240,
|
||||
RenderTargetCube::forwardVectors[step] * SECTOR(10),
|
||||
RenderTargetCube::upVectors[step]);
|
||||
|
||||
projection = Matrix::CreatePerspectiveFieldOfView(90.0f, 1.0f, 16.0f,
|
||||
shadowLight->Out);
|
||||
projection = Matrix::CreatePerspectiveFieldOfView(90.0f, 1.0f, 16.0f, shadowLight->Out);
|
||||
|
||||
}
|
||||
else if(shadowLight->Type == LIGHT_TYPE_SPOT)
|
||||
else if (shadowLight->Type == LIGHT_TYPE_SPOT)
|
||||
{
|
||||
view = Matrix::CreateLookAt(lightPos,
|
||||
lightPos - shadowLight->Direction*10240,
|
||||
lightPos - shadowLight->Direction * SECTOR(10),
|
||||
Vector3(0.0f, -1.0f, 0.0f));
|
||||
|
||||
projection = Matrix::CreatePerspectiveFieldOfView(shadowLight->Out, 1.0f, 16.0f,shadowLight->Range);
|
||||
projection = Matrix::CreatePerspectiveFieldOfView(shadowLight->OutRange, 1.0f, 16.0f, shadowLight->Out);
|
||||
}
|
||||
|
||||
CCameraMatrixBuffer shadowProjection;
|
||||
|
@ -214,16 +213,19 @@ namespace TEN::Renderer
|
|||
m_stItem.World = m_LaraWorldMatrix;
|
||||
m_stItem.Position = Vector4(LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z, 1.0f);
|
||||
m_stItem.AmbientLight = room.AmbientLight;
|
||||
memcpy(m_stItem.BonesMatrices, laraObj.AnimationTransforms.data(), sizeof(Matrix) * 32);
|
||||
memcpy(m_stItem.BonesMatrices, laraObj.AnimationTransforms.data(), sizeof(Matrix) * MAX_BONES);
|
||||
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
|
||||
m_stItem.BoneLightModes[k] = GetMesh(Lara.MeshPtrs[k])->LightMode;
|
||||
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
|
||||
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
|
||||
|
||||
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
|
||||
{
|
||||
RendererMesh* mesh = GetMesh(Lara.MeshPtrs[k]);
|
||||
auto* mesh = GetMesh(Lara.MeshPtrs[k]);
|
||||
|
||||
for (auto& bucket : mesh->buckets)
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0 && bucket.BlendMode != BLEND_MODES::BLENDMODE_OPAQUE)
|
||||
continue;
|
||||
|
@ -243,7 +245,7 @@ namespace TEN::Renderer
|
|||
{
|
||||
RendererMesh* mesh = laraSkinJoints.ObjectMeshes[k];
|
||||
|
||||
for (auto& bucket : mesh->buckets)
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0 && bucket.BlendMode != BLEND_MODES::BLENDMODE_OPAQUE)
|
||||
continue;
|
||||
|
@ -260,7 +262,7 @@ namespace TEN::Renderer
|
|||
{
|
||||
RendererMesh* mesh = laraSkin.ObjectMeshes[k];
|
||||
|
||||
for (auto& bucket : mesh->buckets)
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0 && bucket.BlendMode != BLEND_MODES::BLENDMODE_OPAQUE)
|
||||
continue;
|
||||
|
@ -278,16 +280,17 @@ namespace TEN::Renderer
|
|||
|
||||
// First matrix is Lara's head matrix, then all 6 hairs matrices. Bones are adjusted at load time for accounting this.
|
||||
m_stItem.World = Matrix::Identity;
|
||||
Matrix matrices[7];
|
||||
matrices[0] = laraObj.AnimationTransforms[LM_HEAD] * m_LaraWorldMatrix;
|
||||
m_stItem.BonesMatrices[0] = laraObj.AnimationTransforms[LM_HEAD] * m_LaraWorldMatrix;
|
||||
|
||||
for (int i = 0; i < hairsObj.BindPoseTransforms.size(); i++)
|
||||
{
|
||||
HAIR_STRUCT* hairs = &Hairs[0][i];
|
||||
auto* hairs = &Hairs[0][i];
|
||||
Matrix world = Matrix::CreateFromYawPitchRoll(TO_RAD(hairs->pos.Orientation.y), TO_RAD(hairs->pos.Orientation.x), 0) *
|
||||
Matrix::CreateTranslation(hairs->pos.Position.x, hairs->pos.Position.y, hairs->pos.Position.z);
|
||||
matrices[i + 1] = world;
|
||||
Matrix::CreateTranslation(hairs->pos.Position.x, hairs->pos.Position.y, hairs->pos.Position.z);
|
||||
m_stItem.BonesMatrices[i + 1] = world;
|
||||
m_stItem.BoneLightModes[i] = LIGHT_MODES::LIGHT_MODE_DYNAMIC;
|
||||
}
|
||||
memcpy(m_stItem.BonesMatrices, matrices, sizeof(Matrix) * 7);
|
||||
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
|
||||
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
|
||||
|
@ -296,7 +299,7 @@ namespace TEN::Renderer
|
|||
{
|
||||
RendererMesh* mesh = hairsObj.ObjectMeshes[k];
|
||||
|
||||
for (auto& bucket : mesh->buckets)
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0 && bucket.BlendMode != BLEND_MODES::BLENDMODE_OPAQUE)
|
||||
continue;
|
||||
|
@ -316,14 +319,10 @@ namespace TEN::Renderer
|
|||
RendererRoom& room = m_rooms[LaraItem->RoomNumber];
|
||||
RendererItem* item = &m_items[Lara.ItemNumber];
|
||||
|
||||
m_stItem.AmbientLight = room.AmbientLight;
|
||||
memcpy(m_stItem.BonesMatrices, &Matrix::Identity, sizeof(Matrix));
|
||||
m_stStatic.Color = room.AmbientLight;
|
||||
m_stStatic.LightMode = LIGHT_MODES::LIGHT_MODE_DYNAMIC;
|
||||
|
||||
m_stLights.NumLights = item->LightsToDraw.size();
|
||||
for (int j = 0; j < item->LightsToDraw.size(); j++)
|
||||
memcpy(&m_stLights.Lights[j], item->LightsToDraw[j], sizeof(ShaderLight));
|
||||
m_cbLights.updateData(m_stLights, m_context.Get());
|
||||
BindConstantBufferPS(CB_LIGHTS, m_cbLights.get());
|
||||
BindLights(item->LightsToDraw);
|
||||
|
||||
SetAlphaTest(ALPHA_TEST_GREATER_THAN, ALPHA_TEST_THRESHOLD);
|
||||
|
||||
|
@ -342,13 +341,16 @@ namespace TEN::Renderer
|
|||
TO_RAD(gunshell->pos.Orientation.z));
|
||||
Matrix world = rotation * translation;
|
||||
|
||||
m_stItem.World = world;
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
|
||||
m_stStatic.World = world;
|
||||
m_stStatic.LightMode = LIGHT_MODES::LIGHT_MODE_DYNAMIC;
|
||||
|
||||
m_cbStatic.updateData(m_stStatic, m_context.Get());
|
||||
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
|
||||
BindConstantBufferPS(CB_STATIC, m_cbStatic.get());
|
||||
|
||||
RendererMesh* mesh = moveableObj.ObjectMeshes[0];
|
||||
|
||||
for (auto& bucket : mesh->buckets)
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0 && bucket.BlendMode == BLEND_MODES::BLENDMODE_OPAQUE)
|
||||
continue;
|
||||
|
@ -552,8 +554,10 @@ namespace TEN::Renderer
|
|||
ObjectInfo* obj = &Objects[ID_RATS_EMITTER];
|
||||
RendererObject& moveableObj = *m_moveableObjects[ID_RATS_EMITTER];
|
||||
|
||||
for (int m = 0; m < 32; m++)
|
||||
for (int m = 0; m < MAX_BONES; m++)
|
||||
memcpy(&m_stItem.BonesMatrices[m], &Matrix::Identity, sizeof(Matrix));
|
||||
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
||||
m_stItem.BoneLightModes[k] = moveableObj.ObjectMeshes[k]->LightMode;
|
||||
|
||||
for (int i = 0; i < NUM_RATS; i++)
|
||||
{
|
||||
|
@ -572,9 +576,9 @@ namespace TEN::Renderer
|
|||
m_stItem.AmbientLight = m_rooms[rat->RoomNumber].AmbientLight;
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
|
||||
for (int b = 0; b < mesh->buckets.size(); b++)
|
||||
for (int b = 0; b < mesh->Buckets.size(); b++)
|
||||
{
|
||||
RendererBucket* bucket = &mesh->buckets[b];
|
||||
RendererBucket* bucket = &mesh->Buckets[b];
|
||||
|
||||
if (bucket->Polygons.size() == 0)
|
||||
continue;
|
||||
|
@ -604,12 +608,14 @@ namespace TEN::Renderer
|
|||
RendererObject& moveableObj = *m_moveableObjects[ID_BATS_EMITTER];
|
||||
RendererMesh* mesh = GetMesh(Objects[ID_BATS_EMITTER].meshIndex + (-GlobalCounter & 3));
|
||||
|
||||
for (int m = 0; m < 32; m++)
|
||||
for (int m = 0; m < MAX_BONES; m++)
|
||||
memcpy(&m_stItem.BonesMatrices[m], &Matrix::Identity, sizeof(Matrix));
|
||||
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
||||
m_stItem.BoneLightModes[k] = moveableObj.ObjectMeshes[k]->LightMode;
|
||||
|
||||
for (int b = 0; b < mesh->buckets.size(); b++)
|
||||
for (int b = 0; b < mesh->Buckets.size(); b++)
|
||||
{
|
||||
RendererBucket* bucket = &mesh->buckets[b];
|
||||
RendererBucket* bucket = &mesh->Buckets[b];
|
||||
|
||||
if (bucket->Polygons.size() == 0)
|
||||
continue;
|
||||
|
@ -654,8 +660,10 @@ namespace TEN::Renderer
|
|||
ObjectInfo* obj = &Objects[ID_LITTLE_BEETLE];
|
||||
RendererObject& moveableObj = *m_moveableObjects[ID_LITTLE_BEETLE];
|
||||
|
||||
for (int m = 0; m < 32; m++)
|
||||
for (int m = 0; m < MAX_BONES; m++)
|
||||
memcpy(&m_stItem.BonesMatrices[m], &Matrix::Identity, sizeof(Matrix));
|
||||
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
||||
m_stItem.BoneLightModes[k] = moveableObj.ObjectMeshes[k]->LightMode;
|
||||
|
||||
for (int i = 0; i < TEN::Entities::TR4::NUM_BEETLES; i++)
|
||||
{
|
||||
|
@ -675,9 +683,9 @@ namespace TEN::Renderer
|
|||
m_stItem.AmbientLight = m_rooms[beetle->RoomNumber].AmbientLight;
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
|
||||
for (int b = 0; b < mesh->buckets.size(); b++)
|
||||
for (int b = 0; b < mesh->Buckets.size(); b++)
|
||||
{
|
||||
RendererBucket* bucket = &mesh->buckets[b];
|
||||
RendererBucket* bucket = &mesh->Buckets[b];
|
||||
|
||||
if (bucket->Polygons.size() == 0)
|
||||
continue;
|
||||
|
@ -706,8 +714,10 @@ namespace TEN::Renderer
|
|||
ObjectInfo* obj = &Objects[ID_LOCUSTS];
|
||||
RendererObject& moveableObj = *m_moveableObjects[ID_LOCUSTS];
|
||||
|
||||
for (int m = 0; m < 32; m++)
|
||||
for (int m = 0; m < MAX_BONES; m++)
|
||||
memcpy(&m_stItem.BonesMatrices[m], &Matrix::Identity, sizeof(Matrix));
|
||||
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
||||
m_stItem.BoneLightModes[k] = moveableObj.ObjectMeshes[k]->LightMode;
|
||||
|
||||
for (int i = 0; i < TEN::Entities::TR4::MAX_LOCUSTS; i++)
|
||||
{
|
||||
|
@ -727,9 +737,9 @@ namespace TEN::Renderer
|
|||
m_stItem.AmbientLight = m_rooms[locust->roomNumber].AmbientLight;
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
|
||||
for (int b = 0; b < mesh->buckets.size(); b++)
|
||||
for (int b = 0; b < mesh->Buckets.size(); b++)
|
||||
{
|
||||
RendererBucket* bucket = &mesh->buckets[b];
|
||||
RendererBucket* bucket = &mesh->Buckets[b];
|
||||
|
||||
if (bucket->Polygons.size() == 0)
|
||||
continue;
|
||||
|
@ -761,12 +771,12 @@ namespace TEN::Renderer
|
|||
RendererLine3D* line = &m_lines3DToDraw[i];
|
||||
|
||||
RendererVertex v1;
|
||||
v1.Position = line->start;
|
||||
v1.Color = line->color;
|
||||
v1.Position = line->Start;
|
||||
v1.Color = line->Color;
|
||||
|
||||
RendererVertex v2;
|
||||
v2.Position = line->end;
|
||||
v2.Color = line->color;
|
||||
v2.Position = line->End;
|
||||
v2.Color = line->Color;
|
||||
m_primitiveBatch->DrawLine(v1, v2);
|
||||
}
|
||||
|
||||
|
@ -780,9 +790,9 @@ namespace TEN::Renderer
|
|||
{
|
||||
RendererLine3D line;
|
||||
|
||||
line.start = start;
|
||||
line.end = end;
|
||||
line.color = color;
|
||||
line.Start = start;
|
||||
line.End = end;
|
||||
line.Color = color;
|
||||
|
||||
m_lines3DToDraw.push_back(line);
|
||||
}
|
||||
|
@ -838,49 +848,49 @@ namespace TEN::Renderer
|
|||
|
||||
switch (i)
|
||||
{
|
||||
case 0: line.start = corners[0];
|
||||
line.end = corners[1];
|
||||
case 0: line.Start = corners[0];
|
||||
line.End = corners[1];
|
||||
break;
|
||||
case 1: line.start = corners[1];
|
||||
line.end = corners[2];
|
||||
case 1: line.Start = corners[1];
|
||||
line.End = corners[2];
|
||||
break;
|
||||
case 2: line.start = corners[2];
|
||||
line.end = corners[3];
|
||||
case 2: line.Start = corners[2];
|
||||
line.End = corners[3];
|
||||
break;
|
||||
case 3: line.start = corners[3];
|
||||
line.end = corners[0];
|
||||
case 3: line.Start = corners[3];
|
||||
line.End = corners[0];
|
||||
break;
|
||||
|
||||
|
||||
case 4: line.start = corners[4];
|
||||
line.end = corners[5];
|
||||
case 4: line.Start = corners[4];
|
||||
line.End = corners[5];
|
||||
break;
|
||||
case 5: line.start = corners[5];
|
||||
line.end = corners[6];
|
||||
case 5: line.Start = corners[5];
|
||||
line.End = corners[6];
|
||||
break;
|
||||
case 6: line.start = corners[6];
|
||||
line.end = corners[7];
|
||||
case 6: line.Start = corners[6];
|
||||
line.End = corners[7];
|
||||
break;
|
||||
case 7: line.start = corners[7];
|
||||
line.end = corners[4];
|
||||
case 7: line.Start = corners[7];
|
||||
line.End = corners[4];
|
||||
break;
|
||||
|
||||
|
||||
case 8: line.start = corners[0];
|
||||
line.end = corners[4];
|
||||
case 8: line.Start = corners[0];
|
||||
line.End = corners[4];
|
||||
break;
|
||||
case 9: line.start = corners[1];
|
||||
line.end = corners[5];
|
||||
case 9: line.Start = corners[1];
|
||||
line.End = corners[5];
|
||||
break;
|
||||
case 10: line.start = corners[2];
|
||||
line.end = corners[6];
|
||||
case 10: line.Start = corners[2];
|
||||
line.End = corners[6];
|
||||
break;
|
||||
case 11: line.start = corners[3];
|
||||
line.end = corners[7];
|
||||
case 11: line.Start = corners[3];
|
||||
line.End = corners[7];
|
||||
break;
|
||||
}
|
||||
|
||||
line.color = color;
|
||||
line.Color = color;
|
||||
m_lines3DToDraw.push_back(line);
|
||||
}
|
||||
}
|
||||
|
@ -893,47 +903,47 @@ namespace TEN::Renderer
|
|||
|
||||
switch (i)
|
||||
{
|
||||
case 0: line.start = Vector3(min.x, min.y, min.z);
|
||||
line.end = Vector3(min.x, min.y, max.z);
|
||||
case 0: line.Start = Vector3(min.x, min.y, min.z);
|
||||
line.End = Vector3(min.x, min.y, max.z);
|
||||
break;
|
||||
case 1: line.start = Vector3(min.x, min.y, max.z);
|
||||
line.end = Vector3(max.x, min.y, max.z);
|
||||
case 1: line.Start = Vector3(min.x, min.y, max.z);
|
||||
line.End = Vector3(max.x, min.y, max.z);
|
||||
break;
|
||||
case 2: line.start = Vector3(max.x, min.y, max.z);
|
||||
line.end = Vector3(max.x, min.y, min.z);
|
||||
case 2: line.Start = Vector3(max.x, min.y, max.z);
|
||||
line.End = Vector3(max.x, min.y, min.z);
|
||||
break;
|
||||
case 3: line.start = Vector3(max.x, min.y, min.z);
|
||||
line.end = Vector3(min.x, min.y, min.z);
|
||||
case 3: line.Start = Vector3(max.x, min.y, min.z);
|
||||
line.End = Vector3(min.x, min.y, min.z);
|
||||
break;
|
||||
|
||||
case 4: line.start = Vector3(min.x, max.y, min.z);
|
||||
line.end = Vector3(min.x, max.y, max.z);
|
||||
case 4: line.Start = Vector3(min.x, max.y, min.z);
|
||||
line.End = Vector3(min.x, max.y, max.z);
|
||||
break;
|
||||
case 5: line.start = Vector3(min.x, max.y, max.z);
|
||||
line.end = Vector3(max.x, max.y, max.z);
|
||||
case 5: line.Start = Vector3(min.x, max.y, max.z);
|
||||
line.End = Vector3(max.x, max.y, max.z);
|
||||
break;
|
||||
case 6: line.start = Vector3(max.x, max.y, max.z);
|
||||
line.end = Vector3(max.x, max.y, min.z);
|
||||
case 6: line.Start = Vector3(max.x, max.y, max.z);
|
||||
line.End = Vector3(max.x, max.y, min.z);
|
||||
break;
|
||||
case 7: line.start = Vector3(max.x, max.y, min.z);
|
||||
line.end = Vector3(min.x, max.y, min.z);
|
||||
case 7: line.Start = Vector3(max.x, max.y, min.z);
|
||||
line.End = Vector3(min.x, max.y, min.z);
|
||||
break;
|
||||
|
||||
case 8: line.start = Vector3(min.x, min.y, min.z);
|
||||
line.end = Vector3(min.x, max.y, min.z);
|
||||
case 8: line.Start = Vector3(min.x, min.y, min.z);
|
||||
line.End = Vector3(min.x, max.y, min.z);
|
||||
break;
|
||||
case 9: line.start = Vector3(min.x, min.y, max.z);
|
||||
line.end = Vector3(min.x, max.y, max.z);
|
||||
case 9: line.Start = Vector3(min.x, min.y, max.z);
|
||||
line.End = Vector3(min.x, max.y, max.z);
|
||||
break;
|
||||
case 10: line.start = Vector3(max.x, min.y, max.z);
|
||||
line.end = Vector3(max.x, max.y, max.z);
|
||||
case 10: line.Start = Vector3(max.x, min.y, max.z);
|
||||
line.End = Vector3(max.x, max.y, max.z);
|
||||
break;
|
||||
case 11: line.start = Vector3(max.x, min.y, min.z);
|
||||
line.end = Vector3(max.x, max.y, min.z);
|
||||
case 11: line.Start = Vector3(max.x, min.y, min.z);
|
||||
line.End = Vector3(max.x, max.y, min.z);
|
||||
break;
|
||||
}
|
||||
|
||||
line.color = color;
|
||||
line.Color = color;
|
||||
m_lines3DToDraw.push_back(line);
|
||||
}
|
||||
}
|
||||
|
@ -961,7 +971,7 @@ namespace TEN::Renderer
|
|||
|
||||
void Renderer11::AddDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b)
|
||||
{
|
||||
RendererLight dynamicLight;
|
||||
RendererLight dynamicLight = {};
|
||||
|
||||
if (falloff >= 8)
|
||||
{
|
||||
|
@ -976,6 +986,7 @@ namespace TEN::Renderer
|
|||
dynamicLight.Color = Vector3(r / 255.0f, g / 255.0f, b / 255.0f) * 2.0f;
|
||||
}
|
||||
|
||||
dynamicLight.Intensity = 1.0f;
|
||||
dynamicLight.Position = Vector3(float(x), float(y), float(z));
|
||||
dynamicLight.Out = falloff * 256.0f;
|
||||
dynamicLight.Type = LIGHT_TYPES::LIGHT_TYPE_POINT;
|
||||
|
@ -1288,11 +1299,7 @@ namespace TEN::Renderer
|
|||
BindConstantBufferVS(CB_SHADOW_LIGHT, m_cbShadowMap.get());
|
||||
BindConstantBufferPS(CB_SHADOW_LIGHT, m_cbShadowMap.get());
|
||||
|
||||
m_stLights.NumLights = view.lightsToDraw.size();
|
||||
for (int j = 0; j < view.lightsToDraw.size(); j++)
|
||||
memcpy(&m_stLights.Lights[j], view.lightsToDraw[j], sizeof(ShaderLight));
|
||||
m_cbLights.updateData(m_stLights, m_context.Get());
|
||||
BindConstantBufferPS(CB_LIGHTS, m_cbLights.get());
|
||||
BindLights(view.lightsToDraw);
|
||||
|
||||
m_stMisc.Caustics = (nativeRoom->flags & ENV_FLAG_WATER);
|
||||
m_cbMisc.updateData(m_stMisc, m_context.Get());
|
||||
|
@ -1382,9 +1389,14 @@ namespace TEN::Renderer
|
|||
|
||||
m_stStatic.World = info->world;
|
||||
m_stStatic.Position = Vector4(info->position.x, info->position.y, info->position.z, 1.0f);
|
||||
m_stStatic.Color = info->color;
|
||||
m_stStatic.Color = info->room->AmbientLight * info->color;
|
||||
m_stStatic.LightMode = m_staticObjects[info->staticMesh->Id]->ObjectMeshes[0]->LightMode;
|
||||
|
||||
m_cbStatic.updateData(m_stStatic, m_context.Get());
|
||||
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
|
||||
BindConstantBufferPS(CB_STATIC, m_cbStatic.get());
|
||||
|
||||
BindLights(info->staticMesh->LightsToDraw);
|
||||
|
||||
SetBlendMode(info->blendMode);
|
||||
|
||||
|
@ -1420,8 +1432,6 @@ namespace TEN::Renderer
|
|||
|
||||
ScriptInterfaceLevel* level = g_GameFlow->GetLevel(CurrentLevel);
|
||||
|
||||
m_stLights.CameraPosition = view.camera.WorldPosition;
|
||||
|
||||
// Prepare the scene to draw
|
||||
auto time1 = std::chrono::high_resolution_clock::now();
|
||||
CollectRooms(view, false);
|
||||
|
@ -1433,15 +1443,16 @@ namespace TEN::Renderer
|
|||
m_stAlphaTest.AlphaThreshold = -1;
|
||||
m_stShadowMap.NumSpheres = 0;
|
||||
|
||||
// Setup Lara item
|
||||
m_items[Lara.ItemNumber].ItemNumber = Lara.ItemNumber;
|
||||
CalculateAmbientLight(&m_items[Lara.ItemNumber]);
|
||||
CollectLightsForItem(LaraItem->RoomNumber, &m_items[Lara.ItemNumber], true);
|
||||
|
||||
// Prepare the shadow map
|
||||
ClearShadowMap(view);
|
||||
RenderShadowMap(view);
|
||||
RenderBlobShadows(view);
|
||||
|
||||
// Setup Lara item
|
||||
m_items[Lara.ItemNumber].ItemNumber = Lara.ItemNumber;
|
||||
CollectLightsForItem(LaraItem->RoomNumber, &m_items[Lara.ItemNumber], view);
|
||||
|
||||
auto time2 = std::chrono::high_resolution_clock::now();
|
||||
m_timeUpdate = (std::chrono::duration_cast<ns>(time2 - time1)).count() / 1000000;
|
||||
time1 = time2;
|
||||
|
@ -1668,17 +1679,16 @@ namespace TEN::Renderer
|
|||
m_stItem.World = item->World;
|
||||
m_stItem.Position = Vector4(nativeItem->Pose.Position.x, nativeItem->Pose.Position.y, nativeItem->Pose.Position.z, 1.0f);
|
||||
m_stItem.AmbientLight = item->AmbientLight;
|
||||
memcpy(m_stItem.BonesMatrices, item->AnimationTransforms, sizeof(Matrix) * 32);
|
||||
memcpy(m_stItem.BonesMatrices, item->AnimationTransforms, sizeof(Matrix) * MAX_BONES);
|
||||
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
||||
m_stItem.BoneLightModes[k] = moveableObj.ObjectMeshes[k]->LightMode;
|
||||
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
|
||||
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
|
||||
|
||||
// Bind lights touching that item
|
||||
m_stLights.NumLights = item->LightsToDraw.size();
|
||||
for (int j = 0; j < m_stLights.NumLights; j++)
|
||||
memcpy(&m_stLights.Lights[j], item->LightsToDraw[j], sizeof(ShaderLight));
|
||||
m_cbLights.updateData(m_stLights, m_context.Get());
|
||||
BindConstantBufferPS(CB_LIGHTS, m_cbLights.get());
|
||||
BindLights(item->LightsToDraw);
|
||||
|
||||
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
||||
{
|
||||
|
@ -1722,17 +1732,16 @@ namespace TEN::Renderer
|
|||
|
||||
m_stItem.World = info->item->World;
|
||||
m_stItem.Position = Vector4(info->position.x, info->position.y, info->position.z, 1.0f);
|
||||
m_stItem.AmbientLight = room.AmbientLight;
|
||||
memcpy(m_stItem.BonesMatrices, info->item->AnimationTransforms, sizeof(Matrix) * 32);
|
||||
m_stItem.AmbientLight = info->room->AmbientLight * info->color;
|
||||
memcpy(m_stItem.BonesMatrices, info->item->AnimationTransforms, sizeof(Matrix) * MAX_BONES);
|
||||
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
||||
m_stItem.BoneLightModes[k] = moveableObj.ObjectMeshes[k]->LightMode;
|
||||
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
|
||||
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
|
||||
|
||||
m_stLights.NumLights = info->item->LightsToDraw.size();
|
||||
for (int j = 0; j < info->item->LightsToDraw.size(); j++)
|
||||
memcpy(&m_stLights.Lights[j], info->item->LightsToDraw[j], sizeof(ShaderLight));
|
||||
m_cbLights.updateData(m_stLights, m_context.Get());
|
||||
BindConstantBufferPS(CB_LIGHTS, m_cbLights.get());
|
||||
BindLights(info->item->LightsToDraw);
|
||||
|
||||
// Set texture
|
||||
BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[info->bucket->Texture]),
|
||||
|
@ -1807,28 +1816,16 @@ namespace TEN::Renderer
|
|||
|
||||
for (auto room : view.roomsToDraw)
|
||||
{
|
||||
for (auto msh : room->StaticsToDraw)
|
||||
for (auto& msh : room->StaticsToDraw)
|
||||
{
|
||||
if (!m_staticObjects[msh->staticNumber])
|
||||
continue;
|
||||
|
||||
Matrix world = (Matrix::CreateFromYawPitchRoll(TO_RAD(msh->pos.Orientation.y), TO_RAD(msh->pos.Orientation.x),
|
||||
TO_RAD(msh->pos.Orientation.z)) *
|
||||
Matrix::CreateTranslation(msh->pos.Position.x, msh->pos.Position.y, msh->pos.Position.z));
|
||||
|
||||
m_stStatic.World = world;
|
||||
m_stStatic.Position = Vector4(msh->pos.Position.x, msh->pos.Position.y, msh->pos.Position.z, 1);
|
||||
m_stStatic.Color = msh->color;
|
||||
m_cbStatic.updateData(m_stStatic, m_context.Get());
|
||||
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
|
||||
|
||||
RendererObject& staticObj = *m_staticObjects[msh->staticNumber];
|
||||
RendererObject& staticObj = *m_staticObjects[msh.Id];
|
||||
|
||||
if (staticObj.ObjectMeshes.size() > 0)
|
||||
{
|
||||
RendererMesh* mesh = staticObj.ObjectMeshes[0];
|
||||
RendererMesh* mesh = staticObj.ObjectMeshes[0];
|
||||
auto pos = Vector3::Transform(Vector3::Zero, msh.World);
|
||||
|
||||
for (auto& bucket : mesh->buckets)
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ transparent))
|
||||
{
|
||||
|
@ -1848,7 +1845,7 @@ namespace TEN::Renderer
|
|||
RendererPolygon* p = &bucket.Polygons[j];
|
||||
|
||||
// As polygon distance, for moveables, we use the averaged distance
|
||||
Vector3 centre = Vector3::Transform(p->centre, world);
|
||||
Vector3 centre = Vector3::Transform(p->centre, msh.World);
|
||||
int distance = (centre - cameraPosition).Length();
|
||||
|
||||
RendererTransparentFace face;
|
||||
|
@ -1858,10 +1855,10 @@ namespace TEN::Renderer
|
|||
face.info.animated = bucket.Animated;
|
||||
face.info.texture = bucket.Texture;
|
||||
face.info.room = room;
|
||||
face.info.staticMesh = msh;
|
||||
face.info.staticMesh = &msh;
|
||||
face.info.world = m_stStatic.World;
|
||||
face.info.position = Vector3(msh->pos.Position.x, msh->pos.Position.y, msh->pos.Position.z);
|
||||
face.info.color = Vector4(msh->color.x, msh->color.y, msh->color.z, 1.0f);
|
||||
face.info.position = Vector3(pos.x, pos.y, pos.z);
|
||||
face.info.color = Vector4(msh.AmbientLight.x, msh.AmbientLight.y, msh.AmbientLight.z, msh.AmbientLight.w);
|
||||
face.info.blendMode = bucket.BlendMode;
|
||||
face.info.bucket = &bucket;
|
||||
room->TransparentFacesToDraw.push_back(face);
|
||||
|
@ -1869,6 +1866,17 @@ namespace TEN::Renderer
|
|||
}
|
||||
else
|
||||
{
|
||||
m_stStatic.World = msh.World;
|
||||
m_stStatic.Position = Vector4(pos.x, pos.y, pos.z, 1);
|
||||
m_stStatic.Color = msh.AmbientLight;
|
||||
m_stStatic.LightMode = mesh->LightMode;
|
||||
|
||||
m_cbStatic.updateData(m_stStatic, m_context.Get());
|
||||
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
|
||||
BindConstantBufferPS(CB_STATIC, m_cbStatic.get());
|
||||
|
||||
BindLights(msh.LightsToDraw);
|
||||
|
||||
int passes = bucket.BlendMode == BLENDMODE_ALPHATEST ? 2 : 1;
|
||||
|
||||
for (int pass = 0; pass < passes; pass++)
|
||||
|
@ -1953,11 +1961,7 @@ namespace TEN::Renderer
|
|||
Vector3 cameraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z);
|
||||
Vector3 roomPosition = Vector3(nativeRoom->x, nativeRoom->y, nativeRoom->z);
|
||||
|
||||
m_stLights.NumLights = view.lightsToDraw.size();
|
||||
for (int j = 0; j < view.lightsToDraw.size(); j++)
|
||||
memcpy(&m_stLights.Lights[j], view.lightsToDraw[j], sizeof(ShaderLight));
|
||||
m_cbLights.updateData(m_stLights, m_context.Get());
|
||||
BindConstantBufferPS(CB_LIGHTS, m_cbLights.get());
|
||||
BindLights(view.lightsToDraw);
|
||||
|
||||
// TODO: make caustics optional in Tomb Editor
|
||||
m_stMisc.Caustics = false; // (nativeRoom->flags & ENV_FLAG_WATER);
|
||||
|
@ -2186,6 +2190,8 @@ namespace TEN::Renderer
|
|||
|
||||
m_stStatic.World = (rotation * translation);
|
||||
m_stStatic.Color = weather.SkyColor();
|
||||
m_stStatic.LightMode = LIGHT_MODES::LIGHT_MODE_STATIC;
|
||||
|
||||
m_cbStatic.updateData(m_stStatic, m_context.Get());
|
||||
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
|
||||
BindConstantBufferPS(CB_STATIC, m_cbStatic.get());
|
||||
|
@ -2209,6 +2215,8 @@ namespace TEN::Renderer
|
|||
m_stStatic.World = Matrix::CreateTranslation(Camera.pos.x, Camera.pos.y, Camera.pos.z);
|
||||
m_stStatic.Position = Vector4::Zero;
|
||||
m_stStatic.Color = Vector4::One;
|
||||
m_stStatic.LightMode = LIGHT_MODES::LIGHT_MODE_STATIC;
|
||||
|
||||
m_cbStatic.updateData(m_stStatic, m_context.Get());
|
||||
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
|
||||
BindConstantBufferPS(CB_STATIC, m_cbStatic.get());
|
||||
|
@ -2217,7 +2225,7 @@ namespace TEN::Renderer
|
|||
{
|
||||
RendererMesh* mesh = moveableObj.ObjectMeshes[k];
|
||||
|
||||
for (auto& bucket : mesh->buckets)
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0)
|
||||
continue;
|
||||
|
@ -2253,7 +2261,7 @@ namespace TEN::Renderer
|
|||
{
|
||||
Vector3 cameraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z);
|
||||
|
||||
for (auto& bucket : mesh->buckets)
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ transparent))
|
||||
{
|
||||
|
@ -2285,6 +2293,7 @@ namespace TEN::Renderer
|
|||
face.info.texture = bucket.Texture;
|
||||
face.info.room = room;
|
||||
face.info.item = itemToDraw;
|
||||
face.info.color = itemToDraw->AmbientLight;
|
||||
face.info.blendMode = bucket.BlendMode;
|
||||
face.info.bucket = &bucket;
|
||||
room->TransparentFacesToDraw.push_back(face);
|
||||
|
|
|
@ -607,13 +607,10 @@ namespace TEN::Renderer
|
|||
RendererItem* item = &m_items[Lara.ItemNumber];
|
||||
|
||||
m_stItem.AmbientLight = room.AmbientLight;
|
||||
m_stItem.BoneLightModes[0] = LIGHT_MODES::LIGHT_MODE_STATIC;
|
||||
memcpy(m_stItem.BonesMatrices, &Matrix::Identity, sizeof(Matrix));
|
||||
|
||||
m_stLights.NumLights = item->LightsToDraw.size();
|
||||
for (int j = 0; j < item->LightsToDraw.size(); j++)
|
||||
memcpy(&m_stLights.Lights[j], item->LightsToDraw[j], sizeof(ShaderLight));
|
||||
m_cbLights.updateData(m_stLights, m_context.Get());
|
||||
BindConstantBufferPS(CB_LIGHTS, m_cbLights.get());
|
||||
BindLights(item->LightsToDraw); // FIXME: Is it really needed for gunflashes? -- Lwmte, 15.07.22
|
||||
|
||||
short length = 0;
|
||||
short zOffset = 0;
|
||||
|
@ -668,7 +665,7 @@ namespace TEN::Renderer
|
|||
RendererObject& flashMoveable = *m_moveableObjects[gunflash];
|
||||
RendererMesh* flashMesh = flashMoveable.ObjectMeshes[0];
|
||||
|
||||
for (auto& flashBucket : flashMesh->buckets)
|
||||
for (auto& flashBucket : flashMesh->Buckets)
|
||||
{
|
||||
if (flashBucket.BlendMode == BLENDMODE_OPAQUE)
|
||||
continue;
|
||||
|
@ -738,13 +735,10 @@ namespace TEN::Renderer
|
|||
RendererObject& flashMoveable = *m_moveableObjects[ID_GUN_FLASH];
|
||||
|
||||
m_stItem.AmbientLight = room.AmbientLight;
|
||||
m_stItem.BoneLightModes[0] = LIGHT_MODES::LIGHT_MODE_STATIC;
|
||||
memcpy(m_stItem.BonesMatrices, &Matrix::Identity, sizeof(Matrix));
|
||||
|
||||
m_stLights.NumLights = item->LightsToDraw.size();
|
||||
for (int j = 0; j < item->LightsToDraw.size(); j++)
|
||||
memcpy(&m_stLights.Lights[j], item->LightsToDraw[j], sizeof(ShaderLight));
|
||||
m_cbLights.updateData(m_stLights, m_context.Get());
|
||||
BindConstantBufferPS(CB_LIGHTS, m_cbLights.get());
|
||||
BindLights(item->LightsToDraw); // FIXME: Is it really needed for gunflashes? -- Lwmte, 15.07.22
|
||||
|
||||
SetBlendMode(BLENDMODE_ADDITIVE);
|
||||
|
||||
|
@ -763,7 +757,7 @@ namespace TEN::Renderer
|
|||
|
||||
RendererMesh* flashMesh = flashMoveable.ObjectMeshes[0];
|
||||
|
||||
for (auto& flashBucket : flashMesh->buckets)
|
||||
for (auto& flashBucket : flashMesh->Buckets)
|
||||
{
|
||||
if (flashBucket.BlendMode == BLENDMODE_OPAQUE)
|
||||
continue;
|
||||
|
@ -1088,16 +1082,12 @@ namespace TEN::Renderer
|
|||
m_stItem.World = effect->World;
|
||||
m_stItem.Position = Vector4(effect->Effect->pos.Position.x, effect->Effect->pos.Position.y, effect->Effect->pos.Position.z, 1.0f);
|
||||
m_stItem.AmbientLight = room.AmbientLight;
|
||||
Matrix matrices[1] = { Matrix::Identity };
|
||||
memcpy(m_stItem.BonesMatrices, matrices, sizeof(Matrix));
|
||||
m_stItem.BoneLightModes[0] = LIGHT_MODES::LIGHT_MODE_DYNAMIC;
|
||||
memcpy(m_stItem.BonesMatrices, &Matrix::Identity, sizeof(Matrix));
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
|
||||
|
||||
m_stLights.NumLights = effect->Lights.size();
|
||||
for (int j = 0; j < effect->Lights.size(); j++)
|
||||
memcpy(&m_stLights.Lights[j], effect->Lights[j], sizeof(ShaderLight));
|
||||
m_cbLights.updateData(m_stLights, m_context.Get());
|
||||
BindConstantBufferPS(CB_LIGHTS, m_cbLights.get());
|
||||
BindLights(effect->LightsToDraw);
|
||||
|
||||
if (transparent)
|
||||
{
|
||||
|
@ -1110,7 +1100,7 @@ namespace TEN::Renderer
|
|||
|
||||
RendererMesh* mesh = effect->Mesh;
|
||||
|
||||
for (auto& bucket : mesh->buckets)
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0)
|
||||
continue;
|
||||
|
@ -1163,8 +1153,8 @@ namespace TEN::Renderer
|
|||
Matrix world = rotation * translation;
|
||||
|
||||
m_primitiveBatch->Begin();
|
||||
m_context->VSSetShader(m_vsStatics.Get(), NULL, 0);
|
||||
m_context->PSSetShader(m_psStatics.Get(), NULL, 0);
|
||||
m_context->VSSetShader(m_vsStatics.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_psStatics.Get(), nullptr, 0);
|
||||
|
||||
if (deb->isStatic)
|
||||
{
|
||||
|
@ -1185,7 +1175,9 @@ namespace TEN::Renderer
|
|||
}
|
||||
|
||||
m_stStatic.World = world;
|
||||
m_stStatic.Color = Vector4::One;
|
||||
m_stStatic.Color = deb->color;
|
||||
m_stStatic.LightMode = LIGHT_MODES::LIGHT_MODE_DYNAMIC;
|
||||
|
||||
m_cbStatic.updateData(m_stStatic, m_context.Get());
|
||||
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
|
||||
|
||||
|
@ -1289,55 +1281,4 @@ namespace TEN::Renderer
|
|||
AddSpriteBillboard(&m_sprites[Objects[s.sequence].meshIndex + s.sprite], s.worldPosition, Vector4(1, 1, 1, 1), 0, 1.0f, { s.size, s.size / 2 }, BLENDMODE_ALPHABLEND,view);
|
||||
}
|
||||
}
|
||||
|
||||
DebrisFragment* getNewDebrisFragment()
|
||||
{
|
||||
return nullptr;
|
||||
|
||||
/*DebrisFragment* fragment = GetFreeDebrisFragment();
|
||||
if (!fragment)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!fragment->active)
|
||||
{
|
||||
Matrix rotationMatrix = Matrix::CreateFromYawPitchRoll(TO_RAD(yRot), 0, 0);
|
||||
RendererVertex vtx0 = meshVertices.at(renderBucket.Indices[i]);
|
||||
RendererVertex vtx1 = meshVertices.at(renderBucket.Indices[i + 1]);
|
||||
RendererVertex vtx2 = meshVertices.at(renderBucket.Indices[i + 2]);
|
||||
|
||||
//Take the average of all 3 local positions
|
||||
Vector3 localPos = (vtx0.Position + vtx1.Position + vtx2.Position) / 3;
|
||||
vtx0.Position -= localPos;
|
||||
vtx1.Position -= localPos;
|
||||
vtx2.Position -= localPos;
|
||||
|
||||
Vector3 worldPos = Vector3::Transform(localPos, rotationMatrix);
|
||||
fragment->worldPosition = worldPos + pos;
|
||||
fragment->mesh.vertices[0] = vtx0;
|
||||
fragment->mesh.vertices[1] = vtx1;
|
||||
fragment->mesh.vertices[2] = vtx2;
|
||||
fragment->mesh.blendMode = renderBucket.BlendMode;
|
||||
fragment->mesh.tex = renderBucket.Texture;
|
||||
fragment->isStatic = isStatic;
|
||||
fragment->active = true;
|
||||
fragment->terminalVelocity = 1024;
|
||||
fragment->gravity = Vector3(0, 7, 0);
|
||||
fragment->restitution = 0.6f;
|
||||
fragment->friction = 0.6f;
|
||||
fragment->linearDrag = .99f;
|
||||
fragment->angularVelocity = Vector3(GenerateFloat(-1, 1) * 0.39, GenerateFloat(-1, 1) * 0.39, GenerateFloat(-1, 1) * 0.39);
|
||||
fragment->angularDrag = GenerateFloat(0.9f, 0.999f);
|
||||
fragment->velocity = CalculateFragmentImpactVelocity(fragment->worldPosition, ShatterImpactData.impactDirection, ShatterImpactData.impactLocation);
|
||||
fragment->roomNumber = roomNumber;
|
||||
fragment->numBounces = 0;
|
||||
|
||||
return fragment;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -574,12 +574,15 @@ namespace TEN::Renderer
|
|||
m_stItem.World = ((*moveableObj).AnimationTransforms[n] * world);
|
||||
else
|
||||
m_stItem.World = ((*moveableObj).BindPoseTransforms[n] * world);
|
||||
|
||||
m_stItem.BoneLightModes[n] = LIGHT_MODES::LIGHT_MODE_DYNAMIC;
|
||||
m_stItem.AmbientLight = Vector4(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
|
||||
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
|
||||
|
||||
for (auto& bucket : mesh->buckets)
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0)
|
||||
continue;
|
||||
|
|
|
@ -68,6 +68,12 @@ enum SHADOW_MODES
|
|||
SHADOW_ALL
|
||||
};
|
||||
|
||||
enum LIGHT_MODES
|
||||
{
|
||||
LIGHT_MODE_DYNAMIC,
|
||||
LIGHT_MODE_STATIC
|
||||
};
|
||||
|
||||
enum DEPTH_STATES
|
||||
{
|
||||
DEPTH_STATE_WRITE_ZBUFFER = 0,
|
||||
|
@ -209,7 +215,7 @@ constexpr auto FADE_FRAMES_COUNT = 16;
|
|||
constexpr auto FADE_FACTOR = 0.0625f;
|
||||
|
||||
constexpr auto NUM_LIGHTS_PER_BUFFER = 48;
|
||||
constexpr auto MAX_LIGHTS_PER_ITEM = 48;
|
||||
constexpr auto MAX_LIGHTS_PER_ITEM = 8;
|
||||
constexpr auto MAX_LIGHTS = 100;
|
||||
constexpr auto AMBIENT_LIGHT_INTERPOLATION_STEPS = 8;
|
||||
constexpr auto MAX_DYNAMIC_SHADOWS = 1;
|
||||
|
@ -233,4 +239,7 @@ constexpr auto HUD_ZERO_Y = -REFERENCE_RES_HEIGHT;
|
|||
|
||||
constexpr auto UNDERWATER_FOG_MIN_DISTANCE = 4;
|
||||
constexpr auto UNDERWATER_FOG_MAX_DISTANCE = 30;
|
||||
constexpr auto MAX_ROOM_BOUNDS = 256;
|
||||
constexpr auto MAX_ROOM_BOUNDS = 256;
|
||||
|
||||
constexpr auto MIN_FAR_VIEW = 3200.0f;
|
||||
constexpr auto DEFAULT_FAR_VIEW = 102400.0f;
|
|
@ -69,7 +69,7 @@ namespace TEN::Renderer
|
|||
// Project vertices of the door in clip space
|
||||
Vector4 tmp = Vector4(
|
||||
door->vertices[i].x + parentNativeRoom->x,
|
||||
door->vertices[i].y + parentNativeRoom->y,
|
||||
door->vertices[i].y,
|
||||
door->vertices[i].z + parentNativeRoom->z,
|
||||
1.0f);
|
||||
|
||||
|
@ -251,8 +251,8 @@ namespace TEN::Renderer
|
|||
{
|
||||
CollectLightsForRoom(roomNumber, renderView);
|
||||
CollectItems(roomNumber, renderView);
|
||||
CollectStatics(roomNumber, renderView);
|
||||
CollectEffects(roomNumber, renderView);
|
||||
CollectStatics(roomNumber);
|
||||
CollectEffects(roomNumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,14 +272,13 @@ namespace TEN::Renderer
|
|||
{
|
||||
ROOM_DOOR* portal = &nativeRoom->doors[i];
|
||||
|
||||
Vector3 n = portal->normal;
|
||||
Vector3 v = Vector3(
|
||||
Vector3Int n = Vector3Int(portal->normal.x, portal->normal.y, portal->normal.z);
|
||||
Vector3Int v = Vector3Int(
|
||||
Camera.pos.x - (nativeRoom->x + portal->vertices[0].x),
|
||||
Camera.pos.y - (nativeRoom->y + portal->vertices[0].y),
|
||||
Camera.pos.z - (nativeRoom->z + portal->vertices[0].z));
|
||||
|
||||
// Test camera and normal positions and decide if process door or not
|
||||
if (n.Dot(v) <= 0.0f)
|
||||
if (n.x * v.x + n.y * v.y + n.z * v.z < 0)
|
||||
continue;
|
||||
|
||||
SetRoomBounds(portal, roomNumber, renderView);
|
||||
|
@ -317,7 +316,7 @@ namespace TEN::Renderer
|
|||
GetRoomBounds(renderView, onlyRooms);
|
||||
}
|
||||
|
||||
void Renderer11::CollectItems(short roomNumber, RenderView &renderView)
|
||||
void Renderer11::CollectItems(short roomNumber, RenderView& renderView)
|
||||
{
|
||||
if (m_rooms.size() < roomNumber)
|
||||
return;
|
||||
|
@ -359,13 +358,14 @@ namespace TEN::Renderer
|
|||
newItem->Scale = Matrix::CreateScale(1.0f);
|
||||
newItem->World = newItem->Rotation * newItem->Translation;
|
||||
|
||||
CollectLightsForItem(item->RoomNumber, newItem, renderView);
|
||||
CalculateAmbientLight(newItem);
|
||||
CollectLightsForItem(item->RoomNumber, newItem, false);
|
||||
|
||||
room.ItemsToDraw.push_back(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer11::CollectStatics(short roomNumber, RenderView &renderView)
|
||||
void Renderer11::CollectStatics(short roomNumber)
|
||||
{
|
||||
if (m_rooms.size() < roomNumber)
|
||||
return;
|
||||
|
@ -373,209 +373,81 @@ namespace TEN::Renderer
|
|||
RendererRoom& room = m_rooms[roomNumber];
|
||||
ROOM_INFO* r = &g_Level.Rooms[room.RoomNumber];
|
||||
|
||||
if (r->mesh.size() <= 0)
|
||||
if (r->mesh.size() == 0)
|
||||
return;
|
||||
|
||||
int numStatics = r->mesh.size();
|
||||
for (int i = 0; i < numStatics; i++)
|
||||
{
|
||||
auto mesh = &r->mesh[i];
|
||||
if (mesh->flags & StaticMeshFlags::SM_VISIBLE)
|
||||
|
||||
if (!(mesh->flags & StaticMeshFlags::SM_VISIBLE))
|
||||
continue;
|
||||
|
||||
if (!m_staticObjects[mesh->staticNumber].has_value())
|
||||
continue;
|
||||
|
||||
auto& obj = *m_staticObjects[mesh->staticNumber];
|
||||
|
||||
if (obj.ObjectMeshes.size() == 0)
|
||||
continue;
|
||||
|
||||
std::vector<RendererLight*> lights;
|
||||
if (obj.ObjectMeshes.front()->LightMode != LIGHT_MODES::LIGHT_MODE_STATIC)
|
||||
CollectLights(mesh->pos.Position, room.RoomNumber, false, lights);
|
||||
|
||||
Matrix world = (Matrix::CreateFromYawPitchRoll(TO_RAD(mesh->pos.Orientation.y), TO_RAD(mesh->pos.Orientation.x), TO_RAD(mesh->pos.Orientation.z)) *
|
||||
Matrix::CreateTranslation(mesh->pos.Position.x, mesh->pos.Position.y, mesh->pos.Position.z));
|
||||
|
||||
auto staticInfo = RendererStatic
|
||||
{
|
||||
auto sinfo = &StaticObjects[mesh->staticNumber];
|
||||
mesh->staticNumber,
|
||||
room.RoomNumber,
|
||||
world,
|
||||
room.AmbientLight * mesh->color,
|
||||
lights
|
||||
};
|
||||
|
||||
auto bounds = TO_DX_BBOX(mesh->pos, &sinfo->visibilityBox);
|
||||
Vector3 min = bounds.Center - bounds.Extents;
|
||||
Vector3 max = bounds.Center + bounds.Extents;
|
||||
|
||||
if (!renderView.camera.frustum.AABBInFrustum(min, max))
|
||||
continue;
|
||||
|
||||
room.StaticsToDraw.push_back(mesh);
|
||||
}
|
||||
room.StaticsToDraw.push_back(staticInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer11::CollectLightsForEffect(short roomNumber, RendererEffect *effect, RenderView &renderView)
|
||||
void Renderer11::CollectLights(Vector3Int position, int roomNumber, bool collectShadowLight, std::vector<RendererLight*>& lights)
|
||||
{
|
||||
effect->Lights.clear();
|
||||
if (m_rooms.size() < roomNumber)
|
||||
return;
|
||||
|
||||
RendererRoom& room = m_rooms[roomNumber];
|
||||
ROOM_INFO* r = &g_Level.Rooms[room.RoomNumber];
|
||||
|
||||
if (r->lights.size() <= 0)
|
||||
return;
|
||||
LinearArrayBuffer<RendererLight*, 8> tempLights;
|
||||
|
||||
Vector3 itemPosition = Vector3(effect->Effect->pos.Position.x, effect->Effect->pos.Position.y, effect->Effect->pos.Position.z);
|
||||
|
||||
// Dynamic lights have the priority
|
||||
for (int i = 0; i < dynamicLights.size(); i++)
|
||||
{
|
||||
RendererLight* light = &dynamicLights[i];
|
||||
|
||||
Vector3 lightPosition = Vector3(light->Position.x, light->Position.y, light->Position.z);
|
||||
|
||||
float distance = (itemPosition - lightPosition).Length();
|
||||
if (distance > light->Out)
|
||||
continue;
|
||||
|
||||
tempLights.push_back(light);
|
||||
}
|
||||
|
||||
int numLights = room.Lights.size();
|
||||
|
||||
RendererLight* brightestLight = NULL;
|
||||
float brightest = 0.0f;
|
||||
|
||||
for (int j = 0; j < numLights; j++)
|
||||
{
|
||||
RendererLight *light = &room.Lights[j];
|
||||
|
||||
// Check only lights different from sun
|
||||
if (light->Type == LIGHT_TYPE_SUN)
|
||||
{
|
||||
// Sun is added without checks
|
||||
}
|
||||
else if (light->Type == LIGHT_TYPE_POINT || light->Type == LIGHT_TYPE_SHADOW)
|
||||
{
|
||||
Vector3 lightPosition = Vector3(light->Position.x, light->Position.y, light->Position.z);
|
||||
|
||||
float distance = (itemPosition - lightPosition).Length();
|
||||
|
||||
// Collect only lights nearer than 20 sectors
|
||||
if (distance >= 20 * WALL_SIZE)
|
||||
continue;
|
||||
|
||||
// Check the out radius
|
||||
if (distance > light->Out)
|
||||
continue;
|
||||
|
||||
// If Lara, try to collect shadow casting light
|
||||
if (light->CastShadows && effect->Effect->objectNumber == ID_LARA)
|
||||
{
|
||||
float attenuation = 1.0f - distance / light->Out;
|
||||
float intensity = std::max(0.0f, attenuation * (light->Color.x + light->Color.y + light->Color.z) / 3.0f);
|
||||
|
||||
if (intensity >= brightest)
|
||||
{
|
||||
brightest = intensity;
|
||||
brightestLight = light;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (light->Type == LIGHT_TYPE_SPOT)
|
||||
{
|
||||
Vector3 lightPosition = Vector3(light->Position.x, light->Position.y, light->Position.z);
|
||||
|
||||
float distance = (itemPosition - lightPosition).Length();
|
||||
|
||||
// Collect only lights nearer than 20 sectors
|
||||
if (distance >= 20 * WALL_SIZE)
|
||||
continue;
|
||||
|
||||
// Check the range
|
||||
if (distance > light->Range)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid light type
|
||||
continue;
|
||||
}
|
||||
|
||||
tempLights.push_back(light);
|
||||
}
|
||||
|
||||
for (int i = 0; i < std::min(static_cast<size_t>(MAX_LIGHTS_PER_ITEM), tempLights.size()); i++)
|
||||
{
|
||||
if (renderView.lightsToDraw.size() < NUM_LIGHTS_PER_BUFFER - 1)
|
||||
renderView.lightsToDraw.push_back(tempLights[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer11::CollectLightsForItem(short roomNumber, RendererItem *item, RenderView &renderView)
|
||||
{
|
||||
item->LightsToDraw.clear();
|
||||
|
||||
if (m_rooms.size() < roomNumber)
|
||||
return;
|
||||
|
||||
RendererRoom& room = m_rooms[roomNumber];
|
||||
ROOM_INFO* nativeRoom = &g_Level.Rooms[room.RoomNumber];
|
||||
ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber];
|
||||
|
||||
std::vector<int> roomsToCheck;
|
||||
roomsToCheck.push_back(roomNumber);
|
||||
for (auto& door : nativeRoom->doors)
|
||||
{
|
||||
roomsToCheck.push_back(door.room);
|
||||
};
|
||||
|
||||
// Interpolate ambient light between rooms
|
||||
if (item->PreviousRoomNumber == NO_ITEM)
|
||||
{
|
||||
item->PreviousRoomNumber = nativeItem->RoomNumber;
|
||||
item->CurrentRoomNumber = nativeItem->RoomNumber;
|
||||
item->AmbientLightSteps = AMBIENT_LIGHT_INTERPOLATION_STEPS;
|
||||
}
|
||||
else if (nativeItem->RoomNumber != item->CurrentRoomNumber)
|
||||
{
|
||||
item->PreviousRoomNumber = item->CurrentRoomNumber;
|
||||
item->CurrentRoomNumber = nativeItem->RoomNumber;
|
||||
item->AmbientLightSteps = 0;
|
||||
}
|
||||
else if (item->AmbientLightSteps < AMBIENT_LIGHT_INTERPOLATION_STEPS)
|
||||
item->AmbientLightSteps++;
|
||||
|
||||
if (item->PreviousRoomNumber == NO_ITEM)
|
||||
item->AmbientLight = m_rooms[nativeItem->RoomNumber].AmbientLight;
|
||||
else
|
||||
{
|
||||
item->AmbientLight = (((AMBIENT_LIGHT_INTERPOLATION_STEPS - item->AmbientLightSteps) / (float)AMBIENT_LIGHT_INTERPOLATION_STEPS) * m_rooms[item->PreviousRoomNumber].AmbientLight +
|
||||
(item->AmbientLightSteps / (float)AMBIENT_LIGHT_INTERPOLATION_STEPS) * m_rooms[item->CurrentRoomNumber].AmbientLight);
|
||||
item->AmbientLight.w = 1.0f;
|
||||
}
|
||||
|
||||
// Multiply calculated ambient light by object tint
|
||||
item->AmbientLight *= nativeItem->Color;
|
||||
|
||||
// Now collect lights from dynamic list and from rooms
|
||||
std::vector<RendererLight*> tempLights;
|
||||
tempLights.reserve(MAX_LIGHTS_DRAW);
|
||||
|
||||
RendererRoom& room = m_rooms[roomNumber];
|
||||
ROOM_INFO* nativeRoom = &g_Level.Rooms[room.RoomNumber];
|
||||
|
||||
Vector3 itemPosition = Vector3(nativeItem->Pose.Position.x, nativeItem->Pose.Position.y, nativeItem->Pose.Position.z);
|
||||
auto roomsToCheck = GetRoomList(roomNumber);
|
||||
auto itemPosition = position.ToVector3();
|
||||
|
||||
if (nativeItem->ObjectNumber == ID_LARA)
|
||||
shadowLight = nullptr;
|
||||
|
||||
RendererLight* brightestLight = NULL;
|
||||
RendererLight* brightestLight = nullptr;
|
||||
float brightest = 0.0f;
|
||||
|
||||
// Dynamic lights have the priority
|
||||
for (int i = 0; i < dynamicLights.size(); i++)
|
||||
for (auto& light : dynamicLights)
|
||||
{
|
||||
RendererLight* light = &dynamicLights[i];
|
||||
|
||||
Vector3 lightPosition = Vector3(light->Position.x, light->Position.y, light->Position.z);
|
||||
|
||||
float distance = (itemPosition - lightPosition).Length();
|
||||
if (distance > light->Out)
|
||||
float distance = (itemPosition - light.Position).Length();
|
||||
if (distance > light.Out)
|
||||
continue;
|
||||
|
||||
float attenuation = 1.0f - distance / light->Out;
|
||||
float intensity = std::max(0.0f, attenuation * (light->Color.x + light->Color.y + light->Color.z) / 3.0f);
|
||||
float attenuation = 1.0f - distance / light.Out;
|
||||
float intensity = std::max(0.0f, attenuation * light.Intensity * Luma(light.Color));
|
||||
|
||||
light->LocalIntensity = intensity;
|
||||
light->Distance = distance;
|
||||
light.LocalIntensity = intensity;
|
||||
light.Distance = distance;
|
||||
|
||||
tempLights.push_back(light);
|
||||
tempLights.push_back(&light);
|
||||
}
|
||||
|
||||
// Check current room and also neighbour rooms
|
||||
for (int roomToCheck : roomsToCheck)
|
||||
for (auto roomToCheck : roomsToCheck)
|
||||
{
|
||||
RendererRoom& currentRoom = m_rooms[roomToCheck];
|
||||
int numLights = currentRoom.Lights.size();
|
||||
|
@ -611,13 +483,13 @@ namespace TEN::Renderer
|
|||
continue;
|
||||
|
||||
float attenuation = 1.0f - distance / light->Out;
|
||||
float intensity = std::max(0.0f, attenuation * (light->Color.x + light->Color.y + light->Color.z) / 3.0f);
|
||||
float intensity = std::max(0.0f, attenuation * light->Intensity * Luma(light->Color));
|
||||
|
||||
light->LocalIntensity = intensity;
|
||||
light->Distance = distance;
|
||||
|
||||
// If Lara, try to collect shadow casting light
|
||||
if (light->CastShadows && nativeItem->ObjectNumber == ID_LARA && light->Type == LIGHT_TYPE_POINT)
|
||||
// If collecting shadows, try to collect shadow casting light
|
||||
if (light->CastShadows && collectShadowLight && light->Type == LIGHT_TYPE_POINT)
|
||||
{
|
||||
if (intensity >= brightest)
|
||||
{
|
||||
|
@ -633,20 +505,20 @@ namespace TEN::Renderer
|
|||
float distance = (itemPosition - lightPosition).Length();
|
||||
|
||||
// Collect only lights nearer than 20 sectors
|
||||
if (distance >= 20 * WALL_SIZE)
|
||||
if (distance >= SECTOR(20))
|
||||
continue;
|
||||
|
||||
// Check the range
|
||||
if (distance > light->Range)
|
||||
if (distance > light->Out)
|
||||
continue;
|
||||
|
||||
float attenuation = 1.0f - distance / light->Range;
|
||||
float intensity = std::max(0.0f, attenuation * (light->Color.x + light->Color.y + light->Color.z) / 3.0f);
|
||||
float attenuation = 1.0f - distance / light->Out;
|
||||
float intensity = std::max(0.0f, attenuation * light->Intensity * Luma(light->Color));
|
||||
|
||||
light->LocalIntensity = intensity;
|
||||
|
||||
// If Lara, try to collect shadow casting light
|
||||
if (light->CastShadows && nativeItem->ObjectNumber == ID_LARA)
|
||||
// If shadow pointer provided, try to collect shadow casting light
|
||||
if (light->CastShadows && collectShadowLight)
|
||||
{
|
||||
if (intensity >= brightest)
|
||||
{
|
||||
|
@ -667,9 +539,6 @@ namespace TEN::Renderer
|
|||
}
|
||||
}
|
||||
|
||||
if (nativeItem->ObjectNumber == ID_LARA)
|
||||
shadowLight = brightestLight;
|
||||
|
||||
// Sort lights by distance
|
||||
std::sort(
|
||||
tempLights.begin(),
|
||||
|
@ -680,21 +549,75 @@ namespace TEN::Renderer
|
|||
}
|
||||
);
|
||||
|
||||
// Now put actual lights to provided vector
|
||||
lights.clear();
|
||||
|
||||
// Always add brightest light, if collecting shadow light is specified, even if it's far in range
|
||||
if (collectShadowLight && brightestLight)
|
||||
lights.push_back(brightestLight);
|
||||
|
||||
// Add max 8 lights per item, including the shadow light for Lara eventually
|
||||
if (shadowLight != nullptr)
|
||||
item->LightsToDraw.push_back(shadowLight);
|
||||
for (int i = 0; i < tempLights.size(); i++)
|
||||
for (auto l : tempLights)
|
||||
{
|
||||
if (shadowLight != nullptr && shadowLight == tempLights[i])
|
||||
if (collectShadowLight && brightestLight == l)
|
||||
continue;
|
||||
|
||||
item->LightsToDraw.push_back(tempLights[i]);
|
||||
lights.push_back(l);
|
||||
|
||||
if (item->LightsToDraw.size() == MAX_LIGHTS_PER_ITEM)
|
||||
if (lights.size() == MAX_LIGHTS_PER_ITEM)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer11::CollectLightsForEffect(short roomNumber, RendererEffect *effect)
|
||||
{
|
||||
CollectLights(effect->Effect->pos.Position, roomNumber, false, effect->LightsToDraw);
|
||||
}
|
||||
|
||||
void Renderer11::CollectLightsForItem(short roomNumber, RendererItem* item, bool collectShadowLight)
|
||||
{
|
||||
ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber];
|
||||
CollectLights(nativeItem->Pose.Position, roomNumber, collectShadowLight, item->LightsToDraw);
|
||||
|
||||
if (collectShadowLight && item->LightsToDraw.size() > 0 && item->LightsToDraw.front()->CastShadows)
|
||||
shadowLight = item->LightsToDraw.front();
|
||||
else
|
||||
shadowLight = nullptr;
|
||||
}
|
||||
|
||||
void Renderer11::CalculateAmbientLight(RendererItem *item)
|
||||
{
|
||||
ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber];
|
||||
|
||||
// Interpolate ambient light between rooms
|
||||
if (item->PreviousRoomNumber == NO_ITEM)
|
||||
{
|
||||
item->PreviousRoomNumber = nativeItem->RoomNumber;
|
||||
item->CurrentRoomNumber = nativeItem->RoomNumber;
|
||||
item->AmbientLightSteps = AMBIENT_LIGHT_INTERPOLATION_STEPS;
|
||||
}
|
||||
else if (nativeItem->RoomNumber != item->CurrentRoomNumber)
|
||||
{
|
||||
item->PreviousRoomNumber = item->CurrentRoomNumber;
|
||||
item->CurrentRoomNumber = nativeItem->RoomNumber;
|
||||
item->AmbientLightSteps = 0;
|
||||
}
|
||||
else if (item->AmbientLightSteps < AMBIENT_LIGHT_INTERPOLATION_STEPS)
|
||||
item->AmbientLightSteps++;
|
||||
|
||||
if (item->PreviousRoomNumber == NO_ITEM)
|
||||
item->AmbientLight = m_rooms[nativeItem->RoomNumber].AmbientLight;
|
||||
else
|
||||
{
|
||||
item->AmbientLight = (((AMBIENT_LIGHT_INTERPOLATION_STEPS - item->AmbientLightSteps) / (float)AMBIENT_LIGHT_INTERPOLATION_STEPS) * m_rooms[item->PreviousRoomNumber].AmbientLight +
|
||||
(item->AmbientLightSteps / (float)AMBIENT_LIGHT_INTERPOLATION_STEPS) * m_rooms[item->CurrentRoomNumber].AmbientLight);
|
||||
item->AmbientLight.w = 1.0f;
|
||||
}
|
||||
|
||||
// Multiply calculated ambient light by object tint
|
||||
item->AmbientLight *= nativeItem->Color;
|
||||
}
|
||||
|
||||
void Renderer11::CollectLightsForRoom(short roomNumber, RenderView &renderView)
|
||||
{
|
||||
if (m_rooms.size() < roomNumber)
|
||||
|
@ -720,7 +643,7 @@ namespace TEN::Renderer
|
|||
}
|
||||
}
|
||||
|
||||
void Renderer11::CollectEffects(short roomNumber, RenderView &renderView)
|
||||
void Renderer11::CollectEffects(short roomNumber)
|
||||
{
|
||||
if (m_rooms.size() < roomNumber)
|
||||
return;
|
||||
|
@ -745,7 +668,7 @@ namespace TEN::Renderer
|
|||
newEffect->World = Matrix::CreateFromYawPitchRoll(fx->pos.Orientation.y, fx->pos.Position.x, fx->pos.Position.z) * Matrix::CreateTranslation(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z);
|
||||
newEffect->Mesh = GetMesh(obj->nmeshes ? obj->meshIndex : fx->frameNumber);
|
||||
|
||||
CollectLightsForEffect(fx->roomNumber, newEffect, renderView);
|
||||
CollectLightsForEffect(fx->roomNumber, newEffect);
|
||||
|
||||
room.EffectsToDraw.push_back(newEffect);
|
||||
}
|
||||
|
|
|
@ -9,14 +9,13 @@
|
|||
#include "Game/Lara/lara.h"
|
||||
#include "Game/collision/sphere.h"
|
||||
#include "Flow/ScriptInterfaceFlowHandler.h"
|
||||
#include "Renderer\RenderView\RenderView.h"
|
||||
#include "Renderer/RenderView/RenderView.h"
|
||||
#include "Objects/TR3/Vehicles/quad_bike.h"
|
||||
#include "Objects/TR3/Vehicles/rubber_boat.h"
|
||||
#include "Objects/TR3/Vehicles/upv.h"
|
||||
#include "Objects/TR3/Vehicles/big_gun.h"
|
||||
#include "Objects/TR4/Vehicles/jeep.h"
|
||||
#include "Objects/TR4/Vehicles/motorbike.h"
|
||||
#include <algorithm>
|
||||
#include "Game/itemdata/creature_info.h"
|
||||
#include "Objects/TR3/Vehicles/quad_bike_info.h"
|
||||
#include "Objects/TR4/Vehicles/jeep_info.h"
|
||||
|
@ -25,6 +24,7 @@
|
|||
#include "Objects/TR3/Vehicles/upv_info.h"
|
||||
#include "Objects/TR3/Vehicles/big_gun_info.h"
|
||||
#include "Game/items.h"
|
||||
#include <algorithm>
|
||||
|
||||
extern GameConfiguration g_Configuration;
|
||||
extern ScriptInterfaceFlowHandler *g_GameFlow;
|
||||
|
@ -52,7 +52,7 @@ namespace TEN::Renderer
|
|||
static std::vector<int> boneIndexList;
|
||||
boneIndexList.clear();
|
||||
|
||||
RendererBone *Bones[32] = {};
|
||||
RendererBone *Bones[MAX_BONES] = {};
|
||||
int nextBone = 0;
|
||||
|
||||
Matrix rotation;
|
||||
|
@ -359,9 +359,12 @@ namespace TEN::Renderer
|
|||
return (!m_windowed);
|
||||
}
|
||||
|
||||
void Renderer11::UpdateCameraMatrices(CAMERA_INFO *cam, float roll, float fov)
|
||||
void Renderer11::UpdateCameraMatrices(CAMERA_INFO *cam, float roll, float fov, float farView)
|
||||
{
|
||||
gameCamera = RenderView(cam, roll, fov, 32, 102400, g_Configuration.Width, g_Configuration.Height);
|
||||
if (farView < MIN_FAR_VIEW)
|
||||
farView = DEFAULT_FAR_VIEW;
|
||||
|
||||
gameCamera = RenderView(cam, roll, fov, 32, farView, g_Configuration.Width, g_Configuration.Height);
|
||||
}
|
||||
|
||||
bool Renderer11::SphereBoxIntersection(Vector3 boxMin, Vector3 boxMax, Vector3 sphereCentre, float sphereRadius)
|
||||
|
|
|
@ -47,7 +47,7 @@ void TEN::Renderer::Renderer11::Initialise(int w, int h, bool windowed, HWND han
|
|||
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"BITANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"ANIMATIONFRAMEOFFSET", 0, DXGI_FORMAT_R8_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"EFFECTS", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"BLENDINDICES", 0, DXGI_FORMAT_R32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"POLYINDEX", 0, DXGI_FORMAT_R32_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
|
@ -115,7 +115,7 @@ void TEN::Renderer::Renderer11::Initialise(int w, int h, bool windowed, HWND han
|
|||
for (int i = 0; i < NUM_ITEMS; i++)
|
||||
{
|
||||
m_items[i].LightsToDraw = createVector<RendererLight*>(MAX_LIGHTS_PER_ITEM);
|
||||
m_effects[i].Lights = createVector<RendererLight*>(MAX_LIGHTS_PER_ITEM);
|
||||
m_effects[i].LightsToDraw = createVector<RendererLight*>(MAX_LIGHTS_PER_ITEM);
|
||||
}
|
||||
|
||||
m_transparentFacesVertexBuffer = VertexBuffer(m_device.Get(), TRANSPARENT_BUCKET_SIZE);
|
||||
|
@ -336,15 +336,15 @@ void TEN::Renderer::Renderer11::Create()
|
|||
Utils::throwIfFailed(res);
|
||||
}
|
||||
|
||||
void Renderer11::ToggleFullScreen()
|
||||
void Renderer11::ToggleFullScreen(bool force)
|
||||
{
|
||||
m_windowed = !m_windowed;
|
||||
m_windowed = force ? false : !m_windowed;
|
||||
|
||||
if (!m_windowed)
|
||||
{
|
||||
SetWindowLongPtr(WindowsHandle, GWL_STYLE, 0);
|
||||
SetWindowLongPtr(WindowsHandle, GWL_EXSTYLE, WS_EX_TOPMOST);
|
||||
SetWindowPos(WindowsHandle, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
||||
SetWindowPos(WindowsHandle, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
||||
ShowWindow(WindowsHandle, SW_SHOWMAXIMIZED);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -267,13 +267,13 @@ void TEN::Renderer::Renderer11::DrawLara(bool shadowMap, RenderView& view, bool
|
|||
// Set shaders
|
||||
if (shadowMap)
|
||||
{
|
||||
m_context->VSSetShader(m_vsShadowMap.Get(), NULL, 0);
|
||||
m_context->PSSetShader(m_psShadowMap.Get(), NULL, 0);
|
||||
m_context->VSSetShader(m_vsShadowMap.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_psShadowMap.Get(), nullptr, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_context->VSSetShader(m_vsItems.Get(), NULL, 0);
|
||||
m_context->PSSetShader(m_psItems.Get(), NULL, 0);
|
||||
m_context->VSSetShader(m_vsItems.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_psItems.Get(), nullptr, 0);
|
||||
}
|
||||
|
||||
// Set texture
|
||||
|
@ -289,21 +289,16 @@ void TEN::Renderer::Renderer11::DrawLara(bool shadowMap, RenderView& view, bool
|
|||
m_stItem.World = m_LaraWorldMatrix;
|
||||
m_stItem.Position = Vector4(LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z, 1.0f);
|
||||
m_stItem.AmbientLight = item->AmbientLight;
|
||||
memcpy(m_stItem.BonesMatrices, laraObj.AnimationTransforms.data(), sizeof(Matrix) * 32);
|
||||
memcpy(m_stItem.BonesMatrices, laraObj.AnimationTransforms.data(), sizeof(Matrix) * MAX_BONES);
|
||||
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
|
||||
m_stItem.BoneLightModes[k] = GetMesh(Lara.MeshPtrs[k])->LightMode;
|
||||
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
|
||||
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
|
||||
|
||||
if (!shadowMap)
|
||||
{
|
||||
m_stLights.NumLights = item->LightsToDraw.size();
|
||||
|
||||
for (int j = 0; j < item->LightsToDraw.size(); j++)
|
||||
memcpy(&m_stLights.Lights[j], item->LightsToDraw[j], sizeof(ShaderLight));
|
||||
|
||||
m_cbLights.updateData(m_stLights, m_context.Get());
|
||||
BindConstantBufferPS(CB_LIGHTS, m_cbLights.get());
|
||||
}
|
||||
BindLights(item->LightsToDraw);
|
||||
|
||||
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
|
||||
{
|
||||
|
@ -334,16 +329,17 @@ void TEN::Renderer::Renderer11::DrawLara(bool shadowMap, RenderView& view, bool
|
|||
|
||||
// First matrix is Lara's head matrix, then all 6 hairs matrices. Bones are adjusted at load time for accounting this.
|
||||
m_stItem.World = Matrix::Identity;
|
||||
Matrix matrices[7];
|
||||
matrices[0] = laraObj.AnimationTransforms[LM_HEAD] * m_LaraWorldMatrix;
|
||||
m_stItem.BonesMatrices[0] = laraObj.AnimationTransforms[LM_HEAD] * m_LaraWorldMatrix;
|
||||
|
||||
for (int i = 0; i < hairsObj.BindPoseTransforms.size(); i++)
|
||||
{
|
||||
HAIR_STRUCT* hairs = &Hairs[0][i];
|
||||
Matrix world = Matrix::CreateFromYawPitchRoll(TO_RAD(hairs->pos.Orientation.y), TO_RAD(hairs->pos.Orientation.x), 0) * Matrix::CreateTranslation(hairs->pos.Position.x, hairs->pos.Position.y, hairs->pos.Position.z);
|
||||
matrices[i + 1] = world;
|
||||
auto* hairs = &Hairs[0][i];
|
||||
Matrix world = Matrix::CreateFromYawPitchRoll(TO_RAD(hairs->pos.Orientation.y), TO_RAD(hairs->pos.Orientation.x), 0) *
|
||||
Matrix::CreateTranslation(hairs->pos.Position.x, hairs->pos.Position.y, hairs->pos.Position.z);
|
||||
m_stItem.BonesMatrices[i + 1] = world;
|
||||
m_stItem.BoneLightModes[i] = LIGHT_MODES::LIGHT_MODE_DYNAMIC;
|
||||
}
|
||||
|
||||
memcpy(m_stItem.BonesMatrices, matrices, sizeof(Matrix) * 7);
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
|
||||
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "framework.h"
|
||||
#include "Renderer/Renderer11.h"
|
||||
#include "Specific/trutils.h"
|
||||
|
||||
namespace TEN::Renderer
|
||||
{
|
||||
|
@ -11,53 +12,65 @@ namespace TEN::Renderer
|
|||
float factorX = m_screenWidth / REFERENCE_RES_WIDTH;
|
||||
float factorY = m_screenHeight / REFERENCE_RES_HEIGHT;
|
||||
float UIScale = m_screenWidth > m_screenHeight ? factorY : factorX;
|
||||
float fontScale = REFERENCE_FONT_SIZE / m_gameFont->GetLineSpacing();
|
||||
float fontSpacing = m_gameFont->GetLineSpacing();
|
||||
float fontScale = REFERENCE_FONT_SIZE / fontSpacing;
|
||||
|
||||
// Convert the string to wstring
|
||||
int sizeNeeded = MultiByteToWideChar(CP_UTF8, 0, string, strlen(string), NULL, 0);
|
||||
std::wstring wstr(sizeNeeded, 0);
|
||||
MultiByteToWideChar(CP_UTF8, 0, string, strlen(string), &wstr[0], sizeNeeded);
|
||||
float currentY = 0;
|
||||
|
||||
// Prepare the structure for the renderer
|
||||
RendererStringToDraw str;
|
||||
str.String = wstr;
|
||||
str.Flags = flags;
|
||||
str.X = 0;
|
||||
str.Y = 0;
|
||||
str.Color = Vector3((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF);
|
||||
str.Scale = UIScale * fontScale;
|
||||
auto lines = TEN::Utils::SplitString(string);
|
||||
|
||||
// Measure the string
|
||||
Vector2 size = m_gameFont->MeasureString(wstr.c_str());
|
||||
float width = size.x * str.Scale;
|
||||
|
||||
str.X = (flags & PRINTSTRING_CENTER) ? (float)x * factorX - (width / 2.0f) : (float)x * factorX;
|
||||
str.Y = y * UIScale;
|
||||
|
||||
if (flags & PRINTSTRING_BLINK)
|
||||
for (auto line : lines)
|
||||
{
|
||||
str.Color = Vector3(m_blinkColorValue, m_blinkColorValue, m_blinkColorValue);
|
||||
auto cLine = line.c_str();
|
||||
|
||||
if (!m_blinkUpdated)
|
||||
// Convert the string to wstring
|
||||
int sizeNeeded = MultiByteToWideChar(CP_UTF8, 0, cLine, line.size(), NULL, 0);
|
||||
std::wstring wstr(sizeNeeded, 0);
|
||||
MultiByteToWideChar(CP_UTF8, 0, cLine, strlen(cLine), &wstr[0], sizeNeeded);
|
||||
|
||||
// Prepare the structure for the renderer
|
||||
RendererStringToDraw str;
|
||||
str.String = wstr;
|
||||
str.Flags = flags;
|
||||
str.X = 0;
|
||||
str.Y = 0;
|
||||
str.Color = Vector3((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF);
|
||||
str.Scale = UIScale * fontScale;
|
||||
|
||||
// Measure the string
|
||||
Vector2 size = m_gameFont->MeasureString(wstr.c_str());
|
||||
float width = size.x * str.Scale;
|
||||
|
||||
str.X = (flags & PRINTSTRING_CENTER) ? (float)x * factorX - (width / 2.0f) : (float)x * factorX;
|
||||
str.Y = y * UIScale + currentY;
|
||||
|
||||
if (flags & PRINTSTRING_BLINK)
|
||||
{
|
||||
m_blinkColorValue += m_blinkColorDirection * 16;
|
||||
m_blinkUpdated = true;
|
||||
str.Color = Vector3(m_blinkColorValue, m_blinkColorValue, m_blinkColorValue);
|
||||
|
||||
if (m_blinkColorValue < 0)
|
||||
if (!m_blinkUpdated)
|
||||
{
|
||||
m_blinkColorValue = 0;
|
||||
m_blinkColorDirection = 1;
|
||||
}
|
||||
m_blinkColorValue += m_blinkColorDirection * 16;
|
||||
m_blinkUpdated = true;
|
||||
|
||||
if (m_blinkColorValue > 255)
|
||||
{
|
||||
m_blinkColorValue = 255;
|
||||
m_blinkColorDirection = -1;
|
||||
if (m_blinkColorValue < 0)
|
||||
{
|
||||
m_blinkColorValue = 0;
|
||||
m_blinkColorDirection = 1;
|
||||
}
|
||||
|
||||
if (m_blinkColorValue > 255)
|
||||
{
|
||||
m_blinkColorValue = 255;
|
||||
m_blinkColorDirection = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_strings.push_back(str);
|
||||
m_strings.push_back(str);
|
||||
|
||||
currentY += fontSpacing * 1.1f;
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer11::DrawAllStrings()
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace TEN::Renderer
|
|||
RendererRoom* room;
|
||||
RendererBucket* bucket;
|
||||
RendererItem* item;
|
||||
MESH_INFO* staticMesh;
|
||||
RendererStatic* staticMesh;
|
||||
Vector4 color;
|
||||
Matrix world;
|
||||
Vector3 position;
|
||||
|
|
|
@ -10,11 +10,11 @@ namespace TEN::Renderer
|
|||
DirectX::SimpleMath::Vector2 UV;
|
||||
DirectX::SimpleMath::Vector4 Color;
|
||||
DirectX::SimpleMath::Vector3 Tangent;
|
||||
DirectX::SimpleMath::Vector3 BiTangent;
|
||||
unsigned char AnimationFrameOffset;
|
||||
DirectX::SimpleMath::Vector4 Effects;
|
||||
float Bone;
|
||||
int IndexInPoly;
|
||||
int OriginalIndex;
|
||||
int hash;
|
||||
int Hash;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,15 +6,17 @@ namespace TEN::Renderer
|
|||
struct RendererLight
|
||||
{
|
||||
Vector3 Position;
|
||||
int Type;
|
||||
unsigned int Type;
|
||||
Vector3 Color;
|
||||
float LocalIntensity;
|
||||
Vector3 Direction;
|
||||
float Distance;
|
||||
float Intensity;
|
||||
Vector3 Direction;
|
||||
float In;
|
||||
float Out;
|
||||
float Range;
|
||||
float InRange;
|
||||
float OutRange;
|
||||
|
||||
float LocalIntensity;
|
||||
float Distance;
|
||||
bool AffectNeighbourRooms;
|
||||
bool CastShadows;
|
||||
};
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace TEN::Renderer
|
|||
std::vector<RendererLight> Lights;
|
||||
std::vector<RendererItem*> ItemsToDraw;
|
||||
std::vector<RendererEffect*> EffectsToDraw;
|
||||
std::vector<MESH_INFO*> StaticsToDraw;
|
||||
std::vector<RendererStatic> StaticsToDraw;
|
||||
std::vector<RendererTransparentFace> TransparentFacesToDraw;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
virtual bool HasSlideExtended() const = 0;
|
||||
virtual ScriptInterfaceLevel * GetLevel(int level) = 0;
|
||||
virtual int GetLevelNumber(std::string const& flieName) = 0;
|
||||
virtual short GetGameFarView() const = 0;
|
||||
virtual bool CanPlayAnyLevel() const = 0;
|
||||
virtual bool DoFlow() = 0;
|
||||
};
|
||||
|
|
|
@ -42,4 +42,5 @@ public:
|
|||
virtual RGBAColor8Byte GetFogColor() const = 0;
|
||||
virtual short GetFogMinDistance() const = 0;
|
||||
virtual short GetFogMaxDistance() const = 0;
|
||||
virtual short GetFarView() const = 0;
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "Game/gui.h"
|
||||
#include "Vec3/Vec3.h"
|
||||
#include "Objects/ScriptInterfaceObjectsHandler.h"
|
||||
#include "Specific/trutils.h"
|
||||
|
||||
/***
|
||||
Functions for use in Flow.lua, settings.lua and strings.lua
|
||||
|
@ -170,10 +171,10 @@ void FlowHandler::SetTitleScreenImagePath(std::string const& path)
|
|||
TitleScreenImagePath = path;
|
||||
}
|
||||
|
||||
void FlowHandler::SetGameFarView(byte val)
|
||||
void FlowHandler::SetGameFarView(short val)
|
||||
{
|
||||
bool cond = val <= 127 && val >= 1;
|
||||
std::string msg{ "Game far view value must be in the range [1, 127]." };
|
||||
std::string msg{ "Game far view value must be in the range [1, 255]." };
|
||||
if (!ScriptAssert(cond, msg))
|
||||
{
|
||||
ScriptWarn("Setting game far view to 32.");
|
||||
|
@ -220,14 +221,11 @@ int FlowHandler::GetLevelNumber(std::string const& fileName)
|
|||
if (fileName.empty())
|
||||
return -1;
|
||||
|
||||
auto lcFilename = fileName;
|
||||
std::transform(lcFilename.begin(), lcFilename.end(), lcFilename.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||
auto lcFilename = TEN::Utils::ToLower(fileName);
|
||||
|
||||
for (int i = 0; i < Levels.size(); i++)
|
||||
{
|
||||
auto level = this->GetLevel(i)->FileName;
|
||||
std::transform(level.begin(), level.end(), level.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||
|
||||
auto level = TEN::Utils::ToLower(this->GetLevel(i)->FileName);
|
||||
if (level == lcFilename && std::filesystem::exists(fileName))
|
||||
return i;
|
||||
}
|
||||
|
@ -308,17 +306,16 @@ bool FlowHandler::DoFlow()
|
|||
|
||||
// Load level
|
||||
CurrentLevel = header.Level;
|
||||
GameTimer = header.Timer;
|
||||
loadFromSavegame = true;
|
||||
|
||||
break;
|
||||
case GameStatus::LevelComplete:
|
||||
if (LevelComplete >= Levels.size())
|
||||
{
|
||||
// TODO: final credits
|
||||
CurrentLevel = 0;
|
||||
}
|
||||
CurrentLevel = 0; // TODO: final credits
|
||||
else
|
||||
CurrentLevel++;
|
||||
CurrentLevel = LevelComplete;
|
||||
LevelComplete = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -330,4 +327,9 @@ bool FlowHandler::DoFlow()
|
|||
bool FlowHandler::CanPlayAnyLevel() const
|
||||
{
|
||||
return PlayAnyLevel;
|
||||
}
|
||||
|
||||
short FlowHandler::GetGameFarView() const
|
||||
{
|
||||
return GameFarView;
|
||||
}
|
|
@ -27,7 +27,7 @@ public:
|
|||
bool PlayAnyLevel{ true };
|
||||
bool FlyCheat{ true };
|
||||
bool DebugMode{ false };
|
||||
byte GameFarView{ 0 };
|
||||
short GameFarView{ 0 };
|
||||
|
||||
// New animation flag table
|
||||
Animations Anims{};
|
||||
|
@ -51,7 +51,8 @@ public:
|
|||
int GetNumLevels() const;
|
||||
void SetIntroImagePath(std::string const& path);
|
||||
void SetTitleScreenImagePath(std::string const& path);
|
||||
void SetGameFarView(byte val);
|
||||
void SetGameFarView(short val);
|
||||
short GetGameFarView() const;
|
||||
bool IsFlyCheatEnabled() const;
|
||||
bool CanPlayAnyLevel() const;
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ e.g. `myLevel.laraType = LaraType.Divesuit`
|
|||
|
||||
/*** (byte) The maximum draw distance for level.
|
||||
Given in sectors (blocks).
|
||||
Must be in the range [1, 127], and equal to or less than the value passed to SetGameFarView.
|
||||
Must be in the range [1, 255], and equal to or less than the value passed to SetGameFarView.
|
||||
|
||||
This is equivalent to TRNG's LevelFarView variable.
|
||||
|
||||
|
@ -156,9 +156,9 @@ void Level::SetWeatherStrength(float val)
|
|||
}
|
||||
}
|
||||
|
||||
void Level::SetLevelFarView(byte val)
|
||||
void Level::SetLevelFarView(short val)
|
||||
{
|
||||
bool cond = val <= 127 && val >= 1;
|
||||
bool cond = val <= 255 && val >= 1;
|
||||
std::string msg{ "levelFarView value must be in the range [1, 127]." };
|
||||
if (!ScriptAssert(cond, msg))
|
||||
{
|
||||
|
@ -258,3 +258,9 @@ short Level::GetFogMaxDistance() const
|
|||
{
|
||||
return Fog.MaxDistance;
|
||||
}
|
||||
|
||||
short Level::GetFarView() const
|
||||
{
|
||||
return float(LevelFarView);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,10 +49,11 @@ struct Level : public ScriptInterfaceLevel
|
|||
RGBAColor8Byte GetSkyLayerColor(int index) const override;
|
||||
LaraType GetLaraType() const override;
|
||||
void SetWeatherStrength(float val);
|
||||
void SetLevelFarView(byte val);
|
||||
void SetLevelFarView(short val);
|
||||
static void Register(sol::table & parent);
|
||||
WeatherType GetWeatherType() const override;
|
||||
short GetMirrorRoom() const override;
|
||||
short GetFogMinDistance() const override;
|
||||
short GetFogMaxDistance() const override;
|
||||
short GetFarView() const override;
|
||||
};
|
||||
|
|
|
@ -121,6 +121,7 @@ static std::unique_ptr<Moveable> Create(
|
|||
ptr->SetHP(USE_IF_HAVE(short, hp, 10));
|
||||
ptr->SetOCB(USE_IF_HAVE(short, ocb, 0));
|
||||
ptr->SetAIBits(USE_IF_HAVE(aiBitsType, aiBits, aiBitsType{}));
|
||||
ptr->SetColor(ScriptColor(Vector4::One));
|
||||
item->CarriedItem = NO_ITEM;
|
||||
|
||||
// call this when resetting name too?
|
||||
|
|
|
@ -31,12 +31,11 @@ PixelShaderInput VS(VertexShaderInput input)
|
|||
output.Normal = (mul(float4(input.Normal, 0.0f), World).xyz);
|
||||
output.Color = input.Color;
|
||||
output.UV = input.UV;
|
||||
output.WorldPosition = (mul(float4(input.Position, 1.0f), World));
|
||||
output.WorldPosition = (mul(float4(input.Position, 1.0f), World).xyz);
|
||||
output.Sheen = input.Effects.w;
|
||||
return output;
|
||||
}
|
||||
|
||||
[earlydepthstencil]
|
||||
float4 PS(PixelShaderInput input) : SV_TARGET
|
||||
{
|
||||
float4 output = Texture.Sample(Sampler, input.UV);
|
||||
|
|
|
@ -1,46 +1,39 @@
|
|||
#include "./Math.hlsli"
|
||||
#include "./CameraMatrixBuffer.hlsli"
|
||||
#include "./ShaderLight.hlsli"
|
||||
#include "./VertexEffects.hlsli"
|
||||
#include "./VertexInput.hlsli"
|
||||
#include "./AlphaTestBuffer.hlsli"
|
||||
|
||||
#define MAX_BONES 32
|
||||
|
||||
cbuffer ItemBuffer : register(b1)
|
||||
{
|
||||
float4x4 World;
|
||||
float4x4 Bones[32];
|
||||
float4x4 Bones[MAX_BONES];
|
||||
float4 ItemPosition;
|
||||
float4 AmbientLight;
|
||||
};
|
||||
|
||||
cbuffer LightsBuffer : register(b2)
|
||||
{
|
||||
ShaderLight Lights[MAX_LIGHTS];
|
||||
int NumLights;
|
||||
float3 CameraPosition;
|
||||
};
|
||||
|
||||
cbuffer MiscBuffer : register(b3)
|
||||
{
|
||||
int Caustics;
|
||||
int4 BoneLightModes[MAX_BONES / 4];
|
||||
};
|
||||
|
||||
struct PixelShaderInput
|
||||
{
|
||||
float4 Position: SV_POSITION;
|
||||
float3 Normal: NORMAL;
|
||||
float3 WorldPosition : POSITION;
|
||||
float3 WorldPosition: POSITION;
|
||||
float2 UV: TEXCOORD;
|
||||
float4 Color: COLOR;
|
||||
float Sheen : SHEEN;
|
||||
float3x3 TBN : TBN;
|
||||
float Fog : FOG;
|
||||
float4 PositionCopy : TEXCOORD2;
|
||||
float Sheen: SHEEN;
|
||||
float3x3 TBN: TBN;
|
||||
float Fog: FOG;
|
||||
float4 PositionCopy: TEXCOORD2;
|
||||
uint Bone: BONE;
|
||||
};
|
||||
|
||||
struct PixelShaderOutput
|
||||
{
|
||||
float4 Color: SV_Target0;
|
||||
float4 Depth: SV_Target1;
|
||||
float4 Color: SV_TARGET0;
|
||||
float4 Depth: SV_TARGET1;
|
||||
};
|
||||
|
||||
Texture2D Texture : register(t0);
|
||||
|
@ -56,46 +49,29 @@ PixelShaderInput VS(VertexShaderInput input)
|
|||
|
||||
float4x4 world = mul(Bones[input.Bone], World);
|
||||
|
||||
float3 Normal = (mul(float4(input.Normal, 0.0f), world).xyz);
|
||||
float3 WorldPosition = (mul(float4(input.Position, 1.0f), world));
|
||||
float3 normal = (mul(float4(input.Normal, 0.0f), world).xyz);
|
||||
float3 worldPosition = (mul(float4(input.Position, 1.0f), world).xyz);
|
||||
|
||||
output.Normal = Normal;
|
||||
output.Normal = normal;
|
||||
output.UV = input.UV;
|
||||
output.WorldPosition = WorldPosition;
|
||||
output.WorldPosition = worldPosition;
|
||||
|
||||
float3 Tangent = mul(float4(input.Tangent, 0), world).xyz;
|
||||
float3 Bitangent = mul(float4(input.Bitangent, 0), world).xyz;
|
||||
float3x3 TBN = float3x3(Tangent, Bitangent, Normal);
|
||||
float3 Bitangent = cross(normal, Tangent);
|
||||
float3x3 TBN = float3x3(Tangent, Bitangent, normal);
|
||||
|
||||
output.TBN = transpose(TBN);
|
||||
|
||||
float3 pos = input.Position;
|
||||
float4 col = input.Color;
|
||||
|
||||
// Setting effect weight on TE side prevents portal vertices from moving.
|
||||
// Here we just read weight and decide if we should apply refraction or movement effect.
|
||||
float weight = input.Effects.z;
|
||||
|
||||
// Wibble effect returns different value depending on vertex hash and frame number.
|
||||
// In theory, hash could be affected by WaterScheme value from room.
|
||||
float wibble = sin((((Frame + input.Hash) % 256) / 256.0) * (PI2)); // sin from -1 to 1 with a period of 64 frames
|
||||
|
||||
// Glow
|
||||
if (input.Effects.x > 0.0f)
|
||||
{
|
||||
float intensity = input.Effects.x * lerp(-0.5f, 1.0f, wibble * 0.5f + 0.5f);
|
||||
col = saturate(col + float4(intensity, intensity, intensity, 0));
|
||||
}
|
||||
|
||||
// Movement
|
||||
if (input.Effects.y > 0.0f)
|
||||
pos.y += wibble * input.Effects.y * weight * 128.0f; // 128 units offset to top and bottom (256 total)
|
||||
// Calculate vertex effects
|
||||
float wibble = Wibble(input.Effects.xyz, input.Hash);
|
||||
float3 pos = Move(input.Position, input.Effects.xyz, wibble);
|
||||
float3 col = Glow(input.Color.xyz, input.Effects.xyz, wibble);
|
||||
|
||||
output.Position = mul(mul(float4(pos, 1.0f), world), ViewProjection);
|
||||
output.Color = col;
|
||||
output.Color = float4(col, input.Color.w);
|
||||
|
||||
// Apply distance fog
|
||||
float d = distance(CamPositionWS.xyz,WorldPosition);
|
||||
float d = distance(CamPositionWS.xyz, worldPosition);
|
||||
if (FogMaxDistance == 0)
|
||||
output.Fog = 1;
|
||||
else
|
||||
|
@ -103,62 +79,32 @@ PixelShaderInput VS(VertexShaderInput input)
|
|||
|
||||
output.PositionCopy = output.Position;
|
||||
output.Sheen = input.Effects.w;
|
||||
output.Bone = input.Bone;
|
||||
return output;
|
||||
}
|
||||
|
||||
PixelShaderOutput PS(PixelShaderInput input) : SV_TARGET
|
||||
PixelShaderOutput PS(PixelShaderInput input)
|
||||
{
|
||||
PixelShaderOutput output;
|
||||
float4 tex = Texture.Sample(Sampler, input.UV);
|
||||
|
||||
float4 tex = Texture.Sample(Sampler, input.UV);
|
||||
DoAlphaTest(tex);
|
||||
float3 ambient = AmbientLight.xyz * tex.xyz;
|
||||
|
||||
float3 normal = NormalTexture.Sample(Sampler, input.UV).rgb;
|
||||
normal = normal * 2 - 1;
|
||||
normal = normalize(mul(input.TBN, normal));
|
||||
|
||||
float3 diffuse = 0;
|
||||
float3 spec = 0;
|
||||
|
||||
for (int i = 0; i < NumLights; i++)
|
||||
{
|
||||
int lightType = Lights[i].Type;
|
||||
float3 color = (BoneLightModes[input.Bone / 4][input.Bone % 4] == 0) ?
|
||||
CombineLights(AmbientLight.xyz, input.Color.xyz, tex.xyz, input.WorldPosition, normal, input.Sheen) :
|
||||
StaticLight(AmbientLight.xyz, input.Color.xyz, tex.xyz);
|
||||
|
||||
if (lightType == LT_POINT || lightType == LT_SHADOW)
|
||||
{
|
||||
diffuse += DoPointLight(input.WorldPosition, normal, Lights[i]);
|
||||
spec += DoSpecularPoint(input.WorldPosition, normal, Lights[i], input.Sheen);
|
||||
output.Color = saturate(float4(color, tex.w));
|
||||
|
||||
}
|
||||
else if (lightType == LT_SUN)
|
||||
{
|
||||
diffuse += DoDirectionalLight(input.WorldPosition, normal, Lights[i]);
|
||||
spec += DoSpecularSun(normal, Lights[i], input.Sheen);
|
||||
|
||||
}
|
||||
else if (lightType == LT_SPOT)
|
||||
{
|
||||
diffuse += DoSpotLight(input.WorldPosition, normal, Lights[i]);
|
||||
spec += DoSpecularSpot(input.WorldPosition, normal, Lights[i], input.Sheen);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
diffuse.xyz *= tex.xyz;
|
||||
output.Depth = tex.w > 0.0f ?
|
||||
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
|
||||
float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
output.Color = float4(ambient + diffuse + spec, tex.w);
|
||||
|
||||
float3 colorMul = min(input.Color.xyz, 1.0f);
|
||||
output.Color.xyz *= colorMul.xyz;
|
||||
|
||||
if (FogMaxDistance != 0)
|
||||
{
|
||||
output.Color.xyz = lerp(output.Color.xyz, FogColor.xyz, input.Fog);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
|
@ -1,17 +1,12 @@
|
|||
#include "./CameraMatrixBuffer.hlsli"
|
||||
#include "./VertexInput.hlsli"
|
||||
#include "./VertexEffects.hlsli"
|
||||
#include "./Math.hlsli"
|
||||
#include "./ShaderLight.hlsli"
|
||||
#include "./AlphaTestBuffer.hlsli"
|
||||
#define SHADOW_INTENSITY (0.55f)
|
||||
#define INV_SHADOW_INTENSITY (1.0f-SHADOW_INTENSITY)
|
||||
|
||||
cbuffer LightsBuffer : register(b2)
|
||||
{
|
||||
ShaderLight Lights[MAX_LIGHTS];
|
||||
int NumLights;
|
||||
float3 Padding;
|
||||
};
|
||||
#define SHADOW_INTENSITY (0.55f)
|
||||
#define INV_SHADOW_INTENSITY (1.0f - SHADOW_INTENSITY)
|
||||
|
||||
struct Sphere
|
||||
{
|
||||
|
@ -22,7 +17,6 @@ struct Sphere
|
|||
cbuffer MiscBuffer : register(b3)
|
||||
{
|
||||
int Caustics;
|
||||
|
||||
};
|
||||
|
||||
cbuffer ShadowLightBuffer : register(b4)
|
||||
|
@ -38,7 +32,7 @@ cbuffer ShadowLightBuffer : register(b4)
|
|||
cbuffer RoomBuffer : register(b5)
|
||||
{
|
||||
float4 AmbientColor;
|
||||
int Water;
|
||||
uint Water;
|
||||
};
|
||||
|
||||
struct AnimatedFrameUV
|
||||
|
@ -79,38 +73,27 @@ SamplerComparisonState ShadowMapSampler : register(s3);
|
|||
|
||||
struct PixelShaderOutput
|
||||
{
|
||||
float4 Color: SV_Target0;
|
||||
float4 Depth: SV_Target1;
|
||||
float4 Color: SV_TARGET0;
|
||||
float4 Depth: SV_TARGET1;
|
||||
};
|
||||
|
||||
PixelShaderInput VS(VertexShaderInput input)
|
||||
{
|
||||
PixelShaderInput output;
|
||||
float3 pos = input.Position;
|
||||
float4 col = input.Color;
|
||||
|
||||
|
||||
// Setting effect weight on TE side prevents portal vertices from moving.
|
||||
// Here we just read weight and decide if we should apply refraction or movement effect.
|
||||
float weight = input.Effects.z;
|
||||
|
||||
// Wibble effect returns different value depending on vertex hash and frame number.
|
||||
// In theory, hash could be affected by WaterScheme value from room.
|
||||
float wibble = sin((((Frame + input.Hash) % 64) / 64.0) * (PI2)); // sin from -1 to 1 with a period of 64 frames
|
||||
|
||||
// Glow
|
||||
if (input.Effects.x > 0.0f)
|
||||
{
|
||||
float intensity = input.Effects.x * lerp(-0.5f, 1.0f, wibble * 0.5f + 0.5f);
|
||||
col = saturate(col + float4(intensity, intensity, intensity, 0));
|
||||
}
|
||||
|
||||
// Movement
|
||||
if (input.Effects.y > 0.0f)
|
||||
pos.y += wibble * input.Effects.y * weight * 128.0f; // 128 units offset to top and bottom (256 total)
|
||||
|
||||
// Calculate vertex effects
|
||||
float wibble = Wibble(input.Effects.xyz, input.Hash);
|
||||
float3 pos = Move(input.Position, input.Effects.xyz * weight, wibble);
|
||||
float3 col = Glow(input.Color.xyz, input.Effects.xyz, wibble);
|
||||
|
||||
// Refraction
|
||||
float4 screenPos = mul(float4(pos, 1.0f), ViewProjection);
|
||||
float2 clipPos = screenPos.xy / screenPos.w;
|
||||
|
||||
if (CameraUnderwater != Water)
|
||||
{
|
||||
float factor = (Frame + clipPos.x * 320);
|
||||
|
@ -122,12 +105,12 @@ PixelShaderInput VS(VertexShaderInput input)
|
|||
|
||||
output.Position = screenPos;
|
||||
output.Normal = input.Normal;
|
||||
output.Color = col;
|
||||
output.Color = float4(col, input.Color.w);
|
||||
output.PositionCopy = screenPos;
|
||||
|
||||
#ifdef ANIMATED
|
||||
float speed = fps / 30.0f;
|
||||
int frame = (int)(Frame * speed) % numAnimFrames;
|
||||
int frame = (int)(Frame * speed + input.AnimationFrameOffset) % numAnimFrames;
|
||||
switch (input.PolyIndex) {
|
||||
case 0:
|
||||
output.UV = AnimFrames[frame].topLeft;
|
||||
|
@ -144,16 +127,15 @@ PixelShaderInput VS(VertexShaderInput input)
|
|||
}
|
||||
#else
|
||||
output.UV = input.UV;
|
||||
|
||||
#endif
|
||||
|
||||
output.WorldPosition = input.Position.xyz;
|
||||
|
||||
float3x3 TBN = float3x3(input.Tangent, input.Bitangent, input.Normal);
|
||||
float3x3 TBN = float3x3(input.Tangent, cross(input.Normal,input.Tangent), input.Normal);
|
||||
output.TBN = TBN;
|
||||
|
||||
// Apply distance fog
|
||||
float4 d = length(CamPositionWS - output.WorldPosition);
|
||||
float d = length(CamPositionWS.xyz - output.WorldPosition);
|
||||
if (FogMaxDistance == 0)
|
||||
output.Fog = 1;
|
||||
else
|
||||
|
@ -287,7 +269,6 @@ void doBlobShadows(float3 worldPos, inout float3 lighting)
|
|||
}
|
||||
shadowFactor = saturate(shadowFactor);
|
||||
lighting *= saturate((shadowFactor+SHADOW_INTENSITY));
|
||||
|
||||
}
|
||||
|
||||
void doSpotLightShadow(float3 worldPos,inout float3 lighting)
|
||||
|
@ -319,7 +300,8 @@ void doSpotLightShadow(float3 worldPos,inout float3 lighting)
|
|||
float angleFactor = min(max(sin(lightClipSpace.x * PI)*1.2, 0), 1);
|
||||
lighting *= saturate((shadowFactor + SHADOW_INTENSITY) + (pow(distanceFactor, 4) * (1 - angleFactor) * INV_SHADOW_INTENSITY));
|
||||
}
|
||||
PixelShaderOutput PS(PixelShaderInput input) : SV_TARGET
|
||||
|
||||
PixelShaderOutput PS(PixelShaderInput input)
|
||||
{
|
||||
PixelShaderOutput output;
|
||||
|
||||
|
@ -329,7 +311,7 @@ PixelShaderOutput PS(PixelShaderInput input) : SV_TARGET
|
|||
|
||||
float3 Normal = NormalTexture.Sample(Sampler,input.UV).rgb;
|
||||
Normal = Normal * 2 - 1;
|
||||
Normal = normalize(mul(Normal,input.TBN));
|
||||
Normal = normalize(mul(Normal, input.TBN));
|
||||
|
||||
float3 lighting = input.Color.xyz;
|
||||
bool doLights = true;
|
||||
|
@ -352,7 +334,7 @@ PixelShaderOutput PS(PixelShaderInput input) : SV_TARGET
|
|||
|
||||
if (doLights)
|
||||
{
|
||||
for (uint i = 0; i < NumLights; i++)
|
||||
for (int i = 0; i < NumLights; i++)
|
||||
{
|
||||
float3 lightPos = Lights[i].Position.xyz;
|
||||
float3 color = Lights[i].Color.xyz;
|
||||
|
@ -395,17 +377,17 @@ PixelShaderOutput PS(PixelShaderInput input) : SV_TARGET
|
|||
float3 yaxis = CausticsTexture.Sample(Sampler, p.xz).xyz;
|
||||
float3 zaxis = CausticsTexture.Sample(Sampler, p.xy).xyz;
|
||||
|
||||
lighting += float4((xaxis * blending.x + yaxis * blending.y + zaxis * blending.z).xyz, 0.0f) * attenuation * 2.0f;
|
||||
lighting += float3((xaxis * blending.x + yaxis * blending.y + zaxis * blending.z).xyz) * attenuation * 2.0f;
|
||||
}
|
||||
|
||||
output.Color.xyz = output.Color.xyz * lighting;
|
||||
output.Color.xyz = saturate(output.Color.xyz * lighting);
|
||||
|
||||
output.Depth = output.Color.w > 0.0f ?
|
||||
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
|
||||
float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
if (FogMaxDistance != 0)
|
||||
output.Color.xyz = lerp(output.Color.xyz, FogColor, input.Fog);
|
||||
output.Color.xyz = lerp(output.Color.xyz, FogColor.xyz, input.Fog);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
cbuffer StaticMatrixBuffer : register(b8)
|
||||
{
|
||||
float4x4 World;
|
||||
float4 StaticPosition;
|
||||
float4 Position;
|
||||
float4 Color;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#include "./Math.hlsli"
|
||||
#include "./CameraMatrixBuffer.hlsli"
|
||||
#include "./ShaderLight.hlsli"
|
||||
#include "./VertexEffects.hlsli"
|
||||
#include "./VertexInput.hlsli"
|
||||
#include "./AlphaTestBuffer.hlsli"
|
||||
|
||||
|
@ -7,22 +10,25 @@ cbuffer StaticMatrixBuffer : register(b8)
|
|||
float4x4 World;
|
||||
float4 Position;
|
||||
float4 Color;
|
||||
int LightType;
|
||||
};
|
||||
|
||||
struct PixelShaderInput
|
||||
{
|
||||
float4 Position: SV_POSITION;
|
||||
float3 Normal: NORMAL;
|
||||
float3 WorldPosition: POSITION;
|
||||
float2 UV: TEXCOORD1;
|
||||
float4 Color: COLOR;
|
||||
float Fog : FOG;
|
||||
float Sheen: SHEEN;
|
||||
float Fog: FOG;
|
||||
float4 PositionCopy: TEXCOORD2;
|
||||
};
|
||||
|
||||
struct PixelShaderOutput
|
||||
{
|
||||
float4 Color: SV_Target0;
|
||||
float4 Depth: SV_Target1;
|
||||
float4 Color: SV_TARGET0;
|
||||
float4 Depth: SV_TARGET1;
|
||||
};
|
||||
|
||||
Texture2D Texture : register(t0);
|
||||
|
@ -32,13 +38,18 @@ PixelShaderInput VS(VertexShaderInput input)
|
|||
{
|
||||
PixelShaderInput output;
|
||||
|
||||
float4 worldPosition = mul(float4(input.Position, 1.0f), World);
|
||||
float4 worldPosition = (mul(float4(input.Position, 1.0f), World));
|
||||
float3 normal = (mul(float4(input.Normal, 0.0f), World).xyz);
|
||||
|
||||
output.Position = mul(worldPosition, ViewProjection);
|
||||
output.Normal = input.Normal;
|
||||
output.Color = input.Color * Color;
|
||||
output.Normal = normal;
|
||||
output.UV = input.UV;
|
||||
output.PositionCopy = output.Position;
|
||||
output.WorldPosition = worldPosition;
|
||||
|
||||
float3 pos = Move(input.Position, input.Effects.xyz, input.Hash);
|
||||
float3 col = Glow(input.Color.xyz, input.Effects.xyz, input.Hash);
|
||||
|
||||
output.Position = mul(worldPosition, ViewProjection);
|
||||
output.Color = float4(col, input.Color.w);
|
||||
|
||||
// Apply distance fog
|
||||
float4 d = length(CamPositionWS - worldPosition);
|
||||
|
@ -46,27 +57,31 @@ PixelShaderInput VS(VertexShaderInput input)
|
|||
output.Fog = 1;
|
||||
else
|
||||
output.Fog = clamp((d - FogMinDistance * 1024) / (FogMaxDistance * 1024 - FogMinDistance * 1024), 0, 1);
|
||||
|
||||
|
||||
output.PositionCopy = output.Position;
|
||||
output.Sheen = input.Effects.w;
|
||||
return output;
|
||||
}
|
||||
|
||||
PixelShaderOutput PS(PixelShaderInput input) : SV_TARGET
|
||||
PixelShaderOutput PS(PixelShaderInput input)
|
||||
{
|
||||
PixelShaderOutput output;
|
||||
|
||||
output.Color = Texture.Sample(Sampler, input.UV);
|
||||
|
||||
DoAlphaTest(output.Color);
|
||||
float4 tex = Texture.Sample(Sampler, input.UV);
|
||||
DoAlphaTest(tex);
|
||||
|
||||
float3 colorMul = min(input.Color.xyz, 1.0f);
|
||||
output.Color.xyz = output.Color.xyz * colorMul.xyz;
|
||||
float3 color = (LightType == 0) ?
|
||||
CombineLights(Color.xyz, input.Color.xyz, tex.xyz, input.WorldPosition, normalize(input.Normal), input.Sheen) :
|
||||
StaticLight(Color.xyz, input.Color.xyz, tex.xyz);
|
||||
|
||||
output.Depth = output.Color.w > 0.0f ?
|
||||
output.Color = float4(color, tex.w);
|
||||
|
||||
output.Depth = tex.w > 0.0f ?
|
||||
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
|
||||
float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
if (FogMaxDistance != 0)
|
||||
output.Color.xyz = lerp(output.Color.xyz, FogColor, input.Fog);
|
||||
output.Color.xyz = lerp(output.Color.xyz, FogColor.xyz, input.Fog);
|
||||
|
||||
return output;
|
||||
}
|
|
@ -1,3 +1,2 @@
|
|||
#pragma once
|
||||
#define PI 3.1415926535897932384626433832795028841971693993751058209749445923
|
||||
#define PI2 6.2831853071795864769252867665590057683943387987502116419498891846
|
|
@ -1,3 +1,4 @@
|
|||
#include "./Math.hlsli"
|
||||
|
||||
#define LT_SUN 0
|
||||
#define LT_POINT 1
|
||||
|
@ -5,139 +6,159 @@
|
|||
#define LT_SHADOW 3
|
||||
|
||||
#define MAX_LIGHTS 48
|
||||
#define SPEC_FACTOR 64
|
||||
|
||||
struct ShaderLight
|
||||
{
|
||||
float3 Position;
|
||||
int Type;
|
||||
uint Type;
|
||||
float3 Color;
|
||||
float LocalIntensity;
|
||||
float3 Direction;
|
||||
float Distance;
|
||||
float Intensity;
|
||||
float3 Direction;
|
||||
float In;
|
||||
float Out;
|
||||
float Range;
|
||||
float InRange;
|
||||
float OutRange;
|
||||
|
||||
float padding;
|
||||
};
|
||||
|
||||
cbuffer LightsBuffer : register(b2)
|
||||
{
|
||||
ShaderLight Lights[MAX_LIGHTS];
|
||||
int NumLights;
|
||||
};
|
||||
|
||||
float3 DoSpecularPoint(float3 pos, float3 n, ShaderLight light, float strength)
|
||||
{
|
||||
if (!(strength > 0.0))
|
||||
{
|
||||
return float3(0, 0, 0);
|
||||
}
|
||||
float3 lightPos = light.Position.xyz;
|
||||
float radius = light.Out;
|
||||
if ((strength <= 0.0))
|
||||
return float3(0, 0, 0);
|
||||
else
|
||||
{
|
||||
float3 lightPos = light.Position.xyz;
|
||||
float radius = light.Out;
|
||||
|
||||
float dist = distance(lightPos, pos);
|
||||
if (dist > radius)
|
||||
{
|
||||
return float3(0, 0, 0);
|
||||
}
|
||||
float3 lightDir = normalize(lightPos - pos);
|
||||
float3 reflectDir = reflect(lightDir, n);
|
||||
|
||||
float3 color = light.Color.xyz;
|
||||
float spec = pow(saturate(dot(CamDirectionWS.xyz, reflectDir)), strength * 64);
|
||||
float attenuation = (radius - dist) / radius;
|
||||
return attenuation * spec * color;
|
||||
float dist = distance(lightPos, pos);
|
||||
if (dist > radius)
|
||||
return float3(0, 0, 0);
|
||||
else
|
||||
{
|
||||
float3 lightDir = normalize(lightPos - pos);
|
||||
float3 reflectDir = reflect(lightDir, n);
|
||||
|
||||
float3 color = light.Color.xyz;
|
||||
float spec = pow(saturate(dot(CamDirectionWS.xyz, reflectDir)), strength * SPEC_FACTOR);
|
||||
float attenuation = (radius - dist) / radius;
|
||||
return attenuation * spec * color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float3 DoSpecularSun(float3 n, ShaderLight light, float strength)
|
||||
{
|
||||
if (!(strength > 0.0))
|
||||
{
|
||||
return float3(0, 0, 0);
|
||||
}
|
||||
float3 lightDir = normalize(light.Direction);
|
||||
float3 reflectDir = reflect(lightDir, n);
|
||||
float3 color = light.Color.xyz;
|
||||
float spec = pow(saturate(dot(CamDirectionWS.xyz, reflectDir)), strength * 64);
|
||||
return spec * color;
|
||||
if (strength <= 0.0)
|
||||
return float3(0, 0, 0);
|
||||
else
|
||||
{
|
||||
float3 lightDir = normalize(light.Direction);
|
||||
float3 reflectDir = reflect(lightDir, n);
|
||||
float3 color = light.Color.xyz;
|
||||
float spec = pow(saturate(dot(CamDirectionWS.xyz, reflectDir)), strength * SPEC_FACTOR);
|
||||
return spec * color;
|
||||
}
|
||||
}
|
||||
|
||||
float3 DoSpecularSpot(float3 pos, float3 n, ShaderLight light, float strength)
|
||||
{
|
||||
if (!(strength > 0.0))
|
||||
{
|
||||
return float3(0, 0, 0);
|
||||
}
|
||||
float3 lightPos = light.Position.xyz;
|
||||
float radius = light.Range;
|
||||
if (strength <= 0.0)
|
||||
return float3(0, 0, 0);
|
||||
else
|
||||
{
|
||||
float3 lightPos = light.Position.xyz;
|
||||
float radius = light.OutRange;
|
||||
|
||||
float dist = distance(lightPos, pos);
|
||||
if (dist > radius)
|
||||
{
|
||||
return float3(0, 0, 0);
|
||||
}
|
||||
float3 lightDir = normalize(lightPos - pos);
|
||||
float3 reflectDir = reflect(lightDir, n);
|
||||
|
||||
float3 color = light.Color.xyz;
|
||||
float spec = pow(saturate(dot(CamDirectionWS.xyz, reflectDir)), strength * 64);
|
||||
float attenuation = (radius - dist) / radius;
|
||||
return attenuation * spec * color;
|
||||
float dist = distance(lightPos, pos);
|
||||
if (dist > radius)
|
||||
return float3(0, 0, 0);
|
||||
else
|
||||
{
|
||||
float3 lightDir = normalize(lightPos - pos);
|
||||
float3 reflectDir = reflect(lightDir, n);
|
||||
|
||||
float3 color = light.Color.xyz;
|
||||
float spec = pow(saturate(dot(CamDirectionWS.xyz, reflectDir)), strength * SPEC_FACTOR);
|
||||
float attenuation = (radius - dist) / radius;
|
||||
return attenuation * spec * color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float3 DoPointLight(float3 pos, float3 n, ShaderLight light)
|
||||
{
|
||||
float3 lightPos = light.Position.xyz;
|
||||
float3 color = light.Color.xyz;
|
||||
float intensity = light.Intensity;
|
||||
float radius = light.Out;
|
||||
|
||||
float3 lightVec = (lightPos - pos);
|
||||
float distance = length(lightVec);
|
||||
|
||||
if (distance > radius)
|
||||
{
|
||||
return float3(0, 0, 0);
|
||||
else
|
||||
{
|
||||
lightVec = normalize(lightVec);
|
||||
float d = saturate(dot(n, lightVec));
|
||||
float attenuation = ((radius - distance) / radius);
|
||||
|
||||
return saturate(color * intensity * attenuation * d);
|
||||
}
|
||||
|
||||
lightVec = normalize(lightVec);
|
||||
float d = saturate(dot(n, lightVec));
|
||||
|
||||
float attenuation = ((radius - distance) / radius);
|
||||
|
||||
return (color * attenuation * d);
|
||||
}
|
||||
|
||||
float3 DoSpotLight(float3 pos, float3 n, ShaderLight light)
|
||||
{
|
||||
float3 lightPos = light.Position.xyz;
|
||||
float3 color = light.Color.xyz;
|
||||
float3 direction = -light.Direction.xyz;
|
||||
float range = light.Range;
|
||||
float inAngle = light.In;
|
||||
float outAngle = light.Out;
|
||||
float intensity = light.Intensity;
|
||||
float3 direction = -light.Direction.xyz;;
|
||||
float innerRange = light.In;
|
||||
float outerRange = light.Out;
|
||||
float coneIn = light.InRange;
|
||||
float coneOut = light.OutRange;
|
||||
|
||||
float3 lightVec = (lightPos - pos);
|
||||
float distance = length(lightVec);
|
||||
|
||||
if (distance > range)
|
||||
{
|
||||
if (distance > outerRange)
|
||||
return float3(0, 0, 0);
|
||||
}
|
||||
|
||||
lightVec = normalize(lightVec);
|
||||
float inCone = acos(dot(lightVec, direction));
|
||||
|
||||
if (inCone < outAngle)
|
||||
else
|
||||
{
|
||||
return float3(0, 0, 0);
|
||||
lightVec = normalize(lightVec);
|
||||
|
||||
float d = saturate(dot(n, lightVec));
|
||||
if (d < 0)
|
||||
return float3(0, 0, 0);
|
||||
else
|
||||
{
|
||||
float cosine = dot(-lightVec, direction);
|
||||
|
||||
float minCosineIn = cos(coneIn * (PI / 180.0f));
|
||||
float attenuationIn = max((cosine - minCosineIn), 0.0f) / (1.0f - minCosineIn);
|
||||
|
||||
float minCosineOut = cos(coneOut * (PI / 180.0f));
|
||||
float attenuationOut = max((cosine - minCosineOut), 0.0f) / (1.0f - minCosineOut);
|
||||
|
||||
float attenuation = saturate(attenuationIn * 2.0f + attenuationOut);
|
||||
|
||||
if (attenuation > 0.0f)
|
||||
{
|
||||
float falloff = saturate((outerRange - distance) / (outerRange - innerRange + 1.0f));
|
||||
return saturate(color * intensity * attenuation * falloff * d);
|
||||
}
|
||||
else
|
||||
return float3(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
float attenuation = 1;
|
||||
|
||||
float d = saturate(dot(n, lightVec));
|
||||
if (d < 0)
|
||||
{
|
||||
return float3(0, 0, 0);
|
||||
}
|
||||
|
||||
return (color * attenuation * d);
|
||||
}
|
||||
|
||||
float3 DoDirectionalLight(float3 pos, float3 n, ShaderLight light)
|
||||
|
@ -148,10 +169,54 @@ float3 DoDirectionalLight(float3 pos, float3 n, ShaderLight light)
|
|||
direction = normalize(direction);
|
||||
|
||||
float d = dot(n, direction);
|
||||
|
||||
if (d < 0)
|
||||
{
|
||||
return float3(0, 0, 0);
|
||||
else
|
||||
return (color * d);
|
||||
}
|
||||
|
||||
float Luma(float3 color)
|
||||
{
|
||||
// Use Rec.709 trichromat formula to get perceptive luma value
|
||||
return float((color.x * 0.2126f) + (color.y * 0.7152f) + (color.z * 0.0722f));
|
||||
}
|
||||
|
||||
float3 CombineLights(float3 ambient, float3 vertex, float3 tex, float3 pos, float3 normal, float sheen)
|
||||
{
|
||||
float3 ambTex = ambient * tex;
|
||||
|
||||
float3 diffuse = 0;
|
||||
float3 spec = 0;
|
||||
|
||||
for (int i = 0; i < NumLights; i++)
|
||||
{
|
||||
int lightType = Lights[i].Type;
|
||||
|
||||
if (lightType == LT_POINT || lightType == LT_SHADOW)
|
||||
{
|
||||
diffuse += DoPointLight(pos, normal, Lights[i]);
|
||||
spec += DoSpecularPoint(pos, normal, Lights[i], sheen);
|
||||
}
|
||||
else if (lightType == LT_SUN)
|
||||
{
|
||||
diffuse += DoDirectionalLight(pos, normal, Lights[i]);
|
||||
spec += DoSpecularSun(normal, Lights[i], sheen);
|
||||
}
|
||||
else if (lightType == LT_SPOT)
|
||||
{
|
||||
diffuse += DoSpotLight(pos, normal, Lights[i]);
|
||||
spec += DoSpecularSpot(pos, normal, Lights[i], sheen);
|
||||
}
|
||||
}
|
||||
|
||||
return (color * d);
|
||||
diffuse.xyz *= tex.xyz;
|
||||
float3 combined = ambTex + diffuse + spec;
|
||||
|
||||
return saturate(combined * vertex);
|
||||
}
|
||||
|
||||
float3 StaticLight(float3 ambient, float3 vertex, float3 tex)
|
||||
{
|
||||
return saturate(ambient * tex * vertex);
|
||||
}
|
37
TombEngine/Shaders/VertexEffects.hlsli
Normal file
37
TombEngine/Shaders/VertexEffects.hlsli
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include "./Math.hlsli"
|
||||
|
||||
#define WIBBLE_FRAME_PERIOD 64.0f
|
||||
|
||||
float Wibble(float3 effect, int hash)
|
||||
{
|
||||
if (effect.x > 0.0f || effect.y > 0.0f)
|
||||
return sin((((Frame + hash) % 256) / WIBBLE_FRAME_PERIOD) * (PI2));
|
||||
else
|
||||
return 0.0f; // Don't calculate if not necessary
|
||||
}
|
||||
|
||||
float3 Glow(float3 color, float3 effect, float wibble)
|
||||
{
|
||||
float3 col = color;
|
||||
|
||||
if (effect.x > 0.0f)
|
||||
{
|
||||
float intensity = effect.x * lerp(-0.5f, 1.0f, wibble * 0.5f + 0.5f);
|
||||
col = color + float3(intensity, intensity, intensity);
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
float3 Move(float3 position, float3 effect, float wibble)
|
||||
{
|
||||
float3 pos = position;
|
||||
float weight = effect.z;
|
||||
|
||||
if (effect.y > 0.0f && weight > 0.0f)
|
||||
{
|
||||
pos.y += wibble * effect.y * weight * 128.0f; // 128 units offset to top and bottom (256 total)
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
|
@ -4,7 +4,7 @@ struct VertexShaderInput {
|
|||
float2 UV: TEXCOORD0;
|
||||
float4 Color: COLOR0;
|
||||
float3 Tangent: TANGENT0;
|
||||
float3 Bitangent: BITANGENT0;
|
||||
uint AnimationFrameOffset: ANIMATIONFRAMEOFFSET;
|
||||
float4 Effects: EFFECTS;
|
||||
float Bone: BLENDINDICES;
|
||||
uint PolyIndex : POLYINDEX;
|
||||
|
|
|
@ -442,17 +442,33 @@ namespace TEN::Input
|
|||
{
|
||||
// Switch debug pages
|
||||
|
||||
static int debugTimeout = 0;
|
||||
static bool rawDebounce1 = false;
|
||||
if (KeyMap[KC_F10] || KeyMap[KC_F11])
|
||||
{
|
||||
if (debugTimeout == 0)
|
||||
if (!rawDebounce1)
|
||||
{
|
||||
debugTimeout = 1;
|
||||
rawDebounce1 = true;
|
||||
g_Renderer.SwitchDebugPage(KeyMap[KC_F10]);
|
||||
}
|
||||
}
|
||||
else
|
||||
debugTimeout = 0;
|
||||
rawDebounce1 = false;
|
||||
|
||||
// Toggle full screen
|
||||
|
||||
static bool rawDebounce2 = false;
|
||||
if ((KeyMap[KC_LMENU] || KeyMap[KC_RMENU]) && KeyMap[KC_RETURN])
|
||||
{
|
||||
if (!rawDebounce2)
|
||||
{
|
||||
rawDebounce2 = true;
|
||||
g_Configuration.Windowed = !g_Configuration.Windowed;
|
||||
SaveConfiguration();
|
||||
g_Renderer.ToggleFullScreen();
|
||||
}
|
||||
}
|
||||
else
|
||||
rawDebounce2 = false;
|
||||
|
||||
// Handle flares
|
||||
|
||||
|
|
|
@ -111,6 +111,18 @@ void ReadBytes(void* dest, int count)
|
|||
LevelDataPtr += count;
|
||||
}
|
||||
|
||||
std::string ReadString()
|
||||
{
|
||||
byte numBytes = ReadInt8(); // FIXME: incorrect, should be read in LEB128 format
|
||||
|
||||
if (!numBytes)
|
||||
return std::string();
|
||||
|
||||
char buffer[255];
|
||||
ReadBytes(buffer, numBytes);
|
||||
return std::string(buffer, buffer + numBytes);
|
||||
}
|
||||
|
||||
void LoadItems()
|
||||
{
|
||||
g_Level.NumItems = ReadInt32();
|
||||
|
@ -139,11 +151,7 @@ void LoadItems()
|
|||
item->Color = ReadVector4();
|
||||
item->TriggerFlags = ReadInt16();
|
||||
item->Flags = ReadInt16();
|
||||
|
||||
byte numBytes = ReadInt8();
|
||||
char buffer[255];
|
||||
ReadBytes(buffer, numBytes);
|
||||
item->LuaName = std::string(buffer, buffer + numBytes);
|
||||
item->LuaName = ReadString();
|
||||
|
||||
g_GameScriptEntities->AddName(item->LuaName, i);
|
||||
g_GameScriptEntities->TryAddColliding(i);
|
||||
|
@ -169,7 +177,7 @@ void LoadObjects()
|
|||
{
|
||||
MESH mesh;
|
||||
|
||||
mesh.LightMode = ReadInt8();
|
||||
mesh.lightMode = ReadInt8();
|
||||
|
||||
mesh.sphere.Center.x = ReadFloat();
|
||||
mesh.sphere.Center.y = ReadFloat();
|
||||
|
@ -384,11 +392,7 @@ void LoadCameras()
|
|||
camera.roomNumber = ReadInt32();
|
||||
camera.flags = ReadInt32();
|
||||
camera.speed = ReadInt32();
|
||||
|
||||
byte numBytes = ReadInt8();
|
||||
char buffer[255];
|
||||
ReadBytes(buffer, numBytes);
|
||||
camera.luaName = std::string(buffer, buffer + numBytes);
|
||||
camera.luaName = ReadString();
|
||||
|
||||
g_GameScriptEntities->AddName(camera.luaName, camera);
|
||||
}
|
||||
|
@ -641,14 +645,14 @@ void ReadRooms()
|
|||
ROOM_DOOR door;
|
||||
|
||||
door.room = ReadInt16();
|
||||
door.normal.x = ReadInt16();
|
||||
door.normal.y = ReadInt16();
|
||||
door.normal.z = ReadInt16();
|
||||
door.normal.x = ReadInt32();
|
||||
door.normal.y = ReadInt32();
|
||||
door.normal.z = ReadInt32();
|
||||
for (int k = 0; k < 4; k++)
|
||||
{
|
||||
door.vertices[k].x = ReadInt16();
|
||||
door.vertices[k].y = ReadInt16();
|
||||
door.vertices[k].z = ReadInt16();
|
||||
door.vertices[k].x = ReadInt32();
|
||||
door.vertices[k].y = ReadInt32();
|
||||
door.vertices[k].z = ReadInt32();
|
||||
}
|
||||
|
||||
room.doors.push_back(door);
|
||||
|
@ -748,11 +752,7 @@ void ReadRooms()
|
|||
mesh.color = ReadVector4();
|
||||
mesh.staticNumber = ReadUInt16();
|
||||
mesh.HitPoints = ReadInt16();
|
||||
|
||||
byte numBytes = ReadInt8();
|
||||
char buffer[255];
|
||||
ReadBytes(buffer, numBytes);
|
||||
mesh.luaName = std::string(buffer, buffer + numBytes);
|
||||
mesh.luaName = ReadString();
|
||||
|
||||
g_GameScriptEntities->AddName(mesh.luaName, mesh);
|
||||
}
|
||||
|
@ -986,7 +986,7 @@ void LoadAIObjects()
|
|||
obj.triggerFlags = ReadInt16();
|
||||
obj.flags = ReadInt16();
|
||||
obj.yRot = ReadInt16();
|
||||
obj.boxNumber = ReadInt16();
|
||||
obj.boxNumber = ReadInt32();
|
||||
|
||||
byte numBytes = ReadInt8();
|
||||
char buffer[255];
|
||||
|
@ -1003,13 +1003,7 @@ void LoadLuaFunctionNames()
|
|||
|
||||
int luaFunctionsCount = ReadInt32();
|
||||
for (int i = 0; i < luaFunctionsCount; i++)
|
||||
{
|
||||
byte numBytes = ReadInt8();
|
||||
char buffer[255];
|
||||
ReadBytes(buffer, numBytes);
|
||||
auto luaFunctionName = std::string(buffer, buffer + numBytes);
|
||||
g_Level.LuaFunctionNames.push_back(luaFunctionName);
|
||||
}
|
||||
g_Level.LuaFunctionNames.push_back(ReadString());
|
||||
}
|
||||
|
||||
FILE* FileOpen(const char* fileName)
|
||||
|
|
|
@ -72,7 +72,7 @@ struct AI_OBJECT
|
|||
short triggerFlags;
|
||||
short flags;
|
||||
short yRot;
|
||||
short boxNumber;
|
||||
int boxNumber;
|
||||
std::string luaName;
|
||||
};
|
||||
|
||||
|
@ -91,7 +91,7 @@ struct SPRITE
|
|||
|
||||
struct MESH
|
||||
{
|
||||
byte LightMode;
|
||||
int lightMode;
|
||||
BoundingSphere sphere;
|
||||
std::vector<Vector3> positions;
|
||||
std::vector<Vector3> normals;
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#include "framework.h"
|
||||
#include "phd_global.h"
|
||||
|
||||
const Vector2Int Vector2Int::Zero = Vector2Int(0, 0);
|
||||
const Vector3Int Vector3Int::Zero = Vector3Int(0, 0, 0);
|
||||
const Vector3Shrt Vector3Shrt::Zero = Vector3Shrt(0, 0, 0);
|
||||
|
||||
BOUNDING_BOX operator+(BOUNDING_BOX const & box, PHD_3DPOS const & vec)
|
||||
{
|
||||
BOUNDING_BOX box2 = box;
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
// TODO: Possibly rename these vector structs to more common standards later:
|
||||
// Vector2i, Vector3i, Vector3s. -- Sezz 2022.07.23
|
||||
struct Vector2Int
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
||||
static const Vector2Int Zero;
|
||||
|
||||
Vector2Int()
|
||||
{
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
*this = Vector2Int::Zero;
|
||||
}
|
||||
|
||||
Vector2Int(int x, int y)
|
||||
|
@ -24,6 +27,25 @@ struct Vector3Int
|
|||
int y;
|
||||
int z;
|
||||
|
||||
static const Vector3Int Zero;
|
||||
|
||||
Vector3Int()
|
||||
{
|
||||
*this = Vector3Int::Zero;
|
||||
}
|
||||
|
||||
Vector3Int(int x, int y, int z)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
Vector3 ToVector3()
|
||||
{
|
||||
return Vector3(x, y, z);
|
||||
}
|
||||
|
||||
bool operator ==(Vector3Int vector)
|
||||
{
|
||||
return (x == vector.x && y == vector.y && z == vector.z);
|
||||
|
@ -96,15 +118,22 @@ struct Vector3Int
|
|||
*this = *this / value;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
Vector3Int()
|
||||
struct Vector3Shrt
|
||||
{
|
||||
short x;
|
||||
short y;
|
||||
short z;
|
||||
|
||||
static const Vector3Shrt Zero;
|
||||
|
||||
Vector3Shrt()
|
||||
{
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
this->z = 0;
|
||||
*this = Vector3Shrt::Zero;
|
||||
}
|
||||
|
||||
Vector3Int(int x, int y, int z)
|
||||
Vector3Shrt(short x, short y, short z)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
|
@ -122,13 +151,6 @@ struct Vector3Int
|
|||
{
|
||||
return Vector3(x, y, z);
|
||||
}
|
||||
};
|
||||
|
||||
struct Vector3Shrt
|
||||
{
|
||||
short x;
|
||||
short y;
|
||||
short z;
|
||||
|
||||
bool operator ==(Vector3Shrt vector)
|
||||
{
|
||||
|
@ -202,25 +224,6 @@ struct Vector3Shrt
|
|||
*this = *this / value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector3Shrt()
|
||||
{
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
this->z = 0;
|
||||
}
|
||||
|
||||
Vector3Shrt(short x, short y, short z)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
Vector3 ToVector3()
|
||||
{
|
||||
return Vector3(x, y, z);
|
||||
}
|
||||
};
|
||||
|
||||
struct RendererRectangle
|
||||
|
@ -247,38 +250,40 @@ struct RendererRectangle
|
|||
}
|
||||
};
|
||||
|
||||
// TODO: Rename to PoseData (or something else that specifically describes a position + orientation representation, if we prefer).
|
||||
// This struct has changed vastly and the old name is no longer appropriate. -- Sezz 2022.07.23
|
||||
struct PHD_3DPOS
|
||||
{
|
||||
Vector3Int Position;
|
||||
Vector3Int Position;
|
||||
Vector3Shrt Orientation;
|
||||
|
||||
PHD_3DPOS()
|
||||
{
|
||||
this->Position = Vector3Int();
|
||||
this->Orientation = Vector3Shrt();
|
||||
this->Position = Vector3Int::Zero;
|
||||
this->Orientation = Vector3Shrt::Zero;
|
||||
}
|
||||
|
||||
PHD_3DPOS(Vector3Int pos)
|
||||
{
|
||||
this->Position = pos;
|
||||
this->Orientation = Vector3Shrt();
|
||||
this->Orientation = Vector3Shrt::Zero;
|
||||
}
|
||||
|
||||
PHD_3DPOS(int xPos, int yPos, int zPos)
|
||||
{
|
||||
this->Position = Vector3Int(xPos, yPos, zPos);
|
||||
this->Orientation = Vector3Shrt();
|
||||
this->Orientation = Vector3Shrt::Zero;
|
||||
}
|
||||
|
||||
PHD_3DPOS(Vector3Shrt orient)
|
||||
{
|
||||
this->Position = Vector3Int();
|
||||
this->Position = Vector3Int::Zero;
|
||||
this->Orientation = orient;
|
||||
}
|
||||
|
||||
PHD_3DPOS(short xOrient, short yOrient, short zOrient)
|
||||
{
|
||||
this->Position = Vector3Int();
|
||||
this->Position = Vector3Int::Zero;
|
||||
this->Orientation = Vector3Shrt(xOrient, yOrient, zOrient);
|
||||
}
|
||||
|
||||
|
|
|
@ -286,6 +286,12 @@ const float Smoothstep(float edge0, float edge1, float x)
|
|||
return x * x * (3 - 2 * x);
|
||||
}
|
||||
|
||||
const float Luma(Vector3 color)
|
||||
{
|
||||
// Use Rec.709 trichromat formula to get perceptive luma value
|
||||
return (float)((color.x * 0.2126f) + (color.y * 0.7152f) + (color.z * 0.0722f));
|
||||
}
|
||||
|
||||
Vector3 TranslateVector(Vector3 vector, short angle, float forward, float up, float right)
|
||||
{
|
||||
if (forward == 0.0f && up == 0.0f && right == 0.0f)
|
||||
|
|
|
@ -16,9 +16,9 @@ constexpr auto WADE_DEPTH = STEPUP_HEIGHT;
|
|||
constexpr auto SHALLOW_WATER_START_LEVEL = STEP_SIZE / 4;
|
||||
constexpr auto BAD_JUMP_CEILING = ((STEP_SIZE * 3) / 4);
|
||||
constexpr auto SLOPE_DIFFERENCE = 60;
|
||||
constexpr auto NO_HEIGHT = (-0x7F00);
|
||||
constexpr auto MAX_HEIGHT = (-0x7FFF);
|
||||
constexpr auto DEEP_WATER = 0x7FFF;
|
||||
constexpr auto NO_HEIGHT = INT_MIN + UCHAR_MAX;
|
||||
constexpr auto MAX_HEIGHT = INT_MIN + 1; // Add 1 to prevent issue with sign changes
|
||||
constexpr auto DEEP_WATER = INT_MAX - 1; // Subtract 1 to prevent issue with sign changes
|
||||
|
||||
constexpr auto SQUARE = [](auto x) { return x * x; };
|
||||
constexpr auto CLICK = [](auto x) { return STEP_SIZE * x; };
|
||||
|
@ -68,6 +68,7 @@ Vector3Int* FP_Normalise(Vector3Int* v);
|
|||
|
||||
const float Lerp(float v0, float v1, float t);
|
||||
const float Smoothstep(float edge0, float edge1, float x);
|
||||
const float Luma(Vector3 color);
|
||||
|
||||
Vector3 TranslateVector(Vector3 vector, short angle, float forward, float up = 0.0f, float right = 0.0f);
|
||||
Vector3Int TranslateVector(Vector3Int vector, short angle, float forward, float up = 0.0f, float right = 0.0f);
|
||||
|
|
43
TombEngine/Specific/trutils.cpp
Normal file
43
TombEngine/Specific/trutils.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include "framework.h"
|
||||
#include "Specific/trutils.h"
|
||||
|
||||
#include <codecvt>
|
||||
|
||||
namespace TEN::Utils
|
||||
{
|
||||
std::string ToLower(std::string source)
|
||||
{
|
||||
std::transform(source.begin(), source.end(), source.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||
return source;
|
||||
}
|
||||
|
||||
std::string FromWchar(wchar_t* source)
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
|
||||
return converter.to_bytes(std::wstring(source));
|
||||
}
|
||||
|
||||
std::vector<std::string> SplitString(const std::string& source)
|
||||
{
|
||||
std::vector<std::string> strings;
|
||||
|
||||
// String is single-line, early exit
|
||||
if (source.find('\n') == std::string::npos)
|
||||
{
|
||||
strings.push_back(source);
|
||||
return strings;
|
||||
}
|
||||
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type prev = 0;
|
||||
while ((pos = source.find('\n', prev)) != std::string::npos)
|
||||
{
|
||||
strings.push_back(source.substr(prev, pos - prev));
|
||||
prev = pos + 1;
|
||||
}
|
||||
|
||||
strings.push_back(source.substr(prev));
|
||||
|
||||
return strings;
|
||||
}
|
||||
}
|
9
TombEngine/Specific/trutils.h
Normal file
9
TombEngine/Specific/trutils.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace TEN::Utils
|
||||
{
|
||||
std::string ToLower(std::string source);
|
||||
std::string FromWchar(wchar_t* source);
|
||||
std::vector<std::string> SplitString(const std::string& source);
|
||||
}
|
|
@ -14,6 +14,7 @@
|
|||
#include "Sound/sound.h"
|
||||
#include "Specific/level.h"
|
||||
#include "Specific/configuration.h"
|
||||
#include "Specific/trutils.h"
|
||||
#include "LanguageScript.h"
|
||||
#include "ScriptInterfaceState.h"
|
||||
#include "ScriptInterfaceLevel.h"
|
||||
|
@ -46,6 +47,12 @@ extern "C"
|
|||
string commit;
|
||||
#endif
|
||||
|
||||
bool ArgEquals(wchar_t* incomingArg, std::string name)
|
||||
{
|
||||
auto lowerArg = TEN::Utils::ToLower(TEN::Utils::FromWchar(incomingArg));
|
||||
return (lowerArg == "-" + name) || (lowerArg == "/" + name);
|
||||
}
|
||||
|
||||
Vector2Int GetScreenResolution()
|
||||
{
|
||||
RECT desktop;
|
||||
|
@ -150,16 +157,7 @@ LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Manually handle ALT + ENTER toggle fullscreen
|
||||
if ((msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN)
|
||||
&& wParam == VK_RETURN
|
||||
&& (HIWORD(lParam) & KF_ALTDOWN))
|
||||
{
|
||||
g_Renderer.ToggleFullScreen();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (msg > 0x10)
|
||||
if (msg > WM_CLOSE)
|
||||
{
|
||||
if (msg == WM_COMMAND)
|
||||
HandleWmCommand((unsigned short)wParam);
|
||||
|
@ -188,6 +186,9 @@ LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
{
|
||||
if ((signed int)(unsigned short)wParam > 0 && (signed int)(unsigned short)wParam <= 2)
|
||||
{
|
||||
if (!g_Configuration.Windowed)
|
||||
g_Renderer.ToggleFullScreen(true);
|
||||
|
||||
if (!Debug && ThreadHandle > 0)
|
||||
{
|
||||
TENLog("Resuming game thread", LogLevel::Info);
|
||||
|
@ -200,6 +201,9 @@ LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!g_Configuration.Windowed)
|
||||
ShowWindow(hWnd, SW_MINIMIZE);
|
||||
|
||||
if (!Debug)
|
||||
{
|
||||
TENLog("Suspending game thread", LogLevel::Info);
|
||||
|
@ -228,26 +232,31 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||
// Parse command line arguments
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
if (wcscmp(argv[i], L"/setup") == 0)
|
||||
if (ArgEquals(argv[i], "setup"))
|
||||
{
|
||||
setup = true;
|
||||
}
|
||||
else if (wcscmp(argv[i], L"/debug") == 0)
|
||||
else if (ArgEquals(argv[i], "debug"))
|
||||
{
|
||||
Debug = true;
|
||||
}
|
||||
else if ((wcscmp(argv[i], L"/level") == 0) && argc > (i + 1))
|
||||
else if (ArgEquals(argv[i], "level") && argc > (i + 1))
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
|
||||
levelFile = converter.to_bytes(std::wstring(argv[i + 1]));
|
||||
levelFile = TEN::Utils::FromWchar(argv[i + 1]);
|
||||
}
|
||||
else if ((wcscmp(argv[i], L"/hash") == 0) && argc > (i + 1))
|
||||
else if (ArgEquals(argv[i], "hash") && argc > (i + 1))
|
||||
{
|
||||
SystemNameHash = std::stoul(std::wstring(argv[i + 1]));
|
||||
}
|
||||
}
|
||||
LocalFree(argv);
|
||||
|
||||
// Hide console window if mode isn't debug
|
||||
#ifndef _DEBUG
|
||||
if (!Debug)
|
||||
ShowWindow(GetConsoleWindow(), 0);
|
||||
#endif
|
||||
|
||||
// Clear Application Structure
|
||||
memset(&App, 0, sizeof(WINAPP));
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)Build\$(Configuration)\</OutDir>
|
||||
<ExecutablePath>$(ExecutablePath);$(DXSDK_DIR)Utilities\bin\x86</ExecutablePath>
|
||||
<IncludePath>$(SolutionDir)Libs;$(SolutionDir)Libs\lua;$(SolutionDir)Libs\sol;$(SolutionDir)Libs\zlib;$(SolutionDir)Libs\spdlog;$(SolutionDir)Libs\ois;$(SolutionDir)Libs\bass;$(IncludePath)</IncludePath>
|
||||
|
@ -52,7 +52,7 @@
|
|||
<TargetExt>.exe</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(ProjectDir)..\Build\$(Configuration)\</OutDir>
|
||||
<ExecutablePath>$(ExecutablePath);$(DXSDK_DIR)Utilities\bin\x86</ExecutablePath>
|
||||
<IncludePath>$(SolutionDir)Libs;$(SolutionDir)Libs\lua;$(SolutionDir)Libs\sol;$(SolutionDir)Libs\ois;$(SolutionDir)Libs\spdlog;$(SolutionDir)Libs\zlib;$(SolutionDir)Libs\bass;$(IncludePath)</IncludePath>
|
||||
|
@ -85,6 +85,7 @@
|
|||
<AdditionalDependencies>comctl32.lib;lua53.lib;bass.lib;bassmix.lib;bass_fx.lib;D3DCompiler.lib;dxgi.lib;dxguid.lib;d3d11.lib;zlib.lib;spdlogd.lib;OIS_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<LargeAddressAware>true</LargeAddressAware>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
|
@ -128,7 +129,7 @@ xcopy /Y "$(ProjectDir)Shaders\HUD\*.hlsl" "$(TargetDir)\Shaders\HUD\"</Command>
|
|||
<DisableSpecificWarnings>4244;5051;4018;4554;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalLibraryDirectories>C:\Program Files %28x86%29\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.15.26726\lib\onecore\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
|
@ -136,6 +137,7 @@ xcopy /Y "$(ProjectDir)Shaders\HUD\*.hlsl" "$(TargetDir)\Shaders\HUD\"</Command>
|
|||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<LargeAddressAware>true</LargeAddressAware>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>md "$(TargetDir)\Shaders"
|
||||
|
@ -578,6 +580,7 @@ CALL gen.bat</Command>
|
|||
<ClInclude Include="Specific\setup.h" />
|
||||
<ClInclude Include="Specific\clock.h" />
|
||||
<ClInclude Include="Specific\trmath.h" />
|
||||
<ClInclude Include="Specific\trutils.h" />
|
||||
<ClInclude Include="Specific\winmain.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="Objects\TR5\Object\tr5_genslot.h" />
|
||||
|
@ -919,6 +922,7 @@ CALL gen.bat</Command>
|
|||
<ClCompile Include="Specific\IO\Streams.cpp" />
|
||||
<ClCompile Include="Specific\level.cpp" />
|
||||
<ClCompile Include="Specific\setup.cpp" />
|
||||
<ClCompile Include="Specific\trutils.cpp" />
|
||||
<ClCompile Include="Specific\winmain.cpp" />
|
||||
<ClCompile Include="Objects\TR5\Object\tr5_genslot.cpp" />
|
||||
<ClCompile Include="Renderer\VertexBuffer\VertexBuffer.cpp" />
|
||||
|
@ -944,6 +948,7 @@ CALL gen.bat</Command>
|
|||
<None Include="Shaders\Math.hlsli">
|
||||
<DeploymentContent>true</DeploymentContent>
|
||||
</None>
|
||||
<None Include="Shaders\VertexEffects.hlsli" />
|
||||
<None Include="Shaders\VertexInput.hlsli">
|
||||
<DeploymentContent>true</DeploymentContent>
|
||||
</None>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue