94
94
/* Uses ray tracing to check if a point is inside or outside an ObjectInstanceRen */
95
static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), float *co)
95
static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), const float co[3])
97
97
Isect isect= {{0}};
98
float dir[3] = {0.0f,0.0f,1.0f};
98
float dir[3] = {0.0f, 0.0f, 1.0f};
99
99
int final_depth=0, depth=0, limit=20;
101
101
/* set up the isect */
120
120
/* find the bounding box of an objectinstance in global space */
121
void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float *bbmin, float *bbmax)
121
void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float bbmin[3], float bbmax[3])
123
123
ObjectRen *obr = obi->obr;
124
124
VolumePrecache *vp = obi->volume_precache;
150
150
/* convert to global space */
151
151
mul_m4_v3(re->viewinv, co);
153
DO_MINMAX(co, vp->bbmin, vp->bbmax);
153
minmax_v3v3_v3(vp->bbmin, vp->bbmax, co);
156
156
copy_v3_v3(bbmin, vp->bbmin);
177
177
for (x=-1; x <= 1; x++) {
179
179
if (x_ >= 0 && x_ <= res[0]-1) {
180
const int i= V_I(x_, y_, z_, res);
180
const int i = BLI_VOXEL_INDEX(x_, y_, z_, res);
182
182
if (cache[i] > 0.0f) {
208
208
for (y=0; y < vp->res[1]; y++) {
209
209
for (x=0; x < vp->res[0]; x++) {
210
210
/* trigger for outside mesh */
211
const int i= V_I(x, y, z, vp->res);
211
const int i = BLI_VOXEL_INDEX(x, y, z, vp->res);
213
213
if (vp->data_r[i] < -0.f)
214
214
vp->data_r[i] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
240
240
for (y=0; y < vp->res[1]; y++) {
241
241
for (x=0; x < vp->res[0]; x++) {
242
242
/* trigger for outside mesh */
243
const int i= V_I(x, y, z, vp->res);
243
const int i = BLI_VOXEL_INDEX(x, y, z, vp->res);
244
244
if (vp->data_r[i] < -0.f)
245
245
new_r[i] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
246
246
if (vp->data_g[i] < -0.f)
264
BLI_INLINE int ms_I(int x, int y, int z, int *n) //has a pad of 1 voxel surrounding the core for boundary simulation
264
BLI_INLINE int ms_I(int x, int y, int z, int *n) /* has a pad of 1 voxel surrounding the core for boundary simulation */
266
266
/* different ordering to light cache */
267
return x*(n[1]+2)*(n[2]+2) + y*(n[2]+2) + z;
267
return x*(n[1]+2)*(n[2]+2) + y*(n[2]+2) + z;
270
BLI_INLINE int v_I_pad(int x, int y, int z, int *n) //has a pad of 1 voxel surrounding the core for boundary simulation
270
BLI_INLINE int v_I_pad(int x, int y, int z, int *n) /* has a pad of 1 voxel surrounding the core for boundary simulation */
272
272
/* same ordering to light cache, with padding */
273
return z*(n[1]+2)*(n[0]+2) + y*(n[0]+2) + x;
273
return z*(n[1]+2)*(n[0]+2) + y*(n[0]+2) + x;
276
276
BLI_INLINE int lc_to_ms_I(int x, int y, int z, int *n)
291
291
for (z=0; z < res[2]; z++) {
292
292
for (y=0; y < res[1]; y++) {
293
293
for (x=0; x < res[0]; x++) {
294
const int i=V_I(x, y, z, res);
294
const int i = BLI_VOXEL_INDEX(x, y, z, res);
296
296
if (vp->data_r[i] > 0.f) energy += vp->data_r[i];
297
297
if (vp->data_g[i] > 0.f) energy += vp->data_g[i];
313
313
for (z=1;z<=res[2];z++) {
314
314
for (y=1;y<=res[1];y++) {
315
315
for (x=1;x<=res[0];x++) {
316
const int i = ms_I(x,y,z,res);
316
const int i = ms_I(x, y, z, res);
318
318
if (sr[i] > 0.f) energy += sr[i];
319
319
if (sg[i] > 0.f) energy += sg[i];
334
334
size_t size = n[0]*n[1]*n[2];
335
335
const float a = dt*diff*size;
339
for (k=1; k<=n[2]; k++)
341
for (j=1; j<=n[1]; j++)
343
for (i=1; i<=n[0]; i++)
345
x[v_I_pad(i,j,k,n)] = (x0[v_I_pad(i,j,k,n)]) + a*( x0[v_I_pad(i-1,j,k,n)]+ x0[v_I_pad(i+1,j,k,n)]+ x0[v_I_pad(i,j-1,k,n)]+
346
x0[v_I_pad(i,j+1,k,n)]+ x0[v_I_pad(i,j,k-1,n)]+x0[v_I_pad(i,j,k+1,n)]
337
for (l=0; l<20; l++) {
338
for (k=1; k<=n[2]; k++) {
339
for (j=1; j<=n[1]; j++) {
340
for (i=1; i<=n[0]; i++) {
341
x[v_I_pad(i, j, k, n)] = (x0[v_I_pad(i, j, k, n)]) + a*( x0[v_I_pad(i-1, j, k, n)]+ x0[v_I_pad(i+1, j, k, n)]+ x0[v_I_pad(i, j-1, k, n)]+
342
x0[v_I_pad(i, j+1, k, n)]+ x0[v_I_pad(i, j, k-1, n)]+x0[v_I_pad(i, j, k+1, n)]
358
354
static void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma)
360
356
const float diff = ma->vol.ms_diff * 0.001f; /* compensate for scaling for a nicer UI range */
361
const int simframes = (int)(ma->vol.ms_spread * (float)MAX3(vp->res[0], vp->res[1], vp->res[2]));
357
const int simframes = (int)(ma->vol.ms_spread * (float)max_iii(vp->res[0], vp->res[1], vp->res[2]));
362
358
const int shade_type = ma->vol.shade_type;
363
359
float fac = ma->vol.ms_intensity;
384
380
energy_ss = total_ss_energy(re, do_test_break, vp);
386
382
/* Scattering as diffusion pass */
387
for (m=0; m<simframes; m++)
383
for (m=0; m<simframes; m++) {
389
384
/* add sources */
390
for (z=1; z<=n[2]; z++)
392
for (y=1; y<=n[1]; y++)
394
for (x=1; x<=n[0]; x++)
396
const int i = lc_to_ms_I(x, y ,z, n); //lc index
385
for (z=1; z<=n[2]; z++) {
386
for (y=1; y<=n[1]; y++) {
387
for (x=1; x<=n[0]; x++) {
388
const int i = lc_to_ms_I(x, y, z, n); //lc index
397
389
const int j = ms_I(x, y, z, n); //ms index
399
391
time= PIL_check_seconds_timer();
401
393
if (vp->data_r[i] > 0.0f)
402
394
sr[j] += vp->data_r[i];
403
395
if (vp->data_g[i] > 0.0f)
423
415
if (re->test_break(re->tbh)) break;
425
SWAP(float *,sr,sr0);
426
SWAP(float *,sg,sg0);
427
SWAP(float *,sb,sb0);
417
SWAP(float *, sr, sr0);
418
SWAP(float *, sg, sg0);
419
SWAP(float *, sb, sb0);
429
421
/* main diffusion simulation */
430
422
ms_diffuse(re, do_test_break, sr0, sr, diff, n);
451
for (z=1;z<=n[2];z++)
453
for (y=1;y<=n[1];y++)
455
for (x=1;x<=n[0];x++)
457
const int i = lc_to_ms_I(x, y ,z, n); //lc index
443
for (z=1;z<=n[2];z++) {
444
for (y=1;y<=n[1];y++) {
445
for (x=1;x<=n[0];x++) {
446
const int i = lc_to_ms_I(x, y, z, n); //lc index
458
447
const int j = ms_I(x, y, z, n); //ms index
460
449
vp->data_r[i] = origf * vp->data_r[i] + fac * sr[j];
538
527
/* convert from world->camera space for shading */
539
528
mul_v3_m4v3(cco, pa->viewmat, co);
541
i= V_I(x, y, z, res);
543
// don't bother if the point is not inside the volume mesh
530
i = BLI_VOXEL_INDEX(x, y, z, res);
532
/* don't bother if the point is not inside the volume mesh */
544
533
if (!point_inside_obi(tree, obi, cco)) {
545
534
obi->volume_precache->data_r[i] = -1.0f;
546
535
obi->volume_precache->data_g[i] = -1.0f;
577
memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); // note, keep this synced with render_types.h
566
memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); /* note, keep this synced with render_types.h */
578
567
shi->har= shi->mat->har;
580
569
shi->obr= obi->obr;
663
652
global_bounds_obi(re, obi, bbmin, bbmax);
664
653
sub_v3_v3v3(dim, bbmax, bbmin);
666
div = MAX3(dim[0], dim[1], dim[2]);
655
div = max_fff(dim[0], dim[1], dim[2]);
768
757
BLI_freelistN(&re->volume_precache_parts);
771
//TODO: makeraytree_object creates a tree and saves it on OBI, if we free this tree we should also clear other pointers to it
760
/* TODO: makeraytree_object creates a tree and saves it on OBI,
761
* if we free this tree we should also clear other pointers to it */
772
762
//RE_rayobject_free(tree);
836
826
BLI_freelistN(&re->volumes);
839
int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float *co)
829
int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, const float co[3])