From 97b8898cb2fa29f596dea9df38d818b903b72d34 Mon Sep 17 00:00:00 2001 From: XProger Date: Thu, 29 Dec 2016 13:56:57 +0300 Subject: [PATCH] #8 cutscene animation sequence --- src/camera.h | 181 +++++++++++++++++++++++++++++++-------------------- src/format.h | 12 ++-- src/game.h | 2 +- src/lara.h | 3 +- src/level.h | 6 +- 5 files changed, 122 insertions(+), 82 deletions(-) diff --git a/src/camera.h b/src/camera.h index 04bc5b0..3ee1a1f 100644 --- a/src/camera.h +++ b/src/camera.h @@ -19,6 +19,7 @@ struct Camera : Controller { float timer; 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) { fov = 65.0f; @@ -31,6 +32,8 @@ struct Camera : Controller { pos = pos - owner->getDir() * 1024.0f; target = owner->getViewPoint(); } + + cutscene = owner->getEntity().type != TR::Entity::LARA && level->cameraFrames; } virtual ~Camera() { @@ -56,93 +59,129 @@ struct Camera : Controller { } virtual void update() { - 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; - } + #ifndef LEVEL_EDITOR + if (cutscene) { // cutscene - angleAdv.x -= Input::joy.R.y * 2.0f * Core::deltaTime; - angleAdv.y += Input::joy.R.x * 2.0f * Core::deltaTime; + vec3 orig = owner->pos; + float rotY = 0.0f; + + switch (level->cameraFramesCount) { + 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; + } + + timer += Core::deltaTime * 30; + int indexA = int(timer) % level->cameraFramesCount; + TR::CameraFrame *frame = &level->cameraFrames[indexA]; + + pos = orig + vec3(frame->pos).rotateY(-rotY); + target = orig + vec3(frame->target).rotateY(-rotY); + //fov = float(frame->fov) / 32767.0f * 120.0f; + // TODO: frame->roll + } else + #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; + } + + angleAdv.x -= Input::joy.R.y * 2.0f * Core::deltaTime; + angleAdv.y += Input::joy.R.x * 2.0f * Core::deltaTime; - angle = owner->angle + angleAdv; - angle.z = 0.0f; + angle = owner->angle + angleAdv; + angle.z = 0.0f; - #ifdef LEVEL_EDITOR - angle = angleAdv; - angle.x = min(max(angle.x, -80 * DEG2RAD), 80 * DEG2RAD); + #ifdef LEVEL_EDITOR + angle = angleAdv; + angle.x = min(max(angle.x, -80 * DEG2RAD), 80 * DEG2RAD); - vec3 d = vec3(sinf(angle.y) * cosf(angle.x), -sinf(angle.x), cosf(angle.y) * cosf(angle.x)); - vec3 v = vec3(0); + 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); + 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); + mViewInv.identity(); + mViewInv.translate(pos); + mViewInv.rotateY(angle.y - PI); + mViewInv.rotateX(-angle.x); + mViewInv.rotateZ(PI); - Sound::listener.matrix = mViewInv; + Sound::listener.matrix = mViewInv; - return; - #endif + return; + #endif - int lookAt = -1; - if (actTargetEntity > -1) lookAt = actTargetEntity; - if (owner->target > -1) lookAt = owner->target; + int lookAt = -1; + if (actTargetEntity > -1) lookAt = actTargetEntity; + if (owner->target > -1) lookAt = owner->target; - owner->viewTarget = lookAt; + 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(); + 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); + 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; + 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 { - 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; - } + if (lookAt > -1) { + TR::Entity &e = level->entities[lookAt]; + dir = (((Controller*)e.controller)->pos - target).normal(); + } 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) { TR::Level::FloorInfo info; diff --git a/src/format.h b/src/format.h index d6f241f..909342d 100644 --- a/src/format.h +++ b/src/format.h @@ -630,14 +630,10 @@ namespace TR { }; struct CameraFrame { - int16 rotY; - int16 rotZ; - int16 unused1; - int16 posZ; - int16 posY; - int16 posX; - int16 unknown; - int16 rotX; + Vertex target; + Vertex pos; + int16 fov; + int16 roll; }; struct SoundSource { diff --git a/src/game.h b/src/game.h index d9e7abd..5439513 100644 --- a/src/game.h +++ b/src/game.h @@ -33,7 +33,7 @@ namespace Game { //lstartLevel("LEVEL2_DEMO.PHD", true, false); //lstartLevel("GYM.PSX", false, true); //lstartLevel("LEVEL3A.PHD", false, false); - startLevel("LEVEL2.PSX", false, false); + startLevel("CUT1.PHD", false, false); } void free() { diff --git a/src/lara.h b/src/lara.h index 53a4da1..cd4cd46 100644 --- a/src/lara.h +++ b/src/lara.h @@ -1601,7 +1601,7 @@ struct Lara : Character { if (velocity.length() >= 0.001f) move(); - + /* if (getEntity().type != TR::Entity::LARA) { TR::Entity &e = getEntity(); vec3 &p = getPos(); @@ -1611,6 +1611,7 @@ struct Lara : Character { checkRoom(); updateEntity(); } + */ } virtual vec3& getPos() { diff --git a/src/level.h b/src/level.h index a7f8ffd..7245c5a 100644 --- a/src/level.h +++ b/src/level.h @@ -749,7 +749,11 @@ struct Level { for (int i = 0; i < level.roomsCount; i++) renderRoom(i); #else - renderRoom(roomIndex); + if (!camera->cutscene) + renderRoom(roomIndex); + else // TODO: use brain + for (int i = 0; i < level.roomsCount; i++) + renderRoom(i); #endif }