forked from bartvdbraak/blender
Bounding box clipping in the render engine.
Now bounding boxes are computed per object, and checked first before zbuffering objects. For strands, bounding boxes are computed per original face in the mesh. Overall the speed improvement from this is quite small (zbuffering is rarely the bottleneck), but it seems a sensible thing to do anyway.
This commit is contained in:
parent
5bf5b030e5
commit
8e94028ed5
@ -780,6 +780,21 @@ void *exec_distribution(void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* not thread safe, but qsort doesn't take userdata argument */
|
||||
static int *COMPARE_ORIG_INDEX = NULL;
|
||||
static int compare_orig_index(const void *p1, const void *p2)
|
||||
{
|
||||
int index1 = COMPARE_ORIG_INDEX[*(const int*)p1];
|
||||
int index2 = COMPARE_ORIG_INDEX[*(const int*)p2];
|
||||
|
||||
if(index1 < index2)
|
||||
return -1;
|
||||
else if(index1 == index2)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* creates a distribution of coordinates on a DerivedMesh */
|
||||
/* */
|
||||
/* 1. lets check from what we are emitting */
|
||||
@ -1157,6 +1172,13 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
|
||||
|
||||
MEM_freeN(sum);
|
||||
|
||||
/* for hair, sort by origindex, allows optimizations in rendering */
|
||||
if(part->type == PART_HAIR) {
|
||||
COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX);
|
||||
if(COMPARE_ORIG_INDEX)
|
||||
qsort(index, totpart, sizeof(int), compare_orig_index);
|
||||
}
|
||||
|
||||
/* weights are no longer used except for FROM_PARTICLE, which needs them zeroed for indexing */
|
||||
if(from==PART_FROM_PARTICLE){
|
||||
for(i=0; i<tot; i++)
|
||||
|
@ -247,13 +247,15 @@ typedef struct ObjectRen {
|
||||
struct Scene *sce;
|
||||
int index, psysindex, flag, lay;
|
||||
|
||||
float boundbox[2][3];
|
||||
|
||||
int totvert, totvlak, totstrand, tothalo;
|
||||
int vertnodeslen, vlaknodeslen, strandnodeslen, blohalen;
|
||||
struct VertTableNode *vertnodes;
|
||||
struct VlakTableNode *vlaknodes;
|
||||
struct StrandTableNode *strandnodes;
|
||||
struct HaloRen **bloha;
|
||||
ListBase strandbufs;
|
||||
struct StrandBuffer *strandbuf;
|
||||
|
||||
char (*mtface)[32];
|
||||
char (*mcol)[32];
|
||||
@ -346,7 +348,7 @@ typedef struct StrandSurface {
|
||||
int (*face)[4];
|
||||
float (*co)[3];
|
||||
/* for occlusion caching */
|
||||
float (*col)[3]; /* for occlusion */
|
||||
float (*col)[3];
|
||||
/* for speedvectors */
|
||||
float (*prevco)[3], (*nextco)[3];
|
||||
int totvert, totface;
|
||||
@ -354,13 +356,14 @@ typedef struct StrandSurface {
|
||||
|
||||
typedef struct StrandBound {
|
||||
int start, end;
|
||||
float bbox[2][3];
|
||||
float boundbox[2][3];
|
||||
} StrandBound;
|
||||
|
||||
typedef struct StrandBuffer {
|
||||
struct StrandBuffer *next, *prev;
|
||||
struct StrandVert *vert;
|
||||
int totvert;
|
||||
struct StrandBound *bound;
|
||||
int totvert, totbound;
|
||||
|
||||
struct ObjectRen *obr;
|
||||
struct Material *ma;
|
||||
|
@ -85,6 +85,7 @@ void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes);
|
||||
|
||||
void set_normalflags(struct Render *re, struct ObjectRen *obr);
|
||||
void project_renderdata(struct Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets);
|
||||
int clip_render_object(float boundbox[][3], float *bounds, float mat[][4]);
|
||||
|
||||
/* functions are not exported... so wrong names */
|
||||
|
||||
|
@ -93,6 +93,7 @@ typedef struct StrandShadeCache StrandShadeCache;
|
||||
|
||||
void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint);
|
||||
void render_strand_segment(struct Render *re, float winmat[][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg);
|
||||
void strand_minmax(struct StrandRen *strand, float *min, float *max);
|
||||
|
||||
struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[][4], int timeoffset);
|
||||
void free_strand_surface(struct Render *re);
|
||||
|
@ -111,6 +111,7 @@
|
||||
#include "strand.h"
|
||||
#include "texture.h"
|
||||
#include "sss.h"
|
||||
#include "strand.h"
|
||||
#include "zbuf.h"
|
||||
|
||||
#ifndef DISABLE_YAFRAY /* disable yafray */
|
||||
@ -1482,6 +1483,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
ParticleCacheKey *cache=0;
|
||||
StrandBuffer *strandbuf=0;
|
||||
StrandVert *svert=0;
|
||||
StrandBound *sbound= 0;
|
||||
StrandRen *strand=0;
|
||||
RNG *rng= 0;
|
||||
float loc[3],loc1[3],loc0[3],vel[3],mat[4][4],nmat[3][3],co[3],nor[3],time;
|
||||
@ -1491,6 +1493,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
int i, a, k, max_k=0, totpart, totuv=0, override_uv=-1, dosimplify = 0, dosurfacecache = 0;
|
||||
int path_possible=0, keys_possible=0, baked_keys=0, totchild=psys->totchild;
|
||||
int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0}, num;
|
||||
int totface, *origindex = 0;
|
||||
char **uv_name=0;
|
||||
|
||||
/* 1. check that everything is ok & updated */
|
||||
@ -1653,6 +1656,18 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
else if((re->wrld.mode & WO_AMB_OCC) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX))
|
||||
if(ma->amb != 0.0f)
|
||||
dosurfacecache= 1;
|
||||
|
||||
totface= psmd->dm->getNumFaces(psmd->dm);
|
||||
origindex= psmd->dm->getFaceDataArray(psmd->dm, CD_ORIGINDEX);
|
||||
if(origindex) {
|
||||
for(a=0; a<totface; a++)
|
||||
strandbuf->totbound= MAX2(strandbuf->totbound, origindex[a]);
|
||||
strandbuf->totbound++;
|
||||
}
|
||||
strandbuf->totbound++;
|
||||
strandbuf->bound= MEM_callocN(sizeof(StrandBound)*strandbuf->totbound, "StrandBound");
|
||||
sbound= strandbuf->bound;
|
||||
sbound->start= sbound->end= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1802,6 +1817,13 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
cache = psys->childcache[a-totpart];
|
||||
max_k = (int)cache->steps;
|
||||
}
|
||||
|
||||
if(strandbuf) {
|
||||
if(origindex[cpa->num]+1 > sbound - strandbuf->bound) {
|
||||
sbound= strandbuf->bound + origindex[cpa->num]+1;
|
||||
sbound->start= sbound->end= obr->totstrand;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* surface normal shading setup */
|
||||
@ -1845,6 +1867,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sbound->end++;
|
||||
}
|
||||
|
||||
/* strandco computation setup */
|
||||
@ -3841,6 +3865,11 @@ static void check_non_flat_quads(ObjectRen *obr)
|
||||
static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset)
|
||||
{
|
||||
Object *ob= obr->ob;
|
||||
VertRen *ver= NULL;
|
||||
StrandRen *strand= NULL;
|
||||
StrandBound *sbound= NULL;
|
||||
float min[3], max[3], smin[3], smax[3];
|
||||
int a, b;
|
||||
|
||||
if(obr->totvert || obr->totvlak || obr->tothalo || obr->totstrand) {
|
||||
/* the exception below is because displace code now is in init_render_mesh call,
|
||||
@ -3858,6 +3887,36 @@ static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset)
|
||||
|
||||
check_non_flat_quads(obr);
|
||||
set_fullsample_flag(re, obr);
|
||||
|
||||
/* compute bounding boxes for clipping */
|
||||
INIT_MINMAX(min, max);
|
||||
for(a=0; a<obr->totvert; a++) {
|
||||
if((a & 255)==0) ver= obr->vertnodes[a>>8].vert;
|
||||
else ver++;
|
||||
|
||||
DO_MINMAX(ver->co, min, max);
|
||||
}
|
||||
|
||||
if(obr->strandbuf) {
|
||||
sbound= obr->strandbuf->bound;
|
||||
for(b=0; b<obr->strandbuf->totbound; b++, sbound++) {
|
||||
INIT_MINMAX(smin, smax);
|
||||
|
||||
for(a=sbound->start; a<sbound->end; a++) {
|
||||
strand= RE_findOrAddStrand(obr, a);
|
||||
strand_minmax(strand, smin, smax);
|
||||
}
|
||||
|
||||
VECCOPY(sbound->boundbox[0], smin);
|
||||
VECCOPY(sbound->boundbox[1], smax);
|
||||
|
||||
DO_MINMAX(smin, min, max);
|
||||
DO_MINMAX(smax, min, max);
|
||||
}
|
||||
}
|
||||
|
||||
VECCOPY(obr->boundbox[0], min);
|
||||
VECCOPY(obr->boundbox[1], max);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4674,7 +4733,7 @@ static void calculate_speedvectors(Render *re, ObjectInstanceRen *obi, float *ve
|
||||
}
|
||||
|
||||
if(obr->strandnodes) {
|
||||
strandbuf= obr->strandbufs.first;
|
||||
strandbuf= obr->strandbuf;
|
||||
mesh= (strandbuf)? strandbuf->surface: NULL;
|
||||
|
||||
/* compute speed vectors at surface vertices */
|
||||
|
@ -711,7 +711,7 @@ StrandBuffer *RE_addStrandBuffer(ObjectRen *obr, int totvert)
|
||||
strandbuf->totvert= totvert;
|
||||
strandbuf->obr= obr;
|
||||
|
||||
BLI_addtail(&obr->strandbufs, strandbuf);
|
||||
obr->strandbuf= strandbuf;
|
||||
|
||||
return strandbuf;
|
||||
}
|
||||
@ -842,9 +842,12 @@ void free_renderdata_tables(Render *re)
|
||||
obr->strandnodeslen= 0;
|
||||
}
|
||||
|
||||
for(strandbuf=obr->strandbufs.first; strandbuf; strandbuf=strandbuf->next)
|
||||
strandbuf= obr->strandbuf;
|
||||
if(strandbuf) {
|
||||
if(strandbuf->vert) MEM_freeN(strandbuf->vert);
|
||||
BLI_freelistN(&obr->strandbufs);
|
||||
if(strandbuf->bound) MEM_freeN(strandbuf->bound);
|
||||
MEM_freeN(strandbuf);
|
||||
}
|
||||
|
||||
if(obr->mtface)
|
||||
MEM_freeN(obr->mtface);
|
||||
@ -1342,13 +1345,11 @@ void RE_makeRenderInstances(Render *re)
|
||||
re->instancetable= newlist;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int clip_render_object(ObjectInstanceRen *obi, float *bounds, float winmat[][4])
|
||||
int clip_render_object(float boundbox[][3], float *bounds, float winmat[][4])
|
||||
{
|
||||
float mat[4][4], vec[4], max, min, (*boundbox)[3];
|
||||
float mat[4][4], vec[4];
|
||||
int a, fl, flag= -1;
|
||||
|
||||
boundbox= obi->obr->boundbox;
|
||||
Mat4CpyMat4(mat, winmat);
|
||||
|
||||
for(a=0; a<8; a++) {
|
||||
@ -1374,22 +1375,10 @@ int clip_render_object(ObjectInstanceRen *obi, float *bounds, float winmat[][4])
|
||||
if(vec[2] < -vec[3]) fl |= 16;
|
||||
if(vec[2] > vec[3]) fl |= 32;
|
||||
|
||||
#if 0
|
||||
max= vec[3];
|
||||
min= -vec[3];
|
||||
|
||||
wco= ho[3];
|
||||
if(vec[0] < min) fl |= 1;
|
||||
if(vec[0] > max) fl |= 2;
|
||||
if(vec[1] < min) fl |= 4;
|
||||
if(vec[1] > max) fl |= 8;
|
||||
#endif
|
||||
|
||||
flag &= fl;
|
||||
if(flag==0) return 0;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -750,12 +750,13 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand
|
||||
ZSpan zspan;
|
||||
StrandRen *strand=0;
|
||||
StrandVert *svert;
|
||||
StrandBound *sbound;
|
||||
StrandPart spart;
|
||||
StrandSegment sseg;
|
||||
StrandSortSegment *sortsegments = NULL, *sortseg, *firstseg;
|
||||
MemArena *memarena;
|
||||
float z[4], bounds[4], winmat[4][4];
|
||||
int a, b, i, totsegment, clip[4];
|
||||
int a, b, c, i, totsegment, clip[4];
|
||||
|
||||
if(re->test_break())
|
||||
return 0;
|
||||
@ -800,58 +801,66 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand
|
||||
sortseg= sortsegments;
|
||||
totsegment= 0;
|
||||
|
||||
/* for all object instances */
|
||||
for(obi=re->instancetable.first, i=0; obi; obi=obi->next, i++) {
|
||||
obr= obi->obr;
|
||||
|
||||
if(!obr->strandbuf || !(obr->strandbuf->lay & rl->lay))
|
||||
continue;
|
||||
|
||||
/* compute matrix and try clipping whole object */
|
||||
if(obi->flag & R_TRANSFORMED)
|
||||
zbuf_make_winmat(re, obi->mat, winmat);
|
||||
else
|
||||
zbuf_make_winmat(re, NULL, winmat);
|
||||
|
||||
for(a=0; a<obr->totstrand; a++) {
|
||||
if((a & 255)==0) strand= obr->strandnodes[a>>8].strand;
|
||||
else strand++;
|
||||
if(clip_render_object(obi->obr->boundbox, bounds, winmat))
|
||||
continue;
|
||||
|
||||
if(re->test_break())
|
||||
break;
|
||||
|
||||
if(!(strand->buffer->lay & rl->lay))
|
||||
/* for each bounding box containing a number of strands */
|
||||
sbound= obr->strandbuf->bound;
|
||||
for(c=0; c<obr->strandbuf->totbound; c++, sbound++) {
|
||||
if(clip_render_object(sbound->boundbox, bounds, winmat))
|
||||
continue;
|
||||
|
||||
svert= strand->vert;
|
||||
/* for each strand in this bounding box */
|
||||
for(a=sbound->start; a<sbound->end; a++) {
|
||||
strand= RE_findOrAddStrand(obr, a);
|
||||
svert= strand->vert;
|
||||
|
||||
/* keep clipping and z depth for 4 control points */
|
||||
clip[1]= strand_test_clip(winmat, &zspan, bounds, svert->co, &z[1]);
|
||||
clip[2]= strand_test_clip(winmat, &zspan, bounds, (svert+1)->co, &z[2]);
|
||||
clip[0]= clip[1]; z[0]= z[1];
|
||||
|
||||
for(b=0; b<strand->totvert-1; b++, svert++) {
|
||||
/* compute 4th point clipping and z depth */
|
||||
if(b < strand->totvert-2) {
|
||||
clip[3]= strand_test_clip(winmat, &zspan, bounds, (svert+2)->co, &z[3]);
|
||||
}
|
||||
else {
|
||||
clip[3]= clip[2]; z[3]= z[2];
|
||||
}
|
||||
|
||||
/* check clipping and add to sortsegments buffer */
|
||||
if(!(clip[0] & clip[1] & clip[2] & clip[3])) {
|
||||
sortseg= BLI_memarena_alloc(memarena, sizeof(StrandSortSegment));
|
||||
sortseg->obi= i;
|
||||
sortseg->strand= strand->index;
|
||||
sortseg->segment= b;
|
||||
|
||||
sortseg->z= 0.5f*(z[1] + z[2]);
|
||||
|
||||
sortseg->next= firstseg;
|
||||
firstseg= sortseg;
|
||||
totsegment++;
|
||||
}
|
||||
|
||||
/* shift clipping and z depth */
|
||||
/* keep clipping and z depth for 4 control points */
|
||||
clip[1]= strand_test_clip(winmat, &zspan, bounds, svert->co, &z[1]);
|
||||
clip[2]= strand_test_clip(winmat, &zspan, bounds, (svert+1)->co, &z[2]);
|
||||
clip[0]= clip[1]; z[0]= z[1];
|
||||
clip[1]= clip[2]; z[1]= z[2];
|
||||
clip[2]= clip[3]; z[2]= z[3];
|
||||
|
||||
for(b=0; b<strand->totvert-1; b++, svert++) {
|
||||
/* compute 4th point clipping and z depth */
|
||||
if(b < strand->totvert-2) {
|
||||
clip[3]= strand_test_clip(winmat, &zspan, bounds, (svert+2)->co, &z[3]);
|
||||
}
|
||||
else {
|
||||
clip[3]= clip[2]; z[3]= z[2];
|
||||
}
|
||||
|
||||
/* check clipping and add to sortsegments buffer */
|
||||
if(!(clip[0] & clip[1] & clip[2] & clip[3])) {
|
||||
sortseg= BLI_memarena_alloc(memarena, sizeof(StrandSortSegment));
|
||||
sortseg->obi= i;
|
||||
sortseg->strand= strand->index;
|
||||
sortseg->segment= b;
|
||||
|
||||
sortseg->z= 0.5f*(z[1] + z[2]);
|
||||
|
||||
sortseg->next= firstseg;
|
||||
firstseg= sortseg;
|
||||
totsegment++;
|
||||
}
|
||||
|
||||
/* shift clipping and z depth */
|
||||
clip[0]= clip[1]; z[0]= z[1];
|
||||
clip[1]= clip[2]; z[1]= z[2];
|
||||
clip[2]= clip[3]; z[2]= z[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -973,3 +982,12 @@ void free_strand_surface(Render *re)
|
||||
BLI_freelistN(&re->strandsurface);
|
||||
}
|
||||
|
||||
void strand_minmax(StrandRen *strand, float *min, float *max)
|
||||
{
|
||||
StrandVert *svert;
|
||||
int a;
|
||||
|
||||
for(a=0, svert=strand->vert; a<strand->totvert; a++, svert++)
|
||||
DO_MINMAX(svert->co, min, max)
|
||||
}
|
||||
|
||||
|
@ -2081,6 +2081,9 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*,
|
||||
else
|
||||
zbuf_make_winmat(&R, NULL, winmat);
|
||||
|
||||
if(clip_render_object(obi->obr->boundbox, bounds, winmat))
|
||||
continue;
|
||||
|
||||
zbuf_project_cache_clear(cache, obr->totvert);
|
||||
|
||||
for(v=0; v<obr->totvlak; v++) {
|
||||
@ -2337,8 +2340,9 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int
|
||||
StrandSegment sseg;
|
||||
StrandRen *strand= NULL;
|
||||
StrandVert *svert;
|
||||
StrandBound *sbound;
|
||||
float obwinmat[4][4], ho1[4], ho2[4], ho3[4], ho4[4];
|
||||
int a, b, i, c1, c2, c3, c4, ok=1, lay= -1;
|
||||
int a, b, c, i, c1, c2, c3, c4, ok=1, lay= -1;
|
||||
|
||||
if(lar->mode & LA_LAYER) lay= lar->lay;
|
||||
|
||||
@ -2374,6 +2378,9 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int
|
||||
else
|
||||
Mat4CpyMat4(obwinmat, winmat);
|
||||
|
||||
if(clip_render_object(obi->obr->boundbox, NULL, obwinmat))
|
||||
continue;
|
||||
|
||||
zbuf_project_cache_clear(cache, obr->totvert);
|
||||
|
||||
/* faces */
|
||||
@ -2417,45 +2424,54 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int
|
||||
}
|
||||
|
||||
/* strands */
|
||||
for(a=0; a<obr->totstrand; a++) {
|
||||
if((a & 255)==0) strand= obr->strandnodes[a>>8].strand;
|
||||
else strand++;
|
||||
if(obr->strandbuf) {
|
||||
/* for each bounding box containing a number of strands */
|
||||
sbound= obr->strandbuf->bound;
|
||||
for(c=0; c<obr->strandbuf->totbound; c++, sbound++) {
|
||||
if(clip_render_object(sbound->boundbox, NULL, obwinmat))
|
||||
continue;
|
||||
|
||||
sseg.obi= obi;
|
||||
sseg.buffer= strand->buffer;
|
||||
sseg.sqadaptcos= sseg.buffer->adaptcos;
|
||||
sseg.sqadaptcos *= sseg.sqadaptcos;
|
||||
sseg.strand= strand;
|
||||
svert= strand->vert;
|
||||
/* for each strand in this bounding box */
|
||||
for(a=sbound->start; a<sbound->end; a++) {
|
||||
strand= RE_findOrAddStrand(obr, a);
|
||||
|
||||
/* note, these conditions are copied in shadowbuf_autoclip() */
|
||||
if(sseg.buffer->ma!= ma) {
|
||||
ma= sseg.buffer->ma;
|
||||
ok= 1;
|
||||
if((ma->mode & MA_SHADBUF)==0) ok= 0;
|
||||
}
|
||||
sseg.obi= obi;
|
||||
sseg.buffer= strand->buffer;
|
||||
sseg.sqadaptcos= sseg.buffer->adaptcos;
|
||||
sseg.sqadaptcos *= sseg.sqadaptcos;
|
||||
sseg.strand= strand;
|
||||
svert= strand->vert;
|
||||
|
||||
if(ok && (sseg.buffer->lay & lay)) {
|
||||
zbuf_project_cache_clear(cache, strand->totvert);
|
||||
/* note, these conditions are copied in shadowbuf_autoclip() */
|
||||
if(sseg.buffer->ma!= ma) {
|
||||
ma= sseg.buffer->ma;
|
||||
ok= 1;
|
||||
if((ma->mode & MA_SHADBUF)==0) ok= 0;
|
||||
}
|
||||
|
||||
for(b=0; b<strand->totvert-1; b++, svert++) {
|
||||
sseg.v[0]= (b > 0)? (svert-1): svert;
|
||||
sseg.v[1]= svert;
|
||||
sseg.v[2]= svert+1;
|
||||
sseg.v[3]= (b < strand->totvert-2)? svert+2: svert+1;
|
||||
if(ok && (sseg.buffer->lay & lay)) {
|
||||
zbuf_project_cache_clear(cache, strand->totvert);
|
||||
|
||||
c1= zbuf_shadow_project(cache, sseg.v[0]-strand->vert, obwinmat, sseg.v[0]->co, ho1);
|
||||
c2= zbuf_shadow_project(cache, sseg.v[1]-strand->vert, obwinmat, sseg.v[1]->co, ho2);
|
||||
c3= zbuf_shadow_project(cache, sseg.v[2]-strand->vert, obwinmat, sseg.v[2]->co, ho3);
|
||||
c4= zbuf_shadow_project(cache, sseg.v[3]-strand->vert, obwinmat, sseg.v[3]->co, ho4);
|
||||
for(b=0; b<strand->totvert-1; b++, svert++) {
|
||||
sseg.v[0]= (b > 0)? (svert-1): svert;
|
||||
sseg.v[1]= svert;
|
||||
sseg.v[2]= svert+1;
|
||||
sseg.v[3]= (b < strand->totvert-2)? svert+2: svert+1;
|
||||
|
||||
if(!(c1 & c2 & c3 & c4))
|
||||
render_strand_segment(re, winmat, NULL, &zspan, 1, &sseg);
|
||||
c1= zbuf_shadow_project(cache, sseg.v[0]-strand->vert, obwinmat, sseg.v[0]->co, ho1);
|
||||
c2= zbuf_shadow_project(cache, sseg.v[1]-strand->vert, obwinmat, sseg.v[1]->co, ho2);
|
||||
c3= zbuf_shadow_project(cache, sseg.v[2]-strand->vert, obwinmat, sseg.v[2]->co, ho3);
|
||||
c4= zbuf_shadow_project(cache, sseg.v[3]-strand->vert, obwinmat, sseg.v[3]->co, ho4);
|
||||
|
||||
if(!(c1 & c2 & c3 & c4))
|
||||
render_strand_segment(re, winmat, NULL, &zspan, 1, &sseg);
|
||||
}
|
||||
}
|
||||
|
||||
if((a & 255)==255 && re->test_break())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if((a & 255)==255 && re->test_break())
|
||||
break;
|
||||
}
|
||||
|
||||
if(re->test_break())
|
||||
@ -2599,6 +2615,9 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo
|
||||
else
|
||||
zbuf_make_winmat(&R, NULL, winmat);
|
||||
|
||||
if(clip_render_object(obi->obr->boundbox, bounds, winmat))
|
||||
continue;
|
||||
|
||||
zbuf_project_cache_clear(cache, obr->totvert);
|
||||
|
||||
for(v=0; v<obr->totvlak; v++) {
|
||||
@ -3286,7 +3305,6 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un
|
||||
/* to center the sample position */
|
||||
zspan->zofsx -= 0.5f;
|
||||
zspan->zofsy -= 0.5f;
|
||||
|
||||
}
|
||||
|
||||
/* we use this to test if nothing was filled in */
|
||||
@ -3303,6 +3321,9 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un
|
||||
else
|
||||
zbuf_make_winmat(&R, NULL, winmat);
|
||||
|
||||
if(clip_render_object(obi->obr->boundbox, bounds, winmat))
|
||||
continue;
|
||||
|
||||
zbuf_project_cache_clear(cache, obr->totvert);
|
||||
|
||||
for(v=0; v<obr->totvlak; v++) {
|
||||
|
Loading…
Reference in New Issue
Block a user