From ce41e348f899d111f36150ef89e707223c1cbdff Mon Sep 17 00:00:00 2001 From: Atdunbg Date: Mon, 29 Dec 2025 13:44:00 +0800 Subject: [PATCH] add physX settings through the setting window for editor --- Editor/Editor/EditorLayer.cpp | 2 +- Editor/assets/scenes/FPSDemo.scene | 253 +++++++++--------- Prism-ScriptCore/Src/Prism/Scene/Component.cs | 35 +++ .../Prism/Editor/PhysicsSettingsWindow.cpp | 118 +++++++- .../src/Prism/Editor/PhysicsSettingsWindow.h | 12 +- Prism/src/Prism/Physics/Physics3D.cpp | 113 ++++++-- Prism/src/Prism/Physics/Physics3D.h | 34 ++- Prism/src/Prism/Physics/PhysicsLayer.cpp | 10 +- Prism/src/Prism/Physics/PhysicsLayer.h | 10 +- Prism/src/Prism/Physics/PhysicsUtils.cpp | 71 ----- Prism/src/Prism/Physics/PhysicsUtils.h | 10 - Prism/src/Prism/Physics/PhysicsWrappers.cpp | 99 ++++++- Prism/src/Prism/Physics/PhysicsWrappers.h | 14 +- Prism/src/Prism/Scene/Components.h | 1 + Prism/src/Prism/Scene/Scene.cpp | 7 +- .../src/Prism/Script/ScriptEngineRegistry.cpp | 6 + Prism/src/Prism/Script/ScriptWrappers.cpp | 74 ++++- Prism/src/Prism/Script/ScriptWrappers.h | 3 + 18 files changed, 605 insertions(+), 267 deletions(-) diff --git a/Editor/Editor/EditorLayer.cpp b/Editor/Editor/EditorLayer.cpp index 480a987..cc2bba7 100644 --- a/Editor/Editor/EditorLayer.cpp +++ b/Editor/Editor/EditorLayer.cpp @@ -388,7 +388,7 @@ namespace Prism } m_SceneHierarchyPanel->OnImGuiRender(); - PhysicsSettingsWindow::OnImGuiRender(&m_ShowPhysicsSettings); + PhysicsSettingsWindow::OnImGuiRender(m_ShowPhysicsSettings); ImGui::Begin("Materials"); diff --git a/Editor/assets/scenes/FPSDemo.scene b/Editor/assets/scenes/FPSDemo.scene index 0790ad7..5decd2e 100644 --- a/Editor/assets/scenes/FPSDemo.scene +++ b/Editor/assets/scenes/FPSDemo.scene @@ -6,6 +6,130 @@ Environment: Radiance: [1, 1, 1] Multiplier: 0.515 Entities: + - Entity: 18306113171518048249 + TagComponent: + Tag: Box + TransformComponent: + Position: [0, 0, 0] + Rotation: [1, 0, 0, 0] + Scale: [50, 1, 50] + MeshComponent: + AssetPath: assets/meshes/Cube1m.fbx + RigidBodyComponent: + BodyType: 0 + Mass: 1 + IsKinematic: false + Layer: 1 + Constraints: + LockPositionX: false + LockPositionY: false + LockPositionZ: false + LockRotationX: false + LockRotationY: false + LockRotationZ: false + PhysicsMaterialComponent: + StaticFriction: 1 + DynamicFriction: 1 + Bounciness: 0 + BoxColliderComponent: + Offset: [0, 0, 0] + Size: [1, 1, 1] + IsTrigger: false + - Entity: 5178862374589434728 + TagComponent: + Tag: Camera + TransformComponent: + Position: [2.808, 2.25, 0] + Rotation: [1, 0, 0, 0] + Scale: [1, 1, 1] + CameraComponent: + Camera: some camera data... + Primary: true + - Entity: 14057422478420564497 + TagComponent: + Tag: Sphere + TransformComponent: + Position: [-3.9876995, 1, -1.9669533e-06] + Rotation: [1, 0, 0, 0] + Scale: [1, 1, 1] + MeshComponent: + AssetPath: assets/meshes/Sphere1m.fbx + RigidBodyComponent: + BodyType: 1 + Mass: 1 + IsKinematic: false + Layer: 1 + Constraints: + LockPositionX: false + LockPositionY: false + LockPositionZ: false + LockRotationX: false + LockRotationY: false + LockRotationZ: false + PhysicsMaterialComponent: + StaticFriction: 0.1 + DynamicFriction: 0.1 + Bounciness: 0.1 + SphereColliderComponent: + Radius: 0.5 + IsTrigger: false + - Entity: 10169503531257462571 + TagComponent: + Tag: Box + TransformComponent: + Position: [0, 1.5, 0] + Rotation: [1, 0, 0, 0] + Scale: [2, 2, 2] + MeshComponent: + AssetPath: assets/meshes/Cube1m.fbx + RigidBodyComponent: + BodyType: 1 + Mass: 0.5 + IsKinematic: false + Layer: 1 + Constraints: + LockPositionX: false + LockPositionY: false + LockPositionZ: false + LockRotationX: false + LockRotationY: false + LockRotationZ: false + PhysicsMaterialComponent: + StaticFriction: 1 + DynamicFriction: 1 + Bounciness: 0 + BoxColliderComponent: + Offset: [0, 0, 0] + Size: [1, 1, 1] + IsTrigger: false + - Entity: 11149966982516343187 + TagComponent: + Tag: Mesh Collider + TransformComponent: + Position: [-2.6045518, 1, -0.0017139912] + Rotation: [1, 0, 0, 0] + Scale: [1, 1, 1] + MeshComponent: + AssetPath: assets/meshes/Sphere1m.fbx + RigidBodyComponent: + BodyType: 1 + Mass: 0.1 + IsKinematic: false + Layer: 1 + Constraints: + LockPositionX: false + LockPositionY: false + LockPositionZ: false + LockRotationX: false + LockRotationY: false + LockRotationZ: false + PhysicsMaterialComponent: + StaticFriction: 1 + DynamicFriction: 1 + Bounciness: 0.1 + MeshColliderComponent: + AssetPath: assets/meshes/Sphere1m.fbx + IsTrigger: false - Entity: 3247025703490125974 TagComponent: Tag: Player @@ -52,131 +176,10 @@ Entities: MeshColliderComponent: AssetPath: assets/meshes/Capsule.fbx IsTrigger: false - - Entity: 11149966982516343187 - TagComponent: - Tag: Mesh Collider - TransformComponent: - Position: [-2.6045518, 1, -0.0017139912] - Rotation: [1, 0, 0, 0] - Scale: [1, 1, 1] - MeshComponent: - AssetPath: assets/meshes/Sphere1m.fbx - RigidBodyComponent: - BodyType: 1 - Mass: 0.1 - IsKinematic: false - Layer: 1 - Constraints: - LockPositionX: false - LockPositionY: false - LockPositionZ: false - LockRotationX: false - LockRotationY: false - LockRotationZ: false - PhysicsMaterialComponent: - StaticFriction: 1 - DynamicFriction: 1 - Bounciness: 0.1 - MeshColliderComponent: - AssetPath: assets/meshes/Sphere1m.fbx - IsTrigger: false - - Entity: 10169503531257462571 - TagComponent: - Tag: Box - TransformComponent: - Position: [0, 1.5, 0] - Rotation: [1, 0, 0, 0] - Scale: [2, 2, 2] - MeshComponent: - AssetPath: assets/meshes/Cube1m.fbx - RigidBodyComponent: - BodyType: 1 - Mass: 0.5 - IsKinematic: false - Layer: 0 - Constraints: - LockPositionX: false - LockPositionY: false - LockPositionZ: false - LockRotationX: false - LockRotationY: false - LockRotationZ: false - PhysicsMaterialComponent: - StaticFriction: 1 - DynamicFriction: 1 - Bounciness: 0 - BoxColliderComponent: - Offset: [0, 0, 0] - Size: [1, 1, 1] - IsTrigger: false - - Entity: 14057422478420564497 - TagComponent: - Tag: Sphere - TransformComponent: - Position: [-3.9876995, 1, -1.9669533e-06] - Rotation: [1, 0, 0, 0] - Scale: [1, 1, 1] - MeshComponent: - AssetPath: assets/meshes/Sphere1m.fbx - RigidBodyComponent: - BodyType: 1 - Mass: 1 - IsKinematic: false - Layer: 1 - Constraints: - LockPositionX: false - LockPositionY: false - LockPositionZ: false - LockRotationX: false - LockRotationY: false - LockRotationZ: false - PhysicsMaterialComponent: - StaticFriction: 0.1 - DynamicFriction: 0.1 - Bounciness: 0.1 - SphereColliderComponent: - Radius: 0.5 - IsTrigger: false - - Entity: 5178862374589434728 - TagComponent: - Tag: Camera - TransformComponent: - Position: [2.808, 2.25, 0] - Rotation: [1, 0, 0, 0] - Scale: [1, 1, 1] - CameraComponent: - Camera: some camera data... - Primary: true - - Entity: 18306113171518048249 - TagComponent: - Tag: Box - TransformComponent: - Position: [0, 0, 0] - Rotation: [1, 0, 0, 0] - Scale: [50, 1, 50] - MeshComponent: - AssetPath: assets/meshes/Cube1m.fbx - RigidBodyComponent: - BodyType: 0 - Mass: 1 - IsKinematic: false - Layer: 0 - Constraints: - LockPositionX: false - LockPositionY: false - LockPositionZ: false - LockRotationX: false - LockRotationY: false - LockRotationZ: false - PhysicsMaterialComponent: - StaticFriction: 1 - DynamicFriction: 1 - Bounciness: 0 - BoxColliderComponent: - Offset: [0, 0, 0] - Size: [1, 1, 1] - IsTrigger: false PhysicsLayers: - Name: Default CollidesWith: - [] \ No newline at end of file + - Name: Box + - Name: Box + CollidesWith: + - Name: Default \ No newline at end of file diff --git a/Prism-ScriptCore/Src/Prism/Scene/Component.cs b/Prism-ScriptCore/Src/Prism/Scene/Component.cs index 2fdf52b..4dfbb76 100644 --- a/Prism-ScriptCore/Src/Prism/Scene/Component.cs +++ b/Prism-ScriptCore/Src/Prism/Scene/Component.cs @@ -185,6 +185,12 @@ namespace Prism public class RigidBodyComponent : Component { + public enum Type + { + Static, + Dynamic + } + public enum ForceMode { Force = 0, @@ -192,6 +198,14 @@ namespace Prism VelocityChange, Acceleration } + + public Type BodyType + { + get + { + return GetBodyType_Native(Entity.ID); + } + } public float Mass { @@ -226,6 +240,17 @@ namespace Prism SetLinearVelocity_Native(Entity.ID, ref velocity); } + public Vec3 GetAngularVelocity() + { + GetAngularVelocity_Native(Entity.ID, out Vec3 velocity); + return velocity; + } + + public void SetAngularVelocity(Vec3 velocity) + { + SetAngularVelocity_Native(Entity.ID, ref velocity); + } + public void Rotate(Vec3 rotation) { Rotate_Native(Entity.ID, ref rotation); @@ -243,6 +268,12 @@ namespace Prism internal static extern void GetLinearVelocity_Native(ulong entityID, out Vec3 velocity); [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void SetLinearVelocity_Native(ulong entityID, ref Vec3 velocity); + [MethodImpl(MethodImplOptions.InternalCall)] + + internal static extern void GetAngularVelocity_Native(ulong entityID, out Vec3 velocity); + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void SetAngularVelocity_Native(ulong entityID, ref Vec3 velocity); + [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void Rotate_Native(ulong entityID, ref Vec3 rotation); @@ -252,8 +283,12 @@ namespace Prism [MethodImpl(MethodImplOptions.InternalCall)] internal static extern float GetMass_Native(ulong entityID); + [MethodImpl(MethodImplOptions.InternalCall)] internal static extern float SetMass_Native(ulong entityID, float mass); + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern Type GetBodyType_Native(ulong entityID); + } } diff --git a/Prism/src/Prism/Editor/PhysicsSettingsWindow.cpp b/Prism/src/Prism/Editor/PhysicsSettingsWindow.cpp index e1dfe8b..ce52e54 100644 --- a/Prism/src/Prism/Editor/PhysicsSettingsWindow.cpp +++ b/Prism/src/Prism/Editor/PhysicsSettingsWindow.cpp @@ -5,6 +5,8 @@ #include "PhysicsSettingsWindow.h" #include "imgui.h" +#include "imgui_internal.h" +#include "Prism/Physics/Physics3D.h" #include "Prism/Physics/PhysicsLayer.h" namespace Prism @@ -12,23 +14,51 @@ namespace Prism static int32_t s_SelectedLayer = -1; static char s_NewLayerNameBuffer[50]; - void PhysicsSettingsWindow::OnImGuiRender(bool* show) + void PhysicsSettingsWindow::OnImGuiRender(bool& show) { - if (!(*show)) + if (!show) return; - ImGui::Begin("Physics", show); + ImGui::Begin("Physics", &show); ImGui::PushID(0); ImGui::Columns(2); + RenderWorldSettings(); + ImGui::EndColumns(); + ImGui::PopID(); + + ImGui::Separator(); + + ImGui::PushID(1); + ImGui::Columns(2); RenderLayerList(); ImGui::NextColumn(); RenderSelectedLayer(); + ImGui::EndColumns(); ImGui::PopID(); ImGui::End(); } + void PhysicsSettingsWindow::RenderWorldSettings() + { + PhysicsSettings& settings = Physics3D::GetSettings(); + + Property("Fixed Timestep (Default: 0.006)", settings.FixedTimestep, 0.001f); + Property("Gravity (Default: -9.81)", settings.Gravity.y); + + // Broadphase Type + static const char* broadphaseTypeStrings[] = { "Sweep And Prune", "Multi Box Pruning", "Automatic Box Pruning" }; + Property("Broadphase Type", broadphaseTypeStrings, 3, reinterpret_cast(&settings.BroadphaseAlgorithm)); + + if (settings.BroadphaseAlgorithm != BroadphaseType::AutomaticBoxPrune) + { + Property("World Bounds (Min)", settings.WorldBoundsMin); + Property("World Bounds (Max)", settings.WorldBoundsMax); + Property("Grid Subdivisions", settings.WorldBoundsSubdivisions, 1, 10000); + } + } + void PhysicsSettingsWindow::RenderLayerList() { if (ImGui::Button("New Layer")) @@ -104,6 +134,88 @@ namespace Prism PhysicsLayerManager::SetLayerCollision(s_SelectedLayer, layer.LayerID, shouldCollide); } } + + if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered()) + { + s_SelectedLayer = -1; + } } + bool PhysicsSettingsWindow::Property(const char* label, const char** options, const int32_t optionCount, int32_t* selected) + { + const char* current = options[*selected]; + ImGui::Text(label); + ImGui::NextColumn(); + ImGui::PushItemWidth(-1); + + bool changed = false; + + const std::string id = "##" + std::string(label); + if (ImGui::BeginCombo(id.c_str(), current)) + { + for (int i = 0; i < optionCount; i++) + { + const bool is_selected = (current == options[i]); + if (ImGui::Selectable(options[i], is_selected)) + { + current = options[i]; + *selected = i; + changed = true; + } + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + + ImGui::PopItemWidth(); + ImGui::NextColumn(); + + return changed; + } + + bool PhysicsSettingsWindow::Property(const char* label, float& value, const float min, const float max) + { + ImGui::Text(label); + ImGui::NextColumn(); + ImGui::PushItemWidth(-1); + + const std::string id = "##" + std::string(label); + const bool changed = ImGui::SliderFloat(id.c_str(), &value, min, max); + + ImGui::PopItemWidth(); + ImGui::NextColumn(); + + return changed; + } + + bool PhysicsSettingsWindow::Property(const char* label, uint32_t& value, const uint32_t min, const uint32_t max) + { + ImGui::Text(label); + ImGui::NextColumn(); + ImGui::PushItemWidth(-1); + + const std::string id = "##" + std::string(label); + const bool changed = ImGui::DragInt(id.c_str(), (int*)&value, 1.0F, min, max); + + ImGui::PopItemWidth(); + ImGui::NextColumn(); + + return changed; + } + + bool PhysicsSettingsWindow::Property(const char* label, glm::vec3& value, const float min, const float max) + { + ImGui::Text(label); + ImGui::NextColumn(); + ImGui::PushItemWidth(-1); + + const std::string id = "##" + std::string(label); + const bool changed = ImGui::DragFloat3(id.c_str(), glm::value_ptr(value), 1.0F, min, max); + + ImGui::PopItemWidth(); + ImGui::NextColumn(); + + return changed; + } } diff --git a/Prism/src/Prism/Editor/PhysicsSettingsWindow.h b/Prism/src/Prism/Editor/PhysicsSettingsWindow.h index a0d9801..de11e9e 100644 --- a/Prism/src/Prism/Editor/PhysicsSettingsWindow.h +++ b/Prism/src/Prism/Editor/PhysicsSettingsWindow.h @@ -4,15 +4,25 @@ #ifndef PHYSICSSETTINGSWINDOW_H #define PHYSICSSETTINGSWINDOW_H +#include "glm/glm.hpp" namespace Prism { class PRISM_API PhysicsSettingsWindow { public: - static void OnImGuiRender(bool* show); + static void OnImGuiRender(bool& show); + + private: + static void RenderWorldSettings(); static void RenderLayerList(); static void RenderSelectedLayer(); + + private: + static bool Property(const char* label, const char** options, int32_t optionCount, int32_t* selected); + static bool Property(const char* label, float& value, float min = -1.0f, float max = 1.0f); + static bool Property(const char* label, uint32_t& value, uint32_t min = 0.0F, uint32_t max = 1.0F); + static bool Property(const char* label, glm::vec3& value, float min = 0.0F, float max = 0.0F); }; } diff --git a/Prism/src/Prism/Physics/Physics3D.cpp b/Prism/src/Prism/Physics/Physics3D.cpp index 68ada63..30d7050 100644 --- a/Prism/src/Prism/Physics/Physics3D.cpp +++ b/Prism/src/Prism/Physics/Physics3D.cpp @@ -18,6 +18,17 @@ namespace Prism { + static physx::PxScene* s_Scene; + static std::vector s_SimulatedEntities; + static Entity* s_EntityStorageBuffer; + static uint32_t s_EntityBufferCount; + static int s_EntityStorageBufferPosition; + static float s_SimulationTime = 0.0f; + + static PhysicsSettings s_Settings; + + + static std::tuple GetTransformDecomposition(const glm::mat4& transform) { glm::vec3 scale, translation, skew; @@ -28,11 +39,6 @@ namespace Prism return { translation, orientation, scale }; } - static physx::PxScene* s_Scene; - static std::vector s_SimulatedEntities; - static Entity* s_EntityStorageBuffer; - static int s_EntityStorageBufferPosition; - void Physics3D::Init() { PhysicsWrappers::Initialize(); @@ -44,14 +50,38 @@ namespace Prism PhysicsWrappers::Shutdown(); } - void Physics3D::CreateScene(const SceneParams& params) + PhysicsSettings& Physics3D::GetSettings() { - PM_CORE_ASSERT(s_Scene == nullptr, "Scene already has a Physics Scene!"); - s_Scene = PhysicsWrappers::CreateScene(params); + return s_Settings; } - void Physics3D::CreateActor(Entity e, int entityCount) + void Physics3D::CreateScene() { + PM_CORE_ASSERT(s_Scene == nullptr, "Scene already has a Physics Scene!"); + s_Scene = PhysicsWrappers::CreateScene(); + + if (s_Settings.BroadphaseAlgorithm != BroadphaseType::AutomaticBoxPrune) + { + physx::PxBounds3* regionBounds = nullptr; + const physx::PxBounds3 globalBounds(ToPhysXVector(s_Settings.WorldBoundsMin), ToPhysXVector(s_Settings.WorldBoundsMax)); + const uint32_t regionCount = physx::PxBroadPhaseExt::createRegionsFromWorldBounds(regionBounds, globalBounds, s_Settings.WorldBoundsSubdivisions); + + if (regionBounds) + { + for (uint32_t i = 0; i < regionCount; i++) + { + physx::PxBroadPhaseRegion region; + region.mBounds = regionBounds[i]; + s_Scene->addBroadPhaseRegion(region); + } + } + } + } + + void Physics3D::CreateActor(Entity e) + { + PM_CORE_ASSERT(s_Scene); + if (!e.HasComponent()) { PM_CORE_WARN("Trying to create PhysX actor from a non-rigidbody actor!"); @@ -66,15 +96,16 @@ namespace Prism RigidBodyComponent& rigidbody = e.GetComponent(); - if (s_EntityStorageBuffer == nullptr) - s_EntityStorageBuffer = new Entity[entityCount]; - physx::PxRigidActor* actor = PhysicsWrappers::CreateActor(rigidbody, e.Transform()); - s_SimulatedEntities.push_back(e); - Entity* entityStorage = &s_EntityStorageBuffer[s_EntityStorageBufferPosition++]; + if (rigidbody.BodyType == RigidBodyComponent::Type::Dynamic) + s_SimulatedEntities.push_back(e); + + Entity* entityStorage = &s_EntityStorageBuffer[s_EntityStorageBufferPosition]; *entityStorage = e; actor->userData = (void*)entityStorage; rigidbody.RuntimeActor = actor; + rigidbody.EntityBufferIndex = s_EntityStorageBufferPosition; + s_EntityStorageBufferPosition++; const physx::PxMaterial* material = PhysicsWrappers::CreateMaterial(e.GetComponent()); @@ -117,7 +148,17 @@ namespace Prism void Physics3D::Simulate(TimeStep ts) { - s_Scene->simulate(ts); + + // TODO: Allow projects to control the fixed step amount + s_SimulationTime += ts.GetMilliseconds(); + + if (s_SimulationTime < s_Settings.FixedTimestep) + return; + + s_SimulationTime -= s_Settings.FixedTimestep; + + + s_Scene->simulate(s_Settings.FixedTimestep); s_Scene->fetchResults(true); for (Entity& e : s_SimulatedEntities) @@ -128,19 +169,14 @@ namespace Prism const auto& rb = e.GetComponent(); const auto actor = static_cast(rb.RuntimeActor); - if (rb.BodyType == RigidBodyComponent::Type::Dynamic) - { - transform = FromPhysXTransform(actor->getGlobalPose()) * glm::scale(glm::mat4(1.0f), scale); - } - else if (rb.BodyType == RigidBodyComponent::Type::Static) - { - actor->setGlobalPose(ToPhysXTransform(transform)); - } + transform = FromPhysXTransform(actor->getGlobalPose()) * glm::scale(glm::mat4(1.0F), scale); } } void Physics3D::DestroyScene() { + PM_CORE_ASSERT(s_Scene); + delete[] s_EntityStorageBuffer; s_EntityStorageBuffer = nullptr; s_EntityStorageBufferPosition = 0; @@ -173,5 +209,36 @@ namespace Prism PhysicsWrappers::DisconnectPVD(); } + void Physics3D::ExpandEntityBuffer(const uint32_t entityCount) + { + PM_CORE_ASSERT(s_Scene); + + if (s_EntityStorageBuffer != nullptr) + { + const auto temp = new Entity[s_EntityBufferCount + entityCount]; + memcpy(temp, s_EntityStorageBuffer, s_EntityBufferCount * sizeof(Entity)); + + for (uint32_t i = 0; i < s_EntityBufferCount; i++) + { + Entity& e = s_EntityStorageBuffer[i]; + const auto& rb = e.GetComponent(); + + if (rb.RuntimeActor) + { + auto* actor = static_cast(rb.RuntimeActor); + actor->userData = &temp[rb.EntityBufferIndex]; + } + } + + delete[] s_EntityStorageBuffer; + s_EntityStorageBuffer = temp; + s_EntityBufferCount += entityCount; + } + else + { + s_EntityStorageBuffer = new Entity[entityCount]; + s_EntityBufferCount = entityCount; + } + } } diff --git a/Prism/src/Prism/Physics/Physics3D.h b/Prism/src/Prism/Physics/Physics3D.h index 2b1f9b0..ec3e051 100644 --- a/Prism/src/Prism/Physics/Physics3D.h +++ b/Prism/src/Prism/Physics/Physics3D.h @@ -35,19 +35,44 @@ namespace Prism float Distance; }; - struct SceneParams + enum class BroadphaseType { - glm::vec3 Gravity = { 0.0F, -9.81F, 0.0F }; + SweepAndPrune, + MultiBoxPrune, + AutomaticBoxPrune }; + enum class FrictionType + { + Patch, + OneDirectional, + TwoDirectional + }; + + struct PhysicsSettings + { + float FixedTimestep = 0.006f; + glm::vec3 Gravity = { 0.0f, -9.81f, 0.0f }; + BroadphaseType BroadphaseAlgorithm = BroadphaseType::AutomaticBoxPrune; + + glm::vec3 WorldBoundsMin = glm::vec3(0.0f); + glm::vec3 WorldBoundsMax = glm::vec3(1.0f); + uint32_t WorldBoundsSubdivisions = 2; + // FrictionType FrictionModel = FrictionType::Patch; + }; + + class PRISM_API Physics3D { public: static void Init(); static void Shutdown(); + static PhysicsSettings& GetSettings(); - static void CreateScene(const SceneParams& params); - static void CreateActor(Entity e, int entityCount); + static void ExpandEntityBuffer(uint32_t entityCount); + + static void CreateScene(); + static void CreateActor(Entity e); static void Simulate(TimeStep ts); @@ -58,6 +83,7 @@ namespace Prism static bool ConnectPVD(); static bool IsPVDConnected(); static void DisconnectPVD(); + }; } diff --git a/Prism/src/Prism/Physics/PhysicsLayer.cpp b/Prism/src/Prism/Physics/PhysicsLayer.cpp index e10c46e..a0ad0a3 100644 --- a/Prism/src/Prism/Physics/PhysicsLayer.cpp +++ b/Prism/src/Prism/Physics/PhysicsLayer.cpp @@ -59,15 +59,15 @@ namespace Prism RemoveIfExists(s_Layers, [&](const PhysicsLayer& layer) { return layer.LayerID == layerId; }); } - void PhysicsLayerManager::SetLayerCollision(uint32_t layerId, uint32_t otherLayer, bool collides) + void PhysicsLayerManager::SetLayerCollision(const uint32_t layerId, const uint32_t otherLayer, const bool shouldCollide) { - if (ShouldCollide(layerId, otherLayer) && collides) + if (ShouldCollide(layerId, otherLayer) && shouldCollide) return; PhysicsLayer& layerInfo = GetLayer(layerId); PhysicsLayer& otherLayerInfo = GetLayer(otherLayer); - if (collides) + if (shouldCollide) { layerInfo.CollidesWith |= otherLayerInfo.BitValue; otherLayerInfo.CollidesWith |= layerInfo.BitValue; @@ -79,7 +79,7 @@ namespace Prism } } - const std::vector& PhysicsLayerManager::GetLayerCollisions(uint32_t layerId) + std::vector PhysicsLayerManager::GetLayerCollisions(const uint32_t layerId) { const PhysicsLayer& layer = GetLayer(layerId); @@ -160,7 +160,7 @@ namespace Prism lastId = layer.LayerID; } - return s_Layers.size(); + return static_cast(s_Layers.size()); } std::vector PhysicsLayerManager::s_Layers; diff --git a/Prism/src/Prism/Physics/PhysicsLayer.h b/Prism/src/Prism/Physics/PhysicsLayer.h index 04ec8ff..441f97c 100644 --- a/Prism/src/Prism/Physics/PhysicsLayer.h +++ b/Prism/src/Prism/Physics/PhysicsLayer.h @@ -23,8 +23,8 @@ namespace Prism static uint32_t AddLayer(const std::string& name, bool setCollisions = true); static void RemoveLayer(uint32_t layerId); - static void SetLayerCollision(uint32_t layerId, uint32_t otherLayer, bool collides); - static const std::vector& GetLayerCollisions(uint32_t layerId); + static void SetLayerCollision(uint32_t layerId, uint32_t otherLayer, bool shouldCollide); + static std::vector GetLayerCollisions(uint32_t layerId); static const std::vector& GetLayers() { return s_Layers; } @@ -35,14 +35,16 @@ namespace Prism static bool ShouldCollide(uint32_t layer1, uint32_t layer2); static bool IsLayerValid(uint32_t layerId); - static void ClearLayers(); - private: + static void ClearLayers(); static uint32_t GetNextLayerID(); private: static std::vector s_Layers; static PhysicsLayer s_NullLayer; + + private: + friend class SceneSerializer; }; } diff --git a/Prism/src/Prism/Physics/PhysicsUtils.cpp b/Prism/src/Prism/Physics/PhysicsUtils.cpp index a714572..0f7a5d6 100644 --- a/Prism/src/Prism/Physics/PhysicsUtils.cpp +++ b/Prism/src/Prism/Physics/PhysicsUtils.cpp @@ -85,76 +85,5 @@ namespace Prism return physx::PxFilterFlag::eSUPPRESS; } - void ContactListener::onConstraintBreak(physx::PxConstraintInfo* constraints, physx::PxU32 count) - { - PX_UNUSED(constraints); - PX_UNUSED(count); - } - - void ContactListener::onWake(physx::PxActor** actors, physx::PxU32 count) - { - for (uint32_t i = 0; i < count; i++) - { - physx::PxActor& actor = *actors[i]; - Entity& entity = *(Entity*)actor.userData; - - PM_CORE_INFO("PhysX Actor waking up: ID: {0}, Name: {1}", static_cast(entity.GetUUID()), entity.GetComponent().Tag); - } - } - - void ContactListener::onSleep(physx::PxActor** actors, physx::PxU32 count) - { - for (uint32_t i = 0; i < count; i++) - { - physx::PxActor& actor = *actors[i]; - Entity& entity = *(Entity*)actor.userData; - - PM_CORE_INFO("PhysX Actor going to sleep: ID: {0}, Name: {1}", static_cast(entity.GetUUID()), entity.GetComponent().Tag); - } - } - - void ContactListener::onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs) - { - const Entity& a = *static_cast(pairHeader.actors[0]->userData); - const Entity& b = *static_cast(pairHeader.actors[1]->userData); - - if (pairs->flags == physx::PxContactPairFlag::eACTOR_PAIR_HAS_FIRST_TOUCH) - { - if (ScriptEngine::IsEntityModuleValid(a)) ScriptEngine::OnCollisionBegin(a); - if (ScriptEngine::IsEntityModuleValid(b)) ScriptEngine::OnCollisionBegin(b); - } - else if (pairs->flags == physx::PxContactPairFlag::eACTOR_PAIR_LOST_TOUCH) - { - if (ScriptEngine::IsEntityModuleValid(a)) ScriptEngine::OnCollisionEnd(a); - if (ScriptEngine::IsEntityModuleValid(b)) ScriptEngine::OnCollisionEnd(b); - } - } - - void ContactListener::onTrigger(physx::PxTriggerPair* pairs, physx::PxU32 count) - { - - const Entity& a = *static_cast(pairs->triggerActor->userData); - const Entity& b = *static_cast(pairs->otherActor->userData); - - if (pairs->status == physx::PxPairFlag::eNOTIFY_TOUCH_FOUND) - { - if (ScriptEngine::IsEntityModuleValid(a)) ScriptEngine::OnTriggerBegin(a); - if (ScriptEngine::IsEntityModuleValid(b)) ScriptEngine::OnTriggerBegin(b); - } - else if (pairs->status == physx::PxPairFlag::eNOTIFY_TOUCH_LOST) - { - if (ScriptEngine::IsEntityModuleValid(a)) ScriptEngine::OnTriggerEnd(a); - if (ScriptEngine::IsEntityModuleValid(b)) ScriptEngine::OnTriggerEnd(b); - } - - PX_UNUSED(count); - } - - void ContactListener::onAdvance(const physx::PxRigidBody* const* bodyBuffer, const physx::PxTransform* poseBuffer, const physx::PxU32 count) - { - PX_UNUSED(bodyBuffer); - PX_UNUSED(poseBuffer); - PX_UNUSED(count); - } } diff --git a/Prism/src/Prism/Physics/PhysicsUtils.h b/Prism/src/Prism/Physics/PhysicsUtils.h index c77bd08..cc42ad5 100644 --- a/Prism/src/Prism/Physics/PhysicsUtils.h +++ b/Prism/src/Prism/Physics/PhysicsUtils.h @@ -28,16 +28,6 @@ namespace Prism physx::PxFilterFlags PrismFilterShader(physx::PxFilterObjectAttributes attributes0, physx::PxFilterData filterData0, physx::PxFilterObjectAttributes attributes1, physx::PxFilterData filterData1, physx::PxPairFlags& pairFlags, const void* constantBlock, physx::PxU32 constantBlockSize); - class ContactListener final : public physx::PxSimulationEventCallback - { - public: - virtual void onConstraintBreak(physx::PxConstraintInfo* constraints, physx::PxU32 count) override; - virtual void onWake(physx::PxActor** actors, physx::PxU32 count) override; - virtual void onSleep(physx::PxActor** actors, physx::PxU32 count) override; - virtual void onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs) override; - virtual void onTrigger(physx::PxTriggerPair* pairs, physx::PxU32 count) override; - virtual void onAdvance(const physx::PxRigidBody* const* bodyBuffer, const physx::PxTransform* poseBuffer, physx::PxU32 count) override; - }; } diff --git a/Prism/src/Prism/Physics/PhysicsWrappers.cpp b/Prism/src/Prism/Physics/PhysicsWrappers.cpp index 6b7a9cd..d27494c 100644 --- a/Prism/src/Prism/Physics/PhysicsWrappers.cpp +++ b/Prism/src/Prism/Physics/PhysicsWrappers.cpp @@ -10,6 +10,7 @@ #include #include "PhysicsLayer.h" +#include "Prism/Script/ScriptEngine.h" #define PHYSX_DEBUGGER namespace Prism @@ -68,12 +69,99 @@ namespace Prism } } + void ContactListener::onConstraintBreak(physx::PxConstraintInfo* constraints, physx::PxU32 count) + { + PX_UNUSED(constraints); + PX_UNUSED(count); + } - physx::PxScene* PhysicsWrappers::CreateScene(const SceneParams& sceneParams) + void ContactListener::onWake(physx::PxActor** actors, physx::PxU32 count) + { + for (uint32_t i = 0; i < count; i++) + { + physx::PxActor& actor = *actors[i]; + Entity& entity = *(Entity*)actor.userData; + + PM_CORE_INFO("PhysX Actor waking up: ID: {0}, Name: {1}", static_cast(entity.GetUUID()), entity.GetComponent().Tag); + } + } + + void ContactListener::onSleep(physx::PxActor** actors, physx::PxU32 count) + { + for (uint32_t i = 0; i < count; i++) + { + physx::PxActor& actor = *actors[i]; + Entity& entity = *(Entity*)actor.userData; + + PM_CORE_INFO("PhysX Actor going to sleep: ID: {0}, Name: {1}", static_cast(entity.GetUUID()), entity.GetComponent().Tag); + } + } + + void ContactListener::onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs) + { + const Entity& a = *static_cast(pairHeader.actors[0]->userData); + const Entity& b = *static_cast(pairHeader.actors[1]->userData); + + if (pairs->flags == physx::PxContactPairFlag::eACTOR_PAIR_HAS_FIRST_TOUCH) + { + if (ScriptEngine::IsEntityModuleValid(a)) ScriptEngine::OnCollisionBegin(a); + if (ScriptEngine::IsEntityModuleValid(b)) ScriptEngine::OnCollisionBegin(b); + } + else if (pairs->flags == physx::PxContactPairFlag::eACTOR_PAIR_LOST_TOUCH) + { + if (ScriptEngine::IsEntityModuleValid(a)) ScriptEngine::OnCollisionEnd(a); + if (ScriptEngine::IsEntityModuleValid(b)) ScriptEngine::OnCollisionEnd(b); + } + } + + void ContactListener::onTrigger(physx::PxTriggerPair* pairs, physx::PxU32 count) + { + + const Entity& a = *static_cast(pairs->triggerActor->userData); + const Entity& b = *static_cast(pairs->otherActor->userData); + + if (pairs->status == physx::PxPairFlag::eNOTIFY_TOUCH_FOUND) + { + if (ScriptEngine::IsEntityModuleValid(a)) ScriptEngine::OnTriggerBegin(a); + if (ScriptEngine::IsEntityModuleValid(b)) ScriptEngine::OnTriggerBegin(b); + } + else if (pairs->status == physx::PxPairFlag::eNOTIFY_TOUCH_LOST) + { + if (ScriptEngine::IsEntityModuleValid(a)) ScriptEngine::OnTriggerEnd(a); + if (ScriptEngine::IsEntityModuleValid(b)) ScriptEngine::OnTriggerEnd(b); + } + + PX_UNUSED(count); + } + + void ContactListener::onAdvance(const physx::PxRigidBody* const* bodyBuffer, const physx::PxTransform* poseBuffer, const physx::PxU32 count) + { + PX_UNUSED(bodyBuffer); + PX_UNUSED(poseBuffer); + PX_UNUSED(count); + } + + static physx::PxBroadPhaseType::Enum PrismToPhysXBroadphaseType(const BroadphaseType type) + { + switch (type) + { + case Prism::BroadphaseType::SweepAndPrune: return physx::PxBroadPhaseType::eSAP; + case Prism::BroadphaseType::MultiBoxPrune: return physx::PxBroadPhaseType::eMBP; + case Prism::BroadphaseType::AutomaticBoxPrune: return physx::PxBroadPhaseType::eABP; + } + + return physx::PxBroadPhaseType::eABP; + } + + + physx::PxScene* PhysicsWrappers::CreateScene() { physx::PxSceneDesc sceneDesc(s_Physics->getTolerancesScale()); - sceneDesc.gravity = ToPhysXVector(sceneParams.Gravity); + const PhysicsSettings& settings = Physics3D::GetSettings(); + + sceneDesc.gravity = ToPhysXVector(settings.Gravity); + sceneDesc.broadPhaseType = PrismToPhysXBroadphaseType(settings.BroadphaseAlgorithm); sceneDesc.cpuDispatcher = physx::PxDefaultCpuDispatcherCreate(1); sceneDesc.filterShader = PrismFilterShader; sceneDesc.simulationEventCallback = &s_ContactListener; @@ -378,8 +466,11 @@ namespace Prism PM_CORE_ASSERT(s_Foundation, "PxCreateFoundation Failed!"); #ifdef PHYSX_DEBUGGER - s_VisualDebugger = PxCreatePvd(*s_Foundation); - ConnectPVD(); + if (s_Foundation) + { + s_VisualDebugger = PxCreatePvd(*s_Foundation); + ConnectPVD(); + } #endif s_Physics = PxCreatePhysics(PX_PHYSICS_VERSION, *s_Foundation, physx::PxTolerancesScale(), true, s_VisualDebugger); diff --git a/Prism/src/Prism/Physics/PhysicsWrappers.h b/Prism/src/Prism/Physics/PhysicsWrappers.h index deec16b..ee1bae6 100644 --- a/Prism/src/Prism/Physics/PhysicsWrappers.h +++ b/Prism/src/Prism/Physics/PhysicsWrappers.h @@ -15,16 +15,28 @@ namespace Prism struct RaycastHit; struct SceneParams; + class PhysicsErrorCallback final : public physx::PxErrorCallback { public: void reportError(physx::PxErrorCode::Enum code, const char* message, const char* file, int line) override; }; + class ContactListener final : public physx::PxSimulationEventCallback + { + public: + virtual void onConstraintBreak(physx::PxConstraintInfo* constraints, physx::PxU32 count) override; + virtual void onWake(physx::PxActor** actors, physx::PxU32 count) override; + virtual void onSleep(physx::PxActor** actors, physx::PxU32 count) override; + virtual void onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs) override; + virtual void onTrigger(physx::PxTriggerPair* pairs, physx::PxU32 count) override; + virtual void onAdvance(const physx::PxRigidBody* const* bodyBuffer, const physx::PxTransform* poseBuffer, physx::PxU32 count) override; + }; + class PhysicsWrappers { public: - static physx::PxScene* CreateScene(const SceneParams& sceneParams); + static physx::PxScene* CreateScene(); static physx::PxRigidActor* CreateActor(const RigidBodyComponent& rigidbody, const glm::mat4& transform); static void SetCollisionFilters(const physx::PxRigidActor& actor, uint32_t physicsLayer); diff --git a/Prism/src/Prism/Scene/Components.h b/Prism/src/Prism/Scene/Components.h index bf26075..2b8166b 100644 --- a/Prism/src/Prism/Scene/Components.h +++ b/Prism/src/Prism/Scene/Components.h @@ -166,6 +166,7 @@ namespace Prism bool LockRotationZ = false; void* RuntimeActor = nullptr; + int32_t EntityBufferIndex = -1; RigidBodyComponent() = default; RigidBodyComponent(const RigidBodyComponent& other) = default; diff --git a/Prism/src/Prism/Scene/Scene.cpp b/Prism/src/Prism/Scene/Scene.cpp index 589f9fb..640b763 100644 --- a/Prism/src/Prism/Scene/Scene.cpp +++ b/Prism/src/Prism/Scene/Scene.cpp @@ -138,9 +138,7 @@ namespace Prism if (!isEditorScene) { - SceneParams sceneDesc; - sceneDesc.Gravity = glm::vec3(0.0F, -9.81F, 0.0F); - Physics3D::CreateScene(sceneDesc); + Physics3D::CreateScene(); } Init(); @@ -478,10 +476,11 @@ namespace Prism { auto view = m_Registry.view(); + Physics3D::ExpandEntityBuffer(static_cast(view.size())); for (auto entity : view) { Entity e = { entity, this }; - Physics3D::CreateActor(e, (int)view.size()); + Physics3D::CreateActor(e); } } diff --git a/Prism/src/Prism/Script/ScriptEngineRegistry.cpp b/Prism/src/Prism/Script/ScriptEngineRegistry.cpp index d9fc3a5..f0c7d56 100644 --- a/Prism/src/Prism/Script/ScriptEngineRegistry.cpp +++ b/Prism/src/Prism/Script/ScriptEngineRegistry.cpp @@ -102,10 +102,16 @@ namespace Prism mono_add_internal_call("Prism.Texture2D::Destructor_Native", (const void*)Prism::Script::Prism_Texture2D_Destructor); mono_add_internal_call("Prism.Texture2D::SetData_Native", (const void*)Prism::Script::Prism_Texture2D_SetData); + + // Physics3D + // RigidBodyComponent + mono_add_internal_call("Prism.RigidBodyComponent::GetBodyType_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_GetBodyType); mono_add_internal_call("Prism.RigidBodyComponent::AddForce_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_AddForce); mono_add_internal_call("Prism.RigidBodyComponent::AddTorque_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_AddTorque); mono_add_internal_call("Prism.RigidBodyComponent::GetLinearVelocity_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_GetLinearVelocity); mono_add_internal_call("Prism.RigidBodyComponent::SetLinearVelocity_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_SetLinearVelocity); + mono_add_internal_call("Prism.RigidBodyComponent::GetAngularVelocity_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_GetAngularVelocity); + mono_add_internal_call("Prism.RigidBodyComponent::SetAngularVelocity_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_SetAngularVelocity); mono_add_internal_call("Prism.RigidBodyComponent::Rotate_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_Rotate); mono_add_internal_call("Prism.RigidBodyComponent::GetLayer_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_GetLayer); mono_add_internal_call("Prism.RigidBodyComponent::GetMass_Native", (const void*)Prism::Script::Prism_RigidBodyComponent_GetMass); diff --git a/Prism/src/Prism/Script/ScriptWrappers.cpp b/Prism/src/Prism/Script/ScriptWrappers.cpp index 28dbb97..cfcfff0 100644 --- a/Prism/src/Prism/Script/ScriptWrappers.cpp +++ b/Prism/src/Prism/Script/ScriptWrappers.cpp @@ -100,14 +100,14 @@ namespace Prism { namespace Script { } // Helper function for the Overlap functions below - static void AddCollidersToArray(MonoArray* array, const std::array& hits, const uint32_t count) + static void AddCollidersToArray(MonoArray* array, const std::array& hits, const uint32_t count, uint32_t arrayLength) { uint32_t arrayIndex = 0; for (uint32_t i = 0; i < count; i++) { Entity& entity = *static_cast(hits[i].actor->userData); - if (entity.HasComponent()) + if (entity.HasComponent() && arrayIndex < arrayLength) { auto& boxCollider = entity.GetComponent(); @@ -123,7 +123,7 @@ namespace Prism { namespace Script { mono_array_set(array, MonoObject*, arrayIndex++, obj); } - if (entity.HasComponent()) + if (entity.HasComponent() && arrayIndex < arrayLength) { auto& sphereCollider = entity.GetComponent(); @@ -138,7 +138,7 @@ namespace Prism { namespace Script { mono_array_set(array, MonoObject*, arrayIndex++, obj); } - if (entity.HasComponent()) + if (entity.HasComponent() && arrayIndex < arrayLength) { auto& capsuleCollider = entity.GetComponent(); @@ -154,7 +154,7 @@ namespace Prism { namespace Script { mono_array_set(array, MonoObject*, arrayIndex++, obj); } - if (entity.HasComponent()) + if (entity.HasComponent() && arrayIndex < arrayLength) { auto& meshCollider = entity.GetComponent(); @@ -184,7 +184,7 @@ namespace Prism { namespace Script { if (PhysicsWrappers::OverlapBox(*origin, *halfSize, s_OverlapBuffer, &count)) { outColliders = mono_array_new(mono_domain_get(), ScriptEngine::GetCoreClass("Prism.Collider"), count); - AddCollidersToArray(outColliders, s_OverlapBuffer, count); + AddCollidersToArray(outColliders, s_OverlapBuffer, count, count); } return outColliders; @@ -199,7 +199,7 @@ namespace Prism { namespace Script { if (PhysicsWrappers::OverlapCapsule(*origin, radius, halfHeight, s_OverlapBuffer, &count)) { outColliders = mono_array_new(mono_domain_get(), ScriptEngine::GetCoreClass("Prism.Collider"), count); - AddCollidersToArray(outColliders, s_OverlapBuffer, count); + AddCollidersToArray(outColliders, s_OverlapBuffer, count, count); } return outColliders; @@ -214,7 +214,7 @@ namespace Prism { namespace Script { if (PhysicsWrappers::OverlapSphere(*origin, radius, s_OverlapBuffer, &count)) { outColliders = mono_array_new(mono_domain_get(), ScriptEngine::GetCoreClass("Prism.Collider"), count); - AddCollidersToArray(outColliders, s_OverlapBuffer, count); + AddCollidersToArray(outColliders, s_OverlapBuffer, count, count); } return outColliders; @@ -232,7 +232,7 @@ namespace Prism { namespace Script { if (count > arrayLength) count = static_cast(arrayLength); - AddCollidersToArray(outColliders, s_OverlapBuffer, count); + AddCollidersToArray(outColliders, s_OverlapBuffer, count, static_cast(arrayLength)); } return static_cast(count); @@ -250,7 +250,7 @@ namespace Prism { namespace Script { if (count > arrayLength) count = static_cast(arrayLength); - AddCollidersToArray(outColliders, s_OverlapBuffer, count); + AddCollidersToArray(outColliders, s_OverlapBuffer, count, static_cast(arrayLength)); } return static_cast(count); @@ -268,7 +268,7 @@ namespace Prism { namespace Script { if (count > arrayLength) count = static_cast(arrayLength); - AddCollidersToArray(outColliders, s_OverlapBuffer, count); + AddCollidersToArray(outColliders, s_OverlapBuffer, count, static_cast(arrayLength)); } return static_cast(count); @@ -456,6 +456,19 @@ namespace Prism { namespace Script { b2Body_SetLinearVelocity(component.RuntimeBodyID, {velocity->x, velocity->y}); } + RigidBodyComponent::Type Prism_RigidBodyComponent_GetBodyType(const uint64_t entityID) + { + 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); + PM_CORE_ASSERT(entity.HasComponent()); + const auto& component = entity.GetComponent(); + return component.BodyType; + } + void Prism_RigidBodyComponent_AddForce(const uint64_t entityID, glm::vec3* force, ForceMode forceMode) { Ref scene = ScriptEngine::GetCurrentSceneContext(); @@ -554,6 +567,45 @@ namespace Prism { namespace Script { dynamicActor->setLinearVelocity({ velocity->x, velocity->y, velocity->z }); } + void Prism_RigidBodyComponent_GetAngularVelocity(uint64_t entityID, glm::vec3* outVelocity) + { + 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); + PM_CORE_ASSERT(entity.HasComponent()); + const auto& component = entity.GetComponent(); + + const auto actor = static_cast(component.RuntimeActor); + const auto* dynamicActor = actor->is(); + PM_CORE_ASSERT(dynamicActor); + + PM_CORE_ASSERT(outVelocity); + physx::PxVec3 velocity = dynamicActor->getAngularVelocity(); + *outVelocity = { velocity.x, velocity.y, velocity.z }; + } + + void Prism_RigidBodyComponent_SetAngularVelocity(uint64_t entityID, glm::vec3* velocity) + { + 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); + PM_CORE_ASSERT(entity.HasComponent()); + const auto& component = entity.GetComponent(); + + auto* actor = static_cast(component.RuntimeActor); + auto* dynamicActor = actor->is(); + PM_CORE_ASSERT(dynamicActor); + + PM_CORE_ASSERT(velocity); + dynamicActor->setAngularVelocity({ velocity->x, velocity->y, velocity->z }); + } + void Prism_RigidBodyComponent_Rotate(uint64_t entityID, glm::vec3* rotation) { Ref scene = ScriptEngine::GetCurrentSceneContext(); diff --git a/Prism/src/Prism/Script/ScriptWrappers.h b/Prism/src/Prism/Script/ScriptWrappers.h index 4f6078f..fe56ab0 100644 --- a/Prism/src/Prism/Script/ScriptWrappers.h +++ b/Prism/src/Prism/Script/ScriptWrappers.h @@ -55,10 +55,13 @@ namespace Prism { namespace Script { void Prism_RigidBody2DComponent_SetLinearVelocity(uint64_t entityID, const glm::vec2* velocity); // 3D Physic + RigidBodyComponent::Type Prism_RigidBodyComponent_GetBodyType(uint64_t entityID); void Prism_RigidBodyComponent_AddForce(uint64_t entityID, glm::vec3* force, ForceMode forceMode); void Prism_RigidBodyComponent_AddTorque(uint64_t entityID, glm::vec3* torque, ForceMode forceMode); void Prism_RigidBodyComponent_GetLinearVelocity(uint64_t entityID, glm::vec3* outVelocity); void Prism_RigidBodyComponent_SetLinearVelocity(uint64_t entityID, glm::vec3* velocity); + void Prism_RigidBodyComponent_GetAngularVelocity(uint64_t entityID, glm::vec3* outVelocity); + void Prism_RigidBodyComponent_SetAngularVelocity(uint64_t entityID, glm::vec3* velocity); void Prism_RigidBodyComponent_Rotate(uint64_t entityID, glm::vec3* rotation); uint32_t Prism_RigidBodyComponent_GetLayer(uint64_t entityID); float Prism_RigidBodyComponent_GetMass(uint64_t entityID);