From 4a5b3073c3d68cea114c8e91ede9843f5f0ba812 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Tue, 8 Aug 2023 11:33:07 +0900 Subject: [PATCH] Impl. randomized environment --- src/ems.cc | 2 +- src/screen_trunner.cc | 182 +++++++++++++++++++++++++++++++++++------- src/screen_trunner.h | 18 ++++- 3 files changed, 172 insertions(+), 30 deletions(-) diff --git a/src/ems.cc b/src/ems.cc index 16e8e61..8cfbcb2 100644 --- a/src/ems.cc +++ b/src/ems.cc @@ -11,7 +11,7 @@ EM_JS(int, canvas_get_width, (), EM_JS(int, canvas_get_height, (), { return document.getElementById("canvas").clientHeight; }); -EM_JS(int, js_get_random, (), { return Math.random(); }); +EM_JS(float, js_get_random, (), { return Math.random(); }); int call_js_get_canvas_width() { return canvas_get_width(); } diff --git a/src/screen_trunner.cc b/src/screen_trunner.cc index 8c76a62..7bc46c4 100644 --- a/src/screen_trunner.cc +++ b/src/screen_trunner.cc @@ -3,6 +3,7 @@ // standard library includes #include #include +#include #ifndef NDEBUG #include @@ -14,12 +15,11 @@ TRunnerScreen::TRunnerScreen(std::weak_ptr stack) : Screen(stack), + surface(), 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(), - default_material(LoadMaterialDefault()), TEMP_cube_model(LoadModel("res/test_cube.obj")), - plane_mesh(GenMeshPlane(1.0F, 1.0F, 2, 2)), TEMP_cube_texture(LoadTexture("res/test_cube_texture.png")), TEMP_matrix(get_identity_matrix()), camera_pos{0.0F, 4.0F, 4.0F}, @@ -32,13 +32,136 @@ TRunnerScreen::TRunnerScreen(std::weak_ptr stack) TEMP_cube_model.transform = TEMP_cube_model.transform * scale_matrix_xyz(0.5F, 0.5F, 0.5F) * translate_matrix_y(0.5F); + + // Initialize surface. +#ifndef NDEBUG + std::cout << "Initializing surface...\n"; +#endif + std::queue to_update; + to_update.push(SURFACE_UNIT_WIDTH / 2 + + (SURFACE_UNIT_HEIGHT / 2) * SURFACE_UNIT_WIDTH); + while (!to_update.empty()) { + unsigned int idx = to_update.front(); + to_update.pop(); + if (surface.at(idx).has_value()) { + continue; + } + SurfaceUnit current{0.0F, 0.0F, 0.0F, 0.0F}; + // 0000 0001 - nw set + // 0000 0010 - ne set + // 0000 0100 - sw set + // 0000 1000 - se set + unsigned char flags = 0; + + // Check adjacent. + if (idx % SURFACE_UNIT_WIDTH > 0) { + if (surface.at(idx - 1).has_value()) { + if ((flags & 1) == 0) { + current.nw = surface.at(idx - 1).value().ne; + flags |= 1; + } + if ((flags & 4) == 0) { + current.sw = surface.at(idx - 1).value().se; + flags |= 4; + } + } else { + to_update.push(idx - 1); + } + } + if (idx % SURFACE_UNIT_WIDTH < SURFACE_UNIT_WIDTH - 1) { + if (surface.at(idx + 1).has_value()) { + if ((flags & 2) == 0) { + current.ne = surface.at(idx + 1).value().nw; + flags |= 2; + } + if ((flags & 8) == 0) { + current.se = surface.at(idx + 1).value().sw; + flags |= 8; + } + } else { + to_update.push(idx + 1); + } + } + if (idx / SURFACE_UNIT_WIDTH > 0) { + if (surface.at(idx - SURFACE_UNIT_WIDTH).has_value()) { + if ((flags & 1) == 0) { + current.nw = surface.at(idx - SURFACE_UNIT_WIDTH).value().sw; + flags |= 1; + } + if ((flags & 2) == 0) { + current.ne = surface.at(idx - SURFACE_UNIT_WIDTH).value().se; + flags |= 2; + } + } else { + to_update.push(idx - SURFACE_UNIT_WIDTH); + } + } + if (idx / SURFACE_UNIT_WIDTH < SURFACE_UNIT_HEIGHT - 1) { + if (surface.at(idx + SURFACE_UNIT_WIDTH).has_value()) { + if ((flags & 4) == 0) { + current.sw = surface.at(idx + SURFACE_UNIT_WIDTH).value().nw; + flags |= 4; + } + if ((flags & 8) == 0) { + current.se = surface.at(idx + SURFACE_UNIT_WIDTH).value().ne; + flags |= 8; + } + } else { + to_update.push(idx + SURFACE_UNIT_WIDTH); + } + } + + // Calculate remaining values. + float avg = 0.0F; + unsigned int count = 0; + if ((flags & 1) != 0) { + avg += current.nw; + ++count; + } + if ((flags & 2) != 0) { + avg += current.ne; + ++count; + } + if ((flags & 4) != 0) { + avg += current.sw; + ++count; + } + if ((flags & 8) != 0) { + avg += current.se; + ++count; + } + if (count != 0) { + avg = avg / (float)count; + } + + if ((flags & 1) == 0) { + current.nw = avg + call_js_get_random() * SURFACE_HEIGHT_INTERVAL - + SURFACE_HEIGHT_INTERVAL / 2.0F; + } + if ((flags & 2) == 0) { + current.ne = avg + call_js_get_random() * SURFACE_HEIGHT_INTERVAL - + SURFACE_HEIGHT_INTERVAL / 2.0F; + } + if ((flags & 4) == 0) { + current.sw = avg + call_js_get_random() * SURFACE_HEIGHT_INTERVAL - + SURFACE_HEIGHT_INTERVAL / 2.0F; + } + if ((flags & 8) == 0) { + current.se = avg + call_js_get_random() * SURFACE_HEIGHT_INTERVAL - + SURFACE_HEIGHT_INTERVAL / 2.0F; + } + + surface.at(idx) = current; + } + +#ifndef NDEBUG + std::cout << "Screen finished init.\n"; +#endif } TRunnerScreen::~TRunnerScreen() { UnloadTexture(TEMP_cube_texture); - UnloadMesh(plane_mesh); UnloadModel(TEMP_cube_model); - UnloadMaterial(default_material); } bool TRunnerScreen::update(float dt) { @@ -77,33 +200,38 @@ bool TRunnerScreen::draw() { ClearBackground(PixelToColor(Pixel::PIXEL_SKY)); BeginMode3D(camera); - for (int z = -25; z <= 25; ++z) { - for (int x = -25; x <= 25; ++x) { - if (x == (int)(mouse_px > 0.0F ? mouse_px + 0.5F : mouse_px - 0.5F) && - z == (int)(mouse_pz > 0.0F ? mouse_pz + 0.5F : mouse_pz - 0.5F)) { - default_material.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE; - } else { - default_material.maps[MATERIAL_MAP_DIFFUSE].color = - Color{(unsigned char)(200 + x * 2), (unsigned char)(150 + z * 2), - 20, 255}; - } - DrawMesh(plane_mesh, default_material, translate_matrix_xyz(x, 0.0F, z)); - } + for (unsigned int idx = 0; idx < SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT; + ++idx) { + int x = idx % SURFACE_UNIT_WIDTH; + int y = idx / SURFACE_UNIT_WIDTH; + int ox = x - SURFACE_UNIT_WIDTH / 2; + int oy = y - SURFACE_UNIT_HEIGHT / 2; + float xf = (float)(x)-SURFACE_X_OFFSET; + float zf = (float)(y)-SURFACE_Y_OFFSET; + Color color{(unsigned char)(200 + ox * 2), (unsigned char)(150 + oy * 2), + 20, 255}; + auto ¤t = surface[idx]; + DrawTriangle3D(Vector3{xf - 0.5F, current->nw, zf - 0.5F}, + Vector3{xf - 0.5F, current->sw, zf + 0.5F}, + Vector3{xf + 0.5F, current->ne, zf - 0.5F}, color); + DrawTriangle3D(Vector3{xf + 0.5F, current->se, zf + 0.5F}, + Vector3{xf + 0.5F, current->ne, zf - 0.5F}, + Vector3{xf - 0.5F, current->sw, zf + 0.5F}, color); } - DrawModel(Model{.transform = TEMP_cube_model.transform * TEMP_matrix, - .meshCount = TEMP_cube_model.meshCount, - .materialCount = TEMP_cube_model.materialCount, - .meshes = TEMP_cube_model.meshes, - .materials = TEMP_cube_model.materials, - .meshMaterial = TEMP_cube_model.meshMaterial, - .boneCount = TEMP_cube_model.boneCount, - .bones = TEMP_cube_model.bones, - .bindPose = TEMP_cube_model.bindPose}, - Vector3{0.0F, 0.0F, -4.0F}, 1.0F, WHITE); + // DrawModel(Model{.transform = TEMP_cube_model.transform * TEMP_matrix, + // .meshCount = TEMP_cube_model.meshCount, + // .materialCount = TEMP_cube_model.materialCount, + // .meshes = TEMP_cube_model.meshes, + // .materials = TEMP_cube_model.materials, + // .meshMaterial = TEMP_cube_model.meshMaterial, + // .boneCount = TEMP_cube_model.boneCount, + // .bones = TEMP_cube_model.bones, + // .bindPose = TEMP_cube_model.bindPose}, + // Vector3{0.0F, 0.0F, -4.0F}, 1.0F, WHITE); // TODO DEBUG - DrawLine3D(Vector3{0.0F, 0.0F, 0.0F}, Vector3{mouse_px, 0.0F, mouse_pz}, + DrawLine3D(Vector3{0.0F, 3.0F, 0.0F}, Vector3{mouse_px, 0.0F, mouse_pz}, BLACK); EndMode3D(); diff --git a/src/screen_trunner.h b/src/screen_trunner.h index 7d762e1..e688738 100644 --- a/src/screen_trunner.h +++ b/src/screen_trunner.h @@ -6,6 +6,7 @@ // standard library includes #include #include +#include // third party includes #include @@ -13,6 +14,14 @@ 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; +constexpr float SURFACE_Y_OFFSET = (float)SURFACE_UNIT_HEIGHT / 2.0F; + +constexpr float SURFACE_HEIGHT_INTERVAL = 0.5F; + class TRunnerScreen : public Screen { public: TRunnerScreen(std::weak_ptr stack); @@ -38,13 +47,18 @@ class TRunnerScreen : public Screen { PIXEL_WHITE }; + struct SurfaceUnit { + float nw, ne, sw, se; + }; + static Color PixelToColor(Pixel p); + std::array, + SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT> + surface; Camera3D camera; std::bitset<64> flags; - Material default_material; Model TEMP_cube_model; - Mesh plane_mesh; Texture2D TEMP_cube_texture; Matrix TEMP_matrix; Vector3 camera_pos;