diff options
Diffstat (limited to 'source/blender/render')
27 files changed, 1520 insertions, 205 deletions
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index 5be10f56d7a..291ee8e44bd 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -61,6 +61,7 @@ set(SRC intern/source/gammaCorrectionTables.c intern/source/imagetexture.c intern/source/initrender.c + intern/source/multires_bake.c intern/source/occlusion.c intern/source/pipeline.c intern/source/pixelblending.c @@ -84,6 +85,7 @@ set(SRC intern/source/zbuf.c extern/include/RE_engine.h + extern/include/RE_multires_bake.h extern/include/RE_pipeline.h extern/include/RE_render_ext.h extern/include/RE_shader_ext.h diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index 5addc45571d..0fd180fed65 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/source/*.c') diff --git a/source/blender/render/extern/include/RE_multires_bake.h b/source/blender/render/extern/include/RE_multires_bake.h new file mode 100644 index 00000000000..5e8ebdd8a18 --- /dev/null +++ b/source/blender/render/extern/include/RE_multires_bake.h @@ -0,0 +1,61 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Morten Mikkelsen, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file RE_multires_bake.h + * \ingroup render + */ + +#ifndef __RE_MULTIRES_BAKE_H__ +#define __RE_MULTIRES_BAKE_H__ + +struct MultiresBakeRender; + +typedef struct MultiresBakeRender { + DerivedMesh *lores_dm, *hires_dm; + int simple, lvl, tot_lvl, bake_filter; + short mode, use_lores_mesh; + + int number_of_rays; + float bias; + + int tot_obj, tot_image; + ListBase image; + + int baked_objects, baked_faces; + + int raytrace_structure; + int octree_resolution; + + short *stop; + short *do_update; + float *progress; +} MultiresBakeRender; + +void RE_multires_bake_images(struct MultiresBakeRender *bkr); + +#endif diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 9d1e2b8e620..56cc0ad9a1c 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -198,7 +198,7 @@ void RE_SetOrtho (struct Render *re, rctf *viewplane, float clipsta, float clipe void RE_SetPixelSize(struct Render *re, float pixsize); /* option to set viewmatrix before making dbase */ -void RE_SetView (struct Render *re, float mat[][4]); +void RE_SetView (struct Render *re, float mat[4][4]); /* make or free the dbase */ void RE_Database_FromScene(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, int use_camera_view); @@ -274,8 +274,8 @@ int RE_seq_render_active(struct Scene *scene, struct RenderData *rd); void RE_Database_Baking(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, const int type, struct Object *actob); -void RE_DataBase_GetView(struct Render *re, float mat[][4]); -void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[][4]); +void RE_DataBase_GetView(struct Render *re, float mat[4][4]); +void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]); struct Scene *RE_GetScene(struct Render *re); int RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override, struct ReportList *reports); diff --git a/source/blender/render/intern/include/pixelblending.h b/source/blender/render/intern/include/pixelblending.h index bb2e7e7f9f9..19759bf3e97 100644 --- a/source/blender/render/intern/include/pixelblending.h +++ b/source/blender/render/intern/include/pixelblending.h @@ -38,8 +38,8 @@ */ void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int row_w); void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize); -void add_filt_fmask_coord(float filt[][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y); -void mask_array(unsigned int mask, float filt[][3]); +void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y); +void mask_array(unsigned int mask, float filt[3][3]); /** * Alpha-over blending for floats. diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 07fc7d7a6ed..e9514b8585e 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -56,7 +56,7 @@ int RE_rayobject_raycast(RayObject *r, struct Isect *i); /* Acceleration Structures */ RayObject *RE_rayobject_octree_create(int ocres, int size); -RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); +RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob); RayObject *RE_rayobject_empty_create(void); RayObject *RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */ @@ -87,6 +87,8 @@ typedef struct RayFace { RayObject *RE_rayface_from_vlak(RayFace *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr); +RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4); + /* RayObject representing faces directly from a given VlakRen structure. Thus * allowing to save memory, but making code triangle intersection dependent on * render structures. */ diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index f7a5a930ac6..45080de3148 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -198,7 +198,6 @@ struct Render ListBase strandsurface; /* use this instead of R.r.cfra */ - float cfra; float mblur_offs, field_offs; /* render database */ diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h index 30712250440..88b639c4ba9 100644 --- a/source/blender/render/intern/include/rendercore.h +++ b/source/blender/render/intern/include/rendercore.h @@ -83,6 +83,8 @@ int get_sample_layers(struct RenderPart *pa, struct RenderLayer *rl, struct Rend /* -------- ray.c ------- */ +struct RayObject *RE_rayobject_create(int type, int size, int octree_resolution); + extern void freeraytree(Render *re); extern void makeraytree(Render *re); struct RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi); diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index 5213f14d773..24989b13c48 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -87,8 +87,8 @@ void free_renderdata_tables(struct Render *re); void free_renderdata_vertnodes(struct VertTableNode *vertnodes); void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes); -void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets); -int clip_render_object(float boundbox[][3], float bounds[4], float mat[][4]); +void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[4][4], float *), int do_pano, float xoffs, int do_buckets); +int clip_render_object(float boundbox[2][3], float bounds[4], float mat[4][4]); /* functions are not exported... so wrong names */ @@ -106,7 +106,7 @@ struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, s struct StrandBuffer *RE_addStrandBuffer(struct ObjectRen *obr, int totvert); struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex, int lay); -struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[][4], int lay); +struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[4][4], int lay); void RE_makeRenderInstances(struct Render *re); float *RE_vertren_get_stress(struct ObjectRen *obr, struct VertRen *ver, int verify); diff --git a/source/blender/render/intern/include/strand.h b/source/blender/render/intern/include/strand.h index 720354219e9..d9594864bff 100644 --- a/source/blender/render/intern/include/strand.h +++ b/source/blender/render/intern/include/strand.h @@ -92,10 +92,10 @@ struct StrandShadeCache; typedef struct StrandShadeCache StrandShadeCache; void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint); -void render_strand_segment(struct Render *re, float winmat[][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg); +void render_strand_segment(struct Render *re, float winmat[4][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg); void strand_minmax(struct StrandRen *strand, float min[3], float max[3], const float width); -struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[][4], int timeoffset); +struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[4][4], int timeoffset); void free_strand_surface(struct Render *re); struct StrandShadeCache *strand_shade_cache_create(void); diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h index e873111e6bf..162fa3b7e88 100644 --- a/source/blender/render/intern/include/zbuf.h +++ b/source/blender/render/intern/include/zbuf.h @@ -49,17 +49,17 @@ void fillrect(int *rect, int x, int y, int val); * Converts a world coordinate into a homogeneous coordinate in view * coordinates. */ -void projectvert(const float v1[3], float winmat[][4], float adr[4]); -void projectverto(const float v1[3], float winmat[][4], float adr[4]); +void projectvert(const float v1[3], float winmat[4][4], float adr[4]); +void projectverto(const float v1[3], float winmat[4][4], float adr[4]); int testclip(const float v[3]); -void zbuffer_shadow(struct Render *re, float winmat[][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity); -void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]); +void zbuffer_shadow(struct Render *re, float winmat[4][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity); +void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[4][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]); void zbuffer_solid(struct RenderPart *pa, struct RenderLayer *rl, void (*fillfunc)(struct RenderPart *, struct ZSpan *, int, void*), void *data); unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass, struct ListBase *psmlist); void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void*, int, int, int, int, int)); -int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct APixstrand *apixbuf, struct ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, struct StrandShadeCache *cache); +int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct APixstrand *apixbuf, struct ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[4][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, struct StrandShadeCache *cache); typedef struct APixstr { unsigned short mask[4]; /* jitter mask */ @@ -136,8 +136,8 @@ void zbufclipwire(struct ZSpan *zspan, int obi, int zvlnr, int ec, float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4); /* exported to shadeinput.c */ -void zbuf_make_winmat(Render *re, float winmat[][4]); -void zbuf_render_project(float winmat[][4], const float co[3], float ho[4]); +void zbuf_make_winmat(Render *re, float winmat[4][4]); +void zbuf_render_project(float winmat[4][4], const float co[3], float ho[4]); /* sould not really be exposed, bad! */ void hoco_to_zco(ZSpan *zspan, float zco[3], const float hoco[4]); diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index c3babf99d51..b31aff82777 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -90,6 +90,11 @@ RayObject *RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRe return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0); } +RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4) +{ + return rayface_from_coords(rayface, ob, face, v1, v2, v3, v4); +} + /* VlakPrimitive */ RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr) diff --git a/source/blender/render/intern/raytrace/rayobject_instance.cpp b/source/blender/render/intern/raytrace/rayobject_instance.cpp index f797f7a4311..f9ed012b117 100644 --- a/source/blender/render/intern/raytrace/rayobject_instance.cpp +++ b/source/blender/render/intern/raytrace/rayobject_instance.cpp @@ -75,7 +75,7 @@ typedef struct InstanceRayObject { } InstanceRayObject; -RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob) +RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob) { InstanceRayObject *obj = (InstanceRayObject *)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject"); assert(RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp index afb8fe6c3b5..dad7fe5fd60 100644 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp @@ -223,7 +223,7 @@ static Node *addnode(Octree *oc) return oc->adrnode[index] + (oc->nodecount & 4095); } -static int face_in_node(RayFace *face, short x, short y, short z, float rtf[][3]) +static int face_in_node(RayFace *face, short x, short y, short z, float rtf[4][3]) { static float nor[3], d; float fx, fy, fz; @@ -321,12 +321,12 @@ static void ocwrite(Octree *oc, RayFace *face, int quad, short x, short y, short calc_ocval_face(rtf[0], rtf[1], rtf[2], NULL, x >> 2, y >> 1, z, &no->ov[a]); } -static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[][3], float rtf[][3]) +static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[4][3], float rtf[4][3]) { int ocx1, ocx2, ocy1, ocy2; int x, y, dx = 0, dy = 0; float ox1, ox2, oy1, oy2; - float labda, labdao, labdax, labday, ldx, ldy; + float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy; ocx1 = rts[b1][c1]; ocy1 = rts[b1][c2]; @@ -345,40 +345,40 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa if (ox1 != ox2) { if (ox2 - ox1 > 0.0f) { - labdax = (ox1 - ocx1 - 1.0f) / (ox1 - ox2); + lambda_x = (ox1 - ocx1 - 1.0f) / (ox1 - ox2); ldx = -1.0f / (ox1 - ox2); dx = 1; } else { - labdax = (ox1 - ocx1) / (ox1 - ox2); + lambda_x = (ox1 - ocx1) / (ox1 - ox2); ldx = 1.0f / (ox1 - ox2); dx = -1; } } else { - labdax = 1.0f; + lambda_x = 1.0f; ldx = 0; } if (oy1 != oy2) { if (oy2 - oy1 > 0.0f) { - labday = (oy1 - ocy1 - 1.0f) / (oy1 - oy2); + lambda_y = (oy1 - ocy1 - 1.0f) / (oy1 - oy2); ldy = -1.0f / (oy1 - oy2); dy = 1; } else { - labday = (oy1 - ocy1) / (oy1 - oy2); + lambda_y = (oy1 - ocy1) / (oy1 - oy2); ldy = 1.0f / (oy1 - oy2); dy = -1; } } else { - labday = 1.0f; + lambda_y = 1.0f; ldy = 0; } x = ocx1; y = ocy1; - labda = MIN2(labdax, labday); + lambda = MIN2(lambda_x, lambda_y); while (TRUE) { @@ -389,26 +389,26 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa ocface[oc->ocres * x + y] = 1; } - labdao = labda; - if (labdax == labday) { - labdax += ldx; + lambda_o = lambda; + if (lambda_x == lambda_y) { + lambda_x += ldx; x += dx; - labday += ldy; + lambda_y += ldy; y += dy; } else { - if (labdax < labday) { - labdax += ldx; + if (lambda_x < lambda_y) { + lambda_x += ldx; x += dx; } else { - labday += ldy; + lambda_y += ldy; y += dy; } } - labda = MIN2(labdax, labday); - if (labda == labdao) break; - if (labda >= 1.0f) break; + lambda = MIN2(lambda_x, lambda_y); + if (lambda == lambda_o) break; + if (lambda >= 1.0f) break; } ocface[oc->ocres * ocx2 + ocy2] = 1; } @@ -851,8 +851,8 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) OcVal ocval; float vec1[3], vec2[3], start[3], end[3]; float u1, u2, ox1, ox2, oy1, oy2, oz1, oz2; - float labdao, labdax, ldx, labday, ldy, labdaz, ldz, ddalabda; - float olabda = 0; + float lambda_o, lambda_x, ldx, lambda_y, ldy, lambda_z, ldz, dda_lambda; + float o_lambda = 0; int dx, dy, dz; int xo, yo, zo, c1 = 0; int ocx1, ocx2, ocy1, ocy2, ocz1, ocz2; @@ -871,7 +871,7 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) copy_v3_v3(start, is->start); madd_v3_v3v3fl(end, is->start, is->dir, is->dist); ldx = is->dir[0] * is->dist; - olabda = is->dist; + o_lambda = is->dist; u1 = 0.0f; u2 = 1.0f; @@ -939,68 +939,68 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) float dox, doy, doz; int eqval; - /* calc labda en ld */ + /* calc lambda en ld */ dox = ox1 - ox2; doy = oy1 - oy2; doz = oz1 - oz2; if (dox < -FLT_EPSILON) { ldx = -1.0f / dox; - labdax = (ocx1 - ox1 + 1.0f) * ldx; + lambda_x = (ocx1 - ox1 + 1.0f) * ldx; dx = 1; } else if (dox > FLT_EPSILON) { ldx = 1.0f / dox; - labdax = (ox1 - ocx1) * ldx; + lambda_x = (ox1 - ocx1) * ldx; dx = -1; } else { - labdax = 1.0f; + lambda_x = 1.0f; ldx = 0; dx = 0; } if (doy < -FLT_EPSILON) { ldy = -1.0f / doy; - labday = (ocy1 - oy1 + 1.0f) * ldy; + lambda_y = (ocy1 - oy1 + 1.0f) * ldy; dy = 1; } else if (doy > FLT_EPSILON) { ldy = 1.0f / doy; - labday = (oy1 - ocy1) * ldy; + lambda_y = (oy1 - ocy1) * ldy; dy = -1; } else { - labday = 1.0f; + lambda_y = 1.0f; ldy = 0; dy = 0; } if (doz < -FLT_EPSILON) { ldz = -1.0f / doz; - labdaz = (ocz1 - oz1 + 1.0f) * ldz; + lambda_z = (ocz1 - oz1 + 1.0f) * ldz; dz = 1; } else if (doz > FLT_EPSILON) { ldz = 1.0f / doz; - labdaz = (oz1 - ocz1) * ldz; + lambda_z = (oz1 - ocz1) * ldz; dz = -1; } else { - labdaz = 1.0f; + lambda_z = 1.0f; ldz = 0; dz = 0; } xo = ocx1; yo = ocy1; zo = ocz1; - ddalabda = MIN3(labdax, labday, labdaz); + dda_lambda = MIN3(lambda_x, lambda_y, lambda_z); vec2[0] = ox1; vec2[1] = oy1; vec2[2] = oz1; /* this loop has been constructed to make sure the first and last node of ray - * are always included, even when ddalabda==1.0f or larger */ + * are always included, even when dda_lambda==1.0f or larger */ while (TRUE) { @@ -1010,83 +1010,83 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) /* calculate ray intersection with octree node */ copy_v3_v3(vec1, vec2); // dox, y, z is negative - vec2[0] = ox1 - ddalabda * dox; - vec2[1] = oy1 - ddalabda * doy; - vec2[2] = oz1 - ddalabda * doz; + vec2[0] = ox1 - dda_lambda * dox; + vec2[1] = oy1 - dda_lambda * doy; + vec2[2] = oz1 - dda_lambda * doz; calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2); - //is->dist = (u1+ddalabda*(u2-u1))*olabda; + //is->dist = (u1+dda_lambda*(u2-u1))*o_lambda; if (testnode(oc, is, no, ocval) ) found = 1; - if (is->dist < (u1 + ddalabda * (u2 - u1)) * olabda) + if (is->dist < (u1 + dda_lambda * (u2 - u1)) * o_lambda) return found; } - labdao = ddalabda; + lambda_o = dda_lambda; /* traversing octree nodes need careful detection of smallest values, with proper - * exceptions for equal labdas */ - eqval = (labdax == labday); - if (labday == labdaz) eqval += 2; - if (labdax == labdaz) eqval += 4; + * exceptions for equal lambdas */ + eqval = (lambda_x == lambda_y); + if (lambda_y == lambda_z) eqval += 2; + if (lambda_x == lambda_z) eqval += 4; if (eqval) { // only 4 cases exist! if (eqval == 7) { // x=y=z - xo += dx; labdax += ldx; - yo += dy; labday += ldy; - zo += dz; labdaz += ldz; + xo += dx; lambda_x += ldx; + yo += dy; lambda_y += ldy; + zo += dz; lambda_z += ldz; } else if (eqval == 1) { // x=y - if (labday < labdaz) { - xo += dx; labdax += ldx; - yo += dy; labday += ldy; + if (lambda_y < lambda_z) { + xo += dx; lambda_x += ldx; + yo += dy; lambda_y += ldy; } else { - zo += dz; labdaz += ldz; + zo += dz; lambda_z += ldz; } } else if (eqval == 2) { // y=z - if (labdax < labday) { - xo += dx; labdax += ldx; + if (lambda_x < lambda_y) { + xo += dx; lambda_x += ldx; } else { - yo += dy; labday += ldy; - zo += dz; labdaz += ldz; + yo += dy; lambda_y += ldy; + zo += dz; lambda_z += ldz; } } else { // x=z - if (labday < labdax) { - yo += dy; labday += ldy; + if (lambda_y < lambda_x) { + yo += dy; lambda_y += ldy; } else { - xo += dx; labdax += ldx; - zo += dz; labdaz += ldz; + xo += dx; lambda_x += ldx; + zo += dz; lambda_z += ldz; } } } else { // all three different, just three cases exist - eqval = (labdax < labday); - if (labday < labdaz) eqval += 2; - if (labdax < labdaz) eqval += 4; + eqval = (lambda_x < lambda_y); + if (lambda_y < lambda_z) eqval += 2; + if (lambda_x < lambda_z) eqval += 4; if (eqval == 7 || eqval == 5) { // x smallest - xo += dx; labdax += ldx; + xo += dx; lambda_x += ldx; } else if (eqval == 2 || eqval == 6) { // y smallest - yo += dy; labday += ldy; + yo += dy; lambda_y += ldy; } else { // z smallest - zo += dz; labdaz += ldz; + zo += dz; lambda_z += ldz; } } - ddalabda = MIN3(labdax, labday, labdaz); - if (ddalabda == labdao) break; + dda_lambda = MIN3(lambda_x, lambda_y, lambda_z); + if (dda_lambda == lambda_o) break; /* to make sure the last node is always checked */ - if (labdao >= 1.0f) break; + if (lambda_o >= 1.0f) break; } } diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index f87478bb663..bc84661698f 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -760,7 +760,7 @@ static VertRen *as_findvertex(VlakRen *vlr, VertRen *UNUSED(ver), ASvert *asv, f /* note; autosmooth happens in object space still, after applying autosmooth we rotate */ /* note2; actually, when original mesh and displist are equal sized, face normals are from original mesh */ -static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[][4], int degr) +static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[4][4], int degr) { ASvert *asv, *asverts; ASface *asf; @@ -2187,7 +2187,7 @@ static short test_for_displace(Render *re, Object *ob) return 0; } -static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[][4], float imat[][3]) +static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[4][4], float imat[3][3]) { MTFace *tface; short texco= shi->mat->texco; @@ -2286,7 +2286,7 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve return; } -static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[][4], float imat[][3]) +static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[4][4], float imat[3][3]) { ShadeInput shi; @@ -2341,7 +2341,7 @@ static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float } } -static void do_displacement(Render *re, ObjectRen *obr, float mat[][4], float imat[][3]) +static void do_displacement(Render *re, ObjectRen *obr, float mat[4][4], float imat[3][3]) { VertRen *vr; VlakRen *vlr; @@ -2821,7 +2821,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) ListBase disp={NULL, NULL}; Material **matar; float *data, *fp, *orco=NULL; - float n[3], mat[4][4]; + float n[3], mat[4][4], nmat[4][4]; int nr, startvert, a, b; int need_orco=0, totmat; @@ -2836,6 +2836,11 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) mult_m4_m4m4(mat, re->viewmat, ob->obmat); invert_m4_m4(ob->imat, mat); + /* local object -> world space transform for normals */ + copy_m4_m4(nmat, mat); + transpose_m4(nmat); + invert_m4(nmat); + /* material array */ totmat= ob->totcol+1; matar= MEM_callocN(sizeof(Material*)*totmat, "init_render_surf matar"); @@ -2892,13 +2897,20 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) zero_v3(n); index= dl->index; for (a=0; a<dl->parts; a++, index+=3) { + int v1 = index[0], v2 = index[1], v3 = index[2]; + float *co1 = &dl->verts[v1 * 3], + *co2 = &dl->verts[v2 * 3], + *co3 = &dl->verts[v3 * 3]; + vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->v1= RE_findOrAddVert(obr, startvert+index[0]); - vlr->v2= RE_findOrAddVert(obr, startvert+index[1]); - vlr->v3= RE_findOrAddVert(obr, startvert+index[2]); + vlr->v1= RE_findOrAddVert(obr, startvert + v1); + vlr->v2= RE_findOrAddVert(obr, startvert + v2); + vlr->v3= RE_findOrAddVert(obr, startvert + v3); vlr->v4= NULL; - if (area_tri_v3(vlr->v3->co, vlr->v2->co, vlr->v1->co)>FLT_EPSILON10) { - normal_tri_v3(tmp, vlr->v3->co, vlr->v2->co, vlr->v1->co); + + /* to prevent float accuracy issues, we calculate normal in local object space (not world) */ + if (area_tri_v3(co3, co2, co1)>FLT_EPSILON10) { + normal_tri_v3(tmp, co3, co2, co1); add_v3_v3(n, tmp); } @@ -2907,6 +2919,8 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) vlr->ec= 0; } + /* transform normal to world space */ + mul_m4_v3(nmat, n); normalize_v3(n); /* vertex normals */ @@ -3159,7 +3173,12 @@ static void init_camera_inside_volumes(Render *re) { ObjectInstanceRen *obi; VolumeOb *vo; - float co[3] = {0.f, 0.f, 0.f}; + /* coordinates are all in camera space, so camera coordinate is zero. we also + * add an offset for the clip start, however note that with clip start it's + * actually impossible to do a single 'inside' test, since there will not be + * a single point where all camera rays start from, though for small clip start + * they will be close together. */ + float co[3] = {0.f, 0.f, -re->clipsta}; for (vo= re->volumes.first; vo; vo= vo->next) { for (obi= re->instancetable.first; obi; obi= obi->next) { @@ -3563,7 +3582,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) /* Lamps and Shadowbuffers */ /* ------------------------------------------------------------------------- */ -static void initshadowbuf(Render *re, LampRen *lar, float mat[][4]) +static void initshadowbuf(Render *re, LampRen *lar, float mat[4][4]) { struct ShadBuf *shb; float viewinv[4][4]; @@ -5196,7 +5215,7 @@ void RE_DataBase_ApplyWindow(Render *re) project_renderdata(re, projectverto, 0, 0, 0); } -void RE_DataBase_GetView(Render *re, float mat[][4]) +void RE_DataBase_GetView(Render *re, float mat[4][4]) { copy_m4_m4(mat, re->viewmat); } diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index c3126e57b53..be8b7f6c357 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -210,7 +210,7 @@ static void envmap_free_render_copy(Render *envre) /* ------------------------------------------------------------------------- */ -static void envmap_transmatrix(float mat[][4], int part) +static void envmap_transmatrix(float mat[4][4], int part) { float tmat[4][4], eul[3], rotmat[4][4]; @@ -247,7 +247,7 @@ static void envmap_transmatrix(float mat[][4], int part) /* ------------------------------------------------------------------------- */ -static void env_rotate_scene(Render *re, float mat[][4], int mode) +static void env_rotate_scene(Render *re, float mat[4][4], int mode) { GroupObject *go; ObjectRen *obr; @@ -587,53 +587,53 @@ void make_envmaps(Render *re) static int envcube_isect(EnvMap *env, const float vec[3], float answ[2]) { - float labda; + float lambda; int face; if (env->type == ENV_PLANE) { face = 1; - labda = 1.0f / vec[2]; - answ[0] = env->viewscale * labda * vec[0]; - answ[1] = -env->viewscale * labda * vec[1]; + lambda = 1.0f / vec[2]; + answ[0] = env->viewscale * lambda * vec[0]; + answ[1] = -env->viewscale * lambda * vec[1]; } else { /* which face */ if (vec[2] <= -fabsf(vec[0]) && vec[2] <= -fabsf(vec[1]) ) { face = 0; - labda = -1.0f / vec[2]; - answ[0] = labda * vec[0]; - answ[1] = labda * vec[1]; + lambda = -1.0f / vec[2]; + answ[0] = lambda * vec[0]; + answ[1] = lambda * vec[1]; } else if (vec[2] >= fabsf(vec[0]) && vec[2] >= fabsf(vec[1])) { face = 1; - labda = 1.0f / vec[2]; - answ[0] = labda * vec[0]; - answ[1] = -labda * vec[1]; + lambda = 1.0f / vec[2]; + answ[0] = lambda * vec[0]; + answ[1] = -lambda * vec[1]; } else if (vec[1] >= fabsf(vec[0])) { face = 2; - labda = 1.0f / vec[1]; - answ[0] = labda * vec[0]; - answ[1] = labda * vec[2]; + lambda = 1.0f / vec[1]; + answ[0] = lambda * vec[0]; + answ[1] = lambda * vec[2]; } else if (vec[0] <= -fabsf(vec[1])) { face = 3; - labda = -1.0f / vec[0]; - answ[0] = labda * vec[1]; - answ[1] = labda * vec[2]; + lambda = -1.0f / vec[0]; + answ[0] = lambda * vec[1]; + answ[1] = lambda * vec[2]; } else if (vec[1] <= -fabsf(vec[0])) { face = 4; - labda = -1.0f / vec[1]; - answ[0] = -labda * vec[0]; - answ[1] = labda * vec[2]; + lambda = -1.0f / vec[1]; + answ[0] = -lambda * vec[0]; + answ[1] = lambda * vec[2]; } else { face = 5; - labda = 1.0f / vec[0]; - answ[0] = -labda * vec[1]; - answ[1] = labda * vec[2]; + lambda = 1.0f / vec[0]; + answ[0] = -lambda * vec[1]; + answ[1] = lambda * vec[2]; } } diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 3ea74abbcc2..0d957f8019f 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -515,7 +515,7 @@ void RE_SetPixelSize(Render *re, float pixsize) re->viewdy = re->ycor * pixsize; } -void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[][4]) +void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]) { re->r.cfra = frame; RE_SetCamera(re, camera); diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c new file mode 100644 index 00000000000..0eb0c9a51c3 --- /dev/null +++ b/source/blender/render/intern/source/multires_bake.c @@ -0,0 +1,1182 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 by Blender Foundation + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Morten Mikkelsen, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/render/intern/source/multires_bake.c + * \ingroup render + */ + +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_object_types.h" +#include "DNA_mesh_types.h" + +#include "BLI_math.h" +#include "BLI_listbase.h" + +#include "BKE_ccg.h" +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_multires.h" +#include "BKE_modifier.h" +#include "BKE_subsurf.h" + +#include "RE_multires_bake.h" +#include "RE_pipeline.h" +#include "RE_shader_ext.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "rayintersection.h" +#include "rayobject.h" +#include "rendercore.h" + +typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data, + ImBuf *ibuf, const int face_index, const int lvl, const float st[2], + float tangmat[3][3], const int x, const int y); + +typedef void * (*MInitBakeData)(MultiresBakeRender *bkr, Image *ima); +typedef void (*MApplyBakeData)(void *bake_data); +typedef void (*MFreeBakeData)(void *bake_data); + +typedef struct { + MVert *mvert; + MFace *mface; + MTFace *mtface; + float *pvtangent; + float *precomputed_normals; + int w, h; + int face_index; + int i0, i1, i2; + DerivedMesh *lores_dm, *hires_dm; + int lvl; + void *bake_data; + ImBuf *ibuf; + MPassKnownData pass_data; +} MResolvePixelData; + +typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y); + +typedef struct { + int w, h; + char *texels; + const MResolvePixelData *data; + MFlushPixel flush_pixel; +} MBakeRast; + +typedef struct { + float *heights; + float height_min, height_max; + Image *ima; + DerivedMesh *ssdm; + const int *orig_index_mf_to_mpoly; + const int *orig_index_mp_to_orig; +} MHeightBakeData; + +typedef struct { + const int *orig_index_mf_to_mpoly; + const int *orig_index_mp_to_orig; +} MNormalBakeData; + +typedef struct { + int number_of_rays; + float bias; + + unsigned short *permutation_table_1; + unsigned short *permutation_table_2; + + RayObject *raytree; + RayFace *rayfaces; + + const int *orig_index_mf_to_mpoly; + const int *orig_index_mp_to_orig; +} MAOBakeData; + +static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index) +{ + unsigned int indices[] = {data->mface[face_num].v1, data->mface[face_num].v2, + data->mface[face_num].v3, data->mface[face_num].v4}; + const int smoothnormal = (data->mface[face_num].flag & ME_SMOOTH); + + if (!smoothnormal) { /* flat */ + if (data->precomputed_normals) { + copy_v3_v3(norm, &data->precomputed_normals[3 * face_num]); + } + else { + float nor[3]; + float *p0, *p1, *p2; + const int iGetNrVerts = data->mface[face_num].v4 != 0 ? 4 : 3; + + p0 = data->mvert[indices[0]].co; + p1 = data->mvert[indices[1]].co; + p2 = data->mvert[indices[2]].co; + + if (iGetNrVerts == 4) { + float *p3 = data->mvert[indices[3]].co; + normal_quad_v3(nor, p0, p1, p2, p3); + } + else { + normal_tri_v3(nor, p0, p1, p2); + } + + copy_v3_v3(norm, nor); + } + } + else { + short *no = data->mvert[indices[vert_index]].no; + + normal_short_to_float_v3(norm, no); + normalize_v3(norm); + } +} + +static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel) +{ + memset(bake_rast, 0, sizeof(MBakeRast)); + + bake_rast->texels = ibuf->userdata; + bake_rast->w = ibuf->x; + bake_rast->h = ibuf->y; + bake_rast->data = data; + bake_rast->flush_pixel = flush_pixel; +} + +static void flush_pixel(const MResolvePixelData *data, const int x, const int y) +{ + float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h}; + float *st0, *st1, *st2; + float *tang0, *tang1, *tang2; + float no0[3], no1[3], no2[3]; + float fUV[2], from_tang[3][3], to_tang[3][3]; + float u, v, w, sign; + int r; + + const int i0 = data->i0; + const int i1 = data->i1; + const int i2 = data->i2; + + st0 = data->mtface[data->face_index].uv[i0]; + st1 = data->mtface[data->face_index].uv[i1]; + st2 = data->mtface[data->face_index].uv[i2]; + + multiresbake_get_normal(data, no0, data->face_index, i0); /* can optimize these 3 into one call */ + multiresbake_get_normal(data, no1, data->face_index, i1); + multiresbake_get_normal(data, no2, data->face_index, i2); + + resolve_tri_uv(fUV, st, st0, st1, st2); + + u = fUV[0]; + v = fUV[1]; + w = 1 - u - v; + + if (data->pvtangent) { + tang0 = data->pvtangent + data->face_index * 16 + i0 * 4; + tang1 = data->pvtangent + data->face_index * 16 + i1 * 4; + tang2 = data->pvtangent + data->face_index * 16 + i2 * 4; + + /* the sign is the same at all face vertices for any non degenerate face. + * Just in case we clamp the interpolated value though. */ + sign = (tang0[3] * u + tang1[3] * v + tang2[3] * w) < 0 ? (-1.0f) : 1.0f; + + /* this sequence of math is designed specifically as is with great care + * to be compatible with our shader. Please don't change without good reason. */ + for (r = 0; r < 3; r++) { + from_tang[0][r] = tang0[r] * u + tang1[r] * v + tang2[r] * w; + from_tang[2][r] = no0[r] * u + no1[r] * v + no2[r] * w; + } + + cross_v3_v3v3(from_tang[1], from_tang[2], from_tang[0]); /* B = sign * cross(N, T) */ + mul_v3_fl(from_tang[1], sign); + invert_m3_m3(to_tang, from_tang); + } + else { + zero_m3(to_tang); + } + + data->pass_data(data->lores_dm, data->hires_dm, data->bake_data, + data->ibuf, data->face_index, data->lvl, st, to_tang, x, y); +} + +static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y) +{ + const int w = bake_rast->w; + const int h = bake_rast->h; + + if (x >= 0 && x < w && y >= 0 && y < h) { + if ((bake_rast->texels[y * w + x]) == 0) { + flush_pixel(bake_rast->data, x, y); + bake_rast->texels[y * w + x] = FILTER_MASK_USED; + } + } +} + +static void rasterize_half(const MBakeRast *bake_rast, + const float s0_s, const float t0_s, const float s1_s, const float t1_s, + const float s0_l, const float t0_l, const float s1_l, const float t1_l, + const int y0_in, const int y1_in, const int is_mid_right) +{ + const int s_stable = fabsf(t1_s - t0_s) > FLT_EPSILON ? 1 : 0; + const int l_stable = fabsf(t1_l - t0_l) > FLT_EPSILON ? 1 : 0; + const int w = bake_rast->w; + const int h = bake_rast->h; + int y, y0, y1; + + if (y1_in <= 0 || y0_in >= h) + return; + + y0 = y0_in < 0 ? 0 : y0_in; + y1 = y1_in >= h ? h : y1_in; + + for (y = y0; y < y1; y++) { + /*-b(x-x0) + a(y-y0) = 0 */ + int iXl, iXr, x; + float x_l = s_stable != 0 ? (s0_s + (((s1_s - s0_s) * (y - t0_s)) / (t1_s - t0_s))) : s0_s; + float x_r = l_stable != 0 ? (s0_l + (((s1_l - s0_l) * (y - t0_l)) / (t1_l - t0_l))) : s0_l; + + if (is_mid_right != 0) + SWAP(float, x_l, x_r); + + iXl = (int)ceilf(x_l); + iXr = (int)ceilf(x_r); + + if (iXr > 0 && iXl < w) { + iXl = iXl < 0 ? 0 : iXl; + iXr = iXr >= w ? w : iXr; + + for (x = iXl; x < iXr; x++) + set_rast_triangle(bake_rast, x, y); + } + } +} + +static void bake_rasterize(const MBakeRast *bake_rast, const float st0_in[2], const float st1_in[2], const float st2_in[2]) +{ + const int w = bake_rast->w; + const int h = bake_rast->h; + float slo = st0_in[0] * w - 0.5f; + float tlo = st0_in[1] * h - 0.5f; + float smi = st1_in[0] * w - 0.5f; + float tmi = st1_in[1] * h - 0.5f; + float shi = st2_in[0] * w - 0.5f; + float thi = st2_in[1] * h - 0.5f; + int is_mid_right = 0, ylo, yhi, yhi_beg; + + /* skip degenerates */ + if ((slo == smi && tlo == tmi) || (slo == shi && tlo == thi) || (smi == shi && tmi == thi)) + return; + + /* sort by T */ + if (tlo > tmi && tlo > thi) { + SWAP(float, shi, slo); + SWAP(float, thi, tlo); + } + else if (tmi > thi) { + SWAP(float, shi, smi); + SWAP(float, thi, tmi); + } + + if (tlo > tmi) { + SWAP(float, slo, smi); + SWAP(float, tlo, tmi); + } + + /* check if mid point is to the left or to the right of the lo-hi edge */ + is_mid_right = (-(shi - slo) * (tmi - thi) + (thi - tlo) * (smi - shi)) > 0 ? 1 : 0; + ylo = (int) ceilf(tlo); + yhi_beg = (int) ceilf(tmi); + yhi = (int) ceilf(thi); + + /*if (fTmi>ceilf(fTlo))*/ + rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right); + rasterize_half(bake_rast, smi, tmi, shi, thi, slo, tlo, shi, thi, yhi_beg, yhi, is_mid_right); +} + +static int multiresbake_test_break(MultiresBakeRender *bkr) +{ + if (!bkr->stop) { + /* this means baker is executed outside from job system */ + return 0; + } + + return G.is_break; +} + +static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, int require_tangent, MPassKnownData passKnownData, + MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData) +{ + DerivedMesh *dm = bkr->lores_dm; + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + const int lvl = bkr->lvl; + const int tot_face = dm->getNumTessFaces(dm); + MVert *mvert = dm->getVertArray(dm); + MFace *mface = dm->getTessFaceArray(dm); + MTFace *mtface = dm->getTessFaceDataArray(dm, CD_MTFACE); + float *pvtangent = NULL; + + if (require_tangent) { + if (CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1) + DM_add_tangent_layer(dm); + + pvtangent = DM_get_tessface_data_layer(dm, CD_TANGENT); + } + + if (tot_face > 0) { /* sanity check */ + int f = 0; + MBakeRast bake_rast; + MResolvePixelData data = {NULL}; + + data.mface = mface; + data.mvert = mvert; + data.mtface = mtface; + data.pvtangent = pvtangent; + data.precomputed_normals = dm->getTessFaceDataArray(dm, CD_NORMAL); /* don't strictly need this */ + data.w = ibuf->x; + data.h = ibuf->y; + data.lores_dm = dm; + data.hires_dm = bkr->hires_dm; + data.lvl = lvl; + data.pass_data = passKnownData; + + if (initBakeData) + data.bake_data = initBakeData(bkr, ima); + + init_bake_rast(&bake_rast, ibuf, &data, flush_pixel); + + for (f = 0; f < tot_face; f++) { + MTFace *mtfate = &mtface[f]; + int verts[3][2], nr_tris, t; + + if (multiresbake_test_break(bkr)) + break; + + if (mtfate->tpage != ima) + continue; + + data.face_index = f; + data.ibuf = ibuf; + + /* might support other forms of diagonal splits later on such as + * split by shortest diagonal.*/ + verts[0][0] = 0; + verts[1][0] = 1; + verts[2][0] = 2; + + verts[0][1] = 0; + verts[1][1] = 2; + verts[2][1] = 3; + + nr_tris = mface[f].v4 != 0 ? 2 : 1; + for (t = 0; t < nr_tris; t++) { + data.i0 = verts[0][t]; + data.i1 = verts[1][t]; + data.i2 = verts[2][t]; + + bake_rasterize(&bake_rast, mtfate->uv[data.i0], mtfate->uv[data.i1], mtfate->uv[data.i2]); + + if (ibuf->rect_float) + ibuf->userflags |= IB_RECT_INVALID; + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + } + + bkr->baked_faces++; + + if (bkr->do_update) + *bkr->do_update = TRUE; + + if (bkr->progress) + *bkr->progress = ((float)bkr->baked_objects + (float)bkr->baked_faces / tot_face) / bkr->tot_obj; + } + + if (applyBakeData) + applyBakeData(data.bake_data); + + if (freeBakeData) + freeBakeData(data.bake_data); + } + + BKE_image_release_ibuf(ima, ibuf, NULL); +} + +/* mode = 0: interpolate normals, + * mode = 1: interpolate coord */ +static void interp_bilinear_grid(CCGKey *key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3]) +{ + int x0, x1, y0, y1; + float u, v; + float data[4][3]; + + x0 = (int) crn_x; + x1 = x0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (x0 + 1); + + y0 = (int) crn_y; + y1 = y0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (y0 + 1); + + u = crn_x - x0; + v = crn_y - y0; + + if (mode == 0) { + copy_v3_v3(data[0], CCG_grid_elem_no(key, grid, x0, y0)); + copy_v3_v3(data[1], CCG_grid_elem_no(key, grid, x1, y0)); + copy_v3_v3(data[2], CCG_grid_elem_no(key, grid, x1, y1)); + copy_v3_v3(data[3], CCG_grid_elem_no(key, grid, x0, y1)); + } + else { + copy_v3_v3(data[0], CCG_grid_elem_co(key, grid, x0, y0)); + copy_v3_v3(data[1], CCG_grid_elem_co(key, grid, x1, y0)); + copy_v3_v3(data[2], CCG_grid_elem_co(key, grid, x1, y1)); + copy_v3_v3(data[3], CCG_grid_elem_co(key, grid, x0, y1)); + } + + interp_bilinear_quad_v3(data, u, v, res); +} + +static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, + const int *index_mf_to_mpoly, const int *index_mp_to_orig, + const int lvl, const int face_index, const float u, const float v, float co[3], float n[3]) +{ + MFace mface; + CCGElem **grid_data; + CCGKey key; + float crn_x, crn_y; + int grid_size, S, face_side; + int *grid_offset, g_index; + + lodm->getTessFace(lodm, face_index, &mface); + + grid_size = hidm->getGridSize(hidm); + grid_data = hidm->getGridData(hidm); + grid_offset = hidm->getGridOffset(hidm); + hidm->getGridKey(hidm, &key); + + face_side = (grid_size << 1) - 1; + + if (lvl == 0) { + g_index = grid_offset[face_index]; + S = mdisp_rot_face_to_crn(mface.v4 ? 4 : 3, face_side, u * (face_side - 1), v * (face_side - 1), &crn_x, &crn_y); + } + else { + int side = (1 << (lvl - 1)) + 1; + int grid_index = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, face_index); + int loc_offs = face_index % (1 << (2 * lvl)); + int cell_index = loc_offs % ((side - 1) * (side - 1)); + int cell_side = (grid_size - 1) / (side - 1); + int row = cell_index / (side - 1); + int col = cell_index % (side - 1); + + S = face_index / (1 << (2 * (lvl - 1))) - grid_offset[grid_index]; + g_index = grid_offset[grid_index]; + + crn_y = (row * cell_side) + u * cell_side; + crn_x = (col * cell_side) + v * cell_side; + } + + CLAMP(crn_x, 0.0f, grid_size); + CLAMP(crn_y, 0.0f, grid_size); + + if (n != NULL) + interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 0, n); + + if (co != NULL) + interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 1, co); +} + +/* mode = 0: interpolate normals, + * mode = 1: interpolate coord */ +static void interp_bilinear_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3]) +{ + float data[4][3]; + + if (mode == 0) { + dm->getVertNo(dm, mface->v1, data[0]); + dm->getVertNo(dm, mface->v2, data[1]); + dm->getVertNo(dm, mface->v3, data[2]); + dm->getVertNo(dm, mface->v4, data[3]); + } + else { + dm->getVertCo(dm, mface->v1, data[0]); + dm->getVertCo(dm, mface->v2, data[1]); + dm->getVertCo(dm, mface->v3, data[2]); + dm->getVertCo(dm, mface->v4, data[3]); + } + + interp_bilinear_quad_v3(data, u, v, res); +} + +/* mode = 0: interpolate normals, + * mode = 1: interpolate coord */ +static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3]) +{ + float data[3][3]; + + if (mode == 0) { + dm->getVertNo(dm, mface->v1, data[0]); + dm->getVertNo(dm, mface->v2, data[1]); + dm->getVertNo(dm, mface->v3, data[2]); + } + else { + dm->getVertCo(dm, mface->v1, data[0]); + dm->getVertCo(dm, mface->v2, data[1]); + dm->getVertCo(dm, mface->v3, data[2]); + } + + interp_barycentric_tri_v3(data, u, v, res); +} + +/* **************** Displacement Baker **************** */ + +static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) +{ + MHeightBakeData *height_data; + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + DerivedMesh *lodm = bkr->lores_dm; + + height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData"); + + height_data->ima = ima; + height_data->heights = MEM_callocN(sizeof(float) * ibuf->x * ibuf->y, "MultiresBake heights"); + height_data->height_max = -FLT_MAX; + height_data->height_min = FLT_MAX; + + if (!bkr->use_lores_mesh) { + SubsurfModifierData smd = {{NULL}}; + int ss_lvl = bkr->tot_lvl - bkr->lvl; + + CLAMP(ss_lvl, 0, 6); + + if (ss_lvl > 0) { + smd.levels = smd.renderLevels = ss_lvl; + smd.flags |= eSubsurfModifierFlag_SubsurfUv; + + if (bkr->simple) + smd.subdivType = ME_SIMPLE_SUBSURF; + + height_data->ssdm = subsurf_make_derived_from_derived(bkr->lores_dm, &smd, NULL, 0); + } + } + + height_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX); + height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); + + BKE_image_release_ibuf(ima, ibuf, NULL); + + return (void *)height_data; +} + +static void apply_heights_data(void *bake_data) +{ + MHeightBakeData *height_data = (MHeightBakeData *)bake_data; + ImBuf *ibuf = BKE_image_acquire_ibuf(height_data->ima, NULL, NULL); + int x, y, i; + float height, *heights = height_data->heights; + float min = height_data->height_min, max = height_data->height_max; + + for (x = 0; x < ibuf->x; x++) { + for (y = 0; y < ibuf->y; y++) { + i = ibuf->x * y + x; + + if (((char *)ibuf->userdata)[i] != FILTER_MASK_USED) + continue; + + if (ibuf->rect_float) { + float *rrgbf = ibuf->rect_float + i * 4; + + if (max - min > 1e-5f) height = (heights[i] - min) / (max - min); + else height = 0; + + rrgbf[0] = rrgbf[1] = rrgbf[2] = height; + } + else { + char *rrgb = (char *)ibuf->rect + i * 4; + + if (max - min > 1e-5f) height = (heights[i] - min) / (max - min); + else height = 0; + + rrgb[0] = rrgb[1] = rrgb[2] = FTOCHAR(height); + } + } + } + + if (ibuf->rect_float) + ibuf->userflags |= IB_RECT_INVALID; + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + + BKE_image_release_ibuf(height_data->ima, ibuf, NULL); +} + +static void free_heights_data(void *bake_data) +{ + MHeightBakeData *height_data = (MHeightBakeData *)bake_data; + + if (height_data->ssdm) + height_data->ssdm->release(height_data->ssdm); + + MEM_freeN(height_data->heights); + MEM_freeN(height_data); +} + +/* MultiresBake callback for heights baking + * general idea: + * - find coord of point with specified UV in hi-res mesh (let's call it p1) + * - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res + * mesh to make texture smoother) let's call this point p0 and n. + * - height wound be dot(n, p1-p0) */ +static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data, + ImBuf *ibuf, const int face_index, const int lvl, const float st[2], + float UNUSED(tangmat[3][3]), const int x, const int y) +{ + MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE); + MFace mface; + MHeightBakeData *height_data = (MHeightBakeData *)bake_data; + float uv[2], *st0, *st1, *st2, *st3; + int pixel = ibuf->x * y + x; + float vec[3], p0[3], p1[3], n[3], len; + + lores_dm->getTessFace(lores_dm, face_index, &mface); + + st0 = mtface[face_index].uv[0]; + st1 = mtface[face_index].uv[1]; + st2 = mtface[face_index].uv[2]; + + if (mface.v4) { + st3 = mtface[face_index].uv[3]; + resolve_quad_uv(uv, st, st0, st1, st2, st3); + } + else + resolve_tri_uv(uv, st, st0, st1, st2); + + CLAMP(uv[0], 0.0f, 1.0f); + CLAMP(uv[1], 0.0f, 1.0f); + + get_ccgdm_data(lores_dm, hires_dm, + height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly, + lvl, face_index, uv[0], uv[1], p1, 0); + + if (height_data->ssdm) { + get_ccgdm_data(lores_dm, height_data->ssdm, + height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly, + 0, face_index, uv[0], uv[1], p0, n); + } + else { + lores_dm->getTessFace(lores_dm, face_index, &mface); + + if (mface.v4) { + interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 1, p0); + interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 0, n); + } + else { + interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 1, p0); + interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 0, n); + } + } + + sub_v3_v3v3(vec, p1, p0); + len = dot_v3v3(n, vec); + + height_data->heights[pixel] = len; + if (len < height_data->height_min) height_data->height_min = len; + if (len > height_data->height_max) height_data->height_max = len; + + if (ibuf->rect_float) { + float *rrgbf = ibuf->rect_float + pixel * 4; + rrgbf[3] = 1.0f; + } + else { + char *rrgb = (char *)ibuf->rect + pixel * 4; + rrgb[3] = 255; + } +} + +/* **************** Normal Maps Baker **************** */ + +static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima)) +{ + MNormalBakeData *normal_data; + DerivedMesh *lodm = bkr->lores_dm; + + normal_data = MEM_callocN(sizeof(MNormalBakeData), "MultiresBake normalData"); + + normal_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX); + normal_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); + + return (void *)normal_data; +} + +static void free_normal_data(void *bake_data) +{ + MNormalBakeData *normal_data = (MNormalBakeData *)bake_data; + + MEM_freeN(normal_data); +} + +/* MultiresBake callback for normals' baking + * general idea: + * - find coord and normal of point with specified UV in hi-res mesh + * - multiply it by tangmat + * - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */ +static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data, + ImBuf *ibuf, const int face_index, const int lvl, const float st[2], + float tangmat[3][3], const int x, const int y) +{ + MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE); + MFace mface; + MNormalBakeData *normal_data = (MNormalBakeData *)bake_data; + float uv[2], *st0, *st1, *st2, *st3; + int pixel = ibuf->x * y + x; + float n[3], vec[3], tmp[3] = {0.5, 0.5, 0.5}; + + lores_dm->getTessFace(lores_dm, face_index, &mface); + + st0 = mtface[face_index].uv[0]; + st1 = mtface[face_index].uv[1]; + st2 = mtface[face_index].uv[2]; + + if (mface.v4) { + st3 = mtface[face_index].uv[3]; + resolve_quad_uv(uv, st, st0, st1, st2, st3); + } + else + resolve_tri_uv(uv, st, st0, st1, st2); + + CLAMP(uv[0], 0.0f, 1.0f); + CLAMP(uv[1], 0.0f, 1.0f); + + get_ccgdm_data(lores_dm, hires_dm, + normal_data->orig_index_mf_to_mpoly, normal_data->orig_index_mp_to_orig, + lvl, face_index, uv[0], uv[1], NULL, n); + + mul_v3_m3v3(vec, tangmat, n); + normalize_v3(vec); + mul_v3_fl(vec, 0.5); + add_v3_v3(vec, tmp); + + if (ibuf->rect_float) { + float *rrgbf = ibuf->rect_float + pixel * 4; + rrgbf[0] = vec[0]; + rrgbf[1] = vec[1]; + rrgbf[2] = vec[2]; + rrgbf[3] = 1.0f; + } + else { + unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4; + rgb_float_to_uchar(rrgb, vec); + rrgb[3] = 255; + } +} + +/* **************** Ambient Occlusion Baker **************** */ + +#define MAX_NUMBER_OF_AO_RAYS 1024 + +static unsigned short ao_random_table_1[MAX_NUMBER_OF_AO_RAYS]; +static unsigned short ao_random_table_2[MAX_NUMBER_OF_AO_RAYS]; + +static void init_ao_random(void) +{ + int i; + + for (i = 0; i < MAX_NUMBER_OF_AO_RAYS; i++) { + ao_random_table_1[i] = rand() & 0xffff; + ao_random_table_2[i] = rand() & 0xffff; + } +} + +static unsigned short get_ao_random1(const int i) +{ + return ao_random_table_1[i & (MAX_NUMBER_OF_AO_RAYS - 1)]; +} + +static unsigned short get_ao_random2(const int i) +{ + return ao_random_table_2[i & (MAX_NUMBER_OF_AO_RAYS - 1)]; +} + +static void build_permutation_table(unsigned short permutation[], unsigned short temp_permutation[], + const int number_of_rays, const int is_first_perm_table) +{ + int i, k; + + for (i = 0; i < number_of_rays; i++) + temp_permutation[i] = i; + + for (i = 0; i < number_of_rays; i++) { + const unsigned int nr_entries_left = number_of_rays - i; + unsigned short rnd = is_first_perm_table != FALSE ? get_ao_random1(i) : get_ao_random2(i); + const unsigned short entry = rnd % nr_entries_left; + + /* pull entry */ + permutation[i] = temp_permutation[entry]; + + /* delete entry */ + for(k = entry; k < nr_entries_left - 1; k++) + temp_permutation[k] = temp_permutation[k + 1]; + } + + /* verify permutation table + * every entry must appear exactly once + */ +#if 0 + for(i = 0; i < number_of_rays; i++) temp_permutation[i] = 0; + for(i = 0; i < number_of_rays; i++) ++temp_permutation[permutation[i]]; + for(i = 0; i < number_of_rays; i++) BLI_assert(temp_permutation[i] == 1); +#endif +} + +static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data) +{ + DerivedMesh *hidm = bkr->hires_dm; + RayObject *raytree; + RayFace *face; + CCGElem **grid_data; + CCGKey key; + int num_grids, grid_size, face_side, num_faces; + int i; + + num_grids = hidm->getNumGrids(hidm); + grid_size = hidm->getGridSize(hidm); + grid_data = hidm->getGridData(hidm); + hidm->getGridKey(hidm, &key); + + face_side = (grid_size << 1) - 1; + num_faces = num_grids * (grid_size - 1) * (grid_size - 1); + + raytree = ao_data->raytree = RE_rayobject_create(bkr->raytrace_structure, num_faces, bkr->octree_resolution); + face = ao_data->rayfaces = (RayFace *) MEM_callocN(num_faces * sizeof(RayFace), "ObjectRen faces"); + + for (i = 0; i < num_grids; i++) { + int x, y; + for (x = 0; x < grid_size - 1; x++) { + for (y = 0; y < grid_size - 1; y++) { + float co[4][3]; + + copy_v3_v3(co[0], CCG_grid_elem_co(&key, grid_data[i], x, y)); + copy_v3_v3(co[1], CCG_grid_elem_co(&key, grid_data[i], x, y + 1)); + copy_v3_v3(co[2], CCG_grid_elem_co(&key, grid_data[i], x + 1, y + 1)); + copy_v3_v3(co[3], CCG_grid_elem_co(&key, grid_data[i], x + 1, y)); + + RE_rayface_from_coords(face, ao_data, face, co[0], co[1], co[2], co[3]); + RE_rayobject_add(raytree, RE_rayobject_unalignRayFace(face)); + + face++; + } + } + } + + RE_rayobject_done(raytree); +} + +static void *init_ao_data(MultiresBakeRender *bkr, Image *UNUSED(ima)) +{ + MAOBakeData *ao_data; + DerivedMesh *lodm = bkr->lores_dm; + unsigned short *temp_permutation_table; + size_t permutation_size; + + init_ao_random(); + + ao_data = MEM_callocN(sizeof(MAOBakeData), "MultiresBake aoData"); + + ao_data->number_of_rays = bkr->number_of_rays; + ao_data->bias = bkr->bias; + + ao_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX); + ao_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); + + create_ao_raytree(bkr, ao_data); + + /* initialize permutation tables */ + permutation_size = sizeof(unsigned short) * bkr->number_of_rays; + ao_data->permutation_table_1 = MEM_callocN(permutation_size, "multires AO baker perm1"); + ao_data->permutation_table_2 = MEM_callocN(permutation_size, "multires AO baker perm2"); + temp_permutation_table = MEM_callocN(permutation_size, "multires AO baker temp perm"); + + build_permutation_table(ao_data->permutation_table_1, temp_permutation_table, bkr->number_of_rays, 1); + build_permutation_table(ao_data->permutation_table_2, temp_permutation_table, bkr->number_of_rays, 0); + + MEM_freeN(temp_permutation_table); + + return (void *)ao_data; +} + +static void free_ao_data(void *bake_data) +{ + MAOBakeData *ao_data = (MAOBakeData *) bake_data; + + RE_rayobject_free(ao_data->raytree); + MEM_freeN(ao_data->rayfaces); + + MEM_freeN(ao_data->permutation_table_1); + MEM_freeN(ao_data->permutation_table_2); + + MEM_freeN(ao_data); +} + +/* builds an X and a Y axis from the given Z axis */ +static void build_coordinate_frame(float axisX[3], float axisY[3], const float axisZ[3]) +{ + const float faX = fabsf(axisZ[0]); + const float faY = fabsf(axisZ[1]); + const float faZ = fabsf(axisZ[2]); + + if (faX <= faY && faX <= faZ) { + const float len = sqrtf(axisZ[1] * axisZ[1] + axisZ[2] * axisZ[2]); + axisY[0] = 0; axisY[1] = axisZ[2] / len; axisY[2] = -axisZ[1] / len; + cross_v3_v3v3(axisX, axisY, axisZ); + } + else if (faY <= faZ) { + const float len = sqrtf(axisZ[0] * axisZ[0] + axisZ[2] * axisZ[2]); + axisX[0] = axisZ[2] / len; axisX[1] = 0; axisX[2] = -axisZ[0] / len; + cross_v3_v3v3(axisY, axisZ, axisX); + } + else { + const float len = sqrtf(axisZ[0] * axisZ[0] + axisZ[1] * axisZ[1]); + axisX[0] = axisZ[1] / len; axisX[1] = -axisZ[0] / len; axisX[2] = 0; + cross_v3_v3v3(axisY, axisZ, axisX); + } +} + +/* return FALSE if nothing was hit and TRUE otherwise */ +static int trace_ao_ray(MAOBakeData *ao_data, float ray_start[3], float ray_direction[3]) +{ + Isect isect = {{0}}; + + isect.dist = RE_RAYTRACE_MAXDIST; + copy_v3_v3(isect.start, ray_start); + copy_v3_v3(isect.dir, ray_direction); + isect.lay = -1; + + normalize_v3(isect.dir); + + return RE_rayobject_raycast(ao_data->raytree, &isect); +} + +static void apply_ao_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data, + ImBuf *ibuf, const int face_index, const int lvl, const float st[2], + float UNUSED(tangmat[3][3]), const int x, const int y) +{ + MAOBakeData *ao_data = (MAOBakeData *) bake_data; + MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE); + MFace mface; + + int i, k, perm_offs; + float pos[3], nrm[3]; + float cen[3]; + float axisX[3], axisY[3], axisZ[3]; + float shadow = 0; + float value; + int pixel = ibuf->x * y + x; + float uv[2], *st0, *st1, *st2, *st3; + + lores_dm->getTessFace(lores_dm, face_index, &mface); + + st0 = mtface[face_index].uv[0]; + st1 = mtface[face_index].uv[1]; + st2 = mtface[face_index].uv[2]; + + if (mface.v4) { + st3 = mtface[face_index].uv[3]; + resolve_quad_uv(uv, st, st0, st1, st2, st3); + } + else + resolve_tri_uv(uv, st, st0, st1, st2); + + CLAMP(uv[0], 0.0f, 1.0f); + CLAMP(uv[1], 0.0f, 1.0f); + + get_ccgdm_data(lores_dm, hires_dm, + ao_data->orig_index_mf_to_mpoly, ao_data->orig_index_mp_to_orig, + lvl, face_index, uv[0], uv[1], pos, nrm); + + /* offset ray origin by user bias along normal */ + for (i = 0; i < 3; i++) + cen[i] = pos[i] + ao_data->bias * nrm[i]; + + /* build tangent frame */ + for (i = 0; i < 3; i++) + axisZ[i] = nrm[i]; + + build_coordinate_frame(axisX, axisY, axisZ); + + /* static noise */ + perm_offs = (get_ao_random2(get_ao_random1(x) + y)) & (MAX_NUMBER_OF_AO_RAYS - 1); + + /* importance sample shadow rays (cosine weighted) */ + for (i = 0; i < ao_data->number_of_rays; i++) { + int hit_something; + + /* use N-Rooks to distribute our N ray samples across + * a multi-dimensional domain (2D) + */ + const unsigned short I = ao_random_table_1[(i + perm_offs) % ao_data->number_of_rays]; + const unsigned short J = ao_random_table_2[i]; + + const float JitPh = (get_ao_random2(I + perm_offs) & (MAX_NUMBER_OF_AO_RAYS-1))/((float) MAX_NUMBER_OF_AO_RAYS); + const float JitTh = (get_ao_random1(J + perm_offs) & (MAX_NUMBER_OF_AO_RAYS-1))/((float) MAX_NUMBER_OF_AO_RAYS); + const float SiSqPhi = (I + JitPh) / ao_data->number_of_rays; + const float Theta = 2 * M_PI * ((J + JitTh) / ao_data->number_of_rays); + + /* this gives results identical to the so-called cosine + * weighted distribution relative to the north pole. + */ + float SiPhi = sqrt(SiSqPhi); + float CoPhi = SiSqPhi < 1.0f ? sqrt(1.0f - SiSqPhi) : 1.0f - SiSqPhi; + float CoThe = cos(Theta); + float SiThe = sin(Theta); + + const float dx = CoThe * CoPhi; + const float dy = SiThe * CoPhi; + const float dz = SiPhi; + + /* transform ray direction out of tangent frame */ + float dv[3]; + for (k = 0; k < 3; k++) + dv[k] = axisX[k] * dx + axisY[k] * dy + axisZ[k] * dz; + + hit_something = trace_ao_ray(ao_data, cen, dv); + + if (hit_something != 0) + shadow += 1; + } + + value = 1.0f - (shadow / ao_data->number_of_rays); + + if (ibuf->rect_float) { + float *rrgbf = ibuf->rect_float + pixel * 4; + rrgbf[0] = rrgbf[1] = rrgbf[2] = value; + rrgbf[3] = 1.0f; + } + else { + unsigned char *rrgb = (unsigned char *) ibuf->rect + pixel * 4; + rrgb[0] = rrgb[1] = rrgb[2] = FTOCHAR(value); + rrgb[3] = 255; + } +} + +/* **************** Common functions public API relates on **************** */ + +static void count_images(MultiresBakeRender *bkr) +{ + int a, totface; + DerivedMesh *dm = bkr->lores_dm; + MTFace *mtface = CustomData_get_layer(&dm->faceData, CD_MTFACE); + + bkr->image.first = bkr->image.last = NULL; + bkr->tot_image = 0; + + totface = dm->getNumTessFaces(dm); + + for (a = 0; a < totface; a++) + mtface[a].tpage->id.flag &= ~LIB_DOIT; + + for (a = 0; a < totface; a++) { + Image *ima = mtface[a].tpage; + if ((ima->id.flag & LIB_DOIT) == 0) { + LinkData *data = BLI_genericNodeN(ima); + BLI_addtail(&bkr->image, data); + bkr->tot_image++; + ima->id.flag |= LIB_DOIT; + } + } + + for (a = 0; a < totface; a++) + mtface[a].tpage->id.flag &= ~LIB_DOIT; +} + +static void bake_images(MultiresBakeRender *bkr) +{ + LinkData *link; + + for (link = bkr->image.first; link; link = link->next) { + Image *ima = (Image *)link->data; + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + + if (ibuf->x > 0 && ibuf->y > 0) { + ibuf->userdata = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask"); + + switch (bkr->mode) { + case RE_BAKE_NORMALS: + do_multires_bake(bkr, ima, TRUE, apply_tangmat_callback, init_normal_data, NULL, free_normal_data); + break; + case RE_BAKE_DISPLACEMENT: + do_multires_bake(bkr, ima, FALSE, apply_heights_callback, init_heights_data, + apply_heights_data, free_heights_data); + break; + case RE_BAKE_AO: + do_multires_bake(bkr, ima, FALSE, apply_ao_callback, init_ao_data, NULL, free_ao_data); + break; + } + } + + BKE_image_release_ibuf(ima, ibuf, NULL); + + ima->id.flag |= LIB_DOIT; + } +} + +static void finish_images(MultiresBakeRender *bkr) +{ + LinkData *link; + + for (link = bkr->image.first; link; link = link->next) { + Image *ima = (Image *)link->data; + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + + if (ibuf->x <= 0 || ibuf->y <= 0) + continue; + + RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter); + + ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID; + + if (ibuf->rect_float) + ibuf->userflags |= IB_RECT_INVALID; + + if (ibuf->mipmap[0]) { + ibuf->userflags |= IB_MIPMAP_INVALID; + imb_freemipmapImBuf(ibuf); + } + + if (ibuf->userdata) { + MEM_freeN(ibuf->userdata); + ibuf->userdata = NULL; + } + + BKE_image_release_ibuf(ima, ibuf, NULL); + } +} + +void RE_multires_bake_images(MultiresBakeRender *bkr) +{ + count_images(bkr); + bake_images(bkr); + finish_images(bkr); +} diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 24b0830e651..39df6a01f61 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -585,7 +585,7 @@ void RE_SetOrtho(Render *re, rctf *viewplane, float clipsta, float clipend) re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend); } -void RE_SetView(Render *re, float mat[][4]) +void RE_SetView(Render *re, float mat[4][4]) { /* re->ok flag? */ copy_m4_m4(re->viewmat, mat); @@ -947,6 +947,9 @@ static void add_freestyle(Render *re); static void do_render_3d(Render *re) { + float cfra; + int cfra_backup; + /* try external */ if (RE_engine_render(re, 0)) return; @@ -954,9 +957,13 @@ static void do_render_3d(Render *re) /* internal */ RE_parts_clamp(re); -// re->cfra= cfra; /* <- unused! */ - re->scene->r.subframe = re->mblur_offs + re->field_offs; - + /* add motion blur and fields offset to frames */ + cfra_backup = re->scene->r.cfra; + + cfra = re->scene->r.cfra + re->mblur_offs + re->field_offs; + re->scene->r.cfra = floorf(cfra); + re->scene->r.subframe = cfra - floorf(cfra); + /* lock drawing in UI during data phase */ if (re->draw_lock) re->draw_lock(re->dlh, 1); @@ -986,6 +993,7 @@ static void do_render_3d(Render *re) /* free all render verts etc */ RE_Database_Free(re); + re->scene->r.cfra = cfra_backup; re->scene->r.subframe = 0.f; } diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c index 74de8a1291f..21ff1151cfb 100644 --- a/source/blender/render/intern/source/pixelblending.c +++ b/source/blender/render/intern/source/pixelblending.c @@ -206,7 +206,7 @@ void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int ro } -void mask_array(unsigned int mask, float filt[][3]) +void mask_array(unsigned int mask, float filt[3][3]) { float **fmask1 = R.samples->fmask1, **fmask2 = R.samples->fmask2; unsigned int maskand = (mask & 255); @@ -244,7 +244,7 @@ void mask_array(unsigned int mask, float filt[][3]) * </pre> */ -void add_filt_fmask_coord(float filt[][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y) +void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y) { float *fpoin[3][3]; float val, r, g, b, al, lfilt[3][3]; diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index a540cdb85d5..3ca4015ff7b 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -447,7 +447,7 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) turb = BLI_gTurbulence(pd->noise_size, texvec[0]+age, texvec[1]+age, texvec[2]+age, pd->noise_depth, 0, pd->noise_basis); } else if (pd->noise_influence == TEX_PD_NOISE_TIME) { - time = R.cfra / (float)R.r.efra; + time = R.r.cfra / (float)R.r.efra; turb = BLI_gTurbulence(pd->noise_size, texvec[0]+time, texvec[1]+time, texvec[2]+time, pd->noise_depth, 0, pd->noise_basis); //turb = BLI_turbulence(pd->noise_size, texvec[0]+time, texvec[1]+time, texvec[2]+time, pd->noise_depth); } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 127e0bc07b9..fb9eb59cbbf 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -94,7 +94,7 @@ static void RE_rayobject_config_control(RayObject *r, Render *re) } } -static RayObject* RE_rayobject_create(Render *re, int type, int size) +RayObject *RE_rayobject_create(int type, int size, int octree_resolution) { RayObject * res = NULL; @@ -117,7 +117,7 @@ static RayObject* RE_rayobject_create(Render *re, int type, int size) if (type == R_RAYSTRUCTURE_OCTREE) //TODO dynamic ocres - res = RE_rayobject_octree_create(re->r.ocres, size); + res = RE_rayobject_octree_create(octree_resolution, size); else if (type == R_RAYSTRUCTURE_BLIBVH) res = RE_rayobject_blibvh_create(size); else if (type == R_RAYSTRUCTURE_VBVH) @@ -129,10 +129,18 @@ static RayObject* RE_rayobject_create(Render *re, int type, int size) else res = RE_rayobject_vbvh_create(size); //Fallback + return res; +} + +static RayObject* rayobject_create(Render *re, int type, int size) +{ + RayObject * res = NULL; + + res = RE_rayobject_create(type, size, re->r.ocres); if (res) RE_rayobject_config_control(res, re); - + return res; } @@ -240,7 +248,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) return NULL; //Create Ray cast accelaration structure - raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces ); + raytree = rayobject_create( re, re->r.raytrace_structure, faces ); if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) vlakprimitive = obr->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "ObjectRen primitives"); else @@ -334,7 +342,7 @@ static void makeraytree_single(Render *re) } //Create raytree - raytree = re->raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces+special ); + raytree = re->raytree = rayobject_create( re, re->r.raytrace_structure, faces+special ); if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) { vlakprimitive = re->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "Raytrace vlak-primitives"); diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 3431c3ff5de..bd0061c0e68 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2795,4 +2795,3 @@ struct Image *RE_bake_shade_get_image(void) { return R.bakebuf; } - diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 44daaf516e1..e189d8bdaea 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -1221,7 +1221,9 @@ static int panotestclip(Render *re, int do_pano, float v[4]) * - shadow buffering (shadbuf.c) */ -void project_renderdata(Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int UNUSED(do_buckets)) +void project_renderdata(Render *re, + void (*projectfunc)(const float *, float mat[4][4], float *), + int do_pano, float xoffs, int UNUSED(do_buckets)) { ObjectRen *obr; HaloRen *har = NULL; @@ -1308,7 +1310,7 @@ void project_renderdata(Render *re, void (*projectfunc)(const float *, float mat /* ------------------------------------------------------------------------- */ -ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4], int lay) +ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[4][4], int lay) { ObjectInstanceRen *obi; float mat3[3][3]; @@ -1363,7 +1365,7 @@ void RE_makeRenderInstances(Render *re) re->instancetable= newlist; } -int clip_render_object(float boundbox[][3], float bounds[4], float winmat[][4]) +int clip_render_object(float boundbox[2][3], float bounds[4], float winmat[4][4]) { float mat[4][4], vec[4]; int a, fl, flag = -1; diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index a7f6b40981d..078c11a2061 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -1302,7 +1302,7 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3]) ShadBuf *shb= lar->shb; ShadSampleBuf *shsample; float co[4], siz; - float labda, labdao, labdax, labday, ldx, ldy; + float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy; float zf, xf1, yf1, zf1, xf2, yf2, zf2; float count, lightcount; int x, y, z, xs1, ys1; @@ -1336,68 +1336,68 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3]) if (xf1 != xf2) { if (xf2-xf1 > 0.0f) { - labdax= (xf1-xs1-1.0f)/(xf1-xf2); + lambda_x= (xf1-xs1-1.0f)/(xf1-xf2); ldx= -shb->shadhalostep/(xf1-xf2); dx= shb->shadhalostep; } else { - labdax= (xf1-xs1)/(xf1-xf2); + lambda_x= (xf1-xs1)/(xf1-xf2); ldx= shb->shadhalostep/(xf1-xf2); dx= -shb->shadhalostep; } } else { - labdax= 1.0; + lambda_x= 1.0; ldx= 0.0; } if (yf1 != yf2) { if (yf2-yf1 > 0.0f) { - labday= (yf1-ys1-1.0f)/(yf1-yf2); + lambda_y= (yf1-ys1-1.0f)/(yf1-yf2); ldy= -shb->shadhalostep/(yf1-yf2); dy= shb->shadhalostep; } else { - labday= (yf1-ys1)/(yf1-yf2); + lambda_y= (yf1-ys1)/(yf1-yf2); ldy= shb->shadhalostep/(yf1-yf2); dy= -shb->shadhalostep; } } else { - labday= 1.0; + lambda_y= 1.0; ldy= 0.0; } x= xs1; y= ys1; - labda= count= lightcount= 0.0; + lambda= count= lightcount= 0.0; /* printf("start %x %x \n", (int)(0x7FFFFFFF*zf1), (int)(0x7FFFFFFF*zf2)); */ while (1) { - labdao= labda; + lambda_o= lambda; - if (labdax==labday) { - labdax+= ldx; + if (lambda_x==lambda_y) { + lambda_x+= ldx; x+= dx; - labday+= ldy; + lambda_y+= ldy; y+= dy; } else { - if (labdax<labday) { - labdax+= ldx; + if (lambda_x<lambda_y) { + lambda_x+= ldx; x+= dx; } else { - labday+= ldy; + lambda_y+= ldy; y+= dy; } } - labda = min_ff(labdax, labday); - if (labda==labdao || labda>=1.0f) break; + lambda = min_ff(lambda_x, lambda_y); + if (lambda==lambda_o || lambda>=1.0f) break; - zf= zf1 + labda*(zf2-zf1); + zf= zf1 + lambda*(zf2-zf1); count+= (float)shb->totbuf; if (zf<= -1.0f) lightcount += 1.0f; /* close to the spot */ @@ -1686,21 +1686,21 @@ static int point_behind_strand(const float p[3], BSPFace *face) return 1; } else { - float labda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len; + float lambda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len; - if (labda > -face->radline_end && labda < 1.0f+face->radline_end) { + if (lambda > -face->radline_end && lambda < 1.0f+face->radline_end) { /* hesse for dist: */ //dist= (float)(fabs( (p[0]-vec2[0])*rc[1] + (p[1]-vec2[1])*rc[0])/len); - pt[0]= labda*face->rc[0]+face->vec1[0]; - pt[1]= labda*face->rc[1]+face->vec1[1]; + pt[0]= lambda*face->rc[0]+face->vec1[0]; + pt[1]= lambda*face->rc[1]+face->vec1[1]; rc[0]= pt[0]-p[0]; rc[1]= pt[1]-p[1]; dist= (float)sqrt(rc[0]*rc[0]+ rc[1]*rc[1]); if (dist < face->radline) { - float zval= face->vec1[2] + labda*face->rc[2]; + float zval= face->vec1[2] + lambda*face->rc[2]; if (p[2] > zval) return 1; } diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 2fe8adaa1ee..569bac29205 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -476,13 +476,13 @@ static int compare_strand_segment(const void *poin1, const void *poin2) return 1; } -static void do_strand_point_project(float winmat[][4], ZSpan *zspan, float *co, float *hoco, float *zco) +static void do_strand_point_project(float winmat[4][4], ZSpan *zspan, float *co, float *hoco, float *zco) { projectvert(co, winmat, hoco); hoco_to_zco(zspan, zco, hoco); } -static void strand_project_point(float winmat[][4], float winx, float winy, StrandPoint *spoint) +static void strand_project_point(float winmat[4][4], float winx, float winy, StrandPoint *spoint) { float div; @@ -603,7 +603,7 @@ static void do_strand_fillac(void *handle, int x, int y, float u, float v, float } /* width is calculated in hoco space, to ensure strands are visible */ -static int strand_test_clip(float winmat[][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy) +static int strand_test_clip(float winmat[4][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy) { float hoco[4]; int clipflag= 0; @@ -663,7 +663,7 @@ static void do_scanconvert_strand(Render *UNUSED(re), StrandPart *spart, ZSpan * zspan_scanconvert_strand(zspan, spart, jco1, jco3, jco4, do_strand_fillac); } -static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2) +static void strand_render(Render *re, StrandSegment *sseg, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2) { if (spart) { float t= p2->t; @@ -696,7 +696,7 @@ static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], St } } -static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth) +static int strand_segment_recursive(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth) { StrandPoint p; StrandBuffer *buffer= sseg->buffer; @@ -745,7 +745,7 @@ static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *s return 1; } -void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg) +void render_strand_segment(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg) { StrandBuffer *buffer= sseg->buffer; StrandPoint *p1= &sseg->point1; @@ -783,7 +783,7 @@ void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSp } /* render call to fill in strands */ -int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache) +int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache) { ObjectRen *obr; ObjectInstanceRen *obi; @@ -976,7 +976,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa /* *************** */ -StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[][4], int timeoffset) +StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[4][4], int timeoffset) { StrandSurface *mesh; MFace *mface; diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index c52fb84a7f8..2e1b23435e5 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -1600,8 +1600,8 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float * /** * (clip pyramid) - * Sets labda: flag, and parametrize the clipping of vertices in - * viewspace coordinates. labda = -1 means no clipping, labda in [0, 1] means a clipping. + * Sets lambda: flag, and parametrize the clipping of vertices in + * viewspace coordinates. lambda = -1 means no clipping, lambda in [0, 1] means a clipping. * Note: uses globals. * \param v1 start coordinate s * \param v2 target coordinate t @@ -1611,13 +1611,13 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float * * \param a index for coordinate (x, y, or z) */ -static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a, float clipcrop) +static void clippyra(float *lambda, float *v1, float *v2, int *b2, int *b3, int a, float clipcrop) { float da, dw, u1=0.0, u2=1.0; float v13; - labda[0]= -1.0; - labda[1]= -1.0; + lambda[0]= -1.0; + lambda[1]= -1.0; da= v2[a]-v1[a]; /* prob; we clip slightly larger, osa renders add 2 pixels on edges, should become variable? */ @@ -1641,16 +1641,16 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a if (cliptestf(da, -dw, v13, -v1[a], &u1, &u2)) { *b3=1; if (u2<1.0f) { - labda[1]= u2; + lambda[1]= u2; *b2=1; } - else labda[1]=1.0; /* u2 */ + else lambda[1]=1.0; /* u2 */ if (u1>0.0f) { - labda[0] = u1; + lambda[0] = u1; *b2 = 1; } else { - labda[0] = 0.0; + lambda[0] = 0.0; } } } @@ -1658,8 +1658,8 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a /** * (make vertex pyramide clip) - * Checks labda and uses this to make decision about clipping the line - * segment from v1 to v2. labda is the factor by which the vector is + * Checks lambda and uses this to make decision about clipping the line + * segment from v1 to v2. lambda is the factor by which the vector is * cut. ( calculate s + l * ( t - s )). The result is appended to the * vertex list of this face. * @@ -1671,12 +1671,12 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a * \param clve vertex vector. */ -static void makevertpyra(float *vez, float *labda, float **trias, float *v1, float *v2, int *b1, int *clve) +static void makevertpyra(float *vez, float *lambda, float **trias, float *v1, float *v2, int *b1, int *clve) { float l1, l2, *adr; - l1= labda[0]; - l2= labda[1]; + l1= lambda[0]; + l2= lambda[1]; if (l1!= -1.0f) { if (l1!= 0.0f) { @@ -1708,7 +1708,7 @@ static void makevertpyra(float *vez, float *labda, float **trias, float *v1, flo /* ------------------------------------------------------------------------- */ -void projectverto(const float v1[3], float winmat[][4], float adr[4]) +void projectverto(const float v1[3], float winmat[4][4], float adr[4]) { /* calcs homogenic coord of vertex v1 */ float x, y, z; @@ -1726,7 +1726,7 @@ void projectverto(const float v1[3], float winmat[][4], float adr[4]) /* ------------------------------------------------------------------------- */ -void projectvert(const float v1[3], float winmat[][4], float adr[4]) +void projectvert(const float v1[3], float winmat[4][4], float adr[4]) { /* calcs homogenic coord of vertex v1 */ float x, y, z; @@ -1761,7 +1761,7 @@ static void zbuf_project_cache_clear(ZbufProjectCache *cache, int size) cache[i].index= -1; } -static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[][4], float *co, float *ho) +static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[4][4], float *co, float *ho) { int cindex= index & 255; @@ -1790,7 +1790,7 @@ static void zbuffer_part_bounds(int winx, int winy, RenderPart *pa, float *bound bounds[3]= (2*pa->disprect.ymax - winy+1)/(float)winy; } -static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][4], float *bounds, float *co, float *ho) +static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[4][4], float *bounds, float *co, float *ho) { float vec[3]; int cindex= index & 255; @@ -1819,7 +1819,7 @@ static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][ } } -void zbuf_render_project(float winmat[][4], const float co[3], float ho[4]) +void zbuf_render_project(float winmat[4][4], const float co[3], float ho[4]) { float vec[3]; @@ -1827,7 +1827,7 @@ void zbuf_render_project(float winmat[][4], const float co[3], float ho[4]) projectvert(vec, winmat, ho); } -void zbuf_make_winmat(Render *re, float winmat[][4]) +void zbuf_make_winmat(Render *re, float winmat[4][4]) { if (re->r.mode & R_PANORAMA) { float panomat[4][4]= MAT4_UNITY; @@ -1847,7 +1847,7 @@ void zbuf_make_winmat(Render *re, float winmat[][4]) void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3) { - float *vlzp[32][3], labda[3][2]; + float *vlzp[32][3], lambda[3][2]; float vez[400], *trias[40]; if (c1 | c2 | c3) { /* not in middle */ @@ -1887,9 +1887,9 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, else if (b==1) arg= 0; else arg= 1; - clippyra(labda[0], vlzp[v][0], vlzp[v][1], &b2, &b3, arg, zspan->clipcrop); - clippyra(labda[1], vlzp[v][1], vlzp[v][2], &b2, &b3, arg, zspan->clipcrop); - clippyra(labda[2], vlzp[v][2], vlzp[v][0], &b2, &b3, arg, zspan->clipcrop); + clippyra(lambda[0], vlzp[v][0], vlzp[v][1], &b2, &b3, arg, zspan->clipcrop); + clippyra(lambda[1], vlzp[v][1], vlzp[v][2], &b2, &b3, arg, zspan->clipcrop); + clippyra(lambda[2], vlzp[v][2], vlzp[v][0], &b2, &b3, arg, zspan->clipcrop); if (b2==0 && b3==1) { /* completely 'in', but we copy because of last for () loop in this section */; @@ -1905,9 +1905,9 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, } else { b1=0; - makevertpyra(vez, labda[0], trias, vlzp[v][0], vlzp[v][1], &b1, &clve); - makevertpyra(vez, labda[1], trias, vlzp[v][1], vlzp[v][2], &b1, &clve); - makevertpyra(vez, labda[2], trias, vlzp[v][2], vlzp[v][0], &b1, &clve); + makevertpyra(vez, lambda[0], trias, vlzp[v][0], vlzp[v][1], &b1, &clve); + makevertpyra(vez, lambda[1], trias, vlzp[v][1], vlzp[v][2], &b1, &clve); + makevertpyra(vez, lambda[2], trias, vlzp[v][2], vlzp[v][0], &b1, &clve); /* after front clip done: now set clip flags */ if (b==0) { @@ -2296,7 +2296,7 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*, } } -void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int size, float jitx, float jity) +void zbuffer_shadow(Render *re, float winmat[4][4], LampRen *lar, int *rectz, int size, float jitx, float jity) { ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; ZSpan zspan; @@ -3261,7 +3261,7 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample) * Do accumulation z buffering. */ -static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float UNUSED(clipcrop), int shadow) +static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float UNUSED(clipcrop), int shadow) { ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; ZSpan zspans[16], *zspan; /* MAX_OSA */ @@ -3459,7 +3459,7 @@ static int zbuffer_abuf_render(RenderPart *pa, APixstr *APixbuf, APixstrand *APi return doztra; } -void zbuffer_abuf_shadow(Render *re, LampRen *lar, float winmat[][4], APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, int size, int samples, float (*jit)[2]) +void zbuffer_abuf_shadow(Render *re, LampRen *lar, float winmat[4][4], APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, int size, int samples, float (*jit)[2]) { RenderPart pa; int lay= -1; |