diff options
author | Julian Eisel <julian@blender.org> | 2020-03-17 22:20:55 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-03-17 23:42:44 +0300 |
commit | dc2df8307f41888bab722f75fa9e73adecf86b72 (patch) | |
tree | f83c54f43e27a07e9cb9fed306d79b08864f29f2 /source/blender/editors | |
parent | 406bfd43040a5526702b51f88f1491cb61aecedb (diff) |
VR: Initial Virtual Reality support - Milestone 1, Scene Inspection
NOTE: While most of the milestone 1 goals are there, a few smaller features and
improvements are still to be done.
Big picture of this milestone: Initial, OpenXR-based virtual reality support
for users and foundation for advanced use cases.
Maniphest Task: https://developer.blender.org/T71347
The tasks contains more information about this milestone.
To be clear: This is not a feature rich VR implementation, it's focused on the
initial scene inspection use case. We intentionally focused on that, further
features like controller support are part of the next milestone.
- How to use?
Instructions on how to use this are here:
https://wiki.blender.org/wiki/User:Severin/GSoC-2019/How_to_Test
These will be updated and moved to a more official place (likely the manual) soon.
Currently Windows Mixed Reality and Oculus devices are usable. Valve/HTC
headsets don't support the OpenXR standard yet and hence, do not work with this
implementation.
---------------
This is the C-side implementation of the features added for initial VR
support as per milestone 1. A "VR Scene Inspection" Add-on will be
committed separately, to expose the VR functionality in the UI. It also
adds some further features for milestone 1, namely a landmarking system
(stored view locations in the VR space)
Main additions/features:
* Support for rendering viewports to an HMD, with good performance.
* Option to sync the VR view perspective with a fully interactive,
regular 3D View (VR-Mirror).
* Option to disable positional tracking. Keeps the current position (calculated
based on the VR eye center pose) when enabled while a VR session is running.
* Some regular viewport settings for the VR view
* RNA/Python-API to query and set VR session state information.
* WM-XR: Layer tying Ghost-XR to the Blender specific APIs/data
* wmSurface API: drawable, non-window container (manages Ghost-OpenGL and GPU
context)
* DNA/RNA for management of VR session settings
* `--debug-xr` and `--debug-xr-time` commandline options
* Utility batch & config file for using the Oculus runtime on Windows.
* Most VR data is runtime only. The exception is user settings which are saved
to files (`XrSessionSettings`).
* VR support can be disabled through the `WITH_XR_OPENXR` compiler flag.
For architecture and code documentation, see
https://wiki.blender.org/wiki/Source/Interface/XR.
---------------
A few thank you's:
* A huge shoutout to Ray Molenkamp for his help during the project - it would
have not been that successful without him!
* Sebastian Koenig and Simeon Conzendorf for testing and feedback!
* The reviewers, especially Brecht Van Lommel!
* Dalai Felinto for pushing and managing me to get this done ;)
* The OpenXR working group for providing an open standard. I think we're the
first bigger application to adopt OpenXR. Congratulations to them and
ourselves :)
This project started as a Google Summer of Code 2019 project - "Core Support of
Virtual Reality Headsets through OpenXR" (see
https://wiki.blender.org/wiki/User:Severin/GSoC-2019/).
Some further information, including ideas for further improvements can be found
in the final GSoC report:
https://wiki.blender.org/wiki/User:Severin/GSoC-2019/Final_Report
Differential Revisions: D6193, D7098
Reviewed by: Brecht Van Lommel, Jeroen Bakker
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/ED_view3d.h | 18 | ||||
-rw-r--r-- | source/blender/editors/include/ED_view3d_offscreen.h | 19 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 3 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_cursor.c | 13 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/CMakeLists.txt | 4 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 87 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 153 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 130 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_fly.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_gizmo_navigate.c | 35 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_utils.c | 20 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_view.c | 99 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_walk.c | 2 |
13 files changed, 457 insertions, 128 deletions
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index f882d6be9a2..06de4705ac6 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -561,6 +561,9 @@ struct RegionView3D *ED_view3d_context_rv3d(struct bContext *C); bool ED_view3d_context_user_region(struct bContext *C, struct View3D **r_v3d, struct ARegion **r_ar); +bool ED_view3d_area_user_region(const struct ScrArea *sa, + const struct View3D *v3d, + struct ARegion **r_ar); bool ED_operator_rv3d_user_region_poll(struct bContext *C); void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d); @@ -584,7 +587,8 @@ void ED_draw_object_facemap(struct Depsgraph *depsgraph, struct RenderEngineType *ED_view3d_engine_type(const struct Scene *scene, int drawtype); bool ED_view3d_context_activate(struct bContext *C); -void ED_view3d_draw_setup_view(struct wmWindow *win, +void ED_view3d_draw_setup_view(const struct wmWindowManager *wm, + struct wmWindow *win, struct Depsgraph *depsgraph, struct Scene *scene, struct ARegion *region, @@ -730,6 +734,18 @@ void ED_view3d_buttons_region_layout_ex(const struct bContext *C, bool ED_view3d_local_collections_set(struct Main *bmain, struct View3D *v3d); void ED_view3d_local_collections_reset(struct bContext *C, const bool reset_all); +#ifdef WITH_XR_OPENXR +void ED_view3d_xr_mirror_update(const struct ScrArea *area, + const struct View3D *v3d, + const bool enable); +void ED_view3d_xr_shading_update(struct wmWindowManager *wm, + const View3D *v3d, + const struct Scene *scene); +bool ED_view3d_is_region_xr_mirror_active(const struct wmWindowManager *wm, + const struct View3D *v3d, + const struct ARegion *region); +#endif + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/include/ED_view3d_offscreen.h b/source/blender/editors/include/ED_view3d_offscreen.h index 3cbb13fa8b5..e1ed7472973 100644 --- a/source/blender/editors/include/ED_view3d_offscreen.h +++ b/source/blender/editors/include/ED_view3d_offscreen.h @@ -51,12 +51,31 @@ void ED_view3d_draw_offscreen(struct Depsgraph *depsgraph, int winy, float viewmat[4][4], float winmat[4][4], + bool is_image_render, bool do_sky, bool is_persp, const char *viewname, const bool do_color_management, struct GPUOffScreen *ofs, struct GPUViewport *viewport); +void ED_view3d_draw_offscreen_simple(struct Depsgraph *depsgraph, + struct Scene *scene, + struct View3DShading *shading_override, + int drawtype, + int winx, + int winy, + unsigned int draw_flags, + float viewmat[4][4], + float winmat[4][4], + float clip_start, + float clip_end, + bool is_image_render, + bool do_sky, + bool is_persp, + const char *viewname, + const bool do_color_management, + struct GPUOffScreen *ofs, + struct GPUViewport *viewport); struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Depsgraph *depsgraph, struct Scene *scene, diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index a9f44f54b3a..a72b18f63f8 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3818,6 +3818,7 @@ static void region_quadview_init_rv3d( } rv3d->viewlock = viewlock; + rv3d->runtime_viewlock = 0; rv3d->view = view; rv3d->view_axis_roll = RV3D_VIEW_AXIS_ROLL_0; rv3d->persp = persp; @@ -3915,7 +3916,7 @@ static int region_quadview_exec(bContext *C, wmOperator *op) RegionView3D *rv3d = region->regiondata; const char viewlock = (rv3d->viewlock_quad & RV3D_VIEWLOCK_INIT) ? (rv3d->viewlock_quad & ~RV3D_VIEWLOCK_INIT) : - RV3D_LOCKED; + RV3D_LOCK_ROTATION; region_quadview_init_rv3d( sa, region, viewlock, ED_view3d_lock_view_from_index(index_qsplit++), RV3D_ORTHO); diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index dd922834d9e..0ddce872545 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -1239,6 +1239,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) return; } + const wmWindowManager *wm = CTX_wm_manager(C); Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); Scene *scene = CTX_data_scene(C); UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; @@ -1443,7 +1444,8 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) /* Draw 3D brush cursor. */ GPU_matrix_push_projection(); - ED_view3d_draw_setup_view(CTX_wm_window(C), + ED_view3d_draw_setup_view(wm, + CTX_wm_window(C), CTX_data_depsgraph_pointer(C), CTX_data_scene(C), region, @@ -1537,7 +1539,8 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) !is_multires) { if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && ss->deform_modifiers_active) { GPU_matrix_push_projection(); - ED_view3d_draw_setup_view(CTX_wm_window(C), + ED_view3d_draw_setup_view(wm, + CTX_wm_window(C), CTX_data_depsgraph_pointer(C), CTX_data_scene(C), region, @@ -1556,7 +1559,8 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) if (brush->sculpt_tool == SCULPT_TOOL_MULTIPLANE_SCRAPE && brush->flag2 & BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW && !ss->cache->first_time) { GPU_matrix_push_projection(); - ED_view3d_draw_setup_view(CTX_wm_window(C), + ED_view3d_draw_setup_view(wm, + CTX_wm_window(C), CTX_data_depsgraph_pointer(C), CTX_data_scene(C), region, @@ -1573,7 +1577,8 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) if (brush->sculpt_tool == SCULPT_TOOL_CLOTH && !ss->cache->first_time) { GPU_matrix_push_projection(); - ED_view3d_draw_setup_view(CTX_wm_window(C), + ED_view3d_draw_setup_view(CTX_wm_manager(C), + CTX_wm_window(C), CTX_data_depsgraph_pointer(C), CTX_data_scene(C), region, diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 91694cfc1ef..c7fe82e0cbb 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -94,6 +94,10 @@ if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() +if(WITH_XR_OPENXR) + add_definitions(-DWITH_XR_OPENXR) +endif() + blender_add_lib(bf_editor_space_view3d "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") # Needed so we can use dna_type_offsets.h for defaults initialization. diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index b2fc6c6e4cc..f16e19c598e 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -39,6 +39,7 @@ #include "BKE_context.h" #include "BKE_curve.h" +#include "BKE_global.h" #include "BKE_icons.h" #include "BKE_idprop.h" #include "BKE_lattice.h" @@ -114,44 +115,61 @@ bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_ar) if (region) { RegionView3D *rv3d; if ((region->regiontype == RGN_TYPE_WINDOW) && (rv3d = region->regiondata) && - (rv3d->viewlock & RV3D_LOCKED) == 0) { + (rv3d->viewlock & RV3D_LOCK_ROTATION) == 0) { *r_v3d = v3d; *r_ar = region; return true; } else { - ARegion *ar_unlock_user = NULL; - ARegion *ar_unlock = NULL; - for (region = sa->regionbase.first; region; region = region->next) { - /* find the first unlocked rv3d */ - if (region->regiondata && region->regiontype == RGN_TYPE_WINDOW) { - rv3d = region->regiondata; - if ((rv3d->viewlock & RV3D_LOCKED) == 0) { - ar_unlock = region; - if (rv3d->persp == RV3D_PERSP || rv3d->persp == RV3D_CAMOB) { - ar_unlock_user = region; - break; - } - } - } - } - - /* camera/perspective view get priority when the active region is locked */ - if (ar_unlock_user) { + if (ED_view3d_area_user_region(sa, v3d, r_ar)) { *r_v3d = v3d; - *r_ar = ar_unlock_user; return true; } + } + } + } - if (ar_unlock) { - *r_v3d = v3d; - *r_ar = ar_unlock; - return true; + return false; +} + +/** + * Similar to #ED_view3d_context_user_region() but does not use context. Always performs a lookup. + * Also works if \a v3d is not the active space. + */ +bool ED_view3d_area_user_region(const ScrArea *sa, const View3D *v3d, ARegion **r_ar) +{ + RegionView3D *rv3d = NULL; + ARegion *ar_unlock_user = NULL; + ARegion *ar_unlock = NULL; + const ListBase *region_list = (v3d == sa->spacedata.first) ? &sa->regionbase : &v3d->regionbase; + + BLI_assert(v3d->spacetype == SPACE_VIEW3D); + + for (ARegion *region = region_list->first; region; region = region->next) { + /* find the first unlocked rv3d */ + if (region->regiondata && region->regiontype == RGN_TYPE_WINDOW) { + rv3d = region->regiondata; + if ((rv3d->viewlock & RV3D_LOCK_ROTATION) == 0) { + ar_unlock = region; + if (rv3d->persp == RV3D_PERSP || rv3d->persp == RV3D_CAMOB) { + ar_unlock_user = region; + break; } } } } + /* camera/perspective view get priority when the active region is locked */ + if (ar_unlock_user) { + *r_ar = ar_unlock_user; + return true; + } + + if (ar_unlock) { + *r_ar = ar_unlock; + return true; + } + return false; } @@ -333,9 +351,11 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) v3dn->localvd = NULL; v3dn->runtime.properties_storage = NULL; } + /* Only one View3D is allowed to have this flag! */ + v3dn->runtime.flag &= ~V3D_RUNTIME_XR_SESSION_ROOT; v3dn->local_collections_uuid = 0; - v3dn->flag &= ~V3D_LOCAL_COLLECTIONS; + v3dn->flag &= ~(V3D_LOCAL_COLLECTIONS | V3D_XR_SESSION_MIRROR); if (v3dn->shading.type == OB_RENDER) { v3dn->shading.type = OB_SOLID; @@ -715,6 +735,13 @@ static void view3d_main_region_listener( if (ELEM(wmn->data, ND_UNDO)) { WM_gizmomap_tag_refresh(gzmap); } + else if (ELEM(wmn->data, ND_XR_DATA_CHANGED)) { + /* Only cause a redraw if this a VR session mirror. Should more features be added that + * require redraws, we could pass something to wmn->reference, e.g. the flag value. */ + if (v3d->flag & V3D_XR_SESSION_MIRROR) { + ED_region_tag_redraw(region); + } + } break; case NC_ANIMATION: switch (wmn->data) { @@ -912,6 +939,11 @@ static void view3d_main_region_listener( if (wmn->subtype == NS_VIEW3D_GPU) { rv3d->rflag |= RV3D_GPULIGHT_UPDATE; } +#ifdef WITH_XR_OPENXR + else if (wmn->subtype == NS_VIEW3D_SHADING) { + ED_view3d_xr_shading_update(G_MAIN->wm.first, v3d, scene); + } +#endif ED_region_tag_redraw(region); WM_gizmomap_tag_refresh(gzmap); } @@ -1374,6 +1406,11 @@ static void view3d_buttons_region_listener(wmWindow *UNUSED(win), ED_region_tag_redraw(region); } break; + case NC_WM: + if (wmn->data == ND_XR_DATA_CHANGED) { + ED_region_tag_redraw(region); + } + break; } } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 4cf5ecfc4f0..78d053c36a7 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -317,10 +317,35 @@ static void view3d_stereo3d_setup( } } +#ifdef WITH_XR_OPENXR +static void view3d_xr_mirror_setup(const wmWindowManager *wm, + Depsgraph *depsgraph, + Scene *scene, + View3D *v3d, + ARegion *region, + const rcti *rect) +{ + RegionView3D *rv3d = region->regiondata; + float viewmat[4][4]; + const float lens_old = v3d->lens; + + if (!WM_xr_session_state_viewer_pose_matrix_info_get(&wm->xr, viewmat, &v3d->lens)) { + /* Can't get info from XR session, use fallback values. */ + copy_m4_m4(viewmat, rv3d->viewmat); + v3d->lens = lens_old; + } + view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, NULL, rect); + + /* Reset overridden View3D data */ + v3d->lens = lens_old; +} +#endif /* WITH_XR_OPENXR */ + /** * Set the correct matrices */ -void ED_view3d_draw_setup_view(wmWindow *win, +void ED_view3d_draw_setup_view(const wmWindowManager *wm, + wmWindow *win, Depsgraph *depsgraph, Scene *scene, ARegion *region, @@ -331,13 +356,23 @@ void ED_view3d_draw_setup_view(wmWindow *win, { RegionView3D *rv3d = region->regiondata; +#ifdef WITH_XR_OPENXR /* Setup the view matrix. */ - if (view3d_stereo3d_active(win, scene, v3d, rv3d)) { + if (ED_view3d_is_region_xr_mirror_active(wm, v3d, region)) { + view3d_xr_mirror_setup(wm, depsgraph, scene, v3d, region, rect); + } + else +#endif + if (view3d_stereo3d_active(win, scene, v3d, rv3d)) { view3d_stereo3d_setup(depsgraph, scene, v3d, region, rect); } else { view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, winmat, rect); } + +#ifndef WITH_XR_OPENXR + UNUSED_VARS(wm); +#endif } /** \} */ @@ -803,7 +838,8 @@ void ED_view3d_draw_depth(Depsgraph *depsgraph, ARegion *region, View3D *v3d, bo UI_Theme_Store(&theme_state); UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW); - ED_view3d_draw_setup_view(NULL, depsgraph, scene, region, v3d, NULL, NULL, NULL); + ED_view3d_draw_setup_view( + G_MAIN->wm.first, NULL, depsgraph, scene, region, v3d, NULL, NULL, NULL); GPU_clear(GPU_DEPTH_BIT); @@ -1481,7 +1517,7 @@ void view3d_draw_region_info(const bContext *C, ARegion *region) wmWindowManager *wm = CTX_wm_manager(C); #ifdef WITH_INPUT_NDOF - if ((U.ndof_flag & NDOF_SHOW_GUIDE) && ((rv3d->viewlock & RV3D_LOCKED) == 0) && + if ((U.ndof_flag & NDOF_SHOW_GUIDE) && ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) && (rv3d->persp != RV3D_CAMOB)) { /* TODO: draw something else (but not this) during fly mode */ draw_rotation_guide(rv3d); @@ -1552,7 +1588,8 @@ void view3d_draw_region_info(const bContext *C, ARegion *region) static void view3d_draw_view(const bContext *C, ARegion *region) { - ED_view3d_draw_setup_view(CTX_wm_window(C), + ED_view3d_draw_setup_view(CTX_wm_manager(C), + CTX_wm_window(C), CTX_data_expect_evaluated_depsgraph(C), CTX_data_scene(C), region, @@ -1641,6 +1678,7 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph, int winy, float viewmat[4][4], float winmat[4][4], + bool is_image_render, bool do_sky, bool UNUSED(is_persp), const char *viewname, @@ -1690,8 +1728,15 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph, } /* main drawing call */ - DRW_draw_render_loop_offscreen( - depsgraph, engine_type, region, v3d, do_sky, do_color_management, ofs, viewport); + DRW_draw_render_loop_offscreen(depsgraph, + engine_type, + region, + v3d, + is_image_render, + do_sky, + do_color_management, + ofs, + viewport); /* restore size */ region->winx = bwinx; @@ -1707,6 +1752,94 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph, } /** + * Creates own fake 3d views (wrapping #ED_view3d_draw_offscreen). Similar too + * #ED_view_draw_offscreen_imbuf_simple, but takes view/projection matrices as arguments. + */ +void ED_view3d_draw_offscreen_simple(Depsgraph *depsgraph, + Scene *scene, + View3DShading *shading_override, + int drawtype, + int winx, + int winy, + uint draw_flags, + float viewmat[4][4], + float winmat[4][4], + float clip_start, + float clip_end, + bool is_image_render, + bool do_sky, + bool is_persp, + const char *viewname, + const bool do_color_management, + GPUOffScreen *ofs, + GPUViewport *viewport) +{ + View3D v3d = {NULL}; + ARegion ar = {NULL}; + RegionView3D rv3d = {{{0}}}; + + v3d.regionbase.first = v3d.regionbase.last = &ar; + ar.regiondata = &rv3d; + ar.regiontype = RGN_TYPE_WINDOW; + + View3DShading *source_shading_settings = &scene->display.shading; + if (draw_flags & V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS && shading_override != NULL) { + source_shading_settings = shading_override; + } + memcpy(&v3d.shading, source_shading_settings, sizeof(View3DShading)); + v3d.shading.type = drawtype; + + if (shading_override) { + /* Pass. */ + } + else if (drawtype == OB_MATERIAL) { + v3d.shading.flag = V3D_SHADING_SCENE_WORLD | V3D_SHADING_SCENE_LIGHTS; + } + + if (draw_flags & V3D_OFSDRAW_SHOW_ANNOTATION) { + v3d.flag2 |= V3D_SHOW_ANNOTATION; + } + if (draw_flags & V3D_OFSDRAW_SHOW_GRIDFLOOR) { + v3d.gridflag |= V3D_SHOW_FLOOR | V3D_SHOW_X | V3D_SHOW_Y; + v3d.grid = 1.0f; + v3d.gridlines = 16; + v3d.gridsubdiv = 10; + + /* Show grid, disable other overlays (set all available _HIDE_ flags). */ + v3d.overlay.flag |= V3D_OVERLAY_HIDE_CURSOR | V3D_OVERLAY_HIDE_TEXT | + V3D_OVERLAY_HIDE_MOTION_PATHS | V3D_OVERLAY_HIDE_BONES | + V3D_OVERLAY_HIDE_OBJECT_XTRAS | V3D_OVERLAY_HIDE_OBJECT_ORIGINS; + v3d.flag |= V3D_HIDE_HELPLINES; + } + else { + v3d.flag2 = V3D_HIDE_OVERLAYS; + } + + rv3d.persp = RV3D_PERSP; + v3d.clip_start = clip_start; + v3d.clip_end = clip_end; + /* Actually not used since we pass in the projection matrix. */ + v3d.lens = 0; + + ED_view3d_draw_offscreen(depsgraph, + scene, + drawtype, + &v3d, + &ar, + winx, + winy, + viewmat, + winmat, + is_image_render, + do_sky, + is_persp, + viewname, + do_color_management, + ofs, + viewport); +} + +/** * Utility func for ED_view3d_draw_offscreen * * \param ofs: Optional off-screen buffer, can be NULL. @@ -1815,6 +1948,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph, sizey, NULL, winmat, + true, draw_sky, !is_ortho, viewname, @@ -1902,6 +2036,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph, if (draw_flags & V3D_OFSDRAW_SHOW_ANNOTATION) { v3d.flag2 |= V3D_SHOW_ANNOTATION; } + if (draw_flags & V3D_OFSDRAW_SHOW_GRIDFLOOR) { + v3d.gridflag |= V3D_SHOW_FLOOR | V3D_SHOW_X | V3D_SHOW_Y; + } v3d.shading.background_type = V3D_SHADING_BACKGROUND_WORLD; @@ -2212,7 +2349,7 @@ float view3d_depth_near(ViewDepths *d) void ED_view3d_draw_depth_gpencil(Depsgraph *depsgraph, Scene *scene, ARegion *region, View3D *v3d) { /* Setup view matrix. */ - ED_view3d_draw_setup_view(NULL, depsgraph, scene, region, v3d, NULL, NULL, NULL); + ED_view3d_draw_setup_view(NULL, NULL, depsgraph, scene, region, v3d, NULL, NULL, NULL); GPU_clear(GPU_DEPTH_BIT); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index a7136cc580c..68d5765e43d 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -85,6 +85,52 @@ enum { HAS_ROTATE = (1 << 0), }; +/* test for unlocked camera view in quad view */ +static bool view3d_camera_user_poll(bContext *C) +{ + View3D *v3d; + ARegion *region; + + if (ED_view3d_context_user_region(C, &v3d, ®ion)) { + RegionView3D *rv3d = region->regiondata; + if ((rv3d->persp == RV3D_CAMOB) && !(RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ANY_TRANSFORM)) { + return 1; + } + } + + return 0; +} + +static bool view3d_lock_poll(bContext *C) +{ + View3D *v3d = CTX_wm_view3d(C); + if (v3d) { + RegionView3D *rv3d = CTX_wm_region_view3d(C); + if (rv3d) { + return ED_view3d_offset_lock_check(v3d, rv3d); + } + } + return false; +} + +static bool view3d_pan_poll(bContext *C) +{ + if (ED_operator_region_view3d_active(C)) { + const RegionView3D *rv3d = CTX_wm_region_view3d(C); + return !(RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_LOCATION); + } + return false; +} + +static bool view3d_zoom_or_dolly_poll(bContext *C) +{ + if (ED_operator_region_view3d_active(C)) { + const RegionView3D *rv3d = CTX_wm_region_view3d(C); + return !(RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ZOOM_AND_DOLLY); + } + return false; +} + /* -------------------------------------------------------------------- */ /** \name Generic View Operator Properties * \{ */ @@ -935,7 +981,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event) vod = op->customdata; /* poll should check but in some cases fails, see poll func for details */ - if (vod->rv3d->viewlock & RV3D_LOCKED) { + if (RV3D_LOCK_FLAGS(vod->rv3d) & RV3D_LOCK_ROTATION) { viewops_data_free(C, op); return OPERATOR_PASS_THROUGH; } @@ -983,34 +1029,6 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event) } } -/* test for unlocked camera view in quad view */ -static bool view3d_camera_user_poll(bContext *C) -{ - View3D *v3d; - ARegion *region; - - if (ED_view3d_context_user_region(C, &v3d, ®ion)) { - RegionView3D *rv3d = region->regiondata; - if (rv3d->persp == RV3D_CAMOB) { - return 1; - } - } - - return 0; -} - -static bool view3d_lock_poll(bContext *C) -{ - View3D *v3d = CTX_wm_view3d(C); - if (v3d) { - RegionView3D *rv3d = CTX_wm_region_view3d(C); - if (rv3d) { - return ED_view3d_offset_lock_check(v3d, rv3d); - } - } - return false; -} - static void viewrotate_cancel(bContext *C, wmOperator *op) { viewops_data_free(C, op); @@ -1051,7 +1069,7 @@ static bool ndof_has_translate(const wmNDOFMotionData *ndof, static bool ndof_has_rotate(const wmNDOFMotionData *ndof, const RegionView3D *rv3d) { - return !is_zero_v3(ndof->rvec) && ((rv3d->viewlock & RV3D_LOCKED) == 0); + return !is_zero_v3(ndof->rvec) && ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0); } /** @@ -1159,7 +1177,7 @@ static void view3d_ndof_pan_zoom(const struct wmNDOFMotionData *ndof, /* move center of view opposite of hand motion (this is camera mode, not object mode) */ sub_v3_v3(rv3d->ofs, pan_vec); - if (rv3d->viewlock & RV3D_BOXVIEW) { + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) { view3d_boxview_sync(sa, region); } } @@ -1176,7 +1194,7 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, float view_inv[4]; - BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0); + BLI_assert((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0); ED_view3d_persp_ensure(vod->depsgraph, v3d, region); @@ -1400,7 +1418,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event) const bool has_rotation = ndof_has_rotate(ndof, rv3d); /* if we can't rotate, fallback to translate (locked axis views) */ const bool has_translate = ndof_has_translate(ndof, v3d, rv3d) && - (rv3d->viewlock & RV3D_LOCKED); + (RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION); const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp; if (has_translate || has_zoom) { @@ -1732,7 +1750,7 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y) add_v3_v3(vod->rv3d->ofs, dvec); - if (vod->rv3d->viewlock & RV3D_BOXVIEW) { + if (RV3D_LOCK_FLAGS(vod->rv3d) & RV3D_BOXVIEW) { view3d_boxview_sync(vod->sa, vod->region); } } @@ -1807,12 +1825,17 @@ static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* makes op->customdata */ viewops_data_alloc(C, op); + vod = op->customdata; + if (RV3D_LOCK_FLAGS(vod->rv3d) & RV3D_LOCK_LOCATION) { + viewops_data_free(C, op); + return OPERATOR_PASS_THROUGH; + } + viewops_data_create(C, op, event, (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) | (use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0)); - vod = op->customdata; ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region); @@ -2165,7 +2188,7 @@ static void viewzoom_apply_3d(ViewOpsData *vod, /* these limits were in old code too */ CLAMP(vod->rv3d->dist, dist_range[0], dist_range[1]); - if (vod->rv3d->viewlock & RV3D_BOXVIEW) { + if (RV3D_LOCK_FLAGS(vod->rv3d) & RV3D_BOXVIEW) { view3d_boxview_sync(vod->sa, vod->region); } @@ -2318,7 +2341,7 @@ static int viewzoom_exec(bContext *C, wmOperator *op) } } - if (rv3d->viewlock & RV3D_BOXVIEW) { + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) { view3d_boxview_sync(sa, region); } @@ -2416,7 +2439,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot) ot->invoke = viewzoom_invoke; ot->exec = viewzoom_exec; ot->modal = viewzoom_modal; - ot->poll = ED_operator_region_view3d_active; + ot->poll = view3d_zoom_or_dolly_poll; ot->cancel = viewzoom_cancel; /* flags */ @@ -2514,7 +2537,7 @@ static void viewdolly_apply(ViewOpsData *vod, const int xy[2], const short zoom_ view_dolly_to_vector_3d(vod->region, vod->init.ofs, vod->init.mousevec, zfac); } - if (vod->rv3d->viewlock & RV3D_BOXVIEW) { + if (RV3D_LOCK_FLAGS(vod->rv3d) & RV3D_BOXVIEW) { view3d_boxview_sync(vod->sa, vod->region); } @@ -2612,7 +2635,7 @@ static int viewdolly_exec(bContext *C, wmOperator *op) view_dolly_to_vector_3d(region, rv3d->ofs, mousevec, delta < 0 ? 0.2f : 1.8f); - if (rv3d->viewlock & RV3D_BOXVIEW) { + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) { view3d_boxview_sync(sa, region); } @@ -2641,7 +2664,7 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event) vod = op->customdata; /* poll should check but in some cases fails, see poll func for details */ - if (vod->rv3d->viewlock & RV3D_LOCKED) { + if (RV3D_LOCK_FLAGS(vod->rv3d) & RV3D_LOCK_ROTATION) { viewops_data_free(C, op); return OPERATOR_PASS_THROUGH; } @@ -3121,7 +3144,7 @@ void VIEW3D_OT_view_selected(wmOperatorType *ot) /* api callbacks */ ot->exec = viewselected_exec; - ot->poll = ED_operator_region_view3d_active; + ot->poll = view3d_zoom_or_dolly_poll; /* flags */ ot->flag = 0; @@ -3265,7 +3288,7 @@ void VIEW3D_OT_view_center_cursor(wmOperatorType *ot) /* api callbacks */ ot->exec = viewcenter_cursor_exec; - ot->poll = ED_operator_view3d_active; + ot->poll = view3d_pan_poll; /* flags */ ot->flag = 0; @@ -3317,7 +3340,7 @@ void VIEW3D_OT_view_center_pick(wmOperatorType *ot) /* api callbacks */ ot->invoke = viewcenter_pick_invoke; - ot->poll = ED_operator_view3d_active; + ot->poll = view3d_pan_poll; /* flags */ ot->flag = 0; @@ -3701,7 +3724,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) .dist = &new_dist, }); - if (rv3d->viewlock & RV3D_BOXVIEW) { + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) { view3d_boxview_sync(CTX_wm_area(C), region); } @@ -3721,7 +3744,7 @@ void VIEW3D_OT_zoom_border(wmOperatorType *ot) ot->modal = WM_gesture_box_modal; ot->cancel = WM_gesture_box_cancel; - ot->poll = ED_operator_region_view3d_active; + ot->poll = view3d_zoom_or_dolly_poll; /* flags */ ot->flag = 0; @@ -3834,7 +3857,7 @@ static void axis_set_view(bContext *C, rv3d->view_axis_roll = view_axis_roll; } - if (rv3d->viewlock & RV3D_LOCKED) { + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) { ED_region_tag_redraw(region); return; } @@ -4058,7 +4081,7 @@ static int view_camera_exec(bContext *C, wmOperator *op) ED_view3d_smooth_view_force_finish(C, v3d, region); - if ((rv3d->viewlock & RV3D_LOCKED) == 0) { + if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ANY_TRANSFORM) == 0) { /* lastview - */ ViewLayer *view_layer = CTX_data_view_layer(C); @@ -4207,7 +4230,7 @@ static int vieworbit_exec(bContext *C, wmOperator *op) RV3D_VIEW_USER; orbitdir = RNA_enum_get(op->ptr, "type"); - if ((rv3d->viewlock & RV3D_LOCKED) && (view_opposite == RV3D_VIEW_USER)) { + if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) && (view_opposite == RV3D_VIEW_USER)) { /* no NULL check is needed, poll checks */ ED_view3d_context_user_region(C, &v3d, ®ion); rv3d = region->regiondata; @@ -4215,7 +4238,7 @@ static int vieworbit_exec(bContext *C, wmOperator *op) ED_view3d_smooth_view_force_finish(C, v3d, region); - if ((rv3d->viewlock & RV3D_LOCKED) == 0 || (view_opposite != RV3D_VIEW_USER)) { + if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0 || (view_opposite != RV3D_VIEW_USER)) { if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) { int smooth_viewtx = WM_operator_smooth_viewtx_get(op); float quat_mul[4]; @@ -4352,7 +4375,7 @@ static void viewroll_apply(ViewOpsData *vod, int x, int UNUSED(y)) vod->rv3d->ofs, vod->init.ofs, vod->init.quat, vod->rv3d->viewquat, vod->dyn_ofs); } - if (vod->rv3d->viewlock & RV3D_BOXVIEW) { + if (RV3D_LOCK_FLAGS(vod->rv3d) & RV3D_BOXVIEW) { view3d_boxview_sync(vod->sa, vod->region); } @@ -4621,7 +4644,7 @@ void VIEW3D_OT_view_pan(wmOperatorType *ot) /* api callbacks */ ot->invoke = viewpan_invoke; - ot->poll = ED_operator_region_view3d_active; + ot->poll = view3d_pan_poll; /* flags */ ot->flag = 0; @@ -4647,7 +4670,8 @@ static int viewpersportho_exec(bContext *C, wmOperator *UNUSED(op)) ED_view3d_context_user_region(C, &v3d_dummy, ®ion); rv3d = region->regiondata; - if ((rv3d->viewlock & RV3D_LOCKED) == 0) { + /* Could add a separate lock flag for locking persp. */ + if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ANY_TRANSFORM) == 0) { if (rv3d->persp != RV3D_ORTHO) { rv3d->persp = RV3D_ORTHO; } diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index eb7b1412fde..b32bcbde3e9 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -1039,7 +1039,7 @@ static int fly_invoke(bContext *C, wmOperator *op, const wmEvent *event) RegionView3D *rv3d = CTX_wm_region_view3d(C); FlyInfo *fly; - if (rv3d->viewlock & RV3D_LOCKED) { + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ANY_TRANSFORM) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c index 422cba7c52e..91a2ee297ad 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c @@ -252,14 +252,14 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g (navgroup->state.rect_visible.ymax == rect_visible->ymax) && (navgroup->state.rv3d.is_persp == rv3d->is_persp) && (navgroup->state.rv3d.is_camera == (rv3d->persp == RV3D_CAMOB)) && - (navgroup->state.rv3d.viewlock == rv3d->viewlock)) { + (navgroup->state.rv3d.viewlock == RV3D_LOCK_FLAGS(rv3d))) { return; } navgroup->state.rect_visible = *rect_visible; navgroup->state.rv3d.is_persp = rv3d->is_persp; navgroup->state.rv3d.is_camera = (rv3d->persp == RV3D_CAMOB); - navgroup->state.rv3d.viewlock = rv3d->viewlock; + navgroup->state.rv3d.viewlock = RV3D_LOCK_FLAGS(rv3d); const bool show_navigate = (U.uiflag & USER_SHOW_GIZMO_NAVIGATE) != 0; const bool show_rotate_gizmo = (U.mini_axis_type == USER_MINI_AXIS_TYPE_GIZMO); @@ -296,7 +296,6 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true); } - /* RV3D_LOCKED or Camera: only show supported buttons. */ if (show_rotate_gizmo) { gz = navgroup->gz_array[GZ_INDEX_ROTATE]; gz->matrix_basis[3][0] = co_rotate[0]; @@ -306,26 +305,30 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g if (show_navigate) { int icon_mini_slot = 0; - gz = navgroup->gz_array[GZ_INDEX_ZOOM]; - gz->matrix_basis[3][0] = roundf(co[0]); - gz->matrix_basis[3][1] = roundf(co[1] - (icon_offset_mini * icon_mini_slot++)); - WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); - - gz = navgroup->gz_array[GZ_INDEX_MOVE]; - gz->matrix_basis[3][0] = roundf(co[0]); - gz->matrix_basis[3][1] = roundf(co[1] - (icon_offset_mini * icon_mini_slot++)); - WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); + if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ZOOM_AND_DOLLY) == 0) { + gz = navgroup->gz_array[GZ_INDEX_ZOOM]; + gz->matrix_basis[3][0] = roundf(co[0]); + gz->matrix_basis[3][1] = roundf(co[1] - (icon_offset_mini * icon_mini_slot++)); + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); + } - if ((rv3d->viewlock & RV3D_LOCKED) == 0) { - gz = navgroup->gz_array[GZ_INDEX_CAMERA]; + if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_LOCATION) == 0) { + gz = navgroup->gz_array[GZ_INDEX_MOVE]; gz->matrix_basis[3][0] = roundf(co[0]); gz->matrix_basis[3][1] = roundf(co[1] - (icon_offset_mini * icon_mini_slot++)); WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); + } + + if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) { + gz = navgroup->gz_array[GZ_INDEX_CAMERA]; + gz->matrix_basis[3][0] = co[0]; + gz->matrix_basis[3][1] = co[1] - (icon_offset_mini * icon_mini_slot++); + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); if (navgroup->state.rv3d.is_camera == false) { gz = navgroup->gz_array[rv3d->is_persp ? GZ_INDEX_PERSP : GZ_INDEX_ORTHO]; - gz->matrix_basis[3][0] = roundf(co[0]); - gz->matrix_basis[3][1] = roundf(co[1] - (icon_offset_mini * icon_mini_slot++)); + gz->matrix_basis[3][0] = co[0]; + gz->matrix_basis[3][1] = co[1] - (icon_offset_mini * icon_mini_slot++); WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); } } diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index bad283740c8..55778db7353 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -459,7 +459,7 @@ bool ED_view3d_persp_ensure(const Depsgraph *depsgraph, View3D *v3d, ARegion *re RegionView3D *rv3d = region->regiondata; const bool autopersp = (U.uiflag & USER_AUTOPERSP) != 0; - BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0); + BLI_assert((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ANY_TRANSFORM) == 0); if (ED_view3d_camera_lock_check(v3d, rv3d)) { return false; @@ -679,7 +679,7 @@ static void view3d_boxview_clip(ScrArea *sa) if (region->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3d = region->regiondata; - if (rv3d->viewlock & RV3D_BOXCLIP) { + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) { if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) { if (region->winx > region->winy) { x1 = rv3d->dist; @@ -751,7 +751,7 @@ static void view3d_boxview_clip(ScrArea *sa) if (region->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3d = region->regiondata; - if (rv3d->viewlock & RV3D_BOXCLIP) { + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) { rv3d->rflag |= RV3D_CLIPPING; memcpy(rv3d->clip, clip, sizeof(clip)); if (rv3d->clipbb) { @@ -822,10 +822,10 @@ void view3d_boxview_sync(ScrArea *sa, ARegion *region) if (artest != region && artest->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3dtest = artest->regiondata; - if (rv3dtest->viewlock & RV3D_LOCKED) { + if (RV3D_LOCK_FLAGS(rv3dtest) & RV3D_LOCK_ROTATION) { rv3dtest->dist = rv3d->dist; view3d_boxview_sync_axis(rv3dtest, rv3d); - clip |= rv3dtest->viewlock & RV3D_BOXCLIP; + clip |= RV3D_LOCK_FLAGS(rv3dtest) & RV3D_BOXCLIP; ED_region_tag_redraw(artest); } @@ -848,12 +848,12 @@ void view3d_boxview_copy(ScrArea *sa, ARegion *region) if (artest != region && artest->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3dtest = artest->regiondata; - if (rv3dtest->viewlock) { + if (RV3D_LOCK_FLAGS(rv3dtest)) { rv3dtest->dist = rv3d->dist; copy_v3_v3(rv3dtest->ofs, rv3d->ofs); ED_region_tag_redraw(artest); - clip |= ((rv3dtest->viewlock & RV3D_BOXCLIP) != 0); + clip |= ((RV3D_LOCK_FLAGS(rv3dtest) & RV3D_BOXCLIP) != 0); } } } @@ -874,7 +874,7 @@ void ED_view3d_quadview_update(ScrArea *sa, ARegion *region, bool do_clip) * properties are always being edited, weak */ viewlock = rv3d->viewlock; - if ((viewlock & RV3D_LOCKED) == 0) { + if ((viewlock & RV3D_LOCK_ROTATION) == 0) { do_clip = (viewlock & RV3D_BOXCLIP) != 0; viewlock = 0; } @@ -899,12 +899,12 @@ void ED_view3d_quadview_update(ScrArea *sa, ARegion *region, bool do_clip) } } - if (rv3d->viewlock & RV3D_BOXVIEW) { + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) { view3d_boxview_sync(sa, ar_sync ? ar_sync : sa->regionbase.last); } /* ensure locked regions have an axis, locked user views don't make much sense */ - if (viewlock & RV3D_LOCKED) { + if (viewlock & RV3D_LOCK_ROTATION) { int index_qsplit = 0; for (region = sa->regionbase.first; region; region = region->next) { if (region->alignment == RGN_ALIGN_QSPLIT) { diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index b27bdf93389..159ea249337 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -36,6 +36,7 @@ #include "BKE_action.h" #include "BKE_camera.h" #include "BKE_context.h" +#include "BKE_idprop.h" #include "BKE_object.h" #include "BKE_global.h" #include "BKE_layer.h" @@ -228,7 +229,7 @@ void ED_view3d_smooth_view_ex( ob_camera_old_eval, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.lens); } /* grid draw as floor */ - if ((rv3d->viewlock & RV3D_LOCKED) == 0) { + if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) { /* use existing if exists, means multiple calls to smooth view * wont loose the original 'view' setting */ rv3d->view = RV3D_VIEW_USER; @@ -291,7 +292,7 @@ void ED_view3d_smooth_view_ex( ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d); } - if (rv3d->viewlock & RV3D_BOXVIEW) { + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) { view3d_boxview_copy(sa, region); } @@ -344,7 +345,7 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, b ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true); } - if ((rv3d->viewlock & RV3D_LOCKED) == 0) { + if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) { rv3d->view = sms->org_view; } @@ -384,7 +385,7 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, b WM_event_add_mousemove(CTX_wm_window(C)); } - if (sync_boxview && (rv3d->viewlock & RV3D_BOXVIEW)) { + if (sync_boxview && (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW)) { view3d_boxview_copy(CTX_wm_area(C), region); } @@ -494,7 +495,7 @@ static bool view3d_camera_to_view_poll(bContext *C) if (ED_view3d_context_user_region(C, &v3d, ®ion)) { RegionView3D *rv3d = region->regiondata; if (v3d && v3d->camera && !ID_IS_LINKED(v3d->camera)) { - if (rv3d && (rv3d->viewlock & RV3D_LOCKED) == 0) { + if (rv3d && (RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ANY_TRANSFORM) == 0) { if (rv3d->persp != RV3D_CAMOB) { return 1; } @@ -826,7 +827,7 @@ void view3d_viewmatrix_set(Depsgraph *depsgraph, bool use_lock_ofs = false; /* should be moved to better initialize later on XXX */ - if (rv3d->viewlock & RV3D_LOCKED) { + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) { ED_view3d_lock(rv3d); } @@ -991,6 +992,7 @@ int view3d_opengl_select(ViewContext *vc, eV3DSelectObjectFilter select_filter) { struct bThemeState theme_state; + const wmWindowManager *wm = CTX_wm_manager(vc->C); Depsgraph *depsgraph = vc->depsgraph; Scene *scene = vc->scene; View3D *v3d = vc->v3d; @@ -1097,7 +1099,7 @@ int view3d_opengl_select(ViewContext *vc, /* Important we use the 'viewmat' and don't re-calculate since * the object & bone view locking takes 'rect' into account, see: T51629. */ ED_view3d_draw_setup_view( - vc->win, depsgraph, scene, region, v3d, vc->rv3d->viewmat, NULL, &rect); + wm, vc->win, depsgraph, scene, region, v3d, vc->rv3d->viewmat, NULL, &rect); if (!XRAY_ACTIVE(v3d)) { GPU_depth_test(true); @@ -1165,7 +1167,8 @@ int view3d_opengl_select(ViewContext *vc, } G.f &= ~G_FLAG_PICKSEL; - ED_view3d_draw_setup_view(vc->win, depsgraph, scene, region, v3d, vc->rv3d->viewmat, NULL, NULL); + ED_view3d_draw_setup_view( + wm, vc->win, depsgraph, scene, region, v3d, vc->rv3d->viewmat, NULL, NULL); if (!XRAY_ACTIVE(v3d)) { GPU_depth_test(false); @@ -1684,3 +1687,83 @@ void ED_view3d_local_collections_reset(struct bContext *C, const bool reset_all) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name XR Functionality + * \{ */ + +#ifdef WITH_XR_OPENXR + +static void view3d_xr_mirror_begin(RegionView3D *rv3d) +{ + /* If there is no session yet, changes below should not be applied! */ + BLI_assert(WM_xr_session_exists(&((wmWindowManager *)G_MAIN->wm.first)->xr)); + + rv3d->runtime_viewlock |= RV3D_LOCK_ANY_TRANSFORM; + /* Force perspective view. This isn't reset but that's not really an issue. */ + rv3d->persp = RV3D_PERSP; +} + +static void view3d_xr_mirror_end(RegionView3D *rv3d) +{ + rv3d->runtime_viewlock &= ~RV3D_LOCK_ANY_TRANSFORM; +} + +void ED_view3d_xr_mirror_update(const ScrArea *area, const View3D *v3d, const bool enable) +{ + ARegion *region_rv3d; + + BLI_assert(v3d->spacetype == SPACE_VIEW3D); + + if (ED_view3d_area_user_region(area, v3d, ®ion_rv3d)) { + if (enable) { + view3d_xr_mirror_begin(region_rv3d->regiondata); + } + else { + view3d_xr_mirror_end(region_rv3d->regiondata); + } + } +} + +void ED_view3d_xr_shading_update(wmWindowManager *wm, const View3D *v3d, const Scene *scene) +{ + if (v3d->runtime.flag & V3D_RUNTIME_XR_SESSION_ROOT) { + View3DShading *xr_shading = &wm->xr.session_settings.shading; + + BLI_assert(WM_xr_session_exists(&wm->xr)); + + if (v3d->shading.type == OB_RENDER) { + if (!(BKE_scene_uses_blender_workbench(scene) || BKE_scene_uses_blender_eevee(scene))) { + /* Keep old shading while using Cycles or another engine, they are typically not usable in + * VR. */ + return; + } + } + + if (xr_shading->prop) { + IDP_FreeProperty(xr_shading->prop); + xr_shading->prop = NULL; + } + + /* Copy shading from View3D to VR view. */ + *xr_shading = v3d->shading; + if (v3d->shading.prop) { + xr_shading->prop = IDP_CopyProperty(xr_shading->prop); + } + } +} + +bool ED_view3d_is_region_xr_mirror_active(const wmWindowManager *wm, + const View3D *v3d, + const ARegion *region) +{ + return (v3d->flag & V3D_XR_SESSION_MIRROR) && + /* The free region (e.g. the camera region in quad-view) is always the last in the list + base. We don't want any other to be affected. */ + !region->next && // + WM_xr_session_is_ready(&wm->xr); +} + +#endif + +/** \} */ diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index 9f488a1ef78..e25f8b4b8ad 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -1347,7 +1347,7 @@ static int walk_invoke(bContext *C, wmOperator *op, const wmEvent *event) RegionView3D *rv3d = CTX_wm_region_view3d(C); WalkInfo *walk; - if (rv3d->viewlock & RV3D_LOCKED) { + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ANY_TRANSFORM) { return OPERATOR_CANCELLED; } |