Geometry Nodes: Scene Time Node

This node outputs the current scene time in seconds or in frames.
Use of this node eliminates the need to use drivers to control values
in the node tree that are driven by the scene time.
Frame is a float value to provide for subframe rendering for motion
blur.

Differential Revision: https://developer.blender.org/D13455
This commit is contained in:
Johnny Matthews 2021-12-09 11:50:25 -06:00
parent ad44f22397
commit bd3bd776c8
Notes: blender-bot 2023-02-14 03:44:41 +01:00
Referenced by commit 710e279b19, Fix missing type declaration compile error
Referenced by issue #93098, Scene time input node
9 changed files with 95 additions and 2 deletions

View File

@ -215,6 +215,7 @@ def geometry_input_node_items(context):
yield NodeItem("GeometryNodeInputNormal")
yield NodeItem("GeometryNodeInputPosition")
yield NodeItem("GeometryNodeInputRadius")
yield NodeItem("GeometryNodeInputSceneTime")
# Custom Menu for Material Nodes
def geometry_material_node_items(context):

View File

@ -1718,6 +1718,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define GEO_NODE_GEOMETRY_TO_INSTANCE 1142
#define GEO_NODE_INPUT_MESH_EDGE_NEIGHBORS 1143
#define GEO_NODE_INPUT_MESH_ISLAND 1144
#define GEO_NODE_INPUT_SCENE_TIME 1145
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -5816,6 +5816,7 @@ static void registerGeometryNodes()
register_node_type_geo_input_normal();
register_node_type_geo_input_position();
register_node_type_geo_input_radius();
register_node_type_geo_input_scene_time();
register_node_type_geo_input_shade_smooth();
register_node_type_geo_input_spline_cyclic();
register_node_type_geo_input_spline_length();

View File

@ -1268,10 +1268,15 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree,
ntreeTexCheckCyclics(ntree);
}
ntreeUpdateTree(CTX_data_main(C), ntree);
Main *bmain = CTX_data_main(C);
ntreeUpdateTree(bmain, ntree);
nodeUpdate(ntree, node);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
if (node->type == GEO_NODE_INPUT_SCENE_TIME) {
DEG_relations_tag_update(bmain);
}
return node;
}

View File

@ -268,6 +268,38 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
}
}
static bool checkForTimeNode(bNodeTree *tree, Set<bNodeTree *> &r_checked_trees)
{
if (!r_checked_trees.add(tree)) {
return false;
}
LISTBASE_FOREACH (bNode *, node, &tree->nodes) {
if (node->type == GEO_NODE_INPUT_SCENE_TIME) {
return true;
}
if (node->type == NODE_GROUP) {
bNodeTree *subtree = (bNodeTree *)node->id;
if (checkForTimeNode(subtree, r_checked_trees)) {
return true;
}
}
}
return false;
}
static bool dependsOnTime(struct Scene *UNUSED(scene),
ModifierData *md,
const int UNUSED(dag_eval_mode))
{
NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
bNodeTree *tree = nmd->node_group;
if (tree == nullptr) {
return false;
}
Set<bNodeTree *> checked_trees;
return checkForTimeNode(tree, checked_trees);
}
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
@ -1590,7 +1622,7 @@ ModifierTypeInfo modifierType_Nodes = {
/* freeData */ freeData,
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ nullptr,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ nullptr,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ foreachTexLink,

View File

@ -114,6 +114,7 @@ void register_node_type_geo_input_mesh_vertex_neighbors(void);
void register_node_type_geo_input_normal(void);
void register_node_type_geo_input_position(void);
void register_node_type_geo_input_radius(void);
void register_node_type_geo_input_scene_time(void);
void register_node_type_geo_input_shade_smooth(void);
void register_node_type_geo_input_spline_cyclic(void);
void register_node_type_geo_input_spline_length(void);

View File

@ -367,6 +367,7 @@ DefNode(GeometryNode, GEO_NODE_INPUT_MESH_VERTEX_NEIGHBORS, 0, "MESH_VERTEX_NEIG
DefNode(GeometryNode, GEO_NODE_INPUT_NORMAL, 0, "INPUT_NORMAL", InputNormal, "Normal", "")
DefNode(GeometryNode, GEO_NODE_INPUT_POSITION, 0, "POSITION", InputPosition, "Position", "")
DefNode(GeometryNode, GEO_NODE_INPUT_RADIUS, 0, "INPUT_RADIUS", InputRadius, "Radius", "")
DefNode(GeometryNode, GEO_NODE_INPUT_SCENE_TIME, 0, "INPUT_SCENE_TIME", InputSceneTime, "Scene Time", "")
DefNode(GeometryNode, GEO_NODE_INPUT_SHADE_SMOOTH, 0, "INPUT_SHADE_SMOOTH", InputShadeSmooth, "Is Shade Smooth", "")
DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_CYCLIC, 0, "INPUT_SPLINE_CYCLIC", InputSplineCyclic, "Is Spline Cyclic", "")
DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_LENGTH, 0, "SPLINE_LENGTH", SplineLength, "Spline Length", "")

View File

@ -132,6 +132,7 @@ set(SRC
nodes/node_geo_input_normal.cc
nodes/node_geo_input_position.cc
nodes/node_geo_input_radius.cc
nodes/node_geo_input_scene_time.cc
nodes/node_geo_input_shade_smooth.cc
nodes/node_geo_input_spline_cyclic.cc
nodes/node_geo_input_spline_length.cc

View File

@ -0,0 +1,50 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "BKE_scene.h"
#include "DEG_depsgraph_query.h"
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_input_scene_time_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Float>(N_("Seconds"));
b.add_output<decl::Float>(N_("Frame"));
}
static void node_exec(GeoNodeExecParams params)
{
const Scene *scene = DEG_get_input_scene(params.depsgraph());
const float scene_ctime = BKE_scene_ctime_get(scene);
const double frame_rate = (((double)scene->r.frs_sec) / (double)scene->r.frs_sec_base);
params.set_output("Seconds", float(scene_ctime / frame_rate));
params.set_output("Frame", scene_ctime);
}
} // namespace blender::nodes::node_geo_input_scene_time_cc
void register_node_type_geo_input_scene_time()
{
static bNodeType ntype;
namespace file_ns = blender::nodes::node_geo_input_scene_time_cc;
geo_node_type_base(&ntype, GEO_NODE_INPUT_SCENE_TIME, "Scene Time", NODE_CLASS_INPUT, 0);
ntype.geometry_node_execute = file_ns::node_exec;
ntype.declare = file_ns::node_declare;
nodeRegisterType(&ntype);
}