Blender  V2.93
overlay_motion_path.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2019, Blender Foundation.
17  */
18 
23 #include "DRW_render.h"
24 
25 #include "BLI_listbase.h"
26 #include "BLI_string.h"
27 
28 #include "DNA_armature_types.h"
29 
30 #include "DEG_depsgraph_query.h"
31 
32 #include "GPU_batch.h"
33 
34 #include "UI_resources.h"
35 
36 #include "draw_manager_text.h"
37 
38 #include "overlay_private.h"
39 
41 {
42  OVERLAY_PassList *psl = vedata->psl;
43  OVERLAY_PrivateData *pd = vedata->stl->pd;
44  DRWShadingGroup *grp;
45  GPUShader *sh;
46 
49 
52  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
53 
56  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
57 }
58 
59 /* Just convert the CPU cache to GPU cache. */
60 /* T0D0(fclem) This should go into a draw_cache_impl_motionpath. */
62 {
63  if (!mpath->points_vbo) {
64  GPUVertFormat format = {0};
65  /* Match structure of bMotionPathVert. */
70  /* meh... a useless memcpy. */
71  memcpy(GPU_vertbuf_get_data(mpath->points_vbo),
72  mpath->points,
73  sizeof(bMotionPathVert) * mpath->length);
74  }
75  return mpath->points_vbo;
76 }
77 
79 {
80  if (!mpath->batch_line) {
82  }
83  return mpath->batch_line;
84 }
85 
87 {
88  if (!mpath->batch_points) {
90  }
91  return mpath->batch_points;
92 }
93 
95  bMotionPath *mpath,
96  int current_frame,
97  int *r_start,
98  int *r_end,
99  int *r_step)
100 {
101  int start, end;
102 
103  if (avs->path_type == MOTIONPATH_TYPE_ACFRA) {
104  start = current_frame - avs->path_bc;
105  end = current_frame + avs->path_ac + 1;
106  }
107  else {
108  start = avs->path_sf;
109  end = avs->path_ef;
110  }
111 
112  if (start > end) {
113  SWAP(int, start, end);
114  }
115 
116  CLAMP(start, mpath->start_frame, mpath->end_frame);
117  CLAMP(end, mpath->start_frame, mpath->end_frame);
118 
119  *r_start = start;
120  *r_end = end;
121  *r_step = max_ii(avs->path_step, 1);
122 }
123 
124 static void motion_path_cache(OVERLAY_Data *vedata,
125  Object *ob,
126  bPoseChannel *pchan,
127  bAnimVizSettings *avs,
128  bMotionPath *mpath)
129 {
130  OVERLAY_PrivateData *pd = vedata->stl->pd;
131  const DRWContextState *draw_ctx = DRW_context_state_get();
132  struct DRWTextStore *dt = DRW_text_cache_ensure();
134  int cfra = (int)DEG_get_ctime(draw_ctx->depsgraph);
135  bool selected = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->base_flag & BASE_SELECTED);
136  bool show_keyframes = (avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) != 0;
137  bool show_keyframes_no = (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) != 0;
138  bool show_frame_no = (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) != 0;
139  bool show_lines = (mpath->flag & MOTIONPATH_FLAG_LINES) != 0;
140  float no_custom_col[3] = {-1.0f, -1.0f, -1.0f};
141  float *color = (mpath->flag & MOTIONPATH_FLAG_CUSTOM) ? mpath->color : no_custom_col;
142 
143  int sfra, efra, stepsize;
144  motion_path_get_frame_range_to_draw(avs, mpath, cfra, &sfra, &efra, &stepsize);
145 
146  int len = efra - sfra;
147  if (len == 0) {
148  return;
149  }
150  int start_index = sfra - mpath->start_frame;
151 
152  /* Draw curve-line of path. */
153  if (show_lines) {
154  const int motion_path_settings[4] = {cfra, sfra, efra, mpath->start_frame};
156  DRW_shgroup_uniform_ivec4_copy(grp, "mpathLineSettings", motion_path_settings);
157  DRW_shgroup_uniform_int_copy(grp, "lineThickness", mpath->line_thickness);
158  DRW_shgroup_uniform_bool_copy(grp, "selected", selected);
159  DRW_shgroup_uniform_vec3_copy(grp, "customColor", color);
160  /* Only draw the required range. */
161  DRW_shgroup_call_range(grp, NULL, mpath_batch_line_get(mpath), start_index, len);
162  }
163 
164  /* Draw points. */
165  {
166  int pt_size = max_ii(mpath->line_thickness - 1, 1);
167  const int motion_path_settings[4] = {pt_size, cfra, mpath->start_frame, stepsize};
169  DRW_shgroup_uniform_ivec4_copy(grp, "mpathPointSettings", motion_path_settings);
170  DRW_shgroup_uniform_bool_copy(grp, "showKeyFrames", show_keyframes);
171  DRW_shgroup_uniform_vec3_copy(grp, "customColor", color);
172  /* Only draw the required range. */
173  DRW_shgroup_call_range(grp, NULL, mpath_batch_points_get(mpath), start_index, len);
174  }
175 
176  /* Draw frame numbers at each frame-step value. */
177  if (show_frame_no || (show_keyframes_no && show_keyframes)) {
178  int i;
179  uchar col[4], col_kf[4];
180  /* Color Management: Exception here as texts are drawn in sRGB space directly. */
183  col[3] = col_kf[3] = 255;
184 
185  bMotionPathVert *mpv = mpath->points + start_index;
186  for (i = 0; i < len; i += stepsize, mpv += stepsize) {
187  int frame = sfra + i;
188  char numstr[32];
189  size_t numstr_len;
190  bool is_keyframe = (mpv->flag & MOTIONPATH_VERT_KEY) != 0;
191 
192  if ((show_keyframes && show_keyframes_no && is_keyframe) || (show_frame_no && (i == 0))) {
193  numstr_len = BLI_snprintf(numstr, sizeof(numstr), " %d", frame);
195  dt, mpv->co, numstr, numstr_len, 0, 0, txt_flag, (is_keyframe) ? col_kf : col);
196  }
197  else if (show_frame_no) {
198  bMotionPathVert *mpvP = (mpv - stepsize);
199  bMotionPathVert *mpvN = (mpv + stepsize);
200  /* Only draw frame number if several consecutive highlighted points
201  * don't occur on same point. */
202  if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) {
203  numstr_len = BLI_snprintf(numstr, sizeof(numstr), " %d", frame);
204  DRW_text_cache_add(dt, mpv->co, numstr, numstr_len, 0, 0, txt_flag, col);
205  }
206  }
207  }
208  }
209 }
210 
212 {
213  const DRWContextState *draw_ctx = DRW_context_state_get();
214 
215  if (ob->type == OB_ARMATURE) {
216  if (OVERLAY_armature_is_pose_mode(ob, draw_ctx)) {
217  LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
218  if (pchan->mpath) {
219  motion_path_cache(vedata, ob, pchan, &ob->pose->avs, pchan->mpath);
220  }
221  }
222  }
223  }
224 
225  if (ob->mpath) {
226  motion_path_cache(vedata, ob, NULL, &ob->avs, ob->mpath);
227  }
228 }
229 
231 {
232  OVERLAY_PassList *psl = vedata->psl;
233 
235 }
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
MINLINE int max_ii(int a, int b)
MINLINE bool equals_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
unsigned char uchar
Definition: BLI_sys_types.h:86
#define SWAP(type, a, b)
float DEG_get_ctime(const Depsgraph *graph)
@ MOTIONPATH_TYPE_ACFRA
@ MOTIONPATH_VERT_KEY
@ MOTIONPATH_VIEW_KFNOS
@ MOTIONPATH_VIEW_FNUMS
@ MOTIONPATH_VIEW_KFRAS
@ MOTIONPATH_FLAG_LINES
@ MOTIONPATH_FLAG_CUSTOM
@ BONE_SELECTED
@ BASE_SELECTED
@ OB_ARMATURE
DRWState
Definition: DRW_render.h:312
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:315
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:593
GPUBatch
Definition: GPU_batch.h:93
#define GPU_batch_create(prim, verts, elem)
Definition: GPU_batch.h:107
@ GPU_PRIM_POINTS
Definition: GPU_primitive.h:35
@ GPU_PRIM_LINE_STRIP
Definition: GPU_primitive.h:38
struct GPUShader GPUShader
Definition: GPU_shader.h:33
#define GPU_vertbuf_create_with_format(format)
struct GPUVertBuf GPUVertBuf
void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len)
void * GPU_vertbuf_get_data(const GPUVertBuf *verts)
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
@ GPU_COMP_I32
Group RGB to Bright Vector Camera CLAMP
@ TH_VERTEX_SELECT
Definition: UI_resources.h:94
@ TH_TEXT_HI
Definition: UI_resources.h:59
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3])
Definition: resources.c:1350
struct DRW_Global G_draw
Definition: draw_common.c:45
const DRWContextState * DRW_context_state_get(void)
struct DRWTextStore * DRW_text_cache_ensure(void)
void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const GPUUniformBuf *ubo)
void DRW_shgroup_uniform_vec3_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
DRWShadingGroup * DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value)
void DRW_shgroup_call_range(DRWShadingGroup *shgroup, struct Object *ob, GPUBatch *geom, uint v_sta, uint v_ct)
void DRW_shgroup_uniform_ivec4_copy(DRWShadingGroup *shgroup, const char *name, const int *value)
void DRW_draw_pass(DRWPass *pass)
void DRW_text_cache_add(DRWTextStore *dt, const float co[3], const char *str, const int str_len, short xoffs, short yoffs, short flag, const uchar col[4])
@ DRW_TEXT_CACHE_GLOBALSPACE
@ DRW_TEXT_CACHE_ASCII
uint col
format
Definition: logImageCore.h:47
static ulong state[N]
bool OVERLAY_armature_is_pose_mode(Object *ob, const DRWContextState *draw_ctx)
static GPUVertBuf * mpath_vbo_get(bMotionPath *mpath)
void OVERLAY_motion_path_cache_populate(OVERLAY_Data *vedata, Object *ob)
void OVERLAY_motion_path_draw(OVERLAY_Data *vedata)
void OVERLAY_motion_path_cache_init(OVERLAY_Data *vedata)
static void motion_path_cache(OVERLAY_Data *vedata, Object *ob, bPoseChannel *pchan, bAnimVizSettings *avs, bMotionPath *mpath)
static GPUBatch * mpath_batch_line_get(bMotionPath *mpath)
static GPUBatch * mpath_batch_points_get(bMotionPath *mpath)
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)
GPUShader * OVERLAY_shader_motion_path_vert(void)
GPUShader * OVERLAY_shader_motion_path_line(void)
struct Depsgraph * depsgraph
Definition: DRW_render.h:753
struct GPUUniformBuf * block_ubo
Definition: draw_common.h:210
OVERLAY_PassList * psl
OVERLAY_StorageList * stl
DRWPass * motion_paths_ps
DRWShadingGroup * motion_path_points_grp
DRWShadingGroup * motion_path_lines_grp
struct OVERLAY_PrivateData * pd
short base_flag
struct bPose * pose
bMotionPath * mpath
bAnimVizSettings avs
struct GPUVertBuf * points_vbo
bMotionPathVert * points
struct GPUBatch * batch_points
struct GPUBatch * batch_line
float color[3]
struct Bone * bone
ListBase chanbase
bAnimVizSettings avs
uint len