Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / space_action / action_draw.c
index a7c94c0..7c8be94 100644 (file)
 /* Types --------------------------------------------------------------- */
 
 #include "DNA_anim_types.h"
+#include "DNA_cachefile_types.h"
+#include "DNA_object_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_scene_types.h"
 
 #include "BKE_action.h"
 #include "BKE_context.h"
+#include "BKE_pointcache.h"
 
 
 /* Everything from source (BIF, BDR, BSE) ------------------------------ */
 
 #include "BIF_gl.h"
 
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+
 #include "UI_interface.h"
 #include "UI_resources.h"
 #include "UI_view2d.h"
@@ -156,15 +163,12 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
 {
        ListBase anim_data = {NULL, NULL};
        bAnimListElem *ale;
-       int filter;
 
        View2D *v2d = &ar->v2d;
        bDopeSheet *ads = &saction->ads;
        AnimData *adt = NULL;
 
        float act_start, act_end, y;
-       size_t items;
-       int height;
 
        unsigned char col1[3], col2[3];
        unsigned char col1a[3], col2a[3];
@@ -194,10 +198,10 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
        }
 
        /* build list of channels to draw */
-       filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
-       items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+       int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+       size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
 
-       height = ((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac)));
+       int height = ((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac)));
        /* don't use totrect set, as the width stays the same
         * (NOTE: this is ok here, the configuration is pretty straightforward)
         */
@@ -205,6 +209,12 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
 
        /* first backdrop strips */
        y = (float)(-ACHANNEL_HEIGHT(ac));
+
+       Gwn_VertFormat *format = immVertexFormat();
+       unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+       immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
        glEnable(GL_BLEND);
 
        for (ale = anim_data.first; ale; ale = ale->next) {
@@ -229,22 +239,20 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
                                                case ANIMTYPE_SUMMARY:
                                                {
                                                        /* reddish color from NLA */
-                                                       UI_ThemeColor4(TH_ANIM_ACTIVE);
+                                                       immUniformThemeColor(TH_ANIM_ACTIVE);
                                                        break;
                                                }
                                                case ANIMTYPE_SCENE:
                                                case ANIMTYPE_OBJECT:
                                                {
-                                                       if (sel) glColor4ub(col1b[0], col1b[1], col1b[2], 0x45);
-                                                       else glColor4ub(col1b[0], col1b[1], col1b[2], 0x22);
+                                                       immUniformColor3ubvAlpha(col1b, sel ? 0x45 : 0x22);
                                                        break;
                                                }
                                                case ANIMTYPE_FILLACTD:
                                                case ANIMTYPE_DSSKEY:
                                                case ANIMTYPE_DSWOR:
                                                {
-                                                       if (sel) glColor4ub(col2b[0], col2b[1], col2b[2], 0x45);
-                                                       else glColor4ub(col2b[0], col2b[1], col2b[2], 0x22);
+                                                       immUniformColor3ubvAlpha(col2b, sel ? 0x45 : 0x22);
                                                        break;
                                                }
                                                case ANIMTYPE_GROUP:
@@ -252,17 +260,14 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
                                                        bActionGroup *agrp = ale->data;
                                                        if (show_group_colors && agrp->customCol) {
                                                                if (sel) {
-                                                                       unsigned char *cp = (unsigned char *)agrp->cs.select;
-                                                                       glColor4ub(cp[0], cp[1], cp[2], 0x45);
+                                                                       immUniformColor3ubvAlpha((unsigned char *)agrp->cs.select, 0x45);
                                                                }
                                                                else {
-                                                                       unsigned char *cp = (unsigned char *)agrp->cs.solid;
-                                                                       glColor4ub(cp[0], cp[1], cp[2], 0x1D);
+                                                                       immUniformColor3ubvAlpha((unsigned char *)agrp->cs.solid, 0x1D);
                                                                }
                                                        }
                                                        else {
-                                                               if (sel) glColor4ub(col1a[0], col1a[1], col1a[2], 0x22);
-                                                               else glColor4ub(col2a[0], col2a[1], col2a[2], 0x22);
+                                                               immUniformColor3ubvAlpha(sel ? col1a : col2a, 0x22);
                                                        }
                                                        break;
                                                }
@@ -270,53 +275,43 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
                                                {
                                                        FCurve *fcu = ale->data;
                                                        if (show_group_colors && fcu->grp && fcu->grp->customCol) {
-                                                               unsigned char *cp = (unsigned char *)fcu->grp->cs.active;
-
-                                                               if (sel) glColor4ub(cp[0], cp[1], cp[2], 0x65);
-                                                               else glColor4ub(cp[0], cp[1], cp[2], 0x0B);
+                                                               immUniformColor3ubvAlpha((unsigned char *)fcu->grp->cs.active, sel ? 0x65 : 0x0B);
                                                        }
                                                        else {
-                                                               if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22);
-                                                               else glColor4ub(col2[0], col2[1], col2[2], 0x22);
+                                                               immUniformColor3ubvAlpha(sel ? col1 : col2, 0x22);
                                                        }
                                                        break;
                                                }
                                                default:
                                                {
-                                                       if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22);
-                                                       else glColor4ub(col2[0], col2[1], col2[2], 0x22);
-                                                       break;
+                                                       immUniformColor3ubvAlpha(sel ? col1 : col2, 0x22);
                                                }
                                        }
 
                                        /* draw region twice: firstly backdrop, then the current range */
-                                       glRectf(v2d->cur.xmin,  (float)y - ACHANNEL_HEIGHT_HALF(ac),  v2d->cur.xmax + EXTRA_SCROLL_PAD,  (float)y + ACHANNEL_HEIGHT_HALF(ac));
+                                       immRectf(pos, v2d->cur.xmin,  (float)y - ACHANNEL_HEIGHT_HALF(ac),  v2d->cur.xmax + EXTRA_SCROLL_PAD,  (float)y + ACHANNEL_HEIGHT_HALF(ac));
 
                                        if (ac->datatype == ANIMCONT_ACTION)
-                                               glRectf(act_start,  (float)y - ACHANNEL_HEIGHT_HALF(ac),  act_end,  (float)y + ACHANNEL_HEIGHT_HALF(ac));
+                                               immRectf(pos, act_start,  (float)y - ACHANNEL_HEIGHT_HALF(ac),  act_end,  (float)y + ACHANNEL_HEIGHT_HALF(ac));
                                }
                                else if (ac->datatype == ANIMCONT_GPENCIL) {
                                        /* frames less than one get less saturated background */
-                                       if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22);
-                                       else glColor4ub(col2[0], col2[1], col2[2], 0x22);
-                                       glRectf(0.0f, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmin, (float)y + ACHANNEL_HEIGHT_HALF(ac));
+                                       immUniformColor3ubvAlpha(sel ? col1 : col2, 0x22);
+                                       immRectf(pos, 0.0f, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmin, (float)y + ACHANNEL_HEIGHT_HALF(ac));
 
                                        /* frames one and higher get a saturated background */
-                                       if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x44);
-                                       else glColor4ub(col2[0], col2[1], col2[2], 0x44);
-                                       glRectf(v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD,  (float)y + ACHANNEL_HEIGHT_HALF(ac));
+                                       immUniformColor3ubvAlpha(sel ? col1 : col2, 0x44);
+                                       immRectf(pos, v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD,  (float)y + ACHANNEL_HEIGHT_HALF(ac));
                                }
                                else if (ac->datatype == ANIMCONT_MASK) {
                                        /* TODO --- this is a copy of gpencil */
                                        /* frames less than one get less saturated background */
-                                       if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22);
-                                       else glColor4ub(col2[0], col2[1], col2[2], 0x22);
-                                       glRectf(0.0f, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmin, (float)y + ACHANNEL_HEIGHT_HALF(ac));
+                                       immUniformColor3ubvAlpha(sel ? col1 : col2, 0x22);
+                                       immRectf(pos, 0.0f, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmin, (float)y + ACHANNEL_HEIGHT_HALF(ac));
 
                                        /* frames one and higher get a saturated background */
-                                       if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x44);
-                                       else glColor4ub(col2[0], col2[1], col2[2], 0x44);
-                                       glRectf(v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD,  (float)y + ACHANNEL_HEIGHT_HALF(ac));
+                                       immUniformColor3ubvAlpha(sel ? col1 : col2, 0x44);
+                                       immRectf(pos, v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD,  (float)y + ACHANNEL_HEIGHT_HALF(ac));
                                }
                        }
                }
@@ -326,6 +321,17 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
        }
        glDisable(GL_BLEND);
 
+       /* black line marking 'current frame' for Time-Slide transform mode */
+       if (saction->flag & SACTION_MOVING) {
+               immUniformColor3f(0.0f, 0.0f, 0.0f);
+
+               immBegin(GWN_PRIM_LINES, 2);
+               immVertex2f(pos, saction->timeslide, v2d->cur.ymin - EXTRA_SCROLL_PAD);
+               immVertex2f(pos, saction->timeslide, v2d->cur.ymax);
+               immEnd();
+       }
+       immUnbindProgram();
+
        /* Draw keyframes
         *      1) Only channels that are visible in the Action Editor get drawn/evaluated.
         *         This is to try to optimize this for heavier data sets
@@ -378,16 +384,141 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
                y -= ACHANNEL_STEP(ac);
        }
 
-       /* free tempolary channels used for drawing */
+       /* free temporary channels used for drawing */
        ANIM_animdata_freelist(&anim_data);
+}
 
-       /* black line marking 'current frame' for Time-Slide transform mode */
-       if (saction->flag & SACTION_MOVING) {
-               glColor3f(0.0f, 0.0f, 0.0f);
+/* ************************************************************************* */
+/* Timeline - Caches */
+
+void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
+{
+       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;
+
+       BKE_ptcache_ids_from_object(&pidlist, ob, scene, 0);
+
+       unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+       immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+       /* iterate over pointcaches on the active object, and draw each one's range */
+       for (pid = pidlist.first; pid; pid = pid->next) {
+               float col[4];
+
+               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;
+               }
+
+               if (pid->cache->cached_frames == NULL)
+                       continue;
+
+               gpuPushMatrix();
+               gpuTranslate2f(0.0, (float)V2D_SCROLL_HEIGHT + yoffs);
+               gpuScale2f(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;
+               }
+
+               const int sta = pid->cache->startframe, end = pid->cache->endframe;
+               const int len = (end - sta + 1) * 6;
+
+               glEnable(GL_BLEND);
+
+               immUniformColor4fv(col);
+               immRectf(pos, (float)sta, 0.0, (float)end, 1.0);
+
+               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;
+               }
+
+               immUniformColor4fv(col);
+
+               if (len > 0) {
+                       immBeginAtMost(GWN_PRIM_TRIS, len);
+
+                       /* draw a quad for each cached frame */
+                       for (int i = sta; i <= end; i++) {
+                               if (pid->cache->cached_frames[i - sta]) {
+                                       immVertex2f(pos, (float)i - 0.5f, 0.0f);
+                                       immVertex2f(pos, (float)i - 0.5f, 1.0f);
+                                       immVertex2f(pos, (float)i + 0.5f, 1.0f);
 
-               glBegin(GL_LINES);
-               glVertex2f(saction->timeslide, v2d->cur.ymin - EXTRA_SCROLL_PAD);
-               glVertex2f(saction->timeslide, v2d->cur.ymax);
-               glEnd();
+                                       immVertex2f(pos, (float)i - 0.5f, 0.0f);
+                                       immVertex2f(pos, (float)i + 0.5f, 1.0f);
+                                       immVertex2f(pos, (float)i + 0.5f, 0.0f);
+                               }
+                       }
+
+                       immEnd();
+               }
+
+               glDisable(GL_BLEND);
+
+               gpuPopMatrix();
+
+               yoffs += cache_draw_height;
        }
+
+       immUnbindProgram();
+
+       BLI_freelistN(&pidlist);
 }
+
+/* ************************************************************************* */