Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <mail@jlucke.com>2019-08-21 18:21:06 +0300
committerJacques Lucke <mail@jlucke.com>2019-08-21 18:21:50 +0300
commit34921e9e5671df4f8932ba671ee5703ca4739ecb (patch)
treee2255035c7115944d0048d1250709dcd01aab44f /source/blender/editors/space_action
parent922da6dfb400514f03145b7a96c15d978fb7141c (diff)
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.
Diffstat (limited to 'source/blender/editors/space_action')
-rw-r--r--source/blender/editors/space_action/action_draw.c352
1 files changed, 202 insertions, 150 deletions
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);