From dded3c1ce73908258f3235fd30a7c49a5f2ad06e Mon Sep 17 00:00:00 2001 From: Cody Winchester Date: Sun, 30 Nov 2025 15:33:25 -0600 Subject: [PATCH] GOOENGINE: Add geometry nodes active camera override Adds a second camera property to the scene that is used only by geometry nodes in the Active Camera node. Necessary for our new environment file pipeline --- scripts/startup/bl_ui/properties_scene.py | 1 + source/blender/blenkernel/intern/scene.cc | 1 + .../depsgraph/intern/builder/deg_builder_nodes.cc | 4 ++++ .../intern/builder/deg_builder_nodes_scene.cc | 3 +++ .../intern/builder/deg_builder_relations.cc | 3 +++ .../intern/builder/deg_builder_relations_scene.cc | 6 ++++++ source/blender/depsgraph/intern/depsgraph_build.cc | 3 +++ source/blender/makesdna/DNA_scene_types.h | 2 +- source/blender/makesrna/intern/rna_scene.cc | 13 +++++++++++++ .../geometry/nodes/node_geo_input_active_camera.cc | 9 +++++++-- 10 files changed, 42 insertions(+), 3 deletions(-) diff --git a/scripts/startup/bl_ui/properties_scene.py b/scripts/startup/bl_ui/properties_scene.py index fabfebec387..48d7f06e97d 100644 --- a/scripts/startup/bl_ui/properties_scene.py +++ b/scripts/startup/bl_ui/properties_scene.py @@ -49,6 +49,7 @@ class SCENE_PT_scene(SceneButtonsPanel, Panel): scene = context.scene layout.prop(scene, "camera") + layout.prop(scene, "gn_camera_override") layout.prop(scene, "background_set") layout.prop(scene, "active_clip", text="Active Clip") diff --git a/source/blender/blenkernel/intern/scene.cc b/source/blender/blenkernel/intern/scene.cc index 7886df2cb5b..befa639cd3a 100644 --- a/source/blender/blenkernel/intern/scene.cc +++ b/source/blender/blenkernel/intern/scene.cc @@ -854,6 +854,7 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data) const int flag = BKE_lib_query_foreachid_process_flags_get(data); BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, scene->camera, IDWALK_CB_NOP); + BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, scene->gn_camera_override, IDWALK_CB_NOP); BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, scene->world, IDWALK_CB_USER); BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, scene->set, IDWALK_CB_NEVER_SELF); BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, scene->clip, IDWALK_CB_USER); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 5dde611c47b..7758f89ddf8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -1989,6 +1989,10 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree) /* TODO(sergey): Use visibility of owner of the node tree. */ build_object(-1, node_scene->camera, DEG_ID_LINKED_INDIRECTLY, true); } + if (node_scene->gn_camera_override != nullptr) { + /* TODO(sergey): Use visibility of owner of the node tree. */ + build_object(-1, node_scene->gn_camera_override, DEG_ID_LINKED_INDIRECTLY, true); + } } else if (id_type == ID_TXT) { /* Ignore script nodes. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc index 8e288f2e70e..d8e8fe3233e 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc @@ -39,6 +39,9 @@ void DepsgraphNodeBuilder::build_scene_camera(Scene *scene) if (scene->camera != nullptr) { build_object(-1, scene->camera, DEG_ID_LINKED_INDIRECTLY, true); } + if (scene->gn_camera_override != nullptr) { + build_object(-1, scene->gn_camera_override, DEG_ID_LINKED_INDIRECTLY, true); + } LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) { if (!ELEM(marker->camera, nullptr, scene->camera)) { build_object(-1, marker->camera, DEG_ID_LINKED_INDIRECTLY, true); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index b0ecda48bc9..1b815d51e32 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -3056,6 +3056,9 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) if (node_scene->camera != nullptr) { build_object(node_scene->camera); } + if (node_scene->gn_camera_override != nullptr) { + build_object(node_scene->gn_camera_override); + } } else if (id_type == ID_TXT) { /* Ignore script nodes. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc index a923e834ad1..1125c3809eb 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc @@ -30,6 +30,9 @@ void DepsgraphRelationBuilder::build_scene_render(Scene *scene, ViewLayer *view_ if (scene->camera != nullptr) { build_object(scene->camera); } + if (scene->gn_camera_override != nullptr) { + build_object(scene->gn_camera_override); + } } void DepsgraphRelationBuilder::build_scene_camera(Scene *scene) @@ -37,6 +40,9 @@ void DepsgraphRelationBuilder::build_scene_camera(Scene *scene) if (scene->camera != nullptr) { build_object(scene->camera); } + if (scene->gn_camera_override != nullptr) { + build_object(scene->gn_camera_override); + } LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) { if (!ELEM(marker->camera, nullptr, scene->camera)) { build_object(marker->camera); diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index f99e70bd792..68f7b42d5a6 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -92,6 +92,9 @@ void DEG_add_scene_camera_relation(DepsNodeHandle *node_handle, if (scene->camera != nullptr) { DEG_add_object_relation(node_handle, scene->camera, component, description); } + if (scene->gn_camera_override != nullptr) { + DEG_add_object_relation(node_handle, scene->gn_camera_override, component, description); + } /* Like DepsgraphNodeBuilder::build_scene_camera(), we also need to account for other cameras * referenced by markers. */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 967a043e89c..517a8420c86 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2027,6 +2027,7 @@ typedef struct Scene { DrawDataList drawdata; struct Object *camera; + struct Object *gn_camera_override; struct World *world; struct Scene *set; @@ -2034,7 +2035,6 @@ typedef struct Scene { ListBase base DNA_DEPRECATED; /** Active base. */ struct Base *basact DNA_DEPRECATED; - void *_pad1; /** 3d cursor location. */ View3DCursor cursor; diff --git a/source/blender/makesrna/intern/rna_scene.cc b/source/blender/makesrna/intern/rna_scene.cc index 3506ccf49ee..da1aca6446b 100644 --- a/source/blender/makesrna/intern/rna_scene.cc +++ b/source/blender/makesrna/intern/rna_scene.cc @@ -2438,12 +2438,17 @@ static void rna_SceneCamera_update(Main * /*bmain*/, Scene * /*scene*/, PointerR { Scene *scene = (Scene *)ptr->owner_id; Object *camera = scene->camera; + Object *gn_camera = scene->gn_camera_override; SEQ_cache_cleanup(scene); if (camera && (camera->type == OB_CAMERA)) { DEG_id_tag_update(&camera->id, ID_RECALC_GEOMETRY); } + + if (gn_camera && (gn_camera->type == OB_CAMERA)) { + DEG_id_tag_update(&gn_camera->id, ID_RECALC_GEOMETRY); + } } static void rna_SceneSequencer_update(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr) @@ -8726,6 +8731,14 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Camera", "Active camera, used for rendering the scene"); RNA_def_property_update(prop, NC_SCENE | NA_EDITED, "rna_Scene_camera_update"); + prop = RNA_def_property(srna, "gn_camera_override", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_pointer_funcs(prop, nullptr, nullptr, nullptr, "rna_Camera_object_poll"); + RNA_def_property_ui_text(prop, "GeoNodes Active Camera Override", "Active camera, used for calculating geometry nodes active camera node"); + RNA_def_property_update(prop, NC_SCENE | NA_EDITED, "rna_Scene_frame_update"); + prop = RNA_def_property(srna, "background_set", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "set"); RNA_def_property_struct_type(prop, "Scene"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_active_camera.cc b/source/blender/nodes/geometry/nodes/node_geo_input_active_camera.cc index aef32aaf152..f71a087de87 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_active_camera.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_active_camera.cc @@ -17,8 +17,13 @@ static void node_declare(NodeDeclarationBuilder &b) static void node_exec(GeoNodeExecParams params) { const Scene *scene = DEG_get_evaluated_scene(params.depsgraph()); - Object *camera = DEG_get_evaluated_object(params.depsgraph(), scene->camera); - params.set_output("Active Camera", camera); + if (scene->gn_camera_override == nullptr) { + Object *camera = DEG_get_evaluated_object(params.depsgraph(), scene->camera); + params.set_output("Active Camera", camera); + } else { + Object *camera = DEG_get_evaluated_object(params.depsgraph(), scene->gn_camera_override); + params.set_output("Active Camera", camera); + } } static void node_register()