Impl. rotation for Walker
All checks were successful
Build and Publish WASM version of demo / Build-And-Deploy (push) Successful in 17s
All checks were successful
Build and Publish WASM version of demo / Build-And-Deploy (push) Successful in 17s
This commit is contained in:
parent
e64f69695c
commit
532654dee0
2 changed files with 132 additions and 38 deletions
|
@ -1,9 +1,13 @@
|
||||||
#include "walker.h"
|
#include "walker.h"
|
||||||
|
|
||||||
|
// standard library includes
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
// third party includes
|
// third party includes
|
||||||
#include <raymath.h>
|
#include <raymath.h>
|
||||||
|
|
||||||
// local includes
|
// local includes
|
||||||
|
#include "3d_helpers.h"
|
||||||
#include "ems.h"
|
#include "ems.h"
|
||||||
|
|
||||||
Walker::Walker(float body_height, float body_feet_radius, float feet_radius)
|
Walker::Walker(float body_height, float body_feet_radius, float feet_radius)
|
||||||
|
@ -25,7 +29,9 @@ Walker::Walker(float body_height, float body_feet_radius, float feet_radius)
|
||||||
body_height(body_height),
|
body_height(body_height),
|
||||||
body_feet_radius(body_feet_radius),
|
body_feet_radius(body_feet_radius),
|
||||||
feet_radius(feet_radius),
|
feet_radius(feet_radius),
|
||||||
lift_start_y(0.0F) {
|
lift_start_y(0.0F),
|
||||||
|
rotation(0.0F),
|
||||||
|
target_rotation(0.0F) {
|
||||||
const Vector3 nw = Vector3Normalize(Vector3{-1.0F, 0.0F, -1.0F});
|
const Vector3 nw = Vector3Normalize(Vector3{-1.0F, 0.0F, -1.0F});
|
||||||
const Vector3 ne = Vector3Normalize(Vector3{1.0F, 0.0F, -1.0F});
|
const Vector3 ne = Vector3Normalize(Vector3{1.0F, 0.0F, -1.0F});
|
||||||
const Vector3 sw = Vector3Normalize(Vector3{-1.0F, 0.0F, 1.0F});
|
const Vector3 sw = Vector3Normalize(Vector3{-1.0F, 0.0F, 1.0F});
|
||||||
|
@ -54,18 +60,77 @@ Walker::Walker(float body_height, float body_feet_radius, float feet_radius)
|
||||||
}
|
}
|
||||||
|
|
||||||
void Walker::draw(const Model &model) {
|
void Walker::draw(const Model &model) {
|
||||||
|
const Matrix rotationMatrix = get_rotation_matrix_about_y(rotation);
|
||||||
// draw body
|
// draw body
|
||||||
DrawModel(model, body_pos, 1.0F, WHITE);
|
DrawModel(Model{.transform = model.transform * rotationMatrix,
|
||||||
|
.meshCount = model.meshCount,
|
||||||
|
.materialCount = model.materialCount,
|
||||||
|
.meshes = model.meshes,
|
||||||
|
.materials = model.materials,
|
||||||
|
.meshMaterial = model.meshMaterial,
|
||||||
|
.boneCount = model.boneCount,
|
||||||
|
.bones = model.bones,
|
||||||
|
.bindPose = model.bindPose},
|
||||||
|
body_pos, 1.0F, WHITE);
|
||||||
|
|
||||||
// draw legs
|
// draw legs
|
||||||
DrawModel(model, leg_nw, 1.0F, WHITE);
|
DrawModel(Model{.transform = model.transform * rotationMatrix,
|
||||||
DrawModel(model, leg_ne, 1.0F, WHITE);
|
.meshCount = model.meshCount,
|
||||||
DrawModel(model, leg_sw, 1.0F, WHITE);
|
.materialCount = model.materialCount,
|
||||||
DrawModel(model, leg_se, 1.0F, WHITE);
|
.meshes = model.meshes,
|
||||||
|
.materials = model.materials,
|
||||||
|
.meshMaterial = model.meshMaterial,
|
||||||
|
.boneCount = model.boneCount,
|
||||||
|
.bones = model.bones,
|
||||||
|
.bindPose = model.bindPose},
|
||||||
|
leg_nw, 1.0F, WHITE);
|
||||||
|
DrawModel(Model{.transform = model.transform * rotationMatrix,
|
||||||
|
.meshCount = model.meshCount,
|
||||||
|
.materialCount = model.materialCount,
|
||||||
|
.meshes = model.meshes,
|
||||||
|
.materials = model.materials,
|
||||||
|
.meshMaterial = model.meshMaterial,
|
||||||
|
.boneCount = model.boneCount,
|
||||||
|
.bones = model.bones,
|
||||||
|
.bindPose = model.bindPose},
|
||||||
|
leg_ne, 1.0F, WHITE);
|
||||||
|
DrawModel(Model{.transform = model.transform * rotationMatrix,
|
||||||
|
.meshCount = model.meshCount,
|
||||||
|
.materialCount = model.materialCount,
|
||||||
|
.meshes = model.meshes,
|
||||||
|
.materials = model.materials,
|
||||||
|
.meshMaterial = model.meshMaterial,
|
||||||
|
.boneCount = model.boneCount,
|
||||||
|
.bones = model.bones,
|
||||||
|
.bindPose = model.bindPose},
|
||||||
|
leg_sw, 1.0F, WHITE);
|
||||||
|
DrawModel(Model{.transform = model.transform * rotationMatrix,
|
||||||
|
.meshCount = model.meshCount,
|
||||||
|
.materialCount = model.materialCount,
|
||||||
|
.meshes = model.meshes,
|
||||||
|
.materials = model.materials,
|
||||||
|
.meshMaterial = model.meshMaterial,
|
||||||
|
.boneCount = model.boneCount,
|
||||||
|
.bones = model.bones,
|
||||||
|
.bindPose = model.bindPose},
|
||||||
|
leg_se, 1.0F, WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Walker::set_body_pos(Vector3 pos) {
|
void Walker::set_body_pos(Vector3 pos) {
|
||||||
target_body_pos = pos;
|
if (!Vector3Equals(target_body_pos, pos)) {
|
||||||
target_body_pos.y += body_height;
|
target_body_pos = pos;
|
||||||
flags &= ~1;
|
target_body_pos.y += body_height;
|
||||||
|
|
||||||
|
Vector3 direction = Vector3Subtract(pos, body_pos);
|
||||||
|
target_rotation = std::atan2(-direction.z, direction.x);
|
||||||
|
while (target_rotation < 0.0F) {
|
||||||
|
target_rotation += PI * 2.0F;
|
||||||
|
}
|
||||||
|
while (target_rotation > PI * 2.0F) {
|
||||||
|
target_rotation -= PI * 2.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags &= ~3;
|
||||||
|
flags |= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
87
src/walker.h
87
src/walker.h
|
@ -3,11 +3,17 @@
|
||||||
|
|
||||||
// standard library includes
|
// standard library includes
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#include <iostream>
|
||||||
|
#endif
|
||||||
|
|
||||||
// third party includes
|
// third party includes
|
||||||
#include <raylib.h>
|
#include <raylib.h>
|
||||||
#include <raymath.h>
|
#include <raymath.h>
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "3d_helpers.h"
|
||||||
|
|
||||||
constexpr float FEET_RADIUS_PLACEMENT_CHECK_SCALE = 1.0F;
|
constexpr float FEET_RADIUS_PLACEMENT_CHECK_SCALE = 1.0F;
|
||||||
constexpr float FEET_RADIUS_PLACEMENT_SCALE = 0.9F;
|
constexpr float FEET_RADIUS_PLACEMENT_SCALE = 0.9F;
|
||||||
constexpr float FEET_TARGET_RATE = 1.0F;
|
constexpr float FEET_TARGET_RATE = 1.0F;
|
||||||
|
@ -16,6 +22,7 @@ constexpr float FEET_LIFT_HEIGHT = 1.0F;
|
||||||
constexpr float FEET_LIFT_SPEED = 5.5F;
|
constexpr float FEET_LIFT_SPEED = 5.5F;
|
||||||
constexpr float FEET_HORIZ_MOVE_SPEED = 8.0F;
|
constexpr float FEET_HORIZ_MOVE_SPEED = 8.0F;
|
||||||
constexpr float FEET_INIT_POS_VARIANCE_DIV = 3.0F;
|
constexpr float FEET_INIT_POS_VARIANCE_DIV = 3.0F;
|
||||||
|
constexpr float BODY_ROTATION_SPEED = 1.0F;
|
||||||
|
|
||||||
class Walker {
|
class Walker {
|
||||||
public:
|
public:
|
||||||
|
@ -46,13 +53,17 @@ class Walker {
|
||||||
// ???1 0??? - is sw
|
// ???1 0??? - is sw
|
||||||
// ???1 1??? - is se
|
// ???1 1??? - is se
|
||||||
unsigned int nw_flags, ne_flags, sw_flags, se_flags;
|
unsigned int nw_flags, ne_flags, sw_flags, se_flags;
|
||||||
// ???? ???1 - body stopped
|
// ???? ??00 - body stopped
|
||||||
|
// ???? ??01 - rotating to move
|
||||||
|
// ???? ??10 - moving
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
|
||||||
const float body_height;
|
const float body_height;
|
||||||
const float body_feet_radius;
|
const float body_feet_radius;
|
||||||
const float feet_radius;
|
const float feet_radius;
|
||||||
float lift_start_y;
|
float lift_start_y;
|
||||||
|
float rotation;
|
||||||
|
float target_rotation;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TBBS>
|
template <typename TBBS>
|
||||||
|
@ -85,24 +96,56 @@ void Walker::update(float dt, const TBBS &bbs, unsigned int width,
|
||||||
se_flags |= 1;
|
se_flags |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// body rotation
|
||||||
|
if ((flags & 3) == 1) {
|
||||||
|
float diff = target_rotation - rotation;
|
||||||
|
if (diff > PI) {
|
||||||
|
rotation -= dt * BODY_ROTATION_SPEED;
|
||||||
|
if (rotation < 0.0F) {
|
||||||
|
rotation += PI * 2.0F;
|
||||||
|
}
|
||||||
|
} else if (diff < -PI) {
|
||||||
|
rotation += dt * BODY_ROTATION_SPEED;
|
||||||
|
if (rotation > PI * 2.0F) {
|
||||||
|
rotation -= PI * 2.0F;
|
||||||
|
}
|
||||||
|
} else if (diff > 0.0F) {
|
||||||
|
rotation += dt * BODY_ROTATION_SPEED;
|
||||||
|
if (rotation > PI * 2.0F) {
|
||||||
|
rotation -= PI * 2.0F;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rotation -= dt * BODY_ROTATION_SPEED;
|
||||||
|
if (rotation < 0.0F) {
|
||||||
|
rotation += PI * 2.0F;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::abs(target_rotation - rotation) < dt * BODY_ROTATION_SPEED) {
|
||||||
|
rotation = target_rotation;
|
||||||
|
flags &= ~3;
|
||||||
|
flags |= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
// body to target pos
|
// body to target pos
|
||||||
if ((flags & 1) == 0) {
|
if ((flags & 3) == 2) {
|
||||||
float diff = Vector3Distance(target_body_pos, body_pos);
|
float diff = Vector3Distance(target_body_pos, body_pos);
|
||||||
body_pos =
|
body_pos =
|
||||||
Vector3Add(body_pos, Vector3Scale(Vector3Normalize(Vector3Subtract(
|
Vector3Add(body_pos, Vector3Scale(Vector3Normalize(Vector3Subtract(
|
||||||
target_body_pos, body_pos)),
|
target_body_pos, body_pos)),
|
||||||
dt * BODY_TARGET_SPEED));
|
dt * BODY_TARGET_SPEED));
|
||||||
if (Vector3Distance(target_body_pos, body_pos) > diff) {
|
if (Vector3Distance(target_body_pos, body_pos) > diff) {
|
||||||
flags |= 1;
|
flags &= ~3;
|
||||||
body_pos = target_body_pos;
|
body_pos = target_body_pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// moving legs
|
// moving legs
|
||||||
const auto update_leg_fn = [this, &bbs, dt](Vector3 &leg_target,
|
const Matrix rotationMatrix = get_rotation_matrix_about_y(rotation);
|
||||||
Vector3 &leg_pos,
|
const auto update_leg_fn = [this, &bbs, dt, &rotationMatrix](
|
||||||
unsigned int &flags,
|
Vector3 &leg_target, Vector3 &leg_pos,
|
||||||
unsigned int grounded_count) {
|
unsigned int &flags,
|
||||||
|
unsigned int grounded_count) {
|
||||||
if ((flags & 7) == 1 && grounded_count > 1) {
|
if ((flags & 7) == 1 && grounded_count > 1) {
|
||||||
// Grounded.
|
// Grounded.
|
||||||
bool should_lift = false;
|
bool should_lift = false;
|
||||||
|
@ -111,16 +154,20 @@ void Walker::update(float dt, const TBBS &bbs, unsigned int width,
|
||||||
Vector3 ideal_foot_pos;
|
Vector3 ideal_foot_pos;
|
||||||
if ((flags & 0x18) == 0) {
|
if ((flags & 0x18) == 0) {
|
||||||
// Is nw.
|
// Is nw.
|
||||||
ideal_foot_pos = Vector3Normalize(Vector3{-1.0F, 0.0F, -1.0F});
|
ideal_foot_pos = Vector3Transform(
|
||||||
|
Vector3Normalize(Vector3{-1.0F, 0.0F, -1.0F}), rotationMatrix);
|
||||||
} else if ((flags & 0x18) == 0x8) {
|
} else if ((flags & 0x18) == 0x8) {
|
||||||
// Is ne.
|
// Is ne.
|
||||||
ideal_foot_pos = Vector3Normalize(Vector3{1.0F, 0.0F, -1.0F});
|
ideal_foot_pos = Vector3Transform(
|
||||||
|
Vector3Normalize(Vector3{1.0F, 0.0F, -1.0F}), rotationMatrix);
|
||||||
} else if ((flags & 0x18) == 0x10) {
|
} else if ((flags & 0x18) == 0x10) {
|
||||||
// Is sw.
|
// Is sw.
|
||||||
ideal_foot_pos = Vector3Normalize(Vector3{-1.0F, 0.0F, 1.0F});
|
ideal_foot_pos = Vector3Transform(
|
||||||
|
Vector3Normalize(Vector3{-1.0F, 0.0F, 1.0F}), rotationMatrix);
|
||||||
} else if ((flags & 0x18) == 0x18) {
|
} else if ((flags & 0x18) == 0x18) {
|
||||||
// Is se.
|
// Is se.
|
||||||
ideal_foot_pos = Vector3Normalize(Vector3{1.0F, 0.0F, 1.0F});
|
ideal_foot_pos = Vector3Transform(
|
||||||
|
Vector3Normalize(Vector3{1.0F, 0.0F, 1.0F}), rotationMatrix);
|
||||||
}
|
}
|
||||||
ideal_foot_pos =
|
ideal_foot_pos =
|
||||||
Vector3Add(body_pos_same_y,
|
Vector3Add(body_pos_same_y,
|
||||||
|
@ -204,24 +251,6 @@ void Walker::update(float dt, const TBBS &bbs, unsigned int width,
|
||||||
update_leg_fn(target_leg_sw, leg_sw, sw_flags,
|
update_leg_fn(target_leg_sw, leg_sw, sw_flags,
|
||||||
((nw_flags & 7) == 1 ? 1 : 0) + ((ne_flags & 7) == 1 ? 1 : 0) +
|
((nw_flags & 7) == 1 ? 1 : 0) + ((ne_flags & 7) == 1 ? 1 : 0) +
|
||||||
((se_flags & 7) == 1 ? 1 : 0));
|
((se_flags & 7) == 1 ? 1 : 0));
|
||||||
|
|
||||||
// legs to target pos
|
|
||||||
// leg_nw =
|
|
||||||
// Vector3Add(leg_nw, Vector3Scale(Vector3Subtract(target_leg_nw,
|
|
||||||
// leg_nw),
|
|
||||||
// dt * FEET_TARGET_RATE));
|
|
||||||
// leg_ne =
|
|
||||||
// Vector3Add(leg_ne, Vector3Scale(Vector3Subtract(target_leg_ne,
|
|
||||||
// leg_ne),
|
|
||||||
// dt * FEET_TARGET_RATE));
|
|
||||||
// leg_sw =
|
|
||||||
// Vector3Add(leg_sw, Vector3Scale(Vector3Subtract(target_leg_sw,
|
|
||||||
// leg_sw),
|
|
||||||
// dt * FEET_TARGET_RATE));
|
|
||||||
// leg_se =
|
|
||||||
// Vector3Add(leg_se, Vector3Scale(Vector3Subtract(target_leg_se,
|
|
||||||
// leg_se),
|
|
||||||
// dt * FEET_TARGET_RATE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue