Render Baking
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 28 Nov 2007 22:21:12 +0000 (22:21 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 28 Nov 2007 22:21:12 +0000 (22:21 +0000)
=============

A new "Selected to Active" option in the Bake panel, to (typically) bake
a high poly object onto a low poly object. Code based on patch #7339 by
Frank Richter (Crystal Space developer), thanks!.

Normal Mapping
==============

Camera, World, Object and Tangent space is now supported for baking, and
for material textures. The "NMap TS" setting is replaced with a dropdown
of the four choices in the image texture buttons.

http://www.blender.org/development/current-projects/changes-since-244/render-baking/

23 files changed:
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/texture.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_texture_types.h
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/extern/include/RE_raytrace.h
source/blender/render/extern/include/RE_shader_ext.h
source/blender/render/intern/include/render_types.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/rayshade.c
source/blender/render/intern/source/raytrace.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/renderdatabase.c
source/blender/render/intern/source/shadeinput.c
source/blender/render/intern/source/texture.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_scene.c
source/blender/src/buttons_shading.c
source/blender/src/meshtools.c

index 5cd905d07ac7c8b74befef11ba63bb9e0958318c..075405b1097cf84abd3cf95ffbef9b135d9ee32d 100644 (file)
@@ -44,7 +44,7 @@ struct ListBase;
 struct MemFile;
 
 #define BLENDER_VERSION                        245
-#define BLENDER_SUBVERSION             8
+#define BLENDER_SUBVERSION             9
 
 #define BLENDER_MINVERSION             240
 #define BLENDER_MINSUBVERSION  0
index f410167c2ac2195d9eeaa829f20b3af86be2dee6..6248e01432eb0baefd6dab4eec456bbf531674a9 100644 (file)
@@ -296,7 +296,7 @@ static Render *fastshade_get_render(void)
        if(re==NULL) {
                re= RE_NewRender("_Shade View_");
        
-               RE_Database_Baking(re, G.scene, 0);     /* 0= no faces */
+               RE_Database_Baking(re, G.scene, 0, 0);  /* 0= no faces */
        }
        return re;
 }
index ed5fe58d06f98dbf75b680c73d83ab7529a830b4..0699e3b865516d055a26baec3677ca1a08d9ad1e 100644 (file)
@@ -629,7 +629,7 @@ void new_material_to_objectdata(Object *ob)
 static void do_init_render_material(Material *ma, int r_mode, float *amb)
 {
        MTex *mtex;
-       int a, needuv=0;
+       int a, needuv=0, needtang=0;
        
        if(ma->flarec==0) ma->flarec= 1;
 
@@ -653,8 +653,14 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb)
                        if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND|TEXCO_STRESS)) needuv= 1;
                        else if(ma->texco & (TEXCO_GLOB|TEXCO_UV|TEXCO_OBJECT|TEXCO_SPEED)) needuv= 1;
                        else if(ma->texco & (TEXCO_LAVECTOR|TEXCO_VIEW|TEXCO_STICKY)) needuv= 1;
+
+                       if((ma->mapto & MAP_NORM) && (mtex->normapspace == MTEX_NSPACE_TANGENT))
+                               needtang= 1;
                }
        }
+
+       if(needtang) ma->mode |= MA_NORMAP_TANG;
+       else ma->mode &= ~MA_NORMAP_TANG;
        
        if(r_mode & R_RADIO)
                if(ma->mode & MA_RADIO) needuv= 1;
index aa9c489044aa0f343dabfedb43a709ab413a3977..ff7b429845d4ea16425175cecd251492c72ecb72 100644 (file)
@@ -206,6 +206,7 @@ Scene *add_scene(char *name)
        sce->r.bake_filter= 2;
        sce->r.bake_osa= 5;
        sce->r.bake_flag= R_BAKE_CLEAR;
+       sce->r.bake_normal_space= R_BAKE_SPACE_TANGENT;
        
        sce->r.xplay= 640;
        sce->r.yplay= 480;
index baa6fae6fc8396728f0dbf52390816a5cca9b19e..d4a085ff8bd8e5a234b5459a7383dd8b7a596dfe 100644 (file)
@@ -517,6 +517,7 @@ void default_mtex(MTex *mtex)
        mtex->norfac= 0.5;
        mtex->varfac= 1.0;
        mtex->dispfac=0.2;
+       mtex->normapspace= MTEX_NSPACE_TANGENT;
 }
 
 
index ae6a2749269e9a0f8a81a961a4f4c455e2919d10..ff2a4edab9d224a527d12c807640276a1f646d29 100644 (file)
@@ -7170,6 +7170,16 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        }
                }
        }
+       if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 9)) {
+               Material *ma;
+               int a;
+
+               for(ma=main->mat.first; ma; ma= ma->id.next)
+                       if(ma->mode & MA_NORMAP_TANG)
+                               for(a=0; a<MAX_MTEX; a++)
+                                       if(ma->mtex[a] && ma->mtex[a]->tex)
+                                               ma->mtex[a]->normapspace = MTEX_NSPACE_TANGENT;
+       }
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
 
index 1a1cb1c0f2bc91541cd4b33e914bd942248a75c7..f9418d1fc85fa2eff139083c779a727f448ce7df 100644 (file)
@@ -265,6 +265,8 @@ typedef struct RenderData {
        
        /* Bake Render options */
        short bake_osa, bake_filter, bake_mode, bake_flag;
+       short bake_normal_space, bpad;
+       float bake_maxdist;
        
        /* yafray: global panel params. TODO: move elsewhere */
        short GIquality, GIcache, GImethod, GIphotons, GIdirect;
@@ -605,8 +607,15 @@ typedef struct Scene {
 
 /* bake_mode: same as RE_BAKE_xxx defines */
 /* bake_flag: */
-#define R_BAKE_CLEAR   1
-#define R_BAKE_OSA             2
+#define R_BAKE_CLEAR           1
+#define R_BAKE_OSA                     2
+#define R_BAKE_TO_ACTIVE       4
+
+/* bake_normal_space */
+#define R_BAKE_SPACE_CAMERA     0
+#define R_BAKE_SPACE_WORLD      1
+#define R_BAKE_SPACE_OBJECT     2
+#define R_BAKE_SPACE_TANGENT 3
 
 /* **************** SCENE ********************* */
 #define RAD_PHASE_PATCHES      1
index 2de6aba6b6fdaa213dd6bbe3f7af34595d966fc3..14ece2b31b293804d6148fe17db46df3b0f5cff2 100644 (file)
@@ -58,6 +58,7 @@ typedef struct MTex {
        float ofs[3], size[3];
        
        short texflag, colormodel, pmapto, pmaptoneg;
+       short normapspace, pad[3];
        float r, g, b, k;
        float def_var, rt;
        
@@ -157,7 +158,7 @@ typedef struct Tex {
        float cropxmin, cropymin, cropxmax, cropymax;
        short xrepeat, yrepeat;
        short extend;
-       
+
        /* variables disabled, moved to struct iuser */
        short fie_ima;
        int len;
@@ -319,6 +320,12 @@ typedef struct TexMapping {
 #define TEX_COL2               2
 #define TEX_COL3               3
 
+/* mtex->normapspace */
+#define MTEX_NSPACE_CAMERA     0
+#define MTEX_NSPACE_WORLD      1
+#define MTEX_NSPACE_OBJECT     2
+#define MTEX_NSPACE_TANGENT    3
+
 /* wrap */
 #define MTEX_FLAT              0
 #define MTEX_CUBE              1
index 9abc873172f03c957e097a90adf64c6cd9f3e2c4..a8abf85a28504abb00f50dacef4b69fdd5eb6776 100644 (file)
@@ -37,6 +37,7 @@
 struct Scene;
 struct RenderData;
 struct NodeBlurData;
+struct Object;
 
 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 /* this include is what is exposed of render to outside world */
@@ -209,7 +210,7 @@ void RE_zbuf_accumulate_vecblur(struct NodeBlurData *nbd, int xsize, int ysize,
 #define RE_BAKE_AO             2
 #define RE_BAKE_NORMALS        3
 #define RE_BAKE_TEXTURE        4
-void RE_Database_Baking(struct Render *re, struct Scene *scene, int type);
+void RE_Database_Baking(struct Render *re, struct Scene *scene, int type, struct Object *actob);
 
 void RE_DataBase_GetView(struct Render *re, float mat[][4]);
 
index 095ffcf0c18b920cab45215c626f0816e28b52c4..d20e3130fa4bdd95feb53cfafddc6d9ba3703147 100644 (file)
@@ -64,6 +64,9 @@ typedef struct Isect {
        RayFace *facecontr;
        float ddalabda;
        short faceisect;                /* flag if facecontr was done or not */
+
+       /* custom pointer to be used in the RayCheckFunc */
+       void *userdata;
 } Isect;
 
 /* function callbacks for face type abstraction */
@@ -80,6 +83,7 @@ void RE_ray_tree_free(RayTree *tree);
 
 /* intersection with full tree and single face */
 int RE_ray_tree_intersect(RayTree *tree, Isect *is);
+int RE_ray_tree_intersect_check(RayTree *tree, Isect *is, RayCheckFunc check);
 int RE_ray_face_intersection(Isect *is, RayCoordsFunc coordsfunc);
 
 /* retrieve the diameter of the tree structure, for setting intersection
index 052e104ee62ac16fc55d1d5beedaf34cdb576323..7717d6fdc4838a3aee9ba1edbb1e3756091cbe54 100644 (file)
@@ -173,9 +173,10 @@ int        multitex_ext(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osa
 /* shaded view and bake */
 struct Render;
 struct Image;
+struct Object;
 
 void RE_shade_external(struct Render *re, struct ShadeInput *shi, struct ShadeResult *shr);
-int RE_bake_shade_all_selected(struct Render *re, int type);
+int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob);
 struct Image *RE_bake_shade_get_image(void);
 
 #endif /* RE_SHADER_EXT_H */
index abcdf417b62a01ebd0967f94d57216179e16b539..c20d27bfcdca157f5cd534500f808f3078fb7bf5 100644 (file)
@@ -181,6 +181,8 @@ struct Render
 
        ListBase customdata_names;
 
+       struct Object *excludeob;
+
        /* arena for allocating data for use during render, for
                * example dynamic TFaces to go in the VlakRen structure.
                */
@@ -394,6 +396,7 @@ typedef struct LampRen {
 #define R_SEC_FIELD            4
 #define R_LAMPHALO             8
 #define R_GLOB_NOPUNOFLIP      16
+#define R_NEED_TANGENT 32
 
 /* vlakren->flag (vlak = face in dutch) char!!! */
 #define R_SMOOTH               1
index dd593d9edcc4e052d4806d56d4fd1a39192f91af..f64ff1501cb46ed88780c0e5a952765929ce07f1 100644 (file)
@@ -447,14 +447,39 @@ static void calc_edge_stress(Render *re, Mesh *me, int startvert, int startvlak)
        MEM_freeN(accum);
 }
 
+void tangent_from_uv(float *uv1, float *uv2, float *uv3, float *co1, float *co2, float *co3, float *n, float *tang)
+{
+       float tangv[3], ct[3], e1[3], e2[3], s1, t1, s2, t2, det;
+
+       s1= uv2[0] - uv1[0];
+       s2= uv3[0] - uv1[0];
+       t1= uv2[1] - uv1[1];
+       t2= uv3[1] - uv1[1];
+       det= 1.0f / (s1 * t2 - s2 * t1);
+       
+       /* normals in render are inversed... */
+       VecSubf(e1, co1, co2);
+       VecSubf(e2, co1, co3);
+       tang[0] = (t2*e1[0] - t1*e2[0])*det;
+       tang[1] = (t2*e1[1] - t1*e2[1])*det;
+       tang[2] = (t2*e1[2] - t1*e2[2])*det;
+       tangv[0] = (s1*e2[0] - s2*e1[0])*det;
+       tangv[1] = (s1*e2[1] - s2*e1[1])*det;
+       tangv[2] = (s1*e2[2] - s2*e1[2])*det;
+       Crossf(ct, tang, tangv);
+
+       /* check flip */
+       if ((ct[0]*n[0] + ct[1]*n[1] + ct[2]*n[2]) < 0.0f)
+               VecMulf(tang, -1.0f);
+}
+
 /* gets tangent from tface or orco */
 static void calc_tangent_vector(Render *re, VlakRen *vlr)
 {
        MTFace *tface= RE_vlakren_get_tface(re, vlr, 0, NULL, 0);
        VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4;
-       float tang[3], tangv[3], ct[3], e1[3], e2[3], *tav;
+       float tang[3], *tav;
        float *uv1, *uv2, *uv3, *uv4;
-       float s1, s2, t1, t2, det;
        float uv[4][2];
        
        if(tface) {
@@ -472,26 +497,8 @@ static void calc_tangent_vector(Render *re, VlakRen *vlr)
                        spheremap(v4->orco[0], v4->orco[1], v4->orco[2], &uv[3][0], &uv[3][1]);
        }
        else return;
-       
-       s1= uv2[0] - uv1[0];
-       s2= uv3[0] - uv1[0];
-       t1= uv2[1] - uv1[1];
-       t2= uv3[1] - uv1[1];
-       det= 1.0f / (s1 * t2 - s2 * t1);
-       
-       /* normals in render are inversed... */
-       VecSubf(e1, v1->co, v2->co);
-       VecSubf(e2, v1->co, v3->co);
-       tang[0] = (t2*e1[0] - t1*e2[0])*det;
-       tang[1] = (t2*e1[1] - t1*e2[1])*det;
-       tang[2] = (t2*e1[2] - t1*e2[2])*det;
-       tangv[0] = (s1*e2[0] - s2*e1[0])*det;
-       tangv[1] = (s1*e2[1] - s2*e1[1])*det;
-       tangv[2] = (s1*e2[2] - s2*e1[2])*det;
-       Crossf(ct, tang, tangv);
-       /* check flip */
-       if ((ct[0]*vlr->n[0] + ct[1]*vlr->n[1] + ct[2]*vlr->n[2]) < 0.f)
-               VecMulf(tang, -1.f);
+
+       tangent_from_uv(uv1, uv2, uv3, v1->co, v2->co, v3->co, vlr->n, tang);
        
        tav= RE_vertren_get_tangent(re, v1, 1);
        VECADD(tav, tav, tang);
@@ -501,24 +508,7 @@ static void calc_tangent_vector(Render *re, VlakRen *vlr)
        VECADD(tav, tav, tang);
        
        if(v4) {
-               s1= uv3[0] - uv1[0];
-               s2= uv4[0] - uv1[0];
-               t1= uv3[1] - uv1[1];
-               t2= uv4[1] - uv1[1];
-               det= 1.0f / (s1 * t2 - s2 * t1);
-               
-               /* normals in render are inversed... */
-               VecSubf(e1, v1->co, v3->co);
-               VecSubf(e2, v1->co, v4->co);
-               tang[0] = (t2*e1[0] - t1*e2[0])*det;
-               tang[1] = (t2*e1[1] - t1*e2[1])*det;
-               tang[2] = (t2*e1[2] - t1*e2[2])*det;
-               tangv[0] = (s1*e2[0] - s2*e1[0])*det;
-               tangv[1] = (s1*e2[1] - s2*e1[1])*det;
-               tangv[2] = (s1*e2[2] - s2*e1[2])*det;
-               Crossf(ct, tang, tangv);
-               if ((ct[0]*vlr->n[0] + ct[1]*vlr->n[1] + ct[2]*vlr->n[2]) < 0.f)
-                       VecMulf(tang, -1.f);
+               tangent_from_uv(uv1, uv3, uv4, v1->co, v3->co, v4->co, vlr->n, tang);
                
                tav= RE_vertren_get_tangent(re, v1, 1);
                VECADD(tav, tav, tang);
@@ -2627,6 +2617,13 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
                                        do_autosmooth= 1;
                }
        }
+
+       if(re->flag & R_NEED_TANGENT) {
+               /* exception for tangent space baking */
+               need_tangent= 1;
+               if(me->mtface==NULL)
+                       need_orco= 1;
+       }
        
        /* check autosmooth and displacement, we then have to skip only-verts optimize */
        do_autosmooth |= (me->flag & ME_AUTOSMOOTH);
@@ -4781,7 +4778,7 @@ void RE_DataBase_ApplyWindow(Render *re)
    RE_BAKE_AO:     for baking, no lamps, but all objects
    RE_BAKE_TEXTURE:for baking, no lamps, only selected objects
 */
-void RE_Database_Baking(Render *re, Scene *scene, int type)
+void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob)
 {
        Base *base;
        Object *ob;
@@ -4795,8 +4792,12 @@ void RE_Database_Baking(Render *re, Scene *scene, int type)
        re->r= scene->r;
        re->r.mode &= ~R_OSA;
        re->flag |= R_GLOB_NOPUNOFLIP;
+       re->excludeob= actob;
+
+       if(type==RE_BAKE_NORMALS && re->r.bake_normal_space==R_BAKE_SPACE_TANGENT)
+               re->flag |= R_NEED_TANGENT;
        
-       if( ELEM3(type, RE_BAKE_LIGHT, RE_BAKE_NORMALS, RE_BAKE_TEXTURE) ) {
+       if(!actob && ELEM3(type, RE_BAKE_LIGHT, RE_BAKE_NORMALS, RE_BAKE_TEXTURE)) {
                re->r.mode &= ~R_SHADOW;
                re->r.mode &= ~R_RAYTRACE;
        }
@@ -4887,7 +4888,7 @@ void RE_Database_Baking(Render *re, Scene *scene, int type)
                                                init_render_object(re, ob, NULL, 0, 0);
                                }
                                else if(type!=RE_BAKE_LIGHT) {
-                                       if( !ELEM(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE) || (ob->flag & SELECT))
+                                       if( !ELEM(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE) || (ob->flag & SELECT) || (ob == actob) )
                                                init_render_object(re, ob, NULL, 0, 0);
                                }
                        }
@@ -4915,14 +4916,10 @@ void RE_Database_Baking(Render *re, Scene *scene, int type)
                }
        }
 
-       if(type!=RE_BAKE_LIGHT) {
-               /* raytree */
-               if(!re->test_break()) {
-                       if(re->r.mode & R_RAYTRACE) {
-                               makeraytree(re);
-                       }
-               }
-       }
+       /* raytree */
+       if(!re->test_break())
+               if(re->r.mode & R_RAYTRACE)
+                       makeraytree(re);
 }
 
 void RE_DataBase_GetView(Render *re, float mat[][4])
index e7345c106a63d6aa6941f74c8cc09e56a1350ef6..5141841e157ee706acbef605317012e161a7e58f 100644 (file)
@@ -111,15 +111,16 @@ void makeraytree(Render *re)
                else vlr++;
                if(vlr->mat->mode & MA_TRACEBLE) {      
                        if((vlr->mat->mode & MA_WIRE)==0) {     
-                               
-                               DO_MINMAX(vlr->v1->co, min, max);
-                               DO_MINMAX(vlr->v2->co, min, max);
-                               DO_MINMAX(vlr->v3->co, min, max);
-                               if(vlr->v4) {
-                                       DO_MINMAX(vlr->v4->co, min, max);
-                               }
+                               if(!re->excludeob || vlr->ob != re->excludeob) {
+                                       DO_MINMAX(vlr->v1->co, min, max);
+                                       DO_MINMAX(vlr->v2->co, min, max);
+                                       DO_MINMAX(vlr->v3->co, min, max);
+                                       if(vlr->v4) {
+                                               DO_MINMAX(vlr->v4->co, min, max);
+                                       }
 
-                               totface++;
+                                       totface++;
+                               }
                        }
                }
        }
@@ -149,11 +150,10 @@ void makeraytree(Render *re)
                }
                else vlr++;
                
-               if(vlr->mat->mode & MA_TRACEBLE) {
-                       if((vlr->mat->mode & MA_WIRE)==0) {     
-                               RE_ray_tree_add_face(re->raytree, (RayFace*)vlr);
-                       }
-               }
+               if(vlr->mat->mode & MA_TRACEBLE)
+                       if((vlr->mat->mode & MA_WIRE)==0)
+                               if(!re->excludeob || vlr->ob != re->excludeob)
+                                       RE_ray_tree_add_face(re->raytree, (RayFace*)vlr);
        }
 
        RE_ray_tree_done(re->raytree);
index f86032b5d686380f6bd7dad83ef34dc8d80c4b68..002148ed97c84ff7b7c90e6a8e538e8df9f443c1 100644 (file)
@@ -902,7 +902,7 @@ int RE_ray_face_intersection(Isect *is, RayCoordsFunc coordsfunc)
 }
 
 /* check all faces in this node */
-static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval)
+static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval, RayCheckFunc checkfunc)
 {
        RayFace *face;
        short nr=0;
@@ -916,7 +916,7 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval)
                
                        if(is->faceorig != face) {
 
-                               if(oc->checkfunc(is, face)) {
+                               if(checkfunc(is, face)) {
                                        
                                        ov= no->ov+nr;
                                        if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { 
@@ -952,7 +952,7 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval)
                while(face) {
 
                        if(is->faceorig != face) {
-                               if(oc->checkfunc(is, face)) {
+                               if(checkfunc(is, face)) {
                                        ov= no->ov+nr;
                                        if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { 
                                                //accepted++;
@@ -1097,9 +1097,16 @@ static int do_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, i
 
 */
 
+int RE_ray_tree_intersect(RayTree *tree, Isect *is)
+{
+       Octree *oc= (Octree*)tree;
+
+       return RE_ray_tree_intersect_check(tree, is, oc->checkfunc);
+}
+
 /* return 1: found valid intersection */
 /* starts with is->faceorig */
-int RE_ray_tree_intersect(RayTree *tree, Isect *is)    
+int RE_ray_tree_intersect_check(RayTree *tree, Isect *is, RayCheckFunc checkfunc)
 {
        Octree *oc= (Octree*)tree;
        Node *no;
@@ -1123,7 +1130,7 @@ int RE_ray_tree_intersect(RayTree *tree, Isect *is)
        
                /* check with last intersected shadow face */
                if(is->face_last!=NULL && is->face_last!=is->faceorig) {
-                       if(oc->checkfunc(is, is->face_last)) {
+                       if(checkfunc(is, is->face_last)) {
                                is->face= is->face_last;
                                VECSUB(is->vec, is->end, is->start);
                                if(RE_ray_face_intersection(is, oc->coordsfunc)) return 1;
@@ -1193,7 +1200,7 @@ int RE_ray_tree_intersect(RayTree *tree, Isect *is)
                        vec2[0]= ox2; vec2[1]= oy2; vec2[2]= oz2;
                        calc_ocval_ray(&ocval, (float)ocx1, (float)ocy1, (float)ocz1, vec1, vec2);
                        is->ddalabda= 1.0f;
-                       if( testnode(oc, is, no, ocval) ) return 1;
+                       if( testnode(oc, is, no, ocval, checkfunc) ) return 1;
                }
        }
        else {
@@ -1272,7 +1279,7 @@ int RE_ray_tree_intersect(RayTree *tree, Isect *is)
                                calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2);
                                                           
                                is->ddalabda= ddalabda;
-                               if( testnode(oc, is, no, ocval) ) return 1;
+                               if( testnode(oc, is, no, ocval, checkfunc) ) return 1;
                        }
 
                        labdao= ddalabda;
index 0f91a92fe9c1c7f37a3c6d55d3cdba5819dd9342..636bee32e052ef46baeddb7d2248c5e2e6bf8bc6 100644 (file)
@@ -66,6 +66,7 @@
 #include "shading.h"
 #include "sss.h"
 #include "zbuf.h"
+#include "RE_raytrace.h"
 
 #include "PIL_time.h"
 
@@ -1657,43 +1658,35 @@ typedef struct BakeShade {
        ImBuf *ibuf;
        
        int rectx, recty, quad, type, vdone, ready;
+
+       float dir[3];
+       Object *actob;
        
        unsigned int *rect;
        float *rect_float;
 } BakeShade;
 
-static void do_bake_shade(void *handle, int x, int y, float u, float v)
+static void bake_set_shade_input(VlakRen *vlr, ShadeInput *shi, int quad, int isect, int x, int y, float u, float v)
 {
-       BakeShade *bs= handle;
-       ShadeSample *ssamp= &bs->ssamp;
-       ShadeInput *shi= ssamp->shi;
-       ShadeResult shr;
-       VlakRen *vlr= bs->vlr;
-       float l, *v1, *v2, *v3;
-       
-       /* fast threadsafe break test */
-       if(R.test_break())
-               return;
-       
-       /* setup render coordinates */
-       if(bs->quad) {
-               v1= vlr->v1->co;
-               v2= vlr->v3->co;
-               v3= vlr->v4->co;
+       if(isect) {
+               /* raytrace intersection with different u,v than scanconvert */
+               if(vlr->v4) {
+                       if(quad)
+                               shade_input_set_triangle_i(shi, vlr, 2, 1, 3);
+                       else
+                               shade_input_set_triangle_i(shi, vlr, 0, 1, 3);
+               }
+               else
+                       shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
        }
        else {
-               v1= vlr->v1->co;
-               v2= vlr->v2->co;
-               v3= vlr->v3->co;
+               /* regular scanconvert */
+               if(quad) 
+                       shade_input_set_triangle_i(shi, vlr, 0, 2, 3);
+               else
+                       shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
        }
-       
-       /* renderco */
-       l= 1.0f-u-v;
-       
-       shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0];
-       shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
-       shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
-       
+               
        /* set up view vector */
        VECCOPY(shi->view, shi->co);
        Normalize(shi->view);
@@ -1704,18 +1697,20 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
        /* cache for shadow */
        shi->samplenr++;
        
-       if(bs->quad) 
-               shade_input_set_triangle_i(shi, vlr, 0, 2, 3);
-       else
-               shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
-       
        shi->u= -u;
        shi->v= -v;
        shi->xs= x;
        shi->ys= y;
        
        shade_input_set_normals(shi);
+}
 
+static void bake_shade(void *handle, Object *ob, VlakRen *vlr, ShadeInput *shi, int quad, int x, int y, float u, float v, float *tvn, float *ttang)
+{
+       BakeShade *bs= handle;
+       ShadeSample *ssamp= &bs->ssamp;
+       ShadeResult shr;
+       
        /* init material vars */
        memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));        // note, keep this synced with render_types.h
        shi->har= shi->mat->har;
@@ -1725,7 +1720,6 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
                ambient_occlusion_to_diffuse(shi, shr.combined);
        }
        else {
-               
                shade_input_set_shade_texco(shi);
                
                shade_samples_do_AO(ssamp);
@@ -1738,9 +1732,39 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
                        shade_material_loop(shi, &shr);
                
                if(bs->type==RE_BAKE_NORMALS) {
-                       shr.combined[0]= shi->vn[0]/2.0f + 0.5f;
-                       shr.combined[1]= 0.5f - shi->vn[1]/2.0f;
-                       shr.combined[2]= shi->vn[2]/2.0f + 0.5f;
+                       float nor[3];
+
+                       VECCOPY(nor, shi->vn);
+
+                       if(R.r.bake_normal_space == R_BAKE_SPACE_CAMERA);
+                       else if(R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) {
+                               float mat[3][3], imat[3][3];
+
+                               /* bitangent */
+                               if(tvn && ttang) {
+                                       VECCOPY(mat[0], ttang);
+                                       Crossf(mat[1], tvn, ttang);
+                                       VECCOPY(mat[2], tvn);
+                               }
+                               else {
+                                       VECCOPY(mat[0], shi->tang);
+                                       Crossf(mat[1], shi->vn, shi->tang);
+                                       VECCOPY(mat[2], shi->vn);
+                               }
+
+                               Mat3Inv(imat, mat);
+                               Mat3MulVecfl(imat, nor);
+                       }
+                       else if(R.r.bake_normal_space == R_BAKE_SPACE_OBJECT)
+                               Mat4Mul3Vecfl(ob->imat, nor); /* ob->imat includes viewinv! */
+                       else if(R.r.bake_normal_space == R_BAKE_SPACE_WORLD)
+                               Mat4Mul3Vecfl(R.viewinv, nor);
+
+                       Normalize(nor); /* in case object has scaling */
+
+                       shr.combined[0]= nor[0]/2.0f + 0.5f;
+                       shr.combined[1]= 0.5f - nor[1]/2.0f;
+                       shr.combined[2]= nor[2]/2.0f + 0.5f;
                }
                else if(bs->type==RE_BAKE_TEXTURE) {
                        shr.combined[0]= shi->r;
@@ -1763,6 +1787,131 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
        }
 }
 
+static int bake_check_intersect(Isect *is, RayFace *face)
+{
+       VlakRen *vlr = (VlakRen*)face;
+       BakeShade *bs = (BakeShade*)is->userdata;
+       
+       /* no direction checking for now, doesn't always improve the result
+        * (INPR(vlr->n, bs->dir) > 0.0f); */
+
+       return (vlr->ob != bs->actob);
+}
+
+static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *dir, float sign, float *hitco)
+{
+       float maxdist;
+       int hit;
+
+       /* might be useful to make a user setting for maxsize*/
+       if(R.r.bake_maxdist > 0.0f)
+               maxdist= R.r.bake_maxdist;
+       else
+               maxdist= RE_ray_tree_max_size(R.raytree);
+
+       isect->end[0] = isect->start[0] + dir[0]*maxdist*sign;
+       isect->end[1] = isect->start[1] + dir[1]*maxdist*sign;
+       isect->end[2] = isect->start[2] + dir[2]*maxdist*sign;
+
+       hit = RE_ray_tree_intersect_check(R.raytree, isect, bake_check_intersect);
+       if(hit) {
+               hitco[0] = isect->start[0] + isect->labda*isect->vec[0];
+               hitco[1] = isect->start[1] + isect->labda*isect->vec[1];
+               hitco[2] = isect->start[2] + isect->labda*isect->vec[2];
+       }
+
+       return hit;
+}
+
+static void do_bake_shade(void *handle, int x, int y, float u, float v)
+{
+       BakeShade *bs= handle;
+       VlakRen *vlr= bs->vlr;
+       Object *ob= vlr->ob;
+       float l, *v1, *v2, *v3, tvn[3], ttang[3];
+       int quad;
+       ShadeSample *ssamp= &bs->ssamp;
+       ShadeInput *shi= ssamp->shi;
+       
+       /* fast threadsafe break test */
+       if(R.test_break())
+               return;
+       
+       /* setup render coordinates */
+       if(bs->quad) {
+               v1= vlr->v1->co;
+               v2= vlr->v3->co;
+               v3= vlr->v4->co;
+       }
+       else {
+               v1= vlr->v1->co;
+               v2= vlr->v2->co;
+               v3= vlr->v3->co;
+       }
+       
+       /* renderco */
+       l= 1.0f-u-v;
+       
+       shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0];
+       shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
+       shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
+       
+       quad= bs->quad;
+       bake_set_shade_input(vlr, shi, quad, 0, x, y, u, v);
+
+       if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) {
+               shade_input_set_shade_texco(shi);
+               VECCOPY(tvn, shi->vn);
+               VECCOPY(ttang, shi->tang);
+       }
+
+       /* if we are doing selected to active baking, find point on other face */
+       if(bs->actob) {
+               Isect isec, minisec;
+               float co[3], minco[3];
+               int hit, sign;
+               
+               /* intersect with ray going forward and backward*/
+               hit= 0;
+               memset(&minisec, 0, sizeof(minisec));
+               minco[0]= minco[1]= minco[2]= 0.0f;
+
+               VECCOPY(bs->dir, shi->vn);
+
+               for(sign=-1; sign<=1; sign+=2) {
+                       memset(&isec, 0, sizeof(isec));
+                       VECCOPY(isec.start, shi->co);
+                       isec.mode= RE_RAY_MIRROR;
+                       isec.faceorig= (RayFace*)vlr;
+                       isec.userdata= bs;
+
+                       if(bake_intersect_tree(R.raytree, &isec, shi->vn, sign, co)) {
+                               if(!hit || VecLenf(shi->co, co) < VecLenf(shi->co, minco)) {
+                                       minisec= isec;
+                                       VECCOPY(minco, co);
+                                       hit= 1;
+                               }
+                       }
+               }
+
+               /* if hit, we shade from the new point, otherwise from point one starting face */
+               if(hit) {
+                       vlr= (VlakRen*)minisec.face;
+                       quad= (minisec.isect == 2);
+                       VECCOPY(shi->co, minco);
+
+                       u= -minisec.u;
+                       v= -minisec.v;
+                       bake_set_shade_input(vlr, shi, quad, 1, x, y, u, v);
+               }
+       }
+
+       if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT)
+               bake_shade(handle, ob, vlr, shi, quad, x, y, u, v, tvn, ttang);
+       else
+               bake_shade(handle, ob, vlr, shi, quad, x, y, u, v, 0, 0);
+}
+
 static int get_next_bake_face(BakeShade *bs)
 {
        VlakRen *vlr;
@@ -1780,7 +1929,7 @@ static int get_next_bake_face(BakeShade *bs)
        for(; v<R.totvlak; v++) {
                vlr= RE_findOrAddVlak(&R, v);
                
-               if(vlr->ob->flag & SELECT) {
+               if((bs->actob && bs->actob == vlr->ob) || (!bs->actob && (vlr->ob->flag & SELECT))) {
                        tface= RE_vlakren_get_tface(&R, vlr, 0, NULL, 0);
 
                        if(tface && tface->tpage) {
@@ -1887,7 +2036,7 @@ static void *do_bake_thread(void *bs_v)
 /* using object selection tags, the faces with UV maps get baked */
 /* render should have been setup */
 /* returns 0 if nothing was handled */
-int RE_bake_shade_all_selected(Render *re, int type)
+int RE_bake_shade_all_selected(Render *re, int type, Object *actob)
 {
        BakeShade handles[BLENDER_MAX_THREADS];
        ListBase threads;
@@ -1919,6 +2068,7 @@ int RE_bake_shade_all_selected(Render *re, int type)
                handles[a].ssamp.tot= 1;
                
                handles[a].type= type;
+               handles[a].actob= actob;
                handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake");
                
                BLI_insert_thread(&threads, &handles[a]);
index 9dc337c1dc4dfa5cc02841a4e817020b2645a3be..6939e70a71bc181cc305c6e2dbbe64c4feedee6f 100644 (file)
@@ -1018,13 +1018,16 @@ void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4],
                if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak;
                else vlr++;
 
+               if(!re->excludeob || vlr->ob != re->excludeob) {
                        vlr->flag |= R_VISIBLE;
                        if(vlr->v4) {
                                if(vlr->v1->clip & vlr->v2->clip & vlr->v3->clip & vlr->v4->clip) vlr->flag &= ~R_VISIBLE;
                        }
                        else if(vlr->v1->clip & vlr->v2->clip & vlr->v3->clip) vlr->flag &= ~R_VISIBLE;
-
                }
+               else
+                       vlr->flag &= ~R_VISIBLE;
+       }
 
 }
 
index 71b59f7b8bebe9e3920ca93341faa84488cbf9e7..52a65b198249efb35e3c659401390ff318a95a7e 100644 (file)
@@ -538,9 +538,9 @@ void shade_input_set_shade_texco(ShadeInput *shi)
                }
                
                /* qdn: normalmap tangent space */
-               if (mode & (MA_TANGENT_V|MA_NORMAP_TANG)) {
+               if (mode & (MA_TANGENT_V|MA_NORMAP_TANG) || R.flag & R_NEED_TANGENT) {
                        float *s1, *s2, *s3;
-                       
+
                        s1= RE_vertren_get_tangent(&R, v1, 0);
                        s2= RE_vertren_get_tangent(&R, v2, 0);
                        s3= RE_vertren_get_tangent(&R, v3, 0);
@@ -556,7 +556,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
        }
        else {
                /* qdn: normalmap tangent space */
-               if (mode & (MA_TANGENT_V|MA_NORMAP_TANG)) {
+               if (mode & (MA_TANGENT_V|MA_NORMAP_TANG) || R.flag & R_NEED_TANGENT) {
                        /* qdn: flat faces have tangents too,
                           could pick either one, using average here */
                        float *s1 = RE_vertren_get_tangent(&R, v1, 0);
@@ -568,6 +568,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
                                shi->tang[2] = (s1[2] + s2[2] + s3[2]);
                                Normalize(shi->tang);
                        }
+                       else shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
                }
        }
        
index 7930fc97f2dd981ebc5057e4a0f084a712e238f6..accd39170e4db13ec5f0b08af036bd7a134d6434 100644 (file)
@@ -1706,7 +1706,6 @@ void do_material_tex(ShadeInput *shi)
                        }
                        if( (mtex->mapto & MAP_NORM) ) {
                                if(texres.nor) {
-                                       
                                        if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac;
                                        else tex->norfac= mtex->norfac;
                                        
@@ -1723,7 +1722,7 @@ void do_material_tex(ShadeInput *shi)
                                                fact = Tnor*tex->norfac;
                                                if (fact>1.f) fact = 1.f;
                                                facm = 1.f-fact;
-                                               if (shi->mat->mode & MA_NORMAP_TANG) {
+                                               if(mtex->normapspace == MTEX_NSPACE_TANGENT) {
                                                        /* qdn: tangent space */
                                                        float B[3], tv[3];
                                                        Crossf(B, shi->vn, shi->tang);  /* bitangent */
@@ -1736,10 +1735,26 @@ void do_material_tex(ShadeInput *shi)
                                                        shi->vn[2]= facm*shi->vn[2] + fact*tv[2];
                                                }
                                                else {
+                                                       float nor[3];
+
+                                                       VECCOPY(nor, texres.nor);
+
+                                                       if(mtex->normapspace == MTEX_NSPACE_CAMERA);
+                                                       else if(mtex->normapspace == MTEX_NSPACE_WORLD) {
+                                                               Mat4Mul3Vecfl(R.viewmat, nor);
+                                                       }
+                                                       else if(mtex->normapspace == MTEX_NSPACE_OBJECT) {
+                                                               if(shi->vlr && shi->vlr->ob)
+                                                                       Mat4Mul3Vecfl(shi->vlr->ob->obmat, nor);
+                                                               Mat4Mul3Vecfl(R.viewmat, nor);
+                                                       }
+
+                                                       Normalize(nor);
+
                                                        /* qdn: worldspace */
-                                                       shi->vn[0]= facm*shi->vn[0] + fact*texres.nor[0];
-                                                       shi->vn[1]= facm*shi->vn[1] + fact*texres.nor[1];
-                                                       shi->vn[2]= facm*shi->vn[2] + fact*texres.nor[2];
+                                                       shi->vn[0]= facm*shi->vn[0] + fact*nor[0];
+                                                       shi->vn[1]= facm*shi->vn[1] + fact*nor[1];
+                                                       shi->vn[2]= facm*shi->vn[2] + fact*nor[2];
                                                }
                                        }
                                        else {
index 7dfd6a956cd4d2ccfd2029efd3883f4b114dcfcd..3855ae7de7d6a0cdbf76aaee0d28df05a4ab0336 100644 (file)
@@ -1928,7 +1928,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
                                  "Material value that gives no displacement");
                        uiDefButF(block, NUM, B_MODIFIER_RECALC, "Strength:",
                                  lx, (cy -= 19), buttonWidth, 19, &dmd->strength,
-                                 -1000, 1000, 10, 10,
+                                 -1000, 1000, 10, 0.1,
                                  "Strength of displacement");
                        sprintf(str, "Direction%%t|Normal%%x%d|RGB -> XYZ%%x%d|"
                                "Z%%x%d|Y%%x%d|X%%x%d",
index 2cc24c643cb3eba54b51752ec7ffda5a56587195..9da6cff138706756a4f2c73db0f2cc941a799ca1 100644 (file)
@@ -1246,6 +1246,16 @@ static void render_panel_bake(void)
        
        but= uiDefBut(block, BUT, B_NOP, "BAKE",        10, 150, 190,40, 0, 0, 0, 0, 0, "Start the bake render for selected Objects");
        uiButSetFunc(but, do_bake_func, NULL, NULL);
+
+       uiBlockBeginAlign(block);
+       uiDefButBitS(block, TOG, R_BAKE_TO_ACTIVE, B_DIFF, "Selected to Active", 10,120,190,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Bake shading on the surface of selected objects to the active object");
+       uiDefButF(block, NUM, B_DIFF, "Dist:", 10,100,(G.scene->r.bake_mode == RE_BAKE_NORMALS)? 95: 190,20,&G.scene->r.bake_maxdist, 0.0, 10.0, 1, 0, "Maximum distance from active object to other object");
+
+       if(G.scene->r.bake_mode == RE_BAKE_NORMALS)
+               uiDefButS(block, MENU, B_DIFF, "Normal Space %t|Camera %x0|World %x1|Object %x2|Tangent %x3", 
+                       105,100,95,20, &G.scene->r.bake_normal_space, 0, 0, 0, 0, "Choose normal space for baking");
+       uiBlockEndAlign(block);
+
 #if 0  
        uiBlockBeginAlign(block);
        uiDefButBitS(block, TOG, R_BAKE_OSA, B_DIFF, "OSA",             10,120,190,20, &G.scene->r.bake_flag, 0, 0, 0, 0, "Enables Oversampling (Anti-aliasing)");
@@ -1255,10 +1265,10 @@ static void render_panel_bake(void)
        uiDefButS(block, ROW,B_DIFF,"16",                       150,100,50,20,&G.scene->r.bake_osa,2.0,16.0, 0, 0, "Sets oversample level to 16");
 #endif 
        uiBlockBeginAlign(block);
-       uiDefButS(block, ROW,B_DIFF,"Full Render",              210,170,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_ALL, 0, 0, "");
-       uiDefButS(block, ROW,B_DIFF,"Ambient Occlusion",210,150,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_AO, 0, 0, "");
-       uiDefButS(block, ROW,B_DIFF,"Normals",          210,130,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_NORMALS, 0, 0, "");
-       uiDefButS(block, ROW,B_DIFF,"Textures",         210,110,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_TEXTURE, 0, 0, "");
+       uiDefButS(block, ROW,B_REDR,"Full Render",              210,170,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_ALL, 0, 0, "");
+       uiDefButS(block, ROW,B_REDR,"Ambient Occlusion",210,150,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_AO, 0, 0, "");
+       uiDefButS(block, ROW,B_REDR,"Normals",          210,130,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_NORMALS, 0, 0, "");
+       uiDefButS(block, ROW,B_REDR,"Textures",         210,110,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_TEXTURE, 0, 0, "");
        uiBlockEndAlign(block);
        
        uiDefButBitS(block, TOG, R_BAKE_CLEAR, B_DIFF, "Clear",         210,80,120,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Clear Images before baking");
index 03fce824f7f08573fa5dacff1ba0cf0665f7668a..f21272f53da66d1c038884b007828f10db916e44 100644 (file)
@@ -1227,7 +1227,7 @@ static void texture_panel_image(Image **ima, ImageUser *iuser)
        uiblock_image_panel(block, ima, iuser, B_REDR, B_IMAGECHANGED);
 }      
 
-static void texture_panel_image_map(Tex *tex)
+static void texture_panel_image_map(Tex *tex, MTex *mtex)
 {
        uiBlock *block;
        
@@ -1249,8 +1249,13 @@ static void texture_panel_image_map(Tex *tex)
 
        uiDefButF(block, NUM, B_TEXPRV, "Filter :",                                             10,120,150,20, &tex->filtersize, 0.1, 25.0, 10, 3, "Sets the filter size used by mipmap and interpol");
        
-       uiDefButBitS(block, TOG, TEX_NORMALMAP, B_NOP, "Normal Map",    160,120,150,20, &tex->imaflag,
+       uiBlockBeginAlign(block);
+       uiDefButBitS(block, TOG, TEX_NORMALMAP, B_NOP, "Normal Map",    160,120,(mtex)? 75: 150,20, &tex->imaflag,
                                        0, 0, 0, 0, "Use image RGB values for normal mapping");
+       if(mtex)
+               uiDefButS(block, MENU, B_DIFF, "Normal Space %t|Camera %x0|World %x1|Object %x2|Tangent %x3", 
+                                               235,120,75,20, &mtex->normapspace, 0, 0, 0, 0, "Sets space of normal map image");
+       uiBlockEndAlign(block);
 
        /* crop extend clip */
        
@@ -3783,9 +3788,6 @@ static void material_panel_shading(Material *ma)
                uiBlockSetCol(block, TH_BUT_SETTING1);
                uiDefButBitI(block, TOG, MA_TANGENT_V, B_MATPRV, "Tangent V",   245,180,65,19, &(ma->mode), 0, 0, 0, 0, "Use the tangent vector in V direction for shading");
                
-               /* qdn: normalmap tangents separated from shading */
-               uiDefButBitI(block, TOG, MA_NORMAP_TANG, B_MATPRV, "NMap TS",   245,160,65,19, &(ma->mode), 0, 0, 0, 0, "Enable Tangent Space normal mapping");
-
                uiBlockBeginAlign(block);
                uiDefButBitI(block, TOG, MA_SHADOW, B_MATPRV,   "Shadow",                       245,140,65,19, &(ma->mode), 0, 0, 0, 0, "Makes material receive shadows");
                uiDefButBitI(block, TOG, MA_SHADOW_TRA, B_MATPRV, "TraShadow",          245,120,65,19, &(ma->mode), 0, 0, 0, 0, "Receives transparent shadows based at material color and alpha");
@@ -4293,7 +4295,7 @@ void texture_panels()
                        switch(tex->type) {
                        case TEX_IMAGE:
                                texture_panel_image(&tex->ima, &tex->iuser);
-                               texture_panel_image_map(tex);
+                               texture_panel_image_map(tex, mtex);
                                break;
                        case TEX_ENVMAP:
                                texture_panel_envmap(tex);
index d901644c19f9077ef7c146f6ba7043a68591cac9..d06208ea503bc6bf130c8f1e9336faeaf0933f5d 100644 (file)
@@ -108,6 +108,7 @@ void sort_faces(void);
 #include "PIL_time.h"
 
 #include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
 
 /* from rendercode.c */
 #define VECMUL(dest, f)                  dest[0]*= f; dest[1]*= f; dest[2]*= f
@@ -945,6 +946,7 @@ static ScrArea *biggest_image_area(void)
 
 typedef struct BakeRender {
        Render *re;
+       struct Object *actob;
        int event, tot, ready;
 } BakeRender;
 
@@ -952,7 +954,7 @@ static void *do_bake_render(void *bake_v)
 {
        BakeRender *bkr= bake_v;
        
-       bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->event);
+       bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->event, bkr->actob);
        bkr->ready= 1;
        
        return NULL;
@@ -971,6 +973,8 @@ void objects_bake_render_menu(void)
 /* all selected meshes with UV maps are rendered for current scene visibility */
 void objects_bake_render(short event)
 {
+       Object *actob= OBACT;
+       int active= G.scene->r.bake_flag & R_BAKE_TO_ACTIVE;
        short prev_r_raytrace= 0, prev_wo_amb_occ= 0;
        
        if(event==0) event= G.scene->r.bake_mode;
@@ -980,13 +984,16 @@ void objects_bake_render(short event)
                return;  
        }        
        
+       if(active && !actob)
+               return;
+               
        if(event>0) {
                Render *re= RE_NewRender("_Bake View_");
                ScrArea *area= biggest_image_area();
                ListBase threads;
                BakeRender bkr;
                int timer=0, tot, sculptmode= G.f & G_SCULPTMODE;
-               
+
                if(sculptmode) set_sculptmode();
                
                if(event==1) event= RE_BAKE_ALL;
@@ -1001,19 +1008,20 @@ void objects_bake_render(short event)
                        }
 
                        /* If raytracing or AO is disabled, switch it on temporarily for baking. */
-                       prev_r_raytrace = (G.scene->r.mode & R_RAYTRACE) != 0;
                        prev_wo_amb_occ = (G.scene->world->mode & WO_AMB_OCC) != 0;
-
-                       G.scene->r.mode |= R_RAYTRACE;
                        G.scene->world->mode |= WO_AMB_OCC;
                }
+               if(event==RE_BAKE_AO || actob) {
+                       prev_r_raytrace = (G.scene->r.mode & R_RAYTRACE) != 0;
+                       G.scene->r.mode |= R_RAYTRACE;
+               }
                
                waitcursor(1);
                RE_test_break_cb(re, thread_break);
                g_break= 0;
                G.afbreek= 0;   /* blender_test_break uses this global */
                
-               RE_Database_Baking(re, G.scene, event);
+               RE_Database_Baking(re, G.scene, event, actob);
                
                /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */
        
@@ -1021,6 +1029,7 @@ void objects_bake_render(short event)
                bkr.re= re;
                bkr.event= event;
                bkr.ready= 0;
+               bkr.actob= actob;
                BLI_insert_thread(&threads, &bkr);
                
                while(bkr.ready==0) {
@@ -1048,21 +1057,26 @@ void objects_bake_render(short event)
                if(tot==0) error("No Images found to bake to");
                else {
                        Image *ima;
-                       /* force OpenGL reload */
+                       /* force OpenGL reload and mipmap recalc */
                        for(ima= G.main->image.first; ima; ima= ima->id.next) {
                                if(ima->ok==IMA_OK_LOADED) {
                                        ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
-                                       if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
+                                       if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
                                                free_realtime_image(ima); 
+                                               imb_freemipmapImBuf(ibuf);
+                                       }
                                }
                        }
                }
                
-                       /* restore raytrace and AO */
-               if(event==RE_BAKE_AO) {
-                       if( prev_wo_amb_occ == 0) G.scene->world->mode &= ~WO_AMB_OCC;
-                       if( prev_r_raytrace == 0) G.scene->r.mode &= ~R_RAYTRACE;
-               }
+               /* restore raytrace and AO */
+               if(event==RE_BAKE_AO)
+                       if(prev_wo_amb_occ == 0)
+                               G.scene->world->mode &= ~WO_AMB_OCC;
+
+               if(event==RE_BAKE_AO || actob)
+                       if(prev_r_raytrace == 0)
+                               G.scene->r.mode &= ~R_RAYTRACE;
                
                allqueue(REDRAWIMAGE, 0);
                allqueue(REDRAWVIEW3D, 0);
@@ -1072,4 +1086,3 @@ void objects_bake_render(short event)
        }
 }
 
-