add serialize for RigidbodyComponent linear/angular drag and gravity, change the physx API for c++ and c#, fixed rotate bug(using radians to storage), some little code tweaks

This commit is contained in:
2026-01-12 18:58:11 +08:00
parent f857d8e791
commit bed57f18d3
17 changed files with 531 additions and 239 deletions

View File

@ -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<glm::vec3, glm::quat, glm::vec3> 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<BoxCollider2DComponent>())
{
const auto& size = selection.Entity.GetComponent<BoxCollider2DComponent>().Size;
auto [translation, rotationQuat, scale] = GetTransformDecomposition(selection.Entity.GetComponent<TransformComponent>().GetTransform());
const glm::vec3 rotation = glm::eulerAngles(rotationQuat);
const auto& transform = selection.Entity.GetComponent<TransformComponent>();
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;
}
}
}

View File

@ -0,0 +1,88 @@
//
// Created by Atdunbg on 2026/1/12.
//
#include "Math.h"
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/matrix_decompose.hpp>
#include <glm/gtx/norm.hpp>
#include <glm/gtx/quaternion.hpp>
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<float>(0), epsilon<T>()))
return false;
// First, isolate perspective. This is the messiest.
if (
epsilonNotEqual(LocalMatrix[0][3], static_cast<T>(0), epsilon<T>()) ||
epsilonNotEqual(LocalMatrix[1][3], static_cast<T>(0), epsilon<T>()) ||
epsilonNotEqual(LocalMatrix[2][3], static_cast<T>(0), epsilon<T>()))
{
// Clear the perspective partition
LocalMatrix[0][3] = LocalMatrix[1][3] = LocalMatrix[2][3] = static_cast<T>(0);
LocalMatrix[3][3] = static_cast<T>(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<T>(1));
scale.y = length(Row[1]);
Row[1] = detail::scale(Row[1], static_cast<T>(1));
scale.z = length(Row[2]);
Row[2] = detail::scale(Row[2], static_cast<T>(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<T>(-1);
Row[i] *= static_cast<T>(-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;
}
}

View File

@ -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

View File

@ -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<Mesh>::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);
}
}

View File

@ -5,8 +5,6 @@
#include "Physics3D.h"
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/quaternion.hpp>
#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<Ref<PhysicsActor>> s_SimulatedActors;
static std::vector<Ref<PhysicsActor>> s_StaticActors;
static Entity* s_EntityStorageBuffer;
static uint32_t s_EntityBufferCount;
static int s_EntityStorageBufferPosition;
static std::vector<Ref<PhysicsActor>> s_Actors;
static float s_SimulationTime = 0.0f;
static PhysicsSettings s_Settings;
@ -68,41 +62,28 @@ namespace Prism
}
}
void Physics3D::CreateActor(Entity e)
Ref<PhysicsActor> Physics3D::CreateActor(Entity e)
{
PM_CORE_ASSERT(s_Scene);
if (!e.HasComponent<RigidBodyComponent>())
{
PM_CORE_WARN("Trying to create PhysX actor from a non-rigidbody actor!");
return;
}
if (!e.HasComponent<PhysicsMaterialComponent>())
{
PM_CORE_WARN("Trying to create PhysX actor without a PhysicsMaterialComponent!");
return;
}
RigidBodyComponent& rigidbody = e.GetComponent<RigidBodyComponent>();
const auto transform = e.Transform();
Ref<PhysicsActor> actor = Ref<PhysicsActor>::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<PhysicsActor> 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<RigidBodyComponent>();
Ref<PhysicsActor> actor = GetActorForEntity(e);
actor->SetUserData(&temp[rb.EntityBufferIndex]);
/*
if (rb.RuntimeActor)
{
auto* actor = static_cast<physx::PxRigidActor*>(rb.RuntimeActor);
actor->userData = &temp[rb.EntityBufferIndex];
}
#1#
}
delete[] s_EntityStorageBuffer;
@ -191,5 +173,6 @@ namespace Prism
s_EntityBufferCount = entityCount;
}
}
*/
}

View File

@ -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<PhysicsActor> CreateActor(Entity e);
static Ref<PhysicsActor> GetActorForEntity(Entity entity);
static void Simulate(TimeStep ts);

View File

@ -9,24 +9,179 @@
#include "PhysicsWrappers.h"
#include "PxRigidActor.h"
#include "Prism/Script/ScriptEngine.h"
#include <glm/gtx/compatibility.hpp>
namespace Prism
{
PhysicsActor::PhysicsActor(Entity entity)
: m_Entity(entity), m_RigidBody(entity.GetComponent<RigidBodyComponent>())
{
m_Material = entity.GetComponent<PhysicsMaterialComponent>();
if (!m_Entity.HasComponent<PhysicsMaterialComponent>())
{
m_Material.StaticFriction = 1.0f;
m_Material.DynamicFriction = 1.0f;
m_Material.Bounciness = 0.0f;
}
else
{
m_Material = entity.GetComponent<PhysicsMaterialComponent>();
}
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<physx::PxRigidDynamic*>(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<physx::PxRigidDynamic*>(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<physx::PxRigidDynamic*>(m_ActorInternal);
actor->addForce(ToPhysXVector(force), static_cast<physx::PxForceMode::Enum>(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<physx::PxRigidDynamic*>(m_ActorInternal);
actor->addTorque(ToPhysXVector(torque), static_cast<physx::PxForceMode::Enum>(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<physx::PxRigidDynamic*>(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<physx::PxRigidDynamic*>(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<physx::PxRigidDynamic*>(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<physx::PxRigidDynamic*>(m_ActorInternal);
actor->setAngularVelocity(ToPhysXVector(velocity));
}
void PhysicsActor::SetLinearDrag(const float drag) const
{
if (!IsDynamic())
return;
auto* actor = static_cast<physx::PxRigidDynamic*>(m_ActorInternal);
actor->setLinearDamping(drag);
}
void PhysicsActor::SetAngularDrag(const float drag) const
{
if (!IsDynamic())
return;
const auto actor = static_cast<physx::PxRigidDynamic*>(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<BoxColliderComponent>()) PhysicsWrappers::AddBoxCollider(*this, *physicsMat);
if (m_Entity.HasComponent<SphereColliderComponent>()) PhysicsWrappers::AddSphereCollider(*this, *physicsMat);
if (m_Entity.HasComponent<CapsuleColliderComponent>()) 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<physx::PxScene*>(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<physx::PxRigidActor*>(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<physx::PxShape*>();
}
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<physx::PxShape**>(allocator.allocate(sizeof(physx::PxShape*) * numShapes, "", "", 0));
m_ActorInternal->getShapes(shapes, numShapes);
for (physx::PxU32 i = 0; i < numShapes; i++)

View File

@ -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<int, std::vector<physx::PxShape*>> m_Shapes;
};
}

View File

@ -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<BoxColliderComponent>();
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<SphereColliderComponent>();
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<CapsuleColliderComponent>();
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<physx::PxConvexMesh*> meshes = CreateConvexMesh(collider, true);
actor.RemoveCollisionsShapes(physx::PxGeometryType::eTRIANGLEMESH);
const std::vector<physx::PxConvexMesh*> 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<physx::PxTriangleMesh*> meshes = CreateTriangleMesh(collider, true);
actor.RemoveCollisionsShapes(physx::PxGeometryType::eCONVEXMESH);
const std::vector<physx::PxTriangleMesh*> 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<physx::PxTriangleMesh*> PhysicsWrappers::CreateTriangleMesh(MeshColliderComponent& collider, bool invalidateOld)
std::vector<physx::PxTriangleMesh*> PhysicsWrappers::CreateTriangleMesh(MeshColliderComponent& collider)
{
std::vector<physx::PxTriangleMesh*> meshes;
@ -279,7 +297,7 @@ namespace Prism
const std::vector<Vertex>& vertices = collider.CollisionMesh->GetStaticVertices();
const std::vector<Index>& indices = collider.CollisionMesh->GetIndices();
// 提取顶点位置(如果需要)
// 提取顶点位置
std::vector<glm::vec3> 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<physx::PxConvexMesh*> PhysicsWrappers::CreateConvexMesh(MeshColliderComponent& collider, bool invalidateOld)
std::vector<physx::PxConvexMesh*> PhysicsWrappers::CreateConvexMesh(MeshColliderComponent& collider, const bool rotatedX)
{
std::vector<physx::PxConvexMesh*> 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<Vertex>& vertices = collider.CollisionMesh->GetStaticVertices();
const std::vector<Index>& indices = collider.CollisionMesh->GetIndices();
// 准备顶点位置数组(如果需要的话)
std::vector<glm::vec3> 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<glm::vec3> 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<Mesh>::Create(collisionVertices, collisionIndices));
}
}

View File

@ -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<physx::PxTriangleMesh*> CreateTriangleMesh(MeshColliderComponent& collider, bool invalidateOld = false);
static std::vector<physx::PxConvexMesh*> CreateConvexMesh(MeshColliderComponent& collider, bool invalidateOld = false);
static std::vector<physx::PxTriangleMesh*> CreateTriangleMesh(MeshColliderComponent& collider);
static std::vector<physx::PxConvexMesh*> CreateConvexMesh(MeshColliderComponent& collider, bool rotatedX = false);
// static physx::PxMaterial* CreateMaterial(const PhysicsMaterialComponent& material);

View File

@ -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++)

View File

@ -505,7 +505,7 @@ namespace Prism
Renderer::SubmitMesh(dc.mesh, dc.Transform, overrideMaterial);
}
if (outline)
if (collider || outline)
{
Renderer::Submit([]()
{

View File

@ -17,6 +17,7 @@
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/quaternion.hpp>
#include <utility>
#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;

View File

@ -15,6 +15,7 @@
#include <glm/gtx/matrix_decompose.hpp>
#include "Prism/Physics/Physics3D.h"
#include "Prism/Physics/PhysicsActor.h"
#define PX_PHYSX_STATIC_LIB
#include <PxPhysicsAPI.h>
@ -219,12 +220,12 @@ namespace Prism
// Process lights
{
m_LightEnvironment = LightEnvironment();
auto lights = m_Registry.group<DirectionalLightComponent>(entt::get<TransformComponent>);
const auto lights = m_Registry.group<DirectionalLightComponent>(entt::get<TransformComponent>);
uint32_t directionalLightIndex = 0;
for (auto entity : lights)
for (const auto entity : lights)
{
auto [transformComponent, lightComponent] = lights.get<TransformComponent, DirectionalLightComponent>(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<SkyLightComponent>(entt::get<TransformComponent>);
for (auto entity : lights)
const auto lights = m_Registry.group<SkyLightComponent>(entt::get<TransformComponent>);
for (const auto entity : lights)
{
auto [transformComponent, skyLightComponent] = lights.get<TransformComponent, SkyLightComponent>(entity);
m_Environment = skyLightComponent.SceneEnvironment;
@ -532,11 +533,12 @@ namespace Prism
{
auto view = m_Registry.view<RigidBodyComponent>();
Physics3D::ExpandEntityBuffer(static_cast<uint32_t>(view.size()));
// Physics3D::ExpandEntityBuffer(static_cast<uint32_t>(view.size()));
for (auto entity : view)
{
Entity e = { entity, this };
Physics3D::CreateActor(e);
// Physics3D::CreateActor(e);
}
}

View File

@ -187,10 +187,10 @@ namespace Prism
out << YAML::Key << "ScriptComponent";
out << YAML::BeginMap; // ScriptComponent
auto& moduleName = entity.GetComponent<ScriptComponent>().ModuleName;
const auto& moduleName = entity.GetComponent<ScriptComponent>().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<uint32_t>(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<MeshComponent>().Mesh;
const auto mesh = entity.GetComponent<MeshComponent>().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<DirectionalLightComponent>();
const auto& directionalLightComponent = entity.GetComponent<DirectionalLightComponent>();
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<SkyLightComponent>();
const auto& skyLightComponent = entity.GetComponent<SkyLightComponent>();
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<RigidBodyComponent>();
out << YAML::Key << "BodyType" << YAML::Value << (int)rigidbodyComponent.BodyType;
const auto& rigidbodyComponent = entity.GetComponent<RigidBodyComponent>();
out << YAML::Key << "BodyType" << YAML::Value << static_cast<int>(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<RigidBodyComponent>();
component.BodyType = (RigidBodyComponent::Type)rigidBodyComponent["BodyType"].as<int>();
component.Mass = rigidBodyComponent["Mass"].as<float>();
component.LinearDrag = rigidBodyComponent["LinearDrag"] ? rigidBodyComponent["LinearDrag"].as<float>() : 0.0f;
component.AngularDrag = rigidBodyComponent["AngularDrag"] ? rigidBodyComponent["AngularDrag"].as<float>() : 0.05f;
component.DisableGravity = rigidBodyComponent["DisableGravity"] ? rigidBodyComponent["DisableGravity"].as<bool>() : false;
component.IsKinematic = rigidBodyComponent["IsKinematic"] ? rigidBodyComponent["IsKinematic"].as<bool>() : false;
component.Layer = rigidBodyComponent["Layer"] ? rigidBodyComponent["Layer"].as<uint32_t>() : 0;

View File

@ -378,13 +378,13 @@ namespace Prism { namespace Script {
Entity entity = entityMap.at(entityID);
const auto& transform = entity.GetComponent<TransformComponent>();
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<TransformComponent>();
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<const b2Vec2*>(impulse), b2Body_GetWorldCenterOfMass(body) + *reinterpret_cast<const b2Vec2*>(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> 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<RigidBodyComponent>());
const auto& component = entity.GetComponent<RigidBodyComponent>();
const auto& component = entity.GetComponent<RigidBodyComponent>();
if (component.IsKinematic)
{
PM_CORE_WARN("Cannot add a force to a kinematic actor! EntityID({0})", entityID);
return;
}
auto* actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
auto* dynamicActor = actor->is<physx::PxRigidDynamic>();
PM_CORE_ASSERT(dynamicActor);
PM_CORE_ASSERT(force);
dynamicActor->addForce({ force->x, force->y, force->z }, (physx::PxForceMode::Enum)forceMode);
Ref<PhysicsActor> 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> scene = ScriptEngine::GetCurrentSceneContext();
PM_CORE_ASSERT(scene, "No active scene!");
@ -529,12 +525,8 @@ namespace Prism { namespace Script {
return;
}
const auto actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
auto* dynamicActor = actor->is<physx::PxRigidDynamic>();
PM_CORE_ASSERT(dynamicActor);
PM_CORE_ASSERT(torque);
dynamicActor->addTorque({ torque->x, torque->y, torque->z }, (physx::PxForceMode::Enum)forceMode);
Ref<PhysicsActor> 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<RigidBodyComponent>());
const auto& component = entity.GetComponent<RigidBodyComponent>();
const auto& component = entity.GetComponent<RigidBodyComponent>();
if (component.IsKinematic)
{
PM_CORE_WARN("Cannot add torque to a kinematic actor! EntityID({0})", entityID);
return;
}
const auto actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
const physx::PxRigidDynamic* dynamicActor = actor->is<physx::PxRigidDynamic>();
PM_CORE_ASSERT(dynamicActor);
PM_CORE_ASSERT(outVelocity);
physx::PxVec3 velocity = dynamicActor->getLinearVelocity();
*outVelocity = { velocity.x, velocity.y, velocity.z };
Ref<PhysicsActor> 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> scene = ScriptEngine::GetCurrentSceneContext();
PM_CORE_ASSERT(scene, "No active scene!");
@ -579,16 +566,12 @@ namespace Prism { namespace Script {
return;
}
const auto actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
auto* dynamicActor = actor->is<physx::PxRigidDynamic>();
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<PhysicsActor> 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> scene = ScriptEngine::GetCurrentSceneContext();
PM_CORE_ASSERT(scene, "No active scene!");
@ -599,16 +582,12 @@ namespace Prism { namespace Script {
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
const auto& component = entity.GetComponent<RigidBodyComponent>();
const auto actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
const auto* dynamicActor = actor->is<physx::PxRigidDynamic>();
PM_CORE_ASSERT(dynamicActor);
PM_CORE_ASSERT(outVelocity);
physx::PxVec3 velocity = dynamicActor->getAngularVelocity();
*outVelocity = { velocity.x, velocity.y, velocity.z };
Ref<PhysicsActor> 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> scene = ScriptEngine::GetCurrentSceneContext();
PM_CORE_ASSERT(scene, "No active scene!");
@ -619,15 +598,12 @@ namespace Prism { namespace Script {
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
const auto& component = entity.GetComponent<RigidBodyComponent>();
auto* actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
auto* dynamicActor = actor->is<physx::PxRigidDynamic>();
PM_CORE_ASSERT(dynamicActor);
PM_CORE_ASSERT(velocity);
dynamicActor->setAngularVelocity({ velocity->x, velocity->y, velocity->z });
Ref<PhysicsActor> 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> scene = ScriptEngine::GetCurrentSceneContext();
PM_CORE_ASSERT(scene, "No active scene!");
@ -638,16 +614,8 @@ namespace Prism { namespace Script {
PM_CORE_ASSERT(entity.HasComponent<RigidBodyComponent>());
const auto& component = entity.GetComponent<RigidBodyComponent>();
const auto actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
auto* dynamicActor = actor->is<physx::PxRigidDynamic>();
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<PhysicsActor> 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<RigidBodyComponent>());
const auto& component = entity.GetComponent<RigidBodyComponent>();
const auto actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
const physx::PxRigidDynamic* dynamicActor = actor->is<physx::PxRigidDynamic>();
PM_CORE_ASSERT(dynamicActor);
return dynamicActor->getMass();
Ref<PhysicsActor> 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<RigidBodyComponent>());
auto& component = entity.GetComponent<RigidBodyComponent>();
auto* actor = static_cast<physx::PxRigidActor*>(component.RuntimeActor);
auto* dynamicActor = actor->is<physx::PxRigidDynamic>();
PM_CORE_ASSERT(dynamicActor);
component.Mass = mass;
physx::PxRigidBodyExt::updateMassAndInertia(*dynamicActor, mass);
Ref<PhysicsActor> actor = Physics3D::GetActorForEntity(entity);
actor->SetMass(mass);
}
@ -731,7 +689,7 @@ namespace Prism { namespace Script {
{
Ref<Mesh>& mesh = *inMesh;
const auto& materials = mesh->GetMaterials();
return (int)materials.size();
return static_cast<int>(materials.size());
}
void* Prism_Texture2D_Constructor(const uint32_t width, const uint32_t height)

View File

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