From ad6a52b9c2ba08512cefd8b01b53703d02259893 Mon Sep 17 00:00:00 2001 From: IzaZed Date: Sun, 23 Jun 2024 16:04:06 +0200 Subject: [PATCH] add setRigBoneAttr --- __init__.py | 16 +--- editor/enum_types.py | 2 +- editor/nodes/__init__.py | 1 + editor/nodes/actions/setrigboneattribute.py | 91 +++++++++++++++++++++ editor/nodes/actions/vehicleaccelerate.py | 4 +- editor/sockets/armaturesocket.py | 32 +++++--- editor/sockets/bitmasksocket.py | 2 +- editor/sockets/stringsocket.py | 8 +- ops/addcomponent.py | 6 +- ops/nodesearch.py | 2 +- ui/node_menu.py | 18 +++- 11 files changed, 145 insertions(+), 37 deletions(-) create mode 100644 editor/nodes/actions/setrigboneattribute.py diff --git a/__init__.py b/__init__.py index 11763af..41f402d 100644 --- a/__init__.py +++ b/__init__.py @@ -34,7 +34,7 @@ "A Node System to create game logic." ), "author": "pgi, Leopold A-C (Iza Zed)", - "version": (3, 2), + "version": (3, 2, 1), "blender": (4, 1, 0), "location": "View Menu", "category": "Game Engine", @@ -307,20 +307,6 @@ class LogicNodeTreeReference(bpy.types.PropertyGroup): _registered_classes.extend(_menu_items) -################################################### -# DEBUG -################################################### -# text = '' - -# for node in _nodes: -# text +=f"- {'(deprecated) ' if node.deprecated else ''}{node.bl_label}\n" -# text += f'Total Nodes: {len(_nodes)}' - -# with open("D:/Data/nodes.txt", 'w') as f: -# f.write(text) -# f.close() -################################################### - def _get_key_for_class(c): if hasattr(c, "bl_label"): return c.bl_label diff --git a/editor/enum_types.py b/editor/enum_types.py index 29a8f83..7609290 100644 --- a/editor/enum_types.py +++ b/editor/enum_types.py @@ -57,7 +57,7 @@ ("cross", "Cross Product", "Project A onto B"), None, ("normalize", "Normalize", "Rescale all values to 0 - 1"), - ("lerp", "Lerp", "Linear Interpolation between the two vectors"), + ("lerp", "Mix (Lerp)", "Linear Interpolation between the two vectors"), ("slerp", "Spherical Lerp", "Spherical Interpolation between the two vectors"), ("negate", "Negate", "Multiply all values by -1") ] diff --git a/editor/nodes/__init__.py b/editor/nodes/__init__.py index 193b363..c1672f1 100644 --- a/editor/nodes/__init__.py +++ b/editor/nodes/__init__.py @@ -23,6 +23,7 @@ from .actions.setuiwidgetattr import LogicNodeSetUIWidgetAttr from .actions.togglefilter import LogicNodeToggleFilter from .actions.draw import LogicNodeDraw +from .actions.setrigboneattribute import LogicNodeSetRigBoneAttribute from .actions.gamepadvibration import LogicNodeGamepadVibration from .actions.addobject import LogicNodeAddObject diff --git a/editor/nodes/actions/setrigboneattribute.py b/editor/nodes/actions/setrigboneattribute.py new file mode 100644 index 0000000..044572b --- /dev/null +++ b/editor/nodes/actions/setrigboneattribute.py @@ -0,0 +1,91 @@ +from bpy.types import Context, UILayout +from ..node import node_type +from ..node import LogicNodeActionType +from ...sockets import NodeSocketLogicCondition +from ...sockets import NodeSocketLogicString +from ...sockets import NodeSocketLogicArmature +from ...sockets import NodeSocketLogicBone +from ...sockets import NodeSocketLogicVectorXYZ +from ...sockets import NodeSocketLogicBoolean +from bpy.props import EnumProperty + + +_attrs = [ + ("name", "Name", "Name of the Bone"), # String + None, + ("head", "Head", "Location of head end of the bone relative to its parent"), # Vector + ("head_local", "Local Head", "Location of head end of the bone relative to armature"), # Vector + ("tail", "Tail", "Location of tail end of the bone relative to its parent"), # Vector + ("tail_local", "Local Tail", "Location of tail end of the bone relative to armature"), # Vector + None, + ("inherit_scale", "Inherit Scale", "Specifies how the bone inherits scaling from the parent bone"), # Enum + ("inherit_rotation", "Inherit Rotation", "Bone inherits rotation or scale from parent bone"), # Boolean + None, + ("connected", "Connected", "When bone has a parent, bone's head is stuck to the parent's tail"), # Boolean + ("deform", "Deform", "Enable Bone to deform geometry"), # Boolean + ("local_location", "Use Local", "Bone location is set in local space"), # Boolean + ("relative_parent", "Use Relative Parent", "Object children will use relative transform, like deform"), # Boolean + ("scale_easing", "Scale Easing", "Multiply the final easing values by the Scale In/Out Y factors"), # Boolean +] + + +_scale_modes = [ + ("NONE", "None", "Completely ignore parent scaling"), + ("FULL", "Full", "Inherit all effects of parent scaling."), + None, + ("NONE_LEGACY", "None (Legacy)", "Ignore parent scaling without compensating for parent shear. Replicates the effect of disabling the original Inherit Scale checkbox"), + ("FIX_SHEAR", "Fix Shear", "Inherit scaling, but remove shearing of the child in the rest orientation"), + ("ALIGNED", "Aligned", "Rotate non-uniform parent scaling to align with the child, applying parent X scale to child X axis, and so forth"), + ("AVERAGE", "Average", "Inherit uniform scaling representing the overall change in the volume of the parent") +] + + +@node_type +class LogicNodeSetRigBoneAttribute(LogicNodeActionType): + bl_idname = "LogicNodeSetRigBoneAttribute" + bl_label = "Set Bone Attribute" + nl_module = 'uplogic.nodes.actions' + nl_class = "SetRigBoneAttributeNode" + + def update_draw(self, context=None): + attr = self.attribute + if attr == 'inherit_scale': + self.inputs[3].enabled = False + self.inputs[4].enabled = False + self.inputs[5].enabled = False + elif attr == 'name': + self.inputs[3].enabled = True + self.inputs[4].enabled = False + self.inputs[5].enabled = False + elif attr in ['head', 'head_local', 'tail', 'tail_local']: + self.inputs[3].enabled = False + self.inputs[4].enabled = True + self.inputs[5].enabled = False + else: + self.inputs[3].enabled = False + self.inputs[4].enabled = False + self.inputs[5].enabled = True + + attribute: EnumProperty(items=_attrs, name='Attribute', update=update_draw) + scale_mode: EnumProperty(items=_scale_modes, name='Scale Mode', update=update_draw) + + def draw_buttons(self, context: Context, layout: UILayout) -> None: + layout.prop(self, 'attribute', text='') + if self.attribute == 'inherit_scale': + layout.prop(self, 'scale_mode', text='') + + def get_attributes(self): + return [ + ('attribute', repr(self.attribute)), + ('scale_mode', repr(self.scale_mode)) + ] + + def init(self, context): + self.add_input(NodeSocketLogicCondition, "Condition", 'condition') + self.add_input(NodeSocketLogicArmature, "", 'armature') + self.add_input(NodeSocketLogicBone, "", 'bone', settings={'ref_index': 1}) + self.add_input(NodeSocketLogicString, "", 'value') + self.add_input(NodeSocketLogicVectorXYZ, "Vector", 'value') + self.add_input(NodeSocketLogicBoolean, "Bool", 'value') + self.add_output(NodeSocketLogicCondition, 'Done', 'DONE') + LogicNodeActionType.init(self, context) diff --git a/editor/nodes/actions/vehicleaccelerate.py b/editor/nodes/actions/vehicleaccelerate.py index d886755..f859344 100644 --- a/editor/nodes/actions/vehicleaccelerate.py +++ b/editor/nodes/actions/vehicleaccelerate.py @@ -2,7 +2,7 @@ from ..node import LogicNodeActionType from ...sockets import NodeSocketLogicCondition from ...sockets import NodeSocketLogicObject -from ...sockets import NodeSocketLogicFloatPositive +from ...sockets import NodeSocketLogicFloat from ...sockets import NodeSocketLogicIntegerPositive from ...enum_types import _enum_vehicle_axis from bpy.props import EnumProperty @@ -32,7 +32,7 @@ def init(self, context): self.add_input(NodeSocketLogicCondition, "Condition", 'condition') self.add_input(NodeSocketLogicObject, "Vehicle", 'vehicle') self.add_input(NodeSocketLogicIntegerPositive, "Wheels", 'wheelcount', {'default_value': 2}) - self.add_input(NodeSocketLogicFloatPositive, "Power", 'power', {'default_value': 1}) + self.add_input(NodeSocketLogicFloat, "Power", 'power', {'default_value': 1}) self.add_output(NodeSocketLogicCondition, 'Done', 'OUT') LogicNodeActionType.init(self, context) diff --git a/editor/sockets/armaturesocket.py b/editor/sockets/armaturesocket.py index 36e775f..37d1bc4 100644 --- a/editor/sockets/armaturesocket.py +++ b/editor/sockets/armaturesocket.py @@ -50,21 +50,31 @@ def draw(self, context, layout, node, text): else: if not self.use_owner: col = layout.column(align=False) - row = col.row() + row = col.row(align=True) if self.name: row.label(text=self.name) - row.prop(self, 'use_owner', icon='USER', text='') - col.prop_search( - self, - 'default_value', - bpy.context.scene, - 'objects', - icon='NONE', - text='' - ) + row.prop(self, 'use_owner', icon='USER', text='') + col.prop_search( + self, + 'default_value', + bpy.context.scene, + 'objects', + icon='NONE', + text='' + ) + else: + row.prop_search( + self, + 'default_value', + bpy.context.scene, + 'objects', + icon='NONE', + text='' + ) + row.prop(self, 'use_owner', icon='USER', text='') else: row = layout.row() - row.label(text=self.name) + row.label(text='Owner Object') row.prop(self, 'use_owner', icon='USER', text='') def get_unlinked_value(self): diff --git a/editor/sockets/bitmasksocket.py b/editor/sockets/bitmasksocket.py index 15ae543..01adaee 100644 --- a/editor/sockets/bitmasksocket.py +++ b/editor/sockets/bitmasksocket.py @@ -13,7 +13,7 @@ class NodeSocketLogicBitMask(NodeSocket, NodeSocketLogic): size=16, default=[True for x in range(16)], name='Mask', - subtype='LAYER_MEMBER' + # subtype='LAYER_MEMBER' XXX: Reactivate if fixed ) selected_bit: IntProperty() diff --git a/editor/sockets/stringsocket.py b/editor/sockets/stringsocket.py index a26482c..64fed00 100644 --- a/editor/sockets/stringsocket.py +++ b/editor/sockets/stringsocket.py @@ -1,4 +1,8 @@ -from .socket import SOCKET_COLOR_STRING, SOCKET_TYPE_VALUE, SOCKET_TYPE_STRING, NodeSocketLogic +from .socket import SOCKET_COLOR_STRING +from .socket import SOCKET_TYPE_VALUE +from .socket import SOCKET_TYPE_STRING +from .socket import SOCKET_TYPE_GENERIC +from .socket import NodeSocketLogic from .socket import socket_type from .socket import update_draw from bpy.types import NodeSocket @@ -14,7 +18,7 @@ class Base(NodeSocket, NodeSocketLogic): formatted: BoolProperty(update=update_draw) nl_color = SOCKET_COLOR_STRING - nl_type = SOCKET_TYPE_STRING + nl_type = SOCKET_TYPE_GENERIC valid_sockets = [ SOCKET_TYPE_VALUE, diff --git a/ops/addcomponent.py b/ops/addcomponent.py index 1e94744..7f4fc87 100644 --- a/ops/addcomponent.py +++ b/ops/addcomponent.py @@ -1,4 +1,4 @@ -from ..utilities import notify, preferences +from ..utilities import notify, preferences, error, debug from .operator import operator from .operator import _enum_components from .operator import reload_texts @@ -47,7 +47,7 @@ def execute(self, context): continue if 'args=' in line.body: in_args = True - if '])' in line.body: + if '])' in line.body and in_args: cargs += line.body break if in_args: @@ -61,6 +61,8 @@ def execute(self, context): select_text.clear() select_text.write(body) except Exception as e: + error(f'Could not add component {mod_name}.{comp_name} to object {context.active_object.name}!') + debug(f'Content:\n\n{select_text.as_string()}\n') select_text.clear() select_text.write(body) self.report({"ERROR"}, str(e)) diff --git a/ops/nodesearch.py b/ops/nodesearch.py index bc1a44c..d5638eb 100644 --- a/ops/nodesearch.py +++ b/ops/nodesearch.py @@ -50,7 +50,7 @@ def add(self): @operator class LOGIC_NODES_OT_node_search(bpy.types.Operator): - bl_idname = "bge_netlogic.node_search" + bl_idname = "logic_nodes.node_search" bl_label = "Node Search" bl_options = {"REGISTER"} bl_description = "Search for registered Logic Nodes" diff --git a/ui/node_menu.py b/ui/node_menu.py index 1ca721d..34729d4 100644 --- a/ui/node_menu.py +++ b/ui/node_menu.py @@ -281,8 +281,22 @@ class ArmatureRigMenu(bpy.types.Menu): def draw(self, context): layout = self.layout insertNode(layout, "NLParameterBoneStatus", "Bone Status") - # insertNode(layout, "NLActionEditBoneNode", "Edit Bone") - insertNode(layout, "NLActionSetBonePos", "Set Bone Position") + insertNode(layout, "LogicNodeSetRigBoneAttribute", "Set Bone Name", settings={'attribute': repr('name')}) + layout.separator() + insertNode(layout, "LogicNodeSetRigBoneAttribute", "Set Bone Head", settings={'attribute': repr('head')}) + insertNode(layout, "LogicNodeSetRigBoneAttribute", "Set Bone Local Head", settings={'attribute': repr('head_local')}) + insertNode(layout, "LogicNodeSetRigBoneAttribute", "Set Bone Tail", settings={'attribute': repr('tail')}) + insertNode(layout, "LogicNodeSetRigBoneAttribute", "Set Bone Local Tail", settings={'attribute': repr('tail_local')}) + layout.separator() + insertNode(layout, "LogicNodeSetRigBoneAttribute", "Set Bone Inherit Scale", settings={'attribute': repr('inherit_scale')}) + insertNode(layout, "LogicNodeSetRigBoneAttribute", "Set Bone Inherit Rotation", settings={'attribute': repr('use_inherit_rotation')}) + layout.separator() + insertNode(layout, "LogicNodeSetRigBoneAttribute", "Set Bone Connected", settings={'attribute': repr('use_connect')}) + insertNode(layout, "LogicNodeSetRigBoneAttribute", "Set Bone Deform", settings={'attribute': repr('use_deform')}) + insertNode(layout, "LogicNodeSetRigBoneAttribute", "Set Bone Local", settings={'attribute': repr('use_local_location')}) + insertNode(layout, "LogicNodeSetRigBoneAttribute", "Set Bone Relative Parent", settings={'attribute': repr('use_relative_parent')}) + insertNode(layout, "LogicNodeSetRigBoneAttribute", "Set Bone Scale Easing", settings={'attribute': repr('use_scale_easing')}) + # insertNode(layout, "NLActionSetBonePos", "Set Bone Position") @menu_item