1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-03-13 23:59:41 +01:00

#8 playing cutscenes, #23 hide shadow from back of walls

This commit is contained in:
XProger 2016-12-30 02:29:11 +03:00
parent 97b8898cb2
commit d52b478e31
7 changed files with 130 additions and 46 deletions

View File

@ -61,7 +61,7 @@ struct Camera : Controller {
virtual void update() {
#ifndef LEVEL_EDITOR
if (cutscene) { // cutscene
/*
vec3 orig = owner->pos;
float rotY = 0.0f;
@ -83,14 +83,29 @@ struct Camera : Controller {
rotY = PI * 0.5f;
break;
}
*/
timer += Core::deltaTime * 30;
float t = timer - int(timer);
int indexA = int(timer) % level->cameraFramesCount;
TR::CameraFrame *frame = &level->cameraFrames[indexA];
int indexB = min(indexA + 1, level->cameraFramesCount - 1);
TR::CameraFrame *frameA = &level->cameraFrames[indexA];
TR::CameraFrame *frameB = &level->cameraFrames[indexB];
const int eps = 128;
if (abs(frameA->pos.x - frameB->pos.x) > eps || abs(frameA->pos.y - frameB->pos.y) > eps || abs(frameA->pos.z - frameB->pos.z) > eps) {
pos = frameA->pos;
target = frameA->target;
fov = frameA->fov / 32767.0f * 120.0f;
} else {
pos = vec3(frameA->pos).lerp(frameB->pos, t);
target = vec3(frameA->target).lerp(frameB->target, t);
fov = lerp(frameA->fov / 32767.0f * 120.0f, frameB->fov / 32767.0f * 120.0f, t);
}
pos = level->cutMatrix * pos;
target = level->cutMatrix * target;
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
@ -181,29 +196,29 @@ struct Camera : Controller {
room = destRoom;
}
pos = pos.lerp(destPos, Core::deltaTime * lerpFactor);
}
if (actCamera <= -1) {
TR::Level::FloorInfo info;
level->getFloorInfo(room, (int)pos.x, (int)pos.y, (int)pos.z, info);
if (actCamera <= -1) {
TR::Level::FloorInfo info;
level->getFloorInfo(room, (int)pos.x, (int)pos.y, (int)pos.z, info);
if (info.roomNext != 255)
room = info.roomNext;
if (info.roomNext != 255)
room = info.roomNext;
if (pos.y < info.roomCeiling) {
if (info.roomAbove != 255)
room = info.roomAbove;
else
if (info.roomCeiling != 0xffff8100)
pos.y = (float)info.roomCeiling;
}
if (pos.y < info.roomCeiling) {
if (info.roomAbove != 255)
room = info.roomAbove;
else
if (info.roomCeiling != 0xffff8100)
pos.y = (float)info.roomCeiling;
}
if (pos.y > info.roomFloor) {
if (info.roomBelow != 255)
room = info.roomBelow;
else
if (info.roomFloor != 0xffff8100)
pos.y = (float)info.roomFloor;
if (pos.y > info.roomFloor) {
if (info.roomBelow != 255)
room = info.roomBelow;
else
if (info.roomFloor != 0xffff8100)
pos.y = (float)info.roomFloor;
}
}
}

View File

@ -426,11 +426,17 @@ struct Controller {
*/
mat4 getMatrix() {
mat4 matrix;
matrix.identity();
matrix.translate(pos);
if (angle.y != 0.0f) matrix.rotateY(angle.y - (animation.flip ? PI * animation.delta : 0.0f));
if (angle.x != 0.0f) matrix.rotateX(angle.x);
if (angle.z != 0.0f) matrix.rotateZ(angle.z);
TR::Entity &e = getEntity();
if (e.type < TR::Entity::CUT_1 || e.type > TR::Entity::CUT_3) { // TODO: move to ctor
matrix.identity();
matrix.translate(pos);
if (angle.y != 0.0f) matrix.rotateY(angle.y - (animation.flip ? PI * animation.delta : 0.0f));
if (angle.x != 0.0f) matrix.rotateX(angle.x);
if (angle.z != 0.0f) matrix.rotateZ(angle.z);
} else
matrix = level->cutMatrix;
return matrix;
}

View File

@ -412,7 +412,9 @@ namespace TR {
GEARS_2 = 75,
GEARS_3 = 76,
LARA_CUT = 77,
CUT_1 = 77,
CUT_2 = 78,
CUT_3 = 79,
CRYSTAL = 83, // sprite
WEAPON_PISTOLS = 84, // sprite
@ -813,13 +815,16 @@ namespace TR {
bool secrets[MAX_SECRETS_COUNT];
void *cameraController;
int cutEntity;
mat4 cutMatrix;
struct {
int16 muzzleFlash;
int16 puzzleSet;
int16 weapons[4];
} extra;
Level(Stream &stream, bool demo) {
Level(Stream &stream, bool demo) : cutEntity(-1) {
tiles4 = NULL;
Tile8 *tiles8 = NULL;
cluts = NULL;
@ -975,6 +980,8 @@ namespace TR {
e.align = 0;
e.controller = NULL;
e.modelIndex = getModelIndex(e.type);
if (e.type == Entity::CUT_1)
cutEntity = i;
}
for (int i = entitiesBaseCount; i < entitiesCount; i++) {
entities[i].type = Entity::NONE;
@ -1026,6 +1033,26 @@ namespace TR {
case Entity::LARA_UZIS : extra.weapons[3] = i; break;
default : ;
}
// init cutscene transform
cutMatrix.identity();
if (cutEntity > -1) {
Entity &e = entities[cutEntity];
switch (cameraFramesCount) { // HACK to detect cutscene level number
case 1600 : // CUT1
cutMatrix.translate(vec3(36668, float(e.y), 63180));
cutMatrix.rotateY(-23312.0f / float(0x4000) * PI * 0.5f);
break;
case 1000 : // CUT2
cutMatrix.translate(vec3(51962, float(e.y), 53760));
cutMatrix.rotateY(16380.0f / float(0x4000) * PI * 0.5f);
break;
case 400 : // CUT3
case 1890 : // CUT4
cutMatrix.translate(vec3(float(e.x), float(e.y), float(e.z)));
cutMatrix.rotateY(PI * 0.5f);
break;
}
}
}
~Level() {
@ -1669,7 +1696,7 @@ namespace TR {
}; // struct Level
bool castShadow(Entity::Type type) {
return (type >= Entity::ENEMY_TWIN && type <= Entity::ENEMY_LARSON) || type == Entity::LARA || type == Entity::LARA_CUT;
return (type >= Entity::ENEMY_TWIN && type <= Entity::ENEMY_LARSON) || type == Entity::LARA || (type >= Entity::CUT_1 && type <= Entity::CUT_3);
}
}

View File

@ -600,6 +600,8 @@ struct Lara : Character {
}
void updateWeapon() {
if (level->cutEntity > -1) return;
if (input & DEATH) {
arms[0].shotTimer = arms[1].shotTimer = MUZZLE_FLASH_TIME + 1.0f;
animation.overrideMask = 0;
@ -889,6 +891,7 @@ struct Lara : Character {
virtual void cmdEffect(int fx) {
switch (fx) {
case TR::EFFECT_FLIP_MAP : break; // TODO
case TR::EFFECT_LARA_HANDSFREE : break;//meshSwap(1, level->extra.weapons[wpnCurrent], BODY_LEG_L1 | BODY_LEG_R1); break;
case TR::EFFECT_DRAW_RIGHTGUN :
case TR::EFFECT_DRAW_LEFTGUN : drawGun(fx == TR::EFFECT_DRAW_RIGHTGUN); break;
@ -1419,6 +1422,7 @@ struct Lara : Character {
}
virtual int getInput() { // TODO: updateInput
if (level->cutEntity > -1) return 0;
input = Character::getInput();
if (input & DEATH) return input;
@ -1601,7 +1605,7 @@ struct Lara : Character {
if (velocity.length() >= 0.001f)
move();
/*
if (getEntity().type != TR::Entity::LARA) {
TR::Entity &e = getEntity();
vec3 &p = getPos();
@ -1611,7 +1615,7 @@ struct Lara : Character {
checkRoom();
updateEntity();
}
*/
}
virtual vec3& getPos() {

View File

@ -161,9 +161,9 @@ struct Level {
void getAmbient(int room, const vec3 &pos, Cube &value) {
TR::Room &r = level->level.rooms[room];
int sx = (int(pos.x) - r.info.x) / 1024;
int sz = (int(pos.z) - r.info.z) / 1024;
int sx = clamp((int(pos.x) - r.info.x) / 1024, 0, r.xSectors - 1);
int sz = clamp((int(pos.z) - r.info.z) / 1024, 0, r.zSectors - 1);
int sector = sx * r.zSectors + sz;
Cube *a = getAmbient(room, sector);
if (a) {
@ -232,11 +232,9 @@ struct Level {
TR::Entity &entity = level.entities[i];
switch (entity.type) {
case TR::Entity::LARA :
case TR::Entity::CUT_1 :
entity.controller = (lara = new Lara(&level, i, home));
break;
case TR::Entity::LARA_CUT :
entity.controller = (lara = new Lara(&level, i, false));
break;
case TR::Entity::ENEMY_WOLF :
entity.controller = new Wolf(&level, i);
break;
@ -789,7 +787,7 @@ struct Level {
}
bool setupLightCamera() {
vec3 pos = (lara->animation.getJoints(lara->getMatrix(), 0, false, NULL)).pos;
vec3 pos = lara->getPos();
// omni-spot light shadows
int room = lara->getRoomIndex();
@ -903,7 +901,7 @@ struct Level {
// Debug::Level::sectors(level, lara->getRoomIndex(), (int)lara->pos.y);
// Debug::Level::portals(level);
// Debug::Level::meshes(level);
// Debug::Level::entities(level);
Debug::Level::entities(level);
static int dbg_ambient = 0;
dbg_ambient = int(time * 2) % 4;
@ -916,7 +914,7 @@ struct Level {
glColor3f(1, 1, 1);
for (int j = 0; j < 6; j++) {
glPushMatrix();
vec3 p = lara->getPos();
vec3 p = lara->pos;//getPos();
glTranslatef(p.x, p.y - 1024, p.z);
switch (j) {
case 0 : glRotatef( 90, 0, 1, 0); break;

View File

@ -217,8 +217,26 @@ uniform int uType;
sqr.y * mix(uAmbient[3], uAmbient[2], pos.y) +
sqr.z * mix(uAmbient[5], uAmbient[4], pos.z);
}
#endif
#endif
/*
float getLuminance(vec3 color) {
return dot(color.xyz, vec3(0.299, 0.587, 0.114));
}
vec3 getNormal() {
const vec2 size = vec2(2.0, 0.0);
const vec3 off = vec3(-1, 0, 1) / 1024.0;
float s01 = getLuminance(texture2D(sDiffuse, vTexCoord + off.xy).xyz);
float s21 = getLuminance(texture2D(sDiffuse, vTexCoord + off.zy).xyz);
float s10 = getLuminance(texture2D(sDiffuse, vTexCoord + off.yx).xyz);
float s12 = getLuminance(texture2D(sDiffuse, vTexCoord + off.yz).xyz);
vec3 va = vec3(size.xy * 0.25, s21-s01);
vec3 vb = vec3(size.yx * 0.25, s12-s10);
return normalize(cross(va, vb));
}
*/
void main() {
vec4 color = texture2D(sDiffuse, vTexCoord);
if (color.w < 0.6)
@ -242,9 +260,16 @@ uniform int uType;
// calc point lights
if (uType != TYPE_FLASH) {
vec3 normal = normalize(vNormal.xyz);
//vec3 n = getNormal();;
//vec3 b = normalize(cross(n, vec3(.0, -1.0, 0.0)));
//vec3 t = normalize(cross(b, n));
//normal = normalize(normal.x * t + normal.y * b + normal.z * n);
vec3 viewVec = normalize(vViewVec);
vec3 light = vec3(0.0);
for (int i = 1; i < MAX_LIGHTS; i++) // additional lights
light += calcLight(normal, uLightPos[i], uLightColor[i]);
@ -254,7 +279,9 @@ uniform int uType;
}
if (uType == TYPE_ROOM) {
light += mix(min(uColor.w, vColor.w), vColor.w, getShadow(vLightProj));
float rShadow = dot(normal, uLightPos[0].xyz - vCoord) > 0.0 ? getShadow(vLightProj) : 1.0;
//light += calcLight(normal, uLightPos[0], uLightColor[0]);
light += mix(min(uColor.w, vColor.w), vColor.w, rShadow);
}
if (uType == TYPE_ENTITY) {
@ -271,6 +298,7 @@ uniform int uType;
}
color.xyz *= light;
//color.xyz = normal * 0.5 + 0.5;
} else {
color.w = uColor.w;
}

View File

@ -70,6 +70,12 @@ inline void swap(T &a, T &b) {
b = tmp;
}
float lerp(float a, float b, float t) {
if (t <= 0.0f) return a;
if (t >= 1.0f) return b;
return a + (b - a) * t;
}
float clampAngle(float a) {
return a < -PI ? a + PI2 : (a >= PI ? a - PI2 : a);
}