Framebuffer resize queued to next frame to fix flickering Wren VM init moved to on play event Added new Wren modules Added missing components to the editor Changed how the wren scripts gets initialized
712 lines
19 KiB
C++
712 lines
19 KiB
C++
#pragma once
|
|
#include "Scene.h"
|
|
#include "Entities/Entity.h"
|
|
#include "Entities/Components.h"
|
|
#include "../Rendering/Renderer.h"
|
|
#include "../Core/MaterialManager.h"
|
|
#include "../Core/Physics/PhysicsManager.h"
|
|
#include "../Core/Core.h"
|
|
#include <GL/glew.h>
|
|
#include "Entities/Components/BoxCollider.h"
|
|
#include "../../Engine.h"
|
|
#include "../Core/FileSystem.h"
|
|
#include "../Scene/Entities/Components/LuaScriptComponent.h"
|
|
#include <fstream>
|
|
#include <streambuf>
|
|
#include "../Scene/Entities/Components/WrenScriptComponent.h"
|
|
Ref<Scene> Scene::New()
|
|
{
|
|
return CreateRef<Scene>();
|
|
}
|
|
|
|
Scene::Scene()
|
|
{
|
|
m_EditorCamera = CreateRef<EditorCamera>();
|
|
m_Environement = CreateRef<Environment>();
|
|
m_Interfaces = std::vector<Ref<UI::UserInterface>>();
|
|
}
|
|
|
|
Scene::~Scene() {}
|
|
|
|
std::string Scene::GetName()
|
|
{
|
|
return this->Name;
|
|
}
|
|
|
|
bool Scene::SetName(std::string& newName)
|
|
{
|
|
if (newName == "")
|
|
return false;
|
|
|
|
this->Name = newName;
|
|
return true;
|
|
}
|
|
|
|
void Scene::OnInit()
|
|
{
|
|
ScriptingEngine::Init();
|
|
|
|
// Create physic world.
|
|
auto view = m_Registry.view<TransformComponent, RigidBodyComponent>();
|
|
for (auto e : view)
|
|
{
|
|
auto [transform, rigidbody] = view.get<TransformComponent, RigidBodyComponent>(e);
|
|
|
|
Entity ent = Entity({ e, this });
|
|
|
|
if (ent.HasComponent<BoxColliderComponent>())
|
|
{
|
|
float mass = rigidbody.mass;
|
|
|
|
BoxColliderComponent& boxComponent = ent.GetComponent<BoxColliderComponent>();
|
|
Ref<Physics::Box> boxShape = CreateRef<Physics::Box>(boxComponent.Size);
|
|
|
|
Ref<Physics::RigidBody> btRigidbody = CreateRef<Physics::RigidBody>(mass, transform.Translation, boxShape);
|
|
rigidbody.m_Rigidbody = btRigidbody;
|
|
|
|
btRigidbody->SetKinematic(rigidbody.IsKinematic);
|
|
|
|
PhysicsManager::Get()->RegisterBody(btRigidbody);
|
|
}
|
|
}
|
|
|
|
// character controllers
|
|
auto ccview = m_Registry.view<TransformComponent, CharacterControllerComponent>();
|
|
for (auto e : ccview)
|
|
{
|
|
auto [transform, cc] = ccview.get<TransformComponent, CharacterControllerComponent>(e);
|
|
|
|
cc.CharacterController = CreateRef<Physics::CharacterController>(cc.Height, cc.Radius, cc.Mass);
|
|
Entity ent = Entity({ e, this });
|
|
|
|
PhysicsManager::Get()->RegisterCharacterController(cc.CharacterController);
|
|
}
|
|
|
|
auto quakeMapview = m_Registry.view<TransformComponent, QuakeMapComponent>();
|
|
for (auto e : quakeMapview)
|
|
{
|
|
auto [transform, quake] = quakeMapview.get<TransformComponent, QuakeMapComponent>(e);
|
|
|
|
if (quake.HasCollisions)
|
|
{
|
|
for (auto m : quake.m_Meshes)
|
|
{
|
|
Ref<Physics::MeshShape> meshShape = CreateRef<Physics::MeshShape>(m);
|
|
Ref<Physics::RigidBody> btRigidbody = CreateRef<Physics::RigidBody>(0.0f, transform.Translation, meshShape);
|
|
PhysicsManager::Get()->RegisterBody(btRigidbody);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Instanciate scripts.
|
|
{
|
|
auto entities = m_Registry.view<WrenScriptComponent>();
|
|
for (auto& e : entities)
|
|
{
|
|
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);
|
|
if (wren.Script != "" && wren.Class != "")
|
|
wren.WrenScript = CreateRef<WrenScript>(wren.Script, wren.Class, true);
|
|
|
|
if (wren.WrenScript != nullptr)
|
|
{
|
|
wren.WrenScript->SetScriptableEntityID((int)e);
|
|
wren.WrenScript->CallInit();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Scene::OnExit()
|
|
{
|
|
PhysicsManager::Get()->Reset();
|
|
|
|
// destroy scripts.
|
|
auto entities = m_Registry.view<WrenScriptComponent>();
|
|
for (auto& e : entities)
|
|
{
|
|
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);
|
|
|
|
if (wren.WrenScript != nullptr)
|
|
{
|
|
wren.WrenScript->CallExit();
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ScriptingEngine::Close();
|
|
}
|
|
|
|
// update entities and some components.
|
|
void Scene::Update(Timestep ts)
|
|
{
|
|
// Update scripts
|
|
{
|
|
m_Registry.view<NativeScriptComponent>().each([=](auto entity, auto& nsc)
|
|
{
|
|
nsc.Instance->OnUpdate(ts);
|
|
});
|
|
}
|
|
|
|
// destroy scripts.
|
|
auto entities = m_Registry.view<WrenScriptComponent>();
|
|
for (auto& e : entities)
|
|
{
|
|
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);
|
|
|
|
if (wren.WrenScript != nullptr)
|
|
wren.WrenScript->CallUpdate(ts);
|
|
}
|
|
|
|
// Update rigidbodies
|
|
PhysicsManager::Get()->Step(ts);
|
|
|
|
auto physicGroup = m_Registry.view<TransformComponent, RigidBodyComponent>();
|
|
for (auto e : physicGroup) {
|
|
auto [transform, rb] = physicGroup.get<TransformComponent, RigidBodyComponent>(e);
|
|
rb.SyncTransformComponent(&m_Registry.get<TransformComponent>(e));
|
|
}
|
|
|
|
auto ccGroup = m_Registry.view<TransformComponent, CharacterControllerComponent>();
|
|
for (auto e : ccGroup) {
|
|
auto [transform, rb] = ccGroup.get<TransformComponent, CharacterControllerComponent>(e);
|
|
rb.SyncWithTransform(m_Registry.get<TransformComponent>(e));
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
void Scene::EditorUpdate(Timestep ts)
|
|
{
|
|
m_EditorCamera->Update(ts);
|
|
|
|
for (auto i : m_Interfaces)
|
|
{
|
|
i->Update(ts);
|
|
}
|
|
}
|
|
|
|
|
|
void Scene::DrawShadows()
|
|
{
|
|
auto modelView = m_Registry.view<TransformComponent, ModelComponent>();
|
|
auto quakeView = m_Registry.view<TransformComponent, QuakeMapComponent>();
|
|
auto view = m_Registry.view<TransformComponent, LightComponent>();
|
|
|
|
Ref<Camera> cam = nullptr;
|
|
if (Engine::IsPlayMode)
|
|
{
|
|
auto view = m_Registry.view<TransformComponent, CameraComponent>();
|
|
for (auto e : view) {
|
|
auto [transform, camera] = view.get<TransformComponent, CameraComponent>(e);
|
|
cam = camera.CameraInstance;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cam = m_EditorCamera;
|
|
}
|
|
|
|
glm::mat4 perspective = cam->GetPerspective();
|
|
|
|
for (auto l : view) {
|
|
auto [lightTransform, light] = view.get<TransformComponent, LightComponent>(l);
|
|
if (light.Type != LightType::Directional)
|
|
continue;
|
|
|
|
light.BeginDrawShadow();
|
|
for (auto e : modelView)
|
|
{
|
|
auto [transform, model] = modelView.get<TransformComponent, ModelComponent>(e);
|
|
|
|
glm::vec3 pos = lightTransform.Translation;
|
|
glm::mat4 lightView = glm::lookAt(pos, pos - light.GetDirection(), glm::vec3(0.0f, 1.0f, 0.0f));
|
|
Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.GetProjection() * lightView);
|
|
Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform());
|
|
|
|
model.Draw();
|
|
}
|
|
|
|
for (auto e : quakeView) {
|
|
auto [transform, model] = quakeView.get<TransformComponent, QuakeMapComponent>(e);
|
|
|
|
glm::vec3 pos = lightTransform.Translation;
|
|
glm::mat4 lightView = glm::lookAt(pos, pos - light.GetDirection(), glm::vec3(0.0f, 1.0f, 0.0f));
|
|
|
|
Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.GetProjection() * lightView);
|
|
Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform());
|
|
|
|
model.Draw();
|
|
}
|
|
light.EndDrawShadow();
|
|
}
|
|
}
|
|
|
|
void Scene::DrawInterface(Vector2 screensize)
|
|
{
|
|
for (auto i : m_Interfaces)
|
|
{
|
|
i->Draw(screensize);
|
|
}
|
|
}
|
|
|
|
|
|
void Scene::Draw()
|
|
{
|
|
// Find the camera of the scene.
|
|
Ref<Camera> cam = nullptr;
|
|
{
|
|
auto view = m_Registry.view<TransformComponent, CameraComponent, ParentComponent>();
|
|
for (auto e : view) {
|
|
auto [transform, camera, parent] = view.get<TransformComponent, CameraComponent, ParentComponent>(e);
|
|
|
|
TransformComponent copyT = transform;
|
|
if (parent.HasParent)
|
|
{
|
|
Entity currentParent = Entity{ e, this };
|
|
glm::vec3 globalOffset = copyT.Translation;
|
|
|
|
while (currentParent.GetComponent<ParentComponent>().HasParent)
|
|
{
|
|
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
|
|
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
|
|
}
|
|
|
|
copyT.Translation = globalOffset;
|
|
}
|
|
|
|
cam = camera.CameraInstance;
|
|
cam->Translation = copyT.Translation;
|
|
break;
|
|
}
|
|
}
|
|
glDisable(GL_DEPTH_TEST);
|
|
Ref<Environment> env = GetEnvironment();
|
|
|
|
if (env->ProceduralSkybox)
|
|
{
|
|
env->ProceduralSkybox->Draw(cam);
|
|
|
|
}
|
|
Renderer::m_Shader->Bind();
|
|
env->Push();
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
// Push lights
|
|
{
|
|
auto view = m_Registry.view<TransformComponent, LightComponent, ParentComponent>();
|
|
for (auto l : view) {
|
|
auto [transform, light, parent] = view.get<TransformComponent, LightComponent, ParentComponent>(l);
|
|
|
|
TransformComponent copyT = transform;
|
|
if (parent.HasParent)
|
|
{
|
|
Entity currentParent = Entity{ l, this };
|
|
glm::vec3 globalOffset = copyT.Translation;
|
|
|
|
while (currentParent.GetComponent<ParentComponent>().HasParent)
|
|
{
|
|
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
|
|
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
|
|
|
|
}
|
|
|
|
copyT.Translation = globalOffset;
|
|
}
|
|
|
|
if (light.SyncDirectionWithSky)
|
|
light.Direction = GetEnvironment()->ProceduralSkybox->GetSunDirection();
|
|
|
|
light.Draw(copyT, m_EditorCamera);
|
|
}
|
|
}
|
|
|
|
Renderer::m_Shader->Bind();
|
|
|
|
Renderer::m_Shader->SetUniform1i("u_ShowNormal", 0);
|
|
if (cam)
|
|
{
|
|
Renderer::m_Shader->SetUniform1f("u_Exposure", cam->Exposure);
|
|
|
|
auto view = m_Registry.view<TransformComponent, ModelComponent, ParentComponent>();
|
|
for (auto e : view) {
|
|
auto [transform, model, parent] = view.get<TransformComponent, ModelComponent, ParentComponent>(e);
|
|
TransformComponent copyT = transform;
|
|
if (parent.HasParent)
|
|
{
|
|
Entity currentParent = Entity{ e, this };
|
|
glm::vec3 globalOffset = copyT.Translation;
|
|
|
|
while (currentParent.GetComponent<ParentComponent>().HasParent)
|
|
{
|
|
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
|
|
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
|
|
}
|
|
|
|
copyT.Translation = globalOffset;
|
|
}
|
|
Renderer::m_Shader->SetUniformMat4f("u_View", cam->GetTransform());
|
|
Renderer::m_Shader->SetUniformMat4f("u_Projection", cam->GetPerspective());
|
|
Renderer::m_Shader->SetUniformMat4f("u_Model", copyT.GetTransform());
|
|
model.Draw();
|
|
}
|
|
|
|
auto quakeView = m_Registry.view<TransformComponent, QuakeMapComponent, ParentComponent>();
|
|
for (auto e : quakeView) {
|
|
auto [transform, model, parent] = quakeView.get<TransformComponent, QuakeMapComponent, ParentComponent>(e);
|
|
|
|
TransformComponent copyT = transform;
|
|
if (parent.HasParent)
|
|
{
|
|
Entity currentParent = Entity{ e, this };
|
|
glm::vec3 globalOffset = copyT.Translation;
|
|
|
|
while (currentParent.GetComponent<ParentComponent>().HasParent)
|
|
{
|
|
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
|
|
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
|
|
}
|
|
|
|
copyT.Translation = globalOffset;
|
|
}
|
|
Renderer::m_Shader->SetUniformMat4f("u_View", cam->GetTransform());
|
|
Renderer::m_Shader->SetUniformMat4f("u_Projection", cam->GetPerspective());
|
|
Renderer::m_Shader->SetUniformMat4f("u_Model", copyT.GetTransform());
|
|
model.Draw();
|
|
}
|
|
|
|
Renderer::m_DebugShader->SetUniformMat4f("u_View", cam->GetTransform());
|
|
Renderer::m_DebugShader->SetUniformMat4f("u_Projection", cam->GetPerspective());
|
|
PhysicsManager::Get()->DrawDebug();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void Scene::EditorDraw()
|
|
{
|
|
glDisable(GL_DEPTH_TEST);
|
|
Ref<Environment> env = GetEnvironment();
|
|
|
|
if (env->ProceduralSkybox)
|
|
{
|
|
env->ProceduralSkybox->Draw(m_EditorCamera);
|
|
}
|
|
|
|
Renderer::m_Shader->Bind();
|
|
env->Push();
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
// Push lights
|
|
{
|
|
auto view = m_Registry.view<TransformComponent, LightComponent, ParentComponent>();
|
|
for (auto l : view) {
|
|
auto [transform, light, parent] = view.get<TransformComponent, LightComponent, ParentComponent>(l);
|
|
|
|
TransformComponent copyT = transform;
|
|
if (parent.HasParent)
|
|
{
|
|
Entity currentParent = Entity{ l, this };
|
|
glm::vec3 globalOffset = copyT.Translation;
|
|
|
|
while (currentParent.GetComponent<ParentComponent>().HasParent)
|
|
{
|
|
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
|
|
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
|
|
}
|
|
|
|
copyT.Translation = globalOffset;
|
|
}
|
|
|
|
if (light.SyncDirectionWithSky)
|
|
light.Direction = GetEnvironment()->ProceduralSkybox->GetSunDirection();
|
|
|
|
light.Draw(copyT, m_EditorCamera);
|
|
}
|
|
}
|
|
|
|
Renderer::m_Shader->Bind();
|
|
Renderer::m_Shader->SetUniform1i("u_ShowNormal", 0);
|
|
if (m_EditorCamera)
|
|
{
|
|
Renderer::m_Shader->SetUniform1f("u_Exposure", m_EditorCamera->Exposure);
|
|
|
|
auto view = m_Registry.view<TransformComponent, ModelComponent, ParentComponent>();
|
|
for (auto e : view) {
|
|
auto [transform, model, parent] = view.get<TransformComponent, ModelComponent, ParentComponent>(e);
|
|
|
|
TransformComponent copyT = transform;
|
|
if (parent.HasParent)
|
|
{
|
|
Entity currentParent = Entity{ e, this };
|
|
glm::vec3 globalOffset = copyT.Translation;
|
|
|
|
while (currentParent.GetComponent<ParentComponent>().HasParent)
|
|
{
|
|
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
|
|
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
|
|
}
|
|
|
|
copyT.Translation = globalOffset;
|
|
}
|
|
|
|
Renderer::m_Shader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform());
|
|
Renderer::m_Shader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective());
|
|
Renderer::m_Shader->SetUniformMat4f("u_Model", copyT.GetTransform());
|
|
model.Draw();
|
|
}
|
|
|
|
auto quakeView = m_Registry.view<TransformComponent, QuakeMapComponent, ParentComponent>();
|
|
for (auto e : quakeView) {
|
|
auto [transform, model, parent] = quakeView.get<TransformComponent, QuakeMapComponent, ParentComponent>(e);
|
|
|
|
|
|
TransformComponent copyT = transform;
|
|
if (parent.HasParent)
|
|
{
|
|
Entity currentParent = Entity{ e, this };
|
|
glm::vec3 globalOffset = copyT.Translation;
|
|
|
|
while (currentParent.GetComponent<ParentComponent>().HasParent)
|
|
{
|
|
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
|
|
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
|
|
}
|
|
|
|
copyT.Translation = globalOffset;
|
|
}
|
|
Renderer::m_Shader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform());
|
|
Renderer::m_Shader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective());
|
|
|
|
Renderer::m_Shader->SetUniformMat4f("u_Model", copyT.GetTransform());
|
|
model.Draw();
|
|
}
|
|
|
|
auto boxCollider = m_Registry.view<TransformComponent, BoxColliderComponent, ParentComponent>();
|
|
for (auto e : boxCollider) {
|
|
auto [transform, box, parent] = boxCollider.get<TransformComponent, BoxColliderComponent, ParentComponent>(e);
|
|
|
|
TransformComponent copyT = transform;
|
|
if (parent.HasParent)
|
|
{
|
|
Entity currentParent = Entity{ e, this };
|
|
glm::vec3 globalOffset = copyT.Translation;
|
|
|
|
while (currentParent.GetComponent<ParentComponent>().HasParent)
|
|
{
|
|
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
|
|
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
|
|
|
|
}
|
|
|
|
copyT.Translation = globalOffset;
|
|
}
|
|
|
|
Renderer::m_DebugShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform());
|
|
Renderer::m_DebugShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective());
|
|
Renderer::m_DebugShader->SetUniformMat4f("u_Model", copyT.GetTransform());
|
|
|
|
TransformComponent t = transform;
|
|
t.Scale = (box.Size * 2.f) * transform.Scale;
|
|
Renderer::DrawCube(t, glm::vec4(0.0f, 0.0f, 0.9f, 0.2f));
|
|
}
|
|
|
|
auto sphereCollider = m_Registry.view<TransformComponent, SphereColliderComponent, ParentComponent>();
|
|
for (auto e : sphereCollider) {
|
|
auto [transform, box, parent] = sphereCollider.get<TransformComponent, SphereColliderComponent, ParentComponent>(e);
|
|
|
|
TransformComponent copyT = transform;
|
|
if (parent.HasParent)
|
|
{
|
|
Entity currentParent = Entity{ e, this };
|
|
glm::vec3 globalOffset = copyT.Translation;
|
|
|
|
while (currentParent.GetComponent<ParentComponent>().HasParent)
|
|
{
|
|
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
|
|
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
|
|
|
|
}
|
|
|
|
copyT.Translation = globalOffset;
|
|
}
|
|
|
|
Renderer::m_DebugShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform());
|
|
Renderer::m_DebugShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective());
|
|
Renderer::m_DebugShader->SetUniformMat4f("u_Model", transform.GetTransform());
|
|
|
|
TransformComponent t = transform;
|
|
t.Scale = (box.Radius * 2.f) * transform.Scale;
|
|
Renderer::DrawSphere(t, glm::vec4(0.0f, 0.0f, 0.9f, 0.2f));
|
|
}
|
|
}
|
|
}
|
|
|
|
std::vector<Entity> Scene::GetAllEntities() {
|
|
std::vector<Entity> allEntities;
|
|
auto view = m_Registry.view<NameComponent>();
|
|
for (auto e : view) {
|
|
allEntities.push_back(Entity(e, this));
|
|
}
|
|
return allEntities;
|
|
}
|
|
|
|
glm::vec3 Scene::GetGlobalPosition(Entity ent)
|
|
{
|
|
glm::vec3 globalPos = ent.GetComponent<TransformComponent>().Translation;
|
|
Entity currentParent = ent.AddComponent<ParentComponent>().Parent;
|
|
while (currentParent.GetHandle() != -1)
|
|
{
|
|
globalPos += currentParent.GetComponent<TransformComponent>().Translation;
|
|
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
|
|
}
|
|
|
|
return globalPos;
|
|
}
|
|
|
|
|
|
Entity Scene::GetEntity(const std::string& name)
|
|
{
|
|
std::vector<Entity> allEntities;
|
|
auto view = m_Registry.view<TransformComponent, NameComponent>();
|
|
for (auto e : view) {
|
|
auto [transform, namec] = view.get<TransformComponent, NameComponent>(e);
|
|
if (namec.Name == name)
|
|
return Entity{ e, this };
|
|
}
|
|
}
|
|
|
|
Entity Scene::CreateEmptyEntity() {
|
|
Entity entity = { m_Registry.create(), this };
|
|
return entity;
|
|
}
|
|
|
|
Entity Scene::CreateEntity(const std::string& name) {
|
|
Entity entity = { m_Registry.create(), this };
|
|
|
|
// Must have transform
|
|
entity.AddComponent<TransformComponent>();
|
|
|
|
NameComponent& nameComponent = entity.AddComponent<NameComponent>();
|
|
nameComponent.Name = name;
|
|
|
|
ParentComponent& parentComponent = entity.AddComponent<ParentComponent>();
|
|
|
|
Logger::Log("Created entity: " + nameComponent.Name + "\n");
|
|
return entity;
|
|
}
|
|
|
|
void Scene::DestroyEntity(Entity entity) {
|
|
entity.Destroy();
|
|
}
|
|
|
|
// Getter
|
|
Ref<Camera> Scene::GetCurrentCamera()
|
|
{
|
|
if (Engine::IsPlayMode)
|
|
{
|
|
Ref<Camera> cam = nullptr;
|
|
{
|
|
auto view = m_Registry.view<TransformComponent, CameraComponent>();
|
|
for (auto e : view) {
|
|
auto [transform, camera] = view.get<TransformComponent, CameraComponent>(e);
|
|
cam = camera.CameraInstance;
|
|
break;
|
|
}
|
|
}
|
|
if (!cam)
|
|
cam = m_EditorCamera;
|
|
return cam;
|
|
}
|
|
|
|
return m_EditorCamera;
|
|
}
|
|
|
|
Ref<Environment> Scene::GetEnvironment() {
|
|
return m_Environement;
|
|
}
|
|
|
|
bool Scene::Save()
|
|
{
|
|
if (Path == "")
|
|
Path = FileSystem::AbsoluteToRelative(FileDialog::SaveFile("*.scene") + ".scene");
|
|
|
|
return SaveAs(Path);
|
|
}
|
|
|
|
bool Scene::SaveAs(const std::string& path)
|
|
{
|
|
std::ofstream sceneFile;
|
|
sceneFile.open(FileSystem::Root + path);
|
|
sceneFile << Serialize().dump(4);
|
|
sceneFile.close();
|
|
|
|
Logger::Log("Scene saved successfully");
|
|
return true;
|
|
}
|
|
|
|
|
|
void Scene::ReloadInterfaces()
|
|
{
|
|
for (auto& i : m_Interfaces)
|
|
i->Reload();
|
|
}
|
|
|
|
|
|
void Scene::AddInterface(Ref<UI::UserInterface> interface)
|
|
{
|
|
this->m_Interfaces.push_back(interface);
|
|
}
|
|
|
|
|
|
json Scene::Serialize()
|
|
{
|
|
BEGIN_SERIALIZE();
|
|
SERIALIZE_VAL(Name);
|
|
SERIALIZE_OBJECT(m_Environement)
|
|
std::vector<json> entities = std::vector<json>();
|
|
for (Entity e : GetAllEntities())
|
|
entities.push_back(e.Serialize());
|
|
SERIALIZE_VAL_LBL("Entities", entities);
|
|
END_SERIALIZE();
|
|
}
|
|
|
|
|
|
bool Scene::Deserialize(const std::string& str)
|
|
{
|
|
if (str == "")
|
|
return false;
|
|
|
|
BEGIN_DESERIALIZE();
|
|
if (!j.contains("Name"))
|
|
return false;
|
|
|
|
Name = j["Name"];
|
|
|
|
m_Environement = CreateRef<Environment>();
|
|
if (j.contains("m_Environement"))
|
|
{
|
|
m_Environement = CreateRef<Environment>();
|
|
std::string env = j["m_Environement"].dump();
|
|
m_Environement->Deserialize(env);
|
|
}
|
|
|
|
// Parse entities
|
|
{
|
|
if (j.contains("Entities"))
|
|
{
|
|
for (json e : j["Entities"])
|
|
{
|
|
std::string name = e["NameComponent"]["Name"];
|
|
Entity ent = CreateEmptyEntity();
|
|
ent.Deserialize(e.dump());
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|