Improve movement, crouching, and add M2 animation

Movement:
- Fix speed controls: Shift=sprint (28), normal run (14), Ctrl=walk (5)
- Reduce character height for doorway clearance (eye height 1.2)
- Add working crouch (C or X key) with smooth transition (eye height 0.6)
- Jump to stand up from crouch

M2 Animation:
- Add animation time tracking per M2 instance
- Add procedural swaying animation in vertex shader
- Update animation each frame for vegetation movement
This commit is contained in:
Kelsi 2026-02-02 23:10:19 -08:00
parent 4287878a73
commit 76a16a214e
5 changed files with 63 additions and 17 deletions

View file

@ -37,7 +37,7 @@ bool M2Renderer::initialize(pipeline::AssetManager* assets) {
LOG_INFO("Initializing M2 renderer...");
// Create M2 shader
// Create M2 shader with simple animation support
const char* vertexSrc = R"(
#version 330 core
layout (location = 0) in vec3 aPos;
@ -47,15 +47,27 @@ bool M2Renderer::initialize(pipeline::AssetManager* assets) {
uniform mat4 uModel;
uniform mat4 uView;
uniform mat4 uProjection;
uniform float uTime;
uniform float uAnimScale; // 0 = no animation, 1 = full animation
out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoord;
void main() {
vec4 worldPos = uModel * vec4(aPos, 1.0);
vec3 pos = aPos;
// Simple swaying animation for vegetation/doodads
// Only animate vertices above ground level (positive Y in model space)
if (uAnimScale > 0.0 && pos.z > 0.5) {
float sway = sin(uTime * 2.0 + pos.x * 0.5 + pos.y * 0.3) * 0.1;
float heightFactor = clamp((pos.z - 0.5) / 3.0, 0.0, 1.0);
pos.x += sway * heightFactor * uAnimScale;
pos.y += sway * 0.5 * heightFactor * uAnimScale;
}
vec4 worldPos = uModel * vec4(pos, 1.0);
FragPos = worldPos.xyz;
// Use mat3(uModel) directly - avoids expensive inverse() per vertex
Normal = mat3(uModel) * aNormal;
TexCoord = aTexCoord;
@ -302,12 +314,20 @@ uint32_t M2Renderer::createInstanceWithMatrix(uint32_t modelId, const glm::mat4&
instance.rotation = glm::vec3(0.0f);
instance.scale = 1.0f;
instance.modelMatrix = modelMatrix;
instance.animTime = static_cast<float>(rand()) / RAND_MAX * 10.0f; // Random start time
instances.push_back(instance);
return instance.id;
}
void M2Renderer::update(float deltaTime) {
// Advance animation time for all instances
for (auto& instance : instances) {
instance.animTime += deltaTime * instance.animSpeed;
}
}
void M2Renderer::render(const Camera& camera, const glm::mat4& view, const glm::mat4& projection) {
(void)camera; // unused for now
@ -371,6 +391,8 @@ void M2Renderer::render(const Camera& camera, const glm::mat4& view, const glm::
}
shader->setUniform("uModel", instance.modelMatrix);
shader->setUniform("uTime", instance.animTime);
shader->setUniform("uAnimScale", 1.0f); // Enable animation for all M2s
glBindVertexArray(model.vao);