// Copyright (c) 2023 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #include "scene/SceneItem.hpp" #include "scene/Scene.hpp" #include "util/JSON.hpp" using namespace Dawn; SceneItem::SceneItem(const std::weak_ptr scene) : scene(scene), SceneItemTransform(), SceneItemComponents() { } std::shared_ptr SceneItem::sceneItemComponentsSelf() { return shared_from_this(); } std::shared_ptr SceneItem::getScene() { auto s = scene.lock(); assertNotNull(s, "Scene has unloaded?"); return s; } void SceneItem::init() { auto sharedThis = shared_from_this(); // Loop until all components initialized... while(true) { // Create copy of the components, components may chose to add more components // but those sub components will not be initialized at this time. auto components = this->components; for(auto &component : components) { if(component->isInitialized()) continue; component->init(sharedThis); } // If they are all initalized we are fine. components = this->components; bool_t allInitialized = std::all_of( components.begin(), components.end(), [](auto &component) { return component->isInitialized(); } ); if(allInitialized) break; } } void SceneItem::deinit() { // Create copy of the components, components may chose to add more components // but those sub components will not be disposed at this time. auto components = this->components; for(auto &component : components) { if(!component->isInitialized()) continue; component->dispose(); } this->components.clear(); } void SceneItem::load(const SceneComponentLoadContext &ctx) { // Transforms if(ctx.data.contains("position")) { this->setLocalPosition(JSON::vec3(ctx.data["position"])); } if(ctx.data.contains("lookAt")) { auto &lookAt = ctx.data["lookAt"]; glm::vec3 pos = glm::vec3(3, 3, 3); glm::vec3 look = glm::vec3(0, 0, 0); glm::vec3 up = glm::vec3(0, 1, 0); if(lookAt.contains("position")) pos = JSON::vec3(lookAt["position"]); if(lookAt.contains("look")) look = JSON::vec3(lookAt["look"]); if(lookAt.contains("up")) up = JSON::vec3(lookAt["up"]); this->lookAt(pos, look, up); } if(ctx.data.contains("scale")) { this->setLocalScale(JSON::vec3(ctx.data["scale"])); } } void SceneItem::remove() { auto scene = getScene(); if(!scene) return; scene->removeItem(shared_from_this()); } SceneItem::~SceneItem() { this->deinit(); }