2023-08-10 04:28:45 +00:00
|
|
|
#include "walker.h"
|
|
|
|
|
2023-08-10 06:54:45 +00:00
|
|
|
// standard library includes
|
|
|
|
#include <cmath>
|
|
|
|
|
2023-08-10 04:28:45 +00:00
|
|
|
// third party includes
|
|
|
|
#include <raymath.h>
|
|
|
|
|
|
|
|
// local includes
|
2023-08-10 06:54:45 +00:00
|
|
|
#include "3d_helpers.h"
|
2023-08-10 04:28:45 +00:00
|
|
|
#include "ems.h"
|
|
|
|
|
2023-08-11 03:38:55 +00:00
|
|
|
Walker::Walker(float x, float z, bool auto_roaming, float body_height,
|
|
|
|
float body_feet_radius, float feet_radius)
|
|
|
|
: body_pos{x, body_height, z},
|
|
|
|
target_body_pos{x, body_height, z},
|
2023-08-10 04:28:45 +00:00
|
|
|
leg_nw(),
|
|
|
|
leg_ne(),
|
|
|
|
leg_sw(),
|
|
|
|
leg_se(),
|
|
|
|
target_leg_nw(),
|
|
|
|
target_leg_ne(),
|
|
|
|
target_leg_sw(),
|
|
|
|
target_leg_se(),
|
|
|
|
nw_flags(0x0),
|
|
|
|
ne_flags(0x08),
|
|
|
|
sw_flags(0x10),
|
|
|
|
se_flags(0x18),
|
|
|
|
flags(0),
|
|
|
|
body_height(body_height),
|
|
|
|
body_feet_radius(body_feet_radius),
|
|
|
|
feet_radius(feet_radius),
|
2023-08-10 06:54:45 +00:00
|
|
|
lift_start_y(0.0F),
|
|
|
|
rotation(0.0F),
|
2023-08-11 03:14:48 +00:00
|
|
|
target_rotation(0.0F),
|
2023-08-11 03:38:55 +00:00
|
|
|
body_idle_move_timer(0.0F),
|
|
|
|
roaming_time(5.0F),
|
|
|
|
roaming_timer(0.0F) {
|
|
|
|
flags |= auto_roaming ? 4 : 0;
|
|
|
|
roaming_time =
|
|
|
|
call_js_get_random() * ROAMING_WAIT_VARIANCE + ROAMING_WAIT_AMOUNT;
|
|
|
|
|
2023-08-10 04:28:45 +00:00
|
|
|
const Vector3 nw = 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 se = Vector3Normalize(Vector3{1.0F, 0.0F, 1.0F});
|
|
|
|
|
2023-08-11 03:38:55 +00:00
|
|
|
const Vector3 offset{x, 0.0F, z};
|
|
|
|
|
|
|
|
leg_nw =
|
|
|
|
offset +
|
2023-08-10 04:28:45 +00:00
|
|
|
Vector3{(call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV, 0.0F,
|
2023-08-11 03:38:55 +00:00
|
|
|
(call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV} +
|
|
|
|
Vector3Scale(nw, body_feet_radius);
|
2023-08-10 04:28:45 +00:00
|
|
|
target_leg_nw = leg_nw;
|
2023-08-11 03:38:55 +00:00
|
|
|
leg_ne =
|
|
|
|
offset +
|
2023-08-10 04:28:45 +00:00
|
|
|
Vector3{(call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV, 0.0F,
|
2023-08-11 03:38:55 +00:00
|
|
|
(call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV} +
|
|
|
|
Vector3Scale(ne, body_feet_radius);
|
2023-08-10 04:28:45 +00:00
|
|
|
target_leg_ne = leg_ne;
|
2023-08-11 03:38:55 +00:00
|
|
|
leg_sw =
|
|
|
|
offset +
|
2023-08-10 04:28:45 +00:00
|
|
|
Vector3{(call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV, 0.0F,
|
2023-08-11 03:38:55 +00:00
|
|
|
(call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV} +
|
|
|
|
Vector3Scale(sw, body_feet_radius);
|
2023-08-10 04:28:45 +00:00
|
|
|
target_leg_sw = leg_sw;
|
2023-08-11 03:38:55 +00:00
|
|
|
leg_se =
|
|
|
|
offset +
|
2023-08-10 04:28:45 +00:00
|
|
|
Vector3{(call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV, 0.0F,
|
2023-08-11 03:38:55 +00:00
|
|
|
(call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV} +
|
|
|
|
Vector3Scale(se, body_feet_radius);
|
2023-08-10 04:28:45 +00:00
|
|
|
target_leg_se = leg_se;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Walker::draw(const Model &model) {
|
2023-08-10 06:54:45 +00:00
|
|
|
const Matrix rotationMatrix = get_rotation_matrix_about_y(rotation);
|
2023-08-10 04:28:45 +00:00
|
|
|
// draw body
|
2023-08-10 06:54:45 +00:00
|
|
|
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},
|
2023-08-11 03:14:48 +00:00
|
|
|
Vector3{body_pos.x,
|
|
|
|
body_pos.y + BODY_IDLE_MOVE_AMOUNT *
|
|
|
|
std::sin(body_idle_move_timer + PI),
|
|
|
|
body_pos.z},
|
|
|
|
1.0F, WHITE);
|
2023-08-10 04:28:45 +00:00
|
|
|
|
|
|
|
// draw legs
|
2023-08-10 06:54:45 +00:00
|
|
|
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_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);
|
2023-08-10 04:28:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Walker::set_body_pos(Vector3 pos) {
|
2023-08-11 06:48:16 +00:00
|
|
|
if (!Vector3Equals(Vector3{target_body_pos.x, target_body_pos.y - body_height,
|
|
|
|
target_body_pos.z},
|
|
|
|
pos)) {
|
2023-08-10 06:54:45 +00:00
|
|
|
target_body_pos = pos;
|
|
|
|
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;
|
|
|
|
}
|
2023-08-10 04:28:45 +00:00
|
|
|
}
|