From 2fffd7d7a85d9e35d4f2b6e0de15504178b26e07 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 19 Sep 2022 14:29:58 +0200 Subject: Move overlay engine to C++ This just makes the minimum changes to make the files compile. --- .../draw/engines/overlay/overlay_motion_path.cc | 220 +++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 source/blender/draw/engines/overlay/overlay_motion_path.cc (limited to 'source/blender/draw/engines/overlay/overlay_motion_path.cc') diff --git a/source/blender/draw/engines/overlay/overlay_motion_path.cc b/source/blender/draw/engines/overlay/overlay_motion_path.cc new file mode 100644 index 00000000000..00b2a8665fd --- /dev/null +++ b/source/blender/draw/engines/overlay/overlay_motion_path.cc @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2019 Blender Foundation. */ + +/** \file + * \ingroup draw_engine + */ + +#include "DRW_render.h" + +#include "BLI_listbase.h" +#include "BLI_string.h" + +#include "DNA_armature_types.h" + +#include "DEG_depsgraph_query.h" + +#include "GPU_batch.h" + +#include "UI_resources.h" + +#include "draw_manager_text.h" + +#include "overlay_private.hh" + +void OVERLAY_motion_path_cache_init(OVERLAY_Data *vedata) +{ + OVERLAY_PassList *psl = vedata->psl; + OVERLAY_PrivateData *pd = vedata->stl->pd; + DRWShadingGroup *grp; + GPUShader *sh; + + DRWState state = DRW_STATE_WRITE_COLOR; + DRW_PASS_CREATE(psl->motion_paths_ps, state | pd->clipping_state); + + sh = OVERLAY_shader_motion_path_line(); + pd->motion_path_lines_grp = grp = DRW_shgroup_create(sh, psl->motion_paths_ps); + DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); + + sh = OVERLAY_shader_motion_path_vert(); + pd->motion_path_points_grp = grp = DRW_shgroup_create(sh, psl->motion_paths_ps); + DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); +} + +/* Just convert the CPU cache to GPU cache. */ +/* T0D0(fclem) This should go into a draw_cache_impl_motionpath. */ +static GPUVertBuf *mpath_vbo_get(bMotionPath *mpath) +{ + if (!mpath->points_vbo) { + GPUVertFormat format = {0}; + /* Match structure of bMotionPathVert. */ + GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + GPU_vertformat_attr_add(&format, "flag", GPU_COMP_I32, 1, GPU_FETCH_INT); + mpath->points_vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(mpath->points_vbo, mpath->length); + /* meh... a useless memcpy. */ + memcpy(GPU_vertbuf_get_data(mpath->points_vbo), + mpath->points, + sizeof(bMotionPathVert) * mpath->length); + } + return mpath->points_vbo; +} + +static GPUBatch *mpath_batch_line_get(bMotionPath *mpath) +{ + if (!mpath->batch_line) { + mpath->batch_line = GPU_batch_create(GPU_PRIM_LINE_STRIP, mpath_vbo_get(mpath), nullptr); + } + return mpath->batch_line; +} + +static GPUBatch *mpath_batch_points_get(bMotionPath *mpath) +{ + if (!mpath->batch_points) { + mpath->batch_points = GPU_batch_create(GPU_PRIM_POINTS, mpath_vbo_get(mpath), nullptr); + } + return mpath->batch_points; +} + +static void motion_path_get_frame_range_to_draw(bAnimVizSettings *avs, + bMotionPath *mpath, + int current_frame, + int *r_start, + int *r_end, + int *r_step) +{ + int start, end; + + if (avs->path_type == MOTIONPATH_TYPE_ACFRA) { + start = current_frame - avs->path_bc; + end = current_frame + avs->path_ac + 1; + } + else { + start = avs->path_sf; + end = avs->path_ef; + } + + if (start > end) { + SWAP(int, start, end); + } + + CLAMP(start, mpath->start_frame, mpath->end_frame); + CLAMP(end, mpath->start_frame, mpath->end_frame); + + *r_start = start; + *r_end = end; + *r_step = max_ii(avs->path_step, 1); +} + +static void motion_path_cache(OVERLAY_Data *vedata, + Object *ob, + bPoseChannel *pchan, + bAnimVizSettings *avs, + bMotionPath *mpath) +{ + OVERLAY_PrivateData *pd = vedata->stl->pd; + const DRWContextState *draw_ctx = DRW_context_state_get(); + struct DRWTextStore *dt = DRW_text_cache_ensure(); + int txt_flag = DRW_TEXT_CACHE_GLOBALSPACE; + int cfra = (int)DEG_get_ctime(draw_ctx->depsgraph); + bool selected = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->base_flag & BASE_SELECTED); + bool show_keyframes = (avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) != 0; + bool show_keyframes_no = (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) != 0; + bool show_frame_no = (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) != 0; + bool show_lines = (mpath->flag & MOTIONPATH_FLAG_LINES) != 0; + float no_custom_col[3] = {-1.0f, -1.0f, -1.0f}; + float *color = (mpath->flag & MOTIONPATH_FLAG_CUSTOM) ? mpath->color : no_custom_col; + + int sfra, efra, stepsize; + motion_path_get_frame_range_to_draw(avs, mpath, cfra, &sfra, &efra, &stepsize); + + int len = efra - sfra; + if (len == 0) { + return; + } + int start_index = sfra - mpath->start_frame; + + /* Draw curve-line of path. */ + if (show_lines) { + const int motion_path_settings[4] = {cfra, sfra, efra, mpath->start_frame}; + DRWShadingGroup *grp = DRW_shgroup_create_sub(pd->motion_path_lines_grp); + DRW_shgroup_uniform_ivec4_copy(grp, "mpathLineSettings", motion_path_settings); + DRW_shgroup_uniform_int_copy(grp, "lineThickness", mpath->line_thickness); + DRW_shgroup_uniform_bool_copy(grp, "selected", selected); + DRW_shgroup_uniform_vec3_copy(grp, "customColor", color); + /* Only draw the required range. */ + DRW_shgroup_call_range(grp, nullptr, mpath_batch_line_get(mpath), start_index, len); + } + + /* Draw points. */ + { + int pt_size = max_ii(mpath->line_thickness - 1, 1); + const int motion_path_settings[4] = {pt_size, cfra, mpath->start_frame, stepsize}; + DRWShadingGroup *grp = DRW_shgroup_create_sub(pd->motion_path_points_grp); + DRW_shgroup_uniform_ivec4_copy(grp, "mpathPointSettings", motion_path_settings); + DRW_shgroup_uniform_bool_copy(grp, "showKeyFrames", show_keyframes); + DRW_shgroup_uniform_vec3_copy(grp, "customColor", color); + /* Only draw the required range. */ + DRW_shgroup_call_range(grp, nullptr, mpath_batch_points_get(mpath), start_index, len); + } + + /* Draw frame numbers at each frame-step value. */ + if (show_frame_no || (show_keyframes_no && show_keyframes)) { + int i; + uchar col[4], col_kf[4]; + /* Color Management: Exception here as texts are drawn in sRGB space directly. */ + UI_GetThemeColor3ubv(TH_TEXT_HI, col); + UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col_kf); + col[3] = col_kf[3] = 255; + + bMotionPathVert *mpv = mpath->points + start_index; + for (i = 0; i < len; i += stepsize, mpv += stepsize) { + int frame = sfra + i; + char numstr[32]; + size_t numstr_len; + bool is_keyframe = (mpv->flag & MOTIONPATH_VERT_KEY) != 0; + + if ((show_keyframes && show_keyframes_no && is_keyframe) || (show_frame_no && (i == 0))) { + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), " %d", frame); + DRW_text_cache_add( + dt, mpv->co, numstr, numstr_len, 0, 0, txt_flag, (is_keyframe) ? col_kf : col); + } + else if (show_frame_no) { + bMotionPathVert *mpvP = (mpv - stepsize); + bMotionPathVert *mpvN = (mpv + stepsize); + /* Only draw frame number if several consecutive highlighted points + * don't occur on same point. */ + if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) { + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), " %d", frame); + DRW_text_cache_add(dt, mpv->co, numstr, numstr_len, 0, 0, txt_flag, col); + } + } + } + } +} + +void OVERLAY_motion_path_cache_populate(OVERLAY_Data *vedata, Object *ob) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + + if (ob->type == OB_ARMATURE) { + if (OVERLAY_armature_is_pose_mode(ob, draw_ctx)) { + LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { + if (pchan->mpath) { + motion_path_cache(vedata, ob, pchan, &ob->pose->avs, pchan->mpath); + } + } + } + } + + if (ob->mpath) { + motion_path_cache(vedata, ob, nullptr, &ob->avs, ob->mpath); + } +} + +void OVERLAY_motion_path_draw(OVERLAY_Data *vedata) +{ + OVERLAY_PassList *psl = vedata->psl; + + DRW_draw_pass(psl->motion_paths_ps); +} -- cgit v1.2.3