diff --git a/src/assets/Assets.cpp b/src/assets/Assets.cpp index 73ed5ede9..c7ef69461 100644 --- a/src/assets/Assets.cpp +++ b/src/assets/Assets.cpp @@ -1,72 +1,8 @@ #include "Assets.hpp" -#include "../audio/audio.hpp" -#include "../graphics/core/Texture.hpp" -#include "../graphics/core/Shader.hpp" -#include "../graphics/core/Atlas.hpp" -#include "../graphics/core/Font.hpp" -#include "../frontend/UiDocument.hpp" -#include "../logic/scripting/scripting.hpp" - Assets::~Assets() { } -Texture* Assets::getTexture(const std::string& name) const { - auto found = textures.find(name); - if (found == textures.end()) - return nullptr; - return found->second.get(); -} - -void Assets::store(std::unique_ptr texture, const std::string& name){ - textures.emplace(name, std::move(texture)); -} - - -Shader* Assets::getShader(const std::string& name) const{ - auto found = shaders.find(name); - if (found == shaders.end()) - return nullptr; - return found->second.get(); -} - -void Assets::store(std::unique_ptr shader, const std::string& name){ - shaders.emplace(name, std::move(shader)); -} - -Font* Assets::getFont(const std::string& name) const { - auto found = fonts.find(name); - if (found == fonts.end()) - return nullptr; - return found->second.get(); -} - -void Assets::store(std::unique_ptr font, const std::string& name){ - fonts.emplace(name, std::move(font)); -} - -Atlas* Assets::getAtlas(const std::string& name) const { - auto found = atlases.find(name); - if (found == atlases.end()) - return nullptr; - return found->second.get(); -} - -void Assets::store(std::unique_ptr atlas, const std::string& name){ - atlases.emplace(name, std::move(atlas)); -} - -audio::Sound* Assets::getSound(const std::string& name) const { - auto found = sounds.find(name); - if (found == sounds.end()) - return nullptr; - return found->second.get(); -} - -void Assets::store(std::unique_ptr sound, const std::string& name) { - sounds.emplace(name, std::move(sound)); -} - const std::vector& Assets::getAnimations() { return animations; } @@ -74,14 +10,3 @@ const std::vector& Assets::getAnimations() { void Assets::store(const TextureAnimation& animation) { animations.emplace_back(animation); } - -UiDocument* Assets::getLayout(const std::string& name) const { - auto found = layouts.find(name); - if (found == layouts.end()) - return nullptr; - return found->second.get(); -} - -void Assets::store(std::unique_ptr layout, const std::string& name) { - layouts[name] = std::shared_ptr(std::move(layout)); -} diff --git a/src/assets/Assets.hpp b/src/assets/Assets.hpp index d4b0f31d2..fd39e8fe0 100644 --- a/src/assets/Assets.hpp +++ b/src/assets/Assets.hpp @@ -7,18 +7,11 @@ #include #include #include +#include +#include #include -class Texture; -class Shader; -class Font; -class Atlas; class Assets; -class UiDocument; - -namespace audio { - class Sound; -} namespace assetload { /// @brief final work to do in the main thread @@ -26,38 +19,36 @@ namespace assetload { } class Assets { - std::unordered_map> textures; - std::unordered_map> shaders; - std::unordered_map> fonts; - std::unordered_map> atlases; - std::unordered_map> layouts; - std::unordered_map> sounds; std::vector animations; + + using assets_map = std::unordered_map>; + std::unordered_map assets; public: Assets() {} Assets(const Assets&) = delete; ~Assets(); - - Texture* getTexture(const std::string& name) const; - void store(std::unique_ptr texture, const std::string& name); - - Shader* getShader(const std::string& name) const; - void store(std::unique_ptr shader, const std::string& name); - - Font* getFont(const std::string& name) const; - void store(std::unique_ptr font, const std::string& name); - - Atlas* getAtlas(const std::string& name) const; - void store(std::unique_ptr atlas, const std::string& name); - - audio::Sound* getSound(const std::string& name) const; - void store(std::unique_ptr sound, const std::string& name); const std::vector& getAnimations(); void store(const TextureAnimation& animation); - UiDocument* getLayout(const std::string& name) const; - void store(std::unique_ptr layout, const std::string& name); + template + void store(std::unique_ptr asset, const std::string& name) { + assets[typeid(T)][name].reset(asset.release()); + } + + template + T* get(const std::string& name) const { + const auto& mapIter = assets.find(typeid(T)); + if (mapIter == assets.end()) { + return nullptr; + } + const auto& map = mapIter->second; + const auto& found = map.find(name); + if (found == map.end()) { + return nullptr; + } + return static_cast(found->second.get()); + } }; #endif // ASSETS_ASSETS_HPP_ diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index f55902e92..65f52da7f 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -30,6 +30,7 @@ AssetsLoader::AssetsLoader(Assets* assets, const ResPaths* paths) addLoader(AssetType::atlas, assetload::atlas); addLoader(AssetType::layout, assetload::layout); addLoader(AssetType::sound, assetload::sound); + addLoader(AssetType::model, assetload::model); } void AssetsLoader::addLoader(AssetType tag, aloader_func func) { @@ -99,6 +100,7 @@ static std::string assets_def_folder(AssetType tag) { case AssetType::atlas: return TEXTURES_FOLDER; case AssetType::layout: return LAYOUTS_FOLDER; case AssetType::sound: return SOUNDS_FOLDER; + case AssetType::model: return MODELS_FOLDER; } return ""; } @@ -155,6 +157,7 @@ void AssetsLoader::processPreloadConfig(const fs::path& file) { processPreloadList(AssetType::shader, root->list("shaders")); processPreloadList(AssetType::texture, root->list("textures")); processPreloadList(AssetType::sound, root->list("sounds")); + processPreloadList(AssetType::model, root->list("models")); // layouts are loaded automatically } @@ -212,7 +215,7 @@ bool AssetsLoader::loadExternalTexture( const std::string& name, const std::vector& alternatives ) { - if (assets->getTexture(name) != nullptr) { + if (assets->get(name) != nullptr) { return true; } for (auto& path : alternatives) { diff --git a/src/assets/AssetsLoader.hpp b/src/assets/AssetsLoader.hpp index b2d819167..91eb1036f 100644 --- a/src/assets/AssetsLoader.hpp +++ b/src/assets/AssetsLoader.hpp @@ -25,7 +25,8 @@ enum class AssetType { font, atlas, layout, - sound + sound, + model, }; class ResPaths; diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index 8698d61f7..b7fe8ccf7 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -9,14 +9,17 @@ #include "../coders/commons.hpp" #include "../coders/imageio.hpp" #include "../coders/json.hpp" +#include "../coders/obj.hpp" #include "../coders/GLSLExtension.hpp" #include "../graphics/core/Shader.hpp" #include "../graphics/core/Texture.hpp" #include "../graphics/core/ImageData.hpp" #include "../graphics/core/Atlas.hpp" #include "../graphics/core/Font.hpp" +#include "../graphics/core/Model.hpp" #include "../graphics/core/TextureAnimation.hpp" #include "../frontend/UiDocument.hpp" +#include "../constants.hpp" #include #include @@ -119,9 +122,9 @@ assetload::postfunc assetload::font( ) { auto pages = std::make_shared>>(); for (size_t i = 0; i <= 4; i++) { - std::string name = filename + "_" + std::to_string(i) + ".png"; - name = paths->find(name).string(); - pages->push_back(imageio::read(name)); + std::string pagefile = filename + "_" + std::to_string(i) + ".png"; + pagefile = paths->find(pagefile).string(); + pages->push_back(imageio::read(pagefile)); } return [=](auto assets) { int res = pages->at(0)->getHeight() / 16; @@ -198,6 +201,30 @@ assetload::postfunc assetload::sound( }; } +assetload::postfunc assetload::model( + AssetsLoader* loader, + const ResPaths* paths, + const std::string& file, + const std::string& name, + const std::shared_ptr& +) { + auto path = paths->find(file+".obj"); + auto text = files::read_string(path); + try { + auto model = obj::parse(path.u8string(), text).release(); + return [=](Assets* assets) { + for (auto& mesh : model->meshes) { + auto filename = TEXTURES_FOLDER+"/"+mesh.texture; + loader->add(AssetType::texture, filename, mesh.texture, nullptr); + } + assets->store(std::unique_ptr(model), name); + }; + } catch (const parsing_error& err) { + std::cerr << err.errorLog() << std::endl; + throw; + } +} + static void read_anim_file( const std::string& animFile, std::vector>& frameList diff --git a/src/assets/assetload_funcs.hpp b/src/assets/assetload_funcs.hpp index f017dcb49..71b3cb935 100644 --- a/src/assets/assetload_funcs.hpp +++ b/src/assets/assetload_funcs.hpp @@ -49,7 +49,6 @@ namespace assetload { const std::string &name, const std::shared_ptr& settings ); - postfunc sound( AssetsLoader*, const ResPaths* paths, @@ -57,6 +56,13 @@ namespace assetload { const std::string &name, const std::shared_ptr& settings ); + postfunc model( + AssetsLoader*, + const ResPaths* paths, + const std::string& file, + const std::string &name, + const std::shared_ptr& settings + ); } #endif // ASSETS_ASSET_LOADERS_HPP_ diff --git a/src/coders/commons.cpp b/src/coders/commons.cpp index 1bc111c23..d8d618734 100644 --- a/src/coders/commons.cpp +++ b/src/coders/commons.cpp @@ -163,6 +163,28 @@ void BasicParser::goBack(size_t count) { } } +void BasicParser::reset() { + pos = 0; +} + +char BasicParser::peekInLine() { + while (hasNext()) { + char next = source[pos]; + if (next == '\n') { + return next; + } + if (is_whitespace(next)) { + pos++; + } else { + break; + } + } + if (pos >= source.length()) { + throw error("unexpected end"); + } + return source[pos]; +} + char BasicParser::peek() { skipWhitespace(); if (pos >= source.length()) { @@ -226,6 +248,19 @@ int64_t BasicParser::parseSimpleInt(int base) { return value; } +dynamic::Value BasicParser::parseNumber() { + switch (peek()) { + case '-': + skip(1); + return parseNumber(-1); + case '+': + skip(1); + return parseNumber(1); + default: + return parseNumber(1); + } +} + dynamic::Value BasicParser::parseNumber(int sign) { char c = peek(); int base = 10; diff --git a/src/coders/commons.hpp b/src/coders/commons.hpp index f8f1b0e92..7b6cb3c23 100644 --- a/src/coders/commons.hpp +++ b/src/coders/commons.hpp @@ -87,9 +87,11 @@ class BasicParser { bool isNext(const std::string& substring); void expectNewLine(); void goBack(size_t count=1); + void reset(); int64_t parseSimpleInt(int base); dynamic::Value parseNumber(int sign); + dynamic::Value parseNumber(); std::string parseString(char chr, bool closeRequired=true); parsing_error error(const std::string& message); @@ -99,6 +101,7 @@ class BasicParser { std::string parseName(); bool hasNext(); char peek(); + char peekInLine(); char peekNoJump(); char nextChar(); diff --git a/src/coders/json.cpp b/src/coders/json.cpp index 19b597265..dbe42b5a0 100644 --- a/src/coders/json.cpp +++ b/src/coders/json.cpp @@ -209,9 +209,8 @@ std::unique_ptr Parser::parseList() { Value Parser::parseValue() { char next = peek(); - if (next == '-' || next == '+') { - pos++; - return parseNumber(next == '-' ? -1 : 1); + if (next == '-' || next == '+' || is_digit(next)) { + return parseNumber(); } if (is_identifier_start(next)) { std::string literal = parseName(); @@ -232,9 +231,6 @@ Value Parser::parseValue() { if (next == '[') { return List_sptr(parseList().release()); } - if (is_digit(next)) { - return parseNumber(1); - } if (next == '"' || next == '\'') { pos++; return parseString(next); diff --git a/src/coders/obj.cpp b/src/coders/obj.cpp new file mode 100644 index 000000000..3ecea677d --- /dev/null +++ b/src/coders/obj.cpp @@ -0,0 +1,124 @@ +#include "obj.hpp" + +#include "commons.hpp" +#include "../graphics/core/Model.hpp" + +using namespace model; + +class ObjParser : BasicParser { + std::vector coords {{0, 0, 0}}; + std::vector uvs {{0, 0}}; + std::vector normals {{0, 1, 0}}; + + void parseFace(Mesh& mesh) { + std::vector vertices; + while (hasNext()) { + auto c = peekInLine(); + if (c == '\n') { + break; + } else { + uint indices[3] {}; + uint i = 0; + do { + char next = peekInLine(); + if (is_digit(next)) { + indices[i] = parseSimpleInt(10); + if (peekInLine() == '/') { + pos++; + } + } else if (next == '/') { + pos++; + } else { + break; + } + } while (peekInLine() != '\n' && ++i < 3); + + vertices.push_back(Vertex { + coords[indices[0]], uvs[indices[1]], normals[indices[2]] + }); + } + } + if (peekInLine() != '\n' && hasNext()) { + skipLine(); + } + if (vertices.size() >= 3) { + for (size_t j = 0; j < vertices.size() - 2; j++) { + mesh.vertices.push_back(vertices[0]); + for (size_t i = 1; i < 3; i++) { + mesh.vertices.push_back(vertices[i + j]); + } + } + } + } +public: + ObjParser(const std::string_view file, const std::string_view src) : BasicParser(file, src) { + } + + std::unique_ptr parse() { + // first iteration - collecting vertex data + while (hasNext()) { + if (peek() == '#') { + skipLine(); + continue; + } + auto cmd = parseName(); + if (cmd == "v") { + float x = dynamic::as_number(parseNumber()); + float y = dynamic::as_number(parseNumber()); + float z = dynamic::as_number(parseNumber()); + coords.emplace_back(x, y, z); + } else if (cmd == "vt") { + float u = dynamic::as_number(parseNumber()); + float v = dynamic::as_number(parseNumber()); + uvs.emplace_back(u, v); + } else if (cmd == "vn") { + float x = dynamic::as_number(parseNumber()); + float y = dynamic::as_number(parseNumber()); + float z = dynamic::as_number(parseNumber()); + normals.emplace_back(x, y, z); + } else { + skipLine(); + } + } + // second iteration - building meshes + reset(); + + auto model = std::make_unique(); + std::string texture; + while (hasNext()) { + if (peek() != '#' && parseName() == "usemtl") { + skipWhitespace(); + texture = readUntil('\n'); + break; + } + skipLine(); + } + do { + Mesh* mesh = &model->addMesh(texture); + while (hasNext()) { + if (peek() == '#') { + skipLine(); + continue; + } + auto cmd = parseName(); + if (cmd == "usemtl") { + skipWhitespace(); + texture = readUntil('\n'); + mesh = &model->addMesh(texture); + break; + } else if (cmd == "f") { + parseFace(*mesh); + } + skipLine(); + } + } while(hasNext()); + model->clean(); + return model; + } +}; + +std::unique_ptr obj::parse( + const std::string_view file, const std::string_view src +) { + return ObjParser(file, src).parse(); +} diff --git a/src/coders/obj.hpp b/src/coders/obj.hpp new file mode 100644 index 000000000..64d0f4ce5 --- /dev/null +++ b/src/coders/obj.hpp @@ -0,0 +1,19 @@ +#ifndef CODERS_OBJ_HPP_ +#define CODERS_OBJ_HPP_ + +#include +#include + +/// Wavefont OBJ files parser + +namespace model { + struct Model; +} + +namespace obj { + std::unique_ptr parse( + const std::string_view file, const std::string_view src + ); +} + +#endif // CODERS_OBJ_HPP_ diff --git a/src/constants.hpp b/src/constants.hpp index e666563aa..76c13a748 100644 --- a/src/constants.hpp +++ b/src/constants.hpp @@ -49,5 +49,6 @@ inline const std::string TEXTURES_FOLDER = "textures"; inline const std::string FONTS_FOLDER = "fonts"; inline const std::string LAYOUTS_FOLDER = "layouts"; inline const std::string SOUNDS_FOLDER = "sounds"; +inline const std::string MODELS_FOLDER = "models"; #endif // CONSTANTS_HPP_ diff --git a/src/data/dynamic.hpp b/src/data/dynamic.hpp index ff0342df3..5dc5dbedc 100644 --- a/src/data/dynamic.hpp +++ b/src/data/dynamic.hpp @@ -3,6 +3,7 @@ #include "../typedefs.hpp" +#include #include #include #include @@ -47,6 +48,15 @@ namespace dynamic { std::holds_alternative(value); } + inline number_t as_number(const Value& value) { + if (auto num = std::get_if(&value)) { + return *num; + } else if (auto num = std::get_if(&value)) { + return *num; + } + return NAN; + } + class List { public: std::vector values; diff --git a/src/frontend/ContentGfxCache.cpp b/src/frontend/ContentGfxCache.cpp index 373e97302..de180760e 100644 --- a/src/frontend/ContentGfxCache.cpp +++ b/src/frontend/ContentGfxCache.cpp @@ -15,7 +15,7 @@ ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) : content(content) { auto indices = content->getIndices(); sideregions = std::make_unique(indices->countBlockDefs() * 6); - Atlas* atlas = assets->getAtlas("blocks"); + auto atlas = assets->get("blocks"); for (uint i = 0; i < indices->countBlockDefs(); i++) { Block* def = indices->getBlockDef(i); diff --git a/src/frontend/LevelFrontend.cpp b/src/frontend/LevelFrontend.cpp index 7a62ca50c..3dffae5c6 100644 --- a/src/frontend/LevelFrontend.cpp +++ b/src/frontend/LevelFrontend.cpp @@ -30,7 +30,7 @@ LevelFrontend::LevelFrontend(LevelController* controller, Assets* assets) } if (type == BlockInteraction::step) { - auto sound = assets->getSound(material->stepsSound); + auto sound = assets->get(material->stepsSound); audio::play( sound, glm::vec3(), @@ -45,10 +45,10 @@ LevelFrontend::LevelFrontend(LevelController* controller, Assets* assets) audio::Sound* sound = nullptr; switch (type) { case BlockInteraction::placing: - sound = assets->getSound(material->placeSound); + sound = assets->get(material->placeSound); break; case BlockInteraction::destruction: - sound = assets->getSound(material->breakSound); + sound = assets->get(material->breakSound); break; case BlockInteraction::step: break; diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index d61e021fd..b49abf89a 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -62,6 +62,11 @@ std::shared_ptr create_debug_panel( panel->add(create_label([](){ return L"meshes: " + std::to_wstring(Mesh::meshesCount); })); + panel->add(create_label([](){ + int drawCalls = Mesh::drawCalls; + Mesh::drawCalls = 0; + return L"draw-calls: " + std::to_wstring(drawCalls); + })); panel->add(create_label([](){ return L"speakers: " + std::to_wstring(audio::count_speakers())+ L" streams: " + std::to_wstring(audio::count_streams()); diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index bc8f2cbfd..53f85bafb 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -208,7 +208,7 @@ void Hud::processInput(bool visible) { } } if (!pause && Events::active(BIND_DEVTOOLS_CONSOLE)) { - showOverlay(assets->getLayout("core:console"), false); + showOverlay(assets->get("core:console"), false); } if (!Window::isFocused() && !pause && !isInventoryOpen()) { setPause(true); @@ -305,7 +305,7 @@ void Hud::openInventory() { inventoryOpen = true; auto inventory = player->getInventory(); - auto inventoryDocument = assets->getLayout("core:inventory"); + auto inventoryDocument = assets->get("core:inventory"); inventoryView = std::dynamic_pointer_cast(inventoryDocument->getRoot()); inventoryView->bind(inventory, content); add(HudElement(hud_element_mode::inventory_bound, inventoryDocument, inventoryView, false)); @@ -460,7 +460,7 @@ void Hud::draw(const DrawContext& ctx){ auto batch = ctx.getBatch2D(); batch->begin(); - Shader* uishader = assets->getShader("ui"); + auto uishader = assets->get("ui"); uishader->use(); uishader->uniformMatrix("u_projview", uicamera->getProjView()); @@ -468,7 +468,7 @@ void Hud::draw(const DrawContext& ctx){ if (!pause && !inventoryOpen && !player->debug) { DrawContext chctx = ctx.sub(); chctx.setBlendMode(BlendMode::inversion); - auto texture = assets->getTexture("gui/crosshair"); + auto texture = assets->get("gui/crosshair"); batch->texture(texture); int chsizex = texture != nullptr ? texture->getWidth() : 16; int chsizey = texture != nullptr ? texture->getHeight() : 16; diff --git a/src/frontend/screens/MenuScreen.cpp b/src/frontend/screens/MenuScreen.cpp index 96b7656c9..74ad04219 100644 --- a/src/frontend/screens/MenuScreen.cpp +++ b/src/frontend/screens/MenuScreen.cpp @@ -35,14 +35,14 @@ void MenuScreen::draw(float delta) { Window::setBgColor(glm::vec3(0.2f)); uicamera->setFov(Window::height); - Shader* uishader = assets->getShader("ui"); + auto uishader = assets->get("ui"); uishader->use(); uishader->uniformMatrix("u_projview", uicamera->getProjView()); uint width = Window::width; uint height = Window::height; - auto bg = assets->getTexture("gui/menubg"); + auto bg = assets->get("gui/menubg"); batch->begin(); batch->texture(bg); batch->rect( diff --git a/src/graphics/core/Batch3D.cpp b/src/graphics/core/Batch3D.cpp index 7481ec6f9..68e59c789 100644 --- a/src/graphics/core/Batch3D.cpp +++ b/src/graphics/core/Batch3D.cpp @@ -5,7 +5,9 @@ #include #include "../../typedefs.hpp" +#include "../../maths/UVRegion.hpp" +/// xyz, uv, rgba inline constexpr uint B3D_VERTEX_SIZE = 9; Batch3D::Batch3D(size_t capacity) diff --git a/src/graphics/core/Batch3D.hpp b/src/graphics/core/Batch3D.hpp index 6ff42caad..61ef2eb03 100644 --- a/src/graphics/core/Batch3D.hpp +++ b/src/graphics/core/Batch3D.hpp @@ -1,7 +1,6 @@ #ifndef GRAPHICS_CORE_BATCH3D_HPP_ #define GRAPHICS_CORE_BATCH3D_HPP_ -#include "../../maths/UVRegion.hpp" #include "../../typedefs.hpp" #include @@ -10,6 +9,7 @@ class Mesh; class Texture; +struct UVRegion; class Batch3D { std::unique_ptr buffer; diff --git a/src/graphics/core/Mesh.cpp b/src/graphics/core/Mesh.cpp index 45ba28783..ac4e2b14e 100644 --- a/src/graphics/core/Mesh.cpp +++ b/src/graphics/core/Mesh.cpp @@ -2,6 +2,7 @@ #include int Mesh::meshesCount = 0; +int Mesh::drawCalls = 0; Mesh::Mesh(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices, const vattr* attrs) : ibo(0), @@ -60,6 +61,7 @@ void Mesh::reload(const float* vertexBuffer, size_t vertices, const int* indexBu } void Mesh::draw(unsigned int primitive){ + drawCalls++; glBindVertexArray(vao); if (ibo != 0) { glDrawElements(primitive, indices, GL_UNSIGNED_INT, 0); diff --git a/src/graphics/core/Mesh.hpp b/src/graphics/core/Mesh.hpp index 541d396ed..abff9d5e7 100644 --- a/src/graphics/core/Mesh.hpp +++ b/src/graphics/core/Mesh.hpp @@ -37,6 +37,7 @@ class Mesh { /// @brief Total numbers of alive mesh objects static int meshesCount; + static int drawCalls; }; #endif // GRAPHICS_CORE_MESH_HPP_ diff --git a/src/graphics/core/Model.cpp b/src/graphics/core/Model.cpp new file mode 100644 index 000000000..78e153547 --- /dev/null +++ b/src/graphics/core/Model.cpp @@ -0,0 +1,41 @@ +#include "Model.hpp" + +#include + +using namespace model; + +inline constexpr glm::vec3 X(1, 0, 0); +inline constexpr glm::vec3 Y(0, 1, 0); +inline constexpr glm::vec3 Z(0, 0, 1); + +void Mesh::addPlane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm) { + vertices.push_back({pos-right-up, {0,0}, norm}); + vertices.push_back({pos+right-up, {1,0}, norm}); + vertices.push_back({pos+right+up, {1,1}, norm}); + + vertices.push_back({pos-right-up, {0,0}, norm}); + vertices.push_back({pos+right+up, {1,1}, norm}); + vertices.push_back({pos-right+up, {0,1}, norm}); +} + +void Mesh::addBox(glm::vec3 pos, glm::vec3 size) { + addPlane(pos+Z*size, X*size, Y*size, Z); + addPlane(pos-Z*size, -X*size, Y*size, -Z); + + addPlane(pos+Y*size, X*size, -Z*size, Y); + addPlane(pos-Y*size, X*size, Z*size, -Y); + + addPlane(pos+X*size, -Z*size, Y*size, X); + addPlane(pos-X*size, Z*size, Y*size, -X); +} + + +void Model::clean() { + meshes.erase( + std::remove_if(meshes.begin(), meshes.end(), + [](const Mesh& mesh){ + return mesh.vertices.empty(); + }), + meshes.end() + ); +} diff --git a/src/graphics/core/Model.hpp b/src/graphics/core/Model.hpp new file mode 100644 index 000000000..03d008268 --- /dev/null +++ b/src/graphics/core/Model.hpp @@ -0,0 +1,38 @@ +#ifndef GRAPHICS_CORE_MODEL_HPP_ +#define GRAPHICS_CORE_MODEL_HPP_ + +#include +#include +#include + +namespace model { + struct Vertex { + glm::vec3 coord; + glm::vec2 uv; + glm::vec3 normal; + }; + + struct Mesh { + std::string texture; + std::vector vertices; + + void addPlane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm); + void addBox(glm::vec3 pos, glm::vec3 size); + }; + + struct Model { + std::vector meshes; + + /// @brief Add mesh to the model + /// @param texture texture name + /// @return writeable Mesh + Mesh& addMesh(const std::string& texture) { + meshes.push_back({texture, {}}); + return meshes[meshes.size()-1]; + } + /// @brief Remove all empty meshes + void clean(); + }; +} + +#endif // GRAPHICS_CORE_MODEL_HPP_ diff --git a/src/graphics/render/BlocksPreview.cpp b/src/graphics/render/BlocksPreview.cpp index eb7e72cf6..88a6f1113 100644 --- a/src/graphics/render/BlocksPreview.cpp +++ b/src/graphics/render/BlocksPreview.cpp @@ -126,8 +126,8 @@ std::unique_ptr BlocksPreview::build( size_t count = indices->countBlockDefs(); size_t iconSize = ITEM_ICON_SIZE; - Shader* shader = assets->getShader("ui3d"); - Atlas* atlas = assets->getAtlas("blocks"); + auto shader = assets->get("ui3d"); + auto atlas = assets->get("blocks"); Viewport viewport(iconSize, iconSize); DrawContext pctx(nullptr, viewport, nullptr); diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp new file mode 100644 index 000000000..67be92e5c --- /dev/null +++ b/src/graphics/render/ModelBatch.cpp @@ -0,0 +1,175 @@ +#include "ModelBatch.hpp" + +#include "../core/Mesh.hpp" +#include "../core/Model.hpp" +#include "../core/Texture.hpp" +#include "../../assets/Assets.hpp" +#include "../../window/Window.hpp" +#include "../../voxels/Chunks.hpp" +#include "../../lighting/Lightmap.hpp" + +#define GLM_ENABLE_EXPERIMENTAL +#include +#include +#include + +#include + +/// xyz, uv, compressed rgba +inline constexpr uint VERTEX_SIZE = 6; + +static const vattr attrs[] = { + {3}, {2}, {1}, {0} +}; + +inline constexpr glm::vec3 X(1, 0, 0); +inline constexpr glm::vec3 Y(0, 1, 0); +inline constexpr glm::vec3 Z(0, 0, 1); + +struct DecomposedMat4 { + glm::vec3 scale; + glm::mat3 rotation; + glm::vec3 translation; + glm::vec3 skew; + glm::vec4 perspective; +}; + +ModelBatch::ModelBatch(size_t capacity, Assets* assets, Chunks* chunks) + : buffer(std::make_unique(capacity * VERTEX_SIZE)), + capacity(capacity), + index(0), + mesh(std::make_unique(buffer.get(), 0, attrs)), + combined(1.0f), + assets(assets), + chunks(chunks) +{ + ubyte pixels[] = { + 255, 255, 255, 255, + }; + blank = std::make_unique(pixels, 1, 1, ImageFormat::rgba8888); +} + +ModelBatch::~ModelBatch() { +} + +void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, const glm::mat3& rotation) { + glm::vec3 gpos = matrix * glm::vec4(glm::vec3(), 1.0f); + light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z); + glm::vec4 lights ( + Lightmap::extract(light, 0) / 15.0f, + Lightmap::extract(light, 1) / 15.0f, + Lightmap::extract(light, 2) / 15.0f, + Lightmap::extract(light, 3) / 15.0f + ); + setTexture(assets->get(mesh.texture)); + size_t vcount = mesh.vertices.size(); + const auto& vertexData = mesh.vertices.data(); + for (size_t i = 0; i < vcount / 3; i++) { + if (index + VERTEX_SIZE * 3 > capacity * VERTEX_SIZE) { + flush(); + } + for (size_t j = 0; j < 3; j++) { + const auto& vert = vertexData[i * 3 + j]; + auto norm = rotation * vert.normal; + float d = glm::dot(norm, SUN_VECTOR); + d = 0.8f + d * 0.2f; + + auto color = lights * d; + vertex(matrix * glm::vec4(vert.coord, 1.0f), vert.uv, color); + } + } +} + +void ModelBatch::draw(const model::Model* model) { + for (const auto& mesh : model->meshes) { + entries.push_back({combined, rotation, &mesh}); + } +} + +void ModelBatch::render() { + std::sort(entries.begin(), entries.end(), + [](const DrawEntry& a, const DrawEntry& b) { + return a.mesh->texture < b.mesh->texture; + } + ); + for (auto& entry : entries) { + draw(*entry.mesh, entry.matrix, entry.rotation); + } + flush(); + entries.clear(); +} + +void ModelBatch::box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights) { + if (index + 36 < capacity*VERTEX_SIZE) { + flush(); + } + plane(pos+Z*size, X*size, Y*size, Z, lights); + plane(pos-Z*size, -X*size, Y*size, -Z, lights); + + plane(pos+Y*size, X*size, -Z*size, Y, lights); + plane(pos-Y*size, X*size, Z*size, -Y, lights); + + plane(pos+X*size, -Z*size, Y*size, X, lights); + plane(pos-X*size, Z*size, Y*size, -X, lights); +} + +void ModelBatch::setTexture(Texture* texture) { + if (texture == nullptr) { + texture = blank.get(); + } + if (texture != this->texture) { + flush(); + } + this->texture = texture; +} + +void ModelBatch::flush() { + if (index == 0) { + return; + } + if (texture == nullptr) { + texture = blank.get(); + } + texture->bind(); + mesh->reload(buffer.get(), index / VERTEX_SIZE); + mesh->draw(); + index = 0; +} + +static glm::mat4 extract_rotation(glm::mat4 matrix) { + DecomposedMat4 decomposed = {}; + glm::quat rotation; + glm::decompose( + matrix, + decomposed.scale, + rotation, + decomposed.translation, + decomposed.skew, + decomposed.perspective + ); + return glm::toMat3(rotation); +} + +void ModelBatch::translate(glm::vec3 vec) { + pushMatrix(glm::translate(glm::mat4(1.0f), vec)); +} + +void ModelBatch::rotate(glm::vec3 axis, float angle) { + pushMatrix(glm::rotate(glm::mat4(1.0f), angle, axis)); +} + +void ModelBatch::scale(glm::vec3 vec) { + pushMatrix(glm::scale(glm::mat4(1.0f), vec)); +} + +void ModelBatch::pushMatrix(glm::mat4 matrix) { + matrices.push_back(combined); + combined = combined * matrix; + rotation = extract_rotation(combined); +} + +void ModelBatch::popMatrix() { + combined = matrices[matrices.size()-1]; + matrices.erase(matrices.end()-1); + rotation = extract_rotation(combined); +} diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp new file mode 100644 index 000000000..ba6f1eeda --- /dev/null +++ b/src/graphics/render/ModelBatch.hpp @@ -0,0 +1,101 @@ +#ifndef GRAPHICS_RENDER_MODEL_BATCH_HPP_ +#define GRAPHICS_RENDER_MODEL_BATCH_HPP_ + +#include +#include +#include + +class Mesh; +class Texture; +class Chunks; +class Assets; + +namespace model { + struct Mesh; + struct Model; +} + +class ModelBatch { + std::unique_ptr const buffer; + size_t const capacity; + size_t index; + + std::unique_ptr mesh; + std::unique_ptr blank; + + glm::mat4 combined; + std::vector matrices; + glm::mat3 rotation; + + Assets* assets; + Chunks* chunks; + Texture* texture = nullptr; + + static inline glm::vec3 SUN_VECTOR {0.411934f, 0.863868f, -0.279161f}; + + inline void vertex( + glm::vec3 pos, glm::vec2 uv, glm::vec4 light + ) { + float* buffer = this->buffer.get(); + buffer[index++] = pos.x; + buffer[index++] = pos.y; + buffer[index++] = pos.z; + buffer[index++] = uv.x; + buffer[index++] = uv.y; + + union { + float floating; + uint32_t integer; + } compressed; + + compressed.integer = (static_cast(light.r * 255) & 0xff) << 24; + compressed.integer |= (static_cast(light.g * 255) & 0xff) << 16; + compressed.integer |= (static_cast(light.b * 255) & 0xff) << 8; + compressed.integer |= (static_cast(light.a * 255) & 0xff); + + buffer[index++] = compressed.floating; + } + + inline void plane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm, glm::vec4 lights) { + norm = rotation * norm; + float d = glm::dot(norm, SUN_VECTOR); + d = 0.8f + d * 0.2f; + + auto color = lights * d; + + vertex(pos-right-up, {0,0}, color); + vertex(pos+right-up, {1,0}, color); + vertex(pos+right+up, {1,1}, color); + + vertex(pos-right-up, {0,0}, color); + vertex(pos+right+up, {1,1}, color); + vertex(pos-right+up, {0,1}, color); + } + + void draw(const model::Mesh& mesh, const glm::mat4& matrix, const glm::mat3& rotation); + void box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights); + void setTexture(Texture* texture); + void flush(); + + struct DrawEntry { + glm::mat4 matrix; + glm::mat3 rotation; + const model::Mesh* mesh; + }; + std::vector entries; +public: + ModelBatch(size_t capacity, Assets* assets, Chunks* chunks); + ~ModelBatch(); + + void translate(glm::vec3 vec); + void rotate(glm::vec3 axis, float angle); + void scale(glm::vec3 vec); + + void pushMatrix(glm::mat4 matrix); + void popMatrix(); + void draw(const model::Model* model); + + void render(); +}; + +#endif // GRAPHICS_RENDER_MODEL_BATCH_HPP_ diff --git a/src/graphics/render/Skybox.cpp b/src/graphics/render/Skybox.cpp index c98406da8..493106099 100644 --- a/src/graphics/render/Skybox.cpp +++ b/src/graphics/render/Skybox.cpp @@ -9,6 +9,7 @@ #include "../../graphics/core/DrawContext.hpp" #include "../../window/Window.hpp" #include "../../window/Camera.hpp" +#include "../../maths/UVRegion.hpp" #include #include @@ -58,7 +59,7 @@ Skybox::~Skybox() { } void Skybox::drawBackground(Camera* camera, Assets* assets, int width, int height) { - Shader* backShader = assets->getShader("background"); + auto backShader = assets->get("background"); backShader->use(); backShader->uniformMatrix("u_view", camera->getView(false)); backShader->uniform1f("u_zoom", camera->zoom*camera->getFov()/(M_PI*0.5f)); @@ -106,7 +107,7 @@ void Skybox::draw( DrawContext ctx = pctx.sub(); ctx.setBlendMode(BlendMode::addition); - Shader* shader = assets->getShader("ui3d"); + auto shader = assets->get("ui3d"); shader->use(); shader->uniformMatrix("u_projview", camera->getProjView(false)); shader->uniformMatrix("u_apply", glm::mat4(1.0f)); @@ -116,7 +117,7 @@ void Skybox::draw( float opacity = glm::pow(1.0f-fog, 7.0f); for (auto& sprite : sprites) { - batch3d->texture(assets->getTexture(sprite.texture)); + batch3d->texture(assets->get(sprite.texture)); float sangle = daytime * M_PI*2 + sprite.phase; float distance = sprite.distance; diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 795e4c0d9..f94939de5 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -1,6 +1,7 @@ #include "WorldRenderer.hpp" #include "ChunksRenderer.hpp" +#include "ModelBatch.hpp" #include "Skybox.hpp" #include "../../assets/Assets.hpp" @@ -31,6 +32,7 @@ #include "../core/PostProcessing.hpp" #include "../core/Shader.hpp" #include "../core/Texture.hpp" +#include "../core/Model.hpp" #include #include @@ -43,11 +45,12 @@ bool WorldRenderer::showChunkBorders = false; WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* player) - : engine(engine), - level(frontend->getLevel()), - player(player), - frustumCulling(std::make_unique()), - lineBatch(std::make_unique()) + : engine(engine), + level(frontend->getLevel()), + player(player), + frustumCulling(std::make_unique()), + lineBatch(std::make_unique()), + modelBatch(std::make_unique(20'000, engine->getAssets(), level->chunks.get())) { renderer = std::make_unique( level, @@ -65,7 +68,7 @@ WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* pl auto assets = engine->getAssets(); skybox = std::make_unique( settings.graphics.skyboxResolution.get(), - assets->getShader("skybox_gen") + assets->get("skybox_gen") ); } @@ -104,7 +107,7 @@ bool WorldRenderer::drawChunk( chunk->z * CHUNK_D + CHUNK_D ); - if (!frustumCulling->IsBoxVisible(min, max)) + if (!frustumCulling->isBoxVisible(min, max)) return false; } glm::vec3 coord(chunk->x*CHUNK_W+0.5f, 0.5f, chunk->z*CHUNK_D+0.5f); @@ -151,9 +154,9 @@ void WorldRenderer::renderLevel( Camera* camera, const EngineSettings& settings ) { - Assets* assets = engine->getAssets(); - Atlas* atlas = assets->getAtlas("blocks"); - Shader* shader = assets->getShader("main"); + auto assets = engine->getAssets(); + auto atlas = assets->get("blocks"); + auto shader = assets->get("main"); auto indices = level->content->getIndices(); @@ -191,6 +194,10 @@ void WorldRenderer::renderLevel( drawChunks(level->chunks.get(), camera, shader); + shader->uniformMatrix("u_model", glm::mat4(1.0f)); + // draw entities here + modelBatch->render(); + skybox->unbind(); } @@ -286,8 +293,8 @@ void WorldRenderer::draw( const EngineSettings& settings = engine->getSettings(); skybox->refresh(pctx, world->daytime, 1.0f+world->fog*2.0f, 4); - Assets* assets = engine->getAssets(); - Shader* linesShader = assets->getShader("lines"); + auto assets = engine->getAssets(); + auto linesShader = assets->get("lines"); // World render scope with diegetic HUD included { @@ -317,7 +324,7 @@ void WorldRenderer::draw( } // Rendering fullscreen quad with - auto screenShader = assets->getShader("screen"); + auto screenShader = assets->get("screen"); screenShader->use(); screenShader->uniform1f("u_timer", Window::time()); screenShader->uniform1f("u_dayTime", level->getWorld()->daytime); diff --git a/src/graphics/render/WorldRenderer.hpp b/src/graphics/render/WorldRenderer.hpp index 27d1a5694..af8eeaff1 100644 --- a/src/graphics/render/WorldRenderer.hpp +++ b/src/graphics/render/WorldRenderer.hpp @@ -23,8 +23,13 @@ class LevelFrontend; class Skybox; class PostProcessing; class DrawContext; +class ModelBatch; struct EngineSettings; +namespace model { + struct Model; +} + class WorldRenderer { Engine* engine; Level* level; @@ -34,6 +39,8 @@ class WorldRenderer { std::unique_ptr renderer; std::unique_ptr skybox; std::unique_ptr batch3d; + std::unique_ptr modelBatch; + bool drawChunk(size_t index, Camera* camera, Shader* shader, bool culling); void drawChunks(Chunks* chunks, Camera* camera, Shader* shader); diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index 7881d5475..54c04476a 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -205,7 +205,7 @@ void GUI::draw(const DrawContext* pctx, Assets* assets) { menu->setPos((wsize - menu->getSize()) / 2.0f); uicamera->setFov(wsize.y); - Shader* uishader = assets->getShader("ui"); + auto uishader = assets->get("ui"); uishader->use(); uishader->uniformMatrix("u_projview", uicamera->getProjView()); diff --git a/src/graphics/ui/elements/Image.cpp b/src/graphics/ui/elements/Image.cpp index d99c5a9de..e3b7243e6 100644 --- a/src/graphics/ui/elements/Image.cpp +++ b/src/graphics/ui/elements/Image.cpp @@ -18,7 +18,7 @@ void Image::draw(const DrawContext* pctx, Assets* assets) { glm::vec2 pos = calcPos(); auto batch = pctx->getBatch2D(); - auto texture = assets->getTexture(this->texture); + auto texture = assets->get(this->texture); if (texture && autoresize) { setSize(glm::vec2(texture->getWidth(), texture->getHeight())); } diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index b364425fc..92084c374 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -21,6 +21,7 @@ #include "../../core/Font.hpp" #include "../../core/DrawContext.hpp" #include "../../core/Shader.hpp" +#include "../../core/Texture.hpp" #include "../../render/BlocksPreview.hpp" #include "../GUI.hpp" @@ -155,7 +156,7 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) { batch->setColor(glm::vec4(1.0f)); - auto previews = assets->getAtlas("block-previews"); + auto previews = assets->get("block-previews"); auto indices = content->getIndices(); ItemDef* item = indices->getItemDef(stack.getItemId()); @@ -177,10 +178,10 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) { std::string name = item->icon.substr(index+1); UVRegion region(0.0f, 0.0, 1.0f, 1.0f); if (index == std::string::npos) { - batch->texture(assets->getTexture(name)); + batch->texture(assets->get(name)); } else { std::string atlasname = item->icon.substr(0, index); - Atlas* atlas = assets->getAtlas(atlasname); + auto atlas = assets->get(atlasname); if (atlas && atlas->has(name)) { region = atlas->get(name); batch->texture(atlas->getTexture()); @@ -194,7 +195,7 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) { } if (stack.getCount() > 1) { - auto font = assets->getFont("normal"); + auto font = assets->get("normal"); std::wstring text = std::to_wstring(stack.getCount()); int x = pos.x+slotSize-text.length()*8; diff --git a/src/graphics/ui/elements/Label.cpp b/src/graphics/ui/elements/Label.cpp index d4a9019cf..ac31e2a96 100644 --- a/src/graphics/ui/elements/Label.cpp +++ b/src/graphics/ui/elements/Label.cpp @@ -158,7 +158,7 @@ uint Label::getLinesNumber() const { void Label::draw(const DrawContext* pctx, Assets* assets) { auto batch = pctx->getBatch2D(); - auto font = assets->getFont(fontName); + auto font = assets->get(fontName); cache.prepare(font, static_cast(glm::abs(getSize().x))); if (supplier) { diff --git a/src/graphics/ui/elements/Plotter.cpp b/src/graphics/ui/elements/Plotter.cpp index bcb653d7a..28057ae58 100644 --- a/src/graphics/ui/elements/Plotter.cpp +++ b/src/graphics/ui/elements/Plotter.cpp @@ -37,7 +37,7 @@ void Plotter::draw(const DrawContext* pctx, Assets* assets) { } int current_point = static_cast(points[index % dmwidth]); - auto font = assets->getFont("normal"); + auto font = assets->get("normal"); for (int y = 0; y < dmheight; y += labelsInterval) { std::wstring string; if (current_point/16 == y/labelsInterval) { diff --git a/src/graphics/ui/elements/TextBox.cpp b/src/graphics/ui/elements/TextBox.cpp index b531bf686..26eaae969 100644 --- a/src/graphics/ui/elements/TextBox.cpp +++ b/src/graphics/ui/elements/TextBox.cpp @@ -33,7 +33,7 @@ TextBox::TextBox(std::wstring placeholder, glm::vec4 padding) void TextBox::draw(const DrawContext* pctx, Assets* assets) { Panel::draw(pctx, assets); - font = assets->getFont(label->getFontName()); + font = assets->get(label->getFontName()); if (!isFocused()) { return; diff --git a/src/logic/scripting/lua/libaudio.cpp b/src/logic/scripting/lua/libaudio.cpp index bec44719d..ec8749713 100644 --- a/src/logic/scripting/lua/libaudio.cpp +++ b/src/logic/scripting/lua/libaudio.cpp @@ -32,7 +32,7 @@ inline audio::speakerid_t play_sound( return 0; } auto assets = scripting::engine->getAssets(); - auto sound = assets->getSound(name); + auto sound = assets->get(name); if (sound == nullptr) { return 0; } diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index 258af55aa..7555f48db 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -27,7 +27,7 @@ struct DocumentNode { }; static DocumentNode getDocumentNode(lua::State*, const std::string& name, const std::string& nodeName) { - auto doc = engine->getAssets()->getLayout(name); + auto doc = engine->getAssets()->get(name); if (doc == nullptr) { throw std::runtime_error("document '"+name+"' not found"); } @@ -545,7 +545,7 @@ static int l_gui_setattr(lua::State* L) { static int l_gui_get_env(lua::State* L) { auto name = lua::require_string(L, 1); - auto doc = engine->getAssets()->getLayout(name); + auto doc = engine->getAssets()->get(name); if (doc == nullptr) { throw std::runtime_error("document '"+std::string(name)+"' not found"); } @@ -566,7 +566,7 @@ static int l_gui_str(lua::State* L) { static int l_gui_reindex(lua::State* L) { auto name = lua::require_string(L, 1); - auto doc = engine->getAssets()->getLayout(name); + auto doc = engine->getAssets()->get(name); if (doc == nullptr) { throw std::runtime_error("document '"+std::string(name)+"' not found"); } diff --git a/src/logic/scripting/lua/libhud.cpp b/src/logic/scripting/lua/libhud.cpp index f2bd5535c..5395e7a14 100644 --- a/src/logic/scripting/lua/libhud.cpp +++ b/src/logic/scripting/lua/libhud.cpp @@ -51,7 +51,7 @@ static int l_hud_open_block(lua::State* L) { } auto def = content->getIndices()->getBlockDef(vox->id); auto assets = engine->getAssets(); - auto layout = assets->getLayout(def->uiLayout); + auto layout = assets->get(def->uiLayout); if (layout == nullptr) { throw std::runtime_error("block '"+def->name+"' has no ui layout"); } @@ -71,7 +71,7 @@ static int l_hud_show_overlay(lua::State* L) { bool playerInventory = lua::toboolean(L, 2); auto assets = engine->getAssets(); - auto layout = assets->getLayout(name); + auto layout = assets->get(name); if (layout == nullptr) { throw std::runtime_error("there is no ui layout "+util::quote(name)); } @@ -81,7 +81,7 @@ static int l_hud_show_overlay(lua::State* L) { static UiDocument* require_layout(const char* name) { auto assets = engine->getAssets(); - auto layout = assets->getLayout(name); + auto layout = assets->get(name); if (layout == nullptr) { throw std::runtime_error("layout '"+std::string(name)+"' is not found"); } diff --git a/src/logic/scripting/lua/libmat4.cpp b/src/logic/scripting/lua/libmat4.cpp index 4e989545e..16cc20986 100644 --- a/src/logic/scripting/lua/libmat4.cpp +++ b/src/logic/scripting/lua/libmat4.cpp @@ -121,7 +121,7 @@ inline int l_rotate(lua::State* L) { auto matrix = lua::tomat4(L, 1); auto vec = lua::tovec3(L, 2); auto angle = glm::radians(static_cast(lua::tonumber(L, 3))); - return lua::setmat4(L, 3, glm::rotate(matrix, angle, vec)); + return lua::setmat4(L, 4, glm::rotate(matrix, angle, vec)); } default: { throw std::runtime_error("invalid arguments number (2, 3 or 4 expected)"); diff --git a/src/maths/FrustumCulling.hpp b/src/maths/FrustumCulling.hpp index b2b46ed4e..309fc1ba8 100644 --- a/src/maths/FrustumCulling.hpp +++ b/src/maths/FrustumCulling.hpp @@ -9,7 +9,7 @@ class Frustum Frustum() {}; void update(glm::mat4 projview); - bool IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const; + bool isBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const; private: enum Planes @@ -76,8 +76,7 @@ inline void Frustum::update(glm::mat4 m) } -inline bool Frustum::IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const -{ +inline bool Frustum::isBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const { // check box outside/inside of frustum for (int i = 0; i < Count; i++) {