diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 2da116ca18f..7fd87a0dde5 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -341,6 +341,7 @@ typedef struct Scene { #define R_NOPUNOFLIP 8 #define R_CMAPCODE 16 #define R_FACE_SPLIT 32 +#define R_DIVIDE_24 64 /* Tells render to divide face other way. */ /* vertren->texofs (texcoordinate offset relative to vertren->orco */ #define R_UVOFS3 1 diff --git a/source/blender/renderconverter/RE_renderconverter.h b/source/blender/renderconverter/RE_renderconverter.h index 851333371f6..450a4f7c764 100644 --- a/source/blender/renderconverter/RE_renderconverter.h +++ b/source/blender/renderconverter/RE_renderconverter.h @@ -87,6 +87,7 @@ extern "C" { void (*vertexfunc)(float*), void (*termfunc)(void)); + #ifdef __cplusplus } #endif diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c index 0260e4697d9..369dcc0e052 100644 --- a/source/blender/renderconverter/intern/convertBlenderScene.c +++ b/source/blender/renderconverter/intern/convertBlenderScene.c @@ -2851,6 +2851,7 @@ void RE_freeRotateBlenderScene(void) R.totvlak=R.totvert=R.totlamp=R.tothalo= 0; } + static void check_non_flat_quads(void) { VlakRen *vlr, *vlr1; @@ -2860,32 +2861,58 @@ static void check_non_flat_quads(void) for(a=R.totvlak-1; a>=0; a--) { vlr= RE_findOrAddVlak(a); + /* Face is divided along edge with the least displace gradient */ + /* Flagged with R_DIVIDE_24 if divide is from vert 2 to 4 */ + /* 4---3 4---3 */ + /* |\ 1| or |1 /| */ + /* |0\ | |/ 0| */ + /* 1---2 1---2 0 = orig face, 1 = new face */ + /* test if rendering as a quad or triangle */ if(vlr->v4) { if(vlr->mat->mode & MA_WIRE); else { + /* blahj, render normals are inverted in render */ - CalcNormFloat(vlr->v4->co, vlr->v3->co, vlr->v1->co, nor); - + CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, nor); + xn= nor[0]*vlr->n[0] + nor[1]*vlr->n[1] + nor[2]*vlr->n[2]; - if( fabs(xn) < 0.9990 ) { + if( fabs(xn) < 0.99990 ) { if( xn<0.0 ) flipnorm= 1; else flipnorm= 0; /* recalc this nor, previous calc was with calcnormfloat4 */ - if(flipnorm) CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n); - else CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); + if(flipnorm) { + if (vlr->flag & R_DIVIDE_24) CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v4->co, vlr->n); + else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n); + } + else { + if (vlr->flag & R_DIVIDE_24) CalcNormFloat(vlr->v4->co, vlr->v2->co, vlr->v1->co, vlr->n); + else CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); + } vlr1= RE_findOrAddVlak(R.totvlak++); *vlr1= *vlr; vlr1->flag |= R_FACE_SPLIT; + if(flipnorm) VecMulf(nor, -1.0); VECCOPY(vlr1->n, nor); - vlr1->v2= vlr->v3; - vlr1->v3= vlr->v4; + + if (vlr->flag&R_DIVIDE_24) { + vlr1->v1=vlr->v2; + vlr1->v2=vlr->v3; + vlr1->v3=vlr->v4; + vlr->v3 =vlr->v4; + } + else { + vlr1->v1= vlr->v1; + vlr1->v2= vlr->v3; + vlr1->v3= vlr->v4; + } + vlr->v4= vlr1->v4= 0; - + vlr1->puno= 0; if(vlr->puno & ME_FLIPV1) vlr1->puno |= ME_FLIPV1; if(vlr->puno & ME_FLIPV3) vlr1->puno |= ME_FLIPV2; @@ -3181,6 +3208,7 @@ void displace_render_face(VlakRen *vlr, float scale) { ShadeInput shi; VertRen vr; + float samp1,samp2, samp3, samp4 ; /* set up shadeinput struct for multitex() */ @@ -3193,19 +3221,24 @@ void displace_render_face(VlakRen *vlr, float scale) if (! (vlr->v1->flag)) displace_render_vert(&shi, vlr->v1, scale); - if (! (vlr->v2->flag) ) displace_render_vert(&shi, vlr->v2, scale); + if (! (vlr->v2->flag)) displace_render_vert(&shi, vlr->v2, scale); if (! (vlr->v3->flag)) displace_render_vert(&shi, vlr->v3, scale); if (vlr->v4) { if (! (vlr->v4->flag)) displace_render_vert(&shi, vlr->v4, scale); + + /* We want to split the quad along the opposite verts that are */ + /* closest in displace value. This will help smooth edges. */ + if ( fabs(vlr->v1->accum-vlr->v3->accum) > fabs(vlr->v2->accum-vlr->v4->accum)) vlr->flag|=R_DIVIDE_24; + else vlr->flag & ~R_DIVIDE_24; } } void displace_render_vert(ShadeInput *shi, VertRen *vr, float scale) { short texco= shi->matren->texco; - + float sample=0; /* shi->co is current render coord, just make sure at least some vector is here */ VECCOPY(shi->co, vr->co); /* vertex normal is used for textures type 'col' and 'var' */ @@ -3234,12 +3267,20 @@ void displace_render_vert(ShadeInput *shi, VertRen *vr, float scale) do_material_tex(shi); /* 0.25 could become button once? */ - vr->co[0] += 0.25*shi->displace[0] * scale ; - vr->co[1] += 0.25*shi->displace[1] * scale ; - vr->co[2] += 0.25*shi->displace[2] * scale ; + vr->co[0] += 0.25 * shi->displace[0] * scale ; + vr->co[1] += 0.25 * shi->displace[1] * scale ; + vr->co[2] += 0.25 * shi->displace[2] * scale ; /* we just don't do this vertex again, bad luck for other face using same vertex with different material... */ vr->flag |= 1; - + + /* Pass sample back so displace_face can decide which way to split the quad */ + sample = shi->displace[0]*shi->displace[0]; + sample += shi->displace[1]*shi->displace[1]; + sample += shi->displace[2]*shi->displace[2]; + + vr->accum=sample; /* Should be sqrt(sample), but I'm olny looking for "bigger". Save the cycles. */ + /* Does abusing this cause heartache for radiosity? */ + return; }