forked from LeenkxTeam/LNXSDK
		
	Merge pull request 'main' (#88) from wuaieyo/LNXSDK:main into main
Reviewed-on: LeenkxTeam/LNXSDK#88
This commit is contained in:
		@ -12,6 +12,7 @@ class SetLookAtRotationNode extends LogicNode {
 | 
				
			|||||||
	public var property2: String; // Use vector for source (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 property3: String; // Damping value (backward compatibility, now input socket)
 | 
				
			||||||
	public var property4: String; // Disable rotation on aligning axis (true/false)
 | 
						public var property4: String; // Disable rotation on aligning axis (true/false)
 | 
				
			||||||
 | 
						public var property5: String; // Use local space (true/false)
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	// Store the calculated rotation for output
 | 
						// Store the calculated rotation for output
 | 
				
			||||||
	var calculatedRotation: Quat = null;
 | 
						var calculatedRotation: Quat = null;
 | 
				
			||||||
@ -51,8 +52,8 @@ class SetLookAtRotationNode extends LogicNode {
 | 
				
			|||||||
				return;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Get source object's position
 | 
								// Get source object's WORLD position (important for child objects)
 | 
				
			||||||
			objectLoc = objectToUse.transform.loc;
 | 
								objectLoc = new Vec4(objectToUse.transform.worldx(), objectToUse.transform.worldy(), objectToUse.transform.worldz());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Determine if we're using a vector or an object as target
 | 
							// Determine if we're using a vector or an object as target
 | 
				
			||||||
@ -74,8 +75,8 @@ class SetLookAtRotationNode extends LogicNode {
 | 
				
			|||||||
				return;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			// Get target object's position
 | 
								// Get target object's WORLD position (important for child objects)
 | 
				
			||||||
			targetLoc = targetObject.transform.loc;
 | 
								targetLoc = new Vec4(targetObject.transform.worldx(), targetObject.transform.worldy(), targetObject.transform.worldz());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		// Calculate direction to target
 | 
							// Calculate direction to target
 | 
				
			||||||
@ -122,6 +123,28 @@ class SetLookAtRotationNode extends LogicNode {
 | 
				
			|||||||
			calculatedRotation.fromEulerOrdered(eulerAngles, "XYZ");
 | 
								calculatedRotation.fromEulerOrdered(eulerAngles, "XYZ");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
 | 
							// Convert world rotation to local rotation if local space is enabled and object has a parent
 | 
				
			||||||
 | 
							var targetRotation = new Quat();
 | 
				
			||||||
 | 
							if (property5 == "true" && objectToUse.parent != null) {
 | 
				
			||||||
 | 
								// Get parent's world rotation
 | 
				
			||||||
 | 
								var parentWorldLoc = new Vec4();
 | 
				
			||||||
 | 
								var parentWorldRot = new Quat();
 | 
				
			||||||
 | 
								var parentWorldScale = new Vec4();
 | 
				
			||||||
 | 
								objectToUse.parent.transform.world.decompose(parentWorldLoc, parentWorldRot, parentWorldScale);
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								// Convert world rotation to local space by removing parent's rotation influence
 | 
				
			||||||
 | 
								// local_rotation = inverse(parent_world_rotation) * world_rotation
 | 
				
			||||||
 | 
								var invParentRot = new Quat().setFrom(parentWorldRot);
 | 
				
			||||||
 | 
								invParentRot.x = -invParentRot.x;
 | 
				
			||||||
 | 
								invParentRot.y = -invParentRot.y;
 | 
				
			||||||
 | 
								invParentRot.z = -invParentRot.z;
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								targetRotation.multquats(invParentRot, calculatedRotation);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// No local space conversion needed, use world rotation directly
 | 
				
			||||||
 | 
								targetRotation.setFrom(calculatedRotation);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		// Apply rotation with damping
 | 
							// Apply rotation with damping
 | 
				
			||||||
		var dampingValue: Float = 0.0;
 | 
							var dampingValue: Float = 0.0;
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
@ -141,17 +164,17 @@ class SetLookAtRotationNode extends LogicNode {
 | 
				
			|||||||
			// Higher damping = slower rotation (smaller step)
 | 
								// Higher damping = slower rotation (smaller step)
 | 
				
			||||||
			var step = Math.max(0.001, (1.0 - dampingValue) * 0.2); // 0.001 to 0.2 range
 | 
								var step = Math.max(0.001, (1.0 - dampingValue) * 0.2); // 0.001 to 0.2 range
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			// Get current rotation as quaternion
 | 
								// Get current local rotation as quaternion
 | 
				
			||||||
			var currentRot = new Quat().setFrom(objectToUse.transform.rot);
 | 
								var currentLocalRot = new Quat().setFrom(objectToUse.transform.rot);
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			// Calculate the difference between current and target rotation
 | 
								// Calculate the difference between current and target rotation
 | 
				
			||||||
			var diffQuat = new Quat();
 | 
								var diffQuat = new Quat();
 | 
				
			||||||
			// q1 * inverse(q2) gives the rotation from q2 to q1
 | 
								// q1 * inverse(q2) gives the rotation from q2 to q1
 | 
				
			||||||
			var invCurrent = new Quat().setFrom(currentRot);
 | 
								var invCurrent = new Quat().setFrom(currentLocalRot);
 | 
				
			||||||
			invCurrent.x = -invCurrent.x;
 | 
								invCurrent.x = -invCurrent.x;
 | 
				
			||||||
			invCurrent.y = -invCurrent.y;
 | 
								invCurrent.y = -invCurrent.y;
 | 
				
			||||||
			invCurrent.z = -invCurrent.z;
 | 
								invCurrent.z = -invCurrent.z;
 | 
				
			||||||
			diffQuat.multquats(calculatedRotation, invCurrent);
 | 
								diffQuat.multquats(targetRotation, invCurrent);
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			// Convert to axis-angle representation
 | 
								// Convert to axis-angle representation
 | 
				
			||||||
			var axis = new Vec4();
 | 
								var axis = new Vec4();
 | 
				
			||||||
@ -163,15 +186,15 @@ class SetLookAtRotationNode extends LogicNode {
 | 
				
			|||||||
			// Create partial rotation quaternion
 | 
								// Create partial rotation quaternion
 | 
				
			||||||
			var partialRot = new Quat().fromAxisAngle(axis, partialAngle);
 | 
								var partialRot = new Quat().fromAxisAngle(axis, partialAngle);
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			// Apply this partial rotation to current
 | 
								// Apply this partial rotation to current local rotation
 | 
				
			||||||
			var newRot = new Quat();
 | 
								var newLocalRot = new Quat();
 | 
				
			||||||
			newRot.multquats(partialRot, currentRot);
 | 
								newLocalRot.multquats(partialRot, currentLocalRot);
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			// Apply the new rotation
 | 
								// Apply the new local rotation
 | 
				
			||||||
			objectToUse.transform.rot.setFrom(newRot);
 | 
								objectToUse.transform.rot.setFrom(newLocalRot);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			// No damping, apply instant rotation
 | 
								// No damping, apply instant rotation
 | 
				
			||||||
			objectToUse.transform.rot.setFrom(calculatedRotation);
 | 
								objectToUse.transform.rot.setFrom(targetRotation);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		objectToUse.transform.buildMatrix();
 | 
							objectToUse.transform.buildMatrix();
 | 
				
			||||||
@ -179,12 +202,5 @@ class SetLookAtRotationNode extends LogicNode {
 | 
				
			|||||||
		runOutput(0);
 | 
							runOutput(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Getter method for output sockets
 | 
						// No output sockets needed - this node only performs actions
 | 
				
			||||||
	override function get(from: Int): Dynamic {
 | 
					 | 
				
			||||||
		// Output index 1 is the rotation socket (global rotation)
 | 
					 | 
				
			||||||
		if (from == 1) {
 | 
					 | 
				
			||||||
			return calculatedRotation;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return null;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -29,6 +29,8 @@ class SetLookAtRotationNode(LnxLogicTreeNode):
 | 
				
			|||||||
        update=lambda self, context: self.update_sockets(context)
 | 
					        update=lambda self, context: self.update_sockets(context)
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    damping: bpy.props.FloatProperty(
 | 
					    damping: bpy.props.FloatProperty(
 | 
				
			||||||
        name='Damping',
 | 
					        name='Damping',
 | 
				
			||||||
        description='Amount of damping for rotation (0.0 = instant, 1.0 = no movement)',
 | 
					        description='Amount of damping for rotation (0.0 = instant, 1.0 = no movement)',
 | 
				
			||||||
@ -74,6 +76,12 @@ class SetLookAtRotationNode(LnxLogicTreeNode):
 | 
				
			|||||||
                 ('false', 'False', 'False')],
 | 
					                 ('false', 'False', 'False')],
 | 
				
			||||||
        name='Disable Rotation on Aligning Axis', default='false')
 | 
					        name='Disable Rotation on Aligning Axis', default='false')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    property5: HaxeEnumProperty(
 | 
				
			||||||
 | 
					        'property5',
 | 
				
			||||||
 | 
					        items = [('true', 'True', 'True'),
 | 
				
			||||||
 | 
					                 ('false', 'False', 'False')],
 | 
				
			||||||
 | 
					        name='Use Local Space', default='false')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
        # Add inputs in standard order
 | 
					        # Add inputs in standard order
 | 
				
			||||||
        self.inputs.new('LnxNodeSocketAction', 'In')
 | 
					        self.inputs.new('LnxNodeSocketAction', 'In')
 | 
				
			||||||
@ -90,8 +98,6 @@ class SetLookAtRotationNode(LnxLogicTreeNode):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # Add outputs
 | 
					        # Add outputs
 | 
				
			||||||
        self.add_output('LnxNodeSocketAction', 'Out')
 | 
					        self.add_output('LnxNodeSocketAction', 'Out')
 | 
				
			||||||
        # Add rotation output socket
 | 
					 | 
				
			||||||
        self.add_output('LnxRotationSocket', 'Rotation')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def draw_buttons(self, context, layout):
 | 
					    def draw_buttons(self, context, layout):
 | 
				
			||||||
        # 1. Axis Selector
 | 
					        # 1. Axis Selector
 | 
				
			||||||
@ -114,6 +120,7 @@ class SetLookAtRotationNode(LnxLogicTreeNode):
 | 
				
			|||||||
        self.property2 = 'true' if self.use_source_vector else 'false'
 | 
					        self.property2 = 'true' if self.use_source_vector else 'false'
 | 
				
			||||||
        self.property3 = str(self.damping) # Keep for backward compatibility
 | 
					        self.property3 = str(self.damping) # Keep for backward compatibility
 | 
				
			||||||
        self.property4 = 'true' if self.disable_rotation_on_align_axis else 'false'
 | 
					        self.property4 = 'true' if self.disable_rotation_on_align_axis else 'false'
 | 
				
			||||||
 | 
					        self.property5 = 'true'  # Always use local space functionality
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Store current object references before changing sockets
 | 
					        # Store current object references before changing sockets
 | 
				
			||||||
        self.save_object_references()
 | 
					        self.save_object_references()
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user