1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-13 16:44:50 +02:00

#22 add sparkles effect; #8 first-person mode for cutscenes

This commit is contained in:
XProger
2017-10-11 07:19:13 +03:00
parent 80b2d70e3c
commit 43088756fd
8 changed files with 75 additions and 33 deletions

View File

@@ -153,6 +153,29 @@ struct Camera : ICamera {
timer = 0.0f; timer = 0.0f;
} }
bool updateFirstPerson() {
if (!firstPerson || viewIndex != -1)
return false;
Basis head = owner->animation.getJoints(owner->getMatrix(), 14, true);
Basis eye(quat(0.0f, 0.0f, 0.0f, 1.0f), vec3(0.0f, -40.0f, 10.0f));
eye = head * eye;
mViewInv.identity();
//prevBasis = prevBasis.lerp(eye, 15.0f * Core::deltaTime);
mViewInv.setRot(eye.rot);
mViewInv.setPos(eye.pos);
mViewInv.rotateY(advAngle.y);
mViewInv.rotateX(advAngle.x + PI);
pos = mViewInv.getPos();
checkRoom();
updateListener();
return true;
}
virtual void update() { virtual void update() {
if (shake > 0.0f) if (shake > 0.0f)
shake = max(0.0f, shake - Core::deltaTime); shake = max(0.0f, shake - Core::deltaTime);
@@ -173,6 +196,9 @@ struct Camera : ICamera {
} }
} }
if (updateFirstPerson())
return;
TR::CameraFrame *frameA = &level->cameraFrames[indexA]; TR::CameraFrame *frameA = &level->cameraFrames[indexA];
TR::CameraFrame *frameB = &level->cameraFrames[indexB]; TR::CameraFrame *frameB = &level->cameraFrames[indexB];
@@ -242,24 +268,8 @@ struct Camera : ICamera {
vec3 viewPoint = getViewPoint(); vec3 viewPoint = getViewPoint();
if (firstPerson && viewIndex == -1) { if (updateFirstPerson())
Basis head = owner->animation.getJoints(owner->getMatrix(), 14, true);
Basis eye(quat(0.0f, 0.0f, 0.0f, 1.0f), vec3(0.0f, -40.0f, 10.0f));
eye = head * eye;
mViewInv.identity();
//prevBasis = prevBasis.lerp(eye, 15.0f * Core::deltaTime);
mViewInv.setRot(eye.rot);
mViewInv.setPos(eye.pos);
mViewInv.rotateY(advAngle.y);
mViewInv.rotateX(advAngle.x + PI);
pos = mViewInv.getPos();
checkRoom();
updateListener();
return; return;
}
float lerpFactor = lookAt ? 10.0f : 6.0f; float lerpFactor = lookAt ? 10.0f : 6.0f;
vec3 dir; vec3 dir;

View File

@@ -11,6 +11,7 @@
#define SPRITE_FPS 10.0f #define SPRITE_FPS 10.0f
#define MAX_LAYERS 4 #define MAX_LAYERS 4
#define MAX_SPHERES 32
#define UNLIMITED_AMMO 10000 #define UNLIMITED_AMMO 10000
@@ -371,6 +372,8 @@ struct Controller {
void getSpheres(Sphere *spheres, int &count) { void getSpheres(Sphere *spheres, int &count) {
TR::Model *m = getModel(); TR::Model *m = getModel();
ASSERT(m->mCount <= MAX_SPHERES);
Basis basis(getMatrix()); Basis basis(getMatrix());
// TODO: optimize (check frame index for animation updates, use joints array) // TODO: optimize (check frame index for animation updates, use joints array)
count = 0; count = 0;
@@ -394,8 +397,8 @@ struct Controller {
ASSERT(a->mCount <= 34); ASSERT(a->mCount <= 34);
ASSERT(b->mCount <= 34); ASSERT(b->mCount <= 34);
Sphere aSpheres[34]; Sphere aSpheres[MAX_SPHERES];
Sphere bSpheres[34]; Sphere bSpheres[MAX_SPHERES];
int aCount, bCount; int aCount, bCount;
getSpheres(aSpheres, aCount); getSpheres(aSpheres, aCount);

View File

@@ -686,7 +686,7 @@ namespace Core {
// init settings // init settings
settings.detail.setFilter (Core::Settings::HIGH); settings.detail.setFilter (Core::Settings::HIGH);
settings.detail.setLighting (Core::Settings::HIGH); settings.detail.setLighting (Core::Settings::HIGH);
settings.detail.setShadows (Core::Settings::MEDIUM); settings.detail.setShadows (Core::Settings::HIGH);
settings.detail.setWater (Core::Settings::HIGH); settings.detail.setWater (Core::Settings::HIGH);
settings.audio.music = 0.7f; settings.audio.music = 0.7f;

View File

@@ -534,7 +534,7 @@ namespace Debug {
Box box = controller->getBoundingBoxLocal(); Box box = controller->getBoundingBoxLocal();
Debug::Draw::box(matrix, box.min, box.max, bboxIntersect ? vec4(1, 0, 0, 1): vec4(1)); Debug::Draw::box(matrix, box.min, box.max, bboxIntersect ? vec4(1, 0, 0, 1): vec4(1));
Sphere spheres[34]; Sphere spheres[MAX_SPHERES];
int count; int count;
controller->getSpheres(spheres, count); controller->getSpheres(spheres, count);

View File

@@ -134,7 +134,7 @@ struct Inventory {
TR::Level *level = game->getLevel(); TR::Level *level = game->getLevel();
TR::Model &m = level->models[desc.model]; TR::Model &m = level->models[desc.model];
Basis joints[34]; Basis joints[MAX_SPHERES];
anim->getJoints(basis, -1, true, joints); anim->getJoints(basis, -1, true, joints);

View File

@@ -167,8 +167,8 @@ struct Lara : Character {
STATE_SURF_BACK, STATE_SURF_BACK,
STATE_SURF_LEFT, STATE_SURF_LEFT,
STATE_SURF_RIGHT, STATE_SURF_RIGHT,
STATE_USE_MIDAS, STATE_MIDAS_USE,
STATE_DIE_MIDAS, STATE_MIDAS_DEATH,
STATE_SWAN_DIVE, STATE_SWAN_DIVE,
STATE_FAST_DIVE, STATE_FAST_DIVE,
STATE_HANDSTAND, STATE_HANDSTAND,
@@ -513,6 +513,8 @@ struct Lara : Character {
} }
void reset(int room, const vec3 &pos, float angle, Stand forceStand = STAND_GROUND) { void reset(int room, const vec3 &pos, float angle, Stand forceStand = STAND_GROUND) {
visibleMask = 0xFFFFFFFF;
if (room == TR::NO_ROOM) { if (room == TR::NO_ROOM) {
stand = STAND_AIR; stand = STAND_AIR;
room = getRoomByPos(pos); room = getRoomByPos(pos);
@@ -1262,7 +1264,7 @@ struct Lara : Character {
if (box.intersect(m, from, v, t)) { if (box.intersect(m, from, v, t)) {
v = v.normal(); v = v.normal();
Sphere spheres[34]; Sphere spheres[MAX_SPHERES];
int count; int count;
target->getSpheres(spheres, count); target->getSpheres(spheres, count);
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
@@ -1319,6 +1321,17 @@ struct Lara : Character {
} }
} }
void addSparks(uint32 mask) {
Sphere spheres[MAX_SPHERES];
int count;
getSpheres(spheres, count);
for (int i = 0; i < count; i++)
if (mask & (1 << i)) {
vec3 sprPos = spheres[i].center + (vec3(randf(), randf(), randf()) * 2.0f - 1.0f) * spheres[i].radius;
Sprite::add(game, TR::Entity::SPARKLES, getRoomIndex(), int(sprPos.x), int(sprPos.y), int(sprPos.z), Sprite::FRAME_ANIMATED);
}
}
void addBlood(const vec3 &sprPos, const vec3 &sprVel) { void addBlood(const vec3 &sprPos, const vec3 &sprVel) {
int index = Sprite::add(game, TR::Entity::BLOOD, getRoomIndex(), int(sprPos.x), int(sprPos.y), int(sprPos.z), Sprite::FRAME_ANIMATED); int index = Sprite::add(game, TR::Entity::BLOOD, getRoomIndex(), int(sprPos.x), int(sprPos.y), int(sprPos.z), Sprite::FRAME_ANIMATED);
if (index > -1) if (index > -1)
@@ -2337,7 +2350,7 @@ struct Lara : Character {
virtual int getStateDeath() { virtual int getStateDeath() {
velocity = vec3(0.0f); velocity = vec3(0.0f);
return (stand == STAND_UNDERWATER || stand == STAND_ONWATER) ? STATE_UNDERWATER_DEATH : STATE_DEATH; return (stand == STAND_UNDERWATER || stand == STAND_ONWATER) ? STATE_UNDERWATER_DEATH : (state == STATE_MIDAS_DEATH ? STATE_MIDAS_DEATH : STATE_DEATH);
} }
virtual int getStateDefault() { virtual int getStateDefault() {
@@ -2486,6 +2499,19 @@ struct Lara : Character {
else else
if (specular > 0.0f) if (specular > 0.0f)
specular = max(0.0f, specular - LARA_WET_TIMER * Core::deltaTime); specular = max(0.0f, specular - LARA_WET_TIMER * Core::deltaTime);
if (state == STATE_MIDAS_DEATH || state == STATE_MIDAS_USE) {
uint32 sparklesMask = getMidasMask();
if (state == STATE_MIDAS_DEATH)
visibleMask = sparklesMask ^ 0xFFFFFFFF;
timer += Core::deltaTime;
if (timer >= 1.0f / 30.0f) {
timer -= 1.0f / 30.0f;
addSparks(sparklesMask);
}
}
} }
virtual void updateVelocity() { virtual void updateVelocity() {
@@ -2878,7 +2904,10 @@ struct Lara : Character {
velocity = v * (sink.speed * 8.0f); velocity = v * (sink.speed * 8.0f);
} }
uint32 getMidasDeathMask() { uint32 getMidasMask() {
if (state == STATE_MIDAS_USE)
return BODY_ARM_L3 | BODY_ARM_R3;
uint32 mask = 0; uint32 mask = 0;
int frame = animation.frameIndex; int frame = animation.frameIndex;
if (frame > 4 ) mask |= BODY_LEG_L3 | BODY_LEG_R3; if (frame > 4 ) mask |= BODY_LEG_L3 | BODY_LEG_R3;
@@ -2926,13 +2955,13 @@ struct Lara : Character {
Core::setBlending(bmNone); Core::setBlending(bmNone);
} }
if (state == STATE_DIE_MIDAS) { if (state == STATE_MIDAS_DEATH) {
game->setRoomParams(getRoomIndex(), Shader::MIRROR, 1.2f, 1.0f, 0.2f, 1.0f, false); game->setRoomParams(getRoomIndex(), Shader::MIRROR, 1.2f, 1.0f, 0.2f, 1.0f, false);
environment->bind(sEnvironment); environment->bind(sEnvironment);
Core::setBlending(bmAlpha); Core::setBlending(bmAlpha);
visibleMask = getMidasDeathMask(); visibleMask ^= 0xFFFFFFFF;
Controller::render(frustum, mesh, type, caustics); Controller::render(frustum, mesh, type, caustics);
visibleMask = 0xFFFFFFFF; visibleMask ^= 0xFFFFFFFF;
Core::setBlending(bmNone); Core::setBlending(bmNone);
} }
} }

View File

@@ -885,7 +885,7 @@ struct Level : IGame {
type = Shader::MIRROR; type = Shader::MIRROR;
if (type == Shader::SPRITE) { if (type == Shader::SPRITE) {
float alpha = (entity.type == TR::Entity::SMOKE || entity.type == TR::Entity::WATER_SPLASH) ? 0.75f : 1.0f; float alpha = (entity.type == TR::Entity::SMOKE || entity.type == TR::Entity::WATER_SPLASH || entity.type == TR::Entity::SPARKLES) ? 0.75f : 1.0f;
float diffuse = entity.isPickup() ? 1.0f : 0.5f; float diffuse = entity.isPickup() ? 1.0f : 0.5f;
setRoomParams(roomIndex, type, diffuse, intensityf(lum), controller->specular, alpha, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true); setRoomParams(roomIndex, type, diffuse, intensityf(lum), controller->specular, alpha, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true);
} else } else