55 const float3 local_main_axis,
58 for (
const int i :
IndexRange(vectors.size())) {
64 float old_rotation[3][3];
67 mul_v3_m3v3(old_axis, old_rotation, local_main_axis);
81 const float angle = factors[i] * full_angle;
86 float new_rotation_matrix[3][3];
87 mul_m3_m3m3(new_rotation_matrix, rotation, old_rotation);
92 rotations[i] = new_rotation;
98 const float3 local_main_axis,
99 const float3 local_pivot_axis,
102 if (local_main_axis == local_pivot_axis) {
107 for (
const int i :
IndexRange(vectors.size())) {
113 float old_rotation[3][3];
116 mul_v3_m3v3(old_axis, old_rotation, local_main_axis);
118 mul_v3_m3v3(pivot_axis, old_rotation, local_pivot_axis);
121 if (full_angle >
M_PI) {
123 full_angle -= 2.0f *
M_PI;
125 const float angle = factors[i] * full_angle;
127 float rotation[3][3];
130 float new_rotation_matrix[3][3];
131 mul_m3_m3m3(new_rotation_matrix, rotation, old_rotation);
136 rotations[i] = new_rotation;
149 if (!rotation_attribute) {
159 float3 local_main_axis{0, 0, 0};
160 local_main_axis[storage.
axis] = 1;
165 float3 local_pivot_axis{0, 0, 0};
170 rotation_attribute.apply_span_and_save();
187 params.set_output(
"Geometry", geometry_set);
199 node->storage = node_storage;
220 "Align Rotation to Vector",
228 "NodeGeometryAlignRotationToVector",
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
#define NODE_CLASS_GEOMETRY
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
#define GEO_NODE_ALIGN_ROTATION_TO_VECTOR
void nodeRegisterType(struct bNodeType *ntype)
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
void eul_to_mat3(float mat[3][3], const float eul[3])
void mat3_to_eul(float eul[3], const float mat[3][3])
void axis_angle_to_mat3(float R[3][3], const float axis[3], const float angle)
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT
float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
static uint8 component(Color32 c, uint i)
@ GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_AUTO
@ GEO_NODE_ALIGN_ROTATION_TO_VECTOR_AXIS_X
GeometryNodeAttributeInputMode
@ GEO_NODE_ATTRIBUTE_INPUT_VECTOR
@ GEO_NODE_ATTRIBUTE_INPUT_FLOAT
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
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)
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
void *(* MEM_callocN)(size_t len, const char *str)
TypedReadAttribute< float > FloatReadAttribute
TypedReadAttribute< float3 > Float3ReadAttribute
GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set)
static void geo_node_align_rotation_to_vector_update(bNodeTree *UNUSED(ntree), bNode *node)
static void geo_node_align_rotation_to_vector_exec(GeoNodeExecParams params)
static void geo_node_align_rotation_to_vector_init(bNodeTree *UNUSED(ntree), bNode *node)
void update_attribute_input_socket_availabilities(bNode &node, const StringRef name, const GeometryNodeAttributeInputMode mode, const bool name_is_available)
static void align_rotations_fixed_pivot(const Float3ReadAttribute &vectors, const FloatReadAttribute &factors, const float3 local_main_axis, const float3 local_pivot_axis, MutableSpan< float3 > rotations)
static void align_rotations_on_component(GeometryComponent &component, const GeoNodeExecParams ¶ms)
static void align_rotations_auto_pivot(const Float3ReadAttribute &vectors, const FloatReadAttribute &factors, const float3 local_main_axis, MutableSpan< float3 > rotations)
static bNodeSocketTemplate geo_node_align_rotation_to_vector_out[]
void register_node_type_geo_align_rotation_to_vector()
static void geo_node_align_rotation_to_vector_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static bNodeSocketTemplate geo_node_align_rotation_to_vector_in[]
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
void node_free_standard_storage(bNode *node)
GeometryComponent & get_component_for_write(GeometryComponentType component_type)
bool has(const GeometryComponentType component_type) const
uint8_t input_type_factor
uint8_t input_type_vector
Compact definition of a node socket.
NodeGeometryExecFunction geometry_node_execute
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
static float3 cross_high_precision(const float3 &a, const float3 &b)