add mono c# (using dotnet9.0 from https://github.com/dotnet/runtime), add ECS (entt), add some c# code, add fastNoise

This commit is contained in:
2025-12-08 23:38:22 +08:00
parent 39378bf23c
commit 3ffb4cc449
341 changed files with 11747 additions and 262 deletions

View File

@ -129,31 +129,43 @@ namespace Prism
void EditorLayer::OnAttach()
{
auto environment = Environment::Load("assets/env/birchwood_4k.hdr");
const auto environment = Environment::Load("assets/env/birchwood_4k.hdr");
// Model Scene
{
m_Scene = Ref<Scene>::Create("Model Scene");
m_Scene->SetCamera(Camera(glm::perspectiveFov(glm::radians(45.0f), 1280.0f, 720.0f, 0.1f, 10000.0f)));
m_CameraEntity = m_Scene->CreateEntity("Camera Entity");
m_CameraEntity.AddComponent<CameraComponent>(Camera(glm::perspectiveFov(glm::radians(45.0f), 1280.0f, 720.0f, 0.1f, 10000.0f)));
m_Scene->SetEnvironment(environment);
m_MeshEntity = m_Scene->CreateEntity("test Entity");
auto mesh = Ref<Mesh>::Create("assets/meshes/TestScene.fbx");
m_MeshEntity->SetMesh(mesh);
// auto mesh = Ref<Mesh>::Create("assets/models/Apollo AE/Apollo AE.fbx");
// auto mesh = Ref<Mesh>::Create("assets/models/tafi/塔菲.pmx");
m_MeshEntity.AddComponent<MeshComponent>(mesh);
m_MeshMaterial = mesh->GetMaterial();
m_MeshEntity.AddComponent<ScriptComponent>("Example.Script");
// Test Sandbox
auto mapGenerator = m_Scene->CreateEntity("Map Generator");
mapGenerator.AddComponent<ScriptComponent>("Example.MapGenerator");
/*
auto secondEntity = m_Scene->CreateEntity("Gun Entity");
secondEntity->Transform() = glm::translate(glm::mat4(1.0f), { 5, 5, 5 }) * glm::scale(glm::mat4(1.0f), {10, 10, 10});
mesh = Ref<Mesh>::Create("assets/models/m1911/M1911Materials.fbx");
secondEntity->SetMesh(mesh);
*/
}
// Sphere Scene
{
m_SphereScene = Ref<Scene>::Create("PBR Sphere Scene");
m_SphereScene->SetCamera(Camera(glm::perspectiveFov(glm::radians(45.0f), 1280.0f, 720.0f, 0.1f, 10000.0f)));
auto cameraEntity = m_SphereScene->CreateEntity("camera");
cameraEntity.AddComponent<CameraComponent>(Camera(glm::perspectiveFov(glm::radians(45.0f), 1280.0f, 720.0f, 0.1f, 10000.0f)));
m_SphereScene->SetEnvironment(environment);
@ -173,9 +185,11 @@ namespace Prism
roughness += 0.15f;
m_MetalSphereMaterialInstances.push_back(mi);
/*
sphereEntity->SetMesh(sphereMesh);
sphereEntity->SetMaterial(mi);
sphereEntity->Transform() = glm::translate(glm::mat4(1.0f), glm::vec3(x, 0.0f, 0.0f));
*/
}
x = -4.0f;
@ -191,16 +205,17 @@ namespace Prism
roughness += 0.15f;
m_DielectricSphereMaterialInstances.push_back(mi);
/*
sphereEntity->SetMesh(sphereMesh);
sphereEntity->SetMaterial(mi);
sphereEntity->Transform() = glm::translate(glm::mat4(1.0f), glm::vec3(x, 1.2f, 0.0f));
*/
}
}
m_ActiveScene = m_Scene;
m_SceneHierarchyPanel = CreateScope<SceneHierarchyPanel>(m_ActiveScene);
m_PlaneMesh = Ref<Mesh>::Create("assets/models/Plane1m.obj");
// Editor
m_CheckerboardTex = Texture2D::Create("assets/editor/Checkerboard.tga");
@ -210,7 +225,7 @@ namespace Prism
light.Direction = { -0.5f, -0.5f, 1.0f };
light.Radiance = { 1.0f, 1.0f, 1.0f };
m_CurrentlySelectedTransform = &m_MeshEntity->Transform();
m_CurrentlySelectedTransform = &m_MeshEntity.Transform();
}
void EditorLayer::OnDetach()
@ -254,29 +269,35 @@ namespace Prism
if (m_RoughnessInput.TextureMap)
m_MeshMaterial->Set("u_RoughnessTexture", m_RoughnessInput.TextureMap);
/*
if (m_AllowViewportCameraEvents)
m_Scene->GetCamera().OnUpdate(deltaTime);
*/
m_ActiveScene->OnUpdate(deltaTime);
if (m_DrawOnTopBoundingBoxes)
{
Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false);
auto viewProj = m_Scene->GetCamera().GetViewProjection();
auto viewProj = m_CameraEntity.GetComponent<CameraComponent>().Camera.GetViewProjection();
Renderer2D::BeginScene(viewProj, false);
Renderer::DrawAABB(m_MeshEntity->GetMesh(), m_MeshEntity->Transform());
Renderer::DrawAABB(m_MeshEntity.GetComponent<MeshComponent>(), m_MeshEntity.GetComponent<TransformComponent>());
Renderer2D::EndScene();
Renderer::EndRenderPass();
}
if (!m_SelectedSubmeshes.empty())
if (!m_SelectionContext.empty())
{
auto& selection = m_SelectionContext[0];
Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false);
const auto viewProj = m_Scene->GetCamera().GetViewProjection();
const auto viewProj = m_CameraEntity.GetComponent<CameraComponent>().Camera.GetViewProjection();
Renderer2D::BeginScene(viewProj, false);
const auto& submesh = m_SelectedSubmeshes[0];
Renderer::DrawAABB(submesh.Mesh->BoundingBox, m_MeshEntity->GetTransform() * submesh.Mesh->Transform);
const glm::vec4 color = (m_SelectionMode == SelectionMode::Entity) ? glm::vec4{ 1.0f, 1.0f, 1.0f, 1.0f } : glm::vec4{ 0.2f, 0.9f, 0.2f, 1.0f };
Renderer::DrawAABB(selection.Mesh->BoundingBox, selection.Entity.GetComponent<TransformComponent>().Transform * selection.Mesh->Transform, color);
Renderer2D::EndScene();
Renderer::EndRenderPass();
}
@ -456,7 +477,7 @@ namespace Prism
Property("Light Direction", light.Direction);
Property("Light Radiance", light.Radiance, PropertyFlag::ColorProperty);
Property("Light Multiplier", light.Multiplier, 0.0f, 5.0f);
Property("Exposure", m_ActiveScene->GetCamera().GetExposure(), 0.0f, 5.0f);
Property("Exposure", m_CameraEntity.GetComponent<CameraComponent>().Camera.GetExposure(), 0.0f, 5.0f);
Property("Radiance Prefiltering", m_RadiancePrefilter);
Property("Env Map Rotation", m_EnvMapRotation, -360.0f, 360.0f);
@ -466,6 +487,12 @@ namespace Prism
if (m_UIShowBoundingBoxes && Property("On Top", m_UIShowBoundingBoxesOnTop))
ShowBoundingBoxes(m_UIShowBoundingBoxes, m_UIShowBoundingBoxesOnTop);
const char* label = m_SelectionMode == SelectionMode::Entity ? "Entity" : "Mesh";
if (ImGui::Button(label))
{
m_SelectionMode = m_SelectionMode == SelectionMode::Entity ? SelectionMode::SubMesh : SelectionMode::Entity;
}
ImGui::Columns(1);
ImGui::End();
@ -473,8 +500,8 @@ namespace Prism
ImGui::Separator();
{
ImGui::Text("Mesh");
auto mesh = m_MeshEntity->GetMesh();
std::string fullpath = mesh ? mesh->GetFilePath() : "None";
auto meshComponent = m_MeshEntity.GetComponent<MeshComponent>();
std::string fullpath = meshComponent.Mesh ? meshComponent.Mesh->GetFilePath() : "None";
size_t found = fullpath.find_last_of("/\\");
std::string path = found != std::string::npos ? fullpath.substr(found + 1) : fullpath;
ImGui::Text(path.c_str());
@ -487,7 +514,7 @@ namespace Prism
auto newMesh = Ref<Mesh>::Create(filename);
// m_MeshMaterial.reset(new MaterialInstance(newMesh->GetMaterial()));
// m_MeshEntity->SetMaterial(m_MeshMaterial);
m_MeshEntity->SetMesh(newMesh);
meshComponent.Mesh = newMesh;
}
}
}
@ -658,8 +685,8 @@ namespace Prism
auto viewportOffset = ImGui::GetCursorPos(); // includes tab bar
auto viewportSize = ImGui::GetContentRegionAvail();
SceneRenderer::SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_ActiveScene->GetCamera().SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f));
m_ActiveScene->GetCamera().SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_CameraEntity.GetComponent<CameraComponent>().Camera.SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f));
m_CameraEntity.GetComponent<CameraComponent>().Camera.SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
ImGui::Image((ImTextureRef)SceneRenderer::GetFinalColorBufferRendererID(), viewportSize, { 0, 1 }, { 1, 0 });
@ -677,21 +704,41 @@ namespace Prism
// ImGuizmo
if (m_GizmoType != -1 && m_CurrentlySelectedTransform)
{
auto& selection = m_SelectionContext[0];
const auto rw = (float)ImGui::GetWindowWidth();
const auto rh = (float)ImGui::GetWindowHeight();
ImGuizmo::SetOrthographic(false);
ImGuizmo::SetDrawlist();
ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, rw, rh);
const auto& camera = m_ActiveScene->GetCamera();
bool snap = Input::IsKeyPressed(PM_KEY_LEFT_CONTROL);
ImGuizmo::Manipulate(glm::value_ptr(camera.GetViewMatrix()),
glm::value_ptr(camera.GetProjectionMatrix()),
(ImGuizmo::OPERATION)m_GizmoType,
ImGuizmo::LOCAL,
glm::value_ptr(m_MeshEntity->Transform()),
nullptr,
snap ? &m_SnapValue : nullptr);
const auto& camera = m_CameraEntity.GetComponent<CameraComponent>().Camera;
bool snap = Input::IsKeyPressed(Key::LEFT_CONTROL);
auto& entityTransform = selection.Entity.Transform();
float snapValue[3] = { m_SnapValue, m_SnapValue, m_SnapValue };
if (m_SelectionMode == SelectionMode::Entity)
{
ImGuizmo::Manipulate(glm::value_ptr(camera.GetViewMatrix()),
glm::value_ptr(camera.GetProjectionMatrix()),
(ImGuizmo::OPERATION)m_GizmoType,
ImGuizmo::LOCAL,
glm::value_ptr(m_MeshEntity.GetComponent<TransformComponent>().Transform),
nullptr,
snap ? snapValue : nullptr);
}else
{
glm::mat4 transformBase = entityTransform * selection.Mesh->Transform;
ImGuizmo::Manipulate(glm::value_ptr(camera.GetViewMatrix()),
glm::value_ptr(camera.GetProjectionMatrix()),
(ImGuizmo::OPERATION)m_GizmoType,
ImGuizmo::LOCAL,
glm::value_ptr(transformBase),
nullptr,
snap ? snapValue : nullptr);
selection.Mesh->Transform = glm::inverse(entityTransform) * transformBase;
}
}
ImGui::End();
@ -701,8 +748,10 @@ namespace Prism
void EditorLayer::OnEvent(Event& e)
{
/*
if (m_AllowViewportCameraEvents)
m_Scene->GetCamera().OnEvent(e);
*/
EventDispatcher dispatcher(e);
dispatcher.Dispatch<KeyPressedEvent>(PM_BIND_EVENT_FN(EditorLayer::OnKeyPressedEvent));
@ -713,26 +762,26 @@ namespace Prism
{
switch (e.GetKeyCode())
{
case PM_KEY_Q:
case KeyCode::Q:
m_GizmoType = -1;
break;
case PM_KEY_W:
case KeyCode::W:
m_GizmoType = ImGuizmo::OPERATION::TRANSLATE;
break;
case PM_KEY_E:
case KeyCode::E:
m_GizmoType = ImGuizmo::OPERATION::ROTATE;
break;
case PM_KEY_R:
case KeyCode::R:
m_GizmoType = ImGuizmo::OPERATION::SCALE;
break;
case PM_KEY_G:
case KeyCode::G:
// Toggle grid
if (Input::IsKeyPressed(PM_KEY_LEFT_CONTROL))
if (Input::IsKeyPressed(KeyCode::LEFT_CONTROL))
SceneRenderer::GetOptions().ShowGrid = !SceneRenderer::GetOptions().ShowGrid;
break;
case PM_KEY_B:
case KeyCode::B:
// Toggle bounding boxes
if (Input::IsKeyPressed(PM_KEY_LEFT_CONTROL))
if (Input::IsKeyPressed(KeyCode::LEFT_CONTROL))
{
m_UIShowBoundingBoxes = !m_UIShowBoundingBoxes;
ShowBoundingBoxes(m_UIShowBoundingBoxes, m_UIShowBoundingBoxesOnTop);
@ -746,49 +795,57 @@ namespace Prism
bool EditorLayer::OnMouseButtonPressedEvent(MouseButtonPressedEvent& e)
{
auto [mx, my] = Input::GetMousePosition();
if (e.GetMouseButton() == PM_MOUSE_BUTTON_LEFT && !Input::IsKeyPressed(PM_KEY_LEFT_ALT) && !ImGuizmo::IsOver())
if (e.GetMouseButton() == PM_MOUSE_BUTTON_LEFT && !Input::IsKeyPressed(KeyCode::LEFT_ALT) && !ImGuizmo::IsOver())
{
auto [mouseX, mouseY] = GetMouseViewportSpace();
if (mouseX > -1.0f && mouseX < 1.0f && mouseY > -1.0f && mouseY < 1.0f)
{
auto [origin, direction] = CastRay(mouseX, mouseY);
m_SelectedSubmeshes.clear();
auto mesh = m_MeshEntity->GetMesh();
auto& submeshes = mesh->GetSubmeshes();
float lastT = std::numeric_limits<float>::max();
for (uint32_t i = 0; i < submeshes.size(); i++)
m_SelectionContext.clear();
const auto meshEntities = m_Scene->GetAllEntitiesWith<MeshComponent>();
for (auto e : meshEntities)
{
auto& submesh = submeshes[i];
Ray ray = {
glm::inverse(m_MeshEntity->GetTransform() * submesh.Transform) * glm::vec4(origin, 1.0f),
glm::inverse(glm::mat3(m_MeshEntity->GetTransform()) * glm::mat3(submesh.Transform)) * direction
};
Entity entity = { e, m_Scene.Raw() };
auto mesh = entity.GetComponent<MeshComponent>().Mesh;
float t;
const bool intersects = ray.IntersectsAABB(submesh.BoundingBox, t);
if (intersects)
if (!mesh)
continue;
auto& submeshes = mesh->GetSubmeshes();
float lastT = std::numeric_limits<float>::max();
for (uint32_t i = 0; i < submeshes.size(); i++)
{
const auto& triangleCache = mesh->GetTriangleCache(i);
for (const auto& triangle : triangleCache)
auto& submesh = submeshes[i];
Ray ray = {
glm::inverse(entity.Transform() * submesh.Transform) * glm::vec4(origin, 1.0f),
glm::inverse(glm::mat3(entity.Transform()) * glm::mat3(submesh.Transform)) * direction
};
float t;
if (bool intersects = ray.IntersectsAABB(submesh.BoundingBox, t))
{
if (ray.IntersectsTriangle(triangle.V0.Position, triangle.V1.Position, triangle.V2.Position, t))
const auto& triangleCache = mesh->GetTriangleCache(i);
for (const auto& triangle : triangleCache)
{
PM_CLIENT_WARN("INTERSECTION: {0}, t={1}", submesh.NodeName, t);
m_SelectedSubmeshes.push_back({ &submesh, t });
break;
if (ray.IntersectsTriangle(triangle.V0.Position, triangle.V1.Position, triangle.V2.Position, t))
{
PM_CLIENT_WARN("INTERSECTION: {0}, t={1}", submesh.NodeName, t);
m_SelectionContext.push_back({ entity, &submesh, t });
break;
}
}
}
}
}
std::sort(m_SelectedSubmeshes.begin(), m_SelectedSubmeshes.end(), [](auto& a, auto& b) { return a.Distance < b.Distance; });
// TODO: Handle mesh being deleted, etc.
if (!m_SelectedSubmeshes.empty())
m_CurrentlySelectedTransform = &m_SelectedSubmeshes[0].Mesh->Transform;
else
m_CurrentlySelectedTransform = &m_MeshEntity->Transform();
std::sort(m_SelectionContext.begin(), m_SelectionContext.end(), [](auto& a, auto& b)
{
return a.Distance < b.Distance;
});
if (!m_SelectionContext.empty())
OnSelected(m_SelectionContext[0]);
}
}
return false;
@ -815,13 +872,29 @@ namespace Prism
{
const glm::vec4 mouseClipPos = { mx, my, -1.0f, 1.0f };
const auto inverseProj = glm::inverse(m_Scene->GetCamera().GetProjectionMatrix());
const auto inverseView = glm::inverse(glm::mat3(m_Scene->GetCamera().GetViewMatrix()));
const auto inverseProj = glm::inverse(m_CameraEntity.GetComponent<CameraComponent>().Camera.GetProjectionMatrix());
const auto inverseView = glm::inverse(glm::mat3(m_CameraEntity.GetComponent<CameraComponent>().Camera.GetViewMatrix()));
const glm::vec4 ray = inverseProj * mouseClipPos;
glm::vec3 rayPos = m_Scene->GetCamera().GetPosition();
glm::vec3 rayPos = m_CameraEntity.GetComponent<CameraComponent>().Camera.GetPosition();
glm::vec3 rayDir = inverseView * glm::vec3(ray);
return { rayPos, rayDir };
}
void EditorLayer::OnSelected(const SelectedSubmesh& selectionContext)
{
m_SceneHierarchyPanel->SetSelected(selectionContext.Entity);
}
Ray EditorLayer::CastMouseRay()
{
auto [mouseX, mouseY] = GetMouseViewportSpace();
if (mouseX > -1.0f && mouseX < 1.0f && mouseY > -1.0f && mouseY < 1.0f)
{
auto [origin, direction] = CastRay(mouseX, mouseY);
return Ray(origin, direction);
}
return Ray::Zero();
}
}

View File

@ -32,6 +32,14 @@ namespace Prism
std::pair<float, float> GetMouseViewportSpace() const;
std::pair<glm::vec3, glm::vec3> CastRay(float mx, float my);
struct SelectedSubmesh
{
Prism::Entity Entity;
Submesh* Mesh;
float Distance;
};
void OnSelected(const SelectedSubmesh& selectionContext);
Ray CastMouseRay();
private:
Scope<SceneHierarchyPanel> m_SceneHierarchyPanel;
@ -39,9 +47,9 @@ namespace Prism
Ref<Scene> m_SphereScene;
Ref<Scene> m_ActiveScene;
Entity* m_MeshEntity = nullptr;
Entity m_MeshEntity;
Entity m_CameraEntity;
Ref<Mesh> m_PlaneMesh;
Ref<Material> m_SphereBaseMaterial;
Ref<Material> m_MeshMaterial;
@ -55,12 +63,14 @@ namespace Prism
int m_GizmoType = -1; // -1 = no gizmo
float m_SnapValue = 0.5f;
struct SelectedSubmesh
enum class SelectionMode
{
Submesh* Mesh;
float Distance;
None = 0, Entity = 1, SubMesh = 2
};
std::vector<SelectedSubmesh> m_SelectedSubmeshes;
SelectionMode m_SelectionMode = SelectionMode::Entity;
std::vector<SelectedSubmesh> m_SelectionContext;
glm::mat4* m_RelativeTransform = nullptr;
glm::mat4* m_CurrentlySelectedTransform = nullptr;
// configure button