aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/CMakeLists.txt2
-rw-r--r--apps/openmb/CMakeLists.txt45
-rw-r--r--apps/openmb/ImguiStyle.hpp80
-rw-r--r--apps/openmb/main.cpp1753
-rw-r--r--apps/openmb/renderer/DirectionalLight.cpp39
-rw-r--r--apps/openmb/renderer/DirectionalLight.hpp28
-rw-r--r--apps/openmb/renderer/EditorHelpers.cpp148
-rw-r--r--apps/openmb/renderer/EditorHelpers.hpp20
-rw-r--r--apps/openmb/renderer/GLHelpers.cpp30
-rw-r--r--apps/openmb/renderer/GLHelpers.hpp14
-rw-r--r--apps/openmb/renderer/Mesh.cpp147
-rw-r--r--apps/openmb/renderer/Mesh.hpp41
-rw-r--r--apps/openmb/renderer/Model.cpp227
-rw-r--r--apps/openmb/renderer/Model.hpp51
-rw-r--r--apps/openmb/renderer/SSAORenderer.cpp319
-rw-r--r--apps/openmb/renderer/SSAORenderer.hpp64
-rw-r--r--apps/openmb/renderer/Shader.cpp137
-rw-r--r--apps/openmb/renderer/Shader.hpp31
-rw-r--r--apps/openmb/renderer/Skybox.cpp155
-rw-r--r--apps/openmb/renderer/Skybox.hpp34
-rw-r--r--apps/openmb/renderer/Texture.cpp53
-rw-r--r--apps/openmb/renderer/Texture.hpp28
-rw-r--r--apps/openmb/renderer/TextureManager.cpp163
-rw-r--r--apps/openmb/renderer/TextureManager.hpp64
-rw-r--r--apps/openmb/renderer/primitives.cpp595
-rw-r--r--apps/openmb/renderer/primitives.hpp22
-rw-r--r--apps/openmb/resources/levels/default.json24701
-rw-r--r--apps/openmb/resources/models/rocks/Rocks_lp_SM_Rock_01_BaseMap.pngbin0 -> 2309127 bytes
-rw-r--r--apps/openmb/resources/models/rocks/Rocks_lp_SM_Rock_01_Normal.pngbin0 -> 1455542 bytes
-rw-r--r--apps/openmb/resources/models/rocks/SM_Rocks_01.obj143
-rw-r--r--apps/openmb/resources/models/rocks/SM_Rocks_02.obj723
-rw-r--r--apps/openmb/resources/models/rocks/SM_Rocks_03.obj1013
-rw-r--r--apps/openmb/resources/models/rocks/SM_Rocks_04.obj373
-rw-r--r--apps/openmb/resources/models/rocks/SM_Rocks_05.obj283
-rw-r--r--apps/openmb/resources/shaders/.gitkeep0
-rw-r--r--apps/openmb/resources/shaders/cube.frag21
-rw-r--r--apps/openmb/resources/shaders/cube.vert11
-rw-r--r--apps/openmb/resources/shaders/depth.frag5
-rw-r--r--apps/openmb/resources/shaders/depth.vert10
-rw-r--r--apps/openmb/resources/shaders/gbuffer.frag10
-rw-r--r--apps/openmb/resources/shaders/gbuffer.vert19
-rw-r--r--apps/openmb/resources/shaders/godrays_quad.vert11
-rw-r--r--apps/openmb/resources/shaders/godrays_radial.frag44
-rw-r--r--apps/openmb/resources/shaders/occlusion.frag8
-rw-r--r--apps/openmb/resources/shaders/occlusion.vert11
-rw-r--r--apps/openmb/resources/shaders/skybox.frag8
-rw-r--r--apps/openmb/resources/shaders/skybox.vert10
-rw-r--r--apps/openmb/resources/shaders/ssao.frag76
-rw-r--r--apps/openmb/resources/shaders/ssao.vert9
-rw-r--r--apps/openmb/resources/shaders/ssao_blur.frag45
-rw-r--r--apps/openmb/resources/shaders/textured.frag45
-rw-r--r--apps/openmb/resources/shaders/textured.vert23
-rw-r--r--apps/openmb/resources/shaders/textured_lit.frag121
-rw-r--r--apps/openmb/resources/skybox/Daylight-Back.bmpbin0 -> 786486 bytes
-rw-r--r--apps/openmb/resources/skybox/Daylight-Bottom.bmpbin0 -> 786486 bytes
-rw-r--r--apps/openmb/resources/skybox/Daylight-Front.bmpbin0 -> 786486 bytes
-rw-r--r--apps/openmb/resources/skybox/Daylight-Left.bmpbin0 -> 786486 bytes
-rw-r--r--apps/openmb/resources/skybox/Daylight-Right.bmpbin0 -> 786486 bytes
-rw-r--r--apps/openmb/resources/skybox/Daylight-Top.bmpbin0 -> 786486 bytes
-rw-r--r--apps/openmb/resources/textures/brush/basic/blue.tgabin0 -> 21 bytes
-rw-r--r--apps/openmb/resources/textures/testing/dark/texture_01.pngbin0 -> 2774 bytes
-rw-r--r--apps/openmb/resources/textures/testing/dark/texture_02.pngbin0 -> 1338 bytes
-rw-r--r--apps/openmb/resources/textures/testing/dark/texture_03.pngbin0 -> 2727 bytes
-rw-r--r--apps/openmb/resources/textures/testing/dark/texture_04.pngbin0 -> 13212 bytes
-rw-r--r--apps/openmb/resources/textures/testing/dark/texture_05.pngbin0 -> 19065 bytes
-rw-r--r--apps/openmb/resources/textures/testing/dark/texture_06.pngbin0 -> 2739 bytes
-rw-r--r--apps/openmb/resources/textures/testing/dark/texture_07.pngbin0 -> 2743 bytes
-rw-r--r--apps/openmb/resources/textures/testing/dark/texture_08.pngbin0 -> 637 bytes
-rw-r--r--apps/openmb/resources/textures/testing/dark/texture_09.pngbin0 -> 2838 bytes
-rw-r--r--apps/openmb/resources/textures/testing/dark/texture_10.pngbin0 -> 9183 bytes
-rw-r--r--apps/openmb/resources/textures/testing/dark/texture_11.pngbin0 -> 9048 bytes
-rw-r--r--apps/openmb/resources/textures/testing/dark/texture_12.pngbin0 -> 9585 bytes
-rw-r--r--apps/openmb/resources/textures/testing/dark/texture_13.pngbin0 -> 9867 bytes
-rw-r--r--apps/openmb/resources/textures/testing/light/texture_01.pngbin0 -> 1338 bytes
-rw-r--r--apps/openmb/resources/textures/testing/light/texture_02.pngbin0 -> 2727 bytes
-rw-r--r--apps/openmb/resources/textures/testing/light/texture_03.pngbin0 -> 13212 bytes
-rw-r--r--apps/openmb/resources/textures/testing/light/texture_04.pngbin0 -> 15848 bytes
-rw-r--r--apps/openmb/resources/textures/testing/light/texture_05.pngbin0 -> 2739 bytes
-rw-r--r--apps/openmb/resources/textures/testing/light/texture_06.pngbin0 -> 2743 bytes
-rw-r--r--apps/openmb/resources/textures/testing/light/texture_07.pngbin0 -> 637 bytes
-rw-r--r--apps/openmb/resources/textures/testing/light/texture_08.pngbin0 -> 2838 bytes
-rw-r--r--apps/openmb/resources/textures/testing/light/texture_09.pngbin0 -> 9102 bytes
-rw-r--r--apps/openmb/resources/textures/testing/light/texture_10.pngbin0 -> 8958 bytes
-rw-r--r--apps/openmb/resources/textures/testing/light/texture_11.pngbin0 -> 9494 bytes
-rw-r--r--apps/openmb/resources/textures/testing/light/texture_12.pngbin0 -> 9076 bytes
-rw-r--r--apps/openmb/resources/textures/testing/light/texture_13.pngbin0 -> 2774 bytes
-rw-r--r--apps/openmb/resources/textures/testing/orange/texture_01.pngbin0 -> 9912 bytes
-rw-r--r--apps/openmb/resources/textures/testing/orange/texture_02.pngbin0 -> 2774 bytes
-rw-r--r--apps/openmb/resources/textures/testing/orange/texture_03.pngbin0 -> 1338 bytes
-rw-r--r--apps/openmb/resources/textures/testing/orange/texture_04.pngbin0 -> 2727 bytes
-rw-r--r--apps/openmb/resources/textures/testing/orange/texture_05.pngbin0 -> 13212 bytes
-rw-r--r--apps/openmb/resources/textures/testing/orange/texture_06.pngbin0 -> 19073 bytes
-rw-r--r--apps/openmb/resources/textures/testing/orange/texture_07.pngbin0 -> 2739 bytes
-rw-r--r--apps/openmb/resources/textures/testing/orange/texture_08.pngbin0 -> 2743 bytes
-rw-r--r--apps/openmb/resources/textures/testing/orange/texture_09.pngbin0 -> 637 bytes
-rw-r--r--apps/openmb/resources/textures/testing/orange/texture_10.pngbin0 -> 2838 bytes
-rw-r--r--apps/openmb/resources/textures/testing/orange/texture_11.pngbin0 -> 9194 bytes
-rw-r--r--apps/openmb/resources/textures/testing/orange/texture_12.pngbin0 -> 9054 bytes
-rw-r--r--apps/openmb/resources/textures/testing/orange/texture_13.pngbin0 -> 9581 bytes
-rw-r--r--apps/openmb/scene/Camera.cpp203
-rw-r--r--apps/openmb/scene/Camera.hpp69
-rw-r--r--apps/openmb/scene/GridSystem.cpp121
-rw-r--r--apps/openmb/scene/GridSystem.hpp66
-rw-r--r--apps/openmb/scene/VoxelEditor.cpp602
-rw-r--r--apps/openmb/scene/VoxelEditor.hpp132
105 files changed, 33206 insertions, 0 deletions
diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt
new file mode 100644
index 0000000..27e581d
--- /dev/null
+++ b/apps/CMakeLists.txt
@@ -0,0 +1,2 @@
+# OpenMB Applications
+add_subdirectory(openmb)
diff --git a/apps/openmb/CMakeLists.txt b/apps/openmb/CMakeLists.txt
new file mode 100644
index 0000000..7ca6f15
--- /dev/null
+++ b/apps/openmb/CMakeLists.txt
@@ -0,0 +1,45 @@
+set(OPENMB_SOURCES
+ main.cpp
+ renderer/GLHelpers.cpp
+ renderer/Shader.cpp
+ renderer/SSAORenderer.cpp
+ renderer/DirectionalLight.cpp
+ renderer/Mesh.cpp
+ renderer/Model.cpp
+ renderer/primitives.cpp
+ renderer/EditorHelpers.cpp
+ renderer/Skybox.cpp
+ scene/Camera.cpp
+ scene/GridSystem.cpp
+ scene/VoxelEditor.cpp
+ renderer/Texture.cpp
+ renderer/TextureManager.cpp
+)
+
+add_executable(OpenMB ${OPENMB_SOURCES})
+
+target_compile_features(OpenMB PRIVATE cxx_std_20)
+
+target_link_libraries(OpenMB PRIVATE
+ spdlog::spdlog
+ nlohmann_json::nlohmann_json
+ imgui::imgui
+ glfw
+
+ # OpenGL linking handled below per-platform
+ glm::glm
+ OpenAL::OpenAL
+ assimp::assimp
+ Jolt::Jolt
+)
+
+target_include_directories(OpenMB PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${Stb_INCLUDE_DIR}
+)
+
+if(APPLE)
+ target_link_libraries(OpenMB PRIVATE "-framework OpenGL")
+else()
+ target_link_libraries(OpenMB PRIVATE OpenGL::GL)
+endif()
diff --git a/apps/openmb/ImguiStyle.hpp b/apps/openmb/ImguiStyle.hpp
new file mode 100644
index 0000000..3409281
--- /dev/null
+++ b/apps/openmb/ImguiStyle.hpp
@@ -0,0 +1,80 @@
+#ifndef IMGUI_STYLE_H
+#define IMGUI_STYLE_H
+
+#include "imgui.h"
+
+inline void ApplyDebugTheme () {
+ auto& style = ImGui::GetStyle();
+ style.WindowRounding = 8.0f;
+ style.WindowPadding = ImVec2( 12.0f, 12.0f );
+ style.DisabledAlpha = 1.0f;
+ style.Alpha = 1.0f;
+}
+
+inline void ApplyImguiTheme () {
+ ImGui::StyleColorsDark();
+ ImGuiStyle& style = ImGui::GetStyle();
+ style.DisabledAlpha = 1.0f;
+ style.Alpha = 1.0f;
+ style.WindowRounding = 4.0f;
+ style.FrameRounding = 4.0f;
+ style.GrabRounding = 4.0f;
+ style.WindowBorderSize = 0.0f;
+ style.FrameBorderSize = 0.0f;
+ style.ItemSpacing = ImVec2( 8.0f, 6.0f );
+
+ const float accentR = 0.95f;
+ const float accentG = 0.95f;
+ const float accentB = 0.95f;
+
+ ImVec4* colors = style.Colors;
+
+ colors[ImGuiCol_Text] = ImVec4( 0.95f, 0.95f, 0.95f, 1.00f );
+ colors[ImGuiCol_TextDisabled] = ImVec4( 0.60f, 0.60f, 0.60f, 1.00f );
+ colors[ImGuiCol_WindowBg] = ImVec4( 0.06f, 0.06f, 0.06f, 0.95f );
+ colors[ImGuiCol_ChildBg] = ImVec4( 0.06f, 0.06f, 0.06f, 0.95f );
+
+ colors[ImGuiCol_PopupBg] = ImVec4( 0.06f, 0.06f, 0.08f, 0.95f );
+ colors[ImGuiCol_Border] = ImVec4( 0.15f, 0.15f, 0.15f, 0.50f );
+ colors[ImGuiCol_BorderShadow] = ImVec4( 0.00f, 0.00f, 0.00f, 0.00f );
+
+ colors[ImGuiCol_FrameBg] = ImVec4( 0.10f, 0.10f, 0.12f, 0.90f );
+ colors[ImGuiCol_FrameBgHovered] = ImVec4( 0.20f, 0.20f, 0.20f, 0.95f );
+ colors[ImGuiCol_FrameBgActive] = ImVec4( 0.24f, 0.24f, 0.24f, 0.95f );
+
+ colors[ImGuiCol_TitleBg] = ImVec4( 0.08f, 0.08f, 0.08f, 0.95f );
+ colors[ImGuiCol_TitleBgActive] = ImVec4( 0.06f, 0.06f, 0.06f, 0.95f );
+ colors[ImGuiCol_TitleBgCollapsed] = ImVec4( 0.00f, 0.00f, 0.00f, 0.51f );
+ colors[ImGuiCol_MenuBarBg] = ImVec4( 0.08f, 0.08f, 0.08f, 0.95f );
+
+ colors[ImGuiCol_Button] = ImVec4( 0.12f, 0.12f, 0.14f, 0.95f );
+ colors[ImGuiCol_ButtonHovered] = ImVec4( accentR * 0.85f, accentG * 0.85f, accentB * 0.85f, 0.95f );
+ colors[ImGuiCol_ButtonActive] = ImVec4( 0.08f, 0.08f, 0.08f, 0.95f );
+
+ colors[ImGuiCol_Header] = ImVec4( 0.08f, 0.08f, 0.08f, 0.95f );
+ colors[ImGuiCol_HeaderHovered] = ImVec4( accentR * 0.85f, accentG * 0.85f, accentB * 0.85f, 0.95f );
+ colors[ImGuiCol_HeaderActive] = ImVec4( accentR * 0.75f, accentG * 0.75f, accentB * 0.75f, 0.95f );
+
+ colors[ImGuiCol_Separator] = ImVec4( 0.12f, 0.12f, 0.14f, 1.00f );
+ colors[ImGuiCol_SeparatorHovered] = ImVec4( accentR * 0.85f, accentG * 0.85f, accentB * 0.85f, 0.95f );
+ colors[ImGuiCol_SeparatorActive] = ImVec4( accentR * 0.75f, accentG * 0.75f, accentB * 0.75f, 1.00f );
+
+ colors[ImGuiCol_Tab] = ImVec4( 0.10f, 0.10f, 0.12f, 0.95f );
+ colors[ImGuiCol_TabHovered] = ImVec4( accentR * 0.85f, accentG * 0.85f, accentB * 0.85f, 0.95f );
+ colors[ImGuiCol_TabActive] = ImVec4( accentR * 0.75f, accentG * 0.75f, accentB * 0.75f, 0.95f );
+
+ colors[ImGuiCol_CheckMark] = ImVec4( accentR * 0.85f, accentG * 0.85f, accentB * 0.85f, 0.95f );
+ colors[ImGuiCol_SliderGrab] = ImVec4( accentR * 0.85f, accentG * 0.85f, accentB * 0.85f, 0.95f );
+ colors[ImGuiCol_SliderGrabActive] = ImVec4( accentR * 0.75f, accentG * 0.75f, accentB * 0.75f, 0.95f );
+
+ colors[ImGuiCol_ScrollbarBg] = ImVec4( 0.05f, 0.05f, 0.06f, 0.90f );
+ colors[ImGuiCol_ScrollbarGrab] = ImVec4( 0.12f, 0.12f, 0.14f, 0.95f );
+ colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4( accentR * 0.85f, accentG * 0.85f, accentB * 0.85f, 0.95f );
+ colors[ImGuiCol_ScrollbarGrabActive] = ImVec4( accentR * 0.75f, accentG * 0.75f, accentB * 0.75f, 0.95f );
+
+ colors[ImGuiCol_ResizeGrip] = ImVec4( 0.12f, 0.12f, 0.14f, 0.95f );
+ colors[ImGuiCol_ResizeGripActive] = ImVec4( 0.12f, 0.12f, 0.14f, 0.95f );
+ colors[ImGuiCol_ResizeGripHovered] = ImVec4( 0.12f, 0.12f, 0.14f, 0.95f );
+}
+
+#endif
diff --git a/apps/openmb/main.cpp b/apps/openmb/main.cpp
new file mode 100644
index 0000000..54027b9
--- /dev/null
+++ b/apps/openmb/main.cpp
@@ -0,0 +1,1753 @@
+#if defined( __APPLE__ )
+#define GL_SILENCE_DEPRECATION
+#endif
+#if defined( __APPLE__ )
+#define GL_SILENCE_DEPRECATION
+#endif
+
+#define GLFW_INCLUDE_NONE
+#include <GLFW/glfw3.h>
+#ifdef __APPLE__
+#include <OpenGL/gl3.h>
+#endif
+
+#include <chrono>
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+#include <iostream>
+#include <vector>
+
+#include "ImguiStyle.hpp"
+#include <imgui.h>
+#include <imgui_impl_glfw.h>
+#include <imgui_impl_opengl3.h>
+
+#include "renderer/DirectionalLight.hpp"
+#include "renderer/EditorHelpers.hpp"
+#include "renderer/GLHelpers.hpp"
+#include "renderer/Model.hpp"
+#include "renderer/SSAORenderer.hpp"
+#include "renderer/Shader.hpp"
+#include "renderer/Skybox.hpp"
+#include "renderer/Texture.hpp"
+#include "renderer/TextureManager.hpp"
+#include "renderer/primitives.hpp"
+#include "scene/Camera.hpp"
+
+#include "scene/GridSystem.hpp"
+#include "scene/VoxelEditor.hpp"
+#include <algorithm>
+#include <assimp/Importer.hpp>
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <filesystem>
+#include <fstream>
+#include <nlohmann/json.hpp>
+
+void keyCallback ( GLFWwindow* window, int key, int scancode, int action, int mods ) {}
+
+int main () {
+ if( !glfwInit() ) {
+ std::cerr << "Failed to initialize GLFW!" << std::endl;
+ return -1;
+ }
+
+ glfwWindowHint( GLFW_DEPTH_BITS, 24 );
+
+ glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
+ glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
+ glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
+
+#ifdef __APPLE__
+ glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE );
+#endif
+
+ int width = 1280;
+ int height = 720;
+ GLFWwindow* window = glfwCreateWindow( width, height, "oh yeah, thats hotsauce alright", nullptr, nullptr );
+ if( !window ) {
+ std::cerr << "Failed to create GLFW window!" << std::endl;
+ glfwTerminate();
+ return -1;
+ }
+ glfwMakeContextCurrent( window );
+ glfwSwapInterval( 1 );
+
+ glfwMaximizeWindow( window );
+ int fbWidth = 0, fbHeight = 0;
+ glfwGetFramebufferSize( window, &fbWidth, &fbHeight );
+ if( fbWidth == 0 || fbHeight == 0 ) {
+ fbWidth = width;
+ fbHeight = height;
+ }
+ bool ePrev = false;
+ bool mouseCaptured = true;
+
+ glViewport( 0, 0, fbWidth, fbHeight );
+ glfwSetFramebufferSizeCallback( window, [] ( GLFWwindow* /*w*/, int w, int h ) { glViewport( 0, 0, w, h ); } );
+ glfwSetKeyCallback( window, keyCallback );
+
+ if( !renderer::initGL() ) {
+ std::cerr << "Failed to initialize OpenGL" << std::endl;
+ glfwDestroyWindow( window );
+ glfwTerminate();
+ return -1;
+ }
+
+ IMGUI_CHECKVERSION();
+ ImGui::CreateContext();
+ ImGuiIO& io = ImGui::GetIO();
+ (void)io;
+ ImGui::StyleColorsDark();
+ ApplyImguiTheme();
+ ImGui_ImplGlfw_InitForOpenGL( window, true );
+ ImGui_ImplOpenGL3_Init( "#version 330 core" );
+
+ renderer::Shader shader;
+ const std::string vertPath = "apps/openmb/resources/shaders/cube.vert";
+ const std::string fragPath = "apps/openmb/resources/shaders/cube.frag";
+ if( !shader.fromFiles( vertPath, fragPath ) ) {
+ std::cerr << "Failed to load/compile shader files: " << vertPath << " and " << fragPath << std::endl;
+ glfwDestroyWindow( window );
+ glfwTerminate();
+ return -1;
+ }
+
+ scene::GridSystem gridSystem;
+
+ renderer::Mesh cube = renderer::primitives::makeCube();
+ renderer::Mesh texturedCube = renderer::primitives::makeTexturedCubeWithNormals();
+ renderer::Mesh grid = renderer::primitives::makeGrid( 100, gridSystem.getCellSize() );
+
+ renderer::Skybox skybox;
+ if( !skybox.loadFromDirectory( "apps/openmb/resources/skybox" ) ) {
+ std::cerr << "Warning: failed to load skybox from resources/skybox" << std::endl;
+ }
+
+ renderer::Shader texShader;
+ const std::string tVert = "apps/openmb/resources/shaders/textured.vert";
+ const std::string tFrag = "apps/openmb/resources/shaders/textured_lit.frag";
+ if( !texShader.fromFiles( tVert, tFrag ) ) {
+ std::cerr << "Failed to load textured shader files: " << tVert << " and " << tFrag << std::endl;
+ } else {
+ texShader.use();
+ texShader.setInt( "radialEnabled", 0 );
+ texShader.setFloat( "radialInner", 0.38f );
+ texShader.setFloat( "radialOuter", 0.5f );
+ texShader.setInt( "albedo", 0 );
+ texShader.setInt( "normalMap", 1 );
+ texShader.setInt( "normalEnabled", 0 );
+ texShader.setFloat( "normalStrength", 1.0f );
+ texShader.setInt( "shadowMap", 2 );
+ texShader.setInt( "ssao", 3 );
+ texShader.setFloat( "aoStrength", 1.0f );
+ }
+
+ glm::vec3 loadedSunDir( 0.3f, 1.0f, 0.5f );
+ glm::vec3 loadedSunColor( 1.0f, 0.98f, 0.9f );
+ float loadedSunIntensity = 1.0f;
+ bool loadedSunAvailable = false;
+
+ renderer::DirectionalLight sun;
+ sun.setDirection( glm::normalize( glm::vec3( 0.3f, 1.0f, 0.5f ) ) );
+ sun.setColor( glm::vec3( 1.0f, 0.98f, 0.9f ) );
+ sun.setIntensity( 1.0f );
+ static bool lightingEnabled = true;
+
+ static float shadowBiasMinGui = 0.00200f;
+ static float shadowBiasScaleGui = 0.005f;
+ static int pcfRadiusGui = 0;
+ static bool snapToTexels = true;
+
+ // Fog parameters (world-space exponential fog)
+ static glm::vec3 fogColor = glm::vec3( 0.6f, 0.65f, 0.7f );
+ static float fogDensity = 0.0741f;
+ static float fogAmount = 1.f;
+
+ // God-rays parameters
+ static bool godraysEnabled = false;
+ // overall multiplier applied to the god-rays composite (keeps defaults conservative)
+ static float godraysIntensity = 0.08f;
+ static int godraysSamples = 30;
+ static float godraysDensity = 0.8f;
+ static float godraysWeight = 0.4f;
+ static float godraysDecay = 0.95f;
+ static int godraysDownscale = 4; // occlusion texture downscale factor
+
+ texShader.use();
+ texShader.setFloat( "shadowBiasMin", shadowBiasMinGui );
+ texShader.setFloat( "shadowBiasScale", shadowBiasScaleGui );
+ texShader.setInt( "pcfRadius", pcfRadiusGui );
+
+ const unsigned int shadowWidth = 4096, shadowHeight = 4096;
+ renderer::Shader depthShader;
+ const std::string dVert = "apps/openmb/resources/shaders/depth.vert";
+ const std::string dFrag = "apps/openmb/resources/shaders/depth.frag";
+ if( !depthShader.fromFiles( dVert, dFrag ) ) {
+ std::cerr << "Warning: failed to load depth shader for shadow mapping" << std::endl;
+ }
+
+ unsigned int depthMapFBO = 0;
+ unsigned int depthMap = 0;
+ glGenFramebuffers( 1, &depthMapFBO );
+ glGenTextures( 1, &depthMap );
+ glBindTexture( GL_TEXTURE_2D, depthMap );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowWidth, shadowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
+ nullptr );
+
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER );
+ float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ glTexParameterfv( GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor );
+
+ // We'll perform manual depth comparisons in the shader, so disable sampler compare mode.
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL ); // ignored when compare mode is NONE
+
+ glBindFramebuffer( GL_FRAMEBUFFER, depthMapFBO );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0 );
+ glDrawBuffer( GL_NONE );
+ glReadBuffer( GL_NONE );
+ if( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE ) {
+ std::cerr << "Warning: Shadow framebuffer not complete" << std::endl;
+ }
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+
+ // --- God rays / occlusion resources ---
+ renderer::Shader occlusionShader;
+ const std::string occVert = "apps/openmb/resources/shaders/occlusion.vert";
+ const std::string occFrag = "apps/openmb/resources/shaders/occlusion.frag";
+ if( !occlusionShader.fromFiles( occVert, occFrag ) ) {
+ std::cerr << "Warning: failed to load occlusion shader" << std::endl;
+ }
+
+ renderer::Shader godraysShader;
+ const std::string grVert = "apps/openmb/resources/shaders/godrays_quad.vert";
+ const std::string grFrag = "apps/openmb/resources/shaders/godrays_radial.frag";
+ if( !godraysShader.fromFiles( grVert, grFrag ) ) {
+ std::cerr << "Warning: failed to load godrays shader" << std::endl;
+ }
+
+ // fullscreen quad (NDC coords)
+ renderer::Mesh quadMesh;
+ {
+ std::vector<float> q = {
+ // pos.x, pos.y, pos.z, u, v
+ -1.0f,
+ -1.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ -1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ -1.0f,
+ -1.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ -1.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ };
+ quadMesh.createFromPosTex( q );
+ }
+
+ // occlusion FBO (low-res)
+ unsigned int occlusionFBO = 0;
+ unsigned int occlusionTex = 0;
+ unsigned int occlusionDepthRBO = 0;
+ glGenFramebuffers( 1, &occlusionFBO );
+ glGenTextures( 1, &occlusionTex );
+ int occlusionW = 0;
+ int occlusionH = 0;
+ // we'll allocate size at first frame (when framebuffer size is known)
+
+ glm::mat4 dirLightSpace( 1.0f );
+
+ renderer::TextureManager textureManager;
+ textureManager.scanDirectory( "apps/openmb/resources/textures" );
+
+ std::vector<std::unique_ptr<renderer::Model>> models;
+ std::vector<std::string> modelNames;
+ {
+ std::string modelsDir = "apps/openmb/resources/models/rocks";
+ if( std::filesystem::exists( modelsDir ) ) {
+ for( const auto& entry : std::filesystem::directory_iterator( modelsDir ) ) {
+ if( entry.path().extension() == ".obj" ) {
+ auto mptr = std::make_unique<renderer::Model>();
+ if( mptr->loadFromFile( entry.path().string() ) ) {
+ modelNames.push_back( entry.path().stem().string() );
+ models.push_back( std::move( mptr ) );
+ } else {
+ std::cerr << "Warning: failed to load model: " << entry.path().string() << std::endl;
+ }
+ }
+ }
+ }
+ }
+
+ renderer::Texture rocksAlbedo;
+ renderer::Texture rocksNormal;
+ bool rocksAlbedoLoaded =
+ rocksAlbedo.loadFromFile( "apps/openmb/resources/models/rocks/Rocks_lp_SM_Rock_01_BaseMap.png" );
+ bool rocksNormalLoaded =
+ rocksNormal.loadFromFile( "apps/openmb/resources/models/rocks/Rocks_lp_SM_Rock_01_Normal.png" );
+ if( !rocksAlbedoLoaded ) {
+ std::cerr << "Warning: failed to load rocks albedo at resources/models/rocks/Rocks_lp_SM_Rock_01_BaseMap.png"
+ << std::endl;
+ }
+ if( !rocksNormalLoaded ) {
+ std::cerr << "Warning: failed to load rocks normal at resources/models/rocks/Rocks_lp_SM_Rock_01_Normal.png"
+ << std::endl;
+ }
+
+ std::filesystem::path bluePath = std::filesystem::path( "apps/openmb/resources/textures/brush/basic/blue.tga" );
+ if( !std::filesystem::exists( bluePath ) ) {
+ std::filesystem::create_directories( bluePath.parent_path() );
+ std::ofstream out( bluePath, std::ios::binary );
+ if( out ) {
+ unsigned char header[18] = { 0 };
+ header[2] = 2;
+ header[12] = 1;
+ header[13] = 0;
+ header[14] = 1;
+ header[15] = 0;
+ header[16] = 32;
+ out.write( reinterpret_cast<char*>( header ), 18 );
+ unsigned char pixel[4] = { 255, 0, 0, 200 };
+ out.write( reinterpret_cast<char*>( pixel ), 4 );
+ out.close();
+ std::cout << "Wrote blue texture to " << bluePath.string() << std::endl;
+ }
+ textureManager.scanDirectory( "apps/openmb/resources/textures" );
+ }
+ textureManager.setCurrentTexture( "brush", "basic", "blue.tga" );
+
+ auto categories = textureManager.getCategories();
+ if( !categories.empty() ) {
+ auto subcategories = textureManager.getSubcategories( categories[0] );
+ if( !subcategories.empty() ) {
+ auto textures = textureManager.getTextureNames( categories[0], subcategories[0] );
+ if( !textures.empty() ) {
+ textureManager.setCurrentTexture( categories[0], subcategories[0], textures[0] );
+ }
+ }
+ }
+
+ const float tileSize = gridSystem.getCellSize();
+
+ static float brushRadius = 1.5f;
+ static float prevBrushRadius = -1.0f;
+
+ static float brushHeight = gridSystem.getCellSize();
+ enum class PlacementBrush {
+ Brush = 0,
+ Cube = 1,
+ Model = 2,
+ };
+
+ static PlacementBrush placementBrush = PlacementBrush::Model;
+ static bool useCircleBrush = ( placementBrush == PlacementBrush::Brush );
+ static int selectedModelIndex = 0;
+ static float selectedModelScale = 0.017f;
+ static float selectedModelYaw = 0.0f;
+ static bool placeCollidable = true;
+
+ renderer::Mesh circleWire = renderer::editor::makeCircleWire( brushRadius, 64 );
+
+ renderer::Mesh filledCircle = renderer::editor::makeCircleFilled( 1.0f, 64 );
+
+ struct PaintedCircle {
+ glm::vec3 mCenter;
+ float mRadius;
+ int mTextureId;
+ };
+
+ std::vector<PaintedCircle> paintedCircles;
+
+ static double lastPaintTime = 0.0;
+ const double paintInterval = 0.08;
+
+ std::vector<std::pair<glm::vec3, glm::vec3>> worldBoxes;
+ std::vector<std::pair<glm::vec3, glm::vec3>> baseWorldBoxes;
+
+ scene::VoxelEditor voxelEditor( gridSystem );
+
+ const std::string defaultLevelPath = "apps/openmb/resources/levels/default.json";
+ if( std::filesystem::exists( defaultLevelPath ) ) {
+ if( voxelEditor.loadFromFile( defaultLevelPath ) ) {
+ std::cout << "Loaded default level (voxels) from " << defaultLevelPath << std::endl;
+ } else {
+ std::cerr << "Failed to load default level voxels" << std::endl;
+ }
+
+ try {
+ std::ifstream in( defaultLevelPath );
+ if( in ) {
+ nlohmann::json j;
+ in >> j;
+ if( j.contains( "paintedCircles" ) && j["paintedCircles"].is_array() ) {
+ for( const auto& pcj : j["paintedCircles"] ) {
+ PaintedCircle pc;
+ pc.mCenter.x = pcj.value( "x", 0.0f );
+ pc.mCenter.y = pcj.value( "y", 0.0f );
+ pc.mCenter.z = pcj.value( "z", 0.0f );
+ pc.mRadius = pcj.value( "radius", 1.0f );
+ pc.mTextureId = pcj.value( "textureId", 0 );
+ paintedCircles.push_back( pc );
+ }
+ std::cout << "Loaded " << paintedCircles.size() << " painted circles from " << defaultLevelPath
+ << std::endl;
+ }
+ if( j.contains( "sun" ) && j["sun"].is_object() ) {
+ try {
+ const auto& sj = j["sun"];
+ if( sj.contains( "direction" ) && sj["direction"].is_array() && sj["direction"].size() >= 3 ) {
+ loadedSunDir.x = sj["direction"][0].get<float>();
+ loadedSunDir.y = sj["direction"][1].get<float>();
+ loadedSunDir.z = sj["direction"][2].get<float>();
+ }
+ if( sj.contains( "color" ) && sj["color"].is_array() && sj["color"].size() >= 3 ) {
+ loadedSunColor.r = sj["color"][0].get<float>();
+ loadedSunColor.g = sj["color"][1].get<float>();
+ loadedSunColor.b = sj["color"][2].get<float>();
+ }
+ if( sj.contains( "intensity" ) )
+ loadedSunIntensity = sj["intensity"].get<float>();
+ loadedSunAvailable = true;
+ } catch( ... ) {
+ }
+ }
+ }
+ } catch( ... ) {
+ }
+ }
+
+ if( loadedSunAvailable ) {
+ sun.setDirection( glm::normalize( loadedSunDir ) );
+ sun.setColor( loadedSunColor );
+ sun.setIntensity( loadedSunIntensity );
+ }
+
+ renderer::Mesh wireCube = renderer::editor::makeWireCube( tileSize );
+
+ auto rayAABBIntersect = [&] ( const glm::vec3& ro, const glm::vec3& rd, const glm::vec3& bmin, const glm::vec3& bmax,
+ float& outT ) -> bool {
+ float tmin = -FLT_MAX;
+ float tmax = FLT_MAX;
+ for( int i = 0; i < 3; ++i ) {
+ float origin = ro[i];
+ float dir = rd[i];
+ float minB = bmin[i];
+ float maxB = bmax[i];
+ if( std::abs( dir ) < 1e-6f ) {
+ if( origin < minB || origin > maxB )
+ return false;
+ } else {
+ float t1 = ( minB - origin ) / dir;
+ float t2 = ( maxB - origin ) / dir;
+ if( t1 > t2 )
+ std::swap( t1, t2 );
+ tmin = std::max( tmin, t1 );
+ tmax = std::min( tmax, t2 );
+ if( tmin > tmax )
+ return false;
+ }
+ }
+ if( tmax < 0.0f )
+ return false;
+ outT = tmin >= 0.0f ? tmin : tmax;
+ return true;
+ };
+
+ bool editorActive = false;
+ glm::vec3 lastRayOrigin( 0.0f );
+ glm::vec3 lastRayDir( 0.0f );
+
+ int initialFBW = 0, initialFBH = 0;
+ glfwGetFramebufferSize( window, &initialFBW, &initialFBH );
+ if( initialFBW == 0 || initialFBH == 0 ) {
+ initialFBW = width;
+ initialFBH = height;
+ }
+ glViewport( 0, 0, initialFBW, initialFBH );
+
+ scene::Camera camera( glm::vec3( 0.0f, 4.0f, 6.0f ), glm::vec3( 0.0f, 4.0f, 0.0f ), -90.0f, 0.0f );
+ glfwSetInputMode( window, GLFW_CURSOR, GLFW_CURSOR_DISABLED );
+ double lastX = width / 2.0, lastY = height / 2.0;
+ bool firstMouse = true;
+ float lastFrame = 0.0f;
+ bool fPrev = false;
+ bool spacePrev = false;
+ bool zPrev = false;
+ bool yPrev = false;
+ bool lPrev = false;
+ bool placementEditorEnabled = true;
+ double lastTime = 0.0;
+ double deltaTime = 0.0;
+ double fps = 0.0;
+
+ using Clock = std::chrono::high_resolution_clock;
+ auto instLastReport = Clock::now();
+ double instAccumShadow = 0.0;
+ double instAccumSSAO = 0.0;
+ double instAccumDraw = 0.0;
+ double instAccumUI = 0.0;
+ double instAccumFrame = 0.0;
+ int instFrames = 0;
+
+ while( !glfwWindowShouldClose( window ) ) {
+ auto instFrameStart = Clock::now();
+ auto instSegStart = instFrameStart;
+ float currentFrame = static_cast<float>( glfwGetTime() );
+ float deltaTime = currentFrame - lastFrame;
+ lastFrame = currentFrame;
+
+ bool fCur = glfwGetKey( window, GLFW_KEY_F ) == GLFW_PRESS;
+ if( fCur && !fPrev )
+ camera.toggleFly();
+ fPrev = fCur;
+
+ bool spaceCur = glfwGetKey( window, GLFW_KEY_SPACE ) == GLFW_PRESS;
+ if( spaceCur && !spacePrev )
+ camera.jump();
+ spacePrev = spaceCur;
+
+ bool eCur = glfwGetKey( window, GLFW_KEY_E ) == GLFW_PRESS;
+ if( eCur && !ePrev ) {
+ mouseCaptured = !mouseCaptured;
+ if( mouseCaptured ) {
+ glfwSetInputMode( window, GLFW_CURSOR, GLFW_CURSOR_DISABLED );
+ } else {
+ glfwSetInputMode( window, GLFW_CURSOR, GLFW_CURSOR_NORMAL );
+ }
+ }
+ ePrev = eCur;
+
+ bool ctrl = ( glfwGetKey( window, GLFW_KEY_LEFT_CONTROL ) == GLFW_PRESS ) ||
+ ( glfwGetKey( window, GLFW_KEY_RIGHT_CONTROL ) == GLFW_PRESS );
+ bool zCur = glfwGetKey( window, GLFW_KEY_Z ) == GLFW_PRESS;
+ bool yCur = glfwGetKey( window, GLFW_KEY_Y ) == GLFW_PRESS;
+ bool lCur = glfwGetKey( window, GLFW_KEY_L ) == GLFW_PRESS;
+
+ if( ctrl && zCur && !zPrev ) {
+ voxelEditor.undo();
+ } else if( ctrl && yCur && !yPrev ) {
+ voxelEditor.redo();
+ }
+
+ zPrev = zCur;
+ yPrev = yCur;
+ if( lCur && !lPrev ) {
+ placementEditorEnabled = !placementEditorEnabled;
+ }
+ lPrev = lCur;
+
+ double now = glfwGetTime();
+ deltaTime = now - lastTime;
+ lastTime = now;
+ fps = 1.0 / deltaTime;
+
+ ImGui_ImplOpenGL3_NewFrame();
+ ImGui_ImplGlfw_NewFrame();
+ ImGui::NewFrame();
+
+ if( mouseCaptured ) {
+ ImGuiIO& io = ImGui::GetIO();
+
+ for( int i = 0; i < IM_ARRAYSIZE( io.MouseDown ); ++i )
+ io.MouseDown[i] = false;
+ io.WantCaptureMouse = false;
+ io.WantCaptureKeyboard = false;
+ }
+
+ {
+ static bool requireFlyForEditing = true;
+
+ editorActive = ( !requireFlyForEditing || camera.isFlying() ) && placementEditorEnabled;
+ ImGui::Begin( "Player" );
+ ImGui::Text( "Flying: %s", camera.isFlying() ? "Yes" : "No" );
+ ImGui::Text( "Grounded: %s", camera.isGrounded() ? "Yes" : "No" );
+ float sm = camera.getSpeedMultiplier();
+ ImGui::Text( "Speed x%.2f", sm );
+ if( ImGui::Button( "Toggle Fly" ) )
+ camera.toggleFly();
+ if( ImGui::Button( "Jump" ) )
+ camera.jump();
+ ImGui::Separator();
+ ImGui::Separator();
+ ImGui::Text( "Edit: Ctrl+Z undo, Ctrl+Y redo" );
+ ImGui::Text( "Undo stack: %zu", voxelEditor.getUndoStackSize() );
+ ImGui::Text( "Redo stack: %zu", voxelEditor.getRedoStackSize() );
+
+ ImGui::Separator();
+ ImGui::Text( "Level Management:" );
+
+ static char levelName[128] = "my_level";
+ ImGui::InputText( "Level Name", levelName, IM_ARRAYSIZE( levelName ) );
+
+ if( ImGui::Button( "Save Level" ) ) {
+ std::filesystem::create_directories( "apps/openmb/resources/levels" );
+ std::string filepath = std::string( "apps/openmb/resources/levels/" ) + levelName + ".json";
+ try {
+ nlohmann::json j;
+ j["version"] = 1;
+
+ nlohmann::json voxels = nlohmann::json::array();
+ for( const auto& cell : voxelEditor.getPlacedCells() ) {
+ nlohmann::json v;
+ v["x"] = cell.x;
+ v["y"] = cell.y;
+ v["z"] = cell.z;
+ v["textureId"] = voxelEditor.getTextureIdForCell( cell );
+ voxels.push_back( v );
+ }
+ j["voxels"] = voxels;
+
+ nlohmann::json pcs = nlohmann::json::array();
+ for( const auto& pc : paintedCircles ) {
+ nlohmann::json p;
+ p["x"] = pc.mCenter.x;
+ p["y"] = pc.mCenter.y;
+ p["z"] = pc.mCenter.z;
+ p["radius"] = pc.mRadius;
+ p["textureId"] = pc.mTextureId;
+ pcs.push_back( p );
+ }
+ j["paintedCircles"] = pcs;
+
+ nlohmann::json modelsJson = nlohmann::json::array();
+ for( const auto& mi : voxelEditor.getPlacedModels() ) {
+ nlohmann::json mj;
+ mj["modelIndex"] = mi.modelIndex;
+ mj["x"] = mi.pos.x;
+ mj["y"] = mi.pos.y;
+ mj["z"] = mi.pos.z;
+ mj["yaw"] = mi.yaw;
+ mj["scale"] = mi.scale;
+ modelsJson.push_back( mj );
+ }
+ j["models"] = modelsJson;
+
+ try {
+ nlohmann::json sj;
+ auto sd = sun.getDirection();
+ sj["direction"] = { sd.x, sd.y, sd.z };
+ auto sc = sun.getColor();
+ sj["color"] = { sc.r, sc.g, sc.b };
+ sj["intensity"] = sun.getIntensity();
+ j["sun"] = sj;
+ } catch( ... ) {
+ }
+
+ std::ofstream out( filepath );
+ if( !out ) {
+ throw std::runtime_error( "failed to open file for writing" );
+ }
+ out << j.dump( 2 );
+ out.close();
+ std::cout << "Level saved to " << filepath << std::endl;
+ } catch( const std::exception& e ) {
+ std::cerr << "Failed to save level: " << e.what() << std::endl;
+ }
+ }
+
+ static int selectedLevel = 0;
+ static std::vector<std::string> levelFiles;
+ static bool levelsScanned = false;
+
+ if( !levelsScanned || ImGui::Button( "Refresh Levels" ) ) {
+ levelFiles.clear();
+ std::string levelsDir = "apps/openmb/resources/levels";
+ if( std::filesystem::exists( levelsDir ) ) {
+ for( const auto& entry : std::filesystem::directory_iterator( levelsDir ) ) {
+ if( entry.path().extension() == ".json" ) {
+ levelFiles.push_back( entry.path().stem().string() );
+ }
+ }
+ }
+ std::sort( levelFiles.begin(), levelFiles.end() );
+ levelsScanned = true;
+ selectedLevel = 0;
+ }
+
+ if( !levelFiles.empty() ) {
+ if( ImGui::BeginCombo( "Available Levels", levelFiles[selectedLevel].c_str() ) ) {
+ for( int i = 0; i < levelFiles.size(); ++i ) {
+ bool isSelected = ( selectedLevel == i );
+ if( ImGui::Selectable( levelFiles[i].c_str(), isSelected ) ) {
+ selectedLevel = i;
+ }
+ if( isSelected )
+ ImGui::SetItemDefaultFocus();
+ }
+ ImGui::EndCombo();
+ }
+
+ if( ImGui::Button( "Load Selected" ) ) {
+ std::string filepath =
+ std::string( "apps/openmb/resources/levels/" ) + levelFiles[selectedLevel] + ".json";
+
+ if( voxelEditor.loadFromFile( filepath ) ) {
+ std::cout << "Level loaded (voxels) from " << filepath << std::endl;
+ } else {
+ std::cerr << "Failed to load level voxels" << std::endl;
+ }
+
+ paintedCircles.clear();
+ try {
+ std::ifstream in( filepath );
+ if( in ) {
+ nlohmann::json j;
+ in >> j;
+ if( j.contains( "paintedCircles" ) && j["paintedCircles"].is_array() ) {
+ for( const auto& pcj : j["paintedCircles"] ) {
+ PaintedCircle pc;
+ pc.mCenter.x = pcj.value( "x", 0.0f );
+ pc.mCenter.y = pcj.value( "y", 0.0f );
+ pc.mCenter.z = pcj.value( "z", 0.0f );
+ pc.mRadius = pcj.value( "radius", 1.0f );
+ pc.mTextureId = pcj.value( "textureId", 0 );
+ paintedCircles.push_back( pc );
+ }
+ std::cout << "Loaded " << paintedCircles.size() << " painted circles from " << filepath
+ << std::endl;
+ }
+ if( j.contains( "sun" ) && j["sun"].is_object() ) {
+ try {
+ const auto& sj = j["sun"];
+ if( sj.contains( "direction" ) && sj["direction"].is_array() &&
+ sj["direction"].size() >= 3 ) {
+ glm::vec3 sd;
+ sd.x = sj["direction"][0].get<float>();
+ sd.y = sj["direction"][1].get<float>();
+ sd.z = sj["direction"][2].get<float>();
+ sun.setDirection( glm::normalize( sd ) );
+ }
+ if( sj.contains( "color" ) && sj["color"].is_array() && sj["color"].size() >= 3 ) {
+ glm::vec3 sc;
+ sc.r = sj["color"][0].get<float>();
+ sc.g = sj["color"][1].get<float>();
+ sc.b = sj["color"][2].get<float>();
+ sun.setColor( sc );
+ }
+ if( sj.contains( "intensity" ) )
+ sun.setIntensity( sj["intensity"].get<float>() );
+ } catch( ... ) {
+ }
+ }
+ }
+ } catch( ... ) {
+ }
+ }
+ } else {
+ ImGui::Text( "No levels found" );
+ }
+
+ if( ImGui::Button( "Clear All" ) ) {
+ voxelEditor.clear();
+ }
+
+ ImGui::Separator();
+ ImGui::Text( "Cube Texture:" );
+
+ auto categories = textureManager.getCategories();
+ if( !categories.empty() ) {
+ static int selectedCategory = 0;
+ static int selectedSubcategory = 0;
+ static int selectedTexture = 0;
+ static std::string lastCategory;
+ static std::string lastSubcategory;
+
+ std::string currentCat = textureManager.getCurrentCategory();
+ if( !currentCat.empty() ) {
+ auto it = std::find( categories.begin(), categories.end(), currentCat );
+ if( it != categories.end() )
+ selectedCategory = std::distance( categories.begin(), it );
+ }
+
+ if( ImGui::BeginCombo( "Category", categories[selectedCategory].c_str() ) ) {
+ for( int i = 0; i < categories.size(); ++i ) {
+ bool isSelected = ( selectedCategory == i );
+ if( ImGui::Selectable( categories[i].c_str(), isSelected ) ) {
+ selectedCategory = i;
+ selectedSubcategory = 0;
+ selectedTexture = 0;
+ lastCategory = categories[selectedCategory];
+
+ auto newSubcats = textureManager.getSubcategories( categories[selectedCategory] );
+ if( !newSubcats.empty() ) {
+ auto newTextures =
+ textureManager.getTextureNames( categories[selectedCategory], newSubcats[0] );
+ if( !newTextures.empty() ) {
+ textureManager.setCurrentTexture( categories[selectedCategory], newSubcats[0],
+ newTextures[0] );
+ }
+ }
+ }
+ if( isSelected )
+ ImGui::SetItemDefaultFocus();
+ }
+ ImGui::EndCombo();
+ }
+
+ auto subcategories = textureManager.getSubcategories( categories[selectedCategory] );
+ if( !subcategories.empty() ) {
+
+ if( selectedSubcategory >= subcategories.size() )
+ selectedSubcategory = 0;
+
+ std::string currentSub = textureManager.getCurrentSubcategory();
+ if( !currentSub.empty() && textureManager.getCurrentCategory() == categories[selectedCategory] ) {
+ auto it = std::find( subcategories.begin(), subcategories.end(), currentSub );
+ if( it != subcategories.end() )
+ selectedSubcategory = std::distance( subcategories.begin(), it );
+ }
+
+ if( ImGui::BeginCombo( "Style", subcategories[selectedSubcategory].c_str() ) ) {
+ for( int i = 0; i < subcategories.size(); ++i ) {
+ bool isSelected = ( selectedSubcategory == i );
+ if( ImGui::Selectable( subcategories[i].c_str(), isSelected ) ) {
+ selectedSubcategory = i;
+ selectedTexture = 0;
+ lastSubcategory = subcategories[selectedSubcategory];
+
+ auto newTextures = textureManager.getTextureNames( categories[selectedCategory],
+ subcategories[selectedSubcategory] );
+ if( !newTextures.empty() ) {
+ textureManager.setCurrentTexture( categories[selectedCategory],
+ subcategories[selectedSubcategory],
+ newTextures[0] );
+ }
+ }
+ if( isSelected )
+ ImGui::SetItemDefaultFocus();
+ }
+ ImGui::EndCombo();
+ }
+
+ auto textures = textureManager.getTextureNames( categories[selectedCategory],
+ subcategories[selectedSubcategory] );
+ if( !textures.empty() ) {
+
+ if( selectedTexture >= textures.size() )
+ selectedTexture = 0;
+
+ std::string currentTex = textureManager.getCurrentTextureName();
+ if( !currentTex.empty() &&
+ textureManager.getCurrentCategory() == categories[selectedCategory] &&
+ textureManager.getCurrentSubcategory() == subcategories[selectedSubcategory] ) {
+ auto it = std::find( textures.begin(), textures.end(), currentTex );
+ if( it != textures.end() )
+ selectedTexture = std::distance( textures.begin(), it );
+ }
+
+ if( ImGui::BeginCombo( "Texture", textures[selectedTexture].c_str() ) ) {
+ for( int i = 0; i < textures.size(); ++i ) {
+ bool isSelected = ( selectedTexture == i );
+ if( ImGui::Selectable( textures[i].c_str(), isSelected ) ) {
+ selectedTexture = i;
+ textureManager.setCurrentTexture( categories[selectedCategory],
+ subcategories[selectedSubcategory],
+ textures[selectedTexture] );
+ }
+ if( isSelected )
+ ImGui::SetItemDefaultFocus();
+ }
+ ImGui::EndCombo();
+ }
+ }
+ }
+ }
+
+ ImGui::Separator();
+ ImGui::Text( "Placement Mode:" );
+
+ const char* brushLabels[] = { "Brush", "Cube", "Model" };
+ int brushIdx = static_cast<int>( placementBrush );
+ if( ImGui::Combo( "Mode", &brushIdx, brushLabels, IM_ARRAYSIZE( brushLabels ) ) ) {
+ placementBrush = static_cast<PlacementBrush>( brushIdx );
+ useCircleBrush = ( placementBrush == PlacementBrush::Brush );
+ }
+
+ if( placementBrush == PlacementBrush::Brush ) {
+ ImGui::Text( "Circle Brush:" );
+ ImGui::SliderFloat( "Brush Radius (m)", &brushRadius, 0.1f, 20.0f );
+ {
+ float minH = gridSystem.getFloorY();
+ float maxH = gridSystem.getFloorY() + gridSystem.getWallHeight() * gridSystem.getCellSize();
+ ImGui::SliderFloat( "Brush Height", &brushHeight, minH, maxH );
+ }
+ } else if( placementBrush == PlacementBrush::Model ) {
+ ImGui::Text( "Model Placement:" );
+ if( modelNames.empty() ) {
+ ImGui::Text( "No models found in resources/models/rocks" );
+ } else {
+ if( selectedModelIndex >= modelNames.size() )
+ selectedModelIndex = 0;
+ if( ImGui::BeginCombo( "Model", modelNames[selectedModelIndex].c_str() ) ) {
+ for( int i = 0; i < modelNames.size(); ++i ) {
+ bool sel = ( i == selectedModelIndex );
+ if( ImGui::Selectable( modelNames[i].c_str(), sel ) )
+ selectedModelIndex = i;
+ if( sel )
+ ImGui::SetItemDefaultFocus();
+ }
+ ImGui::EndCombo();
+ }
+
+ ImGui::SliderFloat( "Scale", &selectedModelScale, 0.01f, 2.0f );
+ ImGui::SliderFloat( "Yaw (deg)", &selectedModelYaw, -180.0f, 180.0f );
+ ImGui::Checkbox( "Place Collidable", &placeCollidable );
+ ImGui::Text( "Left-click to place selected model at cursor height" );
+ }
+ } else {
+ }
+ ImGui::Separator();
+ ImGui::Checkbox( "Enable Lighting", &lightingEnabled );
+
+ ImGui::Text( "Sun / Directional Light" );
+ glm::vec3 sunDir = sun.getDirection();
+ float dirVals[3] = { sunDir.x, sunDir.y, sunDir.z };
+ if( ImGui::SliderFloat3( "Direction", dirVals, -1.0f, 1.0f ) ) {
+ glm::vec3 nd = glm::normalize( glm::vec3( dirVals[0], dirVals[1], dirVals[2] ) );
+ if( glm::length( nd ) > 0.0f )
+ sun.setDirection( nd );
+ }
+
+ glm::vec3 sunCol = sun.getColor();
+ float colVals[3] = { sunCol.r, sunCol.g, sunCol.b };
+ if( ImGui::ColorEdit3( "Color", colVals ) ) {
+ sun.setColor( glm::vec3( colVals[0], colVals[1], colVals[2] ) );
+ }
+
+ float intensity = sun.getIntensity();
+ if( ImGui::SliderFloat( "Intensity", &intensity, 0.0f, 5.0f ) ) {
+ sun.setIntensity( intensity );
+ }
+
+ ImGui::Separator();
+ ImGui::Text( "Shadows" );
+ ImGui::Checkbox( "Snap Shadow Texels", &snapToTexels );
+ ImGui::SliderFloat( "Shadow Bias Min", &shadowBiasMinGui, 0.0f, 0.01f, "%.6f" );
+ ImGui::SliderFloat( "Shadow Bias Scale", &shadowBiasScaleGui, 0.0f, 0.05f, "%.5f" );
+ ImGui::SliderInt( "PCF Radius", &pcfRadiusGui, 0, 4 );
+
+ ImGui::Separator();
+ ImGui::Text( "Fog" );
+ float fogColVals[3] = { fogColor.r, fogColor.g, fogColor.b };
+ if( ImGui::ColorEdit3( "Fog Color", fogColVals ) ) {
+ fogColor = glm::vec3( fogColVals[0], fogColVals[1], fogColVals[2] );
+ }
+ ImGui::SliderFloat( "Fog Density", &fogDensity, 0.0f, 0.1f, "%.4f" );
+ ImGui::SliderFloat( "Fog Amount", &fogAmount, 0.0f, 1.0f );
+
+ ImGui::Separator();
+ ImGui::Text( "God Rays" );
+ ImGui::Checkbox( "Enable God Rays", &godraysEnabled );
+ ImGui::SliderFloat( "God Rays Intensity", &godraysIntensity, 0.0f, 2.0f );
+ ImGui::SliderInt( "Samples", &godraysSamples, 4, 256 );
+ ImGui::SliderFloat( "Density", &godraysDensity, 0.0f, 2.0f );
+ ImGui::SliderFloat( "Weight", &godraysWeight, 0.0f, 2.0f );
+ ImGui::SliderFloat( "Decay", &godraysDecay, 0.0f, 1.0f );
+ ImGui::SliderInt( "Downscale", &godraysDownscale, 1, 8 );
+
+ if( !lightingEnabled ) {
+
+ texShader.use();
+ texShader.setFloat( "dirLight.intensity", 0.0f );
+ }
+
+ ImGui::End();
+ }
+
+ ImGui::SetNextWindowPos( ImVec2( io.DisplaySize.x - 10.0f, 10.0f ), ImGuiCond_Always, ImVec2( 1.0f, 0.0f ) );
+
+ ImGui::SetNextWindowSize( ImVec2( 180.0f, 0.0f ), ImGuiCond_Once );
+
+ ImGuiWindowFlags perfFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar |
+ ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoFocusOnAppearing |
+ ImGuiWindowFlags_NoBringToFrontOnFocus;
+
+ ImGui::PushStyleVar( ImGuiStyleVar_WindowRounding, 6.0f );
+ ImGui::PushStyleVar( ImGuiStyleVar_WindowPadding, ImVec2( 10, 6 ) );
+ if( ImGui::Begin( "Performance", nullptr, perfFlags ) ) {
+ ImGui::Text( "FPS: %1.0f", fps );
+ ImGui::Separator();
+ ImGui::Text( "Resolution: %dx%d", fbWidth, fbHeight );
+ }
+ ImGui::End();
+ ImGui::PopStyleVar( 2 );
+
+ bool shift = ( glfwGetKey( window, GLFW_KEY_LEFT_SHIFT ) == GLFW_PRESS ) ||
+ ( glfwGetKey( window, GLFW_KEY_RIGHT_SHIFT ) == GLFW_PRESS );
+ camera.setSpeedMultiplier( shift ? 3.0f : 1.0f );
+
+ if( mouseCaptured ) {
+ if( glfwGetKey( window, GLFW_KEY_W ) == GLFW_PRESS )
+ camera.processKeyboard( scene::Movement::Forward, deltaTime );
+ if( glfwGetKey( window, GLFW_KEY_S ) == GLFW_PRESS )
+ camera.processKeyboard( scene::Movement::Backward, deltaTime );
+ if( glfwGetKey( window, GLFW_KEY_A ) == GLFW_PRESS )
+ camera.processKeyboard( scene::Movement::Left, deltaTime );
+ if( glfwGetKey( window, GLFW_KEY_D ) == GLFW_PRESS )
+ camera.processKeyboard( scene::Movement::Right, deltaTime );
+ }
+
+ worldBoxes = voxelEditor.getAllCollisionBoxes( baseWorldBoxes );
+
+ if( !models.empty() ) {
+ const auto& placed = voxelEditor.getPlacedModels();
+ for( const auto& mi : placed ) {
+ if( !mi.mCollidable )
+ continue;
+ if( mi.modelIndex < 0 || mi.modelIndex >= static_cast<int>( models.size() ) )
+ continue;
+ renderer::Model* mdl = models[mi.modelIndex].get();
+ glm::vec3 bmin = mdl->getBoundsMin();
+ glm::vec3 bmax = mdl->getBoundsMax();
+
+ glm::mat4 modelMat = glm::translate( glm::mat4( 1.0f ), mi.pos );
+ modelMat = glm::rotate( modelMat, glm::radians( mi.yaw ), glm::vec3( 0.0f, 1.0f, 0.0f ) );
+ modelMat = glm::scale( modelMat, glm::vec3( mi.scale ) );
+
+ glm::vec3 corners[8];
+ corners[0] = glm::vec3( bmin.x, bmin.y, bmin.z );
+ corners[1] = glm::vec3( bmax.x, bmin.y, bmin.z );
+ corners[2] = glm::vec3( bmin.x, bmax.y, bmin.z );
+ corners[3] = glm::vec3( bmin.x, bmin.y, bmax.z );
+ corners[4] = glm::vec3( bmax.x, bmax.y, bmin.z );
+ corners[5] = glm::vec3( bmax.x, bmin.y, bmax.z );
+ corners[6] = glm::vec3( bmin.x, bmax.y, bmax.z );
+ corners[7] = glm::vec3( bmax.x, bmax.y, bmax.z );
+
+ glm::vec3 wmin( FLT_MAX );
+ glm::vec3 wmax( -FLT_MAX );
+ for( int i = 0; i < 8; ++i ) {
+ glm::vec4 wc = modelMat * glm::vec4( corners[i], 1.0f );
+ wmin = glm::min( wmin, glm::vec3( wc ) );
+ wmax = glm::max( wmax, glm::vec3( wc ) );
+ }
+ worldBoxes.emplace_back( wmin, wmax );
+ }
+ }
+
+ camera.updatePhysics( deltaTime, worldBoxes, 0.0f );
+
+ double xpos, ypos;
+ glfwGetCursorPos( window, &xpos, &ypos );
+ if( firstMouse ) {
+ lastX = xpos;
+ lastY = ypos;
+ firstMouse = false;
+ }
+ float xoffset = static_cast<float>( xpos - lastX );
+ float yoffset = static_cast<float>( lastY - ypos );
+ lastX = xpos;
+ lastY = ypos;
+ if( mouseCaptured )
+ camera.processMouseMovement( xoffset, yoffset );
+
+ glm::vec3 sceneCenter( 0.0f, 5.0f, 0.0f );
+ float sceneRadius = 50.0f;
+ for( const auto& c : voxelEditor.getPlacedCells() ) {
+ glm::mat4 model = glm::translate( glm::mat4( 1.0f ), voxelEditor.cellToWorldCenter( c ) );
+ texturedCube.draw();
+ }
+ int fbw = 0, fbh = 0;
+ glfwGetFramebufferSize( window, &fbw, &fbh );
+ glViewport( 0, 0, fbw, fbh );
+ glEnable( GL_DEPTH_TEST );
+ glClearColor( 0.1f, 0.12f, 0.15f, 1.0f );
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ float aspect = ( fbw > 0 && fbh > 0 ) ? (float)fbw / (float)fbh : (float)width / (float)height;
+ glm::mat4 proj = camera.getProjectionMatrix( aspect );
+ glm::mat4 view = camera.getViewMatrix();
+
+ {
+ float nearPlane = 1.0f;
+ float farPlane = 200.0f;
+ glm::mat4 lightProj =
+ glm::ortho( -sceneRadius, sceneRadius, -sceneRadius, sceneRadius, nearPlane, farPlane );
+ glm::vec3 lightDir = sun.getDirection();
+
+ glm::vec3 initialLightPos = sceneCenter - lightDir * 50.0f;
+ glm::mat4 initialLightView = glm::lookAt( initialLightPos, sceneCenter, glm::vec3( 0.0f, 1.0f, 0.0f ) );
+
+ glm::vec4 centerLS = initialLightView * glm::vec4( sceneCenter, 1.0f );
+
+ float worldTexelSize = ( 2.0f * sceneRadius ) / static_cast<float>( shadowWidth );
+
+ if( snapToTexels ) {
+ centerLS.x = std::floor( centerLS.x / worldTexelSize + 0.5f ) * worldTexelSize;
+ centerLS.y = std::floor( centerLS.y / worldTexelSize + 0.5f ) * worldTexelSize;
+ }
+
+ glm::mat4 invInitialLightView = glm::inverse( initialLightView );
+ glm::vec4 snappedCenterWorld4 = invInitialLightView * centerLS;
+ glm::vec3 snappedCenterWorld = glm::vec3( snappedCenterWorld4 );
+
+ static bool shadeSmoothInit = false;
+ static glm::vec3 smoothedCenter( 0.0f );
+ if( !shadeSmoothInit ) {
+ smoothedCenter = snappedCenterWorld;
+ shadeSmoothInit = true;
+ }
+
+ float smoothAlpha = ( shadowWidth > 4096 ) ? 0.20f : 0.08f;
+ smoothedCenter = glm::mix( smoothedCenter, snappedCenterWorld, smoothAlpha );
+
+ glm::vec3 lightPos = smoothedCenter - lightDir * 50.0f;
+ glm::mat4 lightView = glm::lookAt( lightPos, smoothedCenter, glm::vec3( 0.0f, 1.0f, 0.0f ) );
+ glm::mat4 lightSpace = lightProj * lightView;
+
+ dirLightSpace = lightSpace;
+
+ glViewport( 0, 0, shadowWidth, shadowHeight );
+ glBindFramebuffer( GL_FRAMEBUFFER, depthMapFBO );
+ glClear( GL_DEPTH_BUFFER_BIT );
+ if( depthShader.id() != 0 ) {
+ depthShader.use();
+ depthShader.setMat4( "lightSpace", lightSpace );
+
+ glm::mat4 model = glm::mat4( 1.0f );
+ depthShader.setMat4( "model", model );
+ grid.draw();
+
+ for( const auto& c : voxelEditor.getPlacedCells() ) {
+ glm::mat4 m = glm::translate( glm::mat4( 1.0f ), voxelEditor.cellToWorldCenter( c ) );
+ depthShader.setMat4( "model", m );
+ texturedCube.draw();
+ }
+
+ if( !models.empty() ) {
+ const auto& placed = voxelEditor.getPlacedModels();
+ for( const auto& mi : placed ) {
+ if( mi.modelIndex < 0 || mi.modelIndex >= static_cast<int>( models.size() ) )
+ continue;
+ renderer::Model* mdl = models[mi.modelIndex].get();
+ glm::mat4 modelMat = glm::translate( glm::mat4( 1.0f ), mi.pos );
+ modelMat = glm::rotate( modelMat, glm::radians( mi.yaw ), glm::vec3( 0.0f, 1.0f, 0.0f ) );
+ modelMat = glm::scale( modelMat, glm::vec3( mi.scale ) );
+
+ const auto& meshList = mdl->getMeshes();
+ for( size_t miIdx = 0; miIdx < meshList.size(); ++miIdx ) {
+ depthShader.setMat4( "model", modelMat );
+ meshList[miIdx]->draw();
+ }
+ }
+ }
+ }
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+
+ {
+ auto instAfterShadow = Clock::now();
+ double shadowMs = std::chrono::duration<double, std::milli>( instAfterShadow - instSegStart ).count();
+ instAccumShadow += shadowMs;
+
+ instSegStart = Clock::now();
+ }
+
+ glViewport( 0, 0, fbw, fbh );
+
+ glActiveTexture( GL_TEXTURE2 );
+ glBindTexture( GL_TEXTURE_2D, depthMap );
+ glActiveTexture( GL_TEXTURE0 );
+
+ texShader.use();
+ texShader.setMat4( "lightSpace", lightSpace );
+
+ static renderer::SSAORenderer ssaoRenderer;
+ static bool ssaoInit = false;
+ if( !ssaoInit ) {
+ int initW = fbw > 0 ? fbw : width;
+ int initH = fbh > 0 ? fbh : height;
+ if( !ssaoRenderer.init( initW, initH, true ) )
+ std::cerr << "Warning: failed to init SSAORenderer" << std::endl;
+ ssaoInit = true;
+ }
+
+ ssaoRenderer.resize( fbw, fbh );
+
+ ssaoRenderer.bindGBuffer();
+ {
+ renderer::Shader& gs = ssaoRenderer.getGBufferShader();
+ gs.use();
+ gs.setMat4( "view", view );
+ gs.setMat4( "proj", proj );
+
+ glm::mat4 gridModel = glm::translate( glm::mat4( 1.0f ), glm::vec3( 0.0f, 0.0f, 0.0f ) );
+ gs.setMat4( "model", gridModel );
+ grid.draw();
+
+ for( const auto& c : voxelEditor.getPlacedCells() ) {
+ glm::mat4 model = glm::translate( glm::mat4( 1.0f ), voxelEditor.cellToWorldCenter( c ) );
+ gs.setMat4( "model", model );
+ texturedCube.draw();
+ }
+
+ if( !models.empty() ) {
+ const auto& placed = voxelEditor.getPlacedModels();
+ for( const auto& mi : placed ) {
+ if( mi.modelIndex < 0 || mi.modelIndex >= static_cast<int>( models.size() ) )
+ continue;
+
+ renderer::Model* mdl = models[mi.modelIndex].get();
+ glm::mat4 modelMat = glm::translate( glm::mat4( 1.0f ), mi.pos );
+ modelMat = glm::rotate( modelMat, glm::radians( mi.yaw ), glm::vec3( 0.0f, 1.0f, 0.0f ) );
+ modelMat = glm::scale( modelMat, glm::vec3( mi.scale ) );
+
+ const auto& meshList = mdl->getMeshes();
+ for( size_t miIdx = 0; miIdx < meshList.size(); ++miIdx ) {
+ gs.setMat4( "model", modelMat );
+ meshList[miIdx]->draw();
+ }
+ }
+ }
+ }
+ ssaoRenderer.unbind();
+
+ glm::mat4 invProj = glm::inverse( proj );
+ float aoRadius = 1.0f;
+ float aoBias = 0.025f;
+ float aoPower = 1.0f;
+ ssaoRenderer.computeSSAO( proj, invProj, aoRadius, aoBias, aoPower );
+ ssaoRenderer.blurSSAO();
+
+ ssaoRenderer.bindSSAOTextureToUnit( 3, texShader, "ssao" );
+
+ glActiveTexture( GL_TEXTURE2 );
+ glBindTexture( GL_TEXTURE_2D, depthMap );
+ glActiveTexture( GL_TEXTURE0 );
+
+ {
+ auto instAfterSSAO = Clock::now();
+ double ssaoMs = std::chrono::duration<double, std::milli>( instAfterSSAO - instSegStart ).count();
+ instAccumSSAO += ssaoMs;
+
+ instSegStart = Clock::now();
+ }
+ }
+
+ if( editorActive && !io.WantCaptureMouse ) {
+ glm::vec2 mouseFb( io.MousePos.x * io.DisplayFramebufferScale.x,
+ io.MousePos.y * io.DisplayFramebufferScale.y );
+ glm::vec3 rayOrigin, rayDir;
+ renderer::editor::makeRayFromMouse( mouseFb, fbw, fbh, view, proj, camera.position(), rayOrigin, rayDir );
+
+ lastRayOrigin = rayOrigin;
+ lastRayDir = rayDir;
+
+ bool leftDown = ( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_LEFT ) == GLFW_PRESS ) || io.MouseDown[0];
+ bool rightDown = ( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_RIGHT ) == GLFW_PRESS ) || io.MouseDown[1];
+
+ if( placementBrush == PlacementBrush::Brush ) {
+ static bool prevLeftDownLocal = false;
+
+ if( std::abs( rayDir.y ) > 1e-6f ) {
+ float t = ( brushHeight - rayOrigin.y ) / rayDir.y;
+ if( t > 0.0f ) {
+ glm::vec3 centerWorld = rayOrigin + rayDir * t;
+
+ double now = glfwGetTime();
+ if( leftDown ) {
+ if( !prevLeftDownLocal || ( now - lastPaintTime ) >= paintInterval ) {
+ PaintedCircle pc;
+ pc.mCenter = centerWorld;
+ pc.mRadius = brushRadius;
+ pc.mTextureId = textureManager.getCurrentTextureId();
+ paintedCircles.push_back( pc );
+ lastPaintTime = now;
+ }
+ } else {
+ }
+ }
+ }
+
+ prevLeftDownLocal = leftDown;
+ } else if( placementBrush == PlacementBrush::Cube ) {
+ voxelEditor.processInput( rayOrigin, rayDir, leftDown, rightDown, shift, baseWorldBoxes,
+ textureManager.getCurrentTextureId(), placeCollidable );
+ } else if( placementBrush == PlacementBrush::Model ) {
+ static bool prevLeftDownModel = false;
+
+ if( std::abs( rayDir.y ) > 1e-6f ) {
+ float t = ( brushHeight - rayOrigin.y ) / rayDir.y;
+ if( t > 0.0f ) {
+ glm::vec3 centerWorld = rayOrigin + rayDir * t;
+
+ double now = glfwGetTime();
+ if( leftDown ) {
+ if( !prevLeftDownModel ) {
+ if( !models.empty() ) {
+ scene::VoxelEditor::ModelInstance mi;
+ mi.modelIndex = selectedModelIndex;
+ mi.pos = centerWorld;
+ mi.yaw = selectedModelYaw;
+ mi.scale = selectedModelScale;
+ mi.mCollidable = placeCollidable;
+ voxelEditor.addModelInstance( mi );
+ }
+ }
+ } else {
+ }
+ }
+ }
+
+ prevLeftDownModel = leftDown;
+ }
+ }
+
+ glViewport( 0, 0, fbw, fbh );
+
+ skybox.draw( view, proj );
+
+ shader.use();
+ glm::mat4 lineModel = glm::mat4( 1.0f );
+ shader.setMat4( "model", lineModel );
+ shader.setMat4( "view", view );
+ shader.setMat4( "proj", proj );
+ // Provide camera position and fog parameters to simple shader
+ shader.setVec3( "cameraPos", camera.position() );
+ shader.setVec3( "fogColor", fogColor );
+ shader.setFloat( "fogDensity", fogDensity );
+ shader.setFloat( "fogAmount", fogAmount );
+
+ glm::mat4 gridModel = glm::translate( glm::mat4( 1.0f ), glm::vec3( 0.0f, 0.0f, 0.0f ) );
+ shader.setMat4( "model", gridModel );
+ shader.setVec3( "color", glm::vec3( 0.25f, 0.5f, 0.25f ) );
+ grid.draw();
+
+ texShader.use();
+ shader.use();
+ shader.setMat4( "view", view );
+ shader.setMat4( "proj", proj );
+
+ texShader.use();
+ texShader.setMat4( "view", view );
+ texShader.setMat4( "proj", proj );
+
+ // Provide camera position and fog parameters to textured shader
+ texShader.setVec3( "cameraPos", camera.position() );
+ texShader.setVec3( "fogColor", fogColor );
+ texShader.setFloat( "fogDensity", fogDensity );
+ texShader.setFloat( "fogAmount", fogAmount );
+
+ texShader.setFloat( "shadowBiasMin", shadowBiasMinGui );
+ texShader.setFloat( "shadowBiasScale", shadowBiasScaleGui );
+ texShader.setInt( "pcfRadius", pcfRadiusGui );
+
+ if( lightingEnabled )
+ sun.applyToShader( texShader );
+ else {
+ texShader.setVec3( "dirLight.direction", glm::vec3( 0.0f, 1.0f, 0.0f ) );
+ texShader.setVec3( "dirLight.color", glm::vec3( 0.0f ) );
+ texShader.setFloat( "dirLight.intensity", 0.0f );
+ }
+
+ texShader.setMat4( "lightSpace", dirLightSpace );
+ texShader.setFloat( "aoStrength", 1.0f );
+ texShader.setFloat( "screenWidth", static_cast<float>( fbw ) );
+ texShader.setFloat( "screenHeight", static_cast<float>( fbh ) );
+ texShader.setVec3( "tint", glm::vec3( 1.0f, 1.0f, 1.0f ) );
+ texShader.setInt( "albedo", 0 );
+
+ for( const auto& c : voxelEditor.getPlacedCells() ) {
+ int textureId = voxelEditor.getTextureIdForCell( c );
+ auto* cellTexture = textureManager.getTextureById( textureId );
+
+ if( cellTexture ) {
+ cellTexture->bind( 0 );
+ glm::mat4 model = glm::translate( glm::mat4( 1.0f ), voxelEditor.cellToWorldCenter( c ) );
+ texShader.setMat4( "model", model );
+ texShader.setVec3( "tint", glm::vec3( 1.0f, 1.0f, 1.0f ) );
+
+ texShader.setInt( "normalEnabled", 0 );
+ texturedCube.draw();
+ }
+ }
+
+ if( !models.empty() ) {
+ texShader.use();
+ texShader.setMat4( "view", view );
+ texShader.setMat4( "proj", proj );
+ texShader.setMat4( "lightSpace", dirLightSpace );
+ const auto& placed = voxelEditor.getPlacedModels();
+ for( const auto& mi : placed ) {
+ if( mi.modelIndex < 0 || mi.modelIndex >= static_cast<int>( models.size() ) )
+ continue;
+
+ renderer::Model* mdl = models[mi.modelIndex].get();
+ glm::mat4 modelMat = glm::translate( glm::mat4( 1.0f ), mi.pos );
+ modelMat = glm::rotate( modelMat, glm::radians( mi.yaw ), glm::vec3( 0.0f, 1.0f, 0.0f ) );
+ modelMat = glm::scale( modelMat, glm::vec3( mi.scale ) );
+
+ const auto& meshList = mdl->getMeshes();
+ const auto& texList = mdl->getTextures();
+ const auto& normalList = mdl->getNormalTextures();
+ const auto& meshToTex = mdl->getMeshTextureIndex();
+ const auto& meshToNormal = mdl->getMeshNormalIndex();
+
+ for( size_t miIdx = 0; miIdx < meshList.size(); ++miIdx ) {
+ texShader.setMat4( "model", modelMat );
+ int tidx = -1;
+ if( miIdx < meshToTex.size() )
+ tidx = meshToTex[miIdx];
+ bool hasNormal = false;
+ if( tidx >= 0 && tidx < static_cast<int>( texList.size() ) ) {
+ texList[tidx].bind( 0 );
+ }
+ int nidx = -1;
+ if( miIdx < meshToNormal.size() )
+ nidx = meshToNormal[miIdx];
+ if( nidx >= 0 && nidx < static_cast<int>( normalList.size() ) ) {
+ normalList[nidx].bind( 1 );
+ texShader.setInt( "normalEnabled", 1 );
+ hasNormal = true;
+ } else {
+ texShader.setInt( "normalEnabled", 0 );
+ }
+
+ texShader.setVec3( "tint", glm::vec3( 1.0f, 1.0f, 1.0f ) );
+ meshList[miIdx]->draw();
+ if( hasNormal ) {
+
+ glActiveTexture( GL_TEXTURE1 );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ glActiveTexture( GL_TEXTURE0 );
+ }
+ }
+ }
+ }
+
+ shader.use();
+
+ const auto& previewCells = voxelEditor.getPreviewCells();
+ if( !previewCells.empty() && placementEditorEnabled ) {
+ if( previewCells.size() > 1 ) {
+ glm::ivec3 minC = previewCells.front();
+ glm::ivec3 maxC = previewCells.front();
+ for( const auto& c : previewCells ) {
+ minC.x = std::min( minC.x, c.x );
+ minC.y = std::min( minC.y, c.y );
+ minC.z = std::min( minC.z, c.z );
+ maxC.x = std::max( maxC.x, c.x );
+ maxC.y = std::max( maxC.y, c.y );
+ maxC.z = std::max( maxC.z, c.z );
+ }
+
+ glm::vec3 aabbMin = voxelEditor.cellToAABB( minC ).first;
+ glm::vec3 aabbMax = voxelEditor.cellToAABB( maxC ).second;
+
+ glm::vec3 center = ( aabbMin + aabbMax ) * 0.5f;
+ glm::vec3 size = aabbMax - aabbMin;
+
+ glm::vec3 scaleVec = size / tileSize;
+
+ glm::mat4 model =
+ glm::translate( glm::mat4( 1.0f ), center ) * glm::scale( glm::mat4( 1.0f ), scaleVec );
+
+ shader.setVec3( "color", glm::vec3( 0.2f, 0.9f, 0.9f ) );
+ shader.setMat4( "model", model );
+ wireCube.draw();
+ } else {
+ const float previewScale = 0.995f;
+ glm::mat4 scaleMat = glm::scale( glm::mat4( 1.0f ), glm::vec3( previewScale ) );
+
+ shader.setVec3( "color", glm::vec3( 0.2f, 0.9f, 0.9f ) );
+
+ for( const auto& c : previewCells ) {
+ glm::mat4 model = glm::translate( glm::mat4( 1.0f ), voxelEditor.cellToWorldCenter( c ) );
+ model = model * scaleMat;
+ shader.setMat4( "model", model );
+ wireCube.draw();
+ }
+ }
+ }
+
+ if( useCircleBrush && editorActive ) {
+ if( std::abs( brushRadius - prevBrushRadius ) > 1e-6f ) {
+ circleWire = renderer::editor::makeCircleWire( brushRadius, 64 );
+ prevBrushRadius = brushRadius;
+ }
+
+ if( std::abs( lastRayDir.y ) > 1e-6f ) {
+ float t = ( brushHeight - lastRayOrigin.y ) / lastRayDir.y;
+ if( t > 0.0f ) {
+ glm::vec3 centerWorld = lastRayOrigin + lastRayDir * t;
+
+ const float previewOffset = 0.01f;
+ glm::mat4 model = glm::translate(
+ glm::mat4( 1.0f ), glm::vec3( centerWorld.x, brushHeight + previewOffset, centerWorld.z ) );
+
+ glEnable( GL_BLEND );
+ glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ glDepthMask( GL_FALSE );
+ texShader.use();
+ texShader.setMat4( "view", view );
+ texShader.setMat4( "proj", proj );
+ if( lightingEnabled )
+ sun.applyToShader( texShader );
+ else
+ texShader.setFloat( "dirLight.intensity", 0.0f );
+ texShader.setMat4( "lightSpace", dirLightSpace );
+ texShader.setMat4( "model", glm::scale( model, glm::vec3( brushRadius, 1.0f, brushRadius ) ) );
+ texShader.setVec3( "tint", glm::vec3( 1.0f, 1.0f, 1.0f ) );
+
+ auto* previewTex = textureManager.getTextureById( textureManager.getCurrentTextureId() );
+ if( previewTex )
+ previewTex->bind( 0 );
+
+ texShader.setInt( "radialEnabled", 1 );
+ texShader.setFloat( "radialInner", 0.38f );
+ texShader.setFloat( "radialOuter", 0.5f );
+ filledCircle.draw();
+
+ texShader.setInt( "radialEnabled", 0 );
+ glDepthMask( GL_TRUE );
+ glDisable( GL_BLEND );
+
+ shader.setVec3( "color", glm::vec3( 0.0f, 0.5f, 1.0f ) );
+ shader.setMat4( "model", model );
+ glLineWidth( 2.5f );
+ circleWire.draw();
+ glLineWidth( 1.0f );
+ }
+ }
+ }
+
+ if( !paintedCircles.empty() ) {
+ glEnable( GL_BLEND );
+ glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ texShader.use();
+ texShader.setMat4( "view", view );
+ texShader.setMat4( "proj", proj );
+ if( lightingEnabled )
+ sun.applyToShader( texShader );
+ else
+ texShader.setFloat( "dirLight.intensity", 0.0f );
+
+ texShader.setInt( "radialEnabled", 1 );
+ texShader.setFloat( "radialInner", 0.38f );
+ texShader.setFloat( "radialOuter", 0.5f );
+
+ std::vector<std::pair<float, size_t>> distIndex;
+ distIndex.reserve( paintedCircles.size() );
+ for( size_t i = 0; i < paintedCircles.size(); ++i ) {
+ const auto& pc = paintedCircles[i];
+ float d2 = glm::length( camera.position() - pc.mCenter );
+ distIndex.emplace_back( d2, i );
+ }
+ std::sort( distIndex.begin(), distIndex.end(),
+ [] ( const auto& a, const auto& b ) { return a.first > b.first; } );
+
+ glDepthMask( GL_FALSE );
+ for( const auto& di : distIndex ) {
+ const auto& pc = paintedCircles[di.second];
+ auto* tex = textureManager.getTextureById( pc.mTextureId );
+ if( !tex )
+ continue;
+ tex->bind( 0 );
+ glm::mat4 model =
+ glm::translate( glm::mat4( 1.0f ), glm::vec3( pc.mCenter.x, pc.mCenter.y + 0.02f, pc.mCenter.z ) );
+ model = glm::scale( model, glm::vec3( pc.mRadius, 1.0f, pc.mRadius ) );
+ texShader.setMat4( "model", model );
+ texShader.setVec3( "tint", glm::vec3( 1.0f, 1.0f, 1.0f ) );
+ filledCircle.draw();
+ }
+
+ glDepthMask( GL_TRUE );
+
+ texShader.setInt( "radialEnabled", 0 );
+
+ glDisable( GL_BLEND );
+ }
+
+ {
+ auto instAfterDraw = Clock::now();
+ double drawMs = std::chrono::duration<double, std::milli>( instAfterDraw - instSegStart ).count();
+ instAccumDraw += drawMs;
+
+ instSegStart = Clock::now();
+ }
+
+ // --- Occlusion pass for god rays ---
+ {
+ int occW = std::max( 1, fbw / godraysDownscale );
+ int occH = std::max( 1, fbh / godraysDownscale );
+ if( occlusionW != occW || occlusionH != occH ) {
+ occlusionW = occW;
+ occlusionH = occH;
+
+ glBindTexture( GL_TEXTURE_2D, occlusionTex );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, occlusionW, occlusionH, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+ if( occlusionDepthRBO == 0 )
+ glGenRenderbuffers( 1, &occlusionDepthRBO );
+ glBindRenderbuffer( GL_RENDERBUFFER, occlusionDepthRBO );
+ glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, occlusionW, occlusionH );
+
+ glBindFramebuffer( GL_FRAMEBUFFER, occlusionFBO );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, occlusionTex, 0 );
+ glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, occlusionDepthRBO );
+ GLenum drawbuf = GL_COLOR_ATTACHMENT0;
+ glDrawBuffers( 1, &drawbuf );
+ if( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE ) {
+ std::cerr << "Warning: occlusion framebuffer not complete" << std::endl;
+ }
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ }
+
+ // Render occluders to low-res occlusion texture
+ glViewport( 0, 0, occlusionW, occlusionH );
+ glBindFramebuffer( GL_FRAMEBUFFER, occlusionFBO );
+ glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+ glEnable( GL_DEPTH_TEST );
+
+ occlusionShader.use();
+ occlusionShader.setMat4( "view", view );
+ occlusionShader.setMat4( "proj", proj );
+
+ // draw grid
+ {
+ glm::mat4 model = glm::mat4( 1.0f );
+ occlusionShader.setMat4( "model", model );
+ grid.draw();
+ }
+
+ // draw voxel cells
+ for( const auto& c : voxelEditor.getPlacedCells() ) {
+ glm::mat4 model = glm::translate( glm::mat4( 1.0f ), voxelEditor.cellToWorldCenter( c ) );
+ occlusionShader.setMat4( "model", model );
+ texturedCube.draw();
+ }
+
+ // draw placed models
+ if( !models.empty() ) {
+ const auto& placed = voxelEditor.getPlacedModels();
+ for( const auto& mi : placed ) {
+ if( mi.modelIndex < 0 || mi.modelIndex >= static_cast<int>( models.size() ) )
+ continue;
+ renderer::Model* mdl = models[mi.modelIndex].get();
+ glm::mat4 modelMat = glm::translate( glm::mat4( 1.0f ), mi.pos );
+ modelMat = glm::rotate( modelMat, glm::radians( mi.yaw ), glm::vec3( 0.0f, 1.0f, 0.0f ) );
+ modelMat = glm::scale( modelMat, glm::vec3( mi.scale ) );
+
+ const auto& meshList = mdl->getMeshes();
+ for( size_t miIdx = 0; miIdx < meshList.size(); ++miIdx ) {
+ occlusionShader.setMat4( "model", modelMat );
+ meshList[miIdx]->draw();
+ }
+ }
+ }
+
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ glViewport( 0, 0, fbw, fbh );
+
+ // Compute light screen position
+ glm::vec3 lightWorldPos = sceneCenter - sun.getDirection() * 50.0f;
+ glm::vec4 clip = proj * view * glm::vec4( lightWorldPos, 1.0f );
+ glm::vec3 ndc = glm::vec3( clip ) / clip.w;
+ glm::vec2 lightScreen = glm::vec2( ndc.x, ndc.y ) * 0.5f + glm::vec2( 0.5f );
+
+ // Composite god rays using alpha so it's less likely to blow out the scene
+ glEnable( GL_BLEND );
+ glBlendFuncSeparate( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
+ glDisable( GL_DEPTH_TEST );
+
+ if( godraysEnabled ) {
+ godraysShader.use();
+ godraysShader.setInt( "occlusionTex", 4 );
+ godraysShader.setVec2( "lightScreenPos", lightScreen );
+ godraysShader.setVec3( "sunColor", sun.getColor() );
+ godraysShader.setFloat( "sunIntensity", sun.getIntensity() );
+ godraysShader.setFloat( "globalIntensity", godraysIntensity );
+ godraysShader.setInt( "samples", godraysSamples );
+ godraysShader.setFloat( "density", godraysDensity );
+ godraysShader.setFloat( "weight", godraysWeight );
+ godraysShader.setFloat( "decay", godraysDecay );
+
+ glActiveTexture( GL_TEXTURE4 );
+ glBindTexture( GL_TEXTURE_2D, occlusionTex );
+ glActiveTexture( GL_TEXTURE0 );
+
+ quadMesh.draw();
+ }
+
+ glActiveTexture( GL_TEXTURE4 );
+ glBindTexture( GL_TEXTURE_2D, occlusionTex );
+ glActiveTexture( GL_TEXTURE0 );
+
+ quadMesh.draw();
+
+ glDisable( GL_BLEND );
+ glEnable( GL_DEPTH_TEST );
+ }
+
+ ImGui::Render();
+ ImGui_ImplOpenGL3_RenderDrawData( ImGui::GetDrawData() );
+
+ {
+ auto instAfterUI = Clock::now();
+ double uiMs = std::chrono::duration<double, std::milli>( instAfterUI - instSegStart ).count();
+ instAccumUI += uiMs;
+
+ auto instFrameEnd = Clock::now();
+ double frameMs = std::chrono::duration<double, std::milli>( instFrameEnd - instFrameStart ).count();
+ instAccumFrame += frameMs;
+ ++instFrames;
+
+ if( std::chrono::duration<double>( instFrameEnd - instLastReport ).count() >= 1.0 ) {
+ double avgShadow = instAccumShadow / double( instFrames );
+ double avgSSAO = instAccumSSAO / double( instFrames );
+ double avgDraw = instAccumDraw / double( instFrames );
+ double avgUI = instAccumUI / double( instFrames );
+ double avgFrame = instAccumFrame / double( instFrames );
+ std::cout << "[TIMING] frames=" << instFrames << " frame(ms)=" << avgFrame << " shadow=" << avgShadow
+ << " ssao=" << avgSSAO << " draw=" << avgDraw << " ui=" << avgUI << std::endl;
+
+ instLastReport = instFrameEnd;
+ instAccumShadow = 0.0;
+ instAccumSSAO = 0.0;
+ instAccumDraw = 0.0;
+ instAccumUI = 0.0;
+ instAccumFrame = 0.0;
+ instFrames = 0;
+ }
+ }
+
+ glfwSwapBuffers( window );
+ glfwPollEvents();
+ }
+
+ ImGui_ImplOpenGL3_Shutdown();
+ ImGui_ImplGlfw_Shutdown();
+ ImGui::DestroyContext();
+
+ glfwDestroyWindow( window );
+ glfwTerminate();
+
+ return 0;
+}
diff --git a/apps/openmb/renderer/DirectionalLight.cpp b/apps/openmb/renderer/DirectionalLight.cpp
new file mode 100644
index 0000000..28fe281
--- /dev/null
+++ b/apps/openmb/renderer/DirectionalLight.cpp
@@ -0,0 +1,39 @@
+#include "DirectionalLight.hpp"
+
+namespace renderer {
+DirectionalLight::DirectionalLight ()
+ : mDirection( 0.3f, 1.0f, 0.5f ), mColor( 1.0f, 1.0f, 1.0f ), mIntensity( 1.0f ) {
+}
+
+void DirectionalLight::setDirection ( const glm::vec3& dir ) {
+ mDirection = dir;
+}
+
+void DirectionalLight::setColor ( const glm::vec3& c ) {
+ mColor = c;
+}
+
+void DirectionalLight::setIntensity ( float i ) {
+ mIntensity = i;
+}
+
+const glm::vec3& DirectionalLight::getDirection () const {
+ return mDirection;
+}
+
+const glm::vec3& DirectionalLight::getColor () const {
+ return mColor;
+}
+
+float DirectionalLight::getIntensity () const {
+ return mIntensity;
+}
+
+void DirectionalLight::applyToShader ( const Shader& shader, const std::string& uniformName ) const {
+
+ shader.setVec3( uniformName + ".direction", mDirection );
+ shader.setVec3( uniformName + ".color", mColor );
+ shader.setFloat( uniformName + ".intensity", mIntensity );
+}
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/DirectionalLight.hpp b/apps/openmb/renderer/DirectionalLight.hpp
new file mode 100644
index 0000000..31e914e
--- /dev/null
+++ b/apps/openmb/renderer/DirectionalLight.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "Shader.hpp"
+#include <glm/glm.hpp>
+
+namespace renderer {
+
+class DirectionalLight {
+ public:
+ DirectionalLight();
+
+ void setDirection( const glm::vec3& dir );
+ void setColor( const glm::vec3& c );
+ void setIntensity( float i );
+
+ const glm::vec3& getDirection() const;
+ const glm::vec3& getColor() const;
+ float getIntensity() const;
+
+ void applyToShader( const Shader& shader, const std::string& uniformName = "dirLight" ) const;
+
+ private:
+ glm::vec3 mDirection;
+ glm::vec3 mColor;
+ float mIntensity;
+};
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/EditorHelpers.cpp b/apps/openmb/renderer/EditorHelpers.cpp
new file mode 100644
index 0000000..9531fb0
--- /dev/null
+++ b/apps/openmb/renderer/EditorHelpers.cpp
@@ -0,0 +1,148 @@
+#include "EditorHelpers.hpp"
+#include <cmath>
+
+#include <glm/gtc/matrix_inverse.hpp>
+#include <vector>
+
+namespace renderer {
+namespace editor {
+Mesh makeWireCube ( float size ) {
+ float h = size * 0.5f;
+ std::vector<float> verts = {
+ -h, -h, -h, h, -h, -h, h, -h, -h, h, -h, h, h, -h, h, -h, -h, h, -h, -h, h, -h, -h, -h,
+
+ -h, h, -h, h, h, -h, h, h, -h, h, h, h, h, h, h, -h, h, h, -h, h, h, -h, h, -h,
+
+ -h, -h, -h, -h, h, -h, h, -h, -h, h, h, -h, h, -h, h, h, h, h, -h, -h, h, -h, h, h };
+
+ Mesh m;
+ m.createFromPositions( verts, true );
+ return m;
+}
+
+Mesh makeCircleWire ( float radius, int segments ) {
+ if( segments < 3 )
+ segments = 3;
+
+ std::vector<float> verts;
+ verts.reserve( segments * 3 );
+
+ const float twoPi = 6.28318530717958647692f;
+
+ for( int i = 0; i < segments; ++i ) {
+ int ni = ( i + 1 ) % segments;
+ float ti = (float)i / (float)segments;
+ float angi = ti * twoPi;
+ float xi = cosf( angi ) * radius;
+ float zi = sinf( angi ) * radius;
+
+ float tni = (float)ni / (float)segments;
+ float angni = tni * twoPi;
+ float xni = cosf( angni ) * radius;
+ float zni = sinf( angni ) * radius;
+
+ verts.push_back( xi );
+ verts.push_back( 0.0f );
+ verts.push_back( zi );
+
+ verts.push_back( xni );
+ verts.push_back( 0.0f );
+ verts.push_back( zni );
+ }
+
+ Mesh m;
+ m.createFromPositions( verts, true );
+ return m;
+}
+
+Mesh makeCircleFilled ( float radius, int segments ) {
+ if( segments < 3 )
+ segments = 3;
+
+ std::vector<float> data;
+ data.reserve( ( segments + 2 ) * 5 );
+
+ const float twoPi = 6.28318530717958647692f;
+
+ float cx = 0.0f, cz = 0.0f;
+ float cu = 0.5f, cv = 0.5f;
+
+ for( int i = 0; i < segments; ++i ) {
+ int i1 = i;
+ int i2 = ( i + 1 ) % segments;
+
+ float t1 = (float)i1 / (float)segments;
+ float ang1 = t1 * twoPi;
+ float x1 = cosf( ang1 ) * radius;
+ float z1 = sinf( ang1 ) * radius;
+ float u1 = ( x1 / ( radius * 2.0f ) ) + 0.5f;
+ float v1 = ( z1 / ( radius * 2.0f ) ) + 0.5f;
+
+ float t2 = (float)i2 / (float)segments;
+ float ang2 = t2 * twoPi;
+ float x2 = cosf( ang2 ) * radius;
+ float z2 = sinf( ang2 ) * radius;
+ float u2 = ( x2 / ( radius * 2.0f ) ) + 0.5f;
+ float v2 = ( z2 / ( radius * 2.0f ) ) + 0.5f;
+
+ data.push_back( cx );
+ data.push_back( 0.0f );
+ data.push_back( cz );
+ data.push_back( cu );
+ data.push_back( cv );
+
+ data.push_back( x1 );
+ data.push_back( 0.0f );
+ data.push_back( z1 );
+ data.push_back( u1 );
+ data.push_back( v1 );
+
+ data.push_back( x2 );
+ data.push_back( 0.0f );
+ data.push_back( z2 );
+ data.push_back( u2 );
+ data.push_back( v2 );
+ }
+
+ Mesh m;
+ m.createFromPosTex( data );
+ return m;
+}
+
+bool makeRayFromMouse ( const glm::vec2& mousePx, int fbw, int fbh, const glm::mat4& view,
+ const glm::mat4& proj, const glm::vec3& camPos, glm::vec3& outOrigin,
+ glm::vec3& outDir ) {
+ if( fbw <= 0 || fbh <= 0 )
+ return false;
+
+ float ndcX = ( mousePx.x / (float)fbw ) * 2.0f - 1.0f;
+ float ndcY = 1.0f - ( mousePx.y / (float)fbh ) * 2.0f;
+
+ glm::vec4 nearPointNDC( ndcX, ndcY, -1.0f, 1.0f );
+ glm::vec4 farPointNDC( ndcX, ndcY, 1.0f, 1.0f );
+
+ glm::mat4 invPV = glm::inverse( proj * view );
+
+ glm::vec4 nearWorld = invPV * nearPointNDC;
+ glm::vec4 farWorld = invPV * farPointNDC;
+ if( nearWorld.w == 0.0f || farWorld.w == 0.0f )
+ return false;
+
+ nearWorld /= nearWorld.w;
+ farWorld /= farWorld.w;
+
+ glm::vec3 nearPos = glm::vec3( nearWorld );
+ glm::vec3 farPos = glm::vec3( farWorld );
+
+ outOrigin = nearPos;
+ outDir = glm::normalize( farPos - nearPos );
+
+ if( !isfinite( outDir.x ) || !isfinite( outDir.y ) || !isfinite( outDir.z ) ) {
+ outOrigin = camPos;
+ outDir = glm::normalize( glm::vec3( 0.0f, 0.0f, -1.0f ) );
+ }
+
+ return true;
+}
+} // namespace editor
+} // namespace renderer
diff --git a/apps/openmb/renderer/EditorHelpers.hpp b/apps/openmb/renderer/EditorHelpers.hpp
new file mode 100644
index 0000000..8156675
--- /dev/null
+++ b/apps/openmb/renderer/EditorHelpers.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "Mesh.hpp"
+#include <glm/glm.hpp>
+
+namespace renderer {
+namespace editor {
+
+Mesh makeWireCube ( float size = 1.0f );
+
+Mesh makeCircleWire ( float radius = 1.0f, int segments = 64 );
+
+Mesh makeCircleFilled ( float radius = 1.0f, int segments = 64 );
+
+bool makeRayFromMouse ( const glm::vec2& mousePx, int fbw, int fbh,
+ const glm::mat4& view, const glm::mat4& proj,
+ const glm::vec3& camPos, glm::vec3& outOrigin,
+ glm::vec3& outDir );
+} // namespace editor
+} // namespace renderer
diff --git a/apps/openmb/renderer/GLHelpers.cpp b/apps/openmb/renderer/GLHelpers.cpp
new file mode 100644
index 0000000..892fec0
--- /dev/null
+++ b/apps/openmb/renderer/GLHelpers.cpp
@@ -0,0 +1,30 @@
+#include "GLHelpers.hpp"
+
+#include <iostream>
+
+namespace renderer {
+static void glDebugOutput ( GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
+ const GLchar* message, const void* userParam ) {
+ (void)source;
+ (void)type;
+ (void)id;
+ (void)severity;
+ (void)length;
+ (void)userParam;
+
+ std::cerr << "GL Debug: " << message << std::endl;
+}
+
+bool initGL () {
+
+ glEnable( GL_DEPTH_TEST );
+ glDepthFunc( GL_LESS );
+
+ setupDebugCallback();
+
+ return true;
+}
+
+void setupDebugCallback () {}
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/GLHelpers.hpp b/apps/openmb/renderer/GLHelpers.hpp
new file mode 100644
index 0000000..a566f51
--- /dev/null
+++ b/apps/openmb/renderer/GLHelpers.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#define GLFW_INCLUDE_NONE
+#include <GLFW/glfw3.h>
+#ifdef __APPLE__
+#include <OpenGL/gl3.h>
+#endif
+
+namespace renderer {
+
+bool initGL();
+
+void setupDebugCallback();
+} // namespace renderer
diff --git a/apps/openmb/renderer/Mesh.cpp b/apps/openmb/renderer/Mesh.cpp
new file mode 100644
index 0000000..4fb34ee
--- /dev/null
+++ b/apps/openmb/renderer/Mesh.cpp
@@ -0,0 +1,147 @@
+#include "Mesh.hpp"
+
+namespace renderer {
+Mesh::Mesh () : mVAO( 0 ), mVBO( 0 ), mEBO( 0 ), mVertexCount( 0 ), mIndexCount( 0 ), mMode( GL_TRIANGLES ) {}
+
+Mesh::~Mesh () {
+ if( mVBO ) {
+ glDeleteBuffers( 1, &mVBO );
+ }
+ if( mEBO ) {
+ glDeleteBuffers( 1, &mEBO );
+ }
+ if( mVAO ) {
+ glDeleteVertexArrays( 1, &mVAO );
+ }
+}
+
+bool Mesh::createFromPositions ( const std::vector<float>& positions, bool lines ) {
+ if( positions.empty() ) {
+ return false;
+ }
+
+ mMode = lines ? GL_LINES : GL_TRIANGLES;
+ mVertexCount = static_cast<GLsizei>( positions.size() / 3 );
+
+ glGenVertexArrays( 1, &mVAO );
+ glGenBuffers( 1, &mVBO );
+
+ glBindVertexArray( mVAO );
+ glBindBuffer( GL_ARRAY_BUFFER, mVBO );
+ glBufferData( GL_ARRAY_BUFFER, positions.size() * sizeof( float ), positions.data(), GL_STATIC_DRAW );
+
+ glEnableVertexAttribArray( 0 );
+ glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof( float ), (void*)0 );
+
+ glBindVertexArray( 0 );
+
+ return true;
+}
+
+bool Mesh::createFromPosTex ( const std::vector<float>& data ) {
+ if( data.empty() )
+ return false;
+
+ const size_t strideFloats = 5;
+ mMode = GL_TRIANGLES;
+ mVertexCount = static_cast<GLsizei>( data.size() / strideFloats );
+
+ glGenVertexArrays( 1, &mVAO );
+ glGenBuffers( 1, &mVBO );
+
+ glBindVertexArray( mVAO );
+ glBindBuffer( GL_ARRAY_BUFFER, mVBO );
+ glBufferData( GL_ARRAY_BUFFER, data.size() * sizeof( float ), data.data(), GL_STATIC_DRAW );
+
+ glEnableVertexAttribArray( 0 );
+ glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ), (void*)0 );
+
+ glEnableVertexAttribArray( 1 );
+ glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ),
+ (void*)( 3 * sizeof( float ) ) );
+
+ glBindVertexArray( 0 );
+ return true;
+}
+
+bool Mesh::createFromPosTexNormal ( const std::vector<float>& data ) {
+ if( data.empty() )
+ return false;
+
+ const size_t strideFloats = 8;
+ mMode = GL_TRIANGLES;
+ mVertexCount = static_cast<GLsizei>( data.size() / strideFloats );
+
+ glGenVertexArrays( 1, &mVAO );
+ glGenBuffers( 1, &mVBO );
+
+ glBindVertexArray( mVAO );
+ glBindBuffer( GL_ARRAY_BUFFER, mVBO );
+ glBufferData( GL_ARRAY_BUFFER, data.size() * sizeof( float ), data.data(), GL_STATIC_DRAW );
+
+ glEnableVertexAttribArray( 0 );
+ glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ), (void*)0 );
+
+ glEnableVertexAttribArray( 1 );
+ glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ),
+ (void*)( 3 * sizeof( float ) ) );
+
+ glEnableVertexAttribArray( 2 );
+ glVertexAttribPointer( 2, 3, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ),
+ (void*)( 5 * sizeof( float ) ) );
+
+ glBindVertexArray( 0 );
+ return true;
+}
+
+bool Mesh::createFromPosTexNormalIndexed ( const std::vector<float>& data,
+ const std::vector<unsigned int>& indices ) {
+ if( data.empty() || indices.empty() )
+ return false;
+
+ const size_t strideFloats = 8;
+ mMode = GL_TRIANGLES;
+ mVertexCount = static_cast<GLsizei>( data.size() / strideFloats );
+ mIndexCount = static_cast<GLsizei>( indices.size() );
+
+ glGenVertexArrays( 1, &mVAO );
+ glGenBuffers( 1, &mVBO );
+ glGenBuffers( 1, &mEBO );
+
+ glBindVertexArray( mVAO );
+ glBindBuffer( GL_ARRAY_BUFFER, mVBO );
+ glBufferData( GL_ARRAY_BUFFER, data.size() * sizeof( float ), data.data(), GL_STATIC_DRAW );
+
+ glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mEBO );
+ glBufferData( GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof( unsigned int ), indices.data(),
+ GL_STATIC_DRAW );
+
+ glEnableVertexAttribArray( 0 );
+ glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ), (void*)0 );
+
+ glEnableVertexAttribArray( 1 );
+ glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ),
+ (void*)( 3 * sizeof( float ) ) );
+
+ glEnableVertexAttribArray( 2 );
+ glVertexAttribPointer( 2, 3, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ),
+ (void*)( 5 * sizeof( float ) ) );
+
+ glBindVertexArray( 0 );
+ return true;
+}
+
+void Mesh::draw () const {
+ if( mVAO == 0 )
+ return;
+
+ glBindVertexArray( mVAO );
+ if( mEBO && mIndexCount > 0 ) {
+ glDrawElements( mMode, mIndexCount, GL_UNSIGNED_INT, 0 );
+ } else {
+ glDrawArrays( mMode, 0, mVertexCount );
+ }
+ glBindVertexArray( 0 );
+}
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/Mesh.hpp b/apps/openmb/renderer/Mesh.hpp
new file mode 100644
index 0000000..de0a8fa
--- /dev/null
+++ b/apps/openmb/renderer/Mesh.hpp
@@ -0,0 +1,41 @@
+#pragma once
+
+#ifdef __APPLE__
+#include <OpenGL/gl3.h>
+#else
+#define GLFW_INCLUDE_NONE
+#include <GLFW/glfw3.h>
+#ifdef __APPLE__
+#include <OpenGL/gl3.h>
+#endif
+#endif
+#include <vector>
+
+namespace renderer
+{
+ class Mesh
+ {
+ public:
+ Mesh();
+ ~Mesh();
+
+ bool createFromPositions( const std::vector< float > &positions, bool lines = false );
+
+ bool createFromPosTex( const std::vector< float > &data );
+
+ bool createFromPosTexNormal( const std::vector< float > &data );
+ bool createFromPosTexNormalIndexed( const std::vector< float > &data,
+ const std::vector< unsigned int > &indices );
+
+ void draw() const;
+
+ private:
+ GLuint mVAO;
+ GLuint mVBO;
+ GLuint mEBO;
+ GLsizei mVertexCount;
+ GLsizei mIndexCount;
+ GLenum mMode;
+ };
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/Model.cpp b/apps/openmb/renderer/Model.cpp
new file mode 100644
index 0000000..d183bbc
--- /dev/null
+++ b/apps/openmb/renderer/Model.cpp
@@ -0,0 +1,227 @@
+#include "Model.hpp"
+
+#include <algorithm>
+#include <assimp/Importer.hpp>
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <cctype>
+#include <cfloat>
+#include <filesystem>
+#include <glm/glm.hpp>
+#include <iostream>
+
+namespace renderer
+{
+ Model::Model() {}
+
+ static glm::vec3 vecMin( const glm::vec3 &a, const glm::vec3 &b )
+ {
+ return glm::vec3( std::min( a.x, b.x ), std::min( a.y, b.y ), std::min( a.z, b.z ) );
+ }
+
+ static glm::vec3 vecMax( const glm::vec3 &a, const glm::vec3 &b )
+ {
+ return glm::vec3( std::max( a.x, b.x ), std::max( a.y, b.y ), std::max( a.z, b.z ) );
+ }
+
+ bool Model::loadFromFile( const std::string &path )
+ {
+ Assimp::Importer importer;
+ const aiScene *scene =
+ importer.ReadFile( path, aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ImproveCacheLocality |
+ aiProcess_JoinIdenticalVertices );
+ if ( !scene || !scene->mRootNode )
+ {
+ std::cerr << "Failed to load model: " << path << " (" << importer.GetErrorString() << ")" << std::endl;
+ return false;
+ }
+
+ std::filesystem::path p( path );
+ std::string baseDir = p.parent_path().string();
+
+ mMeshes.clear();
+ mTextures.clear();
+ mNormalTextures.clear();
+ mMeshToTex.clear();
+ mMeshToNormal.clear();
+ mFallbackAlbedoIndex = -1;
+ mFallbackNormalIndex = -1;
+ mBoundsMin = glm::vec3( FLT_MAX );
+ mBoundsMax = glm::vec3( -FLT_MAX );
+
+ if ( std::filesystem::exists( baseDir ) && std::filesystem::is_directory( baseDir ) )
+ {
+ for ( const auto &e : std::filesystem::directory_iterator( baseDir ) )
+ {
+ if ( !e.is_regular_file() )
+ continue;
+ auto ext = e.path().extension().string();
+ std::string extLower = ext;
+ std::transform( extLower.begin(), extLower.end(), extLower.begin(),
+ []( unsigned char c ) { return std::tolower( c ); } );
+ if ( extLower != ".png" && extLower != ".jpg" && extLower != ".jpeg" && extLower != ".tga" )
+ continue;
+
+ std::string fname = e.path().filename().string();
+ std::string fnameLower = fname;
+ std::transform( fnameLower.begin(), fnameLower.end(), fnameLower.begin(),
+ []( unsigned char c ) { return std::tolower( c ); } );
+
+ if ( fnameLower.find( "base" ) != std::string::npos ||
+ fnameLower.find( "albedo" ) != std::string::npos ||
+ fnameLower.find( "diff" ) != std::string::npos )
+ {
+ Texture t;
+ if ( t.loadFromFile( e.path().string() ) )
+ {
+ mFallbackAlbedoIndex = static_cast< int >( mTextures.size() );
+ mTextures.push_back( std::move( t ) );
+ std::cerr << "Model: found fallback albedo: " << e.path().string() << " (index "
+ << mFallbackAlbedoIndex << ")\n";
+ }
+ }
+ else if ( fnameLower.find( "normal" ) != std::string::npos ||
+ fnameLower.find( "nrm" ) != std::string::npos ||
+ fnameLower.find( "bump" ) != std::string::npos )
+ {
+ Texture tn;
+ if ( tn.loadFromFile( e.path().string() ) )
+ {
+ mFallbackNormalIndex = static_cast< int >( mNormalTextures.size() );
+ mNormalTextures.push_back( std::move( tn ) );
+ std::cerr << "Model: found fallback normal: " << e.path().string() << " (index "
+ << mFallbackNormalIndex << ")\n";
+ }
+ }
+ }
+ }
+
+ return processNode( scene->mRootNode, scene, baseDir );
+ }
+
+ bool Model::processNode( aiNode *node, const aiScene *scene, const std::string &baseDir )
+ {
+ for ( unsigned int i = 0; i < node->mNumMeshes; ++i )
+ {
+ aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
+ int texIndex = -1;
+ int normalIndex = -1;
+ if ( !processMesh( mesh, scene, baseDir, texIndex, normalIndex ) )
+ return false;
+
+ if ( texIndex == -1 && mFallbackAlbedoIndex != -1 )
+ texIndex = mFallbackAlbedoIndex;
+ if ( normalIndex == -1 && mFallbackNormalIndex != -1 )
+ normalIndex = mFallbackNormalIndex;
+ mMeshToTex.push_back( texIndex );
+ mMeshToNormal.push_back( normalIndex );
+ std::cerr << "Model: mesh " << i << " -> albedo index " << texIndex << ", normal index " << normalIndex
+ << "\n";
+ }
+
+ for ( unsigned int i = 0; i < node->mNumChildren; ++i )
+ {
+ if ( !processNode( node->mChildren[i], scene, baseDir ) )
+ return false;
+ }
+
+ return true;
+ }
+
+ bool Model::processMesh( aiMesh *mesh, const aiScene *scene, const std::string &baseDir, int &outTexIndex,
+ int &outNormalIndex )
+ {
+ std::vector< float > data;
+ data.reserve( mesh->mNumFaces * 3 * 8 );
+
+ glm::vec3 localMin( FLT_MAX );
+ glm::vec3 localMax( -FLT_MAX );
+
+ for ( unsigned int f = 0; f < mesh->mNumFaces; ++f )
+ {
+ aiFace &face = mesh->mFaces[f];
+ for ( unsigned int vi = 0; vi < face.mNumIndices; ++vi )
+ {
+ unsigned int idx = face.mIndices[vi];
+ aiVector3D pos = mesh->mVertices[idx];
+ aiVector3D normal = mesh->HasNormals() ? mesh->mNormals[idx] : aiVector3D( 0.0f, 1.0f, 0.0f );
+ aiVector3D texcoord =
+ mesh->HasTextureCoords( 0 ) ? mesh->mTextureCoords[0][idx] : aiVector3D( 0.0f, 0.0f, 0.0f );
+
+ data.push_back( pos.x );
+ data.push_back( pos.y );
+ data.push_back( pos.z );
+
+ data.push_back( texcoord.x );
+ data.push_back( texcoord.y );
+
+ data.push_back( normal.x );
+ data.push_back( normal.y );
+ data.push_back( normal.z );
+ }
+ }
+
+ for ( size_t i = 0; i + 7 < data.size(); i += 8 )
+ {
+ glm::vec3 p( data[i + 0], data[i + 1], data[i + 2] );
+ localMin = vecMin( localMin, p );
+ localMax = vecMax( localMax, p );
+ }
+ if ( localMin.x <= localMax.x )
+ {
+ mBoundsMin = vecMin( mBoundsMin, localMin );
+ mBoundsMax = vecMax( mBoundsMax, localMax );
+ }
+ auto m = std::make_unique< Mesh >();
+ if ( !m->createFromPosTexNormal( data ) )
+ {
+ std::cerr << "Failed to create mesh for model" << std::endl;
+ return false;
+ }
+
+ mMeshes.push_back( std::move( m ) );
+
+ outTexIndex = -1;
+ outNormalIndex = -1;
+ if ( mesh->mMaterialIndex >= 0 && scene->mMaterials && mesh->mMaterialIndex < scene->mNumMaterials )
+ {
+ aiMaterial *mat = scene->mMaterials[mesh->mMaterialIndex];
+ aiString texPath;
+ if ( AI_SUCCESS == mat->GetTexture( aiTextureType_DIFFUSE, 0, &texPath ) )
+ {
+ std::string texStr = texPath.C_Str();
+ std::filesystem::path full = std::filesystem::path( baseDir ) / texStr;
+ Texture t;
+ if ( t.loadFromFile( full.string() ) )
+ {
+ outTexIndex = static_cast< int >( mTextures.size() );
+ mTextures.push_back( std::move( t ) );
+ }
+ else
+ {
+ std::cerr << "Warning: failed to load texture: " << full.string() << std::endl;
+ }
+ }
+
+ if ( AI_SUCCESS == mat->GetTexture( aiTextureType_NORMALS, 0, &texPath ) ||
+ AI_SUCCESS == mat->GetTexture( aiTextureType_HEIGHT, 0, &texPath ) )
+ {
+ std::string texStrN = texPath.C_Str();
+ std::filesystem::path fullN = std::filesystem::path( baseDir ) / texStrN;
+ Texture tn;
+ if ( tn.loadFromFile( fullN.string() ) )
+ {
+ outNormalIndex = static_cast< int >( mNormalTextures.size() );
+ mNormalTextures.push_back( std::move( tn ) );
+ }
+ else
+ {
+ std::cerr << "Warning: failed to load normal map: " << fullN.string() << std::endl;
+ }
+ }
+ }
+
+ return true;
+ }
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/Model.hpp b/apps/openmb/renderer/Model.hpp
new file mode 100644
index 0000000..e20c523
--- /dev/null
+++ b/apps/openmb/renderer/Model.hpp
@@ -0,0 +1,51 @@
+#pragma once
+
+#include "Mesh.hpp"
+#include "Shader.hpp"
+#include "Texture.hpp"
+
+#include <assimp/scene.h>
+#include <glm/glm.hpp>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace renderer
+{
+ class Model
+ {
+ public:
+ Model();
+ ~Model() = default;
+
+ bool loadFromFile( const std::string &path );
+
+ size_t meshCount() const { return mMeshes.size(); }
+
+ const glm::vec3 &getBoundsMin() const { return mBoundsMin; }
+ const glm::vec3 &getBoundsMax() const { return mBoundsMax; }
+
+ const std::vector< std::unique_ptr< Mesh > > &getMeshes() const { return mMeshes; }
+ const std::vector< Texture > &getTextures() const { return mTextures; }
+ const std::vector< Texture > &getNormalTextures() const { return mNormalTextures; }
+ const std::vector< int > &getMeshTextureIndex() const { return mMeshToTex; }
+ const std::vector< int > &getMeshNormalIndex() const { return mMeshToNormal; }
+
+ private:
+ bool processNode( aiNode *node, const aiScene *scene, const std::string &baseDir );
+ bool processMesh( aiMesh *mesh, const aiScene *scene, const std::string &baseDir, int &outTexIndex,
+ int &outNormalIndex );
+
+ std::vector< std::unique_ptr< Mesh > > mMeshes;
+ std::vector< Texture > mTextures;
+ std::vector< Texture > mNormalTextures;
+
+ std::vector< int > mMeshToTex;
+ std::vector< int > mMeshToNormal;
+ int mFallbackAlbedoIndex;
+ int mFallbackNormalIndex;
+ glm::vec3 mBoundsMin;
+ glm::vec3 mBoundsMax;
+ };
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/SSAORenderer.cpp b/apps/openmb/renderer/SSAORenderer.cpp
new file mode 100644
index 0000000..8493529
--- /dev/null
+++ b/apps/openmb/renderer/SSAORenderer.cpp
@@ -0,0 +1,319 @@
+#include "SSAORenderer.hpp"
+
+#define GLFW_INCLUDE_NONE
+#include <GLFW/glfw3.h>
+#ifdef __APPLE__
+#include <OpenGL/gl3.h>
+#endif
+#include <glm/gtc/type_ptr.hpp>
+#include <iostream>
+#include <random>
+
+namespace renderer {
+
+SSAORenderer::SSAORenderer ()
+ : mWidth( 0 ), mHeight( 0 ), mHalfRes( true ), mKernelSize( 32 ), mGBufferFBO( 0 ), mGNormal( 0 ), mGDepth( 0 ),
+ mSSAOFBO( 0 ), mSSAOTexture( 0 ), mSSAOBlurFBO( 0 ), mSSAOBlurTexture( 0 ), mNoiseTexture( 0 ), mQuadVAO( 0 ),
+ mQuadVBO( 0 ) {
+}
+
+SSAORenderer::~SSAORenderer () {
+ if( mGNormal )
+ glDeleteTextures( 1, &mGNormal );
+ if( mGDepth )
+ glDeleteTextures( 1, &mGDepth );
+ if( mGBufferFBO )
+ glDeleteFramebuffers( 1, &mGBufferFBO );
+ if( mSSAOTexture )
+ glDeleteTextures( 1, &mSSAOTexture );
+ if( mSSAOBlurTexture )
+ glDeleteTextures( 1, &mSSAOBlurTexture );
+ if( mSSAOFBO )
+ glDeleteFramebuffers( 1, &mSSAOFBO );
+ if( mSSAOBlurFBO )
+ glDeleteFramebuffers( 1, &mSSAOBlurFBO );
+ if( mNoiseTexture )
+ glDeleteTextures( 1, &mNoiseTexture );
+ if( mQuadVBO )
+ glDeleteBuffers( 1, &mQuadVBO );
+ if( mQuadVAO )
+ glDeleteVertexArrays( 1, &mQuadVAO );
+}
+
+bool SSAORenderer::init ( int width, int height, bool halfRes ) {
+ mWidth = width;
+ mHeight = height;
+ mHalfRes = halfRes;
+
+ if( !mGBufferShader.fromFiles( "apps/openmb/resources/shaders/gbuffer.vert",
+ "apps/openmb/resources/shaders/gbuffer.frag" ) ) {
+ std::cerr << "Failed to load gbuffer shader" << std::endl;
+ return false;
+ }
+ if( !mSSAOShader.fromFiles( "apps/openmb/resources/shaders/ssao.vert",
+ "apps/openmb/resources/shaders/ssao.frag" ) ) {
+ std::cerr << "Failed to load ssao shader" << std::endl;
+ return false;
+ }
+ if( !mBlurShader.fromFiles( "apps/openmb/resources/shaders/ssao.vert",
+ "apps/openmb/resources/shaders/ssao_blur.frag" ) ) {
+ std::cerr << "Failed to load ssao blur shader" << std::endl;
+ return false;
+ }
+
+ initBuffers();
+ initKernelAndNoise();
+
+ float quadVertices[] = {
+
+ -1.0f,
+ -1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ -1.0f,
+ 1.0f,
+ 0.0f,
+ -1.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ -1.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ -1.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ };
+
+ glGenVertexArrays( 1, &mQuadVAO );
+ glGenBuffers( 1, &mQuadVBO );
+ glBindVertexArray( mQuadVAO );
+ glBindBuffer( GL_ARRAY_BUFFER, mQuadVBO );
+ glBufferData( GL_ARRAY_BUFFER, sizeof( quadVertices ), quadVertices, GL_STATIC_DRAW );
+ glEnableVertexAttribArray( 0 );
+ glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof( float ), (void*)0 );
+ glEnableVertexAttribArray( 1 );
+ glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof( float ), (void*)( 2 * sizeof( float ) ) );
+ glBindVertexArray( 0 );
+
+ return true;
+}
+
+void SSAORenderer::initBuffers () {
+
+ if( mGBufferFBO == 0 )
+ glGenFramebuffers( 1, &mGBufferFBO );
+ glBindFramebuffer( GL_FRAMEBUFFER, mGBufferFBO );
+
+ if( mGNormal )
+ glDeleteTextures( 1, &mGNormal );
+ glGenTextures( 1, &mGNormal );
+ glBindTexture( GL_TEXTURE_2D, mGNormal );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB16F, mWidth, mHeight, 0, GL_RGB, GL_FLOAT, nullptr );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mGNormal, 0 );
+
+ if( mGDepth )
+ glDeleteTextures( 1, &mGDepth );
+ glGenTextures( 1, &mGDepth );
+ glBindTexture( GL_TEXTURE_2D, mGDepth );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, mWidth, mHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, mGDepth, 0 );
+
+ GLenum attachments[1] = { GL_COLOR_ATTACHMENT0 };
+ glDrawBuffers( 1, attachments );
+
+ if( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE )
+ std::cerr << "GBuffer not complete" << std::endl;
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+
+ if( mSSAOFBO == 0 )
+ glGenFramebuffers( 1, &mSSAOFBO );
+ glBindFramebuffer( GL_FRAMEBUFFER, mSSAOFBO );
+ if( mSSAOTexture )
+ glDeleteTextures( 1, &mSSAOTexture );
+ glGenTextures( 1, &mSSAOTexture );
+ glBindTexture( GL_TEXTURE_2D, mSSAOTexture );
+ int w = mHalfRes ? std::max( 1, mWidth / 2 ) : mWidth;
+ int h = mHalfRes ? std::max( 1, mHeight / 2 ) : mHeight;
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mSSAOTexture, 0 );
+ if( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE )
+ std::cerr << "SSAO FBO not complete" << std::endl;
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+
+ if( mSSAOBlurFBO == 0 )
+ glGenFramebuffers( 1, &mSSAOBlurFBO );
+ glBindFramebuffer( GL_FRAMEBUFFER, mSSAOBlurFBO );
+ if( mSSAOBlurTexture )
+ glDeleteTextures( 1, &mSSAOBlurTexture );
+ glGenTextures( 1, &mSSAOBlurTexture );
+ glBindTexture( GL_TEXTURE_2D, mSSAOBlurTexture );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mSSAOBlurTexture, 0 );
+ if( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE )
+ std::cerr << "SSAO Blur FBO not complete" << std::endl;
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+}
+
+void SSAORenderer::initKernelAndNoise () {
+ mKernel.clear();
+ std::uniform_real_distribution<float> randomFloats( 0.0f, 1.0f );
+ std::mt19937 gen;
+
+ for( int i = 0; i < mKernelSize; ++i ) {
+ glm::vec3 sample( randomFloats( gen ) * 2.0f - 1.0f, randomFloats( gen ) * 2.0f - 1.0f,
+ randomFloats( gen ) );
+ sample = glm::normalize( sample );
+ sample *= randomFloats( gen );
+ float scale = float( i ) / float( mKernelSize );
+ scale = glm::mix( 0.1f, 1.0f, scale * scale );
+ sample *= scale;
+ mKernel.push_back( sample );
+ }
+
+ mSSAOShader.use();
+ for( int i = 0; i < mKernelSize; ++i ) {
+ mSSAOShader.setVec3( std::string( "samples[" ) + std::to_string( i ) + std::string( "]" ), mKernel[i] );
+ }
+ mSSAOShader.setInt( "kernelSize", mKernelSize );
+
+ std::vector<float> noise;
+ for( int i = 0; i < 16; ++i ) {
+ float x = randomFloats( gen ) * 2.0f - 1.0f;
+ float y = randomFloats( gen ) * 2.0f - 1.0f;
+ noise.push_back( x );
+ noise.push_back( y );
+ noise.push_back( 0.0f );
+ }
+ if( mNoiseTexture )
+ glDeleteTextures( 1, &mNoiseTexture );
+ glGenTextures( 1, &mNoiseTexture );
+ glBindTexture( GL_TEXTURE_2D, mNoiseTexture );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F, 4, 4, 0, GL_RGB, GL_FLOAT, noise.data() );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+}
+
+void SSAORenderer::resize ( int width, int height ) {
+ if( width == mWidth && height == mHeight )
+ return;
+ mWidth = width;
+ mHeight = height;
+ initBuffers();
+}
+
+void SSAORenderer::bindGBuffer () {
+ glBindFramebuffer( GL_FRAMEBUFFER, mGBufferFBO );
+ glViewport( 0, 0, mWidth, mHeight );
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+}
+
+void SSAORenderer::unbind () {
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+}
+
+void SSAORenderer::computeSSAO ( const glm::mat4& proj, const glm::mat4& invProj, float radius, float bias,
+ float power ) {
+ int w = mHalfRes ? std::max( 1, mWidth / 2 ) : mWidth;
+ int h = mHalfRes ? std::max( 1, mHeight / 2 ) : mHeight;
+
+ glBindFramebuffer( GL_FRAMEBUFFER, mSSAOFBO );
+ glViewport( 0, 0, w, h );
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ mSSAOShader.use();
+ mSSAOShader.setMat4( "proj", proj );
+ mSSAOShader.setMat4( "invProj", invProj );
+ mSSAOShader.setFloat( "radius", radius );
+ mSSAOShader.setFloat( "bias", bias );
+ mSSAOShader.setFloat( "power", power );
+
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, mGDepth );
+ mSSAOShader.setInt( "gDepth", 0 );
+
+ glActiveTexture( GL_TEXTURE1 );
+ glBindTexture( GL_TEXTURE_2D, mGNormal );
+ mSSAOShader.setInt( "gNormal", 1 );
+
+ glActiveTexture( GL_TEXTURE2 );
+ glBindTexture( GL_TEXTURE_2D, mNoiseTexture );
+ mSSAOShader.setInt( "texNoise", 2 );
+
+ float noiseScaleVal = float( w ) / 4.0f;
+ mSSAOShader.setInt( "gDepth", 0 );
+ mSSAOShader.setInt( "gNormal", 1 );
+ mSSAOShader.setInt( "texNoise", 2 );
+ mSSAOShader.setFloat( "noiseScale", noiseScaleVal );
+ glBindVertexArray( mQuadVAO );
+ glDrawArrays( GL_TRIANGLES, 0, 6 );
+ glBindVertexArray( 0 );
+
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+}
+
+void SSAORenderer::blurSSAO () {
+ int w = mHalfRes ? std::max( 1, mWidth / 2 ) : mWidth;
+ int h = mHalfRes ? std::max( 1, mHeight / 2 ) : mHeight;
+
+ glBindFramebuffer( GL_FRAMEBUFFER, mSSAOBlurFBO );
+ glViewport( 0, 0, w, h );
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ mBlurShader.use();
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, mSSAOTexture );
+ mBlurShader.setInt( "ssaoInput", 0 );
+ mBlurShader.setInt( "horizontal", 1 );
+ mBlurShader.setVec2( "texelSize", glm::vec2( 1.0f / float( w ), 1.0f / float( h ) ) );
+ glBindVertexArray( mQuadVAO );
+ glDrawArrays( GL_TRIANGLES, 0, 6 );
+ glBindVertexArray( 0 );
+
+ glBindFramebuffer( GL_FRAMEBUFFER, mSSAOFBO );
+ glViewport( 0, 0, w, h );
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ mBlurShader.use();
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, mSSAOBlurTexture );
+ mBlurShader.setInt( "ssaoInput", 0 );
+ mBlurShader.setInt( "horizontal", 0 );
+ mBlurShader.setVec2( "texelSize", glm::vec2( 1.0f / float( w ), 1.0f / float( h ) ) );
+ glBindVertexArray( mQuadVAO );
+ glDrawArrays( GL_TRIANGLES, 0, 6 );
+ glBindVertexArray( 0 );
+
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+}
+
+unsigned int SSAORenderer::getSSAOTextureID () const {
+ return mSSAOTexture;
+}
+
+void SSAORenderer::bindSSAOTextureToUnit ( int unit, renderer::Shader& shader, const std::string& uniformName ) const {
+ glActiveTexture( GL_TEXTURE0 + unit );
+ glBindTexture( GL_TEXTURE_2D, getSSAOTextureID() );
+ shader.setInt( uniformName, unit );
+}
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/SSAORenderer.hpp b/apps/openmb/renderer/SSAORenderer.hpp
new file mode 100644
index 0000000..3075252
--- /dev/null
+++ b/apps/openmb/renderer/SSAORenderer.hpp
@@ -0,0 +1,64 @@
+#pragma once
+
+#include "Shader.hpp"
+#include <glm/glm.hpp>
+#include <vector>
+
+#define GLFW_INCLUDE_NONE
+#include <GLFW/glfw3.h>
+#ifdef __APPLE__
+#include <OpenGL/gl3.h>
+#endif
+
+namespace renderer {
+class SSAORenderer {
+ public:
+ SSAORenderer();
+ ~SSAORenderer();
+
+ bool init( int width, int height, bool halfRes = true );
+ void resize( int width, int height );
+
+ void bindGBuffer();
+ void unbind();
+
+ void computeSSAO( const glm::mat4& proj, const glm::mat4& invProj, float radius, float bias, float power );
+ void blurSSAO();
+
+ unsigned int getSSAOTextureID() const;
+ void bindSSAOTextureToUnit( int unit, renderer::Shader& shader, const std::string& uniformName = "ssao" ) const;
+
+ renderer::Shader& getGBufferShader () { return mGBufferShader; }
+
+ private:
+ void initBuffers();
+ void initKernelAndNoise();
+
+ int mWidth;
+ int mHeight;
+ bool mHalfRes;
+
+ GLuint mGBufferFBO;
+ GLuint mGNormal;
+ GLuint mGDepth;
+
+ GLuint mSSAOFBO;
+ GLuint mSSAOTexture;
+
+ GLuint mSSAOBlurFBO;
+ GLuint mSSAOBlurTexture;
+
+ GLuint mNoiseTexture;
+
+ GLuint mQuadVAO;
+ GLuint mQuadVBO;
+
+ std::vector<glm::vec3> mKernel;
+ int mKernelSize;
+
+ renderer::Shader mGBufferShader;
+ renderer::Shader mSSAOShader;
+ renderer::Shader mBlurShader;
+};
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/Shader.cpp b/apps/openmb/renderer/Shader.cpp
new file mode 100644
index 0000000..a7c94e6
--- /dev/null
+++ b/apps/openmb/renderer/Shader.cpp
@@ -0,0 +1,137 @@
+#include "Shader.hpp"
+
+#define GLFW_INCLUDE_NONE
+#include <GLFW/glfw3.h>
+#ifdef __APPLE__
+#include <OpenGL/gl3.h>
+#endif
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
+namespace renderer {
+Shader::Shader () : mID( 0 ) {}
+
+Shader::~Shader () {
+ if( mID ) {
+ glDeleteProgram( mID );
+ }
+}
+
+bool Shader::fromSource ( const std::string& vertexSrc, const std::string& fragmentSrc ) {
+ return compileShader( vertexSrc.c_str(), fragmentSrc.c_str() );
+}
+
+bool Shader::fromFiles ( const std::string& vertexPath, const std::string& fragmentPath ) {
+ std::string vs = readFile( vertexPath );
+ std::string fs = readFile( fragmentPath );
+ if( vs.empty() || fs.empty() ) {
+ return false;
+ }
+ return compileShader( vs.c_str(), fs.c_str() );
+}
+
+void Shader::use () const {
+ glUseProgram( mID );
+}
+
+unsigned int Shader::id () const {
+ return mID;
+}
+
+void Shader::setInt ( const std::string& name, int value ) const {
+ glUniform1i( glGetUniformLocation( mID, name.c_str() ), value );
+}
+
+void Shader::setFloat ( const std::string& name, float value ) const {
+ glUniform1f( glGetUniformLocation( mID, name.c_str() ), value );
+}
+
+void Shader::setVec3 ( const std::string& name, const glm::vec3& v ) const {
+ glUniform3f( glGetUniformLocation( mID, name.c_str() ), v.x, v.y, v.z );
+}
+
+void Shader::setVec2 ( const std::string& name, const glm::vec2& v ) const {
+ glUniform2f( glGetUniformLocation( mID, name.c_str() ), v.x, v.y );
+}
+
+void Shader::setMat4 ( const std::string& name, const glm::mat4& m ) const {
+ glUniformMatrix4fv( glGetUniformLocation( mID, name.c_str() ), 1, GL_FALSE, &m[0][0] );
+}
+
+bool Shader::compileShader ( const char* vSrc, const char* fSrc ) {
+ GLuint vert = glCreateShader( GL_VERTEX_SHADER );
+ glShaderSource( vert, 1, &vSrc, nullptr );
+ glCompileShader( vert );
+
+ GLint success = 0;
+ glGetShaderiv( vert, GL_COMPILE_STATUS, &success );
+ if( success == GL_FALSE ) {
+ GLint len = 0;
+ glGetShaderiv( vert, GL_INFO_LOG_LENGTH, &len );
+ std::string log( len, '\0' );
+ glGetShaderInfoLog( vert, len, &len, &log[0] );
+ std::cerr << "Vertex shader compile error:\n"
+ << log << std::endl;
+ std::cerr << "[Shader] Vertex shader ID = " << vert << std::endl;
+ glDeleteShader( vert );
+ return false;
+ }
+
+ GLuint frag = glCreateShader( GL_FRAGMENT_SHADER );
+
+ glShaderSource( frag, 1, &fSrc, nullptr );
+ glCompileShader( frag );
+
+ glGetShaderiv( frag, GL_COMPILE_STATUS, &success );
+ if( success == GL_FALSE ) {
+ GLint len = 0;
+ glGetShaderiv( frag, GL_INFO_LOG_LENGTH, &len );
+ std::string log( len, '\0' );
+ glGetShaderInfoLog( frag, len, &len, &log[0] );
+ std::cerr << "Fragment shader compile error:\n"
+ << log << std::endl;
+ glDeleteShader( frag );
+ glDeleteShader( vert );
+ return false;
+ }
+
+ mID = glCreateProgram();
+ glAttachShader( mID, vert );
+ glAttachShader( mID, frag );
+ glLinkProgram( mID );
+
+ glGetProgramiv( mID, GL_LINK_STATUS, &success );
+ if( success == GL_FALSE ) {
+ GLint len = 0;
+ glGetProgramiv( mID, GL_INFO_LOG_LENGTH, &len );
+ std::string log( len, '\0' );
+ glGetProgramInfoLog( mID, len, &len, &log[0] );
+ std::cerr << "Shader link error:\n"
+ << log << std::endl;
+ glDeleteProgram( mID );
+ mID = 0;
+ glDeleteShader( vert );
+ glDeleteShader( frag );
+ return false;
+ }
+
+ glDetachShader( mID, vert );
+ glDetachShader( mID, frag );
+ glDeleteShader( vert );
+ glDeleteShader( frag );
+
+ return true;
+}
+
+std::string Shader::readFile ( const std::string& path ) const {
+ std::ifstream in( path );
+ if( !in ) {
+ return std::string();
+ }
+ std::stringstream ss;
+ ss << in.rdbuf();
+ return ss.str();
+}
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/Shader.hpp b/apps/openmb/renderer/Shader.hpp
new file mode 100644
index 0000000..260e67e
--- /dev/null
+++ b/apps/openmb/renderer/Shader.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <glm/glm.hpp>
+#include <string>
+
+namespace renderer {
+class Shader {
+ public:
+ Shader();
+ ~Shader();
+
+ bool fromSource( const std::string& vertexSrc, const std::string& fragmentSrc );
+ bool fromFiles( const std::string& vertexPath, const std::string& fragmentPath );
+
+ void use() const;
+
+ unsigned int id() const;
+
+ void setInt( const std::string& name, int value ) const;
+ void setFloat( const std::string& name, float value ) const;
+ void setVec3( const std::string& name, const glm::vec3& v ) const;
+ void setVec2( const std::string& name, const glm::vec2& v ) const;
+ void setMat4( const std::string& name, const glm::mat4& m ) const;
+
+ private:
+ unsigned int mID;
+ bool compileShader( const char* vSrc, const char* fSrc );
+ std::string readFile( const std::string& path ) const;
+};
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/Skybox.cpp b/apps/openmb/renderer/Skybox.cpp
new file mode 100644
index 0000000..fea0021
--- /dev/null
+++ b/apps/openmb/renderer/Skybox.cpp
@@ -0,0 +1,155 @@
+#include "Skybox.hpp"
+
+#include "Shader.hpp"
+#include <stb_image.h>
+
+#include <algorithm>
+#include <filesystem>
+#include <iostream>
+
+namespace Fs = std::filesystem;
+
+namespace renderer {
+Skybox::Skybox () : mTexID( 0 ), mVAO( 0 ), mVBO( 0 ), mInitialized( false ) {}
+
+Skybox::~Skybox () {
+ if( mVBO )
+ glDeleteBuffers( 1, &mVBO );
+ if( mVAO )
+ glDeleteVertexArrays( 1, &mVAO );
+ if( mTexID )
+ glDeleteTextures( 1, &mTexID );
+}
+
+static std::string toLower ( const std::string& s ) {
+ std::string out = s;
+ std::transform( out.begin(), out.end(), out.begin(), [] ( unsigned char c ) { return std::tolower( c ); } );
+ return out;
+}
+
+bool Skybox::loadFromDirectory ( const std::string& dirPath ) {
+
+ std::vector<std::string> faceTokens = { "right", "left", "top", "bottom", "front", "back" };
+ std::vector<std::string> faces( 6 );
+
+ if( !Fs::exists( dirPath ) || !Fs::is_directory( dirPath ) ) {
+ std::cerr << "Skybox directory does not exist: " << dirPath << std::endl;
+ return false;
+ }
+
+ for( auto& entry : Fs::directory_iterator( dirPath ) ) {
+ if( !entry.is_regular_file() )
+ continue;
+ auto name = entry.path().filename().string();
+ std::string lname = toLower( name );
+ for( size_t i = 0; i < faceTokens.size(); ++i ) {
+ if( lname.find( faceTokens[i] ) != std::string::npos ) {
+ faces[i] = entry.path().string();
+ }
+ }
+ }
+
+ for( size_t i = 0; i < faces.size(); ++i ) {
+ if( faces[i].empty() ) {
+ std::cerr << "Missing skybox face for token: " << faceTokens[i] << std::endl;
+ return false;
+ }
+ }
+
+ return loadFaces( faces );
+}
+
+bool Skybox::loadFaces ( const std::vector<std::string>& faces ) {
+ glGenTextures( 1, &mTexID );
+ glBindTexture( GL_TEXTURE_CUBE_MAP, mTexID );
+
+ stbi_set_flip_vertically_on_load( false );
+ for( unsigned i = 0; i < faces.size(); ++i ) {
+ int w, h, ch;
+ unsigned char* data = stbi_load( faces[i].c_str(), &w, &h, &ch, 0 );
+ if( !data ) {
+ std::cerr << "Failed to load skybox face: " << faces[i] << std::endl;
+ glBindTexture( GL_TEXTURE_CUBE_MAP, 0 );
+ return false;
+ }
+ GLenum format = ( ch == 4 ) ? GL_RGBA : GL_RGB;
+ glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, data );
+ stbi_image_free( data );
+ }
+
+ glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
+
+ glBindTexture( GL_TEXTURE_CUBE_MAP, 0 );
+
+ initMesh();
+ mInitialized = true;
+ return true;
+}
+
+void Skybox::initMesh () {
+
+ float skyboxVertices[] = { -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
+
+ -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
+ -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
+
+ 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
+
+ -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
+
+ -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f,
+
+ -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f };
+
+ glGenVertexArrays( 1, &mVAO );
+ glGenBuffers( 1, &mVBO );
+ glBindVertexArray( mVAO );
+ glBindBuffer( GL_ARRAY_BUFFER, mVBO );
+ glBufferData( GL_ARRAY_BUFFER, sizeof( skyboxVertices ), &skyboxVertices, GL_STATIC_DRAW );
+ glEnableVertexAttribArray( 0 );
+ glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof( float ), (void*)0 );
+ glBindVertexArray( 0 );
+}
+
+void Skybox::draw ( const glm::mat4& view, const glm::mat4& proj ) {
+ if( !mInitialized )
+ return;
+
+ static Shader s;
+ static bool shaderLoaded = false;
+ if( !shaderLoaded ) {
+ s.fromFiles( "apps/openmb/resources/shaders/skybox.vert", "apps/openmb/resources/shaders/skybox.frag" );
+ shaderLoaded = true;
+ }
+
+ glDepthFunc( GL_LEQUAL );
+ glDepthMask( GL_FALSE );
+
+ s.use();
+
+ glm::mat4 viewNoTrans = glm::mat4( glm::mat3( view ) );
+ s.setMat4( "view", viewNoTrans );
+ s.setMat4( "proj", proj );
+
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_CUBE_MAP, mTexID );
+ s.setInt( "skybox", 0 );
+
+ glBindVertexArray( mVAO );
+ glDrawArrays( GL_TRIANGLES, 0, 36 );
+ glBindVertexArray( 0 );
+
+ glDepthMask( GL_TRUE );
+ glDepthFunc( GL_LESS );
+}
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/Skybox.hpp b/apps/openmb/renderer/Skybox.hpp
new file mode 100644
index 0000000..656494f
--- /dev/null
+++ b/apps/openmb/renderer/Skybox.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <glm/glm.hpp>
+#include <string>
+#include <vector>
+
+#ifdef __APPLE__
+#include <OpenGL/gl3.h>
+#else
+#define GLFW_INCLUDE_NONE
+#include <GLFW/glfw3.h>
+#endif
+
+namespace renderer {
+class Skybox {
+ public:
+ Skybox();
+ ~Skybox();
+
+ bool loadFromDirectory( const std::string& dirPath );
+
+ void draw( const glm::mat4& view, const glm::mat4& proj );
+
+ private:
+ bool loadFaces( const std::vector<std::string>& faces );
+ void initMesh();
+
+ GLuint mTexID;
+ GLuint mVAO;
+ GLuint mVBO;
+ bool mInitialized;
+};
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/Texture.cpp b/apps/openmb/renderer/Texture.cpp
new file mode 100644
index 0000000..e551f86
--- /dev/null
+++ b/apps/openmb/renderer/Texture.cpp
@@ -0,0 +1,53 @@
+#define STB_IMAGE_IMPLEMENTATION
+#include <stb_image.h>
+
+#include "Texture.hpp"
+
+#include <iostream>
+
+namespace renderer {
+Texture::Texture () : mID( 0 ) {}
+
+Texture::~Texture () {
+ if( mID )
+ glDeleteTextures( 1, &mID );
+}
+
+bool Texture::loadFromFile ( const std::string& path, bool flip ) {
+ stbi_set_flip_vertically_on_load( flip );
+ int w, h, channels;
+ unsigned char* data = stbi_load( path.c_str(), &w, &h, &channels, 0 );
+ if( !data ) {
+ std::cerr << "Failed to load texture: " << path << std::endl;
+ return false;
+ }
+
+ GLenum format = GL_RGB;
+ if( channels == 1 )
+ format = GL_RED;
+ else if( channels == 3 )
+ format = GL_RGB;
+ else if( channels == 4 )
+ format = GL_RGBA;
+
+ glGenTextures( 1, &mID );
+ glBindTexture( GL_TEXTURE_2D, mID );
+ glTexImage2D( GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, data );
+ glGenerateMipmap( GL_TEXTURE_2D );
+
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+ stbi_image_free( data );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ return true;
+}
+
+void Texture::bind ( unsigned unit ) const {
+ glActiveTexture( GL_TEXTURE0 + unit );
+ glBindTexture( GL_TEXTURE_2D, mID );
+}
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/Texture.hpp b/apps/openmb/renderer/Texture.hpp
new file mode 100644
index 0000000..9acb5cd
--- /dev/null
+++ b/apps/openmb/renderer/Texture.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#ifdef __APPLE__
+#include <OpenGL/gl3.h>
+#else
+#define GLFW_INCLUDE_NONE
+#include <GLFW/glfw3.h>
+#ifdef __APPLE__
+#include <OpenGL/gl3.h>
+#endif
+#endif
+#include <string>
+
+namespace renderer {
+class Texture {
+ public:
+ Texture();
+ ~Texture();
+
+ bool loadFromFile( const std::string& path, bool flip = true );
+ void bind( unsigned unit = 0 ) const;
+ GLuint id () const { return mID; }
+
+ private:
+ GLuint mID;
+};
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/TextureManager.cpp b/apps/openmb/renderer/TextureManager.cpp
new file mode 100644
index 0000000..bfd7e15
--- /dev/null
+++ b/apps/openmb/renderer/TextureManager.cpp
@@ -0,0 +1,163 @@
+#include "TextureManager.hpp"
+
+#include <algorithm>
+#include <iostream>
+
+namespace renderer {
+TextureManager::TextureManager ()
+ : mBasePath(), mTextures(), mCurrentCategory(), mCurrentSubcategory(), mCurrentTextureName(),
+ mCurrentTexture( nullptr ), mCurrentTextureId( 0 ), mTextureIdToPath(), mNextTextureId( 1 ) {
+}
+
+void TextureManager::scanDirectory ( const std::string& basePath ) {
+ mBasePath = basePath;
+ mTextures.clear();
+
+ if( !std::filesystem::exists( basePath ) ) {
+ std::cerr << "TextureManager: Base path does not exist: " << basePath << std::endl;
+ return;
+ }
+
+ for( const auto& categoryEntry : std::filesystem::directory_iterator( basePath ) ) {
+ if( !categoryEntry.is_directory() )
+ continue;
+
+ std::string categoryName = categoryEntry.path().filename().string();
+
+ for( const auto& subcategoryEntry : std::filesystem::directory_iterator( categoryEntry.path() ) ) {
+ if( !subcategoryEntry.is_directory() )
+ continue;
+
+ std::string subcategoryName = subcategoryEntry.path().filename().string();
+
+ for( const auto& fileEntry : std::filesystem::directory_iterator( subcategoryEntry.path() ) ) {
+ if( !fileEntry.is_regular_file() )
+ continue;
+
+ std::string fileName = fileEntry.path().filename().string();
+ std::string extension = fileEntry.path().extension().string();
+
+ if( extension != ".png" && extension != ".jpg" && extension != ".jpeg" && extension != ".bmp" &&
+ extension != ".tga" )
+ continue;
+
+ TextureEntry entry;
+ entry.mFullPath = fileEntry.path().string();
+ entry.mLoaded = false;
+
+ mTextures[categoryName][subcategoryName][fileName] = entry;
+
+ int textureId = mNextTextureId++;
+ mTextureIdToPath[textureId] = std::make_tuple( categoryName, subcategoryName, fileName );
+ }
+ }
+ }
+
+ std::cout << "TextureManager: Scanned " << mTextures.size() << " categories" << std::endl;
+}
+
+std::vector<std::string> TextureManager::getCategories () const {
+ std::vector<std::string> categories;
+ for( const auto& [category, _] : mTextures ) {
+ categories.push_back( category );
+ }
+ std::sort( categories.begin(), categories.end() );
+ return categories;
+}
+
+std::vector<std::string> TextureManager::getSubcategories ( const std::string& category ) const {
+ std::vector<std::string> subcategories;
+ auto catIt = mTextures.find( category );
+ if( catIt != mTextures.end() ) {
+ for( const auto& [subcategory, _] : catIt->second ) {
+ subcategories.push_back( subcategory );
+ }
+ std::sort( subcategories.begin(), subcategories.end() );
+ }
+ return subcategories;
+}
+
+std::vector<std::string> TextureManager::getTextureNames ( const std::string& category,
+ const std::string& subcategory ) const {
+ std::vector<std::string> textureNames;
+ auto catIt = mTextures.find( category );
+ if( catIt != mTextures.end() ) {
+ auto subIt = catIt->second.find( subcategory );
+ if( subIt != catIt->second.end() ) {
+ for( const auto& [textureName, _] : subIt->second ) {
+ textureNames.push_back( textureName );
+ }
+ std::sort( textureNames.begin(), textureNames.end() );
+ }
+ }
+ return textureNames;
+}
+
+Texture* TextureManager::getTexture ( const std::string& category, const std::string& subcategory,
+ const std::string& textureName ) {
+ auto catIt = mTextures.find( category );
+ if( catIt == mTextures.end() )
+ return nullptr;
+
+ auto subIt = catIt->second.find( subcategory );
+ if( subIt == catIt->second.end() )
+ return nullptr;
+
+ auto texIt = subIt->second.find( textureName );
+ if( texIt == subIt->second.end() )
+ return nullptr;
+
+ TextureEntry& entry = texIt->second;
+
+ if( !entry.mLoaded ) {
+ if( entry.mTexture.loadFromFile( entry.mFullPath ) ) {
+ entry.mLoaded = true;
+ } else {
+ std::cerr << "TextureManager: Failed to load texture: " << entry.mFullPath << std::endl;
+ return nullptr;
+ }
+ }
+
+ return &entry.mTexture;
+}
+
+Texture* TextureManager::getCurrentTexture () {
+ if( mCurrentTexture )
+ return mCurrentTexture;
+
+ if( !mCurrentCategory.empty() && !mCurrentSubcategory.empty() && !mCurrentTextureName.empty() ) {
+ mCurrentTexture = getTexture( mCurrentCategory, mCurrentSubcategory, mCurrentTextureName );
+ }
+
+ return mCurrentTexture;
+}
+
+void TextureManager::setCurrentTexture ( const std::string& category, const std::string& subcategory,
+ const std::string& textureName ) {
+ mCurrentCategory = category;
+ mCurrentSubcategory = subcategory;
+ mCurrentTextureName = textureName;
+ mCurrentTexture = getTexture( category, subcategory, textureName );
+
+ for( const auto& [id, path] : mTextureIdToPath ) {
+ if( std::get<0>( path ) == category && std::get<1>( path ) == subcategory &&
+ std::get<2>( path ) == textureName ) {
+ mCurrentTextureId = id;
+ break;
+ }
+ }
+}
+
+int TextureManager::getCurrentTextureId () const {
+ return mCurrentTextureId;
+}
+
+Texture* TextureManager::getTextureById ( int textureId ) {
+ auto it = mTextureIdToPath.find( textureId );
+ if( it == mTextureIdToPath.end() )
+ return nullptr;
+
+ const auto& [category, subcategory, textureName] = it->second;
+ return getTexture( category, subcategory, textureName );
+}
+} // namespace renderer
diff --git a/apps/openmb/renderer/TextureManager.hpp b/apps/openmb/renderer/TextureManager.hpp
new file mode 100644
index 0000000..f3e183f
--- /dev/null
+++ b/apps/openmb/renderer/TextureManager.hpp
@@ -0,0 +1,64 @@
+#ifndef OPENMB_APPS_OPENMB_RENDERER_TEXTUREMANAGER_H
+#define OPENMB_APPS_OPENMB_RENDERER_TEXTUREMANAGER_H
+
+#include "Texture.hpp"
+
+#include <filesystem>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace renderer {
+
+class TextureManager {
+ public:
+ TextureManager();
+ ~TextureManager() = default;
+
+ void scanDirectory( const std::string& basePath );
+
+ std::vector<std::string> getCategories() const;
+
+ std::vector<std::string> getSubcategories( const std::string& category ) const;
+
+ std::vector<std::string> getTextureNames( const std::string& category, const std::string& subcategory ) const;
+
+ Texture* getTexture( const std::string& category, const std::string& subcategory,
+ const std::string& textureName );
+
+ Texture* getCurrentTexture();
+
+ void setCurrentTexture( const std::string& category, const std::string& subcategory,
+ const std::string& textureName );
+
+ const std::string& getCurrentCategory () const { return mCurrentCategory; }
+ const std::string& getCurrentSubcategory () const { return mCurrentSubcategory; }
+ const std::string& getCurrentTextureName () const { return mCurrentTextureName; }
+
+ int getCurrentTextureId() const;
+
+ Texture* getTextureById( int textureId );
+
+ private:
+ struct TextureEntry {
+ std::string mFullPath;
+ Texture mTexture;
+ bool mLoaded;
+ };
+
+ std::string mBasePath;
+
+ std::map<std::string, std::map<std::string, std::map<std::string, TextureEntry>>> mTextures;
+
+ std::string mCurrentCategory;
+ std::string mCurrentSubcategory;
+ std::string mCurrentTextureName;
+ Texture* mCurrentTexture;
+ int mCurrentTextureId;
+
+ std::map<int, std::tuple<std::string, std::string, std::string>> mTextureIdToPath;
+ int mNextTextureId;
+};
+} // namespace renderer
+
+#endif
diff --git a/apps/openmb/renderer/primitives.cpp b/apps/openmb/renderer/primitives.cpp
new file mode 100644
index 0000000..245f7e1
--- /dev/null
+++ b/apps/openmb/renderer/primitives.cpp
@@ -0,0 +1,595 @@
+#include "primitives.hpp"
+
+#include <vector>
+
+#include <glm/glm.hpp>
+
+namespace renderer
+{
+ namespace primitives
+ {
+ Mesh makeCube()
+ {
+
+ std::vector< float > verts = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f,
+
+ -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
+
+ -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
+ -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
+
+ 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
+
+ -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
+
+ -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f,
+ 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f };
+
+ Mesh m;
+ m.createFromPositions( verts, false );
+ return m;
+ }
+
+ Mesh makeTexturedCube()
+ {
+ std::vector< float > verts;
+
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f } );
+
+ Mesh m;
+ m.createFromPosTex( verts );
+ return m;
+ }
+
+ Mesh makeGrid( int halfSize, float spacing )
+ {
+ std::vector< float > verts;
+ for ( int i = -halfSize; i <= halfSize; ++i )
+ {
+ float x = i * spacing;
+ verts.push_back( x );
+ verts.push_back( 0.0f );
+ verts.push_back( -halfSize * spacing );
+ verts.push_back( x );
+ verts.push_back( 0.0f );
+ verts.push_back( halfSize * spacing );
+ }
+
+ for ( int j = -halfSize; j <= halfSize; ++j )
+ {
+ float z = j * spacing;
+ verts.push_back( -halfSize * spacing );
+ verts.push_back( 0.0f );
+ verts.push_back( z );
+ verts.push_back( halfSize * spacing );
+ verts.push_back( 0.0f );
+ verts.push_back( z );
+ }
+
+ Mesh m;
+ m.createFromPositions( verts, true );
+ return m;
+ }
+
+ Mesh makeTexturedGrid( int width, int depth, float tileSize )
+ {
+ std::vector< float > verts;
+
+ for ( int z = 0; z < depth; ++z )
+ {
+ for ( int x = 0; x < width; ++x )
+ {
+ float x0 = ( x - width * 0.5f ) * tileSize;
+ float z0 = ( z - depth * 0.5f ) * tileSize;
+ float x1 = x0 + tileSize;
+ float z1 = z0 + tileSize;
+
+ verts.push_back( x0 );
+ verts.push_back( 0.0f );
+ verts.push_back( z0 );
+ verts.push_back( 0.0f );
+ verts.push_back( 0.0f );
+
+ verts.push_back( x1 );
+ verts.push_back( 0.0f );
+ verts.push_back( z0 );
+ verts.push_back( 1.0f );
+ verts.push_back( 0.0f );
+
+ verts.push_back( x0 );
+ verts.push_back( 0.0f );
+ verts.push_back( z1 );
+ verts.push_back( 0.0f );
+ verts.push_back( 1.0f );
+
+ verts.push_back( x0 );
+ verts.push_back( 0.0f );
+ verts.push_back( z1 );
+ verts.push_back( 0.0f );
+ verts.push_back( 1.0f );
+
+ verts.push_back( x1 );
+ verts.push_back( 0.0f );
+ verts.push_back( z0 );
+ verts.push_back( 1.0f );
+ verts.push_back( 0.0f );
+
+ verts.push_back( x1 );
+ verts.push_back( 0.0f );
+ verts.push_back( z1 );
+ verts.push_back( 1.0f );
+ verts.push_back( 1.0f );
+ }
+ }
+
+ Mesh m;
+ m.createFromPosTex( verts );
+ return m;
+ }
+
+ Mesh makeTexturedCubeGrid( int width, int depth, float tileSize )
+ {
+ std::vector< float > verts;
+
+ auto pushFace = [&]( const std::array< float, 18 > &pos, const std::array< float, 12 > &uv, float cx,
+ float cy, float cz, float scale )
+ {
+ for ( int i = 0; i < 6; ++i )
+ {
+ int pi = i * 3;
+ int ui = i * 2;
+ verts.push_back( cx + pos[pi + 0] * scale );
+ verts.push_back( cy + pos[pi + 1] * scale );
+ verts.push_back( cz + pos[pi + 2] * scale );
+ verts.push_back( uv[ui + 0] );
+ verts.push_back( uv[ui + 1] );
+ }
+ };
+
+ const std::array< float, 18 > topPos = { -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f };
+ const std::array< float, 12 > topUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > bottomPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > bottomUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > frontPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > frontUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > backPos = { 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > backUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > leftPos = { -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > leftUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > rightPos = { 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > rightUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ for ( int z = 0; z < depth; ++z )
+ {
+ for ( int x = 0; x < width; ++x )
+ {
+ float cx = ( x - width * 0.5f ) * tileSize + tileSize * 0.5f;
+ float cz = ( z - depth * 0.5f ) * tileSize + tileSize * 0.5f;
+
+ float cy = -0.5f * tileSize;
+ float scale = tileSize;
+
+ pushFace( topPos, topUV, cx, cy, cz, scale );
+ pushFace( bottomPos, bottomUV, cx, cy, cz, scale );
+ pushFace( frontPos, frontUV, cx, cy, cz, scale );
+ pushFace( backPos, backUV, cx, cy, cz, scale );
+ pushFace( leftPos, leftUV, cx, cy, cz, scale );
+ pushFace( rightPos, rightUV, cx, cy, cz, scale );
+ }
+ }
+
+ Mesh m;
+ m.createFromPosTex( verts );
+ return m;
+ }
+
+ Mesh makeTexturedWall( int length, int height, float tileSize, bool alongX, float fixedCoord )
+ {
+ std::vector< float > verts;
+
+ auto pushFace = [&]( const std::array< float, 18 > &pos, const std::array< float, 12 > &uv, float cx,
+ float cy, float cz, float scale )
+ {
+ for ( int i = 0; i < 6; ++i )
+ {
+ int pi = i * 3;
+ int ui = i * 2;
+ verts.push_back( cx + pos[pi + 0] * scale );
+ verts.push_back( cy + pos[pi + 1] * scale );
+ verts.push_back( cz + pos[pi + 2] * scale );
+ verts.push_back( uv[ui + 0] );
+ verts.push_back( uv[ui + 1] );
+ }
+ };
+
+ const std::array< float, 18 > topPos = { -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f };
+ const std::array< float, 12 > topUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > bottomPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > bottomUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > frontPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > frontUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > backPos = { 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > backUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > leftPos = { -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > leftUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > rightPos = { 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > rightUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ if ( alongX )
+ {
+
+ for ( int lx = 0; lx < length; ++lx )
+ {
+ float cx = ( lx - length * 0.5f ) * tileSize + tileSize * 0.5f;
+ float cz = fixedCoord;
+ for ( int hy = 0; hy < height; ++hy )
+ {
+ float cy = 0.02f * tileSize + hy * tileSize;
+ float scale = tileSize;
+ pushFace( topPos, topUV, cx, cy, cz, scale );
+ pushFace( bottomPos, bottomUV, cx, cy, cz, scale );
+ pushFace( frontPos, frontUV, cx, cy, cz, scale );
+ pushFace( backPos, backUV, cx, cy, cz, scale );
+ pushFace( leftPos, leftUV, cx, cy, cz, scale );
+ pushFace( rightPos, rightUV, cx, cy, cz, scale );
+ }
+ }
+ }
+ else
+ {
+
+ for ( int lz = 0; lz < length; ++lz )
+ {
+ float cz = ( lz - length * 0.5f ) * tileSize + tileSize * 0.5f;
+ float cx = fixedCoord;
+ for ( int hy = 0; hy < height; ++hy )
+ {
+ float cy = 0.02f * tileSize + hy * tileSize;
+ float scale = tileSize;
+ pushFace( topPos, topUV, cx, cy, cz, scale );
+ pushFace( bottomPos, bottomUV, cx, cy, cz, scale );
+ pushFace( frontPos, frontUV, cx, cy, cz, scale );
+ pushFace( backPos, backUV, cx, cy, cz, scale );
+ pushFace( leftPos, leftUV, cx, cy, cz, scale );
+ pushFace( rightPos, rightUV, cx, cy, cz, scale );
+ }
+ }
+ }
+
+ Mesh m;
+ m.createFromPosTex( verts );
+ return m;
+ }
+
+ Mesh makeTexturedCubeWithNormals()
+ {
+ std::vector< float > verts;
+
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } );
+
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f } );
+
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f } );
+
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 0.0f, -1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 0.0f, -1.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f } );
+
+ Mesh m;
+ m.createFromPosTexNormal( verts );
+ return m;
+ }
+
+ Mesh makeTexturedGridWithNormals( int width, int depth, float tileSize )
+ {
+ std::vector< float > verts;
+
+ for ( int z = 0; z < depth; ++z )
+ {
+ for ( int x = 0; x < width; ++x )
+ {
+ float x0 = ( x - width * 0.5f ) * tileSize;
+ float z0 = ( z - depth * 0.5f ) * tileSize;
+ float x1 = x0 + tileSize;
+ float z1 = z0 + tileSize;
+
+ verts.insert( verts.end(), { x0, 0.0f, z0, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { x1, 0.0f, z0, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { x0, 0.0f, z1, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f } );
+
+ verts.insert( verts.end(), { x0, 0.0f, z1, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { x1, 0.0f, z0, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { x1, 0.0f, z1, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f } );
+ }
+ }
+
+ Mesh m;
+ m.createFromPosTexNormal( verts );
+ return m;
+ }
+
+ Mesh makeTexturedCubeGridWithNormals( int width, int depth, float tileSize )
+ {
+ std::vector< float > verts;
+
+ auto pushFaceWithNormal = [&]( const std::array< float, 18 > &pos, const std::array< float, 12 > &uv,
+ const glm::vec3 &normal, float cx, float cy, float cz, float scale )
+ {
+ for ( int i = 0; i < 6; ++i )
+ {
+ int pi = i * 3;
+ int ui = i * 2;
+ verts.push_back( cx + pos[pi + 0] * scale );
+ verts.push_back( cy + pos[pi + 1] * scale );
+ verts.push_back( cz + pos[pi + 2] * scale );
+ verts.push_back( uv[ui + 0] );
+ verts.push_back( uv[ui + 1] );
+ verts.push_back( normal.x );
+ verts.push_back( normal.y );
+ verts.push_back( normal.z );
+ }
+ };
+
+ const std::array< float, 18 > topPos = { -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f };
+ const std::array< float, 12 > topUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > bottomPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > bottomUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > frontPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > frontUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > backPos = { 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > backUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > leftPos = { -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > leftUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > rightPos = { 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > rightUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ for ( int z = 0; z < depth; ++z )
+ {
+ for ( int x = 0; x < width; ++x )
+ {
+ float cx = ( x - width * 0.5f ) * tileSize + tileSize * 0.5f;
+ float cz = ( z - depth * 0.5f ) * tileSize + tileSize * 0.5f;
+
+ float cy = -0.5f * tileSize;
+ float scale = tileSize;
+
+ pushFaceWithNormal( topPos, topUV, glm::vec3( 0.0f, 1.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( bottomPos, bottomUV, glm::vec3( 0.0f, -1.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( frontPos, frontUV, glm::vec3( 0.0f, 0.0f, 1.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( backPos, backUV, glm::vec3( 0.0f, 0.0f, -1.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( leftPos, leftUV, glm::vec3( -1.0f, 0.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( rightPos, rightUV, glm::vec3( 1.0f, 0.0f, 0.0f ), cx, cy, cz, scale );
+ }
+ }
+
+ Mesh m;
+ m.createFromPosTexNormal( verts );
+ return m;
+ }
+
+ Mesh makeTexturedWallWithNormals( int length, int height, float tileSize, bool alongX, float fixedCoord )
+ {
+ std::vector< float > verts;
+
+ auto pushFaceWithNormal = [&]( const std::array< float, 18 > &pos, const std::array< float, 12 > &uv,
+ const glm::vec3 &normal, float cx, float cy, float cz, float scale )
+ {
+ for ( int i = 0; i < 6; ++i )
+ {
+ int pi = i * 3;
+ int ui = i * 2;
+ verts.push_back( cx + pos[pi + 0] * scale );
+ verts.push_back( cy + pos[pi + 1] * scale );
+ verts.push_back( cz + pos[pi + 2] * scale );
+ verts.push_back( uv[ui + 0] );
+ verts.push_back( uv[ui + 1] );
+ verts.push_back( normal.x );
+ verts.push_back( normal.y );
+ verts.push_back( normal.z );
+ }
+ };
+
+ const std::array< float, 18 > topPos = { -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f };
+ const std::array< float, 12 > topUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > bottomPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > bottomUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > frontPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > frontUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > backPos = { 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > backUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > leftPos = { -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > leftUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > rightPos = { 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > rightUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ if ( alongX )
+ {
+ for ( int lx = 0; lx < length; ++lx )
+ {
+ float cx = ( lx - length * 0.5f ) * tileSize + tileSize * 0.5f;
+ float cz = fixedCoord;
+ for ( int hy = 0; hy < height; ++hy )
+ {
+ float cy = hy * tileSize + tileSize * 0.5f;
+ float scale = tileSize;
+ pushFaceWithNormal( topPos, topUV, glm::vec3( 0.0f, 1.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( bottomPos, bottomUV, glm::vec3( 0.0f, -1.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( frontPos, frontUV, glm::vec3( 0.0f, 0.0f, 1.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( backPos, backUV, glm::vec3( 0.0f, 0.0f, -1.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( leftPos, leftUV, glm::vec3( -1.0f, 0.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( rightPos, rightUV, glm::vec3( 1.0f, 0.0f, 0.0f ), cx, cy, cz, scale );
+ }
+ }
+ }
+ else
+ {
+ for ( int lz = 0; lz < length; ++lz )
+ {
+ float cz = ( lz - length * 0.5f ) * tileSize + tileSize * 0.5f;
+ float cx = fixedCoord;
+ for ( int hy = 0; hy < height; ++hy )
+ {
+ float cy = hy * tileSize + tileSize * 0.5f;
+ float scale = tileSize;
+ pushFaceWithNormal( topPos, topUV, glm::vec3( 0.0f, 1.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( bottomPos, bottomUV, glm::vec3( 0.0f, -1.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( frontPos, frontUV, glm::vec3( 0.0f, 0.0f, 1.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( backPos, backUV, glm::vec3( 0.0f, 0.0f, -1.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( leftPos, leftUV, glm::vec3( -1.0f, 0.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( rightPos, rightUV, glm::vec3( 1.0f, 0.0f, 0.0f ), cx, cy, cz, scale );
+ }
+ }
+ }
+
+ Mesh m;
+ m.createFromPosTexNormal( verts );
+ return m;
+ }
+
+ } // namespace primitives
+
+} // namespace renderer
diff --git a/apps/openmb/renderer/primitives.hpp b/apps/openmb/renderer/primitives.hpp
new file mode 100644
index 0000000..bd07c02
--- /dev/null
+++ b/apps/openmb/renderer/primitives.hpp
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "Mesh.hpp"
+
+namespace renderer
+{
+ namespace primitives
+ {
+ Mesh makeCube();
+ Mesh makeTexturedCube();
+ Mesh makeTexturedCubeWithNormals();
+ Mesh makeGrid( int halfSize, float spacing );
+ Mesh makeTexturedGrid( int width, int depth, float tileSize );
+ Mesh makeTexturedGridWithNormals( int width, int depth, float tileSize );
+ Mesh makeTexturedCubeGrid( int width, int depth, float tileSize );
+ Mesh makeTexturedCubeGridWithNormals( int width, int depth, float tileSize );
+ Mesh makeTexturedWall( int length, int height, float tileSize, bool alongX = true, float fixedCoord = 0.0f );
+ Mesh makeTexturedWallWithNormals( int length, int height, float tileSize, bool alongX = true,
+ float fixedCoord = 0.0f );
+ } // namespace primitives
+
+} // namespace renderer
diff --git a/apps/openmb/resources/levels/default.json b/apps/openmb/resources/levels/default.json
new file mode 100644
index 0000000..47322c3
--- /dev/null
+++ b/apps/openmb/resources/levels/default.json
@@ -0,0 +1,24701 @@
+{
+ "models": [
+ {
+ "modelIndex": 3,
+ "scale": 0.017000000923871994,
+ "x": -8.920812606811523,
+ "y": 1.0,
+ "yaw": 0.0,
+ "z": -5.858656883239746
+ },
+ {
+ "modelIndex": 3,
+ "scale": 0.017000000923871994,
+ "x": -6.891270160675049,
+ "y": 1.0,
+ "yaw": 0.0,
+ "z": -4.801188945770264
+ },
+ {
+ "modelIndex": 4,
+ "scale": 0.017000000923871994,
+ "x": -10.715228080749512,
+ "y": 1.0,
+ "yaw": 0.0,
+ "z": -7.831607818603516
+ },
+ {
+ "modelIndex": 4,
+ "scale": 0.017000000923871994,
+ "x": -11.074238777160645,
+ "y": 1.0,
+ "yaw": 0.0,
+ "z": -3.105196475982666
+ },
+ {
+ "modelIndex": 4,
+ "scale": 0.017000000923871994,
+ "x": -2.7807230949401855,
+ "y": 1.0,
+ "yaw": 0.0,
+ "z": -3.1151580810546875
+ },
+ {
+ "modelIndex": 1,
+ "scale": 0.017000000923871994,
+ "x": -4.819826126098633,
+ "y": 1.0,
+ "yaw": 0.0,
+ "z": 0.524317741394043
+ },
+ {
+ "modelIndex": 1,
+ "scale": 0.017000000923871994,
+ "x": -6.733904838562012,
+ "y": 1.0000004768371582,
+ "yaw": 0.0,
+ "z": 0.9215221405029297
+ },
+ {
+ "modelIndex": 1,
+ "scale": 0.017000000923871994,
+ "x": -8.02570629119873,
+ "y": 1.0,
+ "yaw": 0.0,
+ "z": 1.3742852210998535
+ },
+ {
+ "modelIndex": 0,
+ "scale": 0.017000000923871994,
+ "x": -9.27149772644043,
+ "y": 1.0,
+ "yaw": 0.0,
+ "z": 0.7743282318115234
+ },
+ {
+ "modelIndex": 0,
+ "scale": 0.017000000923871994,
+ "x": -10.817995071411133,
+ "y": 0.9999995231628418,
+ "yaw": 0.0,
+ "z": -0.1147160530090332
+ },
+ {
+ "modelIndex": 0,
+ "scale": 0.017000000923871994,
+ "x": 8.604547500610352,
+ "y": 1.0,
+ "yaw": 0.0,
+ "z": 1.912936806678772
+ },
+ {
+ "modelIndex": 3,
+ "scale": 0.017000000923871994,
+ "x": 2.3309972286224365,
+ "y": 1.0,
+ "yaw": 0.0,
+ "z": 12.099968910217285
+ },
+ {
+ "modelIndex": 3,
+ "scale": 0.017000000923871994,
+ "x": 6.445761680603027,
+ "y": 0.9999995231628418,
+ "yaw": 0.0,
+ "z": 12.606679916381836
+ },
+ {
+ "modelIndex": 0,
+ "scale": 0.017000000923871994,
+ "x": 5.363408088684082,
+ "y": 1.0,
+ "yaw": 0.0,
+ "z": 2.2424755096435547
+ },
+ {
+ "modelIndex": 0,
+ "scale": 0.017000000923871994,
+ "x": 4.560368061065674,
+ "y": 1.0,
+ "yaw": 0.0,
+ "z": 8.449825286865234
+ },
+ {
+ "modelIndex": 0,
+ "scale": 0.017000000923871994,
+ "x": 2.835254192352295,
+ "y": 1.0,
+ "yaw": 0.0,
+ "z": 1.8184318542480469
+ }
+ ],
+ "paintedCircles": [],
+ "sun": {
+ "color": [
+ 1.0,
+ 0.9800000190734863,
+ 0.8999999761581421
+ ],
+ "direction": [
+ 0.03500000014901161,
+ -0.30804863572120667,
+ 0.9507266283035278
+ ],
+ "intensity": 0.8019999861717224
+ },
+ "version": 1,
+ "voxels": [
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 0,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 1,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 2,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 3,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 4,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 5,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 18,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 19,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 20,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 21,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 22,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 0
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 1
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 2
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 3
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 4
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 5
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 6
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 7
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 8
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 9
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 23,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 6,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 7,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 8,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 9,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 10,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 11,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 12,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 13,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 14,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 15,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 16,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 10
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 11
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 12
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 13
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 14
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 15
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 16
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 17
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 18
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 19
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 20
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 21
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 22
+ },
+ {
+ "textureId": 11,
+ "x": 17,
+ "y": 0,
+ "z": 23
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 487,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 488,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 489,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 490,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 491,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 492,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 493,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 494,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 495,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 496,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 497,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 498,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 499,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 500,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 501,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 502,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 503,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 504,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 505,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 506,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 507,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 508,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 509,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 501,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 502,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 503,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 504,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 505,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 506,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 507,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 508,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 1,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 501,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 502,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 503,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 504,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 505,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 506,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 507,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 508,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 1,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 2,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 501,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 501,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 502,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 502,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 503,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 503,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 504,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 504,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 505,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 505,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 506,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 506,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 507,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 507,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 508,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 508,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 2,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 1,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 1,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 1,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 1,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 1,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 2,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 2,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 2,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 2,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 2,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 1,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 2,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 1,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 1,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 2,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 2,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 3,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 3,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 1,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 1,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 2,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 2,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 3,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 3,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 501,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 502,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 503,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 504,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 505,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 506,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 507,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 508,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 3,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 488,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 489,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 490,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 491,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 492,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 493,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 494,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 495,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 496,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 497,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 498,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 499,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 500,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 501,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 502,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 503,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 504,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 505,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 506,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 507,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 508,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 487,
+ "y": 3,
+ "z": 508
+ },
+ {
+ "textureId": 2,
+ "x": 500,
+ "y": 1,
+ "z": 491
+ },
+ {
+ "textureId": 2,
+ "x": 499,
+ "y": 1,
+ "z": 492
+ },
+ {
+ "textureId": 6,
+ "x": 497,
+ "y": 1,
+ "z": 492
+ },
+ {
+ "textureId": 6,
+ "x": 499,
+ "y": 1,
+ "z": 493
+ },
+ {
+ "textureId": 6,
+ "x": 499,
+ "y": 2,
+ "z": 492
+ },
+ {
+ "textureId": 21,
+ "x": 497,
+ "y": 2,
+ "z": 492
+ },
+ {
+ "textureId": 21,
+ "x": 499,
+ "y": 2,
+ "z": 493
+ },
+ {
+ "textureId": 21,
+ "x": 499,
+ "y": 3,
+ "z": 492
+ },
+ {
+ "textureId": 21,
+ "x": 498,
+ "y": 1,
+ "z": 493
+ },
+ {
+ "textureId": 8,
+ "x": 497,
+ "y": 1,
+ "z": 491
+ },
+ {
+ "textureId": 8,
+ "x": 496,
+ "y": 1,
+ "z": 491
+ },
+ {
+ "textureId": 8,
+ "x": 497,
+ "y": 1,
+ "z": 493
+ },
+ {
+ "textureId": 8,
+ "x": 499,
+ "y": 1,
+ "z": 494
+ },
+ {
+ "textureId": 8,
+ "x": 503,
+ "y": 1,
+ "z": 493
+ },
+ {
+ "textureId": 8,
+ "x": 502,
+ "y": 1,
+ "z": 493
+ },
+ {
+ "textureId": 8,
+ "x": 501,
+ "y": 1,
+ "z": 493
+ },
+ {
+ "textureId": 8,
+ "x": 501,
+ "y": 2,
+ "z": 493
+ },
+ {
+ "textureId": 8,
+ "x": 502,
+ "y": 2,
+ "z": 493
+ },
+ {
+ "textureId": 8,
+ "x": 498,
+ "y": 2,
+ "z": 493
+ },
+ {
+ "textureId": 8,
+ "x": 498,
+ "y": 3,
+ "z": 493
+ },
+ {
+ "textureId": 8,
+ "x": 499,
+ "y": 3,
+ "z": 493
+ },
+ {
+ "textureId": 8,
+ "x": 500,
+ "y": 2,
+ "z": 493
+ },
+ {
+ "textureId": 8,
+ "x": 500,
+ "y": 3,
+ "z": 493
+ },
+ {
+ "textureId": 8,
+ "x": 501,
+ "y": 3,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 510,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 511,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 512,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 513,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 514,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 515,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 516,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 517,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 518,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 519,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 520,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 483
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 484
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 485
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 486
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 487
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 514
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 515
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 516
+ },
+ {
+ "textureId": 24,
+ "x": 521,
+ "y": 0,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 1,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 2,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 3,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 1,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 2,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 3,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 521,
+ "y": 4,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 517
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 483
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 509,
+ "y": 4,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 512,
+ "y": 4,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 513,
+ "y": 4,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 514,
+ "y": 4,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 515,
+ "y": 4,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 516,
+ "y": 4,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 517,
+ "y": 4,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 518,
+ "y": 4,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 519,
+ "y": 4,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 515
+ },
+ {
+ "textureId": 37,
+ "x": 520,
+ "y": 4,
+ "z": 516
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 484
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 485
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 486
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 487
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 511,
+ "y": 4,
+ "z": 514
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 510,
+ "y": 4,
+ "z": 514
+ },
+ {
+ "textureId": 11,
+ "x": 512,
+ "y": 5,
+ "z": 516
+ },
+ {
+ "textureId": 11,
+ "x": 512,
+ "y": 5,
+ "z": 515
+ },
+ {
+ "textureId": 11,
+ "x": 511,
+ "y": 5,
+ "z": 514
+ },
+ {
+ "textureId": 11,
+ "x": 510,
+ "y": 5,
+ "z": 514
+ },
+ {
+ "textureId": 11,
+ "x": 509,
+ "y": 5,
+ "z": 515
+ },
+ {
+ "textureId": 11,
+ "x": 509,
+ "y": 5,
+ "z": 517
+ },
+ {
+ "textureId": 11,
+ "x": 509,
+ "y": 5,
+ "z": 516
+ },
+ {
+ "textureId": 11,
+ "x": 509,
+ "y": 5,
+ "z": 514
+ },
+ {
+ "textureId": 11,
+ "x": 512,
+ "y": 5,
+ "z": 514
+ },
+ {
+ "textureId": 11,
+ "x": 510,
+ "y": 5,
+ "z": 517
+ },
+ {
+ "textureId": 11,
+ "x": 511,
+ "y": 5,
+ "z": 517
+ },
+ {
+ "textureId": 11,
+ "x": 512,
+ "y": 5,
+ "z": 517
+ },
+ {
+ "textureId": 11,
+ "x": 509,
+ "y": 6,
+ "z": 517
+ },
+ {
+ "textureId": 11,
+ "x": 510,
+ "y": 6,
+ "z": 517
+ },
+ {
+ "textureId": 11,
+ "x": 511,
+ "y": 6,
+ "z": 517
+ },
+ {
+ "textureId": 11,
+ "x": 512,
+ "y": 6,
+ "z": 517
+ },
+ {
+ "textureId": 11,
+ "x": 509,
+ "y": 6,
+ "z": 514
+ },
+ {
+ "textureId": 11,
+ "x": 509,
+ "y": 6,
+ "z": 515
+ },
+ {
+ "textureId": 11,
+ "x": 509,
+ "y": 6,
+ "z": 516
+ },
+ {
+ "textureId": 11,
+ "x": 511,
+ "y": 6,
+ "z": 514
+ },
+ {
+ "textureId": 11,
+ "x": 512,
+ "y": 6,
+ "z": 514
+ },
+ {
+ "textureId": 11,
+ "x": 512,
+ "y": 6,
+ "z": 515
+ },
+ {
+ "textureId": 11,
+ "x": 512,
+ "y": 6,
+ "z": 516
+ },
+ {
+ "textureId": 11,
+ "x": 510,
+ "y": 6,
+ "z": 514
+ },
+ {
+ "textureId": 29,
+ "x": 510,
+ "y": 1,
+ "z": 499
+ },
+ {
+ "textureId": 29,
+ "x": 511,
+ "y": 1,
+ "z": 499
+ },
+ {
+ "textureId": 29,
+ "x": 512,
+ "y": 1,
+ "z": 499
+ },
+ {
+ "textureId": 29,
+ "x": 513,
+ "y": 1,
+ "z": 499
+ },
+ {
+ "textureId": 29,
+ "x": 514,
+ "y": 1,
+ "z": 499
+ },
+ {
+ "textureId": 29,
+ "x": 510,
+ "y": 2,
+ "z": 499
+ },
+ {
+ "textureId": 29,
+ "x": 510,
+ "y": 3,
+ "z": 499
+ },
+ {
+ "textureId": 29,
+ "x": 511,
+ "y": 2,
+ "z": 499
+ },
+ {
+ "textureId": 29,
+ "x": 511,
+ "y": 3,
+ "z": 499
+ },
+ {
+ "textureId": 29,
+ "x": 512,
+ "y": 2,
+ "z": 499
+ },
+ {
+ "textureId": 29,
+ "x": 512,
+ "y": 3,
+ "z": 499
+ },
+ {
+ "textureId": 29,
+ "x": 520,
+ "y": 1,
+ "z": 495
+ },
+ {
+ "textureId": 29,
+ "x": 520,
+ "y": 2,
+ "z": 495
+ },
+ {
+ "textureId": 29,
+ "x": 520,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 29,
+ "x": 516,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 29,
+ "x": 517,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 29,
+ "x": 518,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 29,
+ "x": 519,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 29,
+ "x": 516,
+ "y": 2,
+ "z": 495
+ },
+ {
+ "textureId": 29,
+ "x": 516,
+ "y": 1,
+ "z": 495
+ },
+ {
+ "textureId": 38,
+ "x": 510,
+ "y": 1,
+ "z": 495
+ },
+ {
+ "textureId": 38,
+ "x": 510,
+ "y": 1,
+ "z": 496
+ },
+ {
+ "textureId": 38,
+ "x": 511,
+ "y": 1,
+ "z": 495
+ },
+ {
+ "textureId": 38,
+ "x": 511,
+ "y": 1,
+ "z": 496
+ },
+ {
+ "textureId": 38,
+ "x": 512,
+ "y": 1,
+ "z": 495
+ },
+ {
+ "textureId": 38,
+ "x": 512,
+ "y": 1,
+ "z": 496
+ },
+ {
+ "textureId": 38,
+ "x": 513,
+ "y": 1,
+ "z": 495
+ },
+ {
+ "textureId": 38,
+ "x": 513,
+ "y": 1,
+ "z": 496
+ },
+ {
+ "textureId": 38,
+ "x": 510,
+ "y": 2,
+ "z": 495
+ },
+ {
+ "textureId": 38,
+ "x": 511,
+ "y": 2,
+ "z": 495
+ },
+ {
+ "textureId": 38,
+ "x": 512,
+ "y": 2,
+ "z": 495
+ },
+ {
+ "textureId": 38,
+ "x": 513,
+ "y": 2,
+ "z": 495
+ },
+ {
+ "textureId": 38,
+ "x": 510,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 38,
+ "x": 511,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 38,
+ "x": 512,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 38,
+ "x": 513,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 33,
+ "x": 515,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 32,
+ "x": 515,
+ "y": 1,
+ "z": 489
+ },
+ {
+ "textureId": 27,
+ "x": 515,
+ "y": 1,
+ "z": 490
+ },
+ {
+ "textureId": 30,
+ "x": 515,
+ "y": 1,
+ "z": 491
+ },
+ {
+ "textureId": 38,
+ "x": 515,
+ "y": 1,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 453,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 454,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 455,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 456,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 457,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 458,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 459,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 460,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 461,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 462,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 463,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 464,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 465,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 466,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 467,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 468,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 469,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 470,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 471,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 472,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 488
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 489
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 490
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 491
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 492
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 493
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 494
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 495
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 496
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 497
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 498
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 499
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 500
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 501
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 502
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 18,
+ "x": 473,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 459,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 459,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 459,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 460,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 460,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 460,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 461,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 461,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 461,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 462,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 462,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 462,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 463,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 463,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 463,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 464,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 464,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 464,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 465,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 465,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 465,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 466,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 466,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 466,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 467,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 467,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 467,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 468,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 468,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 468,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 469,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 469,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 469,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 470,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 470,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 470,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 471,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 471,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 471,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 472,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 472,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 472,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 459,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 459,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 459,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 460,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 460,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 460,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 461,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 461,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 461,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 462,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 462,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 462,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 463,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 463,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 463,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 464,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 464,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 464,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 465,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 465,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 465,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 466,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 466,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 466,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 467,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 467,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 467,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 468,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 468,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 468,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 469,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 469,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 469,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 470,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 470,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 470,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 471,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 471,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 471,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 472,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 472,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 472,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 488
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 2,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 489
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 490
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 491
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 492
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 493
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 494
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 495
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 496
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 497
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 498
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 499
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 500
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 501
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 473,
+ "y": 3,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 467,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 468,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 469,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 470,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 471,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 472,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 467,
+ "y": 2,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 468,
+ "y": 2,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 469,
+ "y": 2,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 470,
+ "y": 2,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 471,
+ "y": 2,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 472,
+ "y": 2,
+ "z": 503
+ },
+ {
+ "textureId": 37,
+ "x": 467,
+ "y": 1,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 465,
+ "y": 1,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 466,
+ "y": 1,
+ "z": 502
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 4,
+ "z": 504
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 4,
+ "z": 505
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 4,
+ "z": 506
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 4,
+ "z": 507
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 453,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 454,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 455,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 456,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 457,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 4,
+ "z": 508
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 4,
+ "z": 509
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 4,
+ "z": 510
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 4,
+ "z": 511
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 4,
+ "z": 512
+ },
+ {
+ "textureId": 37,
+ "x": 458,
+ "y": 4,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 474,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 474,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 474,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 474,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 474,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 474,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 474,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 474,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 474,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 474,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 474,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 475,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 475,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 475,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 475,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 475,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 475,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 475,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 475,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 475,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 475,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 475,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 476,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 476,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 476,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 476,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 476,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 476,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 476,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 476,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 476,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 476,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 476,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 477,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 477,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 477,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 477,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 477,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 477,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 477,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 477,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 477,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 477,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 477,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 478,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 478,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 478,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 478,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 478,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 478,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 478,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 478,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 478,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 478,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 478,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 479,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 479,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 479,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 479,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 479,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 479,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 479,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 479,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 479,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 479,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 479,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 480,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 480,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 480,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 480,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 480,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 480,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 480,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 480,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 480,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 480,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 480,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 481,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 481,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 481,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 481,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 481,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 481,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 481,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 481,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 481,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 481,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 481,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 482,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 482,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 482,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 482,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 482,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 482,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 482,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 482,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 482,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 482,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 482,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 483,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 483,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 483,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 483,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 483,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 483,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 483,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 483,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 483,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 483,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 483,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 484,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 484,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 484,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 484,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 484,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 484,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 484,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 484,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 484,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 484,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 484,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 485,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 485,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 485,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 485,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 485,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 485,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 485,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 485,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 485,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 485,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 485,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 24,
+ "x": 486,
+ "y": 0,
+ "z": 503
+ },
+ {
+ "textureId": 24,
+ "x": 486,
+ "y": 0,
+ "z": 504
+ },
+ {
+ "textureId": 24,
+ "x": 486,
+ "y": 0,
+ "z": 505
+ },
+ {
+ "textureId": 24,
+ "x": 486,
+ "y": 0,
+ "z": 506
+ },
+ {
+ "textureId": 24,
+ "x": 486,
+ "y": 0,
+ "z": 507
+ },
+ {
+ "textureId": 24,
+ "x": 486,
+ "y": 0,
+ "z": 508
+ },
+ {
+ "textureId": 24,
+ "x": 486,
+ "y": 0,
+ "z": 509
+ },
+ {
+ "textureId": 24,
+ "x": 486,
+ "y": 0,
+ "z": 510
+ },
+ {
+ "textureId": 24,
+ "x": 486,
+ "y": 0,
+ "z": 511
+ },
+ {
+ "textureId": 24,
+ "x": 486,
+ "y": 0,
+ "z": 512
+ },
+ {
+ "textureId": 24,
+ "x": 486,
+ "y": 0,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 474,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 475,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 476,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 477,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 478,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 479,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 480,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 481,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 482,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 483,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 484,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 485,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 1,
+ "z": 513
+ },
+ {
+ "textureId": 28,
+ "x": 474,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 475,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 476,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 477,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 478,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 479,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 480,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 481,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 482,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 483,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 484,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 485,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 1,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 1,
+ "z": 504
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 1,
+ "z": 505
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 1,
+ "z": 507
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 1,
+ "z": 508
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 1,
+ "z": 510
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 1,
+ "z": 511
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 1,
+ "z": 512
+ },
+ {
+ "textureId": 28,
+ "x": 485,
+ "y": 1,
+ "z": 504
+ },
+ {
+ "textureId": 28,
+ "x": 485,
+ "y": 1,
+ "z": 505
+ },
+ {
+ "textureId": 28,
+ "x": 485,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 28,
+ "x": 485,
+ "y": 1,
+ "z": 507
+ },
+ {
+ "textureId": 28,
+ "x": 485,
+ "y": 1,
+ "z": 508
+ },
+ {
+ "textureId": 28,
+ "x": 485,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 28,
+ "x": 485,
+ "y": 1,
+ "z": 510
+ },
+ {
+ "textureId": 28,
+ "x": 485,
+ "y": 1,
+ "z": 511
+ },
+ {
+ "textureId": 28,
+ "x": 485,
+ "y": 1,
+ "z": 512
+ },
+ {
+ "textureId": 28,
+ "x": 484,
+ "y": 1,
+ "z": 504
+ },
+ {
+ "textureId": 28,
+ "x": 484,
+ "y": 1,
+ "z": 505
+ },
+ {
+ "textureId": 28,
+ "x": 484,
+ "y": 1,
+ "z": 506
+ },
+ {
+ "textureId": 28,
+ "x": 484,
+ "y": 1,
+ "z": 507
+ },
+ {
+ "textureId": 28,
+ "x": 484,
+ "y": 1,
+ "z": 508
+ },
+ {
+ "textureId": 28,
+ "x": 484,
+ "y": 1,
+ "z": 509
+ },
+ {
+ "textureId": 28,
+ "x": 484,
+ "y": 1,
+ "z": 510
+ },
+ {
+ "textureId": 28,
+ "x": 484,
+ "y": 1,
+ "z": 511
+ },
+ {
+ "textureId": 28,
+ "x": 484,
+ "y": 1,
+ "z": 512
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 2,
+ "z": 504
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 2,
+ "z": 505
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 2,
+ "z": 506
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 2,
+ "z": 507
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 2,
+ "z": 508
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 2,
+ "z": 509
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 2,
+ "z": 510
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 2,
+ "z": 511
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 2,
+ "z": 512
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 2,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 486,
+ "y": 3,
+ "z": 503
+ },
+ {
+ "textureId": 28,
+ "x": 485,
+ "y": 2,
+ "z": 503
+ }
+ ]
+} \ No newline at end of file
diff --git a/apps/openmb/resources/models/rocks/Rocks_lp_SM_Rock_01_BaseMap.png b/apps/openmb/resources/models/rocks/Rocks_lp_SM_Rock_01_BaseMap.png
new file mode 100644
index 0000000..df63233
--- /dev/null
+++ b/apps/openmb/resources/models/rocks/Rocks_lp_SM_Rock_01_BaseMap.png
Binary files differ
diff --git a/apps/openmb/resources/models/rocks/Rocks_lp_SM_Rock_01_Normal.png b/apps/openmb/resources/models/rocks/Rocks_lp_SM_Rock_01_Normal.png
new file mode 100644
index 0000000..0d053e9
--- /dev/null
+++ b/apps/openmb/resources/models/rocks/Rocks_lp_SM_Rock_01_Normal.png
Binary files differ
diff --git a/apps/openmb/resources/models/rocks/SM_Rocks_01.obj b/apps/openmb/resources/models/rocks/SM_Rocks_01.obj
new file mode 100644
index 0000000..7ce69a3
--- /dev/null
+++ b/apps/openmb/resources/models/rocks/SM_Rocks_01.obj
@@ -0,0 +1,143 @@
+mtllib SM_Rocks_01.mtl
+o SM_Rock_01
+usemtl SM_Rock_01
+v 25.26092529296875 -2.9519944190979004 -22.238948822021484 1 1 1
+v 17.55608558654785 28.462902069091797 -14.90195369720459 1 1 1
+v 25.384950637817383 -3.000762462615967 26.61064910888672 1 1 1
+v 25.384950637817383 -3.000762462615967 26.61064910888672 1 1 1
+v 18.888885498046875 22.837478637695312 17.41868782043457 1 1 1
+v -23.75592041015625 19.70545196533203 15.467035293579102 1 1 1
+v 25.384950637817383 -3.000762462615967 26.61064910888672 1 1 1
+v -23.75592041015625 19.70545196533203 15.467035293579102 1 1 1
+v -29.990339279174805 -3.1008284091949463 24.58433723449707 1 1 1
+v -29.990339279174805 -3.1008284091949463 24.58433723449707 1 1 1
+v -23.75592041015625 19.70545196533203 15.467035293579102 1 1 1
+v -16.769838333129883 34.94828796386719 -13.60036563873291 1 1 1
+v -29.990339279174805 -3.1008284091949463 24.58433723449707 1 1 1
+v -16.769838333129883 34.94828796386719 -13.60036563873291 1 1 1
+v -23.316240310668945 -2.7831718921661377 -22.27688217163086 1 1 1
+v -23.316240310668945 -2.7831718921661377 -22.27688217163086 1 1 1
+v 17.55608558654785 28.462902069091797 -14.90195369720459 1 1 1
+v 25.26092529296875 -2.9519944190979004 -22.238948822021484 1 1 1
+v 16.510061264038086 32.85257339477539 -5.287999629974365 1 1 1
+v 17.55608558654785 28.462902069091797 -14.90195369720459 1 1 1
+v 7.284137725830078 35.79560470581055 -13.225668907165527 1 1 1
+v 18.888885498046875 22.837478637695312 17.41868782043457 1 1 1
+v 16.510061264038086 32.85257339477539 -5.287999629974365 1 1 1
+v -23.75592041015625 19.70545196533203 15.467035293579102 1 1 1
+v 25.384950637817383 -3.000762462615967 26.61064910888672 1 1 1
+v 17.55608558654785 28.462902069091797 -14.90195369720459 1 1 1
+v 16.510061264038086 32.85257339477539 -5.287999629974365 1 1 1
+v 25.384950637817383 -3.000762462615967 26.61064910888672 1 1 1
+v 16.510061264038086 32.85257339477539 -5.287999629974365 1 1 1
+v 18.888885498046875 22.837478637695312 17.41868782043457 1 1 1
+v -23.75592041015625 19.70545196533203 15.467035293579102 1 1 1
+v 16.510061264038086 32.85257339477539 -5.287999629974365 1 1 1
+v 7.284137725830078 35.79560470581055 -13.225668907165527 1 1 1
+v -23.75592041015625 19.70545196533203 15.467035293579102 1 1 1
+v 7.284137725830078 35.79560470581055 -13.225668907165527 1 1 1
+v -16.769838333129883 34.94828796386719 -13.60036563873291 1 1 1
+v 17.55608558654785 28.462902069091797 -14.90195369720459 1 1 1
+v -23.316240310668945 -2.7831718921661377 -22.27688217163086 1 1 1
+v -16.769838333129883 34.94828796386719 -13.60036563873291 1 1 1
+v 17.55608558654785 28.462902069091797 -14.90195369720459 1 1 1
+v -16.769838333129883 34.94828796386719 -13.60036563873291 1 1 1
+v 7.284137725830078 35.79560470581055 -13.225668907165527 1 1 1
+vt 0.9151540398597717 0.6638060212135315
+vt 0.8233218789100647 0.6420246958732605
+vt 0.9151540994644165 0.525446355342865
+vt 0.6432810425758362 0.7442019581794739
+vt 0.7207525372505188 0.7599366903305054
+vt 0.7089783549308777 0.8796431422233582
+vt 0.6432810425758362 0.7442019581794739
+vt 0.7089783549308777 0.8796431422233582
+vt 0.643281102180481 0.9011420607566833
+vt 0.9023555517196655 0.2807621955871582
+vt 0.8462424278259277 0.2405529022216797
+vt 0.8163553476333618 0.14913451671600342
+vt 0.9023555517196655 0.2807621955871582
+vt 0.8163553476333618 0.14913451671600342
+vt 0.9274819493293762 0.14913451671600342
+vt 0.8163553476333618 0.003841996192932129
+vt 0.9079443216323853 0.1185804009437561
+vt 0.8163553476333618 0.14145052433013916
+vt 0.8106706142425537 0.61598140001297
+vt 0.8233218789100647 0.6420246958732605
+vt 0.7966386675834656 0.6379318237304688
+vt 0.7207525372505188 0.7599366903305054
+vt 0.7705004215240479 0.7734178900718689
+vt 0.7089783549308777 0.8796431422233582
+vt 0.9151540994644165 0.525446355342865
+vt 0.8233218789100647 0.6420246958732605
+vt 0.8106706142425537 0.61598140001297
+vt 0.9151540994644165 0.525446355342865
+vt 0.8106706142425537 0.61598140001297
+vt 0.8405073881149292 0.551552414894104
+vt 0.7089783549308777 0.8796431422233582
+vt 0.7705004215240479 0.7734178900718689
+vt 0.7857733368873596 0.800637423992157
+vt 0.7089783549308777 0.8796431422233582
+vt 0.7857733368873596 0.800637423992157
+vt 0.7835135459899902 0.8688094019889832
+vt 0.9079443216323853 0.1185804009437561
+vt 0.8163553476333618 0.003841996192932129
+vt 0.9260876178741455 0.02202659845352173
+vt 0.9079443216323853 0.1185804009437561
+vt 0.9260876178741455 0.02202659845352173
+vt 0.9291304349899292 0.09016966819763184
+vn 0.6726377770794297 0.32071716377217097 -0.6668574973017682
+vn 0.6339659239284751 0.4552281602650777 -0.6251835965531946
+vn 0.6144392709305254 0.41362667525230684 0.6718462293249006
+vn 0.6144392709305254 0.41362667525230684 0.6718462293249006
+vn 0.5201511502918131 0.6370423582962276 0.5688759219605662
+vn -0.6344013988511402 0.5915086435673553 0.4976468524172781
+vn 0.6144392709305254 0.41362667525230684 0.6718462293249006
+vn -0.6344013988511402 0.5915086435673553 0.4976468524172781
+vn -0.676035904620863 0.39984581723878665 0.6189497379433149
+vn -0.676035904620863 0.39984581723878665 0.6189497379433149
+vn -0.6344013988511402 0.5915086435673553 0.4976468524172781
+vn -0.4690241375337951 0.7922316552647998 -0.39036567831595415
+vn -0.676035904620863 0.39984581723878665 0.6189497379433149
+vn -0.4690241375337951 0.7922316552647998 -0.39036567831595415
+vn -0.6253659710280434 0.2808616452673895 -0.7280344349670883
+vn -0.6253659710280434 0.2808616452673895 -0.7280344349670883
+vn 0.6339659239284751 0.4552281602650777 -0.6251835965531946
+vn 0.6726377770794297 0.32071716377217097 -0.6668574973017682
+vn 0.5808586579053835 0.8002336535071202 0.1490950010262017
+vn 0.6339659239284751 0.4552281602650777 -0.6251835965531946
+vn 0.08841150891547786 0.8997927794700963 -0.42726614551678077
+vn 0.5201511502918131 0.6370423582962276 0.5688759219605662
+vn 0.5808586579053835 0.8002336535071202 0.1490950010262017
+vn -0.6344013988511402 0.5915086435673553 0.4976468524172781
+vn 0.6144392709305254 0.41362667525230684 0.6718462293249006
+vn 0.6339659239284751 0.4552281602650777 -0.6251835965531946
+vn 0.5808586579053835 0.8002336535071202 0.1490950010262017
+vn 0.6144392709305254 0.41362667525230684 0.6718462293249006
+vn 0.5808586579053835 0.8002336535071202 0.1490950010262017
+vn 0.5201511502918131 0.6370423582962276 0.5688759219605662
+vn -0.6344013988511402 0.5915086435673553 0.4976468524172781
+vn 0.5808586579053835 0.8002336535071202 0.1490950010262017
+vn 0.08841150891547786 0.8997927794700963 -0.42726614551678077
+vn -0.6344013988511402 0.5915086435673553 0.4976468524172781
+vn 0.08841150891547786 0.8997927794700963 -0.42726614551678077
+vn -0.4690241375337951 0.7922316552647998 -0.39036567831595415
+vn 0.6339659239284751 0.4552281602650777 -0.6251835965531946
+vn -0.6253659710280434 0.2808616452673895 -0.7280344349670883
+vn -0.4690241375337951 0.7922316552647998 -0.39036567831595415
+vn 0.6339659239284751 0.4552281602650777 -0.6251835965531946
+vn -0.4690241375337951 0.7922316552647998 -0.39036567831595415
+vn 0.08841150891547786 0.8997927794700963 -0.42726614551678077
+f 1/1/1 2/2/2 3/3/3
+f 4/4/4 5/5/5 6/6/6
+f 7/7/7 8/8/8 9/9/9
+f 10/10/10 11/11/11 12/12/12
+f 13/13/13 14/14/14 15/15/15
+f 16/16/16 17/17/17 18/18/18
+f 19/19/19 20/20/20 21/21/21
+f 22/22/22 23/23/23 24/24/24
+f 25/25/25 26/26/26 27/27/27
+f 28/28/28 29/29/29 30/30/30
+f 31/31/31 32/32/32 33/33/33
+f 34/34/34 35/35/35 36/36/36
+f 37/37/37 38/38/38 39/39/39
+f 40/40/40 41/41/41 42/42/42
diff --git a/apps/openmb/resources/models/rocks/SM_Rocks_02.obj b/apps/openmb/resources/models/rocks/SM_Rocks_02.obj
new file mode 100644
index 0000000..286e946
--- /dev/null
+++ b/apps/openmb/resources/models/rocks/SM_Rocks_02.obj
@@ -0,0 +1,723 @@
+mtllib SM_Rocks_02.mtl
+o SM_Rock_02
+usemtl SM_Rock_01
+v -24.055938720703125 -2.7198753356933594 21.76458168029785 1 1 1
+v -23.67823028564453 5.3347392082214355 23.636808395385742 1 1 1
+v -23.61898422241211 5.268172740936279 -0.3714485168457031 1 1 1
+v -24.055938720703125 -2.7198753356933594 21.76458168029785 1 1 1
+v -23.61898422241211 5.268172740936279 -0.3714485168457031 1 1 1
+v -24.176836013793945 -2.7240138053894043 -0.34766215085983276 1 1 1
+v -23.67823028564453 5.3347392082214355 23.636808395385742 1 1 1
+v -22.744583129882812 13.409550666809082 23.675697326660156 1 1 1
+v -22.13628387451172 13.480212211608887 -0.4199879765510559 1 1 1
+v -23.67823028564453 5.3347392082214355 23.636808395385742 1 1 1
+v -22.13628387451172 13.480212211608887 -0.4199879765510559 1 1 1
+v -23.61898422241211 5.268172740936279 -0.3714485168457031 1 1 1
+v -23.61898422241211 5.268172740936279 -0.3714485168457031 1 1 1
+v -22.13628387451172 13.480212211608887 -0.4199879765510559 1 1 1
+v -18.710731506347656 12.634712219238281 -22.355607986450195 1 1 1
+v -23.61898422241211 5.268172740936279 -0.3714485168457031 1 1 1
+v -18.710731506347656 12.634712219238281 -22.355607986450195 1 1 1
+v -20.693063735961914 4.721319198608398 -21.627622604370117 1 1 1
+v -24.176836013793945 -2.7240138053894043 -0.34766215085983276 1 1 1
+v -23.61898422241211 5.268172740936279 -0.3714485168457031 1 1 1
+v -20.693063735961914 4.721319198608398 -21.627622604370117 1 1 1
+v -24.176836013793945 -2.7240138053894043 -0.34766215085983276 1 1 1
+v -20.693063735961914 4.721319198608398 -21.627622604370117 1 1 1
+v -22.415781021118164 -2.731252431869507 -20.6809024810791 1 1 1
+v -22.415781021118164 -2.731252431869507 -20.6809024810791 1 1 1
+v -20.693063735961914 4.721319198608398 -21.627622604370117 1 1 1
+v -0.5668163299560547 7.3641357421875 -23.636262893676758 1 1 1
+v -22.415781021118164 -2.731252431869507 -20.6809024810791 1 1 1
+v -0.5668163299560547 7.3641357421875 -23.636262893676758 1 1 1
+v -1.9873559474945068 -2.724776029586792 -22.56745147705078 1 1 1
+v -20.693063735961914 4.721319198608398 -21.627622604370117 1 1 1
+v -18.710731506347656 12.634712219238281 -22.355607986450195 1 1 1
+v 0.5532503128051758 17.697351455688477 -23.990585327148438 1 1 1
+v -20.693063735961914 4.721319198608398 -21.627622604370117 1 1 1
+v 0.5532503128051758 17.697351455688477 -23.990585327148438 1 1 1
+v -0.5668163299560547 7.3641357421875 -23.636262893676758 1 1 1
+v -0.5668163299560547 7.3641357421875 -23.636262893676758 1 1 1
+v 0.5532503128051758 17.697351455688477 -23.990585327148438 1 1 1
+v 22.11053466796875 21.398813247680664 -23.82655906677246 1 1 1
+v -0.5668163299560547 7.3641357421875 -23.636262893676758 1 1 1
+v 22.11053466796875 21.398813247680664 -23.82655906677246 1 1 1
+v 21.990467071533203 9.517776489257812 -23.895198822021484 1 1 1
+v -1.9873559474945068 -2.724776029586792 -22.56745147705078 1 1 1
+v -0.5668163299560547 7.3641357421875 -23.636262893676758 1 1 1
+v 21.990467071533203 9.517776489257812 -23.895198822021484 1 1 1
+v -1.9873559474945068 -2.724776029586792 -22.56745147705078 1 1 1
+v 21.990467071533203 9.517776489257812 -23.895198822021484 1 1 1
+v 19.872539520263672 -2.7096211910247803 -22.1872615814209 1 1 1
+v 19.872539520263672 -2.7096211910247803 -22.1872615814209 1 1 1
+v 21.990467071533203 9.517776489257812 -23.895198822021484 1 1 1
+v 22.783470153808594 9.66994571685791 0.16245421767234802 1 1 1
+v 19.872539520263672 -2.7096211910247803 -22.1872615814209 1 1 1
+v 22.783470153808594 9.66994571685791 0.16245421767234802 1 1 1
+v 20.263948440551758 -2.715498685836792 -0.35254400968551636 1 1 1
+v 21.990467071533203 9.517776489257812 -23.895198822021484 1 1 1
+v 22.11053466796875 21.398813247680664 -23.82655906677246 1 1 1
+v 24.008560180664062 22.104433059692383 -0.38888269662857056 1 1 1
+v 21.990467071533203 9.517776489257812 -23.895198822021484 1 1 1
+v 24.008560180664062 22.104433059692383 -0.38888269662857056 1 1 1
+v 22.783470153808594 9.66994571685791 0.16245421767234802 1 1 1
+v 22.783470153808594 9.66994571685791 0.16245421767234802 1 1 1
+v 24.008560180664062 22.104433059692383 -0.38888269662857056 1 1 1
+v 20.42901611328125 21.42203712463379 21.506250381469727 1 1 1
+v 22.783470153808594 9.66994571685791 0.16245421767234802 1 1 1
+v 20.42901611328125 21.42203712463379 21.506250381469727 1 1 1
+v 21.26266860961914 9.389525413513184 22.756641387939453 1 1 1
+v 20.263948440551758 -2.715498685836792 -0.35254400968551636 1 1 1
+v 22.783470153808594 9.66994571685791 0.16245421767234802 1 1 1
+v 21.26266860961914 9.389525413513184 22.756641387939453 1 1 1
+v 20.263948440551758 -2.715498685836792 -0.35254400968551636 1 1 1
+v 21.26266860961914 9.389525413513184 22.756641387939453 1 1 1
+v 18.593219757080078 -2.662442207336426 20.46881103515625 1 1 1
+v 18.593219757080078 -2.662442207336426 20.46881103515625 1 1 1
+v 21.26266860961914 9.389525413513184 22.756641387939453 1 1 1
+v -0.6047964096069336 7.412437915802002 23.94782066345215 1 1 1
+v 18.593219757080078 -2.662442207336426 20.46881103515625 1 1 1
+v -0.6047964096069336 7.412437915802002 23.94782066345215 1 1 1
+v -2.012502670288086 -2.720414876937866 21.87948226928711 1 1 1
+v 21.26266860961914 9.389525413513184 22.756641387939453 1 1 1
+v 20.42901611328125 21.42203712463379 21.506250381469727 1 1 1
+v 0.5940914154052734 17.66459846496582 24.32925796508789 1 1 1
+v 21.26266860961914 9.389525413513184 22.756641387939453 1 1 1
+v 0.5940914154052734 17.66459846496582 24.32925796508789 1 1 1
+v -0.6047964096069336 7.412437915802002 23.94782066345215 1 1 1
+v -0.6047964096069336 7.412437915802002 23.94782066345215 1 1 1
+v 0.5940914154052734 17.66459846496582 24.32925796508789 1 1 1
+v -22.744583129882812 13.409550666809082 23.675697326660156 1 1 1
+v -0.6047964096069336 7.412437915802002 23.94782066345215 1 1 1
+v -22.744583129882812 13.409550666809082 23.675697326660156 1 1 1
+v -23.67823028564453 5.3347392082214355 23.636808395385742 1 1 1
+v -2.012502670288086 -2.720414876937866 21.87948226928711 1 1 1
+v -0.6047964096069336 7.412437915802002 23.94782066345215 1 1 1
+v -23.67823028564453 5.3347392082214355 23.636808395385742 1 1 1
+v -2.012502670288086 -2.720414876937866 21.87948226928711 1 1 1
+v -23.67823028564453 5.3347392082214355 23.636808395385742 1 1 1
+v -24.055938720703125 -2.7198753356933594 21.76458168029785 1 1 1
+v -18.710731506347656 12.634712219238281 -22.355607986450195 1 1 1
+v -22.13628387451172 13.480212211608887 -0.4199879765510559 1 1 1
+v -19.28179168701172 23.09201431274414 -0.40094390511512756 1 1 1
+v -18.710731506347656 12.634712219238281 -22.355607986450195 1 1 1
+v -19.28179168701172 23.09201431274414 -0.40094390511512756 1 1 1
+v -16.962766647338867 21.690853118896484 -20.4646053314209 1 1 1
+v -22.13628387451172 13.480212211608887 -0.4199879765510559 1 1 1
+v -22.744583129882812 13.409550666809082 23.675697326660156 1 1 1
+v -18.88330078125 22.80573844909668 20.25123405456543 1 1 1
+v -22.13628387451172 13.480212211608887 -0.4199879765510559 1 1 1
+v -18.88330078125 22.80573844909668 20.25123405456543 1 1 1
+v -19.28179168701172 23.09201431274414 -0.40094390511512756 1 1 1
+v -19.28179168701172 23.09201431274414 -0.40094390511512756 1 1 1
+v -18.88330078125 22.80573844909668 20.25123405456543 1 1 1
+v -15.017461776733398 32.02982711791992 16.262922286987305 1 1 1
+v -19.28179168701172 23.09201431274414 -0.40094390511512756 1 1 1
+v -15.017461776733398 32.02982711791992 16.262922286987305 1 1 1
+v -15.003299713134766 32.14637756347656 -0.40167802572250366 1 1 1
+v -16.962766647338867 21.690853118896484 -20.4646053314209 1 1 1
+v -19.28179168701172 23.09201431274414 -0.40094390511512756 1 1 1
+v -15.003299713134766 32.14637756347656 -0.40167802572250366 1 1 1
+v -16.962766647338867 21.690853118896484 -20.4646053314209 1 1 1
+v -15.003299713134766 32.14637756347656 -0.40167802572250366 1 1 1
+v -13.85345458984375 31.184247970581055 -16.449951171875 1 1 1
+v 0.0286102294921875 41.531524658203125 -16.41400146484375 1 1 1
+v -7.422924041748047 37.50237274169922 -17.331745147705078 1 1 1
+v -7.4855804443359375 37.742950439453125 -0.46993908286094666 1 1 1
+v 0.0286102294921875 41.531524658203125 -16.41400146484375 1 1 1
+v -7.4855804443359375 37.742950439453125 -0.46993908286094666 1 1 1
+v 0.22161006927490234 42.54776382446289 -0.5730391144752502 1 1 1
+v -7.422924041748047 37.50237274169922 -17.331745147705078 1 1 1
+v -13.85345458984375 31.184247970581055 -16.449951171875 1 1 1
+v -15.003299713134766 32.14637756347656 -0.40167802572250366 1 1 1
+v -7.422924041748047 37.50237274169922 -17.331745147705078 1 1 1
+v -15.003299713134766 32.14637756347656 -0.40167802572250366 1 1 1
+v -7.4855804443359375 37.742950439453125 -0.46993908286094666 1 1 1
+v -7.4855804443359375 37.742950439453125 -0.46993908286094666 1 1 1
+v -15.003299713134766 32.14637756347656 -0.40167802572250366 1 1 1
+v -15.017461776733398 32.02982711791992 16.262922286987305 1 1 1
+v -7.4855804443359375 37.742950439453125 -0.46993908286094666 1 1 1
+v -15.017461776733398 32.02982711791992 16.262922286987305 1 1 1
+v -7.476067543029785 37.67071533203125 16.48223304748535 1 1 1
+v 0.22161006927490234 42.54776382446289 -0.5730391144752502 1 1 1
+v -7.4855804443359375 37.742950439453125 -0.46993908286094666 1 1 1
+v -7.476067543029785 37.67071533203125 16.48223304748535 1 1 1
+v 0.22161006927490234 42.54776382446289 -0.5730391144752502 1 1 1
+v -7.476067543029785 37.67071533203125 16.48223304748535 1 1 1
+v 0.3472328186035156 42.346988677978516 16.059913635253906 1 1 1
+v -22.744583129882812 13.409550666809082 23.675697326660156 1 1 1
+v 0.5940914154052734 17.66459846496582 24.32925796508789 1 1 1
+v -3.412318229675293 27.7247314453125 20.515581130981445 1 1 1
+v -22.744583129882812 13.409550666809082 23.675697326660156 1 1 1
+v -3.412318229675293 27.7247314453125 20.515581130981445 1 1 1
+v -18.88330078125 22.80573844909668 20.25123405456543 1 1 1
+v 0.5940914154052734 17.66459846496582 24.32925796508789 1 1 1
+v 20.42901611328125 21.42203712463379 21.506250381469727 1 1 1
+v 12.146782875061035 32.61277770996094 20.98918342590332 1 1 1
+v 0.5940914154052734 17.66459846496582 24.32925796508789 1 1 1
+v 12.146782875061035 32.61277770996094 20.98918342590332 1 1 1
+v -3.412318229675293 27.7247314453125 20.515581130981445 1 1 1
+v -3.412318229675293 27.7247314453125 20.515581130981445 1 1 1
+v 12.146782875061035 32.61277770996094 20.98918342590332 1 1 1
+v 0.3472328186035156 42.346988677978516 16.059913635253906 1 1 1
+v -3.412318229675293 27.7247314453125 20.515581130981445 1 1 1
+v 0.3472328186035156 42.346988677978516 16.059913635253906 1 1 1
+v -7.476067543029785 37.67071533203125 16.48223304748535 1 1 1
+v -18.88330078125 22.80573844909668 20.25123405456543 1 1 1
+v -3.412318229675293 27.7247314453125 20.515581130981445 1 1 1
+v -7.476067543029785 37.67071533203125 16.48223304748535 1 1 1
+v -18.88330078125 22.80573844909668 20.25123405456543 1 1 1
+v -7.476067543029785 37.67071533203125 16.48223304748535 1 1 1
+v -15.017461776733398 32.02982711791992 16.262922286987305 1 1 1
+v 22.11053466796875 21.398813247680664 -23.82655906677246 1 1 1
+v 0.5532503128051758 17.697351455688477 -23.990585327148438 1 1 1
+v -3.47137451171875 27.784055709838867 -22.0271053314209 1 1 1
+v 22.11053466796875 21.398813247680664 -23.82655906677246 1 1 1
+v -3.47137451171875 27.784055709838867 -22.0271053314209 1 1 1
+v 12.162232398986816 32.550628662109375 -21.80869483947754 1 1 1
+v 0.5532503128051758 17.697351455688477 -23.990585327148438 1 1 1
+v -18.710731506347656 12.634712219238281 -22.355607986450195 1 1 1
+v -16.962766647338867 21.690853118896484 -20.4646053314209 1 1 1
+v 0.5532503128051758 17.697351455688477 -23.990585327148438 1 1 1
+v -16.962766647338867 21.690853118896484 -20.4646053314209 1 1 1
+v -3.47137451171875 27.784055709838867 -22.0271053314209 1 1 1
+v -3.47137451171875 27.784055709838867 -22.0271053314209 1 1 1
+v -16.962766647338867 21.690853118896484 -20.4646053314209 1 1 1
+v -13.85345458984375 31.184247970581055 -16.449951171875 1 1 1
+v -3.47137451171875 27.784055709838867 -22.0271053314209 1 1 1
+v -13.85345458984375 31.184247970581055 -16.449951171875 1 1 1
+v -7.422924041748047 37.50237274169922 -17.331745147705078 1 1 1
+v 12.162232398986816 32.550628662109375 -21.80869483947754 1 1 1
+v -3.47137451171875 27.784055709838867 -22.0271053314209 1 1 1
+v -7.422924041748047 37.50237274169922 -17.331745147705078 1 1 1
+v 12.162232398986816 32.550628662109375 -21.80869483947754 1 1 1
+v -7.422924041748047 37.50237274169922 -17.331745147705078 1 1 1
+v 0.0286102294921875 41.531524658203125 -16.41400146484375 1 1 1
+v 20.42901611328125 21.42203712463379 21.506250381469727 1 1 1
+v 24.008560180664062 22.104433059692383 -0.38888269662857056 1 1 1
+v 12.492728233337402 32.62037658691406 -0.8444314002990723 1 1 1
+v 20.42901611328125 21.42203712463379 21.506250381469727 1 1 1
+v 12.492728233337402 32.62037658691406 -0.8444314002990723 1 1 1
+v 12.146782875061035 32.61277770996094 20.98918342590332 1 1 1
+v 24.008560180664062 22.104433059692383 -0.38888269662857056 1 1 1
+v 22.11053466796875 21.398813247680664 -23.82655906677246 1 1 1
+v 12.162232398986816 32.550628662109375 -21.80869483947754 1 1 1
+v 24.008560180664062 22.104433059692383 -0.38888269662857056 1 1 1
+v 12.162232398986816 32.550628662109375 -21.80869483947754 1 1 1
+v 12.492728233337402 32.62037658691406 -0.8444314002990723 1 1 1
+v 12.492728233337402 32.62037658691406 -0.8444314002990723 1 1 1
+v 12.162232398986816 32.550628662109375 -21.80869483947754 1 1 1
+v 0.0286102294921875 41.531524658203125 -16.41400146484375 1 1 1
+v 12.492728233337402 32.62037658691406 -0.8444314002990723 1 1 1
+v 0.0286102294921875 41.531524658203125 -16.41400146484375 1 1 1
+v 0.22161006927490234 42.54776382446289 -0.5730391144752502 1 1 1
+v 12.146782875061035 32.61277770996094 20.98918342590332 1 1 1
+v 12.492728233337402 32.62037658691406 -0.8444314002990723 1 1 1
+v 0.22161006927490234 42.54776382446289 -0.5730391144752502 1 1 1
+v 12.146782875061035 32.61277770996094 20.98918342590332 1 1 1
+v 0.22161006927490234 42.54776382446289 -0.5730391144752502 1 1 1
+v 0.3472328186035156 42.346988677978516 16.059913635253906 1 1 1
+vt 0.798905611038208 0.8846748471260071
+vt 0.7935385704040527 0.8622298836708069
+vt 0.8614128828048706 0.8630435466766357
+vt 0.798905611038208 0.8846748471260071
+vt 0.8614128828048706 0.8630435466766357
+vt 0.8613858222961426 0.8853878974914551
+vt 0.7935385704040527 0.8622298836708069
+vt 0.7934572696685791 0.8393980860710144
+vt 0.861678957939148 0.8394591808319092
+vt 0.7935385704040527 0.8622298836708069
+vt 0.861678957939148 0.8394591808319092
+vt 0.8614128828048706 0.8630435466766357
+vt 0.8614128828048706 0.8630435466766357
+vt 0.861678957939148 0.8394591808319092
+vt 0.9243384599685669 0.8400381207466125
+vt 0.8614128828048706 0.8630435466766357
+vt 0.9243384599685669 0.8400381207466125
+vt 0.9220530390739441 0.8631267547607422
+vt 0.8613858222961426 0.8853878974914551
+vt 0.8614128828048706 0.8630435466766357
+vt 0.9220530390739441 0.8631267547607422
+vt 0.8613858222961426 0.8853878974914551
+vt 0.9220530390739441 0.8631267547607422
+vt 0.9191895127296448 0.8847643733024597
+vt 0.003841985482722521 0.9961579442024231
+vt 0.008685518056154251 0.9752037525177002
+vt 0.06587769836187363 0.9673058390617371
+vt 0.003841985482722521 0.9961579442024231
+vt 0.06587769836187363 0.9673058390617371
+vt 0.06193755194544792 0.9956760406494141
+vt 0.008685518056154251 0.9752037525177002
+vt 0.01420876570045948 0.9528955817222595
+vt 0.06882666051387787 0.9381227493286133
+vt 0.008685518056154251 0.9752037525177002
+vt 0.06882666051387787 0.9381227493286133
+vt 0.06587769836187363 0.9673058390617371
+vt 0.06587769836187363 0.9673058390617371
+vt 0.06882666051387787 0.9381227493286133
+vt 0.12962321937084198 0.9267666339874268
+vt 0.06587769836187363 0.9673058390617371
+vt 0.12962321937084198 0.9267666339874268
+vt 0.12962321937084198 0.9603638648986816
+vt 0.06193755194544792 0.9956760406494141
+vt 0.06587769836187363 0.9673058390617371
+vt 0.12962321937084198 0.9603638648986816
+vt 0.06193755194544792 0.9956760406494141
+vt 0.12962321937084198 0.9603638648986816
+vt 0.12364975363016129 0.9946857690811157
+vt 0.559004008769989 0.9372794032096863
+vt 0.5399733185768127 0.9415040612220764
+vt 0.5436710715293884 0.8734409809112549
+vt 0.559004008769989 0.9372794032096863
+vt 0.5436710715293884 0.8734409809112549
+vt 0.5619469881057739 0.8754901885986328
+vt 0.5399733185768127 0.9415040612220764
+vt 0.5175911784172058 0.9405732750892639
+vt 0.5224881172180176 0.8743122220039368
+vt 0.5399733185768127 0.9415040612220764
+vt 0.5224881172180176 0.8743122220039368
+vt 0.5436710715293884 0.8734409809112549
+vt 0.5436710715293884 0.8734409809112549
+vt 0.5224881172180176 0.8743122220039368
+vt 0.5184112787246704 0.8121017217636108
+vt 0.5436710715293884 0.8734409809112549
+vt 0.5184112787246704 0.8121017217636108
+vt 0.5432066917419434 0.8093778491020203
+vt 0.5619469881057739 0.8754901885986328
+vt 0.5436710715293884 0.8734409809112549
+vt 0.5432066917419434 0.8093778491020203
+vt 0.5619469881057739 0.8754901885986328
+vt 0.5432066917419434 0.8093778491020203
+vt 0.5603617429733276 0.8164142966270447
+vt 0.33764275908470154 0.9348790049552917
+vt 0.30365124344825745 0.942414402961731
+vt 0.3093186318874359 0.8804537653923035
+vt 0.33764275908470154 0.9348790049552917
+vt 0.3093186318874359 0.8804537653923035
+vt 0.3378887474536896 0.8764901161193848
+vt 0.30365124344825745 0.942414402961731
+vt 0.2694956362247467 0.9400674104690552
+vt 0.28030648827552795 0.8838455677032471
+vt 0.30365124344825745 0.942414402961731
+vt 0.28030648827552795 0.8838455677032471
+vt 0.3093186318874359 0.8804537653923035
+vt 0.3093186318874359 0.8804537653923035
+vt 0.28030648827552795 0.8838455677032471
+vt 0.29231131076812744 0.8177387118339539
+vt 0.3093186318874359 0.8804537653923035
+vt 0.29231131076812744 0.8177387118339539
+vt 0.3151780068874359 0.8150942921638489
+vt 0.3378887474536896 0.8764901161193848
+vt 0.3093186318874359 0.8804537653923035
+vt 0.3151780068874359 0.8150942921638489
+vt 0.3378887474536896 0.8764901161193848
+vt 0.3151780068874359 0.8150942921638489
+vt 0.33787453174591064 0.8140461444854736
+vt 0.9243384599685669 0.8400381207466125
+vt 0.861678957939148 0.8394591808319092
+vt 0.8619852066040039 0.8110823631286621
+vt 0.9243384599685669 0.8400381207466125
+vt 0.8619852066040039 0.8110823631286621
+vt 0.9191564917564392 0.8138974905014038
+vt 0.861678957939148 0.8394591808319092
+vt 0.7934572696685791 0.8393980860710144
+vt 0.8036892414093018 0.8110170960426331
+vt 0.861678957939148 0.8394591808319092
+vt 0.8036892414093018 0.8110170960426331
+vt 0.8619852066040039 0.8110823631286621
+vt 0.8619852066040039 0.8110823631286621
+vt 0.8036892414093018 0.8110170960426331
+vt 0.8155189752578735 0.7831215858459473
+vt 0.8619852066040039 0.8110823631286621
+vt 0.8155189752578735 0.7831215858459473
+vt 0.8626238703727722 0.7832577228546143
+vt 0.9191564917564392 0.8138974905014038
+vt 0.8619852066040039 0.8110823631286621
+vt 0.8626238703727722 0.7832577228546143
+vt 0.9191564917564392 0.8138974905014038
+vt 0.8626238703727722 0.7832577228546143
+vt 0.9082185626029968 0.7855588793754578
+vt 0.9105263948440552 0.7475702166557312
+vt 0.9117996096611023 0.7637962698936462
+vt 0.8641217350959778 0.7627066969871521
+vt 0.9105263948440552 0.7475702166557312
+vt 0.8641217350959778 0.7627066969871521
+vt 0.8657678961753845 0.7442018389701843
+vt 0.9117996096611023 0.7637962698936462
+vt 0.9082185626029968 0.7855588793754578
+vt 0.8626238703727722 0.7832577228546143
+vt 0.9117996096611023 0.7637962698936462
+vt 0.8626238703727722 0.7832577228546143
+vt 0.8641217350959778 0.7627066969871521
+vt 0.8641217350959778 0.7627066969871521
+vt 0.8626238703727722 0.7832577228546143
+vt 0.8155189752578735 0.7831215858459473
+vt 0.8641217350959778 0.7627066969871521
+vt 0.8155189752578735 0.7831215858459473
+vt 0.8162076473236084 0.7624244689941406
+vt 0.8657678961753845 0.7442018389701843
+vt 0.8641217350959778 0.7627066969871521
+vt 0.8162076473236084 0.7624244689941406
+vt 0.8657678961753845 0.7442018389701843
+vt 0.8162076473236084 0.7624244689941406
+vt 0.8187801241874695 0.7442018389701843
+vt 0.29231131076812744 0.8177387118339539
+vt 0.28030648827552795 0.8838455677032471
+vt 0.25157809257507324 0.8725405335426331
+vt 0.29231131076812744 0.8177387118339539
+vt 0.25157809257507324 0.8725405335426331
+vt 0.2654893398284912 0.8287169933319092
+vt 0.28030648827552795 0.8838455677032471
+vt 0.2694956362247467 0.9400674104690552
+vt 0.23776744306087494 0.9166113138198853
+vt 0.28030648827552795 0.8838455677032471
+vt 0.23776744306087494 0.9166113138198853
+vt 0.25157809257507324 0.8725405335426331
+vt 0.25157809257507324 0.8725405335426331
+vt 0.23776744306087494 0.9166113138198853
+vt 0.20989131927490234 0.883242666721344
+vt 0.25157809257507324 0.8725405335426331
+vt 0.20989131927490234 0.883242666721344
+vt 0.22315941751003265 0.8610756993293762
+vt 0.2654893398284912 0.8287169933319092
+vt 0.25157809257507324 0.8725405335426331
+vt 0.22315941751003265 0.8610756993293762
+vt 0.2654893398284912 0.8287169933319092
+vt 0.22315941751003265 0.8610756993293762
+vt 0.2391199916601181 0.839714765548706
+vt 0.12962321937084198 0.9267666339874268
+vt 0.06882666051387787 0.9381227493286133
+vt 0.05680280178785324 0.9094063639640808
+vt 0.12962321937084198 0.9267666339874268
+vt 0.05680280178785324 0.9094063639640808
+vt 0.10081718862056732 0.8952670097351074
+vt 0.06882666051387787 0.9381227493286133
+vt 0.01420876570045948 0.9528955817222595
+vt 0.018542522564530373 0.9268742203712463
+vt 0.06882666051387787 0.9381227493286133
+vt 0.018542522564530373 0.9268742203712463
+vt 0.05680280178785324 0.9094063639640808
+vt 0.05680280178785324 0.9094063639640808
+vt 0.018542522564530373 0.9268742203712463
+vt 0.026310032233595848 0.8991629481315613
+vt 0.05680280178785324 0.9094063639640808
+vt 0.026310032233595848 0.8991629481315613
+vt 0.04447855055332184 0.8812142014503479
+vt 0.10081718862056732 0.8952670097351074
+vt 0.05680280178785324 0.9094063639640808
+vt 0.04447855055332184 0.8812142014503479
+vt 0.10081718862056732 0.8952670097351074
+vt 0.04447855055332184 0.8812142014503479
+vt 0.06525511294603348 0.8693552613258362
+vt 0.5184112787246704 0.8121017217636108
+vt 0.5224881172180176 0.8743122220039368
+vt 0.47829195857048035 0.8740934729576111
+vt 0.5184112787246704 0.8121017217636108
+vt 0.47829195857048035 0.8740934729576111
+vt 0.4796941876411438 0.8122531771659851
+vt 0.5224881172180176 0.8743122220039368
+vt 0.5175911784172058 0.9405732750892639
+vt 0.4757048189640045 0.9334274530410767
+vt 0.5224881172180176 0.8743122220039368
+vt 0.4757048189640045 0.9334274530410767
+vt 0.47829195857048035 0.8740934729576111
+vt 0.47829195857048035 0.8740934729576111
+vt 0.4757048189640045 0.9334274530410767
+vt 0.4337061643600464 0.9166962504386902
+vt 0.47829195857048035 0.8740934729576111
+vt 0.4337061643600464 0.9166962504386902
+vt 0.4337061643600464 0.8717978596687317
+vt 0.4796941876411438 0.8122531771659851
+vt 0.47829195857048035 0.8740934729576111
+vt 0.4337061643600464 0.8717978596687317
+vt 0.4796941876411438 0.8122531771659851
+vt 0.4337061643600464 0.8717978596687317
+vt 0.4359608292579651 0.8247285485267639
+vn -0.7658524512160326 -0.09311585147346466 0.6362385253745377
+vn -0.6960056284593561 -0.0192073337608014 0.7177793835731824
+vn -0.9882792960813065 0.13639172268933886 -0.06856625204043063
+vn -0.7658524512160326 -0.09311585147346466 0.6362385253745377
+vn -0.9882792960813065 0.13639172268933886 -0.06856625204043063
+vn -0.9936044277775063 0.09823478229962283 -0.05567915810677949
+vn -0.6960056284593561 -0.0192073337608014 0.7177793835731824
+vn -0.692892177480864 0.2335044537642879 0.6821847993455062
+vn -0.9690770227322479 0.2342792681825583 -0.07747869715119822
+vn -0.6960056284593561 -0.0192073337608014 0.7177793835731824
+vn -0.9690770227322479 0.2342792681825583 -0.07747869715119822
+vn -0.9882792960813065 0.13639172268933886 -0.06856625204043063
+vn -0.9882792960813065 0.13639172268933886 -0.06856625204043063
+vn -0.9690770227322479 0.2342792681825583 -0.07747869715119822
+vn -0.642982244231693 0.15608689182648408 -0.7498071190664456
+vn -0.9882792960813065 0.13639172268933886 -0.06856625204043063
+vn -0.642982244231693 0.15608689182648408 -0.7498071190664456
+vn -0.683877201053344 0.06026136995338454 -0.7271042161690341
+vn -0.9936044277775063 0.09823478229962283 -0.05567915810677949
+vn -0.9882792960813065 0.13639172268933886 -0.06856625204043063
+vn -0.683877201053344 0.06026136995338454 -0.7271042161690341
+vn -0.9936044277775063 0.09823478229962283 -0.05567915810677949
+vn -0.683877201053344 0.06026136995338454 -0.7271042161690341
+vn -0.7647800228916277 0.04492418735673611 -0.6427233728255246
+vn -0.7647800228916277 0.04492418735673611 -0.6427233728255246
+vn -0.683877201053344 0.06026136995338454 -0.7271042161690341
+vn -0.03997046448625307 -0.07198179419896308 -0.9966047276993278
+vn -0.7647800228916277 0.04492418735673611 -0.6427233728255246
+vn -0.03997046448625307 -0.07198179419896308 -0.9966047276993278
+vn -0.04449174744449951 -0.11033117321719993 -0.9928985429669293
+vn -0.683877201053344 0.06026136995338454 -0.7271042161690341
+vn -0.642982244231693 0.15608689182648408 -0.7498071190664456
+vn -0.06000629482956411 0.07591231495504497 -0.9953072716598597
+vn -0.683877201053344 0.06026136995338454 -0.7271042161690341
+vn -0.06000629482956411 0.07591231495504497 -0.9953072716598597
+vn -0.03997046448625307 -0.07198179419896308 -0.9966047276993278
+vn -0.03997046448625307 -0.07198179419896308 -0.9966047276993278
+vn -0.06000629482956411 0.07591231495504497 -0.9953072716598597
+vn 0.6848947465796044 0.2873341466318297 -0.6695956050386064
+vn -0.03997046448625307 -0.07198179419896308 -0.9966047276993278
+vn 0.6848947465796044 0.2873341466318297 -0.6695956050386064
+vn 0.6889308271838824 -0.12498175673661659 -0.7139705006782567
+vn -0.04449174744449951 -0.11033117321719993 -0.9928985429669293
+vn -0.03997046448625307 -0.07198179419896308 -0.9966047276993278
+vn 0.6889308271838824 -0.12498175673661659 -0.7139705006782567
+vn -0.04449174744449951 -0.11033117321719993 -0.9928985429669293
+vn 0.6889308271838824 -0.12498175673661659 -0.7139705006782567
+vn 0.6750775032660218 -0.2135959135395753 -0.7061495240409843
+vn 0.6750775032660218 -0.2135959135395753 -0.7061495240409843
+vn 0.6889308271838824 -0.12498175673661659 -0.7139705006782567
+vn 0.9928719399854794 -0.11584041315516197 0.0280412102005586
+vn 0.6750775032660218 -0.2135959135395753 -0.7061495240409843
+vn 0.9928719399854794 -0.11584041315516197 0.0280412102005586
+vn 0.9794475240871835 -0.2005157430712719 0.021817065340279825
+vn 0.6889308271838824 -0.12498175673661659 -0.7139705006782567
+vn 0.6848947465796044 0.2873341466318297 -0.6695956050386064
+vn 0.935117282275238 0.3536376869737989 0.022272286411464986
+vn 0.6889308271838824 -0.12498175673661659 -0.7139705006782567
+vn 0.935117282275238 0.3536376869737989 0.022272286411464986
+vn 0.9928719399854794 -0.11584041315516197 0.0280412102005586
+vn 0.9928719399854794 -0.11584041315516197 0.0280412102005586
+vn 0.935117282275238 0.3536376869737989 0.022272286411464986
+vn 0.6892475341759589 0.3110881084756211 0.6543409091577728
+vn 0.9928719399854794 -0.11584041315516197 0.0280412102005586
+vn 0.6892475341759589 0.3110881084756211 0.6543409091577728
+vn 0.6974296690735602 -0.1177265414858794 0.7069174761778901
+vn 0.9794475240871835 -0.2005157430712719 0.021817065340279825
+vn 0.9928719399854794 -0.11584041315516197 0.0280412102005586
+vn 0.6974296690735602 -0.1177265414858794 0.7069174761778901
+vn 0.9794475240871835 -0.2005157430712719 0.021817065340279825
+vn 0.6974296690735602 -0.1177265414858794 0.7069174761778901
+vn 0.673179723923595 -0.27288120103347857 0.687288083281442
+vn 0.673179723923595 -0.27288120103347857 0.687288083281442
+vn 0.6974296690735602 -0.1177265414858794 0.7069174761778901
+vn 0.03481894144832179 -0.10203793017301757 0.9941709622204951
+vn 0.673179723923595 -0.27288120103347857 0.687288083281442
+vn 0.03481894144832179 -0.10203793017301757 0.9941709622204951
+vn 0.03223567444743522 -0.20858278797701574 0.9774733151614188
+vn 0.6974296690735602 -0.1177265414858794 0.7069174761778901
+vn 0.6892475341759589 0.3110881084756211 0.6543409091577728
+vn 0.00453048294868246 0.14207755101982042 0.9898451617401897
+vn 0.6974296690735602 -0.1177265414858794 0.7069174761778901
+vn 0.00453048294868246 0.14207755101982042 0.9898451617401897
+vn 0.03481894144832179 -0.10203793017301757 0.9941709622204951
+vn 0.03481894144832179 -0.10203793017301757 0.9941709622204951
+vn 0.00453048294868246 0.14207755101982042 0.9898451617401897
+vn -0.692892177480864 0.2335044537642879 0.6821847993455062
+vn 0.03481894144832179 -0.10203793017301757 0.9941709622204951
+vn -0.692892177480864 0.2335044537642879 0.6821847993455062
+vn -0.6960056284593561 -0.0192073337608014 0.7177793835731824
+vn 0.03223567444743522 -0.20858278797701574 0.9774733151614188
+vn 0.03481894144832179 -0.10203793017301757 0.9941709622204951
+vn -0.6960056284593561 -0.0192073337608014 0.7177793835731824
+vn 0.03223567444743522 -0.20858278797701574 0.9774733151614188
+vn -0.6960056284593561 -0.0192073337608014 0.7177793835731824
+vn -0.7658524512160326 -0.09311585147346466 0.6362385253745377
+vn -0.642982244231693 0.15608689182648408 -0.7498071190664456
+vn -0.9690770227322479 0.2342792681825583 -0.07747869715119822
+vn -0.9356101157617274 0.34767136751758615 -0.06130523218110122
+vn -0.642982244231693 0.15608689182648408 -0.7498071190664456
+vn -0.9356101157617274 0.34767136751758615 -0.06130523218110122
+vn -0.6846666233354775 0.32547190297177336 -0.6521500251217722
+vn -0.9690770227322479 0.2342792681825583 -0.07747869715119822
+vn -0.692892177480864 0.2335044537642879 0.6821847993455062
+vn -0.665416780489932 0.45344406595040115 0.5929662615164388
+vn -0.9690770227322479 0.2342792681825583 -0.07747869715119822
+vn -0.665416780489932 0.45344406595040115 0.5929662615164388
+vn -0.9356101157617274 0.34767136751758615 -0.06130523218110122
+vn -0.9356101157617274 0.34767136751758615 -0.06130523218110122
+vn -0.665416780489932 0.45344406595040115 0.5929662615164388
+vn -0.6475796052717011 0.6070646000007461 0.4605575167794811
+vn -0.9356101157617274 0.34767136751758615 -0.06130523218110122
+vn -0.6475796052717011 0.6070646000007461 0.4605575167794811
+vn -0.792640893611793 0.6085381409529894 -0.03743988220838353
+vn -0.6846666233354775 0.32547190297177336 -0.6521500251217722
+vn -0.9356101157617274 0.34767136751758615 -0.06130523218110122
+vn -0.792640893611793 0.6085381409529894 -0.03743988220838353
+vn -0.6846666233354775 0.32547190297177336 -0.6521500251217722
+vn -0.792640893611793 0.6085381409529894 -0.03743988220838353
+vn -0.6978232905979236 0.5533658898126775 -0.4547843962702649
+vn 0.025496957528712894 0.8958672181455717 -0.443589712018768
+vn -0.45677883369588523 0.700727967860512 -0.5480268352421297
+vn -0.569571709848857 0.8217578785492288 -0.017379769334499195
+vn 0.025496957528712894 0.8958672181455717 -0.443589712018768
+vn -0.569571709848857 0.8217578785492288 -0.017379769334499195
+vn 0.06575791094630122 0.9977400822619501 -0.013806715608554225
+vn -0.45677883369588523 0.700727967860512 -0.5480268352421297
+vn -0.6978232905979236 0.5533658898126775 -0.4547843962702649
+vn -0.792640893611793 0.6085381409529894 -0.03743988220838353
+vn -0.45677883369588523 0.700727967860512 -0.5480268352421297
+vn -0.792640893611793 0.6085381409529894 -0.03743988220838353
+vn -0.569571709848857 0.8217578785492288 -0.017379769334499195
+vn -0.569571709848857 0.8217578785492288 -0.017379769334499195
+vn -0.792640893611793 0.6085381409529894 -0.03743988220838353
+vn -0.6475796052717011 0.6070646000007461 0.4605575167794811
+vn -0.569571709848857 0.8217578785492288 -0.017379769334499195
+vn -0.6475796052717011 0.6070646000007461 0.4605575167794811
+vn -0.4328885381523027 0.7061487444564377 0.5603226429825579
+vn 0.06575791094630122 0.9977400822619501 -0.013806715608554225
+vn -0.569571709848857 0.8217578785492288 -0.017379769334499195
+vn -0.4328885381523027 0.7061487444564377 0.5603226429825579
+vn 0.06575791094630122 0.9977400822619501 -0.013806715608554225
+vn -0.4328885381523027 0.7061487444564377 0.5603226429825579
+vn 0.027135236149421885 0.8870363209768896 0.46090155589550763
+vn -0.692892177480864 0.2335044537642879 0.6821847993455062
+vn 0.00453048294868246 0.14207755101982042 0.9898451617401897
+vn -0.10497748132216511 0.3152740083599685 0.9431765625098479
+vn -0.692892177480864 0.2335044537642879 0.6821847993455062
+vn -0.10497748132216511 0.3152740083599685 0.9431765625098479
+vn -0.665416780489932 0.45344406595040115 0.5929662615164388
+vn 0.00453048294868246 0.14207755101982042 0.9898451617401897
+vn 0.6892475341759589 0.3110881084756211 0.6543409091577728
+vn 0.4189406321917698 0.6233655194317278 0.6602303960606271
+vn 0.00453048294868246 0.14207755101982042 0.9898451617401897
+vn 0.4189406321917698 0.6233655194317278 0.6602303960606271
+vn -0.10497748132216511 0.3152740083599685 0.9431765625098479
+vn -0.10497748132216511 0.3152740083599685 0.9431765625098479
+vn 0.4189406321917698 0.6233655194317278 0.6602303960606271
+vn 0.027135236149421885 0.8870363209768896 0.46090155589550763
+vn -0.10497748132216511 0.3152740083599685 0.9431765625098479
+vn 0.027135236149421885 0.8870363209768896 0.46090155589550763
+vn -0.4328885381523027 0.7061487444564377 0.5603226429825579
+vn -0.665416780489932 0.45344406595040115 0.5929662615164388
+vn -0.10497748132216511 0.3152740083599685 0.9431765625098479
+vn -0.4328885381523027 0.7061487444564377 0.5603226429825579
+vn -0.665416780489932 0.45344406595040115 0.5929662615164388
+vn -0.4328885381523027 0.7061487444564377 0.5603226429825579
+vn -0.6475796052717011 0.6070646000007461 0.4605575167794811
+vn 0.6848947465796044 0.2873341466318297 -0.6695956050386064
+vn -0.06000629482956411 0.07591231495504497 -0.9953072716598597
+vn -0.16055593051477232 0.286806648996217 -0.9444383194619416
+vn 0.6848947465796044 0.2873341466318297 -0.6695956050386064
+vn -0.16055593051477232 0.286806648996217 -0.9444383194619416
+vn 0.3956119121280836 0.6405301209453955 -0.6581887108907586
+vn -0.06000629482956411 0.07591231495504497 -0.9953072716598597
+vn -0.642982244231693 0.15608689182648408 -0.7498071190664456
+vn -0.6846666233354775 0.32547190297177336 -0.6521500251217722
+vn -0.06000629482956411 0.07591231495504497 -0.9953072716598597
+vn -0.6846666233354775 0.32547190297177336 -0.6521500251217722
+vn -0.16055593051477232 0.286806648996217 -0.9444383194619416
+vn -0.16055593051477232 0.286806648996217 -0.9444383194619416
+vn -0.6846666233354775 0.32547190297177336 -0.6521500251217722
+vn -0.6978232905979236 0.5533658898126775 -0.4547843962702649
+vn -0.16055593051477232 0.286806648996217 -0.9444383194619416
+vn -0.6978232905979236 0.5533658898126775 -0.4547843962702649
+vn -0.45677883369588523 0.700727967860512 -0.5480268352421297
+vn 0.3956119121280836 0.6405301209453955 -0.6581887108907586
+vn -0.16055593051477232 0.286806648996217 -0.9444383194619416
+vn -0.45677883369588523 0.700727967860512 -0.5480268352421297
+vn 0.3956119121280836 0.6405301209453955 -0.6581887108907586
+vn -0.45677883369588523 0.700727967860512 -0.5480268352421297
+vn 0.025496957528712894 0.8958672181455717 -0.443589712018768
+vn 0.6892475341759589 0.3110881084756211 0.6543409091577728
+vn 0.935117282275238 0.3536376869737989 0.022272286411464986
+vn 0.6731883146249377 0.7394708835969569 0.0005525982007909237
+vn 0.6892475341759589 0.3110881084756211 0.6543409091577728
+vn 0.6731883146249377 0.7394708835969569 0.0005525982007909237
+vn 0.4189406321917698 0.6233655194317278 0.6602303960606271
+vn 0.935117282275238 0.3536376869737989 0.022272286411464986
+vn 0.6848947465796044 0.2873341466318297 -0.6695956050386064
+vn 0.3956119121280836 0.6405301209453955 -0.6581887108907586
+vn 0.935117282275238 0.3536376869737989 0.022272286411464986
+vn 0.3956119121280836 0.6405301209453955 -0.6581887108907586
+vn 0.6731883146249377 0.7394708835969569 0.0005525982007909237
+vn 0.6731883146249377 0.7394708835969569 0.0005525982007909237
+vn 0.3956119121280836 0.6405301209453955 -0.6581887108907586
+vn 0.025496957528712894 0.8958672181455717 -0.443589712018768
+vn 0.6731883146249377 0.7394708835969569 0.0005525982007909237
+vn 0.025496957528712894 0.8958672181455717 -0.443589712018768
+vn 0.06575791094630122 0.9977400822619501 -0.013806715608554225
+vn 0.4189406321917698 0.6233655194317278 0.6602303960606271
+vn 0.6731883146249377 0.7394708835969569 0.0005525982007909237
+vn 0.06575791094630122 0.9977400822619501 -0.013806715608554225
+vn 0.4189406321917698 0.6233655194317278 0.6602303960606271
+vn 0.06575791094630122 0.9977400822619501 -0.013806715608554225
+vn 0.027135236149421885 0.8870363209768896 0.46090155589550763
+f 1/1/1 2/2/2 3/3/3
+f 4/4/4 5/5/5 6/6/6
+f 7/7/7 8/8/8 9/9/9
+f 10/10/10 11/11/11 12/12/12
+f 13/13/13 14/14/14 15/15/15
+f 16/16/16 17/17/17 18/18/18
+f 19/19/19 20/20/20 21/21/21
+f 22/22/22 23/23/23 24/24/24
+f 25/25/25 26/26/26 27/27/27
+f 28/28/28 29/29/29 30/30/30
+f 31/31/31 32/32/32 33/33/33
+f 34/34/34 35/35/35 36/36/36
+f 37/37/37 38/38/38 39/39/39
+f 40/40/40 41/41/41 42/42/42
+f 43/43/43 44/44/44 45/45/45
+f 46/46/46 47/47/47 48/48/48
+f 49/49/49 50/50/50 51/51/51
+f 52/52/52 53/53/53 54/54/54
+f 55/55/55 56/56/56 57/57/57
+f 58/58/58 59/59/59 60/60/60
+f 61/61/61 62/62/62 63/63/63
+f 64/64/64 65/65/65 66/66/66
+f 67/67/67 68/68/68 69/69/69
+f 70/70/70 71/71/71 72/72/72
+f 73/73/73 74/74/74 75/75/75
+f 76/76/76 77/77/77 78/78/78
+f 79/79/79 80/80/80 81/81/81
+f 82/82/82 83/83/83 84/84/84
+f 85/85/85 86/86/86 87/87/87
+f 88/88/88 89/89/89 90/90/90
+f 91/91/91 92/92/92 93/93/93
+f 94/94/94 95/95/95 96/96/96
+f 97/97/97 98/98/98 99/99/99
+f 100/100/100 101/101/101 102/102/102
+f 103/103/103 104/104/104 105/105/105
+f 106/106/106 107/107/107 108/108/108
+f 109/109/109 110/110/110 111/111/111
+f 112/112/112 113/113/113 114/114/114
+f 115/115/115 116/116/116 117/117/117
+f 118/118/118 119/119/119 120/120/120
+f 121/121/121 122/122/122 123/123/123
+f 124/124/124 125/125/125 126/126/126
+f 127/127/127 128/128/128 129/129/129
+f 130/130/130 131/131/131 132/132/132
+f 133/133/133 134/134/134 135/135/135
+f 136/136/136 137/137/137 138/138/138
+f 139/139/139 140/140/140 141/141/141
+f 142/142/142 143/143/143 144/144/144
+f 145/145/145 146/146/146 147/147/147
+f 148/148/148 149/149/149 150/150/150
+f 151/151/151 152/152/152 153/153/153
+f 154/154/154 155/155/155 156/156/156
+f 157/157/157 158/158/158 159/159/159
+f 160/160/160 161/161/161 162/162/162
+f 163/163/163 164/164/164 165/165/165
+f 166/166/166 167/167/167 168/168/168
+f 169/169/169 170/170/170 171/171/171
+f 172/172/172 173/173/173 174/174/174
+f 175/175/175 176/176/176 177/177/177
+f 178/178/178 179/179/179 180/180/180
+f 181/181/181 182/182/182 183/183/183
+f 184/184/184 185/185/185 186/186/186
+f 187/187/187 188/188/188 189/189/189
+f 190/190/190 191/191/191 192/192/192
+f 193/193/193 194/194/194 195/195/195
+f 196/196/196 197/197/197 198/198/198
+f 199/199/199 200/200/200 201/201/201
+f 202/202/202 203/203/203 204/204/204
+f 205/205/205 206/206/206 207/207/207
+f 208/208/208 209/209/209 210/210/210
+f 211/211/211 212/212/212 213/213/213
+f 214/214/214 215/215/215 216/216/216
diff --git a/apps/openmb/resources/models/rocks/SM_Rocks_03.obj b/apps/openmb/resources/models/rocks/SM_Rocks_03.obj
new file mode 100644
index 0000000..0ccf8fb
--- /dev/null
+++ b/apps/openmb/resources/models/rocks/SM_Rocks_03.obj
@@ -0,0 +1,1013 @@
+mtllib SM_Rocks_03.mtl
+o SM_Rock_03
+usemtl SM_Rock_01
+v 24.102996826171875 2.109623432159424 -20.2135066986084 1 1 1
+v 25.17680549621582 20.669584274291992 -20.675390243530273 1 1 1
+v 27.105754852294922 21.046741485595703 0.8125303983688354 1 1 1
+v 24.102996826171875 2.109623432159424 -20.2135066986084 1 1 1
+v 27.105754852294922 21.046741485595703 0.8125303983688354 1 1 1
+v 27.063522338867188 2.102771282196045 0.8984864950180054 1 1 1
+v 25.17680549621582 20.669584274291992 -20.675390243530273 1 1 1
+v 25.3117618560791 45.796504974365234 -18.276704788208008 1 1 1
+v 26.901775360107422 46.14866256713867 1.0090612173080444 1 1 1
+v 25.17680549621582 20.669584274291992 -20.675390243530273 1 1 1
+v 26.901775360107422 46.14866256713867 1.0090612173080444 1 1 1
+v 27.105754852294922 21.046741485595703 0.8125303983688354 1 1 1
+v 27.105754852294922 21.046741485595703 0.8125303983688354 1 1 1
+v 26.901775360107422 46.14866256713867 1.0090612173080444 1 1 1
+v 21.960323333740234 44.71691131591797 17.9605712890625 1 1 1
+v 27.105754852294922 21.046741485595703 0.8125303983688354 1 1 1
+v 21.960323333740234 44.71691131591797 17.9605712890625 1 1 1
+v 22.81016731262207 20.644498825073242 21.59063720703125 1 1 1
+v 27.063522338867188 2.102771282196045 0.8984864950180054 1 1 1
+v 27.105754852294922 21.046741485595703 0.8125303983688354 1 1 1
+v 22.81016731262207 20.644498825073242 21.59063720703125 1 1 1
+v 27.063522338867188 2.102771282196045 0.8984864950180054 1 1 1
+v 22.81016731262207 20.644498825073242 21.59063720703125 1 1 1
+v 23.010488510131836 2.108046770095825 24.250598907470703 1 1 1
+v 23.010488510131836 2.108046770095825 24.250598907470703 1 1 1
+v 22.81016731262207 20.644498825073242 21.59063720703125 1 1 1
+v -0.5384087562561035 20.94900131225586 24.9691104888916 1 1 1
+v 23.010488510131836 2.108046770095825 24.250598907470703 1 1 1
+v -0.5384087562561035 20.94900131225586 24.9691104888916 1 1 1
+v -2.554523468017578 2.1057519912719727 25.57318878173828 1 1 1
+v 22.81016731262207 20.644498825073242 21.59063720703125 1 1 1
+v 21.960323333740234 44.71691131591797 17.9605712890625 1 1 1
+v 1.6479790210723877 46.197532653808594 22.29827880859375 1 1 1
+v 22.81016731262207 20.644498825073242 21.59063720703125 1 1 1
+v 1.6479790210723877 46.197532653808594 22.29827880859375 1 1 1
+v -0.5384087562561035 20.94900131225586 24.9691104888916 1 1 1
+v -26.291093826293945 20.63870620727539 19.6416072845459 1 1 1
+v -20.376386642456055 44.54086685180664 16.565536499023438 1 1 1
+v -21.786752700805664 45.70438766479492 0.9341658353805542 1 1 1
+v -26.291093826293945 20.63870620727539 19.6416072845459 1 1 1
+v -21.786752700805664 45.70438766479492 0.9341658353805542 1 1 1
+v -27.537437438964844 21.083316802978516 0.9495380520820618 1 1 1
+v -28.443017959594727 2.1124043464660645 18.142826080322266 1 1 1
+v -30.438459396362305 2.104883909225464 0.9969171285629272 1 1 1
+v -28.676578521728516 -2.84039306640625 0.9735827445983887 1 1 1
+v -28.443017959594727 2.1124043464660645 18.142826080322266 1 1 1
+v -28.676578521728516 -2.84039306640625 0.9735827445983887 1 1 1
+v -26.830217361450195 -2.833434820175171 16.838520050048828 1 1 1
+v -2.554523468017578 2.1057519912719727 25.57318878173828 1 1 1
+v -0.5384087562561035 20.94900131225586 24.9691104888916 1 1 1
+v -22.602901458740234 20.613067626953125 23.21518898010254 1 1 1
+v -2.554523468017578 2.1057519912719727 25.57318878173828 1 1 1
+v -22.602901458740234 20.613067626953125 23.21518898010254 1 1 1
+v -24.64027976989746 2.1127634048461914 21.9910945892334 1 1 1
+v -21.786752700805664 45.70438766479492 0.9341658353805542 1 1 1
+v -20.376386642456055 44.54086685180664 16.565536499023438 1 1 1
+v -14.949970245361328 56.596553802490234 14.897974014282227 1 1 1
+v -21.786752700805664 45.70438766479492 0.9341658353805542 1 1 1
+v -14.949970245361328 56.596553802490234 14.897974014282227 1 1 1
+v -16.1763916015625 57.27262496948242 0.9122868776321411 1 1 1
+v -27.537437438964844 21.083316802978516 0.9495380520820618 1 1 1
+v -21.786752700805664 45.70438766479492 0.9341658353805542 1 1 1
+v -21.627721786499023 45.612953186035156 -18.927734375 1 1 1
+v -27.537437438964844 21.083316802978516 0.9495380520820618 1 1 1
+v -21.627721786499023 45.612953186035156 -18.927734375 1 1 1
+v -26.759565353393555 20.709436416625977 -21.591917037963867 1 1 1
+v -30.438459396362305 2.104883909225464 0.9969171285629272 1 1 1
+v -27.537437438964844 21.083316802978516 0.9495380520820618 1 1 1
+v -26.759565353393555 20.709436416625977 -21.591917037963867 1 1 1
+v -30.438459396362305 2.104883909225464 0.9969171285629272 1 1 1
+v -26.759565353393555 20.709436416625977 -21.591917037963867 1 1 1
+v -28.77391815185547 2.108934164047241 -22.423187255859375 1 1 1
+v -28.77391815185547 2.108934164047241 -22.423187255859375 1 1 1
+v -26.759565353393555 20.709436416625977 -21.591917037963867 1 1 1
+v -0.6570637226104736 21.0732421875 -22.99456024169922 1 1 1
+v -28.77391815185547 2.108934164047241 -22.423187255859375 1 1 1
+v -0.6570637226104736 21.0732421875 -22.99456024169922 1 1 1
+v -2.6890134811401367 2.1030220985412598 -25.525798797607422 1 1 1
+v -26.759565353393555 20.709436416625977 -21.591917037963867 1 1 1
+v -21.627721786499023 45.612953186035156 -18.927734375 1 1 1
+v 1.7398536205291748 46.03704071044922 -20.196895599365234 1 1 1
+v -26.759565353393555 20.709436416625977 -21.591917037963867 1 1 1
+v 1.7398536205291748 46.03704071044922 -20.196895599365234 1 1 1
+v -0.6570637226104736 21.0732421875 -22.99456024169922 1 1 1
+v -0.6570637226104736 21.0732421875 -22.99456024169922 1 1 1
+v 1.7398536205291748 46.03704071044922 -20.196895599365234 1 1 1
+v 25.3117618560791 45.796504974365234 -18.276704788208008 1 1 1
+v -0.6570637226104736 21.0732421875 -22.99456024169922 1 1 1
+v 25.3117618560791 45.796504974365234 -18.276704788208008 1 1 1
+v 25.17680549621582 20.669584274291992 -20.675390243530273 1 1 1
+v -2.6890134811401367 2.1030220985412598 -25.525798797607422 1 1 1
+v -0.6570637226104736 21.0732421875 -22.99456024169922 1 1 1
+v 25.17680549621582 20.669584274291992 -20.675390243530273 1 1 1
+v -2.6890134811401367 2.1030220985412598 -25.525798797607422 1 1 1
+v 25.17680549621582 20.669584274291992 -20.675390243530273 1 1 1
+v 24.102996826171875 2.109623432159424 -20.2135066986084 1 1 1
+v -21.627721786499023 45.612953186035156 -18.927734375 1 1 1
+v -21.786752700805664 45.70438766479492 0.9341658353805542 1 1 1
+v -16.1763916015625 57.27262496948242 0.9122868776321411 1 1 1
+v -21.627721786499023 45.612953186035156 -18.927734375 1 1 1
+v -16.1763916015625 57.27262496948242 0.9122868776321411 1 1 1
+v -16.09264373779297 56.52162551879883 -16.337142944335938 1 1 1
+v -11.084192276000977 56.81629180908203 18.64681625366211 1 1 1
+v 3.086501359939575 58.3183479309082 20.437314987182617 1 1 1
+v 3.7630434036254883 70.16995239257812 16.965778350830078 1 1 1
+v -11.084192276000977 56.81629180908203 18.64681625366211 1 1 1
+v 3.7630434036254883 70.16995239257812 16.965778350830078 1 1 1
+v -4.9680585861206055 67.9369125366211 17.239137649536133 1 1 1
+v -9.33358097076416 65.68399047851562 1.5693678855895996 1 1 1
+v -9.047629356384277 66.65656280517578 14.070704460144043 1 1 1
+v -4.9680585861206055 67.9369125366211 17.239137649536133 1 1 1
+v 3.7630434036254883 70.16995239257812 16.965778350830078 1 1 1
+v -9.33358097076416 65.68399047851562 1.5693678855895996 1 1 1
+v -4.9680585861206055 67.9369125366211 17.239137649536133 1 1 1
+v -9.33358097076416 65.68399047851562 1.5693678855895996 1 1 1
+v 3.7630434036254883 70.16995239257812 16.965778350830078 1 1 1
+v 4.825991630554199 69.64688873291016 0.9021260738372803 1 1 1
+v -16.09264373779297 56.52162551879883 -16.337142944335938 1 1 1
+v -16.1763916015625 57.27262496948242 0.9122868776321411 1 1 1
+v -9.33358097076416 65.68399047851562 1.5693678855895996 1 1 1
+v -16.09264373779297 56.52162551879883 -16.337142944335938 1 1 1
+v -9.33358097076416 65.68399047851562 1.5693678855895996 1 1 1
+v -9.032130241394043 64.44466400146484 -15.526206970214844 1 1 1
+v 3.7630434036254883 70.16995239257812 16.965778350830078 1 1 1
+v 14.833868026733398 63.24214172363281 11.738170623779297 1 1 1
+v 11.598214149475098 71.0783920288086 9.441937446594238 1 1 1
+v 4.825991630554199 69.64688873291016 0.9021260738372803 1 1 1
+v 21.03374671936035 69.18138885498047 1.0395972728729248 1 1 1
+v 20.918495178222656 68.42858123779297 -15.427020072937012 1 1 1
+v 4.825991630554199 69.64688873291016 0.9021260738372803 1 1 1
+v 20.918495178222656 68.42858123779297 -15.427020072937012 1 1 1
+v 5.033344268798828 68.26182556152344 -15.076560020446777 1 1 1
+v -9.33358097076416 65.68399047851562 1.5693678855895996 1 1 1
+v 4.825991630554199 69.64688873291016 0.9021260738372803 1 1 1
+v 5.033344268798828 68.26182556152344 -15.076560020446777 1 1 1
+v -9.33358097076416 65.68399047851562 1.5693678855895996 1 1 1
+v 5.033344268798828 68.26182556152344 -15.076560020446777 1 1 1
+v -9.032130241394043 64.44466400146484 -15.526206970214844 1 1 1
+v 21.960323333740234 44.71691131591797 17.9605712890625 1 1 1
+v 26.901775360107422 46.14866256713867 1.0090612173080444 1 1 1
+v 24.363643646240234 57.438236236572266 0.3839377164840698 1 1 1
+v 21.960323333740234 44.71691131591797 17.9605712890625 1 1 1
+v 24.363643646240234 57.438236236572266 0.3839377164840698 1 1 1
+v 17.606029510498047 54.68180847167969 13.835805892944336 1 1 1
+v 26.901775360107422 46.14866256713867 1.0090612173080444 1 1 1
+v 25.3117618560791 45.796504974365234 -18.276704788208008 1 1 1
+v 22.87507438659668 57.75265121459961 -17.21247673034668 1 1 1
+v 26.901775360107422 46.14866256713867 1.0090612173080444 1 1 1
+v 22.87507438659668 57.75265121459961 -17.21247673034668 1 1 1
+v 24.363643646240234 57.438236236572266 0.3839377164840698 1 1 1
+v 24.363643646240234 57.438236236572266 0.3839377164840698 1 1 1
+v 22.87507438659668 57.75265121459961 -17.21247673034668 1 1 1
+v 20.918495178222656 68.42858123779297 -15.427020072937012 1 1 1
+v 24.363643646240234 57.438236236572266 0.3839377164840698 1 1 1
+v 20.918495178222656 68.42858123779297 -15.427020072937012 1 1 1
+v 21.03374671936035 69.18138885498047 1.0395972728729248 1 1 1
+v 17.606029510498047 54.68180847167969 13.835805892944336 1 1 1
+v 24.363643646240234 57.438236236572266 0.3839377164840698 1 1 1
+v 21.03374671936035 69.18138885498047 1.0395972728729248 1 1 1
+v 17.606029510498047 54.68180847167969 13.835805892944336 1 1 1
+v 21.03374671936035 69.18138885498047 1.0395972728729248 1 1 1
+v 14.833868026733398 63.24214172363281 11.738170623779297 1 1 1
+v 25.3117618560791 45.796504974365234 -18.276704788208008 1 1 1
+v 1.7398536205291748 46.03704071044922 -20.196895599365234 1 1 1
+v 3.3124923706054688 58.01219177246094 -18.6970157623291 1 1 1
+v 25.3117618560791 45.796504974365234 -18.276704788208008 1 1 1
+v 3.3124923706054688 58.01219177246094 -18.6970157623291 1 1 1
+v 22.87507438659668 57.75265121459961 -17.21247673034668 1 1 1
+v 1.7398536205291748 46.03704071044922 -20.196895599365234 1 1 1
+v -21.627721786499023 45.612953186035156 -18.927734375 1 1 1
+v -16.09264373779297 56.52162551879883 -16.337142944335938 1 1 1
+v 1.7398536205291748 46.03704071044922 -20.196895599365234 1 1 1
+v -16.09264373779297 56.52162551879883 -16.337142944335938 1 1 1
+v 3.3124923706054688 58.01219177246094 -18.6970157623291 1 1 1
+v 3.3124923706054688 58.01219177246094 -18.6970157623291 1 1 1
+v -16.09264373779297 56.52162551879883 -16.337142944335938 1 1 1
+v -9.032130241394043 64.44466400146484 -15.526206970214844 1 1 1
+v 3.3124923706054688 58.01219177246094 -18.6970157623291 1 1 1
+v -9.032130241394043 64.44466400146484 -15.526206970214844 1 1 1
+v 5.033344268798828 68.26182556152344 -15.076560020446777 1 1 1
+v 22.87507438659668 57.75265121459961 -17.21247673034668 1 1 1
+v 3.3124923706054688 58.01219177246094 -18.6970157623291 1 1 1
+v 5.033344268798828 68.26182556152344 -15.076560020446777 1 1 1
+v 22.87507438659668 57.75265121459961 -17.21247673034668 1 1 1
+v 5.033344268798828 68.26182556152344 -15.076560020446777 1 1 1
+v 20.918495178222656 68.42858123779297 -15.427020072937012 1 1 1
+v -0.5384087562561035 20.94900131225586 24.9691104888916 1 1 1
+v 1.6479790210723877 46.197532653808594 22.29827880859375 1 1 1
+v -16.54390525817871 44.60447311401367 20.264305114746094 1 1 1
+v -0.5384087562561035 20.94900131225586 24.9691104888916 1 1 1
+v -16.54390525817871 44.60447311401367 20.264305114746094 1 1 1
+v -22.602901458740234 20.613067626953125 23.21518898010254 1 1 1
+v 1.6479790210723877 46.197532653808594 22.29827880859375 1 1 1
+v 21.960323333740234 44.71691131591797 17.9605712890625 1 1 1
+v 17.606029510498047 54.68180847167969 13.835805892944336 1 1 1
+v 1.6479790210723877 46.197532653808594 22.29827880859375 1 1 1
+v 17.606029510498047 54.68180847167969 13.835805892944336 1 1 1
+v 3.086501359939575 58.3183479309082 20.437314987182617 1 1 1
+v 3.086501359939575 58.3183479309082 20.437314987182617 1 1 1
+v 17.606029510498047 54.68180847167969 13.835805892944336 1 1 1
+v 14.833868026733398 63.24214172363281 11.738170623779297 1 1 1
+v 3.086501359939575 58.3183479309082 20.437314987182617 1 1 1
+v 14.833868026733398 63.24214172363281 11.738170623779297 1 1 1
+v 3.7630434036254883 70.16995239257812 16.965778350830078 1 1 1
+v -16.1763916015625 57.27262496948242 0.9122868776321411 1 1 1
+v -14.949970245361328 56.596553802490234 14.897974014282227 1 1 1
+v -9.047629356384277 66.65656280517578 14.070704460144043 1 1 1
+v -16.1763916015625 57.27262496948242 0.9122868776321411 1 1 1
+v -9.047629356384277 66.65656280517578 14.070704460144043 1 1 1
+v -9.33358097076416 65.68399047851562 1.5693678855895996 1 1 1
+v 4.825991630554199 69.64688873291016 0.9021260738372803 1 1 1
+v 11.598214149475098 71.0783920288086 9.441937446594238 1 1 1
+v 21.03374671936035 69.18138885498047 1.0395972728729248 1 1 1
+v 21.03374671936035 69.18138885498047 1.0395972728729248 1 1 1
+v 11.598214149475098 71.0783920288086 9.441937446594238 1 1 1
+v 14.833868026733398 63.24214172363281 11.738170623779297 1 1 1
+v 11.598214149475098 71.0783920288086 9.441937446594238 1 1 1
+v 4.825991630554199 69.64688873291016 0.9021260738372803 1 1 1
+v 3.7630434036254883 70.16995239257812 16.965778350830078 1 1 1
+v -28.77391815185547 2.108934164047241 -22.423187255859375 1 1 1
+v -2.6890134811401367 2.1030220985412598 -25.525798797607422 1 1 1
+v -2.664181709289551 -2.8421382904052734 -23.88887596130371 1 1 1
+v -28.77391815185547 2.108934164047241 -22.423187255859375 1 1 1
+v -2.664181709289551 -2.8421382904052734 -23.88887596130371 1 1 1
+v -27.116233825683594 -2.8365964889526367 -20.980478286743164 1 1 1
+v -16.54390525817871 44.60447311401367 20.264305114746094 1 1 1
+v 1.6479790210723877 46.197532653808594 22.29827880859375 1 1 1
+v 3.086501359939575 58.3183479309082 20.437314987182617 1 1 1
+v -16.54390525817871 44.60447311401367 20.264305114746094 1 1 1
+v 3.086501359939575 58.3183479309082 20.437314987182617 1 1 1
+v -11.084192276000977 56.81629180908203 18.64681625366211 1 1 1
+v -2.6890134811401367 2.1030220985412598 -25.525798797607422 1 1 1
+v 24.102996826171875 2.109623432159424 -20.2135066986084 1 1 1
+v 22.450716018676758 -2.8359503746032715 -18.909120559692383 1 1 1
+v -2.6890134811401367 2.1030220985412598 -25.525798797607422 1 1 1
+v 22.450716018676758 -2.8359503746032715 -18.909120559692383 1 1 1
+v -2.664181709289551 -2.8421382904052734 -23.88887596130371 1 1 1
+v -2.554523468017578 2.1057519912719727 25.57318878173828 1 1 1
+v -24.64027976989746 2.1127634048461914 21.9910945892334 1 1 1
+v -23.029817581176758 -2.833073854446411 20.687883377075195 1 1 1
+v -2.554523468017578 2.1057519912719727 25.57318878173828 1 1 1
+v -23.029817581176758 -2.833073854446411 20.687883377075195 1 1 1
+v -2.5381104946136475 -2.8395793437957764 24.011438369750977 1 1 1
+v 27.063522338867188 2.102771282196045 0.8984864950180054 1 1 1
+v 23.010488510131836 2.108046770095825 24.250598907470703 1 1 1
+v 21.426591873168945 -2.837428331375122 22.77164077758789 1 1 1
+v 27.063522338867188 2.102771282196045 0.8984864950180054 1 1 1
+v 21.426591873168945 -2.837428331375122 22.77164077758789 1 1 1
+v 25.225915908813477 -2.8423733711242676 0.8813136219978333 1 1 1
+v -30.438459396362305 2.104883909225464 0.9969171285629272 1 1 1
+v -28.77391815185547 2.108934164047241 -22.423187255859375 1 1 1
+v -27.116233825683594 -2.8365964889526367 -20.980478286743164 1 1 1
+v -30.438459396362305 2.104883909225464 0.9969171285629272 1 1 1
+v -27.116233825683594 -2.8365964889526367 -20.980478286743164 1 1 1
+v -28.676578521728516 -2.84039306640625 0.9735827445983887 1 1 1
+v 24.102996826171875 2.109623432159424 -20.2135066986084 1 1 1
+v 27.063522338867188 2.102771282196045 0.8984864950180054 1 1 1
+v 25.225915908813477 -2.8423733711242676 0.8813136219978333 1 1 1
+v 24.102996826171875 2.109623432159424 -20.2135066986084 1 1 1
+v 25.225915908813477 -2.8423733711242676 0.8813136219978333 1 1 1
+v 22.450716018676758 -2.8359503746032715 -18.909120559692383 1 1 1
+v 23.010488510131836 2.108046770095825 24.250598907470703 1 1 1
+v -2.554523468017578 2.1057519912719727 25.57318878173828 1 1 1
+v -2.5381104946136475 -2.8395793437957764 24.011438369750977 1 1 1
+v 23.010488510131836 2.108046770095825 24.250598907470703 1 1 1
+v -2.5381104946136475 -2.8395793437957764 24.011438369750977 1 1 1
+v 21.426591873168945 -2.837428331375122 22.77164077758789 1 1 1
+v -20.376386642456055 44.54086685180664 16.565536499023438 1 1 1
+v -26.291093826293945 20.63870620727539 19.6416072845459 1 1 1
+v -22.602901458740234 20.613067626953125 23.21518898010254 1 1 1
+v -20.376386642456055 44.54086685180664 16.565536499023438 1 1 1
+v -22.602901458740234 20.613067626953125 23.21518898010254 1 1 1
+v -16.54390525817871 44.60447311401367 20.264305114746094 1 1 1
+v -26.291093826293945 20.63870620727539 19.6416072845459 1 1 1
+v -28.443017959594727 2.1124043464660645 18.142826080322266 1 1 1
+v -24.64027976989746 2.1127634048461914 21.9910945892334 1 1 1
+v -26.291093826293945 20.63870620727539 19.6416072845459 1 1 1
+v -24.64027976989746 2.1127634048461914 21.9910945892334 1 1 1
+v -22.602901458740234 20.613067626953125 23.21518898010254 1 1 1
+v -16.54390525817871 44.60447311401367 20.264305114746094 1 1 1
+v -11.084192276000977 56.81629180908203 18.64681625366211 1 1 1
+v -14.949970245361328 56.596553802490234 14.897974014282227 1 1 1
+v -16.54390525817871 44.60447311401367 20.264305114746094 1 1 1
+v -14.949970245361328 56.596553802490234 14.897974014282227 1 1 1
+v -20.376386642456055 44.54086685180664 16.565536499023438 1 1 1
+v -11.084192276000977 56.81629180908203 18.64681625366211 1 1 1
+v -4.9680585861206055 67.9369125366211 17.239137649536133 1 1 1
+v -9.047629356384277 66.65656280517578 14.070704460144043 1 1 1
+v -11.084192276000977 56.81629180908203 18.64681625366211 1 1 1
+v -9.047629356384277 66.65656280517578 14.070704460144043 1 1 1
+v -14.949970245361328 56.596553802490234 14.897974014282227 1 1 1
+v -28.443017959594727 2.1124043464660645 18.142826080322266 1 1 1
+v -26.830217361450195 -2.833434820175171 16.838520050048828 1 1 1
+v -23.029817581176758 -2.833073854446411 20.687883377075195 1 1 1
+v -28.443017959594727 2.1124043464660645 18.142826080322266 1 1 1
+v -23.029817581176758 -2.833073854446411 20.687883377075195 1 1 1
+v -24.64027976989746 2.1127634048461914 21.9910945892334 1 1 1
+v -28.443017959594727 2.1124043464660645 18.142826080322266 1 1 1
+v -26.291093826293945 20.63870620727539 19.6416072845459 1 1 1
+v -27.537437438964844 21.083316802978516 0.9495380520820618 1 1 1
+v -28.443017959594727 2.1124043464660645 18.142826080322266 1 1 1
+v -27.537437438964844 21.083316802978516 0.9495380520820618 1 1 1
+v -30.438459396362305 2.104883909225464 0.9969171285629272 1 1 1
+vt 0.643281102180481 0.4869915246963501
+vt 0.6489467024803162 0.43546026945114136
+vt 0.7086883187294006 0.4439382553100586
+vt 0.643281102180481 0.4869915246963501
+vt 0.7086883187294006 0.4439382553100586
+vt 0.7015703320503235 0.49670857191085815
+vt 0.6489467024803162 0.43546026945114136
+vt 0.6653923988342285 0.36653459072113037
+vt 0.7190513610839844 0.37406110763549805
+vt 0.6489467024803162 0.43546026945114136
+vt 0.7190513610839844 0.37406110763549805
+vt 0.7086883187294006 0.4439382553100586
+vt 0.7086883187294006 0.4439382553100586
+vt 0.7190513610839844 0.37406110763549805
+vt 0.7670877575874329 0.38352280855178833
+vt 0.7086883187294006 0.4439382553100586
+vt 0.7670877575874329 0.38352280855178833
+vt 0.7676640152931213 0.452325701713562
+vt 0.7015703320503235 0.49670857191085815
+vt 0.7086883187294006 0.4439382553100586
+vt 0.7676640152931213 0.452325701713562
+vt 0.7015703320503235 0.49670857191085815
+vt 0.7676640152931213 0.452325701713562
+vt 0.7678405046463013 0.5051062703132629
+vt 0.6432810425758362 0.7227435111999512
+vt 0.6436856985092163 0.6699236631393433
+vt 0.7098723649978638 0.6693590879440308
+vt 0.6432810425758362 0.7227435111999512
+vt 0.7098723649978638 0.6693590879440308
+vt 0.7157201766967773 0.7227434515953064
+vt 0.6436856985092163 0.6699236631393433
+vt 0.6458792686462402 0.601300060749054
+vt 0.7034701108932495 0.5975643992424011
+vt 0.6436856985092163 0.6699236631393433
+vt 0.7034701108932495 0.5975643992424011
+vt 0.7098723649978638 0.6693590879440308
+vt 0.690540075302124 0.1479201316833496
+vt 0.700365424156189 0.07832419872283936
+vt 0.7447772026062012 0.0767446756362915
+vt 0.690540075302124 0.1479201316833496
+vt 0.7447772026062012 0.0767446756362915
+vt 0.7435660362243652 0.1483595371246338
+vt 0.6937839984893799 0.20047730207443237
+vt 0.7424463033676147 0.20257443189620972
+vt 0.7421149611473083 0.21508288383483887
+vt 0.6937839984893799 0.20047730207443237
+vt 0.7421149611473083 0.21508288383483887
+vt 0.6970882415771484 0.21314239501953125
+vt 0.7157201766967773 0.7227434515953064
+vt 0.7098723649978638 0.6693590879440308
+vt 0.7723549604415894 0.6698998212814331
+vt 0.7157201766967773 0.7227434515953064
+vt 0.7723549604415894 0.6698998212814331
+vt 0.7782354354858398 0.7220585346221924
+vt 0.7447772026062012 0.0767446756362915
+vt 0.700365424156189 0.07832419872283936
+vt 0.7055132985115051 0.04165482521057129
+vt 0.7447772026062012 0.0767446756362915
+vt 0.7055132985115051 0.04165482521057129
+vt 0.7452253103256226 0.04122549295425415
+vt 0.7435660362243652 0.1483595371246338
+vt 0.7447772026062012 0.0767446756362915
+vt 0.8010048866271973 0.07781237363815308
+vt 0.7435660362243652 0.1483595371246338
+vt 0.8010048866271973 0.07781237363815308
+vt 0.8073296546936035 0.14993196725845337
+vt 0.7424463033676147 0.20257443189620972
+vt 0.7435660362243652 0.1483595371246338
+vt 0.8073296546936035 0.14993196725845337
+vt 0.7424463033676147 0.20257443189620972
+vt 0.8073296546936035 0.14993196725845337
+vt 0.8086712956428528 0.20257443189620972
+vt 0.20989134907722473 0.7926543354988098
+vt 0.21520638465881348 0.7398747801780701
+vt 0.28910690546035767 0.7385429739952087
+vt 0.20989134907722473 0.7926543354988098
+vt 0.28910690546035767 0.7385429739952087
+vt 0.2837119996547699 0.792654275894165
+vt 0.21520638465881348 0.7398747801780701
+vt 0.2292546033859253 0.6688989996910095
+vt 0.29540959000587463 0.6674306988716125
+vt 0.21520638465881348 0.7398747801780701
+vt 0.29540959000587463 0.6674306988716125
+vt 0.28910690546035767 0.7385429739952087
+vt 0.28910690546035767 0.7385429739952087
+vt 0.29540959000587463 0.6674306988716125
+vt 0.3622296154499054 0.6673010587692261
+vt 0.28910690546035767 0.7385429739952087
+vt 0.3622296154499054 0.6673010587692261
+vt 0.3623468279838562 0.7387607097625732
+vt 0.2837119996547699 0.792654275894165
+vt 0.28910690546035767 0.7385429739952087
+vt 0.3623468279838562 0.7387607097625732
+vt 0.2837119996547699 0.792654275894165
+vt 0.3623468279838562 0.7387607097625732
+vt 0.3597241938114166 0.791188657283783
+vt 0.8010048866271973 0.07781237363815308
+vt 0.7447772026062012 0.0767446756362915
+vt 0.7452253103256226 0.04122549295425415
+vt 0.8010048866271973 0.07781237363815308
+vt 0.7452253103256226 0.04122549295425415
+vt 0.7940196990966797 0.0440402626991272
+vt 0.7394152283668518 0.5669148564338684
+vt 0.6992868781089783 0.5630207657814026
+vt 0.6972417831420898 0.5290083289146423
+vt 0.7394152283668518 0.5669148564338684
+vt 0.6972417831420898 0.5290083289146423
+vt 0.7219942808151245 0.5352993607521057
+vt 0.7934572696685791 0.9376599788665771
+vt 0.7947403192520142 0.902155876159668
+vt 0.8067024350166321 0.8930720090866089
+vt 0.832048237323761 0.8936619162559509
+vt 0.7934572696685791 0.9376599788665771
+vt 0.8067024350166321 0.8930720090866089
+vt 0.7934572696685791 0.9376599788665771
+vt 0.832048237323761 0.8936619162559509
+vt 0.8346858620643616 0.9391646981239319
+vt 0.7940196990966797 0.0440402626991272
+vt 0.7452253103256226 0.04122549295425415
+vt 0.7434911131858826 0.013589799404144287
+vt 0.7940196990966797 0.0440402626991272
+vt 0.7434911131858826 0.013589799404144287
+vt 0.7918081283569336 0.017604410648345947
+vt 0.6972417831420898 0.5290083289146423
+vt 0.6658551692962646 0.5479629039764404
+vt 0.6749361157417297 0.525446355342865
+vt 0.8346858620643616 0.9391646981239319
+vt 0.8800348043441772 0.939571738243103
+vt 0.8792744874954224 0.9862185716629028
+vt 0.8346858620643616 0.9391646981239319
+vt 0.8792744874954224 0.9862185716629028
+vt 0.8346021771430969 0.9846034049987793
+vt 0.7934572696685791 0.9376599788665771
+vt 0.8346858620643616 0.9391646981239319
+vt 0.8346021771430969 0.9846034049987793
+vt 0.7934572696685791 0.9376599788665771
+vt 0.8346021771430969 0.9846034049987793
+vt 0.7936810851097107 0.9862185716629028
+vt 0.7670877575874329 0.38352280855178833
+vt 0.7190513610839844 0.37406110763549805
+vt 0.7223155498504639 0.34156501293182373
+vt 0.7670877575874329 0.38352280855178833
+vt 0.7223155498504639 0.34156501293182373
+vt 0.7604978680610657 0.35268890857696533
+vt 0.7190513610839844 0.37406110763549805
+vt 0.6653923988342285 0.36653459072113037
+vt 0.673613429069519 0.33291566371917725
+vt 0.7190513610839844 0.37406110763549805
+vt 0.673613429069519 0.33291566371917725
+vt 0.7223155498504639 0.34156501293182373
+vt 0.7223155498504639 0.34156501293182373
+vt 0.673613429069519 0.33291566371917725
+vt 0.683235228061676 0.30331242084503174
+vt 0.7223155498504639 0.34156501293182373
+vt 0.683235228061676 0.30331242084503174
+vt 0.7295299172401428 0.30808746814727783
+vt 0.7604978680610657 0.35268890857696533
+vt 0.7223155498504639 0.34156501293182373
+vt 0.7295299172401428 0.30808746814727783
+vt 0.7604978680610657 0.35268890857696533
+vt 0.7295299172401428 0.30808746814727783
+vt 0.7586414813995361 0.3271070122718811
+vt 0.3622296154499054 0.6673010587692261
+vt 0.29540959000587463 0.6674306988716125
+vt 0.29963430762290955 0.6332828402519226
+vt 0.3622296154499054 0.6673010587692261
+vt 0.29963430762290955 0.6332828402519226
+vt 0.35508784651756287 0.6333630681037903
+vt 0.29540959000587463 0.6674306988716125
+vt 0.2292546033859253 0.6688989996910095
+vt 0.24475157260894775 0.63750159740448
+vt 0.29540959000587463 0.6674306988716125
+vt 0.24475157260894775 0.63750159740448
+vt 0.29963430762290955 0.6332828402519226
+vt 0.29963430762290955 0.6332828402519226
+vt 0.24475157260894775 0.63750159740448
+vt 0.2645954489707947 0.6148147583007812
+vt 0.29963430762290955 0.6332828402519226
+vt 0.2645954489707947 0.6148147583007812
+vt 0.3043644428253174 0.6036545634269714
+vt 0.35508784651756287 0.6333630681037903
+vt 0.29963430762290955 0.6332828402519226
+vt 0.3043644428253174 0.6036545634269714
+vt 0.35508784651756287 0.6333630681037903
+vt 0.3043644428253174 0.6036545634269714
+vt 0.3493504226207733 0.6029139161109924
+vt 0.7098723649978638 0.6693590879440308
+vt 0.7034701108932495 0.5975643992424011
+vt 0.7549870014190674 0.6016519069671631
+vt 0.7098723649978638 0.6693590879440308
+vt 0.7549870014190674 0.6016519069671631
+vt 0.7723549604415894 0.6698998212814331
+vt 0.7034701108932495 0.5975643992424011
+vt 0.6458792686462402 0.601300060749054
+vt 0.6580893397331238 0.5724970698356628
+vt 0.7034701108932495 0.5975643992424011
+vt 0.6580893397331238 0.5724970698356628
+vt 0.6992868781089783 0.5630207657814026
+vt 0.6992868781089783 0.5630207657814026
+vt 0.6580893397331238 0.5724970698356628
+vt 0.6658551692962646 0.5479629039764404
+vt 0.6992868781089783 0.5630207657814026
+vt 0.6658551692962646 0.5479629039764404
+vt 0.6972417831420898 0.5290083289146423
+vt 0.7452253103256226 0.04122549295425415
+vt 0.7055132985115051 0.04165482521057129
+vt 0.7081344723701477 0.010145306587219238
+vt 0.7452253103256226 0.04122549295425415
+vt 0.7081344723701477 0.010145306587219238
+vt 0.7434911131858826 0.013589799404144287
+vt 0.8346858620643616 0.9391646981239319
+vt 0.8543177843093872 0.9149993658065796
+vt 0.8800348043441772 0.939571738243103
+vt 0.7295299172401428 0.30808746814727783
+vt 0.7560615539550781 0.30331242084503174
+vt 0.7586414813995361 0.3271070122718811
+vt 0.8543177843093872 0.9149993658065796
+vt 0.8346858620643616 0.9391646981239319
+vt 0.832048237323761 0.8936619162559509
+vt 0.20989134907722473 0.7926543354988098
+vt 0.2837119996547699 0.792654275894165
+vt 0.2839279770851135 0.8063622117042542
+vt 0.20989134907722473 0.7926543354988098
+vt 0.2839279770851135 0.8063622117042542
+vt 0.21472831070423126 0.8063622117042542
+vt 0.7549870014190674 0.6016519069671631
+vt 0.7034701108932495 0.5975643992424011
+vt 0.6992868781089783 0.5630207657814026
+vt 0.7549870014190674 0.6016519069671631
+vt 0.6992868781089783 0.5630207657814026
+vt 0.7394152283668518 0.5669148564338684
+vt 0.2837119996547699 0.792654275894165
+vt 0.3597241938114166 0.791188657283783
+vt 0.3551819622516632 0.8049882650375366
+vt 0.2837119996547699 0.792654275894165
+vt 0.3551819622516632 0.8049882650375366
+vt 0.2839279770851135 0.8063622117042542
+vt 0.7157201766967773 0.7227434515953064
+vt 0.7782354354858398 0.7220585346221924
+vt 0.7736889719963074 0.7358824014663696
+vt 0.7157201766967773 0.7227434515953064
+vt 0.7736889719963074 0.7358824014663696
+vt 0.7156857848167419 0.7365179061889648
+vt 0.7015703320503235 0.49670857191085815
+vt 0.7678405046463013 0.5051062703132629
+vt 0.7621698379516602 0.5177623629570007
+vt 0.7015703320503235 0.49670857191085815
+vt 0.7621698379516602 0.5177623629570007
+vt 0.7000479698181152 0.5098903775215149
+vt 0.7424463033676147 0.20257443189620972
+vt 0.8086712956428528 0.20257443189620972
+vt 0.8041943907737732 0.21508288383483887
+vt 0.7424463033676147 0.20257443189620972
+vt 0.8041943907737732 0.21508288383483887
+vt 0.7421149611473083 0.21508288383483887
+vt 0.643281102180481 0.4869915246963501
+vt 0.7015703320503235 0.49670857191085815
+vt 0.7000479698181152 0.5098903775215149
+vt 0.643281102180481 0.4869915246963501
+vt 0.7000479698181152 0.5098903775215149
+vt 0.645407497882843 0.5007815361022949
+vt 0.6432810425758362 0.7227435111999512
+vt 0.7157201766967773 0.7227434515953064
+vt 0.7156857848167419 0.7365179061889648
+vt 0.6432810425758362 0.7227435111999512
+vt 0.7156857848167419 0.7365179061889648
+vt 0.6477811932563782 0.7365179657936096
+vt 0.700365424156189 0.07832419872283936
+vt 0.690540075302124 0.1479201316833496
+vt 0.6802133321762085 0.1454523801803589
+vt 0.700365424156189 0.07832419872283936
+vt 0.6802133321762085 0.1454523801803589
+vt 0.6896815896034241 0.075511634349823
+vt 0.690540075302124 0.1479201316833496
+vt 0.6937839984893799 0.20047730207443237
+vt 0.6826746463775635 0.19785141944885254
+vt 0.690540075302124 0.1479201316833496
+vt 0.6826746463775635 0.19785141944885254
+vt 0.6802133321762085 0.1454523801803589
+vt 0.6896815896034241 0.075511634349823
+vt 0.694695234298706 0.03838789463043213
+vt 0.7055132985115051 0.04165482521057129
+vt 0.6896815896034241 0.075511634349823
+vt 0.7055132985115051 0.04165482521057129
+vt 0.700365424156189 0.07832419872283936
+vt 0.694695234298706 0.03838789463043213
+vt 0.6990121603012085 0.003841996192932129
+vt 0.7081344723701477 0.010145306587219238
+vt 0.694695234298706 0.03838789463043213
+vt 0.7081344723701477 0.010145306587219238
+vt 0.7055132985115051 0.04165482521057129
+vt 0.7889547348022461 0.7214939594268799
+vt 0.7844015955924988 0.7353177070617676
+vt 0.7736889719963074 0.7358824014663696
+vt 0.7889547348022461 0.7214939594268799
+vt 0.7736889719963074 0.7358824014663696
+vt 0.7782354354858398 0.7220585346221924
+vt 0.6937839984893799 0.20047730207443237
+vt 0.690540075302124 0.1479201316833496
+vt 0.7435660362243652 0.1483595371246338
+vt 0.6937839984893799 0.20047730207443237
+vt 0.7435660362243652 0.1483595371246338
+vt 0.7424463033676147 0.20257443189620972
+vn 0.7097417492795982 -0.1829898151808711 -0.6802803663708125
+vn 0.7058310449119094 0.03760175747706376 -0.7073815405233574
+vn 0.9983612816873655 0.0076505280432351665 0.056711732897354136
+vn 0.7097417492795982 -0.1829898151808711 -0.6802803663708125
+vn 0.9983612816873655 0.0076505280432351665 0.056711732897354136
+vn 0.9837901350634028 -0.17733885327973467 0.02660641406428711
+vn 0.7058310449119094 0.03760175747706376 -0.7073815405233574
+vn 0.7208662084698857 0.13378547227812645 -0.6800392318782572
+vn 0.9792895558713576 0.16276540263773298 0.1204134106545272
+vn 0.7058310449119094 0.03760175747706376 -0.7073815405233574
+vn 0.9792895558713576 0.16276540263773298 0.1204134106545272
+vn 0.9983612816873655 0.0076505280432351665 0.056711732897354136
+vn 0.9983612816873655 0.0076505280432351665 0.056711732897354136
+vn 0.9792895558713576 0.16276540263773298 0.1204134106545272
+vn 0.6810698852418977 0.2080724013091918 0.7020325400079507
+vn 0.9983612816873655 0.0076505280432351665 0.056711732897354136
+vn 0.6810698852418977 0.2080724013091918 0.7020325400079507
+vn 0.6814371370208067 0.07766392852997338 0.727744283724838
+vn 0.9837901350634028 -0.17733885327973467 0.02660641406428711
+vn 0.9983612816873655 0.0076505280432351665 0.056711732897354136
+vn 0.6814371370208067 0.07766392852997338 0.727744283724838
+vn 0.9837901350634028 -0.17733885327973467 0.02660641406428711
+vn 0.6814371370208067 0.07766392852997338 0.727744283724838
+vn 0.6517133562709272 -0.15851294629372636 0.741716487018703
+vn 0.6517133562709272 -0.15851294629372636 0.741716487018703
+vn 0.6814371370208067 0.07766392852997338 0.727744283724838
+vn 0.01358643573754679 0.08449273145537824 0.9963314644711161
+vn 0.6517133562709272 -0.15851294629372636 0.741716487018703
+vn 0.01358643573754679 0.08449273145537824 0.9963314644711161
+vn -0.03567480384470595 -0.13271598951652872 0.9905118749905476
+vn 0.6814371370208067 0.07766392852997338 0.727744283724838
+vn 0.6810698852418977 0.2080724013091918 0.7020325400079507
+vn 0.06512300008157354 0.1817122960150499 0.9811929659028922
+vn 0.6814371370208067 0.07766392852997338 0.727744283724838
+vn 0.06512300008157354 0.1817122960150499 0.9811929659028922
+vn 0.01358643573754679 0.08449273145537824 0.9963314644711161
+vn -0.8841383452573867 0.16795282414964627 0.4359945358667791
+vn -0.8511331717889251 0.3364868776101403 0.4029254336433759
+vn -0.941227499687925 0.3355829134006586 0.03840445370973725
+vn -0.8841383452573867 0.16795282414964627 0.4359945358667791
+vn -0.941227499687925 0.3355829134006586 0.03840445370973725
+vn -0.9834605097559777 0.17940530615475422 0.024882963529921857
+vn -0.8961485599960235 -0.14356160124866077 0.41989025359488164
+vn -0.9943567713149957 -0.10411073596521707 0.020385435899152794
+vn -0.9417535786574657 -0.33562446938233104 0.021363816084343658
+vn -0.8961485599960235 -0.14356160124866077 0.41989025359488164
+vn -0.9417535786574657 -0.33562446938233104 0.021363816084343658
+vn -0.8435083940194295 -0.3760793114928615 0.3834813433347417
+vn -0.03567480384470595 -0.13271598951652872 0.9905118749905476
+vn 0.01358643573754679 0.08449273145537824 0.9963314644711161
+vn -0.42850222208687605 0.10894018151150854 0.8969492084387215
+vn -0.03567480384470595 -0.13271598951652872 0.9905118749905476
+vn -0.42850222208687605 0.10894018151150854 0.8969492084387215
+vn -0.4633038123683755 -0.17104412199178726 0.8695363625386737
+vn -0.941227499687925 0.3355829134006586 0.03840445370973725
+vn -0.8511331717889251 0.3364868776101403 0.4029254336433759
+vn -0.7980895498222257 0.4722984052156664 0.3741487496909424
+vn -0.941227499687925 0.3355829134006586 0.03840445370973725
+vn -0.7980895498222257 0.4722984052156664 0.3741487496909424
+vn -0.8486909055579567 0.5285002455522558 0.020278986030386838
+vn -0.9834605097559777 0.17940530615475422 0.024882963529921857
+vn -0.941227499687925 0.3355829134006586 0.03840445370973725
+vn -0.6872191260632746 0.3152074438531002 -0.6545029718132863
+vn -0.9834605097559777 0.17940530615475422 0.024882963529921857
+vn -0.6872191260632746 0.3152074438531002 -0.6545029718132863
+vn -0.7065522299265036 0.18490274838189358 -0.6830775358820604
+vn -0.9943567713149957 -0.10411073596521707 0.020385435899152794
+vn -0.9834605097559777 0.17940530615475422 0.024882963529921857
+vn -0.7065522299265036 0.18490274838189358 -0.6830775358820604
+vn -0.9943567713149957 -0.10411073596521707 0.020385435899152794
+vn -0.7065522299265036 0.18490274838189358 -0.6830775358820604
+vn -0.7239451931682047 -0.1200571718668144 -0.6793302825371418
+vn -0.7239451931682047 -0.1200571718668144 -0.6793302825371418
+vn -0.7065522299265036 0.18490274838189358 -0.6830775358820604
+vn 0.023936930166870388 0.08888390334636201 -0.9957543246705489
+vn -0.7239451931682047 -0.1200571718668144 -0.6793302825371418
+vn 0.023936930166870388 0.08888390334636201 -0.9957543246705489
+vn 0.02842898504555128 -0.12066283133185045 -0.9922863870598353
+vn -0.7065522299265036 0.18490274838189358 -0.6830775358820604
+vn -0.6872191260632746 0.3152074438531002 -0.6545029718132863
+vn 0.0032124219887417317 0.13418687279576144 -0.9909508380915071
+vn -0.7065522299265036 0.18490274838189358 -0.6830775358820604
+vn 0.0032124219887417317 0.13418687279576144 -0.9909508380915071
+vn 0.023936930166870388 0.08888390334636201 -0.9957543246705489
+vn 0.023936930166870388 0.08888390334636201 -0.9957543246705489
+vn 0.0032124219887417317 0.13418687279576144 -0.9909508380915071
+vn 0.7208662084698857 0.13378547227812645 -0.6800392318782572
+vn 0.023936930166870388 0.08888390334636201 -0.9957543246705489
+vn 0.7208662084698857 0.13378547227812645 -0.6800392318782572
+vn 0.7058310449119094 0.03760175747706376 -0.7073815405233574
+vn 0.02842898504555128 -0.12066283133185045 -0.9922863870598353
+vn 0.023936930166870388 0.08888390334636201 -0.9957543246705489
+vn 0.7058310449119094 0.03760175747706376 -0.7073815405233574
+vn 0.02842898504555128 -0.12066283133185045 -0.9922863870598353
+vn 0.7058310449119094 0.03760175747706376 -0.7073815405233574
+vn 0.7097417492795982 -0.1829898151808711 -0.6802803663708125
+vn -0.6872191260632746 0.3152074438531002 -0.6545029718132863
+vn -0.941227499687925 0.3355829134006586 0.03840445370973725
+vn -0.8486909055579567 0.5285002455522558 0.020278986030386838
+vn -0.6872191260632746 0.3152074438531002 -0.6545029718132863
+vn -0.8486909055579567 0.5285002455522558 0.020278986030386838
+vn -0.6260926457987154 0.5006357815164799 -0.5978058323085746
+vn -0.41113035063210696 0.32260129775719243 0.8525844459491952
+vn 0.15822398156616502 0.25602244512131117 0.9536339335675167
+vn 0.08027150295075214 0.7838061734035136 0.6157957196575569
+vn -0.41113035063210696 0.32260129775719243 0.8525844459491952
+vn 0.08027150295075214 0.7838061734035136 0.6157957196575569
+vn -0.33381177749086666 0.7293253273127284 0.5972053785328543
+vn -0.5614847532242626 0.8267078105428459 -0.035903591521501535
+vn -0.6124933152538132 0.7508812289933203 0.24704112757772534
+vn -0.33381177749086666 0.7293253273127284 0.5972053785328543
+vn 0.08027150295075214 0.7838061734035136 0.6157957196575569
+vn -0.5614847532242626 0.8267078105428459 -0.035903591521501535
+vn -0.33381177749086666 0.7293253273127284 0.5972053785328543
+vn -0.5614847532242626 0.8267078105428459 -0.035903591521501535
+vn 0.08027150295075214 0.7838061734035136 0.6157957196575569
+vn -0.14215544931887256 0.9863233867876754 -0.08341465641384077
+vn -0.6260926457987154 0.5006357815164799 -0.5978058323085746
+vn -0.8486909055579567 0.5285002455522558 0.020278986030386838
+vn -0.5614847532242626 0.8267078105428459 -0.035903591521501535
+vn -0.6260926457987154 0.5006357815164799 -0.5978058323085746
+vn -0.5614847532242626 0.8267078105428459 -0.035903591521501535
+vn -0.4177276093459393 0.7081685491662232 -0.5692108136375598
+vn 0.08027150295075214 0.7838061734035136 0.6157957196575569
+vn 0.6469167811389347 0.3375269637269374 0.6837939945905598
+vn 0.322318590237706 0.8933716366834041 0.3130460751339866
+vn -0.14215544931887256 0.9863233867876754 -0.08341465641384077
+vn 0.6570188351403856 0.7325003685503467 0.1782398954902558
+vn 0.5071302661966973 0.679713190889666 -0.5299140224959663
+vn -0.14215544931887256 0.9863233867876754 -0.08341465641384077
+vn 0.5071302661966973 0.679713190889666 -0.5299140224959663
+vn -0.09548820079878363 0.7884330972221066 -0.6076637678132272
+vn -0.5614847532242626 0.8267078105428459 -0.035903591521501535
+vn -0.14215544931887256 0.9863233867876754 -0.08341465641384077
+vn -0.09548820079878363 0.7884330972221066 -0.6076637678132272
+vn -0.5614847532242626 0.8267078105428459 -0.035903591521501535
+vn -0.09548820079878363 0.7884330972221066 -0.6076637678132272
+vn -0.4177276093459393 0.7081685491662232 -0.5692108136375598
+vn 0.6810698852418977 0.2080724013091918 0.7020325400079507
+vn 0.9792895558713576 0.16276540263773298 0.1204134106545272
+vn 0.9402272936450381 0.2795676006462085 0.194459746358595
+vn 0.6810698852418977 0.2080724013091918 0.7020325400079507
+vn 0.9402272936450381 0.2795676006462085 0.194459746358595
+vn 0.6470120134562971 0.32214550099601613 0.6910844598392111
+vn 0.9792895558713576 0.16276540263773298 0.1204134106545272
+vn 0.7208662084698857 0.13378547227812645 -0.6800392318782572
+vn 0.6678655760015628 0.25752237502456715 -0.6983106749533525
+vn 0.9792895558713576 0.16276540263773298 0.1204134106545272
+vn 0.6678655760015628 0.25752237502456715 -0.6983106749533525
+vn 0.9402272936450381 0.2795676006462085 0.194459746358595
+vn 0.9402272936450381 0.2795676006462085 0.194459746358595
+vn 0.6678655760015628 0.25752237502456715 -0.6983106749533525
+vn 0.5071302661966973 0.679713190889666 -0.5299140224959663
+vn 0.9402272936450381 0.2795676006462085 0.194459746358595
+vn 0.5071302661966973 0.679713190889666 -0.5299140224959663
+vn 0.6570188351403856 0.7325003685503467 0.1782398954902558
+vn 0.6470120134562971 0.32214550099601613 0.6910844598392111
+vn 0.9402272936450381 0.2795676006462085 0.194459746358595
+vn 0.6570188351403856 0.7325003685503467 0.1782398954902558
+vn 0.6470120134562971 0.32214550099601613 0.6910844598392111
+vn 0.6570188351403856 0.7325003685503467 0.1782398954902558
+vn 0.6469167811389347 0.3375269637269374 0.6837939945905598
+vn 0.7208662084698857 0.13378547227812645 -0.6800392318782572
+vn 0.0032124219887417317 0.13418687279576144 -0.9909508380915071
+vn -0.01962378074917468 0.2110693118951234 -0.9772740929776189
+vn 0.7208662084698857 0.13378547227812645 -0.6800392318782572
+vn -0.01962378074917468 0.2110693118951234 -0.9772740929776189
+vn 0.6678655760015628 0.25752237502456715 -0.6983106749533525
+vn 0.0032124219887417317 0.13418687279576144 -0.9909508380915071
+vn -0.6872191260632746 0.3152074438531002 -0.6545029718132863
+vn -0.6260926457987154 0.5006357815164799 -0.5978058323085746
+vn 0.0032124219887417317 0.13418687279576144 -0.9909508380915071
+vn -0.6260926457987154 0.5006357815164799 -0.5978058323085746
+vn -0.01962378074917468 0.2110693118951234 -0.9772740929776189
+vn -0.01962378074917468 0.2110693118951234 -0.9772740929776189
+vn -0.6260926457987154 0.5006357815164799 -0.5978058323085746
+vn -0.4177276093459393 0.7081685491662232 -0.5692108136375598
+vn -0.01962378074917468 0.2110693118951234 -0.9772740929776189
+vn -0.4177276093459393 0.7081685491662232 -0.5692108136375598
+vn -0.09548820079878363 0.7884330972221066 -0.6076637678132272
+vn 0.6678655760015628 0.25752237502456715 -0.6983106749533525
+vn -0.01962378074917468 0.2110693118951234 -0.9772740929776189
+vn -0.09548820079878363 0.7884330972221066 -0.6076637678132272
+vn 0.6678655760015628 0.25752237502456715 -0.6983106749533525
+vn -0.09548820079878363 0.7884330972221066 -0.6076637678132272
+vn 0.5071302661966973 0.679713190889666 -0.5299140224959663
+vn 0.01358643573754679 0.08449273145537824 0.9963314644711161
+vn 0.06512300008157354 0.1817122960150499 0.9811929659028922
+vn -0.422079644008911 0.2538695700822324 0.8702867432631464
+vn 0.01358643573754679 0.08449273145537824 0.9963314644711161
+vn -0.422079644008911 0.2538695700822324 0.8702867432631464
+vn -0.42850222208687605 0.10894018151150854 0.8969492084387215
+vn 0.06512300008157354 0.1817122960150499 0.9811929659028922
+vn 0.6810698852418977 0.2080724013091918 0.7020325400079507
+vn 0.6470120134562971 0.32214550099601613 0.6910844598392111
+vn 0.06512300008157354 0.1817122960150499 0.9811929659028922
+vn 0.6470120134562971 0.32214550099601613 0.6910844598392111
+vn 0.15822398156616502 0.25602244512131117 0.9536339335675167
+vn 0.15822398156616502 0.25602244512131117 0.9536339335675167
+vn 0.6470120134562971 0.32214550099601613 0.6910844598392111
+vn 0.6469167811389347 0.3375269637269374 0.6837939945905598
+vn 0.15822398156616502 0.25602244512131117 0.9536339335675167
+vn 0.6469167811389347 0.3375269637269374 0.6837939945905598
+vn 0.08027150295075214 0.7838061734035136 0.6157957196575569
+vn -0.8486909055579567 0.5285002455522558 0.020278986030386838
+vn -0.7980895498222257 0.4722984052156664 0.3741487496909424
+vn -0.6124933152538132 0.7508812289933203 0.24704112757772534
+vn -0.8486909055579567 0.5285002455522558 0.020278986030386838
+vn -0.6124933152538132 0.7508812289933203 0.24704112757772534
+vn -0.5614847532242626 0.8267078105428459 -0.035903591521501535
+vn -0.14215544931887256 0.9863233867876754 -0.08341465641384077
+vn 0.322318590237706 0.8933716366834041 0.3130460751339866
+vn 0.6570188351403856 0.7325003685503467 0.1782398954902558
+vn 0.6570188351403856 0.7325003685503467 0.1782398954902558
+vn 0.322318590237706 0.8933716366834041 0.3130460751339866
+vn 0.6469167811389347 0.3375269637269374 0.6837939945905598
+vn 0.322318590237706 0.8933716366834041 0.3130460751339866
+vn -0.14215544931887256 0.9863233867876754 -0.08341465641384077
+vn 0.08027150295075214 0.7838061734035136 0.6157957196575569
+vn -0.7239451931682047 -0.1200571718668144 -0.6793302825371418
+vn 0.02842898504555128 -0.12066283133185045 -0.9922863870598353
+vn 0.038390780432269365 -0.31384103429059534 -0.9486990846275812
+vn -0.7239451931682047 -0.1200571718668144 -0.6793302825371418
+vn 0.038390780432269365 -0.31384103429059534 -0.9486990846275812
+vn -0.6552077295232146 -0.4055494221640525 -0.6373637088471835
+vn -0.422079644008911 0.2538695700822324 0.8702867432631464
+vn 0.06512300008157354 0.1817122960150499 0.9811929659028922
+vn 0.15822398156616502 0.25602244512131117 0.9536339335675167
+vn -0.422079644008911 0.2538695700822324 0.8702867432631464
+vn 0.15822398156616502 0.25602244512131117 0.9536339335675167
+vn -0.41113035063210696 0.32260129775719243 0.8525844459491952
+vn 0.02842898504555128 -0.12066283133185045 -0.9922863870598353
+vn 0.7097417492795982 -0.1829898151808711 -0.6802803663708125
+vn 0.6588789857307925 -0.38981446840557793 -0.6433686053764504
+vn 0.02842898504555128 -0.12066283133185045 -0.9922863870598353
+vn 0.6588789857307925 -0.38981446840557793 -0.6433686053764504
+vn 0.038390780432269365 -0.31384103429059534 -0.9486990846275812
+vn -0.03567480384470595 -0.13271598951652872 0.9905118749905476
+vn -0.4633038123683755 -0.17104412199178726 0.8695363625386737
+vn -0.40002549681229516 -0.35320575265136483 0.8457099373863709
+vn -0.03567480384470595 -0.13271598951652872 0.9905118749905476
+vn -0.40002549681229516 -0.35320575265136483 0.8457099373863709
+vn -0.05290294202028155 -0.30088077630193094 0.9521932772171553
+vn 0.9837901350634028 -0.17733885327973467 0.02660641406428711
+vn 0.6517133562709272 -0.15851294629372636 0.741716487018703
+vn 0.5946519669805319 -0.39915860658432406 0.6978978757353007
+vn 0.9837901350634028 -0.17733885327973467 0.02660641406428711
+vn 0.5946519669805319 -0.39915860658432406 0.6978978757353007
+vn 0.9372438037171197 -0.34833148310033496 0.0154670706659773
+vn -0.9943567713149957 -0.10411073596521707 0.020385435899152794
+vn -0.7239451931682047 -0.1200571718668144 -0.6793302825371418
+vn -0.6552077295232146 -0.4055494221640525 -0.6373637088471835
+vn -0.9943567713149957 -0.10411073596521707 0.020385435899152794
+vn -0.6552077295232146 -0.4055494221640525 -0.6373637088471835
+vn -0.9417535786574657 -0.33562446938233104 0.021363816084343658
+vn 0.7097417492795982 -0.1829898151808711 -0.6802803663708125
+vn 0.9837901350634028 -0.17733885327973467 0.02660641406428711
+vn 0.9372438037171197 -0.34833148310033496 0.0154670706659773
+vn 0.7097417492795982 -0.1829898151808711 -0.6802803663708125
+vn 0.9372438037171197 -0.34833148310033496 0.0154670706659773
+vn 0.6588789857307925 -0.38981446840557793 -0.6433686053764504
+vn 0.6517133562709272 -0.15851294629372636 0.741716487018703
+vn -0.03567480384470595 -0.13271598951652872 0.9905118749905476
+vn -0.05290294202028155 -0.30088077630193094 0.9521932772171553
+vn 0.6517133562709272 -0.15851294629372636 0.741716487018703
+vn -0.05290294202028155 -0.30088077630193094 0.9521932772171553
+vn 0.5946519669805319 -0.39915860658432406 0.6978978757353007
+vn -0.8511331717889251 0.3364868776101403 0.4029254336433759
+vn -0.8841383452573867 0.16795282414964627 0.4359945358667791
+vn -0.42850222208687605 0.10894018151150854 0.8969492084387215
+vn -0.8511331717889251 0.3364868776101403 0.4029254336433759
+vn -0.42850222208687605 0.10894018151150854 0.8969492084387215
+vn -0.422079644008911 0.2538695700822324 0.8702867432631464
+vn -0.8841383452573867 0.16795282414964627 0.4359945358667791
+vn -0.8961485599960235 -0.14356160124866077 0.41989025359488164
+vn -0.4633038123683755 -0.17104412199178726 0.8695363625386737
+vn -0.8841383452573867 0.16795282414964627 0.4359945358667791
+vn -0.4633038123683755 -0.17104412199178726 0.8695363625386737
+vn -0.42850222208687605 0.10894018151150854 0.8969492084387215
+vn -0.422079644008911 0.2538695700822324 0.8702867432631464
+vn -0.41113035063210696 0.32260129775719243 0.8525844459491952
+vn -0.7980895498222257 0.4722984052156664 0.3741487496909424
+vn -0.422079644008911 0.2538695700822324 0.8702867432631464
+vn -0.7980895498222257 0.4722984052156664 0.3741487496909424
+vn -0.8511331717889251 0.3364868776101403 0.4029254336433759
+vn -0.41113035063210696 0.32260129775719243 0.8525844459491952
+vn -0.33381177749086666 0.7293253273127284 0.5972053785328543
+vn -0.6124933152538132 0.7508812289933203 0.24704112757772534
+vn -0.41113035063210696 0.32260129775719243 0.8525844459491952
+vn -0.6124933152538132 0.7508812289933203 0.24704112757772534
+vn -0.7980895498222257 0.4722984052156664 0.3741487496909424
+vn -0.8961485599960235 -0.14356160124866077 0.41989025359488164
+vn -0.8435083940194295 -0.3760793114928615 0.3834813433347417
+vn -0.40002549681229516 -0.35320575265136483 0.8457099373863709
+vn -0.8961485599960235 -0.14356160124866077 0.41989025359488164
+vn -0.40002549681229516 -0.35320575265136483 0.8457099373863709
+vn -0.4633038123683755 -0.17104412199178726 0.8695363625386737
+vn -0.8961485599960235 -0.14356160124866077 0.41989025359488164
+vn -0.8841383452573867 0.16795282414964627 0.4359945358667791
+vn -0.9834605097559777 0.17940530615475422 0.024882963529921857
+vn -0.8961485599960235 -0.14356160124866077 0.41989025359488164
+vn -0.9834605097559777 0.17940530615475422 0.024882963529921857
+vn -0.9943567713149957 -0.10411073596521707 0.020385435899152794
+f 1/1/1 2/2/2 3/3/3
+f 4/4/4 5/5/5 6/6/6
+f 7/7/7 8/8/8 9/9/9
+f 10/10/10 11/11/11 12/12/12
+f 13/13/13 14/14/14 15/15/15
+f 16/16/16 17/17/17 18/18/18
+f 19/19/19 20/20/20 21/21/21
+f 22/22/22 23/23/23 24/24/24
+f 25/25/25 26/26/26 27/27/27
+f 28/28/28 29/29/29 30/30/30
+f 31/31/31 32/32/32 33/33/33
+f 34/34/34 35/35/35 36/36/36
+f 37/37/37 38/38/38 39/39/39
+f 40/40/40 41/41/41 42/42/42
+f 43/43/43 44/44/44 45/45/45
+f 46/46/46 47/47/47 48/48/48
+f 49/49/49 50/50/50 51/51/51
+f 52/52/52 53/53/53 54/54/54
+f 55/55/55 56/56/56 57/57/57
+f 58/58/58 59/59/59 60/60/60
+f 61/61/61 62/62/62 63/63/63
+f 64/64/64 65/65/65 66/66/66
+f 67/67/67 68/68/68 69/69/69
+f 70/70/70 71/71/71 72/72/72
+f 73/73/73 74/74/74 75/75/75
+f 76/76/76 77/77/77 78/78/78
+f 79/79/79 80/80/80 81/81/81
+f 82/82/82 83/83/83 84/84/84
+f 85/85/85 86/86/86 87/87/87
+f 88/88/88 89/89/89 90/90/90
+f 91/91/91 92/92/92 93/93/93
+f 94/94/94 95/95/95 96/96/96
+f 97/97/97 98/98/98 99/99/99
+f 100/100/100 101/101/101 102/102/102
+f 103/103/103 104/104/104 105/105/105
+f 106/106/106 107/107/107 108/108/108
+f 109/109/109 110/110/110 111/111/111
+f 112/112/112 113/113/113 114/114/114
+f 115/115/115 116/116/116 117/117/117
+f 118/118/118 119/119/119 120/120/120
+f 121/121/121 122/122/122 123/123/123
+f 124/124/124 125/125/125 126/126/126
+f 127/127/127 128/128/128 129/129/129
+f 130/130/130 131/131/131 132/132/132
+f 133/133/133 134/134/134 135/135/135
+f 136/136/136 137/137/137 138/138/138
+f 139/139/139 140/140/140 141/141/141
+f 142/142/142 143/143/143 144/144/144
+f 145/145/145 146/146/146 147/147/147
+f 148/148/148 149/149/149 150/150/150
+f 151/151/151 152/152/152 153/153/153
+f 154/154/154 155/155/155 156/156/156
+f 157/157/157 158/158/158 159/159/159
+f 160/160/160 161/161/161 162/162/162
+f 163/163/163 164/164/164 165/165/165
+f 166/166/166 167/167/167 168/168/168
+f 169/169/169 170/170/170 171/171/171
+f 172/172/172 173/173/173 174/174/174
+f 175/175/175 176/176/176 177/177/177
+f 178/178/178 179/179/179 180/180/180
+f 181/181/181 182/182/182 183/183/183
+f 184/184/184 185/185/185 186/186/186
+f 187/187/187 188/188/188 189/189/189
+f 190/190/190 191/191/191 192/192/192
+f 193/193/193 194/194/194 195/195/195
+f 196/196/196 197/197/197 198/198/198
+f 199/199/199 200/200/200 201/201/201
+f 202/202/202 203/203/203 204/204/204
+f 205/205/205 206/206/206 207/207/207
+f 208/208/208 209/209/209 210/210/210
+f 211/211/211 212/212/212 213/213/213
+f 214/214/214 215/215/215 216/216/216
+f 217/217/217 218/218/218 219/219/219
+f 220/220/220 221/221/221 222/222/222
+f 223/223/223 224/224/224 225/225/225
+f 226/226/226 227/227/227 228/228/228
+f 229/229/229 230/230/230 231/231/231
+f 232/232/232 233/233/233 234/234/234
+f 235/235/235 236/236/236 237/237/237
+f 238/238/238 239/239/239 240/240/240
+f 241/241/241 242/242/242 243/243/243
+f 244/244/244 245/245/245 246/246/246
+f 247/247/247 248/248/248 249/249/249
+f 250/250/250 251/251/251 252/252/252
+f 253/253/253 254/254/254 255/255/255
+f 256/256/256 257/257/257 258/258/258
+f 259/259/259 260/260/260 261/261/261
+f 262/262/262 263/263/263 264/264/264
+f 265/265/265 266/266/266 267/267/267
+f 268/268/268 269/269/269 270/270/270
+f 271/271/271 272/272/272 273/273/273
+f 274/274/274 275/275/275 276/276/276
+f 277/277/277 278/278/278 279/279/279
+f 280/280/280 281/281/281 282/282/282
+f 283/283/283 284/284/284 285/285/285
+f 286/286/286 287/287/287 288/288/288
+f 289/289/289 290/290/290 291/291/291
+f 292/292/292 293/293/293 294/294/294
+f 295/295/295 296/296/296 297/297/297
+f 298/298/298 299/299/299 300/300/300
+f 301/301/301 302/302/302 303/303/303
diff --git a/apps/openmb/resources/models/rocks/SM_Rocks_04.obj b/apps/openmb/resources/models/rocks/SM_Rocks_04.obj
new file mode 100644
index 0000000..7236bbd
--- /dev/null
+++ b/apps/openmb/resources/models/rocks/SM_Rocks_04.obj
@@ -0,0 +1,373 @@
+mtllib SM_Rocks_04.mtl
+o SM_Rock_04
+usemtl SM_Rock_01
+v -43.19601058959961 30.734363555908203 28.441789627075195 1 1 1
+v -29.872751235961914 64.30950164794922 16.75210952758789 1 1 1
+v -17.701387405395508 64.43751525878906 -23.968463897705078 1 1 1
+v -43.19601058959961 30.734363555908203 28.441789627075195 1 1 1
+v -17.701387405395508 64.43751525878906 -23.968463897705078 1 1 1
+v -29.772281646728516 31.171714782714844 -34.29191589355469 1 1 1
+v 36.006526947021484 28.326520919799805 -28.65474510192871 1 1 1
+v 9.810304641723633 29.882055282592773 -35.11172103881836 1 1 1
+v 9.623098373413086 70.37802124023438 -26.080387115478516 1 1 1
+v 28.456357955932617 71.23019409179688 -20.94366455078125 1 1 1
+v 36.006526947021484 28.326520919799805 -28.65474510192871 1 1 1
+v 9.623098373413086 70.37802124023438 -26.080387115478516 1 1 1
+v 36.006526947021484 28.326520919799805 -28.65474510192871 1 1 1
+v 28.456357955932617 71.23019409179688 -20.94366455078125 1 1 1
+v 42.13508224487305 36.413055419921875 -26.57986831665039 1 1 1
+v 7.537317276000977 30.22222137451172 31.765287399291992 1 1 1
+v 7.250070571899414 71.78343200683594 21.94721031188965 1 1 1
+v -29.872751235961914 64.30950164794922 16.75210952758789 1 1 1
+v 7.537317276000977 30.22222137451172 31.765287399291992 1 1 1
+v -29.872751235961914 64.30950164794922 16.75210952758789 1 1 1
+v -43.19601058959961 30.734363555908203 28.441789627075195 1 1 1
+v 9.623098373413086 70.37802124023438 -26.080387115478516 1 1 1
+v -17.701387405395508 64.43751525878906 -23.968463897705078 1 1 1
+v -29.872751235961914 64.30950164794922 16.75210952758789 1 1 1
+v 9.623098373413086 70.37802124023438 -26.080387115478516 1 1 1
+v -29.872751235961914 64.30950164794922 16.75210952758789 1 1 1
+v 7.250070571899414 71.78343200683594 21.94721031188965 1 1 1
+v 7.273340225219727 -2.6153628826141357 35.4881706237793 1 1 1
+v 7.537317276000977 30.22222137451172 31.765287399291992 1 1 1
+v -43.19601058959961 30.734363555908203 28.441789627075195 1 1 1
+v 7.273340225219727 -2.6153628826141357 35.4881706237793 1 1 1
+v -43.19601058959961 30.734363555908203 28.441789627075195 1 1 1
+v -55.033447265625 -3.083256721496582 26.640764236450195 1 1 1
+v 41.65410232543945 20.471298217773438 34.866695404052734 1 1 1
+v 45.1383171081543 26.66870880126953 -17.448444366455078 1 1 1
+v 42.13508224487305 36.413055419921875 -26.57986831665039 1 1 1
+v 28.456357955932617 71.23019409179688 -20.94366455078125 1 1 1
+v 41.65410232543945 20.471298217773438 34.866695404052734 1 1 1
+v 42.13508224487305 36.413055419921875 -26.57986831665039 1 1 1
+v 41.65410232543945 20.471298217773438 34.866695404052734 1 1 1
+v 28.456357955932617 71.23019409179688 -20.94366455078125 1 1 1
+v 31.017959594726562 52.629913330078125 26.992488861083984 1 1 1
+v 38.726280212402344 -0.8372985124588013 -18.067529678344727 1 1 1
+v 45.1383171081543 26.66870880126953 -17.448444366455078 1 1 1
+v 41.65410232543945 20.471298217773438 34.866695404052734 1 1 1
+v 38.726280212402344 -0.8372985124588013 -18.067529678344727 1 1 1
+v 41.65410232543945 20.471298217773438 34.866695404052734 1 1 1
+v 33.438865661621094 -2.486894130706787 32.72226333618164 1 1 1
+v -55.033447265625 -3.083256721496582 26.640764236450195 1 1 1
+v -43.19601058959961 30.734363555908203 28.441789627075195 1 1 1
+v -29.772281646728516 31.171714782714844 -34.29191589355469 1 1 1
+v -55.033447265625 -3.083256721496582 26.640764236450195 1 1 1
+v -29.772281646728516 31.171714782714844 -34.29191589355469 1 1 1
+v -41.63890075683594 -2.820389747619629 -31.34072494506836 1 1 1
+v -41.63890075683594 -2.820389747619629 -31.34072494506836 1 1 1
+v -29.772281646728516 31.171714782714844 -34.29191589355469 1 1 1
+v 9.810304641723633 29.882055282592773 -35.11172103881836 1 1 1
+v -41.63890075683594 -2.820389747619629 -31.34072494506836 1 1 1
+v 9.810304641723633 29.882055282592773 -35.11172103881836 1 1 1
+v 9.735822677612305 -2.8241753578186035 -40.674346923828125 1 1 1
+v 33.438865661621094 -2.486894130706787 32.72226333618164 1 1 1
+v 41.65410232543945 20.471298217773438 34.866695404052734 1 1 1
+v 7.537317276000977 30.22222137451172 31.765287399291992 1 1 1
+v 33.438865661621094 -2.486894130706787 32.72226333618164 1 1 1
+v 7.537317276000977 30.22222137451172 31.765287399291992 1 1 1
+v 7.273340225219727 -2.6153628826141357 35.4881706237793 1 1 1
+v 28.456357955932617 71.23019409179688 -20.94366455078125 1 1 1
+v 9.623098373413086 70.37802124023438 -26.080387115478516 1 1 1
+v 7.250070571899414 71.78343200683594 21.94721031188965 1 1 1
+v 28.456357955932617 71.23019409179688 -20.94366455078125 1 1 1
+v 7.250070571899414 71.78343200683594 21.94721031188965 1 1 1
+v 24.20393943786621 72.47430419921875 14.655621528625488 1 1 1
+v 41.65410232543945 20.471298217773438 34.866695404052734 1 1 1
+v 22.798749923706055 53.188026428222656 28.880756378173828 1 1 1
+v 7.537317276000977 30.22222137451172 31.765287399291992 1 1 1
+v -29.772281646728516 31.171714782714844 -34.29191589355469 1 1 1
+v -17.701387405395508 64.43751525878906 -23.968463897705078 1 1 1
+v 9.623098373413086 70.37802124023438 -26.080387115478516 1 1 1
+v -29.772281646728516 31.171714782714844 -34.29191589355469 1 1 1
+v 9.623098373413086 70.37802124023438 -26.080387115478516 1 1 1
+v 9.810304641723633 29.882055282592773 -35.11172103881836 1 1 1
+v 7.250070571899414 71.78343200683594 21.94721031188965 1 1 1
+v 22.798749923706055 53.188026428222656 28.880756378173828 1 1 1
+v 31.017959594726562 52.629913330078125 26.992488861083984 1 1 1
+v 7.250070571899414 71.78343200683594 21.94721031188965 1 1 1
+v 31.017959594726562 52.629913330078125 26.992488861083984 1 1 1
+v 24.20393943786621 72.47430419921875 14.655621528625488 1 1 1
+v 31.017959594726562 52.629913330078125 26.992488861083984 1 1 1
+v 22.798749923706055 53.188026428222656 28.880756378173828 1 1 1
+v 41.65410232543945 20.471298217773438 34.866695404052734 1 1 1
+v 7.537317276000977 30.22222137451172 31.765287399291992 1 1 1
+v 22.798749923706055 53.188026428222656 28.880756378173828 1 1 1
+v 7.250070571899414 71.78343200683594 21.94721031188965 1 1 1
+v 31.017959594726562 52.629913330078125 26.992488861083984 1 1 1
+v 28.456357955932617 71.23019409179688 -20.94366455078125 1 1 1
+v 24.20393943786621 72.47430419921875 14.655621528625488 1 1 1
+v 45.1383171081543 26.66870880126953 -17.448444366455078 1 1 1
+v 36.006526947021484 28.326520919799805 -28.65474510192871 1 1 1
+v 42.13508224487305 36.413055419921875 -26.57986831665039 1 1 1
+v 30.425613403320312 -1.2934051752090454 -31.27834129333496 1 1 1
+v 36.006526947021484 28.326520919799805 -28.65474510192871 1 1 1
+v 45.1383171081543 26.66870880126953 -17.448444366455078 1 1 1
+v 30.425613403320312 -1.2934051752090454 -31.27834129333496 1 1 1
+v 45.1383171081543 26.66870880126953 -17.448444366455078 1 1 1
+v 38.726280212402344 -0.8372985124588013 -18.067529678344727 1 1 1
+v 9.735822677612305 -2.8241753578186035 -40.674346923828125 1 1 1
+v 9.810304641723633 29.882055282592773 -35.11172103881836 1 1 1
+v 36.006526947021484 28.326520919799805 -28.65474510192871 1 1 1
+v 9.735822677612305 -2.8241753578186035 -40.674346923828125 1 1 1
+v 36.006526947021484 28.326520919799805 -28.65474510192871 1 1 1
+v 30.425613403320312 -1.2934051752090454 -31.27834129333496 1 1 1
+vt 0.4367067813873291 0.7001103758811951
+vt 0.4778760075569153 0.6008245348930359
+vt 0.5980533957481384 0.598456859588623
+vt 0.4367067813873291 0.7001103758811951
+vt 0.5980533957481384 0.598456859588623
+vt 0.6184154748916626 0.700675368309021
+vt 0.18712486326694489 0.5098891854286194
+vt 0.11431802064180374 0.5305035710334778
+vt 0.08036277443170547 0.41818636655807495
+vt 0.13108490407466888 0.3978651165962219
+vt 0.18712486326694489 0.5098891854286194
+vt 0.08036277443170547 0.41818636655807495
+vt 0.18712486326694489 0.5098891854286194
+vt 0.13108490407466888 0.3978651165962219
+vt 0.1970166563987732 0.4822726845741272
+vt 0.5791115760803223 0.18038535118103027
+vt 0.45834165811538696 0.17720985412597656
+vt 0.4784361720085144 0.07184475660324097
+vt 0.5791115760803223 0.18038535118103027
+vt 0.4784361720085144 0.07184475660324097
+vt 0.578572154045105 0.03641456365585327
+vt 0.9111959338188171 0.36068034172058105
+vt 0.8945875763893127 0.4380154609680176
+vt 0.7755244374275208 0.45587849617004395
+vt 0.9111959338188171 0.36068034172058105
+vt 0.7755244374275208 0.45587849617004395
+vt 0.7755244374275208 0.3478517532348633
+vt 0.672529399394989 0.1810988187789917
+vt 0.5791115760803223 0.18038535118103027
+vt 0.578572154045105 0.03641456365585327
+vt 0.672529399394989 0.1810988187789917
+vt 0.578572154045105 0.03641456365585327
+vt 0.672529399394989 0.003841996192932129
+vt 0.18977078795433044 0.7926868200302124
+vt 0.04147539287805557 0.7737540602684021
+vt 0.01649971306324005 0.7497761845588684
+vt 0.03594992309808731 0.6659449934959412
+vt 0.18977078795433044 0.7926868200302124
+vt 0.01649971306324005 0.7497761845588684
+vt 0.18977078795433044 0.7926868200302124
+vt 0.03594992309808731 0.6659449934959412
+vt 0.1704154908657074 0.7138378024101257
+vt 0.0398271270096302 0.8536456227302551
+vt 0.04147539287805557 0.7737540602684021
+vt 0.18977078795433044 0.7926868200302124
+vt 0.0398271270096302 0.8536456227302551
+vt 0.18977078795433044 0.7926868200302124
+vt 0.18427087366580963 0.8616713285446167
+vt 0.4337061941623688 0.8016939163208008
+vt 0.4367067813873291 0.7001103758811951
+vt 0.6184154748916626 0.700675368309021
+vt 0.4337061941623688 0.8016939163208008
+vt 0.6184154748916626 0.700675368309021
+vt 0.6022860407829285 0.801693856716156
+vt 0.0038419701159000397 0.6577960848808289
+vt 0.006501962896436453 0.5590629577636719
+vt 0.11431802064180374 0.5305035710334778
+vt 0.0038419701159000397 0.6577960848808289
+vt 0.11431802064180374 0.5305035710334778
+vt 0.14134392142295837 0.6205140948295593
+vt 0.6694618463516235 0.2548877000808716
+vt 0.6061301231384277 0.27760010957717896
+vt 0.5791115760803223 0.18038535118103027
+vt 0.6694618463516235 0.2548877000808716
+vt 0.5791115760803223 0.18038535118103027
+vt 0.672529399394989 0.1810988187789917
+vt 0.9043798446655273 0.3059588670730591
+vt 0.9111959338188171 0.36068034172058105
+vt 0.7755244374275208 0.3478517532348633
+vt 0.9043798446655273 0.3059588670730591
+vt 0.7755244374275208 0.3478517532348633
+vt 0.8027920722961426 0.30331242084503174
+vt 0.6061301231384277 0.27760010957717896
+vt 0.512876033782959 0.22253865003585815
+vt 0.5791115760803223 0.18038535118103027
+vt 0.006501962896436453 0.5590629577636719
+vt 0.011952386237680912 0.4553014039993286
+vt 0.08036277443170547 0.41818636655807495
+vt 0.006501962896436453 0.5590629577636719
+vt 0.08036277443170547 0.41818636655807495
+vt 0.11431802064180374 0.5305035710334778
+vt 0.45834165811538696 0.17720985412597656
+vt 0.512876033782959 0.22253865003585815
+vt 0.5130683183670044 0.2456347942352295
+vt 0.45834165811538696 0.17720985412597656
+vt 0.5130683183670044 0.2456347942352295
+vt 0.4518965482711792 0.2244480848312378
+vt 0.5130683183670044 0.2456347942352295
+vt 0.512876033782959 0.22253865003585815
+vt 0.6061301231384277 0.27760010957717896
+vt 0.5791115760803223 0.18038535118103027
+vt 0.512876033782959 0.22253865003585815
+vt 0.45834165811538696 0.17720985412597656
+vt 0.1704154908657074 0.7138378024101257
+vt 0.03594992309808731 0.6659449934959412
+vt 0.13736848533153534 0.6654801368713379
+vt 0.04147539287805557 0.7737540602684021
+vt 0.0113717932254076 0.7766685485839844
+vt 0.01649971306324005 0.7497761845588684
+vt 0.0038419971242547035 0.8616713285446167
+vt 0.0113717932254076 0.7766685485839844
+vt 0.04147539287805557 0.7737540602684021
+vt 0.0038419971242547035 0.8616713285446167
+vt 0.04147539287805557 0.7737540602684021
+vt 0.0398271270096302 0.8536456227302551
+vt 0.14134392142295837 0.6205140948295593
+vt 0.11431802064180374 0.5305035710334778
+vt 0.18712486326694489 0.5098891854286194
+vt 0.14134392142295837 0.6205140948295593
+vt 0.18712486326694489 0.5098891854286194
+vt 0.1970166563987732 0.5946849584579468
+vn -0.7157215323560417 0.337741695599858 0.611288176865259
+vn -0.6088136470227327 0.6974004547927667 0.3781250439388028
+vn -0.47315092157166316 0.6811844888289839 -0.5586733371073671
+vn -0.7157215323560417 0.337741695599858 0.611288176865259
+vn -0.47315092157166316 0.6811844888289839 -0.5586733371073671
+vn -0.5863432100539792 0.28169181158222495 -0.7595073161669474
+vn 0.5138889051374591 -0.006636006881918351 -0.8578310769547154
+vn 0.09447895418186718 0.1586745798979265 -0.9828001347735545
+vn -0.014116165970960468 0.7541001338369113 -0.6566077383076083
+vn 0.5312390249885971 0.7260330809441002 -0.4366475279948141
+vn 0.5138889051374591 -0.006636006881918351 -0.8578310769547154
+vn -0.014116165970960468 0.7541001338369113 -0.6566077383076083
+vn 0.5138889051374591 -0.006636006881918351 -0.8578310769547154
+vn 0.5312390249885971 0.7260330809441002 -0.4366475279948141
+vn 0.7866441323316651 0.17337355881502692 -0.5925644422102747
+vn -0.08018530835205877 0.143189250172142 0.9864416632318533
+vn -0.06411527903658107 0.8038538771331262 0.5913612899168341
+vn -0.6088136470227327 0.6974004547927667 0.3781250439388028
+vn -0.08018530835205877 0.143189250172142 0.9864416632318533
+vn -0.6088136470227327 0.6974004547927667 0.3781250439388028
+vn -0.7157215323560417 0.337741695599858 0.611288176865259
+vn -0.014116165970960468 0.7541001338369113 -0.6566077383076083
+vn -0.47315092157166316 0.6811844888289839 -0.5586733371073671
+vn -0.6088136470227327 0.6974004547927667 0.3781250439388028
+vn -0.014116165970960468 0.7541001338369113 -0.6566077383076083
+vn -0.6088136470227327 0.6974004547927667 0.3781250439388028
+vn -0.06411527903658107 0.8038538771331262 0.5913612899168341
+vn -0.05445489001765192 0.03837041728114668 0.9977787209751651
+vn -0.08018530835205877 0.143189250172142 0.9864416632318533
+vn -0.7157215323560417 0.337741695599858 0.611288176865259
+vn -0.05445489001765192 0.03837041728114668 0.9977787209751651
+vn -0.7157215323560417 0.337741695599858 0.611288176865259
+vn -0.8274922513719093 0.2933713844384553 0.47873772016847915
+vn 0.7148287441594655 0.05391033475903227 0.6972184322933312
+vn 0.981756335737993 -0.011495907863576193 -0.18979552508081196
+vn 0.7866441323316651 0.17337355881502692 -0.5925644422102747
+vn 0.5312390249885971 0.7260330809441002 -0.4366475279948141
+vn 0.7148287441594655 0.05391033475903227 0.6972184322933312
+vn 0.7866441323316651 0.17337355881502692 -0.5925644422102747
+vn 0.7148287441594655 0.05391033475903227 0.6972184322933312
+vn 0.5312390249885971 0.7260330809441002 -0.4366475279948141
+vn 0.668746728282906 0.45002077271961904 0.5918269320770608
+vn 0.9318677121397121 -0.21812245191220234 -0.289905438105786
+vn 0.981756335737993 -0.011495907863576193 -0.18979552508081196
+vn 0.7148287441594655 0.05391033475903227 0.6972184322933312
+vn 0.9318677121397121 -0.21812245191220234 -0.289905438105786
+vn 0.7148287441594655 0.05391033475903227 0.6972184322933312
+vn 0.5985417453835973 -0.15448180019410104 0.7860554385295906
+vn -0.8274922513719093 0.2933713844384553 0.47873772016847915
+vn -0.7157215323560417 0.337741695599858 0.611288176865259
+vn -0.5863432100539792 0.28169181158222495 -0.7595073161669474
+vn -0.8274922513719093 0.2933713844384553 0.47873772016847915
+vn -0.5863432100539792 0.28169181158222495 -0.7595073161669474
+vn -0.7165060974330482 0.25818081749418853 -0.6480445029620233
+vn -0.7165060974330482 0.25818081749418853 -0.6480445029620233
+vn -0.5863432100539792 0.28169181158222495 -0.7595073161669474
+vn 0.09447895418186718 0.1586745798979265 -0.9828001347735545
+vn -0.7165060974330482 0.25818081749418853 -0.6480445029620233
+vn 0.09447895418186718 0.1586745798979265 -0.9828001347735545
+vn 0.09890089624040926 0.0778997888974533 -0.99204346457833
+vn 0.5985417453835973 -0.15448180019410104 0.7860554385295906
+vn 0.7148287441594655 0.05391033475903227 0.6972184322933312
+vn -0.08018530835205877 0.143189250172142 0.9864416632318533
+vn 0.5985417453835973 -0.15448180019410104 0.7860554385295906
+vn -0.08018530835205877 0.143189250172142 0.9864416632318533
+vn -0.05445489001765192 0.03837041728114668 0.9977787209751651
+vn 0.5312390249885971 0.7260330809441002 -0.4366475279948141
+vn -0.014116165970960468 0.7541001338369113 -0.6566077383076083
+vn -0.06411527903658107 0.8038538771331262 0.5913612899168341
+vn 0.5312390249885971 0.7260330809441002 -0.4366475279948141
+vn -0.06411527903658107 0.8038538771331262 0.5913612899168341
+vn 0.4873899318332148 0.8198584670639274 0.30047154329686754
+vn 0.7148287441594655 0.05391033475903227 0.6972184322933312
+vn 0.08624149391751162 0.3561094508373157 0.9304560514883125
+vn -0.08018530835205877 0.143189250172142 0.9864416632318533
+vn -0.5863432100539792 0.28169181158222495 -0.7595073161669474
+vn -0.47315092157166316 0.6811844888289839 -0.5586733371073671
+vn -0.014116165970960468 0.7541001338369113 -0.6566077383076083
+vn -0.5863432100539792 0.28169181158222495 -0.7595073161669474
+vn -0.014116165970960468 0.7541001338369113 -0.6566077383076083
+vn 0.09447895418186718 0.1586745798979265 -0.9828001347735545
+vn -0.06411527903658107 0.8038538771331262 0.5913612899168341
+vn 0.08624149391751162 0.3561094508373157 0.9304560514883125
+vn 0.668746728282906 0.45002077271961904 0.5918269320770608
+vn -0.06411527903658107 0.8038538771331262 0.5913612899168341
+vn 0.668746728282906 0.45002077271961904 0.5918269320770608
+vn 0.4873899318332148 0.8198584670639274 0.30047154329686754
+vn 0.668746728282906 0.45002077271961904 0.5918269320770608
+vn 0.08624149391751162 0.3561094508373157 0.9304560514883125
+vn 0.7148287441594655 0.05391033475903227 0.6972184322933312
+vn -0.08018530835205877 0.143189250172142 0.9864416632318533
+vn 0.08624149391751162 0.3561094508373157 0.9304560514883125
+vn -0.06411527903658107 0.8038538771331262 0.5913612899168341
+vn 0.668746728282906 0.45002077271961904 0.5918269320770608
+vn 0.5312390249885971 0.7260330809441002 -0.4366475279948141
+vn 0.4873899318332148 0.8198584670639274 0.30047154329686754
+vn 0.981756335737993 -0.011495907863576193 -0.18979552508081196
+vn 0.5138889051374591 -0.006636006881918351 -0.8578310769547154
+vn 0.7866441323316651 0.17337355881502692 -0.5925644422102747
+vn 0.5545206928214875 -0.0035577463172636495 -0.8321623301219055
+vn 0.5138889051374591 -0.006636006881918351 -0.8578310769547154
+vn 0.981756335737993 -0.011495907863576193 -0.18979552508081196
+vn 0.5545206928214875 -0.0035577463172636495 -0.8321623301219055
+vn 0.981756335737993 -0.011495907863576193 -0.18979552508081196
+vn 0.9318677121397121 -0.21812245191220234 -0.289905438105786
+vn 0.09890089624040926 0.0778997888974533 -0.99204346457833
+vn 0.09447895418186718 0.1586745798979265 -0.9828001347735545
+vn 0.5138889051374591 -0.006636006881918351 -0.8578310769547154
+vn 0.09890089624040926 0.0778997888974533 -0.99204346457833
+vn 0.5138889051374591 -0.006636006881918351 -0.8578310769547154
+vn 0.5545206928214875 -0.0035577463172636495 -0.8321623301219055
+f 1/1/1 2/2/2 3/3/3
+f 4/4/4 5/5/5 6/6/6
+f 7/7/7 8/8/8 9/9/9
+f 10/10/10 11/11/11 12/12/12
+f 13/13/13 14/14/14 15/15/15
+f 16/16/16 17/17/17 18/18/18
+f 19/19/19 20/20/20 21/21/21
+f 22/22/22 23/23/23 24/24/24
+f 25/25/25 26/26/26 27/27/27
+f 28/28/28 29/29/29 30/30/30
+f 31/31/31 32/32/32 33/33/33
+f 34/34/34 35/35/35 36/36/36
+f 37/37/37 38/38/38 39/39/39
+f 40/40/40 41/41/41 42/42/42
+f 43/43/43 44/44/44 45/45/45
+f 46/46/46 47/47/47 48/48/48
+f 49/49/49 50/50/50 51/51/51
+f 52/52/52 53/53/53 54/54/54
+f 55/55/55 56/56/56 57/57/57
+f 58/58/58 59/59/59 60/60/60
+f 61/61/61 62/62/62 63/63/63
+f 64/64/64 65/65/65 66/66/66
+f 67/67/67 68/68/68 69/69/69
+f 70/70/70 71/71/71 72/72/72
+f 73/73/73 74/74/74 75/75/75
+f 76/76/76 77/77/77 78/78/78
+f 79/79/79 80/80/80 81/81/81
+f 82/82/82 83/83/83 84/84/84
+f 85/85/85 86/86/86 87/87/87
+f 88/88/88 89/89/89 90/90/90
+f 91/91/91 92/92/92 93/93/93
+f 94/94/94 95/95/95 96/96/96
+f 97/97/97 98/98/98 99/99/99
+f 100/100/100 101/101/101 102/102/102
+f 103/103/103 104/104/104 105/105/105
+f 106/106/106 107/107/107 108/108/108
+f 109/109/109 110/110/110 111/111/111
diff --git a/apps/openmb/resources/models/rocks/SM_Rocks_05.obj b/apps/openmb/resources/models/rocks/SM_Rocks_05.obj
new file mode 100644
index 0000000..8542373
--- /dev/null
+++ b/apps/openmb/resources/models/rocks/SM_Rocks_05.obj
@@ -0,0 +1,283 @@
+mtllib SM_Rocks_05.mtl
+o SM_Rock_05
+usemtl SM_Rock_01
+v -40.50653076171875 46.60209274291992 27.66851234436035 1 1 1
+v -38.85527801513672 96.24703979492188 12.692525863647461 1 1 1
+v -37.72928237915039 98.91350555419922 -17.942962646484375 1 1 1
+v -40.50653076171875 46.60209274291992 27.66851234436035 1 1 1
+v -37.72928237915039 98.91350555419922 -17.942962646484375 1 1 1
+v -40.456756591796875 46.42837905883789 -33.537349700927734 1 1 1
+v -6.37501335144043 46.57329177856445 -43.0497932434082 1 1 1
+v -19.741682052612305 94.74181365966797 -28.24983024597168 1 1 1
+v 0.13704803586006165 89.18071746826172 -13.498573303222656 1 1 1
+v -6.37501335144043 46.57329177856445 -43.0497932434082 1 1 1
+v 0.13704803586006165 89.18071746826172 -13.498573303222656 1 1 1
+v 27.812252044677734 46.73490905761719 -12.94567584991455 1 1 1
+v 27.812252044677734 46.73490905761719 -12.94567584991455 1 1 1
+v 0.13704803586006165 89.18071746826172 -13.498573303222656 1 1 1
+v -1.4110591411590576 87.11785888671875 18.313655853271484 1 1 1
+v 27.812252044677734 46.73490905761719 -12.94567584991455 1 1 1
+v -1.4110591411590576 87.11785888671875 18.313655853271484 1 1 1
+v 24.609643936157227 46.474308013916016 33.71485900878906 1 1 1
+v -7.459566116333008 46.733516693115234 32.7945556640625 1 1 1
+v -20.50605583190918 93.2823715209961 18.686105728149414 1 1 1
+v -38.85527801513672 96.24703979492188 12.692525863647461 1 1 1
+v -7.459566116333008 46.733516693115234 32.7945556640625 1 1 1
+v -38.85527801513672 96.24703979492188 12.692525863647461 1 1 1
+v -40.50653076171875 46.60209274291992 27.66851234436035 1 1 1
+v -19.741682052612305 94.74181365966797 -28.24983024597168 1 1 1
+v -37.72928237915039 98.91350555419922 -17.942962646484375 1 1 1
+v -38.85527801513672 96.24703979492188 12.692525863647461 1 1 1
+v -19.741682052612305 94.74181365966797 -28.24983024597168 1 1 1
+v -38.85527801513672 96.24703979492188 12.692525863647461 1 1 1
+v -20.50605583190918 93.2823715209961 18.686105728149414 1 1 1
+v 0.8742848634719849 -2.4600632190704346 43.09696960449219 1 1 1
+v -7.459566116333008 46.733516693115234 32.7945556640625 1 1 1
+v -40.50653076171875 46.60209274291992 27.66851234436035 1 1 1
+v 0.8742848634719849 -2.4600632190704346 43.09696960449219 1 1 1
+v -40.50653076171875 46.60209274291992 27.66851234436035 1 1 1
+v -40.38329315185547 -2.5335843563079834 36.885772705078125 1 1 1
+v 45.409767150878906 -2.484806776046753 -13.021038055419922 1 1 1
+v 27.812252044677734 46.73490905761719 -12.94567584991455 1 1 1
+v 24.609643936157227 46.474308013916016 33.71485900878906 1 1 1
+v 45.409767150878906 -2.484806776046753 -13.021038055419922 1 1 1
+v 24.609643936157227 46.474308013916016 33.71485900878906 1 1 1
+v 42.05434036254883 -2.6127004623413086 43.10321044921875 1 1 1
+v 2.3169233798980713 -2.429234027862549 -43.255126953125 1 1 1
+v -6.37501335144043 46.57329177856445 -43.0497932434082 1 1 1
+v 27.812252044677734 46.73490905761719 -12.94567584991455 1 1 1
+v 2.3169233798980713 -2.429234027862549 -43.255126953125 1 1 1
+v 27.812252044677734 46.73490905761719 -12.94567584991455 1 1 1
+v 45.409767150878906 -2.484806776046753 -13.021038055419922 1 1 1
+v -40.38329315185547 -2.5335843563079834 36.885772705078125 1 1 1
+v -40.50653076171875 46.60209274291992 27.66851234436035 1 1 1
+v -40.456756591796875 46.42837905883789 -33.537349700927734 1 1 1
+v -40.38329315185547 -2.5335843563079834 36.885772705078125 1 1 1
+v -40.456756591796875 46.42837905883789 -33.537349700927734 1 1 1
+v -40.46354675292969 -2.4489197731018066 -34.38356399536133 1 1 1
+v -40.46354675292969 -2.4489197731018066 -34.38356399536133 1 1 1
+v -40.456756591796875 46.42837905883789 -33.537349700927734 1 1 1
+v -6.37501335144043 46.57329177856445 -43.0497932434082 1 1 1
+v -40.46354675292969 -2.4489197731018066 -34.38356399536133 1 1 1
+v -6.37501335144043 46.57329177856445 -43.0497932434082 1 1 1
+v 2.3169233798980713 -2.429234027862549 -43.255126953125 1 1 1
+v 42.05434036254883 -2.6127004623413086 43.10321044921875 1 1 1
+v 24.609643936157227 46.474308013916016 33.71485900878906 1 1 1
+v -7.459566116333008 46.733516693115234 32.7945556640625 1 1 1
+v 42.05434036254883 -2.6127004623413086 43.10321044921875 1 1 1
+v -7.459566116333008 46.733516693115234 32.7945556640625 1 1 1
+v 0.8742848634719849 -2.4600632190704346 43.09696960449219 1 1 1
+v 0.13704803586006165 89.18071746826172 -13.498573303222656 1 1 1
+v -19.741682052612305 94.74181365966797 -28.24983024597168 1 1 1
+v -20.50605583190918 93.2823715209961 18.686105728149414 1 1 1
+v 0.13704803586006165 89.18071746826172 -13.498573303222656 1 1 1
+v -20.50605583190918 93.2823715209961 18.686105728149414 1 1 1
+v -1.4110591411590576 87.11785888671875 18.313655853271484 1 1 1
+v 24.609643936157227 46.474308013916016 33.71485900878906 1 1 1
+v -1.4110591411590576 87.11785888671875 18.313655853271484 1 1 1
+v -20.50605583190918 93.2823715209961 18.686105728149414 1 1 1
+v 24.609643936157227 46.474308013916016 33.71485900878906 1 1 1
+v -20.50605583190918 93.2823715209961 18.686105728149414 1 1 1
+v -7.459566116333008 46.733516693115234 32.7945556640625 1 1 1
+v -40.456756591796875 46.42837905883789 -33.537349700927734 1 1 1
+v -37.72928237915039 98.91350555419922 -17.942962646484375 1 1 1
+v -19.741682052612305 94.74181365966797 -28.24983024597168 1 1 1
+v -40.456756591796875 46.42837905883789 -33.537349700927734 1 1 1
+v -19.741682052612305 94.74181365966797 -28.24983024597168 1 1 1
+v -6.37501335144043 46.57329177856445 -43.0497932434082 1 1 1
+vt 0.4598149061203003 0.4516195058822632
+vt 0.5022656321525574 0.310920774936676
+vt 0.5890682339668274 0.30331242084503174
+vt 0.4598149061203003 0.4516195058822632
+vt 0.5890682339668274 0.30331242084503174
+vt 0.6332000494003296 0.45212918519973755
+vt 0.003841998288407922 0.1566031575202942
+vt 0.07301238924264908 0.02964681386947632
+vt 0.10249044746160507 0.07651758193969727
+vt 0.003841998288407922 0.1566031575202942
+vt 0.10249044746160507 0.07651758193969727
+vt 0.07215281575918198 0.21590596437454224
+vt 0.07215281575918198 0.21590596437454224
+vt 0.10249044746160507 0.07651758193969727
+vt 0.19000186026096344 0.0992354154586792
+vt 0.07215281575918198 0.21590596437454224
+vt 0.19000186026096344 0.0992354154586792
+vt 0.20220735669136047 0.24122107028961182
+vt 0.34975001215934753 0.1534515619277954
+vt 0.38760825991630554 0.015950024127960205
+vt 0.4406205117702484 0.003841996192932129
+vt 0.34975001215934753 0.1534515619277954
+vt 0.4406205117702484 0.003841996192932129
+vt 0.4442126750946045 0.1506001353263855
+vt 0.07301238924264908 0.02964681386947632
+vt 0.11122466623783112 0.0038419365882873535
+vt 0.19502270221710205 0.02785205841064453
+vt 0.07301238924264908 0.02964681386947632
+vt 0.19502270221710205 0.02785205841064453
+vt 0.20220735669136047 0.061058640480041504
+vt 0.32616686820983887 0.2956284284591675
+vt 0.34975001215934753 0.1534515619277954
+vt 0.4442126750946045 0.1506001353263855
+vt 0.32616686820983887 0.2956284284591675
+vt 0.4442126750946045 0.1506001353263855
+vt 0.44405293464660645 0.29195040464401245
+vt 0.04129339009523392 0.3595932722091675
+vt 0.07215281575918198 0.21590596437454224
+vt 0.20220735669136047 0.24122107028961182
+vt 0.04129339009523392 0.3595932722091675
+vt 0.20220735669136047 0.24122107028961182
+vt 0.19759654998779297 0.3901810646057129
+vt 0.3332149088382721 0.5952299237251282
+vt 0.3122228682041168 0.45766007900238037
+vt 0.3809558153152466 0.4458489418029785
+vt 0.3332149088382721 0.5952299237251282
+vt 0.3809558153152466 0.4458489418029785
+vt 0.4260222017765045 0.5836359262466431
+vt 0.4337061643600464 0.5907729268074036
+vt 0.4598149061203003 0.4516195058822632
+vt 0.6332000494003296 0.45212918519973755
+vt 0.4337061643600464 0.5907729268074036
+vt 0.6332000494003296 0.45212918519973755
+vt 0.6355971097946167 0.5905618667602539
+vt 0.20989133417606354 0.5940188765525818
+vt 0.2120072841644287 0.4562457799911499
+vt 0.3122228682041168 0.45766007900238037
+vt 0.20989133417606354 0.5940188765525818
+vt 0.3122228682041168 0.45766007900238037
+vt 0.3332149088382721 0.5952299237251282
+vt 0.20989134907722473 0.2956284284591675
+vt 0.2590023875236511 0.15447145700454712
+vt 0.34975001215934753 0.1534515619277954
+vt 0.20989134907722473 0.2956284284591675
+vt 0.34975001215934753 0.1534515619277954
+vt 0.32616686820983887 0.2956284284591675
+vt 0.10249044746160507 0.07651758193969727
+vt 0.07301238924264908 0.02964681386947632
+vt 0.20220735669136047 0.061058640480041504
+vt 0.10249044746160507 0.07651758193969727
+vt 0.20220735669136047 0.061058640480041504
+vt 0.19000186026096344 0.0992354154586792
+vt 0.2590023875236511 0.15447145700454712
+vt 0.33405324816703796 0.032427966594696045
+vt 0.38760825991630554 0.015950024127960205
+vt 0.2590023875236511 0.15447145700454712
+vt 0.38760825991630554 0.015950024127960205
+vt 0.34975001215934753 0.1534515619277954
+vt 0.2120072841644287 0.4562457799911499
+vt 0.20989136397838593 0.30331242084503174
+vt 0.2667810618877411 0.3177669048309326
+vt 0.2120072841644287 0.4562457799911499
+vt 0.2667810618877411 0.3177669048309326
+vt 0.3122228682041168 0.45766007900238037
+vn -0.7572498372999124 0.158828053377099 0.6335190078992877
+vn -0.5706052151986355 0.7018495758604838 0.42639988420797886
+vn -0.5550298286839305 0.7612513941802773 -0.3353180641266899
+vn -0.7572498372999124 0.158828053377099 0.6335190078992877
+vn -0.5550298286839305 0.7612513941802773 -0.3353180641266899
+vn -0.7787844744038005 0.08731374374782407 -0.6211851999044533
+vn 0.19484776919781263 0.21413928997127954 -0.9571722474712857
+vn 0.14086980450775322 0.7258771910322607 -0.6732443848388655
+vn 0.626905745312635 0.7348083821518948 -0.25893209150919166
+vn 0.19484776919781263 0.21413928997127954 -0.9571722474712857
+vn 0.626905745312635 0.7348083821518948 -0.25893209150919166
+vn 0.8427307453405789 0.3923032212867617 -0.36865034033043104
+vn 0.8427307453405789 0.3923032212867617 -0.36865034033043104
+vn 0.626905745312635 0.7348083821518948 -0.25893209150919166
+vn 0.44751232912724975 0.7244215133345491 0.5243531122222753
+vn 0.8427307453405789 0.3923032212867617 -0.36865034033043104
+vn 0.44751232912724975 0.7244215133345491 0.5243531122222753
+vn 0.5977325011734748 0.44326458629530474 0.6680062601333573
+vn -0.07392964468225123 0.24670541140024185 0.9662664475303866
+vn 0.06570325963075113 0.7614497473416393 0.6448855432921782
+vn -0.5706052151986355 0.7018495758604838 0.42639988420797886
+vn -0.07392964468225123 0.24670541140024185 0.9662664475303866
+vn -0.5706052151986355 0.7018495758604838 0.42639988420797886
+vn -0.7572498372999124 0.158828053377099 0.6335190078992877
+vn 0.14086980450775322 0.7258771910322607 -0.6732443848388655
+vn -0.5550298286839305 0.7612513941802773 -0.3353180641266899
+vn -0.5706052151986355 0.7018495758604838 0.42639988420797886
+vn 0.14086980450775322 0.7258771910322607 -0.6732443848388655
+vn -0.5706052151986355 0.7018495758604838 0.42639988420797886
+vn 0.06570325963075113 0.7614497473416393 0.6448855432921782
+vn -0.07233257618517844 0.18811179767193992 0.9794804490131728
+vn -0.07392964468225123 0.24670541140024185 0.9662664475303866
+vn -0.7572498372999124 0.158828053377099 0.6335190078992877
+vn -0.07233257618517844 0.18811179767193992 0.9794804490131728
+vn -0.7572498372999124 0.158828053377099 0.6335190078992877
+vn -0.7161014037497411 0.12648911698999613 0.6864395696860297
+vn 0.8858925722248271 0.2929421968602402 -0.3596932300941676
+vn 0.8427307453405789 0.3923032212867617 -0.36865034033043104
+vn 0.5977325011734748 0.44326458629530474 0.6680062601333573
+vn 0.8858925722248271 0.2929421968602402 -0.3596932300941676
+vn 0.5977325011734748 0.44326458629530474 0.6680062601333573
+vn 0.6626612593852685 0.36345809971210374 0.6548116256325907
+vn 0.25526761305033085 0.09570637081503638 -0.9621219965851532
+vn 0.19484776919781263 0.21413928997127954 -0.9571722474712857
+vn 0.8427307453405789 0.3923032212867617 -0.36865034033043104
+vn 0.25526761305033085 0.09570637081503638 -0.9621219965851532
+vn 0.8427307453405789 0.3923032212867617 -0.36865034033043104
+vn 0.8858925722248271 0.2929421968602402 -0.3596932300941676
+vn -0.7161014037497411 0.12648911698999613 0.6864395696860297
+vn -0.7572498372999124 0.158828053377099 0.6335190078992877
+vn -0.7787844744038005 0.08731374374782407 -0.6211851999044533
+vn -0.7161014037497411 0.12648911698999613 0.6864395696860297
+vn -0.7787844744038005 0.08731374374782407 -0.6211851999044533
+vn -0.7821251490730478 -0.0072697604411478935 -0.6230789691287862
+vn -0.7821251490730478 -0.0072697604411478935 -0.6230789691287862
+vn -0.7787844744038005 0.08731374374782407 -0.6211851999044533
+vn 0.19484776919781263 0.21413928997127954 -0.9571722474712857
+vn -0.7821251490730478 -0.0072697604411478935 -0.6230789691287862
+vn 0.19484776919781263 0.21413928997127954 -0.9571722474712857
+vn 0.25526761305033085 0.09570637081503638 -0.9621219965851532
+vn 0.6626612593852685 0.36345809971210374 0.6548116256325907
+vn 0.5977325011734748 0.44326458629530474 0.6680062601333573
+vn -0.07392964468225123 0.24670541140024185 0.9662664475303866
+vn 0.6626612593852685 0.36345809971210374 0.6548116256325907
+vn -0.07392964468225123 0.24670541140024185 0.9662664475303866
+vn -0.07233257618517844 0.18811179767193992 0.9794804490131728
+vn 0.626905745312635 0.7348083821518948 -0.25893209150919166
+vn 0.14086980450775322 0.7258771910322607 -0.6732443848388655
+vn 0.06570325963075113 0.7614497473416393 0.6448855432921782
+vn 0.626905745312635 0.7348083821518948 -0.25893209150919166
+vn 0.06570325963075113 0.7614497473416393 0.6448855432921782
+vn 0.44751232912724975 0.7244215133345491 0.5243531122222753
+vn 0.5977325011734748 0.44326458629530474 0.6680062601333573
+vn 0.44751232912724975 0.7244215133345491 0.5243531122222753
+vn 0.06570325963075113 0.7614497473416393 0.6448855432921782
+vn 0.5977325011734748 0.44326458629530474 0.6680062601333573
+vn 0.06570325963075113 0.7614497473416393 0.6448855432921782
+vn -0.07392964468225123 0.24670541140024185 0.9662664475303866
+vn -0.7787844744038005 0.08731374374782407 -0.6211851999044533
+vn -0.5550298286839305 0.7612513941802773 -0.3353180641266899
+vn 0.14086980450775322 0.7258771910322607 -0.6732443848388655
+vn -0.7787844744038005 0.08731374374782407 -0.6211851999044533
+vn 0.14086980450775322 0.7258771910322607 -0.6732443848388655
+vn 0.19484776919781263 0.21413928997127954 -0.9571722474712857
+f 1/1/1 2/2/2 3/3/3
+f 4/4/4 5/5/5 6/6/6
+f 7/7/7 8/8/8 9/9/9
+f 10/10/10 11/11/11 12/12/12
+f 13/13/13 14/14/14 15/15/15
+f 16/16/16 17/17/17 18/18/18
+f 19/19/19 20/20/20 21/21/21
+f 22/22/22 23/23/23 24/24/24
+f 25/25/25 26/26/26 27/27/27
+f 28/28/28 29/29/29 30/30/30
+f 31/31/31 32/32/32 33/33/33
+f 34/34/34 35/35/35 36/36/36
+f 37/37/37 38/38/38 39/39/39
+f 40/40/40 41/41/41 42/42/42
+f 43/43/43 44/44/44 45/45/45
+f 46/46/46 47/47/47 48/48/48
+f 49/49/49 50/50/50 51/51/51
+f 52/52/52 53/53/53 54/54/54
+f 55/55/55 56/56/56 57/57/57
+f 58/58/58 59/59/59 60/60/60
+f 61/61/61 62/62/62 63/63/63
+f 64/64/64 65/65/65 66/66/66
+f 67/67/67 68/68/68 69/69/69
+f 70/70/70 71/71/71 72/72/72
+f 73/73/73 74/74/74 75/75/75
+f 76/76/76 77/77/77 78/78/78
+f 79/79/79 80/80/80 81/81/81
+f 82/82/82 83/83/83 84/84/84
diff --git a/apps/openmb/resources/shaders/.gitkeep b/apps/openmb/resources/shaders/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/apps/openmb/resources/shaders/.gitkeep
diff --git a/apps/openmb/resources/shaders/cube.frag b/apps/openmb/resources/shaders/cube.frag
new file mode 100644
index 0000000..cb15430
--- /dev/null
+++ b/apps/openmb/resources/shaders/cube.frag
@@ -0,0 +1,21 @@
+#version 330 core
+out vec4 FragColor;
+uniform vec3 color;
+in vec3 vFragPos;
+uniform vec3 cameraPos;
+uniform vec3 fogColor;
+uniform float fogDensity;
+uniform float fogAmount;
+
+void main()
+{
+ // Basic color with fog applied
+ vec3 base = color;
+
+ // vFragPos provided by vertex shader
+ float dist = length(vFragPos - cameraPos);
+ float fogFactor = 1.0 - exp(-fogDensity * dist);
+ fogFactor = clamp(fogFactor * fogAmount, 0.0, 1.0);
+ vec3 finalColor = mix(base, fogColor, fogFactor);
+ FragColor = vec4(finalColor, 1.0);
+}
diff --git a/apps/openmb/resources/shaders/cube.vert b/apps/openmb/resources/shaders/cube.vert
new file mode 100644
index 0000000..805c883
--- /dev/null
+++ b/apps/openmb/resources/shaders/cube.vert
@@ -0,0 +1,11 @@
+#version 330 core
+layout(location = 0) in vec3 aPos;
+uniform mat4 model;
+uniform mat4 view;
+uniform mat4 proj;
+out vec3 vFragPos;
+void main()
+{
+ vFragPos = vec3(model * vec4(aPos, 1.0));
+ gl_Position = proj * view * model * vec4(aPos, 1.0);
+}
diff --git a/apps/openmb/resources/shaders/depth.frag b/apps/openmb/resources/shaders/depth.frag
new file mode 100644
index 0000000..f6ba8e2
--- /dev/null
+++ b/apps/openmb/resources/shaders/depth.frag
@@ -0,0 +1,5 @@
+#version 330 core
+void main()
+{
+
+}
diff --git a/apps/openmb/resources/shaders/depth.vert b/apps/openmb/resources/shaders/depth.vert
new file mode 100644
index 0000000..e80ee01
--- /dev/null
+++ b/apps/openmb/resources/shaders/depth.vert
@@ -0,0 +1,10 @@
+#version 330 core
+layout(location = 0) in vec3 aPos;
+
+uniform mat4 model;
+uniform mat4 lightSpace;
+
+void main()
+{
+ gl_Position = lightSpace * model * vec4(aPos, 1.0);
+}
diff --git a/apps/openmb/resources/shaders/gbuffer.frag b/apps/openmb/resources/shaders/gbuffer.frag
new file mode 100644
index 0000000..f6ddb45
--- /dev/null
+++ b/apps/openmb/resources/shaders/gbuffer.frag
@@ -0,0 +1,10 @@
+#version 330 core
+in vec2 vUV;
+in vec3 vNormalView;
+layout(location = 0) out vec3 gNormal;
+
+void main()
+{
+ vec3 n = normalize(vNormalView);
+ gNormal = n * 0.5 + 0.5;
+}
diff --git a/apps/openmb/resources/shaders/gbuffer.vert b/apps/openmb/resources/shaders/gbuffer.vert
new file mode 100644
index 0000000..c9e677c
--- /dev/null
+++ b/apps/openmb/resources/shaders/gbuffer.vert
@@ -0,0 +1,19 @@
+#version 330 core
+layout(location = 0) in vec3 aPos;
+layout(location = 1) in vec2 aUV;
+layout(location = 2) in vec3 aNormal;
+
+uniform mat4 model;
+uniform mat4 view;
+uniform mat4 proj;
+
+out vec2 vUV;
+out vec3 vNormalView;
+
+void main()
+{
+ vUV = aUV;
+ vec4 viewPos = view * model * vec4(aPos, 1.0);
+ vNormalView = mat3(transpose(inverse(view * model))) * aNormal;
+ gl_Position = proj * viewPos;
+}
diff --git a/apps/openmb/resources/shaders/godrays_quad.vert b/apps/openmb/resources/shaders/godrays_quad.vert
new file mode 100644
index 0000000..6a33825
--- /dev/null
+++ b/apps/openmb/resources/shaders/godrays_quad.vert
@@ -0,0 +1,11 @@
+#version 330 core
+layout (location = 0) in vec3 aPos;
+layout (location = 1) in vec2 aTex;
+
+out vec2 vTex;
+
+void main()
+{
+ vTex = aTex;
+ gl_Position = vec4(aPos, 1.0);
+}
diff --git a/apps/openmb/resources/shaders/godrays_radial.frag b/apps/openmb/resources/shaders/godrays_radial.frag
new file mode 100644
index 0000000..3dfac87
--- /dev/null
+++ b/apps/openmb/resources/shaders/godrays_radial.frag
@@ -0,0 +1,44 @@
+#version 330 core
+in vec2 vTex;
+out vec4 FragColor;
+
+uniform sampler2D occlusionTex;
+uniform vec2 lightScreenPos; // in [0,1]
+uniform vec3 sunColor;
+uniform float sunIntensity;
+uniform float globalIntensity;
+uniform int samples;
+uniform float density;
+uniform float weight;
+uniform float decay;
+
+void main()
+{
+ vec2 texCoord = vTex;
+ // vector from current pixel to light
+ vec2 delta = lightScreenPos - texCoord;
+ float dist = length(delta);
+ vec2 stepv = delta * (1.0 / float(samples)) * density;
+
+ vec3 illumination = vec3(0.0);
+ float illumDecay = 1.0;
+
+ vec2 coord = texCoord;
+ for (int i = 0; i < samples; ++i)
+ {
+ coord += stepv;
+ vec3 sample = texture(occlusionTex, coord).rgb;
+ // occlusion tex stores white where geometry present
+ float occ = sample.r;
+ illumination += occ * illumDecay * weight;
+ illumDecay *= decay;
+ }
+
+ vec3 result = illumination * sunColor * sunIntensity * globalIntensity;
+ // tone-map / clamp to avoid extreme brightness
+ result = clamp(result, vec3(0.0), vec3(1.0));
+ // use luminance as alpha so we can composite less aggressively
+ float lum = dot(result, vec3(0.299, 0.587, 0.114));
+ float alpha = clamp(lum, 0.0, 1.0);
+ FragColor = vec4(result, alpha);
+}
diff --git a/apps/openmb/resources/shaders/occlusion.frag b/apps/openmb/resources/shaders/occlusion.frag
new file mode 100644
index 0000000..02a0732
--- /dev/null
+++ b/apps/openmb/resources/shaders/occlusion.frag
@@ -0,0 +1,8 @@
+#version 330 core
+out vec4 FragColor;
+
+void main()
+{
+ // Solid white occluder
+ FragColor = vec4(1.0);
+}
diff --git a/apps/openmb/resources/shaders/occlusion.vert b/apps/openmb/resources/shaders/occlusion.vert
new file mode 100644
index 0000000..9d95f3a
--- /dev/null
+++ b/apps/openmb/resources/shaders/occlusion.vert
@@ -0,0 +1,11 @@
+#version 330 core
+layout (location = 0) in vec3 aPos;
+
+uniform mat4 model;
+uniform mat4 view;
+uniform mat4 proj;
+
+void main()
+{
+ gl_Position = proj * view * model * vec4(aPos, 1.0);
+}
diff --git a/apps/openmb/resources/shaders/skybox.frag b/apps/openmb/resources/shaders/skybox.frag
new file mode 100644
index 0000000..f9e41eb
--- /dev/null
+++ b/apps/openmb/resources/shaders/skybox.frag
@@ -0,0 +1,8 @@
+#version 330 core
+in vec3 TexCoords;
+out vec4 FragColor;
+uniform samplerCube skybox;
+void main()
+{
+ FragColor = texture(skybox, TexCoords);
+}
diff --git a/apps/openmb/resources/shaders/skybox.vert b/apps/openmb/resources/shaders/skybox.vert
new file mode 100644
index 0000000..8e66a99
--- /dev/null
+++ b/apps/openmb/resources/shaders/skybox.vert
@@ -0,0 +1,10 @@
+#version 330 core
+layout(location = 0) in vec3 aPos;
+out vec3 TexCoords;
+uniform mat4 view;
+uniform mat4 proj;
+void main()
+{
+ TexCoords = aPos;
+ gl_Position = proj * view * vec4(aPos, 1.0);
+}
diff --git a/apps/openmb/resources/shaders/ssao.frag b/apps/openmb/resources/shaders/ssao.frag
new file mode 100644
index 0000000..60479f2
--- /dev/null
+++ b/apps/openmb/resources/shaders/ssao.frag
@@ -0,0 +1,76 @@
+#version 330 core
+in vec2 vUV;
+out float FragColor;
+
+uniform sampler2D gDepth;
+uniform sampler2D gNormal;
+uniform sampler2D texNoise;
+
+uniform vec3 samples[64];
+uniform mat4 proj;
+uniform mat4 invProj;
+uniform float radius;
+uniform float bias;
+uniform float noiseScale;
+
+uniform int kernelSize;
+uniform float power;
+
+vec3 getViewPos(vec2 uv)
+{
+ float depth = texture(gDepth, uv).r;
+ if (depth == 1.0) return vec3(0.0);
+ float z = depth * 2.0 - 1.0;
+ vec4 clip = vec4(uv * 2.0 - 1.0, z, 1.0);
+ vec4 viewPos = invProj * clip;
+ viewPos /= viewPos.w;
+ return viewPos.xyz;
+}
+
+void main()
+{
+ vec3 fragPos = getViewPos(vUV);
+ if (fragPos == vec3(0.0))
+ {
+ FragColor = 1.0;
+ return;
+ }
+
+ vec3 normal = texture(gNormal, vUV).rgb;
+ normal = normalize(normal * 2.0 - 1.0);
+
+ vec3 randomVec = normalize(texture(texNoise, vUV * noiseScale).xyz * 2.0 - 1.0);
+
+
+ vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
+ vec3 bitangent = cross(normal, tangent);
+ mat3 TBN = mat3(tangent, bitangent, normal);
+
+ float occlusion = 0.0;
+ for (int i = 0; i < kernelSize; ++i)
+ {
+ vec3 sample = TBN * samples[i];
+ sample = fragPos + sample * radius;
+
+
+ vec4 offset = proj * vec4(sample, 1.0);
+ offset.xyz /= offset.w;
+ vec2 sampleUV = offset.xy * 0.5 + 0.5;
+
+ if (sampleUV.x < 0.0 || sampleUV.x > 1.0 || sampleUV.y < 0.0 || sampleUV.y > 1.0)
+ continue;
+
+ vec3 samplePos = getViewPos(sampleUV);
+ if (samplePos == vec3(0.0))
+ continue;
+
+ float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - samplePos.z));
+ float diff = samplePos.z - sample.z;
+ if (diff > bias)
+ occlusion += rangeCheck;
+ }
+
+ occlusion = 1.0 - (occlusion / float(kernelSize));
+ occlusion = pow(occlusion, power);
+ FragColor = occlusion;
+}
diff --git a/apps/openmb/resources/shaders/ssao.vert b/apps/openmb/resources/shaders/ssao.vert
new file mode 100644
index 0000000..5afd1d3
--- /dev/null
+++ b/apps/openmb/resources/shaders/ssao.vert
@@ -0,0 +1,9 @@
+#version 330 core
+layout(location = 0) in vec2 aPos;
+layout(location = 1) in vec2 aUV;
+out vec2 vUV;
+void main()
+{
+ vUV = aUV;
+ gl_Position = vec4(aPos, 0.0, 1.0);
+}
diff --git a/apps/openmb/resources/shaders/ssao_blur.frag b/apps/openmb/resources/shaders/ssao_blur.frag
new file mode 100644
index 0000000..e093eff
--- /dev/null
+++ b/apps/openmb/resources/shaders/ssao_blur.frag
@@ -0,0 +1,45 @@
+#version 330 core
+in vec2 vUV;
+out float FragColor;
+
+uniform sampler2D ssaoInput;
+uniform vec2 texelSize;
+uniform int horizontal;
+
+
+const float w0 = 0.2270270270;
+const float w1 = 0.1945945946;
+const float w2 = 0.1216216216;
+const float w3 = 0.0540540541;
+const float w4 = 0.0162162162;
+
+void main()
+{
+ float result = 0.0;
+ if (horizontal == 1)
+ {
+ result += texture(ssaoInput, vUV).r * w0;
+ result += texture(ssaoInput, vUV + vec2(texelSize.x, 0.0)).r * w1;
+ result += texture(ssaoInput, vUV - vec2(texelSize.x, 0.0)).r * w1;
+ result += texture(ssaoInput, vUV + vec2(2.0 * texelSize.x, 0.0)).r * w2;
+ result += texture(ssaoInput, vUV - vec2(2.0 * texelSize.x, 0.0)).r * w2;
+ result += texture(ssaoInput, vUV + vec2(3.0 * texelSize.x, 0.0)).r * w3;
+ result += texture(ssaoInput, vUV - vec2(3.0 * texelSize.x, 0.0)).r * w3;
+ result += texture(ssaoInput, vUV + vec2(4.0 * texelSize.x, 0.0)).r * w4;
+ result += texture(ssaoInput, vUV - vec2(4.0 * texelSize.x, 0.0)).r * w4;
+ }
+ else
+ {
+ result += texture(ssaoInput, vUV).r * w0;
+ result += texture(ssaoInput, vUV + vec2(0.0, texelSize.y)).r * w1;
+ result += texture(ssaoInput, vUV - vec2(0.0, texelSize.y)).r * w1;
+ result += texture(ssaoInput, vUV + vec2(0.0, 2.0 * texelSize.y)).r * w2;
+ result += texture(ssaoInput, vUV - vec2(0.0, 2.0 * texelSize.y)).r * w2;
+ result += texture(ssaoInput, vUV + vec2(0.0, 3.0 * texelSize.y)).r * w3;
+ result += texture(ssaoInput, vUV - vec2(0.0, 3.0 * texelSize.y)).r * w3;
+ result += texture(ssaoInput, vUV + vec2(0.0, 4.0 * texelSize.y)).r * w4;
+ result += texture(ssaoInput, vUV - vec2(0.0, 4.0 * texelSize.y)).r * w4;
+ }
+
+ FragColor = result;
+}
diff --git a/apps/openmb/resources/shaders/textured.frag b/apps/openmb/resources/shaders/textured.frag
new file mode 100644
index 0000000..ea5e207
--- /dev/null
+++ b/apps/openmb/resources/shaders/textured.frag
@@ -0,0 +1,45 @@
+#version 330 core
+
+in vec2 vUV;
+out vec4 FragColor;
+
+uniform sampler2D albedo;
+uniform sampler2D normalMap;
+uniform int normalEnabled;
+uniform float normalStrength;
+uniform vec3 tint;
+uniform int radialEnabled;
+uniform float radialInner;
+uniform float radialOuter;
+
+void main()
+{
+ vec4 tex = texture(albedo, vUV);
+ vec3 color = tex.rgb * tint;
+ float alpha = tex.a;
+ vec3 finalNormal = vec3(0.0, 0.0, 1.0);
+ if (normalEnabled == 1)
+ {
+ vec3 n = texture(normalMap, vUV).rgb;
+ n = n * 2.0 - 1.0;
+ finalNormal = normalize(vec3(n.x * normalStrength, n.y * normalStrength, 1.0));
+ }
+ if (radialEnabled == 1)
+ {
+
+ float dist = distance(vUV, vec2(0.5, 0.5));
+
+ float mask = 1.0 - smoothstep(radialInner, radialOuter, dist);
+ alpha *= mask;
+ }
+
+ if (normalEnabled == 1)
+ {
+ vec3 lightDir = normalize(vec3(0.3, 1.0, 0.5));
+ float l = max(dot(normalize(finalNormal), lightDir), 0.0);
+
+ color *= (0.4 + 0.6 * l);
+ }
+
+ FragColor = vec4(color, alpha);
+}
diff --git a/apps/openmb/resources/shaders/textured.vert b/apps/openmb/resources/shaders/textured.vert
new file mode 100644
index 0000000..f71f407
--- /dev/null
+++ b/apps/openmb/resources/shaders/textured.vert
@@ -0,0 +1,23 @@
+#version 330 core
+layout(location = 0) in vec3 aPos;
+layout(location = 1) in vec2 aUV;
+layout(location = 2) in vec3 aNormal;
+
+uniform mat4 model;
+uniform mat4 view;
+uniform mat4 proj;
+uniform mat4 lightSpace;
+
+out vec2 vUV;
+out vec3 vNormal;
+out vec3 vFragPos;
+out vec4 vFragPosLightSpace;
+
+void main()
+{
+ vUV = aUV;
+ vFragPos = vec3(model * vec4(aPos, 1.0));
+ vNormal = mat3(transpose(inverse(model))) * aNormal;
+ vFragPosLightSpace = lightSpace * vec4(vFragPos, 1.0);
+ gl_Position = proj * view * model * vec4(aPos, 1.0);
+}
diff --git a/apps/openmb/resources/shaders/textured_lit.frag b/apps/openmb/resources/shaders/textured_lit.frag
new file mode 100644
index 0000000..58c71f7
--- /dev/null
+++ b/apps/openmb/resources/shaders/textured_lit.frag
@@ -0,0 +1,121 @@
+#version 330 core
+
+in vec2 vUV;
+in vec3 vNormal;
+in vec3 vFragPos;
+in vec4 vFragPosLightSpace;
+out vec4 FragColor;
+
+uniform sampler2D albedo;
+uniform sampler2D normalMap;
+uniform int normalEnabled;
+uniform float normalStrength;
+uniform vec3 tint;
+uniform int radialEnabled;
+uniform float radialInner;
+uniform float radialOuter;
+
+struct DirectionalLight
+{
+ vec3 direction;
+ vec3 color;
+ float intensity;
+};
+
+uniform DirectionalLight dirLight;
+uniform vec3 ambientColor = vec3(0.15, 0.15, 0.15);
+uniform sampler2D shadowMap;
+uniform float shadowBiasMin;
+uniform float shadowBiasScale;
+uniform int pcfRadius;
+uniform sampler2D ssao;
+uniform float aoStrength;
+uniform float screenWidth;
+uniform float screenHeight;
+
+// Fog
+uniform vec3 cameraPos;
+uniform vec3 fogColor;
+uniform float fogDensity; // e.g. 0.02
+uniform float fogAmount; // 0..1 blend factor
+float ShadowCalculation(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir)
+{
+
+ vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
+
+ projCoords = projCoords * 0.5 + 0.5;
+
+ if (projCoords.z > 1.0)
+ return 0.0;
+
+
+ float currentDepth = projCoords.z;
+
+ float bias = max(shadowBiasScale * (1.0 - max(dot(normal, lightDir), 0.0)), shadowBiasMin);
+
+
+ ivec2 texSize = textureSize(shadowMap, 0);
+ vec2 texelSize = 1.0 / vec2(texSize);
+ float vis = 0.0;
+ int samples = 0;
+ for (int x = -pcfRadius; x <= pcfRadius; ++x)
+ {
+ for (int y = -pcfRadius; y <= pcfRadius; ++y)
+ {
+ vec2 offset = vec2(x, y) * texelSize;
+ float depthSample = texture(shadowMap, projCoords.xy + offset).r;
+ // texture returns stored light-space depth. If our fragment's depth (minus bias)
+ // is less than or equal to the sampled depth, it's visible to the light.
+ vis += (currentDepth - bias <= depthSample) ? 1.0 : 0.0;
+ samples++;
+ }
+ }
+ float visibility = vis / float(samples);
+ float shadow = 1.0 - visibility;
+ return shadow;
+}
+
+void main()
+{
+ vec4 tex = texture(albedo, vUV);
+ vec3 color = tex.rgb * tint;
+ float alpha = tex.a;
+ vec3 finalNormal = vec3(0.0, 0.0, 1.0);
+ if (normalEnabled == 1)
+ {
+ vec3 n = texture(normalMap, vUV).rgb;
+ n = n * 2.0 - 1.0;
+ finalNormal = normalize(vec3(n.x * normalStrength, n.y * normalStrength, 1.0));
+ }
+ if (radialEnabled == 1)
+ {
+ float dist = distance(vUV, vec2(0.5, 0.5));
+ float mask = 1.0 - smoothstep(radialInner, radialOuter, dist);
+ alpha *= mask;
+ }
+
+
+ vec3 N = normalize(finalNormal);
+ vec3 L = normalize(dirLight.direction);
+ float diff = max(dot(N, L), 0.0);
+ vec3 diffuse = dirLight.color * dirLight.intensity * diff;
+
+ float shadow = ShadowCalculation(vFragPosLightSpace, N, L);
+ float shadowFactor = 1.0 - shadow * 0.9;
+ float ao = 1.0;
+ if (aoStrength > 0.0)
+ {
+ vec2 ssaoUV = gl_FragCoord.xy / vec2(screenWidth, screenHeight);
+ ao = texture(ssao, ssaoUV).r;
+ }
+ float aoFactor = mix(1.0, ao, aoStrength);
+ vec3 result = color * (ambientColor * aoFactor + diffuse * shadowFactor);
+
+ // Compute fog based on distance from camera
+ float dist = length(vFragPos - cameraPos);
+ float fogFactor = 1.0 - exp(-fogDensity * dist);
+ fogFactor = clamp(fogFactor * fogAmount, 0.0, 1.0);
+ vec3 finalColor = mix(result, fogColor, fogFactor);
+
+ FragColor = vec4(finalColor, alpha);
+}
diff --git a/apps/openmb/resources/skybox/Daylight-Back.bmp b/apps/openmb/resources/skybox/Daylight-Back.bmp
new file mode 100644
index 0000000..1b6c44e
--- /dev/null
+++ b/apps/openmb/resources/skybox/Daylight-Back.bmp
Binary files differ
diff --git a/apps/openmb/resources/skybox/Daylight-Bottom.bmp b/apps/openmb/resources/skybox/Daylight-Bottom.bmp
new file mode 100644
index 0000000..4e36683
--- /dev/null
+++ b/apps/openmb/resources/skybox/Daylight-Bottom.bmp
Binary files differ
diff --git a/apps/openmb/resources/skybox/Daylight-Front.bmp b/apps/openmb/resources/skybox/Daylight-Front.bmp
new file mode 100644
index 0000000..571df47
--- /dev/null
+++ b/apps/openmb/resources/skybox/Daylight-Front.bmp
Binary files differ
diff --git a/apps/openmb/resources/skybox/Daylight-Left.bmp b/apps/openmb/resources/skybox/Daylight-Left.bmp
new file mode 100644
index 0000000..b3954a3
--- /dev/null
+++ b/apps/openmb/resources/skybox/Daylight-Left.bmp
Binary files differ
diff --git a/apps/openmb/resources/skybox/Daylight-Right.bmp b/apps/openmb/resources/skybox/Daylight-Right.bmp
new file mode 100644
index 0000000..48c6433
--- /dev/null
+++ b/apps/openmb/resources/skybox/Daylight-Right.bmp
Binary files differ
diff --git a/apps/openmb/resources/skybox/Daylight-Top.bmp b/apps/openmb/resources/skybox/Daylight-Top.bmp
new file mode 100644
index 0000000..f949f7f
--- /dev/null
+++ b/apps/openmb/resources/skybox/Daylight-Top.bmp
Binary files differ
diff --git a/apps/openmb/resources/textures/brush/basic/blue.tga b/apps/openmb/resources/textures/brush/basic/blue.tga
new file mode 100644
index 0000000..a731a65
--- /dev/null
+++ b/apps/openmb/resources/textures/brush/basic/blue.tga
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/dark/texture_01.png b/apps/openmb/resources/textures/testing/dark/texture_01.png
new file mode 100644
index 0000000..69be211
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/dark/texture_01.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/dark/texture_02.png b/apps/openmb/resources/textures/testing/dark/texture_02.png
new file mode 100644
index 0000000..6fb471b
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/dark/texture_02.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/dark/texture_03.png b/apps/openmb/resources/textures/testing/dark/texture_03.png
new file mode 100644
index 0000000..3f8b186
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/dark/texture_03.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/dark/texture_04.png b/apps/openmb/resources/textures/testing/dark/texture_04.png
new file mode 100644
index 0000000..e2bc22b
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/dark/texture_04.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/dark/texture_05.png b/apps/openmb/resources/textures/testing/dark/texture_05.png
new file mode 100644
index 0000000..3fd2e56
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/dark/texture_05.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/dark/texture_06.png b/apps/openmb/resources/textures/testing/dark/texture_06.png
new file mode 100644
index 0000000..45d4a34
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/dark/texture_06.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/dark/texture_07.png b/apps/openmb/resources/textures/testing/dark/texture_07.png
new file mode 100644
index 0000000..adf5e6f
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/dark/texture_07.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/dark/texture_08.png b/apps/openmb/resources/textures/testing/dark/texture_08.png
new file mode 100644
index 0000000..a5a9f24
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/dark/texture_08.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/dark/texture_09.png b/apps/openmb/resources/textures/testing/dark/texture_09.png
new file mode 100644
index 0000000..57cc607
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/dark/texture_09.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/dark/texture_10.png b/apps/openmb/resources/textures/testing/dark/texture_10.png
new file mode 100644
index 0000000..4c737d0
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/dark/texture_10.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/dark/texture_11.png b/apps/openmb/resources/textures/testing/dark/texture_11.png
new file mode 100644
index 0000000..424ba71
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/dark/texture_11.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/dark/texture_12.png b/apps/openmb/resources/textures/testing/dark/texture_12.png
new file mode 100644
index 0000000..32169db
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/dark/texture_12.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/dark/texture_13.png b/apps/openmb/resources/textures/testing/dark/texture_13.png
new file mode 100644
index 0000000..13c4388
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/dark/texture_13.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/light/texture_01.png b/apps/openmb/resources/textures/testing/light/texture_01.png
new file mode 100644
index 0000000..60b632b
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/light/texture_01.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/light/texture_02.png b/apps/openmb/resources/textures/testing/light/texture_02.png
new file mode 100644
index 0000000..19aad62
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/light/texture_02.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/light/texture_03.png b/apps/openmb/resources/textures/testing/light/texture_03.png
new file mode 100644
index 0000000..a8a6c06
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/light/texture_03.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/light/texture_04.png b/apps/openmb/resources/textures/testing/light/texture_04.png
new file mode 100644
index 0000000..b8270e1
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/light/texture_04.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/light/texture_05.png b/apps/openmb/resources/textures/testing/light/texture_05.png
new file mode 100644
index 0000000..5b985bf
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/light/texture_05.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/light/texture_06.png b/apps/openmb/resources/textures/testing/light/texture_06.png
new file mode 100644
index 0000000..195ad77
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/light/texture_06.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/light/texture_07.png b/apps/openmb/resources/textures/testing/light/texture_07.png
new file mode 100644
index 0000000..fbf92e0
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/light/texture_07.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/light/texture_08.png b/apps/openmb/resources/textures/testing/light/texture_08.png
new file mode 100644
index 0000000..72e1a07
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/light/texture_08.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/light/texture_09.png b/apps/openmb/resources/textures/testing/light/texture_09.png
new file mode 100644
index 0000000..9ada5dd
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/light/texture_09.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/light/texture_10.png b/apps/openmb/resources/textures/testing/light/texture_10.png
new file mode 100644
index 0000000..4fbcc80
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/light/texture_10.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/light/texture_11.png b/apps/openmb/resources/textures/testing/light/texture_11.png
new file mode 100644
index 0000000..840ecec
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/light/texture_11.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/light/texture_12.png b/apps/openmb/resources/textures/testing/light/texture_12.png
new file mode 100644
index 0000000..25c2e78
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/light/texture_12.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/light/texture_13.png b/apps/openmb/resources/textures/testing/light/texture_13.png
new file mode 100644
index 0000000..a235965
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/light/texture_13.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/orange/texture_01.png b/apps/openmb/resources/textures/testing/orange/texture_01.png
new file mode 100644
index 0000000..4f5bf92
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/orange/texture_01.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/orange/texture_02.png b/apps/openmb/resources/textures/testing/orange/texture_02.png
new file mode 100644
index 0000000..dec5b59
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/orange/texture_02.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/orange/texture_03.png b/apps/openmb/resources/textures/testing/orange/texture_03.png
new file mode 100644
index 0000000..666197f
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/orange/texture_03.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/orange/texture_04.png b/apps/openmb/resources/textures/testing/orange/texture_04.png
new file mode 100644
index 0000000..23d6fc4
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/orange/texture_04.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/orange/texture_05.png b/apps/openmb/resources/textures/testing/orange/texture_05.png
new file mode 100644
index 0000000..1e0448a
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/orange/texture_05.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/orange/texture_06.png b/apps/openmb/resources/textures/testing/orange/texture_06.png
new file mode 100644
index 0000000..5486825
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/orange/texture_06.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/orange/texture_07.png b/apps/openmb/resources/textures/testing/orange/texture_07.png
new file mode 100644
index 0000000..95f2790
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/orange/texture_07.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/orange/texture_08.png b/apps/openmb/resources/textures/testing/orange/texture_08.png
new file mode 100644
index 0000000..5a500d9
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/orange/texture_08.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/orange/texture_09.png b/apps/openmb/resources/textures/testing/orange/texture_09.png
new file mode 100644
index 0000000..adcfa33
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/orange/texture_09.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/orange/texture_10.png b/apps/openmb/resources/textures/testing/orange/texture_10.png
new file mode 100644
index 0000000..aa227e5
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/orange/texture_10.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/orange/texture_11.png b/apps/openmb/resources/textures/testing/orange/texture_11.png
new file mode 100644
index 0000000..dc94567
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/orange/texture_11.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/orange/texture_12.png b/apps/openmb/resources/textures/testing/orange/texture_12.png
new file mode 100644
index 0000000..b730544
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/orange/texture_12.png
Binary files differ
diff --git a/apps/openmb/resources/textures/testing/orange/texture_13.png b/apps/openmb/resources/textures/testing/orange/texture_13.png
new file mode 100644
index 0000000..01f4aa8
--- /dev/null
+++ b/apps/openmb/resources/textures/testing/orange/texture_13.png
Binary files differ
diff --git a/apps/openmb/scene/Camera.cpp b/apps/openmb/scene/Camera.cpp
new file mode 100644
index 0000000..d3a3e7d
--- /dev/null
+++ b/apps/openmb/scene/Camera.cpp
@@ -0,0 +1,203 @@
+#include "Camera.hpp"
+
+#include <algorithm>
+#include <glm/gtc/matrix_transform.hpp>
+#include <vector>
+
+namespace scene {
+Camera::Camera ()
+ : mPosition( 0.0f, 0.0f, 3.0f ), mFront( 0.0f, 0.0f, -1.0f ), mWorldUp( 0.0f, 1.0f, 0.0f ), mYaw( -90.0f ),
+ mPitch( 0.0f ), mMovementSpeed( 3.0f ), mMouseSensitivity( 0.1f ), mFov( 60.0f ),
+ mVelocity( 0.0f, 0.0f, 0.0f ), mFlying( true ), mGrounded( false ), mSpeedMultiplier( 1.0f ) {
+ updateCameraVectors();
+}
+
+Camera::Camera ( const glm::vec3& position, const glm::vec3& up, float yaw, float pitch )
+ : mPosition( position ), mWorldUp( up ), mYaw( yaw ), mPitch( pitch ), mMovementSpeed( 3.0f ),
+ mMouseSensitivity( 0.1f ), mFov( 60.0f ), mVelocity( 0.0f, 0.0f, 0.0f ), mFlying( true ), mGrounded( false ),
+ mSpeedMultiplier( 1.0f ) {
+ mFront = glm::vec3( 0.0f, 0.0f, -1.0f );
+ updateCameraVectors();
+}
+
+glm::mat4 Camera::getViewMatrix () const {
+ return glm::lookAt( mPosition, mPosition + mFront, mUp );
+}
+
+glm::mat4 Camera::getProjectionMatrix ( float aspect ) const {
+ return glm::perspective( glm::radians( mFov ), aspect, 0.1f, 100.0f );
+}
+
+void Camera::processKeyboard ( Movement dir, float deltaTime ) {
+ float velocity = mMovementSpeed * mSpeedMultiplier * deltaTime;
+
+ glm::vec3 moveForward = mFront;
+ glm::vec3 moveRight = mRight;
+ if( !mFlying ) {
+ moveForward.y = 0.0f;
+ if( glm::length( moveForward ) < 1e-6f )
+ moveForward = glm::vec3( 0.0f, 0.0f, -1.0f );
+ moveForward = glm::normalize( moveForward );
+ moveRight = glm::normalize( glm::cross( moveForward, mWorldUp ) );
+ }
+
+ if( dir == Movement::Forward )
+ mPosition += moveForward * velocity;
+ if( dir == Movement::Backward )
+ mPosition -= moveForward * velocity;
+ if( dir == Movement::Left )
+ mPosition -= moveRight * velocity;
+ if( dir == Movement::Right )
+ mPosition += moveRight * velocity;
+ if( dir == Movement::Up && mFlying )
+ mPosition += mWorldUp * velocity;
+ if( dir == Movement::Down && mFlying )
+ mPosition -= mWorldUp * velocity;
+}
+
+void Camera::toggleFly () {
+ mFlying = !mFlying;
+ if( mFlying ) {
+
+ mVelocity.y = 0.0f;
+ }
+}
+
+void Camera::setSpeedMultiplier ( float m ) {
+ mSpeedMultiplier = m;
+}
+
+static bool aabbOverlap ( const glm::vec3& amin, const glm::vec3& amax, const glm::vec3& bmin,
+ const glm::vec3& bmax ) {
+ return ( amin.x <= bmax.x && amax.x >= bmin.x ) && ( amin.y <= bmax.y && amax.y >= bmin.y ) &&
+ ( amin.z <= bmax.z && amax.z >= bmin.z );
+}
+
+void Camera::updatePhysics ( float deltaTime, const std::vector<std::pair<glm::vec3, glm::vec3>>& worldAABBs,
+ float floorY ) {
+ const glm::vec3 halfExtents( 0.3f, 0.9f, 0.3f );
+
+ if( mFlying ) {
+ mGrounded = false;
+ return;
+ }
+
+ if( !mFlying ) {
+ const float gravity = -9.8f;
+ mVelocity.y += gravity * deltaTime;
+ if( mVelocity.y < -50.0f )
+ mVelocity.y = -50.0f;
+ }
+
+ glm::vec3 newPos = mPosition + mVelocity * deltaTime;
+
+ float camBottom = newPos.y - halfExtents.y;
+ if( camBottom < floorY ) {
+ newPos.y = floorY + halfExtents.y;
+ mVelocity.y = 0.0f;
+ mGrounded = true;
+ } else {
+ mGrounded = false;
+ }
+
+ for( const auto& box : worldAABBs ) {
+ glm::vec3 bmin = box.first;
+ glm::vec3 bmax = box.second;
+
+ glm::vec3 camMin = newPos - halfExtents;
+ glm::vec3 camMax = newPos + halfExtents;
+
+ if( !aabbOverlap( camMin, camMax, bmin, bmax ) )
+ continue;
+
+ float ox = std::min( camMax.x, bmax.x ) - std::max( camMin.x, bmin.x );
+ float oy = std::min( camMax.y, bmax.y ) - std::max( camMin.y, bmin.y );
+ float oz = std::min( camMax.z, bmax.z ) - std::max( camMin.z, bmin.z );
+
+ if( ox <= oy && ox <= oz ) {
+
+ float boxCenterX = ( bmin.x + bmax.x ) * 0.5f;
+ if( newPos.x < boxCenterX )
+ newPos.x -= ox;
+ else
+ newPos.x += ox;
+ } else if( oy <= ox && oy <= oz ) {
+ float boxCenterY = ( bmin.y + bmax.y ) * 0.5f;
+ if( newPos.y < boxCenterY ) {
+ newPos.y -= oy;
+ mVelocity.y = 0.0f;
+ } else {
+ newPos.y += oy;
+ mVelocity.y = 0.0f;
+ mGrounded = true;
+ }
+ } else {
+ float boxCenterZ = ( bmin.z + bmax.z ) * 0.5f;
+ if( newPos.z < boxCenterZ )
+ newPos.z -= oz;
+ else
+ newPos.z += oz;
+ }
+ }
+
+ mPosition = newPos;
+}
+
+void Camera::jump () {
+ if( mFlying )
+ return;
+ if( mGrounded ) {
+ const float jumpImpulse = 5.0f;
+ mVelocity.y = jumpImpulse;
+ mGrounded = false;
+ }
+}
+
+bool Camera::isFlying () const {
+ return mFlying;
+}
+
+bool Camera::isGrounded () const {
+ return mGrounded;
+}
+
+float Camera::getSpeedMultiplier () const {
+ return mSpeedMultiplier;
+}
+
+void Camera::processMouseMovement ( float xoffset, float yoffset, bool constrainPitch ) {
+ xoffset *= mMouseSensitivity;
+ yoffset *= mMouseSensitivity;
+
+ mYaw += xoffset;
+ mPitch += yoffset;
+
+ if( constrainPitch ) {
+ if( mPitch > 89.0f )
+ mPitch = 89.0f;
+ if( mPitch < -89.0f )
+ mPitch = -89.0f;
+ }
+
+ updateCameraVectors();
+}
+
+void Camera::processMouseScroll ( float yoffset ) {
+ mFov -= yoffset;
+ if( mFov < 1.0f )
+ mFov = 1.0f;
+ if( mFov > 90.0f )
+ mFov = 90.0f;
+}
+
+void Camera::updateCameraVectors () {
+ glm::vec3 front;
+ front.x = cos( glm::radians( mYaw ) ) * cos( glm::radians( mPitch ) );
+ front.y = sin( glm::radians( mPitch ) );
+ front.z = sin( glm::radians( mYaw ) ) * cos( glm::radians( mPitch ) );
+ mFront = glm::normalize( front );
+ mRight = glm::normalize( glm::cross( mFront, mWorldUp ) );
+ mUp = glm::normalize( glm::cross( mRight, mFront ) );
+}
+
+} // namespace scene
diff --git a/apps/openmb/scene/Camera.hpp b/apps/openmb/scene/Camera.hpp
new file mode 100644
index 0000000..7c5edc7
--- /dev/null
+++ b/apps/openmb/scene/Camera.hpp
@@ -0,0 +1,69 @@
+#pragma once
+
+#include <glm/glm.hpp>
+#include <utility>
+#include <vector>
+
+namespace scene {
+enum class Movement {
+ Forward,
+ Backward,
+ Left,
+ Right,
+ Up,
+ Down
+};
+
+class Camera {
+ public:
+ Camera();
+ Camera( const glm::vec3& position, const glm::vec3& up, float yaw, float pitch );
+
+ glm::mat4 getViewMatrix() const;
+ glm::mat4 getProjectionMatrix( float aspect ) const;
+
+ void processKeyboard( Movement dir, float deltaTime );
+ void processMouseMovement( float xoffset, float yoffset, bool constrainPitch = true );
+ void processMouseScroll( float yoffset );
+
+ void toggleFly();
+ void setSpeedMultiplier( float m );
+ void jump();
+
+ bool isFlying() const;
+ bool isGrounded() const;
+ float getSpeedMultiplier() const;
+
+ void updatePhysics( float deltaTime, const std::vector<std::pair<glm::vec3, glm::vec3>>& worldAABBs,
+ float floorY = 0.0f );
+
+ glm::vec3 position () const { return mPosition; }
+
+ float getPitch () const { return mPitch; }
+
+ float getYaw () const { return mYaw; }
+
+ private:
+ void updateCameraVectors();
+
+ private:
+ glm::vec3 mPosition;
+ glm::vec3 mFront;
+ glm::vec3 mUp;
+ glm::vec3 mRight;
+ glm::vec3 mWorldUp;
+
+ float mYaw;
+ float mPitch;
+
+ float mMovementSpeed;
+ float mMouseSensitivity;
+ float mFov;
+
+ glm::vec3 mVelocity;
+ bool mFlying;
+ bool mGrounded;
+ float mSpeedMultiplier;
+};
+
+} // namespace scene
diff --git a/apps/openmb/scene/GridSystem.cpp b/apps/openmb/scene/GridSystem.cpp
new file mode 100644
index 0000000..273cb02
--- /dev/null
+++ b/apps/openmb/scene/GridSystem.cpp
@@ -0,0 +1,121 @@
+#include "GridSystem.hpp"
+
+#include <cmath>
+
+namespace scene {
+GridSystem::GridSystem ()
+ : mCellSize( 1.0f ), mFloorY( 0.0f ), mGridWidth( 1000 ), mGridDepth( 1000 ), mWallHeight( 4 ) {
+}
+
+float GridSystem::getCellSize () const {
+ return mCellSize;
+}
+
+float GridSystem::getFloorY () const {
+ return mFloorY;
+}
+
+int GridSystem::getGridWidth () const {
+ return mGridWidth;
+}
+
+int GridSystem::getGridDepth () const {
+ return mGridDepth;
+}
+
+int GridSystem::getWallHeight () const {
+ return mWallHeight;
+}
+
+glm::vec3 GridSystem::gridToWorld ( int gridX, int gridZ, float y ) const {
+ float halfW = mGridWidth * 0.5f;
+ float halfD = mGridDepth * 0.5f;
+
+ float worldX = ( gridX - halfW ) * mCellSize + mCellSize * 0.5f;
+ float worldZ = ( gridZ - halfD ) * mCellSize + mCellSize * 0.5f;
+
+ return glm::vec3( worldX, y, worldZ );
+}
+
+glm::vec3 GridSystem::gridToWorldFloor ( int gridX, int gridZ ) const {
+ return gridToWorld( gridX, gridZ, mFloorY );
+}
+
+bool GridSystem::worldToGrid ( const glm::vec3& worldPos, int& outGridX, int& outGridZ ) const {
+ float halfW = mGridWidth * 0.5f;
+ float halfD = mGridDepth * 0.5f;
+
+ float localX = worldPos.x / mCellSize + halfW - 0.5f;
+ float localZ = worldPos.z / mCellSize + halfD - 0.5f;
+
+ outGridX = static_cast<int>( std::floor( localX ) );
+ outGridZ = static_cast<int>( std::floor( localZ ) );
+
+ return ( outGridX >= 0 && outGridX < mGridWidth && outGridZ >= 0 && outGridZ < mGridDepth );
+}
+
+glm::vec3 GridSystem::getCellCenter ( int gridX, int gridZ, int cellY ) const {
+ float y = mFloorY + cellY * mCellSize + mCellSize * 0.5f;
+ return gridToWorld( gridX, gridZ, y );
+}
+
+float GridSystem::getMinWorldX () const {
+ float halfW = mGridWidth * 0.5f;
+ return ( 0 - halfW ) * mCellSize;
+}
+
+float GridSystem::getMaxWorldX () const {
+ float halfW = mGridWidth * 0.5f;
+ return ( mGridWidth - 1 - halfW ) * mCellSize + mCellSize;
+}
+
+float GridSystem::getMinWorldZ () const {
+ float halfD = mGridDepth * 0.5f;
+ return ( 0 - halfD ) * mCellSize;
+}
+
+float GridSystem::getMaxWorldZ () const {
+ float halfD = mGridDepth * 0.5f;
+ return ( mGridDepth - 1 - halfD ) * mCellSize + mCellSize;
+}
+
+float GridSystem::getHalfWidth () const {
+ return mGridWidth * 0.5f;
+}
+
+float GridSystem::getHalfDepth () const {
+ return mGridDepth * 0.5f;
+}
+
+float GridSystem::getFrontWallZ () const {
+ float halfD = mGridDepth * 0.5f;
+ return ( 0 - halfD ) * mCellSize + mCellSize * 0.5f;
+}
+
+float GridSystem::getBackWallZ () const {
+ float halfD = mGridDepth * 0.5f;
+ return ( mGridDepth - 1 - halfD ) * mCellSize + mCellSize * 0.5f;
+}
+
+float GridSystem::getLeftWallX () const {
+ float halfW = mGridWidth * 0.5f;
+ return ( 0 - halfW ) * mCellSize + mCellSize * 0.5f;
+}
+
+float GridSystem::getRightWallX () const {
+ float halfW = mGridWidth * 0.5f;
+ return ( mGridWidth - 1 - halfW ) * mCellSize + mCellSize * 0.5f;
+}
+
+float GridSystem::getWallMinY () const {
+ return mFloorY;
+}
+
+float GridSystem::getWallMaxY () const {
+ return mFloorY + mWallHeight * mCellSize;
+}
+
+float GridSystem::getWallBaseY () const {
+ return mFloorY + mCellSize;
+}
+} // namespace scene
diff --git a/apps/openmb/scene/GridSystem.hpp b/apps/openmb/scene/GridSystem.hpp
new file mode 100644
index 0000000..7fff5d2
--- /dev/null
+++ b/apps/openmb/scene/GridSystem.hpp
@@ -0,0 +1,66 @@
+#ifndef OPENMB_APPS_OPENMB_SCENE_GRIDSYSTEM_H
+#define OPENMB_APPS_OPENMB_SCENE_GRIDSYSTEM_H
+
+#include <glm/glm.hpp>
+
+namespace scene {
+
+class GridSystem {
+ public:
+ GridSystem();
+ ~GridSystem() = default;
+
+ float getCellSize() const;
+
+ float getFloorY() const;
+
+ int getGridWidth() const;
+
+ int getGridDepth() const;
+
+ int getWallHeight() const;
+
+ glm::vec3 gridToWorld( int gridX, int gridZ, float y ) const;
+
+ glm::vec3 gridToWorldFloor( int gridX, int gridZ ) const;
+
+ bool worldToGrid( const glm::vec3& worldPos, int& outGridX, int& outGridZ ) const;
+
+ glm::vec3 getCellCenter( int gridX, int gridZ, int cellY ) const;
+
+ float getMinWorldX() const;
+
+ float getMaxWorldX() const;
+
+ float getMinWorldZ() const;
+
+ float getMaxWorldZ() const;
+
+ float getHalfWidth() const;
+
+ float getHalfDepth() const;
+
+ float getFrontWallZ() const;
+
+ float getBackWallZ() const;
+
+ float getLeftWallX() const;
+
+ float getRightWallX() const;
+
+ float getWallMinY() const;
+
+ float getWallMaxY() const;
+
+ float getWallBaseY() const;
+
+ private:
+ float mCellSize;
+ float mFloorY;
+ int mGridWidth;
+ int mGridDepth;
+ int mWallHeight;
+};
+} // namespace scene
+
+#endif
diff --git a/apps/openmb/scene/VoxelEditor.cpp b/apps/openmb/scene/VoxelEditor.cpp
new file mode 100644
index 0000000..b113580
--- /dev/null
+++ b/apps/openmb/scene/VoxelEditor.cpp
@@ -0,0 +1,602 @@
+#include "VoxelEditor.hpp"
+
+#include "GridSystem.hpp"
+
+#include <algorithm>
+#include <cmath>
+#include <fstream>
+
+#include <nlohmann/json.hpp>
+
+namespace scene {
+VoxelEditor::VoxelEditor ( const GridSystem& gridSystem )
+ : mGridSystem( gridSystem ), mPlacedSet(), mPlacedList(), mCellTextureIds(), mCellCollidable(), mUndoStack(),
+ mRedoStack(), mPlacedModels(), mDragging( false ), mDragButton( -1 ), mDragStartCell( 0 ), mPreviewCells(),
+ mPrevLeftDown( false ), mPrevRightDown( false ) {
+}
+
+void VoxelEditor::addModelInstance ( const ModelInstance& mi ) {
+
+ Action action;
+ Action::ModelInstance ami;
+ ami.modelIndex = mi.modelIndex;
+ ami.pos = mi.pos;
+ ami.yaw = mi.yaw;
+ ami.scale = mi.scale;
+ ami.mCollidable = mi.mCollidable;
+ action.mAddedModels.push_back( ami );
+ mPlacedModels.push_back( mi );
+
+ mUndoStack.push_back( action );
+ if( mUndoStack.size() > mMaxUndoSteps )
+ mUndoStack.erase( mUndoStack.begin() );
+ mRedoStack.clear();
+}
+
+const std::vector<VoxelEditor::ModelInstance>& VoxelEditor::getPlacedModels () const {
+ return mPlacedModels;
+}
+
+void VoxelEditor::processInput ( const glm::vec3& rayOrigin, const glm::vec3& rayDir, bool leftMouseDown,
+ bool rightMouseDown, bool shiftPressed,
+ const std::vector<std::pair<glm::vec3, glm::vec3>>& baseWorldBoxes,
+ int currentTextureId, bool placeCollidable ) {
+ bool hitExisting = false;
+ float bestT = FLT_MAX;
+ glm::ivec3 hitCell( 0 );
+ glm::vec3 hitNormal( 0.0f );
+
+ for( const auto& c : mPlacedList ) {
+ auto aabb = cellToAABB( c );
+ float t = 0.0f;
+ if( rayAABBIntersect( rayOrigin, rayDir, aabb.first, aabb.second, t ) ) {
+ if( t >= 0.0f && t < bestT ) {
+ bestT = t;
+ hitExisting = true;
+ hitCell = c;
+ glm::vec3 hitPoint = rayOrigin + rayDir * t;
+ glm::vec3 center = ( aabb.first + aabb.second ) * 0.5f;
+ glm::vec3 diff = hitPoint - center;
+ glm::vec3 ad = glm::abs( diff );
+ if( ad.x > ad.y && ad.x > ad.z )
+ hitNormal = glm::vec3( diff.x > 0.0f ? 1.0f : -1.0f, 0.0f, 0.0f );
+ else if( ad.y > ad.x && ad.y > ad.z )
+ hitNormal = glm::vec3( 0.0f, diff.y > 0.0f ? 1.0f : -1.0f, 0.0f );
+ else
+ hitNormal = glm::vec3( 0.0f, 0.0f, diff.z > 0.0f ? 1.0f : -1.0f );
+ }
+ }
+ }
+
+ glm::ivec3 placeCell( 0 );
+ bool validHit = false;
+
+ if( !hitExisting ) {
+ float wallT = FLT_MAX;
+ glm::vec3 wallHitPoint( 0.0f );
+ glm::vec3 wallHitNormal( 0.0f );
+ bool hitWall = false;
+
+ for( const auto& box : baseWorldBoxes ) {
+ float t = 0.0f;
+ if( rayAABBIntersect( rayOrigin, rayDir, box.first, box.second, t ) ) {
+ if( t > 0.0f && t < wallT ) {
+ wallT = t;
+ wallHitPoint = rayOrigin + rayDir * t;
+ glm::vec3 center = ( box.first + box.second ) * 0.5f;
+ glm::vec3 diff = wallHitPoint - center;
+ glm::vec3 ad = glm::abs( diff );
+ if( ad.x > ad.y && ad.x > ad.z )
+ wallHitNormal = glm::vec3( diff.x > 0.0f ? 1.0f : -1.0f, 0.0f, 0.0f );
+ else if( ad.y > ad.x && ad.y > ad.z )
+ wallHitNormal = glm::vec3( 0.0f, diff.y > 0.0f ? 1.0f : -1.0f, 0.0f );
+ else
+ wallHitNormal = glm::vec3( 0.0f, 0.0f, diff.z > 0.0f ? 1.0f : -1.0f );
+ hitWall = true;
+ }
+ }
+ }
+
+ if( hitWall ) {
+
+ glm::vec3 offsetPoint = wallHitPoint + wallHitNormal * 0.01f;
+
+ int xi = 0, zi = 0;
+ mGridSystem.worldToGrid( offsetPoint, xi, zi );
+ int yi = static_cast<int>( std::floor( offsetPoint.y / mGridSystem.getCellSize() ) );
+
+ hitCell = glm::ivec3( xi, yi, zi );
+ hitNormal = wallHitNormal;
+ placeCell = hitCell;
+ validHit = true;
+ } else if( std::abs( rayDir.y ) > 1e-6f ) {
+ float t = ( 0.0f - rayOrigin.y ) / rayDir.y;
+ if( t > 0.0f ) {
+ glm::vec3 hitPoint = rayOrigin + rayDir * t;
+ hitCell = worldPosToCell( hitPoint );
+ hitNormal = glm::vec3( 0.0f, 1.0f, 0.0f );
+ placeCell = hitCell;
+ validHit = true;
+ }
+ }
+ }
+
+ if( hitExisting ) {
+ validHit = true;
+ placeCell = hitCell + glm::ivec3( static_cast<int>( std::round( hitNormal.x ) ),
+ static_cast<int>( std::round( hitNormal.y ) ),
+ static_cast<int>( std::round( hitNormal.z ) ) );
+ placeCell.x = std::clamp( placeCell.x, 0, mGridSystem.getGridWidth() - 1 );
+ placeCell.z = std::clamp( placeCell.z, 0, mGridSystem.getGridDepth() - 1 );
+ } else if( validHit ) {
+ placeCell.x = std::clamp( placeCell.x, 0, mGridSystem.getGridWidth() - 1 );
+ placeCell.z = std::clamp( placeCell.z, 0, mGridSystem.getGridDepth() - 1 );
+ }
+
+ if( leftMouseDown && !mPrevLeftDown ) {
+ mDragging = true;
+ mDragButton = 0;
+ mDragStartCell = placeCell;
+ }
+ if( rightMouseDown && !mPrevRightDown ) {
+ mDragging = true;
+ mDragButton = 1;
+ mDragStartCell = placeCell;
+ }
+
+ if( mDragging ) {
+ glm::ivec3 endCell = placeCell;
+ if( shiftPressed ) {
+ endCell.y = mDragStartCell.y;
+ }
+ mPreviewCells = rasterizeGridBox( mDragStartCell, endCell );
+ }
+
+ if( !leftMouseDown && mPrevLeftDown && mDragButton == 0 ) {
+ Action action;
+ for( const auto& cell : mPreviewCells ) {
+ if( mPlacedSet.insert( cell ).second ) {
+ mPlacedList.push_back( cell );
+ mCellTextureIds[cell] = currentTextureId;
+ mCellCollidable[cell] = placeCollidable;
+ VoxelData voxelData;
+ voxelData.mCell = cell;
+ voxelData.mTextureId = currentTextureId;
+ voxelData.mCollidable = placeCollidable;
+ action.mAddedCells.push_back( voxelData );
+ }
+ }
+ if( !action.mAddedCells.empty() ) {
+ mUndoStack.push_back( action );
+ if( mUndoStack.size() > mMaxUndoSteps )
+ mUndoStack.erase( mUndoStack.begin() );
+ mRedoStack.clear();
+ }
+ mDragging = false;
+ }
+
+ if( !rightMouseDown && mPrevRightDown && mDragButton == 1 ) {
+ Action action;
+ for( const auto& cell : mPreviewCells ) {
+ if( mPlacedSet.erase( cell ) > 0 ) {
+ mPlacedList.erase( std::remove( mPlacedList.begin(), mPlacedList.end(), cell ), mPlacedList.end() );
+ auto texIt = mCellTextureIds.find( cell );
+ VoxelData voxelData;
+ voxelData.mCell = cell;
+ voxelData.mTextureId = ( texIt != mCellTextureIds.end() ) ? texIt->second : 0;
+ auto collIt = mCellCollidable.find( cell );
+ voxelData.mCollidable = ( collIt != mCellCollidable.end() ) ? collIt->second : true;
+ action.mRemovedCells.push_back( voxelData );
+ mCellTextureIds.erase( cell );
+ mCellCollidable.erase( cell );
+ }
+ }
+ if( !action.mRemovedCells.empty() ) {
+ mUndoStack.push_back( action );
+ if( mUndoStack.size() > mMaxUndoSteps )
+ mUndoStack.erase( mUndoStack.begin() );
+ mRedoStack.clear();
+ }
+ mDragging = false;
+ }
+
+ if( !mDragging ) {
+ if( validHit ) {
+ mPreviewCells.clear();
+ mPreviewCells.push_back( placeCell );
+ } else {
+ mPreviewCells.clear();
+ }
+ }
+
+ mPrevLeftDown = leftMouseDown;
+ mPrevRightDown = rightMouseDown;
+}
+
+void VoxelEditor::undo () {
+ if( mUndoStack.empty() )
+ return;
+
+ Action action = mUndoStack.back();
+ mUndoStack.pop_back();
+
+ for( const auto& voxelData : action.mAddedCells ) {
+ mPlacedSet.erase( voxelData.mCell );
+ mPlacedList.erase( std::remove( mPlacedList.begin(), mPlacedList.end(), voxelData.mCell ),
+ mPlacedList.end() );
+ mCellTextureIds.erase( voxelData.mCell );
+ mCellCollidable.erase( voxelData.mCell );
+ }
+ for( const auto& voxelData : action.mRemovedCells ) {
+ if( mPlacedSet.insert( voxelData.mCell ).second ) {
+ mPlacedList.push_back( voxelData.mCell );
+ mCellTextureIds[voxelData.mCell] = voxelData.mTextureId;
+ mCellCollidable[voxelData.mCell] = voxelData.mCollidable;
+ }
+ }
+
+ for( const auto& mi : action.mAddedModels ) {
+
+ auto it = std::find_if( mPlacedModels.begin(), mPlacedModels.end(),
+ [&] ( const ModelInstance& m ) {
+ return m.modelIndex == mi.modelIndex && m.pos == mi.pos && m.yaw == mi.yaw &&
+ m.scale == mi.scale;
+ } );
+ if( it != mPlacedModels.end() )
+ mPlacedModels.erase( it );
+ }
+ for( const auto& mi : action.mRemovedModels ) {
+ ModelInstance m;
+ m.modelIndex = mi.modelIndex;
+ m.pos = mi.pos;
+ m.yaw = mi.yaw;
+ m.scale = mi.scale;
+ m.mCollidable = mi.mCollidable;
+ mPlacedModels.push_back( m );
+ }
+
+ mRedoStack.push_back( action );
+}
+
+void VoxelEditor::redo () {
+ if( mRedoStack.empty() )
+ return;
+
+ Action action = mRedoStack.back();
+ mRedoStack.pop_back();
+
+ for( const auto& voxelData : action.mAddedCells ) {
+ if( mPlacedSet.insert( voxelData.mCell ).second ) {
+ mPlacedList.push_back( voxelData.mCell );
+ mCellTextureIds[voxelData.mCell] = voxelData.mTextureId;
+ mCellCollidable[voxelData.mCell] = voxelData.mCollidable;
+ }
+ }
+ for( const auto& voxelData : action.mRemovedCells ) {
+ mPlacedSet.erase( voxelData.mCell );
+ mPlacedList.erase( std::remove( mPlacedList.begin(), mPlacedList.end(), voxelData.mCell ),
+ mPlacedList.end() );
+ mCellTextureIds.erase( voxelData.mCell );
+ mCellCollidable.erase( voxelData.mCell );
+ }
+
+ for( const auto& mi : action.mAddedModels ) {
+ ModelInstance m;
+ m.modelIndex = mi.modelIndex;
+ m.pos = mi.pos;
+ m.yaw = mi.yaw;
+ m.scale = mi.scale;
+ m.mCollidable = mi.mCollidable;
+ mPlacedModels.push_back( m );
+ }
+ for( const auto& mi : action.mRemovedModels ) {
+ auto it = std::find_if( mPlacedModels.begin(), mPlacedModels.end(),
+ [&] ( const ModelInstance& m ) {
+ return m.modelIndex == mi.modelIndex && m.pos == mi.pos && m.yaw == mi.yaw &&
+ m.scale == mi.scale;
+ } );
+ if( it != mPlacedModels.end() )
+ mPlacedModels.erase( it );
+ }
+
+ mUndoStack.push_back( action );
+}
+
+const std::vector<glm::ivec3>& VoxelEditor::getPlacedCells () const {
+ return mPlacedList;
+}
+
+const std::vector<glm::ivec3>& VoxelEditor::getPreviewCells () const {
+ return mPreviewCells;
+}
+
+size_t VoxelEditor::getUndoStackSize () const {
+ return mUndoStack.size();
+}
+
+size_t VoxelEditor::getRedoStackSize () const {
+ return mRedoStack.size();
+}
+
+glm::ivec3 VoxelEditor::worldPosToCell ( const glm::vec3& pos ) const {
+ int xi = 0, zi = 0;
+ mGridSystem.worldToGrid( pos, xi, zi );
+ int yi = static_cast<int>( std::floor( ( pos.y - mGridSystem.getFloorY() ) / mGridSystem.getCellSize() ) );
+ return glm::ivec3( xi, yi, zi );
+}
+
+glm::vec3 VoxelEditor::cellToWorldCenter ( const glm::ivec3& cell ) const {
+ return mGridSystem.getCellCenter( cell.x, cell.z, cell.y );
+}
+
+std::pair<glm::vec3, glm::vec3> VoxelEditor::cellToAABB ( const glm::ivec3& cell ) const {
+ glm::vec3 center = cellToWorldCenter( cell );
+ float halfSize = mGridSystem.getCellSize() * 0.5f;
+ glm::vec3 he( halfSize, halfSize, halfSize );
+ return { center - he, center + he };
+}
+
+std::vector<std::pair<glm::vec3, glm::vec3>>
+VoxelEditor::getAllCollisionBoxes ( const std::vector<std::pair<glm::vec3, glm::vec3>>& baseWorldBoxes ) const {
+ std::vector<std::pair<glm::vec3, glm::vec3>> boxes = baseWorldBoxes;
+ for( const auto& c : mPlacedList ) {
+ auto it = mCellCollidable.find( c );
+ bool coll = true;
+ if( it != mCellCollidable.end() )
+ coll = it->second;
+ if( coll )
+ boxes.push_back( cellToAABB( c ) );
+ }
+
+ return boxes;
+}
+
+bool VoxelEditor::rayAABBIntersect ( const glm::vec3& ro, const glm::vec3& rd, const glm::vec3& bmin,
+ const glm::vec3& bmax, float& outT ) const {
+ float tmin = -FLT_MAX;
+ float tmax = FLT_MAX;
+ for( int i = 0; i < 3; ++i ) {
+ float origin = ro[i];
+ float dir = rd[i];
+ float minB = bmin[i];
+ float maxB = bmax[i];
+ if( std::abs( dir ) < 1e-6f ) {
+ if( origin < minB || origin > maxB )
+ return false;
+ } else {
+ float t1 = ( minB - origin ) / dir;
+ float t2 = ( maxB - origin ) / dir;
+ if( t1 > t2 )
+ std::swap( t1, t2 );
+ tmin = std::max( tmin, t1 );
+ tmax = std::min( tmax, t2 );
+ if( tmin > tmax )
+ return false;
+ }
+ }
+ if( tmax < 0.0f )
+ return false;
+ outT = tmin >= 0.0f ? tmin : tmax;
+ return true;
+}
+
+std::vector<glm::ivec3> VoxelEditor::rasterizeGridBox ( const glm::ivec3& a, const glm::ivec3& b ) const {
+ std::vector<glm::ivec3> out;
+ glm::ivec3 minC( std::min( a.x, b.x ), std::min( a.y, b.y ), std::min( a.z, b.z ) );
+ glm::ivec3 maxC( std::max( a.x, b.x ), std::max( a.y, b.y ), std::max( a.z, b.z ) );
+
+ minC.x = std::clamp( minC.x, 0, mGridSystem.getGridWidth() - 1 );
+ maxC.x = std::clamp( maxC.x, 0, mGridSystem.getGridWidth() - 1 );
+ minC.z = std::clamp( minC.z, 0, mGridSystem.getGridDepth() - 1 );
+ maxC.z = std::clamp( maxC.z, 0, mGridSystem.getGridDepth() - 1 );
+
+ for( int x = minC.x; x <= maxC.x; ++x ) {
+ for( int y = minC.y; y <= maxC.y; ++y ) {
+ for( int z = minC.z; z <= maxC.z; ++z ) {
+ out.emplace_back( x, y, z );
+ }
+ }
+ }
+
+ return out;
+}
+
+std::vector<glm::ivec3> VoxelEditor::rasterizeCircle ( const glm::ivec3& centerCell, int radiusCells,
+ int heightLayers ) const {
+ std::vector<glm::ivec3> out;
+
+ if( radiusCells < 1 )
+ radiusCells = 1;
+ if( heightLayers < 1 )
+ heightLayers = 1;
+
+ int minX = std::max( 0, centerCell.x - radiusCells );
+ int maxX = std::min( mGridSystem.getGridWidth() - 1, centerCell.x + radiusCells );
+ int minZ = std::max( 0, centerCell.z - radiusCells );
+ int maxZ = std::min( mGridSystem.getGridDepth() - 1, centerCell.z + radiusCells );
+
+ int maxY = mGridSystem.getWallHeight() - 1;
+
+ int r2 = radiusCells * radiusCells;
+
+ for( int x = minX; x <= maxX; ++x ) {
+ for( int z = minZ; z <= maxZ; ++z ) {
+ int dx = x - centerCell.x;
+ int dz = z - centerCell.z;
+ if( dx * dx + dz * dz <= r2 ) {
+ for( int h = 0; h < heightLayers; ++h ) {
+ int y = centerCell.y + h;
+ y = std::clamp( y, 0, maxY );
+ out.emplace_back( x, y, z );
+ }
+ }
+ }
+ }
+
+ return out;
+}
+
+void VoxelEditor::applyCircularBrush ( const glm::vec3& centerWorld, float radiusWorld, float /*heightWorld*/,
+ int textureId, bool placeCollidable ) {
+ float cellSize = mGridSystem.getCellSize();
+
+ int radiusCells = std::max( 1, static_cast<int>( std::ceil( radiusWorld / cellSize ) ) );
+
+ glm::ivec3 centerCell = worldPosToCell( centerWorld );
+
+ int minX = std::max( 0, centerCell.x - radiusCells );
+ int maxX = std::min( mGridSystem.getGridWidth() - 1, centerCell.x + radiusCells );
+ int minZ = std::max( 0, centerCell.z - radiusCells );
+ int maxZ = std::min( mGridSystem.getGridDepth() - 1, centerCell.z + radiusCells );
+
+ int targetY = centerCell.y;
+ int maxY = mGridSystem.getWallHeight() - 1;
+ targetY = std::clamp( targetY, 0, maxY );
+
+ float r2 = radiusWorld * radiusWorld;
+
+ Action action;
+
+ for( int x = minX; x <= maxX; ++x ) {
+ for( int z = minZ; z <= maxZ; ++z ) {
+
+ glm::vec3 cellCenter = mGridSystem.getCellCenter( x, z, targetY );
+ float dx = cellCenter.x - centerWorld.x;
+ float dz = cellCenter.z - centerWorld.z;
+ if( dx * dx + dz * dz <= r2 ) {
+ glm::ivec3 cell( x, targetY, z );
+ if( mPlacedSet.insert( cell ).second ) {
+ mPlacedList.push_back( cell );
+ mCellTextureIds[cell] = textureId;
+ mCellCollidable[cell] = placeCollidable;
+ VoxelData vd;
+ vd.mCell = cell;
+ vd.mTextureId = textureId;
+ vd.mCollidable = placeCollidable;
+ action.mAddedCells.push_back( vd );
+ }
+ }
+ }
+ }
+
+ if( !action.mAddedCells.empty() ) {
+ mUndoStack.push_back( action );
+ if( mUndoStack.size() > mMaxUndoSteps )
+ mUndoStack.erase( mUndoStack.begin() );
+ mRedoStack.clear();
+ }
+}
+
+int VoxelEditor::getTextureIdForCell ( const glm::ivec3& cell ) const {
+ auto it = mCellTextureIds.find( cell );
+ if( it != mCellTextureIds.end() )
+ return it->second;
+ return -1;
+}
+
+bool VoxelEditor::saveToFile ( const std::string& filepath ) const {
+ try {
+ nlohmann::json j;
+ j["version"] = 1;
+
+ nlohmann::json voxelsArray = nlohmann::json::array();
+ for( const auto& cell : mPlacedList ) {
+ auto it = mCellTextureIds.find( cell );
+ int textureId = ( it != mCellTextureIds.end() ) ? it->second : 0;
+
+ nlohmann::json voxel;
+ voxel["x"] = cell.x;
+ voxel["y"] = cell.y;
+ voxel["z"] = cell.z;
+ voxel["textureId"] = textureId;
+ auto cit = mCellCollidable.find( cell );
+ voxel["collidable"] = ( cit != mCellCollidable.end() ) ? cit->second : true;
+ voxelsArray.push_back( voxel );
+ }
+
+ j["voxels"] = voxelsArray;
+
+ nlohmann::json modelsArray = nlohmann::json::array();
+ for( const auto& m : mPlacedModels ) {
+ nlohmann::json mj;
+ mj["modelIndex"] = m.modelIndex;
+ mj["x"] = m.pos.x;
+ mj["y"] = m.pos.y;
+ mj["z"] = m.pos.z;
+ mj["yaw"] = m.yaw;
+ mj["scale"] = m.scale;
+ mj["collidable"] = m.mCollidable;
+ modelsArray.push_back( mj );
+ }
+ j["models"] = modelsArray;
+
+ std::ofstream file( filepath );
+ if( !file.is_open() )
+ return false;
+
+ file << j.dump( 2 );
+ file.close();
+ return true;
+ } catch( ... ) {
+ return false;
+ }
+}
+
+bool VoxelEditor::loadFromFile ( const std::string& filepath ) {
+ try {
+ std::ifstream file( filepath );
+ if( !file.is_open() )
+ return false;
+
+ nlohmann::json j;
+ file >> j;
+ file.close();
+
+ if( !j.contains( "version" ) || !j.contains( "voxels" ) )
+ return false;
+
+ clear();
+
+ for( const auto& voxelJson : j["voxels"] ) {
+ glm::ivec3 cell( voxelJson["x"].get<int>(), voxelJson["y"].get<int>(),
+ voxelJson["z"].get<int>() );
+
+ int textureId = voxelJson.value( "textureId", 0 );
+ bool collidable = voxelJson.value( "collidable", true );
+
+ if( mPlacedSet.insert( cell ).second ) {
+ mPlacedList.push_back( cell );
+ mCellTextureIds[cell] = textureId;
+ mCellCollidable[cell] = collidable;
+ }
+ }
+
+ if( j.contains( "models" ) && j["models"].is_array() ) {
+ for( const auto& mj : j["models"] ) {
+ ModelInstance mi;
+ mi.modelIndex = mj.value( "modelIndex", 0 );
+ mi.pos.x = mj.value( "x", 0.0f );
+ mi.pos.y = mj.value( "y", 0.0f );
+ mi.pos.z = mj.value( "z", 0.0f );
+ mi.yaw = mj.value( "yaw", 0.0f );
+ mi.scale = mj.value( "scale", 1.0f );
+ mi.mCollidable = mj.value( "collidable", true );
+ mPlacedModels.push_back( mi );
+ }
+ }
+
+ return true;
+ } catch( ... ) {
+ return false;
+ }
+}
+
+void VoxelEditor::clear () {
+ mPlacedSet.clear();
+ mPlacedList.clear();
+ mCellTextureIds.clear();
+ mUndoStack.clear();
+ mRedoStack.clear();
+ mPlacedModels.clear();
+}
+} // namespace scene
diff --git a/apps/openmb/scene/VoxelEditor.hpp b/apps/openmb/scene/VoxelEditor.hpp
new file mode 100644
index 0000000..a77f547
--- /dev/null
+++ b/apps/openmb/scene/VoxelEditor.hpp
@@ -0,0 +1,132 @@
+#ifndef OPENMB_APPS_OPENMB_SCENE_VOXELEDITOR_H
+#define OPENMB_APPS_OPENMB_SCENE_VOXELEDITOR_H
+
+#include <glm/glm.hpp>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+namespace scene {
+class GridSystem;
+
+struct IVec3Hash {
+ size_t operator()( const glm::ivec3& v ) const noexcept {
+ uint32_t x = static_cast<uint32_t>( v.x );
+ uint32_t y = static_cast<uint32_t>( v.y );
+ uint32_t z = static_cast<uint32_t>( v.z );
+ return (size_t)( ( x * 73856093u ) ^ ( y * 19349663u ) ^ ( z * 83492791u ) );
+ }
+};
+
+struct IVec3Eq {
+ bool operator()( const glm::ivec3& a, const glm::ivec3& b ) const noexcept {
+ return a.x == b.x && a.y == b.y && a.z == b.z;
+ }
+};
+
+class VoxelEditor {
+ public:
+ VoxelEditor( const GridSystem& gridSystem );
+ ~VoxelEditor() = default;
+
+ void processInput( const glm::vec3& rayOrigin, const glm::vec3& rayDir, bool leftMouseDown, bool rightMouseDown,
+ bool shiftPressed, const std::vector<std::pair<glm::vec3, glm::vec3>>& baseWorldBoxes,
+ int currentTextureId, bool placeCollidable );
+
+ void applyCircularBrush( const glm::vec3& centerWorld, float radiusWorld, float heightWorld, int textureId,
+ bool placeCollidable );
+
+ void undo();
+
+ void redo();
+
+ const std::vector<glm::ivec3>& getPlacedCells() const;
+
+ const std::vector<glm::ivec3>& getPreviewCells() const;
+
+ size_t getUndoStackSize() const;
+
+ size_t getRedoStackSize() const;
+
+ glm::ivec3 worldPosToCell( const glm::vec3& pos ) const;
+
+ glm::vec3 cellToWorldCenter( const glm::ivec3& cell ) const;
+
+ std::pair<glm::vec3, glm::vec3> cellToAABB( const glm::ivec3& cell ) const;
+
+ std::vector<std::pair<glm::vec3, glm::vec3>>
+ getAllCollisionBoxes( const std::vector<std::pair<glm::vec3, glm::vec3>>& baseWorldBoxes ) const;
+
+ int getTextureIdForCell( const glm::ivec3& cell ) const;
+
+ bool saveToFile( const std::string& filepath ) const;
+
+ bool loadFromFile( const std::string& filepath );
+
+ void clear();
+
+ struct ModelInstance {
+ int modelIndex;
+ glm::vec3 pos;
+ float yaw;
+ float scale;
+ bool mCollidable;
+ };
+
+ void addModelInstance( const ModelInstance& mi );
+ const std::vector<ModelInstance>& getPlacedModels() const;
+
+ private:
+ struct VoxelData {
+ glm::ivec3 mCell;
+ int mTextureId;
+ bool mCollidable;
+ };
+
+ struct Action {
+ std::vector<VoxelData> mAddedCells;
+ std::vector<VoxelData> mRemovedCells;
+ struct ModelInstance {
+ int modelIndex;
+ glm::vec3 pos;
+ float yaw;
+ float scale;
+ bool mCollidable;
+ };
+ std::vector<ModelInstance> mAddedModels;
+ std::vector<ModelInstance> mRemovedModels;
+ };
+
+ bool rayAABBIntersect( const glm::vec3& ro, const glm::vec3& rd, const glm::vec3& bmin, const glm::vec3& bmax,
+ float& outT ) const;
+
+ std::vector<glm::ivec3> rasterizeGridBox( const glm::ivec3& a, const glm::ivec3& b ) const;
+
+ std::vector<glm::ivec3> rasterizeCircle( const glm::ivec3& centerCell, int radiusCells,
+ int heightLayers ) const;
+
+ const GridSystem& mGridSystem;
+
+ std::unordered_set<glm::ivec3, IVec3Hash, IVec3Eq> mPlacedSet;
+ std::vector<glm::ivec3> mPlacedList;
+ std::unordered_map<glm::ivec3, int, IVec3Hash, IVec3Eq> mCellTextureIds;
+ std::unordered_map<glm::ivec3, bool, IVec3Hash, IVec3Eq> mCellCollidable;
+
+ std::vector<Action> mUndoStack;
+ std::vector<Action> mRedoStack;
+ static constexpr int mMaxUndoSteps = 100;
+
+ std::vector<ModelInstance> mPlacedModels;
+
+ bool mDragging;
+ int mDragButton;
+ glm::ivec3 mDragStartCell;
+ std::vector<glm::ivec3> mPreviewCells;
+
+ bool mPrevLeftDown;
+ bool mPrevRightDown;
+};
+} // namespace scene
+
+#endif