From 323d64661107c6e03d0b2f254fac3c952e899238 Mon Sep 17 00:00:00 2001 From: Atdunbg Date: Mon, 19 Jan 2026 13:05:24 +0800 Subject: [PATCH] default mesh collider are generated by default mesh, add camera info serialization, using error info instead of assert to process missing filepath when deserializing scene, move cullface into internal renderer api, fixed dynamic vertex buffer bug --- Editor/Editor/EditorLayer.cpp | 12 +- Editor/Editor/EditorLayer.h | 2 +- Editor/assets/scenes/FPSDemo.scene | 17 +- ExampleApp/Src/FPSPlayer.cs | 10 +- Prism-ScriptCore/Src/Prism/Entity.cs | 48 ++- Prism-ScriptCore/Src/Prism/Math/Transform.cs | 6 +- Prism-ScriptCore/Src/Prism/Math/Vec2.cs | 24 ++ Prism-ScriptCore/Src/Prism/Math/Vec3.cs | 18 +- Prism-ScriptCore/Src/Prism/Scene/Component.cs | 61 ++-- Prism/src/Prism/Editor/SceneHierachyPanel.cpp | 86 +++-- Prism/src/Prism/Editor/SceneHierachyPanel.h | 3 + Prism/src/Prism/Physics/PhysicsActor.cpp | 21 +- Prism/src/Prism/Physics/PhysicsActor.h | 8 +- Prism/src/Prism/Physics/PhysicsUtils.cpp | 5 + Prism/src/Prism/Physics/PhysicsUtils.h | 1 + Prism/src/Prism/Physics/PhysicsWrappers.cpp | 296 ++++++++---------- Prism/src/Prism/Physics/PhysicsWrappers.h | 12 +- .../Platform/OpenGL/OpenGLRendererAPI.cpp | 7 +- .../Platform/OpenGL/OpenGLVertexBuffer.cpp | 2 +- Prism/src/Prism/Renderer/Mesh.cpp | 12 +- Prism/src/Prism/Renderer/Mesh.h | 3 +- Prism/src/Prism/Renderer/MeshFactory.cpp | 6 +- Prism/src/Prism/Renderer/Renderer.cpp | 18 +- Prism/src/Prism/Renderer/Renderer.h | 2 +- Prism/src/Prism/Renderer/RendererAPI.h | 2 +- Prism/src/Prism/Renderer/SceneRenderer.cpp | 16 +- Prism/src/Prism/Scene/Components.h | 2 +- Prism/src/Prism/Scene/Scene.cpp | 6 +- Prism/src/Prism/Scene/SceneSerializer.cpp | 136 +++++++- .../src/Prism/Script/ScriptEngineRegistry.cpp | 6 + Prism/src/Prism/Script/ScriptWrappers.cpp | 99 +++++- Prism/src/Prism/Script/ScriptWrappers.h | 6 + 32 files changed, 646 insertions(+), 307 deletions(-) diff --git a/Editor/Editor/EditorLayer.cpp b/Editor/Editor/EditorLayer.cpp index d7394e4..fb8dd41 100644 --- a/Editor/Editor/EditorLayer.cpp +++ b/Editor/Editor/EditorLayer.cpp @@ -171,7 +171,8 @@ namespace Prism m_SceneHierarchyPanel->SetEntityDeletedCallback(std::bind(&EditorLayer::OnEntityDeleted, this, std::placeholders::_1)); UpdateWindowTitle("untitled Scene"); - OpenScene("assets/scenes/FPSDemo.scene"); + // OpenScene("assets/scenes/FPSDemo.scene"); + NewScene(); } void EditorLayer::OnDetach() @@ -1128,15 +1129,15 @@ namespace Prism void EditorLayer::SaveSceneAs() { - auto& app = Application::Get(); - std::string filepath = app.SaveFile("Prism Scene (*.hsc)\0*.hsc\0"); + const auto& app = Application::Get(); + const std::string filepath = app.SaveFile("Prism Scene (*.hsc)\0*.hsc\0"); if (!filepath.empty()) { PM_CLIENT_INFO("Saving scene to: {0}", m_SceneFilePath); SceneSerializer serializer(m_EditorScene); serializer.Serialize(filepath); - std::filesystem::path path = filepath; + const std::filesystem::path path = filepath; UpdateWindowTitle(path.filename().string()); m_SceneFilePath = filepath; }else @@ -1174,13 +1175,14 @@ namespace Prism m_SceneHierarchyPanel->SetContext(m_EditorScene); } - float EditorLayer::GetSnapValue() + float EditorLayer::GetSnapValue() const { switch (m_GizmoType) { case ImGuizmo::OPERATION::TRANSLATE: return 0.5f; case ImGuizmo::OPERATION::ROTATE: return 45.0f; case ImGuizmo::OPERATION::SCALE: return 0.5f; + default: break; } return 0.0f; } diff --git a/Editor/Editor/EditorLayer.h b/Editor/Editor/EditorLayer.h index 984ed35..cc9a011 100644 --- a/Editor/Editor/EditorLayer.h +++ b/Editor/Editor/EditorLayer.h @@ -53,7 +53,7 @@ namespace Prism void OnScenePlay(); void OnSceneStop(); - float GetSnapValue(); + float GetSnapValue() const; private: Scope m_SceneHierarchyPanel; diff --git a/Editor/assets/scenes/FPSDemo.scene b/Editor/assets/scenes/FPSDemo.scene index 498445e..e6c3266 100644 --- a/Editor/assets/scenes/FPSDemo.scene +++ b/Editor/assets/scenes/FPSDemo.scene @@ -18,13 +18,13 @@ Entities: StoredFields: - Name: WalkingSpeed Type: 1 - Data: 20 + Data: 4 - Name: RunSpeed Type: 1 - Data: 50 + Data: 10 - Name: JumpForce Type: 1 - Data: 50 + Data: 1 - Name: MouseSensitivity Type: 1 Data: 10 @@ -147,7 +147,14 @@ Entities: Rotation: [0, 0, 0] Scale: [1, 1, 1] CameraComponent: - Camera: some camera data... + Camera: + ProjectionType: 0 + PerspectiveFOV: 65 + PerspectiveNear: 0.100000001 + PerspectiveFar: 1000 + OrthographicSize: 10 + OrthographicNear: -1 + OrthographicFar: 1 Primary: true - Entity: 18306113171518048249 TagComponent: @@ -186,7 +193,7 @@ Entities: Rotation: [0, 0, 0] Scale: [1, 1, 1] SkyLightComponent: - EnvironmentAssetPath: assets\env\birchwood_4k.hdr + EnvironmentAssetPath: assets/env/birchwood_4k.hdr Intensity: 1 Angle: 0 PhysicsLayers: diff --git a/ExampleApp/Src/FPSPlayer.cs b/ExampleApp/Src/FPSPlayer.cs index 00621e8..16f0dbf 100644 --- a/ExampleApp/Src/FPSPlayer.cs +++ b/ExampleApp/Src/FPSPlayer.cs @@ -109,7 +109,7 @@ namespace FPSExample { RaycastHit hitInfo; if (Input.IsKeyPressed(KeyCode.H) && - Physics.Raycast(m_CameraTransform.Position + (m_CameraTransform.Transform.Forward), + Physics.Raycast(m_CameraTransform.Translation + (m_CameraTransform.Transform.Forward), m_CameraTransform.Transform.Forward, 20.0f, out hitInfo)) { FindEntityByID(hitInfo.EntityID).GetComponent().Mesh.GetMaterial(0).Set("u_AlbedoColor", new Vec3(1.0f ,0.0f, 0.0f)); @@ -120,7 +120,7 @@ namespace FPSExample // NOTE: The NonAlloc version of Overlap functions should be used when possible since it doesn't allocate a new array // whenever you call it. The normal versions allocates a brand new array every time. - int numColliders = Physics.OverlapBoxNonAlloc(m_Transform.Position, new Vec3(1.0f), colliders); + int numColliders = Physics.OverlapBoxNonAlloc(m_Transform.Translation, new Vec3(1.0f), colliders); Console.WriteLine("Colliders: {0}", numColliders); // When using NonAlloc it's not safe to use a foreach loop since some of the colliders may not exist @@ -158,9 +158,9 @@ namespace FPSExample } private void UpdateCameraTransform(){ - Vec3 position = m_Transform.Position + m_CameraTransform.Transform.Forward * CameraForwardOffset; - position.Y += m_Transform.Position.Y + CameraYOffset; - m_CameraTransform.Position = position; + Vec3 position = m_Transform.Translation + m_CameraTransform.Transform.Forward * CameraForwardOffset; + position.Y += m_Transform.Translation.Y + CameraYOffset; + m_CameraTransform.Translation = position; } } } \ No newline at end of file diff --git a/Prism-ScriptCore/Src/Prism/Entity.cs b/Prism-ScriptCore/Src/Prism/Entity.cs index 84a6033..149f7b2 100644 --- a/Prism-ScriptCore/Src/Prism/Entity.cs +++ b/Prism-ScriptCore/Src/Prism/Entity.cs @@ -5,18 +5,54 @@ namespace Prism { public class Entity { + private Action? m_CollisionBeginCallbacks; + private Action? m_CollisionEndCallbacks; + private Action? m_Collision2DBeginCallbacks; + private Action? m_Collision2DEndCallbacks; + private Action? m_TriggerBeginCallbacks; + private Action? m_TriggerEndCallbacks; + public ulong ID { get; private set; } ~Entity() { } - private Action? m_CollisionBeginCallbacks; - private Action? m_CollisionEndCallbacks; - private Action? m_Collision2DBeginCallbacks; - private Action? m_Collision2DEndCallbacks; - private Action? m_TriggerBeginCallbacks; - private Action? m_TriggerEndCallbacks; + public Vec3 Translation + { + get + { + return GetComponent().Translation; + } + set + { + GetComponent().Translation = value; + } + } + + public Vec3 Rotation + { + get + { + return GetComponent().Rotation; + } + set + { + GetComponent().Rotation = value; + } + } + + public Vec3 Scale + { + get + { + return GetComponent().Scale; + } + set + { + GetComponent().Scale = value; + } + } protected Entity() { ID = 0; } diff --git a/Prism-ScriptCore/Src/Prism/Math/Transform.cs b/Prism-ScriptCore/Src/Prism/Math/Transform.cs index 8c8a834..47b9edf 100644 --- a/Prism-ScriptCore/Src/Prism/Math/Transform.cs +++ b/Prism-ScriptCore/Src/Prism/Math/Transform.cs @@ -9,8 +9,8 @@ namespace Prism public Vec3 Rotation; public Vec3 Scale; - public Vec3 Up; - public Vec3 Right; - public Vec3 Forward; + public Vec3 Up { get; } + public Vec3 Right { get; } + public Vec3 Forward { get; } } } \ No newline at end of file diff --git a/Prism-ScriptCore/Src/Prism/Math/Vec2.cs b/Prism-ScriptCore/Src/Prism/Math/Vec2.cs index c50f399..e2e5ac6 100644 --- a/Prism-ScriptCore/Src/Prism/Math/Vec2.cs +++ b/Prism-ScriptCore/Src/Prism/Math/Vec2.cs @@ -8,6 +8,8 @@ namespace Prism public float X; public float Y; + + public static Vec2 Zero = new Vec2(0.0f, 0.0f); public Vec2(float scalar) { X = Y = scalar; @@ -39,12 +41,34 @@ namespace Prism return (float)Math.Sqrt(X * X + Y * Y); } + public Vec2 SafeNormalized() + { + float length = Length(); + if (length > float.Epsilon) + { + return new Vec2(X / length, Y / length); + } + else + { + return Zero; + } + } public Vec2 Normalized() { float length = Length(); return new Vec2(X / length, Y / length); } + public void SafeNormalize() + { + float length = Length(); + if (length > float.Epsilon) + { + X = X / length; + Y = Y / length; + } + } + public void Normalize() { float length = Length(); diff --git a/Prism-ScriptCore/Src/Prism/Math/Vec3.cs b/Prism-ScriptCore/Src/Prism/Math/Vec3.cs index 71d3798..60669f3 100644 --- a/Prism-ScriptCore/Src/Prism/Math/Vec3.cs +++ b/Prism-ScriptCore/Src/Prism/Math/Vec3.cs @@ -73,15 +73,25 @@ namespace Prism public Vec3 Normalized() { float length = Length(); - return new Vec3(X / length, Y / length, Z / length); + if (length > float.Epsilon) + { + return new Vec3(X / length, Y / length, Z / length); + } + else + { + return Zero; + } } public void Normalize() { float length = Length(); - X = X / length; - Y = Y / length; - Z = Z / length; + if (length > float.Epsilon) + { + X = X / length; + Y = Y / length; + Z = Z / length; + } } diff --git a/Prism-ScriptCore/Src/Prism/Scene/Component.cs b/Prism-ScriptCore/Src/Prism/Scene/Component.cs index b90f844..297ed75 100644 --- a/Prism-ScriptCore/Src/Prism/Scene/Component.cs +++ b/Prism-ScriptCore/Src/Prism/Scene/Component.cs @@ -33,21 +33,29 @@ namespace Prism public class TransformComponent : Component { - private Transform m_Transform; - - public Transform Transform { get { return m_Transform; } } - - public Vec3 Position + public Transform Transform { get { - GetTransform_Native(Entity.ID, out m_Transform); - return m_Transform.Position; + GetTransform_Native(Entity.ID, out Transform result); + return result; } set { - m_Transform.Position = value; - SetTransform_Native(Entity.ID, ref m_Transform); + SetTransform_Native(Entity.ID, ref value); + } + } + + public Vec3 Translation + { + get + { + GetTranslation_Native(Entity.ID, out Vec3 result); + return result; + } + set + { + SetTranslation_Native(Entity.ID, ref value); } } @@ -55,13 +63,12 @@ namespace Prism { get { - GetTransform_Native(Entity.ID, out m_Transform); - return m_Transform.Rotation; + GetRotation_Native(Entity.ID, out Vec3 result); + return result; } set { - m_Transform.Rotation = value; - SetTransform_Native(Entity.ID, ref m_Transform); + SetRotation_Native(Entity.ID, ref value); } } @@ -69,22 +76,38 @@ namespace Prism { get { - GetTransform_Native(Entity.ID, out m_Transform); - return m_Transform.Scale; + GetScale_Native(Entity.ID, out Vec3 result); + return result; } set { - m_Transform.Scale = value; - SetTransform_Native(Entity.ID, ref m_Transform); + SetScale_Native(Entity.ID, ref value); } } [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void GetTransform_Native(ulong entityID, out Transform result); + internal static extern void GetTransform_Native(ulong entityID, out Transform inTransform); [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void SetTransform_Native(ulong entityID, ref Transform result); + internal static extern void SetTransform_Native(ulong entityID, ref Transform outTransform); + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void GetTranslation_Native(ulong entityID, out Vec3 outTranslation); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void SetTranslation_Native(ulong entityID, ref Vec3 inTranslation); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void GetRotation_Native(ulong entityID, out Vec3 outRotation); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void SetRotation_Native(ulong entityID, ref Vec3 inRotation); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void GetScale_Native(ulong entityID, out Vec3 outScale); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void SetScale_Native(ulong entityID, ref Vec3 inScale); } public class MeshComponent : Component diff --git a/Prism/src/Prism/Editor/SceneHierachyPanel.cpp b/Prism/src/Prism/Editor/SceneHierachyPanel.cpp index db8d122..903ea88 100644 --- a/Prism/src/Prism/Editor/SceneHierachyPanel.cpp +++ b/Prism/src/Prism/Editor/SceneHierachyPanel.cpp @@ -151,6 +151,20 @@ namespace Prism } } + template + void SceneHierarchyPanel::AddComponentPopup(const char* componentName, Function function) + { + if (!m_SelectionContext.HasComponent()) + { + if (ImGui::Button(componentName)) + { + T& component = m_SelectionContext.AddComponent(); + function(component); + ImGui::CloseCurrentPopup(); + } + } + } + void SceneHierarchyPanel::OnImGuiRender() { ImGui::Begin("Scene Hierarchy"); @@ -442,7 +456,15 @@ namespace Prism AddComponentPopup("BoxCollider"); AddComponentPopup("SphereCollider"); AddComponentPopup("CapsuleCollider"); - AddComponentPopup("MeshCollider"); + + AddComponentPopup("MeshCollider", [&](MeshColliderComponent& component) + { + if (m_SelectionContext.HasComponent()) + { + component.CollisionMesh = m_SelectionContext.GetComponent().Mesh; + PhysicsWrappers::CreateTriangleMesh(component); + } + }); ImGui::EndPopup(); @@ -890,34 +912,37 @@ namespace Prism UI::EndPropertyGrid(); }); - DrawComponent("Mesh Collider", entity, [](MeshColliderComponent& mcc) + DrawComponent("Mesh Collider", entity, [&](MeshColliderComponent& mcc) { - ImGui::Columns(3); - ImGui::SetColumnWidth(0, 100); - ImGui::SetColumnWidth(1, 250); - ImGui::SetColumnWidth(2, 40); - ImGui::Text("File Path"); - ImGui::NextColumn(); - ImGui::PushItemWidth(-1); - if (mcc.CollisionMesh) - ImGui::InputText("##meshfilepath", (char*)mcc.CollisionMesh->GetFilePath().c_str(), 256, ImGuiInputTextFlags_ReadOnly); - else - ImGui::InputText("##meshfilepath", (char*)"Null", 256, ImGuiInputTextFlags_ReadOnly); - ImGui::PopItemWidth(); - ImGui::NextColumn(); - if (ImGui::Button("...##openmesh")) + if (mcc.OverrideMesh) { - std::string file = Application::Get().OpenFile(); - if (!file.empty()) + ImGui::Columns(3); + ImGui::SetColumnWidth(0, 100); + ImGui::SetColumnWidth(1, 250); + ImGui::SetColumnWidth(2, 40); + ImGui::Text("File Path"); + ImGui::NextColumn(); + ImGui::PushItemWidth(-1); + if (mcc.CollisionMesh) + ImGui::InputText("##meshfilepath", (char*)mcc.CollisionMesh->GetFilePath().c_str(), 256, ImGuiInputTextFlags_ReadOnly); + else + ImGui::InputText("##meshfilepath", (char*)"Null", 256, ImGuiInputTextFlags_ReadOnly); + ImGui::PopItemWidth(); + ImGui::NextColumn(); + if (ImGui::Button("...##openmesh")) { - mcc.CollisionMesh = Ref::Create(file); - if (mcc.IsConvex) - PhysicsWrappers::CreateConvexMesh(mcc); - else - PhysicsWrappers::CreateTriangleMesh(mcc); + std::string file = Application::Get().OpenFile(); + if (!file.empty()) + { + mcc.CollisionMesh = Ref::Create(file); + if (mcc.IsConvex) + PhysicsWrappers::CreateConvexMesh(mcc, entity.Transform().Scale); + else + PhysicsWrappers::CreateTriangleMesh(mcc, entity.Transform().Scale); + } } + ImGui::EndColumns(); } - ImGui::EndColumns(); UI::BeginPropertyGrid(); if (UI::Property("Is Convex", mcc.IsConvex)) @@ -932,6 +957,19 @@ namespace Prism } UI::Property("Is Trigger", mcc.IsTrigger); + if (UI::Property("Override Mesh", mcc.OverrideMesh)) + { + if (!mcc.OverrideMesh && entity.HasComponent()) + { + mcc.CollisionMesh = entity.GetComponent().Mesh; + + if (mcc.IsConvex) + PhysicsWrappers::CreateConvexMesh(mcc); + else + PhysicsWrappers::CreateTriangleMesh(mcc); + } + } + UI::EndPropertyGrid(); }); diff --git a/Prism/src/Prism/Editor/SceneHierachyPanel.h b/Prism/src/Prism/Editor/SceneHierachyPanel.h index 4ab6f6d..fc56009 100644 --- a/Prism/src/Prism/Editor/SceneHierachyPanel.h +++ b/Prism/src/Prism/Editor/SceneHierachyPanel.h @@ -30,6 +30,9 @@ namespace Prism template void AddComponentPopup(const char* componentName); + + template + void AddComponentPopup(const char* componentName, Function function); private: Ref m_Context; Entity m_SelectionContext; diff --git a/Prism/src/Prism/Physics/PhysicsActor.cpp b/Prism/src/Prism/Physics/PhysicsActor.cpp index 831fef7..6ecb3bd 100644 --- a/Prism/src/Prism/Physics/PhysicsActor.cpp +++ b/Prism/src/Prism/Physics/PhysicsActor.cpp @@ -210,11 +210,11 @@ namespace Prism m_ActorInternal = actor; } - const physx::PxMaterial* physicsMat = physics.createMaterial(m_Material.StaticFriction, m_Material.DynamicFriction, m_Material.Bounciness); - if (m_Entity.HasComponent()) PhysicsWrappers::AddBoxCollider(*this, *physicsMat); - if (m_Entity.HasComponent()) PhysicsWrappers::AddSphereCollider(*this, *physicsMat); - if (m_Entity.HasComponent()) PhysicsWrappers::AddCapsuleCollider(*this, *physicsMat); - if (m_Entity.HasComponent()) PhysicsWrappers::AddMeshCollider(*this, *physicsMat); + m_MaterialInternal = physics.createMaterial(m_Material.StaticFriction, m_Material.DynamicFriction, m_Material.Bounciness); + if (m_Entity.HasComponent()) PhysicsWrappers::AddBoxCollider(*this); + if (m_Entity.HasComponent()) PhysicsWrappers::AddSphereCollider(*this); + if (m_Entity.HasComponent()) PhysicsWrappers::AddCapsuleCollider(*this); + if (m_Entity.HasComponent()) PhysicsWrappers::AddMeshCollider(*this); if (!PhysicsLayerManager::IsLayerValid(m_RigidBody.Layer)) m_RigidBody.Layer = 0; @@ -253,8 +253,14 @@ namespace Prism } } - void PhysicsActor::AddCollisionShape(physx::PxShape* shape) + void PhysicsActor::AddCollisionShape(physx::PxShape* shape) const { + const bool status = m_ActorInternal->attachShape(*shape); + shape->release(); + if (!status) + shape = nullptr; + + /* const int shapeType = shape->getGeometry().getType(); if (m_Shapes.find(shapeType) == m_Shapes.end()) @@ -263,8 +269,10 @@ namespace Prism } m_Shapes[shapeType].push_back(shape); + */ } + /* void PhysicsActor::RemoveCollisionsShapes(const int type) { if (m_Shapes.find(type) != m_Shapes.end()) @@ -276,6 +284,7 @@ namespace Prism m_Shapes.erase(type); } } + */ void PhysicsActor::SetLayer(const uint32_t layer) const { diff --git a/Prism/src/Prism/Physics/PhysicsActor.h b/Prism/src/Prism/Physics/PhysicsActor.h index 2111505..e7d83dc 100644 --- a/Prism/src/Prism/Physics/PhysicsActor.h +++ b/Prism/src/Prism/Physics/PhysicsActor.h @@ -12,6 +12,7 @@ namespace physx { class PxRigidActor; class PxShape; + class PxMaterial; } namespace Prism @@ -55,14 +56,15 @@ namespace Prism void Update(float fixedTimestep) const; void SynchronizeTransform(); - void AddCollisionShape(physx::PxShape* shape); - void RemoveCollisionsShapes(int type); + void AddCollisionShape(physx::PxShape* shape) const; + private: Entity m_Entity; RigidBodyComponent& m_RigidBody; PhysicsMaterialComponent m_Material; - physx::PxRigidActor* m_ActorInternal{}; + physx::PxRigidActor* m_ActorInternal; + physx::PxMaterial* m_MaterialInternal; friend class Physics3D; friend class PhysicsWrappers; diff --git a/Prism/src/Prism/Physics/PhysicsUtils.cpp b/Prism/src/Prism/Physics/PhysicsUtils.cpp index a198ab1..5d296ad 100644 --- a/Prism/src/Prism/Physics/PhysicsUtils.cpp +++ b/Prism/src/Prism/Physics/PhysicsUtils.cpp @@ -24,6 +24,11 @@ namespace Prism return physx::PxTransform{p, r}; } + physx::PxTransform ToPhysXTransform(const glm::vec3& translation, const glm::vec3& rotation) + { + return physx::PxTransform(ToPhysXVector(translation), ToPhysXQuat(glm::quat(rotation))); + } + physx::PxMat44 ToPhysXMatrix(const glm::mat4& matrix) { return *(physx::PxMat44*)&matrix; diff --git a/Prism/src/Prism/Physics/PhysicsUtils.h b/Prism/src/Prism/Physics/PhysicsUtils.h index 53d0d14..21556d6 100644 --- a/Prism/src/Prism/Physics/PhysicsUtils.h +++ b/Prism/src/Prism/Physics/PhysicsUtils.h @@ -16,6 +16,7 @@ namespace Prism physx::PxTransform ToPhysXTransform(const TransformComponent& transform); physx::PxTransform ToPhysXTransform(const glm::mat4& matrix); + physx::PxTransform ToPhysXTransform(const glm::vec3& translation, const glm::vec3& rotation); physx::PxMat44 ToPhysXMatrix(const glm::mat4& matrix); physx::PxVec3 ToPhysXVector(const glm::vec3& vector); physx::PxVec4 ToPhysXVector(const glm::vec4& vector); diff --git a/Prism/src/Prism/Physics/PhysicsWrappers.cpp b/Prism/src/Prism/Physics/PhysicsWrappers.cpp index 1a671fa..7d0d2ce 100644 --- a/Prism/src/Prism/Physics/PhysicsWrappers.cpp +++ b/Prism/src/Prism/Physics/PhysicsWrappers.cpp @@ -9,6 +9,7 @@ #include #include "PhysicsLayer.h" +#include "Prism/Core/Math/Math.h" #include "Prism/Script/ScriptEngine.h" #define PHYSX_DEBUGGER @@ -177,9 +178,8 @@ namespace Prism return s_Physics->createScene(sceneDesc); } - void PhysicsWrappers::AddBoxCollider(PhysicsActor& actor, const physx::PxMaterial& material) + void PhysicsWrappers::AddBoxCollider(PhysicsActor& actor) { - actor.RemoveCollisionsShapes(physx::PxGeometryType::eBOX); const auto& collider = actor.m_Entity.GetComponent(); const glm::vec3 scale = actor.m_Entity.Transform().Scale; @@ -191,20 +191,15 @@ namespace Prism const auto boxGeometry = physx::PxBoxGeometry(colliderSize.x / 2.0f, colliderSize.y / 2.0f, colliderSize.z / 2.0f); - physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor.m_ActorInternal, boxGeometry, material); - // physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, boxGeometry, material); + physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor.m_ActorInternal, boxGeometry, *actor.m_MaterialInternal); shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger); shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger); - shape->setLocalPose(ToPhysXTransform(glm::translate(glm::mat4(1.0F), collider.Offset))); - - actor.AddCollisionShape(shape); + shape->setLocalPose(ToPhysXTransform(glm::translate(glm::mat4(1.0f), collider.Offset))); } - void PhysicsWrappers::AddSphereCollider(PhysicsActor& actor, const physx::PxMaterial& material) + void PhysicsWrappers::AddSphereCollider(PhysicsActor& actor) { - actor.RemoveCollisionsShapes(physx::PxGeometryType::eSPHERE); - const auto& collider = actor.m_Entity.GetComponent(); const glm::vec3 scale = actor.m_Entity.Transform().Scale; float colliderRadius = collider.Radius; @@ -213,52 +208,43 @@ namespace Prism const auto sphereGeometry = physx::PxSphereGeometry(colliderRadius); - physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor.m_ActorInternal, sphereGeometry, material); + physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor.m_ActorInternal, sphereGeometry, *actor.m_MaterialInternal); // physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, sphereGeometry, material); shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger); shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger); - - actor.AddCollisionShape(shape); } - void PhysicsWrappers::AddCapsuleCollider(PhysicsActor& actor, const physx::PxMaterial& material) + void PhysicsWrappers::AddCapsuleCollider(PhysicsActor& actor) { - actor.RemoveCollisionsShapes(physx::PxGeometryType::eCAPSULE); - const auto& collider = actor.m_Entity.GetComponent(); const glm::vec3 scale = actor.m_Entity.Transform().Scale; float colliderRadius = collider.Radius; float colliderHeight = collider.Height; - if (scale.x != 0.0F) colliderRadius *= scale.x; - if (scale.y != 0.0F) colliderHeight *= scale.y ; + if (scale.x != 0.0f) colliderRadius *= scale.x; + if (scale.y != 0.0f) colliderHeight *= scale.y ; const auto capsuleGeometry = physx::PxCapsuleGeometry(colliderRadius, colliderHeight * 0.5f); - physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor.m_ActorInternal, capsuleGeometry, material); + physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor.m_ActorInternal, capsuleGeometry, *actor.m_MaterialInternal); shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger); shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger); - - actor.AddCollisionShape(shape); } - void PhysicsWrappers::AddMeshCollider(PhysicsActor& actor, const physx::PxMaterial& material) + void PhysicsWrappers::AddMeshCollider(PhysicsActor& actor) { auto& collider = actor.m_Entity.GetComponent(); glm::vec3 scale = actor.m_Entity.Transform().Scale; if (collider.IsConvex) { - actor.RemoveCollisionsShapes(physx::PxGeometryType::eTRIANGLEMESH); + const std::vector shapes = CreateConvexMesh(collider, scale); - const std::vector meshes = CreateConvexMesh(collider, true); - - for (const auto mesh : meshes) + for (const auto shape : shapes) { - physx::PxConvexMeshGeometry convexGeometry = physx::PxConvexMeshGeometry(mesh, physx::PxMeshScale(ToPhysXVector(scale))); - convexGeometry.meshFlags = physx::PxConvexMeshGeometryFlag::eTIGHT_BOUNDS; - physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor.m_ActorInternal, convexGeometry, material); + physx::PxMaterial* materials[] = { actor.m_MaterialInternal }; + shape->setMaterials(materials, 1); shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger); shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger); @@ -267,14 +253,13 @@ namespace Prism } else { - actor.RemoveCollisionsShapes(physx::PxGeometryType::eCONVEXMESH); + const std::vector shapes = CreateTriangleMesh(collider, scale); - const std::vector meshes = CreateTriangleMesh(collider); - - for (const auto mesh : meshes) + for (const auto shape : shapes) { - physx::PxTriangleMeshGeometry convexGeometry = physx::PxTriangleMeshGeometry(mesh, physx::PxMeshScale(ToPhysXVector(scale))); - physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor.m_ActorInternal, convexGeometry, material); + physx::PxMaterial* materials[] = { actor.m_MaterialInternal }; + shape->setMaterials(materials, 1); + shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger); shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger); @@ -283,167 +268,143 @@ namespace Prism } } - std::vector PhysicsWrappers::CreateTriangleMesh(MeshColliderComponent& collider) + std::vector PhysicsWrappers::CreateTriangleMesh(MeshColliderComponent& collider, const glm::vec3& scale) { - std::vector meshes; + std::vector shapes; - // 设置烹饪参数,可以根据需要调整 - physx::PxCookingParams cookingParams(s_Physics->getTolerancesScale()); - // 可以添加额外的烹饪参数设置,如: - // cookingParams.meshPreprocessParams = physx::PxMeshPreprocessingFlag::eWELD_VERTICES; - // cookingParams.meshWeldTolerance = 0.01f; + // 设置烹饪参数,可以根据需要调整 + physx::PxCookingParams cookingParams(s_Physics->getTolerancesScale()); + // 可以添加额外的烹饪参数设置,如: + // cookingParams.meshPreprocessParams = physx::PxMeshPreprocessingFlag::eWELD_VERTICES; + // cookingParams.meshWeldTolerance = 0.01f; - // 获取顶点和索引数据 - const std::vector& vertices = collider.CollisionMesh->GetStaticVertices(); - const std::vector& indices = collider.CollisionMesh->GetIndices(); + // 获取顶点和索引数据 + const std::vector& vertices = collider.CollisionMesh->GetStaticVertices(); + const std::vector& indices = collider.CollisionMesh->GetIndices(); - // 提取顶点位置 - std::vector vertexPositions; - if (vertices[0].Position != glm::vec3()) { - vertexPositions.reserve(vertices.size()); - for (const auto& vertex : vertices) { - vertexPositions.push_back(vertex.Position); - } - } + // 清空旧的处理网格 + collider.ProcessedMeshes.clear(); - // 清空旧的处理网格 - collider.ProcessedMeshes.clear(); + // 处理每个子网格 + for (const auto& submesh : collider.CollisionMesh->GetSubmeshes()) + { + // 准备三角形网格描述 + physx::PxTriangleMeshDesc triangleDesc; + triangleDesc.points.count = submesh.VertexCount; + triangleDesc.points.data = &vertices[submesh.BaseVertex]; + triangleDesc.points.stride = sizeof(Vertex); - // 处理每个子网格 - for (const auto& submesh : collider.CollisionMesh->GetSubmeshes()) - { - // 准备三角形网格描述 - physx::PxTriangleMeshDesc triangleDesc; - triangleDesc.points.count = submesh.VertexCount; - triangleDesc.points.stride = sizeof(glm::vec3); + triangleDesc.triangles.count = submesh.IndexCount / 3; + triangleDesc.triangles.data = &indices[submesh.BaseIndex / 3]; + triangleDesc.triangles.stride = sizeof(Index); // 假设Index包含三个值 - // 使用顶点位置数组或原始顶点数据 - if (!vertexPositions.empty()) { - triangleDesc.points.data = &vertexPositions[submesh.BaseVertex]; - } else { - triangleDesc.points.stride = sizeof(Vertex); - triangleDesc.points.data = &vertices[submesh.BaseVertex]; - } + // 如果需要,设置三角形标志 + // triangleDesc.flags = physx::PxMeshFlag::e16_BIT_INDICES; // 如果使用16位索引 - triangleDesc.triangles.count = submesh.IndexCount / 3; - triangleDesc.triangles.data = &indices[submesh.BaseIndex / 3]; - triangleDesc.triangles.stride = sizeof(Index); // 假设Index包含三个值 + // 创建三角形网格 + physx::PxTriangleMeshCookingResult::Enum result; + physx::PxTriangleMesh* triangleMesh = PxCreateTriangleMesh( + cookingParams, + triangleDesc, + *PxGetStandaloneInsertionCallback(), + &result + ); - // 如果需要,设置三角形标志 - // triangleDesc.flags = physx::PxMeshFlag::e16_BIT_INDICES; // 如果使用16位索引 - // 创建三角形网格 - physx::PxTriangleMeshCookingResult::Enum result; - physx::PxTriangleMesh* triangleMesh = PxCreateTriangleMesh( - cookingParams, - triangleDesc, - *PxGetStandaloneInsertionCallback(), - &result - ); + if (!triangleMesh) { + PM_CORE_ERROR("Failed to create triangle mesh for submesh: {0}", submesh.MeshName); + continue; + } - if (!triangleMesh) { - PM_CORE_ERROR("Failed to create triangle mesh for submesh: {0}", submesh.MeshName); - continue; - } + glm::vec3 submeshTranslation, submeshRotation, submeshScale; + Math::DecomposeTransform(submesh.LocalTransform, submeshTranslation, submeshRotation, submeshScale); - meshes.push_back(triangleMesh); + auto triangleGeometry = physx::PxTriangleMeshGeometry(triangleMesh, physx::PxMeshScale(ToPhysXVector(submeshScale * scale))); + physx::PxMaterial* material = s_Physics->createMaterial(0, 0, 0); // Dummy material, will be replaced at runtime. + physx::PxShape* shape = s_Physics->createShape(triangleGeometry, *material, true); + shape->setLocalPose(ToPhysXTransform(submeshTranslation, submeshRotation)); - // 为可视化生成渲染网格 - if (collider.ProcessedMeshes.empty()) - { - const uint32_t nbVerts = triangleMesh->getNbVertices(); - const physx::PxVec3* meshVertices = triangleMesh->getVertices(); - const uint32_t nbTriangles = triangleMesh->getNbTriangles(); + shapes.push_back(shape); - std::vector processedVertices; - std::vector processedIndices; + // 为可视化生成渲染网格 + { + const uint32_t nbVerts = triangleMesh->getNbVertices(); + const physx::PxVec3* meshVertices = triangleMesh->getVertices(); + const uint32_t nbTriangles = triangleMesh->getNbTriangles(); - // 获取顶点数据 - processedVertices.reserve(nbVerts); - for (uint32_t v = 0; v < nbVerts; v++) - { - Vertex vertex; - vertex.Position = FromPhysXVector(meshVertices[v]); - processedVertices.push_back(vertex); - } + std::vector processedVertices; + std::vector processedIndices; - // 获取三角形索引 - processedIndices.reserve(nbTriangles); + processedVertices.reserve(nbVerts); + for (uint32_t v = 0; v < nbVerts; v++) + { + Vertex vertex{}; + vertex.Position = FromPhysXVector(meshVertices[v]); + processedVertices.push_back(vertex); + } - // 检查索引格式(16位或32位) - if (triangleMesh->getTriangleMeshFlags() & physx::PxTriangleMeshFlag::e16_BIT_INDICES) - { - const physx::PxU16* tris = static_cast(triangleMesh->getTriangles()); - for (uint32_t tri = 0; tri < nbTriangles; tri++) - { - Index index; - index.V1 = tris[3 * tri + 0]; - index.V2 = tris[3 * tri + 1]; - index.V3 = tris[3 * tri + 2]; - processedIndices.push_back(index); - } - } - else - { - const physx::PxU32* tris = static_cast(triangleMesh->getTriangles()); - for (uint32_t tri = 0; tri < nbTriangles; tri++) - { - Index index; - index.V1 = static_cast(tris[3 * tri + 0]); - index.V2 = static_cast(tris[3 * tri + 1]); - index.V3 = static_cast(tris[3 * tri + 2]); - processedIndices.push_back(index); - } - } + processedIndices.reserve(nbTriangles); - // 为当前子网格创建渲染网格 - collider.ProcessedMeshes.push_back(Ref::Create(processedVertices, processedIndices)); - } - } + // 检查索引格式(16位或32位) + if (triangleMesh->getTriangleMeshFlags() & physx::PxTriangleMeshFlag::e16_BIT_INDICES) + { + const auto* tris = static_cast(triangleMesh->getTriangles()); + for (uint32_t tri = 0; tri < nbTriangles; tri++) + { + Index index{}; + index.V1 = tris[3 * tri + 0]; + index.V2 = tris[3 * tri + 1]; + index.V3 = tris[3 * tri + 2]; + processedIndices.push_back(index); + } + } + else + { + const auto* tris = static_cast(triangleMesh->getTriangles()); + for (uint32_t tri = 0; tri < nbTriangles; tri++) + { + Index index{}; + index.V1 = static_cast(tris[3 * tri + 0]); + index.V2 = static_cast(tris[3 * tri + 1]); + index.V3 = static_cast(tris[3 * tri + 2]); + processedIndices.push_back(index); + } + } - return meshes; + glm::mat4 scale = glm::scale(glm::mat4(1.0f), *(glm::vec3*)&triangleGeometry.scale.scale); + glm::mat4 transform = FromPhysXTransform(shape->getLocalPose()) * scale; + collider.ProcessedMeshes.push_back(Ref::Create(vertices, indices, transform)); + // collider.ProcessedMeshes.push_back(Ref::Create(processedVertices, processedIndices, FromPhysXTransform(shape->getLocalPose()))); + } + } + + return shapes; } - std::vector PhysicsWrappers::CreateConvexMesh(MeshColliderComponent& collider, const bool rotatedX) + std::vector PhysicsWrappers::CreateConvexMesh(MeshColliderComponent& collider, const glm::vec3& scale) { - std::vector meshes; + std::vector shapes; physx::PxCookingParams cookingParams(s_Physics->getTolerancesScale()); - cookingParams.planeTolerance = 0.0F; + // cookingParams.planeTolerance = 0.001f; // because of float accuracy, this value should not be zero, using default value now (0.0007f) cookingParams.meshPreprocessParams = physx::PxMeshPreprocessingFlags(physx::PxMeshPreprocessingFlag::eWELD_VERTICES); cookingParams.meshWeldTolerance = 0.01f; const std::vector& vertices = collider.CollisionMesh->GetStaticVertices(); const std::vector& indices = collider.CollisionMesh->GetIndices(); - // prepare vertices - std::vector position; - - if (rotatedX) - { - for (auto& vertex : vertices) - position.push_back(glm::rotate(vertex.Position, glm::radians(90.0f), { -1.0f, 0.0f, 0.0f })); - }else - { - for (auto& vertex : vertices) - position.push_back(vertex.Position); - } - - // clear old meshes collider.ProcessedMeshes.clear(); - // 处理每个子网格 + // process all submesh for (const auto& submesh : collider.CollisionMesh->GetSubmeshes()) { - // 准备凸包描述 physx::PxConvexMeshDesc convexDesc; convexDesc.points.count = submesh.VertexCount; - convexDesc.points.stride = sizeof(glm::vec3); + convexDesc.points.data = &vertices[submesh.BaseVertex]; + convexDesc.points.stride = sizeof(Vertex); - // 使用顶点位置数组或原始顶点数据 - convexDesc.points.data = &position[submesh.BaseVertex]; convexDesc.indices.count = submesh.IndexCount / 3; convexDesc.indices.data = &indices[submesh.BaseIndex / 3]; @@ -467,10 +428,15 @@ namespace Prism continue; } - meshes.push_back(convexMesh); + auto convexGeometry = physx::PxConvexMeshGeometry(convexMesh, physx::PxMeshScale(ToPhysXVector(scale))); + convexGeometry.meshFlags = physx::PxConvexMeshGeometryFlag::eTIGHT_BOUNDS; + physx::PxMaterial* material = s_Physics->createMaterial(0, 0, 0); // Dummy material, will be replaced at runtime. + physx::PxShape* shape = s_Physics->createShape(convexGeometry, *material, true); + shape->setLocalPose(ToPhysXTransform(submesh.Transform)); + + shapes.push_back(shape); // 为可视化生成渲染网格 - if (collider.ProcessedMeshes.empty()) { const uint32_t nbPolygons = convexMesh->getNbPolygons(); const physx::PxVec3* convexVertices = convexMesh->getVertices(); @@ -495,8 +461,6 @@ namespace Prism vertex.Position = FromPhysXVector( convexVertices[convexIndices[polygon.mIndexBase + vI]] ); - // 如果需要坐标系转换,可以在这里添加 - // vertex.Position = glm::rotate(vertex.Position, glm::radians(90.0f), {1.0f, 0.0f, 0.0f}); collisionVertices.push_back(vertex); vertCounter++; @@ -514,11 +478,11 @@ namespace Prism } } - collider.ProcessedMeshes.push_back(Ref::Create(collisionVertices, collisionIndices)); + collider.ProcessedMeshes.push_back(Ref::Create(collisionVertices, collisionIndices, FromPhysXTransform(shape->getLocalPose()))); } } - return meshes; + return shapes; #if 0 const auto& vertices = collider.CollisionMesh->GetStaticVertices(); @@ -624,7 +588,7 @@ namespace Prism physx::PxOverlapBuffer buf(s_OverlapBuffer, OVERLAP_MAX_COLLIDERS); const auto geometry = physx::PxBoxGeometry(halfSize.x, halfSize.y, halfSize.z); - const physx::PxTransform pose = ToPhysXTransform(glm::translate(glm::mat4(1.0F), origin)); + const physx::PxTransform pose = ToPhysXTransform(glm::translate(glm::mat4(1.0f), origin)); const bool result = scene->overlap(geometry, pose, buf); @@ -645,7 +609,7 @@ namespace Prism memset(s_OverlapBuffer, 0, sizeof(s_OverlapBuffer)); physx::PxOverlapBuffer buf(s_OverlapBuffer, OVERLAP_MAX_COLLIDERS); const auto geometry = physx::PxSphereGeometry(radius); - const physx::PxTransform pose = ToPhysXTransform(glm::translate(glm::mat4(1.0F), origin)); + const physx::PxTransform pose = ToPhysXTransform(glm::translate(glm::mat4(1.0f), origin)); const bool result = scene->overlap(geometry, pose, buf); @@ -666,7 +630,7 @@ namespace Prism memset(s_OverlapBuffer, 0, sizeof(s_OverlapBuffer)); physx::PxOverlapBuffer buf(s_OverlapBuffer, OVERLAP_MAX_COLLIDERS); const auto geometry = physx::PxCapsuleGeometry(radius, halfHeight); - const physx::PxTransform pose = ToPhysXTransform(glm::translate(glm::mat4(1.0F), origin)); + const physx::PxTransform pose = ToPhysXTransform(glm::translate(glm::mat4(1.0f), origin)); const bool result = scene->overlap(geometry, pose, buf); diff --git a/Prism/src/Prism/Physics/PhysicsWrappers.h b/Prism/src/Prism/Physics/PhysicsWrappers.h index fcdac39..27e74ab 100644 --- a/Prism/src/Prism/Physics/PhysicsWrappers.h +++ b/Prism/src/Prism/Physics/PhysicsWrappers.h @@ -40,10 +40,10 @@ namespace Prism // static physx::PxRigidActor* CreateActor(const RigidBodyComponent& rigidbody, const TransformComponent& transformComponent); // static void SetCollisionFilters(const physx::PxRigidActor& actor, uint32_t physicsLayer); - static void AddBoxCollider(PhysicsActor& actor, const physx::PxMaterial& material); - static void AddSphereCollider(PhysicsActor& actor, const physx::PxMaterial& material); - static void AddCapsuleCollider(PhysicsActor& actor, const physx::PxMaterial& material); - static void AddMeshCollider(PhysicsActor& actor, const physx::PxMaterial& material); + static void AddBoxCollider(PhysicsActor& actor); + static void AddSphereCollider(PhysicsActor& actor); + static void AddCapsuleCollider(PhysicsActor& actor); + static void AddMeshCollider(PhysicsActor& actor); // static void AddBoxCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const BoxColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f)); // static void AddSphereCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const SphereColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f)); @@ -51,8 +51,8 @@ namespace Prism // static void AddMeshCollider(::physx::PxRigidActor& actor, const ::physx::PxMaterial& material, ::Prism::MeshColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f)); - static std::vector CreateTriangleMesh(MeshColliderComponent& collider); - static std::vector CreateConvexMesh(MeshColliderComponent& collider, bool rotatedX = false); + static std::vector CreateTriangleMesh(MeshColliderComponent& collider, const glm::vec3& scale = glm::vec3(1.0f)); + static std::vector CreateConvexMesh(MeshColliderComponent& collider, const glm::vec3& scale = glm::vec3(1.0f)); // static physx::PxMaterial* CreateMaterial(const PhysicsMaterialComponent& material); diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLRendererAPI.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLRendererAPI.cpp index 4b77b7a..803a546 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLRendererAPI.cpp +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLRendererAPI.cpp @@ -156,7 +156,7 @@ namespace Prism glClearColor(r, g, b, a); } - void RendererAPI::DrawIndexed(uint32_t count, PrimitiveType type, bool depthTest) + void RendererAPI::DrawIndexed(uint32_t count, PrimitiveType type, bool depthTest, bool faceCulling) { if (!depthTest) glDisable(GL_DEPTH_TEST); @@ -172,6 +172,11 @@ namespace Prism break; } + if (faceCulling) + glEnable(GL_CULL_FACE); + else + glDisable(GL_CULL_FACE); + glDrawElements(glPrimitiveType, count, GL_UNSIGNED_INT, nullptr); if (!depthTest) diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.cpp index 4721f8d..df409f5 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.cpp +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.cpp @@ -57,7 +57,7 @@ namespace Prism { m_Size = size; Ref instance = this; Renderer::Submit([instance, offset]() { - glNamedBufferSubData(instance->m_RendererID, offset, instance->m_Size, instance->m_LocalData.Data); + glNamedBufferSubData(instance->m_RendererID, offset, instance->m_LocalData.Size, instance->m_LocalData.Data); }); } diff --git a/Prism/src/Prism/Renderer/Mesh.cpp b/Prism/src/Prism/Renderer/Mesh.cpp index 9803ff4..079c206 100644 --- a/Prism/src/Prism/Renderer/Mesh.cpp +++ b/Prism/src/Prism/Renderer/Mesh.cpp @@ -508,14 +508,14 @@ namespace Prism m_Pipeline = Pipeline::Create(pipelineSpecification); } - Mesh::Mesh(const std::vector& vertices, const std::vector& indices) - : m_StaticVertices(vertices), m_Indices(indices), m_IsAnimated(false) + Mesh::Mesh(const std::vector& vertices, const std::vector& indices, const glm::mat4& transform) + : m_StaticVertices(vertices), m_Indices(indices), m_Scene(nullptr) { Submesh submesh; submesh.BaseVertex = 0; submesh.BaseIndex = 0; submesh.IndexCount = static_cast(indices.size()) * 3; - submesh.Transform = glm::mat4(1.0F); + submesh.Transform = transform; m_Submeshes.push_back(submesh); m_VertexBuffer = VertexBuffer::Create(m_StaticVertices.data(), static_cast(m_StaticVertices.size()) * sizeof(Vertex)); @@ -640,18 +640,20 @@ namespace Prism void Mesh::TraverseNodes(const aiNode* node, const glm::mat4& parentTransform, uint32_t level) { - const glm::mat4 transform = parentTransform * Mat4FromAssimpMat4(node->mTransformation); + const glm::mat4 localTransform = parentTransform * Mat4FromAssimpMat4(node->mTransformation); + glm::mat4 transform = parentTransform * localTransform; for (uint32_t i = 0; i < node->mNumMeshes; i++) { const uint32_t mesh = node->mMeshes[i]; auto& submesh = m_Submeshes[mesh]; submesh.NodeName = node->mName.C_Str(); submesh.Transform = transform; + submesh.LocalTransform = localTransform; } for (uint32_t i = 0; i < node->mNumChildren; i++) { - TraverseNodes(node->mChildren[i], transform, level + 1); + TraverseNodes(node->mChildren[i], localTransform, level + 1); } } diff --git a/Prism/src/Prism/Renderer/Mesh.h b/Prism/src/Prism/Renderer/Mesh.h index b54ca74..649b1ab 100644 --- a/Prism/src/Prism/Renderer/Mesh.h +++ b/Prism/src/Prism/Renderer/Mesh.h @@ -97,6 +97,7 @@ namespace Prism uint32_t VertexCount; glm::mat4 Transform; + glm::mat4 LocalTransform; AABB BoundingBox; std::string NodeName, MeshName; @@ -108,7 +109,7 @@ namespace Prism Mesh(const std::string& filename); - Mesh(const std::vector& vertices, const std::vector& indices); + Mesh(const std::vector& vertices, const std::vector& indices, const glm::mat4& transform); ~Mesh(); void OnUpdate(TimeStep deltaTime); diff --git a/Prism/src/Prism/Renderer/MeshFactory.cpp b/Prism/src/Prism/Renderer/MeshFactory.cpp index dc61882..c164db4 100644 --- a/Prism/src/Prism/Renderer/MeshFactory.cpp +++ b/Prism/src/Prism/Renderer/MeshFactory.cpp @@ -45,7 +45,7 @@ namespace Prism { 6, 7, 3 } }; - return Ref::Create(vertices, indices); + return Ref::Create(vertices, indices, glm::mat4(1.0f)); } Prism::Ref MeshFactory::CreateSphere(float radius) @@ -87,7 +87,7 @@ namespace Prism } } - return Ref::Create(vertices, indices); + return Ref::Create(vertices, indices, glm::mat4(1.0f)); } Ref MeshFactory::CreateCapsule(float radius, float height) @@ -166,7 +166,7 @@ namespace Prism } } - return Ref::Create(vertices, indices); + return Ref::Create(vertices, indices, glm::mat4(1.0f)); } } \ No newline at end of file diff --git a/Prism/src/Prism/Renderer/Renderer.cpp b/Prism/src/Prism/Renderer/Renderer.cpp index 7cfabb9..22f2099 100644 --- a/Prism/src/Prism/Renderer/Renderer.cpp +++ b/Prism/src/Prism/Renderer/Renderer.cpp @@ -81,10 +81,10 @@ namespace Prism { } - void Renderer::DrawIndexed(const uint32_t count, const PrimitiveType type, const bool depthTest) + void Renderer::DrawIndexed(const uint32_t count, const PrimitiveType type, const bool depthTest, bool cullFace) { Submit([=]() { - RendererAPI::DrawIndexed(count, type, depthTest); + RendererAPI::DrawIndexed(count, type, depthTest, cullFace); }); } @@ -147,16 +147,11 @@ namespace Prism shader->SetMat4("u_Transform", transform); } - if (cullFace) - Submit([]() { glEnable(GL_CULL_FACE); }); - else - Submit([]() { glDisable(GL_CULL_FACE); }); - s_Data.m_FullscreenQuadVertexBuffer->Bind(); s_Data.m_FullscreenQuadPipeline->Bind(); s_Data.m_FullscreenQuadIndexBuffer->Bind(); - DrawIndexed(6, PrimitiveType::Triangles, depthTest); + DrawIndexed(6, PrimitiveType::Triangles, depthTest, cullFace); } void Renderer::SubmitFullscreenQuad(Ref material) @@ -170,16 +165,11 @@ namespace Prism cullFace = !material->GetFlag(MaterialFlag::TwoSided); } - if (cullFace) - Submit([]() { glEnable(GL_CULL_FACE); }); - else - Submit([]() { glDisable(GL_CULL_FACE); }); - s_Data.m_FullscreenQuadVertexBuffer->Bind(); s_Data.m_FullscreenQuadPipeline->Bind(); s_Data.m_FullscreenQuadIndexBuffer->Bind(); - Renderer::DrawIndexed(6, PrimitiveType::Triangles, depthTest); + Renderer::DrawIndexed(6, PrimitiveType::Triangles, depthTest, cullFace); } void Renderer::SubmitMesh(Ref& mesh, const glm::mat4& transform, const Ref& overrideMaterial) diff --git a/Prism/src/Prism/Renderer/Renderer.h b/Prism/src/Prism/Renderer/Renderer.h index 9cdd006..02ab038 100644 --- a/Prism/src/Prism/Renderer/Renderer.h +++ b/Prism/src/Prism/Renderer/Renderer.h @@ -25,7 +25,7 @@ namespace Prism static Ref GetShaderLibrary(); - static void DrawIndexed(uint32_t count, PrimitiveType type, bool depthTest = true); + static void DrawIndexed(uint32_t count, PrimitiveType type, bool depthTest = true, bool faceCulling = true); // For OpenGL static void SetLineThickness(float thickness); diff --git a/Prism/src/Prism/Renderer/RendererAPI.h b/Prism/src/Prism/Renderer/RendererAPI.h index f962fb5..3fbff92 100644 --- a/Prism/src/Prism/Renderer/RendererAPI.h +++ b/Prism/src/Prism/Renderer/RendererAPI.h @@ -42,7 +42,7 @@ namespace Prism static void Clear(float r, float g, float b, float a); static void SetClearColor(float r, float g, float b, float a); - static void DrawIndexed(uint32_t count,PrimitiveType type, bool depthTest = true); + static void DrawIndexed(uint32_t count,PrimitiveType type, bool depthTest = true, bool faceCulling = true); static void SetLineThickness(float thickness); static RendererAPIType Current() { return s_CurrentRendererAPI; } diff --git a/Prism/src/Prism/Renderer/SceneRenderer.cpp b/Prism/src/Prism/Renderer/SceneRenderer.cpp index f5ba7c2..30f5a73 100644 --- a/Prism/src/Prism/Renderer/SceneRenderer.cpp +++ b/Prism/src/Prism/Renderer/SceneRenderer.cpp @@ -439,8 +439,8 @@ namespace Prism // s_Data.SceneInfo.EnvironmentIrradianceMap->Bind(0); Renderer::SubmitFullscreenQuad(s_Data.SceneData.SkyboxMaterial); - const float aspectRatio = (float)s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetWidth() / (float)s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetHeight(); - float frustumSize = 2.0f * sceneCamera.Near * glm::tan(sceneCamera.FOV * 0.5f) * aspectRatio; + // const float aspectRatio = (float)s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetWidth() / (float)s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetHeight(); + // float frustumSize = 2.0f * sceneCamera.Near * glm::tan(sceneCamera.FOV * 0.5f) * aspectRatio; // Render entities for (auto& dc : s_Data.DrawList) @@ -858,6 +858,18 @@ namespace Prism glm::mat4 lightViewMatrix = glm::lookAt(frustumCenter - lightDir * -minExtents.z, frustumCenter, glm::vec3(0.0f, 0.0f, 1.0f)); glm::mat4 lightOrthoMatrix = glm::ortho(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f + s_Data.CascadeNearPlaneOffset, maxExtents.z - minExtents.z + s_Data.CascadeFarPlaneOffset); + // Offset to texel space to avoid shimmering (from https://stackoverflow.com/questions/33499053/cascaded-shadow-map-shimmering) + glm::mat4 shadowMatrix = lightOrthoMatrix * lightViewMatrix; + constexpr float ShadowMapResolution = 4096.0f; + glm::vec4 shadowOrigin = (shadowMatrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)) * ShadowMapResolution / 2.0f; + glm::vec4 roundedOrigin = glm::round(shadowOrigin); + glm::vec4 roundOffset = roundedOrigin - shadowOrigin; + roundOffset = roundOffset * 2.0f / ShadowMapResolution; + roundOffset.z = 0.0f; + roundOffset.w = 0.0f; + + lightOrthoMatrix[3] += roundOffset; + // Store split distance and matrix in cascade cascades[i].SplitDepth = (nearClip + splitDist * clipRange) * -1.0f; cascades[i].ViewProj = lightOrthoMatrix * lightViewMatrix; diff --git a/Prism/src/Prism/Scene/Components.h b/Prism/src/Prism/Scene/Components.h index 09468c5..822ba37 100644 --- a/Prism/src/Prism/Scene/Components.h +++ b/Prism/src/Prism/Scene/Components.h @@ -230,8 +230,8 @@ namespace Prism Ref CollisionMesh; std::vector> ProcessedMeshes; bool IsConvex = false; - bool IsTrigger = false; + bool OverrideMesh = false; MeshColliderComponent() = default; MeshColliderComponent(const MeshColliderComponent& other) = default; diff --git a/Prism/src/Prism/Scene/Scene.cpp b/Prism/src/Prism/Scene/Scene.cpp index bfb8378..a3ae2fe 100644 --- a/Prism/src/Prism/Scene/Scene.cpp +++ b/Prism/src/Prism/Scene/Scene.cpp @@ -339,12 +339,10 @@ namespace Prism meshComponent.Mesh->OnUpdate(ts); // TODO: Should we render (logically) - SceneRenderer::SubmitMesh(meshComponent, transformComponent.GetTransform()); - if (m_SelectedEntity == entity) - { SceneRenderer::SubmitSelectedMesh(meshComponent, transformComponent.GetTransform()); - } + else + SceneRenderer::SubmitMesh(meshComponent, transformComponent.GetTransform()); } } diff --git a/Prism/src/Prism/Scene/SceneSerializer.cpp b/Prism/src/Prism/Scene/SceneSerializer.cpp index 101a48c..08cc2e2 100644 --- a/Prism/src/Prism/Scene/SceneSerializer.cpp +++ b/Prism/src/Prism/Scene/SceneSerializer.cpp @@ -4,6 +4,8 @@ #include "SceneSerializer.h" +#include + #include "yaml-cpp/yaml.h" #include "Prism/Script/ScriptEngine.h" @@ -277,7 +279,17 @@ namespace Prism out << YAML::BeginMap; // CameraComponent const auto& cameraComponent = entity.GetComponent(); - out << YAML::Key << "Camera" << YAML::Value << "some camera data..."; + auto& camera = cameraComponent.Camera; + out << YAML::Key << "Camera" << YAML::Value; + out << YAML::BeginMap; // Camera + out << YAML::Key << "ProjectionType" << YAML::Value << static_cast(camera.GetProjectionType()); + out << YAML::Key << "PerspectiveFOV" << YAML::Value << camera.GetPerspectiveVerticalFOV(); + out << YAML::Key << "PerspectiveNear" << YAML::Value << camera.GetPerspectiveNearClip(); + out << YAML::Key << "PerspectiveFar" << YAML::Value << camera.GetPerspectiveFarClip(); + out << YAML::Key << "OrthographicSize" << YAML::Value << camera.GetOrthographicSize(); + out << YAML::Key << "OrthographicNear" << YAML::Value << camera.GetOrthographicNearClip(); + out << YAML::Key << "OrthographicFar" << YAML::Value << camera.GetOrthographicFarClip(); + out << YAML::EndMap; // Camera out << YAML::Key << "Primary" << YAML::Value << cameraComponent.Primary; out << YAML::EndMap; // CameraComponent @@ -425,9 +437,13 @@ namespace Prism out << YAML::BeginMap; // MeshColliderComponent auto meshColliderComponent = entity.GetComponent(); - out << YAML::Key << "AssetPath" << YAML::Value << meshColliderComponent.CollisionMesh->GetFilePath(); + + if (meshColliderComponent.OverrideMesh) + out << YAML::Key << "AssetPath" << YAML::Value << meshColliderComponent.CollisionMesh->GetFilePath(); + out << YAML::Key << "IsConvex" << YAML::Value << meshColliderComponent.IsConvex; out << YAML::Key << "IsTrigger" << YAML::Value << meshColliderComponent.IsTrigger; + out << YAML::Key << "OverrideMesh" << YAML::Value << meshColliderComponent.OverrideMesh; out << YAML::EndMap; // MeshColliderComponent } @@ -505,12 +521,19 @@ namespace Prism PM_CORE_ASSERT(false); } + bool CheckPath(const std::string& path) + { + return std::filesystem::exists(path); + } + bool SceneSerializer::Deserialize(const std::string& filepath) { std::ifstream stream(filepath); std::stringstream strStream; strStream << stream.rdbuf(); + std::vector missingPaths; + YAML::Node data = YAML::Load(strStream.str()); if (!data["Scene"]) return false; @@ -557,7 +580,20 @@ namespace Prism auto& transform = deserializedEntity.GetComponent(); transform.Translation = transformComponent["Position"].as(); - transform.Rotation = transformComponent["Rotation"].as(); + // transform.Rotation = transformComponent["Rotation"].as(); + + const auto& rotationNode = transformComponent["Rotation"]; + if (rotationNode.size() == 4) + { + auto rotation = transformComponent["Rotation"].as(); + transform.Rotation = glm::eulerAngles(rotation); + } + else + { + PM_CORE_ASSERT(rotationNode.size() == 3); + transform.Rotation = transformComponent["Rotation"].as(); + } + transform.Scale = transformComponent["Scale"].as(); PM_CORE_INFO("Entity Transform:"); @@ -642,7 +678,15 @@ namespace Prism const std::string meshPath = meshComponent["AssetPath"].as(); // TEMP (because script creates mesh component...) if (!deserializedEntity.HasComponent()) - deserializedEntity.AddComponent(Ref::Create(meshPath)); + { + Ref mesh; + if (!CheckPath(meshPath)) + missingPaths.emplace_back(meshPath); + else + mesh = Ref::Create(meshPath); + + deserializedEntity.AddComponent(mesh); + } PM_CORE_INFO(" Mesh Asset Path: {0}", meshPath); } @@ -661,7 +705,16 @@ namespace Prism auto& component = deserializedEntity.AddComponent(); const std::string env = skyLightComponent["EnvironmentAssetPath"].as(); if (!env.empty()) - component.SceneEnvironment = Environment::Load(env); + { + if (!CheckPath(env)) + { + missingPaths.emplace_back(env); + } + else + { + component.SceneEnvironment = Environment::Load(env); + } + } component.Intensity = skyLightComponent["Intensity"].as(); component.Angle = skyLightComponent["Angle"].as(); } @@ -669,10 +722,25 @@ namespace Prism if (auto cameraComponent = entity["CameraComponent"]) { auto& component = deserializedEntity.AddComponent(); - component.Camera = SceneCamera(); - component.Primary = cameraComponent["Primary"].as(); + const auto& cameraNode = cameraComponent["Camera"]; - PM_CORE_INFO(" Primary Camera: {0}", component.Primary); + auto& camera = component.Camera; + if (cameraNode["ProjectionType"]) + camera.SetProjectionType(static_cast(cameraNode["ProjectionType"].as())); + if (cameraNode["PerspectiveFOV"]) + camera.SetPerspectiveVerticalFOV(cameraNode["PerspectiveFOV"].as()); + if (cameraNode["PerspectiveNear"]) + camera.SetPerspectiveNearClip(cameraNode["PerspectiveNear"].as()); + if (cameraNode["PerspectiveFar"]) + camera.SetPerspectiveFarClip(cameraNode["PerspectiveFar"].as()); + if (cameraNode["OrthographicSize"]) + camera.SetOrthographicSize(cameraNode["OrthographicSize"].as()); + if (cameraNode["OrthographicNear"]) + camera.SetOrthographicNearClip(cameraNode["OrthographicNear"].as()); + if (cameraNode["OrthographicFar"]) + camera.SetOrthographicFarClip(cameraNode["OrthographicFar"].as()); + + component.Primary = cameraComponent["Primary"].as(); } if (auto spriteRendererComponent = entity["SpriteRendererComponent"]) @@ -767,16 +835,39 @@ namespace Prism if (auto meshColliderComponent = entity["MeshColliderComponent"]) { - auto meshPath = meshColliderComponent["AssetPath"].as(); - auto& component = deserializedEntity.AddComponent(Ref::Create(meshPath)); - component.IsConvex = meshColliderComponent["IsConvex"] ? meshColliderComponent["IsConvex"].as() : false; - component.IsTrigger = meshColliderComponent["IsTrigger"] ? meshColliderComponent["IsTrigger"].as() : false; - if (component.IsConvex) - PhysicsWrappers::CreateConvexMesh(component); - else - PhysicsWrappers::CreateTriangleMesh(component); + Ref collisionMesh = deserializedEntity.HasComponent() ? deserializedEntity.GetComponent().Mesh : nullptr; + bool overrideMesh = meshColliderComponent["OverrideMesh"] ? meshColliderComponent["OverrideMesh"].as() : false; - PM_CORE_INFO(" Mesh Collider Asset Path: {0}", meshPath); + if (overrideMesh) + { + auto meshPath = meshColliderComponent["AssetPath"].as(); + if (!CheckPath(meshPath)) + { + missingPaths.emplace_back(meshPath); + } + else + { + collisionMesh = Ref::Create(meshPath); + } + collisionMesh = Ref::Create(meshPath); + } + + if (collisionMesh) + { + auto& component = deserializedEntity.AddComponent(collisionMesh); + component.IsConvex = meshColliderComponent["IsConvex"] ? meshColliderComponent["IsConvex"].as() : false; + component.IsTrigger = meshColliderComponent["IsTrigger"] ? meshColliderComponent["IsTrigger"].as() : false; + component.OverrideMesh = overrideMesh; + + if (component.IsConvex) + PhysicsWrappers::CreateConvexMesh(component, deserializedEntity.Transform().Scale); + else + PhysicsWrappers::CreateTriangleMesh(component, deserializedEntity.Transform().Scale); + } + else + { + PM_CORE_WARN("MeshColliderComponent in use without valid mesh!"); + } } } } @@ -805,6 +896,17 @@ namespace Prism } } + if (missingPaths.size()) + { + PM_CORE_ERROR("The following files could not be loaded:"); + for (auto& path : missingPaths) + { + PM_CORE_ERROR(" {0}", path); + } + + return false; + } + return true; } diff --git a/Prism/src/Prism/Script/ScriptEngineRegistry.cpp b/Prism/src/Prism/Script/ScriptEngineRegistry.cpp index 047ca62..bfc7d76 100644 --- a/Prism/src/Prism/Script/ScriptEngineRegistry.cpp +++ b/Prism/src/Prism/Script/ScriptEngineRegistry.cpp @@ -68,6 +68,12 @@ namespace Prism mono_add_internal_call("Prism.TransformComponent::GetTransform_Native", (const void*)Prism::Script::Prism_TransformComponent_GetTransform); mono_add_internal_call("Prism.TransformComponent::SetTransform_Native", (const void*)Prism::Script::Prism_TransformComponent_SetTransform); + mono_add_internal_call("Prism.TransformComponent::GetTranslation_Native", (const void*)Prism::Script::Prism_TransformComponent_GetTranslation); + mono_add_internal_call("Prism.TransformComponent::SetTranslation_Native", (const void*)Prism::Script::Prism_TransformComponent_SetTranslation); + mono_add_internal_call("Prism.TransformComponent::GetRotation_Native", (const void*)Prism::Script::Prism_TransformComponent_GetRotation); + mono_add_internal_call("Prism.TransformComponent::SetRotation_Native", (const void*)Prism::Script::Prism_TransformComponent_SetRotation); + mono_add_internal_call("Prism.TransformComponent::GetScale_Native", (const void*)Prism::Script::Prism_TransformComponent_GetScale); + mono_add_internal_call("Prism.TransformComponent::SetScale_Native", (const void*)Prism::Script::Prism_TransformComponent_SetScale); /* diff --git a/Prism/src/Prism/Script/ScriptWrappers.cpp b/Prism/src/Prism/Script/ScriptWrappers.cpp index b1aafff..6b5c239 100644 --- a/Prism/src/Prism/Script/ScriptWrappers.cpp +++ b/Prism/src/Prism/Script/ScriptWrappers.cpp @@ -311,7 +311,6 @@ namespace Prism { namespace Script { uint64_t Prism_Entity_FindEntityByTag(MonoString* tag) { - size_t a = sizeof(ScriptTransform); Ref scene = ScriptEngine::GetCurrentSceneContext(); PM_CORE_ASSERT(scene, "No active scene!"); @@ -322,6 +321,7 @@ namespace Prism { namespace Script { return 0; } + /* void Prism_TransformComponent_GetRelativeDirection(const uint64_t entityID, glm::vec3* outDirection, const glm::vec3* inAbsoluteDirection) { @@ -376,13 +376,15 @@ namespace Prism { namespace Script { PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!"); Entity entity = entityMap.at(entityID); - const auto& transform = entity.GetComponent(); + + const auto transform = entity.GetComponent(); const glm::quat rotation = glm::quat(transform.Rotation); const glm::vec3 right = glm::normalize(glm::rotate(rotation, glm::vec3(1.0f, 0.0f, 0.0f))); const glm::vec3 up = glm::normalize(glm::rotate(rotation, glm::vec3(0.0f, 1.0f, 0.0f))); const glm::vec3 forward = glm::normalize(glm::rotate(rotation, glm::vec3(0.0f, 0.0f, -1.0f))); + *outTransform = { transform.Translation, glm::degrees(transform.Rotation), transform.Scale, up, right, forward @@ -397,13 +399,104 @@ namespace Prism { namespace Script { PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!"); Entity entity = entityMap.at(entityID); - auto& transform = entity.GetComponent(); + + auto transform = entity.GetComponent(); transform.Translation = inTransform->Translation; transform.Rotation = glm::radians(inTransform->Rotation); transform.Scale = inTransform->Scale; } + /* + void Prism_TransformComponent_GetTransform(const uint64_t entityID, TransformComponent* outTransform) + { + Ref scene = ScriptEngine::GetCurrentSceneContext(); + PM_CORE_ASSERT(scene, "No active scene!"); + const auto& entityMap = scene->GetEntityMap(); + PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!"); + + Entity entity = entityMap.at(entityID); + *outTransform = entity.GetComponent(); + } + + void Prism_TransformComponent_SetTransform(const uint64_t entityID, const TransformComponent* inTransform) + { + Ref scene = ScriptEngine::GetCurrentSceneContext(); + PM_CORE_ASSERT(scene, "No active scene!"); + const auto& entityMap = scene->GetEntityMap(); + PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!"); + + Entity entity = entityMap.at(entityID); + entity.GetComponent() = *inTransform; + } + */ + + void Prism_TransformComponent_GetTranslation(const uint64_t entityID, glm::vec3* outTranslation) + { + Ref scene = ScriptEngine::GetCurrentSceneContext(); + PM_CORE_ASSERT(scene, "No active scene!"); + const auto& entityMap = scene->GetEntityMap(); + PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!"); + + Entity entity = entityMap.at(entityID); + *outTranslation = entity.GetComponent().Translation; + } + + void Prism_TransformComponent_SetTranslation(const uint64_t entityID, const glm::vec3* inTranslation) + { + Ref scene = ScriptEngine::GetCurrentSceneContext(); + PM_CORE_ASSERT(scene, "No active scene!"); + const auto& entityMap = scene->GetEntityMap(); + PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!"); + + Entity entity = entityMap.at(entityID); + entity.GetComponent().Translation = *inTranslation; + } + + void Prism_TransformComponent_GetRotation(const uint64_t entityID, glm::vec3* outRotation) + { + Ref scene = ScriptEngine::GetCurrentSceneContext(); + PM_CORE_ASSERT(scene, "No active scene!"); + const auto& entityMap = scene->GetEntityMap(); + PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!"); + + Entity entity = entityMap.at(entityID); + *outRotation = glm::degrees(entity.GetComponent().Rotation); + } + + void Prism_TransformComponent_SetRotation(const uint64_t entityID, const glm::vec3* inRotation) + { + Ref scene = ScriptEngine::GetCurrentSceneContext(); + PM_CORE_ASSERT(scene, "No active scene!"); + const auto& entityMap = scene->GetEntityMap(); + PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!"); + + Entity entity = entityMap.at(entityID); + entity.GetComponent().Rotation = glm::radians(*inRotation); + } + + void Prism_TransformComponent_GetScale(uint64_t entityID, glm::vec3* outScale) + { + Ref scene = ScriptEngine::GetCurrentSceneContext(); + PM_CORE_ASSERT(scene, "No active scene!"); + const auto& entityMap = scene->GetEntityMap(); + PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!"); + + Entity entity = entityMap.at(entityID); + *outScale = entity.GetComponent().Scale; + } + + void Prism_TransformComponent_SetScale(const uint64_t entityID, const glm::vec3* inScale) + { + Ref scene = ScriptEngine::GetCurrentSceneContext(); + PM_CORE_ASSERT(scene, "No active scene!"); + const auto& entityMap = scene->GetEntityMap(); + PM_CORE_ASSERT(entityMap.find(entityID) != entityMap.end(), "Invalid entity ID or entity doesn't exist in scene!"); + + Entity entity = entityMap.at(entityID); + entity.GetComponent().Scale = *inScale; + } + void* Prism_MeshComponent_GetMesh(const uint64_t entityID) { Ref scene = ScriptEngine::GetCurrentSceneContext(); diff --git a/Prism/src/Prism/Script/ScriptWrappers.h b/Prism/src/Prism/Script/ScriptWrappers.h index d6fef0c..e7174e8 100644 --- a/Prism/src/Prism/Script/ScriptWrappers.h +++ b/Prism/src/Prism/Script/ScriptWrappers.h @@ -59,6 +59,12 @@ namespace Prism { namespace Script { */ void Prism_TransformComponent_GetTransform(uint64_t entityID, ScriptTransform* outTransform); void Prism_TransformComponent_SetTransform(uint64_t entityID, const ScriptTransform* inTransform); + void Prism_TransformComponent_GetTranslation(uint64_t entityID, glm::vec3* outTranslation); + void Prism_TransformComponent_SetTranslation(uint64_t entityID, const glm::vec3* inTranslation); + void Prism_TransformComponent_GetRotation(uint64_t entityID, glm::vec3* outRotation); + void Prism_TransformComponent_SetRotation(uint64_t entityID, const glm::vec3* inRotation); + void Prism_TransformComponent_GetScale(uint64_t entityID, glm::vec3* outScale); + void Prism_TransformComponent_SetScale(uint64_t entityID, const glm::vec3* inScale); // 2D Physic void Prism_RigidBody2DComponent_ApplyLinearImpulse(uint64_t entityID, const glm::vec2* impulse, const glm::vec2* offset, bool wake);