Add ECS to replace scene calls with bare code

This commit is contained in:
2026-05-10 10:53:34 +08:00
parent 79707b77f5
commit d11f8bb0c9
31 changed files with 775 additions and 446 deletions

View File

@ -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

View File

@ -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"

View File

@ -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)

View File

@ -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"

View File

@ -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

View File

@ -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
{

View File

@ -9,7 +9,7 @@
#include <PxPhysicsAPI.h>
#include "glm/glm.hpp"
#include "Prism/Scene/Components.h"
#include "../Scene/ECSFramework/Components/Components.h"
namespace Prism
{

View File

@ -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;

View File

@ -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"

View File

@ -178,7 +178,7 @@ namespace Prism
}
// TODO: this maybe storage in SceneRenderer
Ref<RenderPass> SceneRenderer::GetFinalRenderPass()
Ref<RenderPass>& SceneRenderer::GetFinalRenderPass()
{
return s_Data.FinalPass;
}

View File

@ -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();

View File

@ -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"

View File

@ -8,7 +8,7 @@
#include "Prism/Renderer/Mesh.h"
#include "Prism/Scene/Scene.h"
#include "Components.h"
#include "../Components/Components.h"
namespace Prism
{

View File

@ -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;
}
}
}
}

View File

@ -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

View File

@ -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)));
}
}
}
}

View File

@ -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

View File

@ -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());
}
}

View File

@ -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

View File

@ -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());
}
}

View File

@ -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

View File

@ -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);
}
}
}
}

View File

@ -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

View 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

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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>