42 const float3 local_main_axis,
46 for (const int maski : mask_range) {
47 const int64_t i = mask[maski];
48 const float3 vector = vectors[i];
49 if (is_zero_v3(vector)) {
50 output_rotations[i] = input_rotations[i];
54 float old_rotation[3][3];
55 eul_to_mat3(old_rotation, input_rotations[i]);
57 mul_v3_m3v3(old_axis, old_rotation, local_main_axis);
59 const float3 new_axis = math::normalize(vector);
60 float3 rotation_axis = math::cross_high_precision(old_axis, new_axis);
61 if (is_zero_v3(rotation_axis)) {
63 rotation_axis = math::cross_high_precision(old_axis, float3(1, 0, 0));
64 if (is_zero_v3(rotation_axis)) {
66 rotation_axis = math::cross_high_precision(old_axis, float3(0, 1, 0));
70 const float full_angle = angle_normalized_v3v3(old_axis, new_axis);
71 const float angle = factors[i] * full_angle;
74 axis_angle_to_mat3(rotation, rotation_axis, angle);
76 float new_rotation_matrix[3][3];
77 mul_m3_m3m3(new_rotation_matrix, rotation, old_rotation);
80 mat3_to_eul(new_rotation, new_rotation_matrix);
82 output_rotations[i] = new_rotation;
91 const float3 local_main_axis,
92 const float3 local_pivot_axis,
96 for (const int64_t maski : mask_range) {
97 const int64_t i = mask[maski];
98 if (local_main_axis == local_pivot_axis) {
100 output_rotations[i] = input_rotations[i];
104 const float3 vector = vectors[i];
105 if (is_zero_v3(vector)) {
106 output_rotations[i] = input_rotations[i];
110 float old_rotation[3][3];
111 eul_to_mat3(old_rotation, input_rotations[i]);
113 mul_v3_m3v3(old_axis, old_rotation, local_main_axis);
115 mul_v3_m3v3(pivot_axis, old_rotation, local_pivot_axis);
117 float full_angle = angle_signed_on_axis_v3v3_v3(vector, old_axis, pivot_axis);
118 if (full_angle > M_PI) {
120 full_angle -= 2.0f * M_PI;
122 const float angle = factors[i] * full_angle;
124 float rotation[3][3];
125 axis_angle_to_mat3(rotation, pivot_axis, angle);
127 float new_rotation_matrix[3][3];
128 mul_m3_m3m3(new_rotation_matrix, rotation, old_rotation);
131 mat3_to_eul(new_rotation, new_rotation_matrix);
133 output_rotations[i] = new_rotation;
141 int pivot_axis_mode_;
145 : main_axis_mode_(main_axis_mode), pivot_axis_mode_(pivot_axis_mode)
148 this->set_signature(&signature);
155 signature.single_input<
float>(
"Factor");
156 signature.single_input<
float3>(
"Vector");
158 signature.single_output<
float3>(
"Rotation");
159 return signature.build();
168 auto output_rotations =
params.uninitialized_single_output<
float3>(3,
"Rotation");
170 float3 local_main_axis = {0.0f, 0.0f, 0.0f};
171 local_main_axis[main_axis_mode_] = 1;
175 mask, input_rotations, vectors, factors, local_main_axis, output_rotations);
178 float3 local_pivot_axis = {0.0f, 0.0f, 0.0f};
179 local_pivot_axis[pivot_axis_mode_ - 1] = 1;
#define NODE_CLASS_CONVERTER
#define FN_NODE_ALIGN_EULER_TO_VECTOR
void nodeRegisterType(struct bNodeType *ntype)
@ FN_NODE_ALIGN_EULER_TO_VECTOR_PIVOT_AXIS_AUTO
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
void single_input(const char *name)
void construct_and_set_matching_fn(Args &&...args)
static fn::MFSignature create_signature()
MF_AlignEulerToVector(int main_axis_mode, int pivot_axis_mode)
void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
static void fn_node_align_euler_to_vector_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static void fn_node_align_euler_to_vector_declare(NodeDeclarationBuilder &b)
static void align_rotations_fixed_pivot(IndexMask mask, const VArray< float3 > &input_rotations, const VArray< float3 > &vectors, const VArray< float > &factors, const float3 local_main_axis, const float3 local_pivot_axis, const MutableSpan< float3 > output_rotations)
static void fn_node_align_euler_to_vector_build_multi_function(NodeMultiFunctionBuilder &builder)
static void align_rotations_auto_pivot(IndexMask mask, const VArray< float3 > &input_rotations, const VArray< float3 > &vectors, const VArray< float > &factors, const float3 local_main_axis, const MutableSpan< float3 > output_rotations)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void register_node_type_fn_align_euler_to_vector()
void fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
NodeMultiFunctionBuildFunction build_multi_function
NodeDeclareFunction declare