123 lines
3.5 KiB
C++
123 lines
3.5 KiB
C++
// 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"
|
|
#include "assert/assert.hpp"
|
|
#include "asset/loader/scene/PrefabLoader.hpp"
|
|
|
|
using namespace Dawn;
|
|
|
|
SceneItem::SceneItem(const std::weak_ptr<Scene> scene) :
|
|
scene(scene),
|
|
SceneItemTransform(),
|
|
SceneItemComponents()
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<SceneItem> SceneItem::sceneItemComponentsSelf() {
|
|
return shared_from_this();
|
|
}
|
|
|
|
std::shared_ptr<Scene> SceneItem::getScene() {
|
|
auto s = scene.lock();
|
|
assertNotNull(s, "Scene has unloaded?");
|
|
return s;
|
|
}
|
|
|
|
void SceneItem::init() {
|
|
assertFlagOff(state, SceneItemState::INITIALIZED, "Already initialized.");
|
|
assertFlagOff(state, SceneItemState::DEINITIALIZED, "Already deinited.");
|
|
Flag::turnOn(state, SceneItemState::INITIALIZED);
|
|
|
|
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() {
|
|
assertFlagOn(state, SceneItemState::INITIALIZED, "SceneItem not ready.");
|
|
assertFlagOff(state, SceneItemState::DEINITIALIZED, "Already deinited");
|
|
Flag::turnOn(state, SceneItemState::DEINITIALIZED);
|
|
|
|
// 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(std::shared_ptr<SceneLoadContext> ctx) {
|
|
// Load prefab first, it can be overriden by other properties.
|
|
if(ctx->data.contains("prefab")) {
|
|
this->name = ctx->data["prefab"].get<std::string>();
|
|
auto prefabLoader = ctx->getAsset<PrefabLoader>(this->name);
|
|
prefabLoader->stagePrefab(shared_from_this());
|
|
}
|
|
|
|
if(ctx->data.contains("name")) {
|
|
this->name = ctx->data["name"].get<std::string>();
|
|
}
|
|
|
|
// 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() {
|
|
if(Flag::isOn(state, SceneItemState::INITIALIZED)) {
|
|
assertFlagOn(state, SceneItemState::DEINITIALIZED, "Not deinited");
|
|
}
|
|
} |