From 1a935bb0e6c05b02ed153af4b89eedbbe1013aea Mon Sep 17 00:00:00 2001 From: TackY Date: Sun, 26 Jun 2022 19:05:36 +0200 Subject: [PATCH 1/3] BSLagBoneController draft --- .../modules/nif_export/armature/__init__.py | 29 ++++++++++++++-- io_scene_niftools/properties/armature.py | 33 +++++++++++++++++-- io_scene_niftools/ui/armature.py | 28 +++++++++++++++- 3 files changed, 85 insertions(+), 5 deletions(-) diff --git a/io_scene_niftools/modules/nif_export/armature/__init__.py b/io_scene_niftools/modules/nif_export/armature/__init__.py index ea3906f84..f7494dc3f 100644 --- a/io_scene_niftools/modules/nif_export/armature/__init__.py +++ b/io_scene_niftools/modules/nif_export/armature/__init__.py @@ -40,7 +40,7 @@ from io_scene_niftools.modules.nif_export import types from io_scene_niftools.modules.nif_export.animation.transform import TransformAnimation from io_scene_niftools.modules.nif_export.block_registry import block_store -from io_scene_niftools.utils import math +from io_scene_niftools.utils import math, consts class Armature: @@ -83,6 +83,9 @@ def export_bone(self, b_obj, b_bone, n_parent_node, n_root_node): for b_child in b_bone.children: self.export_bone(b_obj, b_child, n_node, n_root_node) + if b_bone.niftools.BSLagBoneController: + self.export_BSLagBoneController(b_bone, n_node) + def export_bone_flags(self, b_bone, n_node): """Exports or sets the flags according to the custom data in b_bone or the game version if none was set""" if b_bone.niftools.flags != 0: @@ -110,4 +113,26 @@ def export_bone_flags(self, b_bone, n_node): # default for Div 2 final bones n_node.flags = 0x0196 else: - n_node.flags = 0x0002 # default for Morrowind bones \ No newline at end of file + n_node.flags = 0x0002 # default for Morrowind bones + + def export_BSLagBoneController(self, b_bone, n_node): + """Exports a BSLagBoneController for the bone""" + + #BSLagBoneControllers are only for skyrim and later, afaik + game = bpy.context.scene.niftools_scene.game + if game not in ('SKYRIM'): + return + + n_controller = block_store.create_block("BSLagBoneController") + n_controller.name = block_store.get_full_name(b_bone) + #This should be active and cycle, what I've seen in game. + n_controller.flags = b_bone.niftools.BSLagBoneController_flags #0x0048? hexa? + n_controller.frequency = 1.0 + n_controller.phase = 0.0 + n_controller.start_time = consts.FLOAT_MIN + n_controller.stop_time = consts.FLOAT_MAX + n_controller.linear_velocity = b_bone.niftools.BSLagBoneController_linear_velocity + n_controller.linear_rotation = b_bone.niftools.BSLagBoneController_linear_rotation + n_controller.maximum_distance = b_bone.niftools.BSLagBoneController_maximum_distance + #add controller to _this_ block + n_node.add_controller(n_controller) \ No newline at end of file diff --git a/io_scene_niftools/properties/armature.py b/io_scene_niftools/properties/armature.py index 89271f374..951d9fe9d 100644 --- a/io_scene_niftools/properties/armature.py +++ b/io_scene_niftools/properties/armature.py @@ -41,7 +41,9 @@ from bpy.props import (PointerProperty, IntProperty, EnumProperty, - StringProperty + StringProperty, + BoolProperty, + FloatProperty ) from bpy.types import PropertyGroup @@ -61,6 +63,34 @@ class BoneProperty(PropertyGroup): name='Nif Long Name' ) + #BSLagbone properties + + BSLagBoneController: BoolProperty( + name='BSLagBoneController', + default=False + ) + + BSLagBoneController_flags: IntProperty( + name='flags', + default=72 + ) + + BSLagBoneController_linear_velocity: FloatProperty( + name='linear velocity', + default=3.0 + ) + + BSLagBoneController_linear_rotation: FloatProperty( + name='linear rotation', + default=1.0 + ) + + BSLagBoneController_maximum_distance: FloatProperty( + name='maximum distance', + default=10.0 + ) + + class ArmatureProperty(PropertyGroup): @@ -101,7 +131,6 @@ def register(): bpy.types.Armature.niftools = bpy.props.PointerProperty(type=ArmatureProperty) bpy.types.Bone.niftools = bpy.props.PointerProperty(type=BoneProperty) - def unregister(): del bpy.types.Armature.niftools del bpy.types.Bone.niftools diff --git a/io_scene_niftools/ui/armature.py b/io_scene_niftools/ui/armature.py index 69e377b08..72a45c5d1 100644 --- a/io_scene_niftools/ui/armature.py +++ b/io_scene_niftools/ui/armature.py @@ -63,6 +63,31 @@ def draw(self, context): row.prop(nif_bone_props, "priority") row.prop(nif_bone_props, "longname") +class BoneControllerPanel(Panel): + bl_idname = "NIFTOOLS_PT_BoneControllerPanel" + bl_label = "Niftools Bone Controller Props" + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "bone" + + # noinspection PyUnusedLocal + @classmethod + def poll(cls, context): + return context.bone is not None + + def draw(self, context): + nif_bone_props = context.bone.niftools + + row = self.layout.column() + row.prop(nif_bone_props, "BSLagBoneController") + row2 = self.layout.column() + row2.prop(nif_bone_props, "BSLagBoneController_flags") + row2.prop(nif_bone_props, "BSLagBoneController_linear_velocity") + row2.prop(nif_bone_props, "BSLagBoneController_linear_rotation") + row2.prop(nif_bone_props, "BSLagBoneController_maximum_distance") + row2.enabled = nif_bone_props.BSLagBoneController + + class ArmaturePanel(Panel): bl_label = "Niftools Armature Props" @@ -88,7 +113,8 @@ def draw(self, context): classes = [ BonePanel, - ArmaturePanel + ArmaturePanel, + BoneControllerPanel ] From df242e2357e9afd1f67c85dfac2adf10e21eceda Mon Sep 17 00:00:00 2001 From: TackY Date: Thu, 30 Jun 2022 20:45:33 +0200 Subject: [PATCH 2/3] import added, panel only visible in pose mode --- .../modules/nif_import/armature/__init__.py | 18 ++++++++++++++++++ io_scene_niftools/properties/armature.py | 4 ++-- io_scene_niftools/ui/armature.py | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/io_scene_niftools/modules/nif_import/armature/__init__.py b/io_scene_niftools/modules/nif_import/armature/__init__.py index 7e4b4a59e..ddc5a2921 100644 --- a/io_scene_niftools/modules/nif_import/armature/__init__.py +++ b/io_scene_niftools/modules/nif_import/armature/__init__.py @@ -220,6 +220,11 @@ def import_armature(self, n_armature): if NifOp.props.animation: self.transform_anim.import_transforms(n_block, b_armature_obj, bone_name) + #Maybe better place to put this? + # Check for bs lagbone controllers and set them + self.import_bslagbonecontrollers(n_block, b_bone) + + # import pose for b_name, n_block in self.name_to_block.items(): n_pose = self.pose_store[n_block] @@ -231,6 +236,19 @@ def import_armature(self, n_armature): return b_armature_obj + + def import_bslagbonecontrollers(self, n_block, b_bone): + """Check for and import bslagbonecontrollers.""" + ctrl = n_block.controller + if isinstance(ctrl, NifFormat.BSLagBoneController): + #Enable bscontrollerlagboneprop + b_bone.niftools.BSLagBoneController = True + #Set the props we care about; flags, linear_velocity, linear_rotation, maximum distance + b_bone.niftools.BSLagBoneController_flags = ctrl.flags + b_bone.niftools.BSLagBoneController_linear_velocity = ctrl.linear_velocity + b_bone.niftools.BSLagBoneController_linear_rotation = ctrl.linear_rotation + b_bone.niftools.BSLagBoneController_maximum_distance = ctrl.maximum_distance + def import_bone_bind(self, n_block, b_armature_data, n_armature, b_parent_bone=None): """Adds a bone to the armature in edit mode.""" # check that n_block is indeed a bone diff --git a/io_scene_niftools/properties/armature.py b/io_scene_niftools/properties/armature.py index 951d9fe9d..100253eae 100644 --- a/io_scene_niftools/properties/armature.py +++ b/io_scene_niftools/properties/armature.py @@ -77,12 +77,12 @@ class BoneProperty(PropertyGroup): BSLagBoneController_linear_velocity: FloatProperty( name='linear velocity', - default=3.0 + default=20.0 ) BSLagBoneController_linear_rotation: FloatProperty( name='linear rotation', - default=1.0 + default=20.0 ) BSLagBoneController_maximum_distance: FloatProperty( diff --git a/io_scene_niftools/ui/armature.py b/io_scene_niftools/ui/armature.py index 72a45c5d1..1666c8242 100644 --- a/io_scene_niftools/ui/armature.py +++ b/io_scene_niftools/ui/armature.py @@ -68,7 +68,7 @@ class BoneControllerPanel(Panel): bl_label = "Niftools Bone Controller Props" bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' - bl_context = "bone" + bl_context = 'bone' # noinspection PyUnusedLocal @classmethod From d1a37e9e354f342d9097c69651e2d52a5f01b262 Mon Sep 17 00:00:00 2001 From: TackY Date: Fri, 1 Jul 2022 17:16:05 +0200 Subject: [PATCH 3/3] split props into their own panel, also case convention & PEP --- .../modules/nif_export/armature/__init__.py | 14 ++-- .../modules/nif_import/armature/__init__.py | 10 +-- io_scene_niftools/properties/armature.py | 83 ++++++++++--------- io_scene_niftools/ui/armature.py | 12 +-- 4 files changed, 61 insertions(+), 58 deletions(-) diff --git a/io_scene_niftools/modules/nif_export/armature/__init__.py b/io_scene_niftools/modules/nif_export/armature/__init__.py index f7494dc3f..66af92fdf 100644 --- a/io_scene_niftools/modules/nif_export/armature/__init__.py +++ b/io_scene_niftools/modules/nif_export/armature/__init__.py @@ -83,8 +83,8 @@ def export_bone(self, b_obj, b_bone, n_parent_node, n_root_node): for b_child in b_bone.children: self.export_bone(b_obj, b_child, n_node, n_root_node) - if b_bone.niftools.BSLagBoneController: - self.export_BSLagBoneController(b_bone, n_node) + if b_bone.niftools.lag_bone.enabled: + self.export_lag_bone(b_bone, n_node) def export_bone_flags(self, b_bone, n_node): """Exports or sets the flags according to the custom data in b_bone or the game version if none was set""" @@ -115,7 +115,7 @@ def export_bone_flags(self, b_bone, n_node): else: n_node.flags = 0x0002 # default for Morrowind bones - def export_BSLagBoneController(self, b_bone, n_node): + def export_lag_bone(self, b_bone, n_node): """Exports a BSLagBoneController for the bone""" #BSLagBoneControllers are only for skyrim and later, afaik @@ -126,13 +126,13 @@ def export_BSLagBoneController(self, b_bone, n_node): n_controller = block_store.create_block("BSLagBoneController") n_controller.name = block_store.get_full_name(b_bone) #This should be active and cycle, what I've seen in game. - n_controller.flags = b_bone.niftools.BSLagBoneController_flags #0x0048? hexa? + n_controller.flags = b_bone.niftools.lag_bone.flags #0x0048? hexa? n_controller.frequency = 1.0 n_controller.phase = 0.0 n_controller.start_time = consts.FLOAT_MIN n_controller.stop_time = consts.FLOAT_MAX - n_controller.linear_velocity = b_bone.niftools.BSLagBoneController_linear_velocity - n_controller.linear_rotation = b_bone.niftools.BSLagBoneController_linear_rotation - n_controller.maximum_distance = b_bone.niftools.BSLagBoneController_maximum_distance + n_controller.linear_velocity = b_bone.niftools.lag_bone.linear_velocity + n_controller.linear_rotation = b_bone.niftools.lag_bone.linear_rotation + n_controller.maximum_distance = b_bone.niftools.lag_bone.maximum_distance #add controller to _this_ block n_node.add_controller(n_controller) \ No newline at end of file diff --git a/io_scene_niftools/modules/nif_import/armature/__init__.py b/io_scene_niftools/modules/nif_import/armature/__init__.py index ddc5a2921..c161b8602 100644 --- a/io_scene_niftools/modules/nif_import/armature/__init__.py +++ b/io_scene_niftools/modules/nif_import/armature/__init__.py @@ -242,12 +242,12 @@ def import_bslagbonecontrollers(self, n_block, b_bone): ctrl = n_block.controller if isinstance(ctrl, NifFormat.BSLagBoneController): #Enable bscontrollerlagboneprop - b_bone.niftools.BSLagBoneController = True + b_bone.niftools.lag_bone.enabled = True #Set the props we care about; flags, linear_velocity, linear_rotation, maximum distance - b_bone.niftools.BSLagBoneController_flags = ctrl.flags - b_bone.niftools.BSLagBoneController_linear_velocity = ctrl.linear_velocity - b_bone.niftools.BSLagBoneController_linear_rotation = ctrl.linear_rotation - b_bone.niftools.BSLagBoneController_maximum_distance = ctrl.maximum_distance + b_bone.niftools.lag_bone.flags = ctrl.flags + b_bone.niftools.lag_bone.linear_velocity = ctrl.linear_velocity + b_bone.niftools.lag_bone.linear_rotation = ctrl.linear_rotation + b_bone.niftools.lag_bone.maximum_distance = ctrl.maximum_distance def import_bone_bind(self, n_block, b_armature_data, n_armature, b_parent_bone=None): """Adds a bone to the armature in edit mode.""" diff --git a/io_scene_niftools/properties/armature.py b/io_scene_niftools/properties/armature.py index 100253eae..9a74de2c2 100644 --- a/io_scene_niftools/properties/armature.py +++ b/io_scene_niftools/properties/armature.py @@ -50,76 +50,78 @@ from io_scene_niftools.utils.decorators import register_classes, unregister_classes -class BoneProperty(PropertyGroup): - flags: IntProperty( - name='Bone Flag', - default=0 - ) - priority: IntProperty( - name='Bone Priority', - default=0 - ) - longname: StringProperty( - name='Nif Long Name' - ) - - #BSLagbone properties - - BSLagBoneController: BoolProperty( +class LagBoneControllerProperty(PropertyGroup): + enabled: BoolProperty( name='BSLagBoneController', default=False ) - BSLagBoneController_flags: IntProperty( + flags: IntProperty( name='flags', default=72 ) - BSLagBoneController_linear_velocity: FloatProperty( + linear_velocity: FloatProperty( name='linear velocity', default=20.0 ) - BSLagBoneController_linear_rotation: FloatProperty( + linear_rotation: FloatProperty( name='linear rotation', default=20.0 ) - BSLagBoneController_maximum_distance: FloatProperty( + maximum_distance: FloatProperty( name='maximum distance', default=10.0 ) +class BoneProperty(PropertyGroup): + flags: IntProperty( + name='Bone Flag', + default=0 + ) + priority: IntProperty( + name='Bone Priority', + default=0 + ) + longname: StringProperty( + name='Nif Long Name' + ) + + lag_bone: PointerProperty(type=LagBoneControllerProperty) + class ArmatureProperty(PropertyGroup): axis_forward: EnumProperty( - name="Forward", - items=(('X', "X Forward", ""), - ('Y', "Y Forward", ""), - ('Z', "Z Forward", ""), - ('-X', "-X Forward", ""), - ('-Y', "-Y Forward", ""), - ('-Z', "-Z Forward", ""), - ), - default="X", - ) + name="Forward", + items=(('X', "X Forward", ""), + ('Y', "Y Forward", ""), + ('Z', "Z Forward", ""), + ('-X', "-X Forward", ""), + ('-Y', "-Y Forward", ""), + ('-Z', "-Z Forward", ""), + ), + default="X", + ) axis_up: EnumProperty( - name="Up", - items=(('X', "X Up", ""), - ('Y', "Y Up", ""), - ('Z', "Z Up", ""), - ('-X', "-X Up", ""), - ('-Y', "-Y Up", ""), - ('-Z', "-Z Up", ""), - ), - default="Y", - ) + name="Up", + items=(('X', "X Up", ""), + ('Y', "Y Up", ""), + ('Z', "Z Up", ""), + ('-X', "-X Up", ""), + ('-Y', "-Y Up", ""), + ('-Z', "-Z Up", ""), + ), + default="Y", + ) CLASSES = [ + LagBoneControllerProperty, BoneProperty, ArmatureProperty ] @@ -131,6 +133,7 @@ def register(): bpy.types.Armature.niftools = bpy.props.PointerProperty(type=ArmatureProperty) bpy.types.Bone.niftools = bpy.props.PointerProperty(type=BoneProperty) + def unregister(): del bpy.types.Armature.niftools del bpy.types.Bone.niftools diff --git a/io_scene_niftools/ui/armature.py b/io_scene_niftools/ui/armature.py index 1666c8242..e8262c015 100644 --- a/io_scene_niftools/ui/armature.py +++ b/io_scene_niftools/ui/armature.py @@ -79,13 +79,13 @@ def draw(self, context): nif_bone_props = context.bone.niftools row = self.layout.column() - row.prop(nif_bone_props, "BSLagBoneController") + row.prop(nif_bone_props.lag_bone, "enabled") row2 = self.layout.column() - row2.prop(nif_bone_props, "BSLagBoneController_flags") - row2.prop(nif_bone_props, "BSLagBoneController_linear_velocity") - row2.prop(nif_bone_props, "BSLagBoneController_linear_rotation") - row2.prop(nif_bone_props, "BSLagBoneController_maximum_distance") - row2.enabled = nif_bone_props.BSLagBoneController + row2.prop(nif_bone_props.lag_bone, "flags") + row2.prop(nif_bone_props.lag_bone, "linear_velocity") + row2.prop(nif_bone_props.lag_bone, "linear_rotation") + row2.prop(nif_bone_props.lag_bone, "maximum_distance") + row2.enabled = nif_bone_props.lag_bone.enabled