Area lights and more...

- New lamp type added "Area". This uses the radiosity formula (Stoke) to
  calculate the amount of energy which is received from a plane. Result
  is very nice local light, which nicely spreads out.
- Area lamps have a 'gamma' option to control the light spread
- Area lamp builtin sizes: square, rect, cube & box. Only first 2 are
  implemented. Set a type, and define area size
- Button area size won't affect the amount of energy. But scaling the lamp
  in 3d window will do. This is to cover the case when you scale an entire
  scene, the light then will remain identical
  If you just want to change area lamp size, use buttons when you dont want
  to make the scene too bright or too dark
- Since area lights realistically are sensitive for distance (quadratic), the
  effect it has is quickly too much, or too less. For this the "Dist" value
  in Lamp can be used. Set it at Dist=10 to have reasonable light on distance
  10 Blender units (assumed you didnt scale lamp object).
- I tried square sized specularity, but this looked totally weird. Not
  committed
- Plan is to extend area light with 3d dimensions, boxes and cubes.
- Note that area light is one-sided, towards negative Z. I need to design
  a nice drawing method for it.

Area Shadow

- Since there are a lot of variables associated with soft shadow, they now
  only are available for Area lights. Allowing spot & normal lamp to have
  soft shadow is possible though, but will require a reorganisation of the
  Lamp buttons. Is a point of research & feedback still.
- Apart from area size, you now can individually set amount of samples in
  X and Y direction (for area lamp type 'Rect'). For box type area lamp,
  this will become 3 dimensions
- Area shadows have four options:
  "Clip circle" : only uses a circular shape of samples, gives smoother
  results
  "Dither" : use a 2x2 dither mask
  "Jitter" : applys a pseudo-random offset to samples
  "Umbra" : extra emphasis on area that's fully in shadow.

Raytrace speedup

- improved filling in faces in Octree. Large faces occupied too many nodes
- added a coherence check; rays fired sequentially that begin and end in
  same octree nodes, and that don't intersect, are quickly rejected
- rendering shadow scenes benefits from this 20-40%. My statue test monkey
  file now renders in 19 seconds (was 30).

Plus:

- adjusted specular max to 511, and made sure Blinn spec has again this
  incredible small spec size
- for UI rounded theme: the color "button" displayed RGB color too dark
- fixed countall() function, to also include Subsurf totals
- removed setting the 'near' clipping for pressing dot-key numpad
- when you press the buttons-window icon for 'Shading Context' the context
  automaticilly switches as with F5 hotkey

Please be warned that this is not a release... settings in files might not
work as it did, nor guaranteed to work when we do a release. :)
This commit is contained in:
Ton Roosendaal 2003-12-29 16:52:51 +00:00
parent 65aeef11e1
commit 3ce1dc9065
19 changed files with 504 additions and 227 deletions

@ -434,20 +434,22 @@ void *add_lamp(void)
la= alloc_libblock(&G.main->lamp, ID_LA, "Lamp");
la->r= la->g= la->b= 1.0;
la->r= la->g= la->b= la->k= 1.0;
la->haint= la->energy= 1.0;
la->dist= 20.0f;
la->spotsize= 45.0f;
la->spotblend= 0.15f;
la->att2= 1.0f;
la->dist= 20.0;
la->spotsize= 45.0;
la->spotblend= 0.15;
la->att2= 1.0;
la->mode= LA_SHAD;
la->bufsize= 512;
la->clipsta= 0.5f;
la->clipend= 40.0f;
la->shadspotsize= 45.0f;
la->clipsta= 0.5;
la->clipend= 40.0;
la->shadspotsize= 45.0;
la->samp= 3;
la->bias= 1.0f;
la->soft= 3.0f;
la->bias= 1.0;
la->soft= 3.0;
la->ray_samp= la->ray_sampy= la->ray_sampz= 1;
la->area_size=la->area_sizey=la->area_sizez= 1.0;
return la;
}

@ -3928,6 +3928,8 @@ static void do_versions(Main *main)
if(main->versionfile <= 231) {
Material *ma= main->mat.first;
Scene *sce;
Lamp *la;
while(ma) {
if(ma->fresnel_tra_i==0.0) ma->fresnel_tra_i= 1.25;
if(ma->fresnel_mir_i==0.0) ma->fresnel_mir_i= 1.25;
@ -3950,6 +3952,17 @@ static void do_versions(Main *main)
if(sce->r.gauss==0.0) sce->r.gauss= 1.0;
sce= sce->id.next;
}
la= main->lamp.first;
while(la) {
if(la->k==0.0) la->k= 1.0;
if(la->ray_samp==0) la->ray_samp= 1;
if(la->ray_sampy==0) la->ray_sampy= 1;
if(la->ray_sampz==0) la->ray_sampz= 1;
if(la->area_size==0.0) la->area_size= 1.0;
if(la->area_sizey==0.0) la->area_sizey= 1.0;
if(la->area_sizez==0.0) la->area_sizez= 1.0;
la= la->id.next;
}
}
/* don't forget to set version number in blender.c! */
}

@ -323,6 +323,7 @@
#define B_MATCOPY 403
#define B_MATPASTE 404
#define B_MESHTYPE 405
#define B_CONTEXT_SWITCH 406
/* IMASEL: 450 */
/* in imasel.h */

@ -107,6 +107,7 @@ void test_actionpoin_but(char *name, ID **idpp);
void test_obcurpoin_but(char *name, ID **idpp);
void test_idbutton_cb(void *namev, void *arg2_unused);
void butspace_context_switch(SpaceButs *buts, struct Base *new);
/* -------------- internal event defines ------------ */

@ -48,8 +48,7 @@
#define UI_MOUSE_OVER 2
#define UI_ACTIVE 4
#define UI_HAS_ICON 8
/* definitions for icons (and their alignment) in buttons */
/* warn: rest of uiBut->flag in BIF_interface.c */
/* block->frontbuf: (only internal here), to nice localize the old global var uiFrontBuf */

@ -56,8 +56,9 @@ typedef struct Lamp {
float clipsta, clipend, shadspotsize;
float bias, soft;
short ray_samp, pad;
float ray_soft;
short ray_samp, ray_sampy, ray_sampz, ray_samp_type;
short area_shape, pad;
float area_size, area_sizey, area_sizez;
/* texact is for buttons */
short texact, shadhalostep;
@ -75,6 +76,7 @@ typedef struct Lamp {
#define LA_SUN 1
#define LA_SPOT 2
#define LA_HEMI 3
#define LA_AREA 4
/* mode */
#define LA_SHAD 1
@ -87,12 +89,23 @@ typedef struct Lamp {
#define LA_SQUARE 128
#define LA_TEXTURE 256
#define LA_OSATEX 512
/* use bit 11 for shadow tests... temp only -nzc- */
#define LA_DEEP_SHADOW 1024
#define LA_NO_DIFF 2048
#define LA_NO_SPEC 4096
#define LA_SHAD_RAY 8192
/* area shape */
#define LA_AREA_SQUARE 0
#define LA_AREA_RECT 1
#define LA_AREA_CUBE 2
#define LA_AREA_BOX 3
/* ray_samp_type */
#define LA_SAMP_ROUND 1
#define LA_SAMP_UMBRA 2
#define LA_SAMP_DITHER 4
#define LA_SAMP_JITTER 8
/* mapto */
#define LAMAP_COL 1

@ -224,7 +224,7 @@ typedef struct LampRen
float xs, ys, dist;
float co[3];
short type, mode;
float r, g, b;
float r, g, b, k;
float energy, haint;
int lay;
float spotsi,spotbl;
@ -249,19 +249,19 @@ typedef struct LampRen
/** A small depth offset to prevent self-shadowing. */
float bias;
float ray_soft;
short ray_samp;
short ray_samp, ray_sampy, ray_sampz, ray_samp_type, area_shape, ray_totsamp;
float area_size, area_sizey, area_sizez;
/** If the lamp casts shadows, one of these is filled. For the old
* renderer, shb is used, for the new pipeline the shadowBufOb,
* which should be a shadowbuffer handle. */
struct ShadBuf *shb;
void* shadowBufOb;
float *jitter;
float imat[3][3];
float spottexfac;
float sh_invcampos[3], sh_zfac; /* sh_= spothalo */
float mat[3][3]; /* 3x3 part from lampmat x viewmat */
float area[8][3], areasize;
struct LampRen *org;
struct MTex *mtex[8];
} LampRen;

@ -58,6 +58,11 @@
#define DEPTH_SHADOW_TRA 10
/* vector defines */
#define VECADD(dest, v1, v2) dest[0]= v1[0]+v2[0];dest[1]= v1[1]+v2[1];dest[2]= v1[2]+v2[2]
#define VECSUB(dest, v1, v2) dest[0]= v1[0]-v2[0];dest[1]= v1[1]-v2[1];dest[2]= v1[2]-v2[2]
/* ********** structs *************** */
typedef struct Octree {
@ -72,10 +77,10 @@ typedef struct Octree {
} Octree;
typedef struct Isect {
float start[3], end[3];
float start[3], vec[3], end[3]; /* start+vec = end, in d3dda */
float labda, u, v;
struct VlakRen *vlr, *vlrcontr, *vlrorig;
short isect, mode; /* mode: DDA_SHADOW or DDA_MIRROR or DDA_SHADOW_TRA */
short isect, mode; /* isect: which half of quad, mode: DDA_SHADOW, DDA_MIRROR, DDA_SHADOW_TRA */
float ddalabda;
float col[4]; /* RGBA for shadow_tra */
} Isect;
@ -424,7 +429,7 @@ void freeoctree(void)
printf("branches %d nodes %d\n", branchcount, nodecount);
printf("raycount %d \n", raycount);
// printf("ray coherent %d \n", coherent_ray);
printf("ray coherent %d \n", coherent_ray);
// printf("accepted %d rejected %d\n", accepted, rejected);
branchcount= 0;
@ -656,7 +661,7 @@ static short intersection(Isect *is)
{
VertRen *v1,*v2,*v3,*v4=NULL;
float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22,r0,r1,r2;
float m0, m1, m2, divdet, det, det1;
float m0, m1, m2, divdet, det1;
static short vlrisect=0;
short ok=0;
@ -677,13 +682,13 @@ static short intersection(Isect *is)
t11= v3->co[1]-v2->co[1];
t12= v3->co[2]-v2->co[2];
r0= is->start[0]-is->end[0];
r1= is->start[1]-is->end[1];
r2= is->start[2]-is->end[2];
r0= is->vec[0];
r1= is->vec[1];
r2= is->vec[2];
x0= t11*r2-t12*r1;
x1= t12*r0-t10*r2;
x2= t10*r1-t11*r0;
x0= t12*r1-t11*r2;
x1= t10*r2-t12*r0;
x2= t11*r0-t10*r1;
divdet= t00*x0+t01*x1+t02*x2;
@ -693,21 +698,21 @@ static short intersection(Isect *is)
det1= m0*x0+m1*x1+m2*x2;
if(divdet!=0.0) {
float u= det1/divdet;
float u;
if(u<0.0) {
float v;
det= t00*(m1*r2-m2*r1);
det+= t01*(m2*r0-m0*r2);
det+= t02*(m0*r1-m1*r0);
v= det/divdet;
divdet= 1.0/divdet;
u= det1*divdet;
if(u<0.0 && u>-1.0) {
float v, cros0, cros1, cros2;
cros0= m1*t02-m2*t01;
cros1= m2*t00-m0*t02;
cros2= m0*t01-m1*t00;
v= divdet*(cros0*r0 + cros1*r1 + cros2*r2);
if(v<0.0 && (u + v) > -1.0) {
float labda;
det= m0*(t12*t01-t11*t02);
det+= m1*(t10*t02-t12*t00);
det+= m2*(t11*t00-t10*t01);
labda= det/divdet;
labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12);
if(labda>0.0 && labda<1.0) {
is->labda= labda;
@ -726,21 +731,20 @@ static short intersection(Isect *is)
divdet= t20*x0+t21*x1+t22*x2;
if(divdet!=0.0) {
float u= det1/divdet;
float u;
divdet= 1.0/divdet;
u = det1*divdet;
if(u<0.0) {
float v;
det= t20*(m1*r2-m2*r1);
det+= t21*(m2*r0-m0*r2);
det+= t22*(m0*r1-m1*r0);
v= det/divdet;
if(u<0.0 && u>-1.0) {
float v, cros0, cros1, cros2;
cros0= m1*t22-m2*t21;
cros1= m2*t20-m0*t22;
cros2= m0*t21-m1*t20;
v= divdet*(cros0*r0 + cros1*r1 + cros2*r2);
if(v<0.0 && (u + v) > -1.0) {
float labda;
det= m0*(t12*t21-t11*t22);
det+= m1*(t10*t22-t12*t20);
det+= m2*(t11*t20-t10*t21);
labda= det/divdet;
labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12);
if(labda>0.0 && labda<1.0) {
ok= 2;
@ -786,7 +790,7 @@ static short intersection(Isect *is)
if(is->vlrcontr==NULL) {
is->vlrcontr= vlr;
vlrisect= intersection2(vlr, r0, r1, r2, is->start[0], is->start[1], is->start[2]);
vlrisect= intersection2(vlr, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2]);
}
if(vlrisect) return 1;
@ -966,6 +970,7 @@ static short cliptest(float p, float q, float *u1, float *u2)
return 1;
}
/* return 1: found valid intersection */
/* starts with is->vlrorig */
static int d3dda(Isect *is)
@ -975,7 +980,7 @@ static int d3dda(Isect *is)
float labdao,labdax,ldx,labday,ldy,labdaz,ldz, ddalabda;
float vec1[3], vec2[3];
int dx,dy,dz;
int xo,yo,zo,c1=0; //, testcoh=0;
int xo,yo,zo,c1=0;
int ocx1,ocx2,ocy1, ocy2,ocz1,ocz2;
/* clip with octree */
@ -986,9 +991,11 @@ static int d3dda(Isect *is)
is->vlrorig->raycount= raycount;
is->vlrcontr= NULL; /* to check shared edge */
/* only for shadow! */
if(is->mode==DDA_SHADOW && g_oc.vlr_last!=NULL && g_oc.vlr_last!=is->vlrorig) {
is->vlr= g_oc.vlr_last;
VECSUB(is->vec, is->end, is->start);
if(intersection(is)) return 1;
}
@ -1043,24 +1050,39 @@ static int d3dda(Isect *is)
ocy2= (int)oy2;
ocz2= (int)oz2;
if(ocx1==ocx2 && ocy1==ocy2 && ocz1==ocz2) {
/* no calc, this is store */
calc_ocval_ray(NULL, ox1, oy1, oz1, ox2, oy2, oz2);
/* for intersection */
VECSUB(is->vec, is->end, is->start);
if(ocx1==ocx2 && ocy1==ocy2 && ocz1==ocz2) {
no= ocread(ocx1, ocy1, ocz1);
if(no) {
/* no calc, this is store */
calc_ocval_ray(NULL, ox1, oy1, oz1, ox2, oy2, oz2);
is->ddalabda= 1.0;
if( testnode(is, no, ocx1, ocy1, ocz1) ) return 1;
}
}
else {
static int coh_ocx1,coh_ocx2,coh_ocy1, coh_ocy2,coh_ocz1,coh_ocz2;
static int coh_test=0;
float dox, doy, doz;
int coherent=1, nodecount=0;
/* check coherence;
coh_test: 0=don't, 1=check
coherent: for current ray
*/
if(coh_test) {
if(coh_ocx1==ocx1 && coh_ocy1==ocy1 && coh_ocz1==ocz1
&& coh_ocx2==ocx2 && coh_ocy2==ocy2 && coh_ocz2==ocz2);
else coh_test= 0;
}
/* calc labda en ld */
dox= ox1-ox2;
doy= oy1-oy2;
doz= oz1-oz2;
/* calc labda en ld */
if(dox!=0.0) {
if(dox<0.0) {
labdax= (ox1-ocx1-1.0)/dox;
@ -1112,7 +1134,6 @@ static int d3dda(Isect *is)
xo=ocx1; yo=ocy1; zo=ocz1;
ddalabda= MIN3(labdax,labday,labdaz);
// dox,y,z is negative
vec2[0]= ox1;
vec2[1]= oy1;
vec2[2]= oz1;
@ -1123,9 +1144,9 @@ static int d3dda(Isect *is)
while(TRUE) {
no= ocread(xo, yo, zo);
nodecount++;
if(no) {
//if(xo==ocx1 && yo==ocy1 && zo==ocz1);
//else testcoh= 1;
if(nodecount>2) coherent= 0;
/* calculate ray intersection with octree node */
VECCOPY(vec1, vec2);
@ -1139,6 +1160,10 @@ static int d3dda(Isect *is)
is->ddalabda= ddalabda;
if( testnode(is, no, xo,yo,zo) ) return 1;
}
else if(coh_test) {
coherent_ray++;
return 0;
}
labdao= ddalabda;
@ -1188,7 +1213,12 @@ static int d3dda(Isect *is)
/* to make sure the last node is always checked */
if(labdao>=1.0) break;
}
//if(testcoh==0) coherent_ray++;
if(coherent) {
coh_test= 1;
coh_ocx1= ocx1; coh_ocy1= ocy1;coh_ocz1= ocz1;
coh_ocx2= ocx2; coh_ocy2= ocy2;coh_ocz2= ocz2;
}
else coh_test= 0;
}
/* reached end, no intersections found */
@ -1203,7 +1233,7 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr, int mask)
int flip= 0;
/* set up view vector */
VecSubf(shi->view, is->end, is->start);
VECCOPY(shi->view, is->vec);
/* render co */
shi->co[0]= is->start[0]+is->labda*(shi->view[0]);
@ -1306,25 +1336,25 @@ static void calc_dx_dy_refract(float *ref, float *n, float *view, float index, i
dview[2]= view[2];
if(smooth) {
VecAddf(dnor, n, O.dxno);
VECADD(dnor, n, O.dxno);
refraction(dref, dnor, dview, index);
}
else {
refraction(dref, n, dview, index);
}
VecSubf(O.dxrefract, ref, dref);
VECSUB(O.dxrefract, ref, dref);
dview[0]= view[0];
dview[1]= view[1]+ O.dyview;
if(smooth) {
VecAddf(dnor, n, O.dyno);
VECADD(dnor, n, O.dyno);
refraction(dref, dnor, dview, index);
}
else {
refraction(dref, n, dview, index);
}
VecSubf(O.dyrefract, ref, dref);
VECSUB(O.dyrefract, ref, dref);
}
@ -1468,59 +1498,64 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen
/* **************** jitter blocks ********** */
static float jit_plane2[2*2*3]={0.0};
static float jit_plane3[3*3*3]={0.0};
static float jit_plane4[4*4*3]={0.0};
static float jit_plane5[5*5*3]={0.0};
static float jit_plane6[5*5*3]={0.0};
static float jit_plane7[7*7*3]={0.0};
static float jit_plane8[8*8*3]={0.0};
static float jit_cube2[2*2*2*3]={0.0};
static float jit_cube3[3*3*3*3]={0.0};
static float jit_cube4[4*4*4*3]={0.0};
static float jit_cube5[5*5*5*3]={0.0};
/* table around origin, -.5 to 0.5 */
static float *jitter_plane(int resol)
static float *jitter_plane(LampRen *lar)
{
extern float hashvectf[];
extern char hash[];
extern int temp_x, temp_y;
static int offs=0;
float dsize, *jit, *fp, *hv;
int x, y;
float dsizex, dsizey, *fp, *hv;
int dit, x, y, resolx, resoly;
if(resol<2) resol= 2;
if(resol>8) resol= 8;
resolx= lar->ray_samp;
resoly= lar->ray_sampy;
switch (resol) {
case 2: jit= jit_plane2; break;
case 3: jit= jit_plane3; break;
case 4: jit= jit_plane4; break;
case 5: jit= jit_plane5; break;
case 6: jit= jit_plane6; break;
case 7: jit= jit_plane7; break;
default: jit= jit_plane8; break;
if(lar->jitter==NULL) {
fp=lar->jitter= MEM_mallocN(4*resolx*resoly*3*sizeof(float), "lamp jitter tab");
/* size of subpixel */
if(resolx>1) dsizex= 1.0/(resolx-1.0); else dsizex= 0.0;
if(resoly>1) dsizey= 1.0/(resoly-1.0); else dsizey= 0.0;
for(dit=0; dit<4; dit++) {
hv= hashvectf;
for(x=0; x<resolx; x++) {
for(y=0; y<resoly; y++, fp+= 3, hv+=3) {
// exact location
fp[0]= -0.5 + x*dsizex; if(dit & 1) fp[0]+= 0.5*dsizex;
fp[1]= -0.5 + y*dsizey; if(dit<2) fp[1]+= 0.5*dsizey;
// jitter
if(lar->ray_samp_type & LA_SAMP_JITTER) {
fp[0]+= 0.5*dsizex*hv[0];
fp[1]+= 0.5*dsizey*hv[1];
}
//if(jit[0]!=0.0) return jit;
offs++;
dsize= 1.0/(resol-1.0);
fp= jit;
hv= hashvectf+3*(hash[ (temp_x&3)+4*(temp_y&3) ]);
for(x=0; x<resol; x++) {
for(y=0; y<resol; y++, fp+= 3, hv+=3) {
fp[0]= -0.5 + (x+0.5*hv[0])*dsize;
fp[1]= -0.5 + (y+0.5*hv[1])*dsize;
// distance check
if(lar->ray_samp_type & LA_SAMP_ROUND) {
fp[2]= fp[0]*fp[0] + fp[1]*fp[1];
if(resol>2)
if(fp[2]>0.3) fp[2]= 0.0;
if(resolx>2 && resoly>2 && fp[2]>0.6) fp[2]= 0.0;
else fp[2]= 1.0;
}
else fp[2]= 1.0;
fp[0]*= lar->area_size;
fp[1]*= lar->area_sizey;
}
}
}
}
return jit;
if(lar->ray_samp_type & LA_SAMP_DITHER)
return lar->jitter + 3*resolx*resoly*((temp_x & 1)+2*(temp_y & 1));
return lar->jitter;
}
static void *jitter_cube(int resol)
@ -1588,11 +1623,9 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr, int mask)
for(j=0; j<R.osa; j++) {
if(mask & 1<<j) {
if(do_tra || do_mir) {
rco[0]= shi->co[0] + (jit[j][0]-0.5)*O.dxco[0] + (jit[j][1]-0.5)*O.dyco[0];
rco[1]= shi->co[1] + (jit[j][0]-0.5)*O.dxco[1] + (jit[j][1]-0.5)*O.dyco[1];
rco[2]= shi->co[2] + (jit[j][0]-0.5)*O.dxco[2] + (jit[j][1]-0.5)*O.dyco[2];
}
if(do_tra) {
vec[0]= refract[0] + (jit[j][0]-0.5)*O.dxrefract[0] + (jit[j][1]-0.5)*O.dyrefract[0] ;
@ -1601,7 +1634,7 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr, int mask)
traceray(shi->matren->ray_depth_tra, rco, vec, tracol, shi->vlr, mask);
VecAddf(accur, accur, tracol);
VECADD(accur, accur, tracol);
divr+= 1.0;
}
@ -1623,7 +1656,7 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr, int mask)
/* result in accum, this is copied to shade_lamp_loop */
traceray(shi->matren->ray_depth, rco, vec, mircol, shi->vlr, 1<<j);
VecAddf(accum, accum, mircol);
VECADD(accum, accum, mircol);
div+= 1.0;
}
}
@ -1821,7 +1854,8 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac, int mask)
VECCOPY(lampco, lar->co);
}
if(lar->ray_samp<2) {
/* shadow and soft not implemented yet */
if(lar->ray_totsamp<2 || isec.mode == DDA_SHADOW_TRA) {
if(R.r.mode & R_OSA) {
float accum[4]={0.0, 0.0, 0.0, 0.0};
int j;
@ -1891,15 +1925,16 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac, int mask)
isec.vlrorig= shi->vlr;
fac= 0.0;
a= lar->ray_samp*lar->ray_samp;
jitlamp= jitter_plane(lar->ray_samp);
jitlamp= jitter_plane(lar);
a= lar->ray_totsamp;
while(a--) {
if(jitlamp[2]!=0.0) {
vec[0]= lar->ray_soft*jitlamp[0];
vec[1]= lar->ray_soft*jitlamp[1];
vec[0]= jitlamp[0];
vec[1]= jitlamp[1];
vec[2]= 0.0;
Mat3TransMulVecfl(lar->imat, vec);
Mat3MulVecfl(lar->mat, vec);
isec.end[0]= lampco[0]+vec[0];
isec.end[1]= lampco[1]+vec[1];
@ -1918,6 +1953,10 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac, int mask)
}
jitlamp+= 3;
}
// sqrt makes nice umbra effect
if(lar->ray_samp_type & LA_SAMP_UMBRA)
shadfac[3]= sqrt(1.0-fac/div);
else
shadfac[3]= 1.0-fac/div;
}
}

@ -1227,6 +1227,60 @@ void halovert()
/* ---------------- shaders ----------------------- */
/* Stoke's form factor */
static float area_lamp_energy(float *co, float *vn, LampRen *lar)
{
float tvec[3], fac;
float vec[4][3]; /* vectors of rendered co to vertices lamp */
float cross[4][3]; /* cross products of this */
float rad[4]; /* angles between vecs */
VecSubf(vec[0], co, lar->area[0]);
VecSubf(vec[1], co, lar->area[1]);
VecSubf(vec[2], co, lar->area[2]);
VecSubf(vec[3], co, lar->area[3]);
Normalise(vec[0]);
Normalise(vec[1]);
Normalise(vec[2]);
Normalise(vec[3]);
/* cross product */
Crossf(cross[0], vec[0], vec[1]);
Crossf(cross[1], vec[1], vec[2]);
Crossf(cross[2], vec[2], vec[3]);
Crossf(cross[3], vec[3], vec[0]);
Normalise(cross[0]);
Normalise(cross[1]);
Normalise(cross[2]);
Normalise(cross[3]);
/* angles */
rad[0]= vec[0][0]*vec[1][0]+ vec[0][1]*vec[1][1]+ vec[0][2]*vec[1][2];
rad[1]= vec[1][0]*vec[2][0]+ vec[1][1]*vec[2][1]+ vec[1][2]*vec[2][2];
rad[2]= vec[2][0]*vec[3][0]+ vec[2][1]*vec[3][1]+ vec[2][2]*vec[3][2];
rad[3]= vec[3][0]*vec[0][0]+ vec[3][1]*vec[0][1]+ vec[3][2]*vec[0][2];
rad[0]= acos(rad[0]);
rad[1]= acos(rad[1]);
rad[2]= acos(rad[2]);
rad[3]= acos(rad[3]);
/* Stoke formula */
VecMulf(cross[0], rad[0]);
VecMulf(cross[1], rad[1]);
VecMulf(cross[2], rad[2]);
VecMulf(cross[3], rad[3]);
VECCOPY(tvec, vn);
fac= tvec[0]*cross[0][0]+ tvec[1]*cross[0][1]+ tvec[2]*cross[0][2];
fac+= tvec[0]*cross[1][0]+ tvec[1]*cross[1][1]+ tvec[2]*cross[1][2];
fac+= tvec[0]*cross[2][0]+ tvec[1]*cross[2][1]+ tvec[2]*cross[2][2];
fac+= tvec[0]*cross[3][0]+ tvec[1]*cross[3][1]+ tvec[2]*cross[3][2];
return pow(fac*lar->areasize, lar->k); // corrected for buttons size and lar->dist^2
}
float spec(float inp, int hard)
{
@ -1255,8 +1309,12 @@ float spec(float inp, int hard)
if(hard & 32) inp*= b1;
b1*= b1;
if(hard & 64) inp*=b1;
b1*= b1;
if(hard & 128) inp*=b1;
if(hard & 128) {
if(b1<0.001) b1= 0.0;
if(hard & 256) {
b1*= b1;
inp*=b1;
}
@ -1297,6 +1355,7 @@ float CookTorr_Spec(float *n, float *l, float *v, int hard)
if(nh<0.0) return 0.0;
nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2];
if(nv<0.0) nv= 0.0;
i= spec(nh, hard);
i= i/(0.1+nv);
@ -1313,7 +1372,9 @@ float Blinn_Spec(float *n, float *l, float *v, float refrac, float spec_power )
if(spec_power == 0.0) return 0.0;
/* conversion from 'hardness' (1-255) to 'spec_power' (50 maps at 0.1) */
if(spec_power<100.0)
spec_power= sqrt(1.0/spec_power);
else spec_power= 10.0/spec_power;
h[0]= v[0]+l[0];
h[1]= v[1]+l[1];
@ -1395,9 +1456,9 @@ float Toon_Diff( float *n, float *l, float *v, float size, float smooth )
}
/* Oren Nayar diffuse */
float OrenNayar_Diff(float *n, float *l, float *v, float rough )
float OrenNayar_Diff_i(float nl, float *n, float *l, float *v, float rough )
{
float i, nh, nv, nl, vh, h[3];
float i, nh, nv, vh, h[3];
float a, b, t, A, B;
float Lit_A, View_A, Lit_B[3], View_B[3];
@ -1412,7 +1473,7 @@ float OrenNayar_Diff(float *n, float *l, float *v, float rough )
nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface normal and view vector */
if(nv<=0.0) nv= 0.0;
nl= n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface normal and light vector */
/* Dot product between surface normal and light vector */
if(nl<0.0) nl= 0.0;
vh= v[0]*h[0]+v[1]*h[1]+v[2]*h[2]; /* Dot product between view vector and halfway vector */
@ -1451,6 +1512,14 @@ float OrenNayar_Diff(float *n, float *l, float *v, float rough )
return i;
}
/* Oren Nayar diffuse */
float OrenNayar_Diff(float *n, float *l, float *v, float rough )
{
float nl= n[0]*l[0] + n[1]*l[1] + n[2]*l[2];
OrenNayar_Diff_i(nl, n, l, v, rough);
}
/* --------------------------------------------- */
void calc_R_ref(ShadeInput *shi)
@ -1767,6 +1836,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr, int mask)
}
/* dot product and reflectivity*/
inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2];
if(lar->mode & LA_NO_DIFF) {
@ -1776,8 +1846,16 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr, int mask)
i= 0.5*inp + 0.5;
}
else {
/* diffuse shaders */
if(ma->diff_shader==MA_DIFF_ORENNAYAR) i= OrenNayar_Diff(vn, lv, view, ma->roughness);
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, shi->vn, lar);
else inp= 0.0;
}
/* diffuse shaders (oren nayer gets inp from area light) */
if(ma->diff_shader==MA_DIFF_ORENNAYAR) i= OrenNayar_Diff_i(inp, vn, lv, view, ma->roughness);
else if(ma->diff_shader==MA_DIFF_TOON) i= Toon_Diff(vn, lv, view, ma->param[0], ma->param[1]);
else i= inp; // Lambert
}
@ -1787,7 +1865,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr, int mask)
}
/* shadow and spec */
if(inp> -0.41) { /* heuristic value */
if(lampdist> 0.0) {
if(i>0.0 && (R.r.mode & R_SHADOW)) {
if(ma->mode & MA_SHADOW) {
@ -1847,6 +1925,9 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr, int mask)
else
specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3]);
/* area lamp correction */
if(lar->type==LA_AREA) specfac*= inp;
t= shadfac[3]*ma->spec*lampdist*specfac;
shr->spec[0]+= t*(lar->r * ma->specr);

@ -1757,6 +1757,34 @@ static void init_render_mesh(Object *ob)
}
/* ------------------------------------------------------------------------- */
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 doshadbuf)
{
@ -1784,6 +1812,7 @@ void RE_add_render_lamp(Object *ob, int doshadbuf)
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;
@ -1794,9 +1823,6 @@ void RE_add_render_lamp(Object *ob, int doshadbuf)
lar->clipend = la->clipend;
lar->bias = la->bias;
lar->ray_soft= la->ray_soft;
lar->ray_samp= la->ray_samp;
lar->type= la->type;
lar->mode= la->mode;
@ -1817,6 +1843,45 @@ void RE_add_render_lamp(Object *ob, int doshadbuf)
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;
lar->spotsi= la->spotsize;
if(lar->mode & LA_HALO) {
@ -1827,7 +1892,6 @@ void RE_add_render_lamp(Object *ob, int doshadbuf)
memcpy(lar->mtex, la->mtex, 8*4);
lar->lay= ob->lay;
lar->ld1= la->att1;
@ -2698,6 +2762,7 @@ void RE_freeRotateBlenderScene(void)
MEM_freeN(R.la[a]->shb);
}
if(R.la[a]->org) MEM_freeN(R.la[a]->org);
if(R.la[a]->jitter) MEM_freeN(R.la[a]->jitter);
MEM_freeN(R.la[a]);
}
a=0;

@ -319,25 +319,8 @@ void do_butspace(unsigned short event)
else if(event>REDRAWVIEW3D) allqueue(event, 0);
}
/* new active object */
void redraw_test_buttons(Base *new)
void butspace_context_switch(SpaceButs *buts, Base *new)
{
ScrArea *sa;
SpaceButs *buts;
sa= G.curscreen->areabase.first;
while(sa) {
if(sa->spacetype==SPACE_BUTS) {
buts= sa->spacedata.first;
if(ELEM5(buts->mainb, CONTEXT_OBJECT, CONTEXT_EDITING, CONTEXT_SHADING, CONTEXT_LOGIC, CONTEXT_SCRIPT)) {
addqueue(sa->win, REDRAW, 1);
buts->re_align= 1;
}
if(buts->mainb==CONTEXT_SHADING) {
buts->re_align= 1;
// change type automatically
if(new) {
int tab= buts->tab[CONTEXT_SHADING];
@ -362,6 +345,29 @@ void redraw_test_buttons(Base *new)
else {
buts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT;
}
}
}
/* new active object */
void redraw_test_buttons(Base *new)
{
ScrArea *sa;
SpaceButs *buts;
sa= G.curscreen->areabase.first;
while(sa) {
if(sa->spacetype==SPACE_BUTS) {
buts= sa->spacedata.first;
if(ELEM5(buts->mainb, CONTEXT_OBJECT, CONTEXT_EDITING, CONTEXT_SHADING, CONTEXT_LOGIC, CONTEXT_SCRIPT)) {
addqueue(sa->win, REDRAW, 1);
buts->re_align= 1;
}
if(buts->mainb==CONTEXT_SHADING) {
buts->re_align= 1;
if(new) {
butspace_context_switch(buts, new);
BIF_preview_changed(buts);
}
}

@ -1031,7 +1031,7 @@ static void render_panel_render(void)
uiBlockBeginAlign(block);
uiDefButI(block, TOG|BIT|14, 0, "MBLUR", 495,114,66,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables Motion Blur calculation");
uiDefButF(block, NUM,B_DIFF,"Bf:", 495,90,65,20,&G.scene->r.blurfac, 0.01, 5.0, 10, 0, "Sets motion blur factor");
uiDefButF(block, NUM,B_DIFF,"Bf:", 495,90,65,20,&G.scene->r.blurfac, 0.01, 5.0, 10, 2, "Sets motion blur factor");
uiBlockBeginAlign(block);
uiDefButS(block, NUM,B_DIFF,"Xparts:", 369,42,99,31,&G.scene->r.xparts,1.0, 64.0, 0, 0, "Sets the number of horizontal parts to render image in (For panorama sets number of camera slices)");
@ -1061,7 +1061,7 @@ static void render_panel_render(void)
uiDefButI(block, TOG|BIT|7,0,"x", 665,50,20,23,&G.scene->r.mode, 0, 0, 0, 0, "Disables time difference in field calculations");
uiDefButI(block, TOG|BIT|17,0,"Gauss", 564,30,60,20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Gauss sampling filter for antialiasing");
uiDefButF(block, NUM,B_DIFF,"", 624,30,60,20,&G.scene->r.gauss,0.5, 2.0, 0, 0, "Sets the Gauss filter size)");
uiDefButF(block, NUM,B_DIFF,"", 624,30,60,20,&G.scene->r.gauss,0.5, 1.5, 100, 2, "Sets the Gauss filter size)");
uiDefButI(block, TOG|BIT|9,REDRAWVIEWCAM, "Border", 564,10,60,20, &G.scene->r.mode, 0, 0, 0, 0, "Render a small cut-out of the image");
uiDefButI(block, TOG|BIT|2,0, "Gamma", 624,10,60,20, &G.scene->r.mode, 0, 0, 0, 0, "Enable gamma correction");

@ -1646,6 +1646,7 @@ void do_lampbuts(unsigned short event)
case B_LAMPREDRAW:
BIF_preview_changed(G.buts);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSSHADING, 0);
break;
case B_TEXCLEARLAMP:
la= G.buts->lockpoin;
@ -1821,12 +1822,15 @@ static void lamp_panel_spot(Object *ob, Lamp *la)
uiBlockSetCol(block, TH_BUT_SETTING1);
uiBlockBeginAlign(block);
uiDefButS(block, TOG|BIT|13, B_SHADRAY,"Ray Shadow", 10,180,80,19,&la->mode, 0, 0, 0, 0, "Use ray tracing for shadow");
uiDefButS(block, TOG|BIT|13, B_SHADRAY,"Ray Shadow",10,180,80,19,&la->mode, 0, 0, 0, 0, "Use ray tracing for shadow");
if(la->type==LA_SPOT)
uiDefButS(block, TOG|BIT|0, B_SHADBUF, "Buf.Shadow",10,160,80,19,&la->mode, 0, 0, 0, 0, "Lets spotlight produce shadows using shadow buffer");
uiBlockEndAlign(block);
uiDefButS(block, TOG|BIT|5, 0,"OnlyShadow", 10,120,80,19,&la->mode, 0, 0, 0, 0, "Causes spotlight to cast shadows only without illuminating objects");
uiDefButS(block, TOG|BIT|7, B_LAMPREDRAW,"Square", 10,90,80,19,&la->mode, 0, 0, 0, 0, "Sets square spotbundles");
uiDefButS(block, TOG|BIT|5, 0,"OnlyShadow", 10,110,80,19,&la->mode, 0, 0, 0, 0, "Causes light to cast shadows only without illuminating objects");
if(la->type==LA_SPOT) {
uiDefButS(block, TOG|BIT|7, B_LAMPREDRAW,"Square", 10,70,80,19,&la->mode, 0, 0, 0, 0, "Sets square spotbundles");
uiDefButS(block, TOG|BIT|1, 0,"Halo", 10,50,80,19,&la->mode, 0, 0, 0, 0, "Renders spotlight with a volumetric halo");
uiBlockSetCol(block, TH_AUTO);
@ -1850,12 +1854,29 @@ static void lamp_panel_spot(Object *ob, Lamp *la)
uiDefButF(block, NUM,0,"Bias:", 100,10,100,19, &la->bias, 0.01, 5.0, 1, 0, "Sets the shadow map sampling bias");
uiDefButF(block, NUM,0,"Soft:", 200,10,100,19, &la->soft,1.0,100.0, 100, 0, "Sets the size of the shadow sample area");
}
else if(la->mode & LA_SHAD_RAY) {
uiBlockBeginAlign(block);
uiDefButS(block, NUM,0,"Samples:", 100,70,100,19, &la->ray_samp, 1,8, 100, 0, "Sets the amount of samples taken extra (samp x samp)");
uiDefButF(block, NUM,0,"Soft:", 200,70,100,19, &la->ray_soft, 0.01, 10.0, 100, 0, "Sets the size of the sampling area");
uiBlockEndAlign(block);
}
else if(la->type==LA_AREA && (la->mode & LA_SHAD_RAY)) {
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_AUTO);
if(la->area_shape==LA_AREA_SQUARE)
uiDefButS(block, NUM,0,"Samples:", 100,180,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp)");
if(la->area_shape==LA_AREA_CUBE)
uiDefButS(block, NUM,0,"Samples:", 100,160,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp x samp)");
if ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_BOX) {
uiDefButS(block, NUM,0,"SamplesX:", 100,180,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of X samples taken extra");
uiDefButS(block, NUM,0,"SamplesY:", 100,160,200,19, &la->ray_sampy, 1.0, 16.0, 100, 0, "Sets the amount of Y samples taken extra");
if(la->area_shape==LA_AREA_BOX)
uiDefButS(block, NUM,0,"SamplesZ:", 100,140,200,19, &la->ray_sampz, 1.0, 8.0, 100, 0, "Sets the amount of Z samples taken extra");
}
uiBlockBeginAlign(block);
uiDefButS(block, TOG|BIT|1, 0,"Umbra", 100,110,100,19,&la->ray_samp_type, 0, 0, 0, 0, "Emphasis parts that are fully shadowed");
uiDefButS(block, TOG|BIT|0, 0,"Clip circle", 200,110,100,19,&la->ray_samp_type, 0, 0, 0, 0, "Use circular sampling mask");
uiDefButS(block, TOG|BIT|2, 0,"Dither", 100,90,100,19,&la->ray_samp_type, 0, 0, 0, 0, "Use 2x2 dithering for sampling");
uiDefButS(block, TOG|BIT|3, 0,"Jitter", 200,90,100,19,&la->ray_samp_type, 0, 0, 0, 0, "Use jittering for sampling");
}
else uiDefBut(block, LABEL,0," ", 100,180,200,19,NULL, 0, 0, 0, 0, "");
}
@ -1882,15 +1903,32 @@ static void lamp_panel_lamp(Object *ob, Lamp *la)
xco= std_libbuttons(block, 8, 180, 0, NULL, B_LAMPBROWSE, id, (ID *)ob, &(G.buts->menunr), B_LAMPALONE, B_LAMPLOCAL, 0, 0, 0);
uiBlockSetCol(block, TH_AUTO);
uiDefButF(block, NUM,B_LAMPREDRAW,"Dist:", xco,180,300-xco,20,&la->dist, 0.01, 5000.0, 100, 0, "Sets the distance value at which light intensity is halved");
uiDefButF(block, NUM,B_LAMPREDRAW,"Dist:", xco,180,300-xco,20,&la->dist, 0.01, 100.0*grid, 100, 0, "Sets the distance value at which light intensity is half");
uiBlockBeginAlign(block);
if(la->type==LA_AREA) {
//uiDefButS(block, MENU, B_LAMPREDRAW, "Shape %t|Square %x0|Rect %x1|Cube %x2|Box %x3",
uiDefButS(block, MENU, B_LAMPREDRAW, "Shape %t|Square %x0|Rect %x1",
10, 150, 100, 19, &la->area_shape, 0,0,0,0, "Sets area light shape");
uiDefButF(block, NUM,B_LAMPREDRAW,"Size ", 10,130,100,19, &la->area_size, 0.001, 100.0, 10, 0, "Area light size, doesn't affect energy amount");
if ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_BOX)
uiDefButF(block, NUM,B_LAMPREDRAW,"SizeY ", 10,110,100,19, &la->area_sizey, 0.001, 100.0, 10, 0, "Area light size Y, doesn't affect energy amount");
if(la->area_shape==LA_AREA_BOX)
uiDefButF(block, NUM,B_LAMPREDRAW,"SizeZ ", 10,90,100,19, &la->area_sizez, 0.001, 100.0, 10, 0, "Area light size Z, doesn't affect energy amount");
}
else if ELEM(la->type, LA_LOCAL, LA_SPOT) {
uiBlockSetCol(block, TH_BUT_SETTING1);
uiDefButS(block, TOG|BIT|3, B_MATPRV,"Quad", 10,150,100,19,&la->mode, 0, 0, 0, 0, "Uses inverse quadratic proportion for light attenuation");
uiDefButS(block, TOG|BIT|6, REDRAWVIEW3D,"Sphere", 10,130,100,19,&la->mode, 0, 0, 0, 0, "Sets light intensity to zero for objects beyond the distance value");
uiDefButS(block, TOG|BIT|2, 0,"Layer", 10,90,100,19,&la->mode, 0, 0, 0, 0, "Illuminates objects in the same layer as the lamp only");
uiDefButS(block, TOG|BIT|4, B_MATPRV,"Negative", 10,70,100,19,&la->mode, 0, 0, 0, 0, "Sets lamp to cast negative light");
}
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1);
uiDefButS(block, TOG|BIT|2, 0,"Layer", 10,70,100,19,&la->mode, 0, 0, 0, 0, "Illuminates objects in the same layer as the lamp only");
uiDefButS(block, TOG|BIT|4, B_MATPRV,"Negative", 10,50,100,19,&la->mode, 0, 0, 0, 0, "Sets lamp to cast negative light");
uiDefButS(block, TOG|BIT|11, 0,"No Diffuse", 10,30,100,19,&la->mode, 0, 0, 0, 0, "Disables diffuse shading of material illuminated by this lamp");
uiDefButS(block, TOG|BIT|12, 0,"No Specular", 10,10,100,19,&la->mode, 0, 0, 0, 0, "Disables specular shading of material illuminated by this lamp");
uiBlockEndAlign(block);
uiBlockSetCol(block, TH_AUTO);
uiDefButF(block, NUMSLI,B_MATPRV,"Energy ", 120,150,180,20, &(la->energy), 0.0, 10.0, 0, 0, "Sets the intensity of the light");
@ -1904,9 +1942,14 @@ static void lamp_panel_lamp(Object *ob, Lamp *la)
uiDefButF(block, COL, B_COLLAMP, "", 120,52,180,24, &la->r, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButF(block, NUMSLI,B_MATPRV,"Quad1 ", 120,30,180,19,&la->att1, 0.0, 1.0, 0, 0, "Set the light intensity value 1 for a quad lamp");
uiDefButF(block, NUMSLI,B_MATPRV,"Quad2 ", 120,10,180,19,&la->att2, 0.0, 1.0, 0, 0, "Set the light intensity value 2 for a quad lamp");
uiBlockEndAlign(block);
if ELEM(la->type, LA_LOCAL, LA_SPOT) {
uiDefButF(block, NUMSLI,B_MATPRV,"Quad1 ", 120,30,180,19,&la->att1, 0.0, 1.0, 0, 0, "Set the linear distance attenuatation for a quad lamp");
uiDefButF(block, NUMSLI,B_MATPRV,"Quad2 ", 120,10,180,19,&la->att2, 0.0, 1.0, 0, 0, "Set the qudratic distance attenuatation for a quad lamp");
}
else if(la->type==LA_AREA) {
if(la->k==0.0) la->k= 1.0;
uiDefButF(block, NUMSLI,0,"Gamma ", 120,10,180,19,&la->k, 0.001, 2.0, 100, 0, "Set the light gamma correction value");
}
}
@ -1926,10 +1969,10 @@ static void lamp_panel_preview(Object *ob, Lamp *la)
uiDefBut(block, LABEL, 0, " ", 20,20,10,10, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButS(block, ROW,B_LAMPREDRAW,"Lamp", 200,175,80,25,&la->type,1.0,(float)LA_LOCAL, 0, 0, "Creates an omnidirectional point light source");
uiDefButS(block, ROW,B_LAMPREDRAW,"Spot", 200,150,80,25,&la->type,1.0,(float)LA_SPOT, 0, 0, "Creates a directional cone light source");
uiDefButS(block, ROW,B_LAMPREDRAW,"Sun", 200,125,80,25,&la->type,1.0,(float)LA_SUN, 0, 0, "Creates a constant direction parallel ray light source");
uiDefButS(block, ROW,B_LAMPREDRAW,"Hemi", 200,100,80,25,&la->type,1.0,(float)LA_HEMI, 0, 0, "Creates a 180 degree point light source");
uiBlockEndAlign(block);
uiDefButS(block, ROW,B_LAMPREDRAW,"Area", 200,150,80,25,&la->type,1.0,(float)LA_AREA, 0, 0, "Creates a directional area light source");
uiDefButS(block, ROW,B_LAMPREDRAW,"Spot", 200,125,80,25,&la->type,1.0,(float)LA_SPOT, 0, 0, "Creates a directional cone light source");
uiDefButS(block, ROW,B_LAMPREDRAW,"Sun", 200,100,80,25,&la->type,1.0,(float)LA_SUN, 0, 0, "Creates a constant direction parallel ray light source");
uiDefButS(block, ROW,B_LAMPREDRAW,"Hemi", 200,75,80,25,&la->type,1.0,(float)LA_HEMI, 0, 0, "Creates a 180 degree constant light source");
}
@ -2344,7 +2387,7 @@ static void material_panel_shading(Material *ma)
uiBlockBeginAlign(block);
uiDefButF(block, NUMSLI, B_MATPRV, "Spec ", 90,120,150,19, &(ma->spec), 0.0, 2.0, 0, 0, "Sets the degree of specularity");
if ELEM3(ma->spec_shader, MA_SPEC_COOKTORR, MA_SPEC_PHONG, MA_SPEC_BLINN) {
uiDefButS(block, NUMSLI, B_MATPRV, "Hard:", 90, 100, 150,19, &(ma->har), 1.0, 255, 0, 0, "Sets the hardness of the specularity");
uiDefButS(block, NUMSLI, B_MATPRV, "Hard:", 90, 100, 150,19, &(ma->har), 1.0, 511, 0, 0, "Sets the hardness of the specularity");
}
if(ma->spec_shader==MA_SPEC_BLINN)
uiDefButF(block, NUMSLI, B_MATPRV, "Refr:", 90, 80,150,19, &(ma->refrac), 1.0, 10.0, 0, 0, "Sets the material's Index of Refraction");

@ -580,7 +580,14 @@ static void drawlamp(Object *ob)
glEnd();
}
else {
if(la->mode & LA_SPHERE) {
if(la->type==LA_AREA) {
setlinestyle(0);
if(la->area_shape==LA_AREA_SQUARE)
fdrawbox(-la->area_size*0.5, -la->area_size*0.5, la->area_size*0.5, la->area_size*0.5);
else if(la->area_shape==LA_AREA_RECT)
fdrawbox(-la->area_size*0.5, -la->area_sizey*0.5, la->area_size*0.5, la->area_sizey*0.5);
}
else if(la->mode & LA_SPHERE) {
float tmat[4][4], imat[4][4];
@ -596,6 +603,7 @@ static void drawlamp(Object *ob)
VECCOPY(vec, ob->obmat[3]);
setlinestyle(3);
glBegin(GL_LINE_STRIP);
glVertex3fv(vec);
vec[2]= 0;

@ -450,11 +450,12 @@ void count_object(Object *ob, int sel)
G.totmesh++;
me= get_mesh(ob);
if(me) {
G.totvert+= me->totvert;
G.totface+= me->totface;
int mult= (me->flag & ME_SUBSURF)?(1<<me->subdiv)*(1<<me->subdiv):1;
G.totvert+= me->totvert*mult;
G.totface+= me->totface*mult;
if(sel) {
G.totvertsel+= me->totvert;
G.totfacesel+= me->totface;
G.totvertsel+= me->totvert*mult;
G.totfacesel+= me->totface*mult;
}
}
break;

@ -184,6 +184,10 @@ void do_buts_buttons(short event)
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWVIEW3D, 0);
break;
case B_CONTEXT_SWITCH:
butspace_context_switch(G.buts, BASACT);
scrarea_queue_winredraw(curarea);
break;
}
}
@ -364,7 +368,7 @@ static uiBlock *sbuts_context_menu(void *arg_unused)
uiDefIconTextButS(block, BUTM, B_REDR, ICON_SCENE_DEHLT, "Scene|F10", 0, yco-=22, 100, 20, &G.buts->mainb, 0.0, 0.0, 0, 0, "");
uiDefIconTextButS(block, BUTM, B_REDR, ICON_EDIT, "Editing|F9", 0, yco-=22, 100, 20, &G.buts->mainb, 4.0, 0.0, 0, 0, "");
uiDefIconTextButS(block, BUTM, B_REDR, ICON_OBJECT, "Object|F6", 0, yco-=22, 100, 20, &G.buts->mainb, 1.0, 0.0, 0, 0, "");
uiDefIconTextButS(block, BUTM, B_REDR, ICON_MATERIAL_DEHLT, "Shading|F5", 0, yco-=22, 100, 20, &G.buts->mainb, 3.0, 0.0, 0, 0, "");
uiDefIconTextButS(block, BUTM, B_CONTEXT_SWITCH, ICON_MATERIAL_DEHLT, "Shading|F5", 0, yco-=22, 100, 20, &G.buts->mainb, 3.0, 0.0, 0, 0, "");
uiDefIconTextButS(block, BUTM, B_REDR, ICON_GAME, "Logic|F4", 0, yco-=22, 100, 20, &G.buts->mainb, 6.0, 0.0, 0, 0, "");
uiDefIconTextButS(block, BUTM, B_REDR, ICON_SCRIPT, "Script", 0, yco-=22, 100, 20, &G.buts->mainb, 5.0, 0.0, 0, 0, "");
@ -421,7 +425,7 @@ void buts_buttons(void)
uiBlockBeginAlign(block);
uiDefIconButS(block, ROW, B_REDR, ICON_GAME, xco+=XIC, 0, XIC, YIC, &(G.buts->mainb), 0.0, (float)CONTEXT_LOGIC, 0, 0, "Logic (F4) ");
uiDefIconButS(block, ROW, B_REDR, ICON_SCRIPT, xco+=XIC, 0, XIC, YIC, &(G.buts->mainb), 0.0, (float)CONTEXT_SCRIPT, 0, 0, "Script ");
uiDefIconButS(block, ROW, B_REDR, ICON_MATERIAL_DEHLT,xco+=XIC, 0, XIC, YIC, &(G.buts->mainb), 0.0, (float)CONTEXT_SHADING, 0, 0, "Shading (F5) ");
uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_MATERIAL_DEHLT,xco+=XIC, 0, XIC, YIC, &(G.buts->mainb), 0.0, (float)CONTEXT_SHADING, 0, 0, "Shading (F5) ");
uiDefIconButS(block, ROW, B_REDR, ICON_OBJECT, xco+=XIC, 0, XIC, YIC, &(G.buts->mainb), 0.0, (float)CONTEXT_OBJECT, 0, 0, "Object (F7) ");
uiDefIconButS(block, ROW, B_REDR, ICON_EDIT, xco+=XIC, 0, XIC, YIC, &(G.buts->mainb), 0.0, (float)CONTEXT_EDITING, 0, 0, "Editing (F9) ");
uiDefIconButS(block, ROW, B_REDR, ICON_SCENE_DEHLT, xco+=XIC, 0, XIC, YIC, &(G.buts->mainb), 0.0, (float)CONTEXT_SCENE, 0, 0, "Scene (F10) ");

@ -1468,6 +1468,7 @@ static void ui_draw_but_COL(uiBut *but)
if(but->embossfunc == ui_draw_round) {
char *cp= BIF_ThemeGetColorPtr(U.themes.first, 0, TH_CUSTOM);
cp[0]= colr; cp[1]= colg; cp[2]= colb;
but->flag &= ~UI_SELECT;
but->embossfunc(but->type, TH_CUSTOM, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
}
else {

@ -447,7 +447,7 @@ static void lamp_preview_pixel(ShadeInput *shi, LampRen *la, int x, int y, char
}
dist*=inpr;
}
else if(la->type==LA_LOCAL) dist*= shi->view[2];
else if ELEM(la->type, LA_LOCAL, LA_AREA) dist*= shi->view[2];
col= 255.0*dist*la->r;
if(col<=0) rect[0]= 0; else if(col>=255) rect[0]= 255; else rect[0]= col;
@ -1213,9 +1213,6 @@ void BIF_previewrender(SpaceButs *sbuts)
else if(tex) {
end_render_texture(tex);
}
else if(wrld) {
end_render_textures();
}
else if(la) {
if(R.totlamp) {
if(R.la[0]->org) MEM_freeN(R.la[0]->org);
@ -1224,5 +1221,8 @@ void BIF_previewrender(SpaceButs *sbuts)
R.totlamp= 0;
end_render_textures();
}
else if(wrld) {
end_render_textures();
}
}

@ -976,7 +976,7 @@ void centreview() /* like a localview without local! */
G.vd->persp= 1;
}
G.vd->near= 0.1;
G.vd->cursor[0]= -G.vd->ofs[0];
G.vd->cursor[1]= -G.vd->ofs[1];
G.vd->cursor[2]= -G.vd->ofs[2];