Blender V2.61 - r43446

shadeinput.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2006 Blender Foundation
00019  * All rights reserved.
00020  *
00021  * Contributors: Hos, Robert Wenzlaff.
00022  *
00023  * ***** END GPL LICENSE BLOCK *****
00024  */
00025 
00031 #include <stdio.h>
00032 #include <math.h>
00033 #include <string.h>
00034 
00035 
00036 #include "BLI_math.h"
00037 #include "BLI_blenlib.h"
00038 #include "BLI_utildefines.h"
00039 
00040 #include "DNA_curve_types.h"
00041 #include "DNA_group_types.h"
00042 #include "DNA_lamp_types.h"
00043 #include "DNA_meshdata_types.h"
00044 #include "DNA_material_types.h"
00045 
00046 #include "BKE_colortools.h"
00047 
00048 #include "BKE_node.h"
00049 
00050 /* local include */
00051 #include "raycounter.h"
00052 #include "renderpipeline.h"
00053 #include "render_types.h"
00054 #include "renderdatabase.h"
00055 #include "rendercore.h"
00056 #include "shadbuf.h"
00057 #include "shading.h"
00058 #include "strand.h"
00059 #include "texture.h"
00060 #include "volumetric.h"
00061 #include "zbuf.h"
00062 
00063 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
00064 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
00065 /* only to be used here in this file, it's for speed */
00066 extern struct Render R;
00067 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
00068 
00069 
00070 #define VECADDISFAC(v1,v3,fac) {*(v1)+= *(v3)*(fac); *(v1+1)+= *(v3+1)*(fac); *(v1+2)+= *(v3+2)*(fac);}
00071 
00072 
00073 
00074 /* Shade Sample order:
00075 
00076 - shade_samples_fill_with_ps()
00077     - for each sample
00078         - shade_input_set_triangle()  <- if prev sample-face is same, use shade_input_copy_triangle()
00079         - if vlr
00080             - shade_input_set_viewco()    <- not for ray or bake
00081             - shade_input_set_uv()        <- not for ray or bake
00082             - shade_input_set_normals()
00083 - shade_samples()
00084     - if AO
00085         - shade_samples_do_AO()
00086     - if shading happens
00087         - for each sample
00088             - shade_input_set_shade_texco()
00089             - shade_samples_do_shade()
00090 - OSA: distribute sample result with filter masking
00091 
00092     */
00093 
00094 /* initialise material variables in shadeinput, 
00095  * doing inverse gamma correction where applicable */
00096 void shade_input_init_material(ShadeInput *shi)
00097 {
00098     /* note, keep this synced with render_types.h */
00099     memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
00100     shi->har= shi->mat->har;
00101 }
00102 
00103 /* also used as callback for nodes */
00104 /* delivers a fully filled in ShadeResult, for all passes */
00105 void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
00106 {
00107 
00108     shade_lamp_loop(shi, shr);  /* clears shr */
00109     
00110     if(shi->translucency!=0.0f) {
00111         ShadeResult shr_t;
00112         float fac= shi->translucency;
00113         
00114         shade_input_init_material(shi);
00115         negate_v3_v3(shi->vn, shi->vno);
00116         negate_v3(shi->facenor);
00117         shi->depth++;   /* hack to get real shadow now */
00118         shade_lamp_loop(shi, &shr_t);
00119         shi->depth--;
00120 
00121         /* a couple of passes */
00122         VECADDISFAC(shr->combined, shr_t.combined, fac);
00123         if(shi->passflag & SCE_PASS_SPEC)
00124             VECADDISFAC(shr->spec, shr_t.spec, fac);
00125         if(shi->passflag & SCE_PASS_DIFFUSE)
00126             VECADDISFAC(shr->diff, shr_t.diff, fac);
00127         if(shi->passflag & SCE_PASS_SHADOW)
00128             VECADDISFAC(shr->shad, shr_t.shad, fac);
00129 
00130         negate_v3(shi->vn);
00131         negate_v3(shi->facenor);
00132     }
00133     
00134     /* depth >= 1 when ray-shading */
00135     if(shi->depth==0 || shi->volume_depth > 0) {
00136         if(R.r.mode & R_RAYTRACE) {
00137             if(shi->ray_mirror!=0.0f || ((shi->mode & MA_TRANSP) && (shi->mode & MA_RAYTRANSP) && shr->alpha!=1.0f)) {
00138                 /* ray trace works on combined, but gives pass info */
00139                 ray_trace(shi, shr);
00140             }
00141         }
00142         /* disable adding of sky for raytransp */
00143         if((shi->mode & MA_TRANSP) && (shi->mode & MA_RAYTRANSP))
00144             if((shi->layflag & SCE_LAY_SKY) && (R.r.alphamode==R_ADDSKY))
00145                 shr->alpha= 1.0f;
00146     }
00147     
00148     if(R.r.mode & R_RAYTRACE) {
00149         if (R.render_volumes_inside.first)
00150             shade_volume_inside(shi, shr);
00151     }
00152 }
00153 
00154 
00155 /* do a shade, finish up some passes, apply mist */
00156 void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
00157 {
00158     float alpha;
00159     
00160     /* ------  main shading loop -------- */
00161 #ifdef RE_RAYCOUNTER
00162     memset(&shi->raycounter, 0, sizeof(shi->raycounter));
00163 #endif
00164     
00165     if(shi->mat->nodetree && shi->mat->use_nodes) {
00166         ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
00167     }
00168     else {
00169         /* copy all relevant material vars, note, keep this synced with render_types.h */
00170         shade_input_init_material(shi);
00171         
00172         if (shi->mat->material_type == MA_TYPE_VOLUME) {
00173             if(R.r.mode & R_RAYTRACE) {
00174                 shade_volume_outside(shi, shr);
00175             }
00176         } else { /* MA_TYPE_SURFACE, MA_TYPE_WIRE */
00177             shade_material_loop(shi, shr);
00178         }
00179     }
00180     
00181     /* copy additional passes */
00182     if(shi->passflag & (SCE_PASS_VECTOR|SCE_PASS_NORMAL)) {
00183         copy_v4_v4(shr->winspeed, shi->winspeed);
00184         copy_v3_v3(shr->nor, shi->vn);
00185     }
00186     
00187     /* MIST */
00188     if((shi->passflag & SCE_PASS_MIST) || ((R.wrld.mode & WO_MIST) && (shi->mat->mode & MA_NOMIST)==0))  {
00189         if(R.r.mode & R_ORTHO)
00190             shr->mist= mistfactor(-shi->co[2], shi->co);
00191         else
00192             shr->mist= mistfactor(len_v3(shi->co), shi->co);
00193     }
00194     else shr->mist= 0.0f;
00195     
00196     if((R.wrld.mode & WO_MIST) && (shi->mat->mode & MA_NOMIST)==0 ) {
00197         alpha= shr->mist;
00198     }
00199     else alpha= 1.0f;
00200     
00201     /* add mist and premul color */
00202     if(shr->alpha!=1.0f || alpha!=1.0f) {
00203         float fac= alpha*(shr->alpha);
00204         shr->combined[3]= fac;
00205         
00206         if (shi->mat->material_type!= MA_TYPE_VOLUME)
00207             mul_v3_fl(shr->combined, fac);
00208     }
00209     else
00210         shr->combined[3]= 1.0f;
00211     
00212     /* add z */
00213     shr->z= -shi->co[2];
00214     
00215     /* RAYHITS */
00216 /*
00217     if(1 || shi->passflag & SCE_PASS_RAYHITS)
00218     {
00219         shr->rayhits[0] = (float)shi->raycounter.faces.test;
00220         shr->rayhits[1] = (float)shi->raycounter.bb.hit;
00221         shr->rayhits[2] = 0.0;
00222         shr->rayhits[3] = 1.0;
00223     }
00224  */
00225     RE_RC_MERGE(&re_rc_counter[shi->thread], &shi->raycounter);
00226 }
00227 
00228 /* **************************************************************************** */
00229 /*                    ShadeInput                                                */
00230 /* **************************************************************************** */
00231 
00232 
00233 void vlr_set_uv_indices(VlakRen *vlr, int *i1, int *i2, int *i3)
00234 {
00235     /* to prevent storing new tfaces or vcols, we check a split runtime */
00236     /*      4---3       4---3 */
00237     /*      |\ 1|   or  |1 /| */
00238     /*      |0\ |       |/ 0| */
00239     /*      1---2       1---2   0 = orig face, 1 = new face */
00240     
00241     /* Update vert nums to point to correct verts of original face */
00242     if(vlr->flag & R_DIVIDE_24) {  
00243         if(vlr->flag & R_FACE_SPLIT) {
00244             (*i1)++; (*i2)++; (*i3)++;
00245         }
00246         else {
00247             (*i3)++;
00248         }
00249     }
00250     else if(vlr->flag & R_FACE_SPLIT) {
00251         (*i2)++; (*i3)++; 
00252     }
00253 }
00254 
00255 /* copy data from face to ShadeInput, general case */
00256 /* indices 0 1 2 3 only */
00257 void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen *vlr, short i1, short i2, short i3)
00258 {
00259     VertRen **vpp= &vlr->v1;
00260     
00261     shi->vlr= vlr;
00262     shi->obi= obi;
00263     shi->obr= obi->obr;
00264 
00265     shi->v1= vpp[i1];
00266     shi->v2= vpp[i2];
00267     shi->v3= vpp[i3];
00268     
00269     shi->i1= i1;
00270     shi->i2= i2;
00271     shi->i3= i3;
00272     
00273     /* note, shi->mat is set in node shaders */
00274     shi->mat= shi->mat_override?shi->mat_override:vlr->mat;
00275     
00276     shi->osatex= (shi->mat->texco & TEXCO_OSA);
00277     shi->mode= shi->mat->mode_l;        /* or-ed result for all nodes */
00278 
00279     /* facenormal copy, can get flipped */
00280     shi->flippednor= 0;
00281     RE_vlakren_get_normal(&R, obi, vlr, shi->facenor);
00282     
00283     /* calculate vertexnormals */
00284     if(vlr->flag & R_SMOOTH) {
00285         copy_v3_v3(shi->n1, shi->v1->n);
00286         copy_v3_v3(shi->n2, shi->v2->n);
00287         copy_v3_v3(shi->n3, shi->v3->n);
00288 
00289         if(obi->flag & R_TRANSFORMED) {
00290             mul_m3_v3(obi->nmat, shi->n1); normalize_v3(shi->n1);
00291             mul_m3_v3(obi->nmat, shi->n2); normalize_v3(shi->n2);
00292             mul_m3_v3(obi->nmat, shi->n3); normalize_v3(shi->n3);
00293         }
00294     }
00295 }
00296 
00297 /* note, facenr declared volatile due to over-eager -O2 optimizations
00298  * on cygwin (particularly -frerun-cse-after-loop)
00299  */
00300 
00301 /* copy data from face to ShadeInput, scanline case */
00302 void shade_input_set_triangle(ShadeInput *shi, volatile int obi, volatile int facenr, int UNUSED(normal_flip))
00303 {
00304     if(facenr>0) {
00305         shi->obi= &R.objectinstance[obi];
00306         shi->obr= shi->obi->obr;
00307         shi->facenr= (facenr-1) & RE_QUAD_MASK;
00308         if( shi->facenr < shi->obr->totvlak ) {
00309             VlakRen *vlr= RE_findOrAddVlak(shi->obr, shi->facenr);
00310             
00311             if(facenr & RE_QUAD_OFFS)
00312                 shade_input_set_triangle_i(shi, shi->obi, vlr, 0, 2, 3);
00313             else
00314                 shade_input_set_triangle_i(shi, shi->obi, vlr, 0, 1, 2);
00315         }
00316         else
00317             shi->vlr= NULL; /* general signal we got sky */
00318     }
00319     else
00320         shi->vlr= NULL; /* general signal we got sky */
00321 }
00322 
00323 /* full osa case: copy static info */
00324 void shade_input_copy_triangle(ShadeInput *shi, ShadeInput *from)
00325 {
00326     /* not so nice, but works... warning is in RE_shader_ext.h */
00327     memcpy(shi, from, sizeof(struct ShadeInputCopy));
00328 }
00329 
00330 /* copy data from strand to shadeinput */
00331 void shade_input_set_strand(ShadeInput *shi, StrandRen *strand, StrandPoint *spoint)
00332 {
00333     /* note, shi->mat is set in node shaders */
00334     shi->mat= shi->mat_override? shi->mat_override: strand->buffer->ma;
00335     
00336     shi->osatex= (shi->mat->texco & TEXCO_OSA);
00337     shi->mode= shi->mat->mode_l;        /* or-ed result for all nodes */
00338 
00339     /* shade_input_set_viewco equivalent */
00340     copy_v3_v3(shi->co, spoint->co);
00341     copy_v3_v3(shi->view, shi->co);
00342     normalize_v3(shi->view);
00343 
00344     shi->xs= (int)spoint->x;
00345     shi->ys= (int)spoint->y;
00346 
00347     if(shi->osatex || (R.r.mode & R_SHADOW)) {
00348         copy_v3_v3(shi->dxco, spoint->dtco);
00349         copy_v3_v3(shi->dyco, spoint->dsco);
00350     }
00351 
00352     /* dxview, dyview, not supported */
00353 
00354     /* facenormal, simply viewco flipped */
00355     copy_v3_v3(shi->facenor, spoint->nor);
00356 
00357     /* shade_input_set_normals equivalent */
00358     if(shi->mat->mode & MA_TANGENT_STR) {
00359         copy_v3_v3(shi->vn, spoint->tan);
00360     }
00361     else {
00362         float cross[3];
00363 
00364         cross_v3_v3v3(cross, spoint->co, spoint->tan);
00365         cross_v3_v3v3(shi->vn, cross, spoint->tan);
00366         normalize_v3(shi->vn);
00367 
00368         if(dot_v3v3(shi->vn, shi->view) < 0.0f)
00369             negate_v3(shi->vn);
00370     }
00371 
00372     copy_v3_v3(shi->vno, shi->vn);
00373 }
00374 
00375 void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert *svert, StrandPoint *spoint)
00376 {
00377     StrandBuffer *strandbuf= strand->buffer;
00378     ObjectRen *obr= strandbuf->obr;
00379     StrandVert *sv;
00380     int mode= shi->mode;        /* or-ed result for all nodes */
00381     short texco= shi->mat->texco;
00382 
00383     if((shi->mat->texco & TEXCO_REFL)) {
00384         /* shi->dxview, shi->dyview, not supported */
00385     }
00386 
00387     if(shi->osatex && (texco & (TEXCO_NORM|TEXCO_REFL))) {
00388         /* not supported */
00389     }
00390 
00391     if(mode & (MA_TANGENT_V|MA_NORMAP_TANG)) {
00392         copy_v3_v3(shi->tang, spoint->tan);
00393         copy_v3_v3(shi->nmaptang, spoint->tan);
00394     }
00395 
00396     if(mode & MA_STR_SURFDIFF) {
00397         float *surfnor= RE_strandren_get_surfnor(obr, strand, 0);
00398 
00399         if(surfnor)
00400             copy_v3_v3(shi->surfnor, surfnor);
00401         else
00402             copy_v3_v3(shi->surfnor, shi->vn);
00403 
00404         if(shi->mat->strand_surfnor > 0.0f) {
00405             shi->surfdist= 0.0f;
00406             for(sv=strand->vert; sv!=svert; sv++)
00407                 shi->surfdist+=len_v3v3(sv->co, (sv+1)->co);
00408             shi->surfdist += spoint->t*len_v3v3(sv->co, (sv+1)->co);
00409         }
00410     }
00411 
00412     if(R.r.mode & R_SPEED) {
00413         float *speed;
00414         
00415         speed= RE_strandren_get_winspeed(shi->obi, strand, 0);
00416         if(speed)
00417             copy_v4_v4(shi->winspeed, speed);
00418         else
00419             shi->winspeed[0]= shi->winspeed[1]= shi->winspeed[2]= shi->winspeed[3]= 0.0f;
00420     }
00421 
00422     /* shade_input_set_shade_texco equivalent */
00423     if(texco & NEED_UV) {
00424         if(texco & TEXCO_ORCO) {
00425             copy_v3_v3(shi->lo, strand->orco);
00426             /* no shi->osatex, orco derivatives are zero */
00427         }
00428 
00429         if(texco & TEXCO_GLOB) {
00430             copy_v3_v3(shi->gl, shi->co);
00431             mul_m4_v3(R.viewinv, shi->gl);
00432             
00433             if(shi->osatex) {
00434                 copy_v3_v3(shi->dxgl, shi->dxco);
00435                 mul_mat3_m4_v3(R.viewinv, shi->dxgl); 
00436                 copy_v3_v3(shi->dygl, shi->dyco);
00437                 mul_mat3_m4_v3(R.viewinv, shi->dygl);
00438             }
00439         }
00440 
00441         if(texco & TEXCO_STRAND) {
00442             shi->strandco= spoint->strandco;
00443 
00444             if(shi->osatex) {
00445                 shi->dxstrand= spoint->dtstrandco;
00446                 shi->dystrand= 0.0f;
00447             }
00448         }
00449 
00450         if((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)))  {
00451             MCol *mcol;
00452             float *uv;
00453             char *name;
00454             int i;
00455 
00456             shi->totuv= 0;
00457             shi->totcol= 0;
00458             shi->actuv= obr->actmtface;
00459             shi->actcol= obr->actmcol;
00460 
00461             if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP)) {
00462                 for (i=0; (mcol=RE_strandren_get_mcol(obr, strand, i, &name, 0)); i++) {
00463                     ShadeInputCol *scol= &shi->col[i];
00464                     char *cp= (char*)mcol;
00465                     
00466                     shi->totcol++;
00467                     scol->name= name;
00468 
00469                     scol->col[0]= cp[3]/255.0f;
00470                     scol->col[1]= cp[2]/255.0f;
00471                     scol->col[2]= cp[1]/255.0f;
00472                     scol->col[3]= cp[0]/255.0f;
00473                 }
00474 
00475                 if(shi->totcol) {
00476                     shi->vcol[0]= shi->col[shi->actcol].col[0];
00477                     shi->vcol[1]= shi->col[shi->actcol].col[1];
00478                     shi->vcol[2]= shi->col[shi->actcol].col[2];
00479                     shi->vcol[3]= shi->col[shi->actcol].col[3];
00480                 }
00481                 else {
00482                     shi->vcol[0]= 0.0f;
00483                     shi->vcol[1]= 0.0f;
00484                     shi->vcol[2]= 0.0f;
00485                     shi->vcol[3]= 0.0f;
00486                 }
00487             }
00488 
00489             for (i=0; (uv=RE_strandren_get_uv(obr, strand, i, &name, 0)); i++) {
00490                 ShadeInputUV *suv= &shi->uv[i];
00491 
00492                 shi->totuv++;
00493                 suv->name= name;
00494 
00495                 if(strandbuf->overrideuv == i) {
00496                     suv->uv[0]= -1.0f;
00497                     suv->uv[1]= spoint->strandco;
00498                     suv->uv[2]= 0.0f;
00499                 }
00500                 else {
00501                     suv->uv[0]= -1.0f + 2.0f*uv[0];
00502                     suv->uv[1]= -1.0f + 2.0f*uv[1];
00503                     suv->uv[2]= 0.0f;   /* texture.c assumes there are 3 coords */
00504                 }
00505 
00506                 if(shi->osatex) {
00507                     suv->dxuv[0]= 0.0f;
00508                     suv->dxuv[1]= 0.0f;
00509                     suv->dyuv[0]= 0.0f;
00510                     suv->dyuv[1]= 0.0f;
00511                 }
00512 
00513                 if((mode & MA_FACETEXTURE) && i==obr->actmtface) {
00514                     if((mode & (MA_VERTEXCOL|MA_VERTEXCOLP))==0) {
00515                         shi->vcol[0]= 1.0f;
00516                         shi->vcol[1]= 1.0f;
00517                         shi->vcol[2]= 1.0f;
00518                         shi->vcol[3]= 1.0f;
00519                     }
00520                 }
00521             }
00522 
00523             if(shi->totuv == 0) {
00524                 ShadeInputUV *suv= &shi->uv[0];
00525 
00526                 suv->uv[0]= 0.0f;
00527                 suv->uv[1]= spoint->strandco;
00528                 suv->uv[2]= 0.0f;   /* texture.c assumes there are 3 coords */
00529                 
00530                 if(mode & MA_FACETEXTURE) {
00531                     /* no tface? set at 1.0f */
00532                     shi->vcol[0]= 1.0f;
00533                     shi->vcol[1]= 1.0f;
00534                     shi->vcol[2]= 1.0f;
00535                     shi->vcol[3]= 1.0f;
00536                 }
00537             }
00538 
00539         }
00540 
00541         if(texco & TEXCO_NORM) {
00542             shi->orn[0]= -shi->vn[0];
00543             shi->orn[1]= -shi->vn[1];
00544             shi->orn[2]= -shi->vn[2];
00545         }
00546 
00547         if(texco & TEXCO_STRESS) {
00548             /* not supported */
00549         }
00550 
00551         if(texco & TEXCO_TANGENT) {
00552             if((mode & MA_TANGENT_V)==0) {
00553                 /* just prevent surprises */
00554                 shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
00555                 shi->nmaptang[0]= shi->nmaptang[1]= shi->nmaptang[2]= 0.0f;
00556             }
00557         }
00558     }
00559 
00560     /* this only avalailable for scanline renders */
00561     if(shi->depth==0) {
00562         if(texco & TEXCO_WINDOW) {
00563             shi->winco[0]= -1.0f + 2.0f*spoint->x/(float)R.winx;
00564             shi->winco[1]= -1.0f + 2.0f*spoint->y/(float)R.winy;
00565             shi->winco[2]= 0.0f;
00566 
00567             /* not supported */
00568             if(shi->osatex) {
00569                 shi->dxwin[0]= 0.0f;
00570                 shi->dywin[1]= 0.0f;
00571                 shi->dxwin[0]= 0.0f;
00572                 shi->dywin[1]= 0.0f;
00573             }
00574         }
00575 
00576         if(texco & TEXCO_STICKY) {
00577             /* not supported */
00578         }
00579     }
00580     
00581     if (shi->do_manage) {
00582         if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)) {
00583             srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol);
00584         }
00585     }
00586     
00587 }
00588 
00589 /* from scanline pixel coordinates to 3d coordinates, requires set_triangle */
00590 void shade_input_calc_viewco(ShadeInput *shi, float x, float y, float z, float view[3], float dxyview[2], float co[3], float dxco[3], float dyco[3])
00591 {
00592     /* returns not normalized, so is in viewplane coords */
00593     calc_view_vector(view, x, y);
00594     
00595     if(shi->mat->material_type == MA_TYPE_WIRE) {
00596         /* wire cannot use normal for calculating shi->co, so
00597          * we reconstruct the coordinate less accurate */
00598         if(R.r.mode & R_ORTHO)
00599             calc_renderco_ortho(co, x, y, z);
00600         else
00601             calc_renderco_zbuf(co, view, z);
00602     }
00603     else {
00604         /* for non-wire, intersect with the triangle to get the exact coord */
00605         float fac, dface, v1[3];
00606         
00607         copy_v3_v3(v1, shi->v1->co);
00608         if(shi->obi->flag & R_TRANSFORMED)
00609             mul_m4_v3(shi->obi->mat, v1);
00610         
00611         dface= v1[0]*shi->facenor[0]+v1[1]*shi->facenor[1]+v1[2]*shi->facenor[2];
00612         
00613         /* ortho viewplane cannot intersect using view vector originating in (0,0,0) */
00614         if(R.r.mode & R_ORTHO) {
00615             /* x and y 3d coordinate can be derived from pixel coord and winmat */
00616             float fx= 2.0f/(R.winx*R.winmat[0][0]);
00617             float fy= 2.0f/(R.winy*R.winmat[1][1]);
00618             
00619             co[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
00620             co[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
00621             
00622             /* using a*x + b*y + c*z = d equation, (a b c) is normal */
00623             if(shi->facenor[2]!=0.0f)
00624                 co[2]= (dface - shi->facenor[0]*co[0] - shi->facenor[1]*co[1])/shi->facenor[2];
00625             else
00626                 co[2]= 0.0f;
00627             
00628             if(dxco && dyco) {
00629                 dxco[0]= fx;
00630                 dxco[1]= 0.0f;
00631                 if(shi->facenor[2]!=0.0f)
00632                     dxco[2]= -(shi->facenor[0]*fx)/shi->facenor[2];
00633                 else 
00634                     dxco[2]= 0.0f;
00635                 
00636                 dyco[0]= 0.0f;
00637                 dyco[1]= fy;
00638                 if(shi->facenor[2]!=0.0f)
00639                     dyco[2]= -(shi->facenor[1]*fy)/shi->facenor[2];
00640                 else 
00641                     dyco[2]= 0.0f;
00642                 
00643                 if(dxyview) {
00644                     if(co[2]!=0.0f) fac= 1.0f/co[2]; else fac= 0.0f;
00645                     dxyview[0]= -R.viewdx*fac;
00646                     dxyview[1]= -R.viewdy*fac;
00647                 }
00648             }
00649         }
00650         else {
00651             float div;
00652             
00653             div= shi->facenor[0]*view[0] + shi->facenor[1]*view[1] + shi->facenor[2]*view[2];
00654             if (div!=0.0f) fac= dface/div;
00655             else fac= 0.0f;
00656             
00657             co[0]= fac*view[0];
00658             co[1]= fac*view[1];
00659             co[2]= fac*view[2];
00660             
00661             /* pixel dx/dy for render coord */
00662             if(dxco && dyco) {
00663                 float u= dface/(div - R.viewdx*shi->facenor[0]);
00664                 float v= dface/(div - R.viewdy*shi->facenor[1]);
00665                 
00666                 dxco[0]= co[0]- (view[0]-R.viewdx)*u;
00667                 dxco[1]= co[1]- (view[1])*u;
00668                 dxco[2]= co[2]- (view[2])*u;
00669                 
00670                 dyco[0]= co[0]- (view[0])*v;
00671                 dyco[1]= co[1]- (view[1]-R.viewdy)*v;
00672                 dyco[2]= co[2]- (view[2])*v;
00673                 
00674                 if(dxyview) {
00675                     if(fac!=0.0f) fac= 1.0f/fac;
00676                     dxyview[0]= -R.viewdx*fac;
00677                     dxyview[1]= -R.viewdy*fac;
00678                 }
00679             }
00680         }
00681     }
00682     
00683     /* set camera coords - for scanline, it's always 0.0,0.0,0.0 (render is in camera space)
00684      * however for raytrace it can be different - the position of the last intersection */
00685     shi->camera_co[0] = shi->camera_co[1] = shi->camera_co[2] = 0.0f;
00686     
00687     /* cannot normalize earlier, code above needs it at viewplane level */
00688     normalize_v3(view);
00689 }
00690 
00691 /* from scanline pixel coordinates to 3d coordinates, requires set_triangle */
00692 void shade_input_set_viewco(ShadeInput *shi, float x, float y, float xs, float ys, float z)
00693 {
00694     float *dxyview= NULL, *dxco= NULL, *dyco= NULL;
00695     
00696     /* currently in use for dithering (soft shadow), node preview, irregular shad */
00697     shi->xs= (int)xs;
00698     shi->ys= (int)ys;
00699 
00700     /* original scanline coordinate without jitter */
00701     shi->scanco[0]= x;
00702     shi->scanco[1]= y;
00703     shi->scanco[2]= z;
00704 
00705     /* check if we need derivatives */
00706     if(shi->osatex || (R.r.mode & R_SHADOW)) {
00707         dxco= shi->dxco;
00708         dyco= shi->dyco;
00709 
00710         if((shi->mat->texco & TEXCO_REFL))
00711             dxyview= &shi->dxview;
00712     }
00713 
00714     shade_input_calc_viewco(shi, xs, ys, z, shi->view, dxyview, shi->co, dxco, dyco);
00715 }
00716 
00717 /* calculate U and V, for scanline (silly render face u and v are in range -1 to 0) */
00718 void shade_input_set_uv(ShadeInput *shi)
00719 {
00720     VlakRen *vlr= shi->vlr;
00721     
00722     if((vlr->flag & R_SMOOTH) || (shi->mat->texco & NEED_UV) || (shi->passflag & SCE_PASS_UV)) {
00723         float v1[3], v2[3], v3[3];
00724 
00725         copy_v3_v3(v1, shi->v1->co);
00726         copy_v3_v3(v2, shi->v2->co);
00727         copy_v3_v3(v3, shi->v3->co);
00728 
00729         if(shi->obi->flag & R_TRANSFORMED) {
00730             mul_m4_v3(shi->obi->mat, v1);
00731             mul_m4_v3(shi->obi->mat, v2);
00732             mul_m4_v3(shi->obi->mat, v3);
00733         }
00734 
00735         /* exception case for wire render of edge */
00736         if(vlr->v2==vlr->v3) {
00737             float lend, lenc;
00738             
00739             lend= len_v3v3(v2, v1);
00740             lenc= len_v3v3(shi->co, v1);
00741             
00742             if(lend==0.0f) {
00743                 shi->u=shi->v= 0.0f;
00744             }
00745             else {
00746                 shi->u= - (1.0f - lenc/lend);
00747                 shi->v= 0.0f;
00748             }
00749             
00750             if(shi->osatex) {
00751                 shi->dx_u=  0.0f;
00752                 shi->dx_v=  0.0f;
00753                 shi->dy_u=  0.0f;
00754                 shi->dy_v=  0.0f;
00755             }
00756         }
00757         else {
00758             /* most of this could become re-used for faces */
00759             float detsh, t00, t10, t01, t11;
00760             int axis1, axis2;
00761 
00762             /* find most stable axis to project */
00763             axis_dominant_v3(&axis1, &axis2, shi->facenor);
00764 
00765             /* compute u,v and derivatives */
00766             t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2];
00767             t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2];
00768 
00769             detsh= (t00*t11-t10*t01);
00770             detsh= (detsh != 0.0f)? 1.0f/detsh: 0.0f;
00771             t00*= detsh; t01*=detsh; 
00772             t10*=detsh; t11*=detsh;
00773 
00774             shi->u= (shi->co[axis1]-v3[axis1])*t11-(shi->co[axis2]-v3[axis2])*t10;
00775             shi->v= (shi->co[axis2]-v3[axis2])*t00-(shi->co[axis1]-v3[axis1])*t01;
00776             if(shi->osatex) {
00777                 shi->dx_u=  shi->dxco[axis1]*t11- shi->dxco[axis2]*t10;
00778                 shi->dx_v=  shi->dxco[axis2]*t00- shi->dxco[axis1]*t01;
00779                 shi->dy_u=  shi->dyco[axis1]*t11- shi->dyco[axis2]*t10;
00780                 shi->dy_v=  shi->dyco[axis2]*t00- shi->dyco[axis1]*t01;
00781             }
00782 
00783             /* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */
00784             CLAMP(shi->u, -2.0f, 1.0f);
00785             CLAMP(shi->v, -2.0f, 1.0f);
00786         }
00787     }   
00788 }
00789 
00790 void shade_input_set_normals(ShadeInput *shi)
00791 {
00792     float u= shi->u, v= shi->v;
00793     float l= 1.0f+u+v;
00794 
00795     shi->flippednor = 0;
00796 
00797     /* test flip normals to viewing direction */
00798     if(!(shi->vlr->flag & R_TANGENT)) {
00799         if(dot_v3v3(shi->facenor, shi->view) < 0.0f) {
00800             negate_v3(shi->facenor);
00801             shi->flippednor= 1;
00802         }
00803     }
00804     
00805     /* calculate vertexnormals */
00806     if(shi->vlr->flag & R_SMOOTH) {
00807         float *n1= shi->n1, *n2= shi->n2, *n3= shi->n3;
00808 
00809         if(shi->flippednor) {
00810             negate_v3(n1);
00811             negate_v3(n2);
00812             negate_v3(n3);
00813         }
00814         
00815         shi->vn[0]= l*n3[0]-u*n1[0]-v*n2[0];
00816         shi->vn[1]= l*n3[1]-u*n1[1]-v*n2[1];
00817         shi->vn[2]= l*n3[2]-u*n1[2]-v*n2[2];
00818 
00819         // use unnormalized normal (closer to games)
00820         copy_v3_v3(shi->nmapnorm, shi->vn);
00821         
00822         normalize_v3(shi->vn);
00823     }
00824     else
00825     {
00826         copy_v3_v3(shi->vn, shi->facenor);
00827         copy_v3_v3(shi->nmapnorm, shi->vn);
00828     }
00829     
00830     /* used in nodes */
00831     copy_v3_v3(shi->vno, shi->vn);
00832 
00833     /* flip normals to viewing direction */
00834     if(!(shi->vlr->flag & R_TANGENT))
00835         if(dot_v3v3(shi->facenor, shi->view) < 0.0f)
00836             shade_input_flip_normals(shi);
00837 }
00838 
00839 /* XXX shi->flippednor messes up otherwise */
00840 void shade_input_set_vertex_normals(ShadeInput *shi)
00841 {
00842     float u= shi->u, v= shi->v;
00843     float l= 1.0f+u+v;
00844     
00845     /* calculate vertexnormals */
00846     if(shi->vlr->flag & R_SMOOTH) {
00847         float *n1= shi->n1, *n2= shi->n2, *n3= shi->n3;
00848         
00849         shi->vn[0]= l*n3[0]-u*n1[0]-v*n2[0];
00850         shi->vn[1]= l*n3[1]-u*n1[1]-v*n2[1];
00851         shi->vn[2]= l*n3[2]-u*n1[2]-v*n2[2];
00852         
00853         // use unnormalized normal (closer to games)
00854         copy_v3_v3(shi->nmapnorm, shi->vn);
00855         
00856         normalize_v3(shi->vn);
00857     }
00858     else
00859     {
00860         copy_v3_v3(shi->vn, shi->facenor);
00861         copy_v3_v3(shi->nmapnorm, shi->vn);
00862     }
00863     
00864     /* used in nodes */
00865     copy_v3_v3(shi->vno, shi->vn);
00866 }
00867 
00868 
00869 /* use by raytrace, sss, bake to flip into the right direction */
00870 void shade_input_flip_normals(ShadeInput *shi)
00871 {
00872     shi->facenor[0]= -shi->facenor[0];
00873     shi->facenor[1]= -shi->facenor[1];
00874     shi->facenor[2]= -shi->facenor[2];
00875 
00876     shi->vn[0]= -shi->vn[0];
00877     shi->vn[1]= -shi->vn[1];
00878     shi->vn[2]= -shi->vn[2];
00879 
00880     shi->vno[0]= -shi->vno[0];
00881     shi->vno[1]= -shi->vno[1];
00882     shi->vno[2]= -shi->vno[2];
00883 
00884     shi->nmapnorm[0] = -shi->nmapnorm[0];
00885     shi->nmapnorm[1] = -shi->nmapnorm[1];
00886     shi->nmapnorm[2] = -shi->nmapnorm[2];
00887 
00888     shi->flippednor= !shi->flippednor;
00889 }
00890 
00891 void shade_input_set_shade_texco(ShadeInput *shi)
00892 {
00893     ObjectInstanceRen *obi= shi->obi;
00894     ObjectRen *obr= shi->obr;
00895     VertRen *v1= shi->v1, *v2= shi->v2, *v3= shi->v3;
00896     float u= shi->u, v= shi->v;
00897     float l= 1.0f+u+v, dl;
00898     int mode= shi->mode;        /* or-ed result for all nodes */
00899     short texco= shi->mat->texco;
00900 
00901     /* calculate dxno */
00902     if(shi->vlr->flag & R_SMOOTH) {
00903         
00904         if(shi->osatex && (texco & (TEXCO_NORM|TEXCO_REFL)) ) {
00905             float *n1= shi->n1, *n2= shi->n2, *n3= shi->n3;
00906             
00907             dl= shi->dx_u+shi->dx_v;
00908             shi->dxno[0]= dl*n3[0]-shi->dx_u*n1[0]-shi->dx_v*n2[0];
00909             shi->dxno[1]= dl*n3[1]-shi->dx_u*n1[1]-shi->dx_v*n2[1];
00910             shi->dxno[2]= dl*n3[2]-shi->dx_u*n1[2]-shi->dx_v*n2[2];
00911             dl= shi->dy_u+shi->dy_v;
00912             shi->dyno[0]= dl*n3[0]-shi->dy_u*n1[0]-shi->dy_v*n2[0];
00913             shi->dyno[1]= dl*n3[1]-shi->dy_u*n1[1]-shi->dy_v*n2[1];
00914             shi->dyno[2]= dl*n3[2]-shi->dy_u*n1[2]-shi->dy_v*n2[2];
00915             
00916         }
00917     }
00918 
00919     /* calc tangents */
00920     if (mode & (MA_TANGENT_V|MA_NORMAP_TANG) || R.flag & R_NEED_TANGENT) {
00921         float *tangent, *s1, *s2, *s3;
00922         float tl, tu, tv;
00923 
00924         if(shi->vlr->flag & R_SMOOTH) {
00925             tl= l;
00926             tu= u;
00927             tv= v;
00928         }
00929         else {
00930             /* qdn: flat faces have tangents too,
00931                could pick either one, using average here */
00932             tl= 1.0f/3.0f;
00933             tu= -1.0f/3.0f;
00934             tv= -1.0f/3.0f;
00935         }
00936 
00937         shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
00938         shi->nmaptang[0]= shi->nmaptang[1]= shi->nmaptang[2]= 0.0f;
00939 
00940         if(mode & MA_TANGENT_V) {
00941             s1 = RE_vertren_get_tangent(obr, v1, 0);
00942             s2 = RE_vertren_get_tangent(obr, v2, 0);
00943             s3 = RE_vertren_get_tangent(obr, v3, 0);
00944 
00945             if(s1 && s2 && s3) {
00946                 shi->tang[0]= (tl*s3[0] - tu*s1[0] - tv*s2[0]);
00947                 shi->tang[1]= (tl*s3[1] - tu*s1[1] - tv*s2[1]);
00948                 shi->tang[2]= (tl*s3[2] - tu*s1[2] - tv*s2[2]);
00949 
00950                 if(obi->flag & R_TRANSFORMED)
00951                     mul_m3_v3(obi->nmat, shi->tang);
00952 
00953                 normalize_v3(shi->tang);
00954                 copy_v3_v3(shi->nmaptang, shi->tang);
00955             }
00956         }
00957 
00958         if(mode & MA_NORMAP_TANG || R.flag & R_NEED_TANGENT) {
00959             tangent= RE_vlakren_get_nmap_tangent(obr, shi->vlr, 0);
00960 
00961             if(tangent) {
00962                 int j1= shi->i1, j2= shi->i2, j3= shi->i3;
00963                 float c0[3], c1[3], c2[3];
00964 
00965                 vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3);
00966 
00967                 copy_v3_v3(c0, &tangent[j1*4]);
00968                 copy_v3_v3(c1, &tangent[j2*4]);
00969                 copy_v3_v3(c2, &tangent[j3*4]);
00970 
00971                 // keeping tangents normalized at vertex level
00972                 // corresponds better to how it's done in game engines
00973                 if(obi->flag & R_TRANSFORMED)
00974                 {
00975                     mul_mat3_m4_v3(obi->mat, c0); normalize_v3(c0);
00976                     mul_mat3_m4_v3(obi->mat, c1); normalize_v3(c1);
00977                     mul_mat3_m4_v3(obi->mat, c2); normalize_v3(c2);
00978                 }
00979                 
00980                 // we don't normalize the interpolated TBN tangent
00981                 // corresponds better to how it's done in game engines
00982                 shi->nmaptang[0]= (tl*c2[0] - tu*c0[0] - tv*c1[0]);
00983                 shi->nmaptang[1]= (tl*c2[1] - tu*c0[1] - tv*c1[1]);
00984                 shi->nmaptang[2]= (tl*c2[2] - tu*c0[2] - tv*c1[2]);
00985 
00986                 // the sign is the same for all 3 vertices of any
00987                 // non degenerate triangle.
00988                 shi->nmaptang[3]= tangent[j1*4+3];
00989             }
00990         }
00991     }
00992 
00993     if(mode & MA_STR_SURFDIFF) {
00994         float *surfnor= RE_vlakren_get_surfnor(obr, shi->vlr, 0);
00995 
00996         if(surfnor) {
00997             copy_v3_v3(shi->surfnor, surfnor);
00998             if(obi->flag & R_TRANSFORMED)
00999                 mul_m3_v3(obi->nmat, shi->surfnor);
01000         }
01001         else
01002             copy_v3_v3(shi->surfnor, shi->vn);
01003 
01004         shi->surfdist= 0.0f;
01005     }
01006     
01007     if(R.r.mode & R_SPEED) {
01008         float *s1, *s2, *s3;
01009         
01010         s1= RE_vertren_get_winspeed(obi, v1, 0);
01011         s2= RE_vertren_get_winspeed(obi, v2, 0);
01012         s3= RE_vertren_get_winspeed(obi, v3, 0);
01013         if(s1 && s2 && s3) {
01014             shi->winspeed[0]= (l*s3[0] - u*s1[0] - v*s2[0]);
01015             shi->winspeed[1]= (l*s3[1] - u*s1[1] - v*s2[1]);
01016             shi->winspeed[2]= (l*s3[2] - u*s1[2] - v*s2[2]);
01017             shi->winspeed[3]= (l*s3[3] - u*s1[3] - v*s2[3]);
01018         }
01019         else {
01020             shi->winspeed[0]= shi->winspeed[1]= shi->winspeed[2]= shi->winspeed[3]= 0.0f;
01021         }
01022     }
01023 
01024     /* pass option forces UV calc */
01025     if(shi->passflag & SCE_PASS_UV)
01026         texco |= (NEED_UV|TEXCO_UV);
01027     
01028     /* texture coordinates. shi->dxuv shi->dyuv have been set */
01029     if(texco & NEED_UV) {
01030         
01031         if(texco & TEXCO_ORCO) {
01032             if(v1->orco) {
01033                 float *o1, *o2, *o3;
01034                 
01035                 o1= v1->orco;
01036                 o2= v2->orco;
01037                 o3= v3->orco;
01038                 
01039                 shi->lo[0]= l*o3[0]-u*o1[0]-v*o2[0];
01040                 shi->lo[1]= l*o3[1]-u*o1[1]-v*o2[1];
01041                 shi->lo[2]= l*o3[2]-u*o1[2]-v*o2[2];
01042                 
01043                 if(shi->osatex) {
01044                     dl= shi->dx_u+shi->dx_v;
01045                     shi->dxlo[0]= dl*o3[0]-shi->dx_u*o1[0]-shi->dx_v*o2[0];
01046                     shi->dxlo[1]= dl*o3[1]-shi->dx_u*o1[1]-shi->dx_v*o2[1];
01047                     shi->dxlo[2]= dl*o3[2]-shi->dx_u*o1[2]-shi->dx_v*o2[2];
01048                     dl= shi->dy_u+shi->dy_v;
01049                     shi->dylo[0]= dl*o3[0]-shi->dy_u*o1[0]-shi->dy_v*o2[0];
01050                     shi->dylo[1]= dl*o3[1]-shi->dy_u*o1[1]-shi->dy_v*o2[1];
01051                     shi->dylo[2]= dl*o3[2]-shi->dy_u*o1[2]-shi->dy_v*o2[2];
01052                 }
01053             }
01054 
01055             copy_v3_v3(shi->duplilo, obi->dupliorco);
01056         }
01057         
01058         if(texco & TEXCO_GLOB) {
01059             copy_v3_v3(shi->gl, shi->co);
01060             mul_m4_v3(R.viewinv, shi->gl);
01061             if(shi->osatex) {
01062                 copy_v3_v3(shi->dxgl, shi->dxco);
01063                 mul_mat3_m4_v3(R.viewinv, shi->dxgl); 
01064                 copy_v3_v3(shi->dygl, shi->dyco);
01065                 mul_mat3_m4_v3(R.viewinv, shi->dygl);
01066             }
01067         }
01068         
01069         if(texco & TEXCO_STRAND) {
01070             shi->strandco= (l*v3->accum - u*v1->accum - v*v2->accum);
01071             if(shi->osatex) {
01072                 dl= shi->dx_u+shi->dx_v;
01073                 shi->dxstrand= dl*v3->accum-shi->dx_u*v1->accum-shi->dx_v*v2->accum;
01074                 dl= shi->dy_u+shi->dy_v;
01075                 shi->dystrand= dl*v3->accum-shi->dy_u*v1->accum-shi->dy_v*v2->accum;
01076             }
01077         }
01078                 
01079         if((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)))  {
01080             VlakRen *vlr= shi->vlr;
01081             MTFace *tface;
01082             MCol *mcol;
01083             char *name;
01084             int i, j1=shi->i1, j2=shi->i2, j3=shi->i3;
01085 
01086             /* uv and vcols are not copied on split, so set them according vlr divide flag */
01087             vlr_set_uv_indices(vlr, &j1, &j2, &j3);
01088 
01089             shi->totuv= 0;
01090             shi->totcol= 0;
01091             shi->actuv= obr->actmtface;
01092             shi->actcol= obr->actmcol;
01093 
01094             if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP)) {
01095                 for (i=0; (mcol=RE_vlakren_get_mcol(obr, vlr, i, &name, 0)); i++) {
01096                     ShadeInputCol *scol= &shi->col[i];
01097                     char *cp1, *cp2, *cp3;
01098                     float a[3];
01099                     
01100                     shi->totcol++;
01101                     scol->name= name;
01102 
01103                     cp1= (char *)(mcol+j1);
01104                     cp2= (char *)(mcol+j2);
01105                     cp3= (char *)(mcol+j3);
01106 
01107                     /* alpha values */
01108                     a[0] = ((float)cp1[0])/255.f;
01109                     a[1] = ((float)cp2[0])/255.f;
01110                     a[2] = ((float)cp3[0])/255.f;
01111                     scol->col[3]= l*a[2] - u*a[0] - v*a[1];
01112 
01113                     /* sample premultiplied color value */
01114                     scol->col[0]= (l*((float)cp3[3])*a[2] - u*((float)cp1[3])*a[0] - v*((float)cp2[3])*a[1])/255.f;
01115                     scol->col[1]= (l*((float)cp3[2])*a[2] - u*((float)cp1[2])*a[0] - v*((float)cp2[2])*a[1])/255.f;
01116                     scol->col[2]= (l*((float)cp3[1])*a[2] - u*((float)cp1[1])*a[0] - v*((float)cp2[1])*a[1])/255.f;
01117 
01118                     /* if not zero alpha, restore non-multiplied color */
01119                     if (scol->col[3]) {
01120                         mul_v3_fl(scol->col, 1.0f/scol->col[3]);
01121                     }
01122                 }
01123 
01124                 if(shi->totcol) {
01125                     shi->vcol[0]= shi->col[shi->actcol].col[0];
01126                     shi->vcol[1]= shi->col[shi->actcol].col[1];
01127                     shi->vcol[2]= shi->col[shi->actcol].col[2];
01128                     shi->vcol[3]= shi->col[shi->actcol].col[3];
01129                 }
01130                 else {
01131                     shi->vcol[0]= 0.0f;
01132                     shi->vcol[1]= 0.0f;
01133                     shi->vcol[2]= 0.0f;
01134                     shi->vcol[3]= 1.0f;
01135                 }
01136             }
01137 
01138             for (i=0; (tface=RE_vlakren_get_tface(obr, vlr, i, &name, 0)); i++) {
01139                 ShadeInputUV *suv= &shi->uv[i];
01140                 float *uv1, *uv2, *uv3;
01141 
01142                 shi->totuv++;
01143                 suv->name= name;
01144                 
01145                 uv1= tface->uv[j1];
01146                 uv2= tface->uv[j2];
01147                 uv3= tface->uv[j3];
01148                 
01149                 suv->uv[0]= -1.0f + 2.0f*(l*uv3[0]-u*uv1[0]-v*uv2[0]);
01150                 suv->uv[1]= -1.0f + 2.0f*(l*uv3[1]-u*uv1[1]-v*uv2[1]);
01151                 suv->uv[2]= 0.0f;   /* texture.c assumes there are 3 coords */
01152 
01153                 if(shi->osatex) {
01154                     float duv[2];
01155                     
01156                     dl= shi->dx_u+shi->dx_v;
01157                     duv[0]= shi->dx_u; 
01158                     duv[1]= shi->dx_v;
01159                     
01160                     suv->dxuv[0]= 2.0f*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]);
01161                     suv->dxuv[1]= 2.0f*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]);
01162                     
01163                     dl= shi->dy_u+shi->dy_v;
01164                     duv[0]= shi->dy_u; 
01165                     duv[1]= shi->dy_v;
01166                     
01167                     suv->dyuv[0]= 2.0f*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]);
01168                     suv->dyuv[1]= 2.0f*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]);
01169                 }
01170 
01171                 if((mode & MA_FACETEXTURE) && i==obr->actmtface) {
01172                     if((mode & (MA_VERTEXCOL|MA_VERTEXCOLP))==0) {
01173                         shi->vcol[0]= 1.0f;
01174                         shi->vcol[1]= 1.0f;
01175                         shi->vcol[2]= 1.0f;
01176                         shi->vcol[3]= 1.0f;
01177                     }
01178                     if(tface->tpage) {
01179                         render_realtime_texture(shi, tface->tpage);
01180                     }
01181                 }
01182 
01183 
01184             }
01185 
01186             shi->dupliuv[0]= -1.0f + 2.0f*obi->dupliuv[0];
01187             shi->dupliuv[1]= -1.0f + 2.0f*obi->dupliuv[1];
01188             shi->dupliuv[2]= 0.0f;
01189 
01190             if(shi->totuv == 0) {
01191                 ShadeInputUV *suv= &shi->uv[0];
01192 
01193                 suv->uv[0]= 2.0f*(u+.5f);
01194                 suv->uv[1]= 2.0f*(v+.5f);
01195                 suv->uv[2]= 0.0f;   /* texture.c assumes there are 3 coords */
01196                 
01197                 if(mode & MA_FACETEXTURE) {
01198                     /* no tface? set at 1.0f */
01199                     shi->vcol[0]= 1.0f;
01200                     shi->vcol[1]= 1.0f;
01201                     shi->vcol[2]= 1.0f;
01202                     shi->vcol[3]= 1.0f;
01203                 }
01204             }
01205         }
01206         
01207         if(texco & TEXCO_NORM) {
01208             shi->orn[0]= -shi->vn[0];
01209             shi->orn[1]= -shi->vn[1];
01210             shi->orn[2]= -shi->vn[2];
01211         }
01212         
01213         if(texco & TEXCO_STRESS) {
01214             float *s1, *s2, *s3;
01215             
01216             s1= RE_vertren_get_stress(obr, v1, 0);
01217             s2= RE_vertren_get_stress(obr, v2, 0);
01218             s3= RE_vertren_get_stress(obr, v3, 0);
01219             if(s1 && s2 && s3) {
01220                 shi->stress= l*s3[0] - u*s1[0] - v*s2[0];
01221                 if(shi->stress<1.0f) shi->stress-= 1.0f;
01222                 else shi->stress= (shi->stress-1.0f)/shi->stress;
01223             }
01224             else shi->stress= 0.0f;
01225         }
01226         
01227         if(texco & TEXCO_TANGENT) {
01228             if((mode & MA_TANGENT_V)==0) {
01229                 /* just prevent surprises */
01230                 shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
01231                 shi->nmaptang[0]= shi->nmaptang[1]= shi->nmaptang[2]= 0.0f;
01232             }
01233         }
01234     }
01235     
01236     /* this only avalailable for scanline renders */
01237     if(shi->depth==0) {
01238         float x= shi->xs;
01239         float y= shi->ys;
01240         
01241         if(texco & TEXCO_WINDOW) {
01242             shi->winco[0]= -1.0f + 2.0f*x/(float)R.winx;
01243             shi->winco[1]= -1.0f + 2.0f*y/(float)R.winy;
01244             shi->winco[2]= 0.0f;
01245             if(shi->osatex) {
01246                 shi->dxwin[0]= 2.0f/(float)R.winx;
01247                 shi->dywin[1]= 2.0f/(float)R.winy;
01248                 shi->dxwin[1]= shi->dxwin[2]= 0.0f;
01249                 shi->dywin[0]= shi->dywin[2]= 0.0f;
01250             }
01251         }
01252 
01253         if(texco & TEXCO_STICKY) {
01254             float *s1, *s2, *s3;
01255             
01256             s1= RE_vertren_get_sticky(obr, v1, 0);
01257             s2= RE_vertren_get_sticky(obr, v2, 0);
01258             s3= RE_vertren_get_sticky(obr, v3, 0);
01259             
01260             if(s1 && s2 && s3) {
01261                 float obwinmat[4][4], winmat[4][4], ho1[4], ho2[4], ho3[4];
01262                 float Zmulx, Zmuly;
01263                 float hox, hoy, l, dl, u, v;
01264                 float s00, s01, s10, s11, detsh;
01265                 
01266                 /* old globals, localized now */
01267                 Zmulx=  ((float)R.winx)/2.0f; Zmuly=  ((float)R.winy)/2.0f;
01268 
01269                 zbuf_make_winmat(&R, winmat);
01270                 if(shi->obi->flag & R_TRANSFORMED)
01271                     mult_m4_m4m4(obwinmat, winmat, obi->mat);
01272                 else
01273                     copy_m4_m4(obwinmat, winmat);
01274 
01275                 zbuf_render_project(obwinmat, v1->co, ho1);
01276                 zbuf_render_project(obwinmat, v2->co, ho2);
01277                 zbuf_render_project(obwinmat, v3->co, ho3);
01278                 
01279                 s00= ho3[0]/ho3[3] - ho1[0]/ho1[3];
01280                 s01= ho3[1]/ho3[3] - ho1[1]/ho1[3];
01281                 s10= ho3[0]/ho3[3] - ho2[0]/ho2[3];
01282                 s11= ho3[1]/ho3[3] - ho2[1]/ho2[3];
01283                 
01284                 detsh= s00*s11-s10*s01;
01285                 detsh= (detsh != 0.0f)? 1.0f/detsh: 0.0f;
01286                 s00*= detsh; s01*=detsh; 
01287                 s10*=detsh; s11*=detsh;
01288                 
01289                 /* recalc u and v again */
01290                 hox= x/Zmulx -1.0f;
01291                 hoy= y/Zmuly -1.0f;
01292                 u= (hox - ho3[0]/ho3[3])*s11 - (hoy - ho3[1]/ho3[3])*s10;
01293                 v= (hoy - ho3[1]/ho3[3])*s00 - (hox - ho3[0]/ho3[3])*s01;
01294                 l= 1.0f+u+v;
01295                 
01296                 shi->sticky[0]= l*s3[0]-u*s1[0]-v*s2[0];
01297                 shi->sticky[1]= l*s3[1]-u*s1[1]-v*s2[1];
01298                 shi->sticky[2]= 0.0f;
01299                 
01300                 if(shi->osatex) {
01301                     float dxuv[2], dyuv[2];
01302                     dxuv[0]=  s11/Zmulx;
01303                     dxuv[1]=  - s01/Zmulx;
01304                     dyuv[0]=  - s10/Zmuly;
01305                     dyuv[1]=  s00/Zmuly;
01306                     
01307                     dl= dxuv[0] + dxuv[1];
01308                     shi->dxsticky[0]= dl*s3[0] - dxuv[0]*s1[0] - dxuv[1]*s2[0];
01309                     shi->dxsticky[1]= dl*s3[1] - dxuv[0]*s1[1] - dxuv[1]*s2[1];
01310                     dl= dyuv[0] + dyuv[1];
01311                     shi->dysticky[0]= dl*s3[0] - dyuv[0]*s1[0] - dyuv[1]*s2[0];
01312                     shi->dysticky[1]= dl*s3[1] - dyuv[0]*s1[1] - dyuv[1]*s2[1];
01313                 }
01314             }
01315         }
01316     } /* else {
01317      Note! For raytracing winco is not set, important because thus means all shader input's need to have their variables set to zero else in-initialized values are used
01318     */
01319     if (shi->do_manage) {
01320         if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)) {
01321             srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol);
01322         }
01323     }
01324     
01325 }
01326 
01327 /* ****************** ShadeSample ************************************** */
01328 
01329 /* initialize per part, not per pixel! */
01330 void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, int sample)
01331 {
01332     
01333     memset(shi, 0, sizeof(ShadeInput));
01334     
01335     shi->sample= sample;
01336     shi->thread= pa->thread;
01337     shi->do_preview= (R.r.scemode & R_MATNODE_PREVIEW) != 0;
01338     shi->do_manage= (R.r.color_mgt_flag & R_COLOR_MANAGEMENT);
01339     shi->lay= rl->lay;
01340     shi->layflag= rl->layflag;
01341     shi->passflag= rl->passflag;
01342     shi->combinedflag= ~rl->pass_xor;
01343     shi->mat_override= rl->mat_override;
01344     shi->light_override= rl->light_override;
01345 //  shi->rl= rl;
01346     /* note shi.depth==0  means first hit, not raytracing */
01347     
01348 }
01349 
01350 /* initialize per part, not per pixel! */
01351 void shade_sample_initialize(ShadeSample *ssamp, RenderPart *pa, RenderLayer *rl)
01352 {
01353     int a, tot;
01354     
01355     tot= R.osa==0?1:R.osa;
01356     
01357     for(a=0; a<tot; a++) {
01358         shade_input_initialize(&ssamp->shi[a], pa, rl, a);
01359         memset(&ssamp->shr[a], 0, sizeof(ShadeResult));
01360     }
01361     
01362     get_sample_layers(pa, rl, ssamp->rlpp);
01363 }
01364 
01365 /* Do AO or (future) GI */
01366 void shade_samples_do_AO(ShadeSample *ssamp)
01367 {
01368     if(!(R.r.mode & R_SHADOW))
01369         return;
01370     if(!(R.r.mode & R_RAYTRACE) && !(R.wrld.ao_gather_method == WO_AOGATHER_APPROX))
01371         return;
01372     
01373     if(R.wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) {
01374         ShadeInput *shi= &ssamp->shi[0];
01375         int sample;
01376 
01377         if(((shi->passflag & SCE_PASS_COMBINED) && (shi->combinedflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT)))
01378             || (shi->passflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT)))
01379             for(sample=0; sample<ssamp->tot; shi++, sample++)
01380                 if(!(shi->mode & MA_SHLESS))
01381                     ambient_occlusion(shi);     /* stores in shi->ao[] */
01382     }
01383 }
01384 
01385 
01386 void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, int y)
01387 {
01388     ShadeInput *shi;
01389     float xs, ys;
01390     
01391     ssamp->tot= 0;
01392     
01393     for(shi= ssamp->shi; ps; ps= ps->next) {
01394         shade_input_set_triangle(shi, ps->obi, ps->facenr, 1);
01395         
01396         if(shi->vlr) {  /* NULL happens for env material or for 'all z' */
01397             unsigned short curmask= ps->mask;
01398             
01399             /* full osa is only set for OSA renders */
01400             if(shi->vlr->flag & R_FULL_OSA) {
01401                 short shi_cp= 0, samp;
01402                 
01403                 for(samp=0; samp<R.osa; samp++) {
01404                     if(curmask & (1<<samp)) {
01405                         /* zbuffer has this inverse corrected, ensures xs,ys are inside pixel */
01406                         xs= (float)x + R.jit[samp][0] + 0.5f;
01407                         ys= (float)y + R.jit[samp][1] + 0.5f;
01408                         
01409                         if(shi_cp)
01410                             shade_input_copy_triangle(shi, shi-1);
01411                         
01412                         shi->mask= (1<<samp);
01413 //                      shi->rl= ssamp->rlpp[samp];
01414                         shi->samplenr= R.shadowsamplenr[shi->thread]++; /* this counter is not being reset per pixel */
01415                         shade_input_set_viewco(shi, x, y, xs, ys, (float)ps->z);
01416                         shade_input_set_uv(shi);
01417                         if(shi_cp==0)
01418                             shade_input_set_normals(shi);
01419                         else  /* XXX shi->flippednor messes up otherwise */
01420                             shade_input_set_vertex_normals(shi);
01421                         
01422                         shi_cp= 1;
01423                         shi++;
01424                     }
01425                 }
01426             }
01427             else {
01428                 if(R.osa) {
01429                     short b= R.samples->centmask[curmask];
01430                     xs= (float)x + R.samples->centLut[b & 15] + 0.5f;
01431                     ys= (float)y + R.samples->centLut[b>>4] + 0.5f;
01432                 }
01433                 else {
01434                     xs= (float)x + 0.5f;
01435                     ys= (float)y + 0.5f;
01436                 }
01437 
01438                 shi->mask= curmask;
01439                 shi->samplenr= R.shadowsamplenr[shi->thread]++;
01440                 shade_input_set_viewco(shi, x, y, xs, ys, (float)ps->z);
01441                 shade_input_set_uv(shi);
01442                 shade_input_set_normals(shi);
01443                 shi++;
01444             }
01445             
01446             /* total sample amount, shi->sample is static set in initialize */
01447             if(shi!=ssamp->shi)
01448                 ssamp->tot= (shi-1)->sample + 1;
01449         }
01450     }
01451 }
01452 
01453 /* shades samples, returns true if anything happened */
01454 int shade_samples(ShadeSample *ssamp, PixStr *ps, int x, int y)
01455 {
01456     shade_samples_fill_with_ps(ssamp, ps, x, y);
01457     
01458     if(ssamp->tot) {
01459         ShadeInput *shi= ssamp->shi;
01460         ShadeResult *shr= ssamp->shr;
01461         int samp;
01462         
01463         /* if shadow or AO? */
01464         shade_samples_do_AO(ssamp);
01465         
01466         /* if shade (all shadepinputs have same passflag) */
01467         if(ssamp->shi[0].passflag & ~(SCE_PASS_Z|SCE_PASS_INDEXOB|SCE_PASS_INDEXMA)) {
01468 
01469             for(samp=0; samp<ssamp->tot; samp++, shi++, shr++) {
01470                 shade_input_set_shade_texco(shi);
01471                 shade_input_do_shade(shi, shr);
01472             }
01473         }
01474         else if(shi->passflag & SCE_PASS_Z) {
01475             for(samp=0; samp<ssamp->tot; samp++, shi++, shr++)
01476                 shr->z= -shi->co[2];
01477         }
01478         
01479         return 1;
01480     }
01481     return 0;
01482 }
01483