@babylonjs/core
Version:
Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.
96 lines • 4.15 kB
JavaScript
import { FlowGraphEventBlock } from "../../flowGraphEventBlock.js";
import { RegisterClass } from "../../../Misc/typeStore.js";
import { RichTypeAny, RichTypeNumber, RichTypeVector3 } from "../../flowGraphRichTypes.js";
/**
* @experimental
* An event block that fires when a physics collision occurs on the specified body.
* Subscribes to the body's collision observable and exposes collision details
* (the other body, contact point, normal, impulse, and distance) as data outputs.
*/
export class FlowGraphPhysicsCollisionEventBlock extends FlowGraphEventBlock {
/**
* Constructs a new FlowGraphPhysicsCollisionEventBlock.
* @param config - optional configuration for the block
*/
constructor(
/**
* the configuration of the block
*/
config) {
super(config);
this.config = config;
this.body = this.registerDataInput("body", RichTypeAny);
this.otherBody = this.registerDataOutput("otherBody", RichTypeAny);
this.point = this.registerDataOutput("point", RichTypeVector3);
this.normal = this.registerDataOutput("normal", RichTypeVector3);
this.impulse = this.registerDataOutput("impulse", RichTypeNumber);
this.distance = this.registerDataOutput("distance", RichTypeNumber);
}
/**
* @internal
*/
_preparePendingTasks(context) {
const physicsBody = this.body.getValue(context);
if (!physicsBody) {
this._reportError(context, "No physics body provided for collision event");
return;
}
// Enable collision callbacks on the body
physicsBody.setCollisionCallbackEnabled(true);
const observer = physicsBody.getCollisionObservable().add((event) => {
this._onCollision(context, event);
});
// Store observer and subscribed body per-context so multi-context usage is safe
// and cleanup can target the original body even if the input changes.
context._setExecutionVariable(this, "_collisionObserver", observer);
context._setExecutionVariable(this, "_subscribedBody", physicsBody);
}
_onCollision(context, event) {
const physicsBody = this.body.getValue(context);
// Determine the "other" body from the collision pair
const other = event.collider === physicsBody ? event.collidedAgainst : event.collider;
this.otherBody.setValue(other, context);
if (event.point) {
this.point.setValue(event.point, context);
}
if (event.normal) {
this.normal.setValue(event.normal, context);
}
this.impulse.setValue(event.impulse, context);
this.distance.setValue(event.distance, context);
this._execute(context);
}
/**
* @internal
*/
_executeEvent(_context, _payload) {
// This block manages its own observable subscription, so the
// central event coordinator does not dispatch to it.
return true;
}
/**
* @internal
*/
_cancelPendingTasks(context) {
const observer = context._getExecutionVariable(this, "_collisionObserver", null);
const subscribedBody = context._getExecutionVariable(this, "_subscribedBody", null);
if (observer && subscribedBody) {
const observable = subscribedBody.getCollisionObservable();
observable.remove(observer);
// Disable collision callbacks if no other observers remain
if (!observable.hasObservers()) {
subscribedBody.setCollisionCallbackEnabled(false);
}
}
context._setExecutionVariable(this, "_collisionObserver", null);
context._setExecutionVariable(this, "_subscribedBody", null);
}
/**
* @returns class name of the block.
*/
getClassName() {
return "FlowGraphPhysicsCollisionEventBlock" /* FlowGraphBlockNames.PhysicsCollisionEvent */;
}
}
RegisterClass("FlowGraphPhysicsCollisionEventBlock" /* FlowGraphBlockNames.PhysicsCollisionEvent */, FlowGraphPhysicsCollisionEventBlock);
//# sourceMappingURL=flowGraphPhysicsCollisionEventBlock.js.map