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:
191
src/camera.h
191
src/camera.h
@@ -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;
|
||||||
|
12
src/format.h
12
src/format.h
@@ -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 {
|
||||||
|
@@ -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() {
|
||||||
|
@@ -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() {
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user