Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-12-19 05:49:58 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-12-19 05:49:58 +0400
commitd433cd65f7127d60e17d05a824290423ad226eae (patch)
treef0a9c821f6046e97b74c6969d41269b558fd52ab /source/blender/render
parent10f0f66560234a04aed3295c74fff20adacbc57f (diff)
parentf10dea7e3b9b431edae9c787fa1a9e09cd567ed7 (diff)
Merged changes in the trunk up to revision 53146.
Conflicts resolved: release/datafiles/startup.blend source/blender/blenkernel/CMakeLists.txt source/blender/blenlib/intern/bpath.c source/blender/blenloader/intern/readfile.c
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/CMakeLists.txt2
-rw-r--r--source/blender/render/SConscript28
-rw-r--r--source/blender/render/extern/include/RE_multires_bake.h61
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h6
-rw-r--r--source/blender/render/intern/include/pixelblending.h4
-rw-r--r--source/blender/render/intern/include/rayobject.h4
-rw-r--r--source/blender/render/intern/include/render_types.h1
-rw-r--r--source/blender/render/intern/include/rendercore.h2
-rw-r--r--source/blender/render/intern/include/renderdatabase.h6
-rw-r--r--source/blender/render/intern/include/strand.h4
-rw-r--r--source/blender/render/intern/include/zbuf.h14
-rw-r--r--source/blender/render/intern/raytrace/rayobject.cpp5
-rw-r--r--source/blender/render/intern/raytrace/rayobject_instance.cpp2
-rw-r--r--source/blender/render/intern/raytrace/rayobject_octree.cpp138
-rw-r--r--source/blender/render/intern/source/convertblender.c45
-rw-r--r--source/blender/render/intern/source/envmap.c48
-rw-r--r--source/blender/render/intern/source/initrender.c2
-rw-r--r--source/blender/render/intern/source/multires_bake.c1182
-rw-r--r--source/blender/render/intern/source/pipeline.c16
-rw-r--r--source/blender/render/intern/source/pixelblending.c4
-rw-r--r--source/blender/render/intern/source/pointdensity.c2
-rw-r--r--source/blender/render/intern/source/rayshade.c18
-rw-r--r--source/blender/render/intern/source/rendercore.c1
-rw-r--r--source/blender/render/intern/source/renderdatabase.c8
-rw-r--r--source/blender/render/intern/source/shadbuf.c46
-rw-r--r--source/blender/render/intern/source/strand.c16
-rw-r--r--source/blender/render/intern/source/zbuf.c60
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;