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
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
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
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 #ifndef lint
00144 static const char RCSrec[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/g_rec.c,v 14.11 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00145 #endif
00146
00147 #include "common.h"
00148
00149
00150
00151 #include <stdio.h>
00152 #ifdef HAVE_STRING_H
00153 #include <string.h>
00154 #endif
00155 #include <math.h>
00156 #include "machine.h"
00157 #include "vmath.h"
00158 #include "raytrace.h"
00159 #include "rtgeom.h"
00160 #include "./debug.h"
00161
00162 struct rec_specific {
00163 vect_t rec_V;
00164 vect_t rec_Hunit;
00165 mat_t rec_SoR;
00166 mat_t rec_invRoS;
00167 vect_t rec_A;
00168 vect_t rec_B;
00169 fastf_t rec_iAsq;
00170 fastf_t rec_iBsq;
00171 };
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 int
00191 rt_rec_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
00192 {
00193 struct rt_tgc_internal *tip;
00194 register struct rec_specific *rec;
00195 LOCAL double magsq_h, magsq_a, magsq_b, magsq_c, magsq_d;
00196 LOCAL double mag_h, mag_a, mag_b;
00197 LOCAL mat_t R;
00198 LOCAL mat_t Rinv;
00199 LOCAL mat_t S;
00200 LOCAL vect_t invsq;
00201 LOCAL vect_t work;
00202 LOCAL fastf_t f;
00203
00204 tip = (struct rt_tgc_internal *)ip->idb_ptr;
00205 RT_TGC_CK_MAGIC(tip);
00206
00207
00208 mag_h = sqrt( magsq_h = MAGSQ( tip->h ) );
00209 mag_a = sqrt( magsq_a = MAGSQ( tip->a ) );
00210 mag_b = sqrt( magsq_b = MAGSQ( tip->b ) );
00211 magsq_c = MAGSQ( tip->c );
00212 magsq_d = MAGSQ( tip->d );
00213
00214
00215 if( NEAR_ZERO(mag_h, RT_LEN_TOL) || NEAR_ZERO(mag_a, RT_LEN_TOL)
00216 || NEAR_ZERO(mag_b, RT_LEN_TOL) ) {
00217 return(1);
00218 }
00219
00220
00221 VSUB2( work, tip->a, tip->c );
00222 f = MAGSQ( work );
00223 if( ! NEAR_ZERO(f, 0.0001) ) {
00224 return(1);
00225 }
00226 VSUB2( work, tip->b, tip->d );
00227 f = MAGSQ( work );
00228 if( ! NEAR_ZERO(f, 0.0001) ) {
00229 return(1);
00230 }
00231
00232
00233 f = VDOT( tip->a, tip->b ) / (mag_a * mag_b);
00234 if( ! NEAR_ZERO(f, RT_DOT_TOL) ) {
00235 return(1);
00236 }
00237 f = VDOT( tip->h, tip->a ) / (mag_h * mag_a);
00238 if( ! NEAR_ZERO(f, RT_DOT_TOL) ) {
00239 return(1);
00240 }
00241 f = VDOT( tip->h, tip->b ) / (mag_h * mag_b);
00242 if( ! NEAR_ZERO(f, RT_DOT_TOL) ) {
00243 return(1);
00244 }
00245
00246
00247
00248
00249 stp->st_id = ID_REC;
00250 stp->st_meth = &rt_functab[ID_REC];
00251
00252 BU_GETSTRUCT( rec, rec_specific );
00253 stp->st_specific = (genptr_t)rec;
00254
00255 VMOVE( rec->rec_Hunit, tip->h );
00256 VUNITIZE( rec->rec_Hunit );
00257
00258 VMOVE( rec->rec_V, tip->v );
00259 VMOVE( rec->rec_A, tip->a );
00260 VMOVE( rec->rec_B, tip->b );
00261 rec->rec_iAsq = 1.0/magsq_a;
00262 rec->rec_iBsq = 1.0/magsq_b;
00263
00264 VSET( invsq, 1.0/magsq_a, 1.0/magsq_b, 1.0/magsq_h );
00265
00266
00267 MAT_IDN( R );
00268 f = 1.0/mag_a;
00269 VSCALE( &R[0], tip->a, f );
00270 f = 1.0/mag_b;
00271 VSCALE( &R[4], tip->b, f );
00272 f = 1.0/mag_h;
00273 VSCALE( &R[8], tip->h, f );
00274 bn_mat_trn( Rinv, R );
00275
00276
00277 MAT_IDN( S );
00278 S[ 0] = sqrt( invsq[0] );
00279 S[ 5] = sqrt( invsq[1] );
00280 S[10] = sqrt( invsq[2] );
00281
00282
00283 bn_mat_mul( rec->rec_SoR, S, R );
00284 bn_mat_mul( rec->rec_invRoS, Rinv, S );
00285
00286
00287 {
00288 LOCAL fastf_t dx, dy, dz;
00289 LOCAL vect_t P, w1;
00290 LOCAL fastf_t f, tmp, z;
00291
00292
00293 VSET( P, 1.0, 0, 0 );
00294 MAT3X3VEC( w1, R, P );
00295
00296 tmp = magsq_a * w1[X] * w1[X] + magsq_b * w1[Y] * w1[Y];
00297 if( tmp > SMALL )
00298 f = sqrt(tmp);
00299 else
00300 f = 0;
00301 stp->st_min[X] = rec->rec_V[X] - f;
00302 stp->st_max[X] = rec->rec_V[X] + f;
00303
00304 z = w1[Z] * mag_h;
00305 tmp = magsq_c * w1[X] * w1[X] + magsq_d * w1[Y] * w1[Y];
00306 if( tmp > SMALL )
00307 f = sqrt(tmp);
00308 else
00309 f = 0;
00310 if( rec->rec_V[X] - f + z < stp->st_min[X] )
00311 stp->st_min[X] = rec->rec_V[X] - f + z;
00312 if( rec->rec_V[X] + f + z > stp->st_max[X] )
00313 stp->st_max[X] = rec->rec_V[X] + f + z;
00314
00315
00316 VSET( P, 0, 1.0, 0 );
00317 MAT3X3VEC( w1, R, P );
00318
00319 tmp = magsq_a * w1[X] * w1[X] + magsq_b * w1[Y] * w1[Y];
00320 if( tmp > SMALL )
00321 f = sqrt(tmp);
00322 else
00323 f = 0;
00324 stp->st_min[Y] = rec->rec_V[Y] - f;
00325 stp->st_max[Y] = rec->rec_V[Y] + f;
00326
00327 z = w1[Z] * mag_h;
00328 tmp = magsq_c * w1[X] * w1[X] + magsq_d * w1[Y] * w1[Y];
00329 if( tmp > SMALL )
00330 f = sqrt(tmp);
00331 else
00332 f = 0;
00333 if( rec->rec_V[Y] - f + z < stp->st_min[Y] )
00334 stp->st_min[Y] = rec->rec_V[Y] - f + z;
00335 if( rec->rec_V[Y] + f + z > stp->st_max[Y] )
00336 stp->st_max[Y] = rec->rec_V[Y] + f + z;
00337
00338
00339 VSET( P, 0, 0, 1.0 );
00340 MAT3X3VEC( w1, R, P );
00341
00342 tmp = magsq_a * w1[X] * w1[X] + magsq_b * w1[Y] * w1[Y];
00343 if( tmp > SMALL )
00344 f = sqrt(tmp);
00345 else
00346 f = 0;
00347 stp->st_min[Z] = rec->rec_V[Z] - f;
00348 stp->st_max[Z] = rec->rec_V[Z] + f;
00349
00350 z = w1[Z] * mag_h;
00351 tmp = magsq_c * w1[X] * w1[X] + magsq_d * w1[Y] * w1[Y];
00352 if( tmp > SMALL )
00353 f = sqrt(tmp);
00354 else
00355 f = 0;
00356 if( rec->rec_V[Z] - f + z < stp->st_min[Z] )
00357 stp->st_min[Z] = rec->rec_V[Z] - f + z;
00358 if( rec->rec_V[Z] + f + z > stp->st_max[Z] )
00359 stp->st_max[Z] = rec->rec_V[Z] + f + z;
00360
00361 VSET( stp->st_center,
00362 (stp->st_max[X] + stp->st_min[X])/2,
00363 (stp->st_max[Y] + stp->st_min[Y])/2,
00364 (stp->st_max[Z] + stp->st_min[Z])/2 );
00365
00366 dx = (stp->st_max[X] - stp->st_min[X])/2;
00367 f = dx;
00368 dy = (stp->st_max[Y] - stp->st_min[Y])/2;
00369 if( dy > f ) f = dy;
00370 dz = (stp->st_max[Z] - stp->st_min[Z])/2;
00371 if( dz > f ) f = dz;
00372 stp->st_aradius = f;
00373 stp->st_bradius = sqrt(dx*dx + dy*dy + dz*dz);
00374 }
00375 return(0);
00376 }
00377
00378
00379
00380
00381 void
00382 rt_rec_print(register const struct soltab *stp)
00383 {
00384 register const struct rec_specific *rec =
00385 (struct rec_specific *)stp->st_specific;
00386
00387 VPRINT("V", rec->rec_V);
00388 VPRINT("Hunit", rec->rec_Hunit);
00389 bn_mat_print("S o R", rec->rec_SoR );
00390 bn_mat_print("invR o S", rec->rec_invRoS );
00391 }
00392
00393
00394 #define REC_NORM_BODY (1)
00395 #define REC_NORM_TOP (2)
00396 #define REC_NORM_BOT (3)
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 int
00411 rt_rec_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
00412 {
00413 register struct rec_specific *rec =
00414 (struct rec_specific *)stp->st_specific;
00415 LOCAL vect_t dprime;
00416 LOCAL vect_t pprime;
00417 LOCAL fastf_t k1, k2;
00418 LOCAL vect_t xlated;
00419 LOCAL struct hit hits[4];
00420 register struct hit *hitp;
00421 int nhits = 0;
00422
00423 hitp = &hits[0];
00424
00425
00426 MAT4X3VEC( dprime, rec->rec_SoR, rp->r_dir );
00427 VSUB2( xlated, rp->r_pt, rec->rec_V );
00428 MAT4X3VEC( pprime, rec->rec_SoR, xlated );
00429
00430 if( NEAR_ZERO(dprime[X], SMALL) && NEAR_ZERO(dprime[Y], SMALL) )
00431 goto check_plates;
00432
00433
00434 {
00435 FAST fastf_t b;
00436 FAST fastf_t root;
00437 FAST fastf_t dx2dy2;
00438
00439 b = 2 * ( dprime[X]*pprime[X] + dprime[Y]*pprime[Y] ) *
00440 (dx2dy2 = 1 / (dprime[X]*dprime[X] + dprime[Y]*dprime[Y]));
00441 if( (root = b*b - 4 * dx2dy2 *
00442 (pprime[X]*pprime[X] + pprime[Y]*pprime[Y] - 1)) <= 0 )
00443 goto check_plates;
00444 root = sqrt(root);
00445
00446 k1 = (root-b) * 0.5;
00447 k2 = (root+b) * (-0.5);
00448 }
00449
00450
00451
00452
00453
00454 VJOIN1( hitp->hit_vpriv, pprime, k1, dprime );
00455 if( hitp->hit_vpriv[Z] >= 0.0 && hitp->hit_vpriv[Z] <= 1.0 ) {
00456 hitp->hit_magic = RT_HIT_MAGIC;
00457 hitp->hit_dist = k1;
00458 hitp->hit_surfno = REC_NORM_BODY;
00459 hitp++; nhits++;
00460 }
00461
00462 VJOIN1( hitp->hit_vpriv, pprime, k2, dprime );
00463 if( hitp->hit_vpriv[Z] >= 0.0 && hitp->hit_vpriv[Z] <= 1.0 ) {
00464 hitp->hit_magic = RT_HIT_MAGIC;
00465 hitp->hit_dist = k2;
00466 hitp->hit_surfno = REC_NORM_BODY;
00467 hitp++; nhits++;
00468 }
00469
00470
00471
00472
00473 check_plates:
00474 if( nhits < 2 && !NEAR_ZERO(dprime[Z], SMALL) ) {
00475
00476 k1 = -pprime[Z] / dprime[Z];
00477 k2 = (1.0 - pprime[Z]) / dprime[Z];
00478
00479 VJOIN1( hitp->hit_vpriv, pprime, k1, dprime );
00480 if( hitp->hit_vpriv[X] * hitp->hit_vpriv[X] +
00481 hitp->hit_vpriv[Y] * hitp->hit_vpriv[Y] <= 1.0 ) {
00482 hitp->hit_magic = RT_HIT_MAGIC;
00483 hitp->hit_dist = k1;
00484 hitp->hit_surfno = REC_NORM_BOT;
00485 hitp++; nhits++;
00486 }
00487
00488 VJOIN1( hitp->hit_vpriv, pprime, k2, dprime );
00489 if( hitp->hit_vpriv[X] * hitp->hit_vpriv[X] +
00490 hitp->hit_vpriv[Y] * hitp->hit_vpriv[Y] <= 1.0 ) {
00491 hitp->hit_magic = RT_HIT_MAGIC;
00492 hitp->hit_dist = k2;
00493 hitp->hit_surfno = REC_NORM_TOP;
00494 hitp++; nhits++;
00495 }
00496 }
00497 if( nhits == 0 ) return 0;
00498 if( nhits == 2 ) {
00499 hit:
00500 if( hits[0].hit_dist < hits[1].hit_dist ) {
00501
00502 register struct seg *segp;
00503
00504 RT_GET_SEG(segp, ap->a_resource);
00505 segp->seg_stp = stp;
00506 segp->seg_in = hits[0];
00507 segp->seg_out = hits[1];
00508 BU_LIST_INSERT( &(seghead->l), &(segp->l) );
00509 } else {
00510
00511 register struct seg *segp;
00512
00513 RT_GET_SEG(segp, ap->a_resource);
00514 segp->seg_stp = stp;
00515 segp->seg_in = hits[1];
00516 segp->seg_out = hits[0];
00517 BU_LIST_INSERT( &(seghead->l), &(segp->l) );
00518 }
00519 return 2;
00520 }
00521 if( nhits == 1 ) {
00522 if( hits[0].hit_surfno != REC_NORM_BODY )
00523 bu_log("rt_rec_shot(%s): 1 intersection with end plate?\n", stp->st_name );
00524
00525
00526
00527
00528
00529
00530 hits[1] = hits[0];
00531 nhits++;
00532 goto hit;
00533 }
00534 if( nhits == 3 ) {
00535 fastf_t tol_dist = ap->a_rt_i->rti_tol.dist;
00536
00537
00538
00539
00540 k1 = hits[0].hit_dist - hits[1].hit_dist;
00541 if( NEAR_ZERO( k1, tol_dist ) ) {
00542 if(RT_G_DEBUG&DEBUG_ARB8)bu_log("rt_rec_shot(%s): 3 hits, collapsing 0&1\n", stp->st_name);
00543 hits[1] = hits[2];
00544 nhits--;
00545 goto hit;
00546 }
00547 k1 = hits[1].hit_dist - hits[2].hit_dist;
00548 if( NEAR_ZERO( k1, tol_dist ) ) {
00549 if(RT_G_DEBUG&DEBUG_ARB8)bu_log("rt_rec_shot(%s): 3 hits, collapsing 1&2\n", stp->st_name);
00550 nhits--;
00551 goto hit;
00552 }
00553 k1 = hits[0].hit_dist - hits[2].hit_dist;
00554 if( NEAR_ZERO( k1, tol_dist ) ) {
00555 if(RT_G_DEBUG&DEBUG_ARB8)bu_log("rt_rec_shot(%s): 3 hits, collapsing 1&2\n", stp->st_name);
00556 nhits--;
00557 goto hit;
00558 }
00559 }
00560
00561 bu_log("rt_rec_shot(%s): %d unique hits?!? %g, %g, %g, %g\n",
00562 stp->st_name, nhits,
00563 hits[0].hit_dist,
00564 hits[1].hit_dist,
00565 hits[2].hit_dist,
00566 hits[3].hit_dist);
00567
00568
00569 goto hit;
00570 }
00571
00572 #define SEG_MISS(SEG) (SEG).seg_stp=(struct soltab *) 0;
00573
00574
00575
00576
00577
00578 void
00579 rt_rec_vshot(struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
00580
00581
00582
00583
00584
00585 {
00586 register int i;
00587 register struct rec_specific *rec;
00588 LOCAL vect_t dprime;
00589 LOCAL vect_t pprime;
00590 LOCAL fastf_t k1, k2;
00591 LOCAL vect_t xlated;
00592 LOCAL struct hit hits[3];
00593 register struct hit *hitp;
00594 FAST fastf_t b;
00595 FAST fastf_t root;
00596 FAST fastf_t dx2dy2;
00597
00598
00599 # include "noalias.h"
00600 for(i = 0; i < n; i++){
00601 #if !CRAY
00602 if (stp[i] == 0) continue;
00603 #endif
00604
00605 rec = (struct rec_specific *)stp[i]->st_specific;
00606 hitp = &hits[0];
00607
00608
00609 MAT4X3VEC( dprime, rec->rec_SoR, rp[i]->r_dir );
00610 VSUB2( xlated, rp[i]->r_pt, rec->rec_V );
00611 MAT4X3VEC( pprime, rec->rec_SoR, xlated );
00612
00613 if( NEAR_ZERO(dprime[X], SMALL) && NEAR_ZERO(dprime[Y], SMALL) )
00614 goto check_plates;
00615
00616
00617 b = 2 * ( dprime[X]*pprime[X] + dprime[Y]*pprime[Y] ) *
00618 (dx2dy2 = 1 / (dprime[X]*dprime[X] + dprime[Y]*dprime[Y]));
00619 if( (root = b*b - 4 * dx2dy2 *
00620 (pprime[X]*pprime[X] + pprime[Y]*pprime[Y] - 1)) <= 0 )
00621 goto check_plates;
00622
00623 root = sqrt(root);
00624 k1 = (root-b) * 0.5;
00625 k2 = (root+b) * (-0.5);
00626
00627
00628
00629
00630
00631 VJOIN1( hitp->hit_vpriv, pprime, k1, dprime );
00632 if( hitp->hit_vpriv[Z] >= 0.0 && hitp->hit_vpriv[Z] <= 1.0 ) {
00633 hitp->hit_dist = k1;
00634 hitp->hit_surfno = REC_NORM_BODY;
00635 hitp++;
00636 }
00637
00638 VJOIN1( hitp->hit_vpriv, pprime, k2, dprime );
00639 if( hitp->hit_vpriv[Z] >= 0.0 && hitp->hit_vpriv[Z] <= 1.0 ) {
00640 hitp->hit_dist = k2;
00641 hitp->hit_surfno = REC_NORM_BODY;
00642 hitp++;
00643 }
00644
00645
00646
00647
00648 check_plates:
00649 if( hitp < &hits[2] && !NEAR_ZERO(dprime[Z], SMALL) ) {
00650
00651 k1 = -pprime[Z] / dprime[Z];
00652 k2 = (1.0 - pprime[Z]) / dprime[Z];
00653
00654 VJOIN1( hitp->hit_vpriv, pprime, k1, dprime );
00655 if( hitp->hit_vpriv[X] * hitp->hit_vpriv[X] +
00656 hitp->hit_vpriv[Y] * hitp->hit_vpriv[Y] <= 1.0 ) {
00657 hitp->hit_dist = k1;
00658 hitp->hit_surfno = REC_NORM_BOT;
00659 hitp++;
00660 }
00661
00662 VJOIN1( hitp->hit_vpriv, pprime, k2, dprime );
00663 if( hitp->hit_vpriv[X] * hitp->hit_vpriv[X] +
00664 hitp->hit_vpriv[Y] * hitp->hit_vpriv[Y] <= 1.0 ) {
00665 hitp->hit_dist = k2;
00666 hitp->hit_surfno = REC_NORM_TOP;
00667 hitp++;
00668 }
00669 }
00670
00671 if( hitp != &hits[2] ) {
00672 SEG_MISS(segp[i]);
00673 } else {
00674 segp[i].seg_stp = stp[i];
00675
00676 if( hits[0].hit_dist < hits[1].hit_dist ) {
00677
00678 VMOVE(segp[i].seg_in.hit_vpriv, hits[0].hit_vpriv);
00679 segp[i].seg_in.hit_dist = hits[0].hit_dist;
00680 segp[i].seg_in.hit_surfno = hits[0].hit_surfno;
00681 VMOVE(segp[i].seg_out.hit_vpriv, hits[1].hit_vpriv);
00682 segp[i].seg_out.hit_dist = hits[1].hit_dist;
00683 segp[i].seg_out.hit_surfno = hits[1].hit_surfno;
00684 } else {
00685
00686 VMOVE(segp[i].seg_in.hit_vpriv, hits[1].hit_vpriv);
00687 segp[i].seg_in.hit_dist = hits[1].hit_dist;
00688 segp[i].seg_in.hit_surfno = hits[1].hit_surfno;
00689 VMOVE(segp[i].seg_out.hit_vpriv, hits[0].hit_vpriv);
00690 segp[i].seg_out.hit_dist = hits[0].hit_dist;
00691 segp[i].seg_out.hit_surfno = hits[0].hit_surfno;
00692 }
00693 }
00694 }
00695 }
00696
00697
00698
00699
00700
00701
00702
00703 void
00704 rt_rec_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
00705 {
00706 register struct rec_specific *rec =
00707 (struct rec_specific *)stp->st_specific;
00708
00709 VJOIN1( hitp->hit_point, rp->r_pt, hitp->hit_dist, rp->r_dir );
00710 switch( hitp->hit_surfno ) {
00711 case REC_NORM_BODY:
00712
00713 hitp->hit_vpriv[Z] = 0.0;
00714 MAT4X3VEC( hitp->hit_normal, rec->rec_invRoS,
00715 hitp->hit_vpriv );
00716 VUNITIZE( hitp->hit_normal );
00717 break;
00718 case REC_NORM_TOP:
00719 VMOVE( hitp->hit_normal, rec->rec_Hunit );
00720 break;
00721 case REC_NORM_BOT:
00722 VREVERSE( hitp->hit_normal, rec->rec_Hunit );
00723 break;
00724 default:
00725 bu_log("rt_rec_norm: surfno=%d bad\n", hitp->hit_surfno);
00726 break;
00727 }
00728 }
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 void
00739 rt_rec_curve(register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
00740 {
00741 register struct rec_specific *rec =
00742 (struct rec_specific *)stp->st_specific;
00743 vect_t uu;
00744 fastf_t ax, bx, q;
00745
00746 switch( hitp->hit_surfno ) {
00747 case REC_NORM_BODY:
00748
00749
00750
00751 VMOVE( cvp->crv_pdir, rec->rec_Hunit );
00752 VSUB2( uu, hitp->hit_point, rec->rec_V );
00753 cvp->crv_c1 = 0;
00754 ax = VDOT( uu, rec->rec_A ) * rec->rec_iAsq;
00755 bx = VDOT( uu, rec->rec_B ) * rec->rec_iBsq;
00756 q = sqrt( ax * ax * rec->rec_iAsq + bx * bx * rec->rec_iBsq );
00757 cvp->crv_c2 = - rec->rec_iAsq * rec->rec_iBsq / (q*q*q);
00758 break;
00759 case REC_NORM_TOP:
00760 case REC_NORM_BOT:
00761 bn_vec_ortho( cvp->crv_pdir, hitp->hit_normal );
00762 cvp->crv_c1 = cvp->crv_c2 = 0;
00763 break;
00764 default:
00765 bu_log("rt_rec_curve: bad surfno %d\n", hitp->hit_surfno);
00766 break;
00767 }
00768 }
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 void
00780 rt_rec_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
00781 {
00782 register struct rec_specific *rec =
00783 (struct rec_specific *)stp->st_specific;
00784 LOCAL vect_t work;
00785 LOCAL vect_t pprime;
00786 FAST fastf_t len;
00787 FAST fastf_t ratio;
00788
00789
00790
00791
00792 VSUB2( work, hitp->hit_point, rec->rec_V );
00793 MAT4X3VEC( pprime, rec->rec_SoR, work );
00794
00795 switch( hitp->hit_surfno ) {
00796 case REC_NORM_BODY:
00797
00798 ratio = pprime[Y];
00799 if( ratio > 1.0 )
00800 ratio = 1.0;
00801 if( ratio < -1.0 )
00802 ratio = -1.0;
00803 uvp->uv_u = acos(ratio) * bn_inv2pi;
00804 uvp->uv_v = pprime[Z];
00805 break;
00806 case REC_NORM_TOP:
00807
00808 len = sqrt(pprime[X]*pprime[X]+pprime[Y]*pprime[Y]);
00809 ratio = pprime[Y]/len;
00810 if( ratio > 1.0 )
00811 ratio = 1.0;
00812 if( ratio < -1.0 )
00813 ratio = -1.0;
00814 uvp->uv_u = acos(ratio) * bn_inv2pi;
00815 uvp->uv_v = len;
00816 break;
00817 case REC_NORM_BOT:
00818
00819 len = sqrt(pprime[X]*pprime[X]+pprime[Y]*pprime[Y]);
00820 ratio = pprime[Y]/len;
00821 if( ratio > 1.0 )
00822 ratio = 1.0;
00823 if( ratio < -1.0 )
00824 ratio = -1.0;
00825 uvp->uv_u = acos(ratio) * bn_inv2pi;
00826 uvp->uv_v = 1 - len;
00827 break;
00828 }
00829
00830 if( pprime[X] < 0 )
00831 uvp->uv_u = 1.0 - uvp->uv_u;
00832
00833 if( uvp->uv_u < 0 ) uvp->uv_u = 0;
00834 else if( uvp->uv_u > 1 ) uvp->uv_u = 1;
00835 if( uvp->uv_v < 0 ) uvp->uv_v = 0;
00836 else if( uvp->uv_v > 1 ) uvp->uv_v = 1;
00837
00838
00839 uvp->uv_du = uvp->uv_dv = 0;
00840 }
00841
00842
00843
00844
00845 void
00846 rt_rec_free(struct soltab *stp)
00847 {
00848 register struct rec_specific *rec =
00849 (struct rec_specific *)stp->st_specific;
00850
00851 bu_free( (char *)rec, "rec_specific");
00852 }
00853
00854 int
00855 rt_rec_class(void)
00856 {
00857 return(0);
00858 }
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872