mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
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:
parent
4287878a73
commit
76a16a214e
5 changed files with 63 additions and 17 deletions
|
|
@ -85,7 +85,9 @@ private:
|
|||
// Gravity / grounding
|
||||
float verticalVelocity = 0.0f;
|
||||
bool grounded = false;
|
||||
float eyeHeight = 1.8f; // WoW human eye height (~2 yard tall character)
|
||||
static constexpr float STAND_EYE_HEIGHT = 1.2f; // Standing eye height
|
||||
static constexpr float CROUCH_EYE_HEIGHT = 0.6f; // Crouching eye height
|
||||
float eyeHeight = STAND_EYE_HEIGHT;
|
||||
float lastGroundZ = 0.0f; // Last known ground height (fallback when no terrain)
|
||||
static constexpr float GRAVITY = -30.0f;
|
||||
static constexpr float JUMP_VELOCITY = 15.0f;
|
||||
|
|
@ -115,11 +117,12 @@ private:
|
|||
// Movement callback
|
||||
MovementCallback movementCallback;
|
||||
|
||||
// Movement speeds (scaled up for better feel)
|
||||
// Movement speeds
|
||||
bool useWoWSpeed = false;
|
||||
static constexpr float WOW_RUN_SPEED = 14.0f; // Double base WoW speed for responsiveness
|
||||
static constexpr float WOW_WALK_SPEED = 5.0f; // Walk (hold Shift)
|
||||
static constexpr float WOW_BACK_SPEED = 9.0f; // Backpedal
|
||||
static constexpr float WOW_RUN_SPEED = 14.0f; // Normal run (WASD)
|
||||
static constexpr float WOW_SPRINT_SPEED = 28.0f; // Sprint (hold Shift)
|
||||
static constexpr float WOW_WALK_SPEED = 5.0f; // Walk (hold Ctrl)
|
||||
static constexpr float WOW_BACK_SPEED = 9.0f; // Backpedal
|
||||
static constexpr float WOW_GRAVITY = -19.29f;
|
||||
static constexpr float WOW_JUMP_VELOCITY = 7.96f;
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,11 @@ struct M2Instance {
|
|||
float scale;
|
||||
glm::mat4 modelMatrix;
|
||||
|
||||
// Animation state
|
||||
float animTime = 0.0f; // Current animation time
|
||||
float animSpeed = 1.0f; // Animation playback speed
|
||||
uint32_t animId = 0; // Current animation sequence
|
||||
|
||||
void updateModelMatrix();
|
||||
};
|
||||
|
||||
|
|
@ -100,6 +105,12 @@ public:
|
|||
uint32_t createInstanceWithMatrix(uint32_t modelId, const glm::mat4& modelMatrix,
|
||||
const glm::vec3& position);
|
||||
|
||||
/**
|
||||
* Update animation state for all instances
|
||||
* @param deltaTime Time since last frame
|
||||
*/
|
||||
void update(float deltaTime);
|
||||
|
||||
/**
|
||||
* Render all visible instances
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -41,13 +41,15 @@ void CameraController::update(float deltaTime) {
|
|||
// Calculate movement speed based on direction and modifiers
|
||||
float speed;
|
||||
if (useWoWSpeed) {
|
||||
// WoW-correct speeds
|
||||
// Movement speeds (Shift = sprint, Ctrl = walk)
|
||||
if (nowBackward && !nowForward) {
|
||||
speed = WOW_BACK_SPEED;
|
||||
} else if (!uiWantsKeyboard && (input.isKeyPressed(SDL_SCANCODE_LSHIFT) || input.isKeyPressed(SDL_SCANCODE_RSHIFT))) {
|
||||
speed = WOW_WALK_SPEED; // Shift = walk in WoW mode
|
||||
speed = WOW_SPRINT_SPEED; // Shift = sprint (faster)
|
||||
} else if (!uiWantsKeyboard && (input.isKeyPressed(SDL_SCANCODE_LCTRL) || input.isKeyPressed(SDL_SCANCODE_RCTRL))) {
|
||||
speed = WOW_WALK_SPEED; // Ctrl = walk (slower)
|
||||
} else {
|
||||
speed = WOW_RUN_SPEED;
|
||||
speed = WOW_RUN_SPEED; // Normal run
|
||||
}
|
||||
} else {
|
||||
// Exploration mode (original behavior)
|
||||
|
|
@ -69,13 +71,18 @@ void CameraController::update(float deltaTime) {
|
|||
right = glm::normalize(right);
|
||||
}
|
||||
|
||||
// Toggle sit with X key (edge-triggered) — only when UI doesn't want keyboard
|
||||
bool xDown = !uiWantsKeyboard && input.isKeyPressed(SDL_SCANCODE_X);
|
||||
// Toggle sit/crouch with X or C key (edge-triggered) — only when UI doesn't want keyboard
|
||||
bool xDown = !uiWantsKeyboard && (input.isKeyPressed(SDL_SCANCODE_X) || input.isKeyPressed(SDL_SCANCODE_C));
|
||||
if (xDown && !xKeyWasDown) {
|
||||
sitting = !sitting;
|
||||
}
|
||||
xKeyWasDown = xDown;
|
||||
|
||||
// Update eye height based on crouch state (smooth transition)
|
||||
float targetEyeHeight = sitting ? CROUCH_EYE_HEIGHT : STAND_EYE_HEIGHT;
|
||||
float heightLerpSpeed = 10.0f * deltaTime;
|
||||
eyeHeight = eyeHeight + (targetEyeHeight - eyeHeight) * std::min(1.0f, heightLerpSpeed);
|
||||
|
||||
// Calculate horizontal movement vector
|
||||
glm::vec3 movement(0.0f);
|
||||
|
||||
|
|
@ -84,10 +91,8 @@ void CameraController::update(float deltaTime) {
|
|||
if (nowStrafeLeft) movement -= right;
|
||||
if (nowStrafeRight) movement += right;
|
||||
|
||||
// Stand up if any movement key is pressed while sitting
|
||||
if (!uiWantsKeyboard && sitting && (input.isKeyPressed(SDL_SCANCODE_W) || input.isKeyPressed(SDL_SCANCODE_S) ||
|
||||
input.isKeyPressed(SDL_SCANCODE_A) || input.isKeyPressed(SDL_SCANCODE_D) ||
|
||||
input.isKeyPressed(SDL_SCANCODE_SPACE))) {
|
||||
// Stand up if jumping while crouched
|
||||
if (!uiWantsKeyboard && sitting && input.isKeyPressed(SDL_SCANCODE_SPACE)) {
|
||||
sitting = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -569,6 +569,11 @@ void Renderer::update(float deltaTime) {
|
|||
characterRenderer->update(deltaTime);
|
||||
}
|
||||
|
||||
// Update M2 doodad animations
|
||||
if (m2Renderer) {
|
||||
m2Renderer->update(deltaTime);
|
||||
}
|
||||
|
||||
// Update zone detection and music
|
||||
if (zoneManager && musicManager && terrainManager && camera) {
|
||||
// First check tile-based zone
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue