WIP: Geometry Nodes: Rotation type #107954

Closed
Hans Goudey wants to merge 4 commits from HooglyBoogly:geometry-nodes-rotation-type into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
40 changed files with 651 additions and 47 deletions

View File

@ -550,7 +550,9 @@ class NODE_MT_category_GEO_UTILITIES_ROTATION(Menu):
def draw(self, _context): def draw(self, _context):
layout = self.layout layout = self.layout
node_add_menu.add_node_type(layout, "FunctionNodeAlignEulerToVector") node_add_menu.add_node_type(layout, "FunctionNodeAlignEulerToVector")
node_add_menu.add_node_type(layout, "FunctionNodeCombineRotation")
node_add_menu.add_node_type(layout, "FunctionNodeRotateEuler") node_add_menu.add_node_type(layout, "FunctionNodeRotateEuler")
node_add_menu.add_node_type(layout, "FunctionNodeSeparateRotation")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label) node_add_menu.draw_assets_for_catalog(layout, self.bl_label)

View File

@ -1337,6 +1337,8 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define FN_NODE_INPUT_INT 1220 #define FN_NODE_INPUT_INT 1220
#define FN_NODE_SEPARATE_COLOR 1221 #define FN_NODE_SEPARATE_COLOR 1221
#define FN_NODE_COMBINE_COLOR 1222 #define FN_NODE_COMBINE_COLOR 1222
#define FN_NODE_COMBINE_ROTATION 1223
#define FN_NODE_SEPARATE_ROTATION 1224
/** \} */ /** \} */

View File

@ -329,6 +329,7 @@ static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket
case SOCK_VECTOR: case SOCK_VECTOR:
case SOCK_RGBA: case SOCK_RGBA:
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
case SOCK_ROTATION:
case SOCK_INT: case SOCK_INT:
case SOCK_STRING: case SOCK_STRING:
case SOCK_CUSTOM: case SOCK_CUSTOM:
@ -475,6 +476,9 @@ static void write_node_socket_default_value(BlendWriter *writer, bNodeSocket *so
case SOCK_MATERIAL: case SOCK_MATERIAL:
BLO_write_struct(writer, bNodeSocketValueMaterial, sock->default_value); BLO_write_struct(writer, bNodeSocketValueMaterial, sock->default_value);
break; break;
case SOCK_ROTATION:
BLO_write_struct(writer, bNodeSocketValueRotation, sock->default_value);
break;
case SOCK_CUSTOM: case SOCK_CUSTOM:
/* Custom node sockets where default_value is defined uses custom properties for storage. */ /* Custom node sockets where default_value is defined uses custom properties for storage. */
break; break;
@ -919,6 +923,7 @@ static void lib_link_node_socket(BlendLibReader *reader, ID *self_id, bNodeSocke
case SOCK_VECTOR: case SOCK_VECTOR:
case SOCK_RGBA: case SOCK_RGBA:
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
case SOCK_ROTATION:
case SOCK_INT: case SOCK_INT:
case SOCK_STRING: case SOCK_STRING:
case SOCK_CUSTOM: case SOCK_CUSTOM:
@ -1011,6 +1016,7 @@ static void expand_node_socket(BlendExpander *expander, bNodeSocket *sock)
case SOCK_VECTOR: case SOCK_VECTOR:
case SOCK_RGBA: case SOCK_RGBA:
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
case SOCK_ROTATION:
case SOCK_INT: case SOCK_INT:
case SOCK_STRING: case SOCK_STRING:
case SOCK_CUSTOM: case SOCK_CUSTOM:
@ -1699,6 +1705,7 @@ static void socket_id_user_increment(bNodeSocket *sock)
case SOCK_VECTOR: case SOCK_VECTOR:
case SOCK_RGBA: case SOCK_RGBA:
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
case SOCK_ROTATION:
case SOCK_INT: case SOCK_INT:
case SOCK_STRING: case SOCK_STRING:
case SOCK_CUSTOM: case SOCK_CUSTOM:
@ -1744,6 +1751,7 @@ static bool socket_id_user_decrement(bNodeSocket *sock)
case SOCK_VECTOR: case SOCK_VECTOR:
case SOCK_RGBA: case SOCK_RGBA:
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
case SOCK_ROTATION:
case SOCK_INT: case SOCK_INT:
case SOCK_STRING: case SOCK_STRING:
case SOCK_CUSTOM: case SOCK_CUSTOM:
@ -1797,6 +1805,7 @@ void nodeModifySocketType(bNodeTree *ntree,
case SOCK_RGBA: case SOCK_RGBA:
case SOCK_SHADER: case SOCK_SHADER:
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
case SOCK_ROTATION:
case SOCK_CUSTOM: case SOCK_CUSTOM:
case SOCK_OBJECT: case SOCK_OBJECT:
case SOCK_IMAGE: case SOCK_IMAGE:
@ -1900,6 +1909,8 @@ const char *nodeStaticSocketType(const int type, const int subtype)
} }
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
return "NodeSocketBool"; return "NodeSocketBool";
case SOCK_ROTATION:
return "NodeSocketRotation";
case SOCK_VECTOR: case SOCK_VECTOR:
switch (PropertySubType(subtype)) { switch (PropertySubType(subtype)) {
case PROP_TRANSLATION: case PROP_TRANSLATION:
@ -1979,6 +1990,8 @@ const char *nodeStaticSocketInterfaceType(const int type, const int subtype)
} }
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
return "NodeSocketInterfaceBool"; return "NodeSocketInterfaceBool";
case SOCK_ROTATION:
return "NodeSocketInterfaceRotation";
case SOCK_VECTOR: case SOCK_VECTOR:
switch (PropertySubType(subtype)) { switch (PropertySubType(subtype)) {
case PROP_TRANSLATION: case PROP_TRANSLATION:
@ -2030,6 +2043,8 @@ const char *nodeStaticSocketLabel(const int type, const int /*subtype*/)
return "Integer"; return "Integer";
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
return "Boolean"; return "Boolean";
case SOCK_ROTATION:
return "Rotation";
case SOCK_VECTOR: case SOCK_VECTOR:
return "Vector"; return "Vector";
case SOCK_RGBA: case SOCK_RGBA:
@ -2570,6 +2585,7 @@ static void *socket_value_storage(bNodeSocket &socket)
case SOCK_MATERIAL: case SOCK_MATERIAL:
return &socket.default_value_typed<bNodeSocketValueMaterial>()->value; return &socket.default_value_typed<bNodeSocketValueMaterial>()->value;
case SOCK_STRING: case SOCK_STRING:
case SOCK_ROTATION:
/* We don't want do this now! */ /* We don't want do this now! */
return nullptr; return nullptr;
case SOCK_CUSTOM: case SOCK_CUSTOM:

View File

@ -22,7 +22,7 @@ using nodes::SocketDeclaration;
static bool is_field_socket_type(eNodeSocketDatatype type) static bool is_field_socket_type(eNodeSocketDatatype type)
{ {
return ELEM(type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA); return ELEM(type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA, SOCK_ROTATION);
} }
static bool is_field_socket_type(const bNodeSocket &socket) static bool is_field_socket_type(const bNodeSocket &socket)

View File

@ -1205,6 +1205,7 @@ static const float std_node_socket_colors[][4] = {
{0.96, 0.96, 0.96, 1.0}, /* SOCK_COLLECTION */ {0.96, 0.96, 0.96, 1.0}, /* SOCK_COLLECTION */
{0.62, 0.31, 0.64, 1.0}, /* SOCK_TEXTURE */ {0.62, 0.31, 0.64, 1.0}, /* SOCK_TEXTURE */
{0.92, 0.46, 0.51, 1.0}, /* SOCK_MATERIAL */ {0.92, 0.46, 0.51, 1.0}, /* SOCK_MATERIAL */
{0.92, 0.46, 0.7, 1.0}, /* SOCK_ROTATION */
}; };
/* common color callbacks for standard types */ /* common color callbacks for standard types */
@ -1327,6 +1328,11 @@ static void std_node_socket_draw(
} }
} }
break; break;
case SOCK_ROTATION: {
uiLayout *column = uiLayoutColumn(layout, true);
uiItemR(column, ptr, "default_value", DEFAULT_FLAGS, text, ICON_NONE);
break;
}
case SOCK_RGBA: { case SOCK_RGBA: {
if (text[0] == '\0') { if (text[0] == '\0') {
uiItemR(layout, ptr, "default_value", DEFAULT_FLAGS, "", 0); uiItemR(layout, ptr, "default_value", DEFAULT_FLAGS, "", 0);
@ -1458,6 +1464,7 @@ static void std_node_socket_interface_draw(bContext * /*C*/, uiLayout *layout, P
break; break;
} }
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
case SOCK_ROTATION:
case SOCK_RGBA: case SOCK_RGBA:
case SOCK_STRING: case SOCK_STRING:
case SOCK_OBJECT: case SOCK_OBJECT:

View File

@ -139,6 +139,7 @@ static eCustomDataType data_type_in_attribute_input_node(const eCustomDataType t
case CD_PROP_FLOAT3: case CD_PROP_FLOAT3:
case CD_PROP_COLOR: case CD_PROP_COLOR:
case CD_PROP_BOOL: case CD_PROP_BOOL:
case CD_PROP_QUATERNION:
return type; return type;
case CD_PROP_BYTE_COLOR: case CD_PROP_BYTE_COLOR:
return CD_PROP_COLOR; return CD_PROP_COLOR;

View File

@ -432,6 +432,7 @@ static bool socket_can_be_viewed(const bNodeSocket &socket)
SOCK_VECTOR, SOCK_VECTOR,
SOCK_INT, SOCK_INT,
SOCK_BOOLEAN, SOCK_BOOLEAN,
SOCK_ROTATION,
SOCK_RGBA); SOCK_RGBA);
} }
@ -448,6 +449,8 @@ static eCustomDataType socket_type_to_custom_data_type(const eNodeSocketDatatype
return CD_PROP_BOOL; return CD_PROP_BOOL;
case SOCK_RGBA: case SOCK_RGBA:
return CD_PROP_COLOR; return CD_PROP_COLOR;
case SOCK_ROTATION:
return CD_PROP_QUATERNION;
default: default:
/* Fallback. */ /* Fallback. */
return CD_AUTO_FROM_NAME; return CD_AUTO_FROM_NAME;
@ -2238,6 +2241,7 @@ static int get_main_socket_priority(const bNodeSocket *socket)
case SOCK_SHADER: case SOCK_SHADER:
case SOCK_OBJECT: case SOCK_OBJECT:
case SOCK_IMAGE: case SOCK_IMAGE:
case SOCK_ROTATION:
case SOCK_GEOMETRY: case SOCK_GEOMETRY:
case SOCK_COLLECTION: case SOCK_COLLECTION:
case SOCK_TEXTURE: case SOCK_TEXTURE:

View File

@ -391,6 +391,9 @@ static Vector<NodeLinkItem> ui_node_link_items(NodeLinkArg *arg,
else if (dynamic_cast<const decl::Color *>(&socket_decl)) { else if (dynamic_cast<const decl::Color *>(&socket_decl)) {
item.socket_type = SOCK_RGBA; item.socket_type = SOCK_RGBA;
} }
else if (dynamic_cast<const decl::Rotation *>(&socket_decl)) {
item.socket_type = SOCK_ROTATION;
}
else if (dynamic_cast<const decl::String *>(&socket_decl)) { else if (dynamic_cast<const decl::String *>(&socket_decl)) {
item.socket_type = SOCK_STRING; item.socket_type = SOCK_STRING;
} }
@ -873,6 +876,7 @@ static void ui_node_draw_input(
ATTR_FALLTHROUGH; ATTR_FALLTHROUGH;
case SOCK_FLOAT: case SOCK_FLOAT:
case SOCK_INT: case SOCK_INT:
case SOCK_ROTATION:
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
case SOCK_RGBA: case SOCK_RGBA:
uiItemR(sub, &inputptr, "default_value", 0, "", ICON_NONE); uiItemR(sub, &inputptr, "default_value", 0, "", ICON_NONE);

View File

@ -238,6 +238,7 @@ typedef enum eNodeSocketDatatype {
SOCK_COLLECTION = 11, SOCK_COLLECTION = 11,
SOCK_TEXTURE = 12, SOCK_TEXTURE = 12,
SOCK_MATERIAL = 13, SOCK_MATERIAL = 13,
SOCK_ROTATION = 14,
} eNodeSocketDatatype; } eNodeSocketDatatype;
/** Socket shape. */ /** Socket shape. */
@ -724,6 +725,10 @@ typedef struct bNodeSocketValueVector {
float min, max; float min, max;
} bNodeSocketValueVector; } bNodeSocketValueVector;
typedef struct bNodeSocketValueRotation {
float value_euler[3];
} bNodeSocketValueRotation;
typedef struct bNodeSocketValueRGBA { typedef struct bNodeSocketValueRGBA {
float value[4]; float value[4];
} bNodeSocketValueRGBA; } bNodeSocketValueRGBA;
@ -2461,3 +2466,8 @@ typedef enum NodeCombSepColorMode {
NODE_COMBSEP_COLOR_HSV = 1, NODE_COMBSEP_COLOR_HSV = 1,
NODE_COMBSEP_COLOR_HSL = 2, NODE_COMBSEP_COLOR_HSL = 2,
} NodeCombSepColorMode; } NodeCombSepColorMode;
typedef enum NodeCombineSeparateRotatioNMode {
NODE_COMBINE_SEPARATE_ROTATION_EULER_XYZ = 0,
NODE_COMBINE_SEPARATE_ROTATION_AXIS_ANGLE = 1,
} NodeCombineSeparateRotatioNMode;

View File

@ -68,6 +68,7 @@ static const EnumPropertyItem node_socket_data_type_items[] = {
{SOCK_INT, "INT", 0, "Integer", ""}, {SOCK_INT, "INT", 0, "Integer", ""},
{SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""}, {SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
{SOCK_VECTOR, "VECTOR", 0, "Vector", ""}, {SOCK_VECTOR, "VECTOR", 0, "Vector", ""},
{SOCK_ROTATION, "ROTATION", 0, "Rotation", ""},
{SOCK_STRING, "STRING", 0, "String", ""}, {SOCK_STRING, "STRING", 0, "String", ""},
{SOCK_RGBA, "RGBA", 0, "Color", ""}, {SOCK_RGBA, "RGBA", 0, "Color", ""},
{SOCK_OBJECT, "OBJECT", 0, "Object", ""}, {SOCK_OBJECT, "OBJECT", 0, "Object", ""},
@ -95,6 +96,7 @@ static const EnumPropertyItem node_socket_type_items[] = {
{SOCK_INT, "INT", 0, "Integer", ""}, {SOCK_INT, "INT", 0, "Integer", ""},
{SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""}, {SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
{SOCK_VECTOR, "VECTOR", 0, "Vector", ""}, {SOCK_VECTOR, "VECTOR", 0, "Vector", ""},
{SOCK_ROTATION, "ROTATION", 0, "Rotation", ""},
{SOCK_STRING, "STRING", 0, "String", ""}, {SOCK_STRING, "STRING", 0, "String", ""},
{SOCK_RGBA, "RGBA", 0, "RGBA", ""}, {SOCK_RGBA, "RGBA", 0, "RGBA", ""},
{SOCK_SHADER, "SHADER", 0, "Shader", ""}, {SOCK_SHADER, "SHADER", 0, "Shader", ""},
@ -510,6 +512,12 @@ static const EnumPropertyItem rna_node_combsep_color_items[] = {
{0, NULL, 0, NULL, NULL}, {0, NULL, 0, NULL, NULL},
}; };
static const EnumPropertyItem rna_node_combine_separate_rotation_items[] = {
{NODE_COMBINE_SEPARATE_ROTATION_EULER_XYZ, "EULER_XYZ", ICON_NONE, "Euler", ""},
{NODE_COMBINE_SEPARATE_ROTATION_AXIS_ANGLE, "AXIS_ANGLE", ICON_NONE, "Axis Angle", ""},
{0, NULL, 0, NULL, NULL},
};
#ifndef RNA_RUNTIME #ifndef RNA_RUNTIME
static const EnumPropertyItem node_sampler_type_items[] = { static const EnumPropertyItem node_sampler_type_items[] = {
{0, "NEAREST", 0, "Nearest", ""}, {0, "NEAREST", 0, "Nearest", ""},
@ -2084,6 +2092,7 @@ static bool switch_type_supported(const EnumPropertyItem *item)
SOCK_FLOAT, SOCK_FLOAT,
SOCK_INT, SOCK_INT,
SOCK_BOOLEAN, SOCK_BOOLEAN,
SOCK_ROTATION,
SOCK_VECTOR, SOCK_VECTOR,
SOCK_STRING, SOCK_STRING,
SOCK_RGBA, SOCK_RGBA,
@ -2232,7 +2241,8 @@ static bool generic_attribute_type_supported(const EnumPropertyItem *item)
CD_PROP_COLOR, CD_PROP_COLOR,
CD_PROP_BOOL, CD_PROP_BOOL,
CD_PROP_INT32, CD_PROP_INT32,
CD_PROP_BYTE_COLOR); CD_PROP_BYTE_COLOR,
CD_PROP_QUATERNION);
} }
static const EnumPropertyItem *rna_GeometryNodeAttributeType_type_itemf(bContext *UNUSED(C), static const EnumPropertyItem *rna_GeometryNodeAttributeType_type_itemf(bContext *UNUSED(C),
PointerRNA *UNUSED(ptr), PointerRNA *UNUSED(ptr),
@ -5339,6 +5349,28 @@ static void def_fn_combsep_color(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
} }
static void def_fn_combine_rotation(StructRNA *srna)
{
PropertyRNA *prop;
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, rna_node_combine_separate_rotation_items);
RNA_def_property_ui_text(prop, "Mode", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
static void def_fn_separate_rotation(StructRNA *srna)
{
PropertyRNA *prop;
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, rna_node_combine_separate_rotation_items);
RNA_def_property_ui_text(prop, "Mode", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
/* -- Shader Nodes ---------------------------------------------------------- */ /* -- Shader Nodes ---------------------------------------------------------- */
static void def_sh_output(StructRNA *srna) static void def_sh_output(StructRNA *srna)
@ -11896,6 +11928,44 @@ static void rna_def_node_socket_bool(BlenderRNA *brna,
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
} }
static void rna_def_node_socket_rotation(BlenderRNA *brna,
const char *identifier,
const char *interface_idname)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, identifier, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "Rotation Node Socket", "Rotation value socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
RNA_def_struct_sdna_from(srna, "bNodeSocketValueRotation", "default_value");
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_EULER);
RNA_def_property_float_sdna(prop, NULL, "value_euler");
// RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
/* socket interface */
srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
RNA_def_struct_ui_text(
srna, "Rotation Node Socket Interface", "Rotation value socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
RNA_def_struct_sdna_from(srna, "bNodeSocketValueRotation", "default_value");
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_EULER);
RNA_def_property_float_sdna(prop, NULL, "value_euler");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
}
static void rna_def_node_socket_vector(BlenderRNA *brna, static void rna_def_node_socket_vector(BlenderRNA *brna,
const char *identifier, const char *identifier,
const char *interface_idname, const char *interface_idname,
@ -12386,6 +12456,7 @@ static void rna_def_node_socket_standard_types(BlenderRNA *brna)
brna, "NodeSocketIntFactor", "NodeSocketInterfaceIntFactor", PROP_FACTOR); brna, "NodeSocketIntFactor", "NodeSocketInterfaceIntFactor", PROP_FACTOR);
rna_def_node_socket_bool(brna, "NodeSocketBool", "NodeSocketInterfaceBool"); rna_def_node_socket_bool(brna, "NodeSocketBool", "NodeSocketInterfaceBool");
rna_def_node_socket_rotation(brna, "NodeSocketRotation", "NodeSocketInterfaceRotation");
rna_def_node_socket_vector(brna, "NodeSocketVector", "NodeSocketInterfaceVector", PROP_NONE); rna_def_node_socket_vector(brna, "NodeSocketVector", "NodeSocketInterfaceVector", PROP_NONE);
rna_def_node_socket_vector(brna, rna_def_node_socket_vector(brna,

View File

@ -4,6 +4,8 @@
#pragma once #pragma once
#include "BLI_math_quaternion_types.hh"
#include "FN_field.hh" #include "FN_field.hh"
#include "FN_lazy_function.hh" #include "FN_lazy_function.hh"
#include "FN_multi_function_builder.hh" #include "FN_multi_function_builder.hh"
@ -72,7 +74,7 @@ class GeoNodeExecParams {
template<typename T> template<typename T>
static inline constexpr bool is_field_base_type_v = static inline constexpr bool is_field_base_type_v =
is_same_any_v<T, float, int, bool, ColorGeometry4f, float3, std::string>; is_same_any_v<T, float, int, bool, ColorGeometry4f, float3, std::string, math::Quaternion>;
/** /**
* Get the input value for the input socket with the given identifier. * Get the input value for the input socket with the given identifier.

View File

@ -9,6 +9,7 @@
#include "RNA_types.h" #include "RNA_types.h"
#include "BLI_color.hh" #include "BLI_color.hh"
#include "BLI_math_euler_types.hh"
#include "BLI_math_vector_types.hh" #include "BLI_math_vector_types.hh"
namespace blender::nodes::decl { namespace blender::nodes::decl {
@ -136,6 +137,27 @@ class ColorBuilder : public SocketDeclarationBuilder<Color> {
ColorBuilder &default_value(const ColorGeometry4f value); ColorBuilder &default_value(const ColorGeometry4f value);
}; };
class RotationBuilder;
class Rotation : public SocketDeclaration {
public:
math::EulerXYZ default_value;
friend RotationBuilder;
using Builder = RotationBuilder;
bNodeSocket &build(bNodeTree &ntree, bNode &node) const override;
bool matches(const bNodeSocket &socket) const override;
bNodeSocket &update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const override;
bool can_connect(const bNodeSocket &socket) const override;
};
class RotationBuilder : public SocketDeclarationBuilder<Rotation> {
public:
RotationBuilder &default_value(const math::EulerXYZ &value);
};
class StringBuilder; class StringBuilder;
class String : public SocketDeclaration { class String : public SocketDeclaration {
@ -387,6 +409,18 @@ inline StringBuilder &StringBuilder::default_value(std::string value)
/** \} */ /** \} */
/* -------------------------------------------------------------------- */
/** \name #RotationBuilder Inline Methods
* \{ */
inline RotationBuilder &RotationBuilder::default_value(const math::EulerXYZ &value)
{
decl_->default_value = value;
return *this;
}
/** \} */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/** \name #IDSocketDeclaration and Children Inline Methods /** \name #IDSocketDeclaration and Children Inline Methods
* \{ */ * \{ */

View File

@ -266,6 +266,7 @@ DefNode(TextureNode, TEX_NODE_PROC+TEX_DISTNOISE, 0, "TEX_DI
DefNode(FunctionNode, FN_NODE_ALIGN_EULER_TO_VECTOR, def_fn_align_euler_to_vector, "ALIGN_EULER_TO_VECTOR", AlignEulerToVector, "Align Euler to Vector", "") DefNode(FunctionNode, FN_NODE_ALIGN_EULER_TO_VECTOR, def_fn_align_euler_to_vector, "ALIGN_EULER_TO_VECTOR", AlignEulerToVector, "Align Euler to Vector", "")
DefNode(FunctionNode, FN_NODE_BOOLEAN_MATH, def_boolean_math, "BOOLEAN_MATH", BooleanMath, "Boolean Math", "") DefNode(FunctionNode, FN_NODE_BOOLEAN_MATH, def_boolean_math, "BOOLEAN_MATH", BooleanMath, "Boolean Math", "")
DefNode(FunctionNode, FN_NODE_COMBINE_COLOR, def_fn_combsep_color, "COMBINE_COLOR", CombineColor, "Combine Color", "") DefNode(FunctionNode, FN_NODE_COMBINE_COLOR, def_fn_combsep_color, "COMBINE_COLOR", CombineColor, "Combine Color", "")
DefNode(FunctionNode, FN_NODE_COMBINE_ROTATION, def_fn_combine_rotation, "COMBINE_ROTATION", CombineRotation, "Combine Rotation", "")
DefNode(FunctionNode, FN_NODE_COMPARE, def_compare, "COMPARE", Compare, "Compare", "") DefNode(FunctionNode, FN_NODE_COMPARE, def_compare, "COMPARE", Compare, "Compare", "")
DefNode(FunctionNode, FN_NODE_FLOAT_TO_INT, def_float_to_int, "FLOAT_TO_INT", FloatToInt, "Float to Integer", "") DefNode(FunctionNode, FN_NODE_FLOAT_TO_INT, def_float_to_int, "FLOAT_TO_INT", FloatToInt, "Float to Integer", "")
DefNode(FunctionNode, FN_NODE_INPUT_BOOL, def_fn_input_bool, "INPUT_BOOL", InputBool, "Boolean", "") DefNode(FunctionNode, FN_NODE_INPUT_BOOL, def_fn_input_bool, "INPUT_BOOL", InputBool, "Boolean", "")
@ -278,6 +279,7 @@ DefNode(FunctionNode, FN_NODE_RANDOM_VALUE, def_fn_random_value, "RANDOM_VALUE",
DefNode(FunctionNode, FN_NODE_REPLACE_STRING, 0, "REPLACE_STRING", ReplaceString, "Replace String", "") DefNode(FunctionNode, FN_NODE_REPLACE_STRING, 0, "REPLACE_STRING", ReplaceString, "Replace String", "")
DefNode(FunctionNode, FN_NODE_ROTATE_EULER, def_fn_rotate_euler, "ROTATE_EULER", RotateEuler, "Rotate Euler", "") DefNode(FunctionNode, FN_NODE_ROTATE_EULER, def_fn_rotate_euler, "ROTATE_EULER", RotateEuler, "Rotate Euler", "")
DefNode(FunctionNode, FN_NODE_SEPARATE_COLOR, def_fn_combsep_color, "SEPARATE_COLOR", SeparateColor, "Separate Color", "") DefNode(FunctionNode, FN_NODE_SEPARATE_COLOR, def_fn_combsep_color, "SEPARATE_COLOR", SeparateColor, "Separate Color", "")
DefNode(FunctionNode, FN_NODE_SEPARATE_ROTATION, def_fn_separate_rotation, "SEPARATE_ROTATION", SeparateRotation, "Separate Rotation", "")
DefNode(FunctionNode, FN_NODE_SLICE_STRING, 0, "SLICE_STRING", SliceString, "Slice String", "") DefNode(FunctionNode, FN_NODE_SLICE_STRING, 0, "SLICE_STRING", SliceString, "Slice String", "")
DefNode(FunctionNode, FN_NODE_STRING_LENGTH, 0, "STRING_LENGTH", StringLength, "String Length", "") DefNode(FunctionNode, FN_NODE_STRING_LENGTH, 0, "STRING_LENGTH", StringLength, "String Length", "")
DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToString, "Value to String", "") DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToString, "Value to String", "")

View File

@ -24,6 +24,7 @@ set(SRC
nodes/node_fn_align_euler_to_vector.cc nodes/node_fn_align_euler_to_vector.cc
nodes/node_fn_boolean_math.cc nodes/node_fn_boolean_math.cc
nodes/node_fn_combine_color.cc nodes/node_fn_combine_color.cc
nodes/node_fn_combine_rotation.cc
nodes/node_fn_compare.cc nodes/node_fn_compare.cc
nodes/node_fn_float_to_int.cc nodes/node_fn_float_to_int.cc
nodes/node_fn_input_bool.cc nodes/node_fn_input_bool.cc
@ -36,6 +37,7 @@ set(SRC
nodes/node_fn_replace_string.cc nodes/node_fn_replace_string.cc
nodes/node_fn_rotate_euler.cc nodes/node_fn_rotate_euler.cc
nodes/node_fn_separate_color.cc nodes/node_fn_separate_color.cc
nodes/node_fn_separate_rotation.cc
nodes/node_fn_slice_string.cc nodes/node_fn_slice_string.cc
nodes/node_fn_string_length.cc nodes/node_fn_string_length.cc
nodes/node_fn_value_to_string.cc nodes/node_fn_value_to_string.cc

View File

@ -11,6 +11,7 @@ void register_function_nodes()
register_node_type_fn_align_euler_to_vector(); register_node_type_fn_align_euler_to_vector();
register_node_type_fn_boolean_math(); register_node_type_fn_boolean_math();
register_node_type_fn_combine_color(); register_node_type_fn_combine_color();
register_node_type_fn_combine_rotation();
register_node_type_fn_compare(); register_node_type_fn_compare();
register_node_type_fn_float_to_int(); register_node_type_fn_float_to_int();
register_node_type_fn_input_bool(); register_node_type_fn_input_bool();
@ -23,6 +24,7 @@ void register_function_nodes()
register_node_type_fn_replace_string(); register_node_type_fn_replace_string();
register_node_type_fn_rotate_euler(); register_node_type_fn_rotate_euler();
register_node_type_fn_separate_color(); register_node_type_fn_separate_color();
register_node_type_fn_separate_rotation();
register_node_type_fn_slice_string(); register_node_type_fn_slice_string();
register_node_type_fn_string_length(); register_node_type_fn_string_length();
register_node_type_fn_value_to_string(); register_node_type_fn_value_to_string();

View File

@ -7,6 +7,7 @@
void register_node_type_fn_align_euler_to_vector(); void register_node_type_fn_align_euler_to_vector();
void register_node_type_fn_boolean_math(); void register_node_type_fn_boolean_math();
void register_node_type_fn_combine_color(); void register_node_type_fn_combine_color();
void register_node_type_fn_combine_rotation();
void register_node_type_fn_compare(); void register_node_type_fn_compare();
void register_node_type_fn_float_to_int(); void register_node_type_fn_float_to_int();
void register_node_type_fn_input_bool(); void register_node_type_fn_input_bool();
@ -19,6 +20,7 @@ void register_node_type_fn_random_value();
void register_node_type_fn_replace_string(); void register_node_type_fn_replace_string();
void register_node_type_fn_rotate_euler(); void register_node_type_fn_rotate_euler();
void register_node_type_fn_separate_color(); void register_node_type_fn_separate_color();
void register_node_type_fn_separate_rotation();
void register_node_type_fn_slice_string(); void register_node_type_fn_slice_string();
void register_node_type_fn_string_length(); void register_node_type_fn_string_length();
void register_node_type_fn_value_to_string(); void register_node_type_fn_value_to_string();

View File

@ -0,0 +1,96 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_axis_angle.hh"
#include "BLI_math_euler.hh"
#include "UI_interface.h"
#include "UI_resources.h"
#include "node_function_util.hh"
namespace blender::nodes::node_fn_combine_rotation_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Vector>(N_("Euler")).subtype(PROP_EULER).make_available([](bNode &node) {
node.custom1 = NODE_COMBINE_SEPARATE_ROTATION_EULER_XYZ;
});
b.add_input<decl::Vector>(N_("Axis"))
.default_value({0.0f, 0.0f, 1.0f})
.make_available(
[](bNode &node) { node.custom1 = NODE_COMBINE_SEPARATE_ROTATION_AXIS_ANGLE; });
b.add_input<decl::Float>(N_("Angle")).subtype(PROP_ANGLE).make_available([](bNode &node) {
node.custom1 = NODE_COMBINE_SEPARATE_ROTATION_AXIS_ANGLE;
});
b.add_output<decl::Rotation>(N_("Rotation"));
};
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
static void node_init(bNodeTree * /*tree*/, bNode *node)
{
node->custom1 = NODE_COMBINE_SEPARATE_ROTATION_EULER_XYZ;
}
static void node_update(bNodeTree *tree, bNode *node)
{
bke::nodeSetSocketAvailability(tree,
static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 0)),
node->custom1 == NODE_COMBINE_SEPARATE_ROTATION_EULER_XYZ);
bke::nodeSetSocketAvailability(tree,
static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 1)),
node->custom1 == NODE_COMBINE_SEPARATE_ROTATION_AXIS_ANGLE);
bke::nodeSetSocketAvailability(tree,
static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 2)),
node->custom1 == NODE_COMBINE_SEPARATE_ROTATION_AXIS_ANGLE);
}
static const mf::MultiFunction *get_multi_function(const bNode &bnode)
{
const auto mode = NodeCombineSeparateRotatioNMode(bnode.custom1);
static auto euler_xyz_fn = mf::build::SI1_SO<float3, math::Quaternion>(
"Euler XYZ to Quaternion",
[](float3 euler) { return math::to_quaternion(math::EulerXYZ(euler)); });
static auto axis_angle_fn = mf::build::SI2_SO<float3, float, math::Quaternion>(
"Axis Angle to Quaternion", [](float3 axis, float angle) {
return math::normalize(math::to_quaternion(math::AxisAngle(math::normalize(axis), angle)));
});
switch (mode) {
case NODE_COMBINE_SEPARATE_ROTATION_EULER_XYZ:
return &euler_xyz_fn;
case NODE_COMBINE_SEPARATE_ROTATION_AXIS_ANGLE:
return &axis_angle_fn;
}
BLI_assert_unreachable();
return nullptr;
}
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const mf::MultiFunction *fn = get_multi_function(builder.node());
builder.set_matching_fn(fn);
}
} // namespace blender::nodes::node_fn_combine_rotation_cc
void register_node_type_fn_combine_rotation(void)
{
namespace file_ns = blender::nodes::node_fn_combine_rotation_cc;
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_COMBINE_ROTATION, "Combine Rotation", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
ntype.initfunc = file_ns::node_init;
ntype.updatefunc = file_ns::node_update;
ntype.build_multi_function = file_ns::node_build_multi_function;
ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}

View File

@ -0,0 +1,118 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_axis_angle.hh"
#include "BLI_math_euler.hh"
#include "UI_interface.h"
#include "UI_resources.h"
#include "node_function_util.hh"
namespace blender::nodes::node_fn_separate_rotation_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Rotation>(N_("Rotation"));
b.add_output<decl::Vector>(N_("Euler")).subtype(PROP_EULER).make_available([](bNode &node) {
node.custom1 = NODE_COMBINE_SEPARATE_ROTATION_EULER_XYZ;
});
b.add_output<decl::Vector>(N_("Axis")).make_available([](bNode &node) {
node.custom1 = NODE_COMBINE_SEPARATE_ROTATION_AXIS_ANGLE;
});
b.add_output<decl::Float>(N_("Angle")).subtype(PROP_ANGLE).make_available([](bNode &node) {
node.custom1 = NODE_COMBINE_SEPARATE_ROTATION_AXIS_ANGLE;
});
};
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
static void node_init(bNodeTree * /*tree*/, bNode *node)
{
node->custom1 = NODE_COMBINE_SEPARATE_ROTATION_EULER_XYZ;
}
static void node_update(bNodeTree *tree, bNode *node)
{
bke::nodeSetSocketAvailability(tree,
static_cast<bNodeSocket *>(BLI_findlink(&node->outputs, 0)),
node->custom1 == NODE_COMBINE_SEPARATE_ROTATION_EULER_XYZ);
bke::nodeSetSocketAvailability(tree,
static_cast<bNodeSocket *>(BLI_findlink(&node->outputs, 1)),
node->custom1 == NODE_COMBINE_SEPARATE_ROTATION_AXIS_ANGLE);
bke::nodeSetSocketAvailability(tree,
static_cast<bNodeSocket *>(BLI_findlink(&node->outputs, 2)),
node->custom1 == NODE_COMBINE_SEPARATE_ROTATION_AXIS_ANGLE);
}
class QuaterniontoAxisAngleFunction : public mf::MultiFunction {
public:
QuaterniontoAxisAngleFunction()
{
static mf::Signature signature_;
mf::SignatureBuilder builder{"Quaternion to Axis Angle", signature_};
builder.single_input<math::Quaternion>("Quaternion");
builder.single_output<float3>("Axis");
builder.single_output<float>("Angle");
this->set_signature(&signature_);
}
void call(const IndexMask &mask, mf::Params params, mf::Context /*context*/) const override
{
const VArraySpan<math::Quaternion> quaternions =
params.readonly_single_input<math::Quaternion>(0, "Quaternion");
MutableSpan<float3> axes = params.uninitialized_single_output<float3>(2, "Axis");
MutableSpan<float> angles = params.uninitialized_single_output<float>(3, "Angle");
mask.foreach_index([&](const int64_t i) {
const math::AxisAngle axis_angle = math::to_axis_angle(quaternions[i]);
axes[i] = axis_angle.axis();
angles[i] = axis_angle.angle().radian();
});
}
};
static const mf::MultiFunction *get_multi_function(const bNode &bnode)
{
const auto mode = NodeCombineSeparateRotatioNMode(bnode.custom1);
static auto euler_xyz_fn = mf::build::SI1_SO<math::Quaternion, float3>(
"Quaternion to Euler XYZ",
[](const math::Quaternion quaternion) { return math::to_euler(quaternion); });
static QuaterniontoAxisAngleFunction axis_angle_fn;
switch (mode) {
case NODE_COMBINE_SEPARATE_ROTATION_EULER_XYZ:
return &euler_xyz_fn;
case NODE_COMBINE_SEPARATE_ROTATION_AXIS_ANGLE:
return &axis_angle_fn;
}
BLI_assert_unreachable();
return nullptr;
}
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const mf::MultiFunction *fn = get_multi_function(builder.node());
builder.set_matching_fn(fn);
}
} // namespace blender::nodes::node_fn_separate_rotation_cc
void register_node_type_fn_separate_rotation(void)
{
namespace file_ns = blender::nodes::node_fn_separate_rotation_cc;
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_SEPARATE_ROTATION, "Separate Rotation", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
ntype.initfunc = file_ns::node_init;
ntype.updatefunc = file_ns::node_update;
ntype.build_multi_function = file_ns::node_build_multi_function;
ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}

View File

@ -98,6 +98,7 @@ static bool geometry_node_tree_socket_type_valid(bNodeTreeType * /*treetype*/,
SOCK_VECTOR, SOCK_VECTOR,
SOCK_RGBA, SOCK_RGBA,
SOCK_BOOLEAN, SOCK_BOOLEAN,
SOCK_ROTATION,
SOCK_INT, SOCK_INT,
SOCK_STRING, SOCK_STRING,
SOCK_OBJECT, SOCK_OBJECT,

View File

@ -28,6 +28,8 @@ std::optional<eCustomDataType> node_data_type_to_custom_data_type(const eNodeSoc
return CD_PROP_COLOR; return CD_PROP_COLOR;
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
return CD_PROP_BOOL; return CD_PROP_BOOL;
case SOCK_ROTATION:
return CD_PROP_QUATERNION;
case SOCK_INT: case SOCK_INT:
return CD_PROP_INT32; return CD_PROP_INT32;
case SOCK_STRING: case SOCK_STRING:

View File

@ -23,6 +23,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Color>("Value", "Value_002").field_on_all(); b.add_input<decl::Color>("Value", "Value_002").field_on_all();
b.add_input<decl::Bool>("Value", "Value_003").field_on_all(); b.add_input<decl::Bool>("Value", "Value_003").field_on_all();
b.add_input<decl::Int>("Value", "Value_004").field_on_all(); b.add_input<decl::Int>("Value", "Value_004").field_on_all();
b.add_input<decl::Rotation>("Value", "Value_005").field_on_all();
b.add_output<decl::Geometry>("Geometry").propagate_all(); b.add_output<decl::Geometry>("Geometry").propagate_all();
b.add_output<decl::Vector>("Attribute").field_on_all(); b.add_output<decl::Vector>("Attribute").field_on_all();
@ -30,6 +31,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>("Attribute", "Attribute_002").field_on_all(); b.add_output<decl::Color>("Attribute", "Attribute_002").field_on_all();
b.add_output<decl::Bool>("Attribute", "Attribute_003").field_on_all(); b.add_output<decl::Bool>("Attribute", "Attribute_003").field_on_all();
b.add_output<decl::Int>("Attribute", "Attribute_004").field_on_all(); b.add_output<decl::Int>("Attribute", "Attribute_004").field_on_all();
b.add_output<decl::Rotation>("Attribute", "Attribute_005").field_on_all();
} }
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@ -60,12 +62,14 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *socket_value_color4f = socket_value_float->next; bNodeSocket *socket_value_color4f = socket_value_float->next;
bNodeSocket *socket_value_boolean = socket_value_color4f->next; bNodeSocket *socket_value_boolean = socket_value_color4f->next;
bNodeSocket *socket_value_int32 = socket_value_boolean->next; bNodeSocket *socket_value_int32 = socket_value_boolean->next;
bNodeSocket *socket_value_quat = socket_value_int32->next;
bke::nodeSetSocketAvailability(ntree, socket_value_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, socket_value_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_value_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, socket_value_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_value_color4f, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, socket_value_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, socket_value_boolean, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, socket_value_boolean, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, socket_value_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, socket_value_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, socket_value_quat, data_type == CD_PROP_QUATERNION);
bNodeSocket *out_socket_value_geometry = static_cast<bNodeSocket *>(node->outputs.first); bNodeSocket *out_socket_value_geometry = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *out_socket_value_vector = out_socket_value_geometry->next; bNodeSocket *out_socket_value_vector = out_socket_value_geometry->next;
@ -73,12 +77,14 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *out_socket_value_color4f = out_socket_value_float->next; bNodeSocket *out_socket_value_color4f = out_socket_value_float->next;
bNodeSocket *out_socket_value_boolean = out_socket_value_color4f->next; bNodeSocket *out_socket_value_boolean = out_socket_value_color4f->next;
bNodeSocket *out_socket_value_int32 = out_socket_value_boolean->next; bNodeSocket *out_socket_value_int32 = out_socket_value_boolean->next;
bNodeSocket *out_socket_value_quat = out_socket_value_int32->next;
bke::nodeSetSocketAvailability(ntree, out_socket_value_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, out_socket_value_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, out_socket_value_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, out_socket_value_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, out_socket_value_color4f, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, out_socket_value_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, out_socket_value_boolean, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, out_socket_value_boolean, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, out_socket_value_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, out_socket_value_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, out_socket_value_quat, data_type == CD_PROP_QUATERNION);
} }
static void node_gather_link_searches(GatherLinkSearchOpParams &params) static void node_gather_link_searches(GatherLinkSearchOpParams &params)
@ -115,6 +121,8 @@ static StringRefNull identifier_suffix(eCustomDataType data_type)
return "_001"; return "_001";
case CD_PROP_INT32: case CD_PROP_INT32:
return "_004"; return "_004";
case CD_PROP_QUATERNION:
return "_005";
case CD_PROP_COLOR: case CD_PROP_COLOR:
return "_002"; return "_002";
case CD_PROP_BOOL: case CD_PROP_BOOL:
@ -172,6 +180,9 @@ static void node_geo_exec(GeoNodeExecParams params)
case CD_PROP_INT32: case CD_PROP_INT32:
field = params.get_input<Field<int>>(input_identifier); field = params.get_input<Field<int>>(input_identifier);
break; break;
case CD_PROP_QUATERNION:
field = params.get_input<Field<math::Quaternion>>(input_identifier);
break;
default: default:
break; break;
} }

View File

@ -97,6 +97,10 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
if (fixed_data_type == CD_PROP_STRING) { if (fixed_data_type == CD_PROP_STRING) {
return; return;
} }
if (fixed_data_type == CD_PROP_QUATERNION) {
/* Don't implement quaternion blurring for now. */
return;
}
if (fixed_data_type == CD_PROP_BOOL) { if (fixed_data_type == CD_PROP_BOOL) {
/* This node does not support boolean sockets, use integer instead. */ /* This node does not support boolean sockets, use integer instead. */
fixed_data_type = CD_PROP_INT32; fixed_data_type = CD_PROP_INT32;

View File

@ -28,6 +28,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Vector>("Value", "Value_Vector").hide_value().field_on_all(); b.add_input<decl::Vector>("Value", "Value_Vector").hide_value().field_on_all();
b.add_input<decl::Color>("Value", "Value_Color").hide_value().field_on_all(); b.add_input<decl::Color>("Value", "Value_Color").hide_value().field_on_all();
b.add_input<decl::Bool>("Value", "Value_Bool").hide_value().field_on_all(); b.add_input<decl::Bool>("Value", "Value_Bool").hide_value().field_on_all();
b.add_input<decl::Rotation>("Value", "Value_Rotation").hide_value().field_on_all();
b.add_input<decl::Float>("Factor") b.add_input<decl::Float>("Factor")
.min(0.0f) .min(0.0f)
@ -44,15 +45,16 @@ static void node_declare(NodeDeclarationBuilder &b)
node_storage(node).use_all_curves = false; node_storage(node).use_all_curves = false;
}); });
b.add_output<decl::Float>("Value", "Value_Float").dependent_field({6, 7, 8}); b.add_output<decl::Float>("Value", "Value_Float").dependent_field({7, 8, 9});
b.add_output<decl::Int>("Value", "Value_Int").dependent_field({6, 7, 8}); b.add_output<decl::Int>("Value", "Value_Int").dependent_field({7, 8, 9});
b.add_output<decl::Vector>("Value", "Value_Vector").dependent_field({6, 7, 8}); b.add_output<decl::Vector>("Value", "Value_Vector").dependent_field({7, 8, 9});
b.add_output<decl::Color>("Value", "Value_Color").dependent_field({6, 7, 8}); b.add_output<decl::Color>("Value", "Value_Color").dependent_field({7, 8, 9});
b.add_output<decl::Bool>("Value", "Value_Bool").dependent_field({6, 7, 8}); b.add_output<decl::Bool>("Value", "Value_Bool").dependent_field({7, 8, 9});
b.add_output<decl::Rotation>("Value", "Value_Rotation").dependent_field({7, 8, 9});
b.add_output<decl::Vector>("Position").dependent_field({6, 7, 8}); b.add_output<decl::Vector>("Position").dependent_field({7, 8, 9});
b.add_output<decl::Vector>("Tangent").dependent_field({6, 7, 8}); b.add_output<decl::Vector>("Tangent").dependent_field({7, 8, 9});
b.add_output<decl::Vector>("Normal").dependent_field({6, 7, 8}); b.add_output<decl::Vector>("Normal").dependent_field({7, 8, 9});
} }
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@ -82,6 +84,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *in_socket_vector = in_socket_int32->next; bNodeSocket *in_socket_vector = in_socket_int32->next;
bNodeSocket *in_socket_color4f = in_socket_vector->next; bNodeSocket *in_socket_color4f = in_socket_vector->next;
bNodeSocket *in_socket_bool = in_socket_color4f->next; bNodeSocket *in_socket_bool = in_socket_color4f->next;
bNodeSocket *in_socket_quat = in_socket_bool->next;
bNodeSocket *factor = in_socket_bool->next; bNodeSocket *factor = in_socket_bool->next;
bNodeSocket *length = factor->next; bNodeSocket *length = factor->next;
@ -96,18 +99,21 @@ static void node_update(bNodeTree *ntree, bNode *node)
bke::nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, in_socket_quat, data_type == CD_PROP_QUATERNION);
bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first); bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *out_socket_int32 = out_socket_float->next; bNodeSocket *out_socket_int32 = out_socket_float->next;
bNodeSocket *out_socket_vector = out_socket_int32->next; bNodeSocket *out_socket_vector = out_socket_int32->next;
bNodeSocket *out_socket_color4f = out_socket_vector->next; bNodeSocket *out_socket_color4f = out_socket_vector->next;
bNodeSocket *out_socket_bool = out_socket_color4f->next; bNodeSocket *out_socket_bool = out_socket_color4f->next;
bNodeSocket *out_socket_quat = out_socket_bool->next;
bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, out_socket_quat, data_type == CD_PROP_QUATERNION);
} }
static void node_gather_link_searches(GatherLinkSearchOpParams &params) static void node_gather_link_searches(GatherLinkSearchOpParams &params)
@ -464,6 +470,8 @@ static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustom
return params.extract_input<Field<bool>>("Value_Bool"); return params.extract_input<Field<bool>>("Value_Bool");
case CD_PROP_INT32: case CD_PROP_INT32:
return params.extract_input<Field<int>>("Value_Int"); return params.extract_input<Field<int>>("Value_Int");
case CD_PROP_QUATERNION:
return params.extract_input<Field<math::Quaternion>>("Value_Rotation");
default: default:
BLI_assert_unreachable(); BLI_assert_unreachable();
} }
@ -493,6 +501,10 @@ static void output_attribute_field(GeoNodeExecParams &params, GField field)
params.set_output("Value_Int", Field<int>(field)); params.set_output("Value_Int", Field<int>(field));
break; break;
} }
case CD_PROP_QUATERNION: {
params.set_output("Value_Rotation", Field<math::Quaternion>(field));
break;
}
default: default:
break; break;
} }

View File

@ -93,24 +93,28 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *sock_in_vector = sock_in_int->next; bNodeSocket *sock_in_vector = sock_in_int->next;
bNodeSocket *sock_in_color = sock_in_vector->next; bNodeSocket *sock_in_color = sock_in_vector->next;
bNodeSocket *sock_in_bool = sock_in_color->next; bNodeSocket *sock_in_bool = sock_in_color->next;
bNodeSocket *sock_in_quat = sock_in_bool->next;
bNodeSocket *sock_out_float = static_cast<bNodeSocket *>(node->outputs.first); bNodeSocket *sock_out_float = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *sock_out_int = sock_out_float->next; bNodeSocket *sock_out_int = sock_out_float->next;
bNodeSocket *sock_out_vector = sock_out_int->next; bNodeSocket *sock_out_vector = sock_out_int->next;
bNodeSocket *sock_out_color = sock_out_vector->next; bNodeSocket *sock_out_color = sock_out_vector->next;
bNodeSocket *sock_out_bool = sock_out_color->next; bNodeSocket *sock_out_bool = sock_out_color->next;
bNodeSocket *sock_out_quat = sock_out_bool->next;
bke::nodeSetSocketAvailability(ntree, sock_in_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, sock_in_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, sock_in_int, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, sock_in_int, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, sock_in_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, sock_in_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, sock_in_color, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, sock_in_color, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, sock_in_bool, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, sock_in_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, sock_in_quat, data_type == CD_PROP_QUATERNION);
bke::nodeSetSocketAvailability(ntree, sock_out_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, sock_out_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, sock_out_int, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, sock_out_int, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, sock_out_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, sock_out_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, sock_out_color, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, sock_out_color, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, sock_out_bool, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, sock_out_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, sock_out_quat, data_type == CD_PROP_QUATERNION);
} }
static void node_gather_link_searches(GatherLinkSearchOpParams &params) static void node_gather_link_searches(GatherLinkSearchOpParams &params)
@ -148,6 +152,8 @@ static StringRefNull identifier_suffix(eCustomDataType data_type)
return "Color"; return "Color";
case CD_PROP_FLOAT3: case CD_PROP_FLOAT3:
return "Vector"; return "Vector";
case CD_PROP_QUATERNION:
return "Rotation";
default: default:
BLI_assert_unreachable(); BLI_assert_unreachable();
return ""; return "";

View File

@ -22,12 +22,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Vector>("Value", "Value_Vector").supports_field(); b.add_input<decl::Vector>("Value", "Value_Vector").supports_field();
b.add_input<decl::Color>("Value", "Value_Color").supports_field(); b.add_input<decl::Color>("Value", "Value_Color").supports_field();
b.add_input<decl::Bool>("Value", "Value_Bool").supports_field(); b.add_input<decl::Bool>("Value", "Value_Bool").supports_field();
b.add_input<decl::Rotation>("Value", "Value_Rotation").supports_field();
b.add_output<decl::Float>("Value", "Value_Float").field_source_reference_all(); b.add_output<decl::Float>("Value", "Value_Float").field_source_reference_all();
b.add_output<decl::Int>("Value", "Value_Int").field_source_reference_all(); b.add_output<decl::Int>("Value", "Value_Int").field_source_reference_all();
b.add_output<decl::Vector>("Value", "Value_Vector").field_source_reference_all(); b.add_output<decl::Vector>("Value", "Value_Vector").field_source_reference_all();
b.add_output<decl::Color>("Value", "Value_Color").field_source_reference_all(); b.add_output<decl::Color>("Value", "Value_Color").field_source_reference_all();
b.add_output<decl::Bool>("Value", "Value_Bool").field_source_reference_all(); b.add_output<decl::Bool>("Value", "Value_Bool").field_source_reference_all();
b.add_output<decl::Rotation>("Value", "Value_Rotation").field_source_reference_all();
} }
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@ -51,24 +53,28 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *sock_in_vector = sock_in_int->next; bNodeSocket *sock_in_vector = sock_in_int->next;
bNodeSocket *sock_in_color = sock_in_vector->next; bNodeSocket *sock_in_color = sock_in_vector->next;
bNodeSocket *sock_in_bool = sock_in_color->next; bNodeSocket *sock_in_bool = sock_in_color->next;
bNodeSocket *sock_in_quat = sock_in_bool->next;
bNodeSocket *sock_out_float = static_cast<bNodeSocket *>(node->outputs.first); bNodeSocket *sock_out_float = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *sock_out_int = sock_out_float->next; bNodeSocket *sock_out_int = sock_out_float->next;
bNodeSocket *sock_out_vector = sock_out_int->next; bNodeSocket *sock_out_vector = sock_out_int->next;
bNodeSocket *sock_out_color = sock_out_vector->next; bNodeSocket *sock_out_color = sock_out_vector->next;
bNodeSocket *sock_out_bool = sock_out_color->next; bNodeSocket *sock_out_bool = sock_out_color->next;
bNodeSocket *sock_out_quat = sock_out_bool->next;
bke::nodeSetSocketAvailability(ntree, sock_in_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, sock_in_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, sock_in_int, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, sock_in_int, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, sock_in_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, sock_in_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, sock_in_color, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, sock_in_color, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, sock_in_bool, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, sock_in_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, sock_in_quat, data_type == CD_PROP_QUATERNION);
bke::nodeSetSocketAvailability(ntree, sock_out_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, sock_out_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, sock_out_int, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, sock_out_int, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, sock_out_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, sock_out_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, sock_out_color, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, sock_out_color, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, sock_out_bool, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, sock_out_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, sock_out_quat, data_type == CD_PROP_QUATERNION);
} }
static void node_gather_link_searches(GatherLinkSearchOpParams &params) static void node_gather_link_searches(GatherLinkSearchOpParams &params)
@ -139,6 +145,8 @@ static StringRefNull identifier_suffix(eCustomDataType data_type)
return "Color"; return "Color";
case CD_PROP_FLOAT3: case CD_PROP_FLOAT3:
return "Vector"; return "Vector";
case CD_PROP_QUATERNION:
return "Rotation";
default: default:
BLI_assert_unreachable(); BLI_assert_unreachable();
return ""; return "";

View File

@ -22,6 +22,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>("Attribute", "Attribute_Color").field_source(); b.add_output<decl::Color>("Attribute", "Attribute_Color").field_source();
b.add_output<decl::Bool>("Attribute", "Attribute_Bool").field_source(); b.add_output<decl::Bool>("Attribute", "Attribute_Bool").field_source();
b.add_output<decl::Int>("Attribute", "Attribute_Int").field_source(); b.add_output<decl::Int>("Attribute", "Attribute_Int").field_source();
b.add_output<decl::Rotation>("Attribute", "Attribute_Rotation").field_source();
b.add_output<decl::Bool>("Exists").field_source(); b.add_output<decl::Bool>("Exists").field_source();
} }
@ -48,12 +49,14 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *socket_color4f = socket_float->next; bNodeSocket *socket_color4f = socket_float->next;
bNodeSocket *socket_boolean = socket_color4f->next; bNodeSocket *socket_boolean = socket_color4f->next;
bNodeSocket *socket_int32 = socket_boolean->next; bNodeSocket *socket_int32 = socket_boolean->next;
bNodeSocket *socket_quat = socket_int32->next;
bke::nodeSetSocketAvailability(ntree, socket_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_color4f, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, socket_boolean, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, socket_boolean, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, socket_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, socket_quat, data_type == CD_PROP_QUATERNION);
} }
static void node_gather_link_searches(GatherLinkSearchOpParams &params) static void node_gather_link_searches(GatherLinkSearchOpParams &params)
@ -145,6 +148,9 @@ static void node_geo_exec(GeoNodeExecParams params)
case CD_PROP_INT32: case CD_PROP_INT32:
params.set_output("Attribute_Int", AttributeFieldInput::Create<int>(name)); params.set_output("Attribute_Int", AttributeFieldInput::Create<int>(name));
break; break;
case CD_PROP_QUATERNION:
params.set_output("Attribute_Rotation", AttributeFieldInput::Create<math::Quaternion>(name));
break;
default: default:
break; break;
} }

View File

@ -34,10 +34,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.description( .description(
"Index of the instance used for each point. This is only used when Pick Instances " "Index of the instance used for each point. This is only used when Pick Instances "
"is on. By default the point index is used"); "is on. By default the point index is used");
b.add_input<decl::Vector>("Rotation") b.add_input<decl::Rotation>("Rotation").field_on({0}).description("Rotation of the instances");
.subtype(PROP_EULER)
.field_on({0})
.description("Rotation of the instances");
b.add_input<decl::Vector>("Scale") b.add_input<decl::Vector>("Scale")
.default_value({1.0f, 1.0f, 1.0f}) .default_value({1.0f, 1.0f, 1.0f})
.subtype(PROP_XYZ) .subtype(PROP_XYZ)
@ -59,7 +56,7 @@ static void add_instances_from_component(
VArray<bool> pick_instance; VArray<bool> pick_instance;
VArray<int> indices; VArray<int> indices;
VArray<float3> rotations; VArray<math::Quaternion> rotations;
VArray<float3> scales; VArray<float3> scales;
const bke::GeometryFieldContext field_context{src_component, domain}; const bke::GeometryFieldContext field_context{src_component, domain};
@ -70,7 +67,7 @@ static void add_instances_from_component(
* selected indices should be copied. */ * selected indices should be copied. */
evaluator.add(params.get_input<Field<bool>>("Pick Instance"), &pick_instance); evaluator.add(params.get_input<Field<bool>>("Pick Instance"), &pick_instance);
evaluator.add(params.get_input<Field<int>>("Instance Index"), &indices); evaluator.add(params.get_input<Field<int>>("Instance Index"), &indices);
evaluator.add(params.get_input<Field<float3>>("Rotation"), &rotations); evaluator.add(params.get_input<Field<math::Quaternion>>("Rotation"), &rotations);
evaluator.add(params.get_input<Field<float3>>("Scale"), &scales); evaluator.add(params.get_input<Field<float3>>("Scale"), &scales);
evaluator.evaluate(); evaluator.evaluate();
@ -118,8 +115,7 @@ static void add_instances_from_component(
/* Compute base transform for every instances. */ /* Compute base transform for every instances. */
float4x4 &dst_transform = dst_transforms[range_i]; float4x4 &dst_transform = dst_transforms[range_i];
dst_transform = math::from_loc_rot_scale<float4x4>( dst_transform = math::from_loc_rot_scale<float4x4>(positions[i], rotations[i], scales[i]);
positions[i], math::EulerXYZ(rotations[i]), scales[i]);
/* Reference that will be used by this new instance. */ /* Reference that will be used by this new instance. */
int dst_handle = empty_reference_handle; int dst_handle = empty_reference_handle;

View File

@ -32,6 +32,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Color>("Attribute", "Attribute_002").hide_value().field_on_all(); b.add_input<decl::Color>("Attribute", "Attribute_002").hide_value().field_on_all();
b.add_input<decl::Bool>("Attribute", "Attribute_003").hide_value().field_on_all(); b.add_input<decl::Bool>("Attribute", "Attribute_003").hide_value().field_on_all();
b.add_input<decl::Int>("Attribute", "Attribute_004").hide_value().field_on_all(); b.add_input<decl::Int>("Attribute", "Attribute_004").hide_value().field_on_all();
b.add_input<decl::Rotation>("Attribute", "Attribute_005").hide_value().field_on_all();
b.add_input<decl::Vector>("Source Position").implicit_field(implicit_field_inputs::position); b.add_input<decl::Vector>("Source Position").implicit_field(implicit_field_inputs::position);
b.add_input<decl::Vector>("Ray Direction").default_value({0.0f, 0.0f, -1.0f}).supports_field(); b.add_input<decl::Vector>("Ray Direction").default_value({0.0f, 0.0f, -1.0f}).supports_field();
@ -51,6 +52,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>("Attribute", "Attribute_002").dependent_field({6, 7, 8}); b.add_output<decl::Color>("Attribute", "Attribute_002").dependent_field({6, 7, 8});
b.add_output<decl::Bool>("Attribute", "Attribute_003").dependent_field({6, 7, 8}); b.add_output<decl::Bool>("Attribute", "Attribute_003").dependent_field({6, 7, 8});
b.add_output<decl::Int>("Attribute", "Attribute_004").dependent_field({6, 7, 8}); b.add_output<decl::Int>("Attribute", "Attribute_004").dependent_field({6, 7, 8});
b.add_output<decl::Rotation>("Attribute", "Attribute_005").dependent_field({6, 7, 8});
} }
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@ -77,24 +79,28 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *socket_color4f = socket_float->next; bNodeSocket *socket_color4f = socket_float->next;
bNodeSocket *socket_boolean = socket_color4f->next; bNodeSocket *socket_boolean = socket_color4f->next;
bNodeSocket *socket_int32 = socket_boolean->next; bNodeSocket *socket_int32 = socket_boolean->next;
bNodeSocket *socket_quat = socket_boolean->next;
bke::nodeSetSocketAvailability(ntree, socket_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_color4f, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, socket_boolean, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, socket_boolean, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, socket_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, socket_quat, data_type == CD_PROP_QUATERNION);
bNodeSocket *out_socket_vector = static_cast<bNodeSocket *>(BLI_findlink(&node->outputs, 4)); bNodeSocket *out_socket_vector = static_cast<bNodeSocket *>(BLI_findlink(&node->outputs, 4));
bNodeSocket *out_socket_float = out_socket_vector->next; bNodeSocket *out_socket_float = out_socket_vector->next;
bNodeSocket *out_socket_color4f = out_socket_float->next; bNodeSocket *out_socket_color4f = out_socket_float->next;
bNodeSocket *out_socket_boolean = out_socket_color4f->next; bNodeSocket *out_socket_boolean = out_socket_color4f->next;
bNodeSocket *out_socket_int32 = out_socket_boolean->next; bNodeSocket *out_socket_int32 = out_socket_boolean->next;
bNodeSocket *out_socket_quat = out_socket_boolean->next;
bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, out_socket_boolean, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, out_socket_boolean, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, out_socket_quat, data_type == CD_PROP_QUATERNION);
} }
static void node_gather_link_searches(GatherLinkSearchOpParams &params) static void node_gather_link_searches(GatherLinkSearchOpParams &params)

View File

@ -65,14 +65,16 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Vector>("Value", "Value_Vector").hide_value().field_on_all(); b.add_input<decl::Vector>("Value", "Value_Vector").hide_value().field_on_all();
b.add_input<decl::Color>("Value", "Value_Color").hide_value().field_on_all(); b.add_input<decl::Color>("Value", "Value_Color").hide_value().field_on_all();
b.add_input<decl::Bool>("Value", "Value_Bool").hide_value().field_on_all(); b.add_input<decl::Bool>("Value", "Value_Bool").hide_value().field_on_all();
b.add_input<decl::Rotation>("Value", "Value_Rotation").hide_value().field_on_all();
b.add_input<decl::Int>("Index").supports_field().description( b.add_input<decl::Int>("Index").supports_field().description(
"Which element to retrieve a value from on the geometry"); "Which element to retrieve a value from on the geometry");
b.add_output<decl::Float>("Value", "Value_Float").dependent_field({6}); b.add_output<decl::Float>("Value", "Value_Float").dependent_field({7});
b.add_output<decl::Int>("Value", "Value_Int").dependent_field({6}); b.add_output<decl::Int>("Value", "Value_Int").dependent_field({7});
b.add_output<decl::Vector>("Value", "Value_Vector").dependent_field({6}); b.add_output<decl::Vector>("Value", "Value_Vector").dependent_field({7});
b.add_output<decl::Color>("Value", "Value_Color").dependent_field({6}); b.add_output<decl::Color>("Value", "Value_Color").dependent_field({7});
b.add_output<decl::Bool>("Value", "Value_Bool").dependent_field({6}); b.add_output<decl::Bool>("Value", "Value_Bool").dependent_field({7});
b.add_output<decl::Rotation>("Value", "Value_Rotation").dependent_field({7});
} }
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@ -101,24 +103,28 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *in_socket_vector = in_socket_int32->next; bNodeSocket *in_socket_vector = in_socket_int32->next;
bNodeSocket *in_socket_color4f = in_socket_vector->next; bNodeSocket *in_socket_color4f = in_socket_vector->next;
bNodeSocket *in_socket_bool = in_socket_color4f->next; bNodeSocket *in_socket_bool = in_socket_color4f->next;
bNodeSocket *in_socket_quat = in_socket_bool->next;
bke::nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, in_socket_quat, data_type == CD_PROP_QUATERNION);
bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first); bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *out_socket_int32 = out_socket_float->next; bNodeSocket *out_socket_int32 = out_socket_float->next;
bNodeSocket *out_socket_vector = out_socket_int32->next; bNodeSocket *out_socket_vector = out_socket_int32->next;
bNodeSocket *out_socket_color4f = out_socket_vector->next; bNodeSocket *out_socket_color4f = out_socket_vector->next;
bNodeSocket *out_socket_bool = out_socket_color4f->next; bNodeSocket *out_socket_bool = out_socket_color4f->next;
bNodeSocket *out_socket_quat = out_socket_bool->next;
bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, out_socket_quat, data_type == CD_PROP_QUATERNION);
} }
static void node_gather_link_searches(GatherLinkSearchOpParams &params) static void node_gather_link_searches(GatherLinkSearchOpParams &params)

View File

@ -30,6 +30,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Vector>("Value", "Value_Vector").hide_value().field_on_all(); b.add_input<decl::Vector>("Value", "Value_Vector").hide_value().field_on_all();
b.add_input<decl::Color>("Value", "Value_Color").hide_value().field_on_all(); b.add_input<decl::Color>("Value", "Value_Color").hide_value().field_on_all();
b.add_input<decl::Bool>("Value", "Value_Bool").hide_value().field_on_all(); b.add_input<decl::Bool>("Value", "Value_Bool").hide_value().field_on_all();
b.add_input<decl::Rotation>("Value", "Value_Rotation").hide_value().field_on_all();
b.add_input<decl::Vector>("Sample Position").implicit_field(implicit_field_inputs::position); b.add_input<decl::Vector>("Sample Position").implicit_field(implicit_field_inputs::position);
@ -38,6 +39,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>("Value", "Value_Vector").dependent_field({6}); b.add_output<decl::Vector>("Value", "Value_Vector").dependent_field({6});
b.add_output<decl::Color>("Value", "Value_Color").dependent_field({6}); b.add_output<decl::Color>("Value", "Value_Color").dependent_field({6});
b.add_output<decl::Bool>("Value", "Value_Bool").dependent_field({6}); b.add_output<decl::Bool>("Value", "Value_Bool").dependent_field({6});
b.add_output<decl::Rotation>("Value", "Value_Rotation").dependent_field({6});
} }
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@ -60,24 +62,28 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *in_socket_vector = in_socket_int32->next; bNodeSocket *in_socket_vector = in_socket_int32->next;
bNodeSocket *in_socket_color4f = in_socket_vector->next; bNodeSocket *in_socket_color4f = in_socket_vector->next;
bNodeSocket *in_socket_bool = in_socket_color4f->next; bNodeSocket *in_socket_bool = in_socket_color4f->next;
bNodeSocket *in_socket_quat = in_socket_bool->next;
bke::nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, in_socket_quat, data_type == CD_PROP_QUATERNION);
bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first); bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *out_socket_int32 = out_socket_float->next; bNodeSocket *out_socket_int32 = out_socket_float->next;
bNodeSocket *out_socket_vector = out_socket_int32->next; bNodeSocket *out_socket_vector = out_socket_int32->next;
bNodeSocket *out_socket_color4f = out_socket_vector->next; bNodeSocket *out_socket_color4f = out_socket_vector->next;
bNodeSocket *out_socket_bool = out_socket_color4f->next; bNodeSocket *out_socket_bool = out_socket_color4f->next;
bNodeSocket *out_socket_quat = out_socket_bool->next;
bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, out_socket_quat, data_type == CD_PROP_QUATERNION);
} }
static void node_gather_link_searches(GatherLinkSearchOpParams &params) static void node_gather_link_searches(GatherLinkSearchOpParams &params)
@ -162,6 +168,8 @@ static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustom
return params.extract_input<Field<bool>>("Value_Bool"); return params.extract_input<Field<bool>>("Value_Bool");
case CD_PROP_INT32: case CD_PROP_INT32:
return params.extract_input<Field<int>>("Value_Int"); return params.extract_input<Field<int>>("Value_Int");
case CD_PROP_QUATERNION:
return params.extract_input<Field<math::Quaternion>>("Value_Rotation");
default: default:
BLI_assert_unreachable(); BLI_assert_unreachable();
} }
@ -191,6 +199,10 @@ static void output_attribute_field(GeoNodeExecParams &params, GField field)
params.set_output("Value_Int", Field<int>(field)); params.set_output("Value_Int", Field<int>(field));
break; break;
} }
case CD_PROP_QUATERNION: {
params.set_output("Value_Rotation", Field<math::Quaternion>(field));
break;
}
default: default:
break; break;
} }

View File

@ -29,6 +29,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Vector>("Value", "Value_Vector").hide_value().field_on_all(); b.add_input<decl::Vector>("Value", "Value_Vector").hide_value().field_on_all();
b.add_input<decl::Color>("Value", "Value_Color").hide_value().field_on_all(); b.add_input<decl::Color>("Value", "Value_Color").hide_value().field_on_all();
b.add_input<decl::Bool>("Value", "Value_Bool").hide_value().field_on_all(); b.add_input<decl::Bool>("Value", "Value_Bool").hide_value().field_on_all();
b.add_input<decl::Rotation>("Value", "Value_Rotation").hide_value().field_on_all();
b.add_input<decl::Vector>("Source UV Map") b.add_input<decl::Vector>("Source UV Map")
.hide_value() .hide_value()
@ -43,6 +44,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>("Value", "Value_Vector").dependent_field({7}); b.add_output<decl::Vector>("Value", "Value_Vector").dependent_field({7});
b.add_output<decl::Color>("Value", "Value_Color").dependent_field({7}); b.add_output<decl::Color>("Value", "Value_Color").dependent_field({7});
b.add_output<decl::Bool>("Value", "Value_Bool").dependent_field({7}); b.add_output<decl::Bool>("Value", "Value_Bool").dependent_field({7});
b.add_output<decl::Rotation>("Value", "Value_Rotation").dependent_field({7});
b.add_output<decl::Bool>("Is Valid") b.add_output<decl::Bool>("Is Valid")
.dependent_field({7}) .dependent_field({7})
@ -69,24 +71,28 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *in_socket_vector = in_socket_int32->next; bNodeSocket *in_socket_vector = in_socket_int32->next;
bNodeSocket *in_socket_color4f = in_socket_vector->next; bNodeSocket *in_socket_color4f = in_socket_vector->next;
bNodeSocket *in_socket_bool = in_socket_color4f->next; bNodeSocket *in_socket_bool = in_socket_color4f->next;
bNodeSocket *in_socket_quat = in_socket_bool->next;
bke::nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, in_socket_quat, data_type == CD_PROP_QUATERNION);
bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first); bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *out_socket_int32 = out_socket_float->next; bNodeSocket *out_socket_int32 = out_socket_float->next;
bNodeSocket *out_socket_vector = out_socket_int32->next; bNodeSocket *out_socket_vector = out_socket_int32->next;
bNodeSocket *out_socket_color4f = out_socket_vector->next; bNodeSocket *out_socket_color4f = out_socket_vector->next;
bNodeSocket *out_socket_bool = out_socket_color4f->next; bNodeSocket *out_socket_bool = out_socket_color4f->next;
bNodeSocket *out_socket_quat = out_socket_bool->next;
bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3); bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT); bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR); bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, out_socket_quat, data_type == CD_PROP_QUATERNION);
} }
static void node_gather_link_searches(GatherLinkSearchOpParams &params) static void node_gather_link_searches(GatherLinkSearchOpParams &params)
@ -188,6 +194,8 @@ static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustom
return params.extract_input<Field<bool>>("Value_Bool"); return params.extract_input<Field<bool>>("Value_Bool");
case CD_PROP_INT32: case CD_PROP_INT32:
return params.extract_input<Field<int>>("Value_Int"); return params.extract_input<Field<int>>("Value_Int");
case CD_PROP_QUATERNION:
return params.extract_input<Field<math::Quaternion>>("Value_Rotation");
default: default:
BLI_assert_unreachable(); BLI_assert_unreachable();
} }
@ -217,6 +225,10 @@ static void output_attribute_field(GeoNodeExecParams &params, GField field)
params.set_output("Value_Int", Field<int>(field)); params.set_output("Value_Int", Field<int>(field));
break; break;
} }
case CD_PROP_QUATERNION: {
params.set_output("Value_Rotation", Field<math::Quaternion>(field));
break;
}
default: default:
break; break;
} }

View File

@ -64,6 +64,11 @@ static std::unique_ptr<SocketDeclaration> socket_declaration_for_simulation_item
decl->input_field_type = InputSocketFieldType::IsSupported; decl->input_field_type = InputSocketFieldType::IsSupported;
decl->output_field_dependency = OutputFieldDependency::ForPartiallyDependentField({index}); decl->output_field_dependency = OutputFieldDependency::ForPartiallyDependentField({index});
break; break;
case SOCK_ROTATION:
decl = std::make_unique<decl::Rotation>();
decl->input_field_type = InputSocketFieldType::IsSupported;
decl->output_field_dependency = OutputFieldDependency::ForPartiallyDependentField({index});
break;
case SOCK_INT: case SOCK_INT:
decl = std::make_unique<decl::Int>(); decl = std::make_unique<decl::Int>();
decl->input_field_type = InputSocketFieldType::IsSupported; decl->input_field_type = InputSocketFieldType::IsSupported;
@ -214,6 +219,7 @@ void simulation_state_to_values(const Span<NodeSimulationItem> node_simulation_i
case SOCK_VECTOR: case SOCK_VECTOR:
case SOCK_INT: case SOCK_INT:
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
case SOCK_ROTATION:
case SOCK_RGBA: { case SOCK_RGBA: {
const fn::ValueOrFieldCPPType &value_or_field_type = const fn::ValueOrFieldCPPType &value_or_field_type =
*fn::ValueOrFieldCPPType::get_from_self(cpp_type); *fn::ValueOrFieldCPPType::get_from_self(cpp_type);
@ -311,6 +317,7 @@ void values_to_simulation_state(const Span<NodeSimulationItem> node_simulation_i
case SOCK_VECTOR: case SOCK_VECTOR:
case SOCK_INT: case SOCK_INT:
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
case SOCK_ROTATION:
case SOCK_RGBA: { case SOCK_RGBA: {
const CPPType &type = get_simulation_item_cpp_type(item); const CPPType &type = get_simulation_item_cpp_type(item);
const fn::ValueOrFieldCPPType &value_or_field_type = const fn::ValueOrFieldCPPType &value_or_field_type =
@ -616,6 +623,7 @@ static void mix_simulation_state(const NodeSimulationItem &item,
case SOCK_VECTOR: case SOCK_VECTOR:
case SOCK_INT: case SOCK_INT:
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
case SOCK_ROTATION:
case SOCK_RGBA: { case SOCK_RGBA: {
const CPPType &type = get_simulation_item_cpp_type(item); const CPPType &type = get_simulation_item_cpp_type(item);
const fn::ValueOrFieldCPPType &value_or_field_type = *fn::ValueOrFieldCPPType::get_from_self( const fn::ValueOrFieldCPPType &value_or_field_type = *fn::ValueOrFieldCPPType::get_from_self(
@ -1005,6 +1013,7 @@ bool NOD_geometry_simulation_output_item_socket_type_supported(
SOCK_VECTOR, SOCK_VECTOR,
SOCK_RGBA, SOCK_RGBA,
SOCK_BOOLEAN, SOCK_BOOLEAN,
SOCK_ROTATION,
SOCK_INT, SOCK_INT,
SOCK_STRING, SOCK_STRING,
SOCK_GEOMETRY); SOCK_GEOMETRY);

View File

@ -29,6 +29,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Color>("Value", "Value_Color").field_on_all(); b.add_input<decl::Color>("Value", "Value_Color").field_on_all();
b.add_input<decl::Bool>("Value", "Value_Bool").field_on_all(); b.add_input<decl::Bool>("Value", "Value_Bool").field_on_all();
b.add_input<decl::Int>("Value", "Value_Int").field_on_all(); b.add_input<decl::Int>("Value", "Value_Int").field_on_all();
b.add_input<decl::Rotation>("Value", "Value_Rotation").field_on_all();
b.add_output<decl::Geometry>("Geometry").propagate_all(); b.add_output<decl::Geometry>("Geometry").propagate_all();
} }
@ -61,6 +62,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *socket_color4f = socket_float->next; bNodeSocket *socket_color4f = socket_float->next;
bNodeSocket *socket_boolean = socket_color4f->next; bNodeSocket *socket_boolean = socket_color4f->next;
bNodeSocket *socket_int32 = socket_boolean->next; bNodeSocket *socket_int32 = socket_boolean->next;
bNodeSocket *socket_quat = socket_int32->next;
bke::nodeSetSocketAvailability( bke::nodeSetSocketAvailability(
ntree, socket_vector, ELEM(data_type, CD_PROP_FLOAT2, CD_PROP_FLOAT3)); ntree, socket_vector, ELEM(data_type, CD_PROP_FLOAT2, CD_PROP_FLOAT3));
@ -69,6 +71,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
ntree, socket_color4f, ELEM(data_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)); ntree, socket_color4f, ELEM(data_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR));
bke::nodeSetSocketAvailability(ntree, socket_boolean, data_type == CD_PROP_BOOL); bke::nodeSetSocketAvailability(ntree, socket_boolean, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, socket_int32, data_type == CD_PROP_INT32); bke::nodeSetSocketAvailability(ntree, socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, socket_quat, data_type == CD_PROP_QUATERNION);
} }
static void node_gather_link_searches(GatherLinkSearchOpParams &params) static void node_gather_link_searches(GatherLinkSearchOpParams &params)
@ -142,6 +145,9 @@ static void node_geo_exec(GeoNodeExecParams params)
case CD_PROP_INT32: case CD_PROP_INT32:
field = params.get_input<Field<int>>("Value_Int"); field = params.get_input<Field<int>>("Value_Int");
break; break;
case CD_PROP_QUATERNION:
field = params.get_input<Field<math::Quaternion>>("Value_Rotation");
break;
default: default:
break; break;
} }

View File

@ -50,6 +50,8 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Material>("True", "True_010"); b.add_input<decl::Material>("True", "True_010");
b.add_input<decl::Image>("False", "False_011"); b.add_input<decl::Image>("False", "False_011");
b.add_input<decl::Image>("True", "True_011"); b.add_input<decl::Image>("True", "True_011");
b.add_input<decl::Rotation>("False", "False_012").supports_field();
b.add_input<decl::Rotation>("True", "True_012").supports_field();
b.add_output<decl::Float>("Output").dependent_field().reference_pass_all(); b.add_output<decl::Float>("Output").dependent_field().reference_pass_all();
b.add_output<decl::Int>("Output", "Output_001").dependent_field().reference_pass_all(); b.add_output<decl::Int>("Output", "Output_001").dependent_field().reference_pass_all();
@ -63,6 +65,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Texture>("Output", "Output_009"); b.add_output<decl::Texture>("Output", "Output_009");
b.add_output<decl::Material>("Output", "Output_010"); b.add_output<decl::Material>("Output", "Output_010");
b.add_output<decl::Image>("Output", "Output_011"); b.add_output<decl::Image>("Output", "Output_011");
b.add_output<decl::Rotation>("Output", "Output_012").propagate_all().reference_pass_all();
} }
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@ -84,8 +87,14 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *field_switch = static_cast<bNodeSocket *>(node->inputs.first); bNodeSocket *field_switch = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *non_field_switch = static_cast<bNodeSocket *>(field_switch->next); bNodeSocket *non_field_switch = static_cast<bNodeSocket *>(field_switch->next);
const bool fields_type = ELEM( const bool fields_type = ELEM(storage.input_type,
storage.input_type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA, SOCK_STRING); SOCK_FLOAT,
SOCK_INT,
SOCK_BOOLEAN,
SOCK_VECTOR,
SOCK_RGBA,
SOCK_STRING,
SOCK_ROTATION);
bke::nodeSetSocketAvailability(ntree, field_switch, fields_type); bke::nodeSetSocketAvailability(ntree, field_switch, fields_type);
bke::nodeSetSocketAvailability(ntree, non_field_switch, !fields_type); bke::nodeSetSocketAvailability(ntree, non_field_switch, !fields_type);
@ -150,7 +159,8 @@ class LazyFunctionForSwitchNode : public LazyFunction {
{ {
const NodeSwitch &storage = node_storage(node); const NodeSwitch &storage = node_storage(node);
const eNodeSocketDatatype data_type = eNodeSocketDatatype(storage.input_type); const eNodeSocketDatatype data_type = eNodeSocketDatatype(storage.input_type);
can_be_field_ = ELEM(data_type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA); can_be_field_ = ELEM(
data_type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA, SOCK_ROTATION);
const bNodeSocketType *socket_type = nullptr; const bNodeSocketType *socket_type = nullptr;
for (const bNodeSocket *socket : node.output_sockets()) { for (const bNodeSocket *socket : node.output_sockets()) {
@ -236,20 +246,25 @@ class LazyFunctionForSwitchNode : public LazyFunction {
const MultiFunction &get_switch_multi_function(const CPPType &type) const const MultiFunction &get_switch_multi_function(const CPPType &type) const
{ {
const MultiFunction *switch_multi_function = nullptr; const MultiFunction *switch_multi_function = nullptr;
type.to_static_type_tag<float, int, bool, float3, ColorGeometry4f, std::string>( type.to_static_type_tag<float,
[&](auto type_tag) { int,
using T = typename decltype(type_tag)::type; bool,
if constexpr (std::is_void_v<T>) { float3,
BLI_assert_unreachable(); ColorGeometry4f,
} std::string,
else { math::Quaternion>([&](auto type_tag) {
static auto switch_fn = mf::build::SI3_SO<bool, T, T, T>( using T = typename decltype(type_tag)::type;
"Switch", [](const bool condition, const T &false_value, const T &true_value) { if constexpr (std::is_void_v<T>) {
return condition ? true_value : false_value; BLI_assert_unreachable();
}); }
switch_multi_function = &switch_fn; else {
} static auto switch_fn = mf::build::SI3_SO<bool, T, T, T>(
}); "Switch", [](const bool condition, const T &false_value, const T &true_value) {
return condition ? true_value : false_value;
});
switch_multi_function = &switch_fn;
}
});
BLI_assert(switch_multi_function != nullptr); BLI_assert(switch_multi_function != nullptr);
return *switch_multi_function; return *switch_multi_function;
} }

View File

@ -8,6 +8,7 @@
#include "BLI_math_matrix.hh" #include "BLI_math_matrix.hh"
#include "BLI_math_matrix_types.hh" #include "BLI_math_matrix_types.hh"
#include "BLI_math_quaternion.hh"
#include "BLI_task.hh" #include "BLI_task.hh"
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
@ -26,9 +27,9 @@
namespace blender::nodes { namespace blender::nodes {
static bool use_translate(const float3 rotation, const float3 scale) static bool use_translate(const math::Quaternion rotation, const float3 scale)
{ {
if (compare_ff(math::length_squared(rotation), 0.0f, 1e-9f) != 1) { if (!math::is_equal(float4(rotation), float4(math::Quaternion::identity()), 1e7f)) {
return false; return false;
} }
if (compare_ff(scale.x, 1.0f, 1e-9f) != 1 || compare_ff(scale.y, 1.0f, 1e-9f) != 1 || if (compare_ff(scale.x, 1.0f, 1e-9f) != 1 || compare_ff(scale.y, 1.0f, 1e-9f) != 1 ||
@ -267,7 +268,7 @@ static void node_declare(NodeDeclarationBuilder &b)
{ {
b.add_input<decl::Geometry>("Geometry"); b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::Vector>("Translation").subtype(PROP_TRANSLATION); b.add_input<decl::Vector>("Translation").subtype(PROP_TRANSLATION);
b.add_input<decl::Vector>("Rotation").subtype(PROP_EULER); b.add_input<decl::Rotation>("Rotation");
b.add_input<decl::Vector>("Scale").default_value({1, 1, 1}).subtype(PROP_XYZ); b.add_input<decl::Vector>("Scale").default_value({1, 1, 1}).subtype(PROP_XYZ);
b.add_output<decl::Geometry>("Geometry").propagate_all(); b.add_output<decl::Geometry>("Geometry").propagate_all();
} }
@ -276,7 +277,7 @@ static void node_geo_exec(GeoNodeExecParams params)
{ {
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
const float3 translation = params.extract_input<float3>("Translation"); const float3 translation = params.extract_input<float3>("Translation");
const float3 rotation = params.extract_input<float3>("Rotation"); const math::Quaternion rotation = params.extract_input<math::Quaternion>("Rotation");
const float3 scale = params.extract_input<float3>("Scale"); const float3 scale = params.extract_input<float3>("Scale");
/* Use only translation if rotation and scale don't apply. */ /* Use only translation if rotation and scale don't apply. */

View File

@ -26,6 +26,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Color>("Value", "Value_002").field_on_all().hide_value(); b.add_input<decl::Color>("Value", "Value_002").field_on_all().hide_value();
b.add_input<decl::Int>("Value", "Value_003").field_on_all().hide_value(); b.add_input<decl::Int>("Value", "Value_003").field_on_all().hide_value();
b.add_input<decl::Bool>("Value", "Value_004").field_on_all().hide_value(); b.add_input<decl::Bool>("Value", "Value_004").field_on_all().hide_value();
b.add_input<decl::Rotation>("Value", "Value_005").field_on_all().hide_value();
} }
static void node_init(bNodeTree * /*tree*/, bNode *node) static void node_init(bNodeTree * /*tree*/, bNode *node)
@ -60,6 +61,8 @@ static eNodeSocketDatatype custom_data_type_to_socket_type(const eCustomDataType
return SOCK_BOOLEAN; return SOCK_BOOLEAN;
case CD_PROP_COLOR: case CD_PROP_COLOR:
return SOCK_RGBA; return SOCK_RGBA;
case CD_PROP_QUATERNION:
return SOCK_ROTATION;
default: default:
BLI_assert_unreachable(); BLI_assert_unreachable();
return SOCK_FLOAT; return SOCK_FLOAT;
@ -103,8 +106,14 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
set_active_fn(params, node); set_active_fn(params, node);
}); });
} }
if (type && if (type && ELEM(type,
ELEM(type, CD_PROP_FLOAT, CD_PROP_BOOL, CD_PROP_INT32, CD_PROP_FLOAT3, CD_PROP_COLOR)) { CD_PROP_FLOAT,
CD_PROP_BOOL,
CD_PROP_INT32,
CD_PROP_FLOAT3,
CD_PROP_COLOR,
CD_PROP_QUATERNION))
{
params.add_item(IFACE_("Value"), [type, set_active_fn](LinkSearchOpParams &params) { params.add_item(IFACE_("Value"), [type, set_active_fn](LinkSearchOpParams &params) {
bNode &node = params.add_node("GeometryNodeViewer"); bNode &node = params.add_node("GeometryNodeViewer");
node_storage(node).data_type = *type; node_storage(node).data_type = *type;

View File

@ -4,6 +4,8 @@
* \ingroup nodes * \ingroup nodes
*/ */
#include "BLI_math_quaternion.hh"
#include "NOD_geometry_nodes_execute.hh" #include "NOD_geometry_nodes_execute.hh"
#include "NOD_geometry_nodes_lazy_function.hh" #include "NOD_geometry_nodes_lazy_function.hh"
#include "NOD_node_declaration.hh" #include "NOD_node_declaration.hh"
@ -115,6 +117,9 @@ std::unique_ptr<IDProperty, bke::idprop::IDPropertyDeleter> id_property_create_f
ui_data->default_value = value->value != 0; ui_data->default_value = value->value != 0;
return property; return property;
} }
case SOCK_ROTATION: {
return nullptr;
}
case SOCK_STRING: { case SOCK_STRING: {
const bNodeSocketValueString *value = static_cast<const bNodeSocketValueString *>( const bNodeSocketValueString *value = static_cast<const bNodeSocketValueString *>(
socket.default_value); socket.default_value);
@ -166,6 +171,7 @@ bool id_property_type_matches_socket(const bNodeSocket &socket, const IDProperty
case SOCK_VECTOR: case SOCK_VECTOR:
return property.type == IDP_ARRAY && property.subtype == IDP_FLOAT && property.len == 3; return property.type == IDP_ARRAY && property.subtype == IDP_FLOAT && property.len == 3;
case SOCK_RGBA: case SOCK_RGBA:
case SOCK_ROTATION:
return property.type == IDP_ARRAY && property.subtype == IDP_FLOAT && property.len == 4; return property.type == IDP_ARRAY && property.subtype == IDP_FLOAT && property.len == 4;
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
return property.type == IDP_BOOLEAN; return property.type == IDP_BOOLEAN;
@ -218,6 +224,12 @@ static void init_socket_cpp_value_from_property(const IDProperty &property,
new (r_value) fn::ValueOrField<bool>(value); new (r_value) fn::ValueOrField<bool>(value);
break; break;
} }
case SOCK_ROTATION: {
const math::Quaternion value = math::Quaternion(
float4(static_cast<const float *>(IDP_Array(&property))));
new (r_value) fn::ValueOrField<math::Quaternion>(value);
break;
}
case SOCK_STRING: { case SOCK_STRING: {
std::string value = IDP_String(&property); std::string value = IDP_String(&property);
new (r_value) fn::ValueOrField<std::string>(std::move(value)); new (r_value) fn::ValueOrField<std::string>(std::move(value));

View File

@ -13,6 +13,7 @@
#include "BLI_listbase.h" #include "BLI_listbase.h"
#include "BLI_map.hh" #include "BLI_map.hh"
#include "BLI_math_euler.hh"
#include "BLI_multi_value_map.hh" #include "BLI_multi_value_map.hh"
#include "BLI_set.hh" #include "BLI_set.hh"
#include "BLI_stack.hh" #include "BLI_stack.hh"
@ -207,6 +208,13 @@ static SocketDeclarationPtr declaration_for_interface_socket(const bNodeTree &nt
dst = std::move(decl); dst = std::move(decl);
break; break;
} }
case SOCK_ROTATION: {
const auto &value = *io_socket.default_value_typed<bNodeSocketValueRotation>();
std::unique_ptr<decl::Rotation> decl = std::make_unique<decl::Rotation>();
decl->default_value = math::EulerXYZ(float3(value.value_euler));
dst = std::move(decl);
break;
}
case SOCK_INT: { case SOCK_INT: {
const auto &value = *io_socket.default_value_typed<bNodeSocketValueInt>(); const auto &value = *io_socket.default_value_typed<bNodeSocketValueInt>();
std::unique_ptr<decl::Int> decl = std::make_unique<decl::Int>(); std::unique_ptr<decl::Int> decl = std::make_unique<decl::Int>();

View File

@ -12,6 +12,8 @@
#include "BLI_color.hh" #include "BLI_color.hh"
#include "BLI_listbase.h" #include "BLI_listbase.h"
#include "BLI_math_euler.hh"
#include "BLI_math_quaternion_types.hh"
#include "BLI_math_vector.h" #include "BLI_math_vector.h"
#include "BLI_math_vector_types.hh" #include "BLI_math_vector_types.hh"
#include "BLI_string.h" #include "BLI_string.h"
@ -341,6 +343,11 @@ void node_socket_init_default_value(bNodeSocket *sock)
sock->default_value = dval; sock->default_value = dval;
break; break;
} }
case SOCK_ROTATION: {
bNodeSocketValueRotation *dval = MEM_cnew<bNodeSocketValueRotation>(__func__);
sock->default_value = dval;
break;
}
case SOCK_VECTOR: { case SOCK_VECTOR: {
static float default_value[] = {0.0f, 0.0f, 0.0f}; static float default_value[] = {0.0f, 0.0f, 0.0f};
bNodeSocketValueVector *dval = MEM_cnew<bNodeSocketValueVector>("node socket value vector"); bNodeSocketValueVector *dval = MEM_cnew<bNodeSocketValueVector>("node socket value vector");
@ -458,6 +465,12 @@ void node_socket_copy_default_value(bNodeSocket *to, const bNodeSocket *from)
*toval = *fromval; *toval = *fromval;
break; break;
} }
case SOCK_ROTATION: {
bNodeSocketValueRotation *toval = (bNodeSocketValueRotation *)to->default_value;
bNodeSocketValueRotation *fromval = (bNodeSocketValueRotation *)from->default_value;
*toval = *fromval;
break;
}
case SOCK_STRING: { case SOCK_STRING: {
bNodeSocketValueString *toval = (bNodeSocketValueString *)to->default_value; bNodeSocketValueString *toval = (bNodeSocketValueString *)to->default_value;
bNodeSocketValueString *fromval = (bNodeSocketValueString *)from->default_value; bNodeSocketValueString *fromval = (bNodeSocketValueString *)from->default_value;
@ -625,6 +638,24 @@ static bNodeSocketType *make_socket_type_bool()
return socktype; return socktype;
} }
static bNodeSocketType *make_socket_type_rotation()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_ROTATION, PROP_NONE);
socktype->base_cpp_type = &blender::CPPType::get<math::Quaternion>();
socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
const auto &value = *socket.default_value_typed<bNodeSocketValueRotation>();
const math::EulerXYZ euler(float3(value.value_euler));
*static_cast<math::Quaternion *>(r_value) = math::to_quaternion(euler);
};
socktype->geometry_nodes_cpp_type = &blender::CPPType::get<ValueOrField<math::Quaternion>>();
socktype->get_geometry_nodes_cpp_value = [](const bNodeSocket &socket, void *r_value) {
math::Quaternion value;
socket.typeinfo->get_base_cpp_value(socket, &value);
new (r_value) ValueOrField<math::Quaternion>(value);
};
return socktype;
}
static bNodeSocketType *make_socket_type_float(PropertySubType subtype) static bNodeSocketType *make_socket_type_float(PropertySubType subtype)
{ {
bNodeSocketType *socktype = make_standard_socket_type(SOCK_FLOAT, subtype); bNodeSocketType *socktype = make_standard_socket_type(SOCK_FLOAT, subtype);
@ -798,6 +829,7 @@ void register_standard_node_socket_types()
nodeRegisterSocketType(make_socket_type_int(PROP_FACTOR)); nodeRegisterSocketType(make_socket_type_int(PROP_FACTOR));
nodeRegisterSocketType(make_socket_type_bool()); nodeRegisterSocketType(make_socket_type_bool());
nodeRegisterSocketType(make_socket_type_rotation());
nodeRegisterSocketType(make_socket_type_vector(PROP_NONE)); nodeRegisterSocketType(make_socket_type_vector(PROP_NONE));
nodeRegisterSocketType(make_socket_type_vector(PROP_TRANSLATION)); nodeRegisterSocketType(make_socket_type_vector(PROP_TRANSLATION));

View File

@ -381,6 +381,61 @@ bNodeSocket &Color::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &
return socket; return socket;
} }
/** \} */
/* -------------------------------------------------------------------- */
/** \name #Rotation
* \{ */
bNodeSocket &Rotation::build(bNodeTree &ntree, bNode &node) const
{
bNodeSocket &socket = *nodeAddStaticSocket(&ntree,
&node,
this->in_out,
SOCK_ROTATION,
PROP_NONE,
this->identifier.c_str(),
this->name.c_str());
this->set_common_flags(socket);
bNodeSocketValueRotation &value = *static_cast<bNodeSocketValueRotation *>(socket.default_value);
copy_v3_v3(value.value_euler, float3(this->default_value));
return socket;
}
bool Rotation::matches(const bNodeSocket &socket) const
{
if (!this->matches_common_data(socket)) {
if (socket.name != this->name) {
return false;
}
if (socket.identifier != this->identifier) {
return false;
}
}
if (socket.type != SOCK_ROTATION) {
return false;
}
return true;
}
bool Rotation::can_connect(const bNodeSocket &socket) const
{
if (!sockets_can_connect(*this, socket)) {
return false;
}
return socket.type == SOCK_ROTATION;
}
bNodeSocket &Rotation::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const
{
if (socket.type != SOCK_ROTATION) {
BLI_assert(socket.in_out == this->in_out);
return this->build(ntree, node);
}
this->set_common_flags(socket);
STRNCPY(socket.name, this->name.c_str());
return socket;
}
/** \} */ /** \} */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */