浏览代码

Add "Set Bone Matrix Tail" node

Note that this just uses roll = 0 so it is terrible, I need a proper align-roll node but porting the code from Blender will be hard.
Joseph Brandenburg 9 月之前
父节点
当前提交
4977ae6b7b
共有 3 个文件被更改,包括 60 次插入4 次删除
  1. 1 0
      __init__.py
  2. 36 4
      misc_containers.py
  3. 23 0
      nodes_generic.py

+ 1 - 0
__init__.py

@@ -166,6 +166,7 @@ matrix_category = [
         NodeItem("UtilityAxesFromMatrix"),
         NodeItem("UtilityMatrixTransform"),
         NodeItem("UtilityTransformationMatrix"),
+        NodeItem("UtilitySetBoneMatrixTail"),
     ]
 groups_category = [
         NodeItem("MantisNodeGroup"),

+ 36 - 4
misc_containers.py

@@ -48,6 +48,7 @@ def TellClasses():
              UtilityTransformationMatrix,
              UtilityIntToString,
              UtilityArrayGet,
+             UtilitySetBoneMatrixTail,
              #
              UtilityCompare,
              UtilityChoose,
@@ -1612,14 +1613,45 @@ class UtilityArrayGet:
         init_connections(from_node)
         if self in from_node.hierarchy_connections:
           raise RuntimeError()
-        self.hierarchy_connections = []
-        self.connections = []
-        self.hierarchy_dependencies = []
-        self.dependencies = []
+        # this is intentional because the Array Get is kind of a weird hybrid between a Utility and a Schema
+        # so it should be removed from the tree when it is done. it has already dealt with the actual links.
+        # however I think this is redundant. Check.
+        self.hierarchy_connections, self.connections = [], []
+        self.hierarchy_dependencies, self.dependencies = [], []
 
         self.prepared = True
         self.executed = True
 
+class UtilitySetBoneMatrixTail:
+    def __init__(self, signature, base_tree):
+        self.base_tree=base_tree
+        self.executed = False
+        self.signature = signature
+        self.inputs = {
+          "Matrix"          : NodeSocket(is_input = True, name = "Matrix", node = self),
+          "Tail Location"  : NodeSocket(is_input = True, name = "Tail Location", node = self),
+        }
+        self.outputs = {
+          "Result"        : NodeSocket(name = "Result", node = self),
+        }
+        self.parameters = {
+          "Matrix"     : None,
+          "Tail Location"   : None,
+          "Result"     : None,
+        }
+        self.node_type = "UTILITY"
+        self.hierarchy_connections, self.connections = [], []
+        self.hierarchy_dependencies, self.dependencies = [], []
+        self.prepared, self.executed = False, False
+
+    def bPrepare(self, bContext = None,):
+      from mathutils import Matrix
+      matrix = self.evaluate_input("Matrix")
+      if matrix is None: matrix = Matrix.Identity(4)
+      #just do this for now lol
+      self.parameters["Result"] = matrix_from_head_tail(matrix.translation, self.evaluate_input("Tail Location"))
+
+
 
 class UtilityPrint:
     def __init__(self, signature, base_tree):

+ 23 - 0
nodes_generic.py

@@ -50,6 +50,7 @@ def TellClasses():
              UtilityBoneMatrixHeadTailFlip,
              UtilityMatrixTransform,
              UtilityTransformationMatrix,
+             UtilitySetBoneMatrixTail,
 
              UtilityIntToString,
              UtilityArrayGet,
@@ -806,6 +807,28 @@ class UtilityTransformationMatrix(Node, MantisNode):
         self.outputs.new("MatrixSocket", "Matrix")
         self.initialized = True
 
+# Blender calculates bone roll this way...
+# https://projects.blender.org/blender/blender/src/commit/dd209221675ac7b62ce47b7ea42f15cbe34a6035/source/blender/editors/armature/armature_edit.cc#L281
+# but this looks like it will be harder to re-implement than to re-use. Unfortunately, it doesn't apply directly to a matrix so I have to call a method
+# in the edit bone. Thus, this node currently does nothing and the xForm node has to handle it by reading back through the tree....
+# this will lead to bugs.
+# So instead, we need to avoid calculating the roll for now.
+# but I want to make that its own node and add roll-recalc to this node, too.
+
+class UtilitySetBoneMatrixTail(Node, MantisNode):
+    """Constructs a matrix representing a transformation"""
+    bl_idname = "UtilitySetBoneMatrixTail"
+    bl_label = "Set Bone Matrix Tail"
+    bl_icon = "NODE"
+    initialized : bpy.props.BoolProperty(default = False)
+    
+    def init(self, context):
+        self.inputs.new("MatrixSocket", "Matrix")
+        self.inputs.new("VectorSocket", "Tail Location")
+        self.outputs.new("MatrixSocket", "Result")
+        self.initialized = True
+
+
 class UtilityMatrixFromXForm(Node, MantisNode):
     """Returns the matrix of the given xForm node."""
     bl_idname = "UtilityMatrixFromXForm"