mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-30 16:57:57 +03:00
Improve handling in swamps
This commit is contained in:
parent
4199b296de
commit
b8cde31501
2 changed files with 81 additions and 76 deletions
|
@ -34,16 +34,10 @@ constexpr auto COLL_CANCEL_THRESHOLD = BLOCK(2);
|
||||||
constexpr auto COLL_DISCARD_THRESHOLD = CLICK(0.5f);
|
constexpr auto COLL_DISCARD_THRESHOLD = CLICK(0.5f);
|
||||||
constexpr auto CAMERA_RADIUS = CLICK(1);
|
constexpr auto CAMERA_RADIUS = CLICK(1);
|
||||||
|
|
||||||
constexpr auto LOOKCAM_TURN_RATE_ACCEL = ANGLE(0.75f);
|
|
||||||
constexpr auto LOOKCAM_TURN_RATE_MAX = ANGLE(4.0f);
|
|
||||||
|
|
||||||
constexpr auto LOOKCAM_ORIENT_CONSTRAINT = std::pair<EulerAngles, EulerAngles>(
|
constexpr auto LOOKCAM_ORIENT_CONSTRAINT = std::pair<EulerAngles, EulerAngles>(
|
||||||
EulerAngles(ANGLE(-70.0f), ANGLE(-90.0f), 0),
|
EulerAngles(ANGLE(-70.0f), ANGLE(-90.0f), 0),
|
||||||
EulerAngles(ANGLE(60.0f), ANGLE(90.0f), 0));
|
EulerAngles(ANGLE(60.0f), ANGLE(90.0f), 0));
|
||||||
|
|
||||||
constexpr auto THUMBCAM_VERTICAL_CONSTRAINT_ANGLE = ANGLE(120.0f);
|
|
||||||
constexpr auto THUMBCAM_HORIZONTAL_CONSTRAINT_ANGLE = ANGLE(80.0f);
|
|
||||||
|
|
||||||
struct OLD_CAMERA
|
struct OLD_CAMERA
|
||||||
{
|
{
|
||||||
short ActiveState;
|
short ActiveState;
|
||||||
|
@ -94,58 +88,7 @@ float CinematicBarsHeight = 0;
|
||||||
float CinematicBarsDestinationHeight = 0;
|
float CinematicBarsDestinationHeight = 0;
|
||||||
float CinematicBarsSpeed = 0;
|
float CinematicBarsSpeed = 0;
|
||||||
|
|
||||||
void DoLookAround(ItemInfo& item, bool invertVerticalAxis)
|
static void ClearLookAroundActions(const ItemInfo& item)
|
||||||
{
|
|
||||||
auto& player = GetLaraInfo(item);
|
|
||||||
|
|
||||||
Camera.type = CameraType::Look;
|
|
||||||
|
|
||||||
// Determine vertical axis coefficient.
|
|
||||||
float vAxisCoeff = 0.0f;
|
|
||||||
if ((IsHeld(In::Forward) || IsHeld(In::Back)) &&
|
|
||||||
(player.Control.Look.Mode == LookMode::Vertical || player.Control.Look.Mode == LookMode::Free))
|
|
||||||
{
|
|
||||||
vAxisCoeff = AxisMap[InputAxis::MoveVertical];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine horizontal axis coefficient.
|
|
||||||
float hAxisCoeff = 0.0f;
|
|
||||||
if ((IsHeld(In::Left) || IsHeld(In::Right)) &&
|
|
||||||
(player.Control.Look.Mode == LookMode::Horizontal || player.Control.Look.Mode == LookMode::Free))
|
|
||||||
{
|
|
||||||
hAxisCoeff = AxisMap[InputAxis::MoveHorizontal];
|
|
||||||
}
|
|
||||||
|
|
||||||
short turnRateMax = LOOKCAM_TURN_RATE_MAX;
|
|
||||||
if (BinocularRange)
|
|
||||||
turnRateMax *= (BinocularRange - ANGLE(10.0f)) / ANGLE(17.0f);
|
|
||||||
|
|
||||||
// Modulate turn rates.
|
|
||||||
player.Control.Look.TurnRate = EulerAngles(
|
|
||||||
ModulateLaraTurnRate(player.Control.Look.TurnRate.x, LOOKCAM_TURN_RATE_ACCEL, 0, turnRateMax, vAxisCoeff, invertVerticalAxis),
|
|
||||||
ModulateLaraTurnRate(player.Control.Look.TurnRate.y, LOOKCAM_TURN_RATE_ACCEL, 0, turnRateMax, hAxisCoeff, false),
|
|
||||||
0);
|
|
||||||
|
|
||||||
// Apply turn rates.
|
|
||||||
player.Control.Look.Orientation += player.Control.Look.TurnRate;
|
|
||||||
player.Control.Look.Orientation = EulerAngles(
|
|
||||||
std::clamp(player.Control.Look.Orientation.x, LOOKCAM_ORIENT_CONSTRAINT.first.x, LOOKCAM_ORIENT_CONSTRAINT.second.x),
|
|
||||||
std::clamp(player.Control.Look.Orientation.y, LOOKCAM_ORIENT_CONSTRAINT.first.y, LOOKCAM_ORIENT_CONSTRAINT.second.y),
|
|
||||||
0);
|
|
||||||
|
|
||||||
// Visually adapt head and torso orientations.
|
|
||||||
player.ExtraHeadRot = player.Control.Look.Orientation / 2;
|
|
||||||
if (player.Control.HandStatus != HandStatus::Busy &&
|
|
||||||
!player.LeftArm.Locked && !player.RightArm.Locked &&
|
|
||||||
player.Context.Vehicle == NO_ITEM)
|
|
||||||
{
|
|
||||||
player.ExtraTorsoRot = player.ExtraHeadRot;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearLookAroundActions(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearLookAroundActions(const ItemInfo& item)
|
|
||||||
{
|
{
|
||||||
const auto& player = GetLaraInfo(item);
|
const auto& player = GetLaraInfo(item);
|
||||||
|
|
||||||
|
@ -174,32 +117,90 @@ void ClearLookAroundActions(const ItemInfo& item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DoLookAround(ItemInfo& item, bool invertXAxis)
|
||||||
|
{
|
||||||
|
constexpr auto LOOKCAM_TURN_RATE_ACCEL = ANGLE(0.75f);
|
||||||
|
constexpr auto LOOKCAM_TURN_RATE_MAX = ANGLE(4.0f);
|
||||||
|
|
||||||
|
auto& player = GetLaraInfo(item);
|
||||||
|
|
||||||
|
Camera.type = CameraType::Look;
|
||||||
|
auto axisCoeff = Vector2::Zero;
|
||||||
|
|
||||||
|
// Determine X axis coefficient.
|
||||||
|
if ((IsHeld(In::Forward) || IsHeld(In::Back)) &&
|
||||||
|
(player.Control.Look.Mode == LookMode::Free || player.Control.Look.Mode == LookMode::Vertical))
|
||||||
|
{
|
||||||
|
axisCoeff.x = AxisMap[InputAxis::MoveVertical];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine Y axis coefficient.
|
||||||
|
if ((IsHeld(In::Left) || IsHeld(In::Right)) &&
|
||||||
|
(player.Control.Look.Mode == LookMode::Free || player.Control.Look.Mode == LookMode::Horizontal))
|
||||||
|
{
|
||||||
|
axisCoeff.y = AxisMap[InputAxis::MoveHorizontal];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define turn rate.
|
||||||
|
short turnRateMax = LOOKCAM_TURN_RATE_MAX;
|
||||||
|
if (BinocularRange)
|
||||||
|
turnRateMax *= (BinocularRange - ANGLE(10.0f)) / ANGLE(17.0f);
|
||||||
|
|
||||||
|
// Modulate turn rates.
|
||||||
|
player.Control.Look.TurnRate = EulerAngles(
|
||||||
|
ModulateLaraTurnRate(player.Control.Look.TurnRate.x, LOOKCAM_TURN_RATE_ACCEL, 0, turnRateMax, axisCoeff.x, invertXAxis),
|
||||||
|
ModulateLaraTurnRate(player.Control.Look.TurnRate.y, LOOKCAM_TURN_RATE_ACCEL, 0, turnRateMax, axisCoeff.y, false),
|
||||||
|
0);
|
||||||
|
|
||||||
|
// Apply turn rates.
|
||||||
|
player.Control.Look.Orientation += player.Control.Look.TurnRate;
|
||||||
|
player.Control.Look.Orientation = EulerAngles(
|
||||||
|
std::clamp(player.Control.Look.Orientation.x, LOOKCAM_ORIENT_CONSTRAINT.first.x, LOOKCAM_ORIENT_CONSTRAINT.second.x),
|
||||||
|
std::clamp(player.Control.Look.Orientation.y, LOOKCAM_ORIENT_CONSTRAINT.first.y, LOOKCAM_ORIENT_CONSTRAINT.second.y),
|
||||||
|
0);
|
||||||
|
|
||||||
|
// Visually adapt head and torso orientations.
|
||||||
|
player.ExtraHeadRot = player.Control.Look.Orientation / 2;
|
||||||
|
if (player.Control.HandStatus != HandStatus::Busy &&
|
||||||
|
!player.LeftArm.Locked && !player.RightArm.Locked &&
|
||||||
|
player.Context.Vehicle == NO_ITEM)
|
||||||
|
{
|
||||||
|
player.ExtraTorsoRot = player.ExtraHeadRot;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearLookAroundActions(item);
|
||||||
|
}
|
||||||
|
|
||||||
void DoThumbstickCamera()
|
void DoThumbstickCamera()
|
||||||
{
|
{
|
||||||
|
constexpr auto VERTICAL_CONSTRAINT_ANGLE = ANGLE(120.0f);
|
||||||
|
constexpr auto HORIZONTAL_CONSTRAINT_ANGLE = ANGLE(80.0f);
|
||||||
|
|
||||||
if (!g_Configuration.EnableThumbstickCameraControl)
|
if (!g_Configuration.EnableThumbstickCameraControl)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Camera.laraNode == -1 && (Camera.target.x == OldCam.target.x &&
|
if (Camera.laraNode == -1 && Camera.target.ToVector3i() == OldCam.target)
|
||||||
Camera.target.y == OldCam.target.y &&
|
|
||||||
Camera.target.z == OldCam.target.z))
|
|
||||||
{
|
{
|
||||||
float xAxisCoeff = AxisMap[InputAxis::CameraHorizontal];
|
auto axisCoeff = Vector2(
|
||||||
float yAxisCoeff = AxisMap[InputAxis::CameraVertical];
|
AxisMap[InputAxis::CameraHorizontal],
|
||||||
|
AxisMap[InputAxis::CameraVertical]);
|
||||||
|
|
||||||
Camera.targetAngle = THUMBCAM_VERTICAL_CONSTRAINT_ANGLE * xAxisCoeff;
|
Camera.targetAngle = VERTICAL_CONSTRAINT_ANGLE * axisCoeff.y;
|
||||||
Camera.targetElevation = ANGLE(-10.0f) + (THUMBCAM_HORIZONTAL_CONSTRAINT_ANGLE * xAxisCoeff);
|
Camera.targetElevation = ANGLE(-10.0f) + (HORIZONTAL_CONSTRAINT_ANGLE * axisCoeff.x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static float GetLookCameraVerticalOffset(const ItemInfo& item, const CollisionInfo& coll)
|
static float GetLookCameraVerticalOffset(const ItemInfo& item, const CollisionInfo& coll)
|
||||||
{
|
{
|
||||||
constexpr auto VERTICAL_OFFSET_DEFAULT = -BLOCK(1 / 16.0f);
|
constexpr auto VERTICAL_OFFSET_DEFAULT = -BLOCK(1 / 16.0f);
|
||||||
constexpr auto VERTICAL_OFFSET_SWAMP = BLOCK(0.5f); // TODO
|
constexpr auto VERTICAL_OFFSET_SWAMP = BLOCK(0.4f);
|
||||||
constexpr auto VERTICAL_OFFSET_MONKEY_SWING = BLOCK(0.25f);
|
constexpr auto VERTICAL_OFFSET_MONKEY_SWING = BLOCK(0.25f);
|
||||||
constexpr auto VERTICAL_OFFSET_TREADING_WATER = BLOCK(0.5f);
|
constexpr auto VERTICAL_OFFSET_TREADING_WATER = BLOCK(0.5f);
|
||||||
|
|
||||||
const auto& player = GetLaraInfo(item);
|
const auto& player = GetLaraInfo(item);
|
||||||
|
|
||||||
|
bool isInSwamp = TestEnvironment(ENV_FLAG_SWAMP, item.RoomNumber);
|
||||||
|
|
||||||
float verticalOffset = -coll.Setup.Height;
|
float verticalOffset = -coll.Setup.Height;
|
||||||
if (player.Control.IsMonkeySwinging)
|
if (player.Control.IsMonkeySwinging)
|
||||||
{
|
{
|
||||||
|
@ -209,6 +210,10 @@ static float GetLookCameraVerticalOffset(const ItemInfo& item, const CollisionIn
|
||||||
{
|
{
|
||||||
verticalOffset += VERTICAL_OFFSET_TREADING_WATER;
|
verticalOffset += VERTICAL_OFFSET_TREADING_WATER;
|
||||||
}
|
}
|
||||||
|
else if (isInSwamp)
|
||||||
|
{
|
||||||
|
verticalOffset = -VERTICAL_OFFSET_SWAMP;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
verticalOffset += VERTICAL_OFFSET_DEFAULT;
|
verticalOffset += VERTICAL_OFFSET_DEFAULT;
|
||||||
|
@ -221,16 +226,13 @@ void LookCamera(ItemInfo& item, const CollisionInfo& coll)
|
||||||
{
|
{
|
||||||
const auto& player = GetLaraInfo(item);
|
const auto& player = GetLaraInfo(item);
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// - Set modes in remaining states.
|
|
||||||
|
|
||||||
constexpr auto POS_LERP_ALPHA = 0.25f;
|
constexpr auto POS_LERP_ALPHA = 0.25f;
|
||||||
constexpr auto COLL_PUSH = BLOCK(0.25f) - BLOCK(1 / 16.0f);
|
constexpr auto COLL_PUSH = BLOCK(0.25f) - BLOCK(1 / 16.0f);
|
||||||
|
|
||||||
// Calculate key offsets.
|
|
||||||
float verticalOffset = GetLookCameraVerticalOffset(item, coll);
|
float verticalOffset = GetLookCameraVerticalOffset(item, coll);
|
||||||
auto pivotPosOffset = Vector3(0.0f, verticalOffset, 0.0f);
|
auto pivotPosOffset = Vector3(0.0f, verticalOffset, 0.0f);
|
||||||
float idealPosDist = -std::max(Camera.targetDistance * 0.5f, BLOCK(3.0f / 4));
|
|
||||||
|
float idealPosDist = -std::max(Camera.targetDistance * 0.5f, BLOCK(0.75f));
|
||||||
float lookAtPosDist = BLOCK(0.5f);
|
float lookAtPosDist = BLOCK(0.5f);
|
||||||
|
|
||||||
// Define absolute camera orientation.
|
// Define absolute camera orientation.
|
||||||
|
@ -239,8 +241,15 @@ void LookCamera(ItemInfo& item, const CollisionInfo& coll)
|
||||||
EulerAngles(0, Camera.targetAngle, 0);
|
EulerAngles(0, Camera.targetAngle, 0);
|
||||||
orient.x = std::clamp(orient.x, LOOKCAM_ORIENT_CONSTRAINT.first.x, LOOKCAM_ORIENT_CONSTRAINT.second.x);
|
orient.x = std::clamp(orient.x, LOOKCAM_ORIENT_CONSTRAINT.first.x, LOOKCAM_ORIENT_CONSTRAINT.second.x);
|
||||||
|
|
||||||
|
// TODO: Goes to the centre in swamps for some reason.
|
||||||
|
// Determine base position.
|
||||||
|
bool isInSwamp = TestEnvironment(ENV_FLAG_SWAMP, item.RoomNumber);
|
||||||
|
auto basePos = isInSwamp ?
|
||||||
|
Vector3i(item.Pose.Position.x, g_Level.Rooms[item.RoomNumber].maxceiling, item.Pose.Position.z) :
|
||||||
|
item.Pose.Position;
|
||||||
|
|
||||||
// Define landmarks.
|
// Define landmarks.
|
||||||
auto pivotPos = Geometry::TranslatePoint(item.Pose.Position, item.Pose.Orientation.y, pivotPosOffset.z, pivotPosOffset.y, pivotPosOffset.x); // TODO: Use overload from ladder branch.
|
auto pivotPos = Geometry::TranslatePoint(basePos, item.Pose.Orientation.y, pivotPosOffset);
|
||||||
auto idealPos = Geometry::TranslatePoint(pivotPos, orient, idealPosDist);
|
auto idealPos = Geometry::TranslatePoint(pivotPos, orient, idealPosDist);
|
||||||
auto lookAtPos = Geometry::TranslatePoint(pivotPos, orient, lookAtPosDist);
|
auto lookAtPos = Geometry::TranslatePoint(pivotPos, orient, lookAtPosDist);
|
||||||
|
|
||||||
|
@ -253,9 +262,6 @@ void LookCamera(ItemInfo& item, const CollisionInfo& coll)
|
||||||
CameraCollisionBounds(&target, COLL_PUSH, true);
|
CameraCollisionBounds(&target, COLL_PUSH, true);
|
||||||
ItemsCollideCamera();
|
ItemsCollideCamera();
|
||||||
|
|
||||||
// Doesn't seem necessary? Can use player's room number.
|
|
||||||
//auto lookAt = GameVector(lookAtPos, GetCollision(origin.ToVector3i(), origin.RoomNumber, orient, BLOCK(3, 8)).RoomNumber);
|
|
||||||
|
|
||||||
// Smoothly update camera position.
|
// Smoothly update camera position.
|
||||||
MoveCamera(&target, Camera.speed);
|
MoveCamera(&target, Camera.speed);
|
||||||
Camera.target = GameVector(Camera.target.ToVector3i() + (lookAtPos - Camera.target.ToVector3i()) * POS_LERP_ALPHA, item.RoomNumber);
|
Camera.target = GameVector(Camera.target.ToVector3i() + (lookAtPos - Camera.target.ToVector3i()) * POS_LERP_ALPHA, item.RoomNumber);
|
||||||
|
|
|
@ -82,7 +82,6 @@ extern float CinematicBarsHeight;
|
||||||
extern float CinematicBarsSpeed;
|
extern float CinematicBarsSpeed;
|
||||||
|
|
||||||
void DoLookAround(ItemInfo& item, bool invertVerticalAxis = true);
|
void DoLookAround(ItemInfo& item, bool invertVerticalAxis = true);
|
||||||
void ClearLookAroundActions(const ItemInfo& item);
|
|
||||||
void DoThumbstickCamera();
|
void DoThumbstickCamera();
|
||||||
void LookCamera(ItemInfo& item, const CollisionInfo& coll);
|
void LookCamera(ItemInfo& item, const CollisionInfo& coll);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue