61
61
#include "strand.h"
65
void hoco_to_zco(ZSpan *zspan, float *zco, float *hoco);
66
void zspan_scanconvert_strand(ZSpan *zspan, void *handle, float *v1, float *v2, float *v3, void (*func)(void *, int, int, float, float, float) );
67
void zbufsinglewire(ZSpan *zspan, int obi, int zvlnr, float *ho1, float *ho2);
69
64
/* *************** */
71
66
static float strand_eval_width(Material *ma, float strandco)
333
328
StrandShadeCache *cache;
335
330
cache= MEM_callocN(sizeof(StrandShadeCache), "StrandShadeCache");
336
cache->resulthash= BLI_ghash_new(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, "strand_shade_cache_create1 gh");
337
cache->refcounthash= BLI_ghash_new(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, "strand_shade_cache_create2 gh");
331
cache->resulthash= BLI_ghash_pair_new("strand_shade_cache_create1 gh");
332
cache->refcounthash= BLI_ghash_pair_new("strand_shade_cache_create2 gh");
338
333
cache->memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "strand shade cache arena");
400
395
interpolate_shade_result(&shr1, &shr2, t, ssamp->shr, addpassflag);
402
397
/* apply alpha along width */
403
if (sseg->buffer->widthfade != 0.0f) {
398
if (sseg->buffer->widthfade != -1.0f) {
404
399
s = 1.0f - powf(fabsf(s), sseg->buffer->widthfade);
406
401
strand_apply_shaderesult_alpha(ssamp->shr, s);
483
static void do_strand_point_project(float winmat[][4], ZSpan *zspan, float *co, float *hoco, float *zco)
479
static void do_strand_point_project(float winmat[4][4], ZSpan *zspan, float *co, float *hoco, float *zco)
485
481
projectvert(co, winmat, hoco);
486
482
hoco_to_zco(zspan, zco, hoco);
489
static void strand_project_point(float winmat[][4], float winx, float winy, StrandPoint *spoint)
485
static void strand_project_point(float winmat[4][4], float winx, float winy, StrandPoint *spoint)
504
500
psm= MEM_mallocN(sizeof(APixstrMain), "addpsmainA");
505
501
BLI_addtail(lb, psm);
506
psm->ps= MEM_callocN(4096*sizeof(APixstrand),"pixstr");
502
psm->ps = MEM_callocN(4096 * sizeof(APixstrand), "pixstr");
527
523
static void do_strand_fillac(void *handle, int x, int y, float u, float v, float z)
529
StrandPart *spart= (StrandPart*)handle;
525
StrandPart *spart= (StrandPart *)handle;
530
526
StrandShadeCache *cache= spart->cache;
531
527
StrandSegment *sseg= spart->segment;
532
528
APixstrand *apn, *apnew;
570
566
#define CHECK_ADD(n) \
571
567
if (apn->p[n]==strnr && apn->obi[n]==obi && apn->seg[n]==seg) \
572
{ if (!(apn->mask[n] & mask)) { apn->mask[n] |= mask; apn->v[n] += t; apn->u[n] += s; } break; }
568
{ if (!(apn->mask[n] & mask)) { apn->mask[n] |= mask; apn->v[n] += t; apn->u[n] += s; } break; } (void)0
573
569
#define CHECK_ASSIGN(n) \
574
570
if (apn->p[n]==0) \
575
{apn->obi[n]= obi; apn->p[n]= strnr; apn->z[n]= zverg; apn->mask[n]= mask; apn->v[n]= t; apn->u[n]= s; apn->seg[n]= seg; break; }
571
{apn->obi[n]= obi; apn->p[n]= strnr; apn->z[n]= zverg; apn->mask[n]= mask; apn->v[n]= t; apn->u[n]= s; apn->seg[n]= seg; break; } (void)0
577
573
/* add to pixel list */
578
574
if (zverg < bufferz && (spart->totapixbuf[offset] < MAX_ZROW)) {
579
575
if (!spart->rectmask || zverg > maskz) {
580
t = u*spart->t[0] + v*spart->t[1] + (1.0f-u-v)*spart->t[2];
581
s = fabs(u*spart->s[0] + v*spart->s[1] + (1.0f-u-v)*spart->s[2]);
576
t = u * spart->t[0] + v * spart->t[1] + (1.0f - u - v) * spart->t[2];
577
s = fabsf(u * spart->s[0] + v * spart->s[1] + (1.0f - u - v) * spart->s[2]);
583
579
apn= spart->apixbuf + offset;
609
605
/* width is calculated in hoco space, to ensure strands are visible */
610
static int strand_test_clip(float winmat[][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy)
606
static int strand_test_clip(float winmat[4][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy)
667
663
zspan_scanconvert_strand(zspan, spart, jco1, jco3, jco4, do_strand_fillac);
670
static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2)
666
static void strand_render(Render *re, StrandSegment *sseg, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2)
674
670
float dt= p2->t - p1->t;
678
for (a=0; a<re->osa; a++)
679
do_scanconvert_strand(re, spart, zspan, t, dt, p1->zco2, p1->zco1, p2->zco1, p2->zco2, a);
682
do_scanconvert_strand(re, spart, zspan, t, dt, p1->zco2, p1->zco1, p2->zco1, p2->zco2, 0);
673
for (a=0; a<spart->samples; a++)
674
do_scanconvert_strand(re, spart, zspan, t, dt, p1->zco2, p1->zco1, p2->zco1, p2->zco2, a);
685
677
float hoco1[4], hoco2[4];
686
678
int a, obi, index;
688
680
obi= sseg->obi - re->objectinstance;
689
681
index= sseg->strand->index;
691
683
projectvert(p1->co, winmat, hoco1);
692
684
projectvert(p2->co, winmat, hoco2);
695
687
for (a=0; a<totzspan; a++) {
697
689
/* render both strand and single pixel wire to counter aliasing */
707
static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth)
699
static int strand_segment_recursive(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth)
710
702
StrandBuffer *buffer= sseg->buffer;
756
void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg)
748
void render_strand_segment(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg)
758
750
StrandBuffer *buffer= sseg->buffer;
759
751
StrandPoint *p1= &sseg->point1;
793
785
/* render call to fill in strands */
794
int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[][4], int winx, int winy, int UNUSED(sample), float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache)
786
int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache)
797
789
ObjectInstanceRen *obi;
984
977
/* *************** */
986
StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[][4], int timeoffset)
979
StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[4][4], int timeoffset)
988
981
StrandSurface *mesh;
1060
1053
BLI_freelistN(&re->strandsurface);
1063
void strand_minmax(StrandRen *strand, float *min, float *max, float width)
1056
void strand_minmax(StrandRen *strand, float min[3], float max[3], const float width)
1065
1058
StrandVert *svert;
1066
float vec[3], width2= 2.0f*width;
1059
const float width2 = width * 2.0f;
1069
1063
for (a=0, svert=strand->vert; a<strand->totvert; a++, svert++) {
1070
1064
copy_v3_v3(vec, svert->co);
1071
DO_MINMAX(vec, min, max);
1065
minmax_v3v3_v3(min, max, vec);
1073
1067
if (width!=0.0f) {
1074
vec[0]+= width; vec[1]+= width; vec[2]+= width;
1075
DO_MINMAX(vec, min, max);
1076
vec[0]-= width2; vec[1]-= width2; vec[2]-= width2;
1077
DO_MINMAX(vec, min, max);
1068
add_v3_fl(vec, width);
1069
minmax_v3v3_v3(min, max, vec);
1070
add_v3_fl(vec, -width2);
1071
minmax_v3v3_v3(min, max, vec);