00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef lint
00040 static const char RCSshoot[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/vshoot.c,v 14.13 2006/09/16 02:04:26 lbutler Exp $ (BRL)";
00041 #endif
00042
00043 #include "common.h"
00044
00045 #include <stdio.h>
00046 #include <math.h>
00047 #include "machine.h"
00048 #include "vmath.h"
00049 #include "raytrace.h"
00050 #include "./debug.h"
00051
00052 struct resource rt_uniresource;
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 int
00095 rt_shootray( struct application *ap )
00096 {
00097 struct seg *HeadSeg;
00098 int ret;
00099 auto vect_t inv_dir;
00100 union bitv_elem *solidbits;
00101 bitv_t *regionbits;
00102 char *status;
00103 auto struct partition InitialPart;
00104 auto struct partition FinalPart;
00105 int nrays = 1;
00106 int vlen;
00107 int id;
00108 int i;
00109 struct soltab **ary_stp;
00110 struct xray **ary_rp;
00111 struct seg *ary_seg;
00112 struct rt_i *rtip;
00113
00114 #define BACKING_DIST (-2.0)
00115 rtip = ap->a_rt_i;
00116 RT_AP_CHECK(ap);
00117 if( ap->a_resource == RESOURCE_NULL ) {
00118 ap->a_resource = &rt_uniresource;
00119 rt_uniresource.re_magic = RESOURCE_MAGIC;
00120 }
00121 RT_CK_RESOURCE(ap->a_resource);
00122
00123 if(RT_G_DEBUG&(DEBUG_ALLRAYS|DEBUG_SHOOT|DEBUG_PARTITION)) {
00124 rt_g.rtg_logindent += 2;
00125 bu_log("\n**********mshootray cpu=%d %d,%d lvl=%d (%s)\n",
00126 ap->a_resource->re_cpu,
00127 ap->a_x, ap->a_y,
00128 ap->a_level,
00129 ap->a_purpose != (char *)0 ? ap->a_purpose : "?" );
00130 VPRINT("Pnt", ap->a_ray.r_pt);
00131 VPRINT("Dir", ap->a_ray.r_dir);
00132 }
00133
00134 rtip->rti_nrays++;
00135 if( rtip->needprep )
00136 rt_prep(rtip);
00137
00138
00139 vlen = nrays * rtip->rti_maxsol_by_type;
00140 ary_stp = (struct soltab **)bu_calloc( vlen, sizeof(struct soltab *),
00141 "*ary_stp[]" );
00142 ary_rp = (struct xray **)bu_calloc( vlen, sizeof(struct xray *),
00143 "*ary_rp[]" );
00144 ary_seg = (struct seg *)bu_calloc( vlen, sizeof(struct seg),
00145 "ary_seg[]" );
00146
00147
00148
00149 InitialPart.pt_forw = InitialPart.pt_back = &InitialPart;
00150 FinalPart.pt_forw = FinalPart.pt_back = &FinalPart;
00151
00152 HeadSeg = SEG_NULL;
00153
00154 GET_BITV( rtip, solidbits, ap->a_resource );
00155 bzero( (char *)solidbits, rtip->rti_bv_bytes );
00156 regionbits = &solidbits->be_v[
00157 2+RT_BITV_BITS2WORDS(ap->a_rt_i->nsolids)];
00158
00159
00160 if( !NEAR_ZERO( ap->a_ray.r_dir[X], SQRT_SMALL_FASTF ) ) {
00161 inv_dir[X]=1.0/ap->a_ray.r_dir[X];
00162 } else {
00163 inv_dir[X] = INFINITY;
00164 ap->a_ray.r_dir[X] = 0.0;
00165 }
00166 if( !NEAR_ZERO( ap->a_ray.r_dir[Y], SQRT_SMALL_FASTF ) ) {
00167 inv_dir[Y]=1.0/ap->a_ray.r_dir[Y];
00168 } else {
00169 inv_dir[Y] = INFINITY;
00170 ap->a_ray.r_dir[Y] = 0.0;
00171 }
00172 if( !NEAR_ZERO( ap->a_ray.r_dir[Z], SQRT_SMALL_FASTF ) ) {
00173 inv_dir[Z]=1.0/ap->a_ray.r_dir[Z];
00174 } else {
00175 inv_dir[Z] = INFINITY;
00176 ap->a_ray.r_dir[Z] = 0.0;
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 if( !rt_in_rpp( &ap->a_ray, inv_dir, rtip->mdl_min, rtip->mdl_max ) ||
00188 ap->a_ray.r_max < 0.0 ) {
00189 rtip->nmiss_model++;
00190 ret = ap->a_miss( ap );
00191 status = "MISS model";
00192 goto out;
00193 }
00194
00195
00196 for( id = 1; id <= ID_MAX_SOLID; id++ ) {
00197 register int nsol;
00198
00199 if( (nsol = rtip->rti_nsol_by_type[id]) <= 0 ) continue;
00200
00201
00202 for( i = nsol-1; i >= 0; i-- ) {
00203 ary_stp[i] = rtip->rti_sol_by_type[id][i];
00204 ary_rp[i] = &(ap->a_ray);
00205 ary_seg[i].seg_stp = SOLTAB_NULL;
00206 ary_seg[i].seg_next = SEG_NULL;
00207 }
00208
00209
00210
00211 ap->a_rt_i->nshots += nsol;
00212 rt_functab[id].ft_vshot(
00213 ary_stp, ary_rp, ary_seg,
00214 nsol, ap->a_resource );
00215
00216
00217
00218
00219 for( i = nsol-1; i >= 0; i-- ) {
00220 register struct seg *seg2;
00221
00222 if( ary_seg[i].seg_stp == SOLTAB_NULL ) {
00223
00224 ap->a_rt_i->nmiss++;
00225 continue;
00226 }
00227 ap->a_rt_i->nhits++;
00228
00229
00230
00231 GET_SEG( seg2, ap->a_resource );
00232 *seg2 = ary_seg[i];
00233 rt_boolweave( seg2, &InitialPart, ap );
00234
00235
00236 {
00237 register struct seg *seg3 = seg2;
00238 while( seg3->seg_next != SEG_NULL )
00239 seg3 = seg3->seg_next;
00240 seg3->seg_next = HeadSeg;
00241 HeadSeg = seg2;
00242 }
00243 }
00244
00245
00246 for( i = nsol-1; i >= 0; i-- ) {
00247 register int words;
00248 register bitv_t *in = ary_stp[i]->st_regions;
00249 register bitv_t *out = regionbits;
00250
00251 words = RT_BITV_BITS2WORDS(ary_stp[i]->st_maxreg);
00252 # include "noalias.h"
00253 for( --words; words >= 0; words-- )
00254 regionbits[words] |= in[words];
00255 }
00256 }
00257
00258
00259
00260
00261 if( InitialPart.pt_forw == &InitialPart ) {
00262 ret = ap->a_miss( ap );
00263 status = "MISSed all primitives";
00264 goto freeup;
00265 }
00266
00267
00268
00269
00270
00271 rt_boolfinal( &InitialPart, &FinalPart, BACKING_DIST,
00272 INFINITY,
00273 regionbits, ap);
00274
00275 if( FinalPart.pt_forw == &FinalPart ) {
00276 ret = ap->a_miss( ap );
00277 status = "MISS bool";
00278 goto freeup;
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 hitit:
00294 if(RT_G_DEBUG&DEBUG_SHOOT) rt_pr_partitions(rtip,&FinalPart,"a_hit()");
00295
00296 ret = ap->a_hit( ap, &FinalPart );
00297 status = "HIT";
00298
00299
00300
00301
00302 freeup:
00303 {
00304 register struct partition *pp;
00305
00306
00307 for( pp = InitialPart.pt_forw; pp != &InitialPart; ) {
00308 register struct partition *newpp;
00309 newpp = pp;
00310 pp = pp->pt_forw;
00311 FREE_PT(newpp, ap->a_resource);
00312 }
00313
00314 for( pp = FinalPart.pt_forw; pp != &FinalPart; ) {
00315 register struct partition *newpp;
00316 newpp = pp;
00317 pp = pp->pt_forw;
00318 FREE_PT(newpp, ap->a_resource);
00319 }
00320 }
00321
00322 {
00323 register struct seg *segp;
00324
00325 while( HeadSeg != SEG_NULL ) {
00326 segp = HeadSeg->seg_next;
00327 FREE_SEG( HeadSeg, ap->a_resource );
00328 HeadSeg = segp;
00329 }
00330 }
00331
00332 out:
00333 bu_free( (char *)ary_stp, "*ary_stp[]" );
00334 bu_free( (char *)ary_rp, "*ary_rp[]" );
00335 bu_free( (char *)ary_seg, "ary_seg[]" );
00336
00337 if( solidbits != BITV_NULL) {
00338 FREE_BITV( solidbits, ap->a_resource );
00339 }
00340 if(RT_G_DEBUG&(DEBUG_ALLRAYS|DEBUG_SHOOT|DEBUG_PARTITION)) {
00341 if( rt_g.rtg_logindent > 0 )
00342 rt_g.rtg_logindent -= 2;
00343 else
00344 rt_g.rtg_logindent = 0;
00345 bu_log("----------mshootray cpu=%d %d,%d lvl=%d (%s) %s ret=%d\n",
00346 ap->a_resource->re_cpu,
00347 ap->a_x, ap->a_y,
00348 ap->a_level,
00349 ap->a_purpose != (char *)0 ? ap->a_purpose : "?",
00350 status, ret);
00351 }
00352 return( ret );
00353 }
00354
00355 #define SEG_MISS(SEG) (SEG).seg_stp=(struct soltab *) 0;
00356
00357
00358
00359 rt_vstub(struct soltab *stp[],
00360 struct xray *rp[],
00361 struct seg segp[],
00362 int n,
00363 struct resource *resp)
00364 {
00365 register int i;
00366 register struct seg *tmp_seg;
00367
00368
00369 for (i = 0; i < n; i++) {
00370 if (stp[i] != 0){
00371
00372 tmp_seg = rt_functab[stp[i]->st_id].ft_shot(
00373 stp[i], rp[i], resp);
00374
00375
00376 if ( tmp_seg == 0) {
00377 SEG_MISS(segp[i]);
00378 }
00379 else {
00380 segp[i] = *tmp_seg;
00381 FREE_SEG(tmp_seg, resp);
00382 }
00383 }
00384 }
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 rt_in_rpp( struct xray *rp, fastf_t *invdir, fastf_t *min, fastf_t *max )
00413 {
00414 register fastf_t *pt = &rp->r_pt[0];
00415 FAST fastf_t sv;
00416 #define st sv
00417
00418
00419 rp->r_min = -INFINITY;
00420 rp->r_max = INFINITY;
00421
00422
00423 if( rp->r_dir[X] < 0.0 ) {
00424
00425
00426 if( (sv = (*min - *pt) * *invdir) < 0.0 )
00427 return(0);
00428 if(rp->r_max > sv)
00429 rp->r_max = sv;
00430 if( rp->r_min < (st = (*max - *pt) * *invdir) )
00431 rp->r_min = st;
00432 } else if( rp->r_dir[X] > 0.0 ) {
00433
00434
00435 if( (st = (*max - *pt) * *invdir) < 0.0 )
00436 return(0);
00437 if(rp->r_max > st)
00438 rp->r_max = st;
00439 if( rp->r_min < ((sv = (*min - *pt) * *invdir)) )
00440 rp->r_min = sv;
00441 } else {
00442
00443
00444
00445
00446
00447 if( (*min > *pt) || (*max < *pt) )
00448 return(0);
00449 }
00450
00451
00452 pt++; invdir++; max++; min++;
00453 if( rp->r_dir[Y] < 0.0 ) {
00454 if( (sv = (*min - *pt) * *invdir) < 0.0 )
00455 return(0);
00456 if(rp->r_max > sv)
00457 rp->r_max = sv;
00458 if( rp->r_min < (st = (*max - *pt) * *invdir) )
00459 rp->r_min = st;
00460 } else if( rp->r_dir[Y] > 0.0 ) {
00461 if( (st = (*max - *pt) * *invdir) < 0.0 )
00462 return(0);
00463 if(rp->r_max > st)
00464 rp->r_max = st;
00465 if( rp->r_min < ((sv = (*min - *pt) * *invdir)) )
00466 rp->r_min = sv;
00467 } else {
00468 if( (*min > *pt) || (*max < *pt) )
00469 return(0);
00470 }
00471
00472
00473 pt++; invdir++; max++; min++;
00474 if( rp->r_dir[Z] < 0.0 ) {
00475 if( (sv = (*min - *pt) * *invdir) < 0.0 )
00476 return(0);
00477 if(rp->r_max > sv)
00478 rp->r_max = sv;
00479 if( rp->r_min < (st = (*max - *pt) * *invdir) )
00480 rp->r_min = st;
00481 } else if( rp->r_dir[Z] > 0.0 ) {
00482 if( (st = (*max - *pt) * *invdir) < 0.0 )
00483 return(0);
00484 if(rp->r_max > st)
00485 rp->r_max = st;
00486 if( rp->r_min < ((sv = (*min - *pt) * *invdir)) )
00487 rp->r_min = sv;
00488 } else {
00489 if( (*min > *pt) || (*max < *pt) )
00490 return(0);
00491 }
00492
00493
00494 if( rp->r_min > rp->r_max )
00495 return(0);
00496 return(1);
00497 }
00498
00499
00500
00501
00502 void
00503 rt_bitv_or( bitv_t *out, bitv_t *in, int nbits )
00504 {
00505 register int words;
00506
00507 words = RT_BITV_BITS2WORDS(nbits);
00508 #ifdef VECTORIZE
00509 # include "noalias.h"
00510 for( --words; words >= 0; words-- )
00511 out[words] |= in[words];
00512 #else
00513 while( words-- > 0 )
00514 *out++ |= *in++;
00515 #endif
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 void
00531 rt_get_bitv(struct rt_i *rtip, struct resource *res)
00532 {
00533 register char *cp;
00534 register int bytes;
00535 register int size;
00536
00537 size = rtip->rti_bv_bytes;
00538 size = (size+sizeof(long)-1) & ~(sizeof(long)-1);
00539 bytes = bu_malloc_len_roundup(16*size);
00540 if( (cp = bu_malloc(bytes, "rt_get_bitv")) == (char *)0 ) {
00541 bu_log("rt_get_bitv: malloc failure\n");
00542 exit(17);
00543 }
00544 while( bytes >= size ) {
00545 ((union bitv_elem *)cp)->be_next = res->re_bitv;
00546 res->re_bitv = (union bitv_elem *)cp;
00547 res->re_bitvlen++;
00548 cp += size;
00549 bytes -= size;
00550 }
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562