merge from trunk #37722
[blender-staging.git] / source / blender / render / intern / source / renderdatabase.c
index 621831fb34111883f64f8423e43c9d9afbfdbedb..456162d2d30596dd5463a433f6792d07c72f7a15 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
  * ***** END GPL/BL DUAL LICENSE BLOCK *****
  */
 
+/** \file blender/render/intern/source/renderdatabase.c
+ *  \ingroup render
+ */
+
+
 /*
  * Storage, retrieval and query of render specific data.
  *
 #include <string.h>
 
 #include "MEM_guardedalloc.h"
-#include "BKE_utildefines.h"
 
-#include "BLI_arithb.h"
+
+#include "BLI_math.h"
 #include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
 #include "BLI_ghash.h"
 #include "BLI_memarena.h"
 
@@ -76,6 +82,7 @@
 
 #include "RE_render_ext.h"     /* externtex */
 
+#include "rayobject.h"
 #include "renderpipeline.h"
 #include "render_types.h"
 #include "renderdatabase.h"
 #define RE_RADFACE_ELEMS       1
 #define RE_SIMPLIFY_ELEMS      2
 #define RE_FACE_ELEMS          1
-#define RE_NMAP_TANGENT_ELEMS  12
+#define RE_NMAP_TANGENT_ELEMS  16
 
 float *RE_vertren_get_sticky(ObjectRen *obr, VertRen *ver, int verify)
 {
@@ -293,7 +300,7 @@ MTFace *RE_vlakren_get_tface(ObjectRen *obr, VlakRen *vlr, int n, char **name, i
        if(verify) {
                if(n>=node->totmtface) {
                        MTFace *mtface= node->mtface;
-                       int size= size= (n+1)*256;
+                       int size= (n+1)*256;
 
                        node->mtface= MEM_callocN(size*sizeof(MTFace), "Vlak mtface");
 
@@ -439,42 +446,18 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
        return vlr1;
 }
 
-int RE_vlakren_get_normal(Render *re, ObjectInstanceRen *obi, VlakRen *vlr, float *nor)
+void RE_vlakren_get_normal(Render *UNUSED(re), ObjectInstanceRen *obi, VlakRen *vlr, float *nor)
 {
-       float v1[3], (*nmat)[3]= obi->nmat;
-       int flipped= 0;
+       float (*nmat)[3]= obi->nmat;
 
        if(obi->flag & R_TRANSFORMED) {
                VECCOPY(nor, vlr->n);
                
-               Mat3MulVecfl(nmat, nor);
-               Normalize(nor);
+               mul_m3_v3(nmat, nor);
+               normalize_v3(nor);
        }
        else
                VECCOPY(nor, vlr->n);
-
-       if((vlr->flag & R_NOPUNOFLIP)==0) {
-               if(re->r.mode & R_ORTHO) {
-                       if(nor[2] > 0.0f)
-                               flipped= 1;
-               }
-               else {
-                       VECCOPY(v1, vlr->v1->co);
-                       if(obi->flag & R_TRANSFORMED)
-                               Mat4MulVecfl(obi->mat, v1);
-                       if(INPR(v1, nor) < 0.0f) {
-                               flipped= 1;
-                       }
-               }
-
-               if(flipped) {
-                       nor[0]= -nor[0];
-                       nor[1]= -nor[1];
-                       nor[2]= -nor[2];
-               }
-       }
-
-       return flipped;
 }
 
 void RE_set_customdata_names(ObjectRen *obr, CustomData *data)
@@ -799,7 +782,7 @@ void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
        MEM_freeN(vlaknodes);
 }
 
-void free_renderdata_strandnodes(StrandTableNode *strandnodes)
+static void free_renderdata_strandnodes(StrandTableNode *strandnodes)
 {
        int a;
        
@@ -872,13 +855,34 @@ void free_renderdata_tables(Render *re)
                        MEM_freeN(obr->mtface);
                if(obr->mcol)
                        MEM_freeN(obr->mcol);
+                       
+               if(obr->rayfaces)
+               {
+                       MEM_freeN(obr->rayfaces);
+                       obr->rayfaces = NULL;
+               }
+               if(obr->rayprimitives)
+               {
+                       MEM_freeN(obr->rayprimitives);
+                       obr->rayprimitives = NULL;
+               }
+               if(obr->raytree)
+               {
+                       RE_rayobject_free(obr->raytree);
+                       obr->raytree = NULL;
+               }
        }
 
        if(re->objectinstance) {
                for(obi=re->instancetable.first; obi; obi=obi->next)
+               {
                        if(obi->vectors)
                                MEM_freeN(obi->vectors);
 
+                       if(obi->raytree)
+                               RE_rayobject_free(obi->raytree);
+               }
+
                MEM_freeN(re->objectinstance);
                re->objectinstance= NULL;
                re->totinstance= 0;
@@ -973,12 +977,12 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,   float *vec,   f
 
                har->sin= sin(zn);
                har->cos= cos(zn);
-               zn= VecLenf(vec1, vec);
+               zn= len_v3v3(vec1, vec);
 
                har->hasize= vectsize*zn + (1.0-vectsize)*hasize;
                
-               VecSubf(har->no, vec, vec1);
-               Normalize(har->no);
+               sub_v3_v3v3(har->no, vec, vec1);
+               normalize_v3(har->no);
        }
 
        if(ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;
@@ -1001,6 +1005,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,   float *vec,   f
        if(ma->mtex[0]) {
 
                if( (ma->mode & MA_HALOTEX) ) har->tex= 1;
+               else if(har->mat->septex & (1<<0));     /* only 1 level textures */
                else {
 
                        mtex= ma->mtex[0];
@@ -1013,7 +1018,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,   float *vec,   f
                                /* texvec[0]+= imatbase->ivec[0]; */
                                /* texvec[1]+= imatbase->ivec[1]; */
                                /* texvec[2]+= imatbase->ivec[2]; */
-                               /* Mat3MulVecfl(imatbase->imat, texvec); */
+                               /* mul_m3_v3(imatbase->imat, texvec); */
                        }
                        else {
                                if(orco) {
@@ -1021,10 +1026,10 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,   float *vec,   f
                                }
                        }
 
-                       externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta);
+                       externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0);
 
                        yn= tin*mtex->colfac;
-                       zn= tin*mtex->varfac;
+                       zn= tin*mtex->alphafac;
 
                        if(mtex->mapto & MAP_COL) {
                                zn= 1.0-yn;
@@ -1044,13 +1049,13 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,   float *vec,   f
 }
 
 HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma,   float *vec,   float *vec1, 
-                                 float *orco, float *uvco, float hasize, float vectsize, int seed)
+                                 float *orco, float *uvco, float hasize, float vectsize, int seed, float *pa_co)
 {
        HaloRen *har;
        MTex *mtex;
        float tin, tr, tg, tb, ta;
        float xn, yn, zn, texvec[3], hoco[4], hoco1[4], in[3],tex[3],out[3];
-       int i;
+       int i, hasrgb;
 
        if(hasize==0.0) return NULL;
 
@@ -1086,12 +1091,12 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
 
                har->sin= sin(zn);
                har->cos= cos(zn);
-               zn= VecLenf(vec1, vec)*0.5;
+               zn= len_v3v3(vec1, vec)*0.5;
 
                har->hasize= vectsize*zn + (1.0-vectsize)*hasize;
                
-               VecSubf(har->no, vec, vec1);
-               Normalize(har->no);
+               sub_v3_v3v3(har->no, vec, vec1);
+               normalize_v3(har->no);
        }
 
        if(ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;
@@ -1124,16 +1129,8 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
                                ;
                        }
                        else if(mtex->texco & TEXCO_OBJECT) {
-                               if(mtex->object){
-                                       float imat[4][4];
-                                       /* imat should really be cached somewhere before this */
-                                       Mat4Invert(imat,mtex->object->obmat);
-                                       Mat4MulVecfl(imat,texvec);
-                               }
-                               /* texvec[0]+= imatbase->ivec[0]; */
-                               /* texvec[1]+= imatbase->ivec[1]; */
-                               /* texvec[2]+= imatbase->ivec[2]; */
-                               /* Mat3MulVecfl(imatbase->imat, texvec); */
+                               if(mtex->object)
+                                       mul_m4_v3(mtex->object->imat_ren,texvec);
                        }
                        else if(mtex->texco & TEXCO_GLOB){
                                VECCOPY(texvec,vec);
@@ -1149,14 +1146,20 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
                                texvec[1]=2.0f*uvco[2*uv_index+1]-1.0f;
                                texvec[2]=0.0f;
                        }
+                       else if(mtex->texco & TEXCO_PARTICLE) {
+                               /* particle coordinates in range [0,1] */
+                               texvec[0] = 2.f * pa_co[0] - 1.f;
+                               texvec[1] = 2.f * pa_co[1] - 1.f;
+                               texvec[2] = pa_co[2];
+                       }
                        else if(orco) {
                                VECCOPY(texvec, orco);
                        }
 
-                       externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta);
+                       hasrgb = externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0);
 
                        //yn= tin*mtex->colfac;
-                       //zn= tin*mtex->varfac;
+                       //zn= tin*mtex->alphafac;
                        if(mtex->mapto & MAP_COL) {
                                tex[0]=tr;
                                tex[1]=tg;
@@ -1174,12 +1177,22 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
                                har->g= in[1];
                                har->b= in[2];
                        }
+
+                       /* alpha returned, so let's use it instead of intensity */
+                       if(hasrgb)
+                               tin = ta;
+
                        if(mtex->mapto & MAP_ALPHA)
-                               har->alfa = texture_value_blend(mtex->def_var,har->alfa,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_ALPHA);
+                               har->alfa = texture_value_blend(mtex->def_var,har->alfa,tin,mtex->alphafac,mtex->blendtype);
                        if(mtex->mapto & MAP_HAR)
-                               har->hard = 1.0+126.0*texture_value_blend(mtex->def_var,((float)har->hard)/127.0,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_HAR);
+                               har->hard = 1.0+126.0*texture_value_blend(mtex->def_var,((float)har->hard)/127.0,tin,mtex->hardfac,mtex->blendtype);
                        if(mtex->mapto & MAP_RAYMIRR)
-                               har->hasize = 100.0*texture_value_blend(mtex->def_var,har->hasize/100.0,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_RAYMIRR);
+                               har->hasize = 100.0*texture_value_blend(mtex->def_var,har->hasize/100.0,tin,mtex->raymirrfac,mtex->blendtype);
+                       if(mtex->mapto & MAP_TRANSLU) {
+                               float add = texture_value_blend(mtex->def_var,(float)har->add/255.0,tin,mtex->translfac,mtex->blendtype);
+                               CLAMP(add, 0.f, 1.f);
+                               har->add = 255.0*add;
+                       }
                        /* now what on earth is this good for?? */
                        //if(mtex->texco & 16) {
                        //      har->alfa= tin;
@@ -1225,7 +1238,7 @@ static int panotestclip(Render *re, int do_pano, float *v)
   - shadow buffering (shadbuf.c)
 */
 
-void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], float *),  int do_pano, float xoffs, int do_buckets)
+void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], float *),  int do_pano, float xoffs, int UNUSED(do_buckets))
 {
        ObjectRen *obr;
        HaloRen *har = NULL;
@@ -1327,10 +1340,10 @@ ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob,
        obi->lay= lay;
 
        if(mat) {
-               Mat4CpyMat4(obi->mat, mat);
-               Mat3CpyMat4(mat3, mat);
-               Mat3Inv(obi->nmat, mat3);
-               Mat3Transp(obi->nmat);
+               copy_m4_m4(obi->mat, mat);
+               copy_m3_m4(mat3, mat);
+               invert_m3_m3(obi->nmat, mat3);
+               transpose_m3(obi->nmat);
                obi->flag |= R_DUPLI_TRANSFORMED;
        }
 
@@ -1373,30 +1386,32 @@ int clip_render_object(float boundbox[][3], float *bounds, float winmat[][4])
        float mat[4][4], vec[4];
        int a, fl, flag= -1;
 
-       Mat4CpyMat4(mat, winmat);
+       copy_m4_m4(mat, winmat);
 
        for(a=0; a<8; a++) {
                vec[0]= (a & 1)? boundbox[0][0]: boundbox[1][0];
                vec[1]= (a & 2)? boundbox[0][1]: boundbox[1][1];
                vec[2]= (a & 4)? boundbox[0][2]: boundbox[1][2];
                vec[3]= 1.0;
-               Mat4MulVec4fl(mat, vec);
+               mul_m4_v4(mat, vec);
 
                fl= 0;
                if(bounds) {
-                       if(vec[0] > bounds[1]*vec[3]) fl |= 1;
-                       if(vec[0]< bounds[0]*vec[3]) fl |= 2;
+                       if(vec[0] < bounds[0]*vec[3]) fl |= 1;
+                       else if(vec[0] > bounds[1]*vec[3]) fl |= 2;
+                       
                        if(vec[1] > bounds[3]*vec[3]) fl |= 4;
-                       if(vec[1]< bounds[2]*vec[3]) fl |= 8;
+                       else if(vec[1]< bounds[2]*vec[3]) fl |= 8;
                }
                else {
                        if(vec[0] < -vec[3]) fl |= 1;
-                       if(vec[0] > vec[3]) fl |= 2;
-                       if(vec[1] < -vec[3]) fl |= 4;
-                       if(vec[1] > vec[3]) fl |= 8;
+                       else if(vec[0] > vec[3]) fl |= 2;
+                       
+                       if(vec[1] > vec[3]) fl |= 4;
+                       else if(vec[1] < -vec[3]) fl |= 8;
                }
                if(vec[2] < -vec[3]) fl |= 16;
-               if(vec[2] > vec[3]) fl |= 32;
+               else if(vec[2] > vec[3]) fl |= 32;
 
                flag &= fl;
                if(flag==0) return 0;