From 34921e9e5671df4f8932ba671ee5703ca4739ecb Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 21 Aug 2019 17:21:06 +0200 Subject: Timeline: refactor cache drawing I did this mostly to get to know the point cache from this direction. This should not change anything from the user perspective. --- source/blender/editors/space_action/action_draw.c | 352 +++++++++++++--------- 1 file changed, 202 insertions(+), 150 deletions(-) (limited to 'source/blender/editors/space_action') diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index a7b6f399187..0c57113956d 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -352,179 +352,231 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) /* ************************************************************************* */ /* Timeline - Caches */ -void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene) +static bool timeline_cache_is_hidden_by_setting(SpaceAction *saction, PTCacheID *pid) { - PTCacheID *pid; - ListBase pidlist; - const float cache_draw_height = (4.0f * UI_DPI_FAC * U.pixelsize); - float yoffs = 0.f; - - if (!(saction->cache_display & TIME_CACHE_DISPLAY) || (!ob)) { - return; + switch (pid->type) { + case PTCACHE_TYPE_SOFTBODY: + if ((saction->cache_display & TIME_CACHE_SOFTBODY) == 0) { + return true; + } + break; + case PTCACHE_TYPE_PARTICLES: + if ((saction->cache_display & TIME_CACHE_PARTICLES) == 0) { + return true; + } + break; + case PTCACHE_TYPE_CLOTH: + if ((saction->cache_display & TIME_CACHE_CLOTH) == 0) { + return true; + } + break; + case PTCACHE_TYPE_SMOKE_DOMAIN: + case PTCACHE_TYPE_SMOKE_HIGHRES: + if ((saction->cache_display & TIME_CACHE_SMOKE) == 0) { + return true; + } + break; + case PTCACHE_TYPE_DYNAMICPAINT: + if ((saction->cache_display & TIME_CACHE_DYNAMICPAINT) == 0) { + return true; + } + break; + case PTCACHE_TYPE_RIGIDBODY: + if ((saction->cache_display & TIME_CACHE_RIGIDBODY) == 0) { + return true; + } + break; } + return false; +} - BKE_ptcache_ids_from_object(&pidlist, ob, scene, 0); +static void timeline_cache_color_get(PTCacheID *pid, float color[4]) +{ + switch (pid->type) { + case PTCACHE_TYPE_SOFTBODY: + color[0] = 1.0; + color[1] = 0.4; + color[2] = 0.02; + color[3] = 0.1; + break; + case PTCACHE_TYPE_PARTICLES: + color[0] = 1.0; + color[1] = 0.1; + color[2] = 0.02; + color[3] = 0.1; + break; + case PTCACHE_TYPE_CLOTH: + color[0] = 0.1; + color[1] = 0.1; + color[2] = 0.75; + color[3] = 0.1; + break; + case PTCACHE_TYPE_SMOKE_DOMAIN: + case PTCACHE_TYPE_SMOKE_HIGHRES: + color[0] = 0.2; + color[1] = 0.2; + color[2] = 0.2; + color[3] = 0.1; + break; + case PTCACHE_TYPE_DYNAMICPAINT: + color[0] = 1.0; + color[1] = 0.1; + color[2] = 0.75; + color[3] = 0.1; + break; + case PTCACHE_TYPE_RIGIDBODY: + color[0] = 1.0; + color[1] = 0.6; + color[2] = 0.0; + color[3] = 0.1; + break; + default: + color[0] = 1.0; + color[1] = 0.0; + color[2] = 1.0; + color[3] = 0.1; + BLI_assert(0); + break; + } +} - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); +static void timeline_cache_modify_color_based_on_state(PointCache *cache, float color[4]) +{ + if (cache->flag & PTCACHE_BAKED) { + color[0] -= 0.4f; + color[1] -= 0.4f; + color[2] -= 0.4f; + } + else if (cache->flag & PTCACHE_OUTDATED) { + color[0] += 0.4f; + color[1] += 0.4f; + color[2] += 0.4f; + } +} - /* iterate over pointcaches on the active object, and draw each one's range */ - for (pid = pidlist.first; pid; pid = pid->next) { - float col[4]; +static bool timeline_cache_find_next_cached_segment(PointCache *cache, + int search_start_frame, + int *r_segment_start, + int *r_segment_end) +{ + int offset = cache->startframe; + int current = search_start_frame; - switch (pid->type) { - case PTCACHE_TYPE_SOFTBODY: - if (!(saction->cache_display & TIME_CACHE_SOFTBODY)) { - continue; - } - break; - case PTCACHE_TYPE_PARTICLES: - if (!(saction->cache_display & TIME_CACHE_PARTICLES)) { - continue; - } - break; - case PTCACHE_TYPE_CLOTH: - if (!(saction->cache_display & TIME_CACHE_CLOTH)) { - continue; - } - break; - case PTCACHE_TYPE_SMOKE_DOMAIN: - case PTCACHE_TYPE_SMOKE_HIGHRES: - if (!(saction->cache_display & TIME_CACHE_SMOKE)) { - continue; - } - break; - case PTCACHE_TYPE_DYNAMICPAINT: - if (!(saction->cache_display & TIME_CACHE_DYNAMICPAINT)) { - continue; - } - break; - case PTCACHE_TYPE_RIGIDBODY: - if (!(saction->cache_display & TIME_CACHE_RIGIDBODY)) { - continue; - } - break; + /* Find segment start frame. */ + while (true) { + if (current > cache->endframe) { + return false; } - - if (pid->cache->cached_frames == NULL) { - continue; + if (cache->cached_frames[current - offset]) { + *r_segment_start = current; + break; } + current++; + } - GPU_matrix_push(); - GPU_matrix_translate_2f(0.0, (float)V2D_SCROLL_HANDLE_HEIGHT + yoffs); - GPU_matrix_scale_2f(1.0, cache_draw_height); - - switch (pid->type) { - case PTCACHE_TYPE_SOFTBODY: - col[0] = 1.0; - col[1] = 0.4; - col[2] = 0.02; - col[3] = 0.1; - break; - case PTCACHE_TYPE_PARTICLES: - col[0] = 1.0; - col[1] = 0.1; - col[2] = 0.02; - col[3] = 0.1; - break; - case PTCACHE_TYPE_CLOTH: - col[0] = 0.1; - col[1] = 0.1; - col[2] = 0.75; - col[3] = 0.1; - break; - case PTCACHE_TYPE_SMOKE_DOMAIN: - case PTCACHE_TYPE_SMOKE_HIGHRES: - col[0] = 0.2; - col[1] = 0.2; - col[2] = 0.2; - col[3] = 0.1; - break; - case PTCACHE_TYPE_DYNAMICPAINT: - col[0] = 1.0; - col[1] = 0.1; - col[2] = 0.75; - col[3] = 0.1; - break; - case PTCACHE_TYPE_RIGIDBODY: - col[0] = 1.0; - col[1] = 0.6; - col[2] = 0.0; - col[3] = 0.1; - break; - default: - col[0] = 1.0; - col[1] = 0.0; - col[2] = 1.0; - col[3] = 0.1; - BLI_assert(0); - break; + /* Find segment end frame. */ + while (true) { + if (current > cache->endframe) { + *r_segment_end = current - 1; + return true; + } + if (!cache->cached_frames[current - offset]) { + *r_segment_end = current - 1; + return true; } + current++; + } +} + +static uint timeline_cache_segments_count(PointCache *cache) +{ + uint count = 0; + + int current = cache->startframe; + int segment_start; + int segment_end; + while (timeline_cache_find_next_cached_segment(cache, current, &segment_start, &segment_end)) { + count++; + current = segment_end + 1; + } + + return count; +} - const int sta = pid->cache->startframe, end = pid->cache->endframe; +static void timeline_cache_draw_cached_segments(PointCache *cache, uint pos_id) +{ + uint segments_count = timeline_cache_segments_count(cache); + if (segments_count == 0) { + return; + } - GPU_blend(true); + immBeginAtMost(GPU_PRIM_TRIS, segments_count * 6); - immUniformColor4fv(col); - immRectf(pos, (float)sta, 0.0, (float)end, 1.0); + int current = cache->startframe; + int segment_start; + int segment_end; + while (timeline_cache_find_next_cached_segment(cache, current, &segment_start, &segment_end)) { + immRectf_fast(pos_id, segment_start - 0.5f, 0, segment_end + 0.5f, 1.0f); + current = segment_end + 1; + } - col[3] = 0.4f; - if (pid->cache->flag & PTCACHE_BAKED) { - col[0] -= 0.4f; - col[1] -= 0.4f; - col[2] -= 0.4f; - } - else if (pid->cache->flag & PTCACHE_OUTDATED) { - col[0] += 0.4f; - col[1] += 0.4f; - col[2] += 0.4f; - } + immEnd(); +} - immUniformColor4fv(col); +static void timeline_cache_draw_single(PTCacheID *pid, float y_offset, float height, uint pos_id) +{ + GPU_matrix_push(); + GPU_matrix_translate_2f(0.0, (float)V2D_SCROLL_HANDLE_HEIGHT + y_offset); + GPU_matrix_scale_2f(1.0, height); - { - /* draw a quad for each chunk of consecutive cached frames */ - const int chunk_tot = 32; - int chunk_len = 0; - int ista = 0, iend = -1; + float color[4]; + timeline_cache_color_get(pid, color); - for (int i = sta; i <= end; i++) { - if (pid->cache->cached_frames[i - sta]) { - if (chunk_len == 0) { - immBeginAtMost(GPU_PRIM_TRIS, chunk_tot * 6); - } - if (ista > iend) { - chunk_len++; - ista = i; - } - iend = i; - } - else { - if (ista <= iend) { - immRectf_fast(pos, (float)ista - 0.5f, 0.0f, (float)iend + 0.5f, 1.0f); - iend = ista - 1; - } - if (chunk_len >= chunk_tot) { - immEnd(); - chunk_len = 0; - } - } - } - if (ista <= iend) { - immRectf_fast(pos, (float)ista - 0.5f, 0.0f, (float)iend + 0.5f, 1.0f); - } - if (chunk_len != 0) { - immEnd(); - } + immUniformColor4fv(color); + immRectf(pos_id, (float)pid->cache->startframe, 0.0, (float)pid->cache->endframe, 1.0); + + color[3] = 0.4f; + timeline_cache_modify_color_based_on_state(pid->cache, color); + immUniformColor4fv(color); + + timeline_cache_draw_cached_segments(pid->cache, pos_id); + + GPU_matrix_pop(); +} + +void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene) +{ + if ((saction->cache_display & TIME_CACHE_DISPLAY) == 0 || ob == NULL) { + return; + } + + ListBase pidlist; + BKE_ptcache_ids_from_object(&pidlist, ob, scene, 0); + + uint pos_id = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + GPU_blend(true); + + /* Iterate over pointcaches on the active object, and draw each one's range. */ + float y_offset = 0.0f; + const float cache_draw_height = 4.0f * UI_DPI_FAC * U.pixelsize; + for (PTCacheID *pid = pidlist.first; pid; pid = pid->next) { + if (timeline_cache_is_hidden_by_setting(saction, pid)) { + continue; } - GPU_blend(false); + if (pid->cache->cached_frames == NULL) { + continue; + } - GPU_matrix_pop(); + timeline_cache_draw_single(pid, y_offset, cache_draw_height, pos_id); - yoffs += cache_draw_height; + y_offset += cache_draw_height; } + GPU_blend(false); immUnbindProgram(); BLI_freelistN(&pidlist); -- cgit v1.2.3