Add ECS to replace scene calls with bare code
This commit is contained in:
@ -35,10 +35,10 @@
|
||||
#include "Prism/Renderer/Material.h"
|
||||
|
||||
// Scene
|
||||
#include "Prism/Scene/Entity.h"
|
||||
#include "Prism/Scene/ECSFramework/Entity/Entity.h"
|
||||
#include "Prism/Scene/Scene.h"
|
||||
#include "Prism/Scene/SceneCamera.h"
|
||||
#include "Prism/Scene/SceneSerializer.h"
|
||||
#include "Prism/Scene/Components.h"
|
||||
#include "Prism/Scene/ECSFramework/Components/Components.h"
|
||||
|
||||
#endif //PRISM_H
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
#ifndef SCENEHIERACHYPANEL_H
|
||||
#define SCENEHIERACHYPANEL_H
|
||||
#include "Prism/Renderer/Mesh.h"
|
||||
#include "Prism/Scene/Entity.h"
|
||||
#include "../Scene/ECSFramework/Entity/Entity.h"
|
||||
#include "Prism/Scene/Scene.h"
|
||||
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
#include "Physics2D.h"
|
||||
|
||||
#include "Prism/Scene/Entity.h"
|
||||
#include "../Scene/ECSFramework/Entity/Entity.h"
|
||||
#include "Prism/Script/ScriptEngine.h"
|
||||
|
||||
namespace Prism
|
||||
@ -355,7 +355,7 @@ namespace Prism
|
||||
|
||||
void Physics2D::OnTransformConstruct(entt::registry& registry, entt::entity entity)
|
||||
{
|
||||
// PM_CORE_TRACE("Transform Component constructed!");
|
||||
PM_CORE_TRACE("Transform Component constructed!");
|
||||
}
|
||||
|
||||
void Physics2D::OnScriptComponentConstruct(entt::registry& registry, entt::entity entity)
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
#include "Physics3D.h"
|
||||
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include "Prism/Scene/Entity.h"
|
||||
#include "../Scene/ECSFramework/Entity/Entity.h"
|
||||
|
||||
#include "PhysicsLayer.h"
|
||||
#include "PhysicsWrappers.h"
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
#ifndef PHYSXMANAGER_H
|
||||
#define PHYSXMANAGER_H
|
||||
|
||||
#include "Prism/Scene/Components.h"
|
||||
#include "Prism/Scene/Entity.h"
|
||||
#include "../Scene/ECSFramework/Components/Components.h"
|
||||
#include "../Scene/ECSFramework/Entity/Entity.h"
|
||||
|
||||
|
||||
namespace Prism
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#define PRISM_PHYSICSACTOR_H
|
||||
#include "Physics3D.h"
|
||||
#include "Prism/Core/Ref.h"
|
||||
#include "Prism/Scene/Entity.h"
|
||||
#include "../Scene/ECSFramework/Entity/Entity.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
#include <PxPhysicsAPI.h>
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
#include "Prism/Scene/Components.h"
|
||||
#include "../Scene/ECSFramework/Components/Components.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
|
||||
@ -53,6 +53,9 @@ namespace Prism {
|
||||
|
||||
void OpenGLVertexBuffer::SetData(void* buffer, uint32_t size, uint32_t offset)
|
||||
{
|
||||
// TODO: fix me, m_LocalData.Data dont delete will copy
|
||||
if (m_LocalData && m_LocalData.Data != buffer)
|
||||
delete [] m_LocalData.Data;
|
||||
m_LocalData = Buffer::Copy(buffer, size);
|
||||
m_Size = size;
|
||||
Ref<OpenGLVertexBuffer> instance = this;
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
#include "Renderer2D.h"
|
||||
#include "SceneRenderer.h"
|
||||
#include "StorageBuffer.h"
|
||||
#include "Prism/Scene/Components.h"
|
||||
#include "../Scene/ECSFramework/Components/Components.h"
|
||||
#include "RHI/RHICommandBuffer.h"
|
||||
#include "RHI/RHIDevice.h"
|
||||
|
||||
|
||||
@ -178,7 +178,7 @@ namespace Prism
|
||||
}
|
||||
|
||||
// TODO: this maybe storage in SceneRenderer
|
||||
Ref<RenderPass> SceneRenderer::GetFinalRenderPass()
|
||||
Ref<RenderPass>& SceneRenderer::GetFinalRenderPass()
|
||||
{
|
||||
return s_Data.FinalPass;
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
#include "Mesh.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Texture.h"
|
||||
#include "Prism/Scene/Components.h"
|
||||
#include "../Scene/ECSFramework/Components/Components.h"
|
||||
#include "Prism/Scene/Scene.h"
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@ namespace Prism
|
||||
|
||||
static std::pair<Ref<TextureCube>, Ref<TextureCube>> CreateEnvironmentMap(const std::string& filepath);
|
||||
|
||||
static Ref<RenderPass> GetFinalRenderPass();
|
||||
static Ref<RenderPass>& GetFinalRenderPass();
|
||||
static Ref<RenderPass> GetGeoPass();
|
||||
static Ref<Texture2D> GetFinalColorBuffer();
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "SceneCamera.h"
|
||||
#include "../../SceneCamera.h"
|
||||
#include "box2d/id.h"
|
||||
#include "Prism/Core/Ref.h"
|
||||
#include "Prism/Core/UUID.h"
|
||||
@ -8,7 +8,7 @@
|
||||
#include "Prism/Renderer/Mesh.h"
|
||||
#include "Prism/Scene/Scene.h"
|
||||
|
||||
#include "Components.h"
|
||||
#include "../Components/Components.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
@ -0,0 +1,53 @@
|
||||
//
|
||||
// Created by Atdunbg on 2026/5/1.
|
||||
//
|
||||
|
||||
#include "PhysicsSystem2D.h"
|
||||
|
||||
#include "Prism/Physics/Physics2D.h"
|
||||
#include "Prism/Scene/ECSFramework/Entity/Entity.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
|
||||
void PhysicsSystem2D::OnRuntimeStart()
|
||||
{
|
||||
// Box2D physics
|
||||
Physics2D::CreateBody(m_Scene);
|
||||
}
|
||||
|
||||
void PhysicsSystem2D::OnRuntimeStop()
|
||||
{
|
||||
}
|
||||
|
||||
void PhysicsSystem2D::OnUpdate(TimeStep ts)
|
||||
{
|
||||
// Box2D physics
|
||||
const auto sceneView = m_Scene->m_Registry.view<Box2DWorldComponent>();
|
||||
const auto& box2DWorld = m_Scene->m_Registry.get<Box2DWorldComponent>(sceneView.front()).World;
|
||||
constexpr int32_t positionIterations = 2;
|
||||
b2World_Step(box2DWorld, ts, positionIterations);
|
||||
// Process Contact Envents box2d version 3.0^ should impl contact event after b2World_Step
|
||||
Physics2D::ProcessContactEvents(box2DWorld);
|
||||
|
||||
|
||||
{
|
||||
const auto view = m_Scene->m_Registry.view<RigidBody2DComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, m_Scene };
|
||||
const auto& rb2d = e.GetComponent<RigidBody2DComponent>();
|
||||
const auto& position = b2Body_GetPosition(rb2d.RuntimeBodyID);
|
||||
const float angle = b2Rot_GetAngle(b2Body_GetRotation(rb2d.RuntimeBodyID));
|
||||
|
||||
auto& transform = e.GetComponent<TransformComponent>();
|
||||
|
||||
transform.Translation.x = position.x;
|
||||
transform.Translation.y = position.y;
|
||||
transform.Rotation.z = angle;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by Atdunbg on 2026/5/1.
|
||||
//
|
||||
|
||||
#ifndef PRISM_PHYSICSSYSTEM2D_H
|
||||
#define PRISM_PHYSICSSYSTEM2D_H
|
||||
#include "Prism/Scene/ECSFramework/Systems/System.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
class PhysicsSystem2D : public System
|
||||
{
|
||||
public:
|
||||
PhysicsSystem2D(Scene* scene) : System(scene) {}
|
||||
|
||||
void OnRuntimeStart() override;
|
||||
void OnRuntimeStop() override;
|
||||
|
||||
void OnUpdate(TimeStep ts) override;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //PRISM_PHYSICSSYSTEM2D_H
|
||||
@ -0,0 +1,58 @@
|
||||
//
|
||||
// Created by Atdunbg on 2026/5/1.
|
||||
//
|
||||
|
||||
#include "PhysicsSystem3D.h"
|
||||
|
||||
#include "Prism/Scene/ECSFramework/Entity/Entity.h"
|
||||
|
||||
#include "Prism/Physics/Physics3D.h"
|
||||
#include "Prism/Physics/PhysicsActor.h"
|
||||
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
void PhysicsSystem3D::OnRuntimeStart()
|
||||
{
|
||||
// PhyX
|
||||
{
|
||||
auto view = m_Scene->m_Registry.view<RigidBodyComponent>();
|
||||
for (auto entity : view)
|
||||
{
|
||||
Entity e = { entity, m_Scene };
|
||||
Physics3D::CreateActor(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsSystem3D::OnRuntimeStop()
|
||||
{
|
||||
Physics3D::DestroyScene();
|
||||
}
|
||||
|
||||
void PhysicsSystem3D::OnUpdate(TimeStep ts)
|
||||
{
|
||||
// Physics3D
|
||||
Physics3D::Simulate(ts);
|
||||
|
||||
// update transformComponent internal direction
|
||||
{
|
||||
const auto view = m_Scene->m_Registry.view<TransformComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, m_Scene };
|
||||
auto& transformComponent = e.GetComponent<TransformComponent>();
|
||||
glm::mat4 transform = m_Scene->GetTransformRelativeToParent(Entity(entity, m_Scene));
|
||||
glm::vec3 translation;
|
||||
glm::vec3 rotation;
|
||||
glm::vec3 scale;
|
||||
Math::DecomposeTransform(transform, translation, rotation, scale);
|
||||
|
||||
auto rotationQuat = glm::quat(rotation);
|
||||
transformComponent.Up = glm::normalize(glm::rotate(rotationQuat, glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||
transformComponent.Right = glm::normalize(glm::rotate(rotationQuat, glm::vec3(1.0f, 0.0f, 0.0f)));
|
||||
transformComponent.Forward = glm::normalize(glm::rotate(rotationQuat, glm::vec3(0.0f, 0.0f, -1.0f)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by Atdunbg on 2026/5/1.
|
||||
//
|
||||
|
||||
#ifndef PRISM_PHYSICSSYSTEM3D_H
|
||||
#define PRISM_PHYSICSSYSTEM3D_H
|
||||
#include "Prism/Scene/ECSFramework/Systems/System.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
class PhysicsSystem3D : public System
|
||||
{
|
||||
public:
|
||||
PhysicsSystem3D(Scene* scene) : System(scene) {}
|
||||
|
||||
void OnRuntimeStart() override;
|
||||
void OnRuntimeStop() override;
|
||||
|
||||
void OnUpdate(TimeStep ts) override;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //PRISM_PHYSICSSYSTEM3D_H
|
||||
@ -0,0 +1,131 @@
|
||||
//
|
||||
// Created by Atdunbg on 2026/5/1.
|
||||
//
|
||||
|
||||
#include "RenderSystem2D.h"
|
||||
|
||||
#include "Prism/Renderer/Renderer2D.h"
|
||||
#include "Prism/Renderer/SceneRenderer.h"
|
||||
#include "Prism/Scene/Scene.h"
|
||||
#include "Prism/Scene/ECSFramework/Components/Components.h"
|
||||
#include "Prism/Scene/ECSFramework/Entity/Entity.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
void RenderSystem2D::OnUpdateEditor(TimeStep ts, const EditorCamera& editorCamera)
|
||||
{
|
||||
Renderer2D::BeginScene(editorCamera.GetViewProjection(), false);
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// RENDER 2D SCENE //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// render sprite
|
||||
{
|
||||
const auto entitiesGroup = m_Scene->m_Registry.group<TransformComponent>(entt::get<SpriteRendererComponent>);
|
||||
for (const auto entity : entitiesGroup)
|
||||
{
|
||||
auto [transformComponent, spriteRendererComponent] = entitiesGroup.get<TransformComponent, SpriteRendererComponent>(entity);
|
||||
if (spriteRendererComponent.Texture)
|
||||
SceneRenderer::SubmitQuad(transformComponent.GetTransform(), spriteRendererComponent.Texture, spriteRendererComponent.TilingFactor, spriteRendererComponent.Color);
|
||||
else
|
||||
SceneRenderer::SubmitQuad(transformComponent.GetTransform(), spriteRendererComponent.Color);
|
||||
}
|
||||
}
|
||||
|
||||
// render camera icon
|
||||
{
|
||||
const auto editorCameraPosition = editorCamera.GetPosition();
|
||||
const auto editorCameraUpDirection = editorCamera.GetUpDirection();
|
||||
|
||||
const auto cameras = m_Scene->m_Registry.view<CameraComponent>();
|
||||
if (!cameras.empty())
|
||||
{
|
||||
for (auto& entity : cameras)
|
||||
{
|
||||
Entity e = { entity, m_Scene };
|
||||
if (!e.GetComponent<CameraComponent>().ShowIcon) continue;
|
||||
SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_Scene->m_CameraIcon, editorCameraPosition, editorCameraUpDirection);
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto skyLights = m_Scene->m_Registry.view<SkyLightComponent>(); !skyLights.empty())
|
||||
{
|
||||
for (auto& entity : skyLights)
|
||||
{
|
||||
Entity e = { entity, m_Scene };
|
||||
if (!e.GetComponent<SkyLightComponent>().ShowIcon) continue;
|
||||
SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_Scene->m_LightIcon, editorCameraPosition, editorCameraUpDirection);
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto directionLight = m_Scene->m_Registry.view<DirectionalLightComponent>(); !directionLight.empty())
|
||||
{
|
||||
for (auto& entity : directionLight)
|
||||
{
|
||||
Entity e = { entity, m_Scene };
|
||||
if (!e.GetComponent<DirectionalLightComponent>().ShowIcon) continue;
|
||||
SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_Scene->m_LightIcon, editorCameraPosition, editorCameraUpDirection);
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto pointLight = m_Scene->m_Registry.view<PointLightComponent>(); !pointLight.empty())
|
||||
{
|
||||
for (auto& entity : pointLight )
|
||||
{
|
||||
Entity e = { entity, m_Scene };
|
||||
if (!e.GetComponent<PointLightComponent>().ShowIcon) continue;
|
||||
SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_Scene->m_LightIcon, editorCameraPosition, editorCameraUpDirection);
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto spotLight = m_Scene->m_Registry.view<SpotLightComponent>(); !spotLight.empty())
|
||||
{
|
||||
for (auto& entity : spotLight )
|
||||
{
|
||||
Entity e = { entity, m_Scene };
|
||||
if (!e.GetComponent<SpotLightComponent>().ShowIcon) continue;
|
||||
SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_Scene->m_LightIcon, editorCameraPosition, editorCameraUpDirection);
|
||||
}
|
||||
}
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
Renderer2D::EndScene(SceneRenderer::GetFinalRenderPass());
|
||||
|
||||
}
|
||||
|
||||
void RenderSystem2D::OnUpdateRuntime(TimeStep ts)
|
||||
{
|
||||
Entity cameraEntity = m_Scene->GetMainCameraEntity();
|
||||
if (!cameraEntity)
|
||||
return;
|
||||
|
||||
const glm::mat4 cameraViewMatrix = glm::inverse(m_Scene->GetTransformRelativeToParent(cameraEntity));
|
||||
SceneCamera& camera = cameraEntity.GetComponent<CameraComponent>();
|
||||
camera.SetViewportSize(m_Scene->GetViewportSize());
|
||||
|
||||
Renderer2D::BeginScene(camera.GetProjectionMatrix() * cameraViewMatrix, false);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// RENDER 2D SCENE //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// render sprite
|
||||
{
|
||||
const auto entitiesGroup = m_Scene->m_Registry.group<TransformComponent>(entt::get<SpriteRendererComponent>);
|
||||
for (const auto entity : entitiesGroup)
|
||||
{
|
||||
auto [transformComponent, spriteRendererComponent] = entitiesGroup.get<TransformComponent, SpriteRendererComponent>(entity);
|
||||
if (spriteRendererComponent.Texture)
|
||||
SceneRenderer::SubmitQuad(transformComponent.GetTransform(), spriteRendererComponent.Texture, spriteRendererComponent.TilingFactor, spriteRendererComponent.Color);
|
||||
else
|
||||
SceneRenderer::SubmitQuad(transformComponent.GetTransform(), spriteRendererComponent.Color);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
Renderer2D::EndScene(SceneRenderer::GetFinalRenderPass());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by Atdunbg on 2026/5/1.
|
||||
//
|
||||
|
||||
#ifndef PRISM_RENDERSYSTEM2D_H
|
||||
#define PRISM_RENDERSYSTEM2D_H
|
||||
#include "Prism/Scene/ECSFramework/Systems/System.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
class RenderSystem2D : public System
|
||||
{
|
||||
public:
|
||||
RenderSystem2D(Scene* scene) : System(scene) {};
|
||||
|
||||
|
||||
void OnUpdateEditor(TimeStep ts, const EditorCamera& editorCamera) override;
|
||||
void OnUpdateRuntime(TimeStep ts) override;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //PRISM_RENDERSYSTEM2D_H
|
||||
@ -0,0 +1,259 @@
|
||||
//
|
||||
// Created by Atdunbg on 2026/5/1.
|
||||
//
|
||||
|
||||
#include "RenderSystem3D.h"
|
||||
|
||||
#include "Prism/Renderer/Renderer3D.h"
|
||||
#include "Prism/Renderer/SceneRenderer.h"
|
||||
#include "Prism/Scene/ECSFramework/Entity/Entity.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
void RenderSystem3D::UpdateLights()
|
||||
{
|
||||
// direction Light
|
||||
{
|
||||
const auto lights = m_Scene->m_Registry.group<DirectionalLightComponent>(entt::get<TransformComponent>);
|
||||
if (!lights.empty())
|
||||
{
|
||||
for (const auto entity : lights)
|
||||
{
|
||||
auto [transformComponent, lightComponent] = lights.get<TransformComponent, DirectionalLightComponent>(entity);
|
||||
const glm::vec3 direction = glm::normalize(glm::mat3(transformComponent.GetTransform()) * glm::vec3(0.0f, 0.0f,1.0f));
|
||||
m_Scene->m_LightEnvironment.DirectionalLights =
|
||||
{
|
||||
direction,
|
||||
lightComponent.Radiance,
|
||||
lightComponent.Intensity,
|
||||
lightComponent.CastShadows
|
||||
};
|
||||
}
|
||||
}else
|
||||
{
|
||||
m_Scene->m_LightEnvironment.DirectionalLights = {};
|
||||
}
|
||||
}
|
||||
|
||||
// Point Light
|
||||
{
|
||||
const auto pointLights = m_Scene->m_Registry.group<PointLightComponent>(entt::get<TransformComponent>);
|
||||
m_Scene->m_LightEnvironment.PointLightCount = 0;
|
||||
for (const auto entity : pointLights)
|
||||
{
|
||||
if (m_Scene->m_LightEnvironment.PointLightCount >= 8) break;
|
||||
auto [transform, light] = pointLights.get<TransformComponent, PointLightComponent>(entity);
|
||||
m_Scene->m_LightEnvironment.PointLights[m_Scene->m_LightEnvironment.PointLightCount++] = {
|
||||
transform.Translation,
|
||||
light.Radiance,
|
||||
light.Radius,
|
||||
light.Intensity,
|
||||
light.CastShadows,
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Spot Light
|
||||
{
|
||||
const auto spotLights = m_Scene->m_Registry.group<SpotLightComponent>(entt::get<TransformComponent>);
|
||||
m_Scene->m_LightEnvironment.SpotLightCount = 0;
|
||||
for (const auto entity : spotLights)
|
||||
{
|
||||
if (m_Scene->m_LightEnvironment.SpotLightCount >= 8) break;
|
||||
auto [transform, light] = spotLights.get<TransformComponent, SpotLightComponent>(entity);
|
||||
const glm::vec3 direction = glm::normalize(glm::mat3(transform.GetTransform()) * glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
const float innerCos = glm::cos(glm::radians(light.InnerConeAngle));
|
||||
const float outerCos = glm::cos(glm::radians(light.OuterConeAngle));
|
||||
m_Scene->m_LightEnvironment.SpotLights[m_Scene->m_LightEnvironment.SpotLightCount++] = {
|
||||
transform.Translation,
|
||||
direction,
|
||||
light.Radiance,
|
||||
light.Intensity,
|
||||
light.Range,
|
||||
innerCos,
|
||||
outerCos,
|
||||
light.CastShadows,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RenderSystem3D::OnUpdateRuntime(TimeStep ts)
|
||||
{
|
||||
Entity cameraEntity = m_Scene->GetMainCameraEntity();
|
||||
if (!cameraEntity)
|
||||
return;
|
||||
|
||||
const glm::mat4 cameraViewMatrix = glm::inverse(m_Scene->GetTransformRelativeToParent(cameraEntity));
|
||||
SceneCamera& camera = cameraEntity.GetComponent<CameraComponent>();
|
||||
camera.SetViewportSize(m_Scene->GetViewportSize());
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// RENDER 3D SCENE //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Process lights
|
||||
UpdateLights();
|
||||
|
||||
// TODO: only one sky light at the moment!
|
||||
{
|
||||
const auto lights = m_Scene->m_Registry.group<SkyLightComponent>(entt::get<TransformComponent>);
|
||||
if (lights.empty())
|
||||
m_Scene->m_Environment = Ref<Environment>::Create(Renderer3D::GetBlackCubeTexture(), Renderer3D::GetBlackCubeTexture());
|
||||
if (!lights.empty())
|
||||
{
|
||||
for (const auto entity : lights)
|
||||
{
|
||||
auto [transformComponent, skyLightComponent] = lights.get<TransformComponent, SkyLightComponent>(entity);
|
||||
if (!skyLightComponent.SceneEnvironment && skyLightComponent.DynamicSky)
|
||||
{
|
||||
Ref<TextureCube> preethamEnv = Renderer3D::CreatePreethamSky(skyLightComponent.TurbidityAzimuthInclination);
|
||||
skyLightComponent.SceneEnvironment = Ref<Environment>::Create(preethamEnv, preethamEnv);
|
||||
}
|
||||
|
||||
m_Scene->m_Environment = skyLightComponent.SceneEnvironment;
|
||||
m_Scene->m_EnvironmentIntensity = skyLightComponent.Intensity;
|
||||
if (m_Scene->m_Environment)
|
||||
m_Scene->SetSkybox(m_Scene->m_Environment->RadianceMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_Scene->m_SkyboxMaterial->Set("u_TextureLod", m_Scene->m_SkyboxLod);
|
||||
|
||||
Renderer3D::BeginScene(m_Scene, { static_cast<Camera>(camera), cameraViewMatrix });
|
||||
{
|
||||
const auto group = m_Scene->m_Registry.group<MeshComponent>(entt::get<TransformComponent>);
|
||||
|
||||
// this maybe not to set
|
||||
// in Editor actually only one materialdesc will be changed
|
||||
Ref<PBRMaterialAsset> materialAsset;
|
||||
|
||||
for (const auto entity : group)
|
||||
{
|
||||
const auto& [transformComponent, meshComponent] = group.get<TransformComponent, MeshComponent>(entity);
|
||||
if (meshComponent.Mesh)
|
||||
{
|
||||
|
||||
for (auto i = 0; i < meshComponent.MaterialInstances.size(); i++)
|
||||
{
|
||||
if (meshComponent.MaterialDescs[i] && meshComponent.MaterialDescs[i]->IsDirty)
|
||||
{
|
||||
materialAsset = meshComponent.MaterialDescs[i];
|
||||
meshComponent.UpdateMaterials(i);
|
||||
}
|
||||
}
|
||||
|
||||
meshComponent.Mesh->OnUpdate(ts);
|
||||
|
||||
glm::mat4 transform = m_Scene->GetTransformRelativeToParent(Entity(entity, m_Scene));
|
||||
|
||||
// TODO: Should we render (logically)
|
||||
SceneRenderer::SubmitMesh(meshComponent, transform, meshComponent.MaterialInstances);
|
||||
}
|
||||
}
|
||||
if (materialAsset) materialAsset->IsDirty = false;
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
Renderer3D::EndScene(SceneRenderer::GetFinalRenderPass());
|
||||
}
|
||||
|
||||
void RenderSystem3D::OnUpdateEditor(TimeStep ts, const EditorCamera& editorCamera)
|
||||
{
|
||||
// Process lights Direction, Point, Spot
|
||||
UpdateLights();
|
||||
|
||||
// TODO: only one sky light at the moment!
|
||||
{
|
||||
const auto lights = m_Scene->m_Registry.group<SkyLightComponent>(entt::get<TransformComponent>);
|
||||
if (lights.empty())
|
||||
m_Scene->m_Environment = Ref<Environment>::Create(Renderer3D::GetBlackCubeTexture(), Renderer3D::GetBlackCubeTexture());
|
||||
if (!lights.empty())
|
||||
{
|
||||
for (const auto entity : lights)
|
||||
{
|
||||
auto [transformComponent, skyLightComponent] = lights.get<TransformComponent, SkyLightComponent>(entity);
|
||||
if (!skyLightComponent.SceneEnvironment && skyLightComponent.DynamicSky)
|
||||
{
|
||||
Ref<TextureCube> preethamEnv = Renderer3D::CreatePreethamSky(skyLightComponent.TurbidityAzimuthInclination);
|
||||
skyLightComponent.SceneEnvironment = Ref<Environment>::Create(preethamEnv, preethamEnv);
|
||||
}
|
||||
|
||||
m_Scene->m_Environment = skyLightComponent.SceneEnvironment;
|
||||
m_Scene->m_EnvironmentIntensity = skyLightComponent.Intensity;
|
||||
if (m_Scene->m_Environment)
|
||||
m_Scene->SetSkybox(m_Scene->m_Environment->RadianceMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_Scene->m_SkyboxMaterial->Set("u_TextureLod", m_Scene->m_SkyboxLod);
|
||||
|
||||
// TODO: this value should be storage and can modify
|
||||
// TODO: Renderer2D cannot blend with Renderer3D
|
||||
Renderer3D::BeginScene(m_Scene, { static_cast<Camera>(editorCamera), editorCamera.GetViewMatrix()});
|
||||
{
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// RENDER 3D SCENE //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
const auto group = m_Scene->m_Registry.group<MeshComponent>(entt::get<TransformComponent>);
|
||||
{
|
||||
|
||||
// in Editor actually only one materialdesc will be changed
|
||||
Ref<PBRMaterialAsset> materialAsset;
|
||||
|
||||
for (const auto [entity, meshComponent, transformComponent]: group.each())
|
||||
{
|
||||
Entity e = {entity, m_Scene};
|
||||
|
||||
if (meshComponent.Mesh)
|
||||
{
|
||||
|
||||
for (auto i = 0; i < meshComponent.MaterialInstances.size(); i++)
|
||||
{
|
||||
if (meshComponent.MaterialDescs[i] && meshComponent.MaterialDescs[i]->IsDirty)
|
||||
{
|
||||
materialAsset = meshComponent.MaterialDescs[i];
|
||||
meshComponent.UpdateMaterials(i);
|
||||
}
|
||||
}
|
||||
|
||||
meshComponent.Mesh->OnUpdate(ts);
|
||||
|
||||
glm::mat4 transform = m_Scene->GetTransformRelativeToParent(e);
|
||||
|
||||
// TODO: Should we render (logically)
|
||||
if (m_Scene->m_SelectedEntity == entity)
|
||||
SceneRenderer::SubmitSelectedMesh(meshComponent, transform, meshComponent.MaterialInstances);
|
||||
else
|
||||
SceneRenderer::SubmitMesh(meshComponent, transform, meshComponent.MaterialInstances);
|
||||
}
|
||||
|
||||
// Renderer Collider
|
||||
if (m_Scene->m_SelectedEntity == entity)
|
||||
{
|
||||
glm::mat4 transform = m_Scene->GetTransformRelativeToParent(e);
|
||||
|
||||
if (const auto collider = e.TryGetComponent<BoxColliderComponent>())
|
||||
SceneRenderer::SubmitColliderMesh(*collider, transform);
|
||||
if (const auto collider = e.TryGetComponent<SphereColliderComponent>())
|
||||
SceneRenderer::SubmitColliderMesh(*collider, transform);
|
||||
if (const auto collider = e.TryGetComponent<CapsuleColliderComponent>())
|
||||
SceneRenderer::SubmitColliderMesh(*collider, transform);
|
||||
if (const auto collider = e.TryGetComponent<MeshColliderComponent>())
|
||||
SceneRenderer::SubmitColliderMesh(*collider, transform);
|
||||
}
|
||||
}
|
||||
|
||||
if (materialAsset) materialAsset->IsDirty = false;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
Renderer3D::EndScene(SceneRenderer::GetFinalRenderPass());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
//
|
||||
// Created by Atdunbg on 2026/5/1.
|
||||
//
|
||||
|
||||
#ifndef PRISM_RENDERSYSTEM3D_H
|
||||
#define PRISM_RENDERSYSTEM3D_H
|
||||
#include "Prism/Scene/ECSFramework/Systems/System.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
class RenderSystem3D : public System
|
||||
{
|
||||
public:
|
||||
RenderSystem3D(Scene* scene) : System(scene) {}
|
||||
|
||||
void OnUpdateEditor(TimeStep ts, const EditorCamera& editorCamera) override;
|
||||
void OnUpdateRuntime(TimeStep ts) override;
|
||||
|
||||
private:
|
||||
void UpdateLights();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //PRISM_RENDERSYSTEM3D_H
|
||||
@ -0,0 +1,43 @@
|
||||
//
|
||||
// Created by Atdunbg on 2026/5/1.
|
||||
//
|
||||
|
||||
#include "ScriptSystem.h"
|
||||
|
||||
#include "Prism/Script/ScriptEngine.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
void ScriptSystem::OnRuntimeStart()
|
||||
{
|
||||
ScriptEngine::SetSceneContext(m_Scene);
|
||||
{
|
||||
const auto view = m_Scene->m_Registry.view<ScriptComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, m_Scene };
|
||||
if (ScriptEngine::ModuleExists(e.GetComponent<ScriptComponent>().ModuleName))
|
||||
ScriptEngine::InstantiateEntityClass(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptSystem::OnRuntimeStop()
|
||||
{
|
||||
}
|
||||
|
||||
void ScriptSystem::OnUpdate(TimeStep ts)
|
||||
{
|
||||
|
||||
// Update all entities
|
||||
{
|
||||
const auto view = m_Scene->m_Registry.view<ScriptComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, m_Scene };
|
||||
if (ScriptEngine::ModuleExists(e.GetComponent<ScriptComponent>().ModuleName))
|
||||
ScriptEngine::OnUpdateEntity(e, ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by Atdunbg on 2026/5/1.
|
||||
//
|
||||
|
||||
#ifndef PRISM_SCRIPTSYSTEM_H
|
||||
#define PRISM_SCRIPTSYSTEM_H
|
||||
#include "Prism/Scene/ECSFramework/Systems/System.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
class ScriptSystem : public System
|
||||
{
|
||||
public:
|
||||
ScriptSystem(Scene* scene) : System(scene) {}
|
||||
|
||||
void OnRuntimeStart() override;
|
||||
void OnRuntimeStop() override;
|
||||
|
||||
void OnUpdate(TimeStep ts) override;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //PRISM_SCRIPTSYSTEM_H
|
||||
34
Prism/src/Prism/Scene/ECSFramework/Systems/System.h
Normal file
34
Prism/src/Prism/Scene/ECSFramework/Systems/System.h
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// Created by Atdunbg on 2026/5/1.
|
||||
//
|
||||
|
||||
#ifndef PRISM_SYSTEM_H
|
||||
#define PRISM_SYSTEM_H
|
||||
#include "Prism/Core/Ref.h"
|
||||
#include "Prism/Core/TimeStep.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
class EditorCamera;
|
||||
class Scene;
|
||||
|
||||
class PRISM_API System : public RefCounted
|
||||
{
|
||||
public:
|
||||
System() = delete;
|
||||
System(Scene* scene) : m_Scene(scene) {}
|
||||
virtual ~System() = default;
|
||||
|
||||
virtual void OnUpdate(TimeStep ts) {}
|
||||
virtual void OnUpdateEditor(TimeStep ts, const EditorCamera& camera) {}
|
||||
virtual void OnUpdateRuntime(TimeStep ts) {}
|
||||
virtual void OnRuntimeStart() {}
|
||||
virtual void OnRuntimeStop() {}
|
||||
|
||||
protected:
|
||||
Scene* m_Scene = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //PRISM_SYSTEM_H
|
||||
@ -4,26 +4,27 @@
|
||||
|
||||
#include "Scene.h"
|
||||
|
||||
#include "Components.h"
|
||||
#include "Entity.h"
|
||||
#include "ECSFramework/Components/Components.h"
|
||||
#include "ECSFramework/Entity/Entity.h"
|
||||
#include "Prism/Renderer/SceneRenderer.h"
|
||||
#include "Prism/Script/ScriptEngine.h"
|
||||
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtx/matrix_decompose.hpp>
|
||||
|
||||
#include "Prism/Physics/Physics3D.h"
|
||||
#include "Prism/Physics/PhysicsActor.h"
|
||||
#define PX_PHYSX_STATIC_LIB
|
||||
#include <PxPhysicsAPI.h>
|
||||
|
||||
#include "ECSFramework/Systems/Physics/PhysicsSystem2D.h"
|
||||
#include "ECSFramework/Systems/Physics/PhysicsSystem3D.h"
|
||||
#include "ECSFramework/Systems/Render/RenderSystem2D.h"
|
||||
#include "ECSFramework/Systems/Render/RenderSystem3D.h"
|
||||
#include "ECSFramework/Systems/Script/ScriptSystem.h"
|
||||
#include "Prism/Asset/AssetsManager.h"
|
||||
#include "Prism/Core/Input.h"
|
||||
#include "Prism/Core/Math/Math.h"
|
||||
#include "Prism/Physics/Physics2D.h"
|
||||
#include "Prism/Physics/Physics3D.h"
|
||||
#include "Prism/Renderer/Renderer.h"
|
||||
#include "Prism/Renderer/Renderer3D.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
@ -66,6 +67,13 @@ namespace Prism
|
||||
|
||||
void Scene::Init(const bool runtime)
|
||||
{
|
||||
m_Systems.emplace_back(Ref<RenderSystem3D>::Create(this));
|
||||
m_Systems.emplace_back(Ref<RenderSystem2D>::Create(this));
|
||||
m_Systems.emplace_back(Ref<PhysicsSystem2D>::Create(this));
|
||||
m_Systems.emplace_back(Ref<PhysicsSystem3D>::Create(this));
|
||||
m_Systems.emplace_back(Ref<ScriptSystem>::Create(this));
|
||||
|
||||
|
||||
const auto skyboxShader = Shader::Create("assets/shaders/Skybox.glsl");
|
||||
m_SkyboxMaterial = MaterialInstance::Create(Material::Create(skyboxShader));
|
||||
m_SkyboxMaterial->SetFlag(MaterialFlag::DepthTest, false);
|
||||
@ -82,342 +90,35 @@ namespace Prism
|
||||
b2DestroyWorld(m_Registry.get<Box2DWorldComponent>(m_SceneEntity).World);
|
||||
Physics3D::DestroyScene();
|
||||
ScriptEngine::OnSceneDestruct(m_SceneID);
|
||||
m_Systems.clear();
|
||||
}
|
||||
|
||||
void Scene::OnUpdate(TimeStep ts)
|
||||
void Scene::OnUpdate(const TimeStep ts)
|
||||
{
|
||||
|
||||
// Box2D physics
|
||||
|
||||
const auto sceneView = m_Registry.view<Box2DWorldComponent>();
|
||||
const auto& box2DWorld = m_Registry.get<Box2DWorldComponent>(sceneView.front()).World;
|
||||
constexpr int32_t positionIterations = 2;
|
||||
b2World_Step(box2DWorld, ts, positionIterations);
|
||||
// Process Contact Envents box2d version 3.0^ should impl contact event after b2World_Step
|
||||
Physics2D::ProcessContactEvents(box2DWorld);
|
||||
|
||||
// Physics3D
|
||||
Physics3D::Simulate(ts);
|
||||
|
||||
for (auto& system : m_Systems)
|
||||
{
|
||||
const auto view = m_Registry.view<RigidBody2DComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
const auto& rb2d = e.GetComponent<RigidBody2DComponent>();
|
||||
const auto& position = b2Body_GetPosition(rb2d.RuntimeBodyID);
|
||||
const float angle = b2Rot_GetAngle(b2Body_GetRotation(rb2d.RuntimeBodyID));
|
||||
|
||||
auto& transform = e.GetComponent<TransformComponent>();
|
||||
|
||||
transform.Translation.x = position.x;
|
||||
transform.Translation.y = position.y;
|
||||
transform.Rotation.z = angle;
|
||||
|
||||
}
|
||||
system->OnUpdate(ts);
|
||||
}
|
||||
|
||||
// update transformComponent internal direction
|
||||
{
|
||||
const auto view = m_Registry.view<TransformComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& transformComponent = e.GetComponent<TransformComponent>();
|
||||
glm::mat4 transform = GetTransformRelativeToParent(Entity(entity, this));
|
||||
glm::vec3 translation;
|
||||
glm::vec3 rotation;
|
||||
glm::vec3 scale;
|
||||
Math::DecomposeTransform(transform, translation, rotation, scale);
|
||||
|
||||
auto rotationQuat = glm::quat(rotation);
|
||||
transformComponent.Up = glm::normalize(glm::rotate(rotationQuat, glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||
transformComponent.Right = glm::normalize(glm::rotate(rotationQuat, glm::vec3(1.0f, 0.0f, 0.0f)));
|
||||
transformComponent.Forward = glm::normalize(glm::rotate(rotationQuat, glm::vec3(0.0f, 0.0f, -1.0f)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Update all entities
|
||||
{
|
||||
const auto view = m_Registry.view<ScriptComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
if (ScriptEngine::ModuleExists(e.GetComponent<ScriptComponent>().ModuleName))
|
||||
ScriptEngine::OnUpdateEntity(e, ts);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Scene::OnRenderRuntime(const TimeStep ts)
|
||||
{
|
||||
Entity cameraEntity = GetMainCameraEntity();
|
||||
if (!cameraEntity)
|
||||
return;
|
||||
|
||||
const glm::mat4 cameraViewMatrix = glm::inverse(GetTransformRelativeToParent(cameraEntity));
|
||||
SceneCamera& camera = cameraEntity.GetComponent<CameraComponent>();
|
||||
camera.SetViewportSize(m_ViewportWidth, m_ViewportHeight);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// RENDER 3D SCENE //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Process lights
|
||||
UpdateLights();
|
||||
|
||||
// TODO: only one sky light at the moment!
|
||||
for (auto& system : m_Systems)
|
||||
{
|
||||
m_Environment = Ref<Environment>::Create();
|
||||
const auto lights = m_Registry.group<SkyLightComponent>(entt::get<TransformComponent>);
|
||||
for (const auto entity : lights)
|
||||
{
|
||||
auto [transformComponent, skyLightComponent] = lights.get<TransformComponent, SkyLightComponent>(entity);
|
||||
m_Environment = skyLightComponent.SceneEnvironment;
|
||||
m_EnvironmentIntensity = skyLightComponent.Intensity;
|
||||
if (m_Environment)
|
||||
SetSkybox(m_Environment->RadianceMap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_SkyboxMaterial->Set("u_TextureLod", m_SkyboxLod);
|
||||
|
||||
SceneRenderer::BeginScene(this, { static_cast<Camera>(camera), cameraViewMatrix }, false);
|
||||
{
|
||||
const auto group = m_Registry.group<MeshComponent>(entt::get<TransformComponent>);
|
||||
|
||||
// this maybe not to set
|
||||
// in Editor actually only one materialdesc will be changed
|
||||
Ref<PBRMaterialAsset> materialAsset;
|
||||
|
||||
for (const auto entity : group)
|
||||
{
|
||||
const auto& [transformComponent, meshComponent] = group.get<TransformComponent, MeshComponent>(entity);
|
||||
if (meshComponent.Mesh)
|
||||
{
|
||||
|
||||
for (auto i = 0; i < meshComponent.MaterialInstances.size(); i++)
|
||||
{
|
||||
if (meshComponent.MaterialDescs[i] && meshComponent.MaterialDescs[i]->IsDirty)
|
||||
{
|
||||
materialAsset = meshComponent.MaterialDescs[i];
|
||||
meshComponent.UpdateMaterials(i);
|
||||
}
|
||||
}
|
||||
|
||||
meshComponent.Mesh->OnUpdate(ts);
|
||||
|
||||
glm::mat4 transform = GetTransformRelativeToParent(Entity(entity, this));
|
||||
|
||||
// TODO: Should we render (logically)
|
||||
SceneRenderer::SubmitMesh(meshComponent, transform, meshComponent.MaterialInstances);
|
||||
}
|
||||
}
|
||||
if (materialAsset) materialAsset->IsDirty = false;
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// RENDER 2D SCENE //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// render sprite
|
||||
{
|
||||
const auto entitiesGroup = m_Registry.group<TransformComponent>(entt::get<SpriteRendererComponent>);
|
||||
for (const auto entity : entitiesGroup)
|
||||
{
|
||||
auto [transformComponent, spriteRendererComponent] = entitiesGroup.get<TransformComponent, SpriteRendererComponent>(entity);
|
||||
if (spriteRendererComponent.Texture)
|
||||
SceneRenderer::SubmitQuad(transformComponent.GetTransform(), spriteRendererComponent.Texture, spriteRendererComponent.TilingFactor, spriteRendererComponent.Color);
|
||||
else
|
||||
SceneRenderer::SubmitQuad(transformComponent.GetTransform(), spriteRendererComponent.Color);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
system->OnUpdateRuntime(ts);
|
||||
}
|
||||
|
||||
#ifdef PRISM_RUNTIME
|
||||
SceneRenderer::FlushToScreen();
|
||||
#endif
|
||||
SceneRenderer::EndScene();
|
||||
|
||||
}
|
||||
|
||||
void Scene::OnRenderEditor(const TimeStep ts, const EditorCamera& editorCamera)
|
||||
{
|
||||
|
||||
// Process lights Direction, Point, Spot
|
||||
UpdateLights();
|
||||
|
||||
// TODO: only one sky light at the moment!
|
||||
for (auto& system : m_Systems)
|
||||
{
|
||||
const auto lights = m_Registry.group<SkyLightComponent>(entt::get<TransformComponent>);
|
||||
if (lights.empty())
|
||||
m_Environment = Ref<Environment>::Create(Renderer3D::GetBlackCubeTexture(), Renderer3D::GetBlackCubeTexture());
|
||||
if (!lights.empty())
|
||||
{
|
||||
for (const auto entity : lights)
|
||||
{
|
||||
auto [transformComponent, skyLightComponent] = lights.get<TransformComponent, SkyLightComponent>(entity);
|
||||
if (!skyLightComponent.SceneEnvironment && skyLightComponent.DynamicSky)
|
||||
{
|
||||
Ref<TextureCube> preethamEnv = Renderer3D::CreatePreethamSky(skyLightComponent.TurbidityAzimuthInclination);
|
||||
skyLightComponent.SceneEnvironment = Ref<Environment>::Create(preethamEnv, preethamEnv);
|
||||
}
|
||||
|
||||
m_Environment = skyLightComponent.SceneEnvironment;
|
||||
m_EnvironmentIntensity = skyLightComponent.Intensity;
|
||||
if (m_Environment)
|
||||
SetSkybox(m_Environment->RadianceMap);
|
||||
}
|
||||
}
|
||||
system->OnUpdateEditor(ts, editorCamera);
|
||||
}
|
||||
|
||||
m_SkyboxMaterial->Set("u_TextureLod", m_SkyboxLod);
|
||||
|
||||
// TODO: this value should be storage and can modify
|
||||
// TODO: Renderer2D cannot blend with Renderer3D
|
||||
SceneRenderer::BeginScene(this, { static_cast<Camera>(editorCamera), editorCamera.GetViewMatrix()}, false);
|
||||
{
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// RENDER 3D SCENE //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
const auto group = m_Registry.group<MeshComponent>(entt::get<TransformComponent>);
|
||||
{
|
||||
|
||||
// in Editor actually only one materialdesc will be changed
|
||||
Ref<PBRMaterialAsset> materialAsset;
|
||||
|
||||
for (const auto [entity, meshComponent, transformComponent]: group.each())
|
||||
{
|
||||
Entity e = {entity, this};
|
||||
|
||||
if (meshComponent.Mesh)
|
||||
{
|
||||
|
||||
for (auto i = 0; i < meshComponent.MaterialInstances.size(); i++)
|
||||
{
|
||||
if (meshComponent.MaterialDescs[i] && meshComponent.MaterialDescs[i]->IsDirty)
|
||||
{
|
||||
materialAsset = meshComponent.MaterialDescs[i];
|
||||
meshComponent.UpdateMaterials(i);
|
||||
}
|
||||
}
|
||||
|
||||
meshComponent.Mesh->OnUpdate(ts);
|
||||
|
||||
glm::mat4 transform = GetTransformRelativeToParent(e);
|
||||
|
||||
// TODO: Should we render (logically)
|
||||
if (m_SelectedEntity == entity)
|
||||
SceneRenderer::SubmitSelectedMesh(meshComponent, transform, meshComponent.MaterialInstances);
|
||||
else
|
||||
SceneRenderer::SubmitMesh(meshComponent, transform, meshComponent.MaterialInstances);
|
||||
}
|
||||
|
||||
// Renderer Collider
|
||||
if (m_SelectedEntity == entity)
|
||||
{
|
||||
glm::mat4 transform = GetTransformRelativeToParent(e);
|
||||
|
||||
if (const auto collider = e.TryGetComponent<BoxColliderComponent>())
|
||||
SceneRenderer::SubmitColliderMesh(*collider, transform);
|
||||
if (const auto collider = e.TryGetComponent<SphereColliderComponent>())
|
||||
SceneRenderer::SubmitColliderMesh(*collider, transform);
|
||||
if (const auto collider = e.TryGetComponent<CapsuleColliderComponent>())
|
||||
SceneRenderer::SubmitColliderMesh(*collider, transform);
|
||||
if (const auto collider = e.TryGetComponent<MeshColliderComponent>())
|
||||
SceneRenderer::SubmitColliderMesh(*collider, transform);
|
||||
}
|
||||
}
|
||||
|
||||
if (materialAsset) materialAsset->IsDirty = false;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// RENDER 2D SCENE //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// render sprite
|
||||
{
|
||||
const auto entitiesGroup = m_Registry.group<TransformComponent>(entt::get<SpriteRendererComponent>);
|
||||
for (const auto entity : entitiesGroup)
|
||||
{
|
||||
auto [transformComponent, spriteRendererComponent] = entitiesGroup.get<TransformComponent, SpriteRendererComponent>(entity);
|
||||
if (spriteRendererComponent.Texture)
|
||||
SceneRenderer::SubmitQuad(transformComponent.GetTransform(), spriteRendererComponent.Texture, spriteRendererComponent.TilingFactor, spriteRendererComponent.Color);
|
||||
else
|
||||
SceneRenderer::SubmitQuad(transformComponent.GetTransform(), spriteRendererComponent.Color);
|
||||
}
|
||||
}
|
||||
|
||||
// render camera icon
|
||||
{
|
||||
const auto editorCameraPosition = editorCamera.GetPosition();
|
||||
const auto editorCameraUpDirection = editorCamera.GetUpDirection();
|
||||
|
||||
const auto cameras = m_Registry.view<CameraComponent>();
|
||||
if (!cameras.empty())
|
||||
{
|
||||
for (auto& entity : cameras)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
if (!e.GetComponent<CameraComponent>().ShowIcon) continue;
|
||||
SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_CameraIcon, editorCameraPosition, editorCameraUpDirection);
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto skyLights = m_Registry.view<SkyLightComponent>(); !skyLights.empty())
|
||||
{
|
||||
for (auto& entity : skyLights)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
if (!e.GetComponent<SkyLightComponent>().ShowIcon) continue;
|
||||
SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_LightIcon, editorCameraPosition, editorCameraUpDirection);
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto directionLight = m_Registry.view<DirectionalLightComponent>(); !directionLight.empty())
|
||||
{
|
||||
for (auto& entity : directionLight)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
if (!e.GetComponent<DirectionalLightComponent>().ShowIcon) continue;
|
||||
SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_LightIcon, editorCameraPosition, editorCameraUpDirection);
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto pointLight = m_Registry.view<PointLightComponent>(); !pointLight.empty())
|
||||
{
|
||||
for (auto& entity : pointLight )
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
if (!e.GetComponent<PointLightComponent>().ShowIcon) continue;
|
||||
SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_LightIcon, editorCameraPosition, editorCameraUpDirection);
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto spotLight = m_Registry.view<SpotLightComponent>(); !spotLight.empty())
|
||||
{
|
||||
for (auto& entity : spotLight )
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
if (!e.GetComponent<SpotLightComponent>().ShowIcon) continue;
|
||||
SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_LightIcon, editorCameraPosition, editorCameraUpDirection);
|
||||
}
|
||||
}
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
SceneRenderer::EndScene();
|
||||
}
|
||||
|
||||
void Scene::OnEvent(Event& e)
|
||||
@ -426,31 +127,10 @@ namespace Prism
|
||||
|
||||
void Scene::OnRuntimeStart()
|
||||
{
|
||||
ScriptEngine::SetSceneContext(this);
|
||||
|
||||
for (auto& system : m_Systems)
|
||||
{
|
||||
auto view = m_Registry.view<ScriptComponent>();
|
||||
for (auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
if (ScriptEngine::ModuleExists(e.GetComponent<ScriptComponent>().ModuleName))
|
||||
ScriptEngine::InstantiateEntityClass(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Box2D physics
|
||||
Physics2D::CreateBody(this);
|
||||
|
||||
// PhyX
|
||||
{
|
||||
auto view = m_Registry.view<RigidBodyComponent>();
|
||||
// Physics3D::ExpandEntityBuffer(static_cast<uint32_t>(view.size()));
|
||||
for (auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
Physics3D::CreateActor(e);
|
||||
// Physics3D::CreateActor(e);
|
||||
}
|
||||
system->OnRuntimeStart();
|
||||
}
|
||||
|
||||
m_IsPlaying = true;
|
||||
@ -460,7 +140,10 @@ namespace Prism
|
||||
{
|
||||
Input::SetCursorMode(CursorMode::Normal);
|
||||
|
||||
Physics3D::DestroyScene();
|
||||
for (auto& system : m_Systems)
|
||||
{
|
||||
system->OnRuntimeStop();
|
||||
}
|
||||
|
||||
delete[] m_Physics3DBodyEntityBuffer;
|
||||
delete[] m_Physics2DBodyEntityBuffer;
|
||||
@ -665,74 +348,6 @@ namespace Prism
|
||||
b2World_SetGravity(m_Registry.get<Box2DWorldComponent>(m_SceneEntity).World, {0.0f, gravity});
|
||||
}
|
||||
|
||||
void Scene::UpdateLights()
|
||||
{
|
||||
// direction Light
|
||||
{
|
||||
const auto lights = m_Registry.group<DirectionalLightComponent>(entt::get<TransformComponent>);
|
||||
if (!lights.empty())
|
||||
{
|
||||
for (const auto entity : lights)
|
||||
{
|
||||
auto [transformComponent, lightComponent] = lights.get<TransformComponent, DirectionalLightComponent>(entity);
|
||||
const glm::vec3 direction = glm::normalize(glm::mat3(transformComponent.GetTransform()) * glm::vec3(0.0f, 0.0f,1.0f));
|
||||
m_LightEnvironment.DirectionalLights =
|
||||
{
|
||||
direction,
|
||||
lightComponent.Radiance,
|
||||
lightComponent.Intensity,
|
||||
lightComponent.CastShadows
|
||||
};
|
||||
}
|
||||
}else
|
||||
{
|
||||
m_LightEnvironment.DirectionalLights = {};
|
||||
}
|
||||
}
|
||||
|
||||
// Point Light
|
||||
{
|
||||
const auto pointLights = m_Registry.group<PointLightComponent>(entt::get<TransformComponent>);
|
||||
m_LightEnvironment.PointLightCount = 0;
|
||||
for (const auto entity : pointLights)
|
||||
{
|
||||
if (m_LightEnvironment.PointLightCount >= 8) break;
|
||||
auto [transform, light] = pointLights.get<TransformComponent, PointLightComponent>(entity);
|
||||
m_LightEnvironment.PointLights[m_LightEnvironment.PointLightCount++] = {
|
||||
transform.Translation,
|
||||
light.Radiance,
|
||||
light.Radius,
|
||||
light.Intensity,
|
||||
light.CastShadows,
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Spot Light
|
||||
{
|
||||
const auto spotLights = m_Registry.group<SpotLightComponent>(entt::get<TransformComponent>);
|
||||
m_LightEnvironment.SpotLightCount = 0;
|
||||
for (const auto entity : spotLights)
|
||||
{
|
||||
if (m_LightEnvironment.SpotLightCount >= 8) break;
|
||||
auto [transform, light] = spotLights.get<TransformComponent, SpotLightComponent>(entity);
|
||||
const glm::vec3 direction = glm::normalize(glm::mat3(transform.GetTransform()) * glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
const float innerCos = glm::cos(glm::radians(light.InnerConeAngle));
|
||||
const float outerCos = glm::cos(glm::radians(light.OuterConeAngle));
|
||||
m_LightEnvironment.SpotLights[m_LightEnvironment.SpotLightCount++] = {
|
||||
transform.Translation,
|
||||
direction,
|
||||
light.Radiance,
|
||||
light.Intensity,
|
||||
light.Range,
|
||||
innerCos,
|
||||
outerCos,
|
||||
light.CastShadows,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Scene::DestroyEntity(Entity entity)
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
class System;
|
||||
|
||||
struct GPUDirectionalLight
|
||||
{
|
||||
@ -88,6 +89,7 @@ namespace Prism
|
||||
void OnRuntimeStart();
|
||||
void OnRuntimeStop();
|
||||
|
||||
glm::vec2 GetViewportSize() const { return {m_ViewportWidth, m_ViewportHeight}; }
|
||||
void SetViewportSize(const glm::ivec2& viewportSize);
|
||||
void SetViewportSize(uint32_t width, uint32_t height);
|
||||
|
||||
@ -140,13 +142,9 @@ namespace Prism
|
||||
// Editor-specific
|
||||
void SetSelectedEntity(const entt::entity entity) { m_SelectedEntity = entity; }
|
||||
|
||||
private:
|
||||
void UpdateLights();
|
||||
|
||||
private:
|
||||
UUID m_SceneID;
|
||||
entt::entity m_SceneEntity;
|
||||
entt::registry m_Registry;
|
||||
|
||||
std::vector<Entity*> m_Entities;
|
||||
Camera m_Camera;
|
||||
@ -156,26 +154,35 @@ namespace Prism
|
||||
|
||||
EntityMap m_EntityIDMap;
|
||||
|
||||
entt::entity m_SelectedEntity;
|
||||
Entity* m_Physics2DBodyEntityBuffer = nullptr;
|
||||
Entity* m_Physics3DBodyEntityBuffer = nullptr;
|
||||
|
||||
LightEnvironment m_LightEnvironment{};
|
||||
|
||||
bool m_IsPlaying = false;
|
||||
|
||||
Ref<Environment> m_Environment;
|
||||
float m_EnvironmentIntensity = 1.0f;
|
||||
Ref<TextureCube> m_SkyboxTexture;
|
||||
Ref<MaterialInstance> m_SkyboxMaterial;
|
||||
|
||||
float m_SkyboxLod = 0.0f;
|
||||
|
||||
|
||||
static std::unordered_map<UUID, Scene*> s_ActiveScenes;
|
||||
|
||||
|
||||
std::vector<Ref<System>> m_Systems;
|
||||
|
||||
// TODO: these will not be public
|
||||
public:
|
||||
entt::registry m_Registry;
|
||||
Ref<Texture2D> m_CameraIcon;
|
||||
Ref<Texture2D> m_LightIcon;
|
||||
|
||||
static std::unordered_map<UUID, Scene*> s_ActiveScenes;
|
||||
entt::entity m_SelectedEntity;
|
||||
|
||||
float m_SkyboxLod = 0.0f;
|
||||
Ref<MaterialInstance> m_SkyboxMaterial;
|
||||
|
||||
Ref<Environment> m_Environment;
|
||||
float m_EnvironmentIntensity = 1.0f;
|
||||
LightEnvironment m_LightEnvironment{};
|
||||
|
||||
private:
|
||||
friend class Entity;
|
||||
friend class Physics2D;
|
||||
|
||||
@ -32,6 +32,11 @@ namespace Prism
|
||||
m_OrthographicFar = farClip;
|
||||
}
|
||||
|
||||
void SceneCamera::SetViewportSize(const glm::ivec2& viewport)
|
||||
{
|
||||
SetViewportSize(viewport.x, viewport.y);
|
||||
}
|
||||
|
||||
void SceneCamera::SetViewportSize(const uint32_t width, const uint32_t height)
|
||||
{
|
||||
switch (m_ProjectionType)
|
||||
|
||||
@ -20,6 +20,7 @@ namespace Prism
|
||||
|
||||
void SetPerspective(float verticalFOV, float nearClip = 0.01f, float farClip = 1000.0f);
|
||||
void SetOrthographic(float size, float nearClip = -1.0f, float farClip = 1.0f);
|
||||
void SetViewportSize(const glm::ivec2& viewport);
|
||||
void SetViewportSize(uint32_t width, uint32_t height);
|
||||
|
||||
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
|
||||
#ifndef SCRIPTENGINE_H
|
||||
#define SCRIPTENGINE_H
|
||||
#include "Prism/Scene/Components.h"
|
||||
#include "Prism/Scene/Entity.h"
|
||||
#include "../Scene/ECSFramework/Components/Components.h"
|
||||
#include "../Scene/ECSFramework/Entity/Entity.h"
|
||||
|
||||
extern "C" {
|
||||
typedef struct _MonoObject MonoObject;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
#include "ScriptEngineRegistry.h"
|
||||
|
||||
#include "ScriptWrappers.h"
|
||||
#include "Prism/Scene/Entity.h"
|
||||
#include "../Scene/ECSFramework/Entity/Entity.h"
|
||||
|
||||
#include "mono/metadata/reflection.h"
|
||||
#include <mono/metadata/class.h>
|
||||
|
||||
Reference in New Issue
Block a user