diff options
Diffstat (limited to 'source/blender/render/intern')
34 files changed, 609 insertions, 532 deletions
diff --git a/source/blender/render/intern/Makefile b/source/blender/render/intern/Makefile index 4fce37df175..4043902a40f 100644 --- a/source/blender/render/intern/Makefile +++ b/source/blender/render/intern/Makefile @@ -15,7 +15,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. # All rights reserved. diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 127fbce20eb..b124102f50b 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -55,6 +55,7 @@ struct RenderBuckets; struct ObjectInstanceRen; struct RayObject; struct RayFace; +struct Main; #define TABLEINITSIZE 1024 #define LAMPINITSIZE 256 @@ -170,7 +171,8 @@ struct Render /* shadow counter, detect shadow-reuse for shaders */ int shadowsamplenr[BLENDER_MAX_THREADS]; - /* scene, and its full copy of renderdata and world */ + /* main, scene, and its full copy of renderdata and world */ + struct Main *main; Scene *scene; RenderData r; World wrld; @@ -189,7 +191,8 @@ struct Render ListBase strandsurface; /* use this instead of R.r.cfra */ - float cfra; + float cfra; + float mblur_offs, field_offs; /* render database */ int totvlak, totvert, tothalo, totstrand, totlamp; @@ -234,8 +237,8 @@ struct Render void (*stats_draw)(void *handle, RenderStats *ri); void *sdh; - void (*timecursor)(void *handle, int i); - void *tch; + void (*progress)(void *handle, float i); + void *prh; int (*test_break)(void *handle); void *tbh; @@ -463,6 +466,7 @@ typedef struct VolPrecachePart struct RayObject *tree; struct ShadeInput *shi; struct ObjectInstanceRen *obi; + float viewmat[4][4]; int num; int minx, maxx; int miny, maxy; @@ -476,6 +480,7 @@ typedef struct VolPrecachePart typedef struct VolumePrecache { int res[3]; + float *bbmin, *bbmax; float *data_r; float *data_g; float *data_b; @@ -564,13 +569,6 @@ typedef struct LampRen { /* passes & node shader support: all shadow info for a pixel */ LampShadowSample *shadsamp; - - /* yafray: photonlight params */ - int YF_numphotons, YF_numsearch; - short YF_phdepth, YF_useqmc, YF_bufsize; - float YF_causticblur, YF_ltradius; - float YF_glowint, YF_glowofs; - short YF_glowtype; /* ray optim */ struct RayObject *last_hit[BLENDER_MAX_THREADS]; @@ -591,23 +589,21 @@ typedef struct LampRen { #define R_HALO 2 #define R_SEC_FIELD 4 #define R_LAMPHALO 8 -#define R_GLOB_NOPUNOFLIP 16 -#define R_NEED_TANGENT 32 -#define R_BAKE_TRACE 128 -#define R_BAKING 256 +#define R_NEED_TANGENT 16 +#define R_BAKE_TRACE 32 +#define R_BAKING 64 /* vlakren->flag (vlak = face in dutch) char!!! */ #define R_SMOOTH 1 #define R_HIDDEN 2 /* strand flag, means special handling */ #define R_STRAND 4 -#define R_NOPUNOFLIP 8 -#define R_FULL_OSA 16 -#define R_FACE_SPLIT 32 +#define R_FULL_OSA 8 +#define R_FACE_SPLIT 16 /* Tells render to divide face other way. */ -#define R_DIVIDE_24 64 +#define R_DIVIDE_24 32 /* vertex normals are tangent or view-corrected vector, for hair strands */ -#define R_TANGENT 128 +#define R_TANGENT 64 /* strandbuffer->flag */ #define R_STRAND_BSPLINE 1 diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index 2a0086b436c..4c80616665d 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -34,6 +34,7 @@ struct Object; struct VlakRen; struct VertRen; struct HaloRen; +struct Main; struct Material; struct Render; struct MCol; @@ -115,7 +116,7 @@ struct MCol *RE_vlakren_get_mcol(struct ObjectRen *obr, VlakRen *ren, int n, cha float *RE_vlakren_get_surfnor(struct ObjectRen *obr, VlakRen *ren, int verify); float *RE_vlakren_get_nmap_tangent(struct ObjectRen *obr, VlakRen *ren, int verify); RadFace **RE_vlakren_get_radface(struct ObjectRen *obr, VlakRen *ren, int verify); -int RE_vlakren_get_normal(struct Render *re, struct ObjectInstanceRen *obi, struct VlakRen *vlr, float *nor); +void RE_vlakren_get_normal(struct Render *re, struct ObjectInstanceRen *obi, struct VlakRen *vlr, float *nor); float *RE_strandren_get_surfnor(struct ObjectRen *obr, struct StrandRen *strand, int verify); float *RE_strandren_get_uv(struct ObjectRen *obr, struct StrandRen *strand, int n, char **name, int verify); @@ -137,7 +138,7 @@ void RE_set_customdata_names(struct ObjectRen *obr, struct CustomData *data); /* convertblender.c */ void init_render_world(Render *re); -void RE_Database_FromScene_Vectors(Render *re, struct Scene *sce, unsigned int lay); +void RE_Database_FromScene_Vectors(Render *re, struct Main *bmain, struct Scene *sce, unsigned int lay); #endif /* RENDERDATABASE_H */ diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h index 3e6fc8c5677..fb941d1b7f3 100644 --- a/source/blender/render/intern/include/texture.h +++ b/source/blender/render/intern/include/texture.h @@ -40,7 +40,13 @@ if(texres->tr<0.0) texres->tr= 0.0; \ texres->tg= tex->gfac*((texres->tg-0.5)*tex->contrast+tex->bright-0.5); \ if(texres->tg<0.0) texres->tg= 0.0; \ texres->tb= tex->bfac*((texres->tb-0.5)*tex->contrast+tex->bright-0.5); \ -if(texres->tb<0.0) texres->tb= 0.0; +if(texres->tb<0.0) texres->tb= 0.0; \ +if(tex->saturation != 1.0f) { \ + float _hsv[3]; \ + rgb_to_hsv(texres->tr, texres->tg, texres->tb, _hsv, _hsv+1, _hsv+2); \ + _hsv[1] *= tex->saturation; \ + hsv_to_rgb(_hsv[0], _hsv[1], _hsv[2], &texres->tr, &texres->tg, &texres->tb); \ +} \ struct HaloRen; @@ -59,7 +65,7 @@ void do_lamp_tex(LampRen *la, float *lavec, struct ShadeInput *shi, float *colf, void do_volume_tex(struct ShadeInput *shi, float *xyz, int mapto_flag, float *col, float *val); void init_render_textures(Render *re); -void end_render_textures(void); +void end_render_textures(Render *re); void render_realtime_texture(struct ShadeInput *shi, struct Image *ima); diff --git a/source/blender/render/intern/include/volume_precache.h b/source/blender/render/intern/include/volume_precache.h index 73e0a3e0415..3ddf8380241 100644 --- a/source/blender/render/intern/include/volume_precache.h +++ b/source/blender/render/intern/include/volume_precache.h @@ -25,9 +25,11 @@ * * ***** END GPL LICENSE BLOCK ***** */ - + +void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float *bbmin, float *bbmax); +int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float *co); + void volume_precache(Render *re); void free_volume_precache(Render *re); -int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float *co); #define VOL_MS_TIMESTEP 0.1f diff --git a/source/blender/render/intern/raytrace/Makefile b/source/blender/render/intern/raytrace/Makefile index 6e40c544c6f..2da8038c610 100644 --- a/source/blender/render/intern/raytrace/Makefile +++ b/source/blender/render/intern/raytrace/Makefile @@ -15,7 +15,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. # All rights reserved. @@ -63,3 +63,7 @@ endif ifeq ($(WITH_OPENEXR),true) CPPFLAGS += -DWITH_OPENEXR endif + +ifeq ($(WITH_BF_RAYOPTIMIZATION), true) + CPPFLAGS += -D__SSE__ +endif diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index e3efb90ec04..133a3d4a005 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -28,7 +28,6 @@ */ #include "rayobject.h" #include "raycounter.h" -#include "MEM_guardedalloc.h" #include "rayobject_rtbuild.h" #include "rayobject_hint.h" diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index b9e9a46b1a9..84ec56e131a 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -497,12 +497,22 @@ void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) else if(RE_rayobject_isVlakPrimitive(r)) { VlakPrimitive *face = (VlakPrimitive*) RE_rayobject_align(r); - VlakRen *vlr = face->face; + RayFace nface; + RE_rayface_from_vlak(&nface, face->ob, face->face); + + if(face->ob->transform_primitives) + { + mul_m4_v3(face->ob->mat, nface.v1); + mul_m4_v3(face->ob->mat, nface.v2); + mul_m4_v3(face->ob->mat, nface.v3); + if(RE_rayface_isQuad(&nface)) + mul_m4_v3(face->ob->mat, nface.v4); + } - DO_MINMAX( vlr->v1->co, min, max ); - DO_MINMAX( vlr->v2->co, min, max ); - DO_MINMAX( vlr->v3->co, min, max ); - if(vlr->v4) DO_MINMAX( vlr->v4->co, min, max ); + DO_MINMAX( nface.v1, min, max ); + DO_MINMAX( nface.v2, min, max ); + DO_MINMAX( nface.v3, min, max ); + if(RE_rayface_isQuad(&nface)) DO_MINMAX( nface.v4, min, max ); } else if(RE_rayobject_isRayAPI(r)) { diff --git a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp index cdc3be4c521..c510af540db 100644 --- a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp @@ -26,6 +26,7 @@ * * ***** END GPL LICENSE BLOCK ***** */ +#include "MEM_guardedalloc.h" #include "vbvh.h" #include "svbvh.h" #include "reorganize.h" @@ -52,10 +53,10 @@ void bvh_done<QBVHTree>(QBVHTree *obj) rtbuild_done(obj->builder, &obj->rayobj.control); //TODO find a away to exactly calculate the needed memory - MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "qbvh arena"); BLI_memarena_use_malloc(arena1); - MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "qbvh arena 2"); BLI_memarena_use_malloc(arena2); BLI_memarena_use_align(arena2, 16); diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp index dcefb2072b8..1c3cdd5919f 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -386,7 +386,9 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) // right_cost -= obj[i]->cost; if(right_cost < 0) right_cost = 0; } - assert(baxis >= 0 && baxis < 3); + //assert(baxis >= 0 && baxis < 3); + if (!(baxis >= 0 && baxis < 3)) + baxis = 0; } @@ -456,8 +458,10 @@ float bb_area(float *min, float *max) sub[2] = max[2]-min[2]; a = (sub[0]*sub[1] + sub[0]*sub[2] + sub[1]*sub[2])*2; - assert(a >= 0.0); - return a; + /* used to have an assert() here on negative results + * however, in this case its likely some overflow or ffast math error. + * so just return 0.0f instead. */ + return a < 0.0f ? 0.0f : a; } int bb_largest_axis(float *min, float *max) diff --git a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp index 67af596e301..647c5771e4f 100644 --- a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp @@ -26,6 +26,8 @@ * * ***** END GPL LICENSE BLOCK ***** */ +#include "MEM_guardedalloc.h" + #include "vbvh.h" #include "svbvh.h" #include "reorganize.h" @@ -63,10 +65,10 @@ void bvh_done<SVBVHTree>(SVBVHTree *obj) rtbuild_done(obj->builder, &obj->rayobj.control); //TODO find a away to exactly calculate the needed memory - MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "svbvh arena"); BLI_memarena_use_malloc(arena1); - MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "svbvh arena2"); BLI_memarena_use_malloc(arena2); BLI_memarena_use_align(arena2, 16); diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 0190b971d84..de1e6d349be 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -76,7 +76,7 @@ void bvh_done<VBVHTree>(VBVHTree *obj) rtbuild_done(obj->builder, &obj->rayobj.control); //TODO find a away to exactly calculate the needed memory - MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vbvh arena"); BLI_memarena_use_malloc(arena1); //Build and optimize the tree @@ -101,7 +101,7 @@ void bvh_done<VBVHTree>(VBVHTree *obj) { /* TODO - MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vbvh arena2"); BLI_memarena_use_malloc(arena2); //Finds the optimal packing of this tree using a given cost model diff --git a/source/blender/render/intern/raytrace/reorganize.h b/source/blender/render/intern/raytrace/reorganize.h index 92667d8de62..7ef7296945c 100644 --- a/source/blender/render/intern/raytrace/reorganize.h +++ b/source/blender/render/intern/raytrace/reorganize.h @@ -269,7 +269,7 @@ void pushdown(Node *parent) /* * BVH refit - * reajust nodes BB (useful if nodes childs where modified) + * readjust nodes BB (useful if nodes childs where modified) */ template<class Node> float bvh_refit(Node *node) @@ -295,7 +295,7 @@ float bvh_refit(Node *node) /* - * this finds the best way to packing a tree acording to a given test cost function + * this finds the best way to packing a tree according to a given test cost function * with the purpose to reduce the expected cost (eg.: number of BB tests). */ #include <vector> diff --git a/source/blender/render/intern/source/Makefile b/source/blender/render/intern/source/Makefile index c313549f9b9..5aaa66e7712 100644 --- a/source/blender/render/intern/source/Makefile +++ b/source/blender/render/intern/source/Makefile @@ -15,7 +15,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. # All rights reserved. diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index db242b0b1d9..149890f830d 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -356,17 +356,6 @@ static void split_v_renderfaces(ObjectRen *obr, int startvlak, int startvert, in } /* ------------------------------------------------------------------------- */ - -static int check_vnormal(float *n, float *veno) -{ - float inp; - - inp=n[0]*veno[0]+n[1]*veno[1]+n[2]*veno[2]; - if(inp < -FLT_EPSILON10) return 1; - return 0; -} - -/* ------------------------------------------------------------------------- */ /* Stress, tangents and normals */ /* ------------------------------------------------------------------------- */ @@ -512,7 +501,7 @@ static void calc_vertexnormals(Render *re, ObjectRen *obr, int do_tangent, int d int a; if(do_nmap_tangent) { - arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "nmap tangent arena"); BLI_memarena_use_calloc(arena); vtangents= MEM_callocN(sizeof(VertexTangent*)*obr->totvert, "VertexTangent"); @@ -536,9 +525,6 @@ static void calc_vertexnormals(Render *re, ObjectRen *obr, int do_tangent, int d float n1[3], n2[3], n3[3], n4[3]; float fac1, fac2, fac3, fac4=0.0f; - if(re->flag & R_GLOB_NOPUNOFLIP) - vlr->flag |= R_NOPUNOFLIP; - sub_v3_v3v3(n1, v2->co, v1->co); normalize_v3(n1); sub_v3_v3v3(n2, v3->co, v2->co); @@ -562,21 +548,11 @@ static void calc_vertexnormals(Render *re, ObjectRen *obr, int do_tangent, int d fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]); fac4= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]); - if(!(vlr->flag & R_NOPUNOFLIP)) { - if( check_vnormal(vlr->n, v4->n) ) fac4= -fac4; - } - v4->n[0] +=fac4*vlr->n[0]; v4->n[1] +=fac4*vlr->n[1]; v4->n[2] +=fac4*vlr->n[2]; } - if(!(vlr->flag & R_NOPUNOFLIP)) { - if( check_vnormal(vlr->n, v1->n) ) fac1= -fac1; - if( check_vnormal(vlr->n, v2->n) ) fac2= -fac2; - if( check_vnormal(vlr->n, v3->n) ) fac3= -fac3; - } - v1->n[0] +=fac1*vlr->n[0]; v1->n[1] +=fac1*vlr->n[1]; v1->n[2] +=fac1*vlr->n[2]; @@ -851,32 +827,30 @@ static void autosmooth(Render *re, ObjectRen *obr, float mat[][4], int degr) static float *get_object_orco(Render *re, Object *ob) { float *orco; - + if (!re->orco_hash) - re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); - + re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "get_object_orco gh"); + orco = BLI_ghash_lookup(re->orco_hash, ob); - + if (!orco) { if (ELEM(ob->type, OB_CURVE, OB_FONT)) { orco = make_orco_curve(re->scene, ob); } else if (ob->type==OB_SURF) { orco = make_orco_surf(ob); - } else if (ob->type==OB_MBALL) { - orco = make_orco_mball(ob); } - + if (orco) BLI_ghash_insert(re->orco_hash, ob, orco); } - + return orco; } static void set_object_orco(Render *re, void *ob, float *orco) { if (!re->orco_hash) - re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "set_object_orco gh"); BLI_ghash_insert(re->orco_hash, ob, orco); } @@ -1023,7 +997,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par else width= 1.0f; if(ma->mode & MA_TANGENT_STR) - flag= R_SMOOTH|R_NOPUNOFLIP|R_TANGENT; + flag= R_SMOOTH|R_TANGENT; else flag= R_SMOOTH; @@ -1041,7 +1015,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par vlr->v4= RE_findOrAddVert(obr, obr->totvert++); VECCOPY(vlr->v1->co, vec); - add_v3_v3v3(vlr->v1->co, vlr->v1->co, cross); + add_v3_v3(vlr->v1->co, cross); VECCOPY(vlr->v1->n, nor); vlr->v1->orco= sd->orco; vlr->v1->accum= -1.0f; // accum abuse for strand texco @@ -1053,7 +1027,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par vlr->v2->accum= vlr->v1->accum; VECCOPY(vlr->v4->co, vec1); - add_v3_v3v3(vlr->v4->co, vlr->v4->co, cross); + add_v3_v3(vlr->v4->co, cross); VECCOPY(vlr->v4->n, nor); vlr->v4->orco= sd->orco; vlr->v4->accum= 1.0f; // accum abuse for strand texco @@ -1115,7 +1089,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par v2= RE_findOrAddVert(obr, obr->totvert++); VECCOPY(v1->co, vec); - add_v3_v3v3(v1->co, v1->co, cross); + add_v3_v3(v1->co, cross); VECCOPY(v1->n, nor); v1->orco= sd->orco; v1->accum= -1.0f; // accum abuse for strand texco @@ -1177,7 +1151,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par } VECCOPY(vlr->v4->co, vec); - add_v3_v3v3(vlr->v4->co, vlr->v4->co, cross); + add_v3_v3(vlr->v4->co, cross); VECCOPY(vlr->v4->n, nor); vlr->v4->orco= sd->orco; vlr->v4->accum= -1.0f + 2.0f*sd->time; // accum abuse for strand texco @@ -1520,7 +1494,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem RNG *rng= 0; float loc[3],loc1[3],loc0[3],mat[4][4],nmat[3][3],co[3],nor[3],time; float strandlen=0.0f, curlen=0.0f; - float hasize, pa_size, r_tilt, r_length, cfra=bsystem_time(re->scene, ob, (float)re->scene->r.cfra, 0.0); + float hasize, pa_size, r_tilt, r_length, cfra= BKE_curframe(re->scene); float pa_time, pa_birthtime, pa_dietime; float random, simplify[2]; int i, a, k, max_k=0, totpart, dosimplify = 0, dosurfacecache = 0; @@ -1532,8 +1506,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem /* 1. check that everything is ok & updated */ if(psys==NULL) return 0; - - totchild=psys->totchild; part=psys->part; pars=psys->particles; @@ -1554,6 +1526,11 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(part->phystype==PART_PHYS_KEYED) psys_count_keyed_targets(&sim); + totchild=psys->totchild; + + /* can happen for disconnected/global hair */ + if(part->type==PART_HAIR && !psys->childcache) + totchild= 0; if(G.rendering == 0) { /* preview render */ totchild = (int)((float)totchild * (float)part->disp / 100.0f); @@ -1639,7 +1616,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(part->flag & PART_GLOB_TIME) #endif // XXX old animation system - cfra = bsystem_time(re->scene, 0, (float)re->scene->r.cfra, 0.0); + cfra = BKE_curframe(re->scene); ///* 2.4 setup reactors */ // if(part->type == PART_REACTOR){ @@ -2366,6 +2343,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) Material *ma; float *data, *nors, *orco, mat[4][4], imat[3][3], xn, yn, zn; int a, need_orco, vlakindex, *index; + ListBase dispbase= {NULL, NULL}; if (ob!=find_basis_mball(re->scene, ob)) return; @@ -2380,14 +2358,22 @@ static void init_render_mball(Render *re, ObjectRen *obr) if(ma->texco & TEXCO_ORCO) { need_orco= 1; } - - makeDispListMBall(re->scene, ob); - dl= ob->disp.first; + + makeDispListMBall_forRender(re->scene, ob, &dispbase); + dl= dispbase.first; if(dl==0) return; data= dl->verts; nors= dl->nors; - orco= get_object_orco(re, ob); + if(need_orco) { + orco= get_object_orco(re, ob); + + if (!orco) { + /* orco hasn't been found in cache - create new one and add to cache */ + orco= make_orco_mball(ob, &dispbase); + set_object_orco(re, ob, orco); + } + } for(a=0; a<dl->nr; a++, data+=3, nors+=3, orco+=3) { @@ -2425,7 +2411,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) normal_tri_v3( vlr->n,vlr->v3->co, vlr->v2->co, vlr->v1->co); vlr->mat= ma; - vlr->flag= ME_SMOOTH+R_NOPUNOFLIP; + vlr->flag= ME_SMOOTH; vlr->ec= 0; /* mball -too bad- always has triangles, because quads can be non-planar */ @@ -2444,10 +2430,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) } /* enforce display lists remade */ - freedisplist(&ob->disp); - - /* this enforces remake for real, orco displist is small (in scale) */ - ob->recalc |= OB_RECALC_DATA; + freedisplist(&dispbase); } /* ------------------------------------------------------------------------- */ @@ -2457,10 +2440,8 @@ static void init_render_mball(Render *re, ObjectRen *obr) /* returns amount of vertices added for orco */ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, float *orco, float mat[4][4]) { - Object *ob= obr->ob; VertRen *v1, *v2, *v3, *v4, *ver; VlakRen *vlr, *vlr1, *vlr2, *vlr3; - Curve *cu= ob->data; float *data, n1[3]; int u, v, orcoret= 0; int p1, p2, p3, p4, a; @@ -2540,14 +2521,11 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, vlr->mat= matar[ dl->col]; vlr->ec= ME_V1V2+ME_V2V3; vlr->flag= dl->rt; - if( (cu->flag & CU_NOPUNOFLIP) ) { - vlr->flag |= R_NOPUNOFLIP; - } - add_v3_v3v3(v1->n, v1->n, n1); - add_v3_v3v3(v2->n, v2->n, n1); - add_v3_v3v3(v3->n, v3->n, n1); - add_v3_v3v3(v4->n, v4->n, n1); + add_v3_v3(v1->n, n1); + add_v3_v3(v2->n, n1); + add_v3_v3(v3->n, n1); + add_v3_v3(v4->n, n1); p1++; p2++; p3++; p4++; } @@ -2561,10 +2539,10 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, /* optimize! :*/ vlr= RE_findOrAddVlak(obr, UVTOINDEX(sizeu - 1, v)); vlr1= RE_findOrAddVlak(obr, UVTOINDEX(0, v)); - add_v3_v3v3(vlr1->v1->n, vlr1->v1->n, vlr->n); - add_v3_v3v3(vlr1->v2->n, vlr1->v2->n, vlr->n); - add_v3_v3v3(vlr->v3->n, vlr->v3->n, vlr1->n); - add_v3_v3v3(vlr->v4->n, vlr->v4->n, vlr1->n); + add_v3_v3(vlr1->v1->n, vlr->n); + add_v3_v3(vlr1->v2->n, vlr->n); + add_v3_v3(vlr->v3->n, vlr1->n); + add_v3_v3(vlr->v4->n, vlr1->n); } } if (dl->flag & DL_CYCL_U) { @@ -2574,10 +2552,10 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, /* optimize! :*/ vlr= RE_findOrAddVlak(obr, UVTOINDEX(u, 0)); vlr1= RE_findOrAddVlak(obr, UVTOINDEX(u, sizev-1)); - add_v3_v3v3(vlr1->v2->n, vlr1->v2->n, vlr->n); - add_v3_v3v3(vlr1->v3->n, vlr1->v3->n, vlr->n); - add_v3_v3v3(vlr->v1->n, vlr->v1->n, vlr1->n); - add_v3_v3v3(vlr->v4->n, vlr->v4->n, vlr1->n); + add_v3_v3(vlr1->v2->n, vlr->n); + add_v3_v3(vlr1->v3->n, vlr->n); + add_v3_v3(vlr->v1->n, vlr1->n); + add_v3_v3(vlr->v4->n, vlr1->n); } } /* last vertex is an extra case: @@ -2603,9 +2581,9 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, vlr1= RE_findOrAddVlak(obr, UVTOINDEX(0,0)); /* (0,0) */ add_v3_v3v3(n1, vlr->n, vlr1->n); vlr2= RE_findOrAddVlak(obr, UVTOINDEX(0, sizev-1)); /* (0,n) */ - add_v3_v3v3(n1, n1, vlr2->n); + add_v3_v3(n1, vlr2->n); vlr3= RE_findOrAddVlak(obr, UVTOINDEX(sizeu-1, 0)); /* (m,0) */ - add_v3_v3v3(n1, n1, vlr3->n); + add_v3_v3(n1, vlr3->n); VECCOPY(vlr->v3->n, n1); VECCOPY(vlr1->v1->n, n1); VECCOPY(vlr2->v2->n, n1); @@ -2691,9 +2669,6 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr, vlr->mat= ma; vlr->flag= flag; - if(cu &&(cu->flag & ME_NOPUNOFLIP)) { - vlr->flag |= R_NOPUNOFLIP; - } vlr->ec= 0; /* mesh edges rendered separately */ if(len==0) obr->totvlak--; @@ -2845,7 +2820,10 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) } while(dl) { - if(dl->type==DL_INDEX3) { + if(dl->col > ob->totcol) { + /* pass */ + } + else if(dl->type==DL_INDEX3) { int *index; startvert= obr->totvert; @@ -2898,9 +2876,6 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) vlr->mat= matar[ dl->col ]; vlr->flag= 0; - if( (cu->flag & CU_NOPUNOFLIP) ) { - vlr->flag |= R_NOPUNOFLIP; - } vlr->ec= 0; } } @@ -2986,10 +2961,10 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) for(a= startvlak; a<obr->totvlak; a++) { vlr= RE_findOrAddVlak(obr, a); - add_v3_v3v3(vlr->v1->n, vlr->v1->n, vlr->n); - add_v3_v3v3(vlr->v3->n, vlr->v3->n, vlr->n); - add_v3_v3v3(vlr->v2->n, vlr->v2->n, vlr->n); - add_v3_v3v3(vlr->v4->n, vlr->v4->n, vlr->n); + add_v3_v3(vlr->v1->n, vlr->n); + add_v3_v3(vlr->v3->n, vlr->n); + add_v3_v3(vlr->v2->n, vlr->n); + add_v3_v3(vlr->v4->n, vlr->n); } for(a=startvert; a<obr->totvert; a++) { ver= RE_findOrAddVert(obr, a); @@ -3385,9 +3360,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) vlr->mat= ma; vlr->flag= flag; - if((me->flag & ME_NOPUNOFLIP) ) { - vlr->flag |= R_NOPUNOFLIP; - } vlr->ec= 0; /* mesh edges rendered separately */ if(len==0) obr->totvlak--; @@ -3887,12 +3859,12 @@ static void set_material_lightgroups(Render *re) if(re->scene->r.scemode & R_PREVIEWBUTS) return; - for(group= G.main->group.first; group; group=group->id.next) + for(group= re->main->group.first; group; group=group->id.next) group->id.flag |= LIB_DOIT; /* it's a bit too many loops in loops... but will survive */ /* hola! materials not in use...? */ - for(ma= G.main->mat.first; ma; ma=ma->id.next) { + for(ma= re->main->mat.first; ma; ma=ma->id.next) { if(ma->group && (ma->group->id.flag & LIB_DOIT)) add_lightgroup(re, ma->group, ma->mode & MA_GROUP_NOLAY); } @@ -4542,7 +4514,6 @@ static void init_render_object(Render *re, Object *ob, Object *par, DupliObject void RE_Database_Free(Render *re) { - Object *ob = NULL; LampRen *lar; /* statistics for debugging render memory usage */ @@ -4569,30 +4540,16 @@ void RE_Database_Free(Render *re) BLI_freelistN(&re->lights); free_renderdata_tables(re); - - /* free orco. check all objects because of duplis and sets */ - ob= G.main->object.first; - while(ob) { - if(ob->type==OB_MBALL) { - if(ob->disp.first && ob->disp.first!=ob->disp.last) { - DispList *dl= ob->disp.first; - BLI_remlink(&ob->disp, dl); - freedisplist(&ob->disp); - BLI_addtail(&ob->disp, dl); - } - } - ob= ob->id.next; - } + /* free orco */ free_mesh_orco_hash(re); #if 0 /* radio can be redone better */ end_radio_render(); #endif - end_render_materials(); - end_render_textures(); + end_render_materials(re->main); + end_render_textures(re); free_pointdensities(re); - free_voxeldata(re); free_camera_inside_volumes(re); @@ -4788,7 +4745,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp /* in the prev/next pass for making speed vectors, avoid creating * objects that are not on a renderlayer with a vector pass, can * save a lot of time in complex scenes */ - vectorlay= get_vector_renderlayers(sce); + vectorlay= get_vector_renderlayers(re->scene); lay= (timeoffset)? renderlay & vectorlay: renderlay; /* if the object has been restricted from rendering in the outliner, ignore it */ @@ -4815,7 +4772,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp /* create list of duplis generated by this object, particle * system need to have render settings set for dupli particles */ dupli_render_particle_set(re, ob, timeoffset, 0, 1); - lb= object_duplilist(sce, ob); + lb= object_duplilist(re->scene, ob); dupli_render_particle_set(re, ob, timeoffset, 0, 0); for(dob= lb->first; dob; dob= dob->next) { @@ -4915,7 +4872,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp /* objects in groups with OB_RENDER_DUPLI set still need to be created, * since they may not be part of the scene */ - for(group= G.main->group.first; group; group=group->id.next) + for(group= re->main->group.first; group; group=group->id.next) add_group_render_dupli_obs(re, group, nolamps, onlyselected, actob, timeoffset, renderlay, 0); /* imat objects has to be done again, since groups can mess it up */ @@ -4932,13 +4889,14 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp } /* used to be 'rotate scene' */ -void RE_Database_FromScene(Render *re, Scene *scene, unsigned int lay, int use_camera_view) +void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int lay, int use_camera_view) { extern int slurph_opt; /* key.c */ Scene *sce; float mat[4][4]; float amb[3]; + re->main= bmain; re->scene= scene; re->lay= lay; @@ -4949,7 +4907,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, unsigned int lay, int use_c /* XXX add test if dbase was filled already? */ - re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "render db arena"); re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0; re->lights.first= re->lights.last= NULL; re->lampren.first= re->lampren.last= NULL; @@ -4963,10 +4921,15 @@ void RE_Database_FromScene(Render *re, Scene *scene, unsigned int lay, int use_c /* applies changes fully */ if((re->r.scemode & R_PREVIEWBUTS)==0) - scene_update_for_newframe(re->scene, lay); + scene_update_for_newframe(re->main, re->scene, lay); /* if no camera, viewmat should have been set! */ if(use_camera_view && re->scene->camera) { + /* called before but need to call again incase of lens animation from the + * above call to scene_update_for_newframe, fixes bug. [#22702]. + * following calls dont depend on 'RE_SetCamera' */ + RE_SetCamera(re, scene->camera); + normalize_m4(re->scene->camera->obmat); invert_m4_m4(mat, re->scene->camera->obmat); RE_SetView(re, mat); @@ -4985,7 +4948,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, unsigned int lay, int use_c /* still bad... doing all */ init_render_textures(re); VECCOPY(amb, &re->wrld.ambr); - init_render_materials(re->r.mode, amb); + init_render_materials(re->main, re->r.mode, amb); set_node_shader_lamp_loop(shade_material_loop); /* MAKE RENDER DATA */ @@ -5099,7 +5062,7 @@ static void database_fromscene_vectors(Render *re, Scene *scene, unsigned int la /* XXX add test if dbase was filled already? */ - re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vector render db arena"); re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0; re->i.totface=re->i.totvert=re->i.totstrand=re->i.totlamp=re->i.tothalo= 0; re->lights.first= re->lights.last= NULL; @@ -5112,7 +5075,7 @@ static void database_fromscene_vectors(Render *re, Scene *scene, unsigned int la /* applies changes fully */ scene->r.cfra += timeoffset; - scene_update_for_newframe(re->scene, lay); + scene_update_for_newframe(re->main, re->scene, lay); /* if no camera, viewmat should have been set! */ if(re->scene->camera) { @@ -5471,7 +5434,7 @@ static void free_dbase_object_vectors(ListBase *lb) BLI_freelistN(lb); } -void RE_Database_FromScene_Vectors(Render *re, Scene *sce, unsigned int lay) +void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned int lay) { ObjectInstanceRen *obi, *oldobi; StrandSurface *mesh; @@ -5513,7 +5476,7 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce, unsigned int lay) re->strandsurface= strandsurface; if(!re->test_break(re->tbh)) - RE_Database_FromScene(re, sce, lay, 1); + RE_Database_FromScene(re, bmain, sce, lay, 1); if(!re->test_break(re->tbh)) { for(step= 0; step<2; step++) { @@ -5602,12 +5565,13 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce, unsigned int lay) RE_BAKE_DISPLACEMENT:for baking, no lamps, only selected objects RE_BAKE_SHADOW: for baking, only shadows, but all objects */ -void RE_Database_Baking(Render *re, Scene *scene, unsigned int lay, int type, Object *actob) +void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, int type, Object *actob) { float mat[4][4]; float amb[3]; int onlyselected, nolamps; + re->main= bmain; re->scene= scene; re->lay= lay; @@ -5616,7 +5580,6 @@ void RE_Database_Baking(Render *re, Scene *scene, unsigned int lay, int type, Ob RE_init_threadcount(re); - re->flag |= R_GLOB_NOPUNOFLIP; re->flag |= R_BAKING; re->excludeob= actob; if(actob) @@ -5635,7 +5598,7 @@ void RE_Database_Baking(Render *re, Scene *scene, unsigned int lay, int type, Ob } /* setup render stuff */ - re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "bake db arena"); re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0; re->lights.first= re->lights.last= NULL; @@ -5669,7 +5632,7 @@ void RE_Database_Baking(Render *re, Scene *scene, unsigned int lay, int type, Ob init_render_textures(re); VECCOPY(amb, &re->wrld.ambr); - init_render_materials(re->r.mode, amb); + init_render_materials(re->main, re->r.mode, amb); set_node_shader_lamp_loop(shade_material_loop); diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 1a34868b9fd..8977bc7f379 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -46,7 +46,6 @@ #include "BKE_library.h" #include "BKE_main.h" -#include "BKE_global.h" #include "BKE_image.h" // BKE_write_ibuf #include "BKE_texture.h" #include "BKE_utildefines.h" @@ -508,7 +507,7 @@ void make_envmaps(Render *re) /* 5 = hardcoded max recursion level */ while(depth<5) { - tex= G.main->tex.first; + tex= re->main->tex.first; while(tex) { if(tex->id.us && tex->type==TEX_ENVMAP) { if(tex->env && tex->env->object) { @@ -719,9 +718,9 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe texr1.nor= texr2.nor= NULL; - add_v3_v3v3(vec, vec, dxt); + add_v3_v3(vec, dxt); face1= envcube_isect(env, vec, sco); - sub_v3_v3v3(vec, vec, dxt); + sub_v3_v3(vec, dxt); if(face!=face1) { ibuf= env->cube[face1]; @@ -732,9 +731,9 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe /* here was the nasty bug! results were not zero-ed. FPE! */ - add_v3_v3v3(vec, vec, dyt); + add_v3_v3(vec, dyt); face1= envcube_isect(env, vec, sco); - sub_v3_v3v3(vec, vec, dyt); + sub_v3_v3(vec, dyt); if(face!=face1) { ibuf= env->cube[face1]; diff --git a/source/blender/render/intern/source/gammaCorrectionTables.c b/source/blender/render/intern/source/gammaCorrectionTables.c index afb7fbb74dc..818c3c72118 100644 --- a/source/blender/render/intern/source/gammaCorrectionTables.c +++ b/source/blender/render/intern/source/gammaCorrectionTables.c @@ -33,10 +33,6 @@ #include <stdlib.h> #include <math.h> -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - /* WARNING; optimized, cannot be used to do gamma(invgamma()) and expect */ /* result remain identical (ton) */ @@ -121,7 +117,7 @@ void makeGammaTables(float gamma) /* The end of the table should match 1.0 carefully. In order to avoid */ /* rounding errors, we just set this explicitly. The last segment may */ - /* have a different lenght than the other segments, but our */ + /* have a different length than the other segments, but our */ /* interpolation is insensitive to that. */ color_domain_table[RE_GAMMA_TABLE_SIZE] = 1.0; gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 21077c289c3..f08529b3f2c 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -236,8 +236,6 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, TexResult *texre } } - BRICONTRGB; - if(texres->talpha) texres->tin= texres->ta; else if(tex->imaflag & TEX_CALCALPHA) { texres->ta= texres->tin= MAX3(texres->tr, texres->tg, texres->tb); @@ -254,6 +252,8 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, TexResult *texre texres->tb*= fx; } + BRICONTRGB; + return retval; } @@ -586,49 +586,19 @@ static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float max } } -void image_sample(Image *ima, float fx, float fy, float dx, float dy, float *result) -{ - TexResult texres; - ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); - - if(ibuf==NULL) { - result[0]= result[1]= result[2]= result[3]= 0.0f; - return; - } - - if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) - ibuf->rect+= (ibuf->x*ibuf->y); - - boxsample(ibuf, fx, fy, fx+dx, fy+dy, &texres, 0, 1, 0); - result[0]= texres.tr; - result[1]= texres.tg; - result[2]= texres.tb; - result[3]= texres.ta; - - if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) - ibuf->rect-= (ibuf->x*ibuf->y); -} - -void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result) -{ - TexResult texres; - - if(ibuf==NULL) { - return; - } - - memset(&texres, 0, sizeof(texres)); - boxsample(ibuf, fx, fy, fx+dx, fy+dy, &texres, 0, 1, 0); - result[0]= texres.tr; - result[1]= texres.tg; - result[2]= texres.tb; - result[3]= texres.ta; -} - - //----------------------------------------------------------------------------------------------------------------- // from here, some functions only used for the new filtering +// anisotropic filters, data struct used instead of long line of (possibly unused) func args +typedef struct afdata_t { + float dxt[2], dyt[2]; + int intpol, extflag; + // feline only + float majrad, minrad, theta; + int iProbes; + float dusc, dvsc; +} afdata_t; + // this only used here to make it easier to pass extend flags as single int enum {TXC_XMIR=1, TXC_YMIR, TXC_REPT, TXC_EXTD}; @@ -713,16 +683,6 @@ static int ibuf_get_color_clip_bilerp(float *col, ImBuf *ibuf, float u, float v, return ibuf_get_color_clip(col, ibuf, (int)u, (int)v, extflag); } -// anisotropic filters, data struct used instead of long line of (possibly unused) func args -typedef struct afdata_t { - float dxt[2], dyt[2]; - int intpol, extflag; - // feline only - float majrad, minrad, theta; - int iProbes; - float dusc, dvsc; -} afdata_t; - static void area_sample(TexResult* texr, ImBuf* ibuf, float fx, float fy, afdata_t* AFD) { int xs, ys, clip = 0; @@ -1358,8 +1318,6 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, } } - BRICONTRGB; - if (tex->imaflag & TEX_CALCALPHA) texres->ta = texres->tin = texres->ta * MAX3(texres->tr, texres->tg, texres->tb); else @@ -1388,6 +1346,8 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, texres->tb *= fx; } + BRICONTRGB; + return retval; } @@ -1745,8 +1705,6 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *DXT, f boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend, 0); } - BRICONTRGB; - if(tex->imaflag & TEX_CALCALPHA) { texres->ta= texres->tin= texres->ta*MAX3(texres->tr, texres->tg, texres->tb); } @@ -1773,5 +1731,57 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *DXT, f texres->tb*= fx; } + BRICONTRGB; + return retval; } + +void image_sample(Image *ima, float fx, float fy, float dx, float dy, float *result) +{ + TexResult texres; + ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + + if(ibuf==NULL) { + result[0]= result[1]= result[2]= result[3]= 0.0f; + return; + } + + if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) + ibuf->rect+= (ibuf->x*ibuf->y); + + boxsample(ibuf, fx, fy, fx+dx, fy+dy, &texres, 0, 1, 0); + result[0]= texres.tr; + result[1]= texres.tg; + result[2]= texres.tb; + result[3]= texres.ta; + + if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) + ibuf->rect-= (ibuf->x*ibuf->y); +} + +void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result) +{ + TexResult texres; + afdata_t AFD; + + if(ibuf==NULL) { + return; + } + + AFD.dxt[0] = dx; AFD.dxt[1] = dx; + AFD.dyt[0] = dy; AFD.dyt[1] = dy; + //copy_v2_v2(AFD.dxt, dx); + //copy_v2_v2(AFD.dyt, dy); + + AFD.intpol = 1; + AFD.extflag = TXC_EXTD; + + memset(&texres, 0, sizeof(texres)); + ewa_eval(&texres, ibuf, fx, fy, &AFD); + + + result[0]= texres.tr; + result[1]= texres.tg; + result[2]= texres.tb; + result[3]= texres.ta; +}
\ No newline at end of file diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index ab656ad1c3b..fb69519236a 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -660,7 +660,7 @@ static OcclusionTree *occ_tree_build(Render *re) tree->doindirect= (re->wrld.ao_indirect_energy > 0.0f && re->wrld.ao_indirect_bounces > 0); /* allocation */ - tree->arena= BLI_memarena_new(0x8000 * sizeof(OccNode)); + tree->arena= BLI_memarena_new(0x8000 * sizeof(OccNode), "occ tree arena"); BLI_memarena_use_calloc(tree->arena); if(re->wrld.aomode & WO_AOCACHE) @@ -1390,8 +1390,7 @@ static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, f if(onlyshadow) envcolor= WO_AOPLAIN; - VECCOPY(nn, n); - negate_v3(nn); + negate_v3_v3(nn, n); occ_lookup(tree, thread, exclude, co, nn, &occ, (tree->doindirect)? rad: NULL, (env && envcolor)? bn: NULL); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index f9089e7399b..44c6a6f008f 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -39,6 +39,8 @@ #include "DNA_sequence_types.h" #include "DNA_userdef_types.h" +#include "MEM_guardedalloc.h" + #include "BKE_utildefines.h" #include "BKE_global.h" #include "BKE_image.h" @@ -52,8 +54,6 @@ #include "BKE_pointcache.h" #include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */ -#include "MEM_guardedalloc.h" - #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_rand.h" @@ -131,17 +131,26 @@ static int thread_break(void *unused) static void result_nothing(void *unused, RenderResult *rr) {} static void result_rcti_nothing(void *unused, RenderResult *rr, volatile struct rcti *rect) {} static void stats_nothing(void *unused, RenderStats *rs) {} -static void int_nothing(void *unused, int val) {} +static void float_nothing(void *unused, float val) {} static void print_error(void *unused, char *str) {printf("ERROR: %s\n", str);} static int default_break(void *unused) {return G.afbreek == 1;} static void stats_background(void *unused, RenderStats *rs) { - uintptr_t mem_in_use= MEM_get_memory_in_use(); - float megs_used_memory= mem_in_use/(1024.0*1024.0); char str[400], *spos= str; - - spos+= sprintf(spos, "Fra:%d Mem:%.2fM ", rs->cfra, megs_used_memory); + uintptr_t mem_in_use, mmap_in_use, peak_memory; + float megs_used_memory, mmap_used_memory, megs_peak_memory; + + mem_in_use= MEM_get_memory_in_use(); + mmap_in_use= MEM_get_mapped_memory_in_use(); + peak_memory = MEM_get_peak_memory(); + + megs_used_memory= (mem_in_use-mmap_in_use)/(1024.0*1024.0); + mmap_used_memory= (mmap_in_use)/(1024.0*1024.0); + megs_peak_memory = (peak_memory)/(1024.0*1024.0); + + spos+= sprintf(spos, "Fra:%d Mem:%.2fM (%.2fM, peak %.2fM) ", rs->cfra, + megs_used_memory, mmap_used_memory, megs_peak_memory); if(rs->curfield) spos+= sprintf(spos, "Field %d ", rs->curfield); @@ -918,12 +927,16 @@ static int read_render_result_from_file(char *filename, RenderResult *rr) int rectx, recty; if(IMB_exr_begin_read(exrhandle, filename, &rectx, &recty)==0) { + printf("failed being read %s\n", filename); IMB_exr_close(exrhandle); return 0; } - + if(rr == NULL || rectx!=rr->rectx || recty!=rr->recty) { - printf("error in reading render result\n"); + if(rr) + printf("error in reading render result: dimensions don't match\n"); + else + printf("error in reading render result: NULL result pointer\n"); IMB_exr_close(exrhandle); return 0; } @@ -1061,7 +1074,6 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr) rr->rectf= re->result->rectf; rr->rectz= re->result->rectz; rr->rect32= re->result->rect32; - rr->compo_seq= (rr->rectf != NULL); /* active layer */ rl= render_get_active_layer(re, re->result); @@ -1073,6 +1085,7 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr) rr->rectz= RE_RenderLayerGetPass(rl, SCE_PASS_Z); } + rr->have_combined= (re->result->rectf != NULL); rr->layers= re->result->layers; } } @@ -1149,7 +1162,7 @@ Render *RE_NewRender(const char *name) re->display_init= result_nothing; re->display_clear= result_nothing; re->display_draw= result_rcti_nothing; - re->timecursor= int_nothing; + re->progress= float_nothing; re->test_break= default_break; re->error= print_error; if(G.background) @@ -1157,7 +1170,7 @@ Render *RE_NewRender(const char *name) else re->stats_draw= stats_nothing; /* clear callback handles */ - re->dih= re->dch= re->ddh= re->sdh= re->tch= re->tbh= re->erh= NULL; + re->dih= re->dch= re->ddh= re->sdh= re->prh= re->tbh= re->erh= NULL; /* init some variables */ re->ycor= 1.0f; @@ -1289,6 +1302,8 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer * /* we clip faces with a minimum of 2 pixel boundary outside of image border. see zbuf.c */ re->clipcrop= 1.0f + 2.0f/(float)(re->winx>re->winy?re->winy:re->winx); + re->mblur_offs = re->field_offs = 0.f; + RE_init_threadcount(re); } @@ -1361,10 +1376,10 @@ void RE_stats_draw_cb(Render *re, void *handle, void (*f)(void *handle, RenderSt re->stats_draw= f; re->sdh= handle; } -void RE_timecursor_cb(Render *re, void *handle, void (*f)(void *handle, int)) +void RE_progress_cb(Render *re, void *handle, void (*f)(void *handle, float)) { - re->timecursor= f; - re->tch= handle; + re->progress= f; + re->prh= handle; } void RE_test_break_cb(Render *re, void *handle, int (*f)(void *handle)) @@ -1564,7 +1579,7 @@ static void print_part_stats(Render *re, RenderPart *pa) { char str[64]; - sprintf(str, "Part %d-%d", pa->nr, re->i.totpart); + sprintf(str, "%s, Part %d-%d", re->scene->id.name+2, pa->nr, re->i.totpart); re->i.infostr= str; re->stats_draw(re->sdh, &re->i); re->i.infostr= NULL; @@ -1681,6 +1696,7 @@ static void threaded_tile_processor(Render *re) free_render_result(&pa->fullresult, pa->result); pa->result= NULL; re->i.partsdone++; + re->progress(re->prh, re->i.partsdone / (float)re->i.totpart); hasdrawn= 1; } } @@ -1748,12 +1764,13 @@ static void do_render_3d(Render *re) /* internal */ // re->cfra= cfra; /* <- unused! */ + re->scene->r.subframe = re->mblur_offs + re->field_offs; /* make render verts/faces/halos/lamps */ if(render_scene_needs_vector(re)) - RE_Database_FromScene_Vectors(re, re->scene, re->lay); + RE_Database_FromScene_Vectors(re, re->main, re->scene, re->lay); else - RE_Database_FromScene(re, re->scene, re->lay, 1); + RE_Database_FromScene(re, re->main, re->scene, re->lay, 1); threaded_tile_processor(re); @@ -1764,6 +1781,8 @@ static void do_render_3d(Render *re) /* free all render verts etc */ RE_Database_Free(re); + + re->scene->r.subframe = 0.f; } /* called by blur loop, accumulate RGBA key alpha */ @@ -1863,7 +1882,7 @@ static void do_render_blur_3d(Render *re) /* do the blur steps */ while(blur--) { - set_mblur_offs( re->r.blurfac*((float)(re->r.mblur_samples-blur))/(float)re->r.mblur_samples ); + re->mblur_offs = re->r.blurfac*((float)(re->r.mblur_samples-blur))/(float)re->r.mblur_samples; re->i.curblur= re->r.mblur_samples-blur; /* stats */ @@ -1881,7 +1900,7 @@ static void do_render_blur_3d(Render *re) re->result= rres; BLI_rw_mutex_unlock(&re->resultmutex); - set_mblur_offs(0.0f); + re->mblur_offs = 0.0f; re->i.curblur= 0; /* stats */ /* weak... the display callback wants an active renderlayer pointer... */ @@ -1961,15 +1980,17 @@ static void do_render_fields_3d(Render *re) re->i.curfield= 2; /* stats */ re->flag |= R_SEC_FIELD; - if((re->r.mode & R_FIELDSTILL)==0) - set_field_offs(0.5f); + if((re->r.mode & R_FIELDSTILL)==0) { + re->field_offs = 0.5f; + } RE_SetCamera(re, re->scene->camera); if(re->r.mode & R_MBLUR) do_render_blur_3d(re); else do_render_3d(re); re->flag &= ~R_SEC_FIELD; - set_field_offs(0.0f); + + re->field_offs = 0.0f; rr2= re->result; } @@ -2121,11 +2142,12 @@ static void render_scene(Render *re, Scene *sce, int cfra) RE_InitState(resc, re, &sce->r, NULL, winx, winy, &re->disprect); /* still unsure entity this... */ + resc->main= re->main; resc->scene= sce; resc->lay= sce->lay; /* ensure scene has depsgraph, base flags etc OK */ - set_scene_bg(sce); + set_scene_bg(re->main, sce); /* copy callbacks */ resc->display_draw= re->display_draw; @@ -2143,7 +2165,7 @@ static void tag_scenes_for_render(Render *re) bNode *node; Scene *sce; - for(sce= G.main->scene.first; sce; sce= sce->id.next) + for(sce= re->main->scene.first; sce; sce= sce->id.next) sce->id.flag &= ~LIB_DOIT; re->scene->id.flag |= LIB_DOIT; @@ -2298,7 +2320,7 @@ void RE_MergeFullSample(Render *re, Scene *sce, bNodeTree *ntree) /* first call RE_ReadRenderResult on every renderlayer scene. this creates Render structs */ /* tag scenes unread */ - for(scene= G.main->scene.first; scene; scene= scene->id.next) + for(scene= re->main->scene.first; scene; scene= scene->id.next) scene->id.flag |= LIB_DOIT; for(node= ntree->nodes.first; node; node= node->next) { @@ -2363,14 +2385,17 @@ static void do_render_composite_fields_blur_3d(Render *re) if(!re->test_break(re->tbh)) { ntree->stats_draw= render_composit_stats; ntree->test_break= re->test_break; + ntree->progress= re->progress; ntree->sdh= re->sdh; ntree->tbh= re->tbh; + ntree->prh= re->prh; + /* in case it was never initialized */ R.sdh= re->sdh; R.stats_draw= re->stats_draw; if (update_newframe) - scene_update_for_newframe(re->scene, re->lay); + scene_update_for_newframe(re->main, re->scene, re->lay); if(re->r.scemode & R_FULL_SAMPLE) do_merge_fullsample(re, ntree); @@ -2380,7 +2405,8 @@ static void do_render_composite_fields_blur_3d(Render *re) ntree->stats_draw= NULL; ntree->test_break= NULL; - ntree->tbh= ntree->sdh= NULL; + ntree->progress= NULL; + ntree->tbh= ntree->sdh= ntree->prh= NULL; } } else if(re->r.scemode & R_FULL_SAMPLE) @@ -2403,6 +2429,24 @@ static void renderresult_stampinfo(Scene *scene) RE_ReleaseResultImage(re); } +static int seq_render_active(Render *re) +{ + Editing *ed; + Sequence *seq; + + ed = re->scene->ed; + + if (!(re->r.scemode & R_DOSEQ) || !ed || !ed->seqbase.first) + return 0; + + for (seq= ed->seqbase.first; seq; seq= seq->next) { + if (seq->type != SEQ_SOUND) + return 1; + } + + return 0; +} + static void do_render_seq(Render * re) { static int recurs_depth = 0; @@ -2410,14 +2454,16 @@ static void do_render_seq(Render * re) RenderResult *rr = re->result; int cfra = re->r.cfra; + re->i.cfra= cfra; + if(recurs_depth==0) { /* otherwise sequencer animation isnt updated */ - BKE_animsys_evaluate_all_animation(G.main, (float)cfra); // XXX, was frame_to_float(re->scene, cfra) + BKE_animsys_evaluate_all_animation(re->main, (float)cfra); // XXX, was BKE_curframe(re->scene) } recurs_depth++; - ibuf= give_ibuf_seq(re->scene, rr->rectx, rr->recty, cfra, 0, 100.0); + ibuf= give_ibuf_seq(re->main, re->scene, rr->rectx, rr->recty, cfra, 0, 100.0); recurs_depth--; @@ -2428,7 +2474,21 @@ static void do_render_seq(Render * re) if (!rr->rectf) rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf"); - memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty); + /* color management: when off ensure rectf is non-lin, since thats what the internal + * render engine delivers */ + if(re->r.color_mgt_flag & R_COLOR_MANAGEMENT) { + if(ibuf->profile == IB_PROFILE_LINEAR_RGB) + memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty); + else + srgb_to_linearrgb_rgba_rgba_buf(rr->rectf, ibuf->rect_float, rr->rectx*rr->recty); + + } + else { + if(ibuf->profile != IB_PROFILE_LINEAR_RGB) + memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty); + else + linearrgb_to_srgb_rgba_rgba_buf(rr->rectf, ibuf->rect_float, rr->rectx*rr->recty); + } /* TSK! Since sequence render doesn't free the *rr render result, the old rect32 can hang around when sequence render has rendered a 32 bits one before */ @@ -2452,9 +2512,10 @@ static void do_render_seq(Render * re) if (recurs_depth == 0) { /* with nested scenes, only free on toplevel... */ Editing * ed = re->scene->ed; if (ed) { - free_imbuf_seq(re->scene, &ed->seqbase, TRUE); + free_imbuf_seq(re->scene, &ed->seqbase, TRUE, TRUE); } } + IMB_freeImBuf(ibuf); } else { /* render result is delivered empty in most cases, nevertheless we handle all cases */ @@ -2484,7 +2545,7 @@ static void do_render_all_options(Render *re) if(external_render_3d(re, 1)) { /* in this case external render overrides all */ } - else if((re->r.scemode & R_DOSEQ) && re->scene->ed && re->scene->ed->seqbase.first) { + else if(seq_render_active(re)) { /* note: do_render_seq() frees rect32 when sequencer returns float images */ if(!re->test_break(re->tbh)) do_render_seq(re); @@ -2620,6 +2681,7 @@ static void update_physics_cache(Render *re, Scene *scene, int anim_init) { PTCacheBaker baker; + baker.main = re->main; baker.scene = scene; baker.pid = NULL; baker.bake = 0; @@ -2633,7 +2695,7 @@ static void update_physics_cache(Render *re, Scene *scene, int anim_init) BKE_ptcache_make_cache(&baker); } /* evaluating scene options for general Blender render */ -static int render_initialize_from_scene(Render *re, Scene *scene, SceneRenderLayer *srl, unsigned int lay, int anim, int anim_init) +static int render_initialize_from_main(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *srl, unsigned int lay, int anim, int anim_init) { int winx, winy; rcti disprect; @@ -2659,6 +2721,7 @@ static int render_initialize_from_scene(Render *re, Scene *scene, SceneRenderLay disprect.ymax= winy; } + re->main= bmain; re->scene= scene; re->lay= lay; @@ -2701,17 +2764,18 @@ static int render_initialize_from_scene(Render *re, Scene *scene, SceneRenderLay } /* general Blender frame render call */ -void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, unsigned int lay, int frame) +void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *srl, unsigned int lay, int frame) { /* ugly global still... is to prevent preview events and signal subsurfs etc to make full resol */ G.rendering= 1; scene->r.cfra= frame; - if(render_initialize_from_scene(re, scene, srl, lay, 0, 0)) { + if(render_initialize_from_main(re, bmain, scene, srl, lay, 0, 0)) { + MEM_reset_peak_memory(); do_render_all_options(re); } - + /* UGLY WARNING */ G.rendering= 0; } @@ -2803,14 +2867,14 @@ static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, R } /* saves images to disk */ -void RE_BlenderAnim(Render *re, Scene *scene, unsigned int lay, int sfra, int efra, int tfra, ReportList *reports) +void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, unsigned int lay, int sfra, int efra, int tfra, ReportList *reports) { bMovieHandle *mh= BKE_get_movie_handle(scene->r.imtype); int cfrao= scene->r.cfra; int nfra; /* do not fully call for each frame, it initializes & pops output window */ - if(!render_initialize_from_scene(re, scene, NULL, lay, 0, 1)) + if(!render_initialize_from_main(re, bmain, scene, NULL, lay, 0, 1)) return; /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ @@ -2843,7 +2907,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, unsigned int lay, int sfra, int ef char name[FILE_MAX]; /* only border now, todo: camera lens. (ton) */ - render_initialize_from_scene(re, scene, NULL, lay, 1, 0); + render_initialize_from_main(re, bmain, scene, NULL, lay, 1, 0); if(nfra!=scene->r.cfra) { /* @@ -2858,7 +2922,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, unsigned int lay, int sfra, int ef else updatelay= re->lay; - scene_update_for_newframe(scene, updatelay); + scene_update_for_newframe(bmain, scene, updatelay); continue; } else @@ -2909,12 +2973,12 @@ void RE_BlenderAnim(Render *re, Scene *scene, unsigned int lay, int sfra, int ef mh->end_movie(); scene->r.cfra= cfrao; - + /* UGLY WARNING */ G.rendering= 0; } -void RE_PreviewRender(Render *re, Scene *sce) +void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) { int winx, winy; @@ -2923,6 +2987,7 @@ void RE_PreviewRender(Render *re, Scene *sce) RE_InitState(re, NULL, &sce->r, NULL, winx, winy, NULL); + re->main = bmain; re->scene = sce; re->lay = sce->lay; diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index d22b24bf544..a09c16b7ed9 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -39,6 +39,7 @@ #include "BKE_main.h" #include "BKE_object.h" #include "BKE_particle.h" +#include "BKE_scene.h" #include "BKE_texture.h" #include "DNA_meshdata_types.h" @@ -95,7 +96,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa ParticleKey state; ParticleSimulationData sim = {re->scene, ob, psys, NULL}; ParticleData *pa=NULL; - float cfra = bsystem_time(re->scene, ob, (float)re->scene->r.cfra, 0.0); + float cfra = BKE_curframe(re->scene); int i, childexists; int total_particles, offset=0; int data_used = point_data_used(pd); @@ -142,9 +143,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa if (pd->psys_cache_space == TEX_PD_OBJECTSPACE) mul_m4_v3(ob->imat, partco); else if (pd->psys_cache_space == TEX_PD_OBJECTLOC) { - float obloc[3]; - VECCOPY(obloc, ob->loc); - sub_v3_v3v3(partco, partco, obloc); + sub_v3_v3(partco, ob->loc); } else { /* TEX_PD_WORLDSPACE */ } @@ -209,7 +208,7 @@ static void pointdensity_cache_object(Render *re, PointDensity *pd, Object *ob) break; case TEX_PD_OBJECTLOC: mul_m4_v3(ob->obmat, co); - sub_v3_v3v3(co, co, ob->loc); + sub_v3_v3(co, ob->loc); break; case TEX_PD_WORLDSPACE: default: @@ -227,6 +226,9 @@ static void pointdensity_cache_object(Render *re, PointDensity *pd, Object *ob) static void cache_pointdensity(Render *re, Tex *tex) { PointDensity *pd = tex->pd; + + if(!pd) + return; if (pd->point_tree) { BLI_bvhtree_free(pd->point_tree); @@ -280,7 +282,7 @@ void make_pointdensities(Render *re) re->i.infostr= "Caching Point Densities"; re->stats_draw(re->sdh, &re->i); - for (tex= G.main->tex.first; tex; tex= tex->id.next) { + for (tex= re->main->tex.first; tex; tex= tex->id.next) { if(tex->id.us && tex->type==TEX_POINTDENSITY) { cache_pointdensity(re, tex); } @@ -297,7 +299,7 @@ void free_pointdensities(Render *re) if(re->scene->r.scemode & R_PREVIEWBUTS) return; - for (tex= G.main->tex.first; tex; tex= tex->id.next) { + for (tex= re->main->tex.first; tex; tex= tex->id.next) { if(tex->id.us && tex->type==TEX_POINTDENSITY) { free_pointdensity(re, tex); } diff --git a/source/blender/render/intern/source/rayobject_instance.c b/source/blender/render/intern/source/rayobject_instance.c index c36ab454f3d..25765c4763a 100644 --- a/source/blender/render/intern/source/rayobject_instance.c +++ b/source/blender/render/intern/source/rayobject_instance.c @@ -143,6 +143,13 @@ static int RE_rayobject_instance_intersect(RayObject *o, Isect *isec) { isec->labda *= dist / isec->dist; isec->hit.ob = obj->ob; + +#ifdef RT_USE_LAST_HIT + // TODO support for last hit optimization in instances that can jump + // directly to the last hit face. + // For now it jumps directly to the last-hit instance root node. + isec->last_hit = RE_rayobject_unalignRayAPI((RayObject*) obj); +#endif } isec->dist = dist; VECCOPY( isec->start, start ); diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 015922216f9..724fd9a3110 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -41,9 +41,10 @@ #include "BKE_node.h" #include "BKE_utildefines.h" -#include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_cpu.h" #include "BLI_jitter.h" +#include "BLI_math.h" #include "BLI_rand.h" #include "PIL_time.h" @@ -98,7 +99,7 @@ RayObject* RE_rayobject_create(Render *re, int type, int size) //TODO //if(detect_simd()) #ifdef __SSE__ - type = R_RAYSTRUCTURE_SIMD_SVBVH; + type = BLI_cpu_support_sse2()? R_RAYSTRUCTURE_SIMD_SVBVH: R_RAYSTRUCTURE_VBVH; #else type = R_RAYSTRUCTURE_VBVH; #endif @@ -240,7 +241,9 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) if(is_raytraceable_vlr(re, vlr)) faces++; } - assert( faces > 0 ); + + if (faces == 0) + return NULL; //Create Ray cast accelaration structure raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces ); @@ -370,7 +373,12 @@ static void makeraytree_single(Render *re) if(has_special_rayobject(re, obi)) { RayObject *obj = makeraytree_object(re, obi); - RE_rayobject_add( re->raytree, obj ); + + if(test_break(re)) + break; + + if (obj) + RE_rayobject_add( re->raytree, obj ); } else { @@ -523,10 +531,6 @@ void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) shade_input_set_normals(shi); - /* point normals to viewing direction */ - if(INPR(shi->facenor, shi->view) < 0.0f) - shade_input_flip_normals(shi); - shade_input_set_shade_texco(shi); if (shi->mat->material_type == MA_TYPE_VOLUME) { if(ELEM(is->mode, RE_RAY_SHADOW, RE_RAY_SHADOW_TRA)) { @@ -550,19 +554,9 @@ void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) shi->mat= vlr->mat; /* shi->mat is being set in nodetree */ } else { - int tempdepth; - /* XXX dodgy business here, set ray depth to -1 - * to ignore raytrace in shade_material_loop() - * this could really use a refactor --Matt */ - if (shi->volume_depth == 0) { - tempdepth = shi->depth; - shi->depth = -1; - shade_material_loop(shi, shr); - shi->depth = tempdepth; - } else { - shade_material_loop(shi, shr); - } + shade_material_loop(shi, shr); } + /* raytrace likes to separate the spec color */ VECSUB(shr->diff, shr->combined, shr->spec); } @@ -1310,7 +1304,7 @@ static void trace_refract(float *col, ShadeInput *shi, ShadeResult *shr) /* and perturb the refraction vector in it */ add_v3_v3v3(v_refract_new, v_refract, orthx); - add_v3_v3v3(v_refract_new, v_refract_new, orthy); + add_v3_v3(v_refract_new, orthy); normalize_v3(v_refract_new); } else { @@ -1405,7 +1399,7 @@ static void trace_reflect(float *col, ShadeInput *shi, ShadeResult *shr, float f /* and perturb the normal in it */ add_v3_v3v3(v_nor_new, shi->vn, orthx); - add_v3_v3v3(v_nor_new, v_nor_new, orthy); + add_v3_v3(v_nor_new, orthy); normalize_v3(v_nor_new); } else { /* no blurriness, use the original normal */ @@ -1728,7 +1722,7 @@ static void DS_energy(float *sphere, int tot, float *vec) } mul_v3_fl(res, 0.5); - add_v3_v3v3(vec, vec, res); + add_v3_v3(vec, res); normalize_v3(vec); } diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 047bbd7629f..8e1a959abef 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2619,7 +2619,7 @@ static void *do_bake_thread(void *bs_v) /* using object selection tags, the faces with UV maps get baked */ /* render should have been setup */ /* returns 0 if nothing was handled */ -int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_update) +int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_update, float *progress) { BakeShade *handles; ListBase threads; @@ -2634,7 +2634,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up get_next_bake_face(NULL); /* do we need a mask? */ - if (re->r.bake_filter && (re->r.bake_flag & R_BAKE_CLEAR)==0) + if (re->r.bake_filter) usemask = 1; /* baker uses this flag to detect if image was initialized */ @@ -2680,12 +2680,18 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up /* wait for everything to be done */ a= 0; while(a!=re->r.threads) { - PIL_sleep_ms(50); - for(a=0; a<re->r.threads; a++) + /* calculate progress */ + for(vdone=0, a=0; a<re->r.threads; a++) + vdone+= handles[a].vdone; + if (progress) + *progress = (float)(vdone / (float)re->totvlak); + + for(a=0; a<re->r.threads; a++) { if(handles[a].ready==0) break; + } } /* filter and refresh images */ @@ -2733,12 +2739,10 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up } /* calculate return value */ - for(a=0; a<re->r.threads; a++) { - vdone+= handles[a].vdone; - + for(a=0; a<re->r.threads; a++) { zbuf_free_span(handles[a].zspan); MEM_freeN(handles[a].zspan); - } + } MEM_freeN(handles); diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 2bfc8f6c1ef..ce55935d392 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -440,10 +440,9 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr) return vlr1; } -int RE_vlakren_get_normal(Render *re, ObjectInstanceRen *obi, VlakRen *vlr, float *nor) +void RE_vlakren_get_normal(Render *re, ObjectInstanceRen *obi, VlakRen *vlr, float *nor) { - float v1[3], (*nmat)[3]= obi->nmat; - int flipped= 0; + float (*nmat)[3]= obi->nmat; if(obi->flag & R_TRANSFORMED) { VECCOPY(nor, vlr->n); @@ -453,29 +452,6 @@ int RE_vlakren_get_normal(Render *re, ObjectInstanceRen *obi, VlakRen *vlr, floa } else VECCOPY(nor, vlr->n); - - if((vlr->flag & R_NOPUNOFLIP)==0) { - if(re->r.mode & R_ORTHO) { - if(nor[2] > 0.0f) - flipped= 1; - } - else { - VECCOPY(v1, vlr->v1->co); - if(obi->flag & R_TRANSFORMED) - mul_m4_v3(obi->mat, v1); - if(INPR(v1, nor) < 0.0f) { - flipped= 1; - } - } - - if(flipped) { - nor[0]= -nor[0]; - nor[1]= -nor[1]; - nor[2]= -nor[2]; - } - } - - return flipped; } void RE_set_customdata_names(ObjectRen *obr, CustomData *data) diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 35d969f9f21..7101ce5daaf 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -2204,7 +2204,7 @@ static void isb_make_buffer(RenderPart *pa, LampRen *lar) isbdata->recty= pa->recty; /* branches are added using memarena (32k branches) */ - memarena = BLI_memarena_new(0x8000 * sizeof(ISBBranch)); + memarena = BLI_memarena_new(0x8000 * sizeof(ISBBranch), "isb arena"); BLI_memarena_use_calloc(memarena); /* samplebuf is in camera view space (pixels) */ @@ -2300,7 +2300,7 @@ static void isb_make_buffer(RenderPart *pa, LampRen *lar) if(R.osa) { ISBShadfacA **isbsa= isbdata->shadfaca= MEM_callocN(pa->rectx*pa->recty*sizeof(void *), "isb shadfacs"); - isbdata->memarena = BLI_memarena_new(0x8000 * sizeof(ISBSampleA)); + isbdata->memarena = BLI_memarena_new(0x8000 * sizeof(ISBSampleA), "isb arena"); BLI_memarena_use_calloc(isbdata->memarena); for(rd= pa->rectdaps, x=pa->rectx*pa->recty; x>0; x--, rd++, isbsa++) { @@ -2412,7 +2412,7 @@ static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *la isbdata->recty= pa->recty; /* branches are added using memarena (32k branches) */ - memarena = BLI_memarena_new(0x8000 * sizeof(ISBBranch)); + memarena = BLI_memarena_new(0x8000 * sizeof(ISBBranch), "isb arena"); BLI_memarena_use_calloc(memarena); /* samplebuf is in camera view space (pixels) */ @@ -2503,7 +2503,7 @@ static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *la /* copy shadow samples to persistant buffer, reduce memory overhead */ isbsa= isbdata->shadfaca= MEM_callocN(pa->rectx*pa->recty*sizeof(void *), "isb shadfacs"); - isbdata->memarena = BLI_memarena_new(0x8000 * sizeof(ISBSampleA)); + isbdata->memarena = BLI_memarena_new(0x8000 * sizeof(ISBSampleA), "isb arena"); for(ap= apixbuf, x=pa->rectx*pa->recty; x>0; x--, ap++, isbsa++) { diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 17ca087c52e..56ab56d0411 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -130,7 +130,7 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr) } /* depth >= 1 when ray-shading */ - if(shi->depth==0) { + if(shi->depth==0 || shi->volume_depth > 0) { if(R.r.mode & R_RAYTRACE) { if(shi->ray_mirror!=0.0f || ((shi->mat->mode & MA_TRANSP) && (shi->mat->mode & MA_RAYTRANSP) && shr->alpha!=1.0f)) { /* ray trace works on combined, but gives pass info */ @@ -142,11 +142,6 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr) if((shi->layflag & SCE_LAY_SKY) && (R.r.alphamode==R_ADDSKY)) shr->alpha= 1.0f; } - - if(R.r.mode & R_RAYTRACE) { - if (R.render_volumes_inside.first) - shade_volume_inside(shi, shr); - } } @@ -168,8 +163,12 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr) shade_input_init_material(shi); if (shi->mat->material_type == MA_TYPE_VOLUME) { - if(R.r.mode & R_RAYTRACE) - shade_volume_outside(shi, shr); + if(R.r.mode & R_RAYTRACE) { + if (R.render_volumes_inside.first) + shade_volume_inside(shi, shr); + else + shade_volume_outside(shi, shr); + } } else { /* MA_TYPE_SURFACE, MA_TYPE_WIRE */ shade_material_loop(shi, shr); } @@ -274,12 +273,8 @@ void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen shi->mode= shi->mat->mode_l; /* or-ed result for all nodes */ /* facenormal copy, can get flipped */ - shi->flippednor= RE_vlakren_get_normal(&R, obi, vlr, shi->facenor); - - /* copy of original pre-flipped normal, for geometry->front/back node output */ - VECCOPY(shi->orignor, shi->facenor); - if(shi->flippednor) - VECMUL(shi->orignor, -1.0f); + shi->flippednor= 0; + RE_vlakren_get_normal(&R, obi, vlr, shi->facenor); /* calculate vertexnormals */ if(vlr->flag & R_SMOOTH) { @@ -292,24 +287,6 @@ void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen mul_m3_v3(obi->nmat, shi->n2); mul_m3_v3(obi->nmat, shi->n3); } - - if(!(vlr->flag & (R_NOPUNOFLIP|R_TANGENT))) { - if(INPR(shi->facenor, shi->n1) < 0.0f) { - shi->n1[0]= -shi->n1[0]; - shi->n1[1]= -shi->n1[1]; - shi->n1[2]= -shi->n1[2]; - } - if(INPR(shi->facenor, shi->n2) < 0.0f) { - shi->n2[0]= -shi->n2[0]; - shi->n2[1]= -shi->n2[1]; - shi->n2[2]= -shi->n2[2]; - } - if(INPR(shi->facenor, shi->n3) < 0.0f) { - shi->n3[0]= -shi->n3[0]; - shi->n3[1]= -shi->n3[1]; - shi->n3[2]= -shi->n3[2]; - } - } } } @@ -372,7 +349,6 @@ void shade_input_set_strand(ShadeInput *shi, StrandRen *strand, StrandPoint *spo /* facenormal, simply viewco flipped */ VECCOPY(shi->facenor, spoint->nor); - VECCOPY(shi->orignor, shi->facenor); /* shade_input_set_normals equivalent */ if(shi->mat->mode & MA_TANGENT_STR) { @@ -833,6 +809,10 @@ void shade_input_set_normals(ShadeInput *shi) /* used in nodes */ VECCOPY(shi->vno, shi->vn); + /* flip normals to viewing direction */ + if(!(shi->vlr->flag & R_TANGENT)) + if(dot_v3v3(shi->facenor, shi->view) < 0.0f) + shade_input_flip_normals(shi); } /* use by raytrace, sss, bake to flip into the right direction */ diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 806cafaf89b..81de553b209 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -1644,7 +1644,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) if(((passflag & SCE_PASS_COMBINED) && (shi->combinedflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT))) || (passflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT))) { /* AO was calculated for scanline already */ - if(shi->depth) + if(shi->depth || shi->volume_depth) ambient_occlusion(shi); VECCOPY(shr->ao, shi->ao); VECCOPY(shr->env, shi->env); // XXX multiply diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 836a60ef4f9..e8c95a34ac4 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -56,7 +56,6 @@ #include "DNA_material_types.h" #include "BKE_colortools.h" -#include "BKE_global.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_node.h" @@ -779,7 +778,7 @@ void scatter_tree_build(ScatterTree *tree) tmppoints= MEM_callocN(sizeof(ScatterPoint*)*totpoint, "ScatterTmpPoints"); tree->tmppoints= tmppoints; - tree->arena= BLI_memarena_new(0x8000 * sizeof(ScatterNode)); + tree->arena= BLI_memarena_new(0x8000 * sizeof(ScatterNode), "sss tree arena"); BLI_memarena_use_calloc(tree->arena); /* build tree */ @@ -988,12 +987,12 @@ void make_sss_tree(Render *re) { Material *mat; - re->sss_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + re->sss_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "make_sss_tree gh"); re->i.infostr= "SSS preprocessing"; re->stats_draw(re->sdh, &re->i); - for(mat= G.main->mat.first; mat; mat= mat->id.next) + for(mat= re->main->mat.first; mat; mat= mat->id.next) if(mat->id.us && (mat->flag & MA_IS_USED) && (mat->sss_flag & MA_DIFF_SSS)) sss_create_tree_mat(re, mat); } diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 1bf1f1fe582..88d042e7b97 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -318,9 +318,9 @@ StrandShadeCache *strand_shade_cache_create() StrandShadeCache *cache; cache= MEM_callocN(sizeof(StrandShadeCache), "StrandShadeCache"); - cache->resulthash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); - cache->refcounthash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); - cache->memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + cache->resulthash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "strand_shade_cache_create1 gh"); + cache->refcounthash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "strand_shade_cache_create2 gh"); + cache->memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "strand shade cache arena"); return cache; } @@ -818,7 +818,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa bounds[2]= (2*pa->disprect.ymin - winy-1)/(float)winy; bounds[3]= (2*pa->disprect.ymax - winy+1)/(float)winy; - memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "strand sort arena"); firstseg= NULL; sortseg= sortsegments; totsegment= 0; diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 8b33753c2b1..0e98069f884 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -98,7 +98,7 @@ void init_render_texture(Render *re, Tex *tex) if(tex->type==TEX_PLUGIN) { if(tex->plugin && tex->plugin->doit) { if(tex->plugin->cfra) { - *(tex->plugin->cfra)= (float)cfra; //frame_to_float(re->scene, cfra); // XXX old animsys - timing stuff to be fixed + *(tex->plugin->cfra)= (float)cfra; //BKE_curframe(re->scene); // XXX old animsys - timing stuff to be fixed } } } @@ -131,7 +131,7 @@ void init_render_textures(Render *re) { Tex *tex; - tex= G.main->tex.first; + tex= re->main->tex.first; while(tex) { if(tex->id.us) init_render_texture(re, tex); tex= tex->id.next; @@ -144,10 +144,10 @@ void end_render_texture(Tex *tex) ntreeEndExecTree(tex->nodetree); } -void end_render_textures(void) +void end_render_textures(Render *re) { Tex *tex; - for(tex= G.main->tex.first; tex; tex= tex->id.next) + for(tex= re->main->tex.first; tex; tex= tex->id.next) if(tex->id.us) end_render_texture(tex); } @@ -1731,7 +1731,7 @@ void do_material_tex(ShadeInput *shi) co= shi->tang; dx= shi->dxno; dy= shi->dyno; } else if(mtex->texco==TEXCO_GLOB) { - co= shi->gl; dx= shi->dxco; dy= shi->dyco; + co= shi->gl; dx= shi->dxgl; dy= shi->dygl; } else if(mtex->texco==TEXCO_UV) { if(mtex->texflag & MTEX_DUPLI_MAPTO) { @@ -1762,7 +1762,7 @@ void do_material_tex(ShadeInput *shi) // NOTE: test for shi->obr->ob here, since vlr/obr/obi can be 'fake' when called from fastshade(), another reason to move it.. // NOTE: shi->v1 is NULL when called from displace_render_vert, assigning verts in this case is not trivial because the shi quad face side is not know. if ((mtex->texflag & MTEX_NEW_BUMP) && shi->obr && shi->obr->ob && shi->v1) { - if(mtex->mapto & (MAP_NORM|MAP_DISPLACE|MAP_WARP) && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) { + if(mtex->mapto & (MAP_NORM|MAP_WARP) && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) { MTFace* tf = RE_vlakren_get_tface(shi->obr, shi->vlr, i, NULL, 0); int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3; @@ -1833,7 +1833,7 @@ void do_material_tex(ShadeInput *shi) else continue; // can happen when texco defines disappear and it renders old files /* the pointer defines if bumping happens */ - if(mtex->mapto & (MAP_NORM|MAP_DISPLACE|MAP_WARP)) { + if(mtex->mapto & (MAP_NORM|MAP_WARP)) { texres.nor= norvec; norvec[0]= norvec[1]= norvec[2]= 0.0; } @@ -2219,8 +2219,7 @@ void do_material_tex(ShadeInput *shi) } if(rgbnor & TEX_RGB) { - if(texres.talpha) texres.tin= texres.ta; - else texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); + texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); } factt= (0.5f-texres.tin)*mtex->dispfac*stencilTin; facmm= 1.0f-factt; @@ -2510,6 +2509,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) if (R.r.scemode & R_NO_TEX) return; mtex= har->mat->mtex[0]; + if(har->mat->septex & (1<<0)) return; if(mtex->tex==NULL) return; /* no normal mapping */ @@ -2676,7 +2676,8 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f switch(mtex->texco) { case TEXCO_ANGMAP: /* only works with texture being "real" */ - fact= (1.0/M_PI)*acos(lo[2])/(sqrt(lo[0]*lo[0] + lo[1]*lo[1])); + /* use saacos(), fixes bug [#22398], float precission caused lo[2] to be slightly less then -1.0 */ + fact= (1.0/M_PI)*saacos(lo[2])/(sqrt(lo[0]*lo[0] + lo[1]*lo[1])); tempvec[0]= lo[0]*fact; tempvec[1]= lo[1]*fact; tempvec[2]= 0.0; @@ -2881,6 +2882,9 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef if(la->type==LA_SPOT) { tempvec[0]*= la->spottexfac; tempvec[1]*= la->spottexfac; + /* project from 3d to 2d */ + tempvec[0] /= -tempvec[2]; + tempvec[1] /= -tempvec[2]; } co= tempvec; diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index 0af05c3cdee..d3e8f4058c5 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -115,6 +115,47 @@ int point_inside_obi(RayObject *tree, ObjectInstanceRen *obi, float *co) else return 1; } +/* find the bounding box of an objectinstance in global space */ +void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float *bbmin, float *bbmax) +{ + ObjectRen *obr = obi->obr; + VolumePrecache *vp = obi->volume_precache; + VertRen *ver= NULL; + float co[3]; + int a; + + if (vp->bbmin != NULL && vp->bbmax != NULL) { + copy_v3_v3(bbmin, vp->bbmin); + copy_v3_v3(bbmax, vp->bbmax); + return; + } + + vp->bbmin = MEM_callocN(sizeof(float)*3, "volume precache min boundbox corner"); + vp->bbmax = MEM_callocN(sizeof(float)*3, "volume precache max boundbox corner"); + + INIT_MINMAX(bbmin, bbmax); + + for(a=0; a<obr->totvert; a++) { + if((a & 255)==0) ver= obr->vertnodes[a>>8].vert; + else ver++; + + copy_v3_v3(co, ver->co); + + /* transformed object instance in camera space */ + if(obi->flag & R_TRANSFORMED) + mul_m4_v3(obi->mat, co); + + /* convert to global space */ + mul_m4_v3(re->viewinv, co); + + DO_MINMAX(co, vp->bbmin, vp->bbmax); + } + + copy_v3_v3(bbmin, vp->bbmin); + copy_v3_v3(bbmax, vp->bbmax); + +} + /* *** light cache filtering *** */ static float get_avg_surrounds(float *cache, int *res, int xx, int yy, int zz) @@ -443,7 +484,7 @@ static void *vol_precache_part(void *data) RayObject *tree = pa->tree; ShadeInput *shi = pa->shi; float scatter_col[3] = {0.f, 0.f, 0.f}; - float co[3]; + float co[3], cco[3]; int x, y, z, i; const int res[3]= {pa->res[0], pa->res[1], pa->res[2]}; @@ -455,24 +496,29 @@ static void *vol_precache_part(void *data) for (x=pa->minx; x < pa->maxx; x++) { co[0] = pa->bbmin[0] + (pa->voxel[0] * (x + 0.5f)); - + + /* convert from world->camera space for shading */ + mul_v3_m4v3(cco, pa->viewmat, co); + i= V_I(x, y, z, res); // don't bother if the point is not inside the volume mesh - if (!point_inside_obi(tree, obi, co)) { + if (!point_inside_obi(tree, obi, cco)) { obi->volume_precache->data_r[i] = -1.0f; obi->volume_precache->data_g[i] = -1.0f; obi->volume_precache->data_b[i] = -1.0f; continue; } - copy_v3_v3(shi->view, co); + /* this view coordinate is very wrong! */ + copy_v3_v3(shi->view, cco); normalize_v3(shi->view); - vol_get_scattering(shi, scatter_col, co); + vol_get_scattering(shi, scatter_col, cco); obi->volume_precache->data_r[i] = scatter_col[0]; obi->volume_precache->data_g[i] = scatter_col[1]; obi->volume_precache->data_b[i] = scatter_col[2]; + } } } @@ -503,7 +549,7 @@ static void precache_init_parts(Render *re, RayObject *tree, ShadeInput *shi, Ob int i=0, x, y, z; float voxel[3]; int sizex, sizey, sizez; - float *bbmin=obi->obr->boundbox[0], *bbmax=obi->obr->boundbox[1]; + float bbmin[3], bbmax[3]; int *res; int minx, maxx; int miny, maxy; @@ -517,11 +563,13 @@ static void precache_init_parts(Render *re, RayObject *tree, ShadeInput *shi, Ob parts[0] = parts[1] = parts[2] = totthread; res = vp->res; + /* using boundbox in worldspace */ + global_bounds_obi(re, obi, bbmin, bbmax); sub_v3_v3v3(voxel, bbmax, bbmin); - voxel[0] /= res[0]; - voxel[1] /= res[1]; - voxel[2] /= res[2]; + voxel[0] /= (float)res[0]; + voxel[1] /= (float)res[1]; + voxel[2] /= (float)res[2]; for (x=0; x < parts[0]; x++) { sizex = ceil(res[0] / (float)parts[0]); @@ -550,8 +598,10 @@ static void precache_init_parts(Render *re, RayObject *tree, ShadeInput *shi, Ob pa->tree = tree; pa->shi = shi; pa->obi = obi; - VECCOPY(pa->bbmin, bbmin); - VECCOPY(pa->voxel, voxel); + copy_m4_m4(pa->viewmat, re->viewmat); + + copy_v3_v3(pa->bbmin, bbmin); + copy_v3_v3(pa->voxel, voxel); VECCOPY(pa->res, res); pa->minx = minx; pa->maxx = maxx; @@ -582,10 +632,14 @@ static VolPrecachePart *precache_get_new_part(Render *re) return nextpa; } -static int precache_resolution(VolumePrecache *vp, float *bbmin, float *bbmax, int res) +/* calculate resolution from bounding box in world space */ +static int precache_resolution(Render *re, VolumePrecache *vp, ObjectInstanceRen *obi, int res) { float dim[3], div; + float bbmin[3], bbmax[3]; + /* bound box in global space */ + global_bounds_obi(re, obi, bbmin, bbmax); sub_v3_v3v3(dim, bbmax, bbmin); div = MAX3(dim[0], dim[1], dim[2]); @@ -593,9 +647,9 @@ static int precache_resolution(VolumePrecache *vp, float *bbmin, float *bbmax, i dim[1] /= div; dim[2] /= div; - vp->res[0] = dim[0] * (float)res; - vp->res[1] = dim[1] * (float)res; - vp->res[2] = dim[2] * (float)res; + vp->res[0] = ceil(dim[0] * res); + vp->res[1] = ceil(dim[1] * res); + vp->res[2] = ceil(dim[2] * res); if ((vp->res[0] < 1) || (vp->res[1] < 1) || (vp->res[2] < 1)) return 0; @@ -615,7 +669,6 @@ void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Mat RayObject *tree; ShadeInput shi; ListBase threads; - float *bbmin=obi->obr->boundbox[0], *bbmax=obi->obr->boundbox[1]; int parts[3] = {1, 1, 1}, totparts; int caching=1, counter=0; @@ -627,15 +680,13 @@ void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Mat /* create a raytree with just the faces of the instanced ObjectRen, * used for checking if the cached point is inside or outside. */ - //tree = create_raytree_obi(obi, bbmin, bbmax); tree = makeraytree_object(&R, obi); if (!tree) return; - INIT_MINMAX(bbmin, bbmax); - RE_rayobject_merge_bb( tree, bbmin, bbmax); vp = MEM_callocN(sizeof(VolumePrecache), "volume light cache"); + obi->volume_precache = vp; - if (!precache_resolution(vp, bbmin, bbmax, ma->vol.precache_resolution)) { + if (!precache_resolution(re, vp, obi, ma->vol.precache_resolution)) { MEM_freeN(vp); vp = NULL; return; @@ -649,7 +700,6 @@ void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Mat vp = NULL; return; } - obi->volume_precache = vp; /* Need a shadeinput to calculate scattering */ precache_setup_shadeinput(re, obi, ma, &shi); @@ -749,6 +799,8 @@ void free_volume_precache(Render *re) MEM_freeN(obi->volume_precache->data_r); MEM_freeN(obi->volume_precache->data_g); MEM_freeN(obi->volume_precache->data_b); + MEM_freeN(obi->volume_precache->bbmin); + MEM_freeN(obi->volume_precache->bbmax); MEM_freeN(obi->volume_precache); obi->volume_precache = NULL; } diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 99c27aaf81e..a58d96736d5 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -56,10 +56,6 @@ #include "volumetric.h" #include "volume_precache.h" -#if defined( _MSC_VER ) && !defined( __cplusplus ) -# define inline __inline -#endif // defined( _MSC_VER ) && !defined( __cplusplus ) - /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ /* only to be used here in this file, it's for speed */ @@ -67,7 +63,7 @@ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* luminance rec. 709 */ -inline float luminance(float* col) +BM_INLINE float luminance(float* col) { return (0.212671f*col[0] + 0.71516f*col[1] + 0.072169f*col[2]); } @@ -197,7 +193,7 @@ static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, float *co, float *co isect.labda = FLT_MAX; isect.mode= RE_RAY_MIRROR; - isect.skip = RE_SKIP_VLR_NEIGHBOUR | RE_SKIP_VLR_RENDER_CHECK; + isect.skip = RE_SKIP_VLR_NEIGHBOUR; isect.orig.ob = (void*) shi->obi; isect.orig.face = (void*)vlr; isect.last_hit = NULL; @@ -209,27 +205,28 @@ static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, float *co, float *co } else { shadeSkyView(col, co, shi->view, NULL, shi->thread); shadeSunView(col, shi->view); - } + } } /* trilinear interpolation */ -static void vol_get_precached_scattering(ShadeInput *shi, float *scatter_col, float *co) +static void vol_get_precached_scattering(Render *re, ShadeInput *shi, float *scatter_col, float *co) { VolumePrecache *vp = shi->obi->volume_precache; float bbmin[3], bbmax[3], dim[3]; - float sample_co[3]; + float world_co[3], sample_co[3]; if (!vp) return; - /* convert input coords to 0.0, 1.0 */ - VECCOPY(bbmin, shi->obi->obr->boundbox[0]); - VECCOPY(bbmax, shi->obi->obr->boundbox[1]); + /* find sample point in global space bounding box 0.0-1.0 */ + global_bounds_obi(re, shi->obi, bbmin, bbmax); sub_v3_v3v3(dim, bbmax, bbmin); + mul_v3_m4v3(world_co, re->viewinv, co); - sample_co[0] = ((co[0] - bbmin[0]) / dim[0]); - sample_co[1] = ((co[1] - bbmin[1]) / dim[1]); - sample_co[2] = ((co[2] - bbmin[2]) / dim[2]); + /* sample_co in 0.0-1.0 */ + sample_co[0] = (world_co[0] - bbmin[0]) / dim[0]; + sample_co[1] = (world_co[1] - bbmin[1]) / dim[1]; + sample_co[2] = (world_co[2] - bbmin[2]) / dim[2]; scatter_col[0] = voxel_sample_triquadratic(vp->data_r, vp->res, sample_co); scatter_col[1] = voxel_sample_triquadratic(vp->data_g, vp->res, sample_co); @@ -449,13 +446,13 @@ static void vol_get_transmittance(ShadeInput *shi, float *tr, float *co, float * const float stepd = (t0 - pt0) * d; float sigma_t[3]; - vol_get_sigma_t(shi, sigma_t, co); + vol_get_sigma_t(shi, sigma_t, p); tau[0] += stepd * sigma_t[0]; tau[1] += stepd * sigma_t[1]; tau[2] += stepd * sigma_t[2]; - add_v3_v3v3(p, p, step_vec); + add_v3_v3(p, step_vec); } /* return transmittance */ @@ -561,7 +558,7 @@ void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co) if (lar) { vol_shade_one_lamp(shi, co, lar, lacol); - add_v3_v3v3(scatter_col, scatter_col, lacol); + add_v3_v3(scatter_col, lacol); } } } @@ -606,13 +603,16 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float const float density = vol_get_density(shi, p); if (density > 0.01f) { - float scatter_col[3], emit_col[3]; + float scatter_col[3] = {0.f, 0.f, 0.f}, emit_col[3]; const float stepd = (t0 - pt0) * density; /* transmittance component (alpha) */ vol_get_transmittance_seg(shi, tr, stepsize, co, density); - if (luminance(tr) < shi->mat->vol.depth_cutoff) break; + if (t0 > t1 * 0.25) { + /* only use depth cutoff after we've traced a little way into the volume */ + if (luminance(tr) < shi->mat->vol.depth_cutoff) break; + } vol_get_emission(shi, emit_col, p); @@ -623,7 +623,7 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float p2[1] = p[1] + (step_vec[1] * 0.5); p2[2] = p[2] + (step_vec[2] * 0.5); - vol_get_precached_scattering(shi, scatter_col, p2); + vol_get_precached_scattering(&R, shi, scatter_col, p2); } else vol_get_scattering(shi, scatter_col, p); @@ -631,12 +631,12 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float radiance[1] += stepd * tr[1] * (emit_col[1] + scatter_col[1]); radiance[2] += stepd * tr[2] * (emit_col[2] + scatter_col[2]); } - add_v3_v3v3(p, p, step_vec); + add_v3_v3(p, step_vec); } /* multiply original color (from behind volume) with transmittance over entire distance */ mul_v3_v3v3(col, tr, col); - add_v3_v3v3(col, col, radiance); + add_v3_v3(col, radiance); /* alpha <-- transmission luminance */ col[3] = 1.0f - luminance(tr); @@ -786,10 +786,7 @@ void shade_volume_inside(ShadeInput *shi, ShadeResult *shr) MatInside *m; Material *mat_backup; ObjectInstanceRen *obi_backup; - float prev_alpha = shr->alpha; - - //if (BLI_countlist(&R.render_volumes_inside) == 0) return; - + /* XXX: extend to multiple volumes perhaps later */ mat_backup = shi->mat; obi_backup = shi->obi; @@ -799,10 +796,10 @@ void shade_volume_inside(ShadeInput *shi, ShadeResult *shr) shi->obi = m->obi; shi->obr = m->obi->obr; - volume_trace(shi, shr, VOL_SHADE_INSIDE); - shr->alpha += prev_alpha; - CLAMP(shr->alpha, 0.f, 1.f); + memset(shr, 0, sizeof(ShadeResult)); + volume_trace(shi, shr, VOL_SHADE_INSIDE); + shi->mat = mat_backup; shi->obi = obi_backup; shi->obr = obi_backup->obr; diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index 762848c402a..076d6355585 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -39,7 +39,6 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -#include "BKE_global.h" #include "BKE_image.h" #include "BKE_main.h" #include "BKE_modifier.h" @@ -57,58 +56,72 @@ #include "texture.h" #include "voxeldata.h" -static int load_frame_blendervoxel(FILE *fp, float *F, int size, int frame, int offset) +static int load_frame_blendervoxel(VoxelData *vd, FILE *fp, int frame) { - if(fseek(fp,frame*size*sizeof(float)+offset,0) == -1) + size_t offset = sizeof(VoxelDataHeader); + int size = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]); + + vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset"); + + if(fseek(fp, frame*size*sizeof(float)+offset, 0) == -1) return 0; - if(fread(F,sizeof(float),size,fp) != size) + if(fread(vd->dataset, sizeof(float), size, fp) != size) return 0; + vd->cachedframe = frame; + vd->ok = 1; return 1; } -static int load_frame_raw8(FILE *fp, float *F, int size, int frame) +static int load_frame_raw8(VoxelData *vd, FILE *fp, int frame) { - char *tmp; + int size = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]); + char *data_c; int i; - tmp = (char *)MEM_mallocN(sizeof(char)*size, "temporary voxel file reading storage"); + vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset"); + data_c = (char *)MEM_mallocN(sizeof(char)*size, "temporary voxel file reading storage"); if(fseek(fp,(frame-1)*size*sizeof(char),0) == -1) { - MEM_freeN(tmp); + MEM_freeN(data_c); return 0; } - if(fread(tmp, sizeof(char), size, fp) != size) { - MEM_freeN(tmp); + if(fread(data_c, sizeof(char), size, fp) != size) { + MEM_freeN(data_c); return 0; } for (i=0; i<size; i++) { - F[i] = (float)tmp[i] / 256.f; + vd->dataset[i] = (float)data_c[i] / 255.f; } - MEM_freeN(tmp); + MEM_freeN(data_c); + + vd->cachedframe = frame; + vd->ok = 1; return 1; } -static void load_frame_image_sequence(Render *re, VoxelData *vd, Tex *tex) +static void load_frame_image_sequence(VoxelData *vd, Tex *tex) { ImBuf *ibuf; Image *ima = tex->ima; - ImageUser *iuser = &tex->iuser; + ImageUser *tiuser = &tex->iuser; + ImageUser iuser = *(tiuser); int x=0, y=0, z=0; float *rf; - if (!ima || !iuser) return; + if (!ima || !tiuser) return; + if (iuser.frames == 0) return; ima->source = IMA_SRC_SEQUENCE; - iuser->framenr = 1 + iuser->offset; + iuser.framenr = 1 + iuser.offset; /* find the first valid ibuf and use it to initialise the resolution of the data set */ /* need to do this in advance so we know how much memory to allocate */ - ibuf= BKE_image_get_ibuf(ima, iuser); - while (!ibuf && (iuser->framenr < iuser->frames)) { - iuser->framenr++; - ibuf= BKE_image_get_ibuf(ima, iuser); + ibuf= BKE_image_get_ibuf(ima, &iuser); + while (!ibuf && (iuser.framenr < iuser.frames)) { + iuser.framenr++; + ibuf= BKE_image_get_ibuf(ima, &iuser); } if (!ibuf) return; if (!ibuf->rect_float) IMB_float_from_rect(ibuf); @@ -116,15 +129,15 @@ static void load_frame_image_sequence(Render *re, VoxelData *vd, Tex *tex) vd->flag |= TEX_VD_STILL; vd->resol[0] = ibuf->x; vd->resol[1] = ibuf->y; - vd->resol[2] = iuser->frames; + vd->resol[2] = iuser.frames; vd->dataset = MEM_mapallocN(sizeof(float)*(vd->resol[0])*(vd->resol[1])*(vd->resol[2]), "voxel dataset"); - for (z=0; z < iuser->frames; z++) + for (z=0; z < iuser.frames; z++) { /* get a new ibuf for each frame */ if (z > 0) { - iuser->framenr++; - ibuf= BKE_image_get_ibuf(ima, iuser); + iuser.framenr++; + ibuf= BKE_image_get_ibuf(ima, &iuser); if (!ibuf) break; if (!ibuf->rect_float) IMB_float_from_rect(ibuf); } @@ -134,14 +147,17 @@ static void load_frame_image_sequence(Render *re, VoxelData *vd, Tex *tex) { for (x=0; x < ibuf->x; x++) { - /* currently converted to monchrome */ + /* currently averaged to monchrome */ vd->dataset[ V_I(x, y, z, vd->resol) ] = (rf[0] + rf[1] + rf[2])*0.333f; rf +=4; } } - BKE_image_free_anim_ibufs(ima, iuser->framenr); + BKE_image_free_anim_ibufs(ima, iuser.framenr); } + + vd->ok = 1; + return; } static int read_voxeldata_header(FILE *fp, struct VoxelData *vd) @@ -162,7 +178,7 @@ static int read_voxeldata_header(FILE *fp, struct VoxelData *vd) return 1; } -static void init_frame_smoke(Render *re, VoxelData *vd, Tex *tex) +static void init_frame_smoke(VoxelData *vd, Tex *tex) { Object *ob; ModifierData *md; @@ -232,53 +248,65 @@ static void init_frame_smoke(Render *re, VoxelData *vd, Tex *tex) } // end of fluid condition } } + + vd->ok = 1; + return; } static void cache_voxeldata(struct Render *re,Tex *tex) { VoxelData *vd = tex->vd; FILE *fp; - int size; int curframe; if (!vd) return; - /* image sequence gets special treatment */ - if (vd->file_format == TEX_VD_IMAGE_SEQUENCE) { - load_frame_image_sequence(re, vd, tex); - return; - } else if (vd->file_format == TEX_VD_SMOKE) { - init_frame_smoke(re, vd, tex); - return; + /* only re-cache if dataset needs updating */ + if ((vd->flag & TEX_VD_STILL) || (vd->cachedframe == re->r.cfra)) + if (vd->ok) return; + + /* clear out old cache, ready for new */ + if (vd->dataset) { + if(vd->file_format != TEX_VD_SMOKE) + MEM_freeN(vd->dataset); + vd->dataset = NULL; } - if (!BLI_exists(vd->source_path)) return; - fp = fopen(vd->source_path,"rb"); - if (!fp) return; - - if (vd->file_format == TEX_VD_BLENDERVOXEL) { - if(!read_voxeldata_header(fp, vd)) { - fclose(fp); - return; - } - } - - size = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]); - vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset"); - - if (vd->flag & TEX_VD_STILL) curframe = vd->still_frame; - else curframe = re->r.cfra; + if (vd->flag & TEX_VD_STILL) + curframe = vd->still_frame; + else + curframe = re->r.cfra; switch(vd->file_format) { + case TEX_VD_IMAGE_SEQUENCE: + load_frame_image_sequence(vd, tex); + return; + case TEX_VD_SMOKE: + init_frame_smoke(vd, tex); + return; case TEX_VD_BLENDERVOXEL: - load_frame_blendervoxel(fp, vd->dataset, size, curframe-1, sizeof(VoxelDataHeader)); - break; + if (!BLI_exists(vd->source_path)) return; + fp = fopen(vd->source_path,"rb"); + if (!fp) return; + + if(read_voxeldata_header(fp, vd)) + load_frame_blendervoxel(vd, fp, curframe-1); + else + fclose(fp); + + return; case TEX_VD_RAW_8BIT: - load_frame_raw8(fp, vd->dataset, size, curframe); - break; + if (!BLI_exists(vd->source_path)) return; + fp = fopen(vd->source_path,"rb"); + if (!fp) return; + + if (load_frame_raw8(vd, fp, curframe)) + ; + else + fclose(fp); + + return; } - - fclose(fp); } void make_voxeldata(struct Render *re) @@ -289,7 +317,7 @@ void make_voxeldata(struct Render *re) re->stats_draw(re->sdh, &re->i); /* XXX: should be doing only textures used in this render */ - for (tex= G.main->tex.first; tex; tex= tex->id.next) { + for (tex= re->main->tex.first; tex; tex= tex->id.next) { if(tex->id.us && tex->type==TEX_VOXELDATA) { cache_voxeldata(re, tex); } @@ -300,29 +328,6 @@ void make_voxeldata(struct Render *re) } -static void free_voxeldata_one(Render *re, Tex *tex) -{ - VoxelData *vd = tex->vd; - - if (vd->dataset) { - if(vd->file_format != TEX_VD_SMOKE) - MEM_freeN(vd->dataset); - vd->dataset = NULL; - } -} - - -void free_voxeldata(Render *re) -{ - Tex *tex; - - for (tex= G.main->tex.first; tex; tex= tex->id.next) { - if(tex->id.us && tex->type==TEX_VOXELDATA) { - free_voxeldata_one(re, tex); - } - } -} - int voxeldatatex(struct Tex *tex, float *texvec, struct TexResult *texres) { int retval = TEX_INT; @@ -339,7 +344,7 @@ int voxeldatatex(struct Tex *tex, float *texvec, struct TexResult *texres) * to the range 0.0, 1.0, before looking up in the voxel structure. */ copy_v3_v3(co, texvec); mul_v3_fl(co, 0.5f); - add_v3_v3v3(co, co, offset); + add_v3_v3(co, offset); /* co is now in the range 0.0, 1.0 */ switch (tex->extend) { |