diff --git a/src/controller.h b/src/controller.h index 8307c45..833e0e9 100644 --- a/src/controller.h +++ b/src/controller.h @@ -23,6 +23,9 @@ struct Controller { int *meshes; int mCount; + mat4 *joints; + int frameIndex; + struct ActionCommand { int emitter; TR::Action action; @@ -36,12 +39,16 @@ struct Controller { Controller(TR::Level *level, int entity) : level(level), entity(entity), animation(level, getModel()), state(animation.state), meshes(NULL), mCount(0), actionCommand(NULL) { TR::Entity &e = getEntity(); - pos = vec3((float)e.x, (float)e.y, (float)e.z); - angle = vec3(0.0f, e.rotation, 0.0f); + pos = vec3((float)e.x, (float)e.y, (float)e.z); + angle = vec3(0.0f, e.rotation, 0.0f); + TR::Model *m = getModel(); + joints = m ? new mat4[m->mCount] : NULL; + frameIndex = -1; } virtual ~Controller() { delete[] meshes; + delete[] joints; } void initMeshOverrides() { @@ -395,11 +402,9 @@ struct Controller { updateAnimation(true); } - void renderMesh(const mat4 &matrix, MeshBuilder *mesh, uint32 offsetIndex) { + void renderMesh(MeshBuilder *mesh, uint32 offsetIndex) { MeshBuilder::MeshInfo *mInfo = mesh->meshMap[offsetIndex]; if (!mInfo) return; // invisible mesh (offsetIndex > 0 && level.meshOffsets[offsetIndex] == 0) camera target entity etc. - - Core::active.shader->setParam(uModel, matrix); mesh->renderMesh(mInfo); } @@ -438,14 +443,19 @@ struct Controller { TR::Entity &entity = getEntity(); TR::Model *model = getModel(); + ASSERT(model); + entity.flags.rendered = true; - mat4 joints[32]; // TODO: UBO heap - ASSERT(model->mCount <= 32); + if (Core::frameIndex != frameIndex) + animation.getJoints(matrix, -1, true, joints); + + Core::active.shader->setParam(uModel, joints[0], model->mCount); - animation.getJoints(matrix, -1, true, joints); for (int i = 0; i < model->mCount; i++) - renderMesh(joints[i], mesh, meshes ? meshes[i] : (model->mStart + i)); + renderMesh(mesh, meshes ? meshes[i] : (model->mStart + i)); + + frameIndex = Core::frameIndex; /* // blob shadow if (TR::castShadow(entity.type)) { diff --git a/src/core.h b/src/core.h index 7f3f22b..fcc99ac 100644 --- a/src/core.h +++ b/src/core.h @@ -132,6 +132,7 @@ struct Texture; namespace Core { int width, height; + int frameIndex; float deltaTime; mat4 mView, mProj, mViewProj, mViewInv, mModel, mLightProj; vec3 viewPos; @@ -252,6 +253,8 @@ namespace Core { for (int i = 0; i < MAX_LIGHTS; i++) lightColor[i] = vec4(0, 0, 0, 1); + + frameIndex = 0; } void free() { diff --git a/src/game.h b/src/game.h index f73b2f5..a1417c6 100644 --- a/src/game.h +++ b/src/game.h @@ -44,6 +44,7 @@ namespace Game { void render() { level->render(); + Core::frameIndex++; } } diff --git a/src/lara.h b/src/lara.h index 89601a8..8cbccc7 100644 --- a/src/lara.h +++ b/src/lara.h @@ -1761,7 +1761,8 @@ struct Lara : Character { m.translate(offset); Core::active.shader->setParam(uColor, vec4(lum, lum, lum, alpha)); - renderMesh(m, mesh, level->extra.muzzleFlash->mStart); + Core::active.shader->setParam(uModel, m); + renderMesh(mesh, level->extra.muzzleFlash->mStart); } virtual void render(Frustum *frustum, MeshBuilder *mesh) { diff --git a/src/mesh.h b/src/mesh.h index 3cdbe4c..e96d800 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -323,6 +323,17 @@ struct MeshBuilder { if (info.offset == level.meshOffsets[j]) meshMap[j] = &info; + int16 joint = 0; + for (int j = 0; j < level.modelsCount; j++) { + TR::Model &m = level.models[j]; + for (int k = m.mStart; k < m.mStart + m.mCount; k++) { + if (mesh.offset == level.meshOffsets[k]) { + joint = k - m.mStart; + break; + } + } + } + int vStart = vCount; for (int j = 0; j < mesh.rCount; j++) { TR::Rectangle &f = mesh.rectangles[j]; @@ -335,7 +346,7 @@ struct MeshBuilder { for (int k = 0; k < 4; k++) { TR::Mesh::Vertex &v = mesh.vertices[f.vertices[k]]; - vertices[vCount].coord = v.coord; + vertices[vCount].coord = { v.coord.x, v.coord.y, v.coord.z, joint }; vertices[vCount].normal = v.normal; vertices[vCount].color = { c.r, c.g, c.b, intensity(v.coord.w) }; @@ -354,7 +365,7 @@ struct MeshBuilder { for (int k = 0; k < 3; k++) { TR::Mesh::Vertex &v = mesh.vertices[f.vertices[k]]; - vertices[vCount].coord = v.coord; + vertices[vCount].coord = { v.coord.x, v.coord.y, v.coord.z, joint }; vertices[vCount].normal = v.normal; vertices[vCount].color = { c.r, c.g, c.b, intensity(v.coord.w) }; diff --git a/src/shader.glsl b/src/shader.glsl index 4976ee8..f7d0f52 100644 --- a/src/shader.glsl +++ b/src/shader.glsl @@ -26,7 +26,7 @@ uniform int uType; #ifdef VERTEX uniform mat4 uViewProj; - uniform mat4 uModel; + uniform mat4 uModel[32]; #ifndef PASS_AMBIENT uniform mat4 uViewInv; @@ -54,7 +54,9 @@ uniform int uType; #define TEXCOORD_SCALE (1.0 / 32767.0) void main() { - vec4 coord = uModel * vec4(aCoord.xyz, 1.0); + mat4 rJoint = uModel[int(aCoord.w)]; + + vec4 coord = rJoint * vec4(aCoord.xyz, 1.0); #ifdef PASS_COMPOSE if (uType != TYPE_SPRITE) { @@ -65,7 +67,7 @@ uniform int uType; vec2 offset = uAnimTexOffsets[int(range.x + f)]; // texCoord offset from first frame vTexCoord = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated - vNormal = vec4((uModel * vec4(aNormal.xyz, 0.0)).xyz, aNormal.w); + vNormal = vec4((rJoint * vec4(aNormal.xyz, 0.0)).xyz, aNormal.w); } else { coord.xyz += uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w; vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;