mirror of
https://github.com/XProger/OpenLara.git
synced 2025-04-20 11:02:18 +02:00
fix camera logic (at LEVEL6 start)
This commit is contained in:
parent
18386a1d35
commit
1b2f3170b2
102
src/camera.h
102
src/camera.h
@ -36,6 +36,7 @@ struct Camera : ICamera {
|
||||
int viewIndex;
|
||||
int viewIndexLast;
|
||||
Controller* viewTarget;
|
||||
Controller* viewTargetLast;
|
||||
Basis fpHead;
|
||||
int speed;
|
||||
bool smooth;
|
||||
@ -97,9 +98,21 @@ struct Camera : ICamera {
|
||||
return level->rooms[getRoomIndex()].flags.water;
|
||||
}
|
||||
|
||||
vec3 getViewPoint() {
|
||||
vec3 getViewPoint(bool useBounds = true) {
|
||||
Box box = owner->getBoundingBox();
|
||||
vec3 pos = owner->pos;
|
||||
|
||||
if (!useBounds) {
|
||||
if (owner->getEntity().type == TR::Entity::LARA &&
|
||||
owner->stand != Character::STAND_UNDERWATER &&
|
||||
owner->stand != Character::STAND_ONWATER)
|
||||
{
|
||||
pos.y -= 512.0f;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
vec3 center = box.center();
|
||||
|
||||
if (centerView) {
|
||||
@ -107,41 +120,27 @@ struct Camera : ICamera {
|
||||
pos.z = center.z;
|
||||
}
|
||||
|
||||
if (mode == MODE_LOOK) {
|
||||
Basis b = owner->getJoint(owner->jointHead);
|
||||
b.translate(vec3(0, -128, 0));
|
||||
pos = b.pos;
|
||||
} else {
|
||||
if (mode != MODE_STATIC)
|
||||
pos.y = box.max.y + (box.min.y - box.max.y) * (3.0f / 4.0f);
|
||||
else
|
||||
pos.y = center.y;
|
||||
if (owner->getEntity().type == TR::Entity::LARA) {
|
||||
if (mode == MODE_LOOK) {
|
||||
Basis b = owner->getJoint(owner->jointHead);
|
||||
b.translate(vec3(0, -128, 0));
|
||||
pos = b.pos;
|
||||
} else {
|
||||
if (mode != MODE_STATIC)
|
||||
pos.y = box.max.y + (box.min.y - box.max.y) * (3.0f / 4.0f);
|
||||
else
|
||||
pos.y = center.y;
|
||||
|
||||
if (owner->stand != Character::STAND_UNDERWATER)
|
||||
pos.y -= 256;
|
||||
if (owner->stand != Character::STAND_UNDERWATER)
|
||||
pos.y -= 256;
|
||||
}
|
||||
} else {
|
||||
pos.y = center.y;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void setView(int viewIndex, float timer, int speed) {
|
||||
viewIndexLast = viewIndex;
|
||||
smooth = speed > 0;
|
||||
mode = MODE_STATIC;
|
||||
this->viewIndex = viewIndex;
|
||||
this->timer = timer;
|
||||
this->speed = speed * 8;
|
||||
}
|
||||
|
||||
void resetTarget() {
|
||||
smooth = speed > 0;
|
||||
mode = MODE_FOLLOW;
|
||||
viewIndex = -1;
|
||||
viewTarget = NULL;
|
||||
timer = -1.0f;
|
||||
speed = CAM_SPEED_FOLLOW;
|
||||
}
|
||||
|
||||
virtual void doCutscene(const vec3 &pos, float rotation) {
|
||||
mode = Camera::MODE_CUTSCENE;
|
||||
level->cutMatrix.identity();
|
||||
@ -334,6 +333,14 @@ struct Camera : ICamera {
|
||||
Input::setJoyVibration(cameraIndex, clamp(shake, 0.0f, 1.0f), 0);
|
||||
}
|
||||
|
||||
if (mode == MODE_FOLLOW) {
|
||||
speed = CAM_SPEED_FOLLOW;
|
||||
}
|
||||
|
||||
if (mode == MODE_COMBAT) {
|
||||
speed = CAM_SPEED_COMBAT;
|
||||
}
|
||||
|
||||
if (mode == MODE_CUTSCENE) {
|
||||
ASSERT(level->cameraFramesCount && level->cameraFrames);
|
||||
|
||||
@ -437,19 +444,13 @@ struct Camera : ICamera {
|
||||
targetAngle += angle;
|
||||
}
|
||||
|
||||
if (!firstPerson || viewIndex != -1) {
|
||||
|
||||
if (timer > 0.0f) {
|
||||
timer -= Core::deltaTime;
|
||||
if (timer <= 0.0f) {
|
||||
resetTarget();
|
||||
}
|
||||
}
|
||||
bool isStatic = (mode == MODE_STATIC || mode == MODE_HEAVY) && viewTarget;
|
||||
|
||||
if (!firstPerson || isStatic) {
|
||||
TR::Location to;
|
||||
|
||||
target.box = TR::NO_BOX;
|
||||
if (viewIndex > -1) {
|
||||
if (mode == MODE_STATIC && viewIndex > -1) {
|
||||
TR::Camera &cam = level->cameras[viewIndex];
|
||||
to.room = cam.room;
|
||||
to.pos = vec3(float(cam.x), float(cam.y), float(cam.z));
|
||||
@ -458,8 +459,7 @@ struct Camera : ICamera {
|
||||
target.pos = lookAt->getBoundingBox().center();
|
||||
} else {
|
||||
target.room = owner->getRoomIndex();
|
||||
target.pos = owner->pos;
|
||||
target.pos.y -= 512.0f;
|
||||
target.pos = getViewPoint(false);
|
||||
}
|
||||
} else {
|
||||
vec3 p = getViewPoint();
|
||||
@ -486,9 +486,6 @@ struct Camera : ICamera {
|
||||
|
||||
move(to);
|
||||
|
||||
if (timer <= 0.0f)
|
||||
resetTarget();
|
||||
|
||||
mViewInv = mat4(eye.pos, target.pos, vec3(0, -1, 0));
|
||||
} else
|
||||
updateFirstPerson();
|
||||
@ -502,6 +499,23 @@ struct Camera : ICamera {
|
||||
updateListener(mViewInv);
|
||||
|
||||
smooth = true;
|
||||
|
||||
viewIndexLast = viewIndex;
|
||||
|
||||
if ((mode == MODE_STATIC || mode == MODE_HEAVY) && timer != 0.0f) {
|
||||
timer -= Core::deltaTime;
|
||||
if (timer <= 0.0f) {
|
||||
timer = -1.0f;
|
||||
smooth = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode != MODE_HEAVY || timer == -1.0f) {
|
||||
mode = MODE_FOLLOW;
|
||||
viewIndex = -1;
|
||||
viewTargetLast = viewTarget;
|
||||
viewTarget = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void setup(bool calcMatrices) {
|
||||
|
90
src/lara.h
90
src/lara.h
@ -1930,6 +1930,53 @@ struct Lara : Character {
|
||||
return false;
|
||||
}
|
||||
|
||||
void refreshCamera(const TR::Level::FloorInfo &info) {
|
||||
const TR::FloorData::TriggerCommand *cameraCmdSwitch = NULL;
|
||||
const TR::FloorData::TriggerCommand *cameraCmdTarget = NULL;
|
||||
|
||||
int cmdIndex = 0;
|
||||
|
||||
while (cmdIndex < info.trigCmdCount) {
|
||||
const TR::FloorData::TriggerCommand &cmd = info.trigCmd[cmdIndex++];
|
||||
|
||||
switch (cmd.action) {
|
||||
case TR::Action::CAMERA_SWITCH :
|
||||
ASSERT(!cameraCmdSwitch);
|
||||
cameraCmdSwitch = &cmd;
|
||||
cmdIndex++; // skip camera info cmd
|
||||
break;
|
||||
case TR::Action::CAMERA_TARGET :
|
||||
ASSERT(!cameraCmdTarget);
|
||||
cameraCmdTarget = &cmd;
|
||||
break;
|
||||
default : ;
|
||||
}
|
||||
}
|
||||
|
||||
if (cameraCmdTarget && camera->mode != Camera::MODE_LOOK && camera->mode != Camera::MODE_COMBAT) {
|
||||
camera->viewTarget = (Controller*)level->entities[cameraCmdTarget->args].controller;
|
||||
}
|
||||
|
||||
if (cameraCmdSwitch) {
|
||||
if (cameraCmdSwitch->args == camera->viewIndexLast) {
|
||||
camera->viewIndex = camera->viewIndexLast;
|
||||
|
||||
if (camera->mode == Camera::MODE_LOOK || camera->mode == Camera::MODE_COMBAT || camera->timer < 0) {
|
||||
camera->timer = -1.0f;
|
||||
camera->viewTarget = NULL;
|
||||
} else {
|
||||
camera->mode = Camera::MODE_STATIC;
|
||||
}
|
||||
} else {
|
||||
camera->viewTarget = NULL;
|
||||
}
|
||||
} else {
|
||||
if (viewTarget && camera->viewTarget != camera->viewTargetLast) {
|
||||
camera->viewTarget = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void checkTrigger(Controller *controller, bool heavy) {
|
||||
TR::Level::FloorInfo info;
|
||||
getFloorInfo(controller->getRoomIndex(), controller->pos, info);
|
||||
@ -1941,6 +1988,10 @@ struct Lara : Character {
|
||||
|
||||
if (!info.trigCmdCount) return; // has no trigger
|
||||
|
||||
if (camera->mode != Camera::MODE_HEAVY) {
|
||||
refreshCamera(info);
|
||||
}
|
||||
|
||||
TR::Limits::Limit *limit = NULL;
|
||||
bool switchIsDown = false;
|
||||
float timer = info.trigInfo.timer == 1 ? EPS : float(info.trigInfo.timer);
|
||||
@ -2050,9 +2101,6 @@ struct Lara : Character {
|
||||
bool needFlip = false;
|
||||
TR::Effect::Type effect = TR::Effect::NONE;
|
||||
|
||||
int cameraIndex = -1;
|
||||
Controller *cameraTarget = NULL;
|
||||
|
||||
while (cmdIndex < info.trigCmdCount) {
|
||||
TR::FloorData::TriggerCommand &cmd = info.trigCmd[cmdIndex++];
|
||||
|
||||
@ -2084,20 +2132,22 @@ struct Lara : Character {
|
||||
}
|
||||
case TR::Action::CAMERA_SWITCH : {
|
||||
TR::FloorData::TriggerCommand &cam = info.trigCmd[cmdIndex++];
|
||||
if (level->cameras[cmd.args].flags.once)
|
||||
break;
|
||||
|
||||
if (info.trigger == TR::Level::Trigger::COMBAT)
|
||||
break;
|
||||
if (info.trigger == TR::Level::Trigger::SWITCH && info.trigInfo.timer && !switchIsDown)
|
||||
break;
|
||||
|
||||
if (info.trigger == TR::Level::Trigger::SWITCH || cmd.args != camera->viewIndexLast) {
|
||||
level->cameras[cmd.args].flags.once |= cam.once;
|
||||
camera->setView(cmd.args, cam.timer == 1 ? EPS : float(cam.timer), cam.speed);
|
||||
cameraIndex = cmd.args;
|
||||
if (!level->cameras[cmd.args].flags.once) {
|
||||
camera->viewIndex = cmd.args;
|
||||
|
||||
if (!(info.trigger == TR::Level::Trigger::COMBAT) &&
|
||||
!(info.trigger == TR::Level::Trigger::SWITCH && info.trigInfo.timer && !switchIsDown) &&
|
||||
(info.trigger == TR::Level::Trigger::SWITCH || camera->viewIndex != camera->viewIndexLast))
|
||||
{
|
||||
camera->smooth = cam.speed > 0;
|
||||
camera->mode = heavy ? Camera::MODE_HEAVY : Camera::MODE_STATIC;
|
||||
camera->timer = cam.timer == 1 ? EPS : float(cam.timer);
|
||||
camera->speed = cam.speed * 8;
|
||||
|
||||
level->cameras[camera->viewIndex].flags.once |= cam.once;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TR::Action::FLOW :
|
||||
@ -2131,7 +2181,9 @@ struct Lara : Character {
|
||||
needFlip = true;
|
||||
break;
|
||||
case TR::Action::CAMERA_TARGET :
|
||||
cameraTarget = (Controller*)level->entities[cmd.args].controller;
|
||||
if (camera->mode == Camera::MODE_STATIC || camera->mode == Camera::MODE_HEAVY) {
|
||||
camera->viewTarget = (Controller*)level->entities[cmd.args].controller;
|
||||
}
|
||||
break;
|
||||
case TR::Action::END :
|
||||
game->loadNextLevel();
|
||||
@ -2175,12 +2227,6 @@ struct Lara : Character {
|
||||
}
|
||||
}
|
||||
|
||||
if (cameraTarget && (camera->mode == Camera::MODE_STATIC || cameraIndex == -1))
|
||||
camera->viewTarget = cameraTarget;
|
||||
|
||||
if (!cameraTarget && cameraIndex > -1)
|
||||
camera->viewIndex = cameraIndex;
|
||||
|
||||
if (needFlip) {
|
||||
game->flipMap();
|
||||
game->setEffect(this, effect);
|
||||
|
12
src/level.h
12
src/level.h
@ -3107,8 +3107,7 @@ struct Level : IGame {
|
||||
|
||||
Core::pushLights();
|
||||
|
||||
UI::begin();
|
||||
UI::updateAspect(camera->aspect);
|
||||
UI::begin(camera->aspect);
|
||||
|
||||
atlasObjects->bind(sDiffuse);
|
||||
UI::renderPickups();
|
||||
@ -3175,8 +3174,7 @@ struct Level : IGame {
|
||||
inventory->render(1.0);
|
||||
|
||||
if (UI::subsStr != STR_EMPTY) {
|
||||
UI::begin();
|
||||
UI::updateAspect(float(Core::width) / float(Core::height));
|
||||
UI::begin(float(Core::width) / float(Core::height));
|
||||
atlasGlyphs->bind(sDiffuse);
|
||||
UI::renderSubs();
|
||||
UI::end();
|
||||
@ -3191,8 +3189,7 @@ struct Level : IGame {
|
||||
atlasObjects->bind(sDiffuse);
|
||||
inventory->render(aspect);
|
||||
|
||||
UI::begin();
|
||||
UI::updateAspect(aspect);
|
||||
UI::begin(aspect);
|
||||
atlasGlyphs->bind(sDiffuse);
|
||||
if (!inventory->video) {
|
||||
inventory->renderUI();
|
||||
@ -3207,8 +3204,7 @@ struct Level : IGame {
|
||||
void render() {
|
||||
if (isEnded && !inventory->video) {
|
||||
Core::setTarget(NULL, NULL, RT_CLEAR_COLOR | RT_STORE_COLOR);
|
||||
UI::begin();
|
||||
UI::updateAspect(float(Core::width) / float(Core::height));
|
||||
UI::begin(float(Core::width) / float(Core::height));
|
||||
atlasGlyphs->bind(sDiffuse);
|
||||
UI::textOut(vec2(0, 480 - 16), STR_LOADING, UI::aCenter, UI::width);
|
||||
UI::end();
|
||||
|
15
src/ui.h
15
src/ui.h
@ -257,16 +257,16 @@ namespace UI {
|
||||
uint16 curTile, curClut;
|
||||
#endif
|
||||
|
||||
void updateAspect(float aspect) {
|
||||
void begin(float aspect) {
|
||||
ensureLanguage(Core::settings.audio.language);
|
||||
|
||||
height = 480.0f;
|
||||
width = height * aspect;
|
||||
|
||||
Core::mModel.identity();
|
||||
Core::mView.identity();
|
||||
Core::mProj = GAPI::ortho(0.0f, width, height, 0.0f, -128.0f, 127.0f);
|
||||
Core::setViewProj(Core::mView, Core::mProj);
|
||||
Core::active.shader->setParam(uViewProj, Core::mViewProj);
|
||||
}
|
||||
|
||||
void begin() {
|
||||
ensureLanguage(Core::settings.audio.language);
|
||||
|
||||
Core::setDepthTest(false);
|
||||
Core::setDepthWrite(false);
|
||||
@ -274,9 +274,6 @@ namespace UI {
|
||||
Core::setCullMode(cmNone);
|
||||
game->setupBinding();
|
||||
|
||||
Core::mView.identity();
|
||||
Core::mModel.identity();
|
||||
|
||||
game->setShader(Core::passGUI, Shader::DEFAULT);
|
||||
Core::setMaterial(1, 1, 1, 1);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user