* Displacement baking wasnt working with negative distances.
authorCampbell Barton <ideasman42@gmail.com>
Fri, 22 Feb 2008 14:27:46 +0000 (14:27 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 22 Feb 2008 14:27:46 +0000 (14:27 +0000)
* Added Normalize option for diplacement so everything in the 'Dist' range is mapped 0-1
* Increased the maximum Dist and Bias to1000.0 (was 10.0)
* Added python utility function in BPyRender.py - bakeToPlane(...), to automate heightmap, normalmap generation for Crystalspace.

release/scripts/bpymodules/BPyRender.py
source/blender/makesdna/DNA_scene_types.h
source/blender/python/api2_2x/sceneRender.c
source/blender/render/intern/source/rendercore.c
source/blender/src/buttons_scene.c

index e335ee7f6a86892bd491919df3159f1fadd0a2b6..7b1ccc7a0bdc7dce12ea46d48b9a78bc6c53d2cf 100644 (file)
@@ -496,3 +496,135 @@ def vcol2image(me_s,\
                                mat.mode &= ~Blender.Material.Modes.SHADELESS
        
        return image
+
+def bakeToPlane(sce, ob_from, width, height, bakemodes, axis='z', margin=0):
+       '''
+       Bakes terrain onto a plane from one object
+       sce - scene to bake with
+       ob_from - mesh object
+       width/height - image size
+       bakemodes - list of baking modes to use, Blender.Scene.Render.BakeModes.NORMALS, Blender.Scene.Render.BakeModes.AO ... etc
+       axis - axis to allign the plane to.
+       margin - margin setting for baking.
+       
+       Example:
+               import Blender
+               from Blender import *
+               import BPyRender
+               sce = Scene.GetCurrent()
+               ob = Object.Get('Plane')
+               BPyRender.bakeToPlane(sce, ob, 512, 512, [Scene.Render.BakeModes.DISPLACEMENT, Scene.Render.BakeModes.NORMALS], 'z', 8 )
+       '''
+       
+       # Backup bake settings
+       rend = sce.render
+       BACKUP_bakeDist = rend.bakeDist
+       BACKUP_bakeBias = rend.bakeBias
+       BACKUP_bakeMode = rend.bakeMode
+       BACKUP_bakeClear = rend.bakeClear
+       BACKUP_bakeMargin = rend.bakeMargin
+       BACKUP_bakeToActive = rend.bakeToActive
+       
+       # Backup object selection
+       BACKUP_obsel = list(sce.objects.selected)
+       BACKUP_obact = sce.objects.active
+       
+       # New bake settings
+       rend.bakeClear = True
+       rend.bakeMargin = margin
+       BACKUP_bakeToActive = True
+       
+       # Assume a mesh
+       me_from = ob_from.getData(mesh=1)
+       
+       xmin = ymin = zmin = 10000000000
+       xmax = ymax = zmax =-10000000000
+       
+       # Dont trust bounding boxes :/
+       #bounds = ob_from.boundingBox
+       #for v in bounds:
+       #       x,y,z = tuple(v)
+       mtx = ob_from.matrixWorld
+       for v in me_from.verts:
+               x,y,z = tuple(v.co*mtx)
+               
+               xmax = max(xmax, x)
+               ymax = max(ymax, y)
+               zmax = max(zmax, z)
+               
+               xmin = min(xmin, x)
+               ymin = min(ymin, y)
+               zmin = min(zmin, z)
+
+       if axis=='x':
+               xmed = (xmin+xmax)/2.0
+               co1 = (xmed, ymin, zmin)
+               co2 = (xmed, ymin, zmax)
+               co3 = (xmed, ymax, zmax)
+               co4 = (xmed, ymax, zmin)
+               rend.bakeDist = (xmax-xmin)/2.0
+       elif axis=='y':
+               ymed = (ymin+ymax)/2.0
+               co1 = (xmin, ymed, zmin)
+               co2 = (xmin, ymed, zmax)
+               co3 = (xmax, ymed, zmax)
+               co4 = (xmax, ymed, zmin)
+               rend.bakeDist = (ymax-ymin)/2.0
+       elif axis=='z':
+               zmed = (zmin+zmax)/2.0
+               co1 = (xmin, ymin, zmed)
+               co2 = (xmin, ymax, zmed)
+               co3 = (xmax, ymax, zmed)
+               co4 = (xmax, ymin, zmed)
+               rend.bakeDist = (zmax-zmin)/2.0
+       else:
+               raise "invalid axis"
+       me_plane = Blender.Mesh.New()
+       ob_plane = Blender.Object.New('Mesh')
+       ob_plane.link(me_plane)
+       sce.objects.link(ob_plane)
+       ob_plane.Layers = ob_from.Layers
+       
+       ob_from.sel = 1 # make active
+       sce.objects.active = ob_plane
+       ob_plane.sel = 1
+       
+       me_plane.verts.extend([co4, co3, co2, co1])
+       me_plane.faces.extend([(0,1,2,3)])
+       me_plane.faceUV = True
+       me_plane_face = me_plane.faces[0]
+       uvs = me_plane_face.uv
+       uvs[0].x = 0.0; uvs[0].y = 0.0
+       uvs[1].x = 0.0; uvs[1].y = 1.0
+       uvs[2].x = 1.0; uvs[2].y = 1.0
+       uvs[3].x = 1.0; uvs[3].y = 0.0
+       
+       images_return = []
+       
+       for mode in bakemodes:
+               img = Blender.Image.New('bake', width, height, 24)
+               
+               me_plane_face.image = img
+               rend.bakeMode = mode
+               rend.bake()
+               images_return.append( img )
+       
+       # Restore bake settings
+       #'''
+       rend.bakeDist = BACKUP_bakeDist
+       rend.bakeBias = BACKUP_bakeBias
+       rend.bakeMode = BACKUP_bakeMode
+       rend.bakeClear = BACKUP_bakeClear
+       rend.bakeMargin = BACKUP_bakeMargin
+       rend.bakeToActive = BACKUP_bakeToActive
+       
+       # Restore obsel
+       sce.objects.selected = BACKUP_obsel
+       sce.objects.active = BACKUP_obact
+       
+       me_plane.verts = None
+       sce.objects.unlink(ob_plane)
+       #'''
+       
+       return me_plane_face
+
index 9b24d8214b0f0f8ee51b7aa8d8652ed98d705fe9..d42c3a4871337fb1b6fbe0dc0a4cd195a9fe1c03 100644 (file)
@@ -676,7 +676,7 @@ typedef struct Scene {
 #define R_BAKE_CLEAR           1
 #define R_BAKE_OSA                     2
 #define R_BAKE_TO_ACTIVE       4
-#define R_BAKE_NORMALIZE_AO 8
+#define R_BAKE_NORMALIZE       8
 
 /* bake_normal_space */
 #define R_BAKE_SPACE_CAMERA     0
index 62ddd5a33bb4f3776f7b111c69097b339de06a21..4bf823bc938e808e23ca10f561758683eb4d725f 100644 (file)
@@ -1899,12 +1899,12 @@ static int RenderData_setFloatAttrClamp( BPy_RenderData *self, PyObject *value,
                break;
        case EXPP_RENDER_ATTR_BAKEDIST:
                min = 0.0f;
-               max = 10.0f;
+               max = 1000.0f;
                param = &self->renderContext->bake_maxdist;
                break;
        case EXPP_RENDER_ATTR_BAKEBIAS:
                min = 0.0f;
-               max = 10.0f;
+               max = 1000.0f;
                param = &self->renderContext->bake_biasdist;
                break;
        default:
@@ -2880,7 +2880,7 @@ static PyGetSetDef BPy_RenderData_getseters[] = {
        {"bakeNormalizeAO",
         (getter)RenderData_getBakeMode, (setter)RenderData_setBakeMode,
         "Bake selection to active",
-        (void *)R_BAKE_NORMALIZE_AO},
+        (void *)R_BAKE_NORMALIZE},
        {"bakeMargin",
         (getter)RenderData_getIValueAttr, (setter)RenderData_setIValueAttrClamp,
         "number of pixels to use as a margin for the edges of the image",
index 84536d384906c4f4c656cd44be6dafc977a73a42..c72edabc65c5090fa5dd0ff51e5ad9ecb2a09ac2 100644 (file)
@@ -1855,7 +1855,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int
        if(bs->type==RE_BAKE_AO) {
                ambient_occlusion(shi);
 
-               if(R.r.bake_flag & R_BAKE_NORMALIZE_AO)
+               if(R.r.bake_flag & R_BAKE_NORMALIZE)
                        VECCOPY(shr.combined, shi->ao)
                else
                        ambient_occlusion_to_diffuse(shi, shr.combined);
@@ -1934,7 +1934,11 @@ static void bake_displacement(void *handle, ShadeInput *shi, float dist, int x,
        BakeShade *bs= handle;
        float disp;
        
-       disp = 0.5 + dist;
+       if(R.r.bake_flag & R_BAKE_NORMALIZE && R.r.bake_maxdist) {
+               disp = (dist+R.r.bake_maxdist) / (R.r.bake_maxdist*2); /* alter the range from [-bake_maxdist, bake_maxdist] to [0, 1]*/
+       } else {
+               disp = 0.5 + dist; /* alter the range from [-0.5,0.5] to [0,1]*/
+       }
        
        if(bs->rect_float) {
                float *col= bs->rect_float + 4*(bs->rectx*y + x);
@@ -2066,7 +2070,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
                }
 
                if (hit && bs->type==RE_BAKE_DISPLACEMENT) {;
-                       bake_displacement(handle, shi, mindist, x, y);
+                       bake_displacement(handle, shi, (dir==-1)? -mindist:mindist, x, y);
                        return;
                }
 
index 9fcd093acb2e9eed6d6321dc7560f65b5bb13ca6..14a660376aeb518d2cf9571dab3fa1e8e3b0ef47 100644 (file)
@@ -2085,16 +2085,20 @@ static void render_panel_bake(void)
 
        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,95,20,&G.scene->r.bake_maxdist, 0.0, 10.0, 1, 0, "Maximum distance from active object to other object (in blender units)");
-       uiDefButF(block, NUM, B_DIFF, "Bias:", 105,100,95,20,&G.scene->r.bake_biasdist, 0.0, 10.0, 1, 0, "Bias towards faces further away from the object (in blender units)");
+       uiDefButF(block, NUM, B_DIFF, "Dist:", 10,100,95,20,&G.scene->r.bake_maxdist, 0.0, 1000.0, 1, 0, "Maximum distance from active object to other object (in blender units)");
+       uiDefButF(block, NUM, B_DIFF, "Bias:", 105,100,95,20,&G.scene->r.bake_biasdist, 0.0, 1000.0, 1, 0, "Bias towards faces further away from the object (in blender units)");
        uiBlockEndAlign(block);
 
        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", 
                        10,70,190,20, &G.scene->r.bake_normal_space, 0, 0, 0, 0, "Choose normal space for baking");
-       else if(G.scene->r.bake_mode == RE_BAKE_AO)
-               uiDefButBitS(block, TOG, R_BAKE_NORMALIZE_AO, B_DIFF, "Normalized", 10,70,190,20, &G.scene->r.bake_flag, 0.0, 0, 0, 0, "Bake ambient occlusion normalized, without taking into acount material settings");
-
+       else if(G.scene->r.bake_mode == RE_BAKE_AO || G.scene->r.bake_mode == RE_BAKE_DISPLACEMENT) {
+               uiDefButBitS(block, TOG, R_BAKE_NORMALIZE, B_DIFF, "Normalized", 10,70,190,20, &G.scene->r.bake_flag, 0.0, 0, 0, 0,
+                               G.scene->r.bake_mode == RE_BAKE_AO ?
+                                "Bake ambient occlusion normalized, without taking into acount material settings":
+                                "Normalized displacement value to fit the 'Dist' range"
+               );
+       }
 #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)");