[brlcad-commits] CVS: brlcad/src/librt g_metaball.c,14.7,14.8
Open Source Solid Modeling CAD
Brought to you by:
brlcad
From: Erik G. <eri...@us...> - 2006-08-01 20:41:27
|
Update of /cvsroot/brlcad/brlcad/src/librt In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv23939 Modified Files: g_metaball.c Log Message: Drastically improved bounding sphere computation (better center and fit). Fix for 'garbage' normals resulting in noisy images in some situations. Obey the 'one-hit' flag in the shot routine. Index: g_metaball.c =================================================================== RCS file: /cvsroot/brlcad/brlcad/src/librt/g_metaball.c,v retrieving revision 14.7 retrieving revision 14.8 diff -w -u -r14.7 -r14.8 --- g_metaball.c 26 Jul 2006 16:42:55 -0000 14.7 +++ g_metaball.c 1 Aug 2006 19:18:25 -0000 14.8 @@ -82,10 +82,11 @@ { struct rt_metaball_internal *mb, *nmb; struct wdb_metaballpt *mbpt, *mbpt2, *nmbpt; - point_t p; - fastf_t cnt = 0.0, r = 0.0; + point_t p, max, min; + fastf_t r = 0.0; + int i; - VSET(p,0,0,0); + VSETALL(p,0); mb = ip->idb_ptr; RT_METABALL_CK_MAGIC(mb); nmb = bu_malloc(sizeof(struct rt_metaball_internal), "rt_metaball_prep: nmb"); @@ -96,11 +97,13 @@ nmbpt->fldstr = mbpt->fldstr; VMOVE(nmbpt->coord,mbpt->coord); BU_LIST_INSERT( &nmb->metaball_pt_head, &nmbpt->l ); - cnt++; - VJOIN1(p,p,mbpt->fldstr,mbpt->coord); + for(i=0;i<3;i++) + if(mbpt->coord[i] < min[i]) + min[i] = mbpt->coord[i]; + else if (mbpt->coord[i] > max[i]) + max[i] = mbpt->coord[i]; } - VSCALE(p,p,-cnt); - VMOVE(stp->st_center, p); + VADD2(stp->st_center,min,max); for(BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_pt_head)){ point_t d; fastf_t dist; @@ -113,11 +116,12 @@ VSUB2(d, mbpt2->coord, mbpt->coord); mag = MAGSQ(d); - dist += mbpt2->fldstr / (mag>.00001?mag:1.0); + dist += mbpt2->fldstr / (mag>.001?mag:1.0); } if(dist > r) r = dist; } + r = sqrt(r); stp->st_aradius = r; stp->st_bradius = r; VSET(stp->st_min, p[X]-r, p[Y]-r, p[Z]-r); @@ -163,40 +167,11 @@ int stat=0; struct wdb_metaballpt *mbpt; register struct seg *segp = NULL; -#if 0 - const static fastf_t step = .01; - fastf_t i = (rp->r_max-rp->r_min)/step; - - mb = (struct rt_metaball_internal *)stp->st_specific; - VMOVE(p, rp->r_pt); - VSCALE(inc, rp->r_dir, step); /* assume it's normalized and we want to creep at step */ - - while( (i -= step) > 0.0 ) { - VADD2(p, p, inc); - if(stat) { - if(rt_metaball_point_value(&p, &mb->metaball_pt_head) < mb->threshhold ) { - point_t delta; - VSUB2(delta, p, rp->r_pt); - segp->seg_out.hit_dist = sqrt(MAGSQ(delta)); - BU_LIST_INSERT( &(seghead->l), &(segp->l) ); - return 2; /* hit */ - } - } else { - if(rt_metaball_point_value(&p, &mb->metaball_pt_head) > mb->threshhold ) { - point_t delta; - VSUB2(delta, p, rp->r_pt); - RT_GET_SEG(segp, ap->a_resource); - segp->seg_stp = stp; - segp->seg_in.hit_dist = sqrt(MAGSQ(delta)); - ++stat; - } - } - } -#else - const static fastf_t initstep = .2, finalstep = .01; + fastf_t initstep = stp->st_bradius / 20, finalstep = stp->st_bradius / 1000000.0; fastf_t step = initstep; fastf_t i = (rp->r_max-rp->r_min)/step; + mb = (struct rt_metaball_internal *)stp->st_specific; VMOVE(p, rp->r_pt); VSCALE(inc, rp->r_dir, step); /* assume it's normalized and we want to creep at step */ @@ -220,6 +195,10 @@ segp->seg_stp = stp; segp->seg_in.hit_dist = sqrt(MAGSQ(delta)); ++stat; + if(ap->a_onehit){ + BU_LIST_INSERT( &(seghead->l), &(segp->l) ); + return 2; + } } else { /* we hit, but not as fine-grained as we * want. So back up one step, cut the step @@ -231,11 +210,9 @@ step *= .5; VSCALE(inc,inc,.5); } - } } } -#endif return 0; /* miss */ } @@ -252,6 +229,7 @@ vect_t v; fastf_t f; + VSETALL(hitp->hit_normal, 0); for(BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_pt_head)){ VSUB2(v, mbpt->coord, hitp->hit_point); f = mbpt->fldstr / MAGSQ(v); |