1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-12 08:04:09 +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;
}
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() {
if (shake > 0.0f)
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 *frameB = &level->cameraFrames[indexB];
@@ -242,24 +268,8 @@ struct Camera : ICamera {
vec3 viewPoint = getViewPoint();
if (firstPerson && viewIndex == -1) {
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();
if (updateFirstPerson())
return;
}
float lerpFactor = lookAt ? 10.0f : 6.0f;
vec3 dir;

View File

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

View File

@@ -686,7 +686,7 @@ namespace Core {
// init settings
settings.detail.setFilter (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.audio.music = 0.7f;

View File

@@ -534,7 +534,7 @@ namespace Debug {
Box box = controller->getBoundingBoxLocal();
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;
controller->getSpheres(spheres, count);

View File

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

View File

@@ -167,8 +167,8 @@ struct Lara : Character {
STATE_SURF_BACK,
STATE_SURF_LEFT,
STATE_SURF_RIGHT,
STATE_USE_MIDAS,
STATE_DIE_MIDAS,
STATE_MIDAS_USE,
STATE_MIDAS_DEATH,
STATE_SWAN_DIVE,
STATE_FAST_DIVE,
STATE_HANDSTAND,
@@ -513,6 +513,8 @@ struct Lara : Character {
}
void reset(int room, const vec3 &pos, float angle, Stand forceStand = STAND_GROUND) {
visibleMask = 0xFFFFFFFF;
if (room == TR::NO_ROOM) {
stand = STAND_AIR;
room = getRoomByPos(pos);
@@ -1262,7 +1264,7 @@ struct Lara : Character {
if (box.intersect(m, from, v, t)) {
v = v.normal();
Sphere spheres[34];
Sphere spheres[MAX_SPHERES];
int count;
target->getSpheres(spheres, count);
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) {
int index = Sprite::add(game, TR::Entity::BLOOD, getRoomIndex(), int(sprPos.x), int(sprPos.y), int(sprPos.z), Sprite::FRAME_ANIMATED);
if (index > -1)
@@ -2337,7 +2350,7 @@ struct Lara : Character {
virtual int getStateDeath() {
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() {
@@ -2486,6 +2499,19 @@ struct Lara : Character {
else
if (specular > 0.0f)
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() {
@@ -2878,7 +2904,10 @@ struct Lara : Character {
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;
int frame = animation.frameIndex;
if (frame > 4 ) mask |= BODY_LEG_L3 | BODY_LEG_R3;
@@ -2926,13 +2955,13 @@ struct Lara : Character {
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);
environment->bind(sEnvironment);
Core::setBlending(bmAlpha);
visibleMask = getMidasDeathMask();
visibleMask ^= 0xFFFFFFFF;
Controller::render(frustum, mesh, type, caustics);
visibleMask = 0xFFFFFFFF;
visibleMask ^= 0xFFFFFFFF;
Core::setBlending(bmNone);
}
}

View File

@@ -885,7 +885,7 @@ struct Level : IGame {
type = Shader::MIRROR;
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;
setRoomParams(roomIndex, type, diffuse, intensityf(lum), controller->specular, alpha, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true);
} else

View File

@@ -448,11 +448,11 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
rSpecular *= rShadow;
light += vAmbient + uLightColor[0].xyz * (vLight.x * rShadow);
#endif
#ifdef TYPE_ROOM
light += mix(vAmbient.x, vLight.x, rShadow);
#endif
#ifdef TYPE_SPRITE
light += vLight.x;
#endif