1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-18 10:51:23 +02:00

#8 cutscene animation sequence

This commit is contained in:
XProger
2016-12-29 13:56:57 +03:00
parent 5df5ec8a60
commit 97b8898cb2
5 changed files with 122 additions and 82 deletions

View File

@@ -19,6 +19,7 @@ struct Camera : Controller {
float timer; float timer;
int actTargetEntity, actCamera; int actTargetEntity, actCamera;
bool cutscene;
Camera(TR::Level *level, Lara *owner) : Controller(level, owner ? owner->entity : 0), owner(owner), frustum(new Frustum()), timer(0.0f), actTargetEntity(-1), actCamera(-1) { Camera(TR::Level *level, Lara *owner) : Controller(level, owner ? owner->entity : 0), owner(owner), frustum(new Frustum()), timer(0.0f), actTargetEntity(-1), actCamera(-1) {
fov = 65.0f; fov = 65.0f;
@@ -31,6 +32,8 @@ struct Camera : Controller {
pos = pos - owner->getDir() * 1024.0f; pos = pos - owner->getDir() * 1024.0f;
target = owner->getViewPoint(); target = owner->getViewPoint();
} }
cutscene = owner->getEntity().type != TR::Entity::LARA && level->cameraFrames;
} }
virtual ~Camera() { virtual ~Camera() {
@@ -56,93 +59,129 @@ struct Camera : Controller {
} }
virtual void update() { virtual void update() {
if (Input::down[ikMouseR]) { #ifndef LEVEL_EDITOR
vec2 delta = Input::mouse.pos - Input::mouse.start.R; if (cutscene) { // cutscene
angleAdv.x -= delta.y * 0.01f;
angleAdv.y += delta.x * 0.01f;
Input::mouse.start.R = Input::mouse.pos;
}
angleAdv.x -= Input::joy.R.y * 2.0f * Core::deltaTime; vec3 orig = owner->pos;
angleAdv.y += Input::joy.R.x * 2.0f * Core::deltaTime; float rotY = 0.0f;
angle = owner->angle + angleAdv; switch (level->cameraFramesCount) {
angle.z = 0.0f; case 1600 : // CUT1
orig.x = 36668;
orig.z = 63180;
rotY = -23312.0f / float(0x4000) * PI * 0.5f;
break;
case 1000 : // CUT2
orig.x = 51962;
orig.z = 53760;
rotY = 16380.0f / float(0x4000) * PI * 0.5f;
break;
case 400 : // CUT3
rotY = PI * 0.5f;
break;
case 1890 : // CUT4
rotY = PI * 0.5f;
break;
}
#ifdef LEVEL_EDITOR timer += Core::deltaTime * 30;
angle = angleAdv; int indexA = int(timer) % level->cameraFramesCount;
angle.x = min(max(angle.x, -80 * DEG2RAD), 80 * DEG2RAD); TR::CameraFrame *frame = &level->cameraFrames[indexA];
vec3 d = vec3(sinf(angle.y) * cosf(angle.x), -sinf(angle.x), cosf(angle.y) * cosf(angle.x)); pos = orig + vec3(frame->pos).rotateY(-rotY);
vec3 v = vec3(0); target = orig + vec3(frame->target).rotateY(-rotY);
//fov = float(frame->fov) / 32767.0f * 120.0f;
if (Input::down[ikW]) v = v + d; // TODO: frame->roll
if (Input::down[ikS]) v = v - d; } else
if (Input::down[ikA]) v = v + d.cross(vec3(0, 1, 0));
if (Input::down[ikD]) v = v - d.cross(vec3(0, 1, 0));
pos = pos + v.normal() * (Core::deltaTime * 2048.0f * 10.0f);
mViewInv.identity();
mViewInv.translate(pos);
mViewInv.rotateY(angle.y - PI);
mViewInv.rotateX(-angle.x);
mViewInv.rotateZ(PI);
Sound::listener.matrix = mViewInv;
return;
#endif #endif
{
if (Input::down[ikMouseR]) {
vec2 delta = Input::mouse.pos - Input::mouse.start.R;
angleAdv.x -= delta.y * 0.01f;
angleAdv.y += delta.x * 0.01f;
Input::mouse.start.R = Input::mouse.pos;
}
int lookAt = -1; angleAdv.x -= Input::joy.R.y * 2.0f * Core::deltaTime;
if (actTargetEntity > -1) lookAt = actTargetEntity; angleAdv.y += Input::joy.R.x * 2.0f * Core::deltaTime;
if (owner->target > -1) lookAt = owner->target;
owner->viewTarget = lookAt; angle = owner->angle + angleAdv;
angle.z = 0.0f;
if (timer > 0.0f) { #ifdef LEVEL_EDITOR
timer -= Core::deltaTime; angle = angleAdv;
if (timer <= 0.0f) { angle.x = min(max(angle.x, -80 * DEG2RAD), 80 * DEG2RAD);
timer = 0.0f;
vec3 d = vec3(sinf(angle.y) * cosf(angle.x), -sinf(angle.x), cosf(angle.y) * cosf(angle.x));
vec3 v = vec3(0);
if (Input::down[ikW]) v = v + d;
if (Input::down[ikS]) v = v - d;
if (Input::down[ikA]) v = v + d.cross(vec3(0, 1, 0));
if (Input::down[ikD]) v = v - d.cross(vec3(0, 1, 0));
pos = pos + v.normal() * (Core::deltaTime * 2048.0f * 10.0f);
mViewInv.identity();
mViewInv.translate(pos);
mViewInv.rotateY(angle.y - PI);
mViewInv.rotateX(-angle.x);
mViewInv.rotateZ(PI);
Sound::listener.matrix = mViewInv;
return;
#endif
int lookAt = -1;
if (actTargetEntity > -1) lookAt = actTargetEntity;
if (owner->target > -1) lookAt = owner->target;
owner->viewTarget = lookAt;
if (timer > 0.0f) {
timer -= Core::deltaTime;
if (timer <= 0.0f) {
timer = 0.0f;
if (room != getRoomIndex())
pos = lastDest;
actTargetEntity = actCamera = -1;
target = owner->getViewPoint();
}
}
float lerpFactor = (lookAt == -1) ? 6.0f : 10.0f;
vec3 dir;
target = target.lerp(owner->getViewPoint(), lerpFactor * Core::deltaTime);
if (actCamera > -1) {
TR::Camera &c = level->cameras[actCamera];
destPos = vec3(float(c.x), float(c.y), float(c.z));
if (room != getRoomIndex()) if (room != getRoomIndex())
pos = lastDest; pos = destPos;
actTargetEntity = actCamera = -1; if (lookAt > -1) {
target = owner->getViewPoint(); TR::Entity &e = level->entities[lookAt];
} target = ((Controller*)e.controller)->pos;
} }
float lerpFactor = (lookAt == -1) ? 6.0f : 10.0f;
vec3 dir;
target = target.lerp(owner->getViewPoint(), lerpFactor * Core::deltaTime);
if (actCamera > -1) {
TR::Camera &c = level->cameras[actCamera];
destPos = vec3(float(c.x), float(c.y), float(c.z));
if (room != getRoomIndex())
pos = destPos;
if (lookAt > -1) {
TR::Entity &e = level->entities[lookAt];
target = ((Controller*)e.controller)->pos;
}
} else {
if (lookAt > -1) {
TR::Entity &e = level->entities[lookAt];
dir = (((Controller*)e.controller)->pos - target).normal();
} else
dir = getDir();
int destRoom;
if ((!owner->emptyHands() || owner->state != Lara::STATE_BACK_JUMP) || lookAt > -1) {
vec3 eye = target - dir * CAMERA_OFFSET;
destPos = trace(owner->getRoomIndex(), target, eye, destRoom, true);
lastDest = destPos;
} else { } else {
vec3 eye = lastDest + dir.cross(vec3(0, 1, 0)).normal() * 2048.0f - vec3(0.0f, 512.0f, 0.0f); if (lookAt > -1) {
destPos = trace(owner->getRoomIndex(), target, eye, destRoom, true); TR::Entity &e = level->entities[lookAt];
} dir = (((Controller*)e.controller)->pos - target).normal();
room = destRoom; } else
} dir = getDir();
pos = pos.lerp(destPos, Core::deltaTime * lerpFactor); int destRoom;
if ((!owner->emptyHands() || owner->state != Lara::STATE_BACK_JUMP) || lookAt > -1) {
vec3 eye = target - dir * CAMERA_OFFSET;
destPos = trace(owner->getRoomIndex(), target, eye, destRoom, true);
lastDest = destPos;
} else {
vec3 eye = lastDest + dir.cross(vec3(0, 1, 0)).normal() * 2048.0f - vec3(0.0f, 512.0f, 0.0f);
destPos = trace(owner->getRoomIndex(), target, eye, destRoom, true);
}
room = destRoom;
}
pos = pos.lerp(destPos, Core::deltaTime * lerpFactor);
}
if (actCamera <= -1) { if (actCamera <= -1) {
TR::Level::FloorInfo info; TR::Level::FloorInfo info;

View File

@@ -630,14 +630,10 @@ namespace TR {
}; };
struct CameraFrame { struct CameraFrame {
int16 rotY; Vertex target;
int16 rotZ; Vertex pos;
int16 unused1; int16 fov;
int16 posZ; int16 roll;
int16 posY;
int16 posX;
int16 unknown;
int16 rotX;
}; };
struct SoundSource { struct SoundSource {

View File

@@ -33,7 +33,7 @@ namespace Game {
//lstartLevel("LEVEL2_DEMO.PHD", true, false); //lstartLevel("LEVEL2_DEMO.PHD", true, false);
//lstartLevel("GYM.PSX", false, true); //lstartLevel("GYM.PSX", false, true);
//lstartLevel("LEVEL3A.PHD", false, false); //lstartLevel("LEVEL3A.PHD", false, false);
startLevel("LEVEL2.PSX", false, false); startLevel("CUT1.PHD", false, false);
} }
void free() { void free() {

View File

@@ -1601,7 +1601,7 @@ struct Lara : Character {
if (velocity.length() >= 0.001f) if (velocity.length() >= 0.001f)
move(); move();
/*
if (getEntity().type != TR::Entity::LARA) { if (getEntity().type != TR::Entity::LARA) {
TR::Entity &e = getEntity(); TR::Entity &e = getEntity();
vec3 &p = getPos(); vec3 &p = getPos();
@@ -1611,6 +1611,7 @@ struct Lara : Character {
checkRoom(); checkRoom();
updateEntity(); updateEntity();
} }
*/
} }
virtual vec3& getPos() { virtual vec3& getPos() {

View File

@@ -749,7 +749,11 @@ struct Level {
for (int i = 0; i < level.roomsCount; i++) for (int i = 0; i < level.roomsCount; i++)
renderRoom(i); renderRoom(i);
#else #else
renderRoom(roomIndex); if (!camera->cutscene)
renderRoom(roomIndex);
else // TODO: use brain
for (int i = 0; i < level.roomsCount; i++)
renderRoom(i);
#endif #endif
} }