Compare commits
20 Commits
draw-viewp
...
tmp-b28-mo
Author | SHA1 | Date | |
---|---|---|---|
a12ab5b2ef | |||
e9e8f105d0 | |||
fea05c695a | |||
83afc4e1a2 | |||
6c177a7478 | |||
70b31c28b6 | |||
71d02d8a35 | |||
cd6109fd4f | |||
49a727a784 | |||
959af5d69d | |||
d886fc0f40 | |||
266c90dc17 | |||
bc4bfef209 | |||
113e5fdd81 | |||
d8203b0422 | |||
f12e22edca | |||
28373293a2 | |||
e781b7692a | |||
2e2371b86e | |||
1fd4b0bdf5 |
@@ -3597,6 +3597,7 @@ class VIEW3D_PT_overlay(Panel):
|
||||
col.prop(overlay, "show_outline_selected")
|
||||
col.prop(overlay, "show_all_objects_origin")
|
||||
col.prop(overlay, "show_relationship_lines")
|
||||
col.prop(overlay, "show_motion_paths")
|
||||
col.prop(overlay, "show_face_orientation")
|
||||
col.prop(overlay, "show_wireframes")
|
||||
col.prop(overlay, "show_backface_culling")
|
||||
|
@@ -48,6 +48,8 @@ struct Main;
|
||||
|
||||
void animviz_settings_init(struct bAnimVizSettings *avs);
|
||||
|
||||
struct bMotionPath *animviz_copy_motionpath(const struct bMotionPath *mpath_src);
|
||||
|
||||
void animviz_free_motionpath_cache(struct bMotionPath *mpath);
|
||||
void animviz_free_motionpath(struct bMotionPath *mpath);
|
||||
|
||||
|
@@ -582,7 +582,9 @@ void BKE_pose_copy_data_ex(bPose **dst, const bPose *src, const int flag, const
|
||||
if (copy_constraints) {
|
||||
BKE_constraints_copy_ex(&listb, &pchan->constraints, flag, true); // BKE_constraints_copy NULLs listb
|
||||
pchan->constraints = listb;
|
||||
pchan->mpath = NULL; /* motion paths should not get copied yet... */
|
||||
|
||||
/* XXX: This is needed for motionpath drawing to work. Dunno why it was setting to null before... */
|
||||
pchan->mpath = animviz_copy_motionpath(pchan->mpath);
|
||||
}
|
||||
|
||||
if (pchan->prop) {
|
||||
|
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_dlrbTree.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
@@ -44,6 +45,7 @@
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_anim.h"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_curve.h"
|
||||
@@ -59,7 +61,12 @@
|
||||
#include "DEG_depsgraph_query.h"
|
||||
#include "DEG_depsgraph_build.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
|
||||
// XXX bad level call...
|
||||
extern short compare_ak_cfraPtr(void *node, void *data);
|
||||
extern void agroup_to_keylist(struct AnimData *adt, struct bActionGroup *agrp, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks);
|
||||
extern void action_to_keylist(struct AnimData *adt, struct bAction *act, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks);
|
||||
|
||||
/* --------------------- */
|
||||
/* forward declarations */
|
||||
@@ -106,6 +113,10 @@ void animviz_free_motionpath_cache(bMotionPath *mpath)
|
||||
/* free the path if necessary */
|
||||
if (mpath->points)
|
||||
MEM_freeN(mpath->points);
|
||||
|
||||
GWN_VERTBUF_DISCARD_SAFE(mpath->points_vbo);
|
||||
GWN_BATCH_DISCARD_SAFE(mpath->batch_line);
|
||||
GWN_BATCH_DISCARD_SAFE(mpath->batch_points);
|
||||
|
||||
/* reset the relevant parameters */
|
||||
mpath->points = NULL;
|
||||
@@ -130,6 +141,27 @@ void animviz_free_motionpath(bMotionPath *mpath)
|
||||
|
||||
/* ------------------- */
|
||||
|
||||
/* Make a copy of motionpath data, so that viewing with copy on write works */
|
||||
bMotionPath *animviz_copy_motionpath(const bMotionPath *mpath_src)
|
||||
{
|
||||
bMotionPath *mpath_dst;
|
||||
|
||||
if (mpath_src == NULL)
|
||||
return NULL;
|
||||
|
||||
mpath_dst = MEM_dupallocN(mpath_src);
|
||||
mpath_dst->points = MEM_dupallocN(mpath_src->points);
|
||||
|
||||
/* should get recreated on draw... */
|
||||
mpath_dst->points_vbo = NULL;
|
||||
mpath_dst->batch_line = NULL;
|
||||
mpath_dst->batch_points = NULL;
|
||||
|
||||
return mpath_dst;
|
||||
}
|
||||
|
||||
/* ------------------- */
|
||||
|
||||
/**
|
||||
* Setup motion paths for the given data.
|
||||
* \note Only used when explicitly calculating paths on bones which may/may not be consider already
|
||||
@@ -212,7 +244,7 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports, Scene *scene, Objec
|
||||
mpath->color[1] = 0.0;
|
||||
mpath->color[2] = 0.0;
|
||||
|
||||
mpath->line_thickness = 1;
|
||||
mpath->line_thickness = 2;
|
||||
mpath->flag |= MOTIONPATH_FLAG_LINES; /* draw lines by default */
|
||||
|
||||
/* allocate a cache */
|
||||
@@ -232,6 +264,8 @@ typedef struct MPathTarget {
|
||||
struct MPathTarget *next, *prev;
|
||||
|
||||
bMotionPath *mpath; /* motion path in question */
|
||||
|
||||
DLRBT_Tree keys; /* temp, to know where the keyframes are */
|
||||
|
||||
/* Original (Source Objects) */
|
||||
Object *ob; /* source object */
|
||||
@@ -344,6 +378,13 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
|
||||
/* worldspace object location */
|
||||
copy_v3_v3(mpv->co, ob_eval->obmat[3]);
|
||||
}
|
||||
|
||||
float mframe = (float)(CFRA);
|
||||
|
||||
/* Tag if it's a keyframe */
|
||||
if (BLI_dlrbTree_search_exact(&mpt->keys, compare_ak_cfraPtr, &mframe)) {
|
||||
mpv->flag |= MOTIONPATH_VERT_KEY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,13 +428,44 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
|
||||
if (mpt->pchan) {
|
||||
mpt->pchan_eval = BKE_pose_channel_find_name(mpt->ob_eval->pose, mpt->pchan->name);
|
||||
}
|
||||
|
||||
AnimData *adt = BKE_animdata_from_id(&mpt->ob_eval->id);
|
||||
|
||||
/* build list of all keyframes in active action for object or pchan */
|
||||
BLI_dlrbTree_init(&mpt->keys);
|
||||
|
||||
if (adt) {
|
||||
bAnimVizSettings *avs;
|
||||
|
||||
/* get pointer to animviz settings for each target */
|
||||
if (mpt->pchan)
|
||||
avs = &mpt->ob->pose->avs;
|
||||
else
|
||||
avs = &mpt->ob->avs;
|
||||
|
||||
/* it is assumed that keyframes for bones are all grouped in a single group
|
||||
* unless an option is set to always use the whole action
|
||||
*/
|
||||
if ((mpt->pchan) && (avs->path_viewflag & MOTIONPATH_VIEW_KFACT) == 0) {
|
||||
bActionGroup *agrp = BKE_action_group_find_name(adt->action, mpt->pchan->name);
|
||||
|
||||
if (agrp) {
|
||||
agroup_to_keylist(adt, agrp, &mpt->keys, NULL);
|
||||
BLI_dlrbTree_linkedlist_sync(&mpt->keys);
|
||||
}
|
||||
}
|
||||
else {
|
||||
action_to_keylist(adt, adt->action, &mpt->keys, NULL);
|
||||
BLI_dlrbTree_linkedlist_sync(&mpt->keys);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* calculate path over requested range */
|
||||
for (CFRA = sfra; CFRA <= efra; CFRA++) {
|
||||
/* update relevant data for new frame */
|
||||
motionpaths_calc_update_scene(bmain, depsgraph);
|
||||
|
||||
|
||||
/* perform baking for targets */
|
||||
motionpaths_calc_bake_targets(scene, targets);
|
||||
}
|
||||
@@ -406,6 +478,7 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
|
||||
/* clear recalc flags from targets */
|
||||
for (mpt = targets->first; mpt; mpt = mpt->next) {
|
||||
bAnimVizSettings *avs;
|
||||
bMotionPath *mpath = mpt->mpath;
|
||||
|
||||
/* get pointer to animviz settings for each target */
|
||||
if (mpt->pchan)
|
||||
@@ -415,6 +488,14 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
|
||||
|
||||
/* clear the flag requesting recalculation of targets */
|
||||
avs->recalc &= ~ANIMVIZ_RECALC_PATHS;
|
||||
|
||||
/* Clean temp data */
|
||||
BLI_dlrbTree_free(&mpt->keys);
|
||||
|
||||
/* Free previous batches to force update. */
|
||||
GWN_VERTBUF_DISCARD_SAFE(mpath->points_vbo);
|
||||
GWN_BATCH_DISCARD_SAFE(mpath->batch_line);
|
||||
GWN_BATCH_DISCARD_SAFE(mpath->batch_points);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1228,7 +1228,8 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_
|
||||
BLI_listbase_clear(&ob_dst->drawdata);
|
||||
BLI_listbase_clear(&ob_dst->pc_ids);
|
||||
|
||||
ob_dst->mpath = NULL;
|
||||
ob_dst->avs = ob_src->avs;
|
||||
ob_dst->mpath = animviz_copy_motionpath(ob_src->mpath);
|
||||
|
||||
copy_object_lod(ob_dst, ob_src, flag_subdata);
|
||||
|
||||
|
@@ -2965,6 +2965,10 @@ static void direct_link_motionpath(FileData *fd, bMotionPath *mpath)
|
||||
|
||||
/* relink points cache */
|
||||
mpath->points = newdataadr(fd, mpath->points);
|
||||
|
||||
mpath->points_vbo = NULL;
|
||||
mpath->batch_line = NULL;
|
||||
mpath->batch_points = NULL;
|
||||
}
|
||||
|
||||
/* ************ READ NODE TREE *************** */
|
||||
|
@@ -53,6 +53,7 @@ set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
intern/draw_anim_viz.c
|
||||
intern/draw_armature.c
|
||||
intern/draw_cache.c
|
||||
intern/draw_cache_impl_curve.c
|
||||
@@ -241,6 +242,9 @@ data_to_c_simple(modes/shaders/common_hair_refine_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/common_view_lib.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/common_fxaa_lib.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/common_fullscreen_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/animviz_mpath_lines_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/animviz_mpath_lines_geom.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/animviz_mpath_points_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_axes_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_sphere_solid_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_sphere_solid_frag.glsl SRC)
|
||||
|
@@ -344,6 +344,8 @@ void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *batc
|
||||
|
||||
void DRW_shgroup_free(struct DRWShadingGroup *shgroup);
|
||||
void DRW_shgroup_call_add(DRWShadingGroup *shgroup, struct Gwn_Batch *geom, float (*obmat)[4]);
|
||||
void DRW_shgroup_call_range_add(
|
||||
DRWShadingGroup *shgroup, struct Gwn_Batch *geom, float (*obmat)[4], uint v_sta, uint v_count);
|
||||
void DRW_shgroup_call_procedural_points_add(DRWShadingGroup *shgroup, unsigned int point_count, float (*obmat)[4]);
|
||||
void DRW_shgroup_call_procedural_lines_add(DRWShadingGroup *shgroup, unsigned int line_count, float (*obmat)[4]);
|
||||
void DRW_shgroup_call_procedural_triangles_add(DRWShadingGroup *shgroup, unsigned int tria_count, float (*obmat)[4]);
|
||||
|
351
source/blender/draw/intern/draw_anim_viz.c
Normal file
351
source/blender/draw/intern/draw_anim_viz.c
Normal file
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2009/2018 by the Blender Foundation.
|
||||
*
|
||||
* Contributor(s): Joshua Leung
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/draw/intern/draw_anim_viz.c
|
||||
* \ingroup draw
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_dlrbTree.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_action.h"
|
||||
|
||||
#include "ED_keyframes_draw.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "DRW_engine.h"
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_matrix.h"
|
||||
|
||||
#include "draw_common.h"
|
||||
#include "draw_manager_text.h"
|
||||
|
||||
#include "draw_mode_engines.h"
|
||||
|
||||
extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
|
||||
|
||||
/* ********************************* Lists ************************************** */
|
||||
/* All lists are per viewport specific datas.
|
||||
* They are all free when viewport changes engines
|
||||
* or is free itself.
|
||||
*/
|
||||
|
||||
/* XXX: How to show frame numbers, etc.? Currently only doing the dots and lines */
|
||||
typedef struct MPATH_PassList {
|
||||
struct DRWPass *lines;
|
||||
struct DRWPass *points;
|
||||
} MPATH_PassList;
|
||||
|
||||
typedef struct MPATH_StorageList {
|
||||
struct MPATH_PrivateData *g_data;
|
||||
} MPATH_StorageList;
|
||||
|
||||
typedef struct MPATH_Data {
|
||||
void *engine_type;
|
||||
DRWViewportEmptyList *fbl;
|
||||
DRWViewportEmptyList *txl;
|
||||
MPATH_PassList *psl;
|
||||
MPATH_StorageList *stl;
|
||||
} MPATH_Data;
|
||||
|
||||
struct {
|
||||
GPUShader *mpath_line_sh;
|
||||
GPUShader *mpath_points_sh;
|
||||
} e_data = {0};
|
||||
|
||||
/* *************************** Path Cache *********************************** */
|
||||
|
||||
/* Just convert the CPU cache to GPU cache. */
|
||||
static Gwn_VertBuf *mpath_vbo_get(bMotionPath *mpath)
|
||||
{
|
||||
if (!mpath->points_vbo) {
|
||||
Gwn_VertFormat format = {0};
|
||||
/* Match structure of bMotionPathVert. */
|
||||
uint pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
|
||||
GWN_vertformat_attr_add(&format, "flag", GWN_COMP_I32, 1, GWN_FETCH_INT);
|
||||
mpath->points_vbo = GWN_vertbuf_create_with_format(&format);
|
||||
GWN_vertbuf_data_alloc(mpath->points_vbo, mpath->length);
|
||||
|
||||
/* meh... a useless memcpy. */
|
||||
Gwn_VertBufRaw raw_data;
|
||||
GWN_vertbuf_attr_get_raw_data(mpath->points_vbo, pos, &raw_data);
|
||||
memcpy(GWN_vertbuf_raw_step(&raw_data), mpath->points, sizeof(bMotionPathVert) * mpath->length);
|
||||
}
|
||||
return mpath->points_vbo;
|
||||
}
|
||||
|
||||
static Gwn_Batch *mpath_batch_line_get(bMotionPath *mpath)
|
||||
{
|
||||
if (!mpath->batch_line) {
|
||||
mpath->batch_line = GWN_batch_create(GWN_PRIM_LINE_STRIP, mpath_vbo_get(mpath), NULL);
|
||||
}
|
||||
return mpath->batch_line;
|
||||
}
|
||||
|
||||
static Gwn_Batch *mpath_batch_points_get(bMotionPath *mpath)
|
||||
{
|
||||
if (!mpath->batch_points) {
|
||||
mpath->batch_points = GWN_batch_create(GWN_PRIM_POINTS, mpath_vbo_get(mpath), NULL);
|
||||
}
|
||||
return mpath->batch_points;
|
||||
}
|
||||
|
||||
/* *************************** Draw Engine Entrypoints ************************** */
|
||||
|
||||
static void MPATH_engine_init(void *UNUSED(vedata))
|
||||
{
|
||||
}
|
||||
|
||||
static void MPATH_engine_free(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* Here init all passes and shading groups
|
||||
* Assume that all Passes are NULL */
|
||||
static void MPATH_cache_init(void *vedata)
|
||||
{
|
||||
MPATH_PassList *psl = ((MPATH_Data *)vedata)->psl;
|
||||
|
||||
{
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
|
||||
psl->lines = DRW_pass_create("Motionpath Line Pass", state);
|
||||
}
|
||||
|
||||
{
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_POINT;
|
||||
psl->points = DRW_pass_create("Motionpath Point Pass", state);
|
||||
}
|
||||
}
|
||||
|
||||
static void MPATH_cache_motion_path(MPATH_PassList *psl,
|
||||
Object *ob, bPoseChannel *pchan,
|
||||
bAnimVizSettings *avs, bMotionPath *mpath)
|
||||
{
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
struct DRWTextStore *dt = DRW_text_cache_ensure();
|
||||
int txt_flag = DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_ASCII;
|
||||
int stepsize = avs->path_step;
|
||||
int sfra, efra, sind, len;
|
||||
int cfra = (int)DEG_get_ctime(draw_ctx->depsgraph);
|
||||
bool sel = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT);
|
||||
bool show_keyframes = (avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) != 0;
|
||||
bMotionPathVert *mpv, *mpv_start;
|
||||
|
||||
/* get frame ranges */
|
||||
if (avs->path_type == MOTIONPATH_TYPE_ACFRA) {
|
||||
/* With "Around Current", we only choose frames from around
|
||||
* the current frame to draw.
|
||||
*/
|
||||
sfra = cfra - avs->path_bc;
|
||||
efra = cfra + avs->path_ac + 1;
|
||||
}
|
||||
else {
|
||||
/* Use the current display range */
|
||||
sfra = avs->path_sf;
|
||||
efra = avs->path_ef;
|
||||
}
|
||||
|
||||
/* no matter what, we can only show what is in the cache and no more
|
||||
* - abort if whole range is past ends of path
|
||||
* - otherwise clamp endpoints to extents of path
|
||||
*/
|
||||
if (sfra < mpath->start_frame) {
|
||||
/* start clamp */
|
||||
sfra = mpath->start_frame;
|
||||
}
|
||||
if (efra > mpath->end_frame) {
|
||||
/* end clamp */
|
||||
efra = mpath->end_frame;
|
||||
}
|
||||
|
||||
if ((sfra > mpath->end_frame) || (efra < mpath->start_frame)) {
|
||||
/* whole path is out of bounds */
|
||||
return;
|
||||
}
|
||||
|
||||
len = efra - sfra;
|
||||
|
||||
if ((len <= 0) || (mpath->points == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
sind = sfra - mpath->start_frame;
|
||||
mpv_start = (mpath->points + sind);
|
||||
|
||||
bool use_custom_col = (mpath->flag & MOTIONPATH_FLAG_CUSTOM) != 0;
|
||||
|
||||
/* draw curve-line of path */
|
||||
/* Draw lines only if line drawing option is enabled */
|
||||
if (mpath->flag & MOTIONPATH_FLAG_LINES) {
|
||||
DRWShadingGroup *shgrp = DRW_shgroup_create(mpath_line_shader_get(), psl->lines);
|
||||
DRW_shgroup_uniform_int_copy(shgrp, "frameCurrent", cfra);
|
||||
DRW_shgroup_uniform_int_copy(shgrp, "frameStart", sfra);
|
||||
DRW_shgroup_uniform_int_copy(shgrp, "frameEnd", efra);
|
||||
DRW_shgroup_uniform_int_copy(shgrp, "cacheStart", mpath->start_frame);
|
||||
DRW_shgroup_uniform_int_copy(shgrp, "lineThickness", mpath->line_thickness);
|
||||
DRW_shgroup_uniform_bool_copy(shgrp, "selected", sel);
|
||||
DRW_shgroup_uniform_bool_copy(shgrp, "useCustomColor", use_custom_col);
|
||||
DRW_shgroup_uniform_vec2(shgrp, "viewportSize", DRW_viewport_size_get(), 1);
|
||||
DRW_shgroup_uniform_block(shgrp, "globalsBlock", globals_ubo);
|
||||
if (use_custom_col) {
|
||||
DRW_shgroup_uniform_vec3(shgrp, "customColor", mpath->color, 1);
|
||||
}
|
||||
/* Only draw the required range. */
|
||||
DRW_shgroup_call_range_add(shgrp, mpath_batch_line_get(mpath), NULL, sind, len);
|
||||
}
|
||||
|
||||
/* Draw points. */
|
||||
DRWShadingGroup *shgrp = DRW_shgroup_create(mpath_points_shader_get(), psl->points);
|
||||
DRW_shgroup_uniform_int_copy(shgrp, "frameCurrent", cfra);
|
||||
DRW_shgroup_uniform_int_copy(shgrp, "cacheStart", mpath->start_frame);
|
||||
DRW_shgroup_uniform_int_copy(shgrp, "pointSize", mpath->line_thickness);
|
||||
DRW_shgroup_uniform_int_copy(shgrp, "stepSize", stepsize);
|
||||
DRW_shgroup_uniform_bool_copy(shgrp, "selected", sel);
|
||||
DRW_shgroup_uniform_bool_copy(shgrp, "showKeyFrames", show_keyframes);
|
||||
DRW_shgroup_uniform_bool_copy(shgrp, "useCustomColor", use_custom_col);
|
||||
DRW_shgroup_uniform_block(shgrp, "globalsBlock", globals_ubo);
|
||||
if (use_custom_col) {
|
||||
DRW_shgroup_uniform_vec3(shgrp, "customColor", mpath->color, 1);
|
||||
}
|
||||
/* Only draw the required range. */
|
||||
DRW_shgroup_call_range_add(shgrp, mpath_batch_points_get(mpath), NULL, sind, len);
|
||||
|
||||
/* Draw frame numbers at each framestep value */
|
||||
bool show_kf_no = (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) != 0;
|
||||
if ((avs->path_viewflag & (MOTIONPATH_VIEW_FNUMS)) || (show_kf_no && show_keyframes)) {
|
||||
int i;
|
||||
unsigned char col[4], col_kf[4];
|
||||
UI_GetThemeColor3ubv(TH_TEXT_HI, col);
|
||||
UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col_kf);
|
||||
col[3] = col_kf[3] = 255;
|
||||
|
||||
for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) {
|
||||
int frame = sfra + i;
|
||||
char numstr[32];
|
||||
size_t numstr_len;
|
||||
float co[3];
|
||||
bool is_keyframe = (mpv->flag & MOTIONPATH_VERT_KEY) != 0;
|
||||
|
||||
if ((show_keyframes && show_kf_no && is_keyframe) ||
|
||||
((avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) && (i == 0)))
|
||||
{
|
||||
numstr_len = sprintf(numstr, " %d", frame);
|
||||
mul_v3_m4v3(co, ob->imat, mpv->co);
|
||||
DRW_text_cache_add(dt, co, numstr, numstr_len, 0, txt_flag, (is_keyframe) ? col_kf : col);
|
||||
}
|
||||
else if (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) {
|
||||
bMotionPathVert *mpvP = (mpv - stepsize);
|
||||
bMotionPathVert *mpvN = (mpv + stepsize);
|
||||
/* only draw framenum 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 = sprintf(numstr, " %d", frame);
|
||||
mul_v3_m4v3(co, ob->imat, mpv->co);
|
||||
DRW_text_cache_add(dt, co, numstr, numstr_len, 0, txt_flag, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add geometry to shading groups. Execute for each objects */
|
||||
static void MPATH_cache_populate(void *vedata, Object *ob)
|
||||
{
|
||||
MPATH_PassList *psl = ((MPATH_Data *)vedata)->psl;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
|
||||
if (draw_ctx->v3d->overlay.flag & V3D_OVERLAY_HIDE_MOTION_PATHS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ob->type == OB_ARMATURE) {
|
||||
if (DRW_pose_mode_armature(ob, draw_ctx->obact)) {
|
||||
for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
if (pchan->mpath) {
|
||||
MPATH_cache_motion_path(psl, ob, pchan, &ob->pose->avs, pchan->mpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ob->mpath) {
|
||||
MPATH_cache_motion_path(psl, ob, NULL, &ob->avs, ob->mpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw time! Control rendering pipeline from here */
|
||||
static void MPATH_draw_scene(void *vedata)
|
||||
{
|
||||
MPATH_PassList *psl = ((MPATH_Data *)vedata)->psl;
|
||||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl)
|
||||
|
||||
DRW_draw_pass(psl->lines);
|
||||
DRW_draw_pass(psl->points);
|
||||
|
||||
MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl)
|
||||
}
|
||||
|
||||
/* *************************** Draw Engine Defines ****************************** */
|
||||
|
||||
static const DrawEngineDataSize MPATH_data_size = DRW_VIEWPORT_DATA_SIZE(MPATH_Data);
|
||||
|
||||
DrawEngineType draw_engine_motion_path_type = {
|
||||
NULL, NULL,
|
||||
N_("MotionPath"),
|
||||
&MPATH_data_size,
|
||||
&MPATH_engine_init,
|
||||
&MPATH_engine_free,
|
||||
&MPATH_cache_init,
|
||||
&MPATH_cache_populate,
|
||||
NULL,
|
||||
NULL,
|
||||
&MPATH_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
@@ -92,6 +92,10 @@ void DRW_globals_update(void)
|
||||
UI_GetThemeColor4fv(TH_NURB_SEL_ULINE, ts.colorNurbSelUline);
|
||||
UI_GetThemeColor4fv(TH_ACTIVE_SPLINE, ts.colorActiveSpline);
|
||||
|
||||
UI_GetThemeColor4fv(TH_BONE_POSE, ts.colorBonePose);
|
||||
|
||||
UI_GetThemeColor4fv(TH_CFRAME, ts.colorCurrentFrame);
|
||||
|
||||
/* Grid */
|
||||
UI_GetThemeColorShade4fv(TH_GRID, 10, ts.colorGrid);
|
||||
/* emphasise division lines lighter instead of darker, if background is darker than grid */
|
||||
@@ -153,6 +157,10 @@ void DRW_globals_update(void)
|
||||
|
||||
/* ********************************* SHGROUP ************************************* */
|
||||
|
||||
extern char datatoc_animviz_mpath_lines_vert_glsl[];
|
||||
extern char datatoc_animviz_mpath_lines_geom_glsl[];
|
||||
extern char datatoc_animviz_mpath_points_vert_glsl[];
|
||||
|
||||
extern char datatoc_armature_axes_vert_glsl[];
|
||||
extern char datatoc_armature_sphere_solid_vert_glsl[];
|
||||
extern char datatoc_armature_sphere_solid_frag_glsl[];
|
||||
@@ -167,7 +175,12 @@ extern char datatoc_armature_shape_outline_vert_glsl[];
|
||||
extern char datatoc_armature_shape_outline_geom_glsl[];
|
||||
extern char datatoc_armature_stick_vert_glsl[];
|
||||
extern char datatoc_armature_stick_frag_glsl[];
|
||||
|
||||
extern char datatoc_common_globals_lib_glsl[];
|
||||
|
||||
extern char datatoc_gpu_shader_flat_color_frag_glsl[];
|
||||
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
|
||||
extern char datatoc_gpu_shader_point_varying_color_frag_glsl[];
|
||||
|
||||
extern char datatoc_object_mball_handles_vert_glsl[];
|
||||
|
||||
@@ -182,6 +195,9 @@ static struct {
|
||||
struct GPUShader *bone_sphere_outline;
|
||||
struct GPUShader *bone_stick;
|
||||
|
||||
struct GPUShader *mpath_line_sh;
|
||||
struct GPUShader *mpath_points_sh;
|
||||
|
||||
struct GPUShader *mball_handles;
|
||||
} g_shaders = {NULL};
|
||||
|
||||
@@ -692,6 +708,33 @@ DRWShadingGroup *shgroup_instance_bone_stick(DRWPass *pass)
|
||||
return grp;
|
||||
}
|
||||
|
||||
struct GPUShader *mpath_line_shader_get(void)
|
||||
{
|
||||
if (g_shaders.mpath_line_sh == NULL) {
|
||||
g_shaders.mpath_line_sh = DRW_shader_create_with_lib(
|
||||
datatoc_animviz_mpath_lines_vert_glsl,
|
||||
datatoc_animviz_mpath_lines_geom_glsl,
|
||||
datatoc_gpu_shader_3D_smooth_color_frag_glsl,
|
||||
datatoc_common_globals_lib_glsl,
|
||||
NULL);
|
||||
}
|
||||
return g_shaders.mpath_line_sh;
|
||||
}
|
||||
|
||||
|
||||
struct GPUShader *mpath_points_shader_get(void)
|
||||
{
|
||||
if (g_shaders.mpath_points_sh == NULL) {
|
||||
g_shaders.mpath_points_sh = DRW_shader_create_with_lib(
|
||||
datatoc_animviz_mpath_points_vert_glsl,
|
||||
NULL,
|
||||
datatoc_gpu_shader_point_varying_color_frag_glsl,
|
||||
datatoc_common_globals_lib_glsl,
|
||||
NULL);
|
||||
}
|
||||
return g_shaders.mpath_points_sh;
|
||||
}
|
||||
|
||||
/* ******************************************** COLOR UTILS *********************************************** */
|
||||
|
||||
/* TODO FINISH */
|
||||
|
@@ -87,6 +87,10 @@ typedef struct GlobalsUboStorage {
|
||||
float colorNurbSelUline[4];
|
||||
float colorActiveSpline[4];
|
||||
|
||||
float colorBonePose[4];
|
||||
|
||||
float colorCurrentFrame[4];
|
||||
|
||||
float colorGrid[4];
|
||||
float colorGridEmphasise[4];
|
||||
float colorGridAxisX[4];
|
||||
@@ -131,6 +135,9 @@ struct DRWShadingGroup *shgroup_instance_bone_sphere_outline(struct DRWPass *pas
|
||||
struct DRWShadingGroup *shgroup_instance_bone_sphere_solid(struct DRWPass *pass);
|
||||
struct DRWShadingGroup *shgroup_instance_bone_stick(struct DRWPass *pass);
|
||||
|
||||
struct GPUShader *mpath_line_shader_get(void);
|
||||
struct GPUShader *mpath_points_shader_get(void);
|
||||
|
||||
int DRW_object_wire_theme_get(
|
||||
struct Object *ob, struct ViewLayer *view_layer, float **r_color);
|
||||
float *DRW_color_background_blend_get(int theme_id);
|
||||
|
@@ -1051,6 +1051,8 @@ static void drw_engines_enable_from_engine(RenderEngineType *engine_type, int dr
|
||||
static void drw_engines_enable_from_object_mode(void)
|
||||
{
|
||||
use_drw_engine(&draw_engine_object_type);
|
||||
/* TODO(fclem) remove this, it does not belong to it's own engine. */
|
||||
use_drw_engine(&draw_engine_motion_path_type);
|
||||
}
|
||||
|
||||
static void drw_engines_enable_from_mode(int mode)
|
||||
@@ -1347,7 +1349,9 @@ void DRW_draw_render_loop_ex(
|
||||
|
||||
drw_debug_draw();
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
drw_engines_draw_text();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
if (DST.draw_ctx.evil_C) {
|
||||
/* needed so manipulator isn't obscured */
|
||||
@@ -2047,6 +2051,7 @@ void DRW_engines_register(void)
|
||||
DRW_engine_register(&draw_engine_edit_metaball_type);
|
||||
DRW_engine_register(&draw_engine_edit_surface_type);
|
||||
DRW_engine_register(&draw_engine_edit_text_type);
|
||||
DRW_engine_register(&draw_engine_motion_path_type);
|
||||
DRW_engine_register(&draw_engine_overlay_type);
|
||||
DRW_engine_register(&draw_engine_paint_texture_type);
|
||||
DRW_engine_register(&draw_engine_paint_vertex_type);
|
||||
|
@@ -126,6 +126,7 @@ typedef struct DRWCallState {
|
||||
|
||||
typedef enum {
|
||||
DRW_CALL_SINGLE, /* A single batch */
|
||||
DRW_CALL_RANGE, /* Like single but only draw a range of vertices/indices. */
|
||||
DRW_CALL_INSTANCES, /* Draw instances without any instancing attribs. */
|
||||
DRW_CALL_GENERATE, /* Uses a callback to draw with any number of batches. */
|
||||
DRW_CALL_PROCEDURAL, /* Generate a drawcall without any Gwn_Batch. */
|
||||
@@ -139,6 +140,10 @@ typedef struct DRWCall {
|
||||
struct { /* type == DRW_CALL_SINGLE */
|
||||
Gwn_Batch *geometry;
|
||||
} single;
|
||||
struct { /* type == DRW_CALL_RANGE */
|
||||
Gwn_Batch *geometry;
|
||||
uint start, count;
|
||||
} range;
|
||||
struct { /* type == DRW_CALL_INSTANCES */
|
||||
Gwn_Batch *geometry;
|
||||
/* Count can be adjusted between redraw. If needed, we can add fixed count. */
|
||||
|
@@ -366,6 +366,25 @@ void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obm
|
||||
BLI_LINKS_APPEND(&shgroup->calls, call);
|
||||
}
|
||||
|
||||
void DRW_shgroup_call_range_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obmat)[4], uint v_sta, uint v_count)
|
||||
{
|
||||
BLI_assert(geom != NULL);
|
||||
BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
|
||||
BLI_assert(v_count);
|
||||
|
||||
DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
|
||||
call->state = drw_call_state_create(shgroup, obmat, NULL);
|
||||
call->type = DRW_CALL_RANGE;
|
||||
call->range.geometry = geom;
|
||||
call->range.start = v_sta;
|
||||
call->range.count = v_count;
|
||||
#ifdef USE_GPU_SELECT
|
||||
call->select_id = DST.select_id;
|
||||
#endif
|
||||
|
||||
BLI_LINKS_APPEND(&shgroup->calls, call);
|
||||
}
|
||||
|
||||
static void drw_shgroup_call_procedural_add_ex(
|
||||
DRWShadingGroup *shgroup, Gwn_PrimType prim_type, uint vert_count, float (*obmat)[4])
|
||||
{
|
||||
@@ -398,12 +417,11 @@ void DRW_shgroup_call_procedural_triangles_add(DRWShadingGroup *shgroup, uint tr
|
||||
drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_TRIS, tria_count * 3, obmat);
|
||||
}
|
||||
|
||||
|
||||
/* These calls can be culled and are optimized for redraw */
|
||||
void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup, Gwn_Batch *geom, Object *ob, bool bypass_culling)
|
||||
{
|
||||
BLI_assert(geom != NULL);
|
||||
BLI_assert(shgroup->type == DRW_SHG_NORMAL);
|
||||
BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
|
||||
|
||||
DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
|
||||
call->state = drw_call_state_object(shgroup, ob->obmat, ob);
|
||||
@@ -423,7 +441,7 @@ void DRW_shgroup_call_object_add_with_callback(
|
||||
DRWCallVisibilityFn *callback, void *user_data)
|
||||
{
|
||||
BLI_assert(geom != NULL);
|
||||
BLI_assert(shgroup->type == DRW_SHG_NORMAL);
|
||||
BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
|
||||
|
||||
DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
|
||||
call->state = drw_call_state_object(shgroup, ob->obmat, ob);
|
||||
@@ -441,7 +459,7 @@ void DRW_shgroup_call_object_add_with_callback(
|
||||
void DRW_shgroup_call_instances_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obmat)[4], uint *count)
|
||||
{
|
||||
BLI_assert(geom != NULL);
|
||||
BLI_assert(shgroup->type == DRW_SHG_NORMAL);
|
||||
BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
|
||||
|
||||
DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
|
||||
call->state = drw_call_state_create(shgroup, obmat, NULL);
|
||||
@@ -459,7 +477,7 @@ void DRW_shgroup_call_instances_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, f
|
||||
void DRW_shgroup_call_object_instances_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, Object *ob, uint *count)
|
||||
{
|
||||
BLI_assert(geom != NULL);
|
||||
BLI_assert(shgroup->type == DRW_SHG_NORMAL);
|
||||
BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
|
||||
|
||||
DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
|
||||
call->state = drw_call_state_object(shgroup, ob->obmat, ob);
|
||||
@@ -479,7 +497,7 @@ void DRW_shgroup_call_generate_add(
|
||||
float (*obmat)[4])
|
||||
{
|
||||
BLI_assert(geometry_fn != NULL);
|
||||
BLI_assert(shgroup->type == DRW_SHG_NORMAL);
|
||||
BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
|
||||
|
||||
DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
|
||||
call->state = drw_call_state_create(shgroup, obmat, NULL);
|
||||
|
@@ -1150,6 +1150,9 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
|
||||
case DRW_CALL_SINGLE:
|
||||
draw_geometry_execute(shgroup, call->single.geometry);
|
||||
break;
|
||||
case DRW_CALL_RANGE:
|
||||
draw_geometry_execute_ex(shgroup, call->range.geometry, call->range.start, call->range.count, false);
|
||||
break;
|
||||
case DRW_CALL_INSTANCES:
|
||||
draw_geometry_execute_ex(shgroup, call->instances.geometry, 0, *call->instances.count, true);
|
||||
break;
|
||||
|
@@ -34,6 +34,7 @@ extern DrawEngineType draw_engine_edit_mesh_type;
|
||||
extern DrawEngineType draw_engine_edit_metaball_type;
|
||||
extern DrawEngineType draw_engine_edit_surface_type;
|
||||
extern DrawEngineType draw_engine_edit_text_type;
|
||||
extern DrawEngineType draw_engine_motion_path_type;
|
||||
extern DrawEngineType draw_engine_paint_texture_type;
|
||||
extern DrawEngineType draw_engine_paint_vertex_type;
|
||||
extern DrawEngineType draw_engine_paint_weight_type;
|
||||
|
@@ -0,0 +1,38 @@
|
||||
|
||||
layout(lines) in;
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform vec2 viewportSize;
|
||||
uniform int lineThickness = 2;
|
||||
|
||||
in vec4 finalColor_geom[];
|
||||
in vec2 ssPos[];
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
vec2 compute_dir(vec2 v0, vec2 v1)
|
||||
{
|
||||
vec2 dir = normalize(v1 - v0 + 1e-8);
|
||||
dir = vec2(-dir.y, dir.x);
|
||||
return dir;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 t;
|
||||
vec2 edge_dir = compute_dir(ssPos[0], ssPos[1]) / viewportSize;
|
||||
|
||||
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
|
||||
|
||||
finalColor = finalColor_geom[0];
|
||||
t = edge_dir * (float(lineThickness) * (is_persp ? gl_in[0].gl_Position.w : 1.0));
|
||||
gl_Position = gl_in[0].gl_Position + vec4(t, 0.0, 0.0); EmitVertex();
|
||||
gl_Position = gl_in[0].gl_Position - vec4(t, 0.0, 0.0); EmitVertex();
|
||||
|
||||
finalColor = finalColor_geom[1];
|
||||
t = edge_dir * (float(lineThickness) * (is_persp ? gl_in[1].gl_Position.w : 1.0));
|
||||
gl_Position = gl_in[1].gl_Position + vec4(t, 0.0, 0.0); EmitVertex();
|
||||
gl_Position = gl_in[1].gl_Position - vec4(t, 0.0, 0.0); EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
@@ -0,0 +1,91 @@
|
||||
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
uniform vec2 viewportSize;
|
||||
|
||||
uniform int frameCurrent;
|
||||
uniform int frameStart;
|
||||
uniform int frameEnd;
|
||||
uniform int cacheStart;
|
||||
uniform bool selected;
|
||||
uniform bool useCustomColor;
|
||||
uniform vec3 customColor;
|
||||
|
||||
in vec3 pos;
|
||||
|
||||
out vec2 ssPos;
|
||||
out vec4 finalColor_geom;
|
||||
|
||||
/* project to screen space */
|
||||
vec2 proj(vec4 pos)
|
||||
{
|
||||
return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
|
||||
}
|
||||
|
||||
#define SET_INTENSITY(A, B, C, min, max) (((1.0 - (float(C - B) / float(C - A))) * (max - min)) + min)
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ViewProjectionMatrix * vec4(pos, 1.0);
|
||||
|
||||
ssPos = proj(gl_Position);
|
||||
|
||||
int frame = gl_VertexID + cacheStart;
|
||||
|
||||
float intensity; /* how faint */
|
||||
|
||||
vec3 blend_base = (abs(frame - frameCurrent) == 1) ? colorCurrentFrame.rgb : colorBackground.rgb; /* "bleed" cframe color to ease color blending */
|
||||
|
||||
/* TODO: We might want something more consistent with custom color and standard colors. */
|
||||
if (frame < frameCurrent) {
|
||||
if (useCustomColor) {
|
||||
/* Custom color: previous frames color is darker than current frame */
|
||||
finalColor_geom.rgb = customColor * 0.25;
|
||||
}
|
||||
else {
|
||||
/* black - before frameCurrent */
|
||||
if (selected) {
|
||||
intensity = SET_INTENSITY(frameStart, frame, frameCurrent, 0.25, 0.75);
|
||||
}
|
||||
else {
|
||||
intensity = SET_INTENSITY(frameStart, frame, frameCurrent, 0.68, 0.92);
|
||||
}
|
||||
finalColor_geom.rgb = mix(colorWire.rgb, blend_base, intensity);
|
||||
}
|
||||
}
|
||||
else if (frame > frameCurrent) {
|
||||
if (useCustomColor) {
|
||||
/* Custom color: next frames color is equal to user selected color */
|
||||
finalColor_geom.rgb = customColor;
|
||||
}
|
||||
else {
|
||||
/* blue - after frameCurrent */
|
||||
if (selected) {
|
||||
intensity = SET_INTENSITY(frameCurrent, frame, frameEnd, 0.25, 0.75);
|
||||
}
|
||||
else {
|
||||
intensity = SET_INTENSITY(frameCurrent, frame, frameEnd, 0.68, 0.92);
|
||||
}
|
||||
|
||||
finalColor_geom.rgb = mix(colorBonePose.rgb, blend_base, intensity);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (useCustomColor) {
|
||||
/* Custom color: current frame color is slightly darker than user selected color */
|
||||
finalColor_geom.rgb = customColor * 0.5;
|
||||
}
|
||||
else {
|
||||
/* green - on frameCurrent */
|
||||
if (selected) {
|
||||
intensity = 0.5f;
|
||||
}
|
||||
else {
|
||||
intensity = 0.99f;
|
||||
}
|
||||
finalColor_geom.rgb = clamp(mix(colorCurrentFrame.rgb, colorBackground.rgb, intensity) - 0.1, 0.0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
finalColor_geom.a = 1.0;
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
|
||||
uniform int pointSize = 2;
|
||||
uniform int frameCurrent;
|
||||
uniform int cacheStart;
|
||||
uniform bool showKeyFrames = true;
|
||||
uniform bool useCustomColor;
|
||||
uniform vec3 customColor;
|
||||
|
||||
in vec3 pos;
|
||||
in int flag;
|
||||
|
||||
#define MOTIONPATH_VERT_SEL (1 << 0)
|
||||
#define MOTIONPATH_VERT_KEY (1 << 1)
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ViewProjectionMatrix * vec4(pos, 1.0);
|
||||
gl_PointSize = float(pointSize + 2);
|
||||
|
||||
int frame = gl_VertexID + cacheStart;
|
||||
finalColor = (useCustomColor) ? vec4(customColor, 1.0) : vec4(1.0);
|
||||
|
||||
/* Bias to reduce z fighting with the path */
|
||||
gl_Position.z -= 1e-4;
|
||||
|
||||
if (showKeyFrames) {
|
||||
if ((flag & MOTIONPATH_VERT_KEY) != 0) {
|
||||
gl_PointSize = float(pointSize + 5);
|
||||
finalColor = colorVertexSelect;
|
||||
/* Bias more to get these on top of regular points */
|
||||
gl_Position.z -= 1e-4;
|
||||
}
|
||||
/* Draw big green dot where the current frame is.
|
||||
* NOTE: this is only done when keyframes are shown, since this adds similar types of clutter
|
||||
*/
|
||||
if (frame == frameCurrent) {
|
||||
gl_PointSize = float(pointSize + 8);
|
||||
finalColor = colorCurrentFrame;
|
||||
/* Bias more to get these on top of keyframes */
|
||||
gl_Position.z -= 1e-4;
|
||||
}
|
||||
}
|
||||
}
|
@@ -48,6 +48,10 @@ layout(std140) uniform globalsBlock {
|
||||
vec4 colorNurbSelUline;
|
||||
vec4 colorActiveSpline;
|
||||
|
||||
vec4 colorBonePose;
|
||||
|
||||
vec4 colorCurrentFrame;
|
||||
|
||||
vec4 colorGrid;
|
||||
vec4 colorGridEmphasise;
|
||||
vec4 colorGridAxisX;
|
||||
|
@@ -193,6 +193,9 @@ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob)
|
||||
/* recalculate paths, then free */
|
||||
animviz_calc_motionpaths(depsgraph, bmain, scene, &targets);
|
||||
BLI_freelistN(&targets);
|
||||
|
||||
/* tag armature object for copy on write - so paths will draw/redraw */
|
||||
DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1004,6 +1004,15 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene)
|
||||
/* recalculate paths, then free */
|
||||
animviz_calc_motionpaths(depsgraph, bmain, scene, &targets);
|
||||
BLI_freelistN(&targets);
|
||||
|
||||
/* tag objects for copy on write - so paths will draw/redraw */
|
||||
CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects)
|
||||
{
|
||||
if (ob->mpath) {
|
||||
DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -61,7 +61,8 @@ typedef struct bMotionPathVert {
|
||||
/* bMotionPathVert->flag */
|
||||
typedef enum eMotionPathVert_Flag {
|
||||
/* vert is selected */
|
||||
MOTIONPATH_VERT_SEL = (1 << 0)
|
||||
MOTIONPATH_VERT_SEL = (1 << 0),
|
||||
MOTIONPATH_VERT_KEY = (1 << 1),
|
||||
} eMotionPathVert_Flag;
|
||||
|
||||
/* ........ */
|
||||
@@ -79,6 +80,12 @@ typedef struct bMotionPath {
|
||||
float color[3]; /* optional custom color */
|
||||
int line_thickness; /* line thickness */
|
||||
int flag; /* baking settings - eMotionPath_Flag */
|
||||
|
||||
/* Used for drawing. */
|
||||
struct Gwn_VertBuf *points_vbo;
|
||||
struct Gwn_Batch *batch_line;
|
||||
struct Gwn_Batch *batch_points;
|
||||
void *pad;
|
||||
} bMotionPath;
|
||||
|
||||
/* bMotionPath->flag */
|
||||
|
@@ -359,6 +359,7 @@ enum {
|
||||
V3D_OVERLAY_LOOK_DEV = (1 << 3),
|
||||
V3D_OVERLAY_WIREFRAMES = (1 << 4),
|
||||
V3D_OVERLAY_HIDE_TEXT = (1 << 5),
|
||||
V3D_OVERLAY_HIDE_MOTION_PATHS = (1 << 6),
|
||||
};
|
||||
|
||||
/* View3DOverlay->edit_flag */
|
||||
|
@@ -2489,6 +2489,12 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Bone Selection", "Show the Bone Selection Overlay");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "show_motion_paths", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_negative_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_HIDE_MOTION_PATHS);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Motion Paths", "Show the Motion Paths Overlay");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "show_look_dev", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_LOOK_DEV);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
|
Reference in New Issue
Block a user