mirror of
https://github.com/XProger/OpenLara.git
synced 2025-02-23 06:53:00 +01:00
TR4 Lara's joints mesh
This commit is contained in:
parent
15d8bd5c3d
commit
4ae25e37a6
@ -272,7 +272,7 @@ struct Character : Controller {
|
||||
}
|
||||
|
||||
void addSparks(uint32 mask) {
|
||||
Sphere spheres[MAX_SPHERES];
|
||||
Sphere spheres[MAX_JOINTS];
|
||||
int count = getSpheres(spheres);
|
||||
for (int i = 0; i < count; i++)
|
||||
if (mask & (1 << i)) {
|
||||
|
@ -10,7 +10,6 @@
|
||||
#define SPRITE_FPS 10.0f
|
||||
|
||||
#define MAX_LAYERS 4
|
||||
#define MAX_SPHERES 32
|
||||
|
||||
#define UNLIMITED_AMMO 10000
|
||||
|
||||
@ -831,7 +830,7 @@ struct Controller {
|
||||
|
||||
int getSpheres(Sphere *spheres) {
|
||||
const TR::Model *m = getModel();
|
||||
ASSERT(m->mCount <= MAX_SPHERES);
|
||||
ASSERT(m->mCount <= MAX_JOINTS);
|
||||
|
||||
int jFrame = jointsFrame;
|
||||
updateJoints();
|
||||
@ -848,7 +847,7 @@ struct Controller {
|
||||
}
|
||||
|
||||
Box getSpheresBox(bool local = false) {
|
||||
Sphere spheres[MAX_SPHERES];
|
||||
Sphere spheres[MAX_JOINTS];
|
||||
int count = getSpheres(spheres);
|
||||
if (count) {
|
||||
|
||||
@ -880,8 +879,8 @@ struct Controller {
|
||||
ASSERT(a->mCount <= 34);
|
||||
ASSERT(b->mCount <= 34);
|
||||
|
||||
Sphere aSpheres[MAX_SPHERES];
|
||||
Sphere bSpheres[MAX_SPHERES];
|
||||
Sphere aSpheres[MAX_JOINTS];
|
||||
Sphere bSpheres[MAX_JOINTS];
|
||||
|
||||
int aCount = getSpheres(aSpheres);
|
||||
int bCount = controller->getSpheres(bSpheres);
|
||||
|
@ -624,7 +624,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[MAX_SPHERES];
|
||||
Sphere spheres[MAX_JOINTS];
|
||||
int count = controller->getSpheres(spheres);
|
||||
|
||||
for (int joint = 0; joint < count; joint++) {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define MAX_TRIGGER_COMMANDS 32
|
||||
#define MAX_MESHES 512
|
||||
#define MAX_WEAPONS 4
|
||||
#define MAX_JOINTS 32
|
||||
|
||||
// Lara's height in units / height in meters
|
||||
#define ONE_METER (768.0f / 1.8f)
|
||||
@ -2405,7 +2406,7 @@ namespace TR {
|
||||
REMAP_4( AI_MODIFY );
|
||||
REMAP_4( AI_FOLLOW );
|
||||
REMAP_4( KILL_ALL_TRIGGERS );
|
||||
REMAP_4( GLYPHS );
|
||||
//REMAP_4( GLYPHS );
|
||||
REMAP_4( MISC_SPRITES );
|
||||
|
||||
default : return type;
|
||||
@ -3107,6 +3108,7 @@ namespace TR {
|
||||
int16 braid;
|
||||
int16 laraSpec;
|
||||
int16 laraSkin;
|
||||
int16 laraJoints;
|
||||
int16 meshSwap[3];
|
||||
int16 sky;
|
||||
int16 smoke;
|
||||
@ -4778,6 +4780,7 @@ namespace TR {
|
||||
case Entity::LARA_BRAID : extra.braid = i; break;
|
||||
case Entity::LARA_SPEC : extra.laraSpec = i; break;
|
||||
case Entity::LARA_SKIN : extra.laraSkin = i; break;
|
||||
case Entity::LARA_SKIN_JOINTS : extra.laraJoints = i; break;
|
||||
case Entity::CUT_1 : extra.meshSwap[0] = i; break;
|
||||
case Entity::CUT_2 : extra.meshSwap[1] = i; break;
|
||||
case Entity::CUT_3 : extra.meshSwap[2] = i; break;
|
||||
@ -4839,7 +4842,7 @@ namespace TR {
|
||||
default : ;
|
||||
}
|
||||
|
||||
ASSERT(extra.glyphs != -1);
|
||||
//ASSERT(extra.glyphs != -1);
|
||||
}
|
||||
|
||||
void initCutscene() {
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "core.h"
|
||||
|
||||
#if defined(_DEBUG) || defined(PROFILE)
|
||||
//#define _DEBUG_SHADERS
|
||||
//#define _DEBUG_SHADERS "../../OpenLara/src/shaders/"
|
||||
#endif
|
||||
|
||||
#ifdef _OS_WIN
|
||||
@ -521,13 +521,13 @@ namespace GAPI {
|
||||
#ifdef _DEBUG_SHADERS
|
||||
Stream *stream = NULL;
|
||||
switch (pass) {
|
||||
case Core::passCompose : stream = new Stream("../../src/shaders/compose.glsl"); break;
|
||||
case Core::passShadow : stream = new Stream("../../src/shaders/shadow.glsl"); break;
|
||||
case Core::passAmbient : stream = new Stream("../../src/shaders/ambient.glsl"); break;
|
||||
case Core::passSky : stream = new Stream("../../src/shaders/sky.glsl"); break;
|
||||
case Core::passWater : stream = new Stream("../../src/shaders/water.glsl"); break;
|
||||
case Core::passFilter : stream = new Stream("../../src/shaders/filter.glsl"); break;
|
||||
case Core::passGUI : stream = new Stream("../../src/shaders/gui.glsl"); break;
|
||||
case Core::passCompose : stream = new Stream(_DEBUG_SHADERS "compose.glsl"); break;
|
||||
case Core::passShadow : stream = new Stream(_DEBUG_SHADERS "shadow.glsl"); break;
|
||||
case Core::passAmbient : stream = new Stream(_DEBUG_SHADERS "ambient.glsl"); break;
|
||||
case Core::passSky : stream = new Stream(_DEBUG_SHADERS "sky.glsl"); break;
|
||||
case Core::passWater : stream = new Stream(_DEBUG_SHADERS "water.glsl"); break;
|
||||
case Core::passFilter : stream = new Stream(_DEBUG_SHADERS "filter.glsl"); break;
|
||||
case Core::passGUI : stream = new Stream(_DEBUG_SHADERS "gui.glsl"); break;
|
||||
default : ASSERT(false); return;
|
||||
}
|
||||
|
||||
|
@ -545,7 +545,7 @@ struct Inventory {
|
||||
|
||||
TR::Level *level = game->getLevel();
|
||||
TR::Model &m = level->models[desc.model];
|
||||
Basis joints[MAX_SPHERES];
|
||||
Basis joints[MAX_JOINTS];
|
||||
|
||||
mat4 matrix;
|
||||
matrix.identity();
|
||||
|
12
src/lara.h
12
src/lara.h
@ -1506,7 +1506,7 @@ struct Lara : Character {
|
||||
if (box.intersect(m, from, v, t)) {
|
||||
t *= v.length();
|
||||
v = v.normal();
|
||||
Sphere spheres[MAX_SPHERES];
|
||||
Sphere spheres[MAX_JOINTS];
|
||||
int count = target->getSpheres(spheres);
|
||||
for (int i = 0; i < count; i++) {
|
||||
float st;
|
||||
@ -3779,6 +3779,16 @@ struct Lara : Character {
|
||||
if (Core::pass != Core::passShadow && camera->firstPerson && camera->viewIndex == -1 && game->getCamera() == camera) // hide head in first person view // TODO: fix for firstPerson with viewIndex always == -1
|
||||
visibleMask &= ~JOINT_MASK_HEAD;
|
||||
Controller::render(frustum, mesh, type, caustics);
|
||||
|
||||
if (level->extra.laraJoints > -1) {
|
||||
const TR::Model *model = getModel();
|
||||
for (int i = 0; i < model->mCount; i++) {
|
||||
joints[i].w = 1.0f;
|
||||
}
|
||||
Core::setBasis(joints, model->mCount);
|
||||
mesh->renderModel(level->extra.laraJoints, caustics);
|
||||
}
|
||||
|
||||
visibleMask = visMask;
|
||||
|
||||
if (braid)
|
||||
|
@ -3052,7 +3052,7 @@ struct Level : IGame {
|
||||
setDefaultTarget(eye, view, invBG);
|
||||
|
||||
if (Core::settings.detail.stereo == Core::Settings::STEREO_SPLIT) {
|
||||
camera->aspect = setViewport(invBG ? -1 : view, invBG ? 0 : eye);
|
||||
camera->aspect = setViewport(invBG ? -1 : view, invBG ? 0 : eye);
|
||||
} else {
|
||||
camera->aspect = setViewport(view, invBG ? 0 : eye);
|
||||
}
|
||||
|
75
src/mesh.h
75
src/mesh.h
@ -166,6 +166,8 @@ struct MeshBuilder {
|
||||
struct ModelRange {
|
||||
int parts[3][32];
|
||||
Geometry geometry[3];
|
||||
int vStart;
|
||||
int vCount;
|
||||
} *models;
|
||||
|
||||
// procedured
|
||||
@ -260,8 +262,10 @@ struct MeshBuilder {
|
||||
}
|
||||
|
||||
// get models info
|
||||
int vStartModel = vCount;
|
||||
models = new ModelRange[level->modelsCount];
|
||||
for (int i = 0; i < level->modelsCount; i++) {
|
||||
models[i].vStart = vCount;
|
||||
TR::Model &model = level->models[i];
|
||||
for (int j = 0; j < model.mCount; j++) {
|
||||
int index = level->meshOffsets[model.mStart + j];
|
||||
@ -271,6 +275,8 @@ struct MeshBuilder {
|
||||
iCount += (mesh.rCount * 6 + mesh.tCount * 3) * DOUBLE_SIDED;
|
||||
vCount += (mesh.rCount * 4 + mesh.tCount * 3);
|
||||
}
|
||||
models[i].vCount = vCount - models[i].vStart;
|
||||
models[i].vStart -= vStartModel;
|
||||
}
|
||||
|
||||
// shadow blob mesh (8 triangles, 8 vertices)
|
||||
@ -381,12 +387,11 @@ struct MeshBuilder {
|
||||
ASSERT(vCount - vStartRoom <= 0xFFFF);
|
||||
|
||||
// build models geometry
|
||||
int vStartModel = vCount;
|
||||
vStartModel = vCount;
|
||||
aCount++;
|
||||
|
||||
for (int i = 0; i < level->modelsCount; i++) {
|
||||
TR::Model &model = level->models[i];
|
||||
|
||||
int vCountStart = vCount;
|
||||
|
||||
for (int transp = 0; transp < 3; transp++) {
|
||||
@ -442,6 +447,9 @@ struct MeshBuilder {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
weldSkinJoints(vertices + vStartModel);
|
||||
|
||||
ASSERT(vCount - vStartModel <= 0xFFFF);
|
||||
|
||||
// build common primitives
|
||||
@ -688,6 +696,69 @@ struct MeshBuilder {
|
||||
return false;
|
||||
}
|
||||
|
||||
void weldSkinJoints(Vertex *vertices) {
|
||||
if (level->extra.laraSkin == -1 || level->extra.laraJoints == -1) {
|
||||
return;
|
||||
}
|
||||
int t = Core::getTime();
|
||||
ASSERT(level->models[level->extra.laraSkin].mCount == level->models[level->extra.laraJoints].mCount);
|
||||
|
||||
const TR::Model *model = level->models + level->extra.laraSkin;
|
||||
const TR::Node *node = (TR::Node*)level->nodesData + model->node;
|
||||
|
||||
int sIndex = 0;
|
||||
short4 stack[16];
|
||||
short4 pos(0, 0, 0, 0);
|
||||
short4 jointsPos[MAX_JOINTS];
|
||||
|
||||
for (int i = 0; i < model->mCount; i++) {
|
||||
if (i > 0 && node) {
|
||||
const TR::Node &t = node[i - 1];
|
||||
if (t.flags & 0x01) pos = stack[--sIndex];
|
||||
if (t.flags & 0x02) stack[sIndex++] = pos;
|
||||
pos.x += t.x;
|
||||
pos.y += t.y;
|
||||
pos.z += t.z;
|
||||
}
|
||||
jointsPos[i] = pos;
|
||||
}
|
||||
|
||||
const ModelRange &rangeSkin = models[level->extra.laraSkin];
|
||||
const ModelRange &rangeJoints = models[level->extra.laraJoints];
|
||||
|
||||
#define COORD_FILL(VAR,RANGE)\
|
||||
short4 *VAR = new short4[RANGE.vCount];\
|
||||
for (int i = 0; i < RANGE.vCount; i++) {\
|
||||
VAR[i] = vertices[RANGE.vStart + i].coord;\
|
||||
VAR[i].x += jointsPos[VAR[i].w].x;\
|
||||
VAR[i].y += jointsPos[VAR[i].w].y;\
|
||||
VAR[i].z += jointsPos[VAR[i].w].z;\
|
||||
}
|
||||
|
||||
COORD_FILL(vSkin, rangeSkin);
|
||||
COORD_FILL(vJoints, rangeJoints);
|
||||
|
||||
// bruteforce :(
|
||||
for (int j = 0; j < rangeJoints.vCount; j++) {
|
||||
for (int i = 0; i < rangeSkin.vCount; i++) {
|
||||
if (abs(vSkin[i].x - vJoints[j].x) <= 1 &&
|
||||
abs(vSkin[i].y - vJoints[j].y) <= 1 &&
|
||||
abs(vSkin[i].z - vJoints[j].z) <= 1) { // compare position
|
||||
vertices[rangeJoints.vStart + j].coord = vertices[rangeSkin.vStart + i].coord; // set bone index
|
||||
vertices[rangeJoints.vStart + j].normal = vertices[rangeSkin.vStart + i].normal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete[] vSkin;
|
||||
delete[] vJoints;
|
||||
|
||||
#undef COORD_FILL
|
||||
|
||||
LOG("remap joints: %d\n", Core::getTime() - t);
|
||||
}
|
||||
|
||||
int calcWaterLevel(int16 roomIndex, bool flip) {
|
||||
TR::Room &room = level->rooms[roomIndex];
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user