diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2018-04-13 13:19:31 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2018-04-13 13:19:31 +0300 |
commit | 07fc6c922493bf0f6252da663e9854b8c9d95b8b (patch) | |
tree | 9823b72f6933d323028ba8157e90c7b6db009687 | |
parent | 199715eabccce8d91cd4f9705762305e8f236b8c (diff) | |
parent | 332846b188d6c7463758fb8d8659785beccde63a (diff) |
Merge branch 'master' into blender2.8
9 files changed, 731 insertions, 595 deletions
diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index bd72dfa9370..2d45d11b423 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -28,8 +28,10 @@ class FILEBROWSER_HT_header(Header): layout = self.layout st = context.space_data + params = st.params - layout.template_header() + if st.active_operator is None: + layout.template_header() row = layout.row() row.separator() @@ -46,7 +48,6 @@ class FILEBROWSER_HT_header(Header): layout.separator() layout.operator_context = 'INVOKE_DEFAULT' - params = st.params # can be None when save/reload with a file selector open if params: diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.h b/source/blender/compositor/operations/COM_RenderLayersProg.h index 1be15906770..7cfead7e98c 100644 --- a/source/blender/compositor/operations/COM_RenderLayersProg.h +++ b/source/blender/compositor/operations/COM_RenderLayersProg.h @@ -30,8 +30,6 @@ #include "BKE_image.h" extern "C" { # include "RE_pipeline.h" -# include "RE_shader_ext.h" -# include "RE_render_ext.h" # include "MEM_guardedalloc.h" } @@ -46,7 +44,7 @@ protected: * Reference to the scene object. */ Scene *m_scene; - + /** * layerId of the layer where this operation needs to get its data from */ @@ -61,24 +59,24 @@ protected: * cached instance to the float buffer inside the layer */ float *m_inputBuffer; - + /** * renderpass where this operation needs to get its data from */ std::string m_passName; - + int m_elementsize; /** * @brief render data used for active rendering */ const RenderData *m_rd; - + /** * Determine the output resolution. The resolution is retrieved from the Renderer */ void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); - + /** * retrieve the reference to the float buffer of the renderer. */ diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp index 36f06e92436..bccfe025089 100644 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp @@ -20,16 +20,30 @@ * Monique Dewanchand */ -#include "COM_VectorBlurOperation.h" -#include "BLI_math.h" - +#include <string.h> #include "MEM_guardedalloc.h" - -// use the implementation of blender internal renderer to calculate the vector blur. +#include "BLI_math.h" extern "C" { -# include "RE_pipeline.h" + #include "BLI_jitter_2d.h" } +#include "COM_VectorBlurOperation.h" + +/* Defined */ +#define PASS_VECTOR_MAX 10000.0f + +/* Forward declarations */ +struct ZSpan; +struct DrawBufPixel; +void zbuf_accumulate_vecblur( + NodeBlurData *nbd, int xsize, int ysize, float *newrect, + const float *imgrect, float *vecbufrect, const float *zbufrect); +void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop); +void zbuf_free_span(ZSpan *zspan); +void antialias_tagbuf(int xsize, int ysize, char *rectmove); + + +/* VectorBlurOperation */ VectorBlurOperation::VectorBlurOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); @@ -51,7 +65,7 @@ void VectorBlurOperation::initExecution() this->m_inputSpeedProgram = getInputSocketReader(2); this->m_cachedInstance = NULL; QualityStepHelper::initExecution(COM_QH_INCREASE); - + } void VectorBlurOperation::executePixel(float output[4], int x, int y, void *data) @@ -77,7 +91,7 @@ void *VectorBlurOperation::initializeTileData(rcti *rect) if (this->m_cachedInstance) { return this->m_cachedInstance; } - + lockMutex(); if (this->m_cachedInstance == NULL) { MemoryBuffer *tile = (MemoryBuffer *)this->m_inputImageProgram->initializeTileData(rect); @@ -114,6 +128,690 @@ void VectorBlurOperation::generateVectorBlur(float *data, MemoryBuffer *inputIma blurdata.minspeed = this->m_settings->minspeed; blurdata.curved = this->m_settings->curved; blurdata.fac = this->m_settings->fac; - RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), inputZ->getBuffer()); + zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), inputZ->getBuffer()); return; } + +/* ****************** Spans ******************************* */ +/* span fill in method, is also used to localize data for zbuffering */ +typedef struct ZSpan { + /* range for clipping */ + int rectx, recty; + + /* actual filled in range */ + int miny1, maxy1, miny2, maxy2; + /* vertex pointers detect min/max range in */ + const float *minp1, *maxp1, *minp2, *maxp2; + float *span1, *span2; + + /* transform from hoco to zbuf co */ + float zmulx, zmuly, zofsx, zofsy; + + int *rectz; + DrawBufPixel* rectdraw; + float clipcrop; + +} ZSpan; + +/* each zbuffer has coordinates transformed to local rect coordinates, so we can simply clip */ +void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop) +{ + memset(zspan, 0, sizeof(ZSpan)); + + zspan->rectx= rectx; + zspan->recty= recty; + + zspan->span1= (float*)MEM_mallocN(recty*sizeof(float), "zspan"); + zspan->span2= (float*)MEM_mallocN(recty*sizeof(float), "zspan"); + + zspan->clipcrop= clipcrop; +} + +void zbuf_free_span(ZSpan *zspan) +{ + if (zspan) { + if (zspan->span1) MEM_freeN(zspan->span1); + if (zspan->span2) MEM_freeN(zspan->span2); + zspan->span1= zspan->span2= NULL; + } +} + +/* reset range for clipping */ +static void zbuf_init_span(ZSpan *zspan) +{ + zspan->miny1= zspan->miny2= zspan->recty+1; + zspan->maxy1= zspan->maxy2= -1; + zspan->minp1= zspan->maxp1= zspan->minp2= zspan->maxp2= NULL; +} + +static void zbuf_add_to_span(ZSpan *zspan, const float v1[2], const float v2[2]) +{ + const float *minv, *maxv; + float *span; + float xx1, dx0, xs0; + int y, my0, my2; + + if (v1[1]<v2[1]) { + minv= v1; maxv= v2; + } + else { + minv= v2; maxv= v1; + } + + my0= ceil(minv[1]); + my2= floor(maxv[1]); + + if (my2<0 || my0>= zspan->recty) return; + + /* clip top */ + if (my2>=zspan->recty) my2= zspan->recty-1; + /* clip bottom */ + if (my0<0) my0= 0; + + if (my0>my2) return; + /* if (my0>my2) should still fill in, that way we get spans that skip nicely */ + + xx1= maxv[1]-minv[1]; + if (xx1>FLT_EPSILON) { + dx0= (minv[0]-maxv[0])/xx1; + xs0= dx0*(minv[1]-my2) + minv[0]; + } + else { + dx0 = 0.0f; + xs0 = min_ff(minv[0], maxv[0]); + } + + /* empty span */ + if (zspan->maxp1 == NULL) { + span= zspan->span1; + } + else { /* does it complete left span? */ + if ( maxv == zspan->minp1 || minv==zspan->maxp1) { + span= zspan->span1; + } + else { + span= zspan->span2; + } + } + + if (span==zspan->span1) { +// printf("left span my0 %d my2 %d\n", my0, my2); + if (zspan->minp1==NULL || zspan->minp1[1] > minv[1] ) { + zspan->minp1= minv; + } + if (zspan->maxp1==NULL || zspan->maxp1[1] < maxv[1] ) { + zspan->maxp1= maxv; + } + if (my0<zspan->miny1) zspan->miny1= my0; + if (my2>zspan->maxy1) zspan->maxy1= my2; + } + else { +// printf("right span my0 %d my2 %d\n", my0, my2); + if (zspan->minp2==NULL || zspan->minp2[1] > minv[1] ) { + zspan->minp2= minv; + } + if (zspan->maxp2==NULL || zspan->maxp2[1] < maxv[1] ) { + zspan->maxp2= maxv; + } + if (my0<zspan->miny2) zspan->miny2= my0; + if (my2>zspan->maxy2) zspan->maxy2= my2; + } + + for (y=my2; y>=my0; y--, xs0+= dx0) { + /* xs0 is the xcoord! */ + span[y]= xs0; + } +} + +/* ******************** VECBLUR ACCUM BUF ************************* */ + +typedef struct DrawBufPixel { + const float *colpoin; + float alpha; +} DrawBufPixel; + + +static void zbuf_fill_in_rgba(ZSpan *zspan, DrawBufPixel *col, float *v1, float *v2, float *v3, float *v4) +{ + DrawBufPixel *rectpofs, *rp; + double zxd, zyd, zy0, zverg; + float x0, y0, z0; + float x1, y1, z1, x2, y2, z2, xx1; + const float *span1, *span2; + float *rectzofs, *rz; + int x, y; + int sn1, sn2, rectx, my0, my2; + + /* init */ + zbuf_init_span(zspan); + + /* set spans */ + zbuf_add_to_span(zspan, v1, v2); + zbuf_add_to_span(zspan, v2, v3); + zbuf_add_to_span(zspan, v3, v4); + zbuf_add_to_span(zspan, v4, v1); + + /* clipped */ + if (zspan->minp2==NULL || zspan->maxp2==NULL) return; + + my0 = max_ii(zspan->miny1, zspan->miny2); + my2 = min_ii(zspan->maxy1, zspan->maxy2); + + // printf("my %d %d\n", my0, my2); + if (my2<my0) return; + + /* ZBUF DX DY, in floats still */ + x1= v1[0]- v2[0]; + x2= v2[0]- v3[0]; + y1= v1[1]- v2[1]; + y2= v2[1]- v3[1]; + z1= v1[2]- v2[2]; + z2= v2[2]- v3[2]; + x0= y1*z2-z1*y2; + y0= z1*x2-x1*z2; + z0= x1*y2-y1*x2; + + if (z0==0.0f) return; + + xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; + + zxd= -(double)x0/(double)z0; + zyd= -(double)y0/(double)z0; + zy0= ((double)my2)*zyd + (double)xx1; + + /* start-offset in rect */ + rectx= zspan->rectx; + rectzofs= (float *)(zspan->rectz + rectx*my2); + rectpofs= ((DrawBufPixel *)zspan->rectdraw) + rectx*my2; + + /* correct span */ + sn1= (my0 + my2)/2; + if (zspan->span1[sn1] < zspan->span2[sn1]) { + span1= zspan->span1+my2; + span2= zspan->span2+my2; + } + else { + span1= zspan->span2+my2; + span2= zspan->span1+my2; + } + + for (y=my2; y>=my0; y--, span1--, span2--) { + + sn1= floor(*span1); + sn2= floor(*span2); + sn1++; + + if (sn2>=rectx) sn2= rectx-1; + if (sn1<0) sn1= 0; + + if (sn2>=sn1) { + zverg= (double)sn1*zxd + zy0; + rz= rectzofs+sn1; + rp= rectpofs+sn1; + x= sn2-sn1; + + while (x>=0) { + if (zverg < (double)*rz) { + *rz= zverg; + *rp= *col; + } + zverg+= zxd; + rz++; + rp++; + x--; + } + } + + zy0-=zyd; + rectzofs-= rectx; + rectpofs-= rectx; + } +} + +/* char value==255 is filled in, rest should be zero */ +/* returns alpha values, but sets alpha to 1 for zero alpha pixels that have an alpha value as neighbor */ +void antialias_tagbuf(int xsize, int ysize, char *rectmove) +{ + char *row1, *row2, *row3; + char prev, next; + int a, x, y, step; + + /* 1: tag pixels to be candidate for AA */ + for (y=2; y<ysize; y++) { + /* setup rows */ + row1= rectmove + (y-2)*xsize; + row2= row1 + xsize; + row3= row2 + xsize; + for (x=2; x<xsize; x++, row1++, row2++, row3++) { + if (row2[1]) { + if (row2[0]==0 || row2[2]==0 || row1[1]==0 || row3[1]==0) + row2[1]= 128; + } + } + } + + /* 2: evaluate horizontal scanlines and calculate alphas */ + row1= rectmove; + for (y=0; y<ysize; y++) { + row1++; + for (x=1; x<xsize; x++, row1++) { + if (row1[0]==128 && row1[1]==128) { + /* find previous color and next color and amount of steps to blend */ + prev= row1[-1]; + step= 1; + while (x+step<xsize && row1[step]==128) + step++; + + if (x+step!=xsize) { + /* now we can blend values */ + next= row1[step]; + + /* note, prev value can be next value, but we do this loop to clear 128 then */ + for (a=0; a<step; a++) { + int fac, mfac; + + fac= ((a+1)<<8)/(step+1); + mfac= 255-fac; + + row1[a]= (prev*mfac + next*fac)>>8; + } + } + } + } + } + + /* 3: evaluate vertical scanlines and calculate alphas */ + /* use for reading a copy of the original tagged buffer */ + for (x=0; x<xsize; x++) { + row1= rectmove + x+xsize; + + for (y=1; y<ysize; y++, row1+=xsize) { + if (row1[0]==128 && row1[xsize]==128) { + /* find previous color and next color and amount of steps to blend */ + prev= row1[-xsize]; + step= 1; + while (y+step<ysize && row1[step*xsize]==128) + step++; + + if (y+step!=ysize) { + /* now we can blend values */ + next= row1[step*xsize]; + /* note, prev value can be next value, but we do this loop to clear 128 then */ + for (a=0; a<step; a++) { + int fac, mfac; + + fac= ((a+1)<<8)/(step+1); + mfac= 255-fac; + + row1[a*xsize]= (prev*mfac + next*fac)>>8; + } + } + } + } + } + + /* last: pixels with 0 we fill in zbuffer, with 1 we skip for mask */ + for (y=2; y<ysize; y++) { + /* setup rows */ + row1= rectmove + (y-2)*xsize; + row2= row1 + xsize; + row3= row2 + xsize; + for (x=2; x<xsize; x++, row1++, row2++, row3++) { + if (row2[1]==0) { + if (row2[0]>1 || row2[2]>1 || row1[1]>1 || row3[1]>1) + row2[1]= 1; + } + } + } +} + +/* in: two vectors, first vector points from origin back in time, 2nd vector points to future */ +/* we make this into 3 points, center point is (0, 0) */ +/* and offset the center point just enough to make curve go through midpoint */ + +static void quad_bezier_2d(float *result, float *v1, float *v2, float *ipodata) +{ + float p1[2], p2[2], p3[2]; + + p3[0]= -v2[0]; + p3[1]= -v2[1]; + + p1[0]= v1[0]; + p1[1]= v1[1]; + + /* official formula 2*p2 - 0.5*p1 - 0.5*p3 */ + p2[0]= -0.5f*p1[0] - 0.5f*p3[0]; + p2[1]= -0.5f*p1[1] - 0.5f*p3[1]; + + result[0]= ipodata[0]*p1[0] + ipodata[1]*p2[0] + ipodata[2]*p3[0]; + result[1]= ipodata[0]*p1[1] + ipodata[1]*p2[1] + ipodata[2]*p3[1]; +} + +static void set_quad_bezier_ipo(float fac, float *data) +{ + float mfac= (1.0f-fac); + + data[0]= mfac*mfac; + data[1]= 2.0f*mfac*fac; + data[2]= fac*fac; +} + +void zbuf_accumulate_vecblur( + NodeBlurData *nbd, int xsize, int ysize, float *newrect, + const float *imgrect, float *vecbufrect, const float *zbufrect) +{ + ZSpan zspan; + DrawBufPixel *rectdraw, *dr; + static float jit[256][2]; + float v1[3], v2[3], v3[3], v4[3], fx, fy; + const float *dimg, *dz, *ro; + float *rectvz, *dvz, *dvec1, *dvec2, *dz1, *dz2, *rectz; + float *minvecbufrect= NULL, *rectweight, *rw, *rectmax, *rm; + float maxspeedsq= (float)nbd->maxspeed*nbd->maxspeed; + int y, x, step, maxspeed=nbd->maxspeed, samples= nbd->samples; + int tsktsk= 0; + static int firsttime= 1; + char *rectmove, *dm; + + zbuf_alloc_span(&zspan, xsize, ysize, 1.0f); + zspan.zmulx= ((float)xsize)/2.0f; + zspan.zmuly= ((float)ysize)/2.0f; + zspan.zofsx= 0.0f; + zspan.zofsy= 0.0f; + + /* the buffers */ + rectz= (float*)MEM_mapallocN(sizeof(float)*xsize*ysize, "zbuf accum"); + zspan.rectz= (int *)rectz; + + rectmove= (char*)MEM_mapallocN(xsize*ysize, "rectmove"); + rectdraw= (DrawBufPixel*)MEM_mapallocN(sizeof(DrawBufPixel)*xsize*ysize, "rect draw"); + zspan.rectdraw= rectdraw; + + rectweight= (float*)MEM_mapallocN(sizeof(float)*xsize*ysize, "rect weight"); + rectmax= (float*)MEM_mapallocN(sizeof(float)*xsize*ysize, "rect max"); + + /* debug... check if PASS_VECTOR_MAX still is in buffers */ + dvec1= vecbufrect; + for (x= 4*xsize*ysize; x>0; x--, dvec1++) { + if (dvec1[0]==PASS_VECTOR_MAX) { + dvec1[0]= 0.0f; + tsktsk= 1; + } + } + if (tsktsk) printf("Found uninitialized speed in vector buffer... fixed.\n"); + + /* min speed? then copy speedbuffer to recalculate speed vectors */ + if (nbd->minspeed) { + float minspeed= (float)nbd->minspeed; + float minspeedsq= minspeed*minspeed; + + minvecbufrect= (float*)MEM_mapallocN(4*sizeof(float)*xsize*ysize, "minspeed buf"); + + dvec1= vecbufrect; + dvec2= minvecbufrect; + for (x= 2*xsize*ysize; x>0; x--, dvec1+=2, dvec2+=2) { + if (dvec1[0]==0.0f && dvec1[1]==0.0f) { + dvec2[0]= dvec1[0]; + dvec2[1]= dvec1[1]; + } + else { + float speedsq= dvec1[0]*dvec1[0] + dvec1[1]*dvec1[1]; + if (speedsq <= minspeedsq) { + dvec2[0]= 0.0f; + dvec2[1]= 0.0f; + } + else { + speedsq = 1.0f - minspeed / sqrtf(speedsq); + dvec2[0]= speedsq*dvec1[0]; + dvec2[1]= speedsq*dvec1[1]; + } + } + } + SWAP(float *, minvecbufrect, vecbufrect); + } + + /* make vertex buffer with averaged speed and zvalues */ + rectvz= (float*)MEM_mapallocN(4*sizeof(float)*(xsize+1)*(ysize+1), "vertices"); + dvz= rectvz; + for (y=0; y<=ysize; y++) { + + if (y==0) + dvec1= vecbufrect + 4*y*xsize; + else + dvec1= vecbufrect + 4*(y-1)*xsize; + + if (y==ysize) + dvec2= vecbufrect + 4*(y-1)*xsize; + else + dvec2= vecbufrect + 4*y*xsize; + + for (x=0; x<=xsize; x++) { + + /* two vectors, so a step loop */ + for (step=0; step<2; step++, dvec1+=2, dvec2+=2, dvz+=2) { + /* average on minimal speed */ + int div= 0; + + if (x!=0) { + if (dvec1[-4]!=0.0f || dvec1[-3]!=0.0f) { + dvz[0]= dvec1[-4]; + dvz[1]= dvec1[-3]; + div++; + } + if (dvec2[-4]!=0.0f || dvec2[-3]!=0.0f) { + if (div==0) { + dvz[0]= dvec2[-4]; + dvz[1]= dvec2[-3]; + div++; + } + else if ( (ABS(dvec2[-4]) + ABS(dvec2[-3]))< (ABS(dvz[0]) + ABS(dvz[1])) ) { + dvz[0]= dvec2[-4]; + dvz[1]= dvec2[-3]; + } + } + } + + if (x!=xsize) { + if (dvec1[0]!=0.0f || dvec1[1]!=0.0f) { + if (div==0) { + dvz[0]= dvec1[0]; + dvz[1]= dvec1[1]; + div++; + } + else if ( (ABS(dvec1[0]) + ABS(dvec1[1]))< (ABS(dvz[0]) + ABS(dvz[1])) ) { + dvz[0]= dvec1[0]; + dvz[1]= dvec1[1]; + } + } + if (dvec2[0]!=0.0f || dvec2[1]!=0.0f) { + if (div==0) { + dvz[0]= dvec2[0]; + dvz[1]= dvec2[1]; + } + else if ( (ABS(dvec2[0]) + ABS(dvec2[1]))< (ABS(dvz[0]) + ABS(dvz[1])) ) { + dvz[0]= dvec2[0]; + dvz[1]= dvec2[1]; + } + } + } + if (maxspeed) { + float speedsq= dvz[0]*dvz[0] + dvz[1]*dvz[1]; + if (speedsq > maxspeedsq) { + speedsq = (float)maxspeed / sqrtf(speedsq); + dvz[0]*= speedsq; + dvz[1]*= speedsq; + } + } + } + } + } + + /* set border speeds to keep border speeds on border */ + dz1= rectvz; + dz2= rectvz+4*(ysize)*(xsize+1); + for (x=0; x<=xsize; x++, dz1+=4, dz2+=4) { + dz1[1]= 0.0f; + dz2[1]= 0.0f; + dz1[3]= 0.0f; + dz2[3]= 0.0f; + } + dz1= rectvz; + dz2= rectvz+4*(xsize); + for (y=0; y<=ysize; y++, dz1+=4*(xsize+1), dz2+=4*(xsize+1)) { + dz1[0]= 0.0f; + dz2[0]= 0.0f; + dz1[2]= 0.0f; + dz2[2]= 0.0f; + } + + /* tag moving pixels, only these faces we draw */ + dm= rectmove; + dvec1= vecbufrect; + for (x=xsize*ysize; x>0; x--, dm++, dvec1+=4) { + if ((dvec1[0]!=0.0f || dvec1[1]!=0.0f || dvec1[2]!=0.0f || dvec1[3]!=0.0f)) + *dm= 255; + } + + antialias_tagbuf(xsize, ysize, rectmove); + + /* has to become static, the init-jit calls a random-seed, screwing up texture noise node */ + if (firsttime) { + firsttime= 0; + BLI_jitter_init(jit, 256); + } + + memset(newrect, 0, sizeof(float)*xsize*ysize*4); + + /* accumulate */ + samples/= 2; + for (step= 1; step<=samples; step++) { + float speedfac= 0.5f*nbd->fac*(float)step/(float)(samples+1); + int side; + + for (side=0; side<2; side++) { + float blendfac, ipodata[4]; + + /* clear zbuf, if we draw future we fill in not moving pixels */ + if (0) + for (x= xsize*ysize-1; x>=0; x--) rectz[x]= 10e16; + else + for (x= xsize*ysize-1; x>=0; x--) { + if (rectmove[x]==0) + rectz[x]= zbufrect[x]; + else + rectz[x]= 10e16; + } + + /* clear drawing buffer */ + for (x= xsize*ysize-1; x>=0; x--) rectdraw[x].colpoin= NULL; + + dimg= imgrect; + dm= rectmove; + dz= zbufrect; + dz1= rectvz; + dz2= rectvz + 4*(xsize + 1); + + if (side) { + if (nbd->curved==0) { + dz1+= 2; + dz2+= 2; + } + speedfac= -speedfac; + } + + set_quad_bezier_ipo(0.5f + 0.5f*speedfac, ipodata); + + for (fy= -0.5f+jit[step & 255][0], y=0; y<ysize; y++, fy+=1.0f) { + for (fx= -0.5f+jit[step & 255][1], x=0; x<xsize; x++, fx+=1.0f, dimg+=4, dz1+=4, dz2+=4, dm++, dz++) { + if (*dm>1) { + float jfx = fx + 0.5f; + float jfy = fy + 0.5f; + DrawBufPixel col; + + /* make vertices */ + if (nbd->curved) { /* curved */ + quad_bezier_2d(v1, dz1, dz1+2, ipodata); + v1[0]+= jfx; v1[1]+= jfy; v1[2]= *dz; + + quad_bezier_2d(v2, dz1+4, dz1+4+2, ipodata); + v2[0]+= jfx+1.0f; v2[1]+= jfy; v2[2]= *dz; + + quad_bezier_2d(v3, dz2+4, dz2+4+2, ipodata); + v3[0]+= jfx+1.0f; v3[1]+= jfy+1.0f; v3[2]= *dz; + + quad_bezier_2d(v4, dz2, dz2+2, ipodata); + v4[0]+= jfx; v4[1]+= jfy+1.0f; v4[2]= *dz; + } + else { + v1[0]= speedfac*dz1[0]+jfx; v1[1]= speedfac*dz1[1]+jfy; v1[2]= *dz; + v2[0]= speedfac*dz1[4]+jfx+1.0f; v2[1]= speedfac*dz1[5]+jfy; v2[2]= *dz; + v3[0]= speedfac*dz2[4]+jfx+1.0f; v3[1]= speedfac*dz2[5]+jfy+1.0f; v3[2]= *dz; + v4[0]= speedfac*dz2[0]+jfx; v4[1]= speedfac*dz2[1]+jfy+1.0f; v4[2]= *dz; + } + if (*dm==255) col.alpha= 1.0f; + else if (*dm<2) col.alpha= 0.0f; + else col.alpha= ((float)*dm)/255.0f; + col.colpoin= dimg; + + zbuf_fill_in_rgba(&zspan, &col, v1, v2, v3, v4); + } + } + dz1+=4; + dz2+=4; + } + + /* blend with a falloff. this fixes the ugly effect you get with + * a fast moving object. then it looks like a solid object overlayed + * over a very transparent moving version of itself. in reality, the + * whole object should become transparent if it is moving fast, be + * we don't know what is behind it so we don't do that. this hack + * overestimates the contribution of foreground pixels but looks a + * bit better without a sudden cutoff. */ + blendfac= ((samples - step)/(float)samples); + /* smoothstep to make it look a bit nicer as well */ + blendfac= 3.0f*pow(blendfac, 2.0f) - 2.0f*pow(blendfac, 3.0f); + + /* accum */ + rw= rectweight; + rm= rectmax; + for (dr= rectdraw, dz2=newrect, x= xsize*ysize-1; x>=0; x--, dr++, dz2+=4, rw++, rm++) { + if (dr->colpoin) { + float bfac= dr->alpha*blendfac; + + dz2[0] += bfac*dr->colpoin[0]; + dz2[1] += bfac*dr->colpoin[1]; + dz2[2] += bfac*dr->colpoin[2]; + dz2[3] += bfac*dr->colpoin[3]; + + *rw += bfac; + *rm= MAX2(*rm, bfac); + } + } + } + } + + /* blend between original images and accumulated image */ + rw= rectweight; + rm= rectmax; + ro= imgrect; + dm= rectmove; + for (dz2=newrect, x= xsize*ysize-1; x>=0; x--, dz2+=4, ro+=4, rw++, rm++, dm++) { + float mfac = *rm; + float fac = (*rw == 0.0f)? 0.0f: mfac/(*rw); + float nfac = 1.0f - mfac; + + dz2[0]= fac*dz2[0] + nfac*ro[0]; + dz2[1]= fac*dz2[1] + nfac*ro[1]; + dz2[2]= fac*dz2[2] + nfac*ro[2]; + dz2[3]= fac*dz2[3] + nfac*ro[3]; + } + + MEM_freeN(rectz); + MEM_freeN(rectmove); + MEM_freeN(rectdraw); + MEM_freeN(rectvz); + MEM_freeN(rectweight); + MEM_freeN(rectmax); + if (minvecbufrect) MEM_freeN(vecbufrect); /* rects were swapped! */ + zbuf_free_span(&zspan); +} diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 104fff986cf..a424084f6b1 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -699,12 +699,14 @@ static void graph_refresh(const bContext *C, ScrArea *sa) static void graph_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) { SpaceIpo *sgraph = (SpaceIpo *)slink; - - if (sgraph->ads && (ID *)sgraph->ads->filter_grp == old_id) { - sgraph->ads->filter_grp = (Group *)new_id; - } - if (sgraph->ads && (ID *)sgraph->ads->source == old_id) { - sgraph->ads->source = new_id; + + if (sgraph->ads) { + if ((ID *)sgraph->ads->filter_grp == old_id) { + sgraph->ads->filter_grp = (Group *)new_id; + } + if ((ID *)sgraph->ads->source == old_id) { + sgraph->ads->source = new_id; + } } } diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index 03265c8dcba..08ac7c8973e 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -517,12 +517,14 @@ static void nla_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scen static void nla_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) { SpaceNla *snla = (SpaceNla *)slink; - - if ((ID *)snla->ads->filter_grp == old_id) { - snla->ads->filter_grp = (Group *)new_id; - } - if ((ID *)snla->ads->source == old_id) { - snla->ads->source = new_id; + + if (snla->ads) { + if ((ID *)snla->ads->filter_grp == old_id) { + snla->ads->filter_grp = (Group *)new_id; + } + if ((ID *)snla->ads->source == old_id) { + snla->ads->source = new_id; + } } } diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 08c2fd4fa7a..c5e8443374a 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -344,10 +344,6 @@ void RE_current_scene_update_cb(struct Render *re, void *handle, void (*f)(void /* should move to kernel once... still unsure on how/where */ float RE_filter_value(int type, float x); -/* vector blur zbuffer method */ -void RE_zbuf_accumulate_vecblur( - struct NodeBlurData *nbd, int xsize, int ysize, float *newrect, - const float *imgrect, float *vecbufrect, const float *zbufrect); int RE_seq_render_active(struct Scene *scene, struct RenderData *rd); diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h index 1a1f455712e..0021687efbd 100644 --- a/source/blender/render/extern/include/RE_render_ext.h +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -65,9 +65,6 @@ void RE_sample_material_color( /* imagetexture.c */ void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4]); -/* zbuf.c */ -void antialias_tagbuf(int xsize, int ysize, char *rectmove); - /* pointdensity.c */ struct PointDensity; @@ -89,4 +86,3 @@ void RE_point_density_sample( void RE_point_density_free(struct PointDensity *pd); #endif /* __RE_RENDER_EXT_H__ */ - diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 770a270592c..e948662df00 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -2642,559 +2642,6 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo zbuf_free_span(&zspan); } -/* ******************** VECBLUR ACCUM BUF ************************* */ - -typedef struct DrawBufPixel { - const float *colpoin; - float alpha; -} DrawBufPixel; - - -static void zbuf_fill_in_rgba(ZSpan *zspan, DrawBufPixel *col, float *v1, float *v2, float *v3, float *v4) -{ - DrawBufPixel *rectpofs, *rp; - double zxd, zyd, zy0, zverg; - float x0, y0, z0; - float x1, y1, z1, x2, y2, z2, xx1; - const float *span1, *span2; - float *rectzofs, *rz; - int x, y; - int sn1, sn2, rectx, my0, my2; - - /* init */ - zbuf_init_span(zspan); - - /* set spans */ - zbuf_add_to_span(zspan, v1, v2); - zbuf_add_to_span(zspan, v2, v3); - zbuf_add_to_span(zspan, v3, v4); - zbuf_add_to_span(zspan, v4, v1); - - /* clipped */ - if (zspan->minp2==NULL || zspan->maxp2==NULL) return; - - my0 = max_ii(zspan->miny1, zspan->miny2); - my2 = min_ii(zspan->maxy1, zspan->maxy2); - - // printf("my %d %d\n", my0, my2); - if (my2<my0) return; - - /* ZBUF DX DY, in floats still */ - x1= v1[0]- v2[0]; - x2= v2[0]- v3[0]; - y1= v1[1]- v2[1]; - y2= v2[1]- v3[1]; - z1= v1[2]- v2[2]; - z2= v2[2]- v3[2]; - x0= y1*z2-z1*y2; - y0= z1*x2-x1*z2; - z0= x1*y2-y1*x2; - - if (z0==0.0f) return; - - xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; - - zxd= -(double)x0/(double)z0; - zyd= -(double)y0/(double)z0; - zy0= ((double)my2)*zyd + (double)xx1; - - /* start-offset in rect */ - rectx= zspan->rectx; - rectzofs= (float *)(zspan->rectz + rectx*my2); - rectpofs= ((DrawBufPixel *)zspan->rectp) + rectx*my2; - - /* correct span */ - sn1= (my0 + my2)/2; - if (zspan->span1[sn1] < zspan->span2[sn1]) { - span1= zspan->span1+my2; - span2= zspan->span2+my2; - } - else { - span1= zspan->span2+my2; - span2= zspan->span1+my2; - } - - for (y=my2; y>=my0; y--, span1--, span2--) { - - sn1= floor(*span1); - sn2= floor(*span2); - sn1++; - - if (sn2>=rectx) sn2= rectx-1; - if (sn1<0) sn1= 0; - - if (sn2>=sn1) { - zverg= (double)sn1*zxd + zy0; - rz= rectzofs+sn1; - rp= rectpofs+sn1; - x= sn2-sn1; - - while (x>=0) { - if (zverg < (double)*rz) { - *rz= zverg; - *rp= *col; - } - zverg+= zxd; - rz++; - rp++; - x--; - } - } - - zy0-=zyd; - rectzofs-= rectx; - rectpofs-= rectx; - } -} - -/* char value==255 is filled in, rest should be zero */ -/* returns alpha values, but sets alpha to 1 for zero alpha pixels that have an alpha value as neighbor */ -void antialias_tagbuf(int xsize, int ysize, char *rectmove) -{ - char *row1, *row2, *row3; - char prev, next; - int a, x, y, step; - - /* 1: tag pixels to be candidate for AA */ - for (y=2; y<ysize; y++) { - /* setup rows */ - row1= rectmove + (y-2)*xsize; - row2= row1 + xsize; - row3= row2 + xsize; - for (x=2; x<xsize; x++, row1++, row2++, row3++) { - if (row2[1]) { - if (row2[0]==0 || row2[2]==0 || row1[1]==0 || row3[1]==0) - row2[1]= 128; - } - } - } - - /* 2: evaluate horizontal scanlines and calculate alphas */ - row1= rectmove; - for (y=0; y<ysize; y++) { - row1++; - for (x=1; x<xsize; x++, row1++) { - if (row1[0]==128 && row1[1]==128) { - /* find previous color and next color and amount of steps to blend */ - prev= row1[-1]; - step= 1; - while (x+step<xsize && row1[step]==128) - step++; - - if (x+step!=xsize) { - /* now we can blend values */ - next= row1[step]; - - /* note, prev value can be next value, but we do this loop to clear 128 then */ - for (a=0; a<step; a++) { - int fac, mfac; - - fac= ((a+1)<<8)/(step+1); - mfac= 255-fac; - - row1[a]= (prev*mfac + next*fac)>>8; - } - } - } - } - } - - /* 3: evaluate vertical scanlines and calculate alphas */ - /* use for reading a copy of the original tagged buffer */ - for (x=0; x<xsize; x++) { - row1= rectmove + x+xsize; - - for (y=1; y<ysize; y++, row1+=xsize) { - if (row1[0]==128 && row1[xsize]==128) { - /* find previous color and next color and amount of steps to blend */ - prev= row1[-xsize]; - step= 1; - while (y+step<ysize && row1[step*xsize]==128) - step++; - - if (y+step!=ysize) { - /* now we can blend values */ - next= row1[step*xsize]; - /* note, prev value can be next value, but we do this loop to clear 128 then */ - for (a=0; a<step; a++) { - int fac, mfac; - - fac= ((a+1)<<8)/(step+1); - mfac= 255-fac; - - row1[a*xsize]= (prev*mfac + next*fac)>>8; - } - } - } - } - } - - /* last: pixels with 0 we fill in zbuffer, with 1 we skip for mask */ - for (y=2; y<ysize; y++) { - /* setup rows */ - row1= rectmove + (y-2)*xsize; - row2= row1 + xsize; - row3= row2 + xsize; - for (x=2; x<xsize; x++, row1++, row2++, row3++) { - if (row2[1]==0) { - if (row2[0]>1 || row2[2]>1 || row1[1]>1 || row3[1]>1) - row2[1]= 1; - } - } - } -} - -/* in: two vectors, first vector points from origin back in time, 2nd vector points to future */ -/* we make this into 3 points, center point is (0, 0) */ -/* and offset the center point just enough to make curve go through midpoint */ - -static void quad_bezier_2d(float *result, float *v1, float *v2, float *ipodata) -{ - float p1[2], p2[2], p3[2]; - - p3[0]= -v2[0]; - p3[1]= -v2[1]; - - p1[0]= v1[0]; - p1[1]= v1[1]; - - /* official formula 2*p2 - 0.5*p1 - 0.5*p3 */ - p2[0]= -0.5f*p1[0] - 0.5f*p3[0]; - p2[1]= -0.5f*p1[1] - 0.5f*p3[1]; - - result[0]= ipodata[0]*p1[0] + ipodata[1]*p2[0] + ipodata[2]*p3[0]; - result[1]= ipodata[0]*p1[1] + ipodata[1]*p2[1] + ipodata[2]*p3[1]; -} - -static void set_quad_bezier_ipo(float fac, float *data) -{ - float mfac= (1.0f-fac); - - data[0]= mfac*mfac; - data[1]= 2.0f*mfac*fac; - data[2]= fac*fac; -} - -void RE_zbuf_accumulate_vecblur( - NodeBlurData *nbd, int xsize, int ysize, float *newrect, - const float *imgrect, float *vecbufrect, const float *zbufrect) -{ - ZSpan zspan; - DrawBufPixel *rectdraw, *dr; - static float jit[256][2]; - float v1[3], v2[3], v3[3], v4[3], fx, fy; - const float *dimg, *dz, *ro; - float *rectvz, *dvz, *dvec1, *dvec2, *dz1, *dz2, *rectz; - float *minvecbufrect= NULL, *rectweight, *rw, *rectmax, *rm; - float maxspeedsq= (float)nbd->maxspeed*nbd->maxspeed; - int y, x, step, maxspeed=nbd->maxspeed, samples= nbd->samples; - int tsktsk= 0; - static int firsttime= 1; - char *rectmove, *dm; - - zbuf_alloc_span(&zspan, xsize, ysize, 1.0f); - zspan.zmulx= ((float)xsize)/2.0f; - zspan.zmuly= ((float)ysize)/2.0f; - zspan.zofsx= 0.0f; - zspan.zofsy= 0.0f; - - /* the buffers */ - rectz= MEM_mapallocN(sizeof(float)*xsize*ysize, "zbuf accum"); - zspan.rectz= (int *)rectz; - - rectmove= MEM_mapallocN(xsize*ysize, "rectmove"); - rectdraw= MEM_mapallocN(sizeof(DrawBufPixel)*xsize*ysize, "rect draw"); - zspan.rectp= (int *)rectdraw; - - rectweight= MEM_mapallocN(sizeof(float)*xsize*ysize, "rect weight"); - rectmax= MEM_mapallocN(sizeof(float)*xsize*ysize, "rect max"); - - /* debug... check if PASS_VECTOR_MAX still is in buffers */ - dvec1= vecbufrect; - for (x= 4*xsize*ysize; x>0; x--, dvec1++) { - if (dvec1[0]==PASS_VECTOR_MAX) { - dvec1[0]= 0.0f; - tsktsk= 1; - } - } - if (tsktsk) printf("Found uninitialized speed in vector buffer... fixed.\n"); - - /* min speed? then copy speedbuffer to recalculate speed vectors */ - if (nbd->minspeed) { - float minspeed= (float)nbd->minspeed; - float minspeedsq= minspeed*minspeed; - - minvecbufrect= MEM_mapallocN(4*sizeof(float)*xsize*ysize, "minspeed buf"); - - dvec1= vecbufrect; - dvec2= minvecbufrect; - for (x= 2*xsize*ysize; x>0; x--, dvec1+=2, dvec2+=2) { - if (dvec1[0]==0.0f && dvec1[1]==0.0f) { - dvec2[0]= dvec1[0]; - dvec2[1]= dvec1[1]; - } - else { - float speedsq= dvec1[0]*dvec1[0] + dvec1[1]*dvec1[1]; - if (speedsq <= minspeedsq) { - dvec2[0]= 0.0f; - dvec2[1]= 0.0f; - } - else { - speedsq = 1.0f - minspeed / sqrtf(speedsq); - dvec2[0]= speedsq*dvec1[0]; - dvec2[1]= speedsq*dvec1[1]; - } - } - } - SWAP(float *, minvecbufrect, vecbufrect); - } - - /* make vertex buffer with averaged speed and zvalues */ - rectvz= MEM_mapallocN(4*sizeof(float)*(xsize+1)*(ysize+1), "vertices"); - dvz= rectvz; - for (y=0; y<=ysize; y++) { - - if (y==0) - dvec1= vecbufrect + 4*y*xsize; - else - dvec1= vecbufrect + 4*(y-1)*xsize; - - if (y==ysize) - dvec2= vecbufrect + 4*(y-1)*xsize; - else - dvec2= vecbufrect + 4*y*xsize; - - for (x=0; x<=xsize; x++) { - - /* two vectors, so a step loop */ - for (step=0; step<2; step++, dvec1+=2, dvec2+=2, dvz+=2) { - /* average on minimal speed */ - int div= 0; - - if (x!=0) { - if (dvec1[-4]!=0.0f || dvec1[-3]!=0.0f) { - dvz[0]= dvec1[-4]; - dvz[1]= dvec1[-3]; - div++; - } - if (dvec2[-4]!=0.0f || dvec2[-3]!=0.0f) { - if (div==0) { - dvz[0]= dvec2[-4]; - dvz[1]= dvec2[-3]; - div++; - } - else if ( (ABS(dvec2[-4]) + ABS(dvec2[-3]))< (ABS(dvz[0]) + ABS(dvz[1])) ) { - dvz[0]= dvec2[-4]; - dvz[1]= dvec2[-3]; - } - } - } - - if (x!=xsize) { - if (dvec1[0]!=0.0f || dvec1[1]!=0.0f) { - if (div==0) { - dvz[0]= dvec1[0]; - dvz[1]= dvec1[1]; - div++; - } - else if ( (ABS(dvec1[0]) + ABS(dvec1[1]))< (ABS(dvz[0]) + ABS(dvz[1])) ) { - dvz[0]= dvec1[0]; - dvz[1]= dvec1[1]; - } - } - if (dvec2[0]!=0.0f || dvec2[1]!=0.0f) { - if (div==0) { - dvz[0]= dvec2[0]; - dvz[1]= dvec2[1]; - } - else if ( (ABS(dvec2[0]) + ABS(dvec2[1]))< (ABS(dvz[0]) + ABS(dvz[1])) ) { - dvz[0]= dvec2[0]; - dvz[1]= dvec2[1]; - } - } - } - if (maxspeed) { - float speedsq= dvz[0]*dvz[0] + dvz[1]*dvz[1]; - if (speedsq > maxspeedsq) { - speedsq = (float)maxspeed / sqrtf(speedsq); - dvz[0]*= speedsq; - dvz[1]*= speedsq; - } - } - } - } - } - - /* set border speeds to keep border speeds on border */ - dz1= rectvz; - dz2= rectvz+4*(ysize)*(xsize+1); - for (x=0; x<=xsize; x++, dz1+=4, dz2+=4) { - dz1[1]= 0.0f; - dz2[1]= 0.0f; - dz1[3]= 0.0f; - dz2[3]= 0.0f; - } - dz1= rectvz; - dz2= rectvz+4*(xsize); - for (y=0; y<=ysize; y++, dz1+=4*(xsize+1), dz2+=4*(xsize+1)) { - dz1[0]= 0.0f; - dz2[0]= 0.0f; - dz1[2]= 0.0f; - dz2[2]= 0.0f; - } - - /* tag moving pixels, only these faces we draw */ - dm= rectmove; - dvec1= vecbufrect; - for (x=xsize*ysize; x>0; x--, dm++, dvec1+=4) { - if ((dvec1[0]!=0.0f || dvec1[1]!=0.0f || dvec1[2]!=0.0f || dvec1[3]!=0.0f)) - *dm= 255; - } - - antialias_tagbuf(xsize, ysize, rectmove); - - /* has to become static, the init-jit calls a random-seed, screwing up texture noise node */ - if (firsttime) { - firsttime= 0; - BLI_jitter_init(jit, 256); - } - - memset(newrect, 0, sizeof(float)*xsize*ysize*4); - - /* accumulate */ - samples/= 2; - for (step= 1; step<=samples; step++) { - float speedfac= 0.5f*nbd->fac*(float)step/(float)(samples+1); - int side; - - for (side=0; side<2; side++) { - float blendfac, ipodata[4]; - - /* clear zbuf, if we draw future we fill in not moving pixels */ - if (0) - for (x= xsize*ysize-1; x>=0; x--) rectz[x]= 10e16; - else - for (x= xsize*ysize-1; x>=0; x--) { - if (rectmove[x]==0) - rectz[x]= zbufrect[x]; - else - rectz[x]= 10e16; - } - - /* clear drawing buffer */ - for (x= xsize*ysize-1; x>=0; x--) rectdraw[x].colpoin= NULL; - - dimg= imgrect; - dm= rectmove; - dz= zbufrect; - dz1= rectvz; - dz2= rectvz + 4*(xsize + 1); - - if (side) { - if (nbd->curved==0) { - dz1+= 2; - dz2+= 2; - } - speedfac= -speedfac; - } - - set_quad_bezier_ipo(0.5f + 0.5f*speedfac, ipodata); - - for (fy= -0.5f+jit[step & 255][0], y=0; y<ysize; y++, fy+=1.0f) { - for (fx= -0.5f+jit[step & 255][1], x=0; x<xsize; x++, fx+=1.0f, dimg+=4, dz1+=4, dz2+=4, dm++, dz++) { - if (*dm>1) { - float jfx = fx + 0.5f; - float jfy = fy + 0.5f; - DrawBufPixel col; - - /* make vertices */ - if (nbd->curved) { /* curved */ - quad_bezier_2d(v1, dz1, dz1+2, ipodata); - v1[0]+= jfx; v1[1]+= jfy; v1[2]= *dz; - - quad_bezier_2d(v2, dz1+4, dz1+4+2, ipodata); - v2[0]+= jfx+1.0f; v2[1]+= jfy; v2[2]= *dz; - - quad_bezier_2d(v3, dz2+4, dz2+4+2, ipodata); - v3[0]+= jfx+1.0f; v3[1]+= jfy+1.0f; v3[2]= *dz; - - quad_bezier_2d(v4, dz2, dz2+2, ipodata); - v4[0]+= jfx; v4[1]+= jfy+1.0f; v4[2]= *dz; - } - else { - v1[0]= speedfac*dz1[0]+jfx; v1[1]= speedfac*dz1[1]+jfy; v1[2]= *dz; - v2[0]= speedfac*dz1[4]+jfx+1.0f; v2[1]= speedfac*dz1[5]+jfy; v2[2]= *dz; - v3[0]= speedfac*dz2[4]+jfx+1.0f; v3[1]= speedfac*dz2[5]+jfy+1.0f; v3[2]= *dz; - v4[0]= speedfac*dz2[0]+jfx; v4[1]= speedfac*dz2[1]+jfy+1.0f; v4[2]= *dz; - } - if (*dm==255) col.alpha= 1.0f; - else if (*dm<2) col.alpha= 0.0f; - else col.alpha= ((float)*dm)/255.0f; - col.colpoin= dimg; - - zbuf_fill_in_rgba(&zspan, &col, v1, v2, v3, v4); - } - } - dz1+=4; - dz2+=4; - } - - /* blend with a falloff. this fixes the ugly effect you get with - * a fast moving object. then it looks like a solid object overlayed - * over a very transparent moving version of itself. in reality, the - * whole object should become transparent if it is moving fast, be - * we don't know what is behind it so we don't do that. this hack - * overestimates the contribution of foreground pixels but looks a - * bit better without a sudden cutoff. */ - blendfac= ((samples - step)/(float)samples); - /* smoothstep to make it look a bit nicer as well */ - blendfac= 3.0f*pow(blendfac, 2.0f) - 2.0f*pow(blendfac, 3.0f); - - /* accum */ - rw= rectweight; - rm= rectmax; - for (dr= rectdraw, dz2=newrect, x= xsize*ysize-1; x>=0; x--, dr++, dz2+=4, rw++, rm++) { - if (dr->colpoin) { - float bfac= dr->alpha*blendfac; - - dz2[0] += bfac*dr->colpoin[0]; - dz2[1] += bfac*dr->colpoin[1]; - dz2[2] += bfac*dr->colpoin[2]; - dz2[3] += bfac*dr->colpoin[3]; - - *rw += bfac; - *rm= MAX2(*rm, bfac); - } - } - } - } - - /* blend between original images and accumulated image */ - rw= rectweight; - rm= rectmax; - ro= imgrect; - dm= rectmove; - for (dz2=newrect, x= xsize*ysize-1; x>=0; x--, dz2+=4, ro+=4, rw++, rm++, dm++) { - float mfac = *rm; - float fac = (*rw == 0.0f)? 0.0f: mfac/(*rw); - float nfac = 1.0f - mfac; - - dz2[0]= fac*dz2[0] + nfac*ro[0]; - dz2[1]= fac*dz2[1] + nfac*ro[1]; - dz2[2]= fac*dz2[2] + nfac*ro[2]; - dz2[3]= fac*dz2[3] + nfac*ro[3]; - } - - MEM_freeN(rectz); - MEM_freeN(rectmove); - MEM_freeN(rectdraw); - MEM_freeN(rectvz); - MEM_freeN(rectweight); - MEM_freeN(rectmax); - if (minvecbufrect) MEM_freeN(vecbufrect); /* rects were swapped! */ - zbuf_free_span(&zspan); -} - /* ******************** ABUF ************************* */ /** diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 865a133ed5d..96242c229d1 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -266,10 +266,6 @@ struct RenderPass *RE_pass_find_by_name(volatile struct RenderLayer *rl, const c struct RenderPass *RE_pass_find_by_type(volatile struct RenderLayer *rl, int passtype, const char *viewname) RET_NULL bool RE_HasCombinedLayer(RenderResult *res) RET_ZERO -/* zbuf.c stub */ -void antialias_tagbuf(int xsize, int ysize, char *rectmove) RET_NONE -void RE_zbuf_accumulate_vecblur(struct NodeBlurData *nbd, int xsize, int ysize, float *newrect, const float *imgrect, float *vecbufrect, const float *zbufrect) RET_NONE - /* imagetexture.c stub */ void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result) RET_NONE |