merge from trunk #37722
[blender-staging.git] / source / blender / render / intern / source / renderdatabase.c
index 059a72507c56128a3c075331dcaefebce502b07e..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_MCOL_ELEMS          4
 #define RE_UV_ELEMS                    2
 #define RE_SURFNOR_ELEMS       3
+#define RE_RADFACE_ELEMS       1
 #define RE_SIMPLIFY_ELEMS      2
+#define RE_FACE_ELEMS          1
+#define RE_NMAP_TANGENT_ELEMS  16
 
 float *RE_vertren_get_sticky(ObjectRen *obr, VertRen *ver, int verify)
 {
@@ -290,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");
 
@@ -362,12 +372,43 @@ float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify)
        return surfnor + (vlak->index & 255)*RE_SURFNOR_ELEMS;
 }
 
+float *RE_vlakren_get_nmap_tangent(ObjectRen *obr, VlakRen *vlak, int verify)
+{
+       float *tangent;
+       int nr= vlak->index>>8;
+
+       tangent= obr->vlaknodes[nr].tangent;
+       if(tangent==NULL) {
+               if(verify) 
+                       tangent= obr->vlaknodes[nr].tangent= MEM_callocN(256*RE_NMAP_TANGENT_ELEMS*sizeof(float), "tangent table");
+               else
+                       return NULL;
+       }
+       return tangent + (vlak->index & 255)*RE_NMAP_TANGENT_ELEMS;
+}
+
+RadFace **RE_vlakren_get_radface(ObjectRen *obr, VlakRen *vlak, int verify)
+{
+       RadFace **radface;
+       int nr= vlak->index>>8;
+       
+       radface= obr->vlaknodes[nr].radface;
+       if(radface==NULL) {
+               if(verify) 
+                       radface= obr->vlaknodes[nr].radface= MEM_callocN(256*RE_RADFACE_ELEMS*sizeof(void*), "radface table");
+               else
+                       return NULL;
+       }
+       return radface + (vlak->index & 255)*RE_RADFACE_ELEMS;
+}
+
 VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
 {
        VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++);
        MTFace *mtface, *mtface1;
        MCol *mcol, *mcol1;
-       float *surfnor, *surfnor1;
+       float *surfnor, *surfnor1, *tangent, *tangent1;
+       RadFace **radface, **radface1;
        int i, index = vlr1->index;
        char *name;
 
@@ -390,50 +431,33 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
                VECCOPY(surfnor1, surfnor);
        }
 
+       tangent= RE_vlakren_get_nmap_tangent(obr, vlr, 0);
+       if(tangent) {
+               tangent1= RE_vlakren_get_nmap_tangent(obr, vlr1, 1);
+               memcpy(tangent1, tangent, sizeof(float)*RE_NMAP_TANGENT_ELEMS);
+       }
+
+       radface= RE_vlakren_get_radface(obr, vlr, 0);
+       if(radface) {
+               radface1= RE_vlakren_get_radface(obr, vlr1, 1);
+               *radface1= *radface;
+       }
+
        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 xn, yn, zn, v1[3];
-       float (*imat)[3]= obi->imat;
-       int flipped= 0;
+       float (*nmat)[3]= obi->nmat;
 
        if(obi->flag & R_TRANSFORMED) {
-               xn= vlr->n[0];
-               yn= vlr->n[1];
-               zn= vlr->n[2];
+               VECCOPY(nor, vlr->n);
                
-               /* transpose! */
-               nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
-               nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
-               nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+               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)
@@ -442,16 +466,16 @@ void RE_set_customdata_names(ObjectRen *obr, CustomData *data)
           DerivedMesh which stores the layers is freed */
        
        CustomDataLayer *layer;
-       int numlayers, i, mtfn, mcn;
+       int numtf = 0, numcol = 0, i, mtfn, mcn;
 
        if (CustomData_has_layer(data, CD_MTFACE)) {
-               numlayers= CustomData_number_of_layers(data, CD_MTFACE);
-               obr->mtface= MEM_callocN(sizeof(*obr->mtface)*numlayers, "mtfacenames");
+               numtf= CustomData_number_of_layers(data, CD_MTFACE);
+               obr->mtface= MEM_callocN(sizeof(*obr->mtface)*numtf, "mtfacenames");
        }
 
        if (CustomData_has_layer(data, CD_MCOL)) {
-               numlayers= CustomData_number_of_layers(data, CD_MCOL);
-               obr->mcol= MEM_callocN(sizeof(*obr->mcol)*numlayers, "mcolnames");
+               numcol= CustomData_number_of_layers(data, CD_MCOL);
+               obr->mcol= MEM_callocN(sizeof(*obr->mcol)*numcol, "mcolnames");
        }
 
        for (i=0, mtfn=0, mcn=0; i < data->totlayer; i++) {
@@ -459,11 +483,12 @@ void RE_set_customdata_names(ObjectRen *obr, CustomData *data)
 
                if (layer->type == CD_MTFACE) {
                        strcpy(obr->mtface[mtfn++], layer->name);
-                       obr->actmtface= layer->active_rnd;
+                       obr->actmtface= CLAMPIS(layer->active_rnd, 0, numtf);
+                       obr->bakemtface= layer->active;
                }
                else if (layer->type == CD_MCOL) {
                        strcpy(obr->mcol[mcn++], layer->name);
-                       obr->actmcol= layer->active_rnd;
+                       obr->actmcol= CLAMPIS(layer->active_rnd, 0, numcol);
                }
        }
 }
@@ -516,7 +541,7 @@ float *RE_strandren_get_surfnor(ObjectRen *obr, StrandRen *strand, int verify)
        surfnor= obr->strandnodes[nr].surfnor;
        if(surfnor==NULL) {
                if(verify) 
-                       surfnor= obr->strandnodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor table");
+                       surfnor= obr->strandnodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor strand table");
                else
                        return NULL;
        }
@@ -536,7 +561,7 @@ float *RE_strandren_get_uv(ObjectRen *obr, StrandRen *strand, int n, char **name
                        float *uv= node->uv;
                        int size= (n+1)*256;
 
-                       node->uv= MEM_callocN(size*sizeof(float)*RE_UV_ELEMS, "Strand uv");
+                       node->uv= MEM_callocN(size*sizeof(float)*RE_UV_ELEMS, "strand uv table");
 
                        if(uv) {
                                size= node->totuv*256;
@@ -570,7 +595,7 @@ MCol *RE_strandren_get_mcol(ObjectRen *obr, StrandRen *strand, int n, char **nam
                        MCol *mcol= node->mcol;
                        int size= (n+1)*256;
 
-                       node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "Strand mcol");
+                       node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "strand mcol table");
 
                        if(mcol) {
                                size= node->totmcol*256;
@@ -599,13 +624,28 @@ float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand
        simplify= obr->strandnodes[nr].simplify;
        if(simplify==NULL) {
                if(verify) 
-                       simplify= obr->strandnodes[nr].simplify= MEM_callocN(256*RE_SIMPLIFY_ELEMS*sizeof(float), "simplify table");
+                       simplify= obr->strandnodes[nr].simplify= MEM_callocN(256*RE_SIMPLIFY_ELEMS*sizeof(float), "simplify strand table");
                else
                        return NULL;
        }
        return simplify + (strand->index & 255)*RE_SIMPLIFY_ELEMS;
 }
 
+int *RE_strandren_get_face(ObjectRen *obr, StrandRen *strand, int verify)
+{
+       int *face;
+       int nr= strand->index>>8;
+       
+       face= obr->strandnodes[nr].face;
+       if(face==NULL) {
+               if(verify) 
+                       face= obr->strandnodes[nr].face= MEM_callocN(256*RE_FACE_ELEMS*sizeof(int), "face strand table");
+               else
+                       return NULL;
+       }
+       return face + (strand->index & 255)*RE_FACE_ELEMS;
+}
+
 /* winspeed is exception, it is stored per instance */
 float *RE_strandren_get_winspeed(ObjectInstanceRen *obi, StrandRen *strand, int verify)
 {
@@ -616,7 +656,7 @@ float *RE_strandren_get_winspeed(ObjectInstanceRen *obi, StrandRen *strand, int
        if(winspeed==NULL) {
                if(verify) {
                        totvector= obi->obr->totvert + obi->obr->totstrand;
-                       winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed table");
+                       winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed strand table");
                }
                else
                        return NULL;
@@ -671,14 +711,14 @@ StrandBuffer *RE_addStrandBuffer(ObjectRen *obr, int totvert)
        strandbuf->totvert= totvert;
        strandbuf->obr= obr;
 
-       BLI_addtail(&obr->strandbufs, strandbuf);
+       obr->strandbuf= strandbuf;
 
        return strandbuf;
 }
 
 /* ------------------------------------------------------------------------ */
 
-ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex)
+ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex, int lay)
 {
        ObjectRen *obr= MEM_callocN(sizeof(ObjectRen), "object render struct");
        
@@ -687,11 +727,7 @@ ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, in
        obr->par= par;
        obr->index= index;
        obr->psysindex= psysindex;
-
-       if(!re->objecthash)
-               re->objecthash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
-       if(!BLI_ghash_lookup(re->objecthash, ob))
-               BLI_ghash_insert(re->objecthash, ob, obr);
+       obr->lay= lay;
 
        return obr;
 }
@@ -737,12 +773,16 @@ void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
                        MEM_freeN(vlaknodes[a].mcol);
                if(vlaknodes[a].surfnor)
                        MEM_freeN(vlaknodes[a].surfnor);
+               if(vlaknodes[a].tangent)
+                       MEM_freeN(vlaknodes[a].tangent);
+               if(vlaknodes[a].radface)
+                       MEM_freeN(vlaknodes[a].radface);
        }
        
        MEM_freeN(vlaknodes);
 }
 
-void free_renderdata_strandnodes(StrandTableNode *strandnodes)
+static void free_renderdata_strandnodes(StrandTableNode *strandnodes)
 {
        int a;
        
@@ -761,6 +801,8 @@ void free_renderdata_strandnodes(StrandTableNode *strandnodes)
                        MEM_freeN(strandnodes[a].surfnor);
                if(strandnodes[a].simplify)
                        MEM_freeN(strandnodes[a].simplify);
+               if(strandnodes[a].face)
+                       MEM_freeN(strandnodes[a].face);
        }
        
        MEM_freeN(strandnodes);
@@ -802,42 +844,56 @@ void free_renderdata_tables(Render *re)
                        obr->strandnodeslen= 0;
                }
 
-               for(strandbuf=obr->strandbufs.first; strandbuf; strandbuf=strandbuf->next)
+               strandbuf= obr->strandbuf;
+               if(strandbuf) {
                        if(strandbuf->vert) MEM_freeN(strandbuf->vert);
-               BLI_freelistN(&obr->strandbufs);
+                       if(strandbuf->bound) MEM_freeN(strandbuf->bound);
+                       MEM_freeN(strandbuf);
+               }
 
                if(obr->mtface)
                        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;
                re->instancetable.first= re->instancetable.last= NULL;
        }
 
-       if(re->objecthash) {
-               BLI_ghash_free(re->objecthash, NULL, NULL);
-               re->objecthash= NULL;
-       }
-
        if(re->sortedhalos) {
                MEM_freeN(re->sortedhalos);
                re->sortedhalos= NULL;
        }
 
-       if(re->strandbuckets) {
-               free_buckets(re->strandbuckets);
-               re->strandbuckets= NULL;
-       }
-
        BLI_freelistN(&re->customdata_names);
        BLI_freelistN(&re->objecttable);
        BLI_freelistN(&re->instancetable);
@@ -921,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;
@@ -949,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];
@@ -961,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) {
@@ -969,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;
@@ -980,9 +1037,11 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,   float *vec,   f
                                har->g= (yn*tg+ zn*ma->g);
                                har->b= (yn*tb+ zn*ma->b);
                        }
-                       if(mtex->texco & 16) {
+                       if(mtex->texco & TEXCO_UV) {
                                har->alfa= tin;
                        }
+                       if(mtex->mapto & MAP_ALPHA)
+                               har->alfa= tin;
                }
        }
 
@@ -990,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;
 
@@ -1032,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;
@@ -1070,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);
@@ -1095,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;
@@ -1120,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;
@@ -1171,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;
@@ -1255,13 +1322,11 @@ void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4],
                        
                }
        }
-
-       project_strands(re, projectfunc, do_pano, do_buckets);
 }
 
 /* ------------------------------------------------------------------------- */
 
-void RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4])
+ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4], int lay)
 {
        ObjectInstanceRen *obi;
        float mat3[3][3];
@@ -1272,15 +1337,19 @@ void RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, i
        obi->par= par;
        obi->index= index;
        obi->psysindex= psysindex;
+       obi->lay= lay;
 
        if(mat) {
-               Mat4CpyMat4(obi->mat, mat);
-               Mat3CpyMat4(mat3, mat);
-               Mat3Inv(obi->imat, mat3);
+               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;
        }
 
        BLI_addtail(&re->instancetable, obi);
+
+       return obi;
 }
 
 void RE_makeRenderInstances(Render *re)
@@ -1299,15 +1368,6 @@ void RE_makeRenderInstances(Render *re)
        for(oldobi=re->instancetable.first; oldobi; oldobi=oldobi->next) {
                *obi= *oldobi;
 
-               if(!obi->obr) {
-                       /* dupli objects are created after object instances, so they were
-                        * stored in a object -> objectren hash, we do lookup of the actual
-                        * pointer here */
-                       if(re->objecthash && (obi->obr=BLI_ghash_lookup(re->objecthash, obi->ob)))
-                               while(obi->obr && obi->obr->psysindex != obi->psysindex)
-                                       obi->obr= obi->obr->next;
-               }
-
                if(obi->obr) {
                        obi->prev= obi->next= NULL;
                        BLI_addtail(&newlist, obi);
@@ -1317,11 +1377,46 @@ void RE_makeRenderInstances(Render *re)
                        re->totinstance--;
        }
 
-       if(re->objecthash) {
-               BLI_ghash_free(re->objecthash, NULL, NULL);
-               re->objecthash= NULL;
-       }
        BLI_freelistN(&re->instancetable);
        re->instancetable= newlist;
 }
 
+int clip_render_object(float boundbox[][3], float *bounds, float winmat[][4])
+{
+       float mat[4][4], vec[4];
+       int a, fl, flag= -1;
+
+       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;
+               mul_m4_v4(mat, vec);
+
+               fl= 0;
+               if(bounds) {
+                       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;
+                       else if(vec[1]< bounds[2]*vec[3]) fl |= 8;
+               }
+               else {
+                       if(vec[0] < -vec[3]) fl |= 1;
+                       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;
+               else if(vec[2] > vec[3]) fl |= 32;
+
+               flag &= fl;
+               if(flag==0) return 0;
+       }
+
+       return flag;
+}
+