diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-12-18 21:46:42 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-12-18 21:46:42 +0400 |
commit | 6571713ddb7e1f091c30a43b315fb37778605ed2 (patch) | |
tree | 6a5cc8bf047a0ee50701db2ace65013834383345 /source/blender/editors/object/object_bake.c | |
parent | 6b3e880311e1046ec60d8647dc4dd0eb0cd4d92c (diff) |
Ambient occlusion baker from multi-resolution mesh
This implements AO baking directly from multi-resolution mesh with much
less memory overhead than regular baker.
Uses rays distribution implementation from Morten Mikkelsen, raycast
is based on RayObject also used by Blender Internal.
Works in single-thread yet, multi-threading would be implemented later.
Diffstat (limited to 'source/blender/editors/object/object_bake.c')
-rw-r--r-- | source/blender/editors/object/object_bake.c | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index e9b4a7e0eb7..77d31a900d4 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -96,6 +96,9 @@ typedef struct { ListBase data; int bake_clear, bake_filter; short mode, use_lores_mesh; + int number_of_rays; + float bias; + int raytrace_structure; } MultiresBakeJob; static int multiresbake_check(bContext *C, wmOperator *op) @@ -203,6 +206,9 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l if (*lvl == 0) { DerivedMesh *tmp_dm = CDDM_from_mesh(me, ob); + + DM_set_only_copy(tmp_dm, CD_MASK_BAREMESH | CD_MASK_MTFACE); + dm = CDDM_copy(tmp_dm); tmp_dm->release(tmp_dm); } @@ -210,6 +216,8 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l MultiresModifierData tmp_mmd = *mmd; DerivedMesh *cddm = CDDM_from_mesh(me, ob); + DM_set_only_copy(cddm, CD_MASK_BAREMESH | CD_MASK_MTFACE); + tmp_mmd.lvl = *lvl; tmp_mmd.sculptlvl = *lvl; dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0); @@ -227,6 +235,14 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l DerivedMesh *cddm = CDDM_from_mesh(me, ob); DerivedMesh *dm; + DM_set_only_copy(cddm, CD_MASK_BAREMESH); + + /* TODO: DM_set_only_copy wouldn't set mask for loop and poly data, + * but we really need BAREMESH only to save lots of memory + */ + CustomData_set_only_copy(&cddm->loopData, CD_MASK_BAREMESH); + CustomData_set_only_copy(&cddm->polyData, CD_MASK_BAREMESH); + *lvl = mmd->totlvl; *simple = mmd->simple; @@ -298,14 +314,13 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) bkr.bake_filter = scene->r.bake_filter; bkr.mode = scene->r.bake_mode; bkr.use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH; + bkr.bias = scene->r.bake_biasdist; + bkr.number_of_rays = scene->r.bake_rays_number; + bkr.raytrace_structure = scene->r.raytrace_structure; /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ - bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl); - - if (!bkr.lores_dm) - continue; - bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple); + bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl); RE_multires_bake_images(&bkr); @@ -335,24 +350,25 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) bkj->mode = scene->r.bake_mode; bkj->use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH; bkj->bake_clear = scene->r.bake_flag & R_BAKE_CLEAR; + bkj->bias = scene->r.bake_biasdist; + bkj->number_of_rays = scene->r.bake_rays_number; + bkj->raytrace_structure = scene->r.raytrace_structure; CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { MultiresBakerJobData *data; - DerivedMesh *lores_dm; int lvl; + ob = base->object; multires_force_update(ob); - lores_dm = multiresbake_create_loresdm(scene, ob, &lvl); - if (!lores_dm) - continue; - data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data"); - data->lores_dm = lores_dm; - data->lvl = lvl; + + /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple); + data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl); + data->lvl = lvl; BLI_addtail(&bkj->data, data); } @@ -399,6 +415,10 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa bkr.do_update = do_update; bkr.progress = progress; + bkr.bias = bkj->bias; + bkr.number_of_rays = bkj->number_of_rays; + bkr.raytrace_structure = bkj->raytrace_structure; + RE_multires_bake_images(&bkr); BLI_freelistN(&bkr.image); @@ -652,7 +672,7 @@ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), wmEven static int is_multires_bake(Scene *scene) { - if (ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT)) + if (ELEM3(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_AO)) return scene->r.bake_flag & R_BAKE_MULTIRES; return 0; |