Render: allow to select an entire collection to set the focal point in the Depth of Field settings in the Camera properties #119869
|
@ -1078,16 +1078,17 @@ class CYCLES_CAMERA_PT_dof(CyclesButtonsPanel, Panel):
|
|||
dof = cam.dof
|
||||
layout.active = dof.use_dof
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop(dof, "focus_object", text="Focus Object")
|
||||
if dof.focus_object and dof.focus_object.type == 'ARMATURE':
|
||||
col.prop_search(dof, "focus_subtarget", dof.focus_object.data, "bones", text="Focus Bone")
|
||||
|
||||
sub = col.row()
|
||||
sub.active = dof.focus_object is None
|
||||
sub.prop(dof, "focus_distance", text="Distance")
|
||||
col = layout.column()
|
||||
if dof.focus_collection is None:
|
||||
col.prop(dof, "focus_object", text="Focus on Object")
|
||||
if dof.focus_object and dof.focus_object.type == 'ARMATURE':
|
||||
col.prop_search(dof, "focus_subtarget", dof.focus_object.data, "bones", text="Focus on Bone")
|
||||
if dof.focus_object is None:
|
||||
sub = col.column()
|
||||
sub.prop(dof, "focus_collection", text="Focus on Collection")
|
||||
if dof.focus_object is None and dof.focus_collection is None:
|
||||
sub = sub.column()
|
||||
sub.prop(dof, "focus_distance", text="Focus Distance")
|
||||
|
||||
|
||||
class CYCLES_CAMERA_PT_dof_aperture(CyclesButtonsPanel, Panel):
|
||||
|
|
|
@ -135,17 +135,49 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings &b_rende
|
|||
bcam->full_height = bcam->render_height;
|
||||
}
|
||||
|
||||
static void sum_obj_positions(float3 &pos, int &count, BL::Collection &coll)
|
||||
{
|
||||
for (BL::Object obj : coll.objects) {
|
||||
Transform dofmat = get_transform(obj.matrix_world());
|
||||
float3 curr = transform_get_column(&dofmat, 3);
|
||||
pos.x += curr.x;
|
||||
pos.y += curr.y;
|
||||
pos.z += curr.z;
|
||||
count += 1;
|
||||
}
|
||||
for (BL::Collection child : coll.children) {
|
||||
sum_obj_positions(pos, count, child);
|
||||
}
|
||||
}
|
||||
|
||||
static float blender_camera_focal_distance(BL::RenderEngine &b_engine,
|
||||
BL::Object &b_ob,
|
||||
BL::Camera &b_camera,
|
||||
BlenderCamera *bcam)
|
||||
{
|
||||
BL::Object b_dof_object = b_camera.dof().focus_object();
|
||||
BL::Collection b_dof_collection = b_camera.dof().focus_collection();
|
||||
|
||||
if (!b_dof_object) {
|
||||
if (!b_dof_object && !b_dof_collection) {
|
||||
return b_camera.dof().focus_distance();
|
||||
}
|
||||
|
||||
if (b_dof_collection) {
|
||||
int count = 0;
|
||||
float3 pos = {};
|
||||
sum_obj_positions(pos, count, b_dof_collection);
|
||||
float den = static_cast<float>(count);
|
||||
pos.x /= den;
|
||||
pos.y /= den;
|
||||
pos.z /= den;
|
||||
BL::Array<float, 16> b_ob_matrix;
|
||||
b_engine.camera_model_matrix(b_ob, bcam->use_spherical_stereo, b_ob_matrix);
|
||||
Transform obmat = transform_clear_scale(get_transform(b_ob_matrix));
|
||||
float3 view_dir = normalize(transform_get_column(&obmat, 2));
|
||||
float3 dof_dir = transform_get_column(&obmat, 3) - pos;
|
||||
return fabsf(dot(view_dir, dof_dir));
|
||||
}
|
||||
|
||||
Transform dofmat = get_transform(b_dof_object.matrix_world());
|
||||
|
||||
string focus_subtarget = b_camera.dof().focus_subtarget();
|
||||
|
|
|
@ -251,12 +251,16 @@ class DATA_PT_camera_dof(CameraButtonsPanel, Panel):
|
|||
layout.active = dof.use_dof
|
||||
|
||||
col = layout.column()
|
||||
col.prop(dof, "focus_object", text="Focus on Object")
|
||||
if dof.focus_object and dof.focus_object.type == 'ARMATURE':
|
||||
col.prop_search(dof, "focus_subtarget", dof.focus_object.data, "bones", text="Focus on Bone")
|
||||
sub = col.column()
|
||||
sub.active = (dof.focus_object is None)
|
||||
sub.prop(dof, "focus_distance", text="Focus Distance")
|
||||
if dof.focus_collection is None:
|
||||
col.prop(dof, "focus_object", text="Focus on Object")
|
||||
if dof.focus_object and dof.focus_object.type == 'ARMATURE':
|
||||
col.prop_search(dof, "focus_subtarget", dof.focus_object.data, "bones", text="Focus on Bone")
|
||||
if dof.focus_object is None:
|
||||
sub = col.column()
|
||||
sub.prop(dof, "focus_collection", text="Focus on Collection")
|
||||
if dof.focus_object is None and dof.focus_collection is None:
|
||||
sub = sub.column()
|
||||
sub.prop(dof, "focus_distance", text="Focus Distance")
|
||||
|
||||
|
||||
class DATA_PT_camera_dof_aperture(CameraButtonsPanel, Panel):
|
||||
|
|
|
@ -2895,7 +2895,7 @@ class VIEW3D_MT_object_context_menu(Menu):
|
|||
props.input_scale = 0.01
|
||||
props.header_text = rpt_("Camera Lens Scale: %.3f")
|
||||
|
||||
if not obj.data.dof.focus_object:
|
||||
if not obj.data.dof.focus_object and not obj.data.dof.focus_collection:
|
||||
if view and view.camera == obj and view.region_3d.view_perspective == 'CAMERA':
|
||||
props = layout.operator("ui.eyedropper_depth", text="DOF Distance (Pick)")
|
||||
else:
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_defaults.h"
|
||||
#include "DNA_light_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
@ -101,6 +102,7 @@ static void camera_foreach_id(ID *id, LibraryForeachIDData *data)
|
|||
const int flag = BKE_lib_query_foreachid_process_flags_get(data);
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, camera->dof.focus_object, IDWALK_CB_NOP);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, camera->dof.focus_collection, IDWALK_CB_NOP);
|
||||
LISTBASE_FOREACH (CameraBGImage *, bgpic, &camera->bg_images) {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, bgpic->ima, IDWALK_CB_USER);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, bgpic->clip, IDWALK_CB_USER);
|
||||
|
@ -276,12 +278,50 @@ void *BKE_camera_add(Main *bmain, const char *name)
|
|||
return cam;
|
||||
}
|
||||
|
||||
static void sum_obj_positions(float pos[3], int *count, Collection *c)
|
||||
{
|
||||
ListBase *gobject = &(c->gobject);
|
||||
ListBase *children = &(c->children);
|
||||
*count += BLI_listbase_count(gobject);
|
||||
LISTBASE_FOREACH (LinkData *, current, gobject) {
|
||||
Object *o = static_cast<Object *>(current->data);
|
||||
const blender::float3 &cpos = o->object_to_world().location();
|
||||
add_v3_v3v3(pos, pos, cpos);
|
||||
printf("Name: %s, Pos: %f, %f, %f, Total: %f, %f, %f\n",
|
||||
o->id.name,
|
||||
cpos.x,
|
||||
cpos.y,
|
||||
cpos.z,
|
||||
pos[0],
|
||||
pos[1],
|
||||
pos[2]); // DEBUG
|
||||
}
|
||||
LISTBASE_FOREACH (LinkData *, current, children) {
|
||||
Collection *child = static_cast<Collection *>(current->data);
|
||||
sum_obj_positions(pos, count, child);
|
||||
}
|
||||
}
|
||||
|
||||
float BKE_camera_object_dof_distance(const Object *ob)
|
||||
{
|
||||
const Camera *cam = (const Camera *)ob->data;
|
||||
if (ob->type != OB_CAMERA) {
|
||||
return 0.0f;
|
||||
}
|
||||
if (cam->dof.focus_collection) {
|
||||
float view_dir[3], dof_dir[3];
|
||||
normalize_v3_v3(view_dir, ob->object_to_world().ptr()[2]);
|
||||
|
||||
float pos[3] = {0.0f, 0.0f, 0.0f};
|
||||
int count = 0;
|
||||
sum_obj_positions(pos, &count, cam->dof.focus_collection);
|
||||
float scale = 1.0f / static_cast<float>(count);
|
||||
mul_v3_fl(pos, scale);
|
||||
printf("Nobjects: %d, AVG Pos: %f, %f, %f\n", count, pos[0], pos[1], pos[2]); // DEBUG
|
||||
|
||||
sub_v3_v3v3(dof_dir, ob->object_to_world().location(), pos);
|
||||
return fabsf(dot_v3v3(view_dir, dof_dir));
|
||||
}
|
||||
if (cam->dof.focus_object) {
|
||||
float view_dir[3], dof_dir[3];
|
||||
normalize_v3_v3(view_dir, ob->object_to_world().ptr()[2]);
|
||||
|
|
|
@ -1874,6 +1874,9 @@ void DepsgraphNodeBuilder::build_camera(Camera *camera)
|
|||
if (camera->dof.focus_object != nullptr) {
|
||||
build_object(-1, camera->dof.focus_object, DEG_ID_LINKED_INDIRECTLY, false);
|
||||
}
|
||||
if (camera->dof.focus_collection != nullptr) {
|
||||
build_collection(nullptr, camera->dof.focus_collection);
|
||||
mod_moder marked this conversation as resolved
Outdated
|
||||
}
|
||||
}
|
||||
|
||||
void DepsgraphNodeBuilder::build_light(Light *lamp)
|
||||
|
|
|
@ -1888,6 +1888,7 @@ static void single_obdata_users(
|
|||
nullptr,
|
||||
LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS)));
|
||||
ID_NEW_REMAP(cam->dof.focus_object);
|
||||
ID_NEW_REMAP(cam->dof.focus_collection);
|
||||
break;
|
||||
case OB_MESH:
|
||||
/* Needed to remap texcomesh below. */
|
||||
|
|
|
@ -51,6 +51,7 @@ typedef struct CameraBGImage {
|
|||
typedef struct CameraDOFSettings {
|
||||
/** Focal distance for depth of field. */
|
||||
struct Object *focus_object;
|
||||
struct Collection *focus_collection;
|
||||
char focus_subtarget[64];
|
||||
float focus_distance;
|
||||
float aperture_fstop;
|
||||
|
|
|
@ -522,6 +522,15 @@ static void rna_def_camera_dof_settings_data(BlenderRNA *brna)
|
|||
prop, "Focus Object", "Use this object to define the depth of field focal point");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_dependency_update");
|
||||
|
||||
prop = RNA_def_property(srna, "focus_collection", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "Collection");
|
||||
RNA_def_property_pointer_sdna(prop, nullptr, "focus_collection");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Focus Collection", "Use this object to define the depth of field focal point");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_dependency_update");
|
||||
|
||||
prop = RNA_def_property(srna, "focus_subtarget", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, nullptr, "focus_subtarget");
|
||||
RNA_def_property_ui_text(
|
||||
|
|
Loading…
Reference in New Issue
Hi, can you run
make format
in root folder of your blender fork?Ok done, thank you. Now the format should be ok