diff --git a/src/3d_helpers.cc b/src/3d_helpers.cc index ec4f3ea..b0f67ec 100644 --- a/src/3d_helpers.cc +++ b/src/3d_helpers.cc @@ -160,3 +160,7 @@ std::optional ray_to_plane(const Ray &ray, const Ray &plane) { ray.position.y + ray.direction.y * amount, ray.position.z + ray.direction.z * amount}; } + +Vector3 operator+(const Vector3 &a, const Vector3 &b) { + return Vector3{a.x + b.x, a.y + b.y, a.z + b.z}; +} diff --git a/src/3d_helpers.h b/src/3d_helpers.h index 88b0021..47695b6 100644 --- a/src/3d_helpers.h +++ b/src/3d_helpers.h @@ -31,4 +31,6 @@ extern std::optional ray_to_plane(const Ray &ray, const Ray &plane); // weirdness regarding column-major matrices. // extern Vector4 operator*(const Matrix &m, const Vector4 &v); +extern Vector3 operator+(const Vector3 &a, const Vector3 &b); + #endif diff --git a/src/common_constants.h b/src/common_constants.h new file mode 100644 index 0000000..47e0c0f --- /dev/null +++ b/src/common_constants.h @@ -0,0 +1,10 @@ +#ifndef JUMPARTIFACT_DOT_COM_DEMO_0_COMMON_CONSTANTS_H_ +#define JUMPARTIFACT_DOT_COM_DEMO_0_COMMON_CONSTANTS_H_ + +constexpr unsigned int SURFACE_UNIT_WIDTH = 51; +constexpr unsigned int SURFACE_UNIT_HEIGHT = 51; + +constexpr float SURFACE_X_OFFSET = (float)SURFACE_UNIT_WIDTH / 2.0F - 0.5F; +constexpr float SURFACE_Y_OFFSET = (float)SURFACE_UNIT_HEIGHT / 2.0F - 0.5F; + +#endif diff --git a/src/screen_trunner.cc b/src/screen_trunner.cc index c652728..7d2d132 100644 --- a/src/screen_trunner.cc +++ b/src/screen_trunner.cc @@ -20,7 +20,21 @@ TRunnerScreen::TRunnerScreen(std::weak_ptr stack) : Screen(stack), surface(), surface_bbs(), - walker(), + walkers{Walker{(float)(SURFACE_UNIT_WIDTH / 4) - SURFACE_X_OFFSET, + (float)(SURFACE_UNIT_HEIGHT / 4) - SURFACE_Y_OFFSET, true}, + + Walker{(float)((SURFACE_UNIT_WIDTH / 4) * 3) - SURFACE_X_OFFSET, + (float)(SURFACE_UNIT_HEIGHT / 4) - SURFACE_Y_OFFSET, true}, + + Walker{(float)(SURFACE_UNIT_WIDTH / 4) - SURFACE_X_OFFSET, + (float)((SURFACE_UNIT_HEIGHT / 4) * 3) - SURFACE_Y_OFFSET, + true}, + + Walker{(float)((SURFACE_UNIT_WIDTH / 4) * 3) - SURFACE_X_OFFSET, + (float)((SURFACE_UNIT_HEIGHT / 4) * 3) - SURFACE_Y_OFFSET, + true} + + }, camera{Vector3{0.0F, 1.0F, 0.5F}, Vector3{0.0F, 0.0F, 0.0F}, Vector3{0.0F, 1.0F, 0.0F}, 80.0F, CAMERA_PERSPECTIVE}, flags(), @@ -241,7 +255,6 @@ bool TRunnerScreen::update(float dt) { this->camera_target.y = (current.nw + current.ne + current.sw + current.se) / 4.0F; this->camera_target.z = zf; - this->walker.set_body_pos(this->camera_target); if (idx != SURFACE_UNIT_WIDTH / 2 + (SURFACE_UNIT_HEIGHT / 2) * SURFACE_UNIT_WIDTH) { this->camera_pos = Vector3Add( @@ -273,7 +286,9 @@ bool TRunnerScreen::update(float dt) { camera_to_targets(dt); - walker.update(dt, surface_bbs, SURFACE_UNIT_WIDTH, SURFACE_UNIT_HEIGHT); + for (auto &walker : walkers) { + walker.update(dt, surface_bbs, SURFACE_UNIT_WIDTH, SURFACE_UNIT_HEIGHT); + } return false; } @@ -315,7 +330,9 @@ bool TRunnerScreen::draw() { // .bindPose = TEMP_cube_model.bindPose}, // Vector3{0.0F, 0.0F, -4.0F}, 1.0F, WHITE); - walker.draw(TEMP_cube_model); + for (auto &walker : walkers) { + walker.draw(TEMP_cube_model); + } // TODO DEBUG DrawLine3D(Vector3{0.0F, 3.0F, 0.0F}, mouse_hit, BLACK); diff --git a/src/screen_trunner.h b/src/screen_trunner.h index 24e6c23..d375309 100644 --- a/src/screen_trunner.h +++ b/src/screen_trunner.h @@ -12,17 +12,12 @@ #include // local includes +#include "common_constants.h" #include "walker.h" constexpr float POS_VALUE_INC_RATE = 0.2F; constexpr float CAMERA_UPDATE_RATE = 1.0F; -constexpr unsigned int SURFACE_UNIT_WIDTH = 51; -constexpr unsigned int SURFACE_UNIT_HEIGHT = 51; - -constexpr float SURFACE_X_OFFSET = (float)SURFACE_UNIT_WIDTH / 2.0F - 0.5F; -constexpr float SURFACE_Y_OFFSET = (float)SURFACE_UNIT_HEIGHT / 2.0F - 0.5F; - constexpr float SURFACE_HEIGHT_INTERVAL = 0.7F; class TRunnerScreen : public Screen { @@ -61,7 +56,7 @@ class TRunnerScreen : public Screen { surface; std::array surface_bbs; - Walker walker; + std::array walkers; Camera3D camera; std::bitset<64> flags; diff --git a/src/walker.cc b/src/walker.cc index 57bba25..357670d 100644 --- a/src/walker.cc +++ b/src/walker.cc @@ -10,9 +10,10 @@ #include "3d_helpers.h" #include "ems.h" -Walker::Walker(float body_height, float body_feet_radius, float feet_radius) - : body_pos{0.0F, body_height, 0.0F}, - target_body_pos{0.0F, body_height, 0.0F}, +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}, leg_nw(), leg_ne(), leg_sw(), @@ -32,31 +33,43 @@ Walker::Walker(float body_height, float body_feet_radius, float feet_radius) lift_start_y(0.0F), rotation(0.0F), target_rotation(0.0F), - body_idle_move_timer(0.0F) { + 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; + 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}); - leg_nw = Vector3Add( + const Vector3 offset{x, 0.0F, z}; + + leg_nw = + offset + Vector3{(call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV, 0.0F, - (call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV}, - Vector3Scale(nw, body_feet_radius)); + (call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV} + + Vector3Scale(nw, body_feet_radius); target_leg_nw = leg_nw; - leg_ne = Vector3Add( + leg_ne = + offset + Vector3{(call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV, 0.0F, - (call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV}, - Vector3Scale(ne, body_feet_radius)); + (call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV} + + Vector3Scale(ne, body_feet_radius); target_leg_ne = leg_ne; - leg_sw = Vector3Add( + leg_sw = + offset + Vector3{(call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV, 0.0F, - (call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV}, - Vector3Scale(sw, body_feet_radius)); + (call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV} + + Vector3Scale(sw, body_feet_radius); target_leg_sw = leg_sw; - leg_se = Vector3Add( + leg_se = + offset + Vector3{(call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV, 0.0F, - (call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV}, - Vector3Scale(se, body_feet_radius)); + (call_js_get_random() - 0.5F) / FEET_INIT_POS_VARIANCE_DIV} + + Vector3Scale(se, body_feet_radius); target_leg_se = leg_se; } diff --git a/src/walker.h b/src/walker.h index a0016c8..850cdd1 100644 --- a/src/walker.h +++ b/src/walker.h @@ -13,6 +13,8 @@ // local includes #include "3d_helpers.h" +#include "common_constants.h" +#include "ems.h" constexpr float FEET_RADIUS_PLACEMENT_CHECK_SCALE = 1.0F; constexpr float FEET_RADIUS_PLACEMENT_SCALE = 0.9F; @@ -25,11 +27,13 @@ constexpr float FEET_INIT_POS_VARIANCE_DIV = 3.0F; constexpr float BODY_ROTATION_SPEED = 1.0F; constexpr float BODY_IDLE_TIMER_RATE = 1.0F; constexpr float BODY_IDLE_MOVE_AMOUNT = 0.2F; +constexpr float ROAMING_WAIT_AMOUNT = 2.0F; +constexpr float ROAMING_WAIT_VARIANCE = 7.0F; class Walker { public: - Walker(float body_height = 2.0F, float body_feet_radius = 1.7F, - float feet_radius = 1.5F); + Walker(float x, float z, bool auto_roaming, float body_height = 2.0F, + float body_feet_radius = 1.7F, float feet_radius = 1.5F); template void update(float dt, const TBBS &bbs, unsigned int width, @@ -58,6 +62,7 @@ class Walker { // ???? ??00 - body stopped // ???? ??01 - rotating to move // ???? ??10 - moving + // ???? ?1?? - auto roaming unsigned int flags; const float body_height; @@ -67,11 +72,36 @@ class Walker { float rotation; float target_rotation; float body_idle_move_timer; + float roaming_time; + float roaming_timer; }; template void Walker::update(float dt, const TBBS &bbs, unsigned int width, unsigned int height) { + if ((flags & 4) != 0 && (flags & 3) == 0) { + roaming_timer += dt; + if (roaming_timer > roaming_time) { + roaming_timer = 0.0F; + roaming_time = + call_js_get_random() * ROAMING_WAIT_VARIANCE + ROAMING_WAIT_AMOUNT; + unsigned int idx = call_js_get_random() * (float)bbs.size(); + float x = (float)(idx % width) - SURFACE_X_OFFSET; + float y = 0.0F; + float z = (float)(idx / width) - SURFACE_Y_OFFSET; + + Ray downwards{.position = Vector3{x, 20.0F, z}, + .direction = Vector3{0.0F, -1.0F, 0.0F}}; + for (const auto &bb : bbs) { + if (GetRayCollisionBox(downwards, bb).hit) { + y = (bb.min.y + bb.max.y) / 2.0F; + } + } + + set_body_pos(Vector3{x, y, z}); + } + } + const auto initialized_setup_fn = [&bbs](Vector3 &leg, Vector3 &leg_target) { Ray downwards{.position = leg, .direction = Vector3{0.0F, -1.0F, 0.0F}}; for (const auto &bb : bbs) {