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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2006-02-02 20:54:22 +0300
committerTon Roosendaal <ton@blender.org>2006-02-02 20:54:22 +0300
commitf493e8ed2e6af6d1ed4d37906ce445b914374f63 (patch)
tree66dce17b2d824624ffcd9134b8982c2eb5ef12c5 /source
parentccbc32abed93fa47f1099f9893a59b8a901b4f56 (diff)
features & fixes:
- Enabled Groups to execute in Compositor. They were ignored still. Note; inside of groups nothing is cached, so a change of a group input will recalculate it fully. This is needed because groups are linked data (instances use same internal nodes). - Made Composit node "Viewer" display correctly input for images with 1/2/3/4 channels. - Added pass rendering, tested now with only regular Materials. For Material nodes this is quite more complex... since they cannot be easily separated in passes (each Material does a full shade) In this commit all pass render is disabled though, will continue work on that later. Sneak preview: http://www.blender.org/bf/rt.jpg (temporal image) - What did remain is the 'Normal' pass output. Normal works very nice for relighting effects. Use the "Normal Node" to define where more or less light should be. (Use "Value Map" node to tweak influence of the Normal node 'dot' output.) - EVIL bug fix: I've spend almost a day finding it... when combining AO and mirror render, the event queue was totally screwing up... two things not related at all! Found out error was in ray-mirror code, which was using partially uninitialized 'ShadeInput' data to pass on to render code. - Another fix; made sure that while thread render, the threads don't get events, only the main program will do. Might fix issues reported by people on linux/windows.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/node.c102
-rw-r--r--source/blender/blenkernel/intern/node_composite.c173
-rw-r--r--source/blender/blenlib/intern/threads.c7
-rw-r--r--source/blender/makesdna/DNA_scene_types.h2
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h59
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h8
-rw-r--r--source/blender/render/intern/include/pixelblending.h1
-rw-r--r--source/blender/render/intern/include/rendercore.h2
-rw-r--r--source/blender/render/intern/source/pipeline.c89
-rw-r--r--source/blender/render/intern/source/pixelblending.c46
-rw-r--r--source/blender/render/intern/source/ray.c24
-rw-r--r--source/blender/render/intern/source/rendercore.c926
-rw-r--r--source/blender/render/intern/source/zbuf.c16
-rw-r--r--source/blender/renderconverter/Makefile37
-rw-r--r--source/blender/renderconverter/RE_renderconverter.h101
-rw-r--r--source/blender/renderconverter/SConscript21
-rw-r--r--source/blender/renderconverter/intern/Makefile58
-rw-r--r--source/blender/renderconverter/intern/convertBlenderScene.c3297
-rw-r--r--source/blender/src/buttons_scene.c19
-rw-r--r--source/blender/src/drawnode.c4
-rw-r--r--source/blender/src/editnode.c30
21 files changed, 980 insertions, 4042 deletions
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 672e3b2a0bd..e2dc623859e 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1243,7 +1243,7 @@ void NodeTagChanged(bNodeTree *ntree, bNode *node)
{
if(ntree->type==NTREE_COMPOSIT) {
bNodeSocket *sock;
-
+
for(sock= node->outputs.first; sock; sock= sock->next) {
if(sock->ns.data) {
free_compbuf(sock->ns.data);
@@ -1447,14 +1447,35 @@ static void composit_end_exec(bNodeTree *ntree)
}
node->need_exec= 0;
}
-
+
+ /* internally, group buffers are not stored */
for(ns= ntree->stack, a=0; a<ntree->stacksize; a++, ns++) {
- if(ns->data) {
- print_compbuf("error: buf hanging in stack", ns->data);
+ if(ns->data)
free_compbuf(ns->data);
+ }
+}
+
+static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack)
+{
+ bNodeTree *ntree= (bNodeTree *)gnode->id;
+ bNode *node;
+
+ stack+= gnode->stack_index;
+
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->typeinfo->execfunc) {
+ bNodeSocket *sock;
+
+ for(sock= node->inputs.first; sock; sock= sock->next) {
+ if(sock->intern) {
+ if(sock->link) {
+ bNodeStack *ns= stack + sock->link->fromsock->stack_index;
+ ns->hasoutput= 1;
+ }
+ }
+ }
}
}
-
}
/* stack indices make sure all nodes only write in allocated data, for making it thread safe */
@@ -1481,7 +1502,6 @@ void ntreeBeginExecTree(bNodeTree *ntree)
for(a=0; a<ntree->stacksize; a++, ns++) ns->hasinput= 1;
/* tag used outputs, so we know when we can skip operations */
- /* hrms... groups... */
for(node= ntree->nodes.first; node; node= node->next) {
bNodeSocket *sock;
for(sock= node->inputs.first; sock; sock= sock->next) {
@@ -1490,6 +1510,8 @@ void ntreeBeginExecTree(bNodeTree *ntree)
ns->hasoutput= 1;
}
}
+ if(node->type==NODE_GROUP && node->id)
+ group_tag_used_outputs(node, ntree->stack);
}
if(ntree->type==NTREE_COMPOSIT)
composit_begin_exec(ntree);
@@ -1610,48 +1632,46 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
int totnode= 0;
for(node= ntree->nodes.first; node; node= node->next) {
- if(node->typeinfo->execfunc) {
- int a;
-
- node_get_stack(node, thd->stack, nsin, nsout);
-
- /* test the inputs */
- for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
- /* is sock in use? */
- if(sock->link) {
- if(nsin[a]->data==NULL || sock->link->fromnode->need_exec) {
- node->need_exec= 1;
- break;
- }
- }
- }
-
- /* test the outputs */
- for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
- if(nsout[a]->data==NULL && nsout[a]->hasoutput) {
+ int a;
+
+ node_get_stack(node, thd->stack, nsin, nsout);
+
+ /* test the inputs */
+ for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
+ /* is sock in use? */
+ if(sock->link) {
+ if(nsin[a]->data==NULL || sock->link->fromnode->need_exec) {
node->need_exec= 1;
break;
}
}
- if(node->need_exec) {
-
- /* free output buffers */
- for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
- if(nsout[a]->data) {
- free_compbuf(nsout[a]->data);
- nsout[a]->data= NULL;
- }
+ }
+
+ /* test the outputs */
+ for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
+ if(nsout[a]->data==NULL && nsout[a]->hasoutput) {
+ node->need_exec= 1;
+ break;
+ }
+ }
+ if(node->need_exec) {
+
+ /* free output buffers */
+ for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
+ if(nsout[a]->data) {
+ free_compbuf(nsout[a]->data);
+ nsout[a]->data= NULL;
}
- totnode++;
- //printf("node needs exec %s\n", node->name);
-
- /* tag for getExecutableNode() */
- node->exec= 0;
}
- else
- /* tag for getExecutableNode() */
- node->exec= NODE_READY|NODE_FINISHED;
+ totnode++;
+ //printf("node needs exec %s\n", node->name);
+
+ /* tag for getExecutableNode() */
+ node->exec= 0;
}
+ else
+ /* tag for getExecutableNode() */
+ node->exec= NODE_READY|NODE_FINISHED;
}
return totnode;
}
diff --git a/source/blender/blenkernel/intern/node_composite.c b/source/blender/blenkernel/intern/node_composite.c
index 89fe2da98cd..8157f56c6e6 100644
--- a/source/blender/blenkernel/intern/node_composite.c
+++ b/source/blender/blenkernel/intern/node_composite.c
@@ -430,6 +430,18 @@ static void do_copy_rgba(bNode *node, float *out, float *in)
{
QUATCOPY(out, in);
}
+static void do_copy_rgb(bNode *node, float *out, float *in)
+{
+ VECCOPY(out, in);
+ out[3]= 1.0f;
+}
+static void do_copy_rg(bNode *node, float *out, float *in)
+{
+ out[0]= in[0];
+ out[1]= in[1];
+ out[2]= 0.0f;
+ out[3]= 1.0f;
+}
static void do_copy_value(bNode *node, float *out, float *in)
{
out[0]= in[0];
@@ -447,7 +459,7 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
if(node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */
Image *ima= (Image *)node->id;
- CompBuf *cbuf;
+ CompBuf *cbuf, *inbuf= in[0]->data;
int rectx, recty;
/* scene size? */
@@ -465,10 +477,18 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
cbuf->rect= ima->ibuf->rect_float;
/* when no alpha, we can simply copy */
- if(in[1]->data==NULL)
- composit1_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, do_copy_rgba);
+ if(in[1]->data==NULL) {
+ void (*func)(bNode *, float *, float *);
+
+ if(inbuf==NULL || inbuf->type==CB_RGBA) func= do_copy_rgba;
+ else if(inbuf->type==CB_VEC3) func= do_copy_rgb;
+ else if(inbuf->type==CB_VEC2) func= do_copy_rg;
+ else func= do_copy_value;
+
+ composit1_pixel_processor(node, cbuf, inbuf, in[0]->vec, func);
+ }
else
- composit2_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba);
+ composit2_pixel_processor(node, cbuf, inbuf, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba);
if(in[2]->data) {
CompBuf *zbuf= alloc_compbuf(rectx, recty, CB_VAL, 0);
@@ -493,8 +513,24 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
}
} /* lets make only previews when not done yet, so activating doesnt update */
- else if(in[0]->data && node->preview && node->preview->rect==NULL)
- generate_preview(node, in[0]->data);
+ else if(in[0]->data && node->preview && node->preview->rect==NULL) {
+ CompBuf *cbuf, *inbuf= in[0]->data;
+
+ if(inbuf->type!=CB_RGBA) {
+ void (*func)(bNode *, float *, float *);
+
+ if(inbuf->type==CB_VEC3) func= do_copy_rgb;
+ else if(inbuf->type==CB_VEC2) func= do_copy_rg;
+ else func= do_copy_value;
+
+ cbuf= alloc_compbuf(inbuf->x, inbuf->y, CB_RGBA, 1);
+ composit1_pixel_processor(node, cbuf, inbuf, in[0]->vec, func);
+ generate_preview(node, cbuf);
+ free_compbuf(cbuf);
+ }
+ else
+ generate_preview(node, inbuf);
+ }
}
static bNodeType cmp_node_viewer= {
@@ -737,14 +773,56 @@ static bNodeType cmp_node_image= {
};
/* **************** RENDER RESULT ******************** */
+
+/* output socket defines */
+#define RRES_OUT_IMAGE 0
+#define RRES_OUT_ALPHA 1
+#define RRES_OUT_Z 2
+#define RRES_OUT_NOR 3
+#define RRES_OUT_VEC 4
+#define RRES_OUT_COL 5
+#define RRES_OUT_DIFF 6
+#define RRES_OUT_SPEC 7
+#define RRES_OUT_SHAD 8
+#define RRES_OUT_AO 9
+#define RRES_OUT_RAY 10
+
static bNodeSocketType cmp_node_rresult_out[]= {
{ SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_VECTOR, 0, "Vec", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 0, "Speed", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+// { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+// { SOCK_RGBA, 0, "Diffuse", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+// { SOCK_RGBA, 0, "Specular", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+// { SOCK_RGBA, 0, "Shadow", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+// { SOCK_RGBA, 0, "AO", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+// { SOCK_RGBA, 0, "Ray", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
+static CompBuf *compbuf_from_pass(RenderLayer *rl, int rectx, int recty, int passcode)
+{
+ float *fp= RE_RenderLayerGetPass(rl, passcode);
+ if(fp) {
+ CompBuf *buf;
+ int buftype= CB_VEC3;
+
+ if(passcode==SCE_PASS_Z)
+ buftype= CB_VAL;
+ else if(passcode==SCE_PASS_VECTOR)
+ buftype= CB_VEC2;
+ else if(passcode==SCE_PASS_RGBA)
+ buftype= CB_RGBA;
+
+ buf= alloc_compbuf(rectx, recty, buftype, 0);
+ buf->rect= fp;
+ return buf;
+ }
+ return NULL;
+}
+
static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
RenderResult *rr= RE_GetResult(RE_GetRender("Render"));
@@ -759,21 +837,30 @@ static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in,
stackbuf->rect= rl->rectf;
/* put on stack */
- out[0]->data= stackbuf;
-
- if(out[1]->hasoutput)
- out[1]->data= alphabuf_from_rgbabuf(stackbuf);
- if(out[2]->hasoutput && rl->rectz) {
- CompBuf *zbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VAL, 0);
- zbuf->rect= rl->rectz;
- out[2]->data= zbuf;
- }
- if(out[3]->hasoutput && rl->rectvec) {
- CompBuf *vecbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VEC2, 0);
- vecbuf->rect= rl->rectvec;
- out[3]->data= vecbuf;
- }
+ out[RRES_OUT_IMAGE]->data= stackbuf;
+ if(out[RRES_OUT_ALPHA]->hasoutput)
+ out[RRES_OUT_ALPHA]->data= alphabuf_from_rgbabuf(stackbuf);
+ if(out[RRES_OUT_Z]->hasoutput)
+ out[RRES_OUT_Z]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_Z);
+ if(out[RRES_OUT_VEC]->hasoutput)
+ out[RRES_OUT_VEC]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_VECTOR);
+ if(out[RRES_OUT_NOR]->hasoutput)
+ out[RRES_OUT_NOR]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_NORMAL);
+/*
+ if(out[RRES_OUT_COL]->hasoutput)
+ out[RRES_OUT_COL]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_RGBA);
+ if(out[RRES_OUT_DIFF]->hasoutput)
+ out[RRES_OUT_DIFF]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_DIFFUSE);
+ if(out[RRES_OUT_SPEC]->hasoutput)
+ out[RRES_OUT_SPEC]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_SPEC);
+ if(out[RRES_OUT_SHAD]->hasoutput)
+ out[RRES_OUT_SHAD]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_SHADOW);
+ if(out[RRES_OUT_AO]->hasoutput)
+ out[RRES_OUT_AO]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_AO);
+ if(out[RRES_OUT_RAY]->hasoutput)
+ out[RRES_OUT_RAY]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_RAY);
+*/
generate_preview(node, stackbuf);
}
}
@@ -804,6 +891,15 @@ static bNodeSocketType cmp_node_normal_out[]= {
{ -1, 0, "" }
};
+static void do_normal(bNode *node, float *out, float *in)
+{
+ bNodeSocket *sock= node->outputs.first;
+ float *nor= sock->ns.vec;
+
+ /* render normals point inside... the widget points outside */
+ out[0]= -INPR(nor, in);
+}
+
/* generates normal, does dot product */
static void node_composit_exec_normal(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
@@ -811,9 +907,23 @@ static void node_composit_exec_normal(void *data, bNode *node, bNodeStack **in,
/* stack order input: normal */
/* stack order output: normal, value */
- VECCOPY(out[0]->vec, sock->ns.vec);
- /* render normals point inside... the widget points outside */
- out[1]->vec[0]= -INPR(out[0]->vec, in[0]->vec);
+ /* input no image? then only vector op */
+ if(in[0]->data==NULL) {
+ VECCOPY(out[0]->vec, sock->ns.vec);
+ /* render normals point inside... the widget points outside */
+ out[1]->vec[0]= -INPR(out[0]->vec, in[0]->vec);
+ }
+ else if(out[1]->hasoutput) {
+ /* make output size of input image */
+ CompBuf *cbuf= in[0]->data;
+ CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocs
+
+ composit1_pixel_processor(node, stackbuf, in[0]->data, NULL, do_normal);
+
+ out[1]->data= stackbuf;
+ }
+
+
}
static bNodeType cmp_node_normal= {
@@ -1843,21 +1953,6 @@ static bNodeSocketType cmp_node_vecblur_out[]= {
{ -1, 0, "" }
};
-static void fill_rct_in_image(rcti poly, float *rect, int xsize, int ysize, float *col)
-{
- float *dest;
- int x, y;
-
- for(y=poly.ymin; y<poly.ymax; y++) {
- for(x=poly.xmin; x<poly.xmax; x++) {
- dest= rect + 4*(xsize*y + x);
- QUATCOPY(dest, col);
- }
- }
-
-}
-
-
static void node_composit_exec_vecblur(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
CompBuf *new, *img= in[0]->data, *vecbuf= in[1]->data, *wbuf;
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index 6a306a5c7b1..19dadd211db 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -112,6 +112,13 @@ void BLI_init_threads(ListBase *threadbase, int (*do_thread)(void *), int tot)
tslot->do_thread= do_thread;
}
+ /* weak weak... now only 1 thread system at a time can be used */
+ if(_malloc_lock) {
+ printf("error; multiple locks active\n");
+ SDL_DestroyMutex(_malloc_lock);
+ _malloc_lock= NULL;
+ }
+
_malloc_lock = SDL_CreateMutex();
}
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index a59e6e06427..9c1e2d3ec9a 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -118,7 +118,7 @@ typedef struct SceneRenderLayer {
#define SCE_PASS_SPEC 16
#define SCE_PASS_SHADOW 32
#define SCE_PASS_AO 64
-#define SCE_PASS_MIRROR 128
+#define SCE_PASS_RAY 128
#define SCE_PASS_NORMAL 256
#define SCE_PASS_VECTOR 512
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index a9b75184e36..1afce546791 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -55,6 +55,12 @@ typedef struct Render Render;
and how it's converted
*/
+typedef struct RenderPass {
+ struct RenderPass *next, *prev;
+ int passtype;
+ float *rect;
+} RenderPass;
+
/* a renderlayer is a full image, but with all passes and samples */
/* size of the rects is defined in RenderResult */
typedef struct RenderLayer {
@@ -66,8 +72,6 @@ typedef struct RenderLayer {
int layflag, passflag;
float *rectf; /* 4 float, standard rgba buffer */
- float *rectz; /* 1 float, standard camera coordinate zbuffer */
- float *rectvec; /* 2 float, screen aligned speed vectors */
ListBase passes;
@@ -113,19 +117,20 @@ typedef struct RenderStats {
/* the name is used as identifier, so elsewhere in blender the result can retrieved */
/* calling a new render with same name, frees automatic existing render */
-Render *RE_NewRender (const char *name);
-Render *RE_GetRender(const char *name);
+struct Render *RE_NewRender (const char *name);
+struct Render *RE_GetRender(const char *name);
/* use free render as signal to do everything over (previews) */
-void RE_FreeRender (Render *re);
+void RE_FreeRender (struct Render *re);
/* only called on exit */
void RE_FreeAllRender (void);
/* get results and statistics */
-RenderResult *RE_GetResult(Render *re);
-void RE_GetResultImage(Render *re, RenderResult *rr);
-RenderStats *RE_GetStats(Render *re);
-void RE_ResultGet32(Render *re, unsigned int *rect);
+RenderResult *RE_GetResult(struct Render *re);
+void RE_GetResultImage(struct Render *re, RenderResult *rr);
+RenderStats *RE_GetStats(struct Render *re);
+void RE_ResultGet32(struct Render *re, unsigned int *rect);
+float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype);
/* obligatory initialize call, disprect is optional */
void RE_InitState (struct Render *re, struct RenderData *rd, int winx, int winy, rcti *disprect);
@@ -134,37 +139,37 @@ void RE_InitState (struct Render *re, struct RenderData *rd, int winx, int winy,
void RE_SetDispRect (struct Render *re, rcti *disprect);
/* set up the viewplane/perspective matrix, three choices */
-void RE_SetCamera(Render *re, struct Object *camera);
-void RE_SetWindow (Render *re, rctf *viewplane, float clipsta, float clipend);
-void RE_SetOrtho (Render *re, rctf *viewplane, float clipsta, float clipend);
+void RE_SetCamera(struct Render *re, struct Object *camera);
+void RE_SetWindow (struct Render *re, rctf *viewplane, float clipsta, float clipend);
+void RE_SetOrtho (struct Render *re, rctf *viewplane, float clipsta, float clipend);
/* option to set viewmatrix before making dbase */
-void RE_SetView (Render *re, float mat[][4]);
+void RE_SetView (struct Render *re, float mat[][4]);
/* make or free the dbase */
-void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view);
-void RE_Database_Free (Render *re);
+void RE_Database_FromScene(struct Render *re, struct Scene *scene, int use_camera_view);
+void RE_Database_Free (struct Render *re);
/* project dbase again, when viewplane/perspective changed */
-void RE_DataBase_ApplyWindow(Render *re);
+void RE_DataBase_ApplyWindow(struct Render *re);
/* the main processor, assumes all was set OK! */
-void RE_TileProcessor(Render *re);
+void RE_TileProcessor(struct Render *re);
/* only RE_NewRender() needed, main Blender render calls */
-void RE_BlenderFrame(Render *re, struct Scene *scene, int frame);
-void RE_BlenderAnim(Render *re, struct Scene *scene, int sfra, int efra);
+void RE_BlenderFrame(struct Render *re, struct Scene *scene, int frame);
+void RE_BlenderAnim(struct Render *re, struct Scene *scene, int sfra, int efra);
/* display and event callbacks */
-void RE_display_init_cb (Render *re, void (*f)(RenderResult *rr));
-void RE_display_clear_cb(Render *re, void (*f)(RenderResult *rr));
-void RE_display_draw_cb (Render *re, void (*f)(RenderResult *rr, struct rcti *rect));
-void RE_stats_draw_cb (Render *re, void (*f)(RenderStats *rs));
-void RE_timecursor_cb (Render *re, void (*f)(int));
-void RE_test_break_cb (Render *re, int (*f)(void));
-void RE_test_return_cb (Render *re, int (*f)(void));
-void RE_error_cb (Render *re, void (*f)(const char *str));
+void RE_display_init_cb (struct Render *re, void (*f)(RenderResult *rr));
+void RE_display_clear_cb(struct Render *re, void (*f)(RenderResult *rr));
+void RE_display_draw_cb (struct Render *re, void (*f)(RenderResult *rr, struct rcti *rect));
+void RE_stats_draw_cb (struct Render *re, void (*f)(RenderStats *rs));
+void RE_timecursor_cb (struct Render *re, void (*f)(int));
+void RE_test_break_cb (struct Render *re, int (*f)(void));
+void RE_test_return_cb (struct Render *re, int (*f)(void));
+void RE_error_cb (struct Render *re, void (*f)(const char *str));
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index b8bd46d784e..54307d933e9 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -46,11 +46,15 @@ typedef struct TexResult {
typedef struct ShadeResult
{
float combined[4];
+ float col[4];
+ float alpha;
float diff[3];
float spec[3];
- float alpha;
+ float shad[3];
+ float ao[3];
+ float ray[3];
float nor[3];
- float winspeed[2];
+ float winspeed[3];
} ShadeResult;
diff --git a/source/blender/render/intern/include/pixelblending.h b/source/blender/render/intern/include/pixelblending.h
index bc44c916701..2713b2023a9 100644
--- a/source/blender/render/intern/include/pixelblending.h
+++ b/source/blender/render/intern/include/pixelblending.h
@@ -34,6 +34,7 @@
* (float vecs to float vec)
*/
void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w);
+void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize);
/**
* Alpha-over blending for floats.
diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h
index 793480458c6..91aeaf788c9 100644
--- a/source/blender/render/intern/include/rendercore.h
+++ b/source/blender/render/intern/include/rendercore.h
@@ -85,7 +85,7 @@ void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr);
void zbufshade(void);
void zbufshadeDA(void); /* Delta Accum Pixel Struct */
-void *shadepixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, struct ShadeResult *shr, float *rco);
+void *shadepixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, struct ShadeResult *shr, float *rco, int passflag);
int count_mask(unsigned short mask);
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index c1baa04553b..558e1cc17ff 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -133,6 +133,11 @@ void RE_freeN(void *poin)
/* ********************** */
+static int g_break= 0;
+static int thread_break(void)
+{
+ return g_break;
+}
/* default callbacks, set in each new render */
static void result_nothing(RenderResult *rr) {}
@@ -148,9 +153,14 @@ static void free_render_result(RenderResult *res)
while(res->layers.first) {
RenderLayer *rl= res->layers.first;
+
if(rl->rectf) RE_freeN(rl->rectf);
- if(rl->rectz) RE_freeN(rl->rectz);
- if(rl->rectvec) RE_freeN(rl->rectvec);
+ while(rl->passes.first) {
+ RenderPass *rpass= rl->passes.first;
+ RE_freeN(rpass->rect);
+ BLI_remlink(&rl->passes, rpass);
+ RE_freeN(rpass);
+ }
BLI_remlink(&res->layers, rl);
RE_freeN(rl);
}
@@ -165,6 +175,25 @@ static void free_render_result(RenderResult *res)
RE_freeN(res);
}
+static void render_layer_add_pass(RenderLayer *rl, int rectsize, int passtype, char *mallocstr)
+{
+ RenderPass *rpass= MEM_mallocN(sizeof(RenderPass), mallocstr);
+
+ BLI_addtail(&rl->passes, rpass);
+ rpass->passtype= passtype;
+ rpass->rect= MEM_callocN(sizeof(float)*rectsize, mallocstr);
+}
+
+float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype)
+{
+ RenderPass *rpass;
+
+ for(rpass=rl->passes.first; rpass; rpass= rpass->next)
+ if(rpass->passtype== passtype)
+ return rpass->rect;
+ return NULL;
+}
+
/* called by main render as well for parts */
/* will read info from Render *re to define layers */
/* called in threads */
@@ -205,10 +234,25 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
rl->passflag= srl->passflag;
rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
+
if(srl->passflag & SCE_PASS_Z)
- rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z");
+ render_layer_add_pass(rl, rectx*recty, SCE_PASS_Z, "Layer float Z");
if(srl->passflag & SCE_PASS_VECTOR)
- rl->rectvec= RE_callocN(rectx*recty*sizeof(float)*2, "layer float Vector");
+ render_layer_add_pass(rl, rectx*recty*2, SCE_PASS_VECTOR, "layer float Vector");
+ if(srl->passflag & SCE_PASS_NORMAL)
+ render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_NORMAL, "layer float Normal");
+ if(srl->passflag & SCE_PASS_RGBA)
+ render_layer_add_pass(rl, rectx*recty*4, SCE_PASS_RGBA, "layer float Color");
+ if(srl->passflag & SCE_PASS_DIFFUSE)
+ render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_DIFFUSE, "layer float Diffuse");
+ if(srl->passflag & SCE_PASS_SPEC)
+ render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_SPEC, "layer float Spec");
+ if(srl->passflag & SCE_PASS_SHADOW)
+ render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_SHADOW, "layer float Shadow");
+ if(srl->passflag & SCE_PASS_AO)
+ render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_AO, "layer float AO");
+ if(srl->passflag & SCE_PASS_RAY)
+ render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_RAY, "layer float Mirror");
}
/* previewrender and envmap don't do layers, so we make a default one */
@@ -217,13 +261,11 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
BLI_addtail(&rr->layers, rl);
rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "prev/env float rgba");
- rl->rectz= RE_callocN(rectx*recty*sizeof(float), "prev/env float Z");
/* note, this has to be in sync with scene.c */
rl->lay= (1<<20) -1;
rl->layflag= 0x7FFF; /* solid ztra halo strand */
- rl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z;
-
+ rl->passflag= SCE_PASS_COMBINED;
}
return rr;
@@ -277,18 +319,30 @@ static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target,
static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
{
RenderLayer *rl, *rlp;
+ RenderPass *rpass, *rpassp;
for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
/* combined */
if(rl->rectf && rlp->rectf)
do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
- /* z */
- if(rl->rectz && rlp->rectz)
- do_merge_tile(rr, rrpart, rl->rectz, rlp->rectz, 1);
- /* vector */
- if(rl->rectvec && rlp->rectvec)
- do_merge_tile(rr, rrpart, rl->rectvec, rlp->rectvec, 2);
+
+ /* passes are allocated in sync */
+ for(rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) {
+ switch(rpass->passtype) {
+ case SCE_PASS_Z:
+ do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 1);
+ break;
+ case SCE_PASS_VECTOR:
+ do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 2);
+ break;
+ case SCE_PASS_RGBA:
+ do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 4);
+ break;
+ default:
+ do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 3);
+ }
+ }
}
}
@@ -337,7 +391,7 @@ void RE_GetResultImage(Render *re, RenderResult *rr)
if(rr->rectf==NULL)
rr->rectf= rl->rectf;
if(rr->rectz==NULL)
- rr->rectz= rl->rectz;
+ rr->rectz= RE_RenderLayerGetPass(rl, SCE_PASS_Z);
}
}
}
@@ -683,11 +737,12 @@ static void threaded_tile_processor(Render *re)
/* assuming no new data gets added to dbase... */
R= *re;
+ /* set threadsafety */
+ R.test_break= thread_break;
malloc_lock = SDL_CreateMutex();
while(rendering) {
- /* I noted that test_break() in a thread doesn't make ghost send ESC */
if(BLI_available_threads(&threads) && !re->test_break()) {
pa= find_nicest_part(re);
if(pa) {
@@ -728,12 +783,14 @@ static void threaded_tile_processor(Render *re)
drawtimer= 0;
/* on break, wait for all slots to get freed */
- if(re->test_break() && BLI_available_threads(&threads)==maxthreads)
+ if( (g_break=re->test_break()) && BLI_available_threads(&threads)==maxthreads)
rendering= 0;
}
+ /* restore threadsafety */
if(malloc_lock) SDL_DestroyMutex(malloc_lock); malloc_lock= NULL;
+ g_break= 0;
BLI_end_threads(&threads);
freeparts(re);
diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c
index ece9970e885..3048a151925 100644
--- a/source/blender/render/intern/source/pixelblending.c
+++ b/source/blender/render/intern/source/pixelblending.c
@@ -212,24 +212,18 @@ void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w)
}
}
-/* filtered adding to scanlines */
-void add_filt_fmask_alphaunder(unsigned int mask, float *col, float *rowbuf, int row_w)
+void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize)
{
/* calc the value of mask */
float **fmask1= R.samples->fmask1, **fmask2=R.samples->fmask2;
float *rb1, *rb2, *rb3;
- float val, r, g, b, al, acol[4];
+ float val;
unsigned int a, maskand, maskshift;
- int j;
-
- r= col[0];
- g= col[1];
- b= col[2];
- al= col[3];
+ int i, j;
- rb2= rowbuf-4;
- rb3= rb2-4*row_w;
- rb1= rb2+4*row_w;
+ rb2= rowbuf-pixsize;
+ rb3= rb2-pixsize*row_w;
+ rb1= rb2+pixsize*row_w;
maskand= (mask & 255);
maskshift= (mask >>8);
@@ -240,40 +234,30 @@ void add_filt_fmask_alphaunder(unsigned int mask, float *col, float *rowbuf, int
val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
if(val!=0.0) {
- acol[0]= val*r;
- acol[1]= val*g;
- acol[2]= val*b;
- acol[3]= val*al;
- addAlphaUnderFloat(rb1, acol);
+ for(i= 0; i<pixsize; i++)
+ rb1[i]+= val*in[i];
}
a+=3;
val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
if(val!=0.0) {
- acol[0]= val*r;
- acol[1]= val*g;
- acol[2]= val*b;
- acol[3]= val*al;
- addAlphaUnderFloat(rb2, acol);
+ for(i= 0; i<pixsize; i++)
+ rb2[i]+= val*in[i];
}
a+=3;
val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
if(val!=0.0) {
- acol[0]= val*r;
- acol[1]= val*g;
- acol[2]= val*b;
- acol[3]= val*al;
- addAlphaUnderFloat(rb3, acol);
+ for(i= 0; i<pixsize; i++)
+ rb3[i]+= val*in[i];
}
- rb1+= 4;
- rb2+= 4;
- rb3+= 4;
+ rb1+= pixsize;
+ rb2+= pixsize;
+ rb3+= pixsize;
}
}
-
/* ------------------------------------------------------------------------- */
void addalphaAddFloat(float *dest, float *source)
{
diff --git a/source/blender/render/intern/source/ray.c b/source/blender/render/intern/source/ray.c
index d5d0a951604..02dcf4bb60d 100644
--- a/source/blender/render/intern/source/ray.c
+++ b/source/blender/render/intern/source/ray.c
@@ -1516,7 +1516,7 @@ static void color_combine(float *result, float fac1, float fac2, float *col1, fl
#endif
/* the main recursive tracer itself */
-static void traceray(short depth, float *start, float *vec, float *col, VlakRen *vlr, int mask, int osatex, int traflag)
+static void traceray(ShadeInput *origshi, short depth, float *start, float *vec, float *col, VlakRen *vlr, int traflag)
{
ShadeInput shi;
ShadeResult shr;
@@ -1533,9 +1533,13 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen
if( d3dda(&isec) ) {
- shi.mask= mask;
- shi.osatex= osatex;
+ shi.mask= origshi->mask;
+ shi.osatex= origshi->osatex;
shi.depth= 1; // only now to indicate tracing
+ shi.thread= origshi->thread;
+ shi.xs= origshi->xs;
+ shi.ys= origshi->ys;
+ shi.do_preview= 0;
shade_ray(&isec, &shi, &shr);
@@ -1559,10 +1563,10 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen
refraction(refract, shi.vn, shi.view, shi.ang);
}
traflag |= RAY_TRA;
- traceray(depth-1, shi.co, refract, tracol, shi.vlr, shi.mask, osatex, traflag ^ RAY_TRAFLIP);
+ traceray(origshi, depth-1, shi.co, refract, tracol, shi.vlr, traflag ^ RAY_TRAFLIP);
}
else
- traceray(depth-1, shi.co, shi.view, tracol, shi.vlr, shi.mask, osatex, 0);
+ traceray(origshi, depth-1, shi.co, shi.view, tracol, shi.vlr, 0);
f= shr.alpha; f1= 1.0-f;
fr= 1.0+ shi.mat->filter*(shi.r-1.0);
@@ -1591,7 +1595,7 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen
float mircol[4];
reflection(ref, shi.vn, shi.view, NULL);
- traceray(depth-1, shi.co, ref, mircol, shi.vlr, shi.mask, osatex, 0);
+ traceray(origshi, depth-1, shi.co, ref, mircol, shi.vlr, 0);
f1= 1.0-f;
@@ -1767,10 +1771,10 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
if(shi->mat->mode & MA_RAYTRANSP) {
refraction(refract, shi->vn, shi->view, shi->ang);
- traceray(shi->mat->ray_depth_tra, shi->co, refract, tracol, shi->vlr, shi->mask, 0, RAY_TRA|RAY_TRAFLIP);
+ traceray(shi, shi->mat->ray_depth_tra, shi->co, refract, tracol, shi->vlr, RAY_TRA|RAY_TRAFLIP);
}
else
- traceray(shi->mat->ray_depth_tra, shi->co, shi->view, tracol, shi->vlr, shi->mask, 0, 0);
+ traceray(shi, shi->mat->ray_depth_tra, shi->co, shi->view, tracol, shi->vlr, 0);
f= shr->alpha; f1= 1.0-f;
fr= 1.0+ shi->mat->filter*(shi->r-1.0);
@@ -1796,7 +1800,7 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
else
reflection(vec, shi->vn, shi->view, NULL);
- traceray(shi->mat->ray_depth, shi->co, vec, mircol, shi->vlr, shi->mask, shi->osatex, 0);
+ traceray(shi, shi->mat->ray_depth, shi->co, vec, mircol, shi->vlr, 0);
f= i*fr*(1.0-shr->spec[0]); f1= 1.0-i;
shr->diff[0]= f*mircol[0] + f1*shr->diff[0];
@@ -2073,7 +2077,7 @@ void ray_ao(ShadeInput *shi, float *shadfac)
bias= 0.0;
nrm= shi->facenor;
}
-
+
vec= sphere_sampler(R.wrld.aomode, R.wrld.aosamp, shi->thread, shi->xs, shi->ys);
// warning: since we use full sphere now, and dotproduct is below, we do twice as much
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index ba45953eefc..c5d362d8c2d 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -1073,7 +1073,9 @@ static void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, floa
/* blending method */
fac= col[3]*ma->rampfac_col;
- colt[0]= shi->r; colt[1]= shi->g; colt[2]= shi->b;
+ colt[0]= shi->r;
+ colt[1]= shi->g;
+ colt[2]= shi->b;
ramp_blend(ma->rampblend_col, colt, colt+1, colt+2, fac, col);
@@ -1158,7 +1160,9 @@ static void ambient_occlusion(ShadeInput *shi, ShadeResult *shr)
else if (R.wrld.aomix==WO_AOSUB) shadfac[3] = shadfac[3]-1.0;
f= R.wrld.aoenergy*shadfac[3]*shi->amb;
- add_to_diffuse(shr->diff, shi, f, f, f, f);
+ shr->ao[0]+= f;
+ shr->ao[1]+= f;
+ shr->ao[2]+= f;
}
else {
if (R.wrld.aomix==WO_AOADDSUB) {
@@ -1172,11 +1176,453 @@ static void ambient_occlusion(ShadeInput *shi, ShadeResult *shr)
shadfac[2] = shadfac[2]-1.0;
}
f= R.wrld.aoenergy*shi->amb;
- add_to_diffuse(shr->diff, shi, f, f*shadfac[0], f*shadfac[1], f*shadfac[2]);
+ shr->ao[0]+= f*shadfac[0];
+ shr->ao[1]+= f*shadfac[1];
+ shr->ao[2]+= f*shadfac[2];
}
}
}
+/* function returns diff, spec and optional shadow */
+/* if passrender it returns shadow color, otherwise it applies it to diffuse and spec */
+static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int passrender)
+{
+ Material *ma= shi->mat;
+ VlakRen *vlr= shi->vlr;
+ float lv[3], lampdist, ld, lacol[3], shadfac[4];
+ float i, is, inp, i_noshad, *vn, *view, vnor[3], phongcorr;
+
+ vn= shi->vn;
+ view= shi->view;
+
+ /* lampdist calculation */
+ if(lar->type==LA_SUN || lar->type==LA_HEMI) {
+ VECCOPY(lv, lar->vec);
+ lampdist= 1.0;
+ }
+ else {
+ lv[0]= shi->co[0]-lar->co[0];
+ lv[1]= shi->co[1]-lar->co[1];
+ lv[2]= shi->co[2]-lar->co[2];
+ ld= sqrt(lv[0]*lv[0]+lv[1]*lv[1]+lv[2]*lv[2]);
+ lv[0]/= ld;
+ lv[1]/= ld;
+ lv[2]/= ld;
+
+ /* ld is re-used further on (texco's) */
+ if(lar->type==LA_AREA) {
+ lampdist= 1.0;
+ }
+ else {
+ if(lar->mode & LA_QUAD) {
+ float t= 1.0;
+ if(lar->ld1>0.0)
+ t= lar->dist/(lar->dist+lar->ld1*ld);
+ if(lar->ld2>0.0)
+ t*= lar->distkw/(lar->distkw+lar->ld2*ld*ld);
+
+ lampdist= t;
+ }
+ else {
+ lampdist= (lar->dist/(lar->dist+ld));
+ }
+
+ if(lar->mode & LA_SPHERE) {
+ float t= lar->dist - ld;
+ if(t<0.0) return;
+
+ t/= lar->dist;
+ lampdist*= (t);
+ }
+ }
+ }
+
+ lacol[0]= lar->r;
+ lacol[1]= lar->g;
+ lacol[2]= lar->b;
+
+ if(lar->type==LA_SPOT) {
+ float t, inpr;
+
+ if(lar->mode & LA_SQUARE) {
+ if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) {
+ float lvrot[3], x;
+
+ /* rotate view to lampspace */
+ VECCOPY(lvrot, lv);
+ MTC_Mat3MulVecfl(lar->imat, lvrot);
+
+ x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2]));
+ /* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
+
+ inpr= 1.0f/(sqrt(1.0f+x*x));
+ }
+ else inpr= 0.0;
+ }
+ else {
+ inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2];
+ }
+
+ t= lar->spotsi;
+ if(inpr<t) return;
+ else {
+ t= inpr-t;
+ i= 1.0;
+ if(t<lar->spotbl && lar->spotbl!=0.0) {
+ /* soft area */
+ i= t/lar->spotbl;
+ t= i*i;
+ inpr*= (3.0*t-2.0*t*i);
+ }
+ lampdist*=inpr;
+ }
+
+ if(lar->mode & LA_OSATEX) {
+ shi->osatex= 1; /* signal for multitex() */
+
+ shi->dxlv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dxco[0])/ld;
+ shi->dxlv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dxco[1])/ld;
+ shi->dxlv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dxco[2])/ld;
+
+ shi->dylv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dyco[0])/ld;
+ shi->dylv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dyco[1])/ld;
+ shi->dylv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dyco[2])/ld;
+ }
+
+ }
+
+ if(lar->mode & LA_TEXTURE) do_lamp_tex(lar, lv, shi, lacol);
+
+ /* dot product and reflectivity */
+ /* inp = dotproduct, is = shader result, i = lamp energy (with shadow) */
+
+ /* tangent case; calculate fake face normal, aligned with lampvector */
+ if(vlr->flag & R_TANGENT) {
+ float cross[3];
+ Crossf(cross, lv, vn);
+ Crossf(vnor, cross, vn);
+ vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
+ vn= vnor;
+ }
+ else if(ma->mode & MA_TANGENT_V) {
+ float cross[3];
+ Crossf(cross, lv, shi->tang);
+ Crossf(vnor, cross, shi->tang);
+ vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
+ vn= vnor;
+ }
+
+ inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2];
+
+ /* phong threshold to prevent backfacing faces having artefacts on ray shadow (terminator problem) */
+ if((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) {
+ float thresh= vlr->ob->smoothresh;
+ if(inp>thresh)
+ phongcorr= (inp-thresh)/(inp*(1.0-thresh));
+ else
+ phongcorr= 0.0;
+ }
+ else if(ma->sbias!=0.0f) {
+ if(inp>ma->sbias)
+ phongcorr= (inp-ma->sbias)/(inp*(1.0-ma->sbias));
+ else
+ phongcorr= 0.0;
+ }
+ else phongcorr= 1.0;
+
+ /* diffuse shaders */
+ if(lar->mode & LA_NO_DIFF) {
+ is= 0.0; // skip shaders
+ }
+ else if(lar->type==LA_HEMI) {
+ is= 0.5*inp + 0.5;
+ }
+ else {
+
+ if(lar->type==LA_AREA) {
+ /* single sided */
+ if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) {
+ inp= area_lamp_energy(shi->co, vn, lar);
+ }
+ else inp= 0.0;
+ }
+
+ /* diffuse shaders (oren nayer gets inp from area light) */
+ if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, vn, lv, view, ma->roughness);
+ else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, view, ma->param[0], ma->param[1]);
+ else if(ma->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(inp, vn, view, ma->darkness);
+ else if(ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, lv, view, ma->param[0], ma->param[1]);
+ else is= inp; // Lambert
+ }
+
+ i= is*phongcorr;
+
+ if(i>0.0) {
+ i*= lampdist*shi->refl;
+ }
+ i_noshad= i;
+
+ vn= shi->vn; // bring back original vector, we use special specular shaders for tangent
+ if(ma->mode & MA_TANGENT_V)
+ vn= shi->tang;
+
+ /* init transp shadow */
+ shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 1.0;
+
+ /* shadow and spec, (lampdist==0 outside spot) */
+ if(lampdist> 0.0) {
+
+ if(i>0.0 && (R.r.mode & R_SHADOW)) {
+ if(ma->mode & MA_SHADOW) {
+ if(lar->type==LA_HEMI); // no shadow
+ else {
+ if(lar->shb) {
+ shadfac[3] = testshadowbuf(lar->shb, shi->co, shi->dxco, shi->dyco, inp);
+ }
+ else if(lar->mode & LA_SHAD_RAY) {
+ ray_shadow(shi, lar, shadfac);
+ }
+
+ /* warning, here it skips the loop */
+ if(lar->mode & LA_ONLYSHADOW) {
+
+ shadfac[3]= i*lar->energy*(1.0-shadfac[3]);
+ shr->diff[0] -= shadfac[3]*shi->r;
+ shr->diff[1] -= shadfac[3]*shi->g;
+ shr->diff[2] -= shadfac[3]*shi->b;
+ return;
+ }
+
+ if(passrender==0)
+ if(shadfac[3]==0.0) return;
+
+ i*= shadfac[3];
+ }
+ }
+ }
+
+ /* in case 'no diffuse' we still do most calculus, spec can be in shadow */
+ if(i>0.0 && !(lar->mode & LA_NO_DIFF)) {
+ if(ma->mode & MA_SHADOW_TRA)
+ add_to_diffuse(shr->diff, shi, is, i*shadfac[0]*lacol[0], i*shadfac[1]*lacol[1], i*shadfac[2]*lacol[2]);
+ else
+ add_to_diffuse(shr->diff, shi, is, i*lacol[0], i*lacol[1], i*lacol[2]);
+ }
+ if(passrender && i_noshad>0.0 && !(lar->mode & LA_NO_DIFF)) {
+ /* while passrender we store shadowless diffuse in shr->shad, so we can subtract */
+ if(ma->mode & MA_SHADOW_TRA)
+ add_to_diffuse(shr->shad, shi, is, i_noshad*shadfac[0]*lacol[0], i_noshad*shadfac[1]*lacol[1], i_noshad*shadfac[2]*lacol[2]);
+ else
+ add_to_diffuse(shr->shad, shi, is, i_noshad*lacol[0], i_noshad*lacol[1], i_noshad*lacol[2]);
+ }
+
+ /* specularity */
+ if(shadfac[3]>0.0 && shi->spec!=0.0 && !(lar->mode & LA_NO_SPEC)) {
+
+ if(lar->type==LA_HEMI) {
+ float t;
+ /* hemi uses no spec shaders (yet) */
+
+ lv[0]+= view[0];
+ lv[1]+= view[1];
+ lv[2]+= view[2];
+
+ Normalise(lv);
+
+ t= vn[0]*lv[0]+vn[1]*lv[1]+vn[2]*lv[2];
+
+ if(lar->type==LA_HEMI) {
+ t= 0.5*t+0.5;
+ }
+
+ t= shadfac[3]*shi->spec*spec(t, shi->har);
+
+ shr->spec[0]+= t*(lacol[0] * shi->specr);
+ shr->spec[1]+= t*(lacol[1] * shi->specg);
+ shr->spec[2]+= t*(lacol[2] * shi->specb);
+ }
+ else {
+ /* specular shaders */
+ float specfac, t;
+
+ if(ma->spec_shader==MA_SPEC_PHONG)
+ specfac= Phong_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+ else if(ma->spec_shader==MA_SPEC_COOKTORR)
+ specfac= CookTorr_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+ else if(ma->spec_shader==MA_SPEC_BLINN)
+ specfac= Blinn_Spec(vn, lv, view, ma->refrac, (float)shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+ else if(ma->spec_shader==MA_SPEC_WARDISO)
+ specfac= WardIso_Spec( vn, lv, view, ma->rms, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+ else
+ specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3], (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+
+ /* area lamp correction */
+ if(lar->type==LA_AREA) specfac*= inp;
+
+ t= shadfac[3]*shi->spec*lampdist*specfac;
+
+ if(ma->mode & MA_RAMP_SPEC) {
+ float spec[3];
+ do_specular_ramp(shi, specfac, t, spec);
+ shr->spec[0]+= t*(lacol[0] * spec[0]);
+ shr->spec[1]+= t*(lacol[1] * spec[1]);
+ shr->spec[2]+= t*(lacol[2] * spec[2]);
+ }
+ else {
+ shr->spec[0]+= t*(lacol[0] * shi->specr);
+ shr->spec[1]+= t*(lacol[1] * shi->specg);
+ shr->spec[2]+= t*(lacol[2] * shi->specb);
+ }
+ }
+ }
+ }
+
+}
+
+
+static void shade_lamp_loop_pass(ShadeInput *shi, ShadeResult *shr, int passflag)
+{
+ Material *ma= shi->mat;
+ VlakRen *vlr= shi->vlr;
+
+ memset(shr, 0, sizeof(ShadeResult));
+
+ /* envmap hack, always reset */
+ shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0f;
+
+ /* material color itself */
+ if(passflag & (SCE_PASS_COMBINED|SCE_PASS_RGBA)) {
+ if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) {
+ shi->r= shi->vcol[0];
+ shi->g= shi->vcol[1];
+ shi->b= shi->vcol[2];
+ }
+ if(ma->texco)
+ do_material_tex(shi);
+
+ shr->col[0]= shi->r;
+ shr->col[1]= shi->g;
+ shr->col[2]= shi->b;
+ }
+
+ if(ma->mode & MA_SHLESS) {
+ shr->diff[0]= shi->r;
+ shr->diff[1]= shi->g;
+ shr->diff[2]= shi->b;
+ shr->alpha= shi->alpha;
+ return;
+ }
+
+ if( (ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL ) { // vertexcolor light
+ shr->diff[0]= shi->r*(shi->emit+shi->vcol[0]);
+ shr->diff[1]= shi->g*(shi->emit+shi->vcol[1]);
+ shr->diff[2]= shi->b*(shi->emit+shi->vcol[2]);
+ }
+ else {
+ shr->diff[0]= shi->r*shi->emit;
+ shr->diff[1]= shi->g*shi->emit;
+ shr->diff[2]= shi->b*shi->emit;
+ }
+
+ /* AO pass */
+ if(passflag & (SCE_PASS_COMBINED|SCE_PASS_AO)) {
+ ambient_occlusion(shi, shr);
+ }
+
+ /* lighting pass */
+ if(passflag & (SCE_PASS_COMBINED|SCE_PASS_DIFFUSE|SCE_PASS_SPEC|SCE_PASS_SHADOW)) {
+ GroupObject *go;
+ ListBase *lights;
+ LampRen *lar;
+ float diff[3];
+
+ /* lights */
+ if(ma->group)
+ lights= &ma->group->gobject;
+ else
+ lights= &R.lights;
+
+ for(go=lights->first; go; go= go->next) {
+ lar= go->lampren;
+ if(lar==NULL) continue;
+
+ /* yafray: ignore shading by photonlights, not used in Blender */
+ if (lar->type==LA_YF_PHOTON) continue;
+
+ /* test for lamp layer */
+ if(lar->mode & LA_LAYER) if((lar->lay & vlr->lay)==0) continue;
+
+ /* accumulates in shr->diff and shr->spec and shr->shad */
+ shade_one_light(lar, shi, shr, passflag);
+ }
+
+ /* calculate shadow */
+ VECCOPY(diff, shr->shad);
+ VECSUB(shr->shad, shr->shad, shr->diff);
+ VECCOPY(shr->diff, diff);
+ }
+
+ /* alpha in end, spec can influence it */
+ if(passflag & (SCE_PASS_COMBINED|SCE_PASS_RGBA)) {
+ if(ma->mode & (MA_ZTRA|MA_RAYTRANSP)) {
+ if(ma->fresnel_tra!=0.0)
+ shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra);
+
+ if(shi->spectra!=0.0) {
+ float t = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
+ t *= shi->spectra;
+ if(t>1.0) t= 1.0;
+ shi->alpha= (1.0-t)*shi->alpha+t;
+ }
+ }
+ shr->col[3]= shi->alpha;
+ }
+ shr->alpha= shi->alpha;
+
+ shr->diff[0]+= shi->ambr + shi->r*shi->amb*shi->rad[0];
+ shr->diff[1]+= shi->ambg + shi->g*shi->amb*shi->rad[1];
+ shr->diff[2]+= shi->ambb + shi->b*shi->amb*shi->rad[2];
+
+ if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shr->diff, shi);
+ if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shr->spec, shr->spec+1, shr->spec+2, shi);
+
+ /* refcol is for envmap only */
+ if(shi->refcol[0]!=0.0) {
+ shr->diff[0]= shi->mirr*shi->refcol[1] + (1.0 - shi->mirr*shi->refcol[0])*shr->diff[0];
+ shr->diff[1]= shi->mirg*shi->refcol[2] + (1.0 - shi->mirg*shi->refcol[0])*shr->diff[1];
+ shr->diff[2]= shi->mirb*shi->refcol[3] + (1.0 - shi->mirb*shi->refcol[0])*shr->diff[2];
+ }
+
+ if(passflag & SCE_PASS_COMBINED) {
+ shr->combined[0]= shr->diff[0]+(shr->ao[0])*shr->col[0] + shr->spec[0];
+ shr->combined[1]= shr->diff[1]+(shr->ao[1])*shr->col[1] + shr->spec[1];
+ shr->combined[2]= shr->diff[2]+(shr->ao[2])*shr->col[2] + shr->spec[2];
+ shr->combined[3]= shr->alpha;
+ }
+
+ if(R.r.mode & R_RAYTRACE) {
+
+ if((ma->mode & MA_RAYMIRROR)==0) shi->ray_mirror= 0.0;
+
+ if(shi->ray_mirror!=0.0 || ((shi->mat->mode & MA_RAYTRANSP) && shr->alpha!=1.0)) {
+ float diff[3];
+
+ VECCOPY(diff, shr->diff);
+
+ ray_trace(shi, shr);
+
+ VECSUB(shr->ray, shr->diff, diff);
+ VECCOPY(shr->diff, diff);
+ VECADD(shr->combined, shr->combined, shr->ray);
+ }
+ }
+ else {
+ /* doesnt look 'correct', but is better for preview, plus envmaps dont raytrace this */
+ if(shi->mat->mode & MA_RAYTRANSP) shr->alpha= 1.0;
+ }
+
+}
+
void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
{
LampRen *lar;
@@ -1184,11 +1630,6 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
Material *ma= shi->mat;
VlakRen *vlr= shi->vlr;
ListBase *lights;
- float i, inp, inpr, is, t, lv[3], vnor[3], lacol[3], lampdist, ld = 0;
- float lvrot[3], *vn, *view, shadfac[4], soft, phongcorr; // shadfac = rgba
-
- vn= shi->vn;
- view= shi->view;
memset(shr, 0, sizeof(ShadeResult));
@@ -1202,7 +1643,12 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
/* separate loop */
if(ma->mode & MA_ONLYSHADOW) {
- float ir;
+ float i, inp, inpr, lv[3];
+ float *vn, *view, shadfac[4];
+ float t, ir;
+
+ vn= shi->vn;
+ view= shi->view;
if(R.r.mode & R_SHADOW) {
@@ -1322,20 +1768,21 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
}
if( (ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL ) { // vertexcolor light
- // add_to_diffuse(shr->diff, shi, 1.0, ma->emit+shi->vcol[0], ma->emit+shi->vcol[1], ma->emit+shi->vcol[2]);
shr->diff[0]= shi->r*(shi->emit+shi->vcol[0]);
shr->diff[1]= shi->g*(shi->emit+shi->vcol[1]);
shr->diff[2]= shi->b*(shi->emit+shi->vcol[2]);
}
else {
- // add_to_diffuse(shr->diff, shi, 1.0, ma->emit, ma->emit, ma->emit);
shr->diff[0]= shi->r*shi->emit;
shr->diff[1]= shi->g*shi->emit;
shr->diff[2]= shi->b*shi->emit;
}
- ambient_occlusion(shi, shr);
-
+ if(R.wrld.mode & WO_AMB_OCC) {
+ ambient_occlusion(shi, shr);
+ VECADD(shr->diff, shr->diff, shr->ao);
+ }
+
for(go=lights->first; go; go= go->next) {
lar= go->lampren;
if(lar==NULL) continue;
@@ -1346,297 +1793,8 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
/* test for lamp layer */
if(lar->mode & LA_LAYER) if((lar->lay & vlr->lay)==0) continue;
- /* lampdist calculation */
- if(lar->type==LA_SUN || lar->type==LA_HEMI) {
- VECCOPY(lv, lar->vec);
- lampdist= 1.0;
- }
- else {
- lv[0]= shi->co[0]-lar->co[0];
- lv[1]= shi->co[1]-lar->co[1];
- lv[2]= shi->co[2]-lar->co[2];
- ld= sqrt(lv[0]*lv[0]+lv[1]*lv[1]+lv[2]*lv[2]);
- lv[0]/= ld;
- lv[1]/= ld;
- lv[2]/= ld;
-
- /* ld is re-used further on (texco's) */
- if(lar->type==LA_AREA) {
- lampdist= 1.0;
- }
- else {
- if(lar->mode & LA_QUAD) {
- t= 1.0;
- if(lar->ld1>0.0)
- t= lar->dist/(lar->dist+lar->ld1*ld);
- if(lar->ld2>0.0)
- t*= lar->distkw/(lar->distkw+lar->ld2*ld*ld);
-
- lampdist= t;
- }
- else {
- lampdist= (lar->dist/(lar->dist+ld));
- }
-
- if(lar->mode & LA_SPHERE) {
- t= lar->dist - ld;
- if(t<0.0) continue;
-
- t/= lar->dist;
- lampdist*= (t);
- }
- }
- }
-
- lacol[0]= lar->r;
- lacol[1]= lar->g;
- lacol[2]= lar->b;
-
- /* init transp shadow */
- shadfac[3]= 1.0;
- if(ma->mode & MA_SHADOW_TRA) shadfac[0]= shadfac[1]= shadfac[2]= 1.0;
-
- if(lar->type==LA_SPOT) {
-
- if(lar->mode & LA_SQUARE) {
- if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) {
- float x;
-
- /* rotate view to lampspace */
- VECCOPY(lvrot, lv);
- MTC_Mat3MulVecfl(lar->imat, lvrot);
-
- x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2]));
- /* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
-
- inpr= 1.0f/(sqrt(1.0f+x*x));
- }
- else inpr= 0.0;
- }
- else {
- inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2];
- }
-
- t= lar->spotsi;
- if(inpr<t) continue;
- else {
- t= inpr-t;
- i= 1.0;
- soft= 1.0;
- if(t<lar->spotbl && lar->spotbl!=0.0) {
- /* soft area */
- i= t/lar->spotbl;
- t= i*i;
- soft= (3.0*t-2.0*t*i);
- inpr*= soft;
- }
- lampdist*=inpr;
- }
-
- if(lar->mode & LA_OSATEX) {
- shi->osatex= 1; /* signal for multitex() */
-
- shi->dxlv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dxco[0])/ld;
- shi->dxlv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dxco[1])/ld;
- shi->dxlv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dxco[2])/ld;
-
- shi->dylv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dyco[0])/ld;
- shi->dylv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dyco[1])/ld;
- shi->dylv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dyco[2])/ld;
- }
-
- }
-
- if(lar->mode & LA_TEXTURE) do_lamp_tex(lar, lv, shi, lacol);
-
- /* dot product and reflectivity */
- /* inp = dotproduct, is = shader result, i = lamp energy (with shadow) */
-
- /* tangent case; calculate fake face normal, aligned with lampvector */
- if(vlr->flag & R_TANGENT) {
- float cross[3];
- Crossf(cross, lv, vn);
- Crossf(vnor, cross, vn);
- vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
- vn= vnor;
- }
- else if(ma->mode & MA_TANGENT_V) {
- float cross[3];
- Crossf(cross, lv, shi->tang);
- Crossf(vnor, cross, shi->tang);
- vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
- vn= vnor;
- }
-
- inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2];
-
- /* phong threshold to prevent backfacing faces having artefacts on ray shadow (terminator problem) */
- if((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) {
- float thresh= vlr->ob->smoothresh;
- if(inp>thresh)
- phongcorr= (inp-thresh)/(inp*(1.0-thresh));
- else
- phongcorr= 0.0;
- }
- else if(ma->sbias!=0.0f) {
- if(inp>ma->sbias)
- phongcorr= (inp-ma->sbias)/(inp*(1.0-ma->sbias));
- else
- phongcorr= 0.0;
- }
- else phongcorr= 1.0;
-
- /* diffuse shaders */
- if(lar->mode & LA_NO_DIFF) {
- is= 0.0; // skip shaders
- }
- else if(lar->type==LA_HEMI) {
- is= 0.5*inp + 0.5;
- }
- else {
-
- if(lar->type==LA_AREA) {
- /* single sided */
- if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) {
- inp= area_lamp_energy(shi->co, vn, lar);
- }
- else inp= 0.0;
- }
-
- /* diffuse shaders (oren nayer gets inp from area light) */
- if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, vn, lv, view, ma->roughness);
- else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, view, ma->param[0], ma->param[1]);
- else if(ma->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(inp, vn, view, ma->darkness);
- else if(ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, lv, view, ma->param[0], ma->param[1]);
- else is= inp; // Lambert
- }
-
- i= is*phongcorr;
-
- if(i>0.0) {
- i*= lampdist*shi->refl;
- }
-
- vn= shi->vn; // bring back original vector, we use special specular shaders for tangent
- if(ma->mode & MA_TANGENT_V)
- vn= shi->tang;
-
- /* shadow and spec, (lampdist==0 outside spot) */
- if(lampdist> 0.0) {
-
- if(i>0.0 && (R.r.mode & R_SHADOW)) {
- if(ma->mode & MA_SHADOW) {
- if(lar->type==LA_HEMI); // no shadow
- else {
- if(lar->shb) {
- shadfac[3] = testshadowbuf(lar->shb, shi->co, shi->dxco, shi->dyco, inp);
- }
- else if(lar->mode & LA_SHAD_RAY) {
- ray_shadow(shi, lar, shadfac);
- }
-
- /* warning, here it skips the loop */
- if(lar->mode & LA_ONLYSHADOW) {
-
- shadfac[3]= i*lar->energy*(1.0-shadfac[3]);
- shr->diff[0] -= shadfac[3]*shi->r;
- shr->diff[1] -= shadfac[3]*shi->g;
- shr->diff[2] -= shadfac[3]*shi->b;
-
- continue;
- }
-
- if(shadfac[3]==0.0) continue;
-
- i*= shadfac[3];
- }
- }
- }
-#if 0
- if(R.r.mode & R_RAYTRACE) {
- extern void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float *co);
- float co[3], distfac;
-
- ray_translucent(shi, lar, &distfac, co);
-
- if(distfac<0.01f*G.rt) {
- // printf("distfac %f\n", distfac);
- distfac= 1.0f - distfac/(0.01f*G.rt);
- shr->diff[0]+= distfac;
- shr->diff[1]+= distfac;
- shr->diff[2]+= distfac;
- }
- }
-#endif
-
- /* specularity */
- if(shadfac[3]>0.0 && shi->spec!=0.0 && !(lar->mode & LA_NO_SPEC)) {
-
- if(lar->type==LA_HEMI) {
- /* hemi uses no spec shaders (yet) */
-
- lv[0]+= view[0];
- lv[1]+= view[1];
- lv[2]+= view[2];
-
- Normalise(lv);
-
- t= vn[0]*lv[0]+vn[1]*lv[1]+vn[2]*lv[2];
-
- if(lar->type==LA_HEMI) {
- t= 0.5*t+0.5;
- }
-
- t= shadfac[3]*shi->spec*spec(t, shi->har);
- shr->spec[0]+= t*(lacol[0] * shi->specr);
- shr->spec[1]+= t*(lacol[1] * shi->specg);
- shr->spec[2]+= t*(lacol[2] * shi->specb);
- }
- else {
- /* specular shaders */
- float specfac;
-
- if(ma->spec_shader==MA_SPEC_PHONG)
- specfac= Phong_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
- else if(ma->spec_shader==MA_SPEC_COOKTORR)
- specfac= CookTorr_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
- else if(ma->spec_shader==MA_SPEC_BLINN)
- specfac= Blinn_Spec(vn, lv, view, ma->refrac, (float)shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
- else if(ma->spec_shader==MA_SPEC_WARDISO)
- specfac= WardIso_Spec( vn, lv, view, ma->rms, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
- else
- specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3], (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
-
- /* area lamp correction */
- if(lar->type==LA_AREA) specfac*= inp;
-
- t= shadfac[3]*shi->spec*lampdist*specfac;
-
- if(ma->mode & MA_RAMP_SPEC) {
- float spec[3];
- do_specular_ramp(shi, specfac, t, spec);
- shr->spec[0]+= t*(lacol[0] * spec[0]);
- shr->spec[1]+= t*(lacol[1] * spec[1]);
- shr->spec[2]+= t*(lacol[2] * spec[2]);
- }
- else {
- shr->spec[0]+= t*(lacol[0] * shi->specr);
- shr->spec[1]+= t*(lacol[1] * shi->specg);
- shr->spec[2]+= t*(lacol[2] * shi->specb);
- }
- }
- }
- }
-
- /* in case 'no diffuse' we still do most calculus, spec can be in shadow */
- if(i>0.0 && !(lar->mode & LA_NO_DIFF)) {
- if(ma->mode & MA_SHADOW_TRA) {
- add_to_diffuse(shr->diff, shi, is, i*shadfac[0]*lacol[0], i*shadfac[1]*lacol[1], i*shadfac[2]*lacol[2]);
- }
- else {
- add_to_diffuse(shr->diff, shi, is, i*lacol[0], i*lacol[1], i*lacol[2]);
- }
- }
+ /* accumulates in shr->diff and shr->spec, 0= no passrender */
+ shade_one_light(lar, shi, shr, 0);
}
if(ma->mode & (MA_ZTRA|MA_RAYTRANSP)) {
@@ -1644,8 +1802,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra);
if(shi->spectra!=0.0) {
-
- t = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
+ float t = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
t *= shi->spectra;
if(t>1.0) t= 1.0;
shi->alpha= (1.0-t)*shi->alpha+t;
@@ -2125,7 +2282,7 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
/* note, facenr declared volatile due to over-eager -O2 optimizations
* on cygwin (particularly -frerun-cse-after-loop)
*/
-void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, int mask, ShadeResult *shr, float *rco)
+void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, int mask, ShadeResult *shr, float *rco, int passflag)
{
ShadeInput shi;
VlakRen *vlr=NULL;
@@ -2347,7 +2504,10 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
memcpy(&shi.r, &shi.mat->r, 23*sizeof(float));
shi.har= shi.mat->har;
- shade_material_loop(&shi, shr);
+// if(passflag)
+// shade_lamp_loop_pass(&shi, shr, passflag);
+// else
+ shade_material_loop(&shi, shr);
}
/* after shading and composit layers */
@@ -2359,7 +2519,9 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
if(shr->diff[1]<0.0f) shr->diff[1]= 0.0f;
if(shr->diff[2]<0.0f) shr->diff[2]= 0.0f;
- VECADD(shr->combined, shr->diff, shr->spec);
+// if(passflag==0) {
+ VECADD(shr->combined, shr->diff, shr->spec);
+// }
/* additional passes */
shr->winspeed[0]= shi.winspeed[0]; shr->winspeed[1]= shi.winspeed[1];
@@ -2423,12 +2585,12 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
return vlr;
}
-static void shadepixel_sky(RenderPart *pa, float x, float y, int z, int facenr, int mask, ShadeResult *shr)
+static void shadepixel_sky(RenderPart *pa, float x, float y, int z, int facenr, int mask, ShadeResult *shr, int passflag)
{
VlakRen *vlr;
float collector[4], rco[3];
- vlr= shadepixel(pa, x, y, z, facenr, mask, shr, rco);
+ vlr= shadepixel(pa, x, y, z, facenr, mask, shr, rco, passflag);
if(shr->combined[3] != 1.0) {
/* bail out when raytrace transparency (sky included already) */
@@ -2515,6 +2677,96 @@ static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
/* ********************* MAINLOOPS ******************** */
+/* osa version */
+static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeResult *shr)
+{
+ RenderPass *rpass;
+
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
+ float *fp, *col= NULL;
+ int pixsize= 3;
+
+ switch(rpass->passtype) {
+ case SCE_PASS_RGBA:
+ col= shr->col;
+ pixsize= 4;
+ break;
+ case SCE_PASS_DIFFUSE:
+ col= shr->diff;
+ break;
+ case SCE_PASS_SPEC:
+ col= shr->spec;
+ break;
+ case SCE_PASS_SHADOW:
+ col= shr->shad;
+ break;
+ case SCE_PASS_AO:
+ col= shr->ao;
+ break;
+ case SCE_PASS_RAY:
+ col= shr->ray;
+ break;
+ case SCE_PASS_NORMAL:
+ col= shr->nor;
+ break;
+ case SCE_PASS_VECTOR:
+ col= shr->winspeed;
+ pixsize= 2;
+ break;
+ }
+ if(col) {
+ fp= rpass->rect + pixsize*offset;
+ add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize);
+ }
+ }
+}
+
+/* non-osa version */
+static void add_passes(RenderLayer *rl, int offset, ShadeResult *shr)
+{
+ RenderPass *rpass;
+
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
+ float *fp, *col= NULL;
+ int a, pixsize= 3;
+
+ switch(rpass->passtype) {
+ case SCE_PASS_RGBA:
+ col= shr->col;
+ pixsize= 4;
+ break;
+ case SCE_PASS_DIFFUSE:
+ col= shr->diff;
+ break;
+ case SCE_PASS_SPEC:
+ col= shr->spec;
+ break;
+ case SCE_PASS_SHADOW:
+ col= shr->shad;
+ break;
+ case SCE_PASS_AO:
+ col= shr->ao;
+ break;
+ case SCE_PASS_RAY:
+ col= shr->ray;
+ break;
+ case SCE_PASS_NORMAL:
+ col= shr->nor;
+ break;
+ case SCE_PASS_VECTOR:
+ col= shr->winspeed;
+ pixsize= 2;
+ break;
+ }
+ if(col) {
+ fp= rpass->rect + pixsize*offset;
+ for(a=0; a<pixsize; a++)
+ fp[a]= col[a];
+ }
+ }
+}
+
+
static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
{
RenderResult *rr= pa->result;
@@ -2524,7 +2776,7 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
float *fcol= shr.combined, *rf, *rectf= rl->rectf;
long *rd, *rectdaps= pa->rectdaps;
int zbuf, samp, curmask, face, mask, fullmask;
- int b, x, y, full_osa, seed, crop=0, offs=0, od;
+ int b, x, y, full_osa, seed, crop=0, offs=0, od, renderpassflag, addpassflag;
if(R.test_break()) return;
@@ -2533,6 +2785,13 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
fullmask= (1<<R.osa)-1;
+ /* bit clumsy, but with passes we need different shade code */
+ if(rl->passflag & ~(SCE_PASS_Z|SCE_PASS_NORMAL|SCE_PASS_VECTOR|SCE_PASS_COMBINED))
+ renderpassflag= rl->passflag;
+ else
+ renderpassflag= 0;
+ addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
+
/* filtered render, for now we assume only 1 filter size */
if(pa->crop) {
crop= 1;
@@ -2582,7 +2841,7 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
if(curmask & (1<<samp)) {
xs= (float)x + R.jit[samp][0];
ys= (float)y + R.jit[samp][1];
- shadepixel_sky(pa, xs, ys, zbuf, face, (1<<samp), &shr);
+ shadepixel_sky(pa, xs, ys, zbuf, face, (1<<samp), &shr, renderpassflag);
if(R.do_gamma) {
fcol[0]= gammaCorrect(fcol[0]);
@@ -2590,6 +2849,9 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
fcol[2]= gammaCorrect(fcol[2]);
}
add_filt_fmask(1<<samp, fcol, rf, pa->rectx);
+
+ if(addpassflag)
+ add_filt_passes(rl, curmask, pa->rectx, od, &shr);
}
}
}
@@ -2597,7 +2859,7 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
b= R.samples->centmask[curmask];
xs= (float)x+R.samples->centLut[b & 15];
ys= (float)y+R.samples->centLut[b>>4];
- shadepixel_sky(pa, xs, ys, zbuf, face, curmask, &shr);
+ shadepixel_sky(pa, xs, ys, zbuf, face, curmask, &shr, renderpassflag);
if(R.do_gamma) {
fcol[0]= gammaCorrect(fcol[0]);
@@ -2605,6 +2867,9 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
fcol[2]= gammaCorrect(fcol[2]);
}
add_filt_fmask(curmask, fcol, rf, pa->rectx);
+
+ if(addpassflag)
+ add_filt_passes(rl, curmask, pa->rectx, od, &shr);
}
mask |= curmask;
@@ -2612,13 +2877,6 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
if(ps==NULL) break;
else ps= ps->next;
}
-
- /* passes */
- if(rl->passflag & SCE_PASS_VECTOR) {
- float *fp= rl->rectvec+2*od;
- fp[0]= shr.winspeed[0];
- fp[1]= shr.winspeed[1];
- }
}
rectf+= 4*pa->rectx;
@@ -2812,10 +3070,10 @@ void zbufshadeDA_tile(RenderPart *pa)
/* supposed to be fully threadable! */
void zbufshade_tile(RenderPart *pa)
{
- ShadeResult shr;
+ ShadeResult *shr= RE_mallocN(sizeof(ShadeResult), "shaderesult");
RenderResult *rr= pa->result;
RenderLayer *rl;
-
+
set_part_zbuf_clipflag(pa);
/* zbuffer code clears/inits rects */
@@ -2831,22 +3089,26 @@ void zbufshade_tile(RenderPart *pa)
if(!R.test_break()) {
if(rl->layflag & SCE_LAY_SOLID) {
float *fcol= rl->rectf;
- int x, y, *rp= pa->rectp, *rz= pa->rectz, offs=0;
+ int x, y, *rp= pa->rectp, *rz= pa->rectz, offs=0, renderpassflag, addpassflag;
+
+ /* bit clumsy, but with passes we shade differently */
+ if(rl->passflag & ~(SCE_PASS_Z|SCE_PASS_NORMAL|SCE_PASS_VECTOR|SCE_PASS_COMBINED))
+ renderpassflag= rl->passflag;
+ else
+ renderpassflag= 0;
+ addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
/* init scanline updates */
rr->renrect.ymin=rr->renrect.ymax= 0;
for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, rp++, fcol+=4, offs++) {
- shadepixel_sky(pa, (float)x, (float)y, *rz, *rp, 0, &shr);
- QUATCOPY(fcol, shr.combined);
+ shadepixel_sky(pa, (float)x, (float)y, *rz, *rp, 0, shr, renderpassflag);
+ QUATCOPY(fcol, shr->combined);
/* passes */
- if(*rp && (rl->passflag & SCE_PASS_VECTOR)) {
- float *fp= rl->rectvec+2*(offs);
- fp[0]= shr.winspeed[0];
- fp[1]= shr.winspeed[1];
- }
+ if(*rp && addpassflag)
+ add_passes(rl, offs, shr);
}
if(y&1)
if(R.test_break()) break;
@@ -2891,7 +3153,7 @@ void zbufshade_tile(RenderPart *pa)
convert_zbuf_to_distbuf(pa, rl);
}
-
+ RE_freeN(shr);
RE_freeN(pa->rectp); pa->rectp= NULL;
RE_freeN(pa->rectz); pa->rectz= NULL;
}
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 4830db352d7..eb1385cab95 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -2049,7 +2049,7 @@ static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, i
if(vlr->flag & R_FULL_OSA) {
for(a=0; a<R.osa; a++) {
if(mask & (1<<a)) {
- shadepixel(pa, x+R.jit[a][0], y+R.jit[a][1], z, facenr, 1<<a, &shr, rco);
+ shadepixel(pa, x+R.jit[a][0], y+R.jit[a][1], z, facenr, 1<<a, &shr, rco, 0);
accumcol[0]+= shr.combined[0];
accumcol[1]+= shr.combined[1];
accumcol[2]+= shr.combined[2];
@@ -2067,12 +2067,12 @@ static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, i
int b= R.samples->centmask[mask];
x= x+R.samples->centLut[b & 15];
y= y+R.samples->centLut[b>>4];
- shadepixel(pa, x, y, z, facenr, mask, &shr, rco);
+ shadepixel(pa, x, y, z, facenr, mask, &shr, rco, 0);
QUATCOPY(fcol, shr.combined);
}
}
else {
- shadepixel(pa, x, y, z, facenr, mask, &shr, rco);
+ shadepixel(pa, x, y, z, facenr, mask, &shr, rco, 0);
QUATCOPY(fcol, shr.combined);
}
}
@@ -2238,15 +2238,21 @@ void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short l
/* uses part zbuffer values to convert into distances from camera in renderlayer */
void convert_zbuf_to_distbuf(RenderPart *pa, RenderLayer *rl)
{
+ RenderPass *rpass;
float *rectzf, zco;
int a, *rectz, ortho= R.r.mode & R_ORTHO;
if(pa->rectz==NULL) return;
- if(rl->rectz==NULL) {
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next)
+ if(rpass->passtype==SCE_PASS_Z)
+ break;
+
+ if(rpass==NULL) {
printf("called convert zbuf wrong...\n");
return;
}
- rectzf= rl->rectz;
+
+ rectzf= rpass->rect;
rectz= pa->rectz;
for(a=pa->rectx*pa->recty; a>0; a--, rectz++, rectzf++) {
diff --git a/source/blender/renderconverter/Makefile b/source/blender/renderconverter/Makefile
deleted file mode 100644
index 0d65772b72b..00000000000
--- a/source/blender/renderconverter/Makefile
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# $Id$
-#
-# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version. The Blender
-# Foundation also sells licenses for use in proprietary software under
-# the Blender License. See http://www.blender.org/BL/ for information
-# about this.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): none yet.
-#
-# ***** END GPL/BL DUAL LICENSE BLOCK *****
-#
-# Bounces make to subdirectories.
-
-SOURCEDIR = source/blender/renderconverter
-DIRS = intern
-
-include nan_subdirs.mk
diff --git a/source/blender/renderconverter/RE_renderconverter.h b/source/blender/renderconverter/RE_renderconverter.h
deleted file mode 100644
index 272248f7066..00000000000
--- a/source/blender/renderconverter/RE_renderconverter.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * $Id$
- *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- * Interface to transform the Blender scene into renderable data.
- *
- * @mainpage RE - Blender RE-converter external interface
- *
- * @section about About the RE-converter module
- *
- * The converter takes a Blender scene, and transforms the data into
- * renderer-specific data.
- *
- * Conversions:
- *
- * halos: (world settings) stars ->
- * some particle effects ->
- * meshes with halo prop ->
- * HaloRen (made by inithalo)
- *
- *
- * VlakRen (face render data)
- * Each vlakren needs several VertRens to make sense.
- * VertRen (vertex render data)
- *
- * @section issues Known issues with RE-converter
- *
- *
- * @section dependencies Dependencies
- *
- *
- * */
-
-#ifndef RE_RENDERCONVERTER_H
-#define RE_RENDERCONVERTER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
- struct LampRen;
- struct Object;
- struct Lamp;
-
- /** Transform a blender scene to render data. */
- void RE_rotateBlenderScene(void);
-
- /** Free all memory used for the conversion. */
- void RE_freeRotateBlenderScene(void);
-
- /**
- * Used by the preview renderer.
- */
- void RE_add_render_lamp(struct Object *ob, int doshadbuf);
-
- /**
- * Strange support for star rendering for drawview.c... For
- * rendering purposes, these function pointers should be NULL.
- */
- void RE_make_stars(void (*initfunc)(void),
- void (*vertexfunc)(float*),
- void (*termfunc)(void));
-
- /**
- * called by meshtools
- */
- void RE_make_sticky(void);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/source/blender/renderconverter/SConscript b/source/blender/renderconverter/SConscript
deleted file mode 100644
index e0f777d59bf..00000000000
--- a/source/blender/renderconverter/SConscript
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/python
-Import ('user_options_dict')
-Import ('library_env')
-
-renderconv_env = library_env.Copy ()
-
-source_files = ['intern/convertBlenderScene.c']
-
-renderconv_env.Append (CPPPATH = ['.',
- '../renderconverter',
- '../blenlib',
- '../yafray',
- '../radiosity/extern/include',
- '#/intern/guardedalloc',
- '../makesdna',
- '../blenkernel',
- '../include',
- '../render/extern/include',
- '../python'])
-
-renderconv_env.Library (target='#'+user_options_dict['BUILD_DIR']+'/lib/blender_renderconverter', source=source_files)
diff --git a/source/blender/renderconverter/intern/Makefile b/source/blender/renderconverter/intern/Makefile
deleted file mode 100644
index 33a462d6e63..00000000000
--- a/source/blender/renderconverter/intern/Makefile
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# $Id$
-#
-# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version. The Blender
-# Foundation also sells licenses for use in proprietary software under
-# the Blender License. See http://www.blender.org/BL/ for information
-# about this.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): none yet.
-#
-# ***** END GPL/BL DUAL LICENSE BLOCK *****
-#
-#
-
-LIBNAME = renderconverter
-DIR = $(OCGDIR)/blender/$(LIBNAME)
-
-include nan_compile.mk
-
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
-# CFLAGS += $(LEVEL_2_C_WARNINGS)
-
-CPPFLAGS += -I$(OPENGL_HEADERS)
-# path to our own external headerfiles
-CPPFLAGS += -I..
-# not very neat: the dirs for external modules
-CPPFLAGS += -I../../render/extern/include
-CPPFLAGS += -I../../yafray
-CPPFLAGS += -I../../radiosity/extern/include
-CPPFLAGS += -I../../python
-CPPFLAGS += -I../../blenkernel
-CPPFLAGS += -I../../blenlib
-CPPFLAGS += -I../../makesdna
-CPPFLAGS += -I../../include
-CPPFLAGS += -I../../
-CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c
deleted file mode 100644
index fae6176983c..00000000000
--- a/source/blender/renderconverter/intern/convertBlenderScene.c
+++ /dev/null
@@ -1,3297 +0,0 @@
-/**
- * $Id$
- *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- * Interface to transform the Blender scene into renderable data.
- */
-
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <limits.h> /* for INT_MAX */
-
-#include "blendef.h"
-#include "MTC_matrixops.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_arithb.h"
-#include "BLI_blenlib.h"
-#include "BLI_rand.h"
-#include "BLI_memarena.h"
-#include "BLI_ghash.h"
-
-#include "DNA_armature_types.h"
-#include "DNA_camera_types.h"
-#include "DNA_material_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_effect_types.h"
-#include "DNA_group_types.h"
-#include "DNA_lamp_types.h"
-#include "DNA_lattice_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_meta_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_scene_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_view3d_types.h"
-
-#include "BKE_anim.h"
-#include "BKE_armature.h"
-#include "BKE_action.h"
-#include "BKE_curve.h"
-#include "BKE_constraint.h"
-#include "BKE_displist.h"
-#include "BKE_deform.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_effect.h"
-#include "BKE_global.h"
-#include "BKE_group.h"
-#include "BKE_key.h"
-#include "BKE_ipo.h"
-#include "BKE_lattice.h"
-#include "BKE_material.h"
-#include "BKE_main.h"
-#include "BKE_mball.h"
-#include "BKE_mesh.h"
-#include "BKE_object.h"
-#include "BKE_scene.h"
-#include "BKE_subsurf.h"
-#include "BKE_texture.h"
-#include "BKE_utildefines.h"
-#include "BKE_world.h"
-
-#include "render_types.h"
-#include "rendercore.h"
-#include "RE_renderconverter.h"
-
-#include "BIF_space.h"
-#include "BIF_screen.h"
-#include "BIF_editkey.h"
-
-#include "BSE_sequence.h"
-
-#include "nla.h"
-
-#include "BPY_extern.h"
-
-#include "butspace.h"
-
-#include "radio.h"
-#include "YafRay_Api.h"
-
-extern Render R;
-extern void error (char *fmt, ...); /* defined in BIF_toolbox.h, but we dont need to include the rest */
-
-/* yafray: Identity transform 'hack' removed, exporter now transforms vertices back to world.
- * Same is true for lamp coords & vec.
- * Duplicated data objects & dupliframe/duplivert objects are only stored once,
- * only the matrix is stored for all others, in yafray these objects are instances of the original.
- * The main changes are in RE_rotateBlenderScene().
- */
-
-/* ------------------------------------------------------------------------- */
-/* Local functions */
-/* ------------------------------------------------------------------------- */
-static Material *give_render_material(Object *ob, int nr);
-static short test_for_displace(Object *ob);
-static void do_displacement(Object *ob, int startface, int numface, int startvert, int numvert );
-
-/* ------------------------------------------------------------------------- */
-/* tool functions/defines for ad hoc simplification and possible future
- cleanup */
-/* ------------------------------------------------------------------------- */
-
-#define UVTOINDEX(u,v) (startvlak + (u) * sizev + (v))
-/*
-
-NOTE THAT U/V COORDINATES ARE SOMETIMES SWAPPED !!
-
-^ ()----p4----p3----()
-| | | | |
-u | | F1 | F2 |
- | | | |
- ()----p1----p2----()
- v ->
-*/
-
-/* ------------------------------------------------------------------------- */
-
-/* Stuff for stars. This sits here because it uses gl-things. Part of
- this code may move down to the converter. */
-/* ------------------------------------------------------------------------- */
-/* this is a bad beast, since it is misused by the 3d view drawing as well. */
-
-/* more star stuff, here used to be a cliptest, removed for envmap render or panorama... */
-static HaloRen *initstar(float *vec, float hasize)
-{
- HaloRen *har;
- float hoco[4];
-
- RE_projectverto(vec, hoco);
-
- har= RE_findOrAddHalo(R.tothalo++);
-
- /* projectvert is done in function zbufvlaggen again, because of parts */
- VECCOPY(har->co, vec);
- har->hasize= hasize;
-
- har->zd= 0.0;
-
- return har;
-}
-
-extern unsigned char hash[512];
-
-/* there must be a 'fixed' amount of stars generated between
- * near and far
- * all stars must by preference lie on the far and solely
- * differ in clarity/color
- */
-
-void RE_make_stars(void (*initfunc)(void),
- void (*vertexfunc)(float*),
- void (*termfunc)(void))
-{
- HaloRen *har;
- double dblrand, hlfrand;
- float vec[4], fx, fy, fz;
- float fac, starmindist, clipend;
- float mat[4][4], stargrid, maxrand, maxjit, force, alpha;
-/* float loc_far_var, loc_near_var; */
- int x, y, z, sx, sy, sz, ex, ey, ez, done = 0;
- Camera * camera;
-
- if(initfunc) R.wrld= *(G.scene->world);
-
- stargrid = R.wrld.stardist; /* distance between stars */
- maxrand = 2.0; /* amount a star can be shifted (in grid units) */
- maxjit = (R.wrld.starcolnoise); /* amount a color is being shifted */
-
-/* loc_far_var = R.far; */
-/* loc_near_var = R.near; */
-
-
- /* size of stars */
- force = ( R.wrld.starsize );
-
- /* minimal free space (starting at camera) */
- starmindist= R.wrld.starmindist;
-
- if (stargrid <= 0.10) return;
-
- if (!initfunc) R.flag |= R_HALO;
- else stargrid *= 1.0; /* then it draws fewer */
-
-
- MTC_Mat4Invert(mat, R.viewmat);
-
- /* BOUNDING BOX CALCULATION
- * bbox goes from z = loc_near_var | loc_far_var,
- * x = -z | +z,
- * y = -z | +z
- */
-
- camera = G.scene->camera->data;
- clipend = camera->clipend;
-
- /* convert to grid coordinates */
-
- sx = ((mat[3][0] - clipend) / stargrid) - maxrand;
- sy = ((mat[3][1] - clipend) / stargrid) - maxrand;
- sz = ((mat[3][2] - clipend) / stargrid) - maxrand;
-
- ex = ((mat[3][0] + clipend) / stargrid) + maxrand;
- ey = ((mat[3][1] + clipend) / stargrid) + maxrand;
- ez = ((mat[3][2] + clipend) / stargrid) + maxrand;
-
- dblrand = maxrand * stargrid;
- hlfrand = 2.0 * dblrand;
-
- if (initfunc) {
- initfunc();
- }
-
- for (x = sx, fx = sx * stargrid; x <= ex; x++, fx += stargrid) {
- for (y = sy, fy = sy * stargrid; y <= ey ; y++, fy += stargrid) {
- for (z = sz, fz = sz * stargrid; z <= ez; z++, fz += stargrid) {
-
- BLI_srand((hash[z & 0xff] << 24) + (hash[y & 0xff] << 16) + (hash[x & 0xff] << 8));
- vec[0] = fx + (hlfrand * BLI_drand()) - dblrand;
- vec[1] = fy + (hlfrand * BLI_drand()) - dblrand;
- vec[2] = fz + (hlfrand * BLI_drand()) - dblrand;
- vec[3] = 1.0;
-
- if (vertexfunc) {
- if(done & 1) vertexfunc(vec);
- done++;
- }
- else {
- MTC_Mat4MulVecfl(R.viewmat, vec);
-
- /* in vec are global coordinates
- * calculate distance to camera
- * and using that, define the alpha
- */
-
- {
- float tx, ty, tz;
-
- tx = vec[0];
- ty = vec[1];
- tz = vec[2];
-
- alpha = sqrt(tx * tx + ty * ty + tz * tz);
-
- if (alpha >= clipend) alpha = 0.0;
- else if (alpha <= starmindist) alpha = 0.0;
- else if (alpha <= 2.0 * starmindist) {
- alpha = (alpha - starmindist) / starmindist;
- } else {
- alpha -= 2.0 * starmindist;
- alpha /= (clipend - 2.0 * starmindist);
- alpha = 1.0 - alpha;
- }
- }
-
-
- if (alpha != 0.0) {
- fac = force * BLI_drand();
-
- har = initstar(vec, fac);
-
- if (har) {
- har->alfa = sqrt(sqrt(alpha));
- har->add= 255;
- har->r = har->g = har->b = 1.0;
- if (maxjit) {
- har->r += ((maxjit * BLI_drand()) ) - maxjit;
- har->g += ((maxjit * BLI_drand()) ) - maxjit;
- har->b += ((maxjit * BLI_drand()) ) - maxjit;
- }
- har->hard = 32;
-
- har->type |= HA_ONLYSKY;
- done++;
- }
- }
- }
- }
- /* do not call blender_test_break() here, since it is used in UI as well, confusing the callback system */
- /* main cause is G.afbreek of course, a global again... (ton) */
- }
- }
- if (termfunc) termfunc();
-}
-
-/* ------------------------------------------------------------------------- */
-
-static VertRen *RE_duplicate_vertren(VertRen *ver)
-{
- VertRen *v1= RE_findOrAddVert(R.totvert++);
- int index= v1->index;
- *v1= *ver;
- v1->index= index;
- return v1;
-}
-
-static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsize, int uIndex, int cyclu, int cyclv)
-{
- int vLen = vsize-1+(!!cyclv);
- int uLen = usize-1+(!!cyclu);
- int v;
-
- for (v=0; v<vLen; v++) {
- VlakRen *vlr = RE_findOrAddVlak(startvlak + vLen*uIndex + v);
- VertRen *vert = RE_duplicate_vertren(vlr->v2);
-
- if (cyclv) {
- vlr->v2 = vert;
-
- if (v==vLen-1) {
- VlakRen *vlr = RE_findOrAddVlak(startvlak + vLen*uIndex + 0);
- vlr->v1 = vert;
- } else {
- VlakRen *vlr = RE_findOrAddVlak(startvlak + vLen*uIndex + v+1);
- vlr->v1 = vert;
- }
- } else {
- vlr->v2 = vert;
-
- if (v<vLen-1) {
- VlakRen *vlr = RE_findOrAddVlak(startvlak + vLen*uIndex + v+1);
- vlr->v1 = vert;
- }
-
- if (v==0) {
- vlr->v1 = RE_duplicate_vertren(vlr->v1);
- }
- }
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int contrpuntnormr(float *n, float *puno)
-{
- float inp;
-
- inp=n[0]*puno[0]+n[1]*puno[1]+n[2]*puno[2];
- if(inp<0.0) return 1;
- return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void calc_edge_stress_add(float *accum, VertRen *v1, VertRen *v2)
-{
- float len= VecLenf(v1->co, v2->co)/VecLenf(v1->orco, v2->orco);
- float *acc;
-
- acc= accum + 2*v1->index;
- acc[0]+= len;
- acc[1]+= 1.0f;
-
- acc= accum + 2*v2->index;
- acc[0]+= len;
- acc[1]+= 1.0f;
-}
-
-static void calc_edge_stress(Mesh *me, int startvert, int startvlak)
-{
- float loc[3], size[3], *accum, *acc, *accumoffs, *stress;
- int a;
-
- if(startvert==R.totvert) return;
-
- mesh_get_texspace(me, loc, NULL, size);
-
- accum= MEM_callocN(2*sizeof(float)*(R.totvert-startvert), "temp accum for stress");
-
- /* de-normalize orco */
- for(a=startvert; a<R.totvert; a++, acc+=2) {
- VertRen *ver= RE_findOrAddVert(a);
- if(ver->orco) {
- ver->orco[0]= ver->orco[0]*size[0] +loc[0];
- ver->orco[1]= ver->orco[1]*size[1] +loc[1];
- ver->orco[2]= ver->orco[2]*size[2] +loc[2];
- }
- }
-
- /* add stress values */
- accumoffs= accum - 2*startvert; /* so we can use vertex index */
- for(a=startvlak; a<R.totvlak; a++) {
- VlakRen *vlr= RE_findOrAddVlak(a);
-
- if(vlr->v1->orco && vlr->v4) {
- calc_edge_stress_add(accumoffs, vlr->v1, vlr->v2);
- calc_edge_stress_add(accumoffs, vlr->v2, vlr->v3);
- calc_edge_stress_add(accumoffs, vlr->v3, vlr->v1);
- if(vlr->v4) {
- calc_edge_stress_add(accumoffs, vlr->v3, vlr->v4);
- calc_edge_stress_add(accumoffs, vlr->v4, vlr->v1);
- calc_edge_stress_add(accumoffs, vlr->v2, vlr->v4);
- }
- }
- }
-
- for(a=startvert; a<R.totvert; a++) {
- VertRen *ver= RE_findOrAddVert(a);
- if(ver->orco) {
- /* find stress value */
- acc= accumoffs + 2*ver->index;
- if(acc[1]!=0.0f)
- acc[0]/= acc[1];
- stress= RE_vertren_get_stress(ver, 1);
- *stress= *acc;
-
- /* restore orcos */
- ver->orco[0] = (ver->orco[0]-loc[0])/size[0];
- ver->orco[1] = (ver->orco[1]-loc[1])/size[1];
- ver->orco[2] = (ver->orco[2]-loc[2])/size[2];
- }
- }
-
- MEM_freeN(accum);
-}
-
-static void calc_tangent_vector(VlakRen *vlr, float fac1, float fac2, float fac3, float fac4)
-{
- TFace *tface= vlr->tface;
-
- if(tface) {
- VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4;
- float *uv1= tface->uv[0], *uv2= tface->uv[1], *uv3= tface->uv[2], *uv4= tface->uv[3];
- float tang[3], *tav;
- float s1, s2, t1, t2, det;
-
- /* we calculate quads as two triangles, so weight for diagonal gets halved */
- if(v4) {
- fac1*= 0.5f;
- fac3*= 0.5f;
- }
-
- /* first tria, we use the V now */
- s1= uv2[0] - uv1[0];
- s2= uv3[0] - uv1[0];
- t1= uv2[1] - uv1[1];
- t2= uv3[1] - uv1[1];
- det= 1.0f / (s1 * t2 - s2 * t1);
-
- /* normals in render are inversed... */
- tang[0]= (t2 * (v1->co[0]-v2->co[0]) - t1 * (v1->co[0]-v3->co[0]));
- tang[1]= (t2 * (v1->co[1]-v2->co[1]) - t1 * (v1->co[1]-v3->co[1]));
- tang[2]= (t2 * (v1->co[2]-v2->co[2]) - t1 * (v1->co[2]-v3->co[2]));
-
- tav= RE_vertren_get_tangent(v1, 1);
- VECADDFAC(tav, tav, tang, fac1);
- tav= RE_vertren_get_tangent(v2, 1);
- VECADDFAC(tav, tav, tang, fac2);
- tav= RE_vertren_get_tangent(v3, 1);
- VECADDFAC(tav, tav, tang, fac3);
-
- if(v4) {
- /* 2nd tria, we use the V now */
- s1= uv3[0] - uv1[0];
- s2= uv4[0] - uv1[0];
- t1= uv3[1] - uv1[1];
- t2= uv4[1] - uv1[1];
- det= 1.0f / (s1 * t2 - s2 * t1);
-
- /* normals in render are inversed... */
- tang[0]= (t2 * (v1->co[0]-v3->co[0]) - t1 * (v1->co[0]-v4->co[0]));
- tang[1]= (t2 * (v1->co[1]-v3->co[1]) - t1 * (v1->co[1]-v4->co[1]));
- tang[2]= (t2 * (v1->co[2]-v3->co[2]) - t1 * (v1->co[2]-v4->co[2]));
-
- Normalise(tang);
-
- tav= RE_vertren_get_tangent(v1, 1);
- VECADDFAC(tav, tav, tang, fac1);
- tav= RE_vertren_get_tangent(v3, 1);
- VECADDFAC(tav, tav, tang, fac3);
- tav= RE_vertren_get_tangent(v4, 1);
- VECADDFAC(tav, tav, tang, fac4);
- }
- }
-}
-
-static void calc_vertexnormals(int startvert, int startvlak, int do_tangent)
-{
- int a;
-
- /* clear all vertex normals */
- for(a=startvert; a<R.totvert; a++) {
- VertRen *ver= RE_findOrAddVert(a);
- ver->n[0]=ver->n[1]=ver->n[2]= 0.0;
- }
-
- /* calculate cos of angles and point-masses, use as weight factor to
- add face normal to vertex */
- for(a=startvlak; a<R.totvlak; a++) {
- VlakRen *vlr= RE_findOrAddVlak(a);
- if(vlr->flag & ME_SMOOTH) {
- VertRen *adrve1= vlr->v1;
- VertRen *adrve2= vlr->v2;
- VertRen *adrve3= vlr->v3;
- VertRen *adrve4= vlr->v4;
- float n1[3], n2[3], n3[3], n4[3];
- float fac1, fac2, fac3, fac4=0.0f;
-
- VecSubf(n1, adrve2->co, adrve1->co);
- Normalise(n1);
- VecSubf(n2, adrve3->co, adrve2->co);
- Normalise(n2);
- if(adrve4==NULL) {
- VecSubf(n3, adrve1->co, adrve3->co);
- Normalise(n3);
-
- fac1= saacos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]);
- fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
- fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
- }
- else {
- VecSubf(n3, adrve4->co, adrve3->co);
- Normalise(n3);
- VecSubf(n4, adrve1->co, adrve4->co);
- Normalise(n4);
-
- fac1= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
- fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
- 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( contrpuntnormr(vlr->n, adrve4->n) ) fac4= -fac4;
- }
-
- adrve4->n[0] +=fac4*vlr->n[0];
- adrve4->n[1] +=fac4*vlr->n[1];
- adrve4->n[2] +=fac4*vlr->n[2];
- }
-
- if(!(vlr->flag & R_NOPUNOFLIP)) {
- if( contrpuntnormr(vlr->n, adrve1->n) ) fac1= -fac1;
- if( contrpuntnormr(vlr->n, adrve2->n) ) fac2= -fac2;
- if( contrpuntnormr(vlr->n, adrve3->n) ) fac3= -fac3;
- }
-
- adrve1->n[0] +=fac1*vlr->n[0];
- adrve1->n[1] +=fac1*vlr->n[1];
- adrve1->n[2] +=fac1*vlr->n[2];
-
- adrve2->n[0] +=fac2*vlr->n[0];
- adrve2->n[1] +=fac2*vlr->n[1];
- adrve2->n[2] +=fac2*vlr->n[2];
-
- adrve3->n[0] +=fac3*vlr->n[0];
- adrve3->n[1] +=fac3*vlr->n[1];
- adrve3->n[2] +=fac3*vlr->n[2];
-
- if(do_tangent)
- calc_tangent_vector(vlr, fac1, fac2, fac3, fac4);
- }
- }
-
- /* do solid faces */
- for(a=startvlak; a<R.totvlak; a++) {
- VlakRen *vlr= RE_findOrAddVlak(a);
- if((vlr->flag & ME_SMOOTH)==0) {
- float *f1= vlr->v1->n;
- if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
- f1= vlr->v2->n;
- if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
- f1= vlr->v3->n;
- if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
- if(vlr->v4) {
- f1= vlr->v4->n;
- if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
- }
- }
- }
-
- /* normalise vertex normals */
- for(a=startvert; a<R.totvert; a++) {
- VertRen *ver= RE_findOrAddVert(a);
- Normalise(ver->n);
- if(do_tangent) {
- float *tav= RE_vertren_get_tangent(ver, 0);
- if(tav) Normalise(tav);
- }
- }
-
- /* vertex normal (puno) switch flags for during render */
- for(a=startvlak; a<R.totvlak; a++) {
- VlakRen *vlr= RE_findOrAddVlak(a);
-
- if((vlr->flag & R_NOPUNOFLIP)==0) {
- VertRen *adrve1= vlr->v1;
- VertRen *adrve2= vlr->v2;
- VertRen *adrve3= vlr->v3;
- VertRen *adrve4= vlr->v4;
- vlr->puno &= ~15;
- if ((vlr->n[0]*adrve1->n[0]+vlr->n[1]*adrve1->n[1]+vlr->n[2]*adrve1->n[2])<0.0) vlr->puno= 1;
- if ((vlr->n[0]*adrve2->n[0]+vlr->n[1]*adrve2->n[1]+vlr->n[2]*adrve2->n[2])<0.0) vlr->puno+= 2;
- if ((vlr->n[0]*adrve3->n[0]+vlr->n[1]*adrve3->n[1]+vlr->n[2]*adrve3->n[2])<0.0) vlr->puno+= 4;
- if(adrve4) {
- if((vlr->n[0]*adrve4->n[0]+vlr->n[1]*adrve4->n[1]+vlr->n[2]*adrve4->n[2])<0.0) vlr->puno+= 8;
- }
- }
- }
-}
-
-/* ------------------------------------------------------------------------- */
-/* Autosmoothing: */
-/* ------------------------------------------------------------------------- */
-
-typedef struct ASvert {
- int totface;
- ListBase faces;
-} ASvert;
-
-typedef struct ASface {
- struct ASface *next, *prev;
- VlakRen *vlr[4];
- VertRen *nver[4];
-} ASface;
-
-static void as_addvert(ASvert *asv, VertRen *v1, VlakRen *vlr)
-{
- ASface *asf;
- int a;
-
- if(v1 == NULL) return;
-
- if(asv->faces.first==NULL) {
- asf= MEM_callocN(sizeof(ASface), "asface");
- BLI_addtail(&asv->faces, asf);
- }
-
- asf= asv->faces.last;
- for(a=0; a<4; a++) {
- if(asf->vlr[a]==NULL) {
- asf->vlr[a]= vlr;
- asv->totface++;
- break;
- }
- }
-
- /* new face struct */
- if(a==4) {
- asf= MEM_callocN(sizeof(ASface), "asface");
- BLI_addtail(&asv->faces, asf);
- asf->vlr[0]= vlr;
- asv->totface++;
- }
-}
-
-static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh)
-{
- /* return 1: vertex needs a copy */
- ASface *asf;
- float inp;
- int a;
-
- if(vlr==0) return 0;
-
- asf= asv->faces.first;
- while(asf) {
- for(a=0; a<4; a++) {
- if(asf->vlr[a] && asf->vlr[a]!=vlr) {
- inp= fabs( vlr->n[0]*asf->vlr[a]->n[0] + vlr->n[1]*asf->vlr[a]->n[1] + vlr->n[2]*asf->vlr[a]->n[2] );
- if(inp < thresh) return 1;
- }
- }
- asf= asf->next;
- }
-
- return 0;
-}
-
-static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh)
-{
- /* return when new vertex already was made */
- ASface *asf;
- float inp;
- int a;
-
- asf= asv->faces.first;
- while(asf) {
- for(a=0; a<4; a++) {
- if(asf->vlr[a] && asf->vlr[a]!=vlr) {
- /* this face already made a copy for this vertex! */
- if(asf->nver[a]) {
- inp= fabs( vlr->n[0]*asf->vlr[a]->n[0] + vlr->n[1]*asf->vlr[a]->n[1] + vlr->n[2]*asf->vlr[a]->n[2] );
- if(inp >= thresh) {
- return asf->nver[a];
- }
- }
- }
- }
- asf= asf->next;
- }
-
- return NULL;
-}
-
-static void autosmooth(int startvert, int startvlak, int degr)
-{
- ASvert *asv, *asverts, *asvertoffs;
- ASface *asf;
- VertRen *ver, *v1;
- VlakRen *vlr;
- float thresh;
- int a, b, totvert;
-
- if(startvert==R.totvert) return;
- asverts= MEM_callocN(sizeof(ASvert)*(R.totvert-startvert), "all smooth verts");
- asvertoffs= asverts-startvert; /* se we can use indices */
-
- thresh= cos( M_PI*((float)degr)/180.0 );
-
- /* step one: construct listbase of all vertices and pointers to faces */
- for(a=startvlak; a<R.totvlak; a++) {
- vlr= RE_findOrAddVlak(a);
-
- as_addvert(asvertoffs+vlr->v1->index, vlr->v1, vlr);
- as_addvert(asvertoffs+vlr->v2->index, vlr->v2, vlr);
- as_addvert(asvertoffs+vlr->v3->index, vlr->v3, vlr);
- if(vlr->v4)
- as_addvert(asvertoffs+vlr->v4->index, vlr->v4, vlr);
- }
-
- /* we now test all vertices, when faces have a normal too much different: they get a new vertex */
- totvert= R.totvert;
- for(a=startvert, asv=asverts; a<totvert; a++, asv++) {
- if(asv && asv->totface>1) {
- ver= RE_findOrAddVert(a);
-
- asf= asv->faces.first;
- while(asf) {
- for(b=0; b<4; b++) {
-
- /* is there a reason to make a new vertex? */
- vlr= asf->vlr[b];
- if( as_testvertex(vlr, ver, asv, thresh) ) {
-
- /* already made a new vertex within threshold? */
- v1= as_findvertex(vlr, ver, asv, thresh);
- if(v1==NULL) {
- /* make a new vertex */
- v1= RE_duplicate_vertren(ver);
- }
- asf->nver[b]= v1;
- if(vlr->v1==ver) vlr->v1= v1;
- if(vlr->v2==ver) vlr->v2= v1;
- if(vlr->v3==ver) vlr->v3= v1;
- if(vlr->v4==ver) vlr->v4= v1;
- }
- }
- asf= asf->next;
- }
- }
- }
-
- /* free */
- for(a=0; a<totvert-startvert; a++) {
- BLI_freelistN(&asverts[a].faces);
- }
- MEM_freeN(asverts);
-}
-
-/* ------------------------------------------------------------------------- */
-/* End of autosmoothing: */
-/* ------------------------------------------------------------------------- */
-
-/* ------------------------------------------------------------------------- */
-/* Orco hash */
-/* ------------------------------------------------------------------------- */
-
-
-static GHash *g_orco_hash = NULL;
-
-static float *get_object_orco(Object *ob)
-{
- float *orco;
-
- if (!g_orco_hash)
- g_orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
-
- orco = BLI_ghash_lookup(g_orco_hash, ob);
-
- if (!orco) {
- if (ob->type==OB_MESH) {
- orco = mesh_create_orco_render(ob);
- } else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
- orco = make_orco_curve(ob);
- } else if (ob->type==OB_SURF) {
- orco = make_orco_surf(ob);
- }
-
- if (orco)
- BLI_ghash_insert(g_orco_hash, ob, orco);
- }
-
- return orco;
-}
-static void free_mesh_orco_hash(void)
-{
- if (g_orco_hash) {
- BLI_ghash_free(g_orco_hash, NULL, (GHashValFreeFP)MEM_freeN);
- g_orco_hash = NULL;
- }
-}
-
-/* ******************** END ORCO HASH ***************** */
-
-
-static void make_render_halos(Object *ob, Mesh *me, int totvert, MVert *mvert, Material *ma, float *orco)
-{
- HaloRen *har;
- float xn, yn, zn, nor[3], view[3];
- float vec[3], hasize, mat[4][4], imat[3][3];
- int a, ok, seed= ma->seed1;
-
- MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
- MTC_Mat3CpyMat4(imat, ob->imat);
-
- R.flag |= R_HALO;
-
- for(a=0; a<totvert; a++, mvert++) {
- ok= 1;
-
- if(ok) {
- hasize= ma->hasize;
-
- VECCOPY(vec, mvert->co);
- MTC_Mat4MulVecfl(mat, vec);
-
- if(ma->mode & MA_HALOPUNO) {
- xn= mvert->no[0];
- yn= mvert->no[1];
- zn= mvert->no[2];
-
- /* transpose ! */
- nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
- nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
- nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
- Normalise(nor);
-
- VECCOPY(view, vec);
- Normalise(view);
-
- zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
- if(zn>=0.0) hasize= 0.0;
- else hasize*= zn*zn*zn*zn;
- }
-
- if(orco) har= RE_inithalo(ma, vec, NULL, orco, hasize, 0.0, seed);
- else har= RE_inithalo(ma, vec, NULL, mvert->co, hasize, 0.0, seed);
- if(har) har->lay= ob->lay;
- }
- if(orco) orco+= 3;
- seed++;
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
-
-static void render_particle_system(Object *ob, PartEff *paf)
-{
- Particle *pa=0;
- HaloRen *har=0;
- Material *ma=0;
- float xn, yn, zn, imat[3][3], tmat[4][4], mat[4][4], hasize, stime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
- int a, mat_nr=1, seed;
-
- pa= paf->keys;
- if(pa==NULL || paf->disp!=100) {
- build_particle_system(ob);
- pa= paf->keys;
- if(pa==NULL) return;
- }
-
- ma= give_render_material(ob, paf->omat);
-
- MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
- MTC_Mat4Invert(ob->imat, mat); /* this is correct, for imat texture */
-
- /* enable duplicators to work */
- Mat4MulMat4(tmat, paf->imat, ob->obmat);
- MTC_Mat4MulMat4(mat, tmat, R.viewmat);
-
- MTC_Mat4Invert(tmat, mat);
- MTC_Mat3CpyMat4(imat, tmat);
-
- R.flag |= R_HALO;
-
- if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
- else ptime= 0.0;
- ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, ptime);
- seed= ma->seed1;
-
- for(a=0; a<paf->totpart; a++, pa+=paf->totkey, seed++) {
-
- /* offset time for calculating normal */
- stime= ctime;
- ptime= ctime+1.0f;
- if(ctime < pa->time) {
- if(paf->flag & PAF_UNBORN)
- ptime= pa->time+1.0f;
- else
- continue;
- }
- if(ctime > pa->time+pa->lifetime) {
- if(paf->flag & PAF_DIED)
- stime= pa->time+pa->lifetime-1.0f;
- else
- continue;
- }
-
- /* watch it: also calculate the normal of a particle */
- if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) {
- where_is_particle(paf, pa, stime, vec);
- MTC_Mat4MulVecfl(mat, vec);
- where_is_particle(paf, pa, ptime, vec1);
- MTC_Mat4MulVecfl(mat, vec1);
- }
- else {
- where_is_particle(paf, pa, ctime, vec);
- MTC_Mat4MulVecfl(mat, vec);
- }
-
- if(pa->mat_nr != mat_nr) {
- mat_nr= pa->mat_nr;
- ma= give_render_material(ob, mat_nr);
- }
-
- if(ma->ipo) {
- /* correction for lifetime */
- ptime= 100.0*(ctime-pa->time)/pa->lifetime;
- calc_ipo(ma->ipo, ptime);
- execute_ipo((ID *)ma, ma->ipo);
- }
-
- hasize= ma->hasize;
-
- if(ma->mode & MA_HALOPUNO) {
- xn= pa->no[0];
- yn= pa->no[1];
- zn= pa->no[2];
-
- /* transpose ! */
- nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
- nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
- nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
- Normalise(nor);
-
- VECCOPY(view, vec);
- Normalise(view);
-
- zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
- if(zn>=0.0) hasize= 0.0;
- else hasize*= zn*zn*zn*zn;
- }
-
- if(paf->stype==PAF_VECT) har= RE_inithalo(ma, vec, vec1, pa->co, hasize, paf->vectsize, seed);
- else {
- har= RE_inithalo(ma, vec, NULL, pa->co, hasize, 0.0, seed);
- if(har && ma->mode & MA_HALO_SHADE) {
- VecSubf(har->no, vec, vec1);
- Normalise(har->no);
- }
- }
- if(har) har->lay= ob->lay;
- }
-
- /* restore material */
- for(a=1; a<=ob->totcol; a++) {
- ma= give_render_material(ob, a);
- if(ma) do_mat_ipo(ma);
- }
-
- if(paf->disp!=100) {
- MEM_freeN(paf->keys);
- paf->keys= NULL;
- }
-}
-
-
-/* ------------------------------------------------------------------------- */
-
-/* old call... for when duplicators were using temporal objects */
-static Object *vlr_set_ob(Object *ob)
-{
- return ob;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void static_particle_strand(Object *ob, Material *ma, float *orco, float *vec, float *vec1, float ctime, int first)
-{
- static VertRen *v1= NULL, *v2= NULL;
- VlakRen *vlr;
- float nor[3], cross[3], w, dx, dy;
- int flag;
-
- VecSubf(nor, vec, vec1);
- Normalise(nor); // nor needed as tangent
- Crossf(cross, vec, nor);
-
- /* turn cross in pixelsize */
- w= vec[2]*R.winmat[2][3] + R.winmat[3][3];
- dx= R.rectx*cross[0]*R.winmat[0][0]/w;
- dy= R.recty*cross[1]*R.winmat[1][1]/w;
- w= sqrt(dx*dx + dy*dy);
- if(w!=0.0f) {
- float fac;
- if(ma->strand_ease!=0.0f) {
- if(ma->strand_ease<0.0f)
- fac= pow(ctime, 1.0+ma->strand_ease);
- else
- fac= pow(ctime, 1.0/(1.0f-ma->strand_ease));
- }
- else fac= ctime;
-
- VecMulf(cross, ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end)/w);
- }
-
- if(ma->mode & MA_TANGENT_STR)
- flag= R_SMOOTH|R_NOPUNOFLIP|R_STRAND|R_TANGENT;
- else
- flag= R_SMOOTH|R_STRAND;
-
- /* first two vertices */
- if(first) {
- v1= RE_findOrAddVert(R.totvert++);
- v2= RE_findOrAddVert(R.totvert++);
-
- VECCOPY(v1->co, vec);
- VecAddf(v1->co, v1->co, cross);
- VECCOPY(v1->n, nor);
- v1->orco= orco;
- v1->accum= -1.0f; // accum abuse for strand texco
-
- VECCOPY(v2->co, vec);
- VecSubf(v2->co, v2->co, cross);
- VECCOPY(v2->n, nor);
- v2->orco= orco;
- v2->accum= v1->accum;
- }
- else {
-
- vlr= RE_findOrAddVlak(R.totvlak++);
- vlr->flag= flag;
- vlr->ob= vlr_set_ob(ob);
- vlr->v1= v1;
- vlr->v2= v2;
- vlr->v3= RE_findOrAddVert(R.totvert++);
- vlr->v4= RE_findOrAddVert(R.totvert++);
-
- v1= vlr->v4; // cycle
- v2= vlr->v3; // cycle
-
- VECCOPY(vlr->v4->co, vec);
- VecAddf(vlr->v4->co, vlr->v4->co, cross);
- VECCOPY(vlr->v4->n, nor);
- vlr->v4->orco= orco;
- vlr->v4->accum= -1.0f + 2.0f*ctime; // accum abuse for strand texco
-
- VECCOPY(vlr->v3->co, vec);
- VecSubf(vlr->v3->co, vlr->v3->co, cross);
- VECCOPY(vlr->v3->n, nor);
- vlr->v3->orco= orco;
- vlr->v3->accum= vlr->v4->accum;
-
- CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
-
- vlr->mat= ma;
- vlr->ec= ME_V2V3;
- vlr->lay= ob->lay;
- }
-}
-
-static void render_static_particle_system(Object *ob, PartEff *paf)
-{
- Particle *pa=0;
- HaloRen *har=0;
- Material *ma=0;
- VertRen *v1= NULL, *v2= NULL;
- VlakRen *vlr;
- float xn, yn, zn, imat[3][3], mat[4][4], hasize;
- float mtime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
- float *orco= NULL, loc_tex[3], size_tex[3];
- int a, mat_nr=1, seed, totvlako, totverto, first;
-
- pa= paf->keys;
- if(pa==NULL || (paf->flag & PAF_ANIMATED) || paf->disp!=100) {
- build_particle_system(ob);
- pa= paf->keys;
- if(pa==NULL) return;
- }
-
- totvlako= R.totvlak;
- totverto= R.totvert;
-
- ma= give_render_material(ob, paf->omat);
- if(ma->mode & MA_HALO)
- R.flag |= R_HALO;
-
- MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
- MTC_Mat4Invert(ob->imat, mat); /* need to be that way, for imat texture */
-
- MTC_Mat3CpyMat4(imat, ob->imat);
-
- /* orcos */
- if(!(ma->mode & (MA_HALO|MA_WIRE))) {
- orco= MEM_mallocN(3*sizeof(float)*paf->totpart, "static particle orcos");
- if (!g_orco_hash)
- g_orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
- BLI_ghash_insert(g_orco_hash, paf, orco); /* pointer is particles, otherwise object uses it */
- }
-
- mesh_get_texspace(ob->data, loc_tex, NULL, size_tex);
-
- if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
- else ptime= 0.0;
- ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, ptime);
- seed= ma->seed1;
-
- for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
-
- where_is_particle(paf, pa, pa->time, vec1);
- if(orco) {
- orco[0] = (vec1[0]-loc_tex[0])/size_tex[0];
- orco[1] = (vec1[1]-loc_tex[1])/size_tex[1];
- orco[2] = (vec1[2]-loc_tex[2])/size_tex[2];
- }
- MTC_Mat4MulVecfl(mat, vec1);
- mtime= pa->time+pa->lifetime+paf->staticstep-1;
-
- first= 1;
- for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
-
- /* make sure hair grows until the end.. */
- if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
-
- /* watch it: also calc the normal of a particle */
- if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) {
- where_is_particle(paf, pa, ctime+1.0, vec);
- MTC_Mat4MulVecfl(mat, vec);
- }
- else {
- where_is_particle(paf, pa, ctime, vec);
- MTC_Mat4MulVecfl(mat, vec);
- }
-
- if(pa->mat_nr != mat_nr) {
- mat_nr= pa->mat_nr;
- ma= give_render_material(ob, mat_nr);
- }
-
- /* wires */
- if(ma->mode & MA_WIRE) {
- if(ctime == pa->time) {
- v1= RE_findOrAddVert(R.totvert++);
- VECCOPY(v1->co, vec);
- }
- else {
- vlr= RE_findOrAddVlak(R.totvlak++);
- vlr->ob= vlr_set_ob(ob);
- vlr->v1= v1;
- vlr->v2= RE_findOrAddVert(R.totvert++);
- vlr->v3= vlr->v2;
- vlr->v4= NULL;
-
- v1= vlr->v2; // cycle
- VECCOPY(v1->co, vec);
-
- VecSubf(vlr->n, vec, vec1);
- Normalise(vlr->n);
- VECCOPY(v1->n, vlr->n);
-
- vlr->mat= ma;
- vlr->ec= ME_V1V2;
- vlr->lay= ob->lay;
- }
- }
- else {
- if(ma->ipo) {
- /* correction for lifetime */
- ptime= 100.0*(ctime-pa->time)/pa->lifetime;
- calc_ipo(ma->ipo, ptime);
- execute_ipo((ID *)ma, ma->ipo);
- }
-
- if(ma->mode & MA_HALO) {
- hasize= ma->hasize;
-
- if(ma->mode & MA_HALOPUNO) {
- xn= pa->no[0];
- yn= pa->no[1];
- zn= pa->no[2];
-
- /* transpose ! */
- nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
- nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
- nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
- Normalise(nor);
-
- VECCOPY(view, vec);
- Normalise(view);
-
- zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
- if(zn>=0.0) hasize= 0.0;
- else hasize*= zn*zn*zn*zn;
- }
-
- if(paf->stype==PAF_VECT) har= RE_inithalo(ma, vec, vec1, pa->co, hasize, paf->vectsize, seed);
- else {
- har= RE_inithalo(ma, vec, NULL, pa->co, hasize, 0.0, seed);
- if(har && (ma->mode & MA_HALO_SHADE)) {
- VecSubf(har->no, vec, vec1);
- Normalise(har->no);
- har->lay= ob->lay;
- }
- }
- if(har) har->lay= ob->lay;
- }
- else { /* generate pixel sized hair strand */
- static_particle_strand(ob, ma, orco, vec, vec1, (ctime-pa->time)/(mtime-pa->time), first);
- }
- }
-
- VECCOPY(vec1, vec);
- first= 0;
- }
-
- seed++;
- if(orco) orco+=3;
- }
-
- if(paf->disp!=100) {
- MEM_freeN(paf->keys);
- paf->keys= NULL;
- }
-
- if((ma->mode & MA_TANGENT_STR)==0)
- calc_vertexnormals(totverto, totvlako, 0);
-}
-
-
-/* ------------------------------------------------------------------------- */
-
-static int verghalo(const void *a1, const void *a2)
-{
- const struct halosort *x1=a1, *x2=a2;
-
- if( x1->z < x2->z ) return 1;
- else if( x1->z > x2->z) return -1;
- return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-extern int rblohalen;
-static void sort_halos(void)
-{
- struct halosort *hablock, *haso;
- HaloRen *har = NULL, **bloha;
- int a;
-
- if(R.tothalo==0) return;
-
- /* make datablock with halo pointers, sort */
- haso= hablock= MEM_mallocN(sizeof(struct halosort)*R.tothalo, "hablock");
-
- for(a=0; a<R.tothalo; a++) {
- if((a & 255)==0) har= R.bloha[a>>8];
- else har++;
- haso->har= har;
- haso->z= har->zs;
- haso++;
- }
-
- qsort(hablock, R.tothalo, sizeof(struct halosort), verghalo);
-
- /* re-assamble R.bloha */
-
- bloha= R.bloha;
- R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(rblohalen),"Bloha");
-
- haso= hablock;
- for(a=0; a<R.tothalo; a++) {
- har= RE_findOrAddHalo(a);
- *har= *(haso->har);
-
- haso++;
- }
-
- /* free */
- a= 0;
- while(bloha[a]) {
- MEM_freeN(bloha[a]);
- a++;
- }
- MEM_freeN(bloha);
- MEM_freeN(hablock);
-
-}
-
-
-
-static Material *give_render_material(Object *ob, int nr)
-{
- extern Material defmaterial; // initrender.c
- Object *temp;
- Material *ma;
-
- ma= give_current_material(ob, nr);
- if(ma==NULL) ma= &defmaterial;
-
- return ma;
-}
-
-/* ------------------------------------------------------------------------- */
-static void init_render_mball(Object *ob)
-{
- DispList *dl, *dlo;
- VertRen *ver;
- VlakRen *vlr, *vlr1;
- Material *ma;
- float *data, *nors, mat[4][4], imat[3][3], xn, yn, zn;
- int a, need_orco, startvert, *index;
-
- if (ob!=find_basis_mball(ob))
- return;
-
- MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
- MTC_Mat4Invert(ob->imat, mat);
- MTC_Mat3CpyMat4(imat, ob->imat);
-
- ma= give_render_material(ob, 1);
-
- need_orco= 0;
- if(ma->texco & TEXCO_ORCO) {
- need_orco= 1;
- }
-
- dlo= ob->disp.first;
- if(dlo) BLI_remlink(&ob->disp, dlo);
-
- makeDispListMBall(ob);
- dl= ob->disp.first;
- if(dl==0) return;
-
- startvert= R.totvert;
- data= dl->verts;
- nors= dl->nors;
-
- for(a=0; a<dl->nr; a++, data+=3, nors+=3) {
-
- ver= RE_findOrAddVert(R.totvert++);
- VECCOPY(ver->co, data);
- MTC_Mat4MulVecfl(mat, ver->co);
-
- xn= nors[0];
- yn= nors[1];
- zn= nors[2];
-
- /* transpose ! */
- ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
- ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
- ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
- Normalise(ver->n);
- //if(ob->transflag & OB_NEG_SCALE) VecMulf(ver->n. -1.0);
-
- if(need_orco) ver->orco= data;
- }
-
- index= dl->index;
- for(a=0; a<dl->parts; a++, index+=4) {
-
- vlr= RE_findOrAddVlak(R.totvlak++);
- vlr->ob= vlr_set_ob(ob);
- vlr->v1= RE_findOrAddVert(startvert+index[0]);
- vlr->v2= RE_findOrAddVert(startvert+index[1]);
- vlr->v3= RE_findOrAddVert(startvert+index[2]);
- vlr->v4= 0;
-
- if(ob->transflag & OB_NEG_SCALE)
- CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
- else
- CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
-
- vlr->mat= ma;
- vlr->flag= ME_SMOOTH+R_NOPUNOFLIP;
- vlr->ec= 0;
- vlr->lay= ob->lay;
-
- /* mball -too bad- always has triangles, because quads can be non-planar */
- if(index[3]) {
- vlr1= RE_findOrAddVlak(R.totvlak++);
- *vlr1= *vlr;
- vlr1->v2= vlr1->v3;
- vlr1->v3= RE_findOrAddVert(startvert+index[3]);
- if(ob->transflag & OB_NEG_SCALE)
- CalcNormFloat(vlr1->v1->co, vlr1->v2->co, vlr1->v3->co, vlr1->n);
- else
- CalcNormFloat(vlr1->v3->co, vlr1->v2->co, vlr1->v1->co, vlr1->n);
- }
- }
-
- if(need_orco) {
- /* store displist and scale */
- make_orco_mball(ob);
- if(dlo) BLI_addhead(&ob->disp, dlo);
-
- }
- else {
- freedisplist(&ob->disp);
- if(dlo) BLI_addtail(&ob->disp, dlo);
- }
-}
-/* ------------------------------------------------------------------------- */
-/* convert */
-
-struct edgesort {
- int v1, v2;
- int has_mcol;
- TFace *tface;
- float uv1[2], uv2[2];
- unsigned int mcol1, mcol2;
-};
-
-/* edges have to be added with lowest index first for sorting */
-static void to_edgesort(struct edgesort *ed, int i1, int i2, int v1, int v2, unsigned int *mcol, TFace *tface)
-{
- if(v1<v2) {
- ed->v1= v1; ed->v2= v2;
- }
- else {
- ed->v1= v2; ed->v2= v1;
- SWAP(int, i1, i2);
- }
- /* copy color and tface, edges use different ordering */
- ed->tface= tface;
- if(tface) {
- ed->uv1[0]= tface->uv[i1][0];
- ed->uv1[1]= tface->uv[i1][1];
- ed->uv2[0]= tface->uv[i2][0];
- ed->uv2[1]= tface->uv[i2][1];
-
- ed->mcol1= tface->col[i1];
- ed->mcol2= tface->col[i2];
- }
- ed->has_mcol= mcol!=NULL;
- if(mcol) {
- ed->mcol1= mcol[i1];
- ed->mcol2= mcol[i2];
- }
-}
-
-static int vergedgesort(const void *v1, const void *v2)
-{
- const struct edgesort *x1=v1, *x2=v2;
-
- if( x1->v1 > x2->v1) return 1;
- else if( x1->v1 < x2->v1) return -1;
- else if( x1->v2 > x2->v2) return 1;
- else if( x1->v2 < x2->v2) return -1;
-
- return 0;
-}
-
-static struct edgesort *make_mesh_edge_lookup(Mesh *me, DispListMesh *dlm, int *totedgesort)
-{
- MFace *mf, *mface;
- TFace *tface=NULL;
- struct edgesort *edsort, *ed;
- unsigned int *mcol=NULL;
- int a, totedge=0, totface;
-
- if (dlm) {
- mface= dlm->mface;
- totface= dlm->totface;
- if (dlm->tface)
- tface= dlm->tface;
- else if (dlm->mcol)
- mcol= (unsigned int *)dlm->mcol;
- } else {
- mface= me->mface;
- totface= me->totface;
- if (me->tface)
- tface= me->tface;
- else if (me->mcol)
- mcol= (unsigned int *)me->mcol;
- }
-
- if(mcol==NULL && tface==NULL) return NULL;
-
- /* make sorted table with edges and and tface/mcol pointers in it */
- for(a= totface, mf= mface; a>0; a--, mf++) {
- if(mf->v4) totedge+=4;
- else if(mf->v3) totedge+=3;
- }
- if(totedge==0) return NULL;
-
- ed= edsort= MEM_mallocN(totedge*sizeof(struct edgesort), "edgesort");
-
- for(a= me->totface, mf= mface; a>0; a--, mf++) {
- if(mface->v4 || mface->v3) {
- to_edgesort(ed++, 0, 1, mf->v1, mf->v2, mcol, tface);
- to_edgesort(ed++, 1, 2, mf->v2, mf->v3, mcol, tface);
- if(mf->v4) {
- to_edgesort(ed++, 2, 3, mf->v3, mf->v4, mcol, tface);
- to_edgesort(ed++, 3, 0, mf->v4, mf->v1, mcol, tface);
- }
- else if(mf->v3) {
- to_edgesort(ed++, 2, 3, mf->v3, mf->v1, mcol, tface);
- }
- }
- if(mcol) mcol+=4;
- if(tface) tface++;
- }
-
- qsort(edsort, totedge, sizeof(struct edgesort), vergedgesort);
-
- *totedgesort= totedge;
- return edsort;
-}
-
-static void use_mesh_edge_lookup(Mesh *me, DispListMesh *dlm, MEdge *medge, VlakRen *vlr, struct edgesort *edgetable, int totedge)
-{
- struct edgesort ed, *edp;
-
- if(medge->v1 < medge->v2) {
- ed.v1= medge->v1; ed.v2= medge->v2;
- }
- else {
- ed.v1= medge->v2; ed.v2= medge->v1;
- }
-
- edp= bsearch(&ed, edgetable, totedge, sizeof(struct edgesort), vergedgesort);
- if(edp) {
- /* since edges have different index ordering, we have to duplicate mcol and tface */
- if(edp->tface) {
- vlr->tface= BLI_memarena_alloc(R.memArena, sizeof(TFace));
- vlr->vcol= vlr->tface->col;
- memcpy(vlr->tface, edp->tface, sizeof(TFace));
-
- if(edp->v1==medge->v1) {
- vlr->vcol[0]= edp->mcol1;
- vlr->vcol[1]= edp->mcol2;
- }
- else {
- vlr->vcol[0]= edp->mcol2;
- vlr->vcol[1]= edp->mcol1;
- }
- vlr->vcol[2]= vlr->vcol[1];
- vlr->vcol[3]= vlr->vcol[1];
-
- if(edp->v1==medge->v1) {
- memcpy(vlr->tface->uv[0], edp->uv1, 2*sizeof(float));
- memcpy(vlr->tface->uv[1], edp->uv2, 2*sizeof(float));
- }
- else {
- memcpy(vlr->tface->uv[0], edp->uv2, 2*sizeof(float));
- memcpy(vlr->tface->uv[1], edp->uv1, 2*sizeof(float));
- }
- memcpy(vlr->tface->uv[2], vlr->tface->uv[1], 2*sizeof(float));
- memcpy(vlr->tface->uv[3], vlr->tface->uv[1], 2*sizeof(float));
- }
- else if(edp->has_mcol) {
- vlr->vcol= BLI_memarena_alloc(R.memArena, sizeof(MCol)*4);
- vlr->vcol[0]= edp->mcol1;
- vlr->vcol[1]= edp->mcol2;
- vlr->vcol[2]= vlr->vcol[1];
- vlr->vcol[3]= vlr->vcol[1];
- }
- }
-}
-
-static void init_render_mesh(Object *ob)
-{
- Mesh *me;
- MVert *mvert = NULL;
- MFace *mface;
- VlakRen *vlr; //, *vlr1;
- VertRen *ver;
- Material *ma;
- MSticky *ms = NULL;
- PartEff *paf;
- DispListMesh *dlm = NULL;
- DerivedMesh *dm;
- unsigned int *vertcol;
- float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
- float *orco=0;
- int a, a1, ok, need_orco=0, need_stress=0, need_tangent=0, totvlako, totverto, vertofs;
- int end, do_autosmooth=0, totvert = 0, dm_needsfree;
-
- me= ob->data;
-
- paf = give_parteff(ob);
- if(paf) {
- /* warning; build_particle_system does modifier calls itself */
- if(paf->flag & PAF_STATIC) render_static_particle_system(ob, paf);
- else render_particle_system(ob, paf);
- if((paf->flag & PAF_SHOWE)==0) return;
- }
-
- MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
- MTC_Mat4Invert(ob->imat, mat);
- MTC_Mat3CpyMat4(imat, ob->imat);
-
- if(me->totvert==0) {
- return;
- }
-
- totvlako= R.totvlak;
- totverto= R.totvert;
-
- need_orco= 0;
- for(a=1; a<=ob->totcol; a++) {
- ma= give_render_material(ob, a);
- if(ma) {
- if(ma->texco & (TEXCO_ORCO|TEXCO_STRESS))
- need_orco= 1;
- if(ma->texco & TEXCO_STRESS)
- need_stress= 1;
- if(ma->mode & MA_TANGENT_V)
- need_tangent= 1;
- }
- }
-
- if(need_orco) orco = get_object_orco(ob);
-
- dm = mesh_create_derived_render(ob);
- dm_needsfree= 1;
-
- if(dm==NULL) return; /* in case duplicated object fails? */
-
- dlm = dm->convertToDispListMesh(dm, 1);
-
- mvert= dlm->mvert;
- totvert= dlm->totvert;
-
- ms = (totvert==me->totvert)?me->msticky:NULL;
-
- ma= give_render_material(ob, 1);
-
- if(ma->mode & MA_HALO) {
- make_render_halos(ob, me, totvert, mvert, ma, orco);
- }
- else {
-
- for(a=0; a<totvert; a++, mvert++) {
- ver= RE_findOrAddVert(R.totvert++);
- VECCOPY(ver->co, mvert->co);
- MTC_Mat4MulVecfl(mat, ver->co);
-
- if(orco) {
- ver->orco= orco;
- orco+=3;
- }
- if(ms) {
- float *sticky= RE_vertren_get_sticky(ver, 1);
- sticky[0]= ms->co[0];
- sticky[1]= ms->co[1];
- ms++;
- }
- }
- /* still to do for keys: the correct local texture coordinate */
-
- /* faces in order of color blocks */
- vertofs= R.totvert - totvert;
- for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
-
- ma= give_render_material(ob, a1+1);
-
- /* test for 100% transparant */
- ok= 1;
- if(ma->alpha==0.0 && ma->spectra==0.0) {
- ok= 0;
- /* texture on transparency? */
- for(a=0; a<MAX_MTEX; a++) {
- if(ma->mtex[a] && ma->mtex[a]->tex) {
- if(ma->mtex[a]->mapto & MAP_ALPHA) ok= 1;
- }
- }
- }
-
- /* if wire material, and we got edges, don't do the faces */
- if(ma->mode & MA_WIRE) {
- end= dlm?dlm->totedge:me->totedge;
- if(end) ok= 0;
- }
-
- if(ok) {
- TFace *tface= NULL;
-
- /* radio faces need autosmooth, to separate shared vertices in corners */
- if(R.r.mode & R_RADIO)
- if(ma->mode & MA_RADIO)
- do_autosmooth= 1;
-
- end= dlm?dlm->totface:me->totface;
- if (dlm) {
- mface= dlm->mface;
- if (dlm->tface) {
- tface= dlm->tface;
- vertcol= NULL;
- } else if (dlm->mcol) {
- vertcol= (unsigned int *)dlm->mcol;
- } else {
- vertcol= NULL;
- }
- } else {
- mface= me->mface;
- if (me->tface) {
- tface= me->tface;
- vertcol= NULL;
- } else if (me->mcol) {
- vertcol= (unsigned int *)me->mcol;
- } else {
- vertcol= NULL;
- }
- }
-
- for(a=0; a<end; a++) {
- int v1, v2, v3, v4, flag;
-
- if( mface->mat_nr==a1 ) {
- float len;
-
- v1= mface->v1;
- v2= mface->v2;
- v3= mface->v3;
- v4= mface->v4;
- flag= mface->flag & ME_SMOOTH;
-
- vlr= RE_findOrAddVlak(R.totvlak++);
- vlr->ob= vlr_set_ob(ob);
- vlr->v1= RE_findOrAddVert(vertofs+v1);
- vlr->v2= RE_findOrAddVert(vertofs+v2);
- vlr->v3= RE_findOrAddVert(vertofs+v3);
- if(v4) vlr->v4= RE_findOrAddVert(vertofs+v4);
- else vlr->v4= 0;
-
- /* render normals are inverted in render */
- if(vlr->v4) len= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co,
- vlr->v1->co, vlr->n);
- else len= CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co,
- vlr->n);
-
- vlr->mat= ma;
- vlr->flag= flag;
- if((me->flag & ME_NOPUNOFLIP) ) {
- vlr->flag |= R_NOPUNOFLIP;
- }
- vlr->ec= 0; /* mesh edges rendered separately */
- vlr->lay= ob->lay;
-
- if(len==0) R.totvlak--;
- else {
- if(dlm) {
- if(tface) {
- vlr->tface= BLI_memarena_alloc(R.memArena, sizeof(TFace));
- vlr->vcol= vlr->tface->col;
- memcpy(vlr->tface, tface, sizeof(TFace));
- }
- else if (vertcol) {
- vlr->vcol= BLI_memarena_alloc(R.memArena, sizeof(int)*4);
- memcpy(vlr->vcol, vertcol+4*a, sizeof(int)*4);
- }
- } else {
- if(tface) {
- vlr->vcol= tface->col;
- vlr->tface= tface;
- }
- else if (vertcol) {
- vlr->vcol= vertcol+4*a;
- }
- }
- }
- }
-
- mface++;
- if(tface) tface++;
- }
- }
- }
-
- /* exception... we do edges for wire mode. potential conflict when faces exist... */
- end= dlm?dlm->totedge:me->totedge;
- mvert= dlm?dlm->mvert:me->mvert;
- ma= give_render_material(ob, 1);
- if(end && (ma->mode & MA_WIRE)) {
- MEdge *medge;
- struct edgesort *edgetable;
- int totedge;
-
- medge= dlm?dlm->medge:me->medge;
-
- /* we want edges to have UV and vcol too... */
- edgetable= make_mesh_edge_lookup(me, dlm, &totedge);
-
- for(a1=0; a1<end; a1++, medge++) {
- if (medge->flag&ME_EDGERENDER) {
- MVert *v0 = &mvert[medge->v1];
- MVert *v1 = &mvert[medge->v2];
-
- vlr= RE_findOrAddVlak(R.totvlak++);
- vlr->ob= vlr_set_ob(ob);
- vlr->v1= RE_findOrAddVert(vertofs+medge->v1);
- vlr->v2= RE_findOrAddVert(vertofs+medge->v2);
- vlr->v3= vlr->v2;
- vlr->v4= NULL;
-
- if(edgetable) {
- use_mesh_edge_lookup(me, dlm, medge, vlr, edgetable, totedge);
- }
-
- xn= (v0->no[0]+v1->no[0]);
- yn= (v0->no[1]+v1->no[1]);
- zn= (v0->no[2]+v1->no[2]);
- /* transpose ! */
- vlr->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
- vlr->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
- vlr->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
- Normalise(vlr->n);
-
- vlr->mat= ma;
- vlr->flag= 0;
- vlr->ec= ME_V1V2;
- vlr->lay= ob->lay;
- }
- }
- if(edgetable)
- MEM_freeN(edgetable);
- }
- }
-
- if (test_for_displace( ob ) ) {
- calc_vertexnormals(totverto, totvlako, 0);
- do_displacement(ob, totvlako, R.totvlak-totvlako, totverto, R.totvert-totverto);
- }
-
- if(do_autosmooth || (me->flag & ME_AUTOSMOOTH)) {
- autosmooth(totverto, totvlako, me->smoothresh);
- }
-
- calc_vertexnormals(totverto, totvlako, need_tangent);
-
- if(need_stress)
- calc_edge_stress(me, totverto, totvlako);
-
- if(dlm) displistmesh_free(dlm);
- if(dm_needsfree) dm->release(dm);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void area_lamp_vectors(LampRen *lar)
-{
- float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey;
-
- /* corner vectors */
- lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
- lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
- lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
-
- /* corner vectors */
- lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
- lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
- lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
-
- /* corner vectors */
- lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
- lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
- lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
-
- /* corner vectors */
- lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
- lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
- lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
- /* only for correction button size, matrix size works on energy */
- lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize);
-}
-
-/* If lar takes more lamp data, the decoupling will be better. */
-void RE_add_render_lamp(Object *ob, int actual_render)
-{
- Lamp *la= ob->data;
- LampRen *lar;
- GroupObject *go;
- float mat[4][4], hoek, xn, yn;
- int c;
-
- /* prevent only shadow from rendering light, but only return on render, not preview */
- if(actual_render) {
- if(la->mode & LA_ONLYSHADOW)
- if((R.r.mode & R_SHADOW)==0)
- return;
- }
-
- go= MEM_callocN(sizeof(GroupObject), "groupobject");
- BLI_addtail(&R.lights, go);
- R.totlamp++;
- lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren");
- go->lampren= lar;
- go->ob= ob;
-
- MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
- MTC_Mat4Invert(ob->imat, mat);
-
- MTC_Mat3CpyMat4(lar->mat, mat);
- MTC_Mat3CpyMat4(lar->imat, ob->imat);
-
- lar->bufsize = la->bufsize;
- lar->samp = la->samp;
- lar->soft = la->soft;
- lar->shadhalostep = la->shadhalostep;
- lar->clipsta = la->clipsta;
- lar->clipend = la->clipend;
- lar->bias = la->bias;
-
- lar->type= la->type;
- lar->mode= la->mode;
-
- lar->energy= la->energy;
- lar->energy= la->energy;
- if(la->mode & LA_NEG) lar->energy= -lar->energy;
-
- lar->vec[0]= -mat[2][0];
- lar->vec[1]= -mat[2][1];
- lar->vec[2]= -mat[2][2];
- Normalise(lar->vec);
- lar->co[0]= mat[3][0];
- lar->co[1]= mat[3][1];
- lar->co[2]= mat[3][2];
- lar->dist= la->dist;
- lar->haint= la->haint;
- lar->distkw= lar->dist*lar->dist;
- lar->r= lar->energy*la->r;
- lar->g= lar->energy*la->g;
- lar->b= lar->energy*la->b;
- lar->k= la->k;
-
- // area
- lar->ray_samp= la->ray_samp;
- lar->ray_sampy= la->ray_sampy;
- lar->ray_sampz= la->ray_sampz;
-
- lar->area_size= la->area_size;
- lar->area_sizey= la->area_sizey;
- lar->area_sizez= la->area_sizez;
-
- lar->area_shape= la->area_shape;
- lar->ray_samp_type= la->ray_samp_type;
-
- if(lar->type==LA_AREA) {
- switch(lar->area_shape) {
- case LA_AREA_SQUARE:
- lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
- lar->ray_sampy= lar->ray_samp;
- lar->area_sizey= lar->area_size;
- break;
- case LA_AREA_RECT:
- lar->ray_totsamp= lar->ray_samp*lar->ray_sampy;
- break;
- case LA_AREA_CUBE:
- lar->ray_totsamp= lar->ray_samp*lar->ray_samp*lar->ray_samp;
- lar->ray_sampy= lar->ray_samp;
- lar->ray_sampz= lar->ray_samp;
- lar->area_sizey= lar->area_size;
- lar->area_sizez= lar->area_size;
- break;
- case LA_AREA_BOX:
- lar->ray_totsamp= lar->ray_samp*lar->ray_sampy*lar->ray_sampz;
- break;
- }
-
- area_lamp_vectors(lar);
- }
- else lar->ray_totsamp= 0;
-
- /* yafray: photonlight and other params */
- if (R.r.renderer==R_YAFRAY) {
- lar->YF_numphotons = la->YF_numphotons;
- lar->YF_numsearch = la->YF_numsearch;
- lar->YF_phdepth = la->YF_phdepth;
- lar->YF_useqmc = la->YF_useqmc;
- lar->YF_causticblur = la->YF_causticblur;
- lar->YF_ltradius = la->YF_ltradius;
- lar->YF_bufsize = la->YF_bufsize;
- lar->YF_glowint = la->YF_glowint;
- lar->YF_glowofs = la->YF_glowofs;
- lar->YF_glowtype = la->YF_glowtype;
- }
-
- lar->spotsi= la->spotsize;
- if(lar->mode & LA_HALO) {
- if(lar->spotsi>170.0) lar->spotsi= 170.0;
- }
- lar->spotsi= cos( M_PI*lar->spotsi/360.0 );
- lar->spotbl= (1.0-lar->spotsi)*la->spotblend;
-
- memcpy(lar->mtex, la->mtex, MAX_MTEX*sizeof(void *));
-
- lar->lay= ob->lay & 0xFFFFFF; // higher 8 bits are localview layers
-
- lar->ld1= la->att1;
- lar->ld2= la->att2;
-
- if(lar->type==LA_SPOT) {
-
- Normalise(lar->imat[0]);
- Normalise(lar->imat[1]);
- Normalise(lar->imat[2]);
-
- xn= saacos(lar->spotsi);
- xn= sin(xn)/cos(xn);
- lar->spottexfac= 1.0/(xn);
-
- if(lar->mode & LA_ONLYSHADOW) {
- if((lar->mode & (LA_SHAD|LA_SHAD_RAY))==0) lar->mode -= LA_ONLYSHADOW;
- }
-
- }
-
- /* set flag for spothalo en initvars */
- if(la->type==LA_SPOT && (la->mode & LA_HALO)) {
- if(la->haint>0.0) {
- R.flag |= R_LAMPHALO;
-
- /* camera position (0,0,0) rotate around lamp */
- lar->sh_invcampos[0]= -lar->co[0];
- lar->sh_invcampos[1]= -lar->co[1];
- lar->sh_invcampos[2]= -lar->co[2];
- MTC_Mat3MulVecfl(lar->imat, lar->sh_invcampos);
-
- /* z factor, for a normalized volume */
- hoek= saacos(lar->spotsi);
- xn= lar->spotsi;
- yn= sin(hoek);
- lar->sh_zfac= yn/xn;
- /* pre-scale */
- lar->sh_invcampos[2]*= lar->sh_zfac;
-
- }
- }
-
- for(c=0; c<MAX_MTEX; c++) {
- if(la->mtex[c] && la->mtex[c]->tex) {
- lar->mode |= LA_TEXTURE;
-
- if(R.flag & R_RENDERING) {
- if(R.osa) {
- if(la->mtex[c]->tex->type==TEX_IMAGE) lar->mode |= LA_OSATEX;
- }
- }
- }
- }
-
- /* yafray: shadowbuffers and jitter only needed for internal render */
- if (actual_render && R.r.renderer==R_INTERN) {
- if(R.r.mode & R_SHADOW) {
- if (la->type==LA_SPOT && (lar->mode & LA_SHAD) ) {
- /* Per lamp, one shadow buffer is made. */
- Mat4CpyMat4(mat, ob->obmat);
- RE_initshadowbuf(lar, mat); // mat is altered
- }
- else if(la->type==LA_AREA && (lar->mode & LA_SHAD_RAY) ) {
- init_jitter_plane(lar);
- }
- }
- }
-
- /* yafray: shadow flag should not be cleared, only used with internal renderer */
- if (R.r.renderer==R_INTERN) {
- /* to make sure we can check ray shadow easily in the render code */
- if(lar->mode & LA_SHAD_RAY) {
- if( (R.r.mode & R_RAYTRACE)==0)
- lar->mode &= ~LA_SHAD_RAY;
- }
- }
-}
-
-/* ------------------------------------------------------------------------- */
-static void init_render_surf(Object *ob)
-{
- extern Material defmaterial; // initrender.c
- Nurb *nu=0;
- Curve *cu;
- ListBase displist;
- DispList *dl;
- VertRen *ver, *v1, *v2, *v3, *v4;
- VlakRen *vlr;
- Material *matar[32];
- float *data, *orco=NULL, *orcobase=NULL, n1[3], flen, mat[4][4];
- int a, need_orco=0, startvlak, startvert, p1, p2, p3, p4;
- int u, v;
- int sizeu, sizev;
- VlakRen *vlr1, *vlr2, *vlr3;
- float vn[3]; // n2[3],
-
- cu= ob->data;
- nu= cu->nurb.first;
- if(nu==0) return;
-
- MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
- MTC_Mat4Invert(ob->imat, mat);
-
- /* material array */
- memset(matar, 0, 4*32);
- matar[0]= &defmaterial;
- for(a=0; a<ob->totcol; a++) {
- matar[a]= give_render_material(ob, a+1);
- if(matar[a] && matar[a]->texco & TEXCO_ORCO) {
- need_orco= 1;
- }
- }
-
- if(ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1;
-
- if(need_orco) orcobase= orco= get_object_orco(ob);
-
- displist.first= displist.last= 0;
- makeDispListSurf(ob, &displist, 1);
-
- dl= displist.first;
- /* walk along displaylist and create rendervertices/-faces */
- while(dl) {
- /* watch out: u ^= y, v ^= x !! */
- if(dl->type==DL_SURF) {
- int nsizeu, nsizev;
-
- startvert= R.totvert;
- nsizeu = sizeu = dl->parts; nsizev = sizev = dl->nr;
-
- data= dl->verts;
- for (u = 0; u < sizeu; u++) {
- v1 = RE_findOrAddVert(R.totvert++); /* save this for possible V wrapping */
- VECCOPY(v1->co, data); data += 3;
- if(orco) {
- v1->orco= orco; orco+= 3;
- }
- MTC_Mat4MulVecfl(mat, v1->co);
-
- for (v = 1; v < sizev; v++) {
- ver= RE_findOrAddVert(R.totvert++);
- VECCOPY(ver->co, data); data += 3;
- if(orco) {
- ver->orco= orco; orco+= 3;
- }
- MTC_Mat4MulVecfl(mat, ver->co);
- }
- /* if V-cyclic, add extra vertices at end of the row */
- if (dl->flag & DL_CYCL_U) {
- ver= RE_findOrAddVert(R.totvert++);
- VECCOPY(ver->co, v1->co);
- if(orco) {
- ver->orco= orcobase + 3*(u*sizev + 0);
- }
- }
- }
-
- /* Done before next loop to get corner vert */
- if (dl->flag & DL_CYCL_U) nsizev++;
- if (dl->flag & DL_CYCL_V) nsizeu++;
-
- /* if U cyclic, add extra row at end of column */
- if (dl->flag & DL_CYCL_V) {
- for (v = 0; v < nsizev; v++) {
- v1= RE_findOrAddVert(startvert + v);
- ver= RE_findOrAddVert(R.totvert++);
- VECCOPY(ver->co, v1->co);
- if(orco) {
- ver->orco= orcobase + 3*(0*sizev + v);
- }
- }
- }
-
- sizeu = nsizeu;
- sizev = nsizev;
-
- startvlak= R.totvlak;
-
- for(u = 0; u < sizeu - 1; u++) {
- p1 = startvert + u * sizev; /* walk through face list */
- p2 = p1 + 1;
- p3 = p2 + sizev;
- p4 = p3 - 1;
-
- for(v = 0; v < sizev - 1; v++) {
- v1= RE_findOrAddVert(p1);
- v2= RE_findOrAddVert(p2);
- v3= RE_findOrAddVert(p3);
- v4= RE_findOrAddVert(p4);
-
- vlr= RE_findOrAddVlak(R.totvlak++);
- vlr->ob= vlr_set_ob(ob);
- vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4;
-
- flen= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, n1);
- VECCOPY(vlr->n, n1);
-
- vlr->lay= ob->lay;
- vlr->mat= matar[ dl->col];
- vlr->ec= ME_V1V2+ME_V2V3;
- vlr->flag= dl->rt;
- if( (cu->flag & CU_NOPUNOFLIP) ) {
- vlr->flag |= R_NOPUNOFLIP;
- }
-
- VecAddf(v1->n, v1->n, n1);
- VecAddf(v2->n, v2->n, n1);
- VecAddf(v3->n, v3->n, n1);
- VecAddf(v4->n, v4->n, n1);
-
- p1++; p2++; p3++; p4++;
- }
- }
- /* fix normals for U resp. V cyclic faces */
- sizeu--; sizev--; /* dec size for face array */
- if (dl->flag & DL_CYCL_V) {
-
- for (v = 0; v < sizev; v++)
- {
- /* optimize! :*/
- vlr= RE_findOrAddVlak(UVTOINDEX(sizeu - 1, v));
- vlr1= RE_findOrAddVlak(UVTOINDEX(0, v));
- VecAddf(vlr1->v1->n, vlr1->v1->n, vlr->n);
- VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
- VecAddf(vlr->v3->n, vlr->v3->n, vlr1->n);
- VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
- }
- }
- if (dl->flag & DL_CYCL_U) {
-
- for (u = 0; u < sizeu; u++)
- {
- /* optimize! :*/
- vlr= RE_findOrAddVlak(UVTOINDEX(u, 0));
- vlr1= RE_findOrAddVlak(UVTOINDEX(u, sizev-1));
- VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
- VecAddf(vlr1->v3->n, vlr1->v3->n, vlr->n);
- VecAddf(vlr->v1->n, vlr->v1->n, vlr1->n);
- VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
- }
- }
- /* last vertex is an extra case:
-
- ^ ()----()----()----()
- | | | || |
- u | |(0,n)||(0,0)|
- | | || |
- ()====()====[]====()
- | | || |
- | |(m,n)||(m,0)|
- | | || |
- ()----()----()----()
- v ->
-
- vertex [] is no longer shared, therefore distribute
- normals of the surrounding faces to all of the duplicates of []
- */
-
- if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U))
- {
- vlr= RE_findOrAddVlak(UVTOINDEX(sizeu - 1, sizev - 1)); /* (m,n) */
- vlr1= RE_findOrAddVlak(UVTOINDEX(0,0)); /* (0,0) */
- VecAddf(vn, vlr->n, vlr1->n);
- vlr2= RE_findOrAddVlak(UVTOINDEX(0, sizev-1)); /* (0,n) */
- VecAddf(vn, vn, vlr2->n);
- vlr3= RE_findOrAddVlak(UVTOINDEX(sizeu-1, 0)); /* (m,0) */
- VecAddf(vn, vn, vlr3->n);
- VECCOPY(vlr->v3->n, vn);
- VECCOPY(vlr1->v1->n, vn);
- VECCOPY(vlr2->v2->n, vn);
- VECCOPY(vlr3->v4->n, vn);
- }
- for(a = startvert; a < R.totvert; a++) {
- ver= RE_findOrAddVert(a);
- Normalise(ver->n);
- }
-
-
- }
-
- dl= dl->next;
- }
- freedisplist(&displist);
-}
-
-static void init_render_curve(Object *ob)
-{
- extern Material defmaterial; // initrender.c
- Curve *cu;
- VertRen *ver;
- VlakRen *vlr;
- DispList *dl;
- Material *matar[32];
- float len, *data, *fp, *orco=NULL;
- float n[3], mat[4][4];
- int nr, startvert, startvlak, a, b;
- int frontside, need_orco=0;
-
- cu= ob->data;
- if(cu->nurb.first==NULL) return;
-
- /* no modifier call here, is in makedisp */
-
- /* test displist */
- if(cu->disp.first==0) makeDispListCurveTypes(ob, 0);
- dl= cu->disp.first;
- if(cu->disp.first==0) return;
-
- MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
- MTC_Mat4Invert(ob->imat, mat);
-
- /* material array */
- memset(matar, 0, 4*32);
- matar[0]= &defmaterial;
- for(a=0; a<ob->totcol; a++) {
- matar[a]= give_render_material(ob, a+1);
- if(matar[a]->texco & TEXCO_ORCO) {
- need_orco= 1;
- }
- }
-
- if(need_orco) orco= get_object_orco(ob);
-
- dl= cu->disp.first;
- while(dl) {
- if(dl->type==DL_INDEX3) {
- int *index;
-
- startvert= R.totvert;
- data= dl->verts;
-
- n[0]= ob->imat[0][2];
- n[1]= ob->imat[1][2];
- n[2]= ob->imat[2][2];
- Normalise(n);
-
- /* copy first, rotate later for comparision trick */
- for(a=0; a<dl->nr; a++, data+=3) {
- ver= RE_findOrAddVert(R.totvert++);
- VECCOPY(ver->co, data);
- MTC_Mat4MulVecfl(mat, ver->co);
-
- if(ver->co[2] < 0.0) {
- VECCOPY(ver->n, n);
- ver->flag = 1;
- }
- else {
- ver->n[0]= -n[0]; ver->n[1]= -n[1]; ver->n[2]= -n[2];
- ver->flag = 0;
- }
-
- if (orco) {
- ver->orco = orco;
- orco += 3;
- }
- }
-
- startvlak= R.totvlak;
- index= dl->index;
- for(a=0; a<dl->parts; a++, index+=3) {
-
- vlr= RE_findOrAddVlak(R.totvlak++);
- vlr->ob = vlr_set_ob(ob); /* yafray: correction for curve rendering, obptr was not set */
- vlr->v1= RE_findOrAddVert(startvert+index[0]);
- vlr->v2= RE_findOrAddVert(startvert+index[1]);
- vlr->v3= RE_findOrAddVert(startvert+index[2]);
- vlr->v4= NULL;
-
- if(vlr->v1->flag) {
- VECCOPY(vlr->n, n);
- }
- else {
- vlr->n[0]= -n[0]; vlr->n[1]= -n[1]; vlr->n[2]= -n[2];
- }
-
- vlr->mat= matar[ dl->col ];
- vlr->flag= 0;
- if( (cu->flag & CU_NOPUNOFLIP) ) {
- vlr->flag |= R_NOPUNOFLIP;
- }
- vlr->ec= 0;
- vlr->lay= ob->lay;
- }
- }
- else if (dl->type==DL_SURF) {
- int p1,p2,p3,p4;
- float *surforco = orco;
-
- fp= dl->verts;
- startvert= R.totvert;
- nr= dl->nr*dl->parts;
-
- while(nr--) {
- ver= RE_findOrAddVert(R.totvert++);
-
- VECCOPY(ver->co, fp);
- MTC_Mat4MulVecfl(mat, ver->co);
- fp+= 3;
-
- if (orco) {
- ver->orco = orco;
- orco += 3;
- }
- }
-
- startvlak= R.totvlak;
-
- for(a=0; a<dl->parts; a++) {
-
- frontside= (a >= dl->nr/2);
-
- DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
- p1+= startvert;
- p2+= startvert;
- p3+= startvert;
- p4+= startvert;
-
- for(; b<dl->nr; b++) {
- vlr= RE_findOrAddVlak(R.totvlak++);
- vlr->ob= vlr_set_ob(ob);
- vlr->v1= RE_findOrAddVert(p2);
- vlr->v2= RE_findOrAddVert(p1);
- vlr->v3= RE_findOrAddVert(p3);
- vlr->v4= RE_findOrAddVert(p4);
- vlr->ec= ME_V2V3+ME_V3V4;
- if(a==0) vlr->ec+= ME_V1V2;
-
- vlr->flag= dl->rt;
- vlr->lay= ob->lay;
-
- /* this is not really scientific: the vertices
- * 2, 3 en 4 seem to give better vertexnormals than 1 2 3:
- * front and backside treated different!!
- */
-
- if(frontside)
- CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, vlr->n);
- else
- CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
-
- vlr->mat= matar[ dl->col ];
-
- p4= p3;
- p3++;
- p2= p1;
- p1++;
- }
- }
-
- if (dl->bevelSplitFlag) {
- for(a=0; a<dl->parts-1+!!(dl->flag&DL_CYCL_V); a++)
- if(dl->bevelSplitFlag[a>>5]&(1<<(a&0x1F)))
- split_v_renderfaces(startvlak, startvert, dl->parts, dl->nr, a, dl->flag&DL_CYCL_V, dl->flag&DL_CYCL_U);
- }
-
- /* vertex normals */
- for(a= startvlak; a<R.totvlak; a++) {
- vlr= RE_findOrAddVlak(a);
-
- VecAddf(vlr->v1->n, vlr->v1->n, vlr->n);
- VecAddf(vlr->v3->n, vlr->v3->n, vlr->n);
- VecAddf(vlr->v2->n, vlr->v2->n, vlr->n);
- VecAddf(vlr->v4->n, vlr->v4->n, vlr->n);
- }
- for(a=startvert; a<R.totvert; a++) {
- ver= RE_findOrAddVert(a);
- len= Normalise(ver->n);
- if(len==0.0) ver->flag= 1; /* flag use, its only used in zbuf now */
- else ver->flag= 0;
- }
- for(a= startvlak; a<R.totvlak; a++) {
- vlr= RE_findOrAddVlak(a);
- if(vlr->v1->flag) VECCOPY(vlr->v1->n, vlr->n);
- if(vlr->v2->flag) VECCOPY(vlr->v2->n, vlr->n);
- if(vlr->v3->flag) VECCOPY(vlr->v3->n, vlr->n);
- if(vlr->v4->flag) VECCOPY(vlr->v4->n, vlr->n);
- }
- }
-
- dl= dl->next;
- }
-}
-
-/* prevent phong interpolation for giving ray shadow errors (terminator problem) */
-static void set_phong_threshold(Object *ob, int startface, int numface, int startvert, int numvert )
-{
-// VertRen *ver;
- VlakRen *vlr;
- float thresh= 0.0, dot;
- int tot=0, i;
-
- /* Added check for 'pointy' situations, only dotproducts of 0.9 and larger
- are taken into account. This threshold is meant to work on smooth geometry, not
- for extreme cases (ton) */
-
- for(i=startface; i<startface+numface; i++) {
- vlr= RE_findOrAddVlak(i);
- if(vlr->flag & R_SMOOTH) {
- dot= INPR(vlr->n, vlr->v1->n);
- dot= ABS(dot);
- if(dot>0.9) {
- thresh+= dot; tot++;
- }
- dot= INPR(vlr->n, vlr->v2->n);
- dot= ABS(dot);
- if(dot>0.9) {
- thresh+= dot; tot++;
- }
-
- dot= INPR(vlr->n, vlr->v3->n);
- dot= ABS(dot);
- if(dot>0.9) {
- thresh+= dot; tot++;
- }
-
- if(vlr->v4) {
- dot= INPR(vlr->n, vlr->v4->n);
- dot= ABS(dot);
- if(dot>0.9) {
- thresh+= dot; tot++;
- }
- }
- }
- }
-
- if(tot) {
- thresh/= (float)tot;
- ob->smoothresh= cos(0.5*M_PI-acos(thresh));
- }
-}
-
-static void init_render_object(Object *ob)
-{
- float mat[4][4];
- int startface, startvert;
-
- startface=R.totvlak;
- startvert=R.totvert;
-
- ob->flag |= OB_DONE;
-
- if(ob->type==OB_LAMP)
- RE_add_render_lamp(ob, 1);
- else if ELEM(ob->type, OB_FONT, OB_CURVE)
- init_render_curve(ob);
- else if(ob->type==OB_SURF)
- init_render_surf(ob);
- else if(ob->type==OB_MESH)
- init_render_mesh(ob);
- else if(ob->type==OB_MBALL)
- init_render_mball(ob);
- else {
- MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
- MTC_Mat4Invert(ob->imat, mat);
- }
-
- /* generic post process here */
- if(startvert!=R.totvert) {
-
- /* the exception below is because displace code now is in init_render_mesh call,
- I will look at means to have autosmooth enabled for all object types
- and have it as general postprocess, like displace */
- if (ob->type!=OB_MESH && test_for_displace( ob ) )
- do_displacement(ob, startface, R.totvlak-startface, startvert, R.totvert-startvert);
-
- /* phong normal interpolation can cause error in tracing (terminator prob) */
- ob->smoothresh= 0.0;
- if( (R.r.mode & R_RAYTRACE) && (R.r.mode & R_SHADOW) )
- set_phong_threshold(ob, startface, R.totvlak-startface, startvert, R.totvert-startvert);
- }
-}
-
-void RE_freeRotateBlenderScene(void)
-{
- ShadBuf *shb;
- Object *ob = NULL;
- GroupObject *go;
- unsigned long *ztile;
- int a, b, v;
- char *ctile;
-
- /* FREE */
-
- BLI_memarena_free(R.memArena);
- R.memArena = NULL;
-
- for(go= R.lights.first; go; go= go->next) {
- struct LampRen *lar= go->lampren;
- if(lar->shb) {
- shb= lar->shb;
- v= (shb->size*shb->size)/256;
- ztile= shb->zbuf;
- ctile= shb->cbuf;
- for(b=0; b<v; b++, ztile++, ctile++) {
- if(*ctile) MEM_freeN((void *) *ztile);
- }
-
- MEM_freeN(shb->zbuf);
- MEM_freeN(shb->cbuf);
- MEM_freeN(lar->shb);
- }
- if(lar->jitter) MEM_freeN(lar->jitter);
- MEM_freeN(lar);
- }
-
- BLI_freelistN(&R.lights);
-
- /* note; these pointer arrays were allocated, with last element NULL to stop loop */
- RE_free_vertex_tables();
-
- a=0;
- while(R.blovl[a]) {
- MEM_freeN(R.blovl[a]);
- R.blovl[a]= NULL;
- a++;
- }
- a=0;
- while(R.bloha[a]) {
- MEM_freeN(R.bloha[a]);
- R.bloha[a]= NULL;
- a++;
- }
-
- /* 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_mesh_orco_hash();
-
- end_radio_render();
- end_render_materials();
-
- if(R.wrld.aosphere) {
- MEM_freeN(R.wrld.aosphere);
- R.wrld.aosphere= NULL;
- G.scene->world->aosphere= NULL;
- }
-
- R.totvlak=R.totvert=R.totlamp=R.tothalo= 0;
-}
-
-/* per face check if all samples should be taken.
- if raytrace, do always for raytraced material, or when material full_osa set */
-static void set_fullsample_flag(void)
-{
- VlakRen *vlr;
- int a, trace;
-
- trace= R.r.mode & R_RAYTRACE;
-
- for(a=R.totvlak-1; a>=0; a--) {
- vlr= RE_findOrAddVlak(a);
-
- if(vlr->mat->mode & MA_FULL_OSA) vlr->flag |= R_FULL_OSA;
- else if(trace) {
- if(vlr->mat->mode & MA_SHLESS);
- else if(vlr->mat->mode & (MA_RAYTRANSP|MA_RAYMIRROR|MA_SHADOW))
- vlr->flag |= R_FULL_OSA;
- }
- }
-}
-
-/* 10 times larger than normal epsilon, test it on default nurbs sphere with ray_transp */
-#ifdef FLT_EPSILON
-#undef FLT_EPSILON
-#endif
-#define FLT_EPSILON 1.19209290e-06F
-
-
-static void check_non_flat_quads(void)
-{
- VlakRen *vlr, *vlr1;
- VertRen *v1, *v2, *v3, *v4;
- float nor[3], xn, flen;
- int a;
-
- for(a=R.totvlak-1; a>=0; a--) {
- vlr= RE_findOrAddVlak(a);
-
- /* test if rendering as a quad or triangle, skip wire */
- if(vlr->v4 && (vlr->flag & R_STRAND)==0 && (vlr->mat->mode & MA_WIRE)==0) {
-
- /* check if quad is actually triangle */
- v1= vlr->v1;
- v2= vlr->v2;
- v3= vlr->v3;
- v4= vlr->v4;
- VECSUB(nor, v1->co, v2->co);
- if( ABS(nor[0])<FLT_EPSILON && ABS(nor[1])<FLT_EPSILON && ABS(nor[2])<FLT_EPSILON ) {
- vlr->v1= v2;
- vlr->v2= v3;
- vlr->v3= v4;
- vlr->v4= NULL;
- }
- else {
- VECSUB(nor, v2->co, v3->co);
- if( ABS(nor[0])<FLT_EPSILON && ABS(nor[1])<FLT_EPSILON && ABS(nor[2])<FLT_EPSILON ) {
- vlr->v2= v3;
- vlr->v3= v4;
- vlr->v4= NULL;
- }
- else {
- VECSUB(nor, v3->co, v4->co);
- if( ABS(nor[0])<FLT_EPSILON && ABS(nor[1])<FLT_EPSILON && ABS(nor[2])<FLT_EPSILON ) {
- vlr->v4= NULL;
- }
- else {
- VECSUB(nor, v4->co, v1->co);
- if( ABS(nor[0])<FLT_EPSILON && ABS(nor[1])<FLT_EPSILON && ABS(nor[2])<FLT_EPSILON ) {
- vlr->v4= NULL;
- }
- }
- }
- }
-
- if(vlr->v4) {
-
- /* Face is divided along edge with the least gradient */
- /* Flagged with R_DIVIDE_24 if divide is from vert 2 to 4 */
- /* 4---3 4---3 */
- /* |\ 1| or |1 /| */
- /* |0\ | |/ 0| */
- /* 1---2 1---2 0 = orig face, 1 = new face */
-
- /* render normals are inverted in render! we calculate normal of single tria here */
- flen= CalcNormFloat(vlr->v4->co, vlr->v3->co, vlr->v1->co, nor);
- if(flen==0.0) CalcNormFloat(vlr->v4->co, vlr->v2->co, vlr->v1->co, nor);
-
- xn= nor[0]*vlr->n[0] + nor[1]*vlr->n[1] + nor[2]*vlr->n[2];
- if(ABS(xn) < 0.99995 ) { // checked on noisy fractal grid
- float d1, d2;
-
- vlr1= RE_findOrAddVlak(R.totvlak++);
- *vlr1= *vlr;
- vlr1->flag |= R_FACE_SPLIT;
-
- /* split direction based on vnorms */
- CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, nor);
- d1= nor[0]*vlr->v1->n[0] + nor[1]*vlr->v1->n[1] + nor[2]*vlr->v1->n[2];
-
- CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, nor);
- d2= nor[0]*vlr->v2->n[0] + nor[1]*vlr->v2->n[1] + nor[2]*vlr->v2->n[2];
-
- if( fabs(d1) < fabs(d2) ) vlr->flag |= R_DIVIDE_24;
- else vlr->flag &= ~R_DIVIDE_24;
-
- /* new vertex pointers */
- if (vlr->flag & R_DIVIDE_24) {
- vlr1->v1= vlr->v2;
- vlr1->v2= vlr->v3;
- vlr1->v3= vlr->v4;
-
- vlr->v3 = vlr->v4;
-
- vlr1->flag |= R_DIVIDE_24;
- }
- else {
- vlr1->v1= vlr->v1;
- vlr1->v2= vlr->v3;
- vlr1->v3= vlr->v4;
-
- vlr1->flag &= ~R_DIVIDE_24;
- }
- vlr->v4 = vlr1->v4 = NULL;
-
- /* new normals */
- CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
- CalcNormFloat(vlr1->v3->co, vlr1->v2->co, vlr1->v1->co, vlr1->n);
-
- /* so later UV can be pulled from original tface, look for R_DIVIDE_24 for direction */
- vlr1->tface=vlr->tface;
-
- }
- /* clear the flag when not divided */
- else vlr->flag &= ~R_DIVIDE_24;
- }
- }
- }
-}
-
-static void set_material_lightgroups(void)
-{
- GroupObject *go, *gol;
- Material *ma;
-
- /* it's a bit too many loops in loops... but will survive */
- for(ma= G.main->mat.first; ma; ma=ma->id.next) {
- if(ma->group) {
- for(go= ma->group->gobject.first; go; go= go->next) {
- for(gol= R.lights.first; gol; gol= gol->next) {
- if(gol->ob==go->ob) {
- go->lampren= gol->lampren;
- break;
- }
- }
- }
- }
- }
-}
-
-extern int slurph_opt; /* key.c */
-extern ListBase duplilist;
-void RE_rotateBlenderScene(void)
-{
- Base *base;
- Object *ob, *obd;
- Scene *sce, *setscene;
- unsigned int lay;
- float mat[4][4];
-
- if(G.scene->camera==NULL) return;
-
- R.memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
- R.totvlak=R.totvert=R.totlamp=R.tothalo= 0;
- R.lights.first= R.lights.last= NULL;
-
- slurph_opt= 0;
-
- /* in localview, lamps are using normal layers, objects only local bits */
- if(G.scene->lay & 0xFF000000) lay= G.scene->lay & 0xFF000000;
- else lay= G.scene->lay;
-
- /* applies changes fully */
- scene_update_for_newframe(G.scene, lay);
-
- MTC_Mat4CpyMat4(R.viewinv, G.scene->camera->obmat);
- MTC_Mat4Ortho(R.viewinv);
- MTC_Mat4Invert(R.viewmat, R.viewinv);
-
- RE_setwindowclip(1,-1); /* no jit:(-1) */
-
- /* clear imat flags */
- ob= G.main->object.first;
- while(ob) {
- ob->flag &= ~OB_DO_IMAT;
- ob= ob->id.next;
- }
-
- init_render_world(); /* do first, because of ambient. also requires R.osa set correct */
- if( (R.wrld.mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) ) {
- R.wrld.aosphere= MEM_mallocN(2*3*R.wrld.aosamp*R.wrld.aosamp*sizeof(float), "AO sphere");
- /* we make twice the amount of samples, because only a hemisphere is used */
- init_ao_sphere(R.wrld.aosphere, 2*R.wrld.aosamp*R.wrld.aosamp, 16);
-
- /* bah... init_render_world writes this over, and that is called/needed in envmap. */
- G.scene->world->aosphere= R.wrld.aosphere;
- }
- init_render_textures();
- init_render_materials();
- set_node_shader_lamp_loop(shade_material_loop);
-
- /* imat objects, OB_DO_IMAT can be set in init_render_materials
- has to be done here, since displace can have texture using Object map-input */
- ob= G.main->object.first;
- while(ob) {
- if(ob->flag & OB_DO_IMAT) {
- ob->flag &= ~OB_DO_IMAT;
- MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
- MTC_Mat4Invert(ob->imat, mat);
- }
- ob= ob->id.next;
- }
-
- /* MAKE RENDER DATA */
-
- /* each object should only be rendered once */
- ob= G.main->object.first;
- while(ob) {
- ob->flag &= ~OB_DONE;
- ob= ob->id.next;
- }
-
- sce= G.scene;
- setscene= G.scene->set;
- base= G.scene->base.first;
- while(base) {
-
- ob= base->object;
-
- if(ob->flag & OB_DONE) {
- /* yafray: this object needs to be included in renderlist for duplivert instancing.
- This only works for dupliverts, dupliframes handled below.
- This is based on the assumption that OB_DONE is only set for duplivert objects,
- before scene conversion, there are no other flags set to indicate it's use as far as I know...
- NOT done for lamps, these are included as separate objects, see below.
- correction: also ignore lattices, armatures and camera's (.....) */
- if ((ob->type!=OB_LATTICE) && (ob->type!=OB_ARMATURE) &&
- (ob->type!=OB_LAMP) && (ob->type!=OB_CAMERA) && (R.r.renderer==R_YAFRAY))
- {
- printf("Adding %s to renderlist\n", ob->id.name);
- ob->flag &= ~OB_DONE;
- init_render_object(ob);
- ob->flag |= OB_DONE;
- }
- }
- else {
- if( (base->lay & lay) || (ob->type==OB_LAMP && (base->lay & G.scene->lay)) ) {
-
- if(ob->transflag & OB_DUPLI) {
-
- /* exception: mballs! */
- /* yafray: Include at least one copy of a dupliframe object for yafray in the renderlist.
- mballs comment above true as well for yafray, they are not included, only all other object types */
- if (R.r.renderer==R_YAFRAY) {
- if ((ob->type!=OB_MBALL) && ((ob->transflag & OB_DUPLIFRAMES)!=0)) {
- printf("Object %s has OB_DUPLIFRAMES set, adding to renderlist\n", ob->id.name);
- init_render_object(ob);
- }
- }
- /* before make duplis, update particle for current frame */
- if(ob->transflag & OB_DUPLIVERTS) {
- PartEff *paf= give_parteff(ob);
- if(paf) {
- if(paf->flag & PAF_ANIMATED) build_particle_system(ob);
- }
- }
-
- if(ob->type==OB_MBALL) {
- init_render_object(ob);
- }
- else {
- DupliObject *dob;
- ListBase *lb= object_duplilist(sce, ob);
-
- for(dob= lb->first; dob; dob= dob->next) {
- Object *obd= dob->ob;
- Mat4CpyMat4(obd->obmat, dob->mat);
-
- if(obd->type!=OB_MBALL) {
- /* yafray: special handling of duplivert objects for yafray:
- only the matrix is stored, together with the source object name.
- Since the original object is needed as well, it is included in the renderlist (see above)
- NOT done for lamps, these need to be included as normal lamps separately
- correction: also ignore lattices, armatures and cameras (....) */
- if ((obd->type!=OB_LATTICE) && (obd->type!=OB_ARMATURE) &&
- (obd->type!=OB_LAMP) && (obd->type!=OB_CAMERA) && (R.r.renderer==R_YAFRAY))
- {
- printf("Adding dupli matrix for object %s\n", obd->id.name);
- YAF_addDupliMtx(obd);
- }
- else init_render_object(obd);
- }
- Mat4CpyMat4(obd->obmat, dob->omat);
- }
- BLI_freelistN(lb);
- }
- }
- else {
- /* yafray: if there are linked data objects (except lamps, empties or armatures),
- yafray only needs to know about one, the rest can be instanciated.
- The dupliMtx list is used for this purpose.
- Exception: objects which have object linked materials, these cannot be instanciated. */
- if ((R.r.renderer==R_YAFRAY) && (ob->colbits==0))
- {
- /* Special case, parent object dupli's: ignore if object itself is lamp or parent is lattice or empty */
- if (ob->parent) {
- if ((ob->type!=OB_LAMP) && (ob->parent->type!=OB_EMPTY) &&
- (ob->parent->type!=OB_LATTICE) && YAF_objectKnownData(ob))
- printf("From parent: Added dupli matrix for linked data object %s\n", ob->id.name);
- else
- init_render_object(ob);
- }
- else if ((ob->type!=OB_EMPTY) && (ob->type!=OB_LAMP) && (ob->type!=OB_ARMATURE) && YAF_objectKnownData(ob))
- printf("Added dupli matrix for linked data object %s\n", ob->id.name);
- else
- init_render_object(ob);
- }
- else init_render_object(ob);
- }
-
- }
- else {
- MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
- MTC_Mat4Invert(ob->imat, mat);
- }
-
- }
- if(blender_test_break()) break;
-
- base= base->next;
- if(base==0 && setscene) {
- sce= setscene;
- base= setscene->base.first;
- setscene= setscene->set;
- }
- /*if(base->next==0 && G.scene->set && base==G.scene->base.last) {
- base= G.scene->set->base.first;
- sce= G.scene->set;
- }
- else base= base->next;*/
-
- }
-
- sort_halos();
-
- set_material_lightgroups();
-
- if(R.wrld.mode & WO_STARS) RE_make_stars(NULL, NULL, NULL);
-
- slurph_opt= 1;
-
- if(blender_test_break()) return;
-
- set_fullsample_flag();
- check_non_flat_quads();
- set_normalflags();
-}
-
-/* **************************************************************** */
-/* sticky texture coords */
-/* **************************************************************** */
-
-void RE_make_sticky(void)
-{
- Object *ob;
- Base *base;
- MVert *mvert;
- Mesh *me;
- MSticky *ms;
- float ho[4], mat[4][4];
- int a;
-
- if(G.scene->camera==0) return;
-
- if(G.obedit) {
- error("Unable to make sticky in Edit Mode");
- return;
- }
- base= FIRSTBASE;
- while(base) {
- if TESTBASELIB(base) {
- if(base->object->type==OB_MESH) {
- ob= base->object;
-
- me= ob->data;
- mvert= me->mvert;
- if(me->msticky) MEM_freeN(me->msticky);
- me->msticky= MEM_mallocN(me->totvert*sizeof(MSticky), "sticky");
-
- /* like convert to render data */
- R.r= G.scene->r;
- R.r.xsch= (R.r.size*R.r.xsch)/100;
- R.r.ysch= (R.r.size*R.r.ysch)/100;
-
- R.afmx= R.r.xsch/2;
- R.afmy= R.r.ysch/2;
-
- R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
-
- R.rectx= R.r.xsch;
- R.recty= R.r.ysch;
- R.xstart= -R.afmx;
- R.ystart= -R.afmy;
- R.xend= R.xstart+R.rectx-1;
- R.yend= R.ystart+R.recty-1;
-
- where_is_object(G.scene->camera);
- Mat4CpyMat4(R.viewinv, G.scene->camera->obmat);
- Mat4Ortho(R.viewinv);
- Mat4Invert(R.viewmat, R.viewinv);
-
- RE_setwindowclip(1, -1);
-
- where_is_object(ob);
- Mat4MulMat4(mat, ob->obmat, R.viewmat);
-
- ms= me->msticky;
- for(a=0; a<me->totvert; a++, ms++, mvert++) {
- VECCOPY(ho, mvert->co);
- Mat4MulVecfl(mat, ho);
- RE_projectverto(ho, ho);
- ms->co[0]= ho[0]/ho[3];
- ms->co[1]= ho[1]/ho[3];
- }
- }
- }
- base= base->next;
- }
-}
-
-
-/* **************************************************************** */
-/* Displacement mapping */
-/* **************************************************************** */
-static short test_for_displace(Object *ob)
-{
- /* return 1 when this object uses displacement textures. */
- Material *ma;
- int i;
-
- for (i=1; i<=ob->totcol; i++) {
- ma=give_render_material(ob, i);
- /* ma->mapto is ORed total of all mapto channels */
- if(ma && (ma->mapto & MAP_DISPLACE)) return 1;
- }
- return 0;
-}
-
-static void displace_render_vert(ShadeInput *shi, VertRen *vr, float *scale)
-{
- short texco= shi->mat->texco;
- float sample=0;
- /* shi->co is current render coord, just make sure at least some vector is here */
- VECCOPY(shi->co, vr->co);
- /* vertex normal is used for textures type 'col' and 'var' */
- VECCOPY(shi->vn, vr->n);
-
- /* set all rendercoords, 'texco' is an ORed value for all textures needed */
- if ((texco & TEXCO_ORCO) && (vr->orco)) {
- VECCOPY(shi->lo, vr->orco);
- }
- if (texco & TEXCO_STICKY) {
- float *sticky= RE_vertren_get_sticky(vr, 0);
- if(sticky) {
- shi->sticky[0]= sticky[0];
- shi->sticky[1]= sticky[1];
- shi->sticky[2]= 0.0f;
- }
- }
- if (texco & TEXCO_GLOB) {
- VECCOPY(shi->gl, shi->co);
- MTC_Mat4MulVecfl(R.viewinv, shi->gl);
- }
- if (texco & TEXCO_NORM) {
- VECCOPY(shi->orn, shi->vn);
- }
- if(texco & TEXCO_REFL) {
- /* not (yet?) */
- }
-
- shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0;
-
- do_material_tex(shi);
-
- //printf("no=%f, %f, %f\nbefore co=%f, %f, %f\n", vr->n[0], vr->n[1], vr->n[2],
- //vr->co[0], vr->co[1], vr->co[2]);
-
- /* 0.5 could become button once? */
- vr->co[0] += shi->displace[0] * scale[0] ;
- vr->co[1] += shi->displace[1] * scale[1] ;
- vr->co[2] += shi->displace[2] * scale[2] ;
-
- //printf("after co=%f, %f, %f\n", vr->co[0], vr->co[1], vr->co[2]);
-
- /* we just don't do this vertex again, bad luck for other face using same vertex with
- different material... */
- vr->flag |= 1;
-
- /* Pass sample back so displace_face can decide which way to split the quad */
- sample = shi->displace[0]*shi->displace[0];
- sample += shi->displace[1]*shi->displace[1];
- sample += shi->displace[2]*shi->displace[2];
-
- vr->accum=sample;
- /* Should be sqrt(sample), but I'm only looking for "bigger". Save the cycles. */
- return;
-}
-
-static void displace_render_face(VlakRen *vlr, float *scale)
-{
- ShadeInput shi;
- // VertRen vr;
- // float samp1,samp2, samp3, samp4, xn;
- short hasuv=0;
- /* set up shadeinput struct for multitex() */
-
- shi.osatex= 0; /* signal not to use dx[] and dy[] texture AA vectors */
- shi.vlr= vlr; /* current render face */
- shi.mat= vlr->mat; /* current input material */
-
-
- /* UV coords must come from face */
- hasuv = vlr->tface && (shi.mat->texco & TEXCO_UV);
- if (hasuv) shi.uv[2]=0.0f;
- /* I don't think this is used, but seting it just in case */
-
- /* Displace the verts, flag is set when done */
- if (! (vlr->v1->flag)){
- if (hasuv) {
- shi.uv[0] = 2*vlr->tface->uv[0][0]-1.0f; /* shi.uv and tface->uv are */
- shi.uv[1]= 2*vlr->tface->uv[0][1]-1.0f; /* scalled differently */
- }
- displace_render_vert(&shi, vlr->v1, scale);
- }
-
- if (! (vlr->v2->flag)) {
- if (hasuv) {
- shi.uv[0] = 2*vlr->tface->uv[1][0]-1.0f;
- shi.uv[1]= 2*vlr->tface->uv[1][1]-1.0f;
- }
- displace_render_vert(&shi, vlr->v2, scale);
- }
-
- if (! (vlr->v3->flag)) {
- if (hasuv) {
- shi.uv[0] = 2*vlr->tface->uv[2][0]-1.0f;
- shi.uv[1]= 2*vlr->tface->uv[2][1]-1.0f;
- }
- displace_render_vert(&shi, vlr->v3, scale);
- }
-
- if (vlr->v4) {
- if (! (vlr->v4->flag)) {
- if (hasuv) {
- shi.uv[0] = 2*vlr->tface->uv[3][0]-1.0f;
- shi.uv[1]= 2*vlr->tface->uv[3][1]-1.0f;
- }
- displace_render_vert(&shi, vlr->v4, scale);
- }
- /* We want to split the quad along the opposite verts that are */
- /* closest in displace value. This will help smooth edges. */
- if ( fabs(vlr->v1->accum - vlr->v3->accum) > fabs(vlr->v2->accum - vlr->v4->accum))
- vlr->flag |= R_DIVIDE_24;
- else vlr->flag &= ~R_DIVIDE_24; // E: typo?, was missing '='
- }
-
- /* Recalculate the face normal - if flipped before, flip now */
- if(vlr->v4) {
- CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
- }
- else {
- CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
- }
-
-}
-
-
-static void do_displacement(Object *ob, int startface, int numface, int startvert, int numvert )
-{
- VertRen *vr;
- VlakRen *vlr;
-// float min[3]={1e30, 1e30, 1e30}, max[3]={-1e30, -1e30, -1e30};
- float scale[3]={1.0f, 1.0f, 1.0f}, temp[3];//, xn
- int i; //, texflag=0;
- Object *obt;
-
- /* Object Size with parenting */
- obt=ob;
- while(obt){
- VecAddf(temp, obt->size, obt->dsize);
- scale[0]*=temp[0]; scale[1]*=temp[1]; scale[2]*=temp[2];
- obt=obt->parent;
- }
-
- /* Clear all flags */
- for(i=startvert; i<startvert+numvert; i++){
- vr= RE_findOrAddVert(i);
- vr->flag= 0;
- }
-
- for(i=startface; i<startface+numface; i++){
- vlr=RE_findOrAddVlak(i);
- displace_render_face(vlr, scale);
- }
-
- /* Recalc vertex normals */
- calc_vertexnormals(startvert, startface, 0);
-}
-
diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c
index e077fa952ee..43bcb30ecca 100644
--- a/source/blender/src/buttons_scene.c
+++ b/source/blender/src/buttons_scene.c
@@ -1576,16 +1576,17 @@ static void render_panel_layers(void)
uiDefBut(block, LABEL, 0, "Passes:", 10,30,150,20, NULL, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, SCE_PASS_COMBINED, B_NOP,"Combined", 130, 30, 155, 20, &srl->passflag, 0, 0, 0, 0, "Deliver full combined RGBA buffer");
- uiDefButBitS(block, TOG, SCE_PASS_Z, B_NOP,"Z", 285, 30, 25, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Z values pass");
+ uiDefButBitS(block, TOG, SCE_PASS_COMBINED, B_NOP,"Combined", 130, 30, 115, 20, &srl->passflag, 0, 0, 0, 0, "Deliver full combined RGBA buffer");
+ uiDefButBitS(block, TOG, SCE_PASS_Z, B_NOP,"Z", 245, 30, 25, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Z values pass");
+ uiDefButBitS(block, TOG, SCE_PASS_VECTOR, B_NOP,"Vec", 270, 30, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Vector pass");
- uiDefButBitS(block, TOG, SCE_PASS_DIFFUSE, B_NOP,"Diff",10, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
- uiDefButBitS(block, TOG, SCE_PASS_SPEC, B_NOP,"Spec", 55, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
- uiDefButBitS(block, TOG, SCE_PASS_SHADOW, B_NOP,"Shad", 100, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
- uiDefButBitS(block, TOG, SCE_PASS_AO, B_NOP,"AO", 145, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
- uiDefButBitS(block, TOG, SCE_PASS_MIRROR, B_NOP,"Mirr", 185, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
- uiDefButBitS(block, TOG, SCE_PASS_NORMAL, B_NOP,"Nor", 230, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
- uiDefButBitS(block, TOG, SCE_PASS_VECTOR, B_NOP,"Vec", 270, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
+ uiDefButBitS(block, TOG, SCE_PASS_RGBA, B_NOP,"Col", 10, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver shade-less Color pass");
+ uiDefButBitS(block, TOG, SCE_PASS_DIFFUSE, B_NOP,"Diff",55, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
+ uiDefButBitS(block, TOG, SCE_PASS_SPEC, B_NOP,"Spec", 100, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Specular pass");
+ uiDefButBitS(block, TOG, SCE_PASS_SHADOW, B_NOP,"Shad", 145, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Shadow pass");
+ uiDefButBitS(block, TOG, SCE_PASS_AO, B_NOP,"AO", 185, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver AO pass");
+ uiDefButBitS(block, TOG, SCE_PASS_RAY, B_NOP,"Ray", 225, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Raytraced Mirror and Transparent pass");
+ uiDefButBitS(block, TOG, SCE_PASS_NORMAL, B_NOP,"Nor", 270, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Normal pass");
}
void render_panels()
diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c
index bdb3c0bf67f..a2697aa559d 100644
--- a/source/blender/src/drawnode.c
+++ b/source/blender/src/drawnode.c
@@ -743,8 +743,8 @@ static int node_composit_buts_map_value(uiBlock *block, bNodeTree *ntree, bNode
uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC+node->nr, "Min", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, "");
dy-= 19;
- uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC+node->nr, "Max", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
- uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, "");
+ uiDefButBitI(block, TOG, TEXMAP_CLIP_MAX, B_NODE_EXEC+node->nr, "Max", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
+ uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", xstart+dx, dy, dx, 19, texmap->max, -1000.0f, 1000.0f, 10, 2, "");
}
return 80;
}
diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c
index c192d801b65..19036c64d14 100644
--- a/source/blender/src/editnode.c
+++ b/source/blender/src/editnode.c
@@ -194,6 +194,18 @@ static void load_node_image(char *str) /* called from fileselect */
}
}
+static bNode *snode_get_editgroup(SpaceNode *snode)
+{
+ bNode *gnode;
+
+ /* get the groupnode */
+ for(gnode= snode->nodetree->nodes.first; gnode; gnode= gnode->next)
+ if(gnode->flag & NODE_GROUP_EDIT)
+ break;
+ return gnode;
+}
+
+
static void composit_node_event(SpaceNode *snode, short event)
{
@@ -219,7 +231,12 @@ static void composit_node_event(SpaceNode *snode, short event)
/* B_NODE_EXEC */
{
bNode *node= BLI_findlink(&snode->edittree->nodes, event-B_NODE_EXEC);
- if(node) NodeTagChanged(snode->edittree, node);
+ if(node) {
+ NodeTagChanged(snode->edittree, node);
+ node= snode_get_editgroup(snode);
+ if(node)
+ NodeTagChanged(snode->nodetree, node);
+ }
snode_handle_recalc(snode);
}
}
@@ -385,17 +402,6 @@ static void node_set_active(SpaceNode *snode, bNode *node)
}
}
-static bNode *snode_get_editgroup(SpaceNode *snode)
-{
- bNode *gnode;
-
- /* get the groupnode */
- for(gnode= snode->nodetree->nodes.first; gnode; gnode= gnode->next)
- if(gnode->flag & NODE_GROUP_EDIT)
- break;
- return gnode;
-}
-
static void snode_make_group_editable(SpaceNode *snode, bNode *gnode)
{
bNode *node;