working on scene management

This commit is contained in:
2025-05-18 18:30:18 +02:00
parent be29d9a3be
commit 18190ac7a5
8 changed files with 42 additions and 59 deletions

View File

@@ -117,7 +117,7 @@ void Chunk::GenerateMesh()
void Chunk::UploadMesh() void Chunk::UploadMesh()
{ {
if(p_actor) if(p_actor || m_mesh_data.empty() || m_mesh_index_data.empty())
return; return;
std::shared_ptr<Scop::Mesh> mesh = std::make_shared<Scop::Mesh>(); std::shared_ptr<Scop::Mesh> mesh = std::make_shared<Scop::Mesh>();
mesh->AddSubMesh({ std::move(m_mesh_data), std::move(m_mesh_index_data) }); mesh->AddSubMesh({ std::move(m_mesh_data), std::move(m_mesh_index_data) });

View File

@@ -5,7 +5,7 @@
#include <World.h> #include <World.h>
#include <Utils.h> #include <Utils.h>
World::World(Scop::Scene& scene) : m_scene(scene), m_narrator(scene.CreateNarrator()), m_previous_chunk_position(-1000, 10000) World::World(Scop::Scene& scene) : m_scene(scene), m_previous_chunk_position(-1000, 10000)
{ {
Scop::Vec2ui32 map_size; Scop::Vec2ui32 map_size;
Scop::MaterialTextures material_params; Scop::MaterialTextures material_params;
@@ -37,7 +37,7 @@ World::World(Scop::Scene& scene) : m_scene(scene), m_narrator(scene.CreateNarrat
Upload(); Upload();
}; };
m_narrator.AttachScript(std::make_shared<Scop::NativeNarratorScript>(std::function<void()>{}, narrator_update, std::function<void()>{})); m_scene.CreateNarrator().AttachScript(std::make_shared<Scop::NativeNarratorScript>(std::function<void()>{}, narrator_update, std::function<void()>{}));
} }
[[nodiscard]] Scop::NonOwningPtr<Chunk> World::GetChunk(Scop::Vec2i position) [[nodiscard]] Scop::NonOwningPtr<Chunk> World::GetChunk(Scop::Vec2i position)
@@ -55,7 +55,7 @@ void World::UnloadChunks(Scop::Vec2i current_chunk_position)
Scop::Vec3i pos = it->first; Scop::Vec3i pos = it->first;
float x_dist = std::abs(pos.x - current_chunk_position.x); float x_dist = std::abs(pos.x - current_chunk_position.x);
float z_dist = std::abs(pos.z - current_chunk_position.y); float z_dist = std::abs(pos.z - current_chunk_position.y);
if(RENDER_DISTANCE_HALF < x_dist || RENDER_DISTANCE_HALF < z_dist) if(RENDER_DISTANCE < x_dist || RENDER_DISTANCE < z_dist)
{ {
if(it->second.GetActor()) if(it->second.GetActor())
m_scene.RemoveActor(*it->second.GetActor()); m_scene.RemoveActor(*it->second.GetActor());
@@ -69,22 +69,19 @@ void World::UnloadChunks(Scop::Vec2i current_chunk_position)
void World::GenerateWorld(Scop::Vec2i current_chunk_position) void World::GenerateWorld(Scop::Vec2i current_chunk_position)
{ {
m_generation_status = GenerationState::Working; m_generation_status = GenerationState::Working;
std::vector<std::future<void>> futures; for(std::int32_t x = current_chunk_position.x - RENDER_DISTANCE; x <= current_chunk_position.x + RENDER_DISTANCE; x++)
for(std::int32_t x = current_chunk_position.x - RENDER_DISTANCE_HALF; x <= current_chunk_position.x + RENDER_DISTANCE_HALF; x++)
{ {
for(std::int32_t z = current_chunk_position.y - RENDER_DISTANCE_HALF; z <= current_chunk_position.y + RENDER_DISTANCE_HALF; z++) for(std::int32_t z = current_chunk_position.y - RENDER_DISTANCE; z <= current_chunk_position.y + RENDER_DISTANCE; z++)
{ {
auto res = m_chunks.try_emplace(Scop::Vec2i{ x, z }, *this, Scop::Vec2i{ x, z }); auto res = m_chunks.try_emplace(Scop::Vec2i{ x, z }, *this, Scop::Vec2i{ x, z });
if(res.second) if(res.second)
{ {
futures.push_back(std::async(std::launch::async, &Chunk::GenerateChunk, &res.first->second)); res.first->second.GenerateChunk();
if(!res.first->second.GetActor()) if(!res.first->second.GetActor())
m_chunks_to_upload.Push(res.first->second); m_chunks_to_upload.Push(res.first->second);
} }
} }
} }
for(auto& future: futures)
future.wait();
m_generation_status = GenerationState::Finished; m_generation_status = GenerationState::Finished;
} }
@@ -95,9 +92,9 @@ void World::Upload()
Scop::RenderCore::Get().ShouldStackSubmits(true); Scop::RenderCore::Get().ShouldStackSubmits(true);
for(std::size_t i = 0; i < CHUNKS_UPLOAD_PER_FRAME && !m_chunks_to_upload.IsEmpty(); i++) for(std::size_t i = 0; i < CHUNKS_UPLOAD_PER_FRAME && !m_chunks_to_upload.IsEmpty(); i++)
{ {
auto chunk = m_chunks_to_upload.Pop().get(); auto chunk = m_chunks_to_upload.Pop();
chunk.GenerateMesh(); chunk.get().GenerateMesh();
chunk.UploadMesh(); chunk.get().UploadMesh();
} }
Scop::RenderCore::Get().WaitQueueIdle(KVF_GRAPHICS_QUEUE); Scop::RenderCore::Get().WaitQueueIdle(KVF_GRAPHICS_QUEUE);
Scop::RenderCore::Get().ShouldStackSubmits(false); Scop::RenderCore::Get().ShouldStackSubmits(false);

View File

@@ -10,7 +10,6 @@
#include <Utils.h> #include <Utils.h>
constexpr std::uint8_t RENDER_DISTANCE = 10; constexpr std::uint8_t RENDER_DISTANCE = 10;
constexpr std::uint8_t RENDER_DISTANCE_HALF = RENDER_DISTANCE / 2;
constexpr std::uint8_t CHUNKS_UPLOAD_PER_FRAME = 1; constexpr std::uint8_t CHUNKS_UPLOAD_PER_FRAME = 1;
enum class GenerationState: std::uint8_t enum class GenerationState: std::uint8_t
@@ -40,7 +39,6 @@ class World
std::unordered_map<Scop::Vec2i, Chunk> m_chunks; std::unordered_map<Scop::Vec2i, Chunk> m_chunks;
ThreadSafeQueue<std::reference_wrapper<Chunk>> m_chunks_to_upload; ThreadSafeQueue<std::reference_wrapper<Chunk>> m_chunks_to_upload;
std::shared_ptr<Scop::Material> p_block_material; std::shared_ptr<Scop::Material> p_block_material;
Scop::Narrator& m_narrator;
Scop::Scene& m_scene; Scop::Scene& m_scene;
Scop::Vec2i m_previous_chunk_position; Scop::Vec2i m_previous_chunk_position;
std::atomic<GenerationState> m_generation_status = GenerationState::Ready; std::atomic<GenerationState> m_generation_status = GenerationState::Ready;

View File

@@ -66,8 +66,8 @@ namespace Scop
void SwitchToParent() const noexcept; void SwitchToParent() const noexcept;
[[nodiscard]] inline ForwardData& GetForwardData() noexcept { return m_forward; } [[nodiscard]] inline ForwardData& GetForwardData() noexcept { return m_forward; }
[[nodiscard]] inline const std::vector<std::shared_ptr<Actor>>& GetActors() const noexcept { return m_actors; } [[nodiscard]] inline const std::vector<Actor>& GetActors() const noexcept { return m_actors; }
[[nodiscard]] inline const std::vector<std::shared_ptr<Sprite>>& GetSprites() const noexcept { return m_sprites; } [[nodiscard]] inline const std::vector<Sprite>& GetSprites() const noexcept { return m_sprites; }
[[nodiscard]] inline const std::string& GetName() const noexcept { return m_name; } [[nodiscard]] inline const std::string& GetName() const noexcept { return m_name; }
[[nodiscard]] inline GraphicPipeline& GetPipeline() noexcept { return m_pipeline; } [[nodiscard]] inline GraphicPipeline& GetPipeline() noexcept { return m_pipeline; }
[[nodiscard]] inline std::shared_ptr<BaseCamera> GetCamera() const { return m_descriptor.camera; } [[nodiscard]] inline std::shared_ptr<BaseCamera> GetCamera() const { return m_descriptor.camera; }
@@ -90,9 +90,9 @@ namespace Scop
DepthImage m_depth; DepthImage m_depth;
SceneDescriptor m_descriptor; SceneDescriptor m_descriptor;
std::shared_ptr<CubeTexture> p_skybox; std::shared_ptr<CubeTexture> p_skybox;
std::vector<std::shared_ptr<Actor>> m_actors; std::vector<Actor> m_actors;
std::vector<std::shared_ptr<Sprite>> m_sprites; std::vector<Sprite> m_sprites;
std::vector<std::shared_ptr<Narrator>> m_narrators; std::vector<Narrator> m_narrators;
std::vector<Scene> m_scene_children; std::vector<Scene> m_scene_children;
std::string m_name; std::string m_name;
NonOwningPtr<Scene> p_parent; NonOwningPtr<Scene> p_parent;

View File

@@ -12,7 +12,7 @@
namespace Scop namespace Scop
{ {
constexpr const int MAX_FRAMES_IN_FLIGHT = 2; constexpr const int MAX_FRAMES_IN_FLIGHT = 3;
constexpr const int DEFAULT_VERTEX_SHADER_ID = 0; constexpr const int DEFAULT_VERTEX_SHADER_ID = 0;
constexpr const int DEFAULT_FRAGMENT_SHADER_ID = 1; constexpr const int DEFAULT_FRAGMENT_SHADER_ID = 1;

View File

@@ -24,49 +24,37 @@ namespace Scop
Actor& Scene::CreateActor(Model model) noexcept Actor& Scene::CreateActor(Model model) noexcept
{ {
std::shared_ptr<Actor> actor = std::make_shared<Actor>(std::move(model)); return m_actors.emplace_back(std::move(model));
m_actors.push_back(actor);
return *actor;
} }
Actor& Scene::CreateActor(std::string_view name, Model model) Actor& Scene::CreateActor(std::string_view name, Model model)
{ {
std::shared_ptr<Actor> actor = std::make_shared<Actor>(std::move(model)); return m_actors.emplace_back(std::move(model));
m_actors.push_back(actor);
return *actor;
} }
Narrator& Scene::CreateNarrator() noexcept Narrator& Scene::CreateNarrator() noexcept
{ {
std::shared_ptr<Narrator> narrator = std::make_shared<Narrator>(); return m_narrators.emplace_back();
m_narrators.push_back(narrator);
return *narrator;
} }
Narrator& Scene::CreateNarrator(std::string_view name) Narrator& Scene::CreateNarrator(std::string_view name)
{ {
std::shared_ptr<Narrator> narrator = std::make_shared<Narrator>(); return m_narrators.emplace_back();
m_narrators.push_back(narrator);
return *narrator;
} }
Sprite& Scene::CreateSprite(std::shared_ptr<Texture> texture) noexcept Sprite& Scene::CreateSprite(std::shared_ptr<Texture> texture) noexcept
{ {
std::shared_ptr<Sprite> sprite = std::make_shared<Sprite>(texture); return m_sprites.emplace_back(texture);
m_sprites.push_back(sprite);
return *sprite;
} }
Sprite& Scene::CreateSprite(std::string_view name, std::shared_ptr<Texture> texture) Sprite& Scene::CreateSprite(std::string_view name, std::shared_ptr<Texture> texture)
{ {
std::shared_ptr<Sprite> sprite = std::make_shared<Sprite>(texture); return m_sprites.emplace_back(texture);
m_sprites.push_back(sprite);
return *sprite;
} }
void Scene::RemoveActor(Actor& actor) noexcept void Scene::RemoveActor(Actor& actor) noexcept
{ {
auto it = std::find_if(m_actors.begin(), m_actors.end(), [actor](const std::shared_ptr<Actor> lhs) { return actor.GetUUID() == lhs->GetUUID(); }); auto it = std::find_if(m_actors.begin(), m_actors.end(), [actor](const Actor& lhs) { return actor.GetUUID() == lhs.GetUUID(); });
if(it == m_actors.end()) if(it == m_actors.end())
{ {
Error("Actor not found"); Error("Actor not found");
@@ -77,7 +65,7 @@ namespace Scop
void Scene::RemoveNarrator(Narrator& narrator) noexcept void Scene::RemoveNarrator(Narrator& narrator) noexcept
{ {
auto it = std::find_if(m_narrators.begin(), m_narrators.end(), [narrator](const std::shared_ptr<Narrator> lhs) { return narrator.GetUUID() == lhs->GetUUID(); }); auto it = std::find_if(m_narrators.begin(), m_narrators.end(), [narrator](const Narrator& lhs) { return narrator.GetUUID() == lhs.GetUUID(); });
if(it == m_narrators.end()) if(it == m_narrators.end())
{ {
Error("Narrator not found"); Error("Narrator not found");
@@ -88,7 +76,7 @@ namespace Scop
void Scene::RemoveSprite(Sprite& sprite) noexcept void Scene::RemoveSprite(Sprite& sprite) noexcept
{ {
auto it = std::find_if(m_sprites.begin(), m_sprites.end(), [sprite](const std::shared_ptr<Sprite> lhs) { return sprite.GetUUID() == lhs->GetUUID(); }); auto it = std::find_if(m_sprites.begin(), m_sprites.end(), [sprite](const Sprite& lhs) { return sprite.GetUUID() == lhs.GetUUID(); });
if(it == m_sprites.end()) if(it == m_sprites.end())
{ {
Error("Sprite not found"); Error("Sprite not found");
@@ -148,11 +136,11 @@ namespace Scop
void Scene::Update(Inputs& input, float timestep, float aspect) void Scene::Update(Inputs& input, float timestep, float aspect)
{ {
for(auto actor : m_actors) for(auto actor : m_actors)
actor->Update(this, input, timestep); actor.Update(this, input, timestep);
for(auto narrator : m_narrators) for(auto narrator : m_narrators)
narrator->Update(this, input, timestep); narrator.Update(this, input, timestep);
for(auto sprite : m_sprites) for(auto sprite : m_sprites)
sprite->Update(this, input, timestep); sprite.Update(this, input, timestep);
if(m_descriptor.camera) if(m_descriptor.camera)
m_descriptor.camera->Update(input, aspect, timestep); m_descriptor.camera->Update(input, aspect, timestep);
} }

View File

@@ -85,18 +85,18 @@ namespace Scop
VkCommandBuffer cmd = renderer.GetActiveCommandBuffer(); VkCommandBuffer cmd = renderer.GetActiveCommandBuffer();
m_pipeline.BindPipeline(cmd, 0, {}); m_pipeline.BindPipeline(cmd, 0, {});
for(auto sprite : scene.GetSprites()) for(const auto& sprite : scene.GetSprites())
{ {
SpriteData sprite_data; SpriteData sprite_data;
sprite_data.position = Vec2f{ static_cast<float>(sprite->GetPosition().x), static_cast<float>(sprite->GetPosition().y) }; sprite_data.position = Vec2f{ static_cast<float>(sprite.GetPosition().x), static_cast<float>(sprite.GetPosition().y) };
sprite_data.color = sprite->GetColor(); sprite_data.color = sprite.GetColor();
if(!sprite->IsSetInit()) if(!sprite.IsSetInit())
sprite->UpdateDescriptorSet(*p_texture_set); const_cast<Sprite&>(sprite).UpdateDescriptorSet(*p_texture_set);
sprite->Bind(frame_index, cmd); const_cast<Sprite&>(sprite).Bind(frame_index, cmd);
std::array<VkDescriptorSet, 2> sets = { p_viewer_data_set->GetSet(frame_index), sprite->GetSet(frame_index) }; std::array<VkDescriptorSet, 2> sets = { p_viewer_data_set->GetSet(frame_index), sprite.GetSet(frame_index) };
RenderCore::Get().vkCmdBindDescriptorSets(cmd, m_pipeline.GetPipelineBindPoint(), m_pipeline.GetPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr); RenderCore::Get().vkCmdBindDescriptorSets(cmd, m_pipeline.GetPipelineBindPoint(), m_pipeline.GetPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
RenderCore::Get().vkCmdPushConstants(cmd, m_pipeline.GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(SpriteData), &sprite_data); RenderCore::Get().vkCmdPushConstants(cmd, m_pipeline.GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(SpriteData), &sprite_data);
sprite->GetMesh()->Draw(cmd, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef()); sprite.GetMesh()->Draw(cmd, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef());
} }
m_pipeline.EndPipeline(cmd); m_pipeline.EndPipeline(cmd);
} }

View File

@@ -43,19 +43,19 @@ namespace Scop
VkCommandBuffer cmd = renderer.GetActiveCommandBuffer(); VkCommandBuffer cmd = renderer.GetActiveCommandBuffer();
pipeline.BindPipeline(cmd, 0, {}); pipeline.BindPipeline(cmd, 0, {});
for(auto actor : scene.GetActors()) for(const auto& actor : scene.GetActors())
{ {
if(!actor->IsVisible()) if(!actor.IsVisible())
continue; continue;
ModelData model_data; ModelData model_data;
model_data.model_mat = Mat4f::Identity(); model_data.model_mat = Mat4f::Identity();
model_data.model_mat.SetTranslation(actor->GetPosition() - actor->GetModel().GetCenter()); model_data.model_mat.SetTranslation(actor.GetPosition() - actor.GetModel().GetCenter());
model_data.model_mat.SetScale(actor->GetScale()); model_data.model_mat.SetScale(actor.GetScale());
model_data.model_mat = Mat4f::Translate(-actor->GetModel().GetCenter()) * Mat4f::Rotate(actor->GetOrientation()) * model_data.model_mat; model_data.model_mat = Mat4f::Translate(-actor.GetModel().GetCenter()) * Mat4f::Rotate(actor.GetOrientation()) * model_data.model_mat;
model_data.normal_mat = model_data.model_mat; model_data.normal_mat = model_data.model_mat;
model_data.normal_mat.Inverse().Transpose(); model_data.normal_mat.Inverse().Transpose();
RenderCore::Get().vkCmdPushConstants(cmd, pipeline.GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(ModelData), &model_data); RenderCore::Get().vkCmdPushConstants(cmd, pipeline.GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(ModelData), &model_data);
actor->GetModel().Draw(cmd, *data.matrices_set, pipeline, *data.albedo_set, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef(), renderer.GetCurrentFrameIndex()); actor.GetModel().Draw(cmd, *data.matrices_set, pipeline, *data.albedo_set, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef(), renderer.GetCurrentFrameIndex());
} }
pipeline.EndPipeline(cmd); pipeline.EndPipeline(cmd);
} }