merge upstream

This commit is contained in:
2025-06-30 20:40:44 +00:00
10 changed files with 433 additions and 31 deletions

View File

@ -543,11 +543,13 @@ class LeenkxExporter:
if psys.settings.instance_object is None or psys.settings.render_type != 'OBJECT' or not psys.settings.instance_object.lnx_export:
return
for mod in bpy.data.objects[out_object['name']].modifiers:
if mod.type == 'PARTICLE_SYSTEM':
if mod.particle_system.name == psys.name:
if not mod.show_render:
return
for obj in bpy.data.objects:
if obj.name == out_object['name']:
for mod in obj.modifiers:
if mod.type == 'PARTICLE_SYSTEM':
if mod.particle_system.name == psys.name:
if not mod.show_render:
return
self.particle_system_array[psys.settings] = {"structName": psys.settings.name}
pref = {
@ -636,7 +638,10 @@ class LeenkxExporter:
continue
for slot in bobject.material_slots:
if slot.material is None or slot.material.library is not None:
if slot.material is None:
continue
if slot.material.library is not None:
slot.material.lnx_particle_flag = True
continue
if slot.material.name.endswith(variant_suffix):
continue

View File

@ -0,0 +1,101 @@
from lnx.logicnode.lnx_nodes import *
class MouseLookNode(LnxLogicTreeNode):
"""Controls object rotation based on mouse movement for FPS-style camera control.
Features:
- Sub-pixel interpolation (always enabled) for optimal precision and smooth low-sensitivity movement
- Resolution-adaptive scaling for consistent feel across different screen resolutions
"""
bl_idname = 'LNMouseLookNode'
bl_label = 'Mouse Look'
lnx_section = 'mouse'
lnx_version = 1
# Front axis property
property0: HaxeEnumProperty(
'property0',
items=[('X', 'X Axis', 'X Axis as front'),
('Y', 'Y Axis', 'Y Axis as front'),
('Z', 'Z Axis', 'Z Axis as front')],
name='Front', default='Y')
# Hide Locked property
property1: HaxeBoolProperty(
'property1',
name='Hide Locked',
description='Automatically center and lock the mouse cursor',
default=True)
# Invert X property
property2: HaxeBoolProperty(
'property2',
name='Invert X',
description='Invert horizontal mouse movement',
default=False)
# Invert Y property
property3: HaxeBoolProperty(
'property3',
name='Invert Y',
description='Invert vertical mouse movement',
default=False)
# Cap Left/Right property
property4: HaxeBoolProperty(
'property4',
name='Cap Left / Right',
description='Limit horizontal rotation',
default=False)
# Cap Up/Down property
property5: HaxeBoolProperty(
'property5',
name='Cap Up / Down',
description='Limit vertical rotation',
default=True)
# Strategy toggles
property6: HaxeBoolProperty(
'property6',
name='Resolution Adaptive',
description='Scale sensitivity based on screen resolution',
default=False)
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxNodeSocketObject', 'Body')
self.add_input('LnxNodeSocketObject', 'Head')
self.add_input('LnxFloatSocket', 'Sensitivity', default_value=0.5)
self.add_input('LnxFloatSocket', 'Smoothing', default_value=0.0)
self.add_output('LnxNodeSocketAction', 'Out')
def draw_buttons(self, context, layout):
layout.prop(self, 'property0', text='Front')
layout.prop(self, 'property1', text='Hide Locked')
# Invert XY section
col = layout.column(align=True)
col.label(text="Invert XY:")
row = col.row(align=True)
row.prop(self, 'property2', text='X', toggle=True)
row.prop(self, 'property3', text='Y', toggle=True)
# Cap rotations section
col = layout.column(align=True)
col.prop(self, 'property4', text='Cap Left / Right')
col.prop(self, 'property5', text='Cap Up / Down')
# Separator
layout.separator()
# Enhancement strategies section
col = layout.column(align=True)
col.label(text="Enhancement Strategies:")
col.prop(self, 'property6', text='Resolution Adaptive')

View File

@ -0,0 +1,14 @@
from lnx.logicnode.lnx_nodes import *
class SetLightShadowNode(LnxLogicTreeNode):
"""Sets the shadow boolean of the given light."""
bl_idname = 'LNSetLightShadowNode'
bl_label = 'Set Light Shadow'
lnx_version = 1
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxNodeSocketObject', 'Light')
self.add_input('LnxBoolSocket', 'Shadow')
self.add_output('LnxNodeSocketAction', 'Out')

View File

@ -29,6 +29,8 @@ class SetLookAtRotationNode(LnxLogicTreeNode):
update=lambda self, context: self.update_sockets(context)
)
damping: bpy.props.FloatProperty(
name='Damping',
description='Amount of damping for rotation (0.0 = instant, 1.0 = no movement)',
@ -74,6 +76,12 @@ class SetLookAtRotationNode(LnxLogicTreeNode):
('false', 'False', '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):
# Add inputs in standard order
self.inputs.new('LnxNodeSocketAction', 'In')
@ -90,8 +98,6 @@ class SetLookAtRotationNode(LnxLogicTreeNode):
# Add outputs
self.add_output('LnxNodeSocketAction', 'Out')
# Add rotation output socket
self.add_output('LnxRotationSocket', 'Rotation')
def draw_buttons(self, context, layout):
# 1. Axis Selector
@ -114,6 +120,7 @@ class SetLookAtRotationNode(LnxLogicTreeNode):
self.property2 = 'true' if self.use_source_vector else 'false'
self.property3 = str(self.damping) # Keep for backward compatibility
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
self.save_object_references()

View File

@ -216,6 +216,7 @@ def parse_shader(node: bpy.types.Node, socket: bpy.types.NodeSocket) -> Tuple[st
'ADD_SHADER',
'BSDF_PRINCIPLED',
'BSDF_DIFFUSE',
'DIFFUSE_BSDF',
'BSDF_GLOSSY',
'BSDF_SHEEN',
'AMBIENT_OCCLUSION',

View File

@ -153,6 +153,7 @@ ALL_NODES: dict[str, MaterialNodeMeta] = {
'AMBIENT_OCCLUSION': MaterialNodeMeta(parse_func=nodes_shader.parse_ambientocclusion),
'BSDF_ANISOTROPIC': MaterialNodeMeta(parse_func=nodes_shader.parse_bsdfanisotropic),
'BSDF_DIFFUSE': MaterialNodeMeta(parse_func=nodes_shader.parse_bsdfdiffuse),
'DIFFUSE_BSDF': MaterialNodeMeta(parse_func=nodes_shader.parse_bsdfdiffuse),
'BSDF_GLASS': MaterialNodeMeta(parse_func=nodes_shader.parse_bsdfglass),
'BSDF_PRINCIPLED': MaterialNodeMeta(parse_func=nodes_shader.parse_bsdfprincipled),
'BSDF_TRANSLUCENT': MaterialNodeMeta(parse_func=nodes_shader.parse_bsdftranslucent),