forked from LeenkxTeam/LNXSDK
merge upstream
This commit is contained in:
@ -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
|
||||
|
101
leenkx/blender/lnx/logicnode/input/LN_mouse_look.py
Normal file
101
leenkx/blender/lnx/logicnode/input/LN_mouse_look.py
Normal 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')
|
14
leenkx/blender/lnx/logicnode/light/LN_set_light_shadow.py
Normal file
14
leenkx/blender/lnx/logicnode/light/LN_set_light_shadow.py
Normal 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')
|
@ -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()
|
||||
|
@ -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',
|
||||
|
@ -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),
|
||||
|
Reference in New Issue
Block a user