Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_node.h34
-rw-r--r--source/blender/blenkernel/intern/lib_query.c23
-rw-r--r--source/blender/blenkernel/intern/node.c136
-rw-r--r--source/blender/blenloader/intern/readfile.c22
-rw-r--r--source/blender/blenloader/intern/writefile.c11
-rw-r--r--source/blender/editors/include/ED_node.h1
-rw-r--r--source/blender/editors/space_node/drawnode.c103
-rw-r--r--source/blender/editors/space_node/node_edit.c7
-rw-r--r--source/blender/editors/space_node/node_group.c9
-rw-r--r--source/blender/makesdna/DNA_node_types.h38
-rw-r--r--source/blender/makesrna/RNA_access.h3
-rw-r--r--source/blender/makesrna/RNA_enum_types.h2
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c412
-rw-r--r--source/blender/nodes/CMakeLists.txt41
-rw-r--r--source/blender/nodes/NOD_common.h8
-rw-r--r--source/blender/nodes/NOD_function.h32
-rw-r--r--source/blender/nodes/NOD_simulation.h31
-rw-r--r--source/blender/nodes/NOD_static_types.h35
-rw-r--r--source/blender/nodes/function/node_fn_util.cc14
-rw-r--r--source/blender/nodes/function/node_fn_util.h24
-rw-r--r--source/blender/nodes/function/nodes/node_fn_boolean_math.cc23
-rw-r--r--source/blender/nodes/function/nodes/node_fn_closest_surface.cc23
-rw-r--r--source/blender/nodes/function/nodes/node_fn_combine_hsv.cc22
-rw-r--r--source/blender/nodes/function/nodes/node_fn_combine_rgb.cc22
-rw-r--r--source/blender/nodes/function/nodes/node_fn_combine_xyz.cc22
-rw-r--r--source/blender/nodes/function/nodes/node_fn_float_compare.cc24
-rw-r--r--source/blender/nodes/function/nodes/node_fn_float_math.cc24
-rw-r--r--source/blender/nodes/function/nodes/node_fn_instance_identifier.cc15
-rw-r--r--source/blender/nodes/function/nodes/node_fn_object_transforms.cc20
-rw-r--r--source/blender/nodes/function/nodes/node_fn_separate_hsv.cc22
-rw-r--r--source/blender/nodes/function/nodes/node_fn_separate_rgb.cc22
-rw-r--r--source/blender/nodes/function/nodes/node_fn_separate_xyz.cc22
-rw-r--r--source/blender/nodes/function/nodes/node_fn_string_concatenation.cc22
-rw-r--r--source/blender/nodes/function/nodes/node_fn_surface_color.cc22
-rw-r--r--source/blender/nodes/function/nodes/node_fn_surface_normal.cc20
-rw-r--r--source/blender/nodes/function/nodes/node_fn_surface_position.cc20
-rw-r--r--source/blender/nodes/function/nodes/node_fn_surface_weight.cc21
-rw-r--r--source/blender/nodes/function/nodes/node_fn_switch.cc63
-rw-r--r--source/blender/nodes/function/nodes/node_fn_vector_math.cc26
-rw-r--r--source/blender/nodes/intern/node_common.h8
-rw-r--r--source/blender/nodes/intern/node_socket.c54
-rw-r--r--source/blender/nodes/intern/node_util.c88
-rw-r--r--source/blender/nodes/intern/node_util.h16
-rw-r--r--source/blender/nodes/shader/node_shader_util.c10
-rw-r--r--source/blender/nodes/shader/node_shader_util.h2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_brick.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_checker.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_gradient.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_magic.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_noise.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_wave.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c3
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_math.c54
-rw-r--r--source/blender/nodes/simulation/node_sim_tree.cc30
-rw-r--r--source/blender/nodes/simulation/node_sim_util.cc13
-rw-r--r--source/blender/nodes/simulation/node_sim_util.h24
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_common.cc30
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_emit_particles.cc22
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_execute_condition.cc23
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_force.cc20
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_multi_execute.cc22
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_particle_attribute.cc37
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_particle_birth_event.cc21
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_particle_mesh_collision_event.cc24
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc24
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_particle_simulation.cc23
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_particle_time_step_event.cc21
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc38
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_simulation_time.cc15
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);
+}