diff options
Diffstat (limited to 'source/blender')
71 files changed, 1999 insertions, 80 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 38fe974c228..d399b40de64 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -145,6 +145,7 @@ typedef struct bNodeSocketType { /* for standard socket types in C */ int type, subtype; + int display_shape_default; /* When set, bNodeSocket->limit does not have any effect anymore. */ bool use_link_limits_of_type; @@ -999,6 +1000,39 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, #define SH_NODE_OUTPUT_AOV 707 #define SH_NODE_VECTOR_ROTATE 708 +#define SIM_NODE_PARTICLE_SIMULATION 1000 +#define SIM_NODE_FORCE 1001 +#define SIM_NODE_SET_PARTICLE_ATTRIBUTE 1002 +#define SIM_NODE_PARTICLE_BIRTH_EVENT 1003 +#define SIM_NODE_PARTICLE_TIME_STEP_EVENT 1004 +#define SIM_NODE_EXECUTE_CONDITION 1005 +#define SIM_NODE_MULTI_EXECUTE 1006 +#define SIM_NODE_PARTICLE_MESH_EMITTER 1007 +#define SIM_NODE_PARTICLE_MESH_COLLISION_EVENT 1008 +#define SIM_NODE_EMIT_PARTICLES 1009 +#define SIM_NODE_SIMULATION_TIME 1010 +#define SIM_NODE_PARTICLE_ATTRIBUTE 1011 + +#define FN_NODE_COMBINE_XYZ 1100 +#define FN_NODE_SEPARATE_XYZ 1101 +#define FN_NODE_COMBINE_RGB 1102 +#define FN_NODE_SEPARATE_RGB 1103 +#define FN_NODE_COMBINE_HSV 1104 +#define FN_NODE_SEPARATE_HSV 1105 +#define FN_NODE_FLOAT_MATH 1106 +#define FN_NODE_VECTOR_MATH 1107 +#define FN_NODE_SURFACE_COLOR 1108 +#define FN_NODE_SURFACE_NORMAL 1109 +#define FN_NODE_SURFACE_POSITION 1110 +#define FN_NODE_SURFACE_WEIGHT 1111 +#define FN_NODE_CLOSEST_SURFACE 1112 +#define FN_NODE_BOOLEAN_MATH 1113 +#define FN_NODE_FLOAT_COMPARE 1114 +#define FN_NODE_INSTANCE_IDENTIFIER 1115 +#define FN_NODE_STRING_CONCATENATION 1116 +#define FN_NODE_OBJECT_TRANSFORMS 1117 +#define FN_NODE_SWITCH 1118 + /* custom defines options for Material node */ // #define SH_NODE_MAT_DIFF 1 // #define SH_NODE_MAT_SPEC 2 diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c index 9c0fa33157c..ac60ad8a92a 100644 --- a/source/blender/blenkernel/intern/lib_query.c +++ b/source/blender/blenkernel/intern/lib_query.c @@ -204,6 +204,21 @@ static void library_foreach_idproperty_ID_link(LibraryForeachIDData *data, FOREACH_FINALIZE_VOID; } +static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket *sock) +{ + library_foreach_idproperty_ID_link(data, sock->prop, IDWALK_CB_USER); + + if (sock->type == SOCK_OBJECT) { + bNodeSocketValueObject *default_value = sock->default_value; + FOREACH_CALLBACK_INVOKE_ID_PP(data, (ID **)&default_value->object, IDWALK_CB_USER); + } + else if (sock->type == SOCK_IMAGE) { + bNodeSocketValueImage *default_value = sock->default_value; + FOREACH_CALLBACK_INVOKE_ID_PP(data, (ID **)&default_value->image, IDWALK_CB_USER); + } + FOREACH_FINALIZE_VOID; +} + static void library_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSED(rbw), ID **id_pointer, void *user_data, @@ -1025,18 +1040,18 @@ static void library_foreach_ID_link(Main *bmain, library_foreach_idproperty_ID_link(&data, node->prop, IDWALK_CB_USER); for (sock = node->inputs.first; sock; sock = sock->next) { - library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER); + library_foreach_node_socket(&data, sock); } for (sock = node->outputs.first; sock; sock = sock->next) { - library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER); + library_foreach_node_socket(&data, sock); } } for (sock = ntree->inputs.first; sock; sock = sock->next) { - library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER); + library_foreach_node_socket(&data, sock); } for (sock = ntree->outputs.first; sock; sock = sock->next) { - library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER); + library_foreach_node_socket(&data, sock); } break; } diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index c3c538f3424..bd7dd007451 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -66,7 +66,9 @@ #include "NOD_common.h" #include "NOD_composite.h" +#include "NOD_function.h" #include "NOD_shader.h" +#include "NOD_simulation.h" #include "NOD_socket.h" #include "NOD_texture.h" @@ -400,6 +402,9 @@ static void node_socket_set_typeinfo(bNodeTree *ntree, /* deprecated integer type */ sock->type = typeinfo->type; + sock->display_shape = typeinfo->display_shape_default; + sock->limit = (sock->in_out == SOCK_IN) ? typeinfo->input_link_limit : + typeinfo->output_link_limit; if (sock->default_value == NULL) { /* initialize the default_value pointer used by standard socket types */ @@ -755,6 +760,14 @@ void nodeModifySocketType( } if (sock->default_value) { + if (sock->type == SOCK_OBJECT) { + bNodeSocketValueObject *default_value = sock->default_value; + id_us_min(&default_value->object->id); + } + else if (sock->type == SOCK_IMAGE) { + bNodeSocketValueImage *default_value = sock->default_value; + id_us_min(&default_value->image->id); + } MEM_freeN(sock->default_value); sock->default_value = NULL; } @@ -858,6 +871,20 @@ const char *nodeStaticSocketType(int type, int subtype) return "NodeSocketString"; case SOCK_SHADER: return "NodeSocketShader"; + case SOCK_EMITTERS: + return "NodeSocketEmitters"; + case SOCK_EVENTS: + return "NodeSocketEvents"; + case SOCK_FORCES: + return "NodeSocketForces"; + case SOCK_CONTROL_FLOW: + return "NodeSocketControlFlow"; + case SOCK_OBJECT: + return "NodeSocketObject"; + case SOCK_IMAGE: + return "NodeSocketImage"; + case SOCK_SURFACE_HOOK: + return "NodeSocketSurfaceHook"; } return NULL; } @@ -919,6 +946,20 @@ const char *nodeStaticSocketInterfaceType(int type, int subtype) return "NodeSocketInterfaceString"; case SOCK_SHADER: return "NodeSocketInterfaceShader"; + case SOCK_EMITTERS: + return "NodeSocketInterfaceEmitters"; + case SOCK_EVENTS: + return "NodeSocketInterfaceEvents"; + case SOCK_FORCES: + return "NodeSocketInterfaceForces"; + case SOCK_CONTROL_FLOW: + return "NodeSocketInterfaceControlFlow"; + case SOCK_OBJECT: + return "NodeSocketInterfaceObject"; + case SOCK_IMAGE: + return "NodeSocketInterfaceImage"; + case SOCK_SURFACE_HOOK: + return "NodeSocketInterfaceSurfaceHook"; } return NULL; } @@ -977,6 +1018,16 @@ static void node_socket_free(bNodeTree *UNUSED(ntree), } if (sock->default_value) { + if (do_id_user) { + if (sock->type == SOCK_OBJECT) { + bNodeSocketValueObject *default_value = sock->default_value; + id_us_min(&default_value->object->id); + } + else if (sock->type == SOCK_IMAGE) { + bNodeSocketValueImage *default_value = sock->default_value; + id_us_min(&default_value->image->id); + } + } MEM_freeN(sock->default_value); } } @@ -1263,6 +1314,17 @@ static void node_socket_copy(bNodeSocket *sock_dst, const bNodeSocket *sock_src, if (sock_src->default_value) { sock_dst->default_value = MEM_dupallocN(sock_src->default_value); + + if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { + if (sock_dst->type == SOCK_OBJECT) { + bNodeSocketValueObject *default_value = sock_dst->default_value; + id_us_plus(&default_value->object->id); + } + else if (sock_dst->type == SOCK_IMAGE) { + bNodeSocketValueImage *default_value = sock_dst->default_value; + id_us_plus(&default_value->image->id); + } + } } sock_dst->stack_index = 0; @@ -2083,6 +2145,27 @@ void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user) if (node->id) { id_us_min(node->id); } + + LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { + if (sock->type == SOCK_OBJECT) { + bNodeSocketValueObject *default_value = sock->default_value; + id_us_min(&default_value->object->id); + } + else if (sock->type == SOCK_IMAGE) { + bNodeSocketValueImage *default_value = sock->default_value; + id_us_min(&default_value->image->id); + } + } + LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { + if (sock->type == SOCK_OBJECT) { + bNodeSocketValueObject *default_value = sock->default_value; + id_us_min(&default_value->object->id); + } + else if (sock->type == SOCK_IMAGE) { + bNodeSocketValueImage *default_value = sock->default_value; + id_us_min(&default_value->image->id); + } + } } /* Remove animation data. */ @@ -2109,6 +2192,15 @@ static void node_socket_interface_free(bNodeTree *UNUSED(ntree), bNodeSocket *so } if (sock->default_value) { + if (sock->type == SOCK_OBJECT) { + bNodeSocketValueObject *default_value = sock->default_value; + id_us_min(&default_value->object->id); + } + else if (sock->type == SOCK_IMAGE) { + bNodeSocketValueImage *default_value = sock->default_value; + id_us_min(&default_value->image->id); + } + MEM_freeN(sock->default_value); } } @@ -4114,6 +4206,47 @@ static void registerTextureNodes(void) register_node_type_tex_proc_distnoise(); } +static void registerSimulationNodes(void) +{ + register_node_type_sim_group(); + + register_node_type_sim_particle_simulation(); + register_node_type_sim_force(); + register_node_type_sim_set_particle_attribute(); + register_node_type_sim_particle_birth_event(); + register_node_type_sim_particle_time_step_event(); + register_node_type_sim_execute_condition(); + register_node_type_sim_multi_execute(); + register_node_type_sim_particle_mesh_emitter(); + register_node_type_sim_particle_mesh_collision_event(); + register_node_type_sim_emit_particles(); + register_node_type_sim_simulation_time(); + register_node_type_sim_particle_attribute(); +} + +static void registerFunctionNodes(void) +{ + register_node_type_fn_combine_xyz(); + register_node_type_fn_separate_xyz(); + register_node_type_fn_combine_rgb(); + register_node_type_fn_separate_rgb(); + register_node_type_fn_combine_hsv(); + register_node_type_fn_separate_hsv(); + register_node_type_fn_float_math(); + register_node_type_fn_vector_math(); + register_node_type_fn_closest_surface(); + register_node_type_fn_surface_color(); + register_node_type_fn_surface_normal(); + register_node_type_fn_surface_position(); + register_node_type_fn_surface_weight(); + register_node_type_fn_boolean_math(); + register_node_type_fn_float_compare(); + register_node_type_fn_instance_identifier(); + register_node_type_fn_string_concatenation(); + register_node_type_fn_object_transforms(); + register_node_type_fn_switch(); +} + void init_nodesystem(void) { nodetreetypes_hash = BLI_ghash_str_new("nodetreetypes_hash gh"); @@ -4127,6 +4260,7 @@ void init_nodesystem(void) register_node_tree_type_cmp(); register_node_tree_type_sh(); register_node_tree_type_tex(); + register_node_tree_type_sim(); register_node_type_frame(); register_node_type_reroute(); @@ -4136,6 +4270,8 @@ void init_nodesystem(void) registerCompositNodes(); registerShaderNodes(); registerTextureNodes(); + registerSimulationNodes(); + registerFunctionNodes(); } void free_nodesystem(void) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 96c7339c6da..7f26019b925 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3595,6 +3595,20 @@ static void lib_link_workspace_instance_hook(FileData *fd, WorkSpaceInstanceHook /** \name Read ID: Node Tree * \{ */ +static void lib_link_node_socket(FileData *fd, Library *lib, bNodeSocket *sock) +{ + IDP_LibLinkProperty(sock->prop, fd); + + if (sock->type == SOCK_OBJECT) { + bNodeSocketValueObject *default_value = sock->default_value; + default_value->object = newlibadr(fd, lib, default_value->object); + } + else if (sock->type == SOCK_IMAGE) { + bNodeSocketValueImage *default_value = sock->default_value; + default_value->image = newlibadr(fd, lib, default_value->image); + } +} + /* Single node tree (also used for material/scene trees), ntree is not NULL */ static void lib_link_ntree(FileData *fd, Library *lib, bNodeTree *ntree) { @@ -3610,18 +3624,18 @@ static void lib_link_ntree(FileData *fd, Library *lib, bNodeTree *ntree) node->id = newlibadr(fd, lib, node->id); LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { - IDP_LibLinkProperty(sock->prop, fd); + lib_link_node_socket(fd, lib, sock); } LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { - IDP_LibLinkProperty(sock->prop, fd); + lib_link_node_socket(fd, lib, sock); } } LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->inputs) { - IDP_LibLinkProperty(sock->prop, fd); + lib_link_node_socket(fd, lib, sock); } LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->outputs) { - IDP_LibLinkProperty(sock->prop, fd); + lib_link_node_socket(fd, lib, sock); } /* Set node->typeinfo pointers. This is done in lib linking, after the diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 68be8683f84..8a6896c6690 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -990,9 +990,20 @@ static void write_node_socket_default_value(WriteData *wd, bNodeSocket *sock) case SOCK_STRING: writestruct(wd, DATA, bNodeSocketValueString, 1, sock->default_value); break; + case SOCK_OBJECT: + writestruct(wd, DATA, bNodeSocketValueObject, 1, sock->default_value); + break; + case SOCK_IMAGE: + writestruct(wd, DATA, bNodeSocketValueImage, 1, sock->default_value); + break; case __SOCK_MESH: case SOCK_CUSTOM: case SOCK_SHADER: + case SOCK_EMITTERS: + case SOCK_EVENTS: + case SOCK_FORCES: + case SOCK_CONTROL_FLOW: + case SOCK_SURFACE_HOOK: BLI_assert(false); break; } diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index 7a1f64b61d4..fe743a40fb5 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -94,6 +94,7 @@ void ED_node_set_tree_type(struct SpaceNode *snode, struct bNodeTreeType *typein bool ED_node_is_compositor(struct SpaceNode *snode); bool ED_node_is_shader(struct SpaceNode *snode); bool ED_node_is_texture(struct SpaceNode *snode); +bool ED_node_is_simulation(struct SpaceNode *snode); void ED_node_shader_default(const struct bContext *C, struct ID *id); void ED_node_composit_default(const struct bContext *C, struct Scene *scene); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index e5ca2efb26f..492f92de8b2 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -69,7 +69,9 @@ #include "NOD_composite.h" #include "NOD_shader.h" +#include "NOD_simulation.h" #include "NOD_texture.h" + #include "node_intern.h" /* own include */ /* ****************** SOCKET BUTTON DRAW FUNCTIONS ***************** */ @@ -3122,6 +3124,89 @@ static void node_texture_set_butfunc(bNodeType *ntype) } } +/* ****************** BUTTON CALLBACKS FOR SIMULATION NODES ***************** */ + +static void node_simulation_buts_particle_time_step_event(uiLayout *layout, + bContext *UNUSED(C), + PointerRNA *ptr) +{ + uiItemR(layout, ptr, "mode", 0, "", ICON_NONE); +} + +static void node_simulation_buts_particle_attribute(uiLayout *layout, + bContext *UNUSED(C), + PointerRNA *ptr) +{ + uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE); +} + +static void node_simulation_buts_set_particle_attribute(uiLayout *layout, + bContext *UNUSED(C), + PointerRNA *ptr) +{ + uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE); +} + +static void node_simulation_set_butfunc(bNodeType *ntype) +{ + switch (ntype->type) { + case SIM_NODE_PARTICLE_TIME_STEP_EVENT: + ntype->draw_buttons = node_simulation_buts_particle_time_step_event; + break; + case SIM_NODE_PARTICLE_ATTRIBUTE: + ntype->draw_buttons = node_simulation_buts_particle_attribute; + break; + case SIM_NODE_SET_PARTICLE_ATTRIBUTE: + ntype->draw_buttons = node_simulation_buts_set_particle_attribute; + break; + } +} + +/* ****************** BUTTON CALLBACKS FOR FUNCTION NODES ***************** */ + +static void node_function_buts_vector_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "operation", 0, "", ICON_NONE); +} + +static void node_function_buts_boolean_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "operation", 0, "", ICON_NONE); +} + +static void node_function_buts_float_compare(uiLayout *layout, + bContext *UNUSED(C), + PointerRNA *ptr) +{ + uiItemR(layout, ptr, "operation", 0, "", ICON_NONE); +} + +static void node_function_buts_switch(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE); +} + +static void node_function_set_butfunc(bNodeType *ntype) +{ + switch (ntype->type) { + case FN_NODE_FLOAT_MATH: + ntype->draw_buttons = node_buts_math; + break; + case FN_NODE_VECTOR_MATH: + ntype->draw_buttons = node_function_buts_vector_math; + break; + case FN_NODE_BOOLEAN_MATH: + ntype->draw_buttons = node_function_buts_boolean_math; + break; + case FN_NODE_FLOAT_COMPARE: + ntype->draw_buttons = node_function_buts_float_compare; + break; + case FN_NODE_SWITCH: + ntype->draw_buttons = node_function_buts_switch; + break; + } +} + /* ****** init draw callbacks for all tree types, only called in usiblender.c, once ************ */ static void node_property_update_default(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) @@ -3230,6 +3315,8 @@ void ED_node_init_butfuncs(void) node_composit_set_butfunc(ntype); node_shader_set_butfunc(ntype); node_texture_set_butfunc(ntype); + node_simulation_set_butfunc(ntype); + node_function_set_butfunc(ntype); /* define update callbacks for socket properties */ node_template_properties_update(ntype); @@ -3240,6 +3327,7 @@ void ED_node_init_butfuncs(void) ntreeType_Composite->ui_icon = ICON_NODE_COMPOSITING; ntreeType_Shader->ui_icon = ICON_NODE_MATERIAL; ntreeType_Texture->ui_icon = ICON_NODE_TEXTURE; + ntreeType_Simulation->ui_icon = ICON_PARTICLES; } void ED_init_custom_node_type(bNodeType *ntype) @@ -3268,6 +3356,13 @@ static const float std_node_socket_colors[][4] = { {0.0, 0.0, 0.0, 1.0}, /*__SOCK_MESH (deprecated) */ {0.06, 0.52, 0.15, 1.0}, /* SOCK_INT */ {0.39, 0.39, 0.39, 1.0}, /* SOCK_STRING */ + {0.8, 0.8, 0.2, 1.0}, /* SOCK_EMITTERS */ + {0.8, 0.2, 0.8, 1.0}, /* SOCK_EVENTS */ + {0.2, 0.8, 0.8, 1.0}, /* SOCK_FORCES */ + {0.3, 0.3, 0.3, 1.0}, /* SOCK_CONTROL_FLOW */ + {0.4, 0.1, 0.1, 1.0}, /* SOCK_OBJECT */ + {0.1, 0.4, 0.1, 1.0}, /* SOCK_IMAGE */ + {0.1, 0.1, 0.4, 1.0}, /* SOCK_SURFACE_HOOK */ }; /* common color callbacks for standard types */ @@ -3385,6 +3480,14 @@ static void std_node_socket_draw( uiItemR(row, ptr, "default_value", 0, "", 0); break; } + case SOCK_OBJECT: { + uiItemR(layout, ptr, "default_value", 0, text, 0); + break; + } + case SOCK_IMAGE: { + uiItemR(layout, ptr, "default_value", 0, text, 0); + break; + } default: node_socket_button_label(C, layout, ptr, node_ptr, text); break; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index a82acfc4dbe..a9080122ffd 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -69,7 +69,9 @@ #include "NOD_composite.h" #include "NOD_shader.h" +#include "NOD_simulation.h" #include "NOD_texture.h" + #include "node_intern.h" /* own include */ #define USE_ESC_COMPO @@ -438,6 +440,11 @@ bool ED_node_is_texture(struct SpaceNode *snode) return STREQ(snode->tree_idname, ntreeType_Texture->idname); } +bool ED_node_is_simulation(struct SpaceNode *snode) +{ + return STREQ(snode->tree_idname, ntreeType_Simulation->idname); +} + /* assumes nothing being done in ntree yet, sets the default in/out node */ /* called from shading buttons or header */ void ED_node_shader_default(const bContext *C, ID *id) diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c index 3a0ef45a68d..2617384d046 100644 --- a/source/blender/editors/space_node/node_group.c +++ b/source/blender/editors/space_node/node_group.c @@ -69,7 +69,8 @@ static bool node_group_operator_active(bContext *C) */ if (STREQ(snode->tree_idname, "ShaderNodeTree") || STREQ(snode->tree_idname, "CompositorNodeTree") || - STREQ(snode->tree_idname, "TextureNodeTree")) { + STREQ(snode->tree_idname, "TextureNodeTree") || + STREQ(snode->tree_idname, "SimulationNodeTree")) { return true; } } @@ -85,7 +86,8 @@ static bool node_group_operator_editable(bContext *C) * Disabled otherwise to allow pynodes define their own operators * with same keymap. */ - if (ED_node_is_shader(snode) || ED_node_is_compositor(snode) || ED_node_is_texture(snode)) { + if (ED_node_is_shader(snode) || ED_node_is_compositor(snode) || ED_node_is_texture(snode) || + ED_node_is_simulation(snode)) { return true; } } @@ -111,6 +113,9 @@ static const char *group_node_idname(bContext *C) else if (ED_node_is_texture(snode)) { return "TextureNodeGroup"; } + else if (ED_node_is_simulation(snode)) { + return "SimulationNodeGroup"; + } return ""; } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 8029e8ebc13..0fc239ffc33 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -154,6 +154,13 @@ typedef enum eNodeSocketDatatype { __SOCK_MESH = 5, /* deprecated */ SOCK_INT = 6, SOCK_STRING = 7, + SOCK_EMITTERS = 8, + SOCK_EVENTS = 9, + SOCK_FORCES = 10, + SOCK_CONTROL_FLOW = 11, + SOCK_OBJECT = 12, + SOCK_IMAGE = 13, + SOCK_SURFACE_HOOK = 14, } eNodeSocketDatatype; /* socket shape */ @@ -498,6 +505,7 @@ typedef struct bNodeTree { #define NTREE_SHADER 0 #define NTREE_COMPOSIT 1 #define NTREE_TEXTURE 2 +#define NTREE_SIMULATION 3 /* ntree->init, flag */ #define NTREE_TYPE_INIT 1 @@ -565,6 +573,14 @@ typedef struct bNodeSocketValueString { char value[1024]; } bNodeSocketValueString; +typedef struct bNodeSocketValueObject { + struct Object *object; +} bNodeSocketValueObject; + +typedef struct bNodeSocketValueImage { + struct Image *image; +} bNodeSocketValueImage; + /* data structs, for node->storage */ enum { CMP_NODE_MASKTYPE_ADD = 0, @@ -1293,6 +1309,23 @@ enum { NODE_VECTOR_MATH_TANGENT = 23, }; +/* Boolean math node operations. */ +enum { + NODE_BOOLEAN_MATH_AND = 0, + NODE_BOOLEAN_MATH_OR = 1, + NODE_BOOLEAN_MATH_NOT = 2, +}; + +/* Float compare node operations. */ +enum { + NODE_FLOAT_COMPARE_LESS_THAN = 0, + NODE_FLOAT_COMPARE_LESS_EQUAL = 1, + NODE_FLOAT_COMPARE_GREATER_THAN = 2, + NODE_FLOAT_COMPARE_GREATER_EQUAL = 3, + NODE_FLOAT_COMPARE_EQUAL = 4, + NODE_FLOAT_COMPARE_NOT_EQUAL = 5, +}; + /* Clamp node types. */ enum { NODE_CLAMP_MINMAX = 0, @@ -1385,4 +1418,9 @@ typedef enum NodeShaderOutputTarget { SHD_OUTPUT_CYCLES = 2, } NodeShaderOutputTarget; +typedef enum NodeSimParticleTimeStepEventType { + NODE_PARTICLE_TIME_STEP_EVENT_BEGIN = 0, + NODE_PARTICLE_TIME_STEP_EVENT_END = 0, +} NodeSimParticleTimeStepEventType; + #endif diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index bab61d9e00e..cf37de331d3 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -260,6 +260,7 @@ extern StructRNA RNA_FreestyleLineStyle; extern StructRNA RNA_FreestyleModuleSettings; extern StructRNA RNA_FreestyleSettings; extern StructRNA RNA_Function; +extern StructRNA RNA_FunctionNode; extern StructRNA RNA_GPencilFrame; extern StructRNA RNA_GPencilInterpolateSettings; extern StructRNA RNA_GPencilLayer; @@ -549,6 +550,8 @@ extern StructRNA RNA_ShrinkwrapConstraint; extern StructRNA RNA_ShrinkwrapModifier; extern StructRNA RNA_SimpleDeformModifier; extern StructRNA RNA_SimplifyGpencilModifier; +extern StructRNA RNA_SimulationNode; +extern StructRNA RNA_SimulationNodeTree; extern StructRNA RNA_SkinModifier; extern StructRNA RNA_SmoothGpencilModifier; extern StructRNA RNA_SmoothModifier; diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index fef98f9da4b..b2f9c90b7f5 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -191,6 +191,8 @@ extern const EnumPropertyItem rna_enum_node_socket_in_out_items[]; extern const EnumPropertyItem rna_enum_node_math_items[]; extern const EnumPropertyItem rna_enum_mapping_type_items[]; extern const EnumPropertyItem rna_enum_node_vec_math_items[]; +extern const EnumPropertyItem rna_enum_node_boolean_math_items[]; +extern const EnumPropertyItem rna_enum_node_float_compare_items[]; extern const EnumPropertyItem rna_enum_node_filter_items[]; extern const EnumPropertyItem rna_enum_node_map_range_items[]; extern const EnumPropertyItem rna_enum_node_clamp_items[]; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 024ed879d34..b884dd98d0a 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -81,6 +81,38 @@ static const EnumPropertyItem node_socket_type_items[] = { {SOCK_STRING, "STRING", 0, "String", ""}, {SOCK_RGBA, "RGBA", 0, "RGBA", ""}, {SOCK_SHADER, "SHADER", 0, "Shader", ""}, + {SOCK_EMITTERS, "EMITTERS", 0, "Emitters", ""}, + {SOCK_EVENTS, "EVENTS", 0, "Events", ""}, + {SOCK_FORCES, "FORCES", 0, "Forces", ""}, + {SOCK_CONTROL_FLOW, "CONTROL_FLOW", 0, "Control Flow", ""}, + {SOCK_OBJECT, "OBJECT", 0, "Object", ""}, + {SOCK_IMAGE, "IMAGE", 0, "Image", ""}, + {SOCK_SURFACE_HOOK, "SURFACE_HOOK", 0, "Surface Hook", ""}, + {0, NULL, 0, NULL, NULL}, +}; + +static const EnumPropertyItem node_socket_particle_attribute_type_items[] = { + {SOCK_FLOAT, "FLOAT", 0, "Float", ""}, + {SOCK_INT, "INT", 0, "Int", ""}, + {SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""}, + {SOCK_VECTOR, "VECTOR", 0, "Vector", ""}, + {SOCK_RGBA, "RGBA", 0, "Color", ""}, + {SOCK_OBJECT, "OBJECT", 0, "Object", ""}, + {SOCK_IMAGE, "IMAGE", 0, "Image", ""}, + {SOCK_SURFACE_HOOK, "SURFACE_HOOK", 0, "Surface Hook", ""}, + {0, NULL, 0, NULL, NULL}, +}; + +static const EnumPropertyItem node_socket_data_type_items[] = { + {SOCK_FLOAT, "FLOAT", 0, "Float", ""}, + {SOCK_INT, "INT", 0, "Int", ""}, + {SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""}, + {SOCK_VECTOR, "VECTOR", 0, "Vector", ""}, + {SOCK_STRING, "STRING", 0, "String", ""}, + {SOCK_RGBA, "RGBA", 0, "Color", ""}, + {SOCK_OBJECT, "OBJECT", 0, "Object", ""}, + {SOCK_IMAGE, "IMAGE", 0, "Image", ""}, + {SOCK_SURFACE_HOOK, "SURFACE_HOOK", 0, "Surface Hook", ""}, {0, NULL, 0, NULL, NULL}, }; @@ -244,6 +276,47 @@ const EnumPropertyItem rna_enum_node_vec_math_items[] = { {0, NULL, 0, NULL, NULL}, }; +const EnumPropertyItem rna_enum_node_boolean_math_items[] = { + {NODE_BOOLEAN_MATH_AND, "AND", 0, "And", "Outputs true only when both inputs are true"}, + {NODE_BOOLEAN_MATH_OR, "OR", 0, "Or", "Outputs or when at least one of the inputs is true"}, + {NODE_BOOLEAN_MATH_NOT, "NOT", 0, "Not", "Outputs the opposite of the input"}, + {0, NULL, 0, NULL, NULL}, +}; + +const EnumPropertyItem rna_enum_node_float_compare_items[] = { + {NODE_FLOAT_COMPARE_LESS_THAN, + "LESS_THAN", + 0, + "A < B", + "True when the first input is smaller than second input"}, + {NODE_FLOAT_COMPARE_LESS_EQUAL, + "LESS_EQUAL", + 0, + "A <= B", + "True when the first input is smaller than the second input or equal"}, + {NODE_FLOAT_COMPARE_GREATER_THAN, + "GREATER_THAN", + 0, + "A > B", + "True when the first input is greater than the second input"}, + {NODE_FLOAT_COMPARE_GREATER_EQUAL, + "GREATER_EQUAL", + 0, + "A >= B", + "True when the first input is greater than the second input or equal"}, + {NODE_FLOAT_COMPARE_EQUAL, + "EQUAL", + 0, + "A = B", + "True when both inputs are approximately equal"}, + {NODE_FLOAT_COMPARE_NOT_EQUAL, + "NOT_EQUAL", + 0, + "A != B", + "True when both inputs are not approximately equal"}, + {0, NULL, 0, NULL, NULL}, +}; + const EnumPropertyItem rna_enum_node_map_range_items[] = { {NODE_MAP_RANGE_LINEAR, "LINEAR", @@ -669,6 +742,34 @@ static const EnumPropertyItem *rna_node_static_type_itemf(bContext *UNUSED(C), # undef DefNode } + if (RNA_struct_is_a(ptr->type, &RNA_SimulationNode)) { +# define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \ + if (STREQ(#Category, "SimulationNode")) { \ + tmp.value = ID; \ + tmp.identifier = EnumName; \ + tmp.name = UIName; \ + tmp.description = UIDesc; \ + tmp.icon = ICON_NONE; \ + RNA_enum_item_add(&item, &totitem, &tmp); \ + } +# include "../../nodes/NOD_static_types.h" +# undef DefNode + } + + if (RNA_struct_is_a(ptr->type, &RNA_FunctionNode)) { +# define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \ + if (STREQ(#Category, "FunctionNode")) { \ + tmp.value = ID; \ + tmp.identifier = EnumName; \ + tmp.name = UIName; \ + tmp.description = UIDesc; \ + tmp.icon = ICON_NONE; \ + RNA_enum_item_add(&item, &totitem, &tmp); \ + } +# include "../../nodes/NOD_static_types.h" +# undef DefNode + } + RNA_enum_item_end(&item, &totitem); *r_free = true; @@ -1785,6 +1886,50 @@ static StructRNA *rna_TextureNode_register(Main *bmain, return nt->rna_ext.srna; } +static StructRNA *rna_SimulationNode_register(Main *bmain, + ReportList *reports, + void *data, + const char *identifier, + StructValidateFunc validate, + StructCallbackFunc call, + StructFreeFunc free) +{ + bNodeType *nt = rna_Node_register_base( + bmain, reports, &RNA_SimulationNode, data, identifier, validate, call, free); + if (!nt) { + return NULL; + } + + nodeRegisterType(nt); + + /* update while blender is running */ + WM_main_add_notifier(NC_NODE | NA_EDITED, NULL); + + return nt->rna_ext.srna; +} + +static StructRNA *rna_FunctionNode_register(Main *bmain, + ReportList *reports, + void *data, + const char *identifier, + StructValidateFunc validate, + StructCallbackFunc call, + StructFreeFunc free) +{ + bNodeType *nt = rna_Node_register_base( + bmain, reports, &RNA_FunctionNode, data, identifier, validate, call, free); + if (!nt) { + return NULL; + } + + nodeRegisterType(nt); + + /* update while blender is running */ + WM_main_add_notifier(NC_NODE | NA_EDITED, NULL); + + return nt->rna_ext.srna; +} + static IDProperty *rna_Node_idprops(PointerRNA *ptr, bool create) { bNode *node = ptr->data; @@ -2185,6 +2330,8 @@ static StructRNA *rna_NodeSocket_register(Main *UNUSED(bmain), } st->free_self = (void (*)(bNodeSocketType * stype)) MEM_freeN; + st->input_link_limit = 1; + st->output_link_limit = 0xFFF; /* if RNA type is already registered, unregister first */ if (st->ext_socket.srna) { @@ -2502,6 +2649,8 @@ static StructRNA *rna_NodeSocketInterface_register(Main *UNUSED(bmain), } st->free_self = (void (*)(bNodeSocketType * stype)) MEM_freeN; + st->input_link_limit = 1; + st->output_link_limit = 0xFFF; /* if RNA type is already registered, unregister first */ if (st->ext_interface.srna) { @@ -3581,6 +3730,24 @@ static void rna_ShaderNode_socket_update(Main *bmain, Scene *scene, PointerRNA * rna_Node_update(bmain, scene, ptr); } +static void rna_SimulationNode_socket_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + bNodeTree *ntree = (bNodeTree *)ptr->owner_id; + bNode *node = (bNode *)ptr->data; + + nodeUpdate(ntree, node); + rna_Node_update(bmain, scene, ptr); +} + +static void rna_FunctionNode_socket_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + bNodeTree *ntree = (bNodeTree *)ptr->owner_id; + bNode *node = (bNode *)ptr->data; + + nodeUpdate(ntree, node); + rna_Node_update(bmain, scene, ptr); +} + static void rna_CompositorNodeScale_update(Main *bmain, Scene *scene, PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->owner_id; @@ -4024,7 +4191,40 @@ static void def_vector_math(StructRNA *srna) RNA_def_property_enum_sdna(prop, NULL, "custom1"); RNA_def_property_enum_items(prop, rna_enum_node_vec_math_items); RNA_def_property_ui_text(prop, "Operation", ""); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_FunctionNode_socket_update"); +} + +static void def_boolean_math(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, rna_enum_node_boolean_math_items); + RNA_def_property_ui_text(prop, "Operation", ""); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_FunctionNode_socket_update"); +} + +static void def_float_compare(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, rna_enum_node_float_compare_items); + RNA_def_property_ui_text(prop, "Operation", ""); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_FunctionNode_socket_update"); +} + +static void def_fn_switch(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, node_socket_data_type_items); + RNA_def_property_ui_text(prop, "Data Type", "Data type for inputs and outputs"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_FunctionNode_socket_update"); } static void def_rgb_curve(StructRNA *srna) @@ -7899,6 +8099,61 @@ static void def_tex_bricks(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } +/* -- Simulation Nodes --------------------------------------------------------- */ + +static void def_sim_particle_time_step_event(StructRNA *srna) +{ + static const EnumPropertyItem mode_items[] = { + {NODE_PARTICLE_TIME_STEP_EVENT_BEGIN, + "BEGIN", + 0, + "Begin", + "Execute for every particle at the beginning of each time step"}, + {NODE_PARTICLE_TIME_STEP_EVENT_END, + "END", + 0, + "End", + "Execute for every particle at the end of each time step"}, + {0, NULL, 0, NULL, NULL}, + }; + + 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, mode_items); + RNA_def_property_ui_text(prop, "Mode", "When in each time step is the event triggered"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); +} + +static void def_sim_particle_attribute(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, node_socket_particle_attribute_type_items); + RNA_def_property_ui_text( + prop, + "Data Type", + "Expected type of the attribute. A default value is returned if the type is not correct"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_SimulationNode_socket_update"); +} + +static void def_sim_set_particle_attribute(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, node_socket_particle_attribute_type_items); + RNA_def_property_ui_text( + prop, + "Data Type", + "Expected type of the attribute. Nothing is done if the type is not correct"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_SimulationNode_socket_update"); +} + /* -------------------------------------------------------------------------- */ static void rna_def_shader_node(BlenderRNA *brna) @@ -7936,6 +8191,26 @@ static void rna_def_texture_node(BlenderRNA *brna) RNA_def_struct_register_funcs(srna, "rna_TextureNode_register", "rna_Node_unregister", NULL); } +static void rna_def_simulation_node(BlenderRNA *brna) +{ + StructRNA *srna; + + srna = RNA_def_struct(brna, "SimulationNode", "NodeInternal"); + RNA_def_struct_ui_text(srna, "Simulation Node", ""); + RNA_def_struct_sdna(srna, "bNode"); + RNA_def_struct_register_funcs(srna, "rna_SimulationNode_register", "rna_Node_unregister", NULL); +} + +static void rna_def_function_node(BlenderRNA *brna) +{ + StructRNA *srna; + + srna = RNA_def_struct(brna, "FunctionNode", "NodeInternal"); + RNA_def_struct_ui_text(srna, "Function Node", ""); + RNA_def_struct_sdna(srna, "bNode"); + RNA_def_struct_register_funcs(srna, "rna_FunctionNode_register", "rna_Node_unregister", NULL); +} + /* -------------------------------------------------------------------------- */ static void rna_def_node_socket(BlenderRNA *brna) @@ -8483,6 +8758,121 @@ static void rna_def_node_socket_shader(BlenderRNA *brna, RNA_def_struct_sdna(srna, "bNodeSocket"); } +static void rna_def_node_socket_object(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, "Object Node Socket", "Object socket of a node"); + RNA_def_struct_sdna(srna, "bNodeSocket"); + + RNA_def_struct_sdna_from(srna, "bNodeSocketValueObject", "default_value"); + + prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "object"); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE); + + /* socket interface */ + srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard"); + RNA_def_struct_ui_text(srna, "Object Node Socket Interface", "Object socket of a node"); + RNA_def_struct_sdna(srna, "bNodeSocket"); + + RNA_def_struct_sdna_from(srna, "bNodeSocketValueObject", "default_value"); + + prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "object"); + RNA_def_property_struct_type(prop, "Object"); + 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"); +} + +static void rna_def_node_socket_image(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, "Image Node Socket", "Image socket of a node"); + RNA_def_struct_sdna(srna, "bNodeSocket"); + + RNA_def_struct_sdna_from(srna, "bNodeSocketValueImage", "default_value"); + + prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "image"); + RNA_def_property_struct_type(prop, "Image"); + RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE); + + /* socket interface */ + srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard"); + RNA_def_struct_ui_text(srna, "Image Node Socket Interface", "Image socket of a node"); + RNA_def_struct_sdna(srna, "bNodeSocket"); + + RNA_def_struct_sdna_from(srna, "bNodeSocketValueImage", "default_value"); + + prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "image"); + RNA_def_property_struct_type(prop, "Image"); + 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"); +} + +static void rna_def_node_socket_surface_hook(BlenderRNA *brna, + const char *identifier, + const char *interface_idname) +{ + StructRNA *srna; + + srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); + RNA_def_struct_ui_text(srna, "Surface Hook Node Socket", "Surface Hook socket of a node"); + RNA_def_struct_sdna(srna, "bNodeSocket"); + + /* socket interface */ + srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard"); + RNA_def_struct_ui_text( + srna, "Surface Hook Node Socket Interface", "Surface Hook socket of a node"); + RNA_def_struct_sdna(srna, "bNodeSocket"); +} + +static void rna_def_node_socket_effector(BlenderRNA *brna, + const char *identifier, + const char *interface_idname) +{ + StructRNA *srna; + + srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); + RNA_def_struct_ui_text(srna, "", ""); + RNA_def_struct_sdna(srna, "bNodeSocket"); + + srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard"); + RNA_def_struct_ui_text(srna, "", ""); + RNA_def_struct_sdna(srna, "bNodeSocket"); +} + +static void rna_def_node_socket_control_flow(BlenderRNA *brna, + const char *identifier, + const char *interface_idname) +{ + StructRNA *srna; + + srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); + RNA_def_struct_ui_text(srna, "", ""); + RNA_def_struct_sdna(srna, "bNodeSocket"); + + srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard"); + RNA_def_struct_ui_text(srna, "", ""); + RNA_def_struct_sdna(srna, "bNodeSocket"); +} + static void rna_def_node_socket_virtual(BlenderRNA *brna, const char *identifier) { StructRNA *srna; @@ -8620,10 +9010,19 @@ static void rna_def_node_socket_standard_types(BlenderRNA *brna) brna, "NodeSocketVectorXYZ", "NodeSocketInterfaceVectorXYZ", PROP_XYZ); rna_def_node_socket_color(brna, "NodeSocketColor", "NodeSocketInterfaceColor"); - rna_def_node_socket_string(brna, "NodeSocketString", "NodeSocketInterfaceString"); - rna_def_node_socket_shader(brna, "NodeSocketShader", "NodeSocketInterfaceShader"); + rna_def_node_socket_object(brna, "NodeSocketObject", "NodeSocketInterfaceObject"); + rna_def_node_socket_image(brna, "NodeSocketImage", "NodeSocketInterfaceImage"); + rna_def_node_socket_surface_hook( + brna, "NodeSocketSurfaceHook", "NodeSocketInterfaceSurfaceHook"); + + rna_def_node_socket_effector(brna, "NodeSocketEmitters", "NodeSocketInterfaceEmitters"); + rna_def_node_socket_effector(brna, "NodeSocketEvents", "NodeSocketInterfaceEvents"); + rna_def_node_socket_effector(brna, "NodeSocketForces", "NodeSocketInterfaceForces"); + + rna_def_node_socket_control_flow( + brna, "NodeSocketControlFlow", "NodeSocketInterfaceControlFlow"); rna_def_node_socket_virtual(brna, "NodeSocketVirtual"); } @@ -9571,6 +9970,8 @@ void RNA_def_nodetree(BlenderRNA *brna) rna_def_shader_node(brna); rna_def_compositor_node(brna); rna_def_texture_node(brna); + rna_def_simulation_node(brna); + rna_def_function_node(brna); rna_def_nodetree(brna); @@ -9596,12 +9997,13 @@ void RNA_def_nodetree(BlenderRNA *brna) */ # include "../../nodes/NOD_static_types.h" - /* Node group types need to be defined for shader, compositor, texture nodes individually. - * Cannot use the static types header for this, since they share the same int id. + /* Node group types need to be defined for shader, compositor, texture, simulation nodes + * individually. Cannot use the static types header for this, since they share the same int id. */ define_specific_node(brna, "ShaderNodeGroup", "ShaderNode", "Group", "", def_group); define_specific_node(brna, "CompositorNodeGroup", "CompositorNode", "Group", "", def_group); define_specific_node(brna, "TextureNodeGroup", "TextureNode", "Group", "", def_group); + define_specific_node(brna, "SimulationNodeGroup", "SimulationNode", "Group", "", def_group); def_custom_group(brna, "ShaderNodeCustomGroup", "ShaderNode", diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index a2f825ee454..02b3f52e33d 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -21,8 +21,10 @@ set(INC . composite + function intern shader + simulation texture ../blenkernel ../blenlib @@ -127,6 +129,27 @@ set(SRC composite/node_composite_tree.c composite/node_composite_util.c + function/nodes/node_fn_boolean_math.cc + function/nodes/node_fn_closest_surface.cc + function/nodes/node_fn_combine_hsv.cc + function/nodes/node_fn_combine_rgb.cc + function/nodes/node_fn_combine_xyz.cc + function/nodes/node_fn_float_compare.cc + function/nodes/node_fn_float_math.cc + function/nodes/node_fn_instance_identifier.cc + function/nodes/node_fn_object_transforms.cc + function/nodes/node_fn_separate_hsv.cc + function/nodes/node_fn_separate_rgb.cc + function/nodes/node_fn_separate_xyz.cc + function/nodes/node_fn_string_concatenation.cc + function/nodes/node_fn_surface_color.cc + function/nodes/node_fn_surface_normal.cc + function/nodes/node_fn_surface_position.cc + function/nodes/node_fn_surface_weight.cc + function/nodes/node_fn_switch.cc + function/nodes/node_fn_vector_math.cc + function/node_fn_util.cc + shader/nodes/node_shader_add_shader.c shader/nodes/node_shader_ambient_occlusion.c shader/nodes/node_shader_attribute.c @@ -220,6 +243,22 @@ set(SRC shader/node_shader_tree.c shader/node_shader_util.c + simulation/nodes/node_sim_common.cc + simulation/nodes/node_sim_emit_particles.cc + simulation/nodes/node_sim_execute_condition.cc + simulation/nodes/node_sim_force.cc + simulation/nodes/node_sim_multi_execute.cc + simulation/nodes/node_sim_particle_attribute.cc + simulation/nodes/node_sim_particle_birth_event.cc + simulation/nodes/node_sim_particle_mesh_collision_event.cc + simulation/nodes/node_sim_particle_mesh_emitter.cc + simulation/nodes/node_sim_particle_simulation.cc + simulation/nodes/node_sim_particle_time_step_event.cc + simulation/nodes/node_sim_set_particle_attribute.cc + simulation/nodes/node_sim_simulation_time.cc + simulation/node_sim_tree.cc + simulation/node_sim_util.cc + texture/nodes/node_texture_at.c texture/nodes/node_texture_bricks.c texture/nodes/node_texture_checker.c @@ -252,12 +291,14 @@ set(SRC intern/node_util.c composite/node_composite_util.h + function/node_fn_util.h shader/node_shader_util.h texture/node_texture_util.h NOD_common.h NOD_composite.h NOD_shader.h + NOD_simulation.h NOD_socket.h NOD_static_types.h NOD_texture.h diff --git a/source/blender/nodes/NOD_common.h b/source/blender/nodes/NOD_common.h index 26c78eab4ec..dcc4f4d0b76 100644 --- a/source/blender/nodes/NOD_common.h +++ b/source/blender/nodes/NOD_common.h @@ -26,6 +26,10 @@ #include "BKE_node.h" +#ifdef __cplusplus +extern "C" { +#endif + void register_node_type_frame(void); void register_node_type_reroute(void); @@ -42,4 +46,8 @@ struct bNodeSocket *node_group_output_find_socket(struct bNode *node, const char void node_group_input_update(struct bNodeTree *ntree, struct bNode *node); void node_group_output_update(struct bNodeTree *ntree, struct bNode *node); +#ifdef __cplusplus +} +#endif + #endif /* __NOD_COMMON_H__ */ diff --git a/source/blender/nodes/NOD_function.h b/source/blender/nodes/NOD_function.h new file mode 100644 index 00000000000..69e0a3ee6ea --- /dev/null +++ b/source/blender/nodes/NOD_function.h @@ -0,0 +1,32 @@ +#ifndef __NOD_FUNCTION_H__ +#define __NOD_FUNCTION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void register_node_type_fn_combine_xyz(void); +void register_node_type_fn_separate_xyz(void); +void register_node_type_fn_combine_rgb(void); +void register_node_type_fn_separate_rgb(void); +void register_node_type_fn_combine_hsv(void); +void register_node_type_fn_separate_hsv(void); +void register_node_type_fn_float_math(void); +void register_node_type_fn_vector_math(void); +void register_node_type_fn_closest_surface(void); +void register_node_type_fn_surface_color(void); +void register_node_type_fn_surface_normal(void); +void register_node_type_fn_surface_position(void); +void register_node_type_fn_surface_weight(void); +void register_node_type_fn_boolean_math(void); +void register_node_type_fn_float_compare(void); +void register_node_type_fn_instance_identifier(void); +void register_node_type_fn_string_concatenation(void); +void register_node_type_fn_object_transforms(void); +void register_node_type_fn_switch(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __NOD_FUNCTION_H__ */ diff --git a/source/blender/nodes/NOD_simulation.h b/source/blender/nodes/NOD_simulation.h new file mode 100644 index 00000000000..2639a115a83 --- /dev/null +++ b/source/blender/nodes/NOD_simulation.h @@ -0,0 +1,31 @@ +#ifndef __NOD_SIMULATION_H__ +#define __NOD_SIMULATION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct bNodeTreeType *ntreeType_Simulation; + +void register_node_tree_type_sim(void); + +void register_node_type_sim_group(void); + +void register_node_type_sim_particle_simulation(void); +void register_node_type_sim_force(void); +void register_node_type_sim_set_particle_attribute(void); +void register_node_type_sim_particle_birth_event(void); +void register_node_type_sim_particle_time_step_event(void); +void register_node_type_sim_execute_condition(void); +void register_node_type_sim_multi_execute(void); +void register_node_type_sim_particle_mesh_emitter(void); +void register_node_type_sim_particle_mesh_collision_event(void); +void register_node_type_sim_emit_particles(void); +void register_node_type_sim_simulation_time(void); +void register_node_type_sim_particle_attribute(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __NOD_SIMULATION_H__ */ diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 7fec3324aab..faf0fe4aa3c 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -258,7 +258,40 @@ DefNode(TextureNode, TEX_NODE_PROC+TEX_NOISE, 0, "TEX_NO DefNode(TextureNode, TEX_NODE_PROC+TEX_STUCCI, 0, "TEX_STUCCI", TexStucci, "Stucci", "" ) DefNode(TextureNode, TEX_NODE_PROC+TEX_DISTNOISE, 0, "TEX_DISTNOISE", TexDistNoise, "Distorted Noise", "" ) +DefNode(SimulationNode, SIM_NODE_PARTICLE_SIMULATION, 0, "PARTICLE_SIMULATION", ParticleSimulation, "Particle Simulation", "") +DefNode(SimulationNode, SIM_NODE_FORCE, 0, "FORCE", Force, "Force", "") +DefNode(SimulationNode, SIM_NODE_SET_PARTICLE_ATTRIBUTE, def_sim_set_particle_attribute, "SET_PARTICLE_ATTRIBUTE", SetParticleAttribute, "Set Particle Attribute", "") +DefNode(SimulationNode, SIM_NODE_PARTICLE_BIRTH_EVENT, 0, "PARTICLE_BIRTH_EVENT", ParticleBirthEvent, "Particle Birth Event", "") +DefNode(SimulationNode, SIM_NODE_PARTICLE_TIME_STEP_EVENT, def_sim_particle_time_step_event, "PARTICLE_TIME_STEP_EVENT", ParticleTimeStepEvent, "Particle Time Step Event", "") +DefNode(SimulationNode, SIM_NODE_EXECUTE_CONDITION, 0, "EXECUTE_CONDITION", ExecuteCondition, "Execute Condition", "") +DefNode(SimulationNode, SIM_NODE_MULTI_EXECUTE, 0, "MULTI_EXECUTE", MultiExecute, "Multi Execute", "") +DefNode(SimulationNode, SIM_NODE_PARTICLE_MESH_EMITTER, 0, "PARTICLE_MESH_EMITTER", ParticleMeshEmitter, "Particle Mesh Emitter", "") +DefNode(SimulationNode, SIM_NODE_PARTICLE_MESH_COLLISION_EVENT, 0, "PARTICLE_MESH_COLLISION_EVENT", ParticleMeshCollisionEvent, "Particle Mesh Collision Event", "") +DefNode(SimulationNode, SIM_NODE_EMIT_PARTICLES, 0, "EMIT_PARTICLES", EmitParticles, "Emit Particles", "") +DefNode(SimulationNode, SIM_NODE_SIMULATION_TIME, 0, "SIMULATION_TIME", SimulationTime, "Simulation Time", "") +DefNode(SimulationNode, SIM_NODE_PARTICLE_ATTRIBUTE, def_sim_particle_attribute, "PARTICLE_ATTRIBUTE", ParticleAttribute, "Particle Attribute", "") + +DefNode(FunctionNode, FN_NODE_COMBINE_XYZ, 0, "COMBINE_XYZ", CombineXYZ, "Combine XYZ", "") +DefNode(FunctionNode, FN_NODE_SEPARATE_XYZ, 0, "SEPARATE_XYZ", SeparateXYZ, "Separate XYZ", "") +DefNode(FunctionNode, FN_NODE_COMBINE_RGB, 0, "COMBINE_RGB", CombineRGB, "Combine RGB", "") +DefNode(FunctionNode, FN_NODE_SEPARATE_RGB, 0, "SEPARATE_RGB", SeparateRGB, "Separate RGB", "") +DefNode(FunctionNode, FN_NODE_COMBINE_HSV, 0, "COMBINE_HSV", CombineHSV, "Combine HSV", "") +DefNode(FunctionNode, FN_NODE_SEPARATE_HSV, 0, "SEPARATE_HSV", SeparateHSV, "Separate HSV", "") +DefNode(FunctionNode, FN_NODE_FLOAT_MATH, def_math, "FLOAT_MATH", FloatMath, "Float Math", ""); +DefNode(FunctionNode, FN_NODE_VECTOR_MATH, def_vector_math, "VECTOR_MATH", VectorMath, "Vector Math", "") +DefNode(FunctionNode, FN_NODE_CLOSEST_SURFACE, 0, "CLOSEST_SURFACE", ClosestSurface, "Closest Surface", "") +DefNode(FunctionNode, FN_NODE_SURFACE_COLOR, 0, "SURFACE_COLOR", SurfaceColor, "Surface Color", "") +DefNode(FunctionNode, FN_NODE_SURFACE_NORMAL, 0, "SURFACE_NORMAL", SurfaceNormal, "Surface Normal", "") +DefNode(FunctionNode, FN_NODE_SURFACE_POSITION, 0, "SURFACE_POSITION", SurfacePosition, "Surface Position", "") +DefNode(FunctionNode, FN_NODE_SURFACE_WEIGHT, 0, "SURFACE_WEIGHT", SurfaceWeight, "Surface Weight", "") +DefNode(FunctionNode, FN_NODE_BOOLEAN_MATH, def_boolean_math, "BOOLEAN_MATH", BooleanMath, "Boolean Math", ""); +DefNode(FunctionNode, FN_NODE_FLOAT_COMPARE, def_float_compare, "FLOAT_COMPARE", FloatCompare, "Float Compare", ""); +DefNode(FunctionNode, FN_NODE_INSTANCE_IDENTIFIER, 0, "INSTANCE_IDENTIFIER", InstanceIdentifier, "Instance Identifier", ""); +DefNode(FunctionNode, FN_NODE_STRING_CONCATENATION, 0, "STRING_CONCATENATION", StringConcatenation, "String Concatenation", ""); +DefNode(FunctionNode, FN_NODE_OBJECT_TRANSFORMS, 0, "OBJECT_TRANSFORMS", ObjectTransforms, "Object Transforms", ""); +DefNode(FunctionNode, FN_NODE_SWITCH, def_fn_switch, "SWITCH", Switch, "Switch", ""); + /* undefine macros */ #undef DefNode - /* clang-format on */ +/* clang-format on */ diff --git a/source/blender/nodes/function/node_fn_util.cc b/source/blender/nodes/function/node_fn_util.cc new file mode 100644 index 00000000000..08ea41c2612 --- /dev/null +++ b/source/blender/nodes/function/node_fn_util.cc @@ -0,0 +1,14 @@ +#include "node_fn_util.h" +#include "node_util.h" + +bool fn_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree) +{ + /* Function nodes are only supported in simulation node trees so far. */ + return STREQ(ntree->idname, "SimulationNodeTree"); +} + +void fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag) +{ + node_type_base(ntype, type, name, nclass, flag); + ntype->poll = fn_node_poll_default; +} diff --git a/source/blender/nodes/function/node_fn_util.h b/source/blender/nodes/function/node_fn_util.h new file mode 100644 index 00000000000..8835273316c --- /dev/null +++ b/source/blender/nodes/function/node_fn_util.h @@ -0,0 +1,24 @@ +#ifndef __NODE_FN_UTIL_H__ +#define __NODE_FN_UTIL_H__ + +#include <string.h> + +#include "BLI_utildefines.h" + +#include "MEM_guardedalloc.h" + +#include "DNA_node_types.h" + +#include "BKE_node.h" + +#include "BLT_translation.h" + +#include "NOD_function.h" + +#include "node_util.h" + +void fn_node_type_base( + struct bNodeType *ntype, int type, const char *name, short nclass, short flag); +bool fn_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree); + +#endif /* __NODE_FN_UTIL_H__ */ diff --git a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc new file mode 100644 index 00000000000..f63141b6164 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc @@ -0,0 +1,23 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_boolean_math_in[] = { + {SOCK_BOOLEAN, N_("Boolean")}, + {SOCK_BOOLEAN, N_("Boolean")}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_boolean_math_out[] = { + {SOCK_BOOLEAN, N_("Boolean")}, + {-1, ""}, +}; + +void register_node_type_fn_boolean_math() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_BOOLEAN_MATH, "Boolean Math", 0, 0); + node_type_socket_templates(&ntype, fn_node_boolean_math_in, fn_node_boolean_math_out); + node_type_label(&ntype, node_boolean_math_label); + node_type_update(&ntype, node_boolean_math_update); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_closest_surface.cc b/source/blender/nodes/function/nodes/node_fn_closest_surface.cc new file mode 100644 index 00000000000..09e12baa1c4 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_closest_surface.cc @@ -0,0 +1,23 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_closest_surface_in[] = { + {SOCK_OBJECT, N_("Object")}, + {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_closest_surface_out[] = { + {SOCK_SURFACE_HOOK, N_("Closest Hook")}, + {SOCK_VECTOR, N_("Closest Position")}, + {SOCK_VECTOR, N_("Closest Normal")}, + {-1, ""}, +}; + +void register_node_type_fn_closest_surface() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_CLOSEST_SURFACE, "Closest Surface", 0, 0); + node_type_socket_templates(&ntype, fn_node_closest_surface_in, fn_node_closest_surface_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_combine_hsv.cc b/source/blender/nodes/function/nodes/node_fn_combine_hsv.cc new file mode 100644 index 00000000000..b564373f78e --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_combine_hsv.cc @@ -0,0 +1,22 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_combine_hsv_in[] = { + {SOCK_FLOAT, N_("H"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {SOCK_FLOAT, N_("S"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {SOCK_FLOAT, N_("V"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_combine_hsv_out[] = { + {SOCK_RGBA, N_("Color")}, + {-1, ""}, +}; + +void register_node_type_fn_combine_hsv() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_COMBINE_HSV, "Combine HSV", 0, 0); + node_type_socket_templates(&ntype, fn_node_combine_hsv_in, fn_node_combine_hsv_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_combine_rgb.cc b/source/blender/nodes/function/nodes/node_fn_combine_rgb.cc new file mode 100644 index 00000000000..6c9a4462761 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_combine_rgb.cc @@ -0,0 +1,22 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_combine_rgb_in[] = { + {SOCK_FLOAT, N_("R"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {SOCK_FLOAT, N_("G"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {SOCK_FLOAT, N_("B"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_combine_rgb_out[] = { + {SOCK_RGBA, N_("Color")}, + {-1, ""}, +}; + +void register_node_type_fn_combine_rgb() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_COMBINE_RGB, "Combine RGB", 0, 0); + node_type_socket_templates(&ntype, fn_node_combine_rgb_in, fn_node_combine_rgb_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_combine_xyz.cc b/source/blender/nodes/function/nodes/node_fn_combine_xyz.cc new file mode 100644 index 00000000000..42b7481ccf5 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_combine_xyz.cc @@ -0,0 +1,22 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_combine_xyz_in[] = { + {SOCK_FLOAT, N_("X"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {SOCK_FLOAT, N_("Y"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {SOCK_FLOAT, N_("Z"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_combine_xyz_out[] = { + {SOCK_VECTOR, N_("Vector")}, + {-1, ""}, +}; + +void register_node_type_fn_combine_xyz() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_COMBINE_XYZ, "Combine XYZ", 0, 0); + node_type_socket_templates(&ntype, fn_node_combine_xyz_in, fn_node_combine_xyz_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_float_compare.cc b/source/blender/nodes/function/nodes/node_fn_float_compare.cc new file mode 100644 index 00000000000..260979bf27b --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_float_compare.cc @@ -0,0 +1,24 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_float_compare_in[] = { + {SOCK_FLOAT, N_("A"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {SOCK_FLOAT, N_("B"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {SOCK_FLOAT, N_("Epsilon"), 0.001f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_float_compare_out[] = { + {SOCK_BOOLEAN, N_("Result")}, + {-1, ""}, +}; + +void register_node_type_fn_float_compare() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_FLOAT_COMPARE, "Boolean Math", 0, 0); + node_type_socket_templates(&ntype, fn_node_float_compare_in, fn_node_float_compare_out); + node_type_label(&ntype, node_float_compare_label); + node_type_update(&ntype, node_float_compare_update); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_float_math.cc b/source/blender/nodes/function/nodes/node_fn_float_math.cc new file mode 100644 index 00000000000..0769b560c2a --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_float_math.cc @@ -0,0 +1,24 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_float_math_in[] = { + {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, + {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, + {SOCK_FLOAT, N_("Value"), 0.0f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_float_math_out[] = { + {SOCK_FLOAT, N_("Value")}, + {-1, ""}, +}; + +void register_node_type_fn_float_math() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_FLOAT_MATH, "Float Math", 0, 0); + node_type_socket_templates(&ntype, fn_node_float_math_in, fn_node_float_math_out); + node_type_label(&ntype, node_math_label); + node_type_update(&ntype, node_math_update); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_instance_identifier.cc b/source/blender/nodes/function/nodes/node_fn_instance_identifier.cc new file mode 100644 index 00000000000..07ce92a748b --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_instance_identifier.cc @@ -0,0 +1,15 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_instance_identifier_out[] = { + {SOCK_STRING, N_("Identifier")}, + {-1, ""}, +}; + +void register_node_type_fn_instance_identifier() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_INSTANCE_IDENTIFIER, "Instance Identifier", 0, 0); + node_type_socket_templates(&ntype, nullptr, fn_node_instance_identifier_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_object_transforms.cc b/source/blender/nodes/function/nodes/node_fn_object_transforms.cc new file mode 100644 index 00000000000..14dc636f9e8 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_object_transforms.cc @@ -0,0 +1,20 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_object_transforms_in[] = { + {SOCK_OBJECT, N_("Object")}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_object_transforms_out[] = { + {SOCK_VECTOR, N_("Location")}, + {-1, ""}, +}; + +void register_node_type_fn_object_transforms() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_OBJECT_TRANSFORMS, "Object Transforms", 0, 0); + node_type_socket_templates(&ntype, fn_node_object_transforms_in, fn_node_object_transforms_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_separate_hsv.cc b/source/blender/nodes/function/nodes/node_fn_separate_hsv.cc new file mode 100644 index 00000000000..0e6bbda50d7 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_separate_hsv.cc @@ -0,0 +1,22 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_separate_hsv_in[] = { + {SOCK_RGBA, N_("Color")}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_separate_hsv_out[] = { + {SOCK_FLOAT, N_("H")}, + {SOCK_FLOAT, N_("S")}, + {SOCK_FLOAT, N_("V")}, + {-1, ""}, +}; + +void register_node_type_fn_separate_hsv() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_SEPARATE_HSV, "Separate HSV", 0, 0); + node_type_socket_templates(&ntype, fn_node_separate_hsv_in, fn_node_separate_hsv_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_separate_rgb.cc b/source/blender/nodes/function/nodes/node_fn_separate_rgb.cc new file mode 100644 index 00000000000..704b7a46958 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_separate_rgb.cc @@ -0,0 +1,22 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_separate_rgb_in[] = { + {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_separate_rgb_out[] = { + {SOCK_FLOAT, N_("R")}, + {SOCK_FLOAT, N_("G")}, + {SOCK_FLOAT, N_("B")}, + {-1, ""}, +}; + +void register_node_type_fn_separate_rgb() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_SEPARATE_RGB, "Separate RGB", 0, 0); + node_type_socket_templates(&ntype, fn_node_separate_rgb_in, fn_node_separate_rgb_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_separate_xyz.cc b/source/blender/nodes/function/nodes/node_fn_separate_xyz.cc new file mode 100644 index 00000000000..b0f1c2e09f4 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_separate_xyz.cc @@ -0,0 +1,22 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_separate_xyz_in[] = { + {SOCK_VECTOR, N_("Vector")}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_separate_xyz_out[] = { + {SOCK_FLOAT, N_("X")}, + {SOCK_FLOAT, N_("Y")}, + {SOCK_FLOAT, N_("Z")}, + {-1, ""}, +}; + +void register_node_type_fn_separate_xyz() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_SEPARATE_XYZ, "Separate XYZ", 0, 0); + node_type_socket_templates(&ntype, fn_node_separate_xyz_in, fn_node_separate_xyz_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_string_concatenation.cc b/source/blender/nodes/function/nodes/node_fn_string_concatenation.cc new file mode 100644 index 00000000000..9325e897b59 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_string_concatenation.cc @@ -0,0 +1,22 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_string_concatenation_in[] = { + {SOCK_STRING, N_("A")}, + {SOCK_STRING, N_("B")}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_string_concatenation_out[] = { + {SOCK_STRING, N_("Result")}, + {-1, ""}, +}; + +void register_node_type_fn_string_concatenation() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_STRING_CONCATENATION, "String Concatenation", 0, 0); + node_type_socket_templates( + &ntype, fn_node_string_concatenation_in, fn_node_string_concatenation_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_surface_color.cc b/source/blender/nodes/function/nodes/node_fn_surface_color.cc new file mode 100644 index 00000000000..4ce59c2caf9 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_surface_color.cc @@ -0,0 +1,22 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_surface_color_in[] = { + {SOCK_SURFACE_HOOK, N_("Surface Hook")}, + {SOCK_IMAGE, N_("Image")}, + {SOCK_STRING, N_("UV Map")}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_surface_color_out[] = { + {SOCK_RGBA, N_("Color")}, + {-1, ""}, +}; + +void register_node_type_fn_surface_color() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_SURFACE_COLOR, "Surface Color", 0, 0); + node_type_socket_templates(&ntype, fn_node_surface_color_in, fn_node_surface_color_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_surface_normal.cc b/source/blender/nodes/function/nodes/node_fn_surface_normal.cc new file mode 100644 index 00000000000..c5592a3c155 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_surface_normal.cc @@ -0,0 +1,20 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_surface_normal_in[] = { + {SOCK_SURFACE_HOOK, N_("Surface Hook")}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_surface_normal_out[] = { + {SOCK_VECTOR, N_("Normal")}, + {-1, ""}, +}; + +void register_node_type_fn_surface_normal() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_SURFACE_NORMAL, "Surface Normal", 0, 0); + node_type_socket_templates(&ntype, fn_node_surface_normal_in, fn_node_surface_normal_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_surface_position.cc b/source/blender/nodes/function/nodes/node_fn_surface_position.cc new file mode 100644 index 00000000000..c92e7682dc6 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_surface_position.cc @@ -0,0 +1,20 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_surface_position_in[] = { + {SOCK_SURFACE_HOOK, N_("Surface Hook")}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_surface_position_out[] = { + {SOCK_VECTOR, N_("Position")}, + {-1, ""}, +}; + +void register_node_type_fn_surface_position() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_SURFACE_POSITION, "Surface Position", 0, 0); + node_type_socket_templates(&ntype, fn_node_surface_position_in, fn_node_surface_position_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_surface_weight.cc b/source/blender/nodes/function/nodes/node_fn_surface_weight.cc new file mode 100644 index 00000000000..e3d40ff83d4 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_surface_weight.cc @@ -0,0 +1,21 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_surface_weight_in[] = { + {SOCK_SURFACE_HOOK, N_("Surface Hook")}, + {SOCK_STRING, N_("Group")}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_surface_weight_out[] = { + {SOCK_FLOAT, N_("Weight")}, + {-1, ""}, +}; + +void register_node_type_fn_surface_weight() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_SURFACE_WEIGHT, "Surface Position", 0, 0); + node_type_socket_templates(&ntype, fn_node_surface_weight_in, fn_node_surface_weight_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_switch.cc b/source/blender/nodes/function/nodes/node_fn_switch.cc new file mode 100644 index 00000000000..f0a49a1ed50 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_switch.cc @@ -0,0 +1,63 @@ +#include "BLI_listbase.h" +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_switch_in[] = { + {SOCK_BOOLEAN, N_("Switch")}, + + {SOCK_FLOAT, N_("If False"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {SOCK_INT, N_("If False"), 0, 0, 0, 0, -10000, 10000}, + {SOCK_BOOLEAN, N_("If False")}, + {SOCK_VECTOR, N_("If False"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {SOCK_STRING, N_("If False")}, + {SOCK_RGBA, N_("If False"), 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_OBJECT, N_("If False")}, + {SOCK_IMAGE, N_("If False")}, + {SOCK_SURFACE_HOOK, N_("If False")}, + + {SOCK_FLOAT, N_("If True"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {SOCK_INT, N_("If True"), 0, 0, 0, 0, -10000, 10000}, + {SOCK_BOOLEAN, N_("If True")}, + {SOCK_VECTOR, N_("If True"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {SOCK_STRING, N_("If True")}, + {SOCK_RGBA, N_("If True"), 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_OBJECT, N_("If True")}, + {SOCK_IMAGE, N_("If True")}, + {SOCK_SURFACE_HOOK, N_("If True")}, + + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_switch_out[] = { + {SOCK_FLOAT, N_("Result")}, + {SOCK_INT, N_("Result")}, + {SOCK_BOOLEAN, N_("Result")}, + {SOCK_VECTOR, N_("Result")}, + {SOCK_STRING, N_("Result")}, + {SOCK_RGBA, N_("Result")}, + {SOCK_OBJECT, N_("Result")}, + {SOCK_IMAGE, N_("Result")}, + {SOCK_SURFACE_HOOK, N_("Result")}, + {-1, ""}, +}; + +static void fn_node_switch_update(bNodeTree *UNUSED(ntree), bNode *node) +{ + int index = 0; + LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { + nodeSetSocketAvailability(sock, index == 0 || sock->type == node->custom1); + index++; + } + LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { + nodeSetSocketAvailability(sock, sock->type == node->custom1); + } +} + +void register_node_type_fn_switch() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_SWITCH, "Switch", 0, 0); + node_type_socket_templates(&ntype, fn_node_switch_in, fn_node_switch_out); + node_type_update(&ntype, fn_node_switch_update); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/nodes/node_fn_vector_math.cc b/source/blender/nodes/function/nodes/node_fn_vector_math.cc new file mode 100644 index 00000000000..a773a3ce788 --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_vector_math.cc @@ -0,0 +1,26 @@ +#include "node_fn_util.h" + +static bNodeSocketTemplate fn_node_vector_math_in[] = { + {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, + {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, + {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, + {SOCK_FLOAT, N_("Scale"), 1.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_vector_math_out[] = { + {SOCK_VECTOR, N_("Vector")}, + {SOCK_FLOAT, N_("Value")}, + {-1, ""}, +}; + +void register_node_type_fn_vector_math() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_VECTOR_MATH, "Vector Math", 0, 0); + node_type_socket_templates(&ntype, fn_node_vector_math_in, fn_node_vector_math_out); + node_type_label(&ntype, node_vector_math_label); + node_type_update(&ntype, node_vector_math_update); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/intern/node_common.h b/source/blender/nodes/intern/node_common.h index c3314ae3c28..7810e9f1f14 100644 --- a/source/blender/nodes/intern/node_common.h +++ b/source/blender/nodes/intern/node_common.h @@ -26,6 +26,10 @@ #include "DNA_listBase.h" +#ifdef __cplusplus +extern "C" { +#endif + struct bNodeTree; void node_group_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); @@ -33,4 +37,8 @@ bool node_group_poll_instance(struct bNode *node, struct bNodeTree *nodetree); void ntree_update_reroute_nodes(struct bNodeTree *ntree); +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c index 199b469781d..a93fd6ea44a 100644 --- a/source/blender/nodes/intern/node_socket.c +++ b/source/blender/nodes/intern/node_socket.c @@ -259,6 +259,22 @@ void node_socket_init_default_value(bNodeSocket *sock) sock->default_value = dval; break; } + case SOCK_OBJECT: { + bNodeSocketValueObject *dval = MEM_callocN(sizeof(bNodeSocketValueObject), + "node socket value object"); + dval->object = NULL; + + sock->default_value = dval; + break; + } + case SOCK_IMAGE: { + bNodeSocketValueImage *dval = MEM_callocN(sizeof(bNodeSocketValueImage), + "node socket value image"); + dval->image = NULL; + + sock->default_value = dval; + break; + } } } @@ -317,6 +333,18 @@ void node_socket_copy_default_value(bNodeSocket *to, const bNodeSocket *from) *toval = *fromval; break; } + case SOCK_OBJECT: { + /* Not sure how to handle user count here yet. For now just don't copy the pointer. */ + bNodeSocketValueObject *toval = to->default_value; + toval->object = NULL; + break; + } + case SOCK_IMAGE: { + /* Not sure how to handle user count here yet. For now just don't copy the pointer. */ + bNodeSocketValueImage *toval = to->default_value; + toval->image = NULL; + break; + } } to->flag |= (from->flag & SOCK_HIDE_VALUE); @@ -436,6 +464,21 @@ static bNodeSocketType *make_standard_socket_type(int type, int subtype) return stype; } +static bNodeSocketType *make_socket_type_effector(int type) +{ + bNodeSocketType *stype = make_standard_socket_type(type, PROP_NONE); + stype->display_shape_default = SOCK_DISPLAY_SHAPE_DIAMOND; + stype->input_link_limit = 0xFFF; + return stype; +} + +static bNodeSocketType *make_socket_type_control_flow(int type) +{ + bNodeSocketType *stype = make_standard_socket_type(type, PROP_NONE); + stype->display_shape_default = SOCK_DISPLAY_SHAPE_SQUARE; + return stype; +} + static bNodeSocketType *make_socket_type_virtual(void) { extern void ED_init_node_socket_type_virtual(bNodeSocketType *); @@ -494,10 +537,17 @@ void register_standard_node_socket_types(void) nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_XYZ)); nodeRegisterSocketType(make_standard_socket_type(SOCK_RGBA, PROP_NONE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_STRING, PROP_NONE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_SHADER, PROP_NONE)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_OBJECT, PROP_NONE)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_IMAGE, PROP_NONE)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_SURFACE_HOOK, PROP_NONE)); + + nodeRegisterSocketType(make_socket_type_effector(SOCK_EMITTERS)); + nodeRegisterSocketType(make_socket_type_effector(SOCK_EVENTS)); + nodeRegisterSocketType(make_socket_type_effector(SOCK_FORCES)); + + nodeRegisterSocketType(make_socket_type_control_flow(SOCK_CONTROL_FLOW)); nodeRegisterSocketType(make_socket_type_virtual()); } diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c index 9efbdc079e6..61c29589dd7 100644 --- a/source/blender/nodes/intern/node_util.c +++ b/source/blender/nodes/intern/node_util.c @@ -173,6 +173,74 @@ void node_math_update(bNodeTree *UNUSED(ntree), bNode *node) } } +void node_vector_math_update(bNodeTree *UNUSED(ntree), bNode *node) +{ + bNodeSocket *sockB = BLI_findlink(&node->inputs, 1); + bNodeSocket *sockC = BLI_findlink(&node->inputs, 2); + bNodeSocket *sockScale = nodeFindSocket(node, SOCK_IN, "Scale"); + + bNodeSocket *sockVector = nodeFindSocket(node, SOCK_OUT, "Vector"); + bNodeSocket *sockValue = nodeFindSocket(node, SOCK_OUT, "Value"); + + nodeSetSocketAvailability(sockB, + !ELEM(node->custom1, + NODE_VECTOR_MATH_SINE, + NODE_VECTOR_MATH_COSINE, + NODE_VECTOR_MATH_TANGENT, + NODE_VECTOR_MATH_CEIL, + NODE_VECTOR_MATH_SCALE, + NODE_VECTOR_MATH_FLOOR, + NODE_VECTOR_MATH_LENGTH, + NODE_VECTOR_MATH_ABSOLUTE, + NODE_VECTOR_MATH_FRACTION, + NODE_VECTOR_MATH_NORMALIZE)); + nodeSetSocketAvailability(sockC, ELEM(node->custom1, NODE_VECTOR_MATH_WRAP)); + nodeSetSocketAvailability(sockScale, node->custom1 == NODE_VECTOR_MATH_SCALE); + nodeSetSocketAvailability(sockVector, + !ELEM(node->custom1, + NODE_VECTOR_MATH_LENGTH, + NODE_VECTOR_MATH_DISTANCE, + NODE_VECTOR_MATH_DOT_PRODUCT)); + nodeSetSocketAvailability(sockValue, + ELEM(node->custom1, + NODE_VECTOR_MATH_LENGTH, + NODE_VECTOR_MATH_DISTANCE, + NODE_VECTOR_MATH_DOT_PRODUCT)); + + /* Labels */ + if (sockB->label[0] != '\0') { + sockB->label[0] = '\0'; + } + if (sockC->label[0] != '\0') { + sockC->label[0] = '\0'; + } + switch (node->custom1) { + case NODE_VECTOR_MATH_WRAP: + node_sock_label(sockB, "Max"); + node_sock_label(sockC, "Min"); + break; + case NODE_VECTOR_MATH_SNAP: + node_sock_label(sockB, "Increment"); + break; + } +} + +void node_boolean_math_update(bNodeTree *UNUSED(ntree), bNode *node) +{ + bNodeSocket *sockB = BLI_findlink(&node->inputs, 1); + + nodeSetSocketAvailability(sockB, + ELEM(node->custom1, NODE_BOOLEAN_MATH_AND, NODE_BOOLEAN_MATH_OR)); +} + +void node_float_compare_update(bNodeTree *UNUSED(ntree), bNode *node) +{ + bNodeSocket *sockEpsilon = BLI_findlink(&node->inputs, 2); + + nodeSetSocketAvailability( + sockEpsilon, ELEM(node->custom1, NODE_FLOAT_COMPARE_EQUAL, NODE_FLOAT_COMPARE_NOT_EQUAL)); +} + /**** Labels ****/ void node_blend_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) @@ -222,6 +290,26 @@ void node_filter_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int m BLI_strncpy(label, IFACE_(name), maxlen); } +void node_boolean_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) +{ + const char *name; + bool enum_label = RNA_enum_name(rna_enum_node_boolean_math_items, node->custom1, &name); + if (!enum_label) { + name = "Unknown"; + } + BLI_strncpy(label, IFACE_(name), maxlen); +} + +void node_float_compare_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) +{ + const char *name; + bool enum_label = RNA_enum_name(rna_enum_node_float_compare_items, node->custom1, &name); + if (!enum_label) { + name = "Unknown"; + } + BLI_strncpy(label, IFACE_(name), maxlen); +} + /*** Link Insertion ***/ /* test if two sockets are interchangeable */ diff --git a/source/blender/nodes/intern/node_util.h b/source/blender/nodes/intern/node_util.h index a7f09d24a70..a362115b982 100644 --- a/source/blender/nodes/intern/node_util.h +++ b/source/blender/nodes/intern/node_util.h @@ -38,6 +38,10 @@ #include "RNA_access.h" +#ifdef __cplusplus +extern "C" { +#endif + struct bNode; struct bNodeTree; @@ -69,12 +73,20 @@ extern void *node_initexec_curves(struct bNodeExecContext *context, /**** Updates ****/ void node_sock_label(struct bNodeSocket *sock, const char *name); void node_math_update(struct bNodeTree *ntree, struct bNode *node); +void node_vector_math_update(struct bNodeTree *ntree, struct bNode *node); +void node_boolean_math_update(struct bNodeTree *ntree, struct bNode *node); +void node_float_compare_update(struct bNodeTree *ntree, struct bNode *node); /**** Labels ****/ void node_blend_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); void node_image_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); void node_math_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); void node_vector_math_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); +void node_boolean_math_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); +void node_float_compare_label(struct bNodeTree *ntree, + struct bNode *node, + char *label, + int maxlen); void node_filter_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); /*** Link Handling */ @@ -103,4 +115,8 @@ void node_socket_set_vector(struct bNodeTree *ntree, struct bNodeSocket *sock, const float *value); +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c index 93d03720058..ecd56088e55 100644 --- a/source/blender/nodes/shader/node_shader_util.c +++ b/source/blender/nodes/shader/node_shader_util.c @@ -32,6 +32,11 @@ bool sh_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree) return STREQ(ntree->idname, "ShaderNodeTree"); } +static bool sh_fn_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree) +{ + return STREQ(ntree->idname, "ShaderNodeTree") || STREQ(ntree->idname, "SimulationNodeTree"); +} + void sh_node_type_base( struct bNodeType *ntype, int type, const char *name, short nclass, short flag) { @@ -41,6 +46,11 @@ void sh_node_type_base( ntype->insert_link = node_insert_link_default; ntype->update_internal_links = node_update_internal_links_default; } +void sh_fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag) +{ + sh_node_type_base(ntype, type, name, nclass, flag); + ntype->poll = sh_fn_node_poll_default; +} /* ****** */ diff --git a/source/blender/nodes/shader/node_shader_util.h b/source/blender/nodes/shader/node_shader_util.h index 8d525c8f23c..8834de0633e 100644 --- a/source/blender/nodes/shader/node_shader_util.h +++ b/source/blender/nodes/shader/node_shader_util.h @@ -72,6 +72,8 @@ bool sh_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree); void sh_node_type_base( struct bNodeType *ntype, int type, const char *name, short nclass, short flag); +void sh_fn_node_type_base( + struct bNodeType *ntype, int type, const char *name, short nclass, short flag); /* ********* exec data struct, remains internal *********** */ diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c index 1b802f1dfd7..92b2254c97f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c @@ -169,7 +169,7 @@ void register_node_type_sh_tex_brick(void) { static bNodeType ntype; - sh_node_type_base(&ntype, SH_NODE_TEX_BRICK, "Brick Texture", NODE_CLASS_TEXTURE, 0); + sh_fn_node_type_base(&ntype, SH_NODE_TEX_BRICK, "Brick Texture", NODE_CLASS_TEXTURE, 0); node_type_socket_templates(&ntype, sh_node_tex_brick_in, sh_node_tex_brick_out); node_type_size_preset(&ntype, NODE_SIZE_MIDDLE); node_type_init(&ntype, node_shader_init_tex_brick); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_checker.c b/source/blender/nodes/shader/nodes/node_shader_tex_checker.c index 75219f4c3f9..74585924955 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_checker.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_checker.c @@ -79,7 +79,7 @@ void register_node_type_sh_tex_checker(void) { static bNodeType ntype; - sh_node_type_base(&ntype, SH_NODE_TEX_CHECKER, "Checker Texture", NODE_CLASS_TEXTURE, 0); + sh_fn_node_type_base(&ntype, SH_NODE_TEX_CHECKER, "Checker Texture", NODE_CLASS_TEXTURE, 0); node_type_socket_templates(&ntype, sh_node_tex_checker_in, sh_node_tex_checker_out); node_type_init(&ntype, node_shader_init_tex_checker); node_type_storage( diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.c b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.c index e3d4bad2bf8..c097c18faab 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.c @@ -70,7 +70,7 @@ void register_node_type_sh_tex_gradient(void) { static bNodeType ntype; - sh_node_type_base(&ntype, SH_NODE_TEX_GRADIENT, "Gradient Texture", NODE_CLASS_TEXTURE, 0); + sh_fn_node_type_base(&ntype, SH_NODE_TEX_GRADIENT, "Gradient Texture", NODE_CLASS_TEXTURE, 0); node_type_socket_templates(&ntype, sh_node_tex_gradient_in, sh_node_tex_gradient_out); node_type_init(&ntype, node_shader_init_tex_gradient); node_type_storage( diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_magic.c b/source/blender/nodes/shader/nodes/node_shader_tex_magic.c index 51721f8bb09..f2e977ac49d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_magic.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_magic.c @@ -73,7 +73,7 @@ void register_node_type_sh_tex_magic(void) { static bNodeType ntype; - sh_node_type_base(&ntype, SH_NODE_TEX_MAGIC, "Magic Texture", NODE_CLASS_TEXTURE, 0); + sh_fn_node_type_base(&ntype, SH_NODE_TEX_MAGIC, "Magic Texture", NODE_CLASS_TEXTURE, 0); node_type_socket_templates(&ntype, sh_node_tex_magic_in, sh_node_tex_magic_out); node_type_init(&ntype, node_shader_init_tex_magic); node_type_storage( diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c index fa98f9efb74..0ef3195f2c0 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c @@ -143,7 +143,7 @@ void register_node_type_sh_tex_musgrave(void) { static bNodeType ntype; - sh_node_type_base(&ntype, SH_NODE_TEX_MUSGRAVE, "Musgrave Texture", NODE_CLASS_TEXTURE, 0); + sh_fn_node_type_base(&ntype, SH_NODE_TEX_MUSGRAVE, "Musgrave Texture", NODE_CLASS_TEXTURE, 0); node_type_socket_templates(&ntype, sh_node_tex_musgrave_in, sh_node_tex_musgrave_out); node_type_size_preset(&ntype, NODE_SIZE_MIDDLE); node_type_init(&ntype, node_shader_init_tex_musgrave); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_noise.c b/source/blender/nodes/shader/nodes/node_shader_tex_noise.c index 2205a1a86a3..8915304ad76 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_noise.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_noise.c @@ -90,7 +90,7 @@ void register_node_type_sh_tex_noise(void) { static bNodeType ntype; - sh_node_type_base(&ntype, SH_NODE_TEX_NOISE, "Noise Texture", NODE_CLASS_TEXTURE, 0); + sh_fn_node_type_base(&ntype, SH_NODE_TEX_NOISE, "Noise Texture", NODE_CLASS_TEXTURE, 0); node_type_socket_templates(&ntype, sh_node_tex_noise_in, sh_node_tex_noise_out); node_type_init(&ntype, node_shader_init_tex_noise); node_type_storage( diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c index 64dc44fc67d..869b00c9b52 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c @@ -182,7 +182,7 @@ void register_node_type_sh_tex_voronoi(void) { static bNodeType ntype; - sh_node_type_base(&ntype, SH_NODE_TEX_VORONOI, "Voronoi Texture", NODE_CLASS_TEXTURE, 0); + sh_fn_node_type_base(&ntype, SH_NODE_TEX_VORONOI, "Voronoi Texture", NODE_CLASS_TEXTURE, 0); node_type_socket_templates(&ntype, sh_node_tex_voronoi_in, sh_node_tex_voronoi_out); node_type_init(&ntype, node_shader_init_tex_voronoi); node_type_storage( diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.c b/source/blender/nodes/shader/nodes/node_shader_tex_wave.c index 0b6cd7ee4db..0158307af30 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.c @@ -89,7 +89,7 @@ void register_node_type_sh_tex_wave(void) { static bNodeType ntype; - sh_node_type_base(&ntype, SH_NODE_TEX_WAVE, "Wave Texture", NODE_CLASS_TEXTURE, 0); + sh_fn_node_type_base(&ntype, SH_NODE_TEX_WAVE, "Wave Texture", NODE_CLASS_TEXTURE, 0); node_type_socket_templates(&ntype, sh_node_tex_wave_in, sh_node_tex_wave_out); node_type_size_preset(&ntype, NODE_SIZE_MIDDLE); node_type_init(&ntype, node_shader_init_tex_wave); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c index 1789dc44bf1..817ccdc8b6a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c @@ -72,7 +72,8 @@ void register_node_type_sh_tex_white_noise(void) { static bNodeType ntype; - sh_node_type_base(&ntype, SH_NODE_TEX_WHITE_NOISE, "White Noise Texture", NODE_CLASS_TEXTURE, 0); + sh_fn_node_type_base( + &ntype, SH_NODE_TEX_WHITE_NOISE, "White Noise Texture", NODE_CLASS_TEXTURE, 0); node_type_socket_templates(&ntype, sh_node_tex_white_noise_in, sh_node_tex_white_noise_out); node_type_init(&ntype, node_shader_init_tex_white_noise); node_type_gpu(&ntype, gpu_shader_tex_white_noise); diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_math.c b/source/blender/nodes/shader/nodes/node_shader_vector_math.c index 3a6e273eb20..94dd5434e5f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_math.c +++ b/source/blender/nodes/shader/nodes/node_shader_vector_math.c @@ -78,58 +78,6 @@ static int gpu_shader_vector_math(GPUMaterial *mat, } } -static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node) -{ - bNodeSocket *sockB = BLI_findlink(&node->inputs, 1); - bNodeSocket *sockC = BLI_findlink(&node->inputs, 2); - bNodeSocket *sockScale = nodeFindSocket(node, SOCK_IN, "Scale"); - - bNodeSocket *sockVector = nodeFindSocket(node, SOCK_OUT, "Vector"); - bNodeSocket *sockValue = nodeFindSocket(node, SOCK_OUT, "Value"); - - nodeSetSocketAvailability(sockB, - !ELEM(node->custom1, - NODE_VECTOR_MATH_SINE, - NODE_VECTOR_MATH_COSINE, - NODE_VECTOR_MATH_TANGENT, - NODE_VECTOR_MATH_CEIL, - NODE_VECTOR_MATH_SCALE, - NODE_VECTOR_MATH_FLOOR, - NODE_VECTOR_MATH_LENGTH, - NODE_VECTOR_MATH_ABSOLUTE, - NODE_VECTOR_MATH_FRACTION, - NODE_VECTOR_MATH_NORMALIZE)); - nodeSetSocketAvailability(sockC, ELEM(node->custom1, NODE_VECTOR_MATH_WRAP)); - nodeSetSocketAvailability(sockScale, node->custom1 == NODE_VECTOR_MATH_SCALE); - nodeSetSocketAvailability(sockVector, - !ELEM(node->custom1, - NODE_VECTOR_MATH_LENGTH, - NODE_VECTOR_MATH_DISTANCE, - NODE_VECTOR_MATH_DOT_PRODUCT)); - nodeSetSocketAvailability(sockValue, - ELEM(node->custom1, - NODE_VECTOR_MATH_LENGTH, - NODE_VECTOR_MATH_DISTANCE, - NODE_VECTOR_MATH_DOT_PRODUCT)); - - /* Labels */ - if (sockB->label[0] != '\0') { - sockB->label[0] = '\0'; - } - if (sockC->label[0] != '\0') { - sockC->label[0] = '\0'; - } - switch (node->custom1) { - case NODE_VECTOR_MATH_WRAP: - node_sock_label(sockB, "Max"); - node_sock_label(sockC, "Min"); - break; - case NODE_VECTOR_MATH_SNAP: - node_sock_label(sockB, "Increment"); - break; - } -} - void register_node_type_sh_vect_math(void) { static bNodeType ntype; @@ -138,7 +86,7 @@ void register_node_type_sh_vect_math(void) node_type_socket_templates(&ntype, sh_node_vector_math_in, sh_node_vector_math_out); node_type_label(&ntype, node_vector_math_label); node_type_gpu(&ntype, gpu_shader_vector_math); - node_type_update(&ntype, node_shader_update_vector_math); + node_type_update(&ntype, node_vector_math_update); nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/simulation/node_sim_tree.cc b/source/blender/nodes/simulation/node_sim_tree.cc new file mode 100644 index 00000000000..ecaeda20edd --- /dev/null +++ b/source/blender/nodes/simulation/node_sim_tree.cc @@ -0,0 +1,30 @@ +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "NOD_simulation.h" + +#include "BKE_node.h" + +#include "BLT_translation.h" + +#include "DNA_node_types.h" + +#include "RNA_access.h" + +bNodeTreeType *ntreeType_Simulation; + +void register_node_tree_type_sim(void) +{ + bNodeTreeType *tt = ntreeType_Simulation = (bNodeTreeType *)MEM_callocN( + sizeof(bNodeTreeType), "simulation node tree type"); + tt->type = NTREE_SIMULATION; + strcpy(tt->idname, "SimulationNodeTree"); + strcpy(tt->ui_name, N_("Simulation Editor")); + tt->ui_icon = 0; /* defined in drawnode.c */ + strcpy(tt->ui_description, N_("Simulation nodes")); + tt->poll = [](const bContext *UNUSED(C), bNodeTreeType *UNUSED(treetype)) { return true; }; + tt->rna_ext.srna = &RNA_SimulationNodeTree; + + ntreeTypeAdd(tt); +} diff --git a/source/blender/nodes/simulation/node_sim_util.cc b/source/blender/nodes/simulation/node_sim_util.cc new file mode 100644 index 00000000000..e55b6e52f55 --- /dev/null +++ b/source/blender/nodes/simulation/node_sim_util.cc @@ -0,0 +1,13 @@ +#include "node_sim_util.h" +#include "node_util.h" + +bool sim_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree) +{ + return STREQ(ntree->idname, "SimulationNodeTree"); +} + +void sim_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag) +{ + node_type_base(ntype, type, name, nclass, flag); + ntype->poll = sim_node_poll_default; +} diff --git a/source/blender/nodes/simulation/node_sim_util.h b/source/blender/nodes/simulation/node_sim_util.h new file mode 100644 index 00000000000..c1ff82cd26f --- /dev/null +++ b/source/blender/nodes/simulation/node_sim_util.h @@ -0,0 +1,24 @@ +#ifndef __NODE_SIM_UTIL_H__ +#define __NODE_SIM_UTIL_H__ + +#include <string.h> + +#include "BLI_utildefines.h" + +#include "MEM_guardedalloc.h" + +#include "DNA_node_types.h" + +#include "BKE_node.h" + +#include "BLT_translation.h" + +#include "NOD_simulation.h" + +#include "node_util.h" + +void sim_node_type_base( + struct bNodeType *ntype, int type, const char *name, short nclass, short flag); +bool sim_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree); + +#endif /* __NODE_SIM_UTIL_H__ */ diff --git a/source/blender/nodes/simulation/nodes/node_sim_common.cc b/source/blender/nodes/simulation/nodes/node_sim_common.cc new file mode 100644 index 00000000000..d61917834fe --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_common.cc @@ -0,0 +1,30 @@ +#include "BKE_node.h" + +#include "NOD_simulation.h" + +#include "NOD_common.h" +#include "node_common.h" +#include "node_sim_util.h" + +void register_node_type_sim_group(void) +{ + static bNodeType ntype; + + node_type_base_custom( + &ntype, "SimulationNodeGroup", "Group", NODE_CLASS_GROUP, NODE_CONST_OUTPUT); + ntype.type = NODE_GROUP; + ntype.poll = sim_node_poll_default; + ntype.poll_instance = node_group_poll_instance; + ntype.insert_link = node_insert_link_default; + ntype.update_internal_links = node_update_internal_links_default; + ntype.rna_ext.srna = RNA_struct_find("SimulationNodeGroup"); + BLI_assert(ntype.rna_ext.srna != NULL); + RNA_struct_blender_type_set(ntype.rna_ext.srna, &ntype); + + node_type_socket_templates(&ntype, NULL, NULL); + node_type_size(&ntype, 140, 60, 400); + node_type_label(&ntype, node_group_label); + node_type_group_update(&ntype, node_group_update); + + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_emit_particles.cc b/source/blender/nodes/simulation/nodes/node_sim_emit_particles.cc new file mode 100644 index 00000000000..47c239e0bca --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_emit_particles.cc @@ -0,0 +1,22 @@ +#include "node_sim_util.h" + +static bNodeSocketTemplate sim_node_emit_particle_in[] = { + {SOCK_INT, N_("Amount"), 10, 0, 0, 0, 0, 10000000}, + {SOCK_CONTROL_FLOW, N_("Execute")}, + {-1, ""}, +}; + +static bNodeSocketTemplate sim_node_emit_particle_out[] = { + {SOCK_CONTROL_FLOW, N_("Execute")}, + {SOCK_EMITTERS, N_("Emitter")}, + {-1, ""}, +}; + +void register_node_type_sim_emit_particles() +{ + static bNodeType ntype; + + sim_node_type_base(&ntype, SIM_NODE_EMIT_PARTICLES, "Emit Particles", 0, 0); + node_type_socket_templates(&ntype, sim_node_emit_particle_in, sim_node_emit_particle_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_execute_condition.cc b/source/blender/nodes/simulation/nodes/node_sim_execute_condition.cc new file mode 100644 index 00000000000..6892deade76 --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_execute_condition.cc @@ -0,0 +1,23 @@ +#include "node_sim_util.h" + +static bNodeSocketTemplate sim_node_execute_condition_in[] = { + {SOCK_BOOLEAN, N_("Condition")}, + {SOCK_CONTROL_FLOW, N_("If True")}, + {SOCK_CONTROL_FLOW, N_("If False")}, + {-1, ""}, +}; + +static bNodeSocketTemplate sim_node_execute_condition_out[] = { + {SOCK_CONTROL_FLOW, N_("Execute")}, + {-1, ""}, +}; + +void register_node_type_sim_execute_condition() +{ + static bNodeType ntype; + + sim_node_type_base(&ntype, SIM_NODE_EXECUTE_CONDITION, "Execute Condition", 0, 0); + node_type_socket_templates( + &ntype, sim_node_execute_condition_in, sim_node_execute_condition_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_force.cc b/source/blender/nodes/simulation/nodes/node_sim_force.cc new file mode 100644 index 00000000000..842bf977181 --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_force.cc @@ -0,0 +1,20 @@ +#include "node_sim_util.h" + +static bNodeSocketTemplate sim_node_force_in[] = { + {SOCK_VECTOR, N_("Force"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {-1, ""}, +}; + +static bNodeSocketTemplate sim_node_force_out[] = { + {SOCK_FORCES, N_("Force")}, + {-1, ""}, +}; + +void register_node_type_sim_force() +{ + static bNodeType ntype; + + sim_node_type_base(&ntype, SIM_NODE_FORCE, "Force", 0, 0); + node_type_socket_templates(&ntype, sim_node_force_in, sim_node_force_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_multi_execute.cc b/source/blender/nodes/simulation/nodes/node_sim_multi_execute.cc new file mode 100644 index 00000000000..ecbe2e5f88c --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_multi_execute.cc @@ -0,0 +1,22 @@ +#include "node_sim_util.h" + +static bNodeSocketTemplate sim_node_multi_execute_in[] = { + {SOCK_CONTROL_FLOW, "1"}, + {SOCK_CONTROL_FLOW, "2"}, + {SOCK_CONTROL_FLOW, "3"}, + {-1, ""}, +}; + +static bNodeSocketTemplate sim_node_multi_execute_out[] = { + {SOCK_CONTROL_FLOW, N_("Execute")}, + {-1, ""}, +}; + +void register_node_type_sim_multi_execute() +{ + static bNodeType ntype; + + sim_node_type_base(&ntype, SIM_NODE_MULTI_EXECUTE, "Multi Execute", 0, 0); + node_type_socket_templates(&ntype, sim_node_multi_execute_in, sim_node_multi_execute_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_particle_attribute.cc b/source/blender/nodes/simulation/nodes/node_sim_particle_attribute.cc new file mode 100644 index 00000000000..623f6e71d39 --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_particle_attribute.cc @@ -0,0 +1,37 @@ +#include "node_sim_util.h" +#include "BLI_listbase.h" + +static bNodeSocketTemplate sim_node_particle_attribute_in[] = { + {SOCK_STRING, N_("Name")}, + {-1, ""}, +}; + +static bNodeSocketTemplate sim_node_particle_attribute_out[] = { + {SOCK_FLOAT, N_("Float")}, + {SOCK_INT, N_("Int")}, + {SOCK_BOOLEAN, N_("Boolean")}, + {SOCK_VECTOR, N_("Vector")}, + {SOCK_RGBA, N_("Color")}, + {SOCK_OBJECT, N_("Object")}, + {SOCK_IMAGE, N_("Image")}, + {SOCK_SURFACE_HOOK, N_("Surface Hook")}, + {-1, ""}, +}; + +static void sim_node_particle_attribute_update(bNodeTree *UNUSED(ntree), bNode *node) +{ + LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { + nodeSetSocketAvailability(sock, sock->type == node->custom1); + } +} + +void register_node_type_sim_particle_attribute() +{ + static bNodeType ntype; + + sim_node_type_base(&ntype, SIM_NODE_PARTICLE_ATTRIBUTE, "Particle Attribute", 0, 0); + node_type_socket_templates( + &ntype, sim_node_particle_attribute_in, sim_node_particle_attribute_out); + node_type_update(&ntype, sim_node_particle_attribute_update); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_particle_birth_event.cc b/source/blender/nodes/simulation/nodes/node_sim_particle_birth_event.cc new file mode 100644 index 00000000000..a2469f0062b --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_particle_birth_event.cc @@ -0,0 +1,21 @@ +#include "node_sim_util.h" + +static bNodeSocketTemplate sim_node_particle_birth_event_in[] = { + {SOCK_CONTROL_FLOW, N_("Execute")}, + {-1, ""}, +}; + +static bNodeSocketTemplate sim_node_particle_birth_event_out[] = { + {SOCK_EVENTS, N_("Event")}, + {-1, ""}, +}; + +void register_node_type_sim_particle_birth_event() +{ + static bNodeType ntype; + + sim_node_type_base(&ntype, SIM_NODE_PARTICLE_BIRTH_EVENT, "Particle Birth Event", 0, 0); + node_type_socket_templates( + &ntype, sim_node_particle_birth_event_in, sim_node_particle_birth_event_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_collision_event.cc b/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_collision_event.cc new file mode 100644 index 00000000000..ee78b1b0585 --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_collision_event.cc @@ -0,0 +1,24 @@ +#include "node_sim_util.h" + +static bNodeSocketTemplate sim_node_particle_mesh_collision_event_in[] = { + {SOCK_OBJECT, N_("Object")}, + {SOCK_CONTROL_FLOW, N_("Execute")}, + {-1, ""}, +}; + +static bNodeSocketTemplate sim_node_particle_mesh_collision_event_out[] = { + {SOCK_EVENTS, N_("Event")}, + {-1, ""}, +}; + +void register_node_type_sim_particle_mesh_collision_event() +{ + static bNodeType ntype; + + sim_node_type_base( + &ntype, SIM_NODE_PARTICLE_MESH_COLLISION_EVENT, "Particle Mesh Collision Event", 0, 0); + node_type_socket_templates(&ntype, + sim_node_particle_mesh_collision_event_in, + sim_node_particle_mesh_collision_event_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc b/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc new file mode 100644 index 00000000000..d1a19f16df0 --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc @@ -0,0 +1,24 @@ +#include "node_sim_util.h" + +#include "float.h" + +static bNodeSocketTemplate sim_node_particle_mesh_emitter_in[] = { + {SOCK_OBJECT, N_("Object")}, + {SOCK_FLOAT, N_("Rate"), 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX}, + {-1, ""}, +}; + +static bNodeSocketTemplate sim_node_particle_mesh_emitter_out[] = { + {SOCK_EMITTERS, N_("Emitter")}, + {-1, ""}, +}; + +void register_node_type_sim_particle_mesh_emitter() +{ + static bNodeType ntype; + + sim_node_type_base(&ntype, SIM_NODE_PARTICLE_MESH_EMITTER, "Mesh Emitter", 0, 0); + node_type_socket_templates( + &ntype, sim_node_particle_mesh_emitter_in, sim_node_particle_mesh_emitter_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_particle_simulation.cc b/source/blender/nodes/simulation/nodes/node_sim_particle_simulation.cc new file mode 100644 index 00000000000..5c17a444588 --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_particle_simulation.cc @@ -0,0 +1,23 @@ +#include "node_sim_util.h" + +static bNodeSocketTemplate sim_node_particle_simulation_in[] = { + {SOCK_EMITTERS, N_("Emitters")}, + {SOCK_EVENTS, N_("Events")}, + {SOCK_FORCES, N_("Forces")}, + {-1, ""}, +}; + +static bNodeSocketTemplate sim_node_particle_simulation_out[] = { + {-1, ""}, +}; + +void register_node_type_sim_particle_simulation() +{ + static bNodeType ntype; + + sim_node_type_base( + &ntype, SIM_NODE_PARTICLE_SIMULATION, "Particle Simulation", NODE_CLASS_OUTPUT, 0); + node_type_socket_templates( + &ntype, sim_node_particle_simulation_in, sim_node_particle_simulation_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_particle_time_step_event.cc b/source/blender/nodes/simulation/nodes/node_sim_particle_time_step_event.cc new file mode 100644 index 00000000000..be2d98f4a81 --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_particle_time_step_event.cc @@ -0,0 +1,21 @@ +#include "node_sim_util.h" + +static bNodeSocketTemplate sim_node_particle_time_step_event_in[] = { + {SOCK_CONTROL_FLOW, N_("Execute")}, + {-1, ""}, +}; + +static bNodeSocketTemplate sim_node_particle_time_step_event_out[] = { + {SOCK_EVENTS, N_("Event")}, + {-1, ""}, +}; + +void register_node_type_sim_particle_time_step_event() +{ + static bNodeType ntype; + + sim_node_type_base(&ntype, SIM_NODE_PARTICLE_TIME_STEP_EVENT, "Particle Time Step Event", 0, 0); + node_type_socket_templates( + &ntype, sim_node_particle_time_step_event_in, sim_node_particle_time_step_event_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc b/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc new file mode 100644 index 00000000000..f72d2d261ab --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc @@ -0,0 +1,38 @@ +#include "node_sim_util.h" +#include "BLI_listbase.h" + +static bNodeSocketTemplate sim_node_set_particle_attribute_in[] = { + {SOCK_STRING, N_("Name")}, + {SOCK_FLOAT, N_("Float"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + {SOCK_INT, N_("Int"), 0, 0, 0, 0, -10000, 10000}, + {SOCK_BOOLEAN, N_("Boolean")}, + {SOCK_VECTOR, N_("Vector")}, + {SOCK_RGBA, N_("Color")}, + {SOCK_OBJECT, N_("Object")}, + {SOCK_IMAGE, N_("Image")}, + {SOCK_SURFACE_HOOK, N_("Surface Hook")}, + {-1, ""}, +}; + +static bNodeSocketTemplate sim_node_set_particle_attribute_out[] = { + {SOCK_CONTROL_FLOW, N_("Execute")}, + {-1, ""}, +}; + +static void sim_node_set_particle_attribute_update(bNodeTree *UNUSED(ntree), bNode *node) +{ + LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { + nodeSetSocketAvailability(sock, sock->type == node->custom1); + } +} + +void register_node_type_sim_set_particle_attribute() +{ + static bNodeType ntype; + + sim_node_type_base(&ntype, SIM_NODE_SET_PARTICLE_ATTRIBUTE, "Set Particle Attribute", 0, 0); + node_type_socket_templates( + &ntype, sim_node_set_particle_attribute_in, sim_node_set_particle_attribute_out); + node_type_update(&ntype, sim_node_set_particle_attribute_update); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_simulation_time.cc b/source/blender/nodes/simulation/nodes/node_sim_simulation_time.cc new file mode 100644 index 00000000000..6eaa7dd37de --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_simulation_time.cc @@ -0,0 +1,15 @@ +#include "node_sim_util.h" + +static bNodeSocketTemplate sim_node_simulation_time_out[] = { + {SOCK_FLOAT, N_("Simulation Time")}, + {-1, ""}, +}; + +void register_node_type_sim_simulation_time() +{ + static bNodeType ntype; + + sim_node_type_base(&ntype, SIM_NODE_SIMULATION_TIME, "Simulation Time", 0, 0); + node_type_socket_templates(&ntype, nullptr, sim_node_simulation_time_out); + nodeRegisterType(&ntype); +} |