1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-15 09:34:18 +02:00

Fixed Lara's gun aiming and various accuracy tweaks.

This commit is contained in:
Saracen
2018-10-14 09:34:14 +01:00
parent 0b39b2ecaf
commit fe548b9bfd
2 changed files with 80 additions and 49 deletions

View File

@@ -56,6 +56,25 @@
#define DESCENT_SPEED 2048.0f #define DESCENT_SPEED 2048.0f
#define TARGET_MAX_DIST (8.0f * 1024.0f) #define TARGET_MAX_DIST (8.0f * 1024.0f)
enum {
LARA_JOINT_HIPS = 0,
LARA_JOINT_THIGH_L,
LARA_JOINT_CALF_L,
LARA_JOINT_FOOT_L,
LARA_JOINT_THIGH_R,
LARA_JOINT_CALF_R,
LARA_JOINT_FOOT_R,
LARA_JOINT_CHEST,
LARA_JOINT_UPPER_ARM_R,
LARA_JOINT_LOWER_ARM_R,
LARA_JOINT_HAND_R,
LARA_JOINT_UPPER_ARM_L,
LARA_JOINT_LOWER_ARM_L,
LARA_JOINT_HAND_L,
LARA_JOINT_HEAD,
LARA_JOINT_COUNT
};
struct Lara : Character { struct Lara : Character {
// http://www.tombraiderforums.com/showthread.php?t=148859 // http://www.tombraiderforums.com/showthread.php?t=148859
@@ -444,8 +463,8 @@ struct Lara : Character {
if (level->extra.laraSkin > -1) if (level->extra.laraSkin > -1)
level->entities[entity].modelIndex = level->extra.laraSkin + 1; level->entities[entity].modelIndex = level->extra.laraSkin + 1;
jointChest = 7; jointChest = LARA_JOINT_CHEST;
jointHead = 14; jointHead = LARA_JOINT_HEAD;
rangeChest = vec4(-0.50f, 0.50f, -0.95f, 0.95f) * PI; rangeChest = vec4(-0.50f, 0.50f, -0.95f, 0.95f) * PI;
rangeHead = vec4(-0.30f, 0.30f, -0.55f, 0.55f) * PI; rangeHead = vec4(-0.30f, 0.30f, -0.55f, 0.55f) * PI;
@@ -1107,39 +1126,15 @@ struct Lara : Character {
} }
void updateOverrides() { void updateOverrides() {
// Copy all current animation joints
for (int i = 0; i < LARA_JOINT_COUNT; i++)
animation.overrides[i] = animation.getJointRot(i);
int overrideMask = 0; int overrideMask = 0;
// head & chest // head & chest
overrideMask |= BODY_CHEST | BODY_HEAD; overrideMask |= BODY_CHEST | BODY_HEAD;
animation.overrides[jointChest] = animation.getJointRot(jointChest); // update hit anim
animation.overrides[jointHead] = animation.getJointRot(jointHead);
/* TODO: shotgun full body animation
if (wpnCurrent == Weapon::SHOTGUN) {
animation.frameA = arms[0].animation.frameA;
animation.frameB = arms[0].animation.frameB;
animation.delta = arms[0].animation.delta;
}
*/
// arms
if (!emptyHands()) {
// right arm
Arm *arm = &arms[0];
animation.overrides[ 8] = arm->animation.getJointRot( 8);
animation.overrides[ 9] = arm->animation.getJointRot( 9);
animation.overrides[10] = arm->animation.getJointRot(10);
// left arm
if (wpnCurrent != TR::Entity::SHOTGUN) arm = &arms[1];
animation.overrides[11] = arm->animation.getJointRot(11);
animation.overrides[12] = arm->animation.getJointRot(12);
animation.overrides[13] = arm->animation.getJointRot(13);
overrideMask |= (BODY_ARM_R | BODY_ARM_L);
} else
overrideMask &= ~(BODY_ARM_R | BODY_ARM_L);
// update hit anim
if (hitDir >= 0) { if (hitDir >= 0) {
Animation hitAnim = Animation(level, getModel()); Animation hitAnim = Animation(level, getModel());
switch (hitDir) { switch (hitDir) {
@@ -1166,6 +1161,25 @@ struct Lara : Character {
overrideMask = BODY_UPPER | BODY_LOWER | BODY_HEAD; overrideMask = BODY_UPPER | BODY_LOWER | BODY_HEAD;
} }
// arms
if (!emptyHands()) {
// right arm
Arm *arm = &arms[0];
animation.overrides[LARA_JOINT_UPPER_ARM_R] = animation.overrides[LARA_JOINT_CHEST].inverse() * animation.overrides[LARA_JOINT_HIPS].inverse() * arm->animation.getJointRot(LARA_JOINT_UPPER_ARM_R);
animation.overrides[LARA_JOINT_LOWER_ARM_R] = arm->animation.getJointRot(LARA_JOINT_LOWER_ARM_R);
animation.overrides[LARA_JOINT_HAND_R] = arm->animation.getJointRot(LARA_JOINT_HAND_R);
// left arm
if (wpnCurrent != TR::Entity::SHOTGUN) arm = &arms[1];
animation.overrides[LARA_JOINT_UPPER_ARM_L] = animation.overrides[LARA_JOINT_CHEST].inverse() * animation.overrides[LARA_JOINT_HIPS].inverse() * arm->animation.getJointRot(LARA_JOINT_UPPER_ARM_L);
animation.overrides[LARA_JOINT_LOWER_ARM_L] = arm->animation.getJointRot(LARA_JOINT_LOWER_ARM_L);
animation.overrides[LARA_JOINT_HAND_L] = arm->animation.getJointRot(LARA_JOINT_HAND_L);
overrideMask |= (BODY_ARM_R | BODY_ARM_L);
}
else
overrideMask &= ~(BODY_ARM_R | BODY_ARM_L);
animation.overrideMask = overrideMask; animation.overrideMask = overrideMask;
jointsFrame = -1; jointsFrame = -1;
} }
@@ -1183,6 +1197,7 @@ struct Lara : Character {
return; return;
updateOverrides(); updateOverrides();
updateTargets();
Controller *lookTarget = canLookAt() ? target : NULL; Controller *lookTarget = canLookAt() ? target : NULL;
if (camera->mode == Camera::MODE_LOOK) { if (camera->mode == Camera::MODE_LOOK) {
@@ -1191,9 +1206,7 @@ struct Lara : Character {
} else } else
Character::lookAt(lookTarget); Character::lookAt(lookTarget);
if (!emptyHands()) { if (wpnReady() && !emptyHands()) {
updateTargets();
if (wpnCurrent == TR::Entity::SHOTGUN) if (wpnCurrent == TR::Entity::SHOTGUN)
aimShotgun(); aimShotgun();
else else
@@ -1213,16 +1226,35 @@ struct Lara : Character {
} }
void aimShotgun() { void aimShotgun() {
quat rot; float speed = 8.0f * Core::deltaTime;
int joints[2] = { LARA_JOINT_UPPER_ARM_R, LARA_JOINT_UPPER_ARM_L };
bool hasAim = true;
quat rot;
Arm &arm = arms[0]; Arm &arm = arms[0];
arm.target = aim(arm.target, 14, vec4(-PI * 0.4f, PI * 0.4f, -PI * 0.25f, PI * 0.25f), rot, &arm.rotAbs) ? arm.target : NULL; if (!aim(arm.target, LARA_JOINT_UPPER_ARM_R, vec4(-PI * 0.4f, PI * 0.4f, -PI * 0.25f, PI * 0.25f), rot, &arm.rotAbs)) {
rot = quat(0, 0, 0, 1);
arm.target = NULL;
hasAim = false;
}
if (hasAim)
rot = animation.getJointRot(LARA_JOINT_HIPS) * animation.getJointRot(LARA_JOINT_CHEST) * rot;
for (int i = 0; i < 2; i++) {
int j = joints[i];
arm.rot = arm.rot.slerp(rot, speed);
animation.overrides[j] = arm.rot * animation.overrides[j];
jointsFrame = -1;
}
} }
void aimPistols() { void aimPistols() {
float speed = 8.0f * Core::deltaTime; float speed = 8.0f * Core::deltaTime;
int joints[2] = { 8, 11 }; int joints[2] = { LARA_JOINT_UPPER_ARM_R, LARA_JOINT_UPPER_ARM_L };
vec4 ranges[2] = { vec4 ranges[2] = {
vec4(-PI * 0.4f, PI * 0.4f, -PI * 0.2f, PI * 0.5f), vec4(-PI * 0.4f, PI * 0.4f, -PI * 0.2f, PI * 0.5f),
@@ -1234,24 +1266,21 @@ struct Lara : Character {
Arm &arm = arms[i]; Arm &arm = arms[i];
int j = joints[i]; int j = joints[i];
bool hasAim = true;
if (!aim(arm.target, j, ranges[i], rot, &arm.rotAbs)) { if (!aim(arm.target, j, ranges[i], rot, &arm.rotAbs)) {
arm.target = arms[i^1].target; arm.target = arms[i^1].target;
if (!aim(arm.target, j, ranges[i], rot, &arm.rotAbs)) { if (!aim(arm.target, j, ranges[i], rot, &arm.rotAbs)) {
rot = quat(0, 0, 0, 1); rot = quat(0, 0, 0, 1);
arm.target = NULL; arm.target = NULL;
hasAim = false;
} }
} }
float t; if (hasAim)
if (arm.anim == Weapon::Anim::FIRE) rot = animation.getJointRot(LARA_JOINT_HIPS) * animation.getJointRot(LARA_JOINT_CHEST) * rot;
t = 1.0f;
else if (arm.anim == Weapon::Anim::AIM)
t = arm.animation.time / arm.animation.timeMax;
else
t = 0.0f;
arm.rot = arm.rot.slerp(rot, speed); arm.rot = arm.rot.slerp(rot, speed);
animation.overrides[j] = animation.overrides[j].slerp(arm.rot * animation.overrides[j], t); animation.overrides[j] = arm.rot * animation.overrides[j];
jointsFrame = -1; jointsFrame = -1;
} }
} }
@@ -1926,7 +1955,7 @@ struct Lara : Character {
} }
case TR::Level::Trigger::COMBAT : case TR::Level::Trigger::COMBAT :
if (emptyHands()) if (wpnReady() && !emptyHands())
return; return;
break; break;
@@ -2396,8 +2425,10 @@ struct Lara : Character {
if (state == STATE_FAST_TURN) if (state == STATE_FAST_TURN)
return state; return state;
if (input & LEFT) return (state == STATE_TURN_LEFT && animation.prev == animation.index) ? STATE_FAST_TURN : STATE_TURN_LEFT; bool weaponReady = wpnReady() && !emptyHands();
if (input & RIGHT) return (state == STATE_TURN_RIGHT && animation.prev == animation.index) ? STATE_FAST_TURN : STATE_TURN_RIGHT;
if (input & LEFT) return (state == STATE_TURN_LEFT && (animation.prev == animation.index || weaponReady)) ? STATE_FAST_TURN : STATE_TURN_LEFT;
if (input & RIGHT) return (state == STATE_TURN_RIGHT && (animation.prev == animation.index || weaponReady)) ? STATE_FAST_TURN : STATE_TURN_RIGHT;
} }
if (state == STATE_STOP && res != STATE_STOP) { if (state == STATE_STOP && res != STATE_STOP) {

View File

@@ -2779,7 +2779,7 @@ struct Level : IGame {
pos.y += 16.0f; pos.y += 16.0f;
} }
if ((!inventory->active && (!player->emptyHands() || player->damageTime > 0.0f || health <= 0.2f))) { if ((!inventory->active && ((player->wpnReady() && !player->emptyHands()) || player->damageTime > 0.0f || health <= 0.2f))) {
UI::renderBar(UI::BAR_HEALTH, pos, size, health); UI::renderBar(UI::BAR_HEALTH, pos, size, health);
pos.y += 32.0f; pos.y += 32.0f;