diff --git a/assets/model/creature/collision.json b/assets/model/creature/pig/collision.json similarity index 100% rename from assets/model/creature/collision.json rename to assets/model/creature/pig/collision.json diff --git a/assets/model/creature/pig.glb b/assets/model/creature/pig/pig.glb similarity index 100% rename from assets/model/creature/pig.glb rename to assets/model/creature/pig/pig.glb diff --git a/assets/model/creature/player/player.glb b/assets/model/creature/player/player.glb new file mode 100644 index 0000000..b94f8d9 Binary files /dev/null and b/assets/model/creature/player/player.glb differ diff --git a/include/Cubed/app.hpp b/include/Cubed/app.hpp index 2d509aa..9fd6c7c 100644 --- a/include/Cubed/app.hpp +++ b/include/Cubed/app.hpp @@ -3,7 +3,6 @@ #include "Cubed/audio/audio_engine.hpp" #include "Cubed/config.hpp" #include "Cubed/dev_panel.hpp" -#include "Cubed/render/model_manager.hpp" #include "Cubed/render/renderer.hpp" #include "Cubed/scene/scene_manager.hpp" #include "Cubed/texture_manager.hpp" @@ -50,7 +49,6 @@ private: Window m_window; TextureManager m_texture_manager; - ModelManager m_model_manager; AudioEngine m_audio; Renderer m_renderer; diff --git a/include/Cubed/gameplay/entity.hpp b/include/Cubed/gameplay/entity.hpp index e600bf2..d13860e 100644 --- a/include/Cubed/gameplay/entity.hpp +++ b/include/Cubed/gameplay/entity.hpp @@ -1,12 +1,13 @@ #pragma once -#include "Cubed/AABB.hpp" #include "Cubed/constants.hpp" +#include "Cubed/gameplay/hitbox.hpp" +#include "Cubed/gameplay/model.hpp" #include "Cubed/gameplay/player.hpp" #include #include namespace Cubed { - +using EntityID = uint64_t; struct Position { glm::vec3 value{0.0f}; }; @@ -22,6 +23,9 @@ struct WalkPose { struct EntityInfo { std::string name; std::string uuid; + EntityID id; + HitboxID hitbox; + ModelID model; }; struct Health { @@ -40,10 +44,6 @@ struct Velocity { glm::vec3 max{4.5f, 7.5f, 7.5f}; }; -struct HitBoxes { - std::vector boxex; -}; - struct Movement { float acceleration = DEFAULT_ACCELERATION; float deceleration = DEFAULT_DECELERATION; @@ -72,6 +72,8 @@ struct Direction { class Entity { public: + Entity(EntityID id, const std::string& name); + glm::vec3& max_speed(); float& acceleration(); float& deceleration(); @@ -91,6 +93,7 @@ public: Gravity& gravity(); MoveState& move_state(); Direction& direction(); + EntityInfo& info(); const Velocity& velocity() const; const Position& pos() const; @@ -100,8 +103,10 @@ public: const Gravity& gravity() const; const MoveState& move_state() const; const Direction& direction() const; + const EntityInfo& info() const; protected: + EntityInfo m_info; Position m_pos; WalkPose m_walk_pose; Velocity m_velocity; diff --git a/include/Cubed/AABB.hpp b/include/Cubed/gameplay/hitbox.hpp similarity index 78% rename from include/Cubed/AABB.hpp rename to include/Cubed/gameplay/hitbox.hpp index fd32468..70ab592 100644 --- a/include/Cubed/AABB.hpp +++ b/include/Cubed/gameplay/hitbox.hpp @@ -3,18 +3,20 @@ namespace Cubed { -struct AABB { +using HitboxID = uint32_t; + +struct Hitbox { glm::vec3 center{0.0f}; glm::vec3 half{0.0f}; - AABB(glm::vec3 center_point, glm::vec3 half_size) + Hitbox(glm::vec3 center_point, glm::vec3 half_size) : center(center_point), half(half_size) {} glm::vec3 min() const { return center - half; } glm::vec3 max() const { return center + half; } - bool intersects(const AABB& other) const { + bool intersects(const Hitbox& other) const { return (glm::abs(center.x - other.center.x) <= half.x + other.half.x) && (glm::abs(center.y - other.center.y) <= half.y + other.half.y) && (glm::abs(center.z - other.center.z) <= half.z + other.half.z); diff --git a/include/Cubed/gameplay/hitbox_manager.hpp b/include/Cubed/gameplay/hitbox_manager.hpp index d62f0e5..b8a2292 100644 --- a/include/Cubed/gameplay/hitbox_manager.hpp +++ b/include/Cubed/gameplay/hitbox_manager.hpp @@ -1,24 +1,37 @@ #pragma once -#include "Cubed/AABB.hpp" +#include "Cubed/gameplay/hitbox.hpp" #include namespace Cubed { class HitboxManager { public: + struct Handle { + Hitbox box; + HitboxID id = 0; + }; HitboxManager(); ~HitboxManager(); static HitboxManager& instance(); - AABB get_aabb(const std::string& key); - - static AABB aabb(const std::string& key); + [[nodiscard]] + Handle get_hitbox(const std::string& key); + [[nodiscard]] + Handle get_hitbox(HitboxID id); + [[nodiscard]] + static Handle hitbox(const std::string& name); + [[nodiscard]] + static Handle hitbox(HitboxID id); + HitboxID get_hitbox_id(const std::string& name); + const std::string& get_hitbox_name(HitboxID id); private: - using HitBoxMap = tbb::concurrent_hash_map; - using cacc = HitBoxMap::const_accessor; - using acc = HitBoxMap::accessor; - HitBoxMap m_hitboxes; - - AABB load(const std::string& path); + using HitboxMap = tbb::concurrent_hash_map; + using IDMap = tbb::concurrent_hash_map; + using NameMap = tbb::concurrent_hash_map; + HitboxID m_next = 0; + IDMap m_id_map; + NameMap m_name_map; + HitboxMap m_hitboxes; + Handle load(std::string_view name); }; } // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/world.hpp b/include/Cubed/gameplay/world.hpp index 038cee1..69ffd7c 100644 --- a/include/Cubed/gameplay/world.hpp +++ b/include/Cubed/gameplay/world.hpp @@ -1,6 +1,6 @@ #pragma once -#include "Cubed/AABB.hpp" #include "Cubed/gameplay/block.hpp" +#include "Cubed/gameplay/hitbox.hpp" #include namespace Cubed { @@ -19,7 +19,7 @@ public: virtual BlockType get_block_tpye(const glm::ivec3& block_pos) const = 0; virtual int get_per_tick_time() const = 0; - static AABB get_block_aabb(const glm::ivec3& pos) { + static Hitbox get_block_aabb(const glm::ivec3& pos) { return {glm::vec3{static_cast(pos.x) + 0.5f, static_cast(pos.y) + 0.5f, static_cast(pos.z) + 0.5f}, diff --git a/include/Cubed/render/model_manager.hpp b/include/Cubed/render/model_manager.hpp index ab78f6e..3a01382 100644 --- a/include/Cubed/render/model_manager.hpp +++ b/include/Cubed/render/model_manager.hpp @@ -7,14 +7,26 @@ namespace Cubed { class ModelManager { public: + struct Handle { + const ModelNode& node; + ModelID id = 0; + }; + ModelManager(); ModelManager(const ModelManager&) = delete; ModelManager(ModelManager&&) = delete; ModelManager& operator=(const ModelManager&) = delete; ModelManager& operator=(ModelManager&&) = delete; + static ModelManager& instance(); ~ModelManager(); - const ModelNode& get_model(const std::string& model_name); - const ModelNode& get_model(ModelID id); + [[nodiscard]] + Handle get_model(const std::string& model_name); + [[nodiscard]] + Handle get_model(ModelID id); + [[nodiscard]] + static Handle model(const std::string& model_name); + [[nodiscard]] + static Handle model(ModelID id); ModelID get_model_id(const std::string& name); const std::string& get_model_name(ModelID id); void init(); @@ -28,6 +40,6 @@ private: ModelMap m_models; IDMap m_id_map; NameMap m_name_map; - const ModelNode& load_model(std::string_view model_name); + Handle load_model(std::string_view model_name); }; } // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/render/model_renderer.hpp b/include/Cubed/render/model_renderer.hpp index fc62ae0..b6ae802 100644 --- a/include/Cubed/render/model_renderer.hpp +++ b/include/Cubed/render/model_renderer.hpp @@ -1,5 +1,6 @@ #pragma once +#include "Cubed/gameplay/model.hpp" #include "Cubed/render/model_node.hpp" #include "Cubed/shader.hpp" @@ -10,11 +11,9 @@ class Camera; class ModelRender { public: ModelRender(Renderer& renderer); - void render_model(const std::string& name, const glm::vec3& pos, - Camera& camera); + void render_model(ModelID id, const glm::vec3& pos, Camera& camera); - void shadow_pass(const std::string& name, const glm::vec3& pos, - Camera& camera); + void shadow_pass(ModelID id, const glm::vec3& pos, Camera& camera); private: Renderer& m_renderer; diff --git a/include/Cubed/render/renderer.hpp b/include/Cubed/render/renderer.hpp index df772f1..b2deb3f 100644 --- a/include/Cubed/render/renderer.hpp +++ b/include/Cubed/render/renderer.hpp @@ -26,8 +26,7 @@ class Renderer { public: constexpr static int NUM_VAO = 7; - Renderer(TextureManager& texture_manager, Config& config, - ModelManager& model_manager); + Renderer(TextureManager& texture_manager, Config& config); ~Renderer(); void reload_config(); void init(); @@ -82,12 +81,10 @@ public: bool handle_event(const Event& e); - ModelManager& model_manager(); ModelRender& model_renderer(); private: TextureManager& m_texture_manager; - ModelManager& m_model_manager; bool m_init = false; float m_aspect = 0.0f; diff --git a/include/Cubed/tools/name_space.hpp b/include/Cubed/tools/name_space.hpp new file mode 100644 index 0000000..10c9d50 --- /dev/null +++ b/include/Cubed/tools/name_space.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include +#include +namespace Cubed { +inline std::vector parse_namespace(std::string_view str) { + std::vector space; + space.reserve(4); + std::size_t p = str.find(':'); + std::size_t start = 0; + while (p != std::string_view::npos) { + space.emplace_back(str.substr(start, p)); + start = p + 1; + p = str.find(':', p + 1); + } + space.emplace_back(str.substr(start)); + return space; +} +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/tools/sparse_vector.hpp b/include/Cubed/tools/sparse_vector.hpp index f70e4a3..3b57c61 100644 --- a/include/Cubed/tools/sparse_vector.hpp +++ b/include/Cubed/tools/sparse_vector.hpp @@ -236,7 +236,7 @@ public: } }; - template Handle insert(U&& value) { + template [[nodiscard]] Handle insert(U&& value) { uint32_t id; if (!m_free_list.empty()) { id = m_free_list.back(); diff --git a/src/app.cpp b/src/app.cpp index 2ae7ddc..1abc51a 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -20,8 +20,7 @@ App::App() : m_game_config(ASSETS_PATH "config.toml"), m_window(m_game_config), m_texture_manager(m_game_config), m_audio(m_game_config), - m_renderer(m_texture_manager, m_game_config, m_model_manager), - m_scene_manager(*this) {} + m_renderer(m_texture_manager, m_game_config), m_scene_manager(*this) {} App::~App() { stop_text_input(); @@ -86,7 +85,6 @@ void App::init(int argc, char** argv) { Logger::info("Renderer Init Success"); // MapTable::init_map(); m_texture_manager.init_texture(); - m_model_manager.init(); Logger::info("Texture Load Success"); m_scene_manager.request_push(SceneType::MAIN_MENU); diff --git a/src/gameplay/client_player.cpp b/src/gameplay/client_player.cpp index b9fb33b..fe073b0 100644 --- a/src/gameplay/client_player.cpp +++ b/src/gameplay/client_player.cpp @@ -10,7 +10,8 @@ namespace {} // namespace namespace Cubed { -ClientPlayer::ClientPlayer(ClientWorld& world) : m_world(world) {} +ClientPlayer::ClientPlayer(ClientWorld& world) + : Entity(0, "cubed:player"), m_world(world) {} ClientPlayer::~ClientPlayer() {} const glm::vec3& ClientPlayer::get_front() const { return m_front; } @@ -312,10 +313,10 @@ void ClientPlayer::place_block(float dt) { if (type != 0) { glm::ivec3 near_pos = m_look_block->pos + m_look_block->normal; if (!m_world.is_solid(near_pos)) { - AABB block_box = ClientWorld::get_block_aabb(near_pos); - AABB player_box = HitboxManager::aabb("cubed:player"); - player_box.center += get_player_pos(); - if (!player_box.intersects(block_box)) { + Hitbox block_box = ClientWorld::get_block_aabb(near_pos); + auto player_box = HitboxManager::hitbox("cubed:player"); + player_box.box.center += get_player_pos(); + if (!player_box.box.intersects(block_box)) { m_world.report_block_change(near_pos, type); } } diff --git a/src/gameplay/client_world.cpp b/src/gameplay/client_world.cpp index 58ca240..e119c7b 100644 --- a/src/gameplay/client_world.cpp +++ b/src/gameplay/client_world.cpp @@ -295,14 +295,14 @@ void ClientWorld::push_delete_vao(std::unique_ptr& vao) { void ClientWorld::report_block_change(const glm::ivec3& pos, unsigned id) const { if (id != 0) { - AABB block_box = get_block_aabb(pos); + Hitbox block_box = get_block_aabb(pos); std::shared_lock lock(m_players_date_mutex); for (const auto& player : m_players_data) { - AABB box = HitboxManager::aabb("cubed:player"); - box.center += player.pos.value; - if (box.intersects(block_box)) { + auto box = HitboxManager::hitbox("cubed:player"); + box.box.center += player.pos.value; + if (box.box.intersects(block_box)) { return; } } diff --git a/src/gameplay/entity.cpp b/src/gameplay/entity.cpp index 7ea7030..2d98c92 100644 --- a/src/gameplay/entity.cpp +++ b/src/gameplay/entity.cpp @@ -1,6 +1,18 @@ #include "Cubed/gameplay/entity.hpp" +#include "Cubed/gameplay/hitbox_manager.hpp" +#include "Cubed/render/model_manager.hpp" namespace Cubed { + +Entity::Entity(EntityID id, const std::string& name) { + m_info.id = id; + m_info.name = name; + auto h = ModelManager::model(name); + m_info.model = h.id; + auto b = HitboxManager::hitbox(name); + m_info.hitbox = b.id; +} + glm::vec3& Entity::max_speed() { return m_velocity.max; } float& Entity::acceleration() { return m_movement.acceleration; } float& Entity::deceleration() { return m_movement.deceleration; } @@ -20,6 +32,7 @@ Movement& Entity::movement() { return m_movement; } Gravity& Entity::gravity() { return m_gravity; } MoveState& Entity::move_state() { return m_move_state; } Direction& Entity::direction() { return m_direction; } +EntityInfo& Entity::info() { return m_info; } const Velocity& Entity::velocity() const { return m_velocity; } const Position& Entity::pos() const { return m_pos; } @@ -29,5 +42,6 @@ const Movement& Entity::movement() const { return m_movement; } const Gravity& Entity::gravity() const { return m_gravity; } const MoveState& Entity::move_state() const { return m_move_state; } const Direction& Entity::direction() const { return m_direction; } +const EntityInfo& Entity::info() const { return m_info; } } // namespace Cubed \ No newline at end of file diff --git a/src/gameplay/hitbox_manager.cpp b/src/gameplay/hitbox_manager.cpp index a340709..f12a10d 100644 --- a/src/gameplay/hitbox_manager.cpp +++ b/src/gameplay/hitbox_manager.cpp @@ -1,7 +1,9 @@ #include "Cubed/gameplay/hitbox_manager.hpp" #include "Cubed/gameplay/player.hpp" +#include "Cubed/tools/cubed_assert.hpp" #include "Cubed/tools/log.hpp" +#include "Cubed/tools/name_space.hpp" #include namespace fs = std::filesystem; @@ -12,7 +14,13 @@ HitboxManager::HitboxManager() { glm::vec3 half = PLAYER_SIZE * 0.5f; glm::vec3 center{0.0f, half.y, 0.0f}; - m_hitboxes.emplace("cubed:player", AABB{center, half}); + + HitboxMap::accessor a; + if (m_hitboxes.insert( + a, std::pair{m_next++, Hitbox{center, half}})) { + m_name_map.emplace(a->first, "cubed:player"); + m_id_map.emplace("cubed:player", a->first); + } } HitboxManager::~HitboxManager() {} @@ -22,23 +30,56 @@ HitboxManager& HitboxManager::instance() { return inst; } -AABB HitboxManager::aabb(const std::string& key) { - return instance().get_aabb(key); +HitboxManager::Handle HitboxManager::hitbox(const std::string& key) { + return instance().get_hitbox(key); } -AABB HitboxManager::get_aabb(const std::string& key) { +HitboxManager::Handle HitboxManager::hitbox(HitboxID id) { + return instance().get_hitbox(id); +} +HitboxID HitboxManager::get_hitbox_id(const std::string& name) { + IDMap::const_accessor cacc; + if (m_id_map.find(cacc, name)) { + return cacc->second; + } + return load(name).id; +} +const std::string& HitboxManager::get_hitbox_name(HitboxID id) { + NameMap::const_accessor cacc; + if (m_name_map.find(cacc, id)) { + return cacc->second; + } + ASSERT_MSG(false, std::format("ModelManager: Can't find {}", id)); + static std::string n = ""; + return n; +} + +HitboxManager::Handle HitboxManager::get_hitbox(HitboxID id) { { - cacc c; - if (m_hitboxes.find(c, key)) { - return c->second; + HitboxMap::const_accessor c; + if (m_hitboxes.find(c, id)) { + return {c->second, c->first}; } } - return load(key); + return load(get_hitbox_name(id)); } +HitboxManager::Handle HitboxManager::get_hitbox(const std::string& name) { + return get_hitbox(get_hitbox_id(name)); +} +HitboxManager::Handle HitboxManager::load(std::string_view name) { + + auto space = parse_namespace(name); + ASSERT(space.size() >= 2); + fs::path p; + if (space[0] == "cubed") { + p = std::format("{}model/creature/{}/collision.json", ASSETS_PATH, + space[1]); + } else { + p = std::format("{}/model/creature/{}/collision.json", space[0], + space[1]); + } -AABB HitboxManager::load(const std::string& path) { - fs::path p = ASSETS_PATH + path; try { glm::vec3 center; glm::vec3 half; @@ -56,16 +97,24 @@ AABB HitboxManager::load(const std::string& path) { half.z = j["boxes"]["half"].at(2).get(); } } - acc a; - if (m_hitboxes.insert( - a, std::pair{path, AABB{center, half}})) { - return a->second; + { + HitboxMap::accessor a; + if (m_hitboxes.insert(a, std::pair{ + m_next++, Hitbox{center, half}})) { + m_name_map.emplace(a->first, name); + m_id_map.emplace(name, a->first); + return {a->second, a->first}; + } + } + HitboxMap::const_accessor cacc; + if (m_hitboxes.find(cacc, get_hitbox_id(std::string(name)))) { + return {cacc->second, cacc->first}; } } catch (const std::exception& e) { Logger::error("Load Hitbox error {}", e.what()); } - Logger::error("Load hitbox {} Failed", path); - return AABB{glm::vec3(0.0f), glm::vec3(0.0f)}; + Logger::error("Load hitbox {} Failed", name); + return {Hitbox{glm::vec3(0.0f), glm::vec3(0.0f)}, 0}; } } // namespace Cubed \ No newline at end of file diff --git a/src/gameplay/systems/physical_system.cpp b/src/gameplay/systems/physical_system.cpp index ed126d4..1115ccb 100644 --- a/src/gameplay/systems/physical_system.cpp +++ b/src/gameplay/systems/physical_system.cpp @@ -6,10 +6,10 @@ namespace Cubed { namespace { bool update_x(const glm::vec3& pos, const glm::vec3& distance, World& world, - const AABB& box) { + const Hitbox& box) { glm::vec3 p = pos; p.x += distance.x; - AABB b = box; + Hitbox b = box; b.center += p; glm::vec3 min = b.min(); glm::vec3 max = b.max(); @@ -25,7 +25,7 @@ bool update_x(const glm::vec3& pos, const glm::vec3& distance, World& world, for (int z = minz; z <= maxz; ++z) { glm::ivec3 block_pos{x, y, z}; if (!world.can_pass_block(block_pos)) { - AABB block_box = World::get_block_aabb(block_pos); + Hitbox block_box = World::get_block_aabb(block_pos); if (b.intersects(block_box)) { return false; } @@ -37,10 +37,10 @@ bool update_x(const glm::vec3& pos, const glm::vec3& distance, World& world, } bool update_y(const glm::vec3& pos, const glm::vec3& distance, World& world, - const AABB& box) { + const Hitbox& box) { glm::vec3 p = pos; p.y += distance.y; - AABB b = box; + Hitbox b = box; b.center += p; glm::vec3 min = b.min(); glm::vec3 max = b.max(); @@ -56,7 +56,7 @@ bool update_y(const glm::vec3& pos, const glm::vec3& distance, World& world, for (int z = minz; z <= maxz; ++z) { glm::ivec3 block_pos{x, y, z}; if (!world.can_pass_block(block_pos)) { - AABB block_box = World::get_block_aabb(block_pos); + Hitbox block_box = World::get_block_aabb(block_pos); if (b.intersects(block_box)) { return false; } @@ -68,10 +68,10 @@ bool update_y(const glm::vec3& pos, const glm::vec3& distance, World& world, } bool update_z(const glm::vec3& pos, const glm::vec3& distance, World& world, - const AABB& box) { + const Hitbox& box) { glm::vec3 p = pos; p.z += distance.z; - AABB b = box; + Hitbox b = box; b.center += p; glm::vec3 min = b.min(); glm::vec3 max = b.max(); @@ -87,7 +87,7 @@ bool update_z(const glm::vec3& pos, const glm::vec3& distance, World& world, for (int z = minz; z <= maxz; ++z) { glm::ivec3 block_pos{x, y, z}; if (!world.can_pass_block(block_pos)) { - AABB block_box = World::get_block_aabb(block_pos); + Hitbox block_box = World::get_block_aabb(block_pos); if (b.intersects(block_box)) { return false; } @@ -113,18 +113,18 @@ std::tuple PhysicalSystem::update(float dt, Entity& e, auto distance = get_move_distance(dt, e); auto& m_velocity = e.velocity(); auto& m_move_state = e.move_state(); - AABB box = HitboxManager::aabb("cubed:player"); + auto box = HitboxManager::hitbox(e.info().hitbox); bool x = false; bool y = false; bool z = false; - if (update_x(moved_pos, distance, world, box)) { + if (update_x(moved_pos, distance, world, box.box)) { moved_pos.x += distance.x; x = true; } else { m_velocity.value.x = 0.0f; } - if (update_y(moved_pos, distance, world, box)) { + if (update_y(moved_pos, distance, world, box.box)) { moved_pos.y += distance.y; y = true; } else { @@ -135,7 +135,7 @@ std::tuple PhysicalSystem::update(float dt, Entity& e, } } - if (update_z(moved_pos, distance, world, box)) { + if (update_z(moved_pos, distance, world, box.box)) { moved_pos.z += distance.z; z = true; } else { diff --git a/src/render/model_manager.cpp b/src/render/model_manager.cpp index 6cd047f..0201783 100644 --- a/src/render/model_manager.cpp +++ b/src/render/model_manager.cpp @@ -2,9 +2,24 @@ #include "Cubed/tools/cubed_assert.hpp" #include "Cubed/tools/log.hpp" +#include "Cubed/tools/name_space.hpp" namespace Cubed { -ModelManager::ModelManager() {} +ModelManager& ModelManager::instance() { + static ModelManager inst; + return inst; +} + +[[nodiscard]] +ModelManager::Handle ModelManager::model(const std::string& model_name) { + return instance().get_model(model_name); +} +[[nodiscard]] +ModelManager::Handle ModelManager::model(ModelID id) { + return instance().get_model(id); +} + +ModelManager::ModelManager() { init(); } ModelManager::~ModelManager() {} @@ -12,15 +27,15 @@ void ModelManager::init() { }; -const ModelNode& ModelManager::get_model(const std::string& model_name) { +ModelManager::Handle ModelManager::get_model(const std::string& model_name) { return get_model(get_model_id(model_name)); } -const ModelNode& ModelManager::get_model(ModelID id) { +ModelManager::Handle ModelManager::get_model(ModelID id) { ModelMap::const_accessor cacc; if (!m_models.find(cacc, id)) { - return cacc->second; + return {cacc->second, cacc->first}; } return load_model(get_model_name(id)); } @@ -32,8 +47,7 @@ ModelID ModelManager::get_model_id(const std::string& name) { if (m_id_map.find(cacc, name)) { return cacc->second; } - ASSERT_MSG(false, std::format("ModelManager: Can't find {}", name)); - return 0; + return load_model(name).id; } const std::string& ModelManager::get_model_name(ModelID id) { @@ -46,23 +60,24 @@ const std::string& ModelManager::get_model_name(ModelID id) { return n; } -const ModelNode& ModelManager::load_model(std::string_view model_name) { +ModelManager::Handle ModelManager::load_model(std::string_view model_name) { auto p = model_name.find(':'); if (p == std::string::npos) { Logger::error("Can't Parse Model name {}", model_name); ASSERT(false); } - auto name = model_name.substr(p + 1); - auto space = model_name.substr(0, p); - if (name.empty()) { + auto space = parse_namespace(model_name); + if (space.size() < 2) { Logger::error("Can't Parse Model name {}", model_name); ASSERT(false); } std::string path; - if (space == "cubed") { - path = std::format("{}model/creature/{}", ASSETS_PATH, name); + if (space[0] == "cubed") { + path = std::format("{}model/creature/{}/{}.gbl", ASSETS_PATH, space[1], + space[1]); } else { - path = std::format("./{}/model/creature/{}", space, name); + path = std::format("./{}/model/creature/{}/{}.gbl", space[0], space[1], + space[1]); } auto model = m_loader.load(path); ModelMap::accessor acc; @@ -70,11 +85,14 @@ const ModelNode& ModelManager::load_model(std::string_view model_name) { acc->second = std::move(model); } else { Logger::error("Can't Insert Model {}", model_name); - ASSERT(false); + ModelMap::const_accessor cacc; + if (m_models.find(cacc, get_model_id(std::string(model_name)))) { + return {cacc->second, cacc->first}; + } } m_id_map.emplace(model_name, acc->first); m_name_map.emplace(acc->first, model_name); - return acc->second; + return {acc->second, acc->first}; } } // namespace Cubed \ No newline at end of file diff --git a/src/render/model_renderer.cpp b/src/render/model_renderer.cpp index 1487f72..66bc4fd 100644 --- a/src/render/model_renderer.cpp +++ b/src/render/model_renderer.cpp @@ -6,10 +6,9 @@ namespace Cubed { ModelRender::ModelRender(Renderer& renderer) : m_renderer(renderer) {} -void ModelRender::render_model(const std::string& name, const glm::vec3& pos, +void ModelRender::render_model(ModelID id, const glm::vec3& pos, Camera& camera) { - auto& model_manager = m_renderer.model_manager(); - auto& root = model_manager.get_model(name); + auto& root = ModelManager::model(id).node; glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos); auto& shader = m_renderer.get_shader("model_shader"); glm::mat4 view = camera.get_camera_lookat(); @@ -17,10 +16,9 @@ void ModelRender::render_model(const std::string& name, const glm::vec3& pos, render_node(root, transform, view, shader, false); } -void ModelRender::shadow_pass(const std::string& name, const glm::vec3& pos, +void ModelRender::shadow_pass(ModelID id, const glm::vec3& pos, Camera& camera) { - auto& model_manager = m_renderer.model_manager(); - auto& root = model_manager.get_model(name); + auto& root = ModelManager::model(id).node; glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos); auto& shader = m_renderer.get_shader("depth_model"); glm::mat4 view = camera.get_camera_lookat(); diff --git a/src/render/renderer.cpp b/src/render/renderer.cpp index 494a5fa..b6d974c 100644 --- a/src/render/renderer.cpp +++ b/src/render/renderer.cpp @@ -15,10 +15,9 @@ namespace Cubed { -Renderer::Renderer(TextureManager& texture_manager, Config& config, - ModelManager& model_manager) - : m_texture_manager(texture_manager), m_model_manager(model_manager), - m_world_renderer(*this), m_model_renderer(*this), m_config(config) {} +Renderer::Renderer(TextureManager& texture_manager, Config& config) + : m_texture_manager(texture_manager), m_world_renderer(*this), + m_model_renderer(*this), m_config(config) {} Renderer::~Renderer() { if (m_init) { @@ -341,6 +340,5 @@ float Renderer::frame_height() const { return m_frame_height; } float Renderer::frame_width() const { return m_frame_width; } const glm::mat4& Renderer::p_mat() const { return m_world_proj_matrix; } const std::vector& Renderer::vao() const { return m_vao; } -ModelManager& Renderer::model_manager() { return m_model_manager; } ModelRender& Renderer::model_renderer() { return m_model_renderer; } } // namespace Cubed \ No newline at end of file