Motion transfer setup #1
39
nodes.py
39
nodes.py
|
@ -83,8 +83,7 @@ class PowerShipNodeTree(bpy.types.NodeTree):
|
|||
|
||||
nodes_before = list(node.exec_order_prerequisites())
|
||||
if nodes_before:
|
||||
print(
|
||||
f" {len(nodes_before)} prerequisites, going there first")
|
||||
print(f" {len(nodes_before)} prerequisites, going there first")
|
||||
# There are nodes to execute before this one. Push them to the front of the queue.
|
||||
to_visit.extendleft(reversed(nodes_before))
|
||||
continue
|
||||
|
@ -170,12 +169,10 @@ class AbstractPowerShipNode(bpy.types.Node):
|
|||
self.add_execution_socket_output()
|
||||
|
||||
def add_execution_socket_input(self) -> None:
|
||||
self.inputs.new(NodeSocketExecute.bl_idname,
|
||||
NodeSocketExecute.bl_label)
|
||||
self.inputs.new(NodeSocketExecute.bl_idname, NodeSocketExecute.bl_label)
|
||||
|
||||
def add_execution_socket_output(self) -> None:
|
||||
self.outputs.new(NodeSocketExecute.bl_idname,
|
||||
NodeSocketExecute.bl_label)
|
||||
self.outputs.new(NodeSocketExecute.bl_idname, NodeSocketExecute.bl_label)
|
||||
|
||||
def add_optional_input_socket(
|
||||
self, typename: str, label: str
|
||||
|
@ -267,8 +264,7 @@ class AbstractPowerShipNode(bpy.types.Node):
|
|||
"""Return the connected socket value, or None if not connected."""
|
||||
input_socket = self.inputs[input_socket_name]
|
||||
for link in input_socket.links:
|
||||
convertedValue = expectType(
|
||||
link.from_socket.default_value) # type: ignore
|
||||
convertedValue = expectType(link.from_socket.default_value) # type: ignore
|
||||
return convertedValue
|
||||
return None
|
||||
|
||||
|
@ -400,8 +396,7 @@ class GetBoneNode(AbstractPowerShipNode):
|
|||
bl_label = "Get Bone"
|
||||
bl_icon = "BONE_DATA"
|
||||
|
||||
head_tail: bpy.props.EnumProperty(
|
||||
name="Side", items=_bone_head_tail) # type: ignore
|
||||
head_tail: bpy.props.EnumProperty(name="Side", items=_bone_head_tail) # type: ignore
|
||||
|
||||
def draw_buttons(
|
||||
self, context: bpy.types.Context, layout: bpy.types.UILayout
|
||||
|
@ -443,8 +438,7 @@ class GetBoneNode(AbstractPowerShipNode):
|
|||
bone_rest_rot_scale = bone.bone.matrix_local.copy()
|
||||
bone_rest_rot_scale.translation = v_nil
|
||||
|
||||
_, rot, scale = (
|
||||
mat_world @ bone_rest_rot_scale.inverted()).decompose()
|
||||
_, rot, scale = (mat_world @ bone_rest_rot_scale.inverted()).decompose()
|
||||
|
||||
self.outputs["Location"].default_value = arm_matrix @ loc
|
||||
self.outputs["Rotation"].default_value = rot
|
||||
|
@ -540,8 +534,7 @@ class SetControlNode(AbstractPowerShipNode):
|
|||
|
||||
def execute(self, depsgraph: bpy.types.Depsgraph) -> None:
|
||||
control_location = self._get_optional_input_value("Location", Vector)
|
||||
control_rotation = self._get_optional_input_value(
|
||||
"Rotation", Quaternion)
|
||||
control_rotation = self._get_optional_input_value("Rotation", Quaternion)
|
||||
control_scale = self._get_optional_input_value("Scale", Vector)
|
||||
control_obj = self._get_input_value("Control", bpy.types.Object)
|
||||
|
||||
|
@ -923,8 +916,7 @@ class SetCursorNode(AbstractAlwaysExecuteNode):
|
|||
|
||||
def execute(self, depsgraph: bpy.types.Depsgraph) -> None:
|
||||
control_location = self._get_optional_input_value("Location", Vector)
|
||||
control_rotation = self._get_optional_input_value(
|
||||
"Rotation", Quaternion)
|
||||
control_rotation = self._get_optional_input_value("Rotation", Quaternion)
|
||||
|
||||
cursor = depsgraph.scene.cursor
|
||||
if control_location is not None:
|
||||
|
@ -963,8 +955,7 @@ class SetBoneNode(AbstractPowerShipNode):
|
|||
|
||||
def execute(self, depsgraph: bpy.types.Depsgraph) -> None:
|
||||
control_location = self._get_optional_input_value("Location", Vector)
|
||||
control_rotation = self._get_optional_input_value(
|
||||
"Rotation", Quaternion)
|
||||
control_rotation = self._get_optional_input_value("Rotation", Quaternion)
|
||||
control_scale = self._get_optional_input_value("Scale", Vector)
|
||||
|
||||
if not (control_location or control_rotation or control_scale):
|
||||
|
@ -1008,8 +999,7 @@ class SetBoneNode(AbstractPowerShipNode):
|
|||
loc, rot, scale = bone_mat_world.decompose()
|
||||
case "CHANNELS":
|
||||
|
||||
bone_rest_rot_scale.translation = v_nil
|
||||
mat_rot_scale = Matrix.LocRotScale(
|
||||
v_nil, rot, scale) @ bone_rest_rot_scale
|
||||
mat_rot_scale = Matrix.LocRotScale(v_nil, rot, scale) @ bone_rest_rot_scale
|
||||
mat_loc = Matrix.Translation(loc)
|
||||
bone_mat_world = mat_loc @ mat_rot_scale
|
||||
|
||||
|
@ -1052,8 +1042,7 @@ class TwoBoneIKNode(AbstractPowerShipNode):
|
|||
|
||||
locator: Callable[[str, Vector], bpy.types.Object]
|
||||
if self._debug:
|
||||
locator = functools.partial(
|
||||
self._debug_locator, scene=depsgraph.scene)
|
||||
locator = functools.partial(self._debug_locator, scene=depsgraph.scene)
|
||||
else:
|
||||
locator = self._locator
|
||||
|
||||
|
@ -1061,11 +1050,9 @@ class TwoBoneIKNode(AbstractPowerShipNode):
|
|||
target_loc = self._get_input_value("Target", Vector)
|
||||
target_ob = locator("temp-ik-target", target_loc)
|
||||
|
||||
pole_target_loc = self._get_optional_input_value(
|
||||
"Pole Target", Vector)
|
||||
pole_target_loc = self._get_optional_input_value("Pole Target", Vector)
|
||||
if pole_target_loc is not None:
|
||||
pole_target_ob = locator(
|
||||
"temp-ik-pole-target", pole_target_loc)
|
||||
pole_target_ob = locator("temp-ik-pole-target", pole_target_loc)
|
||||
|
||||
try:
|
||||
# Reuse constraint from previous run. This can be useful for
|
||||
|
|
Loading…
Reference in New Issue
in which case would
rot
not be normalized? I'd expectbone_mat_world.decompose()
to return a unit quaternion. If you want to normalize the socket value, do that above withrot = control_rotation.normalized()
.I think that can be removed. I was confused because the quaternion affected the scale which indicates that it's not a unit quaternion. This happened on longer bone chains - rounding the scale seemed to fix the issue so I guess it has been some floating point error.