Skip to content

Commit

Permalink
#8 trace obstacles for camera, #13 "look-at" triggers, #13 dart mesh,…
Browse files Browse the repository at this point in the history
… smoke & sparks sprite sequences, #15 split long time steps to 1/30 steps
  • Loading branch information
XProger committed Sep 26, 2016
1 parent f22e45a commit ec4216f
Show file tree
Hide file tree
Showing 11 changed files with 533 additions and 297 deletions.
Binary file modified bin/OpenLara.exe
Binary file not shown.
95 changes: 80 additions & 15 deletions src/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,18 +153,17 @@ struct Frustum {


struct Camera : Controller {
Controller *owner;
Frustum *frustum;
Lara *owner;
Frustum *frustum;

float fov, znear, zfar;
vec3 target, destPos, lastDest, angleAdv;
float fov, znear, zfar;
vec3 target, destPos, lastDest, angleAdv;
int room;

int room;

Camera(TR::Level *level, Controller *owner) : Controller(level, owner->entity), owner(owner), frustum(new Frustum()) {
Camera(TR::Level *level, Lara *owner) : Controller(level, owner->entity), owner(owner), frustum(new Frustum()) {
fov = 75.0f;
znear = 0.1f * 2048.0f;
zfar = 1000.0f * 2048.0f;
znear = 128;
zfar = 100.0f * 1024.0f;
angleAdv = vec3(0.0f);

room = owner->getEntity().room;
Expand Down Expand Up @@ -212,18 +211,28 @@ struct Camera : Controller {
angle = owner->angle + angleAdv;
angle.z = 0.0f;
//angle.x = min(max(angle.x, -80 * DEG2RAD), 80 * DEG2RAD);

target = vec3(owner->pos.x, owner->pos.y - height, owner->pos.z);

vec3 dir = getDir();
vec3 dir;
float lerpFactor = 2.0f;
if (owner->targetEntity > -1) {
TR::Entity &e = level->entities[owner->targetEntity];
dir = (vec3(e.x, e.y, e.z) - target).normal();
lerpFactor = 10.0f;
} else
dir = getDir();

if (owner->state != Lara::STATE_BACK_JUMP) {
destPos = target - dir * 1024.0f;
vec3 eye = target - dir * 1024.0f;
destPos = trace(owner->getRoomIndex(), target, eye);
lastDest = destPos;
} else
destPos = lastDest + dir.cross(vec3(0, 1, 0)).normal() * 2048.0f - vec3(0.0f, 512.0f, 0.0f);
} 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);
}

pos = pos.lerp(destPos, min(1.0f, Core::deltaTime * 2.0f));
pos = pos.lerp(destPos, min(1.0f, Core::deltaTime * lerpFactor));

TR::Level::FloorInfo info;
level->getFloorInfo(room, (int)pos.x, (int)pos.z, info);
Expand All @@ -248,6 +257,62 @@ struct Camera : Controller {
}
}

vec3 trace(int fromRoom, const vec3 &from, const vec3 &to) { // TODO: use Bresenham
int room = fromRoom;

vec3 pos = from, dir = to - from;
int px = (int)pos.x, py = (int)pos.y, pz = (int)pos.z;

float dist = dir.length();
dir = dir * (1.0f / dist);

int lx = -1, lz = -1;
TR::Level::FloorInfo info;
while (dist > 1.0f) {
int sx = px / 1024 * 1024 + 512,
sz = pz / 1024 * 1024 + 512;

if (lx != sx || lz != sz) {
level->getFloorInfo(room, sx, sz, info);
lx = sx;
lz = sz;
if (info.roomNext != 0xFF) room = info.roomNext;
}

if (py > info.floor && info.roomBelow != 0xFF)
room = info.roomBelow;
else if (py < info.ceiling && info.roomAbove != 0xFF)
room = info.roomAbove;
else if (py > info.floor || py < info.ceiling) {
int minX = px / 1024 * 1024;
int minZ = pz / 1024 * 1024;
int maxX = minX + 1024;
int maxZ = minZ + 1024;

pos = vec3(clamp(px, minX, maxX), pos.y, clamp(pz, minZ, maxZ)) + boxNormal(px, pz) * 256.0f;
dir = (pos - from).normal();
}

float d = min(dist, 128.0f); // STEP = 128
dist -= d;
pos = pos + dir * d;

px = (int)pos.x, py = (int)pos.y, pz = (int)pos.z;
}

return pos;
}

vec3 boxNormal(int x, int z) {
x %= 1024;
z %= 1024;

if (x > 1024 - z)
return x < z ? vec3(0, 0, 1) : vec3(1, 0, 0);
else
return x < z ? vec3(-1, 0, 0) : vec3(0, 0, -1);
}

void setup() {
Core::mViewInv = mat4(pos, target, vec3(0, -1, 0));
Core::mView = Core::mViewInv.inverse();
Expand Down
64 changes: 51 additions & 13 deletions src/controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ struct Controller {
Controller(TR::Level *level, int entity) : level(level), entity(entity), velocity(0.0f), animTime(0.0f), animPrevFrame(0), health(100), turnTime(0.0f), nextAction(TR::Action::NONE, 0, 0.0f) {
TR::Entity &e = getEntity();
pos = vec3((float)e.x, (float)e.y, (float)e.z);
angle = vec3(0.0f, e.rotation / 16384.0f * PI * 0.5f, 0.0f);
angle = vec3(0.0f, e.rotation, 0.0f);
stand = STAND_GROUND;
animIndex = getModel().animation;
animIndex = e.modelIndex > 0 ? level->models[e.modelIndex - 1].animation : 0;
state = level->anims[animIndex].state;
}

Expand All @@ -63,7 +63,7 @@ struct Controller {
e.x = int(pos.x);
e.y = int(pos.y);
e.z = int(pos.z);
e.rotation = int(angle.y / (PI * 0.5f) * 16384.0f);
e.rotation = angle.y;
}

bool insideRoom(const vec3 &pos, int room) const {
Expand All @@ -80,15 +80,6 @@ struct Controller {
return level->entities[entity];
}

TR::Model& getModel() const {
TR::Entity &entity = getEntity();
for (int i = 0; i < level->modelsCount; i++)
if (entity.id == level->models[i].id)
return level->models[i];
ASSERT(false);
return level->models[0];
}

TR::Room& getRoom() const {
int index = getRoomIndex();
ASSERT(index >= 0 && index < level->roomsCount);
Expand Down Expand Up @@ -337,7 +328,7 @@ struct Controller {
int idx = frame - anim->frameStart;

if (idx > animPrevFrame && idx <= frameIndex) {
if (getEntity().id != ENTITY_ENEMY_BAT) // temporary mute the bat
if (getEntity().id != TR::Entity::ENEMY_BAT) // temporary mute the bat
playSound(id);
}
break;
Expand Down Expand Up @@ -375,4 +366,51 @@ struct Controller {
}
};


struct SpriteController : Controller {

enum {
FRAME_ANIMATED = -1,
FRAME_RANDOM = -2,
};

int frame;
bool instant, animated;

SpriteController(TR::Level *level, int entity, bool instant = true, int frame = FRAME_ANIMATED) : Controller(level, entity), instant(instant), animated(frame == FRAME_ANIMATED) {
if (frame >= 0) { // specific frame
this->frame = frame;
} else if (frame == FRAME_RANDOM) { // random frame
this->frame = rand() % getSequence().sCount;
} else if (frame == FRAME_ANIMATED) { // animated
this->frame = 0;
}
}

TR::SpriteSequence& getSequence() {
return level->spriteSequences[-(getEntity().modelIndex + 1)];
}

void update() {
bool remove = false;
animTime += Core::deltaTime;

if (animated) {
frame = int(animTime * 10.0f);
TR::SpriteSequence &seq = getSequence();
if (instant && frame >= seq.sCount)
remove = true;
else
frame %= seq.sCount;
} else
if (instant && animTime >= 0.1f)
remove = true;

if (remove) {
level->entityRemove(entity);
delete this;
}
}
};

#endif
28 changes: 6 additions & 22 deletions src/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,19 +195,19 @@ namespace Debug {
cmd = (*fd++).cmd;

switch (cmd.func) {
case TR::FD_PORTAL :
case TR::FloorData::PORTAL :
isPortal = true;
fd++;
break; // portal
case TR::FD_FLOOR : // floor & ceiling
case TR::FD_CEILING : {
case TR::FloorData::FLOOR : // floor & ceiling
case TR::FloorData::CEILING : {
TR::FloorData::Slant slant = (*fd++).slant;
int sx = 256 * (int)slant.x;
int sz = 256 * (int)slant.z;

auto &p = cmd.func == 0x02 ? vf : vc;

if (cmd.func == 0x02) { // floor
if (cmd.func == TR::FloorData::FLOOR) { // floor
if (sx > 0) {
p[0].y += sx;
p[3].y += sx;
Expand Down Expand Up @@ -242,28 +242,12 @@ namespace Debug {
}
break;
}
case TR::FD_TRIGGER : {
case TR::FloorData::TRIGGER : {
TR::FloorData::TriggerInfo info = (*fd++).triggerInfo;
TR::FloorData::TriggerCommand trigCmd;
glColor3f(1, 0, 1);
do {
trigCmd = (*fd++).triggerCmd; // trigger action
switch (trigCmd.func) {
case 0 : break; // activate item
case 1 : break; // switch to camera
case 2 : break; // camera delay
case 3 : break; // flip map
case 4 : break; // flip on
case 5 : break; // flip off
case 6 : break; // look at item
case 7 : break; // end level
case 8 : break; // play soundtrack
case 9 : break; // special hadrdcode trigger
case 10 : break; // secret found
case 11 : break; // clear bodies
case 12 : break; // flyby camera sequence
case 13 : break; // play cutscene
}
} while (!trigCmd.end);
break;
}
Expand Down Expand Up @@ -468,7 +452,7 @@ namespace Debug {
matrix.rotateX(controller->angle.x);
matrix.rotateZ(controller->angle.z);
} else
matrix.rotateY(e.rotation / 16384.0f * PI * 0.5f);
matrix.rotateY(e.rotation);

for (int j = 0; j < level.modelsCount; j++) {
TR::Model &m = level.models[j];
Expand Down
Loading

0 comments on commit ec4216f

Please sign in to comment.