Files
LNXSDK/leenkx/Sources/leenkx/logicnode/OnContactNode.hx

104 lines
2.8 KiB
Haxe

package leenkx.logicnode;
import iron.object.Object;
import leenkx.trait.physics.RigidBody;
class OnContactNode extends LogicNode {
public var property0: String; // Contact type: "begin", "overlap", "end"
public var property1: Bool; // "On Any Object" checkbox
// Cache for performance optimization
var cachedRb1: RigidBody = null;
var cachedRb2: RigidBody = null;
var lastObject1: Object = null;
var lastObject2: Object = null;
var lastObject1TraitCount: Int = 0;
var lastObject2TraitCount: Int = 0;
var lastContact = false; // Track previous contact state
public function new(tree: LogicTree) {
super(tree);
// Subscribe to update events for event-based triggering
tree.notifyOnUpdate(update);
}
function update() {
var object1: Object = inputs[0].get();
if (object1 == null) return;
#if lnx_physics
// Smart caching: update cache if object changes OR if trait count changes
var shouldUpdateCache1 = (object1 != lastObject1) ||
(lastObject1 != null && lastObject1.traits.length != lastObject1TraitCount);
if (shouldUpdateCache1) {
cachedRb1 = object1.getTrait(RigidBody);
lastObject1 = object1;
lastObject1TraitCount = object1.traits.length;
}
if (cachedRb1 == null) return;
var rbs = leenkx.trait.physics.PhysicsWorld.active.getContacts(cachedRb1);
if (rbs == null || rbs.length == 0) {
// No contacts - handle "end" event
if (lastContact && property0 == "end") {
runOutput(0);
}
lastContact = false;
return;
}
// Check for contact
var contact = false;
// If "On Any Object" mode, any contact is valid
if (property1) {
contact = true;
} else {
// Specific object mode - check if second input exists
if (inputs.length <= 1) return;
var object2: Object = inputs[1].get();
if (object2 == null) return;
// Smart caching for second object
var shouldUpdateCache2 = (object2 != lastObject2) ||
(lastObject2 != null && lastObject2.traits.length != lastObject2TraitCount);
if (shouldUpdateCache2) {
cachedRb2 = object2.getTrait(RigidBody);
lastObject2 = object2;
lastObject2TraitCount = object2.traits.length;
}
if (cachedRb2 == null) return;
// Check if target object is in contact list
contact = rbs.indexOf(cachedRb2) >= 0;
}
// Handle different contact event types
var shouldTrigger = false;
switch (property0) {
case "begin":
shouldTrigger = contact && !lastContact;
case "overlap":
shouldTrigger = contact;
case "end":
shouldTrigger = !contact && lastContact;
}
lastContact = contact;
if (shouldTrigger) {
runOutput(0);
}
#end
}
// Keep the get method for backward compatibility, but it's not the primary interface
override function get(from: Int): Dynamic {
return lastContact;
}
}