Three features;
authorTon Roosendaal <ton@blender.org>
Tue, 31 Jan 2006 21:49:05 +0000 (21:49 +0000)
committerTon Roosendaal <ton@blender.org>
Tue, 31 Jan 2006 21:49:05 +0000 (21:49 +0000)
- Live scanline updates while rendering
Using a timer system, each second now the tiles that are being processed
are checked if they could use display.
To make this work pretty, I had to use the threaded 'tile processor' for
a single thread too, but that's now proven to be stable.

Also note that these updates draw per layer, including ztransp progress
separately from solid render.

- Recode of ztransp OSA
Until now (since blender 1.0) the ztransp part was fully rendered and
added on top of the solid part with alpha-over. This adding was done before
the solid part applied sub-pixel sample filtering, causing the ztransp
layer to be always too blurry.

Now the ztransp layer uses same sub=pixel filter, resulting in the same
AA level (and filter results) as the solid part. Quite noticable with hair
renders.

- Vector buffer support & preliminary vector-blur Node
Using the "Render Layer" panel "Vector" pass button, the motion vectors
per pixel are calculated and stored. Accessible via the Compositor.

The vector-blur node is horrible btw! It just uses the length of the
vector to apply a filter like with current (z)blur. I'm committing it anyway,
I'll experiment with it further, and who knows some surprise code shows up!

19 files changed:
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/node_composite.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_material_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/extern/include/RE_shader_ext.h
source/blender/render/intern/include/rendercore.h
source/blender/render/intern/include/renderdatabase.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/pipeline.c
source/blender/render/intern/source/pixelblending.c
source/blender/render/intern/source/ray.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/renderdatabase.c
source/blender/render/intern/source/zbuf.c
source/blender/src/editnode.c
source/blender/src/renderwin.c

index d6ebdbef08313aac4ccc9bcc12b019a739ba1d9e..353389fde38c81ea0d5a06b759c032a5aeed44c4 100644 (file)
@@ -200,6 +200,7 @@ void                        set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str
 #define CMP_NODE_FILTER                212
 #define CMP_NODE_MAP_VALUE     213
 #define CMP_NODE_TIME          214
+#define CMP_NODE_VECBLUR       215
 
 #define CMP_NODE_IMAGE                 220
 #define CMP_NODE_R_RESULT              221
index b95c401808df7bf27fa341c21aa8edc3dea9bc3a..adeac4e6dc3991d70e9f84fc9de9667be016c4db 100644 (file)
@@ -584,7 +584,7 @@ static void do_init_render_material(Material *ma, int osa, float *amb)
                        }
                        
                        if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND|TEXCO_STRESS)) needuv= 1;
-                       else if(ma->texco & (TEXCO_GLOB|TEXCO_UV|TEXCO_OBJECT)) needuv= 1;
+                       else if(ma->texco & (TEXCO_GLOB|TEXCO_UV|TEXCO_OBJECT|TEXCO_SPEED)) needuv= 1;
                        else if(ma->texco & (TEXCO_LAVECTOR|TEXCO_VIEW|TEXCO_STICKY)) needuv= 1;
                }
        }
index e7bfcd722b9763dd84cce58158ed9de506cad5be..89fe2da98cde6915cbcd626d74e9af17a0fc3404 100644 (file)
@@ -70,6 +70,8 @@ typedef struct CompBuf {
 
 /* defines also used for pixel size */
 #define CB_RGBA                4
+#define CB_VEC3                3
+#define CB_VEC2                2
 #define CB_VAL         1
 
 static CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc)
@@ -82,6 +84,10 @@ static CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc)
        if(alloc) {
                if(cbuf->type==CB_RGBA)
                        cbuf->rect= MEM_mallocT(4*sizeof(float)*sizex*sizey, "compbuf RGBA rect");
+               else if(cbuf->type==CB_VEC3)
+                       cbuf->rect= MEM_mallocT(4*sizeof(float)*sizex*sizey, "compbuf Vector3 rect");
+               else if(cbuf->type==CB_VEC2)
+                       cbuf->rect= MEM_mallocT(4*sizeof(float)*sizex*sizey, "compbuf Vector2 rect");
                else
                        cbuf->rect= MEM_mallocT(sizeof(float)*sizex*sizey, "compbuf Fac rect");
                cbuf->malloc= 1;
@@ -735,6 +741,7 @@ static bNodeSocketType cmp_node_rresult_out[]= {
        {       SOCK_RGBA, 0, "Image",          0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
        {       SOCK_VALUE, 0, "Alpha",         1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
        {       SOCK_VALUE, 0, "Z",                     1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_VECTOR, 0, "Vec",          0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
        {       -1, 0, ""       }
 };
 
@@ -761,6 +768,11 @@ static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in,
                                zbuf->rect= rl->rectz;
                                out[2]->data= zbuf;
                        }
+                       if(out[3]->hasoutput && rl->rectvec) {
+                               CompBuf *vecbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VEC2, 0);
+                               vecbuf->rect= rl->rectvec;
+                               out[3]->data= vecbuf;
+                       }
                        
                        generate_preview(node, stackbuf);
                }
@@ -1080,34 +1092,33 @@ static void do_filter3(CompBuf *out, CompBuf *in, float *filter, float fac)
        float *row1, *row2, *row3;
        float *fp, mfac= 1.0f-fac;
        int rowlen, x, y, c;
+       int pixlen= in->type;
        
        rowlen= in->x;
        
-       if(in->type==CB_RGBA) {
+       for(y=2; y<in->y; y++) {
+               /* setup rows */
+               row1= in->rect + pixlen*(y-2)*rowlen;
+               row2= row1 + pixlen*rowlen;
+               row3= row2 + pixlen*rowlen;
                
-               for(y=2; y<in->y; y++) {
-                       /* setup rows */
-                       row1= in->rect + 4*(y-2)*rowlen;
-                       row2= row1 + 4*rowlen;
-                       row3= row2 + 4*rowlen;
-                       
-                       fp= out->rect + 4*(y-1)*rowlen;
-                       QUATCOPY(fp, row2);
-                       fp+= 4;
-                       
-                       for(x=2; x<rowlen; x++) {
-                               for(c=0; c<4; c++) {
-                                       fp[0]= mfac*row2[4] + fac*(filter[0]*row1[0] + filter[1]*row1[4] + filter[2]*row1[8] + filter[3]*row2[0] + filter[4]*row2[4] + filter[5]*row2[8] + filter[6]*row3[0] + filter[7]*row3[4] + filter[8]*row3[8]);
-                                       fp++; row1++; row2++; row3++;
-                               }
+               fp= out->rect + pixlen*(y-1)*rowlen;
+               QUATCOPY(fp, row2);
+               fp+= pixlen;
+               
+               for(x=2; x<rowlen; x++) {
+                       for(c=0; c<pixlen; c++) {
+                               fp[0]= mfac*row2[4] + fac*(filter[0]*row1[0] + filter[1]*row1[4] + filter[2]*row1[8] + filter[3]*row2[0] + filter[4]*row2[4] + filter[5]*row2[8] + filter[6]*row3[0] + filter[7]*row3[4] + filter[8]*row3[8]);
+                               fp++; row1++; row2++; row3++;
                        }
                }
-       }       
+       }
 }
 
+static float soft[9]= {1/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 4/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 1/16.0f};
+
 static void node_composit_exec_filter(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
 {
-       float soft[9]= {1/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 4/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 1/16.0f};
        float sharp[9]= {-1,-1,-1,-1,9,-1,-1,-1,-1};
        float laplace[9]= {1/8.0f, -1/8.0f, 1/8.0f, -1/8.0f, 1.0f, -1/8.0f, 1/8.0f, -1/8.0f, 1/8.0f};
        float sobel[9]= {1,2,1,0,0,0,-1,-2,-1};
@@ -1821,6 +1832,81 @@ static bNodeType cmp_node_blur= {
        
 };
 
+/* **************** VECTOR BLUR ******************** */
+static bNodeSocketType cmp_node_vecblur_in[]= {
+       {       SOCK_RGBA, 1, "Image",                  0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+       {       SOCK_VECTOR, 1, "Vec",                  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       -1, 0, ""       }
+};
+static bNodeSocketType cmp_node_vecblur_out[]= {
+       {       SOCK_RGBA, 0, "Image",                  0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+       {       -1, 0, ""       }
+};
+
+static void fill_rct_in_image(rcti poly, float *rect, int xsize, int ysize, float *col)
+{
+       float *dest;
+       int x, y;
+       
+       for(y=poly.ymin; y<poly.ymax; y++) {
+               for(x=poly.xmin; x<poly.xmax; x++) {
+                       dest= rect + 4*(xsize*y + x);
+                       QUATCOPY(dest, col);
+               }
+       }
+       
+}
+
+
+static void node_composit_exec_vecblur(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+       CompBuf *new, *img= in[0]->data, *vecbuf= in[1]->data, *wbuf;
+       float *vect, *dest;
+       int x, y;
+       
+       if(img==NULL || vecbuf==NULL || out[0]->hasoutput==0)
+               return;
+       if(vecbuf->x!=img->x || vecbuf->y!=img->y) {
+               printf("cannot do different sized vecbuf yet\n");
+               return;
+       }
+       if(vecbuf->type!=CB_VEC2) {
+               printf("input should be vecbuf\n");
+               return;
+       }
+       
+       /* make weights version of vectors */
+       wbuf= alloc_compbuf(img->x, img->y, CB_VAL, 1); // allocs
+       dest= wbuf->rect;
+       vect= vecbuf->rect;
+       for(y=0; y<img->y; y++) {
+               for(x=0; x<img->x; x++, dest++, vect+=2) {
+                       *dest= 0.02f*sqrt(vect[0]*vect[0] + vect[1]*vect[1]);
+                       if(*dest>1.0f) *dest= 1.0f;
+               }
+       }
+       
+       /* make output size of input image */
+       new= alloc_compbuf(img->x, img->y, CB_RGBA, 1); // allocs
+       
+       blur_with_reference(new, img, wbuf, 100.0f, 100.0f);
+       
+       free_compbuf(wbuf);
+       out[0]->data= new;
+}
+
+static bNodeType cmp_node_vecblur= {
+       /* type code   */       CMP_NODE_VECBLUR,
+       /* name        */       "Vector Blur",
+       /* width+range */       120, 80, 200,
+       /* class+opts  */       NODE_CLASS_OPERATOR, NODE_OPTIONS,
+       /* input sock  */       cmp_node_vecblur_in,
+       /* output sock */       cmp_node_vecblur_out,
+       /* storage     */       "",
+       /* execfunc    */       node_composit_exec_vecblur
+       
+};
+
 
 /* ****************** types array for all shaders ****************** */
 
@@ -1842,6 +1928,7 @@ bNodeType *node_all_composit[]= {
        &cmp_node_rresult,
        &cmp_node_alphaover,
        &cmp_node_blur,
+       &cmp_node_vecblur,
        &cmp_node_map_value,
        NULL
 };
index df36fafcab1ec4cca7e8ffe6729e0c08985b2372..6342578115ece445481b81f80df59b176674b6c8 100644 (file)
@@ -4910,7 +4910,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                bScreen *sc;
 
                while(sce) {
-                       sce->r.mode &= ~R_ZBLUR;        // disabled for release
                        
                        if(sce->r.postsat==0.0) sce->r.postsat= 1.0f;
                        
index 04cd1c29a71c5fcfa9f1c92af781851a8a2ebdce..b9b4eaa0c29b04fcad1ae86042d5067e4f498548 100644 (file)
@@ -216,6 +216,7 @@ typedef struct Material {
        /* still stored in vertex->accum, 1 D */
 #define TEXCO_STRAND   8192
 #define TEXCO_STRESS   16384
+#define TEXCO_SPEED            32768
 
 /* mapto */
 #define MAP_COL                        1
index 01776a2e98120202dc1d2a351a1e0596baf453b2..a59e6e064277f546af38abb94d5117ff377c89ef 100644 (file)
@@ -387,9 +387,10 @@ typedef struct Scene {
 #define R_RAYTRACE      0x10000
                /* R_GAUSS is obsolete, but used to retrieve setting from old files */
 #define R_GAUSS        0x20000
+               /* fbuf obsolete... */
 #define R_FBUF                 0x40000
 #define R_THREADS              0x80000
-#define R_ZBLUR                        0x100000
+#define R_SPEED                        0x100000
 
 /* filtertype */
 #define R_FILTER_BOX   0
index d34fc968e773c478b8e0c05f30bed2654f11d230..a9b75184e363c468cb68c993f37c727d828b7f68 100644 (file)
@@ -65,8 +65,9 @@ typedef struct RenderLayer {
        unsigned int lay;                       
        int layflag, passflag;          
        
-       float *rectf;   /* standard rgba buffer */
-       float *rectz;   /* standard camera coordinate zbuffer */
+       float *rectf;   /* 4 float, standard rgba buffer */
+       float *rectz;   /* 1 float, standard camera coordinate zbuffer */
+       float *rectvec; /* 2 float, screen aligned speed vectors */
        
        ListBase passes;
        
@@ -90,7 +91,10 @@ typedef struct RenderResult {
        
        /* the main buffers */
        ListBase layers;
-       int actlay;                             /* copy of renderdata..., so display callbacks can find out */
+       
+       /* allowing live updates: */
+       rcti renrect;
+       RenderLayer *renlay;
        
        /* optional saved endresult on disk */
        char exrfile[FILE_MAXDIR];
index 3524523f9bce48a7ebf2888f0a3dfecb3d7738cb..b8bd46d784e53bbad5c97a826b4fe2a0f6f16e09 100644 (file)
@@ -45,9 +45,12 @@ typedef struct TexResult {
 /* localized shade result data */
 typedef struct ShadeResult 
 {
+       float combined[4];
        float diff[3];
        float spec[3];
        float alpha;
+       float nor[3];
+       float winspeed[2];
        
 } ShadeResult;
 
@@ -76,7 +79,8 @@ typedef struct ShadeInput
        
        /* texture coordinates */
        float lo[3], gl[3], uv[3], ref[3], orn[3], winco[3], sticky[3], vcol[3], rad[3];
-       float vn[3], vno[3], facenor[3], view[3], refcol[4], displace[3], strand, tang[3], stress;
+       float vn[3], vno[3], facenor[3], view[3], refcol[4], displace[3];
+       float strand, tang[3], stress, winspeed[3];
        
        /* dx/dy OSA coordinates */
        float dxco[3], dyco[3];
index cfdf34c205bd2ea7b9a800228a18b6bd36f6d72d..793480458c6f6816725a70c19849309c4dc8d096 100644 (file)
@@ -45,6 +45,7 @@
 
 struct HaloRen;
 struct ShadeInput;
+struct ShadeResult;
 
 /* ------------------------------------------------------------------------- */
 
@@ -84,7 +85,7 @@ void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr);
 void zbufshade(void);
 void zbufshadeDA(void);        /* Delta Accum Pixel Struct */
 
-void *shadepixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, float *col, float *rco);
+void *shadepixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, struct ShadeResult *shr, float *rco);
 
 int count_mask(unsigned short mask);
 
index 6996bca7a5c08e228cc75baff5bf3d34883ba72f..a820800fae101211c83086fa1e590bf1ce848a4b 100644 (file)
@@ -36,8 +36,21 @@ struct HaloRen;
 struct Material;
 struct Render;
 
+/* render allocates totvert/256 of these nodes, for lookup and quick alloc */
+typedef struct VertTableNode {
+       struct VertRen *vert;
+       float *rad;
+       float *sticky;
+       float *strand;
+       float *tangent;
+       float *stress;
+       float *winspeed;
+} VertTableNode;
+
 /* renderdatabase.c */
 void free_renderdata_tables(struct Render *re);
+void free_renderdata_vertnodes(struct VertTableNode *vertnodes);
+
 void set_normalflags(Render *re);
 void project_renderdata(struct Render *re, void (*projectfunc)(float *, float mat[][4], float *),  int do_pano, int part);
 
@@ -54,6 +67,7 @@ float *RE_vertren_get_stress(struct Render *re, struct VertRen *ver, int verify)
 float *RE_vertren_get_rad(struct Render *re, struct VertRen *ver, int verify);
 float *RE_vertren_get_strand(struct Render *re, struct VertRen *ver, int verify);
 float *RE_vertren_get_tangent(struct Render *re, struct VertRen *ver, int verify);
+float *RE_vertren_get_winspeed(struct Render *re, struct VertRen *ver, int verify);
 
 /* haloren->type: flags */
 #define HA_ONLYSKY             1
@@ -61,8 +75,9 @@ float *RE_vertren_get_tangent(struct Render *re, struct VertRen *ver, int verify
 #define HA_XALPHA              4
 #define HA_FLARECIRC   8
 
-
+/* convertblender.c */
 void init_render_world(Render *re);
+void RE_Database_FromScene_Vectors(Render *re, struct Scene *sce);
 
 
 #endif /* RENDERDATABASE_H */
index 9fbc071f0aa610c38ff910232611a458454d4521..beac431ce9d2290a66f55b3db1497cfbdc046566 100644 (file)
@@ -708,6 +708,8 @@ static Material *give_render_material(Render *re, Object *ob, int nr)
                if(ma->mode & MA_ZTRA)
                        re->flag |= R_ZTRA;
        
+       if(re->r.mode & R_SPEED) ma->texco |= NEED_UV;
+       
        return ma;
 }
 
@@ -1404,7 +1406,7 @@ static void use_mesh_edge_lookup(Render *re, Mesh *me, DispListMesh *dlm, MEdge
        }
 }
 
-static void init_render_mesh(Render *re, Object *ob)
+static void init_render_mesh(Render *re, Object *ob, int only_verts)
 {
        Mesh *me;
        MVert *mvert = NULL;
@@ -1493,190 +1495,196 @@ static void init_render_mesh(Render *re, Object *ob)
                                ms++;
                        }
                }
-               /* still to do for keys: the correct local texture coordinate */
-
-               /* faces in order of color blocks */
-               vertofs= re->totvert - totvert;
-               for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
-
-                       ma= give_render_material(re, ob, a1+1);
-                       
-                       /* test for 100% transparant */
-                       ok= 1;
-                       if(ma->alpha==0.0 && ma->spectra==0.0) {
-                               ok= 0;
-                               /* texture on transparency? */
-                               for(a=0; a<MAX_MTEX; a++) {
-                                       if(ma->mtex[a] && ma->mtex[a]->tex) {
-                                               if(ma->mtex[a]->mapto & MAP_ALPHA) ok= 1;
-                                       }
-                               }
-                       }
+               
+               if(!only_verts) {
                        
-                       /* if wire material, and we got edges, don't do the faces */
-                       if(ma->mode & MA_WIRE) {
-                               end= dlm?dlm->totedge:me->totedge;
-                               if(end) ok= 0;
-                       }
+                       /* still to do for keys: the correct local texture coordinate */
 
-                       if(ok) {
-                               TFace *tface= NULL;
+                       /* faces in order of color blocks */
+                       vertofs= re->totvert - totvert;
+                       for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
 
-                               /* radio faces need autosmooth, to separate shared vertices in corners */
-                               if(re->r.mode & R_RADIO)
-                                       if(ma->mode & MA_RADIO) 
-                                               do_autosmooth= 1;
+                               ma= give_render_material(re, ob, a1+1);
                                
-                               end= dlm?dlm->totface:me->totface;
-                               if (dlm) {
-                                       mface= dlm->mface;
-                                       if (dlm->tface) {
-                                               tface= dlm->tface;
-                                               vertcol= NULL;
-                                       } else if (dlm->mcol) {
-                                               vertcol= (unsigned int *)dlm->mcol;
-                                       } else {
-                                               vertcol= NULL;
-                                       }
-                               } else {
-                                       mface= me->mface;
-                                       if (me->tface) {
-                                               tface= me->tface;
-                                               vertcol= NULL;
-                                       } else if (me->mcol) {
-                                               vertcol= (unsigned int *)me->mcol;
-                                       } else {
-                                               vertcol= NULL;
+                               /* test for 100% transparant */
+                               ok= 1;
+                               if(ma->alpha==0.0 && ma->spectra==0.0) {
+                                       ok= 0;
+                                       /* texture on transparency? */
+                                       for(a=0; a<MAX_MTEX; a++) {
+                                               if(ma->mtex[a] && ma->mtex[a]->tex) {
+                                                       if(ma->mtex[a]->mapto & MAP_ALPHA) ok= 1;
+                                               }
                                        }
                                }
+                               
+                               /* if wire material, and we got edges, don't do the faces */
+                               if(ma->mode & MA_WIRE) {
+                                       end= dlm?dlm->totedge:me->totedge;
+                                       if(end) ok= 0;
+                               }
 
-                               for(a=0; a<end; a++) {
-                                       int v1, v2, v3, v4, flag;
-                                       
-                                       if( mface->mat_nr==a1 ) {
-                                               float len;
-                                                       
-                                               v1= mface->v1;
-                                               v2= mface->v2;
-                                               v3= mface->v3;
-                                               v4= mface->v4;
-                                               flag= mface->flag & ME_SMOOTH;
-                                               
-                                               vlr= RE_findOrAddVlak(re, re->totvlak++);
-                                               vlr->ob= ob;
-                                               vlr->v1= RE_findOrAddVert(re, vertofs+v1);
-                                               vlr->v2= RE_findOrAddVert(re, vertofs+v2);
-                                               vlr->v3= RE_findOrAddVert(re, vertofs+v3);
-                                               if(v4) vlr->v4= RE_findOrAddVert(re, vertofs+v4);
-                                               else vlr->v4= 0;
-
-                                               /* render normals are inverted in render */
-                                               if(vlr->v4) len= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co,
-                                                       vlr->v1->co, vlr->n);
-                                               else len= CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co,
-                                                       vlr->n);
+                               if(ok) {
+                                       TFace *tface= NULL;
 
-                                               vlr->mat= ma;
-                                               vlr->flag= flag;
-                                               if((me->flag & ME_NOPUNOFLIP) ) {
-                                                       vlr->flag |= R_NOPUNOFLIP;
+                                       /* radio faces need autosmooth, to separate shared vertices in corners */
+                                       if(re->r.mode & R_RADIO)
+                                               if(ma->mode & MA_RADIO) 
+                                                       do_autosmooth= 1;
+                                       
+                                       end= dlm?dlm->totface:me->totface;
+                                       if (dlm) {
+                                               mface= dlm->mface;
+                                               if (dlm->tface) {
+                                                       tface= dlm->tface;
+                                                       vertcol= NULL;
+                                               } else if (dlm->mcol) {
+                                                       vertcol= (unsigned int *)dlm->mcol;
+                                               } else {
+                                                       vertcol= NULL;
                                                }
-                                               vlr->ec= 0; /* mesh edges rendered separately */
-                                               vlr->lay= ob->lay;
+                                       } else {
+                                               mface= me->mface;
+                                               if (me->tface) {
+                                                       tface= me->tface;
+                                                       vertcol= NULL;
+                                               } else if (me->mcol) {
+                                                       vertcol= (unsigned int *)me->mcol;
+                                               } else {
+                                                       vertcol= NULL;
+                                               }
+                                       }
 
-                                               if(len==0) re->totvlak--;
-                                               else {
-                                                       if(dlm) {
-                                                               if(tface) {
-                                                                       vlr->tface= BLI_memarena_alloc(re->memArena, sizeof(TFace));
-                                                                       vlr->vcol= vlr->tface->col;
-                                                                       memcpy(vlr->tface, tface, sizeof(TFace));
-                                                               } 
-                                                               else if (vertcol) {
-                                                                       vlr->vcol= BLI_memarena_alloc(re->memArena, sizeof(int)*4);
-                                                                       memcpy(vlr->vcol, vertcol+4*a, sizeof(int)*4);
-                                                               }
-                                                       } else {
-                                                               if(tface) {
-                                                                       vlr->vcol= tface->col;
-                                                                       vlr->tface= tface;
-                                                               } 
-                                                               else if (vertcol) {
-                                                                       vlr->vcol= vertcol+4*a;
+                                       for(a=0; a<end; a++) {
+                                               int v1, v2, v3, v4, flag;
+                                               
+                                               if( mface->mat_nr==a1 ) {
+                                                       float len;
+                                                               
+                                                       v1= mface->v1;
+                                                       v2= mface->v2;
+                                                       v3= mface->v3;
+                                                       v4= mface->v4;
+                                                       flag= mface->flag & ME_SMOOTH;
+                                                       
+                                                       vlr= RE_findOrAddVlak(re, re->totvlak++);
+                                                       vlr->ob= ob;
+                                                       vlr->v1= RE_findOrAddVert(re, vertofs+v1);
+                                                       vlr->v2= RE_findOrAddVert(re, vertofs+v2);
+                                                       vlr->v3= RE_findOrAddVert(re, vertofs+v3);
+                                                       if(v4) vlr->v4= RE_findOrAddVert(re, vertofs+v4);
+                                                       else vlr->v4= 0;
+
+                                                       /* render normals are inverted in render */
+                                                       if(vlr->v4) len= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co,
+                                                               vlr->v1->co, vlr->n);
+                                                       else len= CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co,
+                                                               vlr->n);
+
+                                                       vlr->mat= ma;
+                                                       vlr->flag= flag;
+                                                       if((me->flag & ME_NOPUNOFLIP) ) {
+                                                               vlr->flag |= R_NOPUNOFLIP;
+                                                       }
+                                                       vlr->ec= 0; /* mesh edges rendered separately */
+                                                       vlr->lay= ob->lay;
+
+                                                       if(len==0) re->totvlak--;
+                                                       else {
+                                                               if(dlm) {
+                                                                       if(tface) {
+                                                                               vlr->tface= BLI_memarena_alloc(re->memArena, sizeof(TFace));
+                                                                               vlr->vcol= vlr->tface->col;
+                                                                               memcpy(vlr->tface, tface, sizeof(TFace));
+                                                                       } 
+                                                                       else if (vertcol) {
+                                                                               vlr->vcol= BLI_memarena_alloc(re->memArena, sizeof(int)*4);
+                                                                               memcpy(vlr->vcol, vertcol+4*a, sizeof(int)*4);
+                                                                       }
+                                                               } else {
+                                                                       if(tface) {
+                                                                               vlr->vcol= tface->col;
+                                                                               vlr->tface= tface;
+                                                                       } 
+                                                                       else if (vertcol) {
+                                                                               vlr->vcol= vertcol+4*a;
+                                                                       }
                                                                }
                                                        }
                                                }
-                                       }
 
-                                       mface++;
-                                       if(tface) tface++;
+                                               mface++;
+                                               if(tface) tface++;
+                                       }
                                }
                        }
-               }
-               
-               /* exception... we do edges for wire mode. potential conflict when faces exist... */
-               end= dlm?dlm->totedge:me->totedge;
-               mvert= dlm?dlm->mvert:me->mvert;
-               ma= give_render_material(re, ob, 1);
-               if(end && (ma->mode & MA_WIRE)) {
-                       MEdge *medge;
-                       struct edgesort *edgetable;
-                       int totedge;
-                       
-                       medge= dlm?dlm->medge:me->medge;
                        
-                       /* we want edges to have UV and vcol too... */
-                       edgetable= make_mesh_edge_lookup(me, dlm, &totedge);
-                       
-                       for(a1=0; a1<end; a1++, medge++) {
-                               if (medge->flag&ME_EDGERENDER) {
-                                       MVert *v0 = &mvert[medge->v1];
-                                       MVert *v1 = &mvert[medge->v2];
+                       /* exception... we do edges for wire mode. potential conflict when faces exist... */
+                       end= dlm?dlm->totedge:me->totedge;
+                       mvert= dlm?dlm->mvert:me->mvert;
+                       ma= give_render_material(re, ob, 1);
+                       if(end && (ma->mode & MA_WIRE)) {
+                               MEdge *medge;
+                               struct edgesort *edgetable;
+                               int totedge;
+                               
+                               medge= dlm?dlm->medge:me->medge;
+                               
+                               /* we want edges to have UV and vcol too... */
+                               edgetable= make_mesh_edge_lookup(me, dlm, &totedge);
+                               
+                               for(a1=0; a1<end; a1++, medge++) {
+                                       if (medge->flag&ME_EDGERENDER) {
+                                               MVert *v0 = &mvert[medge->v1];
+                                               MVert *v1 = &mvert[medge->v2];
 
-                                       vlr= RE_findOrAddVlak(re, re->totvlak++);
-                                       vlr->ob= ob;
-                                       vlr->v1= RE_findOrAddVert(re, vertofs+medge->v1);
-                                       vlr->v2= RE_findOrAddVert(re, vertofs+medge->v2);
-                                       vlr->v3= vlr->v2;
-                                       vlr->v4= NULL;
-                                       
-                                       if(edgetable) {
-                                               use_mesh_edge_lookup(re, me, dlm, medge, vlr, edgetable, totedge);
+                                               vlr= RE_findOrAddVlak(re, re->totvlak++);
+                                               vlr->ob= ob;
+                                               vlr->v1= RE_findOrAddVert(re, vertofs+medge->v1);
+                                               vlr->v2= RE_findOrAddVert(re, vertofs+medge->v2);
+                                               vlr->v3= vlr->v2;
+                                               vlr->v4= NULL;
+                                               
+                                               if(edgetable) {
+                                                       use_mesh_edge_lookup(re, me, dlm, medge, vlr, edgetable, totedge);
+                                               }
+                                               
+                                               xn= (v0->no[0]+v1->no[0]);
+                                               yn= (v0->no[1]+v1->no[1]);
+                                               zn= (v0->no[2]+v1->no[2]);
+                                               /* transpose ! */
+                                               vlr->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
+                                               vlr->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
+                                               vlr->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+                                               Normalise(vlr->n);
+                                               
+                                               vlr->mat= ma;
+                                               vlr->flag= 0;
+                                               vlr->ec= ME_V1V2;
+                                               vlr->lay= ob->lay;
                                        }
-                                       
-                                       xn= (v0->no[0]+v1->no[0]);
-                                       yn= (v0->no[1]+v1->no[1]);
-                                       zn= (v0->no[2]+v1->no[2]);
-                                       /* transpose ! */
-                                       vlr->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
-                                       vlr->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
-                                       vlr->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
-                                       Normalise(vlr->n);
-                                       
-                                       vlr->mat= ma;
-                                       vlr->flag= 0;
-                                       vlr->ec= ME_V1V2;
-                                       vlr->lay= ob->lay;
                                }
+                               if(edgetable)
+                                       MEM_freeN(edgetable);
                        }
-                       if(edgetable)
-                               MEM_freeN(edgetable);
                }
        }
        
-       if (test_for_displace(re, ob ) ) {
-               calc_vertexnormals(re, totverto, totvlako, 0);
-               do_displacement(re, ob, totvlako, re->totvlak-totvlako, totverto, re->totvert-totverto);
-       }
+       if(!only_verts) {
+               if (test_for_displace(re, ob ) ) {
+                       calc_vertexnormals(re, totverto, totvlako, 0);
+                       do_displacement(re, ob, totvlako, re->totvlak-totvlako, totverto, re->totvert-totverto);
+               }
 
-       if(do_autosmooth || (me->flag & ME_AUTOSMOOTH)) {
-               autosmooth(re, totverto, totvlako, me->smoothresh);
-       }
+               if(do_autosmooth || (me->flag & ME_AUTOSMOOTH)) {
+                       autosmooth(re, totverto, totvlako, me->smoothresh);
+               }
 
-       calc_vertexnormals(re, totverto, totvlako, need_tangent);
+               calc_vertexnormals(re, totverto, totvlako, need_tangent);
 
-       if(need_stress)
-               calc_edge_stress(re, me, totverto, totvlako);
+               if(need_stress)
+                       calc_edge_stress(re, me, totverto, totvlako);
+       }
        
        if(dlm) displistmesh_free(dlm);
        if(dm_needsfree) dm->release(dm);
@@ -2422,7 +2430,7 @@ static void set_phong_threshold(Render *re, Object *ob, int startface, int numfa
        }
 }
 
-static void init_render_object(Render *re, Object *ob)
+static void init_render_object(Render *re, Object *ob, int only_verts)
 {
        float mat[4][4];
        int startface, startvert;
@@ -2439,7 +2447,7 @@ static void init_render_object(Render *re, Object *ob)
        else if(ob->type==OB_SURF)
                init_render_surf(re, ob);
        else if(ob->type==OB_MESH)
-               init_render_mesh(re, ob);
+               init_render_mesh(re, ob, only_verts);
        else if(ob->type==OB_MBALL)
                init_render_mball(re, ob);
        else {
@@ -2735,8 +2743,8 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
        Base *base;
        Object *ob;
        Scene *sce;
-       unsigned int lay;
        float mat[4][4];
+       unsigned int lay;
 
        re->scene= scene;
 
@@ -2799,7 +2807,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
                                if (re->r.renderer==R_YAFRAY) {
                                        if ((ob->type!=OB_MBALL) && ((ob->transflag & OB_DUPLIFRAMES)!=0)) {
                                                printf("Object %s has OB_DUPLIFRAMES set, adding to renderlist\n", ob->id.name);
-                                               init_render_object(re, ob);
+                                               init_render_object(re, ob, 0);
                                        }
                                }
                                /* before make duplis, update particle for current frame */
@@ -2811,7 +2819,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
                                }
                                
                                if(ob->type==OB_MBALL) {
-                                       init_render_object(re, ob);
+                                       init_render_object(re, ob, 0);
                                }
                                else {
                                        DupliObject *dob;
@@ -2833,7 +2841,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
                                                                printf("Adding dupli matrix for object %s\n", obd->id.name);
                                                                YAF_addDupliMtx(obd);
                                                        }
-                                                       else init_render_object(re, obd);
+                                                       else init_render_object(re, obd, 0);
                                                }
                                                Mat4CpyMat4(obd->obmat, dob->omat);
                                        }
@@ -2853,14 +2861,14 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
                                                                (ob->parent->type!=OB_LATTICE) && YAF_objectKnownData(ob))
                                                        printf("From parent: Added dupli matrix for linked data object %s\n", ob->id.name);
                                                else
-                                                       init_render_object(re, ob);
+                                                       init_render_object(re, ob, 0);
                                        }
                                        else if ((ob->type!=OB_EMPTY) && (ob->type!=OB_LAMP) && (ob->type!=OB_ARMATURE) && YAF_objectKnownData(ob))
                                                printf("Added dupli matrix for linked data object %s\n", ob->id.name);
                                        else
-                                               init_render_object(re, ob);
+                                               init_render_object(re, ob, 0);
                                }
-                               else init_render_object(re, ob);
+                               else init_render_object(re, ob, 0);
                        }
 
                }
@@ -2895,6 +2903,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
                        if(lar->shb) {
                                makeshadowbuf(re, lar);
                        }
+                       re->stats_draw(&re->i);
                }
                
                /* yafray: 'direct' radiosity, environment maps and octree init not needed for yafray render */
@@ -2924,6 +2933,158 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
        
 }
 
+static void database_fromscene_vectors(Render *re, Scene *scene)
+{
+       extern int slurph_opt;  /* key.c */
+       Base *base;
+       Object *ob;
+       Scene *sce;
+       float mat[4][4];
+       unsigned int lay;
+       
+       re->scene= scene;
+       
+       /* XXX add test if dbase was filled already? */
+       
+       re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+       re->totvlak=re->totvert=re->totlamp=re->tothalo= 0;
+       re->lights.first= re->lights.last= NULL;
+
+       slurph_opt= 0;
+       
+       /* in localview, lamps are using normal layers, objects only local bits */
+       if(re->scene->lay & 0xFF000000) lay= re->scene->lay & 0xFF000000;
+       else lay= re->scene->lay;
+       
+       /* applies changes fully, still using G.scene for timing... */
+       G.scene->r.cfra--;
+       scene_update_for_newframe(re->scene, lay);
+       G.scene->r.cfra++;
+       
+       /* if no camera, viewmat should have been set! */
+       if(re->scene->camera) {
+               Mat4Ortho(re->scene->camera->obmat);
+               Mat4Invert(mat, re->scene->camera->obmat);
+               RE_SetView(re, mat);
+       }
+       
+       for(SETLOOPER(re->scene, base)) {
+               ob= base->object;
+               /* imat objects has to be done here, since displace can have texture using Object map-input */
+               MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+               MTC_Mat4Invert(ob->imat, mat);
+               /* each object should only be rendered once */
+               ob->flag &= ~OB_DONE;
+       }
+       
+       /* MAKE RENDER DATA */
+       
+       for(SETLOOPER(re->scene, base)) {
+               ob= base->object;
+               
+               /* OB_DONE means the object itself got duplicated, so was already converted */
+               if(ob->flag & OB_DONE);
+               else if( (base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->scene->lay)) ) {
+                       if(ob->transflag & OB_DUPLI) {
+                               
+                               /* before make duplis, update particle for current frame */
+                               if(ob->transflag & OB_DUPLIVERTS) {
+                                       PartEff *paf= give_parteff(ob);
+                                       if(paf) {
+                                               if(paf->flag & PAF_ANIMATED) build_particle_system(ob);
+                                       }
+                               }
+                               
+                               if(ob->type==OB_MBALL) {
+                                       init_render_object(re, ob, 1);
+                               }
+                               else {
+                                       DupliObject *dob;
+                                       ListBase *lb= object_duplilist(sce, ob);
+                                       
+                                       for(dob= lb->first; dob; dob= dob->next) {
+                                               Object *obd= dob->ob;
+                                               Mat4CpyMat4(obd->obmat, dob->mat);
+                                               
+                                               if(obd->type!=OB_MBALL) {
+                                                       init_render_object(re, obd, 1);
+                                               }
+                                               Mat4CpyMat4(obd->obmat, dob->omat);
+                                       }
+                                       BLI_freelistN(lb);
+                               }
+                       }
+                       else {
+                               init_render_object(re, ob, 1);
+                       }
+                       
+               }
+       }
+       
+       project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0);
+}
+
+void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
+{
+       struct VertTableNode *vertnodes;
+       int vertnodeslen= 0;
+       printf("creating speed vectors \n");
+       re->r.mode |= R_SPEED;
+
+       /* creates entire dbase */
+       database_fromscene_vectors(re, sce);
+       
+       /* copy away vertex info */
+       vertnodes= re->vertnodes;
+       vertnodeslen= re->vertnodeslen;
+       re->vertnodes= NULL;
+       re->vertnodeslen= 0;
+       
+       /* free dbase and make the real one */
+       RE_Database_Free(re);
+       
+       RE_Database_FromScene(re, sce, 1);
+       
+       if(re->vertnodeslen!=vertnodeslen) {
+               printf("ERROR: vertex tables different in size %d %d\n", re->vertnodeslen, vertnodeslen);
+       }
+       else {
+               VertRen *ver= NULL, *oldver= NULL;
+               float *speed, div, zco[2], oldzco[2];
+               float zmulx= re->winx/2, zmuly= re->winy/2;
+               int a;
+               
+               for(a=0; a< re->totvert;a++) {
+                       if((a & 255)==0) {
+                               ver= re->vertnodes[a>>8].vert;
+                               oldver= vertnodes[a>>8].vert;
+                       }
+                       else {
+                               ver++;
+                               oldver++;
+                       }
+                       
+                       /* now map both hocos to screenspace */
+                       div= 1.0f/ver->ho[3];
+                       zco[0]= zmulx*(1.0+ver->ho[0]*div);
+                       zco[1]= zmuly*(1.0+ver->ho[1]*div);
+                       
+                       div= 1.0f/oldver->ho[3];
+                       oldzco[0]= zmulx*(1.0+oldver->ho[0]*div);
+                       oldzco[1]= zmuly*(1.0+oldver->ho[1]*div);
+                       
+                       speed= RE_vertren_get_winspeed(re, ver, 1);
+                       speed[0]= oldzco[0] - zco[0];
+                       speed[1]= oldzco[1] - zco[1];
+                       //printf("speed %d %f %f\n", a, speed[0], speed[1]);
+               }
+       }
+       
+       free_renderdata_vertnodes(vertnodes);
+       
+}
+
+
 /* exported call to recalculate hoco for vertices, when winmat changed */
 void RE_DataBase_ApplyWindow(Render *re)
 {
index 375cb5f3a0c1719e2244d0d3aa75f488403e1960..e4268735e8abfa58c86283f3cc0aab8440aa7da0 100644 (file)
@@ -150,6 +150,7 @@ static void free_render_result(RenderResult *res)
                RenderLayer *rl= res->layers.first;
                if(rl->rectf) RE_freeN(rl->rectf);
                if(rl->rectz) RE_freeN(rl->rectz);
+               if(rl->rectvec) RE_freeN(rl->rectvec);
                BLI_remlink(&res->layers, rl);
                RE_freeN(rl);
        }
@@ -193,9 +194,6 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
        rr->tilerect.ymin= partrct->ymin - re->disprect.ymin;
        rr->tilerect.ymax= partrct->ymax - re->disprect.ymax;
        
-       /* copy, so display callbacks can find out too */
-       rr->actlay= re->r.actlay;
-       
        /* check renderdata for amount of layers */
        for(srl= re->r.layers.first; srl; srl= srl->next) {
                rl= RE_callocN(sizeof(RenderLayer), "new render layer");
@@ -209,6 +207,8 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
                rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
                if(srl->passflag  & SCE_PASS_Z)
                        rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z");
+               if(srl->passflag  & SCE_PASS_VECTOR)
+                       rl->rectvec= RE_callocN(rectx*recty*sizeof(float)*2, "layer float Vector");
                
        }
        /* previewrender and envmap don't do layers, so we make a default one */
@@ -229,6 +229,47 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
        return rr;
 }
 
+static int render_result_needs_vector(RenderResult *rr)
+{
+       RenderLayer *rl;
+       
+       for(rl= rr->layers.first; rl; rl= rl->next)
+               if(rl->passflag & SCE_PASS_VECTOR)
+                       return 1;
+       return 0;
+}
+
+static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize)
+{
+       int y, ofs, copylen, tilex, tiley;
+       
+       copylen= tilex= rrpart->rectx;
+       tiley= rrpart->recty;
+       
+       if(rrpart->crop) {      /* filters add pixel extra */
+               tile+= pixsize*(rrpart->crop + rrpart->crop*tilex);
+               
+               copylen= tilex - 2*rrpart->crop;
+               tiley -= 2*rrpart->crop;
+               
+               ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop);
+               target+= pixsize*ofs;
+       }
+       else {
+               ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin);
+               target+= pixsize*ofs;
+       }
+
+       copylen *= sizeof(float)*pixsize;
+       tilex *= pixsize;
+       ofs= pixsize*rr->rectx;
+
+       for(y=0; y<tiley; y++) {
+               memcpy(target, tile, copylen);
+               target+= ofs;
+               tile+= tilex;
+       }
+}
 
 /* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
 /* no test happens here if it fits... we also assume layers are in sync */
@@ -236,53 +277,18 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
 static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
 {
        RenderLayer *rl, *rlp;
-       float *rf, *rfp;
-       float *rz, *rzp;
-       int y, height, len, copylen;
        
        for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
                
-               /* first combined and z pass */
-               if(rl->rectf && rlp->rectf) {
-                       int ofs;
-                       
-                       rzp= rlp->rectz;
-                       rfp= rlp->rectf;
-                       
-                       copylen=len= rrpart->rectx;
-                       height= rrpart->recty;
-                       
-                       if(rrpart->crop) {      /* filters add pixel extra */
-                               
-                               if(rzp) rzp+= rrpart->crop + rrpart->crop*len;
-                               if(rfp) rfp+= 4*(rrpart->crop + rrpart->crop*len);
-                               
-                               copylen= len-2*rrpart->crop;
-                               height -= 2*rrpart->crop;
-                               
-                               ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop);
-                               rz= rl->rectz+ ofs;
-                               rf= rl->rectf+ 4*ofs;
-                       }
-                       else {
-                               ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin);
-                               rz= rl->rectz+ ofs;
-                               rf= rl->rectf+ 4*ofs;
-                       }
-
-                       for(y=0; y<height; y++) {
-                               if(rzp) {
-                                       memcpy(rz, rzp, 4*copylen);
-                                       rz+= rr->rectx;
-                                       rzp+= len;
-                               }
-                               if(rfp) {
-                                       memcpy(rf, rfp, 16*copylen);
-                                       rf+= 4*rr->rectx;
-                                       rfp+= 4*len;
-                               }
-                       }
-               }
+               /* combined */
+               if(rl->rectf && rlp->rectf)
+                       do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
+               /* z */
+               if(rl->rectz && rlp->rectz)
+                       do_merge_tile(rr, rrpart, rl->rectz, rlp->rectz, 1);
+               /* vector */
+               if(rl->rectvec && rlp->rectvec)
+                       do_merge_tile(rr, rrpart, rl->rectvec, rlp->rectvec, 2);
        }
 }
 
@@ -313,7 +319,7 @@ RenderResult *RE_GetResult(Render *re)
 /* fill provided result struct with what's currently active or done */
 void RE_GetResultImage(Render *re, RenderResult *rr)
 {
-       memset(rr, sizeof(RenderResult), 0);
+       memset(rr, 0, sizeof(RenderResult));
 
        if(re && re->result) {
                RenderLayer *rl;
@@ -359,7 +365,7 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
        }
        else
                /* else fill with black */
-               memset(rect, sizeof(int)*re->rectx*re->recty, 0);
+               memset(rect, 0, sizeof(int)*re->rectx*re->recty);
 }
 
 
@@ -573,9 +579,9 @@ static int do_part_thread(void *pa_v)
                        zbufshadeDA_tile(pa);
                else
                        zbufshade_tile(pa);
-                       
-               if(!R.test_break())
-                       merge_render_result(R.result, pa->result);
+               
+               /* merge too on break! */       
+               merge_render_result(R.result, pa->result);
        }
        
        pa->ready= 1;
@@ -661,13 +667,16 @@ static void threaded_tile_processor(Render *re)
 {
        ListBase threads;
        RenderPart *pa;
-       int maxthreads=2, rendering=1, counter= 1;
+       int maxthreads, rendering=1, counter= 1, hasdrawn, drawtimer=0;
        
        if(re->result==NULL)
                return;
        if(re->test_break())
                return;
        
+       if(re->r.mode & R_THREADS) maxthreads= 2;
+       else maxthreads= 1;
+       
        initparts(re);
        BLI_init_threads(&threads, do_part_thread, maxthreads);
        
@@ -687,10 +696,13 @@ static void threaded_tile_processor(Render *re)
                                BLI_insert_thread(&threads, pa);
                        }
                }
-               else
+               else {
                        PIL_sleep_ms(50);
+                       drawtimer++;
+               }
                
                /* check for ready ones to display, and if we need to continue */
+               hasdrawn= 0;
                rendering= 0;
                for(pa= re->parts.first; pa; pa= pa->next) {
                        if(pa->ready) {
@@ -700,11 +712,21 @@ static void threaded_tile_processor(Render *re)
                                        free_render_result(pa->result);
                                        pa->result= NULL;
                                        re->i.partsdone++;
+                                       hasdrawn= 1;
+                               }
+                       }
+                       else {
+                               rendering= 1;
+                               if(pa->nr && pa->result && drawtimer>20) {
+                                       re->display_draw(pa->result, &pa->result->renrect);
+                                       hasdrawn= 1;
                                }
                        }
-                       else rendering= 1;
                }
                
+               if(hasdrawn)
+                       drawtimer= 0;
+               
                /* on break, wait for all slots to get freed */
                if(re->test_break() && BLI_available_threads(&threads)==maxthreads)
                        rendering= 0;
@@ -719,7 +741,7 @@ static void threaded_tile_processor(Render *re)
 
 void RE_TileProcessor(Render *re)
 {
-       if(re->r.mode & R_THREADS
+       if(1
                threaded_tile_processor(re);
        else
                render_tile_processor(re);      
@@ -734,8 +756,11 @@ void render_one_frame(Render *re)
 //     re->cfra= cfra; /* <- unused! */
        
        /* make render verts/faces/halos/lamps */
-       RE_Database_FromScene(re, re->scene, 1);
-
+       if(render_result_needs_vector(re->result))
+               RE_Database_FromScene_Vectors(re, re->scene);
+       else
+          RE_Database_FromScene(re, re->scene, 1);
+       
        RE_TileProcessor(re);
        
        /* free all render verts etc */
index 860aeed29d7996f5d178faef2789b820956e7b70..ece9970e885c71c846e6760bfbe2148c5a7e6a57 100644 (file)
@@ -74,22 +74,14 @@ extern struct Render R;
 void addAlphaOverFloat(float *dest, float *source)
 {
     /* d = s + (1-alpha_s)d*/
-    float c;
     float mul;
     
        mul= 1.0 - source[3];
 
-       c= (mul*dest[0]) + source[0];
-       dest[0]= c;
-   
-       c= (mul*dest[1]) + source[1];
-       dest[1]= c;
-
-       c= (mul*dest[2]) + source[2];
-       dest[2]= c;
-
-       c= (mul*dest[3]) + source[3];
-       dest[3]= c;
+       dest[0]= (mul*dest[0]) + source[0];
+       dest[1]= (mul*dest[1]) + source[1];
+       dest[2]= (mul*dest[2]) + source[2];
+       dest[3]= (mul*dest[3]) + source[3];
 
 }
 
@@ -98,7 +90,6 @@ void addAlphaOverFloat(float *dest, float *source)
 
 void addAlphaUnderFloat(float *dest, float *source)
 {
-    float c;
     float mul;
     
     if( (-RE_EMPTY_COLOUR_FLOAT < dest[3])
@@ -112,18 +103,10 @@ void addAlphaUnderFloat(float *dest, float *source)
 
        mul= 1.0 - dest[3];
 
-       c= (mul*source[0]) + dest[0];
-       dest[0]= c;
-   
-       c= (mul*source[1]) + dest[1];
-       dest[1]= c;
-
-       c= (mul*source[2]) + dest[2];
-       dest[2]= c;
-
-       c= (mul*source[3]) + dest[3];
-       dest[3]= c;
-
+       dest[0]+= (mul*source[0]);
+       dest[1]+= (mul*source[1]);
+       dest[2]+= (mul*source[2]);
+       dest[3]+= (mul*source[3]);
 } 
 
 
@@ -229,6 +212,68 @@ void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w)
        }
 }
 
+/* filtered adding to scanlines */
+void add_filt_fmask_alphaunder(unsigned int mask, float *col, float *rowbuf, int row_w)
+{
+       /* calc the value of mask */
+       float **fmask1= R.samples->fmask1, **fmask2=R.samples->fmask2;
+       float *rb1, *rb2, *rb3;
+       float val, r, g, b, al, acol[4];
+       unsigned int a, maskand, maskshift;
+       int j;
+       
+       r= col[0];
+       g= col[1];
+       b= col[2];
+       al= col[3];
+       
+       rb2= rowbuf-4;
+       rb3= rb2-4*row_w;
+       rb1= rb2+4*row_w;
+       
+       maskand= (mask & 255);
+       maskshift= (mask >>8);
+       
+       for(j=2; j>=0; j--) {
+               
+               a= j;
+               
+               val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
+               if(val!=0.0) {
+                       acol[0]= val*r;
+                       acol[1]= val*g;
+                       acol[2]= val*b;
+                       acol[3]= val*al;
+                       addAlphaUnderFloat(rb1, acol);
+               }
+               a+=3;
+               
+               val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
+               if(val!=0.0) {
+                       acol[0]= val*r;
+                       acol[1]= val*g;
+                       acol[2]= val*b;
+                       acol[3]= val*al;
+                       addAlphaUnderFloat(rb2, acol);
+               }
+               a+=3;
+               
+               val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
+               if(val!=0.0) {
+                       acol[0]= val*r;
+                       acol[1]= val*g;
+                       acol[2]= val*b;
+                       acol[3]= val*al;
+                       addAlphaUnderFloat(rb3, acol);
+               }
+               
+               rb1+= 4;
+               rb2+= 4;
+               rb3+= 4;
+       }
+}
+
+
 /* ------------------------------------------------------------------------- */
 void addalphaAddFloat(float *dest, float *source)
 {
index 19ec1dd546d0e4c81ecbc6a0d5922f50f5b2c01f..d5d0a951604592ff0f5c8de94d2ea5cfc908839d 100644 (file)
@@ -628,6 +628,8 @@ void makeoctree(Render *re)
        }
        
        MEM_freeN(ocface);
+       re->stats_draw(&re->i);
+
 }
 
 /* ************ raytracer **************** */
index 87c1330d5ef3cca62494562ece54744a52b3913c..ba45953eefcbd67c45014a644cba7baaf7eb58f4 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 /* system includes */
+#include <stdio.h>
 #include <math.h>
 #include <string.h>
 #include <stdlib.h>
@@ -1854,7 +1855,20 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i
                if(mode & MA_TANGENT_V) 
                        shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
        }
-
+       
+       if(R.r.mode & R_SPEED) {
+               float *s1, *s2, *s3;
+               
+               s1= RE_vertren_get_winspeed(&R, v1, 0);
+               s2= RE_vertren_get_winspeed(&R, v2, 0);
+               s3= RE_vertren_get_winspeed(&R, v3, 0);
+               if(s1 && s2 && s3) {
+                       shi->winspeed[0]= (l*s3[0] - u*s1[0] - v*s2[0]);
+                       shi->winspeed[1]= (l*s3[1] - u*s1[1] - v*s2[1]);
+                       shi->winspeed[2]= 0.0f;
+               }                       
+       }
+       
        /* texture coordinates. shi->dxuv shi->dyuv have been set */
        if(texco & NEED_UV) {
                if(texco & TEXCO_ORCO) {
@@ -2111,9 +2125,8 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
 /* note, facenr declared volatile due to over-eager -O2 optimizations
  * on cygwin (particularly -frerun-cse-after-loop)
  */
-void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, int mask, float *col, float *rco)
+void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, int mask, ShadeResult *shr, float *rco)
 {
-       ShadeResult shr;
        ShadeInput shi;
        VlakRen *vlr=NULL;
        
@@ -2131,8 +2144,8 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
        shi.depth= 0;   // means first hit, not raytracing
        
        if(facenr==0) { /* sky */
-               col[0]= 0.0; col[1]= 0.0; col[2]= 0.0; col[3]= 0.0;
-               VECCOPY(rco, col);
+               memset(shr, 0, sizeof(ShadeResult));
+               rco[0]= rco[1]= rco[2]= 0.0f;
        }
        else if( (facenr & 0x7FFFFF) <= R.totvlak) {
                VertRen *v1;
@@ -2327,34 +2340,38 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
                VECCOPY(shi.vno, shi.vn);
                
                if(shi.mat->nodetree && shi.mat->use_nodes) {
-                       ntreeShaderExecTree(shi.mat->nodetree, &shi, &shr);
+                       ntreeShaderExecTree(shi.mat->nodetree, &shi, shr);
                }
                else {
                        /* copy all relevant material vars, note, keep this synced with render_types.h */
                        memcpy(&shi.r, &shi.mat->r, 23*sizeof(float));
                        shi.har= shi.mat->har;
                        
-                       shade_material_loop(&shi, &shr);
+                       shade_material_loop(&shi, shr);
                }
                
                /* after shading and composit layers */
-               if(shr.spec[0]<0.0f) shr.spec[0]= 0.0f;
-               if(shr.spec[1]<0.0f) shr.spec[1]= 0.0f;
-               if(shr.spec[2]<0.0f) shr.spec[2]= 0.0f;
+               if(shr->spec[0]<0.0f) shr->spec[0]= 0.0f;
+               if(shr->spec[1]<0.0f) shr->spec[1]= 0.0f;
+               if(shr->spec[2]<0.0f) shr->spec[2]= 0.0f;
                
-               if(shr.diff[0]<0.0f) shr.diff[0]= 0.0f;
-               if(shr.diff[1]<0.0f) shr.diff[1]= 0.0f;
-               if(shr.diff[2]<0.0f) shr.diff[2]= 0.0f;
+               if(shr->diff[0]<0.0f) shr->diff[0]= 0.0f;
+               if(shr->diff[1]<0.0f) shr->diff[1]= 0.0f;
+               if(shr->diff[2]<0.0f) shr->diff[2]= 0.0f;
                
-               VECADD(col, shr.diff, shr.spec);
+               VECADD(shr->combined, shr->diff, shr->spec);
+               
+               /* additional passes */
+               shr->winspeed[0]= shi.winspeed[0]; shr->winspeed[1]= shi.winspeed[1];
+               VECCOPY(shr->nor, shi.vn);
                
                /* NOTE: this is not correct here, sky from raytrace gets corrected... */
                /* exposure correction */
                if(R.wrld.exp!=0.0 || R.wrld.range!=1.0) {
                        if((shi.mat->mode & MA_SHLESS)==0) {
-                               col[0]= R.wrld.linfac*(1.0-exp( col[0]*R.wrld.logfac) );
-                               col[1]= R.wrld.linfac*(1.0-exp( col[1]*R.wrld.logfac) );
-                               col[2]= R.wrld.linfac*(1.0-exp( col[2]*R.wrld.logfac) );
+                               shr->combined[0]= R.wrld.linfac*(1.0-exp( shr->combined[0]*R.wrld.logfac) );
+                               shr->combined[1]= R.wrld.linfac*(1.0-exp( shr->combined[1]*R.wrld.logfac) );
+                               shr->combined[2]= R.wrld.linfac*(1.0-exp( shr->combined[2]*R.wrld.logfac) );
                        }
                }
                
@@ -2367,26 +2384,20 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
                }
                else alpha= 1.0;
 
-               if(shr.alpha!=1.0 || alpha!=1.0) {
+               if(shr->alpha!=1.0 || alpha!=1.0) {
                        if(shi.mat->mode & MA_RAYTRANSP) {
                                fac= alpha;     
-                               if(R.r.mode & R_UNIFIED)
-                                       /* unified alpha overs everything... */
-                                       col[3]= 1.0f;
-                               else {
-                                       /* sky was applied allready for ray transp, only do mist */
-                                       col[3]= shr.alpha;
-                               }
+                               shr->combined[3]= shr->alpha;
                        }
                        else {
-                               fac= alpha*(shr.alpha);
-                               col[3]= fac;
+                               fac= alpha*(shr->alpha);
+                               shr->combined[3]= fac;
                        }                       
-                       col[0]*= fac;
-                       col[1]*= fac;
-                       col[2]*= fac;
+                       shr->combined[0]*= fac;
+                       shr->combined[1]*= fac;
+                       shr->combined[2]*= fac;
                }
-               else col[3]= 1.0;
+               else shr->combined[3]= 1.0;
        }
        
        if(R.flag & R_LAMPHALO) {
@@ -2403,29 +2414,30 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
                        calc_view_vector(shi.view, x, y);
                        shi.co[2]= 0.0;
                        
-                       renderspothalo(&shi, col, 1.0);
+                       renderspothalo(&shi, shr->combined, 1.0);
                }
                else
-                       renderspothalo(&shi, col, col[3]);
+                       renderspothalo(&shi, shr->combined, shr->combined[3]);
        }
        
        return vlr;
 }
 
-static void shadepixel_sky(RenderPart *pa, float x, float y, int z, int facenr, int mask, float *colf)
+static void shadepixel_sky(RenderPart *pa, float x, float y, int z, int facenr, int mask, ShadeResult *shr)
 {
        VlakRen *vlr;
        float collector[4], rco[3];
        
-       vlr= shadepixel(pa, x, y, z, facenr, mask, colf, rco);
-       if(colf[3] != 1.0) {
+       vlr= shadepixel(pa, x, y, z, facenr, mask, shr, rco);
+       if(shr->combined[3] != 1.0) {
+               
                /* bail out when raytrace transparency (sky included already) */
                if(vlr && (R.r.mode & R_RAYTRACE))
                        if(vlr->mat->mode & MA_RAYTRANSP) return;
                
                renderSkyPixelFloat(collector, x, y, vlr?rco:NULL);
-               addAlphaOverFloat(collector, colf);
-               QUATCOPY(colf, collector);
+               addAlphaOverFloat(collector, shr->combined);
+               QUATCOPY(shr->combined, collector);
        }
 }
 
@@ -2503,14 +2515,16 @@ static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
 
 /* ********************* MAINLOOPS ******************** */
 
-static void shadeDA_tile(RenderPart *pa, float *rectf, float *recta)
+static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
 {
+       RenderResult *rr= pa->result;
+       ShadeResult shr;
        PixStr *ps;
        float xs, ys;
-       float fcol[4], *rf, *grf, *acol= NULL;
+       float *fcol= shr.combined, *rf, *rectf= rl->rectf;
        long *rd, *rectdaps= pa->rectdaps;
        int zbuf, samp, curmask, face, mask, fullmask;
-       int b, x, y, full_osa, seed, crop=0;
+       int b, x, y, full_osa, seed, crop=0, offs=0, od;
        
        if(R.test_break()) return; 
        
@@ -2519,23 +2533,24 @@ static void shadeDA_tile(RenderPart *pa, float *rectf, float *recta)
 
        fullmask= (1<<R.osa)-1;
        
-       /* might need it for gamma, in end of this function */
-       grf= rectf;
-       
        /* filtered render, for now we assume only 1 filter size */
        if(pa->crop) {
                crop= 1;
                rectf+= 4*(pa->rectx + 1);
                rectdaps+= pa->rectx + 1;
-               if(recta) recta+= 4*(pa->rectx + 1);
+               offs= pa->rectx + 1;
        }
        
-       for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++) {
+       /* scanline updates have to be 2 lines behind */
+       rr->renrect.ymin= 0;
+       rr->renrect.ymax= -2*crop;
+       
+       for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
                rf= rectf;
                rd= rectdaps;
-               if(recta) acol= recta;
-
-               for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, rf+=4) {
+               od= offs;
+               
+               for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, rf+=4, od++) {
                        BLI_thread_srandom(pa->thread, seed+x);
                        
                        ps= (PixStr *)(*rd);
@@ -2567,9 +2582,8 @@ static void shadeDA_tile(RenderPart *pa, float *rectf, float *recta)
                                                if(curmask & (1<<samp)) {
                                                        xs= (float)x + R.jit[samp][0];
                                                        ys= (float)y + R.jit[samp][1];
-                                                       shadepixel_sky(pa, xs, ys, zbuf, face, (1<<samp), fcol);
+                                                       shadepixel_sky(pa, xs, ys, zbuf, face, (1<<samp), &shr);
                                                        
-                                                       if(acol && acol[3]!=0.0) addAlphaOverFloat(fcol, acol);
                                                        if(R.do_gamma) {
                                                                fcol[0]= gammaCorrect(fcol[0]);
                                                                fcol[1]= gammaCorrect(fcol[1]);
@@ -2579,14 +2593,12 @@ static void shadeDA_tile(RenderPart *pa, float *rectf, float *recta)
                                                }
                                        }
                                }
-                               else {
+                               else if(curmask) {
                                        b= R.samples->centmask[curmask];
                                        xs= (float)x+R.samples->centLut[b & 15];
                                        ys= (float)y+R.samples->centLut[b>>4];
-                                       shadepixel_sky(pa, xs, ys, zbuf, face, curmask, fcol);
-                                       
-                                       if(acol && acol[3]!=0.0) addAlphaOverFloat(fcol, acol);
-                                       
+                                       shadepixel_sky(pa, xs, ys, zbuf, face, curmask, &shr);
+       
                                        if(R.do_gamma) {
                                                fcol[0]= gammaCorrect(fcol[0]);
                                                fcol[1]= gammaCorrect(fcol[1]);
@@ -2600,22 +2612,29 @@ static void shadeDA_tile(RenderPart *pa, float *rectf, float *recta)
                                if(ps==NULL) break;
                                else ps= ps->next;
                        }
-                       if(acol) acol+=4;
+                       
+                       /* passes */
+                       if(rl->passflag & SCE_PASS_VECTOR) {
+                               float *fp= rl->rectvec+2*od;
+                               fp[0]= shr.winspeed[0];
+                               fp[1]= shr.winspeed[1];
+                       }
                }
                
                rectf+= 4*pa->rectx;
                rectdaps+= pa->rectx;
-               if(recta) recta+= 4*pa->rectx;
+               offs+= pa->rectx;
                seed+= pa->rectx;
                
                if(y&1) if(R.test_break()) break; 
        }
        
        if(R.do_gamma) {
-               for(y= pa->rectx*pa->recty; y>0; y--, grf+=4) {
-                       grf[0] = invGammaCorrect(grf[0]);
-                       grf[1] = invGammaCorrect(grf[1]);
-                       grf[2] = invGammaCorrect(grf[2]);
+               rectf= rl->rectf;
+               for(y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
+                       rectf[0] = invGammaCorrect(rectf[0]);
+                       rectf[1] = invGammaCorrect(rectf[1]);
+                       rectf[2] = invGammaCorrect(rectf[2]);
                }
        }                       
        
@@ -2706,9 +2725,10 @@ static void make_pixelstructs(RenderPart *pa, ListBase *lb)
 /* supposed to be fully threadable! */
 void zbufshadeDA_tile(RenderPart *pa)
 {
+       RenderResult *rr= pa->result;
        RenderLayer *rl;
        ListBase psmlist= {NULL, NULL};
-       float *acolrect= NULL, *edgerect= NULL;
+       float *edgerect= NULL;
        
        set_part_zbuf_clipflag(pa);
        
@@ -2718,7 +2738,9 @@ void zbufshadeDA_tile(RenderPart *pa)
        pa->rectz= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
        if(R.r.mode & R_EDGE) edgerect= RE_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
        
-       for(rl= pa->result->layers.first; rl; rl= rl->next) {
+       for(rl= rr->layers.first; rl; rl= rl->next) {
+               /* indication for scanline updates */
+               rr->renlay= rl;
 
                /* initialize pixelstructs */
                addpsmain(&psmlist);
@@ -2737,20 +2759,28 @@ void zbufshadeDA_tile(RenderPart *pa)
                        fillrect(pa->rectz, pa->rectx, pa->recty, 0x7FFFFFFF);
 
                
-               /* we do transp layer first, so its get added with filter in main buffer... still incorrect though */
+               /* shades solid */
+               if(rl->layflag & SCE_LAY_SOLID) 
+                       shadeDA_tile(pa, rl);
+               
+               /* transp layer */
                if(R.flag & R_ZTRA) {
                        if(rl->layflag & SCE_LAY_ZTRA) {
-                               acolrect= RE_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
-                               zbuffer_transp_shade(pa, acolrect, rl->lay, rl->layflag);
+                               float *acolrect= RE_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
+                               float *fcol= rl->rectf, *acol= acolrect;
+                               int x;
+                               
+                               /* swap for live updates */
+                               SWAP(float *, acolrect, rl->rectf);
+                               zbuffer_transp_shade(pa, rl->rectf, rl->lay, rl->layflag);
+                               SWAP(float *, acolrect, rl->rectf);
+                               
+                               for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
+                                       addAlphaOverFloat(fcol, acol);
+                               }
+                               RE_freeN(acolrect);
                        }
                }
-
-               /* shades solid and adds transparent layer */
-               if(rl->layflag & SCE_LAY_SOLID) 
-                       shadeDA_tile(pa, rl->rectf, acolrect);
-               else if(acolrect) {
-                       SWAP(float *, acolrect, rl->rectf);
-               }
                
                /* extra layers */
                if(R.r.mode & R_EDGE) 
@@ -2763,10 +2793,6 @@ void zbufshadeDA_tile(RenderPart *pa)
                        convert_zbuf_to_distbuf(pa, rl);
                
                /* free stuff within loop! */
-               if(acolrect) {
-                       RE_freeN(acolrect);
-                       acolrect= NULL;
-               }
                RE_freeN(pa->rectdaps); pa->rectdaps= NULL;
                freeps(&psmlist);
        }
@@ -2786,35 +2812,67 @@ void zbufshadeDA_tile(RenderPart *pa)
 /* supposed to be fully threadable! */
 void zbufshade_tile(RenderPart *pa)
 {
+       ShadeResult shr;
+       RenderResult *rr= pa->result;
        RenderLayer *rl;
-       
+
        set_part_zbuf_clipflag(pa);
        
        /* zbuffer code clears/inits rects */
        pa->rectp= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
        pa->rectz= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
        
-       for(rl= pa->result->layers.first; rl; rl= rl->next) {
+       for(rl= rr->layers.first; rl; rl= rl->next) {
+               /* indication for scanline updates */
+               rr->renlay= rl;
+               
                zbuffer_solid(pa, rl->lay, rl->layflag);
                
                if(!R.test_break()) {
                        if(rl->layflag & SCE_LAY_SOLID) {
                                float *fcol= rl->rectf;
-                               int x, y, *rp= pa->rectp, *rz= pa->rectz;
-
-                               for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
-                                       for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, rp++, fcol+=4) {
-                                               shadepixel_sky(pa, (float)x, (float)y, *rz, *rp, 0, fcol);
+                               int x, y, *rp= pa->rectp, *rz= pa->rectz, offs=0;
+                               
+                               /* init scanline updates */
+                               rr->renrect.ymin=rr->renrect.ymax= 0;
+                               
+                               for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
+                                       for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, rp++, fcol+=4, offs++) {
+                                               shadepixel_sky(pa, (float)x, (float)y, *rz, *rp, 0, &shr);
+                                               QUATCOPY(fcol, shr.combined);
+                                               
+                                               /* passes */
+                                               if(*rp && (rl->passflag & SCE_PASS_VECTOR)) {
+                                                       float *fp= rl->rectvec+2*(offs);
+                                                       fp[0]= shr.winspeed[0];
+                                                       fp[1]= shr.winspeed[1];
+                                               }
                                        }
-                                       if(y&1) if(R.test_break()) break; 
+                                       if(y&1)
+                                               if(R.test_break()) break; 
                                }
                        }
                }
                
-               if(!R.test_break())
-                       if(R.flag & R_ZTRA)
-                               if(rl->layflag & SCE_LAY_ZTRA)
+               if(!R.test_break()) {
+                       if(R.flag & R_ZTRA) {
+                               if(rl->layflag & SCE_LAY_ZTRA) {
+                                       float *acolrect= RE_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
+                                       float *fcol= rl->rectf, *acol= acolrect;
+                                       int x;
+                                       
+                                       /* swap for live updates */
+                                       SWAP(float *, acolrect, rl->rectf);
                                        zbuffer_transp_shade(pa, rl->rectf, rl->lay, rl->layflag);
+                                       SWAP(float *, acolrect, rl->rectf);
+                                       
+                                       for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
+                                               addAlphaOverFloat(fcol, acol);
+                                       }
+                                       RE_freeN(acolrect);
+                               }
+                       }
+               }
                
                if(!R.test_break()) {
                        if(R.r.mode & R_EDGE) {
index 098d4491060d426b715768dfca0002cd1cd96b2e..d43a2bea8b855f75538082c02d5f7e2bd9b44f08 100644 (file)
 #define RE_STRAND_ELEMS                1
 #define RE_TANGENT_ELEMS       3
 #define RE_STRESS_ELEMS                1
-
-/* render allocates totvert/256 of these nodes, for lookup and quick alloc */
-typedef struct VertTableNode {
-       struct VertRen *vert;
-       float *rad;
-       float *sticky;
-       float *strand;
-       float *tangent;
-       float *stress;
-} VertTableNode;
+#define RE_WINSPEED_ELEMS              2
 
 float *RE_vertren_get_sticky(Render *re, VertRen *ver, int verify)
 {
@@ -179,6 +170,21 @@ float *RE_vertren_get_tangent(Render *re, VertRen *ver, int verify)
        return tangent + (ver->index & 255)*RE_TANGENT_ELEMS;
 }
 
+/* needs malloc */
+float *RE_vertren_get_winspeed(Render *re, VertRen *ver, int verify)
+{
+       float *winspeed;
+       int nr= ver->index>>8;
+       
+       winspeed= re->vertnodes[nr].winspeed;
+       if(winspeed==NULL) {
+               if(verify) 
+                       winspeed= re->vertnodes[nr].winspeed= MEM_mallocN(256*RE_WINSPEED_ELEMS*sizeof(float), "winspeed table");
+               else
+                       return NULL;
+       }
+       return winspeed + (ver->index & 255)*RE_WINSPEED_ELEMS;
+}
 
 VertRen *RE_findOrAddVert(Render *re, int nr)
 {
@@ -218,6 +224,31 @@ VertRen *RE_findOrAddVert(Render *re, int nr)
        return v;
 }
 
+void free_renderdata_vertnodes(VertTableNode *vertnodes)
+{
+       int a;
+       
+       for(a=0; vertnodes[a].vert; a++) {
+               MEM_freeN(vertnodes[a].vert);
+               
+               if(vertnodes[a].rad)
+                       MEM_freeN(vertnodes[a].rad);
+               if(vertnodes[a].sticky)
+                       MEM_freeN(vertnodes[a].sticky);
+               if(vertnodes[a].strand)
+                       MEM_freeN(vertnodes[a].strand);
+               if(vertnodes[a].tangent)
+                       MEM_freeN(vertnodes[a].tangent);
+               if(vertnodes[a].stress)
+                       MEM_freeN(vertnodes[a].stress);
+               if(vertnodes[a].winspeed)
+                       MEM_freeN(vertnodes[a].winspeed);
+       }
+       
+       MEM_freeN(vertnodes);
+       
+}
+
 void free_renderdata_tables(Render *re)
 {
        int a=0;
@@ -241,22 +272,7 @@ void free_renderdata_tables(Render *re)
        }
 
        if(re->vertnodes) {
-               for(a=0; re->vertnodes[a].vert; a++) {
-                       MEM_freeN(re->vertnodes[a].vert);
-
-                       if(re->vertnodes[a].rad)
-                               MEM_freeN(re->vertnodes[a].rad);
-                       if(re->vertnodes[a].sticky)
-                               MEM_freeN(re->vertnodes[a].sticky);
-                       if(re->vertnodes[a].strand)
-                               MEM_freeN(re->vertnodes[a].strand);
-                       if(re->vertnodes[a].tangent)
-                               MEM_freeN(re->vertnodes[a].tangent);
-                       if(re->vertnodes[a].stress)
-                               MEM_freeN(re->vertnodes[a].stress);
-               }
-               
-               MEM_freeN(re->vertnodes);
+               free_renderdata_vertnodes(re->vertnodes);
                re->vertnodes= NULL;
                re->vertnodeslen= 0;
        }
index 7fac9f599447453cf144bbf511f4ea735fc5c2c7..4830db352d77cb7d6849aa7ea8602e022cbe856c 100644 (file)
@@ -56,6 +56,7 @@
 #include "RE_render_ext.h"
 
 /* local includes */
+#include "gammaCorrectionTables.h"
 #include "render_types.h"
 #include "renderpipeline.h"
 #include "renderdatabase.h"
@@ -1879,7 +1880,7 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int sample)
        long *rd;
        
        /* now, in OSA the pixstructs contain all faces filled in */
-       if(R.r.mode & R_OSA) fillrect(arectz, pa->rectx, pa->recty, 0x7FFFFFFF);
+       if(R.osa) fillrect(arectz, pa->rectx, pa->recty, 0x7FFFFFFF);
        else {
                memcpy(arectz, pa->rectz, 4*pa->rectx*pa->recty);
                return;
@@ -1952,7 +1953,7 @@ static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, u
                copyto_abufz(pa, zspan.arectz, zsample);        /* init zbuffer */
                zspan.mask= 1<<zsample;
                
-               if(R.r.mode & R_OSA) {
+               if(R.osa) {
                        zspan.zofsx= -pa->disprect.xmin-R.jit[zsample][0];
                        zspan.zofsy= -pa->disprect.ymin-R.jit[zsample][1];
                }
@@ -2010,7 +2011,7 @@ static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, u
                        }
                }
                
-               if((R.r.mode & R_OSA)==0) break;
+               if(R.osa==0) break;
                if(R.test_break()) break;
        }
        
@@ -2033,13 +2034,14 @@ static int vergzvlak(const void *a1, const void *a2)
  */
 static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, float *fcol)
 {
+       ShadeResult shr;
        float rco[3];
        
        if( (facenr & 0x7FFFFF) > R.totvlak) {
                printf("error in shadetrapixel nr: %d\n", (facenr & 0x7FFFFF));
                return;
        }
-       if(R.r.mode & R_OSA) {
+       if(R.osa) {
                VlakRen *vlr= RE_findOrAddVlak(&R, (facenr-1) & 0x7FFFFF);
                float accumcol[4]={0,0,0,0}, tot=0.0;
                int a;
@@ -2047,11 +2049,11 @@ static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, i
                if(vlr->flag & R_FULL_OSA) {
                        for(a=0; a<R.osa; a++) {
                                if(mask & (1<<a)) {
-                                       shadepixel(pa, x+R.jit[a][0], y+R.jit[a][1], z, facenr, 1<<a, fcol, rco);
-                                       accumcol[0]+= fcol[0];
-                                       accumcol[1]+= fcol[1];
-                                       accumcol[2]+= fcol[2];
-                                       accumcol[3]+= fcol[3];
+                                       shadepixel(pa, x+R.jit[a][0], y+R.jit[a][1], z, facenr, 1<<a, &shr, rco);
+                                       accumcol[0]+= shr.combined[0];
+                                       accumcol[1]+= shr.combined[1];
+                                       accumcol[2]+= shr.combined[2];
+                                       accumcol[3]+= shr.combined[3];
                                        tot+= 1.0;
                                }
                        }
@@ -2065,11 +2067,14 @@ static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, i
                        int b= R.samples->centmask[mask];
                        x= x+R.samples->centLut[b & 15];
                        y= y+R.samples->centLut[b>>4];
-                       shadepixel(pa, x, y, z, facenr, mask, fcol, rco);
-       
+                       shadepixel(pa, x, y, z, facenr, mask, &shr, rco);
+                       QUATCOPY(fcol, shr.combined);
                }
        }
-       else shadepixel(pa, x, y, z, facenr, mask, fcol, rco);
+       else {
+               shadepixel(pa, x, y, z, facenr, mask, &shr, rco);
+               QUATCOPY(fcol, shr.combined);
+       }
 }
 
 static int addtosampcol(float *sampcol, float *fcol, int mask)
@@ -2089,14 +2094,15 @@ static int addtosampcol(float *sampcol, float *fcol, int mask)
 
 void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short layflag)
 {
+       RenderResult *rr= pa->result;
        APixstr *APixbuf;      /* Zbuffer: linked list of face samples */
-       APixstr *ap, *apn;
+       APixstr *ap, *aprect, *apn;
        ListBase apsmbase={NULL, NULL};
-       float col[4], fcol[4], tempcol[4], sampcol[16*4], *scol, accumcol[4];
-       float fac, alpha[32];
-       int x, y, a, zrow[MAX_ZROW][3], totface, nr;
+       float fcol[4], sampcol[16*4];
+       float fac, alpha[32], *passrect= pass;
+       int x, y, crop=0, a, zrow[MAX_ZROW][3], totface;
        int sval;
-       
+
        /* looks nicer for calling code */
        if(R.test_break())
                return;
@@ -2110,7 +2116,7 @@ void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short l
        }
        
        /* alpha LUT */
-       if(R.r.mode & R_OSA ) {
+       if(R.osa) {
                fac= (1.0/(float)R.osa);
                for(a=0; a<=R.osa; a++) {
                        alpha[a]= (float)a*fac;
@@ -2119,12 +2125,26 @@ void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short l
        
        /* fill the Apixbuf */
        zbuffer_abuf(pa, APixbuf, &apsmbase, lay, layflag);
+       aprect= APixbuf;
        
-       /* render tile */
-       ap= APixbuf;
+       /* filtered render, for now we assume only 1 filter size */
+       if(pa->crop) {
+               crop= 1;
+               passrect+= 4*(pa->rectx + 1);
+               aprect+= pa->rectx + 1;
+       }
        
-       for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
-               for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ap++, pass+=4) {
+       /* init scanline updates */
+       rr->renrect.ymin= 0;
+       rr->renrect.ymax= -pa->crop;
+
+       /* render the tile */
+       
+       for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
+               pass= passrect;
+               ap= aprect;
+               
+               for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, ap++, pass+=4) {
 
                        if(ap->p[0]) {
                                /* sort in z */
@@ -2148,23 +2168,14 @@ void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short l
                                        
                                        shadetrapixel(pa, (float)x, (float)y, zrow[0][0], zrow[0][1], zrow[0][2], fcol);
                                        
-                                       nr= count_mask(zrow[0][2]);
-                                       if( (R.r.mode & R_OSA) && nr<R.osa) {
-                                               fac= alpha[ nr ];
-                                               col[0]= (fcol[0]*fac);
-                                               col[1]= (fcol[1]*fac);
-                                               col[2]= (fcol[2]*fac);
-                                               col[3]= (fcol[3]*fac);
+                                       if(R.osa) {
+                                               add_filt_fmask(zrow[0][2], fcol, pass, rr->rectx);
                                        }
                                        else {
-                                               col[0]= fcol[0];
-                                               col[1]= fcol[1];
-                                               col[2]= fcol[2];
-                                               col[3]= fcol[3];
+                                               QUATCOPY(pass, fcol);
                                        }
                                }
                                else {
-                                       col[0]= col[1]= col[2]= col[3]= 0.0f;
                                        
                                        if(totface==2) {
                                                if(zrow[0][0] < zrow[1][0]) {
@@ -2178,62 +2189,43 @@ void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short l
                                                qsort(zrow, totface, sizeof(int)*3, vergzvlak);
                                        }
                                        
-                                       /* join when pixels are adjacent */
-                                       
-                                       while(totface>0) {
-                                               totface--;
-                                               
-                                               shadetrapixel(pa, (float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol);
-                                               
-                                               a= count_mask(zrow[totface][2]);
-                                               if( (R.r.mode & R_OSA ) && a<R.osa) {
-                                                       if(totface>0) {
-                                                               memset(sampcol, 0, 4*sizeof(float)*R.osa);
-                                                               sval= addtosampcol(sampcol, fcol, zrow[totface][2]);
-                                                               
-                                                               /* sval==0: alpha completely full */
-                                                               while( (sval != 0) && (totface>0) ) {
-                                                                       a= count_mask(zrow[totface-1][2]);
-                                                                       if(a==R.osa) break;
-                                                                       totface--;
-                                                                       
-                                                                       shadetrapixel(pa, (float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol);
-                                                                       sval= addtosampcol(sampcol, fcol, zrow[totface][2]);
-                                                               }
-                                                               
-                                                               scol= sampcol;
-                                                               accumcol[0]= scol[0]; accumcol[1]= scol[1];
-                                                               accumcol[2]= scol[2]; accumcol[3]= scol[3];
-                                                               scol+= 4;
-                                                               for(a=1; a<R.osa; a++, scol+=4) {
-                                                                       accumcol[0]+= scol[0]; accumcol[1]+= scol[1];
-                                                                       accumcol[2]+= scol[2]; accumcol[3]+= scol[3];
-                                                               }
-                                                               tempcol[0]= accumcol[0]/R.osa;
-                                                               tempcol[1]= accumcol[1]/R.osa;
-                                                               tempcol[2]= accumcol[2]/R.osa;
-                                                               tempcol[3]= accumcol[3]/R.osa;
-                                                               
-                                                               addAlphaUnderFloat(col, tempcol);
-                                                               
-                                                       }
-                                                       else {
-                                                               fac= alpha[a];
-                                                               fcol[0]= (fcol[0]*fac);
-                                                               fcol[1]= (fcol[1]*fac);
-                                                               fcol[2]= (fcol[2]*fac);
-                                                               fcol[3]= (fcol[3]*fac);
-                                                               addAlphaUnderFloat(col, fcol);
-                                                       }
-                                               }       
-                                               else addAlphaUnderFloat(col, fcol);     /* no osa or full pixel with same face? */
+                                       if(R.osa==0) {
+                                               while(totface>0) {
+                                                       totface--;
+                                                       
+                                                       shadetrapixel(pa, (float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol);
+                                                       addAlphaUnderFloat(pass, fcol);
+                                                       
+                                                       if(pass[3]>=0.999) break;
+                                               }
+                                       }
+                                       else {
+                                               /* for each mask-sample we alpha-under colors. then in end it's added using filter */
+                                               memset(sampcol, 0, 4*sizeof(float)*R.osa);
+
+                                               while(totface>0) {
+                                                       totface--;
+                                                       
+                                                       shadetrapixel(pa, (float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol);
+                                                       sval= addtosampcol(sampcol, fcol, zrow[totface][2]);
+                                                       
+                                                       if(sval==0) break;
+                                               }
                                                
-                                               if(col[3]>=0.999) break;
+                                               for(a=0; a<R.osa; a++) 
+                                                       add_filt_fmask(1<<a, sampcol+4*a, pass, rr->rectx);
                                        }
                                }
-                               if(col[3]!=0.0) addAlphaOverFloat(pass, col);
+                               //if(R.osa && R.do_gamma) {
+                               //      pass[0]= invGammaCorrect(pass[0]);
+                               //      pass[1]= invGammaCorrect(pass[1]);
+                               //      pass[2]= invGammaCorrect(pass[2]);
+                               //}
                        }
                }
+               
+               aprect+= pa->rectx;
+               passrect+= 4*pa->rectx;
        }
 
        RE_freeN(APixbuf);
index 843548590672e4fb2527db399006aa8eb7410f8e..c192d801b6547ecf533a8007e0e168a09b843ca3 100644 (file)
@@ -1178,7 +1178,7 @@ static void node_add_menu(SpaceNode *snode)
        }
        else if(snode->treetype==NTREE_COMPOSIT) {
                /* compo menu, still hardcoded defines... solve */
-               event= pupmenu("Add Node%t|Render Result %x221|Composite %x222|Viewer%x201|Image %x220|RGB Curves%x209|AlphaOver %x210|Blur %x211|Filter %x212|Value %x203|Color %x202|Mix %x204|ColorRamp %x205|Color to BW %x206|Map Value %x213|Normal %x207");
+               event= pupmenu("Add Node%t|Render Result %x221|Composite %x222|Viewer%x201|Image %x220|RGB Curves%x209|AlphaOver %x210|Blur %x211|Vector Blur %x215|Filter %x212|Value %x203|Color %x202|Mix %x204|ColorRamp %x205|Color to BW %x206|Map Value %x213|Normal %x207");
                if(event<1) return;
        }
        else return;
index 579dc8b892adc14d9a21be5f2761fdac0621d954..8b2c0093b3e3c37e834994eae217b210a884456c 100644 (file)
@@ -721,10 +721,23 @@ static void renderwin_clear_display_cb(RenderResult *rr)
 */
 
 /* can get as well the full picture, as the parts while rendering */
-static void renderwin_progress(RenderWin *rw, RenderResult *rr, rcti *unused)
+static void renderwin_progress(RenderWin *rw, RenderResult *rr, rcti *renrect)
 {
        rcti win_rct;
        float *rectf, fullrect[2][2];
+       int ymin, ymax;
+       
+       /* if renrect argument, we only display scanlines */
+       if(renrect) {
+               ymin= renrect->ymin;
+               ymax= renrect->ymax-ymin;
+               if(ymax<2) return;
+               renrect->ymin= renrect->ymax;
+       }
+       else {
+               ymin= 0;
+               ymax= rr->recty-2*rr->crop;
+       }
        
        /* renderwindow cruft */
        win_rct.xmin= win_rct.ymin= 0;
@@ -736,9 +749,13 @@ static void renderwin_progress(RenderWin *rw, RenderResult *rr, rcti *unused)
        if(rr->rectf)
                rectf= rr->rectf;
        else {
-               RenderLayer *rl= BLI_findlink(&rr->layers, rr->actlay);
+               RenderLayer *rl= rr->renlay;
+               if(rl==NULL) return;
                rectf= rl->rectf;
-       }       
+       }
+       /* if scanline updates... */
+       rectf+= 4*rr->rectx*ymin;
+       
        /* when rendering more pixels than needed, we crop away cruft */
        if(rr->crop)
                rectf+= 4*(rr->crop*rr->rectx + rr->crop);
@@ -746,14 +763,14 @@ static void renderwin_progress(RenderWin *rw, RenderResult *rr, rcti *unused)
        /* tilerect defines drawing offset from (0,0) */
        /* however, tilerect (xmin, ymin) is first pixel */
        fullrect[0][0] += (rr->tilerect.xmin+rr->crop)*rw->zoom;
-       fullrect[0][1] += (rr->tilerect.ymin+rr->crop)*rw->zoom;
+       fullrect[0][1] += (rr->tilerect.ymin+rr->crop + ymin)*rw->zoom;
 
        glEnable(GL_SCISSOR_TEST);
        glaDefine2DArea(&win_rct);
 
        glDrawBuffer(GL_FRONT);
        glPixelZoom(rw->zoom, rw->zoom);
-       glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rr->rectx-2*rr->crop, rr->recty-2*rr->crop, rr->rectx, 
+       glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rr->rectx-2*rr->crop, ymax, rr->rectx, 
                                          GL_RGBA, GL_FLOAT, rectf);
        glPixelZoom(1.0, 1.0);
        glFlush();