feat(physics): dispatch PhysX simulation events to scene scripts

This commit is contained in:
2026-04-15 13:36:39 +08:00
parent 077786e4c7
commit 51aea47c83
20 changed files with 955 additions and 7 deletions

View File

@@ -7,6 +7,51 @@
namespace XCEngine {
namespace Components {
namespace {
Scripting::ScriptPhysicsMessage ToScriptPhysicsMessage(Physics::PhysicsEventType type) {
switch (type) {
case Physics::PhysicsEventType::CollisionEnter:
return Scripting::ScriptPhysicsMessage::CollisionEnter;
case Physics::PhysicsEventType::CollisionStay:
return Scripting::ScriptPhysicsMessage::CollisionStay;
case Physics::PhysicsEventType::CollisionExit:
return Scripting::ScriptPhysicsMessage::CollisionExit;
case Physics::PhysicsEventType::TriggerEnter:
return Scripting::ScriptPhysicsMessage::TriggerEnter;
case Physics::PhysicsEventType::TriggerStay:
return Scripting::ScriptPhysicsMessage::TriggerStay;
case Physics::PhysicsEventType::TriggerExit:
default:
return Scripting::ScriptPhysicsMessage::TriggerExit;
}
}
void DispatchPhysicsEventToComponent(Component& component, const Physics::PhysicsEvent& event) {
switch (event.type) {
case Physics::PhysicsEventType::CollisionEnter:
component.OnCollisionEnter(event.other);
return;
case Physics::PhysicsEventType::CollisionStay:
component.OnCollisionStay(event.other);
return;
case Physics::PhysicsEventType::CollisionExit:
component.OnCollisionExit(event.other);
return;
case Physics::PhysicsEventType::TriggerEnter:
component.OnTriggerEnter(event.other);
return;
case Physics::PhysicsEventType::TriggerStay:
component.OnTriggerStay(event.other);
return;
case Physics::PhysicsEventType::TriggerExit:
component.OnTriggerExit(event.other);
return;
}
}
} // namespace
SceneRuntime::SceneRuntime()
: m_uiRuntime(std::make_unique<UI::Runtime::UISceneRuntimeContext>()) {
}
@@ -74,6 +119,27 @@ void SceneRuntime::FixedUpdate(float fixedDeltaTime) {
m_scene->FixedUpdate(fixedDeltaTime);
if (m_physicsWorld) {
m_physicsWorld->Step(fixedDeltaTime);
std::vector<Physics::PhysicsEvent> physicsEvents;
m_physicsWorld->ConsumeSimulationEvents(physicsEvents);
for (const Physics::PhysicsEvent& event : physicsEvents) {
if (!event.self || !event.other || !event.self->IsActiveInHierarchy()) {
continue;
}
for (Component* component : event.self->GetComponents<Component>()) {
if (!component || !component->IsEnabled()) {
continue;
}
DispatchPhysicsEventToComponent(*component, event);
}
Scripting::ScriptEngine::Get().DispatchPhysicsMessage(
event.self,
ToScriptPhysicsMessage(event.type),
event.other);
}
}
}