forked from LeenkxTeam/LNXSDK
@ -1,190 +0,0 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.math.Vec4;
|
||||
import iron.math.Quat;
|
||||
import iron.math.Mat4;
|
||||
import iron.object.Object;
|
||||
|
||||
class SetLookAtRotationNode extends LogicNode {
|
||||
|
||||
public var property0: String; // Axis to align
|
||||
public var property1: String; // Use vector for target (true/false)
|
||||
public var property2: String; // Use vector for source (true/false)
|
||||
public var property3: String; // Damping value (backward compatibility, now input socket)
|
||||
public var property4: String; // Disable rotation on aligning axis (true/false)
|
||||
|
||||
// Store the calculated rotation for output
|
||||
var calculatedRotation: Quat = null;
|
||||
// Store the previous rotation for smooth interpolation
|
||||
var previousRotation: Quat = null;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
previousRotation = new Quat();
|
||||
}
|
||||
|
||||
override function run(from: Int): Void {
|
||||
// Determine if we're using a vector or an object as source
|
||||
var useSourceVector: Bool = property2 == "true";
|
||||
var objectToUse: Object = null;
|
||||
var objectLoc: Vec4 = null;
|
||||
|
||||
if (useSourceVector) {
|
||||
// Use tree.object as the object to rotate
|
||||
objectToUse = tree.object;
|
||||
if (objectToUse == null) {
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the source location directly
|
||||
objectLoc = inputs[1].get();
|
||||
if (objectLoc == null) {
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Get the source object (or fallback to tree.object)
|
||||
objectToUse = (inputs.length > 1 && inputs[1] != null) ? inputs[1].get() : tree.object;
|
||||
if (objectToUse == null) {
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get source object's position
|
||||
objectLoc = objectToUse.transform.loc;
|
||||
}
|
||||
|
||||
// Determine if we're using a vector or an object as target
|
||||
var useTargetVector: Bool = property1 == "true";
|
||||
var targetLoc: Vec4 = null;
|
||||
|
||||
if (useTargetVector) {
|
||||
// Get the target location directly
|
||||
targetLoc = inputs[2].get();
|
||||
if (targetLoc == null) {
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Get the target object
|
||||
var targetObject: Object = inputs[2].get();
|
||||
if (targetObject == null) {
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get target object's position
|
||||
targetLoc = targetObject.transform.loc;
|
||||
}
|
||||
|
||||
// Calculate direction to target
|
||||
var direction = new Vec4(
|
||||
targetLoc.x - objectLoc.x,
|
||||
targetLoc.y - objectLoc.y,
|
||||
targetLoc.z - objectLoc.z
|
||||
);
|
||||
direction.normalize();
|
||||
|
||||
// Calculate target rotation based on selected axis
|
||||
calculatedRotation = new Quat();
|
||||
switch (property0) {
|
||||
case "X":
|
||||
calculatedRotation.fromTo(new Vec4(1, 0, 0), direction);
|
||||
case "-X":
|
||||
calculatedRotation.fromTo(new Vec4(-1, 0, 0), direction);
|
||||
case "Y":
|
||||
calculatedRotation.fromTo(new Vec4(0, 1, 0), direction);
|
||||
case "-Y":
|
||||
calculatedRotation.fromTo(new Vec4(0, -1, 0), direction);
|
||||
case "Z":
|
||||
calculatedRotation.fromTo(new Vec4(0, 0, 1), direction);
|
||||
case "-Z":
|
||||
calculatedRotation.fromTo(new Vec4(0, 0, -1), direction);
|
||||
}
|
||||
|
||||
// If disable rotation on aligning axis is enabled, constrain the target rotation
|
||||
if (property4 == "true") {
|
||||
// Apply constraint to the target rotation BEFORE damping to avoid jiggling
|
||||
var eulerAngles = calculatedRotation.toEulerOrdered("XYZ");
|
||||
|
||||
// Set the rotation around the selected axis to 0
|
||||
switch (property0) {
|
||||
case "X", "-X":
|
||||
eulerAngles.x = 0.0;
|
||||
case "Y", "-Y":
|
||||
eulerAngles.y = 0.0;
|
||||
case "Z", "-Z":
|
||||
eulerAngles.z = 0.0;
|
||||
}
|
||||
|
||||
// Convert back to quaternion
|
||||
calculatedRotation.fromEulerOrdered(eulerAngles, "XYZ");
|
||||
}
|
||||
|
||||
// Apply rotation with damping
|
||||
var dampingValue: Float = 0.0;
|
||||
|
||||
// Try to get damping from input socket first (index 3), fallback to property
|
||||
if (inputs.length > 3 && inputs[3] != null) {
|
||||
var dampingInput: Dynamic = inputs[3].get();
|
||||
if (dampingInput != null) {
|
||||
dampingValue = dampingInput;
|
||||
}
|
||||
} else {
|
||||
// Fallback to property for backward compatibility
|
||||
dampingValue = Std.parseFloat(property3);
|
||||
}
|
||||
|
||||
if (dampingValue > 0.0) {
|
||||
// Create a fixed interpolation rate that never reaches exactly 1.0
|
||||
// Higher damping = slower rotation (smaller step)
|
||||
var step = Math.max(0.001, (1.0 - dampingValue) * 0.2); // 0.001 to 0.2 range
|
||||
|
||||
// Get current rotation as quaternion
|
||||
var currentRot = new Quat().setFrom(objectToUse.transform.rot);
|
||||
|
||||
// Calculate the difference between current and target rotation
|
||||
var diffQuat = new Quat();
|
||||
// q1 * inverse(q2) gives the rotation from q2 to q1
|
||||
var invCurrent = new Quat().setFrom(currentRot);
|
||||
invCurrent.x = -invCurrent.x;
|
||||
invCurrent.y = -invCurrent.y;
|
||||
invCurrent.z = -invCurrent.z;
|
||||
diffQuat.multquats(calculatedRotation, invCurrent);
|
||||
|
||||
// Convert to axis-angle representation
|
||||
var axis = new Vec4();
|
||||
var angle = diffQuat.toAxisAngle(axis);
|
||||
|
||||
// Apply only a portion of this rotation (step)
|
||||
var partialAngle = angle * step;
|
||||
|
||||
// Create partial rotation quaternion
|
||||
var partialRot = new Quat().fromAxisAngle(axis, partialAngle);
|
||||
|
||||
// Apply this partial rotation to current
|
||||
var newRot = new Quat();
|
||||
newRot.multquats(partialRot, currentRot);
|
||||
|
||||
// Apply the new rotation
|
||||
objectToUse.transform.rot.setFrom(newRot);
|
||||
} else {
|
||||
// No damping, apply instant rotation
|
||||
objectToUse.transform.rot.setFrom(calculatedRotation);
|
||||
}
|
||||
|
||||
objectToUse.transform.buildMatrix();
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
// Getter method for output sockets
|
||||
override function get(from: Int): Dynamic {
|
||||
// Output index 1 is the rotation socket (global rotation)
|
||||
if (from == 1) {
|
||||
return calculatedRotation;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user