Motion transfer setup #1
161
nodes.py
161
nodes.py
@ -724,10 +724,8 @@ class RotateTowards(AbstractPowerShipNode):
|
||||
|
||||
# Set the rotation of the control
|
||||
vec = Vector((destination - origin))
|
||||
# vec.normalize()
|
||||
rot = vec.to_track_quat(self.track, self.up)
|
||||
rot.normalize()
|
||||
self.outputs["Rotation"].default_value = rot
|
||||
self.outputs["Rotation"].default_value = rot.normalized()
|
||||
|
||||
|
||||
class OffsetRotation(AbstractPowerShipNode):
|
||||
@ -776,20 +774,15 @@ class MapRange(AbstractPowerShipNode):
|
||||
self.outputs["Result"].default_value = slope * val + offset
|
||||
|
||||
|
||||
class RotationFromAngle(AbstractPowerShipNode):
|
||||
bl_idname = "RotationFromAngle"
|
||||
bl_label = "Rotation From Vector Angle"
|
||||
class AngleFromVectors(AbstractPowerShipNode):
|
||||
bl_idname = "AngleFromVectors"
|
||||
bl_label = "Angle From Vectors"
|
||||
bl_icon = "EMPTY_ARROWS"
|
||||
|
||||
axis: bpy.props.EnumProperty( # type: ignore
|
||||
name="Axis",
|
||||
items=_enum_up_axis_items,
|
||||
)
|
||||
|
||||
angle_type: bpy.props.EnumProperty( # type: ignore
|
||||
name="Type",
|
||||
items=[
|
||||
("DEFAULT", "Default", ""),
|
||||
("DEFAULT", "Unsigned", ""),
|
||||
("SIGNED", "Signed", ""),
|
||||
],
|
||||
)
|
||||
@ -798,13 +791,12 @@ class RotationFromAngle(AbstractPowerShipNode):
|
||||
self, context: bpy.types.Context, layout: bpy.types.UILayout
|
||||
) -> None:
|
||||
super().draw_buttons(context, layout)
|
||||
layout.prop(self, "axis")
|
||||
layout.prop(self, "angle_type")
|
||||
|
||||
def init(self, context):
|
||||
self.add_optional_input_socket("NodeSocketVector", "U")
|
||||
self.add_optional_input_socket("NodeSocketVector", "V")
|
||||
self.outputs.new("NodeSocketQuaternion", "Rotation")
|
||||
self.outputs.new("NodeSocketFloat", "Angle")
|
||||
|
||||
def execute(self, depsgraph: bpy.types.Depsgraph) -> None:
|
||||
u = self._get_optional_input_value("U", Vector)
|
||||
@ -818,10 +810,7 @@ class RotationFromAngle(AbstractPowerShipNode):
|
||||
else:
|
||||
angle = u.angle(v)
|
||||
|
||||
m = Matrix.Rotation(angle, 3, self.axis)
|
||||
res = m.to_quaternion()
|
||||
|
||||
self.outputs["Rotation"].default_value = res
|
||||
self.outputs["Angle"].default_value = angle
|
||||
|
||||
|
||||
_enum_vector_math_operations = [
|
||||
@ -1006,6 +995,7 @@ class SetBoneNode(AbstractPowerShipNode):
|
||||
bone_mat_world: Matrix = arm_matrix @ bone.matrix
|
||||
|
||||
loc, rot, scale = bone_mat_world.decompose()
|
||||
|
||||
if control_location is not None:
|
||||
loc = control_location
|
||||
if control_rotation is not None:
|
||||
@ -1013,24 +1003,27 @@ class SetBoneNode(AbstractPowerShipNode):
|
||||
if control_scale is not None:
|
||||
scale = control_scale
|
||||
|
||||
# TODO: Fix jittering bone scale which happens
|
||||
# esp. when multiple bones are parented to the rotated bone
|
||||
# rounding helps but does not entirely fix the issue.
|
||||
scale = [round(x, 4) for x in scale]
|
||||
v_nil = Vector((0, 0, 0))
|
||||
bone_rest_rot_scale = bone.bone.matrix_local.copy()
|
||||
|
||||
match self.space:
|
||||
case "WORLD":
|
||||
bone_mat_world = Matrix.LocRotScale(loc, rot, scale)
|
||||
bone_mat_world = Matrix.LocRotScale(
|
||||
loc, rot.normalized(), scale)
|
||||
loc, rot, scale = bone_mat_world.decompose()
|
||||
case "CHANNELS":
|
||||
# Not sure what causes the scale to flip, however...
|
||||
# The y/z-scale flips on update if multiple rotations are chained,
|
||||
# this generates jitter when running const updates - flipping seems to temp fix it.
|
||||
scale = [scale[i] for i in [0, 2, 1]]
|
||||
v_nil = Vector((0, 0, 0))
|
||||
bone_rest_rot_scale = bone.bone.matrix_local.copy()
|
||||
bone_rest_rot_scale.translation = v_nil
|
||||
bone_rest_rot = bone_rest_rot_scale.to_quaternion()
|
||||
mat_rot_scale = Matrix.LocRotScale(
|
||||
v_nil, rot, scale) @ bone_rest_rot.to_matrix().to_4x4()
|
||||
v_nil, rot, scale) @ bone_rest_rot_scale
|
||||
mat_loc = Matrix.Translation(loc)
|
||||
bone_mat_world = mat_loc @ mat_rot_scale
|
||||
|
||||
bone.matrix = arm_matrix.inverted() @ bone_mat_world
|
||||
loc, rot, scale = bone.matrix.decompose()
|
||||
|
||||
|
||||
class TwoBoneIKNode(AbstractPowerShipNode):
|
||||
@ -1237,61 +1230,61 @@ class ClampNode(AbstractPowerShipNode):
|
||||
self.outputs["Result"].default_value = clamped
|
||||
|
||||
|
||||
class AbstractTwoValueMathNode(AbstractPowerShipNode):
|
||||
def init(self, context: bpy.types.Context) -> None:
|
||||
self.inputs.new("NodeSocketFloat", "A")
|
||||
self.inputs.new("NodeSocketFloat", "B")
|
||||
self.outputs.new("NodeSocketFloat", "Result")
|
||||
|
||||
def execute(self, depsgraph: bpy.types.Depsgraph) -> None:
|
||||
a = self._get_input_value("A", float)
|
||||
b = self._get_input_value("B", float)
|
||||
self.outputs["Result"].default_value = self.calculate(a, b)
|
||||
|
||||
def calculate(self, a: float, b: float) -> float:
|
||||
return 0
|
||||
|
||||
|
||||
class AddNode(AbstractTwoValueMathNode):
|
||||
"""Add two values"""
|
||||
|
||||
bl_idname = "AddNode"
|
||||
bl_label = "Add"
|
||||
|
||||
def calculate(self, a: float, b: float) -> float:
|
||||
return a + b
|
||||
|
||||
|
||||
class SubtractNode(AbstractTwoValueMathNode):
|
||||
"""Subtract two values"""
|
||||
|
||||
bl_idname = "SubtractNode"
|
||||
bl_label = "Subtract"
|
||||
|
||||
def calculate(self, a: float, b: float) -> float:
|
||||
return a - b
|
||||
|
||||
|
||||
class MultiplyNode(AbstractTwoValueMathNode):
|
||||
"""Multiply two values"""
|
||||
|
||||
bl_idname = "MultiplyNode"
|
||||
bl_label = "Multiply"
|
||||
|
||||
def calculate(self, a: float, b: float) -> float:
|
||||
return a * b
|
||||
|
||||
|
||||
class DivideNode(AbstractTwoValueMathNode):
|
||||
"""Divide two values; division by zero results in NaN"""
|
||||
|
||||
bl_idname = "DivideNode"
|
||||
bl_label = "Divide"
|
||||
|
||||
def calculate(self, a: float, b: float) -> float:
|
||||
if b == 0:
|
||||
return float("nan")
|
||||
return a / b
|
||||
# class AbstractTwoValueMathNode(AbstractPowerShipNode):
|
||||
# def init(self, context: bpy.types.Context) -> None:
|
||||
# self.inputs.new("NodeSocketFloat", "A")
|
||||
# self.inputs.new("NodeSocketFloat", "B")
|
||||
# self.outputs.new("NodeSocketFloat", "Result")
|
||||
#
|
||||
# def execute(self, depsgraph: bpy.types.Depsgraph) -> None:
|
||||
# a = self._get_input_value("A", float)
|
||||
# b = self._get_input_value("B", float)
|
||||
# self.outputs["Result"].default_value = self.calculate(a, b)
|
||||
#
|
||||
# def calculate(self, a: float, b: float) -> float:
|
||||
# return 0
|
||||
#
|
||||
#
|
||||
# class AddNode(AbstractTwoValueMathNode):
|
||||
# """Add two values"""
|
||||
#
|
||||
# bl_idname = "AddNode"
|
||||
# bl_label = "Add"
|
||||
#
|
||||
# def calculate(self, a: float, b: float) -> float:
|
||||
# return a + b
|
||||
#
|
||||
#
|
||||
# class SubtractNode(AbstractTwoValueMathNode):
|
||||
# """Subtract two values"""
|
||||
#
|
||||
# bl_idname = "SubtractNode"
|
||||
# bl_label = "Subtract"
|
||||
#
|
||||
# def calculate(self, a: float, b: float) -> float:
|
||||
# return a - b
|
||||
#
|
||||
#
|
||||
# class MultiplyNode(AbstractTwoValueMathNode):
|
||||
# """Multiply two values"""
|
||||
#
|
||||
# bl_idname = "MultiplyNode"
|
||||
# bl_label = "Multiply"
|
||||
#
|
||||
# def calculate(self, a: float, b: float) -> float:
|
||||
# return a * b
|
||||
#
|
||||
#
|
||||
# class DivideNode(AbstractTwoValueMathNode):
|
||||
# """Divide two values; division by zero results in NaN"""
|
||||
#
|
||||
# bl_idname = "DivideNode"
|
||||
# bl_label = "Divide"
|
||||
#
|
||||
# def calculate(self, a: float, b: float) -> float:
|
||||
# if b == 0:
|
||||
# return float("nan")
|
||||
# return a / b
|
||||
|
||||
|
||||
def _on_num_sockets_change(self: "SequenceNode", context: bpy.types.Context) -> None:
|
||||
@ -1394,7 +1387,7 @@ node_categories = [
|
||||
items=[
|
||||
nodeitems_utils.NodeItem("RotateTowards"),
|
||||
nodeitems_utils.NodeItem("OffsetRotation"),
|
||||
nodeitems_utils.NodeItem("RotationFromAngle"),
|
||||
nodeitems_utils.NodeItem("AngleFromVectors"),
|
||||
nodeitems_utils.NodeItem("NormalFromPoints"),
|
||||
nodeitems_utils.NodeItem("SplitVector"),
|
||||
nodeitems_utils.NodeItem("ToVector"),
|
||||
@ -1439,7 +1432,7 @@ classes = (
|
||||
SequenceNode,
|
||||
# Math Nodes
|
||||
RotateTowards,
|
||||
RotationFromAngle,
|
||||
AngleFromVectors,
|
||||
OffsetRotation,
|
||||
NormalFromPoints,
|
||||
ToVector,
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user