diff --git a/Editor/Editor/EditorLayer.cpp b/Editor/Editor/EditorLayer.cpp index fb28358..d7394e4 100644 --- a/Editor/Editor/EditorLayer.cpp +++ b/Editor/Editor/EditorLayer.cpp @@ -10,6 +10,7 @@ #include "glm/gtx/matrix_decompose.hpp" #include "Prism/Core/Input.h" +#include "Prism/Core/Math/Math.h" #include "Prism/Editor/PhysicsSettingsWindow.h" #include "Prism/Physics/Physics3D.h" #include "Prism/Renderer/Renderer2D.h" @@ -22,16 +23,6 @@ namespace Prism None = 0, ColorProperty = 1, SliderProperty = 2, DragProperty = 4 }; - static std::tuple GetTransformDecomposition(const glm::mat4& transform) - { - glm::vec3 scale, translation, skew; - glm::vec4 perspective; - glm::quat orientation; - glm::decompose(transform, scale, orientation, translation, skew, perspective); - - return { translation, orientation, scale }; - } - bool Property(const std::string& name, bool& value) { ImGui::Text(name.c_str()); @@ -236,13 +227,12 @@ namespace Prism if (selection.Entity.HasComponent()) { const auto& size = selection.Entity.GetComponent().Size; - auto [translation, rotationQuat, scale] = GetTransformDecomposition(selection.Entity.GetComponent().GetTransform()); - const glm::vec3 rotation = glm::eulerAngles(rotationQuat); + const auto& transform = selection.Entity.GetComponent(); Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false); const auto viewProj = m_EditorCamera.GetViewProjection(); Renderer2D::BeginScene(viewProj, false); - Renderer2D::DrawRotatedQuad({ translation.x, translation.y }, size * 2.0f, glm::degrees(rotation.z), { 1.0f, 0.0f, 1.0f, 1.0f }); + Renderer2D::DrawRotatedQuad({ transform.Translation.x, transform.Translation.y }, size * 2.0f, transform.Rotation.z, { 1.0f, 0.0f, 1.0f, 1.0f }); Renderer2D::EndScene(); Renderer::EndRenderPass(); } @@ -802,10 +792,18 @@ namespace Prism nullptr, snap ? snapValues : nullptr); - auto [translation, rotation, scale] = GetTransformDecomposition(transform); - entityTransform.Translation = translation; - entityTransform.Rotation = glm::degrees(glm::eulerAngles(rotation)); - entityTransform.Scale = scale; + if (ImGuizmo::IsUsing()) + { + glm::vec3 translation, rotation, scale; + Math::DecomposeTransform(transform, translation,rotation,scale); + + entityTransform.Translation = translation; + + glm::vec3 deltaRotation = rotation - entityTransform.Rotation; + entityTransform.Rotation += deltaRotation; + + entityTransform.Scale = scale; + } }else { glm::mat4 transformBase = entityTransform.GetTransform() * selection.Mesh->Transform; @@ -817,7 +815,10 @@ namespace Prism nullptr, snap ? snapValues : nullptr); - selection.Mesh->Transform = glm::inverse(entityTransform.GetTransform()) * transformBase; + if (ImGuizmo::IsUsing()) + { + selection.Mesh->Transform = glm::inverse(entityTransform.GetTransform()) * transformBase; + } } } diff --git a/Prism/src/Prism/Core/Math/Math.cpp b/Prism/src/Prism/Core/Math/Math.cpp new file mode 100644 index 0000000..91b6acb --- /dev/null +++ b/Prism/src/Prism/Core/Math/Math.cpp @@ -0,0 +1,88 @@ +// +// Created by Atdunbg on 2026/1/12. +// + +#include "Math.h" + +#define GLM_ENABLE_EXPERIMENTAL +#include + +#include +#include + +namespace Prism::Math +{ + + bool DecomposeTransform(const glm::mat4& transform, glm::vec3& translation, glm::vec3& rotation, glm::vec3& scale) + { + + using namespace glm; + using T = float; + + mat4 LocalMatrix(transform); + + // Normalize the matrix. + if (epsilonEqual(LocalMatrix[3][3], static_cast(0), epsilon())) + return false; + + // First, isolate perspective. This is the messiest. + if ( + epsilonNotEqual(LocalMatrix[0][3], static_cast(0), epsilon()) || + epsilonNotEqual(LocalMatrix[1][3], static_cast(0), epsilon()) || + epsilonNotEqual(LocalMatrix[2][3], static_cast(0), epsilon())) + { + // Clear the perspective partition + LocalMatrix[0][3] = LocalMatrix[1][3] = LocalMatrix[2][3] = static_cast(0); + LocalMatrix[3][3] = static_cast(1); + } + + // Next take care of translation (easy). + translation = vec3(LocalMatrix[3]); + LocalMatrix[3] = vec4(0, 0, 0, LocalMatrix[3].w); + + vec3 Row[3]; + + // Now get scale and shear. + for (length_t i = 0; i < 3; ++i) + for (length_t j = 0; j < 3; ++j) + Row[i][j] = LocalMatrix[i][j]; + + // Compute X scale factor and normalize first row. + scale.x = length(Row[0]); + Row[0] = detail::scale(Row[0], static_cast(1)); + scale.y = length(Row[1]); + Row[1] = detail::scale(Row[1], static_cast(1)); + scale.z = length(Row[2]); + Row[2] = detail::scale(Row[2], static_cast(1)); + + // At this point, the matrix (in rows[]) is orthonormal. + // Check for a coordinate system flip. If the determinant + // is -1, then negate the matrix and the scaling factors. +#if 0 + vec3 Pdum3; + + Pdum3 = cross(Row[1], Row[2]); // v3Cross(row[1], row[2], Pdum3); + if (dot(Row[0], Pdum3) < 0) + { + for (length_t i = 0; i < 3; i++) + { + scale[i] *= static_cast(-1); + Row[i] *= static_cast(-1); + } + } +#endif + + rotation.y = asin(-Row[0][2]); + if (cos(rotation.y) != 0) { + rotation.x = atan2(Row[1][2], Row[2][2]); + rotation.z = atan2(Row[0][1], Row[0][0]); + } + else { + rotation.x = atan2(-Row[2][0], Row[1][1]); + rotation.z = 0; + } + + + return true; + } +} diff --git a/Prism/src/Prism/Core/Math/Math.h b/Prism/src/Prism/Core/Math/Math.h new file mode 100644 index 0000000..8d50491 --- /dev/null +++ b/Prism/src/Prism/Core/Math/Math.h @@ -0,0 +1,16 @@ +// +// Created by Atdunbg on 2026/1/12. +// + +#ifndef PRISM_MATH_H +#define PRISM_MATH_H +#include "glm/fwd.hpp" +#include "Prism/Core/Core.h" + + +namespace Prism::Math +{ + PRISM_API bool DecomposeTransform(const glm::mat4& transform, glm::vec3& translation, glm::vec3& rotation, glm::vec3& scale); +} + +#endif //PRISM_MATH_H \ No newline at end of file diff --git a/Prism/src/Prism/Editor/SceneHierachyPanel.cpp b/Prism/src/Prism/Editor/SceneHierachyPanel.cpp index 35f50e6..db8d122 100644 --- a/Prism/src/Prism/Editor/SceneHierachyPanel.cpp +++ b/Prism/src/Prism/Editor/SceneHierachyPanel.cpp @@ -462,7 +462,11 @@ namespace Prism { DrawVec3Control("Translation", transform.Translation); - DrawVec3Control("Rotation", transform.Rotation); + + glm::vec3 rotation = glm::degrees(transform.Rotation); + if (DrawVec3Control("Rotation", rotation)) + transform.Rotation = glm::radians(rotation); + DrawVec3Control("Scale", transform.Scale, 1.0f); ImGui::TreePop(); @@ -908,9 +912,9 @@ namespace Prism { mcc.CollisionMesh = Ref::Create(file); if (mcc.IsConvex) - PhysicsWrappers::CreateConvexMesh(mcc, true); + PhysicsWrappers::CreateConvexMesh(mcc); else - PhysicsWrappers::CreateTriangleMesh(mcc, true); + PhysicsWrappers::CreateTriangleMesh(mcc); } } ImGui::EndColumns(); @@ -921,9 +925,9 @@ namespace Prism if (mcc.CollisionMesh) { if (mcc.IsConvex) - PhysicsWrappers::CreateConvexMesh(mcc, true); + PhysicsWrappers::CreateConvexMesh(mcc); else - PhysicsWrappers::CreateTriangleMesh(mcc, true); + PhysicsWrappers::CreateTriangleMesh(mcc); } } diff --git a/Prism/src/Prism/Physics/Physics3D.cpp b/Prism/src/Prism/Physics/Physics3D.cpp index 6a89590..3f5356b 100644 --- a/Prism/src/Prism/Physics/Physics3D.cpp +++ b/Prism/src/Prism/Physics/Physics3D.cpp @@ -5,8 +5,6 @@ #include "Physics3D.h" #define GLM_ENABLE_EXPERIMENTAL -#include -#include "glm/gtx/matrix_decompose.hpp" #include "Prism/Scene/Entity.h" #include "PhysicsLayer.h" @@ -17,11 +15,7 @@ namespace Prism { static physx::PxScene* s_Scene; - static std::vector> s_SimulatedActors; - static std::vector> s_StaticActors; - static Entity* s_EntityStorageBuffer; - static uint32_t s_EntityBufferCount; - static int s_EntityStorageBufferPosition; + static std::vector> s_Actors; static float s_SimulationTime = 0.0f; static PhysicsSettings s_Settings; @@ -68,41 +62,28 @@ namespace Prism } } - void Physics3D::CreateActor(Entity e) + Ref 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!"); - return; - } - - if (!e.HasComponent()) - { - PM_CORE_WARN("Trying to create PhysX actor without a PhysicsMaterialComponent!"); - return; - } - - RigidBodyComponent& rigidbody = e.GetComponent(); - - const auto transform = e.Transform(); - Ref actor = Ref::Create(e); - - if (actor->IsDynamic()) - s_SimulatedActors.push_back(actor); - else - s_StaticActors.push_back(actor); - - Entity* entityStorage = &s_EntityStorageBuffer[s_EntityStorageBufferPosition]; - *entityStorage = e; - - actor->SetRuntimeDataInternal((void *)entityStorage, s_EntityStorageBufferPosition); - s_EntityStorageBufferPosition++; + s_Actors.push_back(actor); + actor->Spawn(); + return actor; } - void Physics3D::Simulate(TimeStep ts) + Ref Physics3D::GetActorForEntity(const Entity entity) + { + for (auto& actor : s_Actors) + { + if (actor->GetEntity() == entity) + return actor; + } + + return nullptr; + } + + void Physics3D::Simulate(const TimeStep ts) { // TODO: Allow projects to control the fixed step amount @@ -113,13 +94,13 @@ namespace Prism s_SimulationTime -= s_Settings.FixedTimestep; - for (auto& actor : s_SimulatedActors) + for (auto& actor : s_Actors) actor->Update(s_Settings.FixedTimestep); s_Scene->simulate(s_Settings.FixedTimestep); s_Scene->fetchResults(true); - for (auto& actor : s_SimulatedActors) + for (auto& actor : s_Actors) actor->SynchronizeTransform(); } @@ -127,12 +108,7 @@ namespace Prism { PM_CORE_ASSERT(s_Scene); - delete[] s_EntityStorageBuffer; - s_EntityStorageBuffer = nullptr; - s_EntityStorageBufferPosition = 0; - - s_SimulatedActors.clear(); - s_StaticActors.clear(); + s_Actors.clear(); s_Scene->release(); s_Scene = nullptr; } @@ -160,6 +136,7 @@ namespace Prism PhysicsWrappers::DisconnectPVD(); } + /* void Physics3D::ExpandEntityBuffer(const uint32_t entityCount) { PM_CORE_ASSERT(s_Scene); @@ -174,11 +151,16 @@ namespace Prism Entity& e = s_EntityStorageBuffer[i]; const auto& rb = e.GetComponent(); + Ref actor = GetActorForEntity(e); + actor->SetUserData(&temp[rb.EntityBufferIndex]); + + /* if (rb.RuntimeActor) { auto* actor = static_cast(rb.RuntimeActor); actor->userData = &temp[rb.EntityBufferIndex]; } + #1# } delete[] s_EntityStorageBuffer; @@ -191,5 +173,6 @@ namespace Prism s_EntityBufferCount = entityCount; } } + */ } diff --git a/Prism/src/Prism/Physics/Physics3D.h b/Prism/src/Prism/Physics/Physics3D.h index ed06bb1..4e4b453 100644 --- a/Prism/src/Prism/Physics/Physics3D.h +++ b/Prism/src/Prism/Physics/Physics3D.h @@ -11,6 +11,8 @@ namespace Prism { + class PhysicsActor; + enum class ForceMode : uint16_t { Force = 0, @@ -70,10 +72,12 @@ namespace Prism static void Shutdown(); static PhysicsSettings& GetSettings(); - static void ExpandEntityBuffer(uint32_t entityCount); + // static void ExpandEntityBuffer(uint32_t entityCount); static void CreateScene(); - static void CreateActor(Entity e); + static Ref CreateActor(Entity e); + + static Ref GetActorForEntity(Entity entity); static void Simulate(TimeStep ts); diff --git a/Prism/src/Prism/Physics/PhysicsActor.cpp b/Prism/src/Prism/Physics/PhysicsActor.cpp index 3934481..831fef7 100644 --- a/Prism/src/Prism/Physics/PhysicsActor.cpp +++ b/Prism/src/Prism/Physics/PhysicsActor.cpp @@ -9,24 +9,179 @@ #include "PhysicsWrappers.h" #include "PxRigidActor.h" #include "Prism/Script/ScriptEngine.h" +#include namespace Prism { PhysicsActor::PhysicsActor(Entity entity) : m_Entity(entity), m_RigidBody(entity.GetComponent()) { - m_Material = entity.GetComponent(); + if (!m_Entity.HasComponent()) + { + m_Material.StaticFriction = 1.0f; + m_Material.DynamicFriction = 1.0f; + m_Material.Bounciness = 0.0f; + } + else + { + m_Material = entity.GetComponent(); + } - Create(); + Initialize(); } PhysicsActor::~PhysicsActor() { - m_ActorInternal->release(); - m_ActorInternal = nullptr; + if (m_ActorInternal && m_ActorInternal->isReleasable()) + { + m_ActorInternal->release(); + m_ActorInternal = nullptr; + } } - void PhysicsActor::Create() + glm::vec3 PhysicsActor::GetPosition() const + { + return FromPhysXVector(m_ActorInternal->getGlobalPose().p); + } + + glm::quat PhysicsActor::GetRotation() const + { + return FromPhysXQuat(m_ActorInternal->getGlobalPose().q); + } + + void PhysicsActor::Rotate(const glm::vec3& rotation) const + { + physx::PxTransform transform = m_ActorInternal->getGlobalPose(); + const auto r = glm::radians(rotation); + transform.q *= physx::PxQuat(r.x, { 1.0f, 0.0f, 0.0f }) * + physx::PxQuat(r.y, { 0.0f, 1.0f, 0.0f }) * + physx::PxQuat(r.z, { 0.0f, 0.0f, 1.0f }); + + m_ActorInternal->setGlobalPose(transform); + } + + float PhysicsActor::GetMass() const + { + if (!IsDynamic()) + { + PM_CORE_WARN("Trying to set mass of non-dynamic PhysicsActor."); + return 0.0f; + } + + const auto actor = static_cast(m_ActorInternal); + return actor->getMass(); + } + + void PhysicsActor::SetMass(const float mass) const + { + if (!IsDynamic()) + { + PM_CORE_WARN("Trying to set mass of non-dynamic PhysicsActor."); + return; + } + + const auto actor = static_cast(m_ActorInternal); + physx::PxRigidBodyExt::setMassAndUpdateInertia(*actor, mass); + m_RigidBody.Mass = mass; + } + + void PhysicsActor::AddForce(const glm::vec3& force, ForceMode forceMode) const + { + if (!IsDynamic()) + { + PM_CORE_WARN("Trying to add force to non-dynamic PhysicsActor."); + return; + } + + auto* actor = static_cast(m_ActorInternal); + actor->addForce(ToPhysXVector(force), static_cast(forceMode)); + } + + void PhysicsActor::AddTorque(const glm::vec3& torque, ForceMode forceMode) const + { + if (!IsDynamic()) + { + PM_CORE_WARN("Trying to add torque to non-dynamic PhysicsActor."); + return; + } + + const auto actor = static_cast(m_ActorInternal); + actor->addTorque(ToPhysXVector(torque), static_cast(forceMode)); + } + + glm::vec3 PhysicsActor::GetLinearVelocity() const + { + if (!IsDynamic()) + { + PM_CORE_WARN("Trying to get velocity of non-dynamic PhysicsActor."); + return glm::vec3(0.0f); + } + + const auto actor = static_cast(m_ActorInternal); + return FromPhysXVector(actor->getLinearVelocity()); + } + + void PhysicsActor::SetLinearVelocity(const glm::vec3& velocity) const + { + if (!IsDynamic()) + { + PM_CORE_WARN("Trying to set velocity of non-dynamic PhysicsActor."); + return; + } + + if (!glm::all(glm::isfinite(velocity))) + return; + + auto* actor = static_cast(m_ActorInternal); + actor->setLinearVelocity(ToPhysXVector(velocity)); + } + + glm::vec3 PhysicsActor::GetAngularVelocity() const + { + if (!IsDynamic()) + { + PM_CORE_WARN("Trying to get angular velocity of non-dynamic PhysicsActor."); + return glm::vec3(0.0f); + } + + const auto* actor = static_cast(m_ActorInternal); + return FromPhysXVector(actor->getAngularVelocity()); + } + + void PhysicsActor::SetAngularVelocity(const glm::vec3& velocity) const + { + if (!IsDynamic()) + { + PM_CORE_WARN("Trying to set angular velocity of non-dynamic PhysicsActor."); + return; + } + + if (!glm::all(glm::isfinite(velocity))) + return; + + auto* actor = static_cast(m_ActorInternal); + actor->setAngularVelocity(ToPhysXVector(velocity)); + } + + void PhysicsActor::SetLinearDrag(const float drag) const + { + if (!IsDynamic()) + return; + + auto* actor = static_cast(m_ActorInternal); + actor->setLinearDamping(drag); + } + + void PhysicsActor::SetAngularDrag(const float drag) const + { + if (!IsDynamic()) + return; + + const auto actor = static_cast(m_ActorInternal); + actor->setAngularDamping(drag); + } + + void PhysicsActor::Initialize() { physx::PxPhysics& physics = PhysicsWrappers::GetPhysics(); @@ -51,11 +206,11 @@ namespace Prism actor->setActorFlag(physx::PxActorFlag::eDISABLE_GRAVITY, m_RigidBody.DisableGravity); actor->setSolverIterationCounts(settings.SolverIterations, settings.SolverVelocityIterations); - physx::PxRigidBodyExt::updateMassAndInertia(*actor, m_RigidBody.Mass); + physx::PxRigidBodyExt::setMassAndUpdateInertia(*actor, m_RigidBody.Mass); m_ActorInternal = actor; } - physx::PxMaterial* physicsMat = physics.createMaterial(m_Material.StaticFriction, m_Material.DynamicFriction, m_Material.Bounciness); + 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); @@ -65,18 +220,15 @@ namespace Prism m_RigidBody.Layer = 0; SetLayer(m_RigidBody.Layer); + m_ActorInternal->userData = &m_Entity; + } + void PhysicsActor::Spawn() const + { static_cast(Physics3D::GetPhysicsScene())->addActor(*m_ActorInternal); } - void PhysicsActor::SetRuntimeDataInternal(void* entityStorage, int storageBufferPosition) - { - m_ActorInternal->userData = entityStorage; - m_RigidBody.RuntimeActor = m_ActorInternal; - m_RigidBody.EntityBufferIndex = storageBufferPosition; - } - - void PhysicsActor::Update(float fixedTimestep) + void PhysicsActor::Update(const float fixedTimestep) const { if (!ScriptEngine::IsEntityModuleValid(m_Entity)) return; @@ -86,14 +238,46 @@ namespace Prism void PhysicsActor::SynchronizeTransform() { - TransformComponent& transform = m_Entity.Transform(); - physx::PxRigidActor* actor = static_cast(m_RigidBody.RuntimeActor); - physx::PxTransform actorPose = actor->getGlobalPose(); - transform.Translation = FromPhysXVector(actorPose.p); - transform.Rotation = glm::eulerAngles(FromPhysXQuat(actorPose.q)); + if (IsDynamic()) + { + TransformComponent& transform = m_Entity.Transform(); + const physx::PxTransform actorPose = m_ActorInternal->getGlobalPose(); + transform.Translation = FromPhysXVector(actorPose.p); + transform.Rotation = glm::eulerAngles(FromPhysXQuat(actorPose.q)); + const auto& a = transform.Rotation; + } + else + { + // Synchronize Physics Actor with static Entity + m_ActorInternal->setGlobalPose(ToPhysXTransform(m_Entity.Transform())); + } } - void PhysicsActor::SetLayer(uint32_t layer) + void PhysicsActor::AddCollisionShape(physx::PxShape* shape) + { + const int shapeType = shape->getGeometry().getType(); + + if (m_Shapes.find(shapeType) == m_Shapes.end()) + { + m_Shapes[shapeType] = std::vector(); + } + + m_Shapes[shapeType].push_back(shape); + } + + void PhysicsActor::RemoveCollisionsShapes(const int type) + { + if (m_Shapes.find(type) != m_Shapes.end()) + { + for (const auto shape : m_Shapes[type]) + shape->release(); + + m_Shapes[type].clear(); + m_Shapes.erase(type); + } + } + + void PhysicsActor::SetLayer(const uint32_t layer) const { physx::PxAllocatorCallback& allocator = PhysicsWrappers::GetAllocator(); @@ -108,7 +292,7 @@ namespace Prism const physx::PxU32 numShapes = m_ActorInternal->getNbShapes(); - physx::PxShape** shapes = (physx::PxShape**)allocator.allocate(sizeof(physx::PxShape*) * numShapes, "", "", 0); + physx::PxShape** shapes = static_cast(allocator.allocate(sizeof(physx::PxShape*) * numShapes, "", "", 0)); m_ActorInternal->getShapes(shapes, numShapes); for (physx::PxU32 i = 0; i < numShapes; i++) diff --git a/Prism/src/Prism/Physics/PhysicsActor.h b/Prism/src/Prism/Physics/PhysicsActor.h index ce4a70e..2111505 100644 --- a/Prism/src/Prism/Physics/PhysicsActor.h +++ b/Prism/src/Prism/Physics/PhysicsActor.h @@ -4,45 +4,70 @@ #ifndef PRISM_PHYSICSACTOR_H #define PRISM_PHYSICSACTOR_H +#include "Physics3D.h" #include "Prism/Core/Ref.h" #include "Prism/Scene/Entity.h" namespace physx { class PxRigidActor; + class PxShape; } namespace Prism { - class PhysicsActor : public RefCounted + class PRISM_API PhysicsActor : public RefCounted { public: PhysicsActor(Entity entity); ~PhysicsActor(); - void Update(float fixedTimestep); - void SynchronizeTransform(); + glm::vec3 GetPosition() const; + glm::quat GetRotation() const; - void SetLayer(uint32_t layer); + void Rotate(const glm::vec3& rotation) const; + + float GetMass() const; + void SetMass(float mass) const; + + void AddForce(const glm::vec3& force, ForceMode forceMode) const; + void AddTorque(const glm::vec3& torque, ForceMode forceMode) const; + + glm::vec3 GetLinearVelocity() const; + void SetLinearVelocity(const glm::vec3& velocity) const; + glm::vec3 GetAngularVelocity() const; + void SetAngularVelocity(const glm::vec3& velocity) const; + + void SetLinearDrag(float drag) const; + void SetAngularDrag(float drag) const; + + + void SetLayer(uint32_t layer) const; bool IsDynamic() const { return m_RigidBody.BodyType == RigidBodyComponent::Type::Dynamic; } Entity& GetEntity() { return m_Entity; } private: - void Create(); + void Initialize(); + void Spawn() const; - void SetRuntimeDataInternal(void* entityStorage, int storageBufferPosition); + void Update(float fixedTimestep) const; + void SynchronizeTransform(); + void AddCollisionShape(physx::PxShape* shape); + void RemoveCollisionsShapes(int type); private: Entity m_Entity; RigidBodyComponent& m_RigidBody; PhysicsMaterialComponent m_Material; - physx::PxRigidActor* m_ActorInternal; + physx::PxRigidActor* m_ActorInternal{}; friend class Physics3D; friend class PhysicsWrappers; + + std::unordered_map> m_Shapes; }; } diff --git a/Prism/src/Prism/Physics/PhysicsWrappers.cpp b/Prism/src/Prism/Physics/PhysicsWrappers.cpp index fce4116..1a671fa 100644 --- a/Prism/src/Prism/Physics/PhysicsWrappers.cpp +++ b/Prism/src/Prism/Physics/PhysicsWrappers.cpp @@ -179,6 +179,8 @@ namespace Prism void PhysicsWrappers::AddBoxCollider(PhysicsActor& actor, const physx::PxMaterial& material) { + actor.RemoveCollisionsShapes(physx::PxGeometryType::eBOX); + const auto& collider = actor.m_Entity.GetComponent(); const glm::vec3 scale = actor.m_Entity.Transform().Scale; glm::vec3 colliderSize = collider.Size; @@ -195,10 +197,14 @@ namespace Prism shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger); shape->setLocalPose(ToPhysXTransform(glm::translate(glm::mat4(1.0F), collider.Offset))); + + actor.AddCollisionShape(shape); } void PhysicsWrappers::AddSphereCollider(PhysicsActor& actor, const physx::PxMaterial& material) { + 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; @@ -211,10 +217,14 @@ namespace Prism // 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) { + 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; @@ -230,7 +240,7 @@ namespace Prism shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger); shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger); - // shape->setLocalPose(physx::PxTransform(physx::PxQuat(physx::PxHalfPi, physx::PxVec3(0, 0, 1)))); + actor.AddCollisionShape(shape); } void PhysicsWrappers::AddMeshCollider(PhysicsActor& actor, const physx::PxMaterial& material) @@ -240,7 +250,9 @@ namespace Prism if (collider.IsConvex) { - std::vector meshes = CreateConvexMesh(collider, true); + actor.RemoveCollisionsShapes(physx::PxGeometryType::eTRIANGLEMESH); + + const std::vector meshes = CreateConvexMesh(collider, true); for (const auto mesh : meshes) { @@ -249,11 +261,15 @@ namespace Prism physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor.m_ActorInternal, convexGeometry, material); shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger); shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger); + + actor.AddCollisionShape(shape); } } else { - std::vector meshes = CreateTriangleMesh(collider, true); + actor.RemoveCollisionsShapes(physx::PxGeometryType::eCONVEXMESH); + + const std::vector meshes = CreateTriangleMesh(collider); for (const auto mesh : meshes) { @@ -261,11 +277,13 @@ namespace Prism physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor.m_ActorInternal, convexGeometry, material); shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger); shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger); + + actor.AddCollisionShape(shape); } } } - std::vector PhysicsWrappers::CreateTriangleMesh(MeshColliderComponent& collider, bool invalidateOld) + std::vector PhysicsWrappers::CreateTriangleMesh(MeshColliderComponent& collider) { std::vector meshes; @@ -279,7 +297,7 @@ namespace Prism 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()); @@ -288,10 +306,8 @@ namespace Prism } } - // 清空旧的处理网格(如果需要) - if (invalidateOld) { - collider.ProcessedMeshes.clear(); - } + // 清空旧的处理网格 + collider.ProcessedMeshes.clear(); // 处理每个子网格 for (const auto& submesh : collider.CollisionMesh->GetSubmeshes()) @@ -332,8 +348,8 @@ namespace Prism meshes.push_back(triangleMesh); - // 为可视化生成渲染网格(如果需要) - if (collider.ProcessedMeshes.empty() || invalidateOld) + // 为可视化生成渲染网格 + if (collider.ProcessedMeshes.empty()) { const uint32_t nbVerts = triangleMesh->getNbVertices(); const physx::PxVec3* meshVertices = triangleMesh->getVertices(); @@ -388,32 +404,34 @@ namespace Prism return meshes; } - std::vector PhysicsWrappers::CreateConvexMesh(MeshColliderComponent& collider, bool invalidateOld) + std::vector PhysicsWrappers::CreateConvexMesh(MeshColliderComponent& collider, const bool rotatedX) { std::vector meshes; - // 设置烹饪参数,保持与原始版本相同的配置 physx::PxCookingParams cookingParams(s_Physics->getTolerancesScale()); cookingParams.planeTolerance = 0.0F; 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(); - // 准备顶点位置数组(如果需要的话) - std::vector vertexPositions; - if (vertices[0].Position != glm::vec3()) { - vertexPositions.reserve(vertices.size()); - for (const auto& vertex : vertices) { - vertexPositions.push_back(vertex.Position); - } + // 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); } - if (invalidateOld) { - collider.ProcessedMeshes.clear(); - } + + // clear old meshes + collider.ProcessedMeshes.clear(); // 处理每个子网格 @@ -425,15 +443,14 @@ namespace Prism convexDesc.points.stride = sizeof(glm::vec3); // 使用顶点位置数组或原始顶点数据 - if (!vertexPositions.empty()) { - convexDesc.points.data = &vertexPositions[submesh.BaseVertex]; - } else { - convexDesc.points.stride = sizeof(Vertex); - convexDesc.points.data = &vertices[submesh.BaseVertex]; - } + convexDesc.points.data = &position[submesh.BaseVertex]; + + convexDesc.indices.count = submesh.IndexCount / 3; + convexDesc.indices.data = &indices[submesh.BaseIndex / 3]; + convexDesc.indices.stride = sizeof(Index); convexDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX | - physx::PxConvexFlag::eCHECK_ZERO_AREA_TRIANGLES | + // physx::PxConvexFlag::eCHECK_ZERO_AREA_TRIANGLES | physx::PxConvexFlag::eSHIFT_VERTICES; // 创建凸包网格 @@ -452,8 +469,8 @@ namespace Prism meshes.push_back(convexMesh); - // 为可视化生成渲染网格(如果需要) - if (collider.ProcessedMeshes.empty() || invalidateOld) + // 为可视化生成渲染网格 + if (collider.ProcessedMeshes.empty()) { const uint32_t nbPolygons = convexMesh->getNbPolygons(); const physx::PxVec3* convexVertices = convexMesh->getVertices(); @@ -466,7 +483,7 @@ namespace Prism for (uint32_t i = 0; i < nbPolygons; i++) { - physx::PxHullPolygon polygon; + physx::PxHullPolygon polygon{}; convexMesh->getPolygonData(i, polygon); const uint32_t vI0 = vertCounter; @@ -474,7 +491,7 @@ namespace Prism // 收集当前多边形的所有顶点 for (uint32_t vI = 0; vI < polygon.mNbVerts; vI++) { - Vertex vertex; + Vertex vertex{}; vertex.Position = FromPhysXVector( convexVertices[convexIndices[polygon.mIndexBase + vI]] ); @@ -488,7 +505,7 @@ namespace Prism // 为当前多边形生成三角形索引(扇形三角剖分) for (auto vI = 1; vI < polygon.mNbVerts - 1; vI++) { - Index index; + Index index{}; index.V1 = vI0; index.V2 = vI0 + vI + 1; index.V3 = vI0 + vI; @@ -497,7 +514,6 @@ namespace Prism } } - // 为当前子网格创建渲染网格 collider.ProcessedMeshes.push_back(Ref::Create(collisionVertices, collisionIndices)); } } diff --git a/Prism/src/Prism/Physics/PhysicsWrappers.h b/Prism/src/Prism/Physics/PhysicsWrappers.h index ed55d06..fcdac39 100644 --- a/Prism/src/Prism/Physics/PhysicsWrappers.h +++ b/Prism/src/Prism/Physics/PhysicsWrappers.h @@ -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, bool invalidateOld = false); - static std::vector CreateConvexMesh(MeshColliderComponent& collider, bool invalidateOld = false); + static std::vector CreateTriangleMesh(MeshColliderComponent& collider); + static std::vector CreateConvexMesh(MeshColliderComponent& collider, bool rotatedX = false); // static physx::PxMaterial* CreateMaterial(const PhysicsMaterialComponent& material); diff --git a/Prism/src/Prism/Renderer/Renderer2D.cpp b/Prism/src/Prism/Renderer/Renderer2D.cpp index a3a90cf..0a9d33e 100644 --- a/Prism/src/Prism/Renderer/Renderer2D.cpp +++ b/Prism/src/Prism/Renderer/Renderer2D.cpp @@ -369,12 +369,12 @@ namespace Prism s_Data.Stats.QuadCount++; } - void Renderer2D::DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const glm::vec4& color) + void Renderer2D::DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, const float rotation, const glm::vec4& color) { DrawRotatedQuad({ position.x, position.y, 0.0f }, size, rotation, color); } - void Renderer2D::DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const glm::vec4& color) + void Renderer2D::DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, const float rotation, const glm::vec4& color) { if (s_Data.QuadIndexCount >= Renderer2DData::MaxIndices) FlushAndReset(); @@ -383,7 +383,7 @@ namespace Prism const float tilingFactor = 1.0f; glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) - * glm::rotate(glm::mat4(1.0f), glm::radians(rotation), { 0.0f, 0.0f, 1.0f }) + * glm::rotate(glm::mat4(1.0f), rotation, { 0.0f, 0.0f, 1.0f }) * glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f }); for (uint32_t i = 0; i < 4; i++) diff --git a/Prism/src/Prism/Renderer/SceneRenderer.cpp b/Prism/src/Prism/Renderer/SceneRenderer.cpp index ac269cc..f5ba7c2 100644 --- a/Prism/src/Prism/Renderer/SceneRenderer.cpp +++ b/Prism/src/Prism/Renderer/SceneRenderer.cpp @@ -505,7 +505,7 @@ namespace Prism Renderer::SubmitMesh(dc.mesh, dc.Transform, overrideMaterial); } - if (outline) + if (collider || outline) { Renderer::Submit([]() { diff --git a/Prism/src/Prism/Scene/Components.h b/Prism/src/Prism/Scene/Components.h index eeed723..09468c5 100644 --- a/Prism/src/Prism/Scene/Components.h +++ b/Prism/src/Prism/Scene/Components.h @@ -17,6 +17,7 @@ #include #include #include +#include #include "Prism/Renderer/SceneEnvironment.h" @@ -33,8 +34,8 @@ namespace Prism TagComponent() = default; TagComponent(const TagComponent& other) = default; - TagComponent(const std::string& tag) - : Tag(tag) {} + TagComponent(std::string tag) + : Tag(std::move(tag)) {} explicit operator std::string& () { return Tag; } explicit operator const std::string& () const { return Tag; } @@ -56,7 +57,7 @@ namespace Prism glm::mat4 GetTransform() const { return glm::translate(glm::mat4(1.0f), Translation) - * glm::toMat4(glm::quat(glm::radians(Rotation))) + * glm::toMat4(glm::quat((Rotation))) * glm::scale(glm::mat4(1.0f), Scale); } }; @@ -166,7 +167,7 @@ namespace Prism struct RigidBodyComponent { enum class Type { Static, Dynamic}; - Type BodyType; + Type BodyType = Type::Static; float Mass = 1.0f; float LinearDrag = 0.0F; float AngularDrag = 0.05F; @@ -181,8 +182,8 @@ namespace Prism bool LockRotationY = false; bool LockRotationZ = false; - void* RuntimeActor = nullptr; - int32_t EntityBufferIndex = -1; + // 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 3c78dfa..bfb8378 100644 --- a/Prism/src/Prism/Scene/Scene.cpp +++ b/Prism/src/Prism/Scene/Scene.cpp @@ -15,6 +15,7 @@ #include #include "Prism/Physics/Physics3D.h" +#include "Prism/Physics/PhysicsActor.h" #define PX_PHYSX_STATIC_LIB #include @@ -219,12 +220,12 @@ namespace Prism // Process lights { m_LightEnvironment = LightEnvironment(); - auto lights = m_Registry.group(entt::get); + const auto lights = m_Registry.group(entt::get); uint32_t directionalLightIndex = 0; - for (auto entity : lights) + for (const auto entity : lights) { auto [transformComponent, lightComponent] = lights.get(entity); - glm::vec3 direction = -glm::normalize(glm::mat3(transformComponent.GetTransform()) * glm::vec3(1.0f)); + const glm::vec3 direction = -glm::normalize(glm::mat3(transformComponent.GetTransform()) * glm::vec3(1.0f)); m_LightEnvironment.DirectionalLights[directionalLightIndex++] = { direction, @@ -238,8 +239,8 @@ namespace Prism // TODO: only one sky light at the moment! { m_Environment = Environment(); - auto lights = m_Registry.group(entt::get); - for (auto entity : lights) + const auto lights = m_Registry.group(entt::get); + for (const auto entity : lights) { auto [transformComponent, skyLightComponent] = lights.get(entity); m_Environment = skyLightComponent.SceneEnvironment; @@ -532,11 +533,12 @@ namespace Prism { auto view = m_Registry.view(); - Physics3D::ExpandEntityBuffer(static_cast(view.size())); + // Physics3D::ExpandEntityBuffer(static_cast(view.size())); for (auto entity : view) { Entity e = { entity, this }; Physics3D::CreateActor(e); + // Physics3D::CreateActor(e); } } diff --git a/Prism/src/Prism/Scene/SceneSerializer.cpp b/Prism/src/Prism/Scene/SceneSerializer.cpp index 492cbc9..101a48c 100644 --- a/Prism/src/Prism/Scene/SceneSerializer.cpp +++ b/Prism/src/Prism/Scene/SceneSerializer.cpp @@ -187,10 +187,10 @@ namespace Prism out << YAML::Key << "ScriptComponent"; out << YAML::BeginMap; // ScriptComponent - auto& moduleName = entity.GetComponent().ModuleName; + const auto& moduleName = entity.GetComponent().ModuleName; out << YAML::Key << "ModuleName" << YAML::Value << moduleName; - EntityInstanceData& data = ScriptEngine::GetEntityInstanceData(entity.GetSceneUUID(), uuid); + const EntityInstanceData& data = ScriptEngine::GetEntityInstanceData(entity.GetSceneUUID(), uuid); const auto& moduleFieldMap = data.ModuleFieldMap; if (moduleFieldMap.find(moduleName) != moduleFieldMap.end()) { @@ -201,7 +201,7 @@ namespace Prism { out << YAML::BeginMap; // Field out << YAML::Key << "Name" << YAML::Value << name; - out << YAML::Key << "Type" << YAML::Value << (uint32_t)field.Type; + out << YAML::Key << "Type" << YAML::Value << static_cast(field.Type); out << YAML::Key << "Data" << YAML::Value; switch (field.Type) @@ -238,7 +238,7 @@ namespace Prism out << YAML::Key << "MeshComponent"; out << YAML::BeginMap; // MeshComponent - auto mesh = entity.GetComponent().Mesh; + const auto mesh = entity.GetComponent().Mesh; out << YAML::Key << "AssetPath" << YAML::Value << mesh->GetFilePath(); out << YAML::EndMap; // MeshComponent @@ -249,7 +249,7 @@ namespace Prism out << YAML::Key << "DirectionalLightComponent"; out << YAML::BeginMap; // DirectionalLightComponent - auto& directionalLightComponent = entity.GetComponent(); + const auto& directionalLightComponent = entity.GetComponent(); out << YAML::Key << "Radiance" << YAML::Value << directionalLightComponent.Radiance; out << YAML::Key << "CastShadows" << YAML::Value << directionalLightComponent.CastShadows; out << YAML::Key << "SoftShadows" << YAML::Value << directionalLightComponent.SoftShadows; @@ -263,7 +263,7 @@ namespace Prism out << YAML::Key << "SkyLightComponent"; out << YAML::BeginMap; // SkyLightComponent - auto& skyLightComponent = entity.GetComponent(); + const auto& skyLightComponent = entity.GetComponent(); out << YAML::Key << "EnvironmentAssetPath" << YAML::Value << skyLightComponent.SceneEnvironment.FilePath; out << YAML::Key << "Intensity" << YAML::Value << skyLightComponent.Intensity; out << YAML::Key << "Angle" << YAML::Value << skyLightComponent.Angle; @@ -342,9 +342,14 @@ namespace Prism out << YAML::Key << "RigidBodyComponent"; out << YAML::BeginMap; // RigidBodyComponent - auto& rigidbodyComponent = entity.GetComponent(); - out << YAML::Key << "BodyType" << YAML::Value << (int)rigidbodyComponent.BodyType; + const auto& rigidbodyComponent = entity.GetComponent(); + out << YAML::Key << "BodyType" << YAML::Value << static_cast(rigidbodyComponent.BodyType); out << YAML::Key << "Mass" << YAML::Value << rigidbodyComponent.Mass; + + out << YAML::Key << "LinearDrag" << YAML::Value << rigidbodyComponent.LinearDrag; + out << YAML::Key << "AngularDrag" << YAML::Value << rigidbodyComponent.AngularDrag; + out << YAML::Key << "DisableGravity" << YAML::Value << rigidbodyComponent.DisableGravity; + out << YAML::Key << "IsKinematic" << YAML::Value << rigidbodyComponent.IsKinematic; out << YAML::Key << "Layer" << YAML::Value << rigidbodyComponent.Layer; @@ -709,6 +714,11 @@ namespace Prism auto& component = deserializedEntity.AddComponent(); component.BodyType = (RigidBodyComponent::Type)rigidBodyComponent["BodyType"].as(); component.Mass = rigidBodyComponent["Mass"].as(); + + component.LinearDrag = rigidBodyComponent["LinearDrag"] ? rigidBodyComponent["LinearDrag"].as() : 0.0f; + component.AngularDrag = rigidBodyComponent["AngularDrag"] ? rigidBodyComponent["AngularDrag"].as() : 0.05f; + component.DisableGravity = rigidBodyComponent["DisableGravity"] ? rigidBodyComponent["DisableGravity"].as() : false; + component.IsKinematic = rigidBodyComponent["IsKinematic"] ? rigidBodyComponent["IsKinematic"].as() : false; component.Layer = rigidBodyComponent["Layer"] ? rigidBodyComponent["Layer"].as() : 0; diff --git a/Prism/src/Prism/Script/ScriptWrappers.cpp b/Prism/src/Prism/Script/ScriptWrappers.cpp index 75d0a04..b1aafff 100644 --- a/Prism/src/Prism/Script/ScriptWrappers.cpp +++ b/Prism/src/Prism/Script/ScriptWrappers.cpp @@ -378,13 +378,13 @@ namespace Prism { namespace Script { Entity entity = entityMap.at(entityID); const auto& transform = entity.GetComponent(); - const glm::quat rotation = glm::quat(glm::radians(transform.Rotation)); + 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, transform.Rotation, transform.Scale, + transform.Translation, glm::degrees(transform.Rotation), transform.Scale, up, right, forward }; } @@ -400,7 +400,7 @@ namespace Prism { namespace Script { auto& transform = entity.GetComponent(); transform.Translation = inTransform->Translation; - transform.Rotation = inTransform->Rotation; + transform.Rotation = glm::radians(inTransform->Rotation); transform.Scale = inTransform->Scale; } @@ -441,7 +441,7 @@ namespace Prism { namespace Script { const b2BodyId body = component.RuntimeBodyID; - b2Body_ApplyLinearImpulse(body, *(const b2Vec2*)impulse, b2Body_GetWorldCenterOfMass(body) + *(const b2Vec2*)offset, wake); + b2Body_ApplyLinearImpulse(body, *reinterpret_cast(impulse), b2Body_GetWorldCenterOfMass(body) + *reinterpret_cast(offset), wake); } void Prism_RigidBody2DComponent_GetLinearVelocity(const uint64_t entityID, glm::vec2 *outVelocity) @@ -489,7 +489,7 @@ namespace Prism { namespace Script { return component.BodyType; } - void Prism_RigidBodyComponent_AddForce(const uint64_t entityID, glm::vec3* force, ForceMode forceMode) + void Prism_RigidBodyComponent_AddForce(const uint64_t entityID, const glm::vec3* force, const ForceMode forceMode) { Ref scene = ScriptEngine::GetCurrentSceneContext(); PM_CORE_ASSERT(scene, "No active scene!"); @@ -498,22 +498,18 @@ namespace Prism { namespace Script { Entity entity = entityMap.at(entityID); PM_CORE_ASSERT(entity.HasComponent()); - const auto& component = entity.GetComponent(); + const auto& component = entity.GetComponent(); if (component.IsKinematic) { PM_CORE_WARN("Cannot add a force to a kinematic actor! EntityID({0})", entityID); return; } - auto* actor = static_cast(component.RuntimeActor); - auto* dynamicActor = actor->is(); - PM_CORE_ASSERT(dynamicActor); - - PM_CORE_ASSERT(force); - dynamicActor->addForce({ force->x, force->y, force->z }, (physx::PxForceMode::Enum)forceMode); + Ref actor = Physics3D::GetActorForEntity(entity); + actor->AddForce(*force, forceMode); } - void Prism_RigidBodyComponent_AddTorque(const uint64_t entityID, glm::vec3* torque, ForceMode forceMode) + void Prism_RigidBodyComponent_AddTorque(const uint64_t entityID, const glm::vec3* torque, const ForceMode forceMode) { Ref scene = ScriptEngine::GetCurrentSceneContext(); PM_CORE_ASSERT(scene, "No active scene!"); @@ -529,12 +525,8 @@ namespace Prism { namespace Script { return; } - const auto actor = static_cast(component.RuntimeActor); - auto* dynamicActor = actor->is(); - PM_CORE_ASSERT(dynamicActor); - - PM_CORE_ASSERT(torque); - dynamicActor->addTorque({ torque->x, torque->y, torque->z }, (physx::PxForceMode::Enum)forceMode); + Ref actor = Physics3D::GetActorForEntity(entity); + actor->AddTorque(*torque, forceMode); } void Prism_RigidBodyComponent_GetLinearVelocity(const uint64_t entityID, glm::vec3* outVelocity) @@ -546,24 +538,19 @@ namespace Prism { namespace Script { Entity entity = entityMap.at(entityID); PM_CORE_ASSERT(entity.HasComponent()); - const auto& component = entity.GetComponent(); + const auto& component = entity.GetComponent(); if (component.IsKinematic) { PM_CORE_WARN("Cannot add torque to a kinematic actor! EntityID({0})", entityID); return; } - const auto actor = static_cast(component.RuntimeActor); - const physx::PxRigidDynamic* dynamicActor = actor->is(); - PM_CORE_ASSERT(dynamicActor); - - PM_CORE_ASSERT(outVelocity); - physx::PxVec3 velocity = dynamicActor->getLinearVelocity(); - *outVelocity = { velocity.x, velocity.y, velocity.z }; + Ref actor = Physics3D::GetActorForEntity(entity); + *outVelocity = actor->GetLinearVelocity(); } - void Prism_RigidBodyComponent_SetLinearVelocity(const uint64_t entityID, glm::vec3* velocity) + void Prism_RigidBodyComponent_SetLinearVelocity(const uint64_t entityID, const glm::vec3* velocity) { Ref scene = ScriptEngine::GetCurrentSceneContext(); PM_CORE_ASSERT(scene, "No active scene!"); @@ -579,16 +566,12 @@ namespace Prism { namespace Script { return; } - const auto actor = static_cast(component.RuntimeActor); - auto* dynamicActor = actor->is(); - PM_CORE_ASSERT(dynamicActor); - PM_CORE_ASSERT(velocity); - PM_CORE_INFO("Hazel_RigidBodyComponent_SetLinearVelocity - {0}, {1}, {2}", velocity->x, velocity->y, velocity->z); - dynamicActor->setLinearVelocity({ velocity->x, velocity->y, velocity->z }); + Ref actor = Physics3D::GetActorForEntity(entity); + actor->SetLinearVelocity(*velocity); } - void Prism_RigidBodyComponent_GetAngularVelocity(uint64_t entityID, glm::vec3* outVelocity) + void Prism_RigidBodyComponent_GetAngularVelocity(const uint64_t entityID, glm::vec3* outVelocity) { Ref scene = ScriptEngine::GetCurrentSceneContext(); PM_CORE_ASSERT(scene, "No active scene!"); @@ -599,16 +582,12 @@ namespace Prism { namespace Script { 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 }; + Ref actor = Physics3D::GetActorForEntity(entity); + *outVelocity = actor->GetAngularVelocity(); } - void Prism_RigidBodyComponent_SetAngularVelocity(uint64_t entityID, glm::vec3* velocity) + void Prism_RigidBodyComponent_SetAngularVelocity(const uint64_t entityID, const glm::vec3* velocity) { Ref scene = ScriptEngine::GetCurrentSceneContext(); PM_CORE_ASSERT(scene, "No active scene!"); @@ -619,15 +598,12 @@ namespace Prism { namespace Script { 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 }); + Ref actor = Physics3D::GetActorForEntity(entity); + actor->SetAngularVelocity(*velocity); } - void Prism_RigidBodyComponent_Rotate(uint64_t entityID, glm::vec3* rotation) + void Prism_RigidBodyComponent_Rotate(const uint64_t entityID, const glm::vec3* rotation) { Ref scene = ScriptEngine::GetCurrentSceneContext(); PM_CORE_ASSERT(scene, "No active scene!"); @@ -638,16 +614,8 @@ namespace Prism { namespace Script { PM_CORE_ASSERT(entity.HasComponent()); const auto& component = entity.GetComponent(); - const auto actor = static_cast(component.RuntimeActor); - auto* dynamicActor = actor->is(); - PM_CORE_ASSERT(dynamicActor); - - physx::PxTransform transform = dynamicActor->getGlobalPose(); - transform.q *= (physx::PxQuat(glm::radians(rotation->x), { 1.0f, 0.0f, 0.0f }) - * physx::PxQuat(glm::radians(rotation->y), { 0.0f, 1.0f, 0.0f }) - * physx::PxQuat(glm::radians(rotation->z), { 0.0f, 0.0f, 1.0f })); - - dynamicActor->setGlobalPose(transform); + Ref actor = Physics3D::GetActorForEntity(entity); + actor->Rotate(*rotation); } uint32_t Prism_RigidBodyComponent_GetLayer(const uint64_t entityID) @@ -672,13 +640,9 @@ namespace Prism { namespace Script { Entity entity = entityMap.at(entityID); PM_CORE_ASSERT(entity.HasComponent()); - const auto& component = entity.GetComponent(); - const auto actor = static_cast(component.RuntimeActor); - const physx::PxRigidDynamic* dynamicActor = actor->is(); - PM_CORE_ASSERT(dynamicActor); - - return dynamicActor->getMass(); + Ref actor = Physics3D::GetActorForEntity(entity); + return actor->GetMass(); } void Prism_RigidBodyComponent_SetMass(const uint64_t entityID, const float mass) @@ -687,17 +651,11 @@ namespace Prism { namespace Script { 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()); - auto& component = entity.GetComponent(); - auto* actor = static_cast(component.RuntimeActor); - auto* dynamicActor = actor->is(); - PM_CORE_ASSERT(dynamicActor); - - component.Mass = mass; - physx::PxRigidBodyExt::updateMassAndInertia(*dynamicActor, mass); + Ref actor = Physics3D::GetActorForEntity(entity); + actor->SetMass(mass); } @@ -731,7 +689,7 @@ namespace Prism { namespace Script { { Ref& mesh = *inMesh; const auto& materials = mesh->GetMaterials(); - return (int)materials.size(); + return static_cast(materials.size()); } void* Prism_Texture2D_Constructor(const uint32_t width, const uint32_t height) diff --git a/Prism/src/Prism/Script/ScriptWrappers.h b/Prism/src/Prism/Script/ScriptWrappers.h index 69a0f83..d6fef0c 100644 --- a/Prism/src/Prism/Script/ScriptWrappers.h +++ b/Prism/src/Prism/Script/ScriptWrappers.h @@ -67,13 +67,13 @@ namespace Prism { namespace Script { // 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_AddForce(uint64_t entityID, const glm::vec3* force, ForceMode forceMode); + void Prism_RigidBodyComponent_AddTorque(uint64_t entityID, const 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_SetLinearVelocity(uint64_t entityID, const 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); + void Prism_RigidBodyComponent_SetAngularVelocity(uint64_t entityID, const glm::vec3* velocity); + void Prism_RigidBodyComponent_Rotate(uint64_t entityID, const glm::vec3* rotation); uint32_t Prism_RigidBodyComponent_GetLayer(uint64_t entityID); float Prism_RigidBodyComponent_GetMass(uint64_t entityID); void Prism_RigidBodyComponent_SetMass(uint64_t entityID, float mass);