Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_view3d/view3d_manipulator_camera.c
| Show All 39 Lines | |||||
| #include "UI_resources.h" | #include "UI_resources.h" | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| #include "WM_message.h" | |||||
| #include "view3d_intern.h" /* own include */ | #include "view3d_intern.h" /* own include */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Camera Manipulators | /** \name Camera Manipulators | ||||
| * \{ */ | * \{ */ | ||||
| struct CameraWidgetGroup { | struct CameraWidgetGroup { | ||||
| wmManipulator *dop_dist; | wmManipulator *dop_dist; | ||||
| wmManipulator *focal_len; | wmManipulator *focal_len; | ||||
| wmManipulator *ortho_scale; | wmManipulator *ortho_scale; | ||||
| }; | }; | ||||
| static bool WIDGETGROUP_camera_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) | static bool WIDGETGROUP_camera_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) | ||||
| { | { | ||||
| Object *ob = CTX_data_active_object(C); | Object *ob = CTX_data_active_object(C); | ||||
| return (ob && ob->type == OB_CAMERA); | return (ob && ob->type == OB_CAMERA); | ||||
| } | } | ||||
| static void cameragroup_property_setup(wmManipulator *widget, Object *ob, Camera *ca, const bool is_ortho) | |||||
| { | |||||
| const float scale[3] = {1.0f / len_v3(ob->obmat[0]), 1.0f / len_v3(ob->obmat[1]), 1.0f / len_v3(ob->obmat[2])}; | |||||
| const float scale_fac = ca->drawsize; | |||||
| const float drawsize = is_ortho ? | |||||
| (0.5f * ca->ortho_scale) : | |||||
| (scale_fac / ((scale[0] + scale[1] + scale[2]) / 3.0f)); | |||||
| const float half_sensor = 0.5f * ((ca->sensor_fit == CAMERA_SENSOR_FIT_VERT) ? ca->sensor_y : ca->sensor_x); | |||||
| const char *propname = is_ortho ? "ortho_scale" : "lens"; | |||||
| PointerRNA camera_ptr; | |||||
| float min, max, range; | |||||
| float step, precision; | |||||
| RNA_pointer_create(&ca->id, &RNA_Camera, ca, &camera_ptr); | |||||
| /* get property range */ | |||||
| PropertyRNA *prop = RNA_struct_find_property(&camera_ptr, propname); | |||||
| RNA_property_float_ui_range(&camera_ptr, prop, &min, &max, &step, &precision); | |||||
| range = max - min; | |||||
| ED_manipulator_arrow3d_set_range_fac(widget, is_ortho ? (scale_fac * range) : (drawsize * range / half_sensor)); | |||||
| } | |||||
| static void WIDGETGROUP_camera_setup(const bContext *C, wmManipulatorGroup *mgroup) | static void WIDGETGROUP_camera_setup(const bContext *C, wmManipulatorGroup *mgroup) | ||||
| { | { | ||||
| Object *ob = CTX_data_active_object(C); | Object *ob = CTX_data_active_object(C); | ||||
| Camera *ca = ob->data; | |||||
| float dir[3]; | float dir[3]; | ||||
| const wmManipulatorType *wt_arrow = WM_manipulatortype_find("MANIPULATOR_WT_arrow_3d", true); | const wmManipulatorType *wt_arrow = WM_manipulatortype_find("MANIPULATOR_WT_arrow_3d", true); | ||||
| struct CameraWidgetGroup *camgroup = MEM_callocN(sizeof(struct CameraWidgetGroup), __func__); | struct CameraWidgetGroup *camgroup = MEM_callocN(sizeof(struct CameraWidgetGroup), __func__); | ||||
| mgroup->customdata = camgroup; | mgroup->customdata = camgroup; | ||||
| negate_v3_v3(dir, ob->obmat[2]); | negate_v3_v3(dir, ob->obmat[2]); | ||||
| Show All 15 Lines | * - logic/calculations are similar to BKE_camera_view_frame_ex, better keep in sync */ | ||||
| wmManipulator *mpr; | wmManipulator *mpr; | ||||
| mpr = camgroup->focal_len = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); | mpr = camgroup->focal_len = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); | ||||
| mpr->flag |= WM_MANIPULATOR_DRAW_NO_SCALE; | mpr->flag |= WM_MANIPULATOR_DRAW_NO_SCALE; | ||||
| RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE); | RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE); | ||||
| RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED); | RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED); | ||||
| UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color); | UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color); | ||||
| UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi); | UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi); | ||||
| cameragroup_property_setup(mpr, ob, ca, false); | |||||
| mpr = camgroup->ortho_scale = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); | mpr = camgroup->ortho_scale = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); | ||||
| mpr->flag |= WM_MANIPULATOR_DRAW_NO_SCALE; | mpr->flag |= WM_MANIPULATOR_DRAW_NO_SCALE; | ||||
| RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE); | RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE); | ||||
| RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED); | RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED); | ||||
| UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color); | UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color); | ||||
| UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi); | UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi); | ||||
| cameragroup_property_setup(mpr, ob, ca, true); | |||||
| } | } | ||||
| } | } | ||||
| static void WIDGETGROUP_camera_refresh(const bContext *C, wmManipulatorGroup *mgroup) | static void WIDGETGROUP_camera_refresh(const bContext *C, wmManipulatorGroup *mgroup) | ||||
| { | { | ||||
| if (!mgroup->customdata) | if (!mgroup->customdata) | ||||
| return; | return; | ||||
| struct CameraWidgetGroup *camgroup = mgroup->customdata; | struct CameraWidgetGroup *camgroup = mgroup->customdata; | ||||
| Object *ob = CTX_data_active_object(C); | Object *ob = CTX_data_active_object(C); | ||||
| Camera *ca = ob->data; | Camera *ca = ob->data; | ||||
| PointerRNA camera_ptr; | PointerRNA camera_ptr; | ||||
| float dir[3]; | float dir[3]; | ||||
| const float ob_scale_inv[3] = { | |||||
| 1.0f / len_v3(ob->obmat[0]), | |||||
| 1.0f / len_v3(ob->obmat[1]), | |||||
| 1.0f / len_v3(ob->obmat[2]), | |||||
| }; | |||||
| const float ob_scale_uniform_inv = (ob_scale_inv[0] + ob_scale_inv[1] + ob_scale_inv[2]) / 3.0f; | |||||
| RNA_pointer_create(&ca->id, &RNA_Camera, ca, &camera_ptr); | RNA_pointer_create(&ca->id, &RNA_Camera, ca, &camera_ptr); | ||||
| negate_v3_v3(dir, ob->obmat[2]); | negate_v3_v3(dir, ob->obmat[2]); | ||||
| if (ca->flag & CAM_SHOWLIMITS) { | if (ca->flag & CAM_SHOWLIMITS) { | ||||
| WM_manipulator_set_matrix_location(camgroup->dop_dist, ob->obmat[3]); | WM_manipulator_set_matrix_location(camgroup->dop_dist, ob->obmat[3]); | ||||
| WM_manipulator_set_matrix_rotation_from_yz_axis(camgroup->dop_dist, ob->obmat[1], dir); | WM_manipulator_set_matrix_rotation_from_yz_axis(camgroup->dop_dist, ob->obmat[1], dir); | ||||
| WM_manipulator_set_scale(camgroup->dop_dist, ca->drawsize); | WM_manipulator_set_scale(camgroup->dop_dist, ca->drawsize); | ||||
| WM_manipulator_set_flag(camgroup->dop_dist, WM_MANIPULATOR_HIDDEN, false); | WM_manipulator_set_flag(camgroup->dop_dist, WM_MANIPULATOR_HIDDEN, false); | ||||
| /* need to set property here for undo. TODO would prefer to do this in _init */ | /* need to set property here for undo. TODO would prefer to do this in _init */ | ||||
| WM_manipulator_target_property_def_rna(camgroup->dop_dist, "offset", &camera_ptr, "dof_distance", -1); | WM_manipulator_target_property_def_rna(camgroup->dop_dist, "offset", &camera_ptr, "dof_distance", -1); | ||||
| } | } | ||||
| else { | else { | ||||
| WM_manipulator_set_flag(camgroup->dop_dist, WM_MANIPULATOR_HIDDEN, true); | WM_manipulator_set_flag(camgroup->dop_dist, WM_MANIPULATOR_HIDDEN, true); | ||||
| } | } | ||||
| /* TODO - make focal length/ortho scale widget optional */ | /* TODO - make focal length/ortho ob_scale_inv widget optional */ | ||||
| if (true) { | if (true) { | ||||
| const bool is_ortho = (ca->type == CAM_ORTHO); | const bool is_ortho = (ca->type == CAM_ORTHO); | ||||
| float offset[3]; | float offset[3]; | ||||
| float aspect[2]; | float aspect[2]; | ||||
| wmManipulator *widget = is_ortho ? camgroup->ortho_scale : camgroup->focal_len; | wmManipulator *widget = is_ortho ? camgroup->ortho_scale : camgroup->focal_len; | ||||
| WM_manipulator_set_flag(widget, WM_MANIPULATOR_HIDDEN, false); | WM_manipulator_set_flag(widget, WM_MANIPULATOR_HIDDEN, false); | ||||
| WM_manipulator_set_flag(is_ortho ? camgroup->focal_len : camgroup->ortho_scale, WM_MANIPULATOR_HIDDEN, true); | WM_manipulator_set_flag(is_ortho ? camgroup->focal_len : camgroup->ortho_scale, WM_MANIPULATOR_HIDDEN, true); | ||||
| Show All 11 Lines | if (true) { | ||||
| const int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, aspx, aspy); | const int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, aspx, aspy); | ||||
| aspect[0] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? 1.0f : aspx / aspy; | aspect[0] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? 1.0f : aspx / aspy; | ||||
| aspect[1] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? aspy / aspx : 1.0f; | aspect[1] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? aspy / aspx : 1.0f; | ||||
| unit_m4(widget->matrix_basis); | unit_m4(widget->matrix_basis); | ||||
| WM_manipulator_set_matrix_location(widget, ob->obmat[3]); | WM_manipulator_set_matrix_location(widget, ob->obmat[3]); | ||||
| WM_manipulator_set_matrix_rotation_from_yz_axis(widget, ob->obmat[1], dir); | WM_manipulator_set_matrix_rotation_from_yz_axis(widget, ob->obmat[1], dir); | ||||
| { | |||||
| float scale_matrix; | float scale_matrix; | ||||
| { | |||||
| if (is_ortho) { | if (is_ortho) { | ||||
| scale_matrix = ca->ortho_scale * 0.5f; | scale_matrix = ca->ortho_scale * 0.5f; | ||||
| } | } | ||||
| else { | else { | ||||
| const float scale[3] = { | scale_matrix = ca->drawsize / ob_scale_uniform_inv; | ||||
| 1.0f / len_v3(ob->obmat[0]), | |||||
| 1.0f / len_v3(ob->obmat[1]), | |||||
| 1.0f / len_v3(ob->obmat[2]), | |||||
| }; | |||||
| scale_matrix = ca->drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f); | |||||
| } | } | ||||
| mul_v3_fl(widget->matrix_basis[0], scale_matrix); | mul_v3_fl(widget->matrix_basis[0], scale_matrix); | ||||
| mul_v3_fl(widget->matrix_basis[1], scale_matrix); | mul_v3_fl(widget->matrix_basis[1], scale_matrix); | ||||
| } | } | ||||
| RNA_float_set_array(widget->ptr, "aspect", aspect); | RNA_float_set_array(widget->ptr, "aspect", aspect); | ||||
| WM_manipulator_set_matrix_offset_location(widget, offset); | WM_manipulator_set_matrix_offset_location(widget, offset); | ||||
| const char *propname = is_ortho ? "ortho_scale" : "lens"; | |||||
| PropertyRNA *prop = RNA_struct_find_property(&camera_ptr, propname); | |||||
| const wmManipulatorPropertyType *mpr_prop_type = WM_manipulatortype_target_property_find(widget->type, "offset"); | |||||
| { | |||||
| WM_manipulator_target_property_clear_rna_ptr(widget, mpr_prop_type); | |||||
| const float half_sensor = 0.5f * ((ca->sensor_fit == CAMERA_SENSOR_FIT_VERT) ? ca->sensor_y : ca->sensor_x); | |||||
| float min, max, range; | |||||
| float step, precision; | |||||
| /* get property range */ | |||||
| RNA_property_float_ui_range(&camera_ptr, prop, &min, &max, &step, &precision); | |||||
| range = max - min; | |||||
| ED_manipulator_arrow3d_set_range_fac( | |||||
| widget, is_ortho ? | |||||
| (ca->drawsize * range) : | |||||
| (scale_matrix * range / half_sensor)); | |||||
| } | |||||
| /* need to set property here for undo. TODO would prefer to do this in _init */ | /* need to set property here for undo. TODO would prefer to do this in _init */ | ||||
| WM_manipulator_target_property_def_rna(camgroup->focal_len, "offset", &camera_ptr, "lens", -1); | WM_manipulator_target_property_def_rna_ptr(widget, mpr_prop_type, &camera_ptr, prop, -1); | ||||
| WM_manipulator_target_property_def_rna(camgroup->ortho_scale, "offset", &camera_ptr, "ortho_scale", -1); | } | ||||
| } | |||||
| static void WIDGETGROUP_camera_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup) | |||||
| { | |||||
| struct CameraWidgetGroup *camgroup = mgroup->customdata; | |||||
| ARegion *ar = CTX_wm_region(C); | |||||
| Object *ob = CTX_data_active_object(C); | |||||
| Camera *ca = ob->data; | |||||
| const bool is_ortho = (ca->type == CAM_ORTHO); | |||||
| wmManipulator *mpr = is_ortho ? camgroup->ortho_scale : camgroup->focal_len; | |||||
| /* explicit property use */ | |||||
| struct wmMsgBus *mbus = CTX_wm_message_bus(C); | |||||
| wmMsgSubscribeValue msg_sub_value_mpr_tag_refresh = { | |||||
| .owner = ar, | |||||
| .user_data = mpr->parent_mgroup->parent_mmap, | |||||
| .notify = WM_manipulator_do_msg_notify_tag_refresh, | |||||
| }; | |||||
| { | |||||
| extern PropertyRNA rna_Camera_dof_distance; | |||||
| extern PropertyRNA rna_Camera_draw_size; | |||||
| extern PropertyRNA rna_Camera_ortho_scale; | |||||
| extern PropertyRNA rna_Camera_sensor_fit; | |||||
| extern PropertyRNA rna_Camera_sensor_width; | |||||
| extern PropertyRNA rna_Camera_shift_x; | |||||
| extern PropertyRNA rna_Camera_shift_y; | |||||
| extern PropertyRNA rna_Camera_type; | |||||
| const PropertyRNA *props[] = { | |||||
| &rna_Camera_dof_distance, | |||||
| &rna_Camera_draw_size, | |||||
| &rna_Camera_ortho_scale, | |||||
| &rna_Camera_sensor_fit, | |||||
| &rna_Camera_sensor_width, | |||||
| &rna_Camera_shift_x, | |||||
| &rna_Camera_shift_y, | |||||
| &rna_Camera_type, | |||||
| }; | |||||
| PointerRNA idptr; | |||||
| RNA_id_pointer_create(&ca->id, &idptr); | |||||
| for (int i = 0; i < ARRAY_SIZE(props); i++) { | |||||
| WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_mpr_tag_refresh); | |||||
| } | |||||
| } | |||||
| /* Subscribe to render settings */ | |||||
| { | |||||
| WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_x, &msg_sub_value_mpr_tag_refresh); | |||||
| WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_y, &msg_sub_value_mpr_tag_refresh); | |||||
| WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_x, &msg_sub_value_mpr_tag_refresh); | |||||
| WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_y, &msg_sub_value_mpr_tag_refresh); | |||||
| } | } | ||||
| } | } | ||||
| void VIEW3D_WGT_camera(wmManipulatorGroupType *wgt) | void VIEW3D_WGT_camera(wmManipulatorGroupType *wgt) | ||||
| { | { | ||||
| wgt->name = "Camera Widgets"; | wgt->name = "Camera Widgets"; | ||||
| wgt->idname = "VIEW3D_WGT_camera"; | wgt->idname = "VIEW3D_WGT_camera"; | ||||
| wgt->flag = (WM_MANIPULATORGROUPTYPE_PERSISTENT | | wgt->flag = (WM_MANIPULATORGROUPTYPE_PERSISTENT | | ||||
| WM_MANIPULATORGROUPTYPE_3D | | WM_MANIPULATORGROUPTYPE_3D | | ||||
| WM_MANIPULATORGROUPTYPE_DEPTH_3D); | WM_MANIPULATORGROUPTYPE_DEPTH_3D); | ||||
| wgt->poll = WIDGETGROUP_camera_poll; | wgt->poll = WIDGETGROUP_camera_poll; | ||||
| wgt->setup = WIDGETGROUP_camera_setup; | wgt->setup = WIDGETGROUP_camera_setup; | ||||
| wgt->refresh = WIDGETGROUP_camera_refresh; | wgt->refresh = WIDGETGROUP_camera_refresh; | ||||
| wgt->draw_prepare = WIDGETGROUP_camera_draw_prepare; | |||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name CameraView Manipulators | /** \name CameraView Manipulators | ||||
| * \{ */ | * \{ */ | ||||
| ▲ Show 20 Lines • Show All 157 Lines • Show Last 20 Lines | |||||