move imgui property code and Pysics Actor code to a single file

This commit is contained in:
2026-01-10 14:48:17 +08:00
parent 9e1474e643
commit f857d8e791
16 changed files with 442 additions and 210 deletions

View File

@ -7,8 +7,13 @@ namespace FPSExample
public float WalkingSpeed = 10.0f;
public float RunSpeed = 20.0f;
public float JumpForce = 50.0f;
[NonSerialized]
public float MouseSensitivity = 10.0f;
public float Distance = 5.0f;
public float CameraForwardOffset = 0.5f;
public float CameraYOffset = 0.5f;
private bool m_Colliding = false;
private float m_CurrentSpeed;
@ -22,6 +27,9 @@ namespace FPSExample
private Vec2 m_LastMousePosition;
private float m_CurrentYMovement = 0.0f;
private Vec2 m_MovementDirection = new Vec2(0.0f);
private bool m_ShouldJump = false;
void OnCreate()
{
m_Transform = GetComponent<TransformComponent>();
@ -40,7 +48,6 @@ namespace FPSExample
Input.SetCursorMode(Input.CursorMode.Locked);
}
Collider[] colliders = new Collider[10];
void OnUpdate(float ts)
{
if (Input.IsKeyPressed(KeyCode.Escape) && Input.GetCursorMode() == Input.CursorMode.Locked)
@ -51,6 +58,55 @@ namespace FPSExample
m_CurrentSpeed = Input.IsKeyPressed(KeyCode.LeftControl) ? RunSpeed : WalkingSpeed;
UpdateRayCasting();
UpdateMovementInput();
UpdateRotation(ts);
UpdateCameraTransform();
}
private void UpdateRotation(float ts)
{
Vec2 currentMousePosition = Input.GetMousePosition();
Vec2 delta = m_LastMousePosition - currentMousePosition;
float m_CurrentYMovement = delta.X * MouseSensitivity * ts;
float xRotation = delta.Y * MouseSensitivity * ts;
m_RigidBody.Rotate(new Vec3(0.0f, m_CurrentYMovement, 0.0f));
if (delta.X != 0 || delta.Y != 0)
{
m_CameraTransform.Rotation += new Vec3(xRotation, m_CurrentYMovement, 0.0f);
}
m_CameraTransform.Rotation = new Vec3(Mathf.Clamp(m_CameraTransform.Rotation.X, -89.0f, 89.0f), m_CameraTransform.Rotation.YZ);
m_LastMousePosition = currentMousePosition;
}
private void UpdateMovementInput()
{
if (Input.IsKeyPressed(KeyCode.W))
m_MovementDirection.Y += 1.0f;
else if (Input.IsKeyPressed(KeyCode.S))
m_MovementDirection.Y -= 1.0f;
else
m_MovementDirection.Y = 0.0f;
if(Input.IsKeyPressed(KeyCode.A))
m_MovementDirection.X -= 1.0f;
else if (Input.IsKeyPressed(KeyCode.D))
m_MovementDirection.X += 1.0f;
else
m_MovementDirection.X = 0.0f;
m_ShouldJump = Input.IsKeyPressed(KeyCode.Space) && !m_ShouldJump;
}
Collider[] colliders = new Collider[10];
private void UpdateRayCasting()
{
RaycastHit hitInfo;
if (Input.IsKeyPressed(KeyCode.H) &&
Physics.Raycast(m_CameraTransform.Position + (m_CameraTransform.Transform.Forward),
@ -74,54 +130,36 @@ namespace FPSExample
}
}
UpdateRotation(ts);
UpdateMovement();
UpdateCameraTransform();
}
private void UpdateRotation(float ts)
void OnPhysicsUpdate(float fixedTimeStep)
{
Vec2 currentMousePosition = Input.GetMousePosition();
Vec2 delta = m_LastMousePosition - currentMousePosition;
float m_CurrentYMovement = delta.X * MouseSensitivity * ts;
float xRotation = delta.Y * MouseSensitivity * ts;
m_RigidBody.Rotate(new Vec3(0.0f, m_CurrentYMovement, 0.0f));
if (delta.X != 0 || delta.Y != 0)
{
m_CameraTransform.Rotation += new Vec3(xRotation, m_CurrentYMovement, 0.0f);
}
m_CameraTransform.Rotation = new Vec3(Mathf.Clamp(m_CameraTransform.Rotation.X, -89.0f, 89.0f), m_CameraTransform.Rotation.YZ);
m_LastMousePosition = currentMousePosition;
UpdateMovement();
}
private void UpdateMovement()
{
m_RigidBody.Rotate(new Vec3(0.0f, m_CurrentYMovement, 0.0f));
if (Input.IsKeyPressed(KeyCode.W))
m_RigidBody.AddForce(m_Transform.Transform.Forward * m_CurrentSpeed);
else if (Input.IsKeyPressed(KeyCode.S))
m_RigidBody.AddForce(m_Transform.Transform.Forward * -m_CurrentSpeed);
if (Input.IsKeyPressed(KeyCode.A))
m_RigidBody.AddForce(m_Transform.Transform.Right * -m_CurrentSpeed);
else if (Input.IsKeyPressed(KeyCode.D))
m_RigidBody.AddForce(m_Transform.Transform.Right * m_CurrentSpeed);
if (Input.IsKeyPressed(KeyCode.Space) && m_Colliding)
m_RigidBody.AddForce(Vec3.Up * JumpForce);
Vec3 movement = m_CameraTransform.Transform.Right * m_MovementDirection.X + m_CameraTransform.Transform.Forward * m_MovementDirection.Y;
if (m_MovementDirection.LengthSquared() != 0.0f)
{
movement.Normalize();
Vec3 velocity = movement * m_CurrentSpeed;
velocity.Y = m_RigidBody.GetLinearVelocity().Y;
m_RigidBody.SetLinearVelocity(velocity);
}
if (m_ShouldJump && m_Colliding)
{
m_RigidBody.AddForce(Vec3.Up * JumpForce, RigidBodyComponent.ForceMode.Impulse);
m_ShouldJump = false;
}
}
private void UpdateCameraTransform(){
Vec3 position = m_Transform.Position;
position.Y += m_Transform.Position.Y + 1.5f;
Vec3 position = m_Transform.Position + m_CameraTransform.Transform.Forward * CameraForwardOffset;
position.Y += m_Transform.Position.Y + CameraYOffset;
m_CameraTransform.Position = position;
}
}

View File

@ -7,4 +7,14 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Content Include="bin\Debug\net9.0\Prism-ScriptCore.deps.json" />
<Content Include="bin\Debug\net9.0\Prism-ScriptCore.dll" />
<Content Include="bin\Debug\net9.0\Prism-ScriptCore.pdb" />
<Content Include="bin\Release\net9.0\Prism-ScriptCore.deps.json" />
<Content Include="bin\Release\net9.0\Prism-ScriptCore.dll" />
<Content Include="bin\Release\net9.0\Prism-ScriptCore.pdb" />
<Content Include="Prism-ScriptCore.sln" />
</ItemGroup>
</Project>

View File

@ -1,5 +1,8 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
VisualStudioVersion = 18.1.11312.151 d18.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prism-ScriptCore", "Prism-ScriptCore.csproj", "{B94EF710-0487-4388-97E3-B650761A849C}"
EndProject
Global
@ -13,4 +16,10 @@ Global
{B94EF710-0487-4388-97E3-B650761A849C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B94EF710-0487-4388-97E3-B650761A849C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BA69725C-3CFE-4882-9EDF-2A8E92423E8F}
EndGlobalSection
EndGlobal

View File

@ -29,6 +29,29 @@ namespace Prism
Y = Mathf.Clamp(Y, min.Y, max.Y);
}
public float LengthSquared()
{
return X * X + Y * Y;
}
public float Length()
{
return (float)Math.Sqrt(X * X + Y * Y);
}
public Vec2 Normalized()
{
float length = Length();
return new Vec2(X / length, Y / length);
}
public void Normalize()
{
float length = Length();
X = X / length;
Y = Y / length;
}
public static Vec2 operator -(Vec2 l, Vec2 r)
{
return new Vec2(l.X - r.X, l.Y - r.Y);

View File

@ -60,6 +60,11 @@ namespace Prism
Z = Mathf.Clamp(Z, min.Z, max.Z);
}
public float LengthSquared()
{
return X * X + Y * Y + Z * Z;
}
public float Length()
{
return (float)Math.Sqrt(X * X + Y * Y + Z * Z);

View File

@ -268,6 +268,42 @@ namespace Prism::UI {
ImGui::TreePop();
}
static int s_CheckboxCount = 0;
static void BeginCheckboxGroup(const char* label)
{
ImGui::Text(label);
ImGui::NextColumn();
ImGui::PushItemWidth(-1);
}
static bool PropertyCheckboxGroup(const char* label, bool& value)
{
bool modified = false;
if (++s_CheckboxCount > 1)
ImGui::SameLine();
ImGui::Text(label);
ImGui::SameLine();
s_IDBuffer[0] = '#';
s_IDBuffer[1] = '#';
memset(s_IDBuffer + 2, 0, 14);
snprintf(s_IDBuffer + 2, 14, "%x", s_Counter++);
if (ImGui::Checkbox(s_IDBuffer, &value))
modified = true;
return modified;
}
static void EndCheckboxGroup()
{
ImGui::PopItemWidth();
ImGui::NextColumn();
s_CheckboxCount = 0;
}
}
#endif //IMGUI_H

View File

@ -367,15 +367,16 @@ namespace Prism
const bool open = ImGui::TreeNodeEx((void*)typeid(T).hash_code(), treeNodeFlags, name.c_str());
ImGui::PopStyleVar();
// TODO: should use address instead
ImGui::SameLine(contentRegionAvailable.x - lineHeight * 0.5f);
if (ImGui::Button("+", ImVec2{ lineHeight, lineHeight }))
if (ImGui::Button(("+##" + name).c_str(), ImVec2{ lineHeight, lineHeight }))
{
ImGui::OpenPopup("ComponentSettings");
ImGui::OpenPopup(("ComponentSettings" + name).c_str());
}
bool removeComponent = false;
if (ImGui::BeginPopup("ComponentSettings"))
if (ImGui::BeginPopup(("ComponentSettings" + name).c_str()))
{
if (ImGui::MenuItem("Remove component"))
removeComponent = true;
@ -799,23 +800,31 @@ namespace Prism
{
UI::BeginPropertyGrid();
UI::Property("Mass", rbc.Mass);
UI::Property("Linear Drag", rbc.LinearDrag);
UI::Property("Angular Drag", rbc.AngularDrag);
UI::Property("Disable Gravity", rbc.DisableGravity);
UI::Property("Is Kinematic", rbc.IsKinematic);
UI::EndPropertyGrid();
if (ImGui::TreeNode("RigidBodyConstraints", "Constraints"))
if (UI::BeginTreeNode("Constraints", false))
{
UI::BeginPropertyGrid();
UI::Property("Position: X", rbc.LockPositionX);
UI::Property("Position: Y", rbc.LockPositionY);
UI::Property("Position: Z", rbc.LockPositionZ);
UI::Property("Rotation: X", rbc.LockRotationX);
UI::Property("Rotation: Y", rbc.LockRotationY);
UI::Property("Rotation: Z", rbc.LockRotationZ);
UI::BeginCheckboxGroup("Freeze Position");
UI::PropertyCheckboxGroup("X", rbc.LockPositionX);
UI::PropertyCheckboxGroup("Y", rbc.LockPositionY);
UI::PropertyCheckboxGroup("Z", rbc.LockPositionZ);
UI::EndCheckboxGroup();
UI::BeginCheckboxGroup("Freeze Rotation");
UI::PropertyCheckboxGroup("X", rbc.LockRotationX);
UI::PropertyCheckboxGroup("Y", rbc.LockRotationY);
UI::PropertyCheckboxGroup("Z", rbc.LockRotationZ);
UI::EndCheckboxGroup();
UI::EndPropertyGrid();
ImGui::TreePop();
UI::EndTreeNode();
}
}
});

View File

@ -17,7 +17,8 @@
namespace Prism
{
static physx::PxScene* s_Scene;
static std::vector<Entity> s_SimulatedEntities;
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;
@ -87,52 +88,18 @@ namespace Prism
const auto transform = e.Transform();
physx::PxRigidActor* actor = PhysicsWrappers::CreateActor(rigidbody, transform);
if (rigidbody.BodyType == RigidBodyComponent::Type::Dynamic)
s_SimulatedEntities.push_back(e);
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->userData = (void*)entityStorage;
rigidbody.RuntimeActor = actor;
rigidbody.EntityBufferIndex = s_EntityStorageBufferPosition;
actor->SetRuntimeDataInternal((void *)entityStorage, s_EntityStorageBufferPosition);
s_EntityStorageBufferPosition++;
const physx::PxMaterial* material = PhysicsWrappers::CreateMaterial(e.GetComponent<PhysicsMaterialComponent>());
// Add all colliders
if (e.HasComponent<BoxColliderComponent>())
{
const BoxColliderComponent& collider = e.GetComponent<BoxColliderComponent>();
PhysicsWrappers::AddBoxCollider(*actor, *material, collider, transform.Scale);
}
if (e.HasComponent<SphereColliderComponent>())
{
const SphereColliderComponent& collider = e.GetComponent<SphereColliderComponent>();
PhysicsWrappers::AddSphereCollider(*actor, *material, collider, transform.Scale);
}
if (e.HasComponent<CapsuleColliderComponent>())
{
const CapsuleColliderComponent& collider = e.GetComponent<CapsuleColliderComponent>();
PhysicsWrappers::AddCapsuleCollider(*actor, *material, collider, transform.Scale);
}
if (e.HasComponent<MeshColliderComponent>())
{
auto& collider = e.GetComponent<MeshColliderComponent>();
PhysicsWrappers::AddMeshCollider(*actor, *material, collider, transform.Scale);
}
if (!PhysicsLayerManager::IsLayerValid(rigidbody.Layer))
rigidbody.Layer = 0;
PhysicsWrappers::SetCollisionFilters(*actor, rigidbody.Layer);
s_Scene->addActor(*actor);
}
void Physics3D::Simulate(TimeStep ts)
@ -146,25 +113,14 @@ namespace Prism
s_SimulationTime -= s_Settings.FixedTimestep;
for (const Entity& e : s_SimulatedEntities)
{
if (ScriptEngine::IsEntityModuleValid(e))
ScriptEngine::OnPhysicsUpdateEntity(e, s_Settings.FixedTimestep);
}
for (auto& actor : s_SimulatedActors)
actor->Update(s_Settings.FixedTimestep);
s_Scene->simulate(s_Settings.FixedTimestep);
s_Scene->fetchResults(true);
for (Entity& e : s_SimulatedEntities)
{
auto& transform = e.Transform();
const auto& rb = e.GetComponent<RigidBodyComponent>();
const auto actor = static_cast<physx::PxRigidActor*>(rb.RuntimeActor);
physx::PxTransform actorPose = actor->getGlobalPose();
transform.Translation = FromPhysXVector(actorPose.p);
transform.Rotation = glm::degrees(glm::eulerAngles(FromPhysXQuat(actorPose.q)));
}
for (auto& actor : s_SimulatedActors)
actor->SynchronizeTransform();
}
void Physics3D::DestroyScene()
@ -175,7 +131,8 @@ namespace Prism
s_EntityStorageBuffer = nullptr;
s_EntityStorageBufferPosition = 0;
s_SimulatedEntities.clear();
s_SimulatedActors.clear();
s_StaticActors.clear();
s_Scene->release();
s_Scene = nullptr;
}
@ -188,12 +145,12 @@ namespace Prism
bool Physics3D::ConnectPVD()
{
PM_CORE_INFO("Trying to connect PVD");
const bool isconnect = PhysicsWrappers::ConnectPVD();
if (isconnect)
const bool isConnect = PhysicsWrappers::ConnectPVD();
if (isConnect)
PM_CORE_INFO("PVD Connected");
else
PM_CORE_WARN("canot connect PVD!");
return isconnect;
PM_CORE_WARN("cannot connect PVD!");
return isConnect;
}
bool Physics3D::IsPVDConnected() {return PhysicsWrappers::IsPVDConnected();}

View File

@ -0,0 +1,121 @@
//
// Created by Atdunbg on 2026/1/10.
//
#include "PhysicsActor.h"
#include "Physics3D.h"
#include "PhysicsLayer.h"
#include "PhysicsWrappers.h"
#include "PxRigidActor.h"
#include "Prism/Script/ScriptEngine.h"
namespace Prism
{
PhysicsActor::PhysicsActor(Entity entity)
: m_Entity(entity), m_RigidBody(entity.GetComponent<RigidBodyComponent>())
{
m_Material = entity.GetComponent<PhysicsMaterialComponent>();
Create();
}
PhysicsActor::~PhysicsActor()
{
m_ActorInternal->release();
m_ActorInternal = nullptr;
}
void PhysicsActor::Create()
{
physx::PxPhysics& physics = PhysicsWrappers::GetPhysics();
if (m_RigidBody.BodyType == RigidBodyComponent::Type::Static)
{
m_ActorInternal = physics.createRigidStatic(ToPhysXTransform(m_Entity.Transform()));
}
else
{
const PhysicsSettings& settings = Physics3D::GetSettings();
physx::PxRigidDynamic* actor = physics.createRigidDynamic(ToPhysXTransform(m_Entity.Transform()));
actor->setLinearDamping(m_RigidBody.LinearDrag);
actor->setAngularDamping(m_RigidBody.AngularDrag);
actor->setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, m_RigidBody.IsKinematic);
actor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_X, m_RigidBody.LockPositionX);
actor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Y, m_RigidBody.LockPositionY);
actor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Z, m_RigidBody.LockPositionZ);
actor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_X, m_RigidBody.LockRotationX);
actor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y, m_RigidBody.LockRotationY);
actor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z, m_RigidBody.LockRotationZ);
actor->setActorFlag(physx::PxActorFlag::eDISABLE_GRAVITY, m_RigidBody.DisableGravity);
actor->setSolverIterationCounts(settings.SolverIterations, settings.SolverVelocityIterations);
physx::PxRigidBodyExt::updateMassAndInertia(*actor, m_RigidBody.Mass);
m_ActorInternal = actor;
}
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);
if (m_Entity.HasComponent<MeshColliderComponent>()) PhysicsWrappers::AddMeshCollider(*this, *physicsMat);
if (!PhysicsLayerManager::IsLayerValid(m_RigidBody.Layer))
m_RigidBody.Layer = 0;
SetLayer(m_RigidBody.Layer);
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)
{
if (!ScriptEngine::IsEntityModuleValid(m_Entity))
return;
ScriptEngine::OnPhysicsUpdateEntity(m_Entity, fixedTimestep);
}
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));
}
void PhysicsActor::SetLayer(uint32_t layer)
{
physx::PxAllocatorCallback& allocator = PhysicsWrappers::GetAllocator();
const PhysicsLayer& layerInfo = PhysicsLayerManager::GetLayer(layer);
if (layerInfo.CollidesWith == 0)
return;
physx::PxFilterData filterData;
filterData.word0 = layerInfo.BitValue;
filterData.word1 = layerInfo.CollidesWith;
const physx::PxU32 numShapes = m_ActorInternal->getNbShapes();
physx::PxShape** shapes = (physx::PxShape**)allocator.allocate(sizeof(physx::PxShape*) * numShapes, "", "", 0);
m_ActorInternal->getShapes(shapes, numShapes);
for (physx::PxU32 i = 0; i < numShapes; i++)
shapes[i]->setSimulationFilterData(filterData);
allocator.deallocate(shapes);
}
}

View File

@ -0,0 +1,49 @@
//
// Created by Atdunbg on 2026/1/10.
//
#ifndef PRISM_PHYSICSACTOR_H
#define PRISM_PHYSICSACTOR_H
#include "Prism/Core/Ref.h"
#include "Prism/Scene/Entity.h"
namespace physx
{
class PxRigidActor;
}
namespace Prism
{
class PhysicsActor : public RefCounted
{
public:
PhysicsActor(Entity entity);
~PhysicsActor();
void Update(float fixedTimestep);
void SynchronizeTransform();
void SetLayer(uint32_t layer);
bool IsDynamic() const { return m_RigidBody.BodyType == RigidBodyComponent::Type::Dynamic; }
Entity& GetEntity() { return m_Entity; }
private:
void Create();
void SetRuntimeDataInternal(void* entityStorage, int storageBufferPosition);
private:
Entity m_Entity;
RigidBodyComponent& m_RigidBody;
PhysicsMaterialComponent m_Material;
physx::PxRigidActor* m_ActorInternal;
friend class Physics3D;
friend class PhysicsWrappers;
};
}
#endif //PRISM_PHYSICSACTOR_H

View File

@ -177,70 +177,10 @@ namespace Prism
return s_Physics->createScene(sceneDesc);
}
physx::PxRigidActor* PhysicsWrappers::CreateActor(const RigidBodyComponent& rigidbody, const TransformComponent& transformComponent)
{
physx::PxRigidActor* actor = nullptr;
const auto transform = ToPhysXTransform(transformComponent.GetTransform());
const PhysicsSettings& settings = Physics3D::GetSettings();
if (rigidbody.BodyType == RigidBodyComponent::Type::Static)
{
actor = s_Physics->createRigidStatic(transform);
}
else if (rigidbody.BodyType == RigidBodyComponent::Type::Dynamic)
{
physx::PxRigidDynamic* dynamicActor = s_Physics->createRigidDynamic(transform);
dynamicActor->setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, rigidbody.IsKinematic);
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_X, rigidbody.LockPositionX);
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Y, rigidbody.LockPositionY);
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Z, rigidbody.LockPositionZ);
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_X, rigidbody.LockRotationX);
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y, rigidbody.LockRotationY);
dynamicActor->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z, rigidbody.LockRotationZ);
dynamicActor->setSleepThreshold(0.1f);
dynamicActor->setAngularVelocity({1,1,1});
dynamicActor->setActorFlag(physx::PxActorFlag::eDISABLE_SIMULATION, false);
dynamicActor->setSolverIterationCounts(settings.SolverIterations, settings.SolverVelocityIterations);
// using OnWake and OnSleep callback should enable eSEND_SLEEP_NOTIFIES
// https://nvidia-omniverse.github.io/PhysX/physx/5.6.1/_api_build/classPxSimulationEventCallback.html#_CPPv4N25PxSimulationEventCallback6onWakeEPP7PxActor5PxU32
dynamicActor->setActorFlag(physx::PxActorFlag::eSEND_SLEEP_NOTIFIES, true);
physx::PxRigidBodyExt::updateMassAndInertia(*dynamicActor, rigidbody.Mass);
actor = dynamicActor;
}
return actor;
}
void PhysicsWrappers::SetCollisionFilters(const physx::PxRigidActor& actor, uint32_t physicsLayer)
{
const PhysicsLayer& layerInfo = PhysicsLayerManager::GetLayer(physicsLayer);
if (layerInfo.CollidesWith == 0)
return;
physx::PxFilterData filterData;
filterData.word0 = layerInfo.BitValue;
filterData.word1 = layerInfo.CollidesWith;
const physx::PxU32 numShapes = actor.getNbShapes();
const auto shapes = static_cast<physx::PxShape**>(s_Allocator.allocate(sizeof(physx::PxShape*) * numShapes, "", "", 0));
actor.getShapes(shapes, numShapes);
for (physx::PxU32 i = 0; i < numShapes; i++)
shapes[i]->setSimulationFilterData(filterData);
s_Allocator.deallocate(shapes);
}
void PhysicsWrappers::AddBoxCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const BoxColliderComponent& collider, const glm::vec3& scale)
void PhysicsWrappers::AddBoxCollider(PhysicsActor& actor, const physx::PxMaterial& material)
{
const auto& collider = actor.m_Entity.GetComponent<BoxColliderComponent>();
const glm::vec3 scale = actor.m_Entity.Transform().Scale;
glm::vec3 colliderSize = collider.Size;
if (scale.x != 0.0f) colliderSize.x *= scale.x;
@ -249,28 +189,34 @@ namespace Prism
const auto boxGeometry = physx::PxBoxGeometry(colliderSize.x / 2.0f, colliderSize.y / 2.0f, colliderSize.z / 2.0f);
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, boxGeometry, material);
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor.m_ActorInternal, boxGeometry, material);
// physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, boxGeometry, material);
shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !collider.IsTrigger);
shape->setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, collider.IsTrigger);
shape->setLocalPose(ToPhysXTransform(glm::translate(glm::mat4(1.0F), collider.Offset)));
}
void PhysicsWrappers::AddSphereCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const SphereColliderComponent& collider, const glm::vec3& scale)
void PhysicsWrappers::AddSphereCollider(PhysicsActor& actor, const physx::PxMaterial& material)
{
const auto& collider = actor.m_Entity.GetComponent<SphereColliderComponent>();
const glm::vec3 scale = actor.m_Entity.Transform().Scale;
float colliderRadius = collider.Radius;
if (scale.x != 0.0f) colliderRadius *= scale.x;
const auto sphereGeometry = physx::PxSphereGeometry(colliderRadius);
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, sphereGeometry, material);
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor.m_ActorInternal, sphereGeometry, material);
// 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);
}
void PhysicsWrappers::AddCapsuleCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material,const CapsuleColliderComponent& collider, const glm::vec3& scale)
void PhysicsWrappers::AddCapsuleCollider(PhysicsActor& actor, const physx::PxMaterial& material)
{
const auto& collider = actor.m_Entity.GetComponent<CapsuleColliderComponent>();
const glm::vec3 scale = actor.m_Entity.Transform().Scale;
float colliderRadius = collider.Radius;
float colliderHeight = collider.Height;
@ -280,16 +226,18 @@ namespace Prism
const auto capsuleGeometry = physx::PxCapsuleGeometry(colliderRadius, colliderHeight * 0.5f);
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, capsuleGeometry, material);
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(*actor.m_ActorInternal, capsuleGeometry, material);
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))));
}
void PhysicsWrappers::AddMeshCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material,MeshColliderComponent& collider, const glm::vec3& scale)
void PhysicsWrappers::AddMeshCollider(PhysicsActor& actor, const physx::PxMaterial& material)
{
auto& collider = actor.m_Entity.GetComponent<MeshColliderComponent>();
glm::vec3 scale = actor.m_Entity.Transform().Scale;
if (collider.IsConvex)
{
std::vector<physx::PxConvexMesh*> meshes = CreateConvexMesh(collider, true);
@ -298,7 +246,7 @@ namespace Prism
{
physx::PxConvexMeshGeometry convexGeometry = physx::PxConvexMeshGeometry(mesh, physx::PxMeshScale(ToPhysXVector(scale)));
convexGeometry.meshFlags = physx::PxConvexMeshGeometryFlag::eTIGHT_BOUNDS;
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, convexGeometry, material);
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);
}
@ -310,7 +258,7 @@ namespace Prism
for (const auto mesh : meshes)
{
physx::PxTriangleMeshGeometry convexGeometry = physx::PxTriangleMeshGeometry(mesh, physx::PxMeshScale(ToPhysXVector(scale)));
physx::PxShape* shape = physx::PxRigidActorExt::createExclusiveShape(actor, convexGeometry, material);
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);
}
@ -633,11 +581,6 @@ namespace Prism
#endif
}
physx::PxMaterial* PhysicsWrappers::CreateMaterial(const PhysicsMaterialComponent& material)
{
return s_Physics->createMaterial(material.StaticFriction, material.DynamicFriction, material.Bounciness);
}
bool PhysicsWrappers::Raycast(const glm::vec3& origin, const glm::vec3& direction, float maxDistance, RaycastHit* hit)
{
const auto* scene = static_cast<physx::PxScene*>(Physics3D::GetPhysicsScene());
@ -746,6 +689,16 @@ namespace Prism
s_Foundation->release();
}
physx::PxPhysics& PhysicsWrappers::GetPhysics()
{
return *s_Physics;
}
physx::PxAllocatorCallback& PhysicsWrappers::GetAllocator()
{
return s_Allocator;
}
bool PhysicsWrappers::ConnectPVD()
{
bool isConnect = false;

View File

@ -5,6 +5,7 @@
#ifndef PHYSICSWRAPPERS_H
#define PHYSICSWRAPPERS_H
#include "PhysicsActor.h"
#include "PhysicsUtils.h"
#define OVERLAP_MAX_COLLIDERS 10
@ -36,20 +37,25 @@ namespace Prism
{
public:
static physx::PxScene* CreateScene();
static physx::PxRigidActor* CreateActor(const RigidBodyComponent& rigidbody, const TransformComponent& transformComponent);
static void SetCollisionFilters(const physx::PxRigidActor& actor, uint32_t physicsLayer);
// static physx::PxRigidActor* CreateActor(const RigidBodyComponent& rigidbody, const TransformComponent& transformComponent);
// static void SetCollisionFilters(const physx::PxRigidActor& actor, uint32_t physicsLayer);
static void AddBoxCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const BoxColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f));
static void AddSphereCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const SphereColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f));
static void AddCapsuleCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const CapsuleColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f));
static void AddMeshCollider(::physx::PxRigidActor& actor, const ::physx::PxMaterial& material, ::Prism::MeshColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f));
static void AddBoxCollider(PhysicsActor& actor, const physx::PxMaterial& material);
static void AddSphereCollider(PhysicsActor& actor, const physx::PxMaterial& material);
static void AddCapsuleCollider(PhysicsActor& actor, const physx::PxMaterial& material);
static void AddMeshCollider(PhysicsActor& actor, const physx::PxMaterial& material);
// static void AddBoxCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const BoxColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f));
// static void AddSphereCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const SphereColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f));
// static void AddCapsuleCollider(physx::PxRigidActor& actor, const physx::PxMaterial& material, const CapsuleColliderComponent& collider, const glm::vec3& scale = glm::vec3(0.0f));
// 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 physx::PxMaterial* CreateMaterial(const PhysicsMaterialComponent& material);
// static physx::PxMaterial* CreateMaterial(const PhysicsMaterialComponent& material);
static bool Raycast(const glm::vec3& origin, const glm::vec3& direction, float maxDistance, RaycastHit* hit);
/*
static bool OverlapBox(const glm::vec3& origin, const glm::vec3& halfSize, std::vector<physx::PxOverlapHit>& buffer);
@ -63,6 +69,8 @@ namespace Prism
static void Initialize();
static void Shutdown();
static physx::PxPhysics& GetPhysics();
static physx::PxAllocatorCallback& GetAllocator();
static bool ConnectPVD();
static bool IsPVDConnected();
@ -70,6 +78,7 @@ namespace Prism
private:
friend class Physics3D;
friend class PhysicsActor;
};
}

View File

@ -405,8 +405,8 @@ namespace Prism
void SceneRenderer::GeometryPass()
{
const bool outline = s_Data.SelectedMeshDrawList.size() > 0;
const bool collider = s_Data.ColliderDrawList.size() > 0;
const bool outline = !s_Data.SelectedMeshDrawList.empty();
const bool collider = !s_Data.ColliderDrawList.empty();
if (outline || collider)
{
@ -923,6 +923,10 @@ namespace Prism
if (UI::BeginTreeNode("Shadows"))
{
UI::Property("Composite Pass time: %.2fs", s_Stats.CompositePass);
UI::Property("Geometry Pass time: %.2fs", s_Stats.GeometryPass);
UI::Property("Shadow Pass time: %.2fs", s_Stats.ShadowPass);
UI::BeginPropertyGrid();
UI::Property("Soft Shadows", s_Data.SoftShadows);
UI::Property("Light Size", s_Data.LightSize, 0.01f);

View File

@ -168,6 +168,9 @@ namespace Prism
enum class Type { Static, Dynamic};
Type BodyType;
float Mass = 1.0f;
float LinearDrag = 0.0F;
float AngularDrag = 0.05F;
bool DisableGravity = false;
bool IsKinematic = false;
uint32_t Layer = 0;

View File

@ -330,7 +330,7 @@ namespace Prism
auto group = m_Registry.group<MeshComponent>(entt::get<TransformComponent>);
// SceneRenderer::BeginScene(this, { static_cast<Camera>(editorCamera), editorCamera.GetViewMatrix() });
SceneRenderer::BeginScene(this, { static_cast<Camera>(editorCamera), editorCamera.GetViewMatrix(), 0.1f, 1000.0f, 45.0f }); // TODO: real values
for (auto entity : group)
for (const auto entity : group)
{
const auto& [transformComponent, meshComponent] = group.get<TransformComponent, MeshComponent>(entity);
if (meshComponent.Mesh)
@ -339,12 +339,17 @@ namespace Prism
// TODO: Should we render (logically)
SceneRenderer::SubmitMesh(meshComponent, transformComponent.GetTransform());
if (m_SelectedEntity == entity)
{
SceneRenderer::SubmitSelectedMesh(meshComponent, transformComponent.GetTransform());
}
}
}
{
auto view = m_Registry.view<BoxColliderComponent>();
for (auto entity : view)
const auto view = m_Registry.view<BoxColliderComponent>();
for (const auto entity : view)
{
Entity e = { entity, this };
auto& collider = e.GetComponent<BoxColliderComponent>();
@ -356,7 +361,7 @@ namespace Prism
{
const auto view = m_Registry.view<SphereColliderComponent>();
for (auto entity : view)
for (const auto entity : view)
{
Entity e = { entity, this };
auto& collider = e.GetComponent<SphereColliderComponent>();
@ -368,7 +373,7 @@ namespace Prism
{
const auto view = m_Registry.view<CapsuleColliderComponent>();
for (auto entity : view)
for (const auto entity : view)
{
Entity e = { entity, this };
auto& collider = e.GetComponent<CapsuleColliderComponent>();
@ -380,7 +385,7 @@ namespace Prism
{
const auto view = m_Registry.view<MeshColliderComponent>();
for (auto entity : view)
for (const auto entity : view)
{
Entity e = { entity, this };
auto& collider = e.GetComponent<MeshColliderComponent>();

View File

@ -584,6 +584,7 @@ namespace Prism { namespace Script {
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 });
}