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