Пример #1
0
/**
 * rt_shootray() was told to call this on a hit.
 *
 * This callback routine utilizes the application structure which
 * describes the current state of the raytrace.
 *
 * This callback routine is provided a circular linked list of
 * partitions, each one describing one in and out segment of one
 * region for each region encountered.
 *
 * The 'segs' segment list is unused in this example.
 */
int
hit(struct application *ap, struct partition *PartHeadp, struct seg *segs)
{
    /* iterating over partitions, this will keep track of the current
     * partition we're working on.
     */
    struct partition *pp;

    /* will serve as a pointer for the entry and exit hitpoints */
    struct hit *hitp;

    /* will serve as a pointer to the solid primitive we hit */
    struct soltab *stp;

    /* will contain surface curvature information at the entry */
    struct curvature cur;

    /* will contain our hit point coordinate */
    point_t pt;

    /* will contain normal vector where ray enters geometry */
     vect_t inormal;

    /* will contain normal vector where ray exits geometry */
    vect_t onormal;

    /* iterate over each partition until we get back to the head.
     * each partition corresponds to a specific homogeneous region of
     * material.
     */
    for (pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw) {

	/* print the name of the region we hit as well as the name of
	 * the primitives encountered on entry and exit.
	 */
	bu_log("\n--- Hit region %s (in %s, out %s)\n",
	       pp->pt_regionp->reg_name,
	       pp->pt_inseg->seg_stp->st_name,
	       pp->pt_outseg->seg_stp->st_name );

	/* entry hit point, so we type less */
	hitp = pp->pt_inhit;

	/* construct the actual (entry) hit-point from the ray and the
	 * distance to the intersection point (i.e., the 't' value).
	 */
	VJOIN1(pt, ap->a_ray.r_pt, hitp->hit_dist, ap->a_ray.r_dir);

	/* primitive we encountered on entry */
	stp = pp->pt_inseg->seg_stp;

	/* compute the normal vector at the entry point, flipping the
	 * normal if necessary.
	 */
	RT_HIT_NORMAL(inormal, hitp, stp, &(ap->a_ray), pp->pt_inflip);

	/* print the entry hit point info */
	rt_pr_hit("  In", hitp);
	VPRINT(   "  Ipoint", pt);
	VPRINT(   "  Inormal", inormal);

	/* This next macro fills in the curvature information which
	 * consists on a principle direction vector, and the inverse
	 * radii of curvature along that direction and perpendicular
	 * to it.  Positive curvature bends toward the outward
	 * pointing normal.
	 */
	RT_CURVATURE(&cur, hitp, pp->pt_inflip, stp);

	/* print the entry curvature information */
	VPRINT("PDir", cur.crv_pdir);
	bu_log(" c1=%g\n", cur.crv_c1);
	bu_log(" c2=%g\n", cur.crv_c2);

	/* exit point, so we type less */
	hitp = pp->pt_outhit;

	/* construct the actual (exit) hit-point from the ray and the
	 * distance to the intersection point (i.e., the 't' value).
	 */
	VJOIN1(pt, ap->a_ray.r_pt, hitp->hit_dist, ap->a_ray.r_dir);

	/* primitive we exited from */
	stp = pp->pt_outseg->seg_stp;

	/* compute the normal vector at the exit point, flipping the
	 * normal if necessary.
	 */
	RT_HIT_NORMAL(onormal, hitp, stp, &(ap->a_ray), pp->pt_outflip);

	/* print the exit hit point info */
	rt_pr_hit("  Out", hitp);
	VPRINT(   "  Opoint", pt);
	VPRINT(   "  Onormal", onormal);
    }

    /* A more complicated application would probably fill in a new
     * local application structure and describe, for example, a
     * reflected or refracted ray, and then call rt_shootray() for
     * those rays.
     */

    /* Hit routine callbacks generally return 1 on hit or 0 on miss.
     * This value is returned by rt_shootray().
     */
    return 1;
}
Пример #2
0
static int
radhit(register struct application *ap, struct partition *PartHeadp, struct seg *segHeadp)
{
    register struct partition *pp;
    register struct hit *hitp;
    struct application sub_ap;
    fastf_t	f;
    vect_t	to_eye, work;
    int	depth;

    for ( pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw )
	if ( pp->pt_outhit->hit_dist >= 0.0 )  break;
    if ( pp == PartHeadp )  {
	bu_log("radhit:  no hit out front?\n");
	return(0);
    }

    if (R_DEBUG&RDEBUG_HITS)  {
	rt_pr_pt( ap->a_rt_i, pp );
    }

    hitp = pp->pt_inhit;
    if ( hitp->hit_dist >= INFINITY )  {
	bu_log("radhit:  entry beyond infinity\n");
	return(1);
    }
    /* Check to see if eye is "inside" the solid */
    if ( hitp->hit_dist < 0 )  {
	/* XXX */
	bu_log("radhit:  GAK, eye inside solid (%g)\n", hitp->hit_dist );
	for ( pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw )
	    rt_pr_pt( ap->a_rt_i, pp );
	return(0);
    }

    rayp = &rayinfo[ ap->a_level ];

    RT_HIT_NORMAL( rayp->norm, hitp, pp->pt_inseg->seg_stp, &(ap->a_ray), pp->pt_inflip );

    if (R_DEBUG&RDEBUG_HITS)  {
	rt_pr_hit( " In", hitp );
    }

    rayp->dist = hitp->hit_dist;
    rayp->reg = pp->pt_regionp->reg_regionid;
    rayp->sol = pp->pt_inseg->seg_stp->st_id;
    rayp->surf = hitp->hit_surfno;
    RT_CURVATURE( &(rayp->curvature), hitp, pp->pt_inflip, pp->pt_inseg->seg_stp );
    if ( VDOT( rayp->norm, ap->a_ray.r_dir ) < 0 ) {
	bu_log(" debug: flipping curvature\n");
	rayp->curvature.crv_c1 = - rayp->curvature.crv_c1;
	rayp->curvature.crv_c2 = - rayp->curvature.crv_c2;
    }
    VMOVE( rayp->ip, hitp->hit_point );

    /* Compute the specular direction */
    VREVERSE( to_eye, ap->a_ray.r_dir );
    f = 2 * VDOT( to_eye, rayp->norm );
    VSCALE( work, rayp->norm, f );
    /* I have been told this has unit length */
    VSUB2( rayp->spec, work, to_eye );

    /* Save info for 1st ray */
    if ( ap->a_level == 0 ) {
	firstray = ap->a_ray;	/* struct copy */
	rayp->sight = 1;	/* the 1st intersect is always visible */
    } else {
	/* Check for visibility */
	rayp->sight = isvisible( ap, hitp, rayp->norm );
    }

    /*
     * Shoot another ray in the specular direction.
     */
    if ( ap->a_level < numreflect-1 ) {
	sub_ap = *ap;	/* struct copy */
	sub_ap.a_level = ap->a_level+1;
	VMOVE( sub_ap.a_ray.r_pt, hitp->hit_point );
	VMOVE( sub_ap.a_ray.r_dir, rayp->spec );
	depth = rt_shootray( &sub_ap );
    } else {
	bu_log( "radhit:  max reflections exceeded [%d %d]\n",
		ap->a_x, ap->a_y );
	depth = 0;
    }

    if ( ap->a_level == 0 ) {
	/* We're the 1st ray, output the raylist */
	dumpall( ap, depth+1 );
    }
    return(depth+1);	/* report hit to main routine */
}
Пример #3
0
int hit(register struct application *ap, struct partition *PartHeadp, struct seg *segp)
{
    register struct partition *pp;
    register struct soltab *stp;
    struct curvature cur;
    fastf_t out;
    point_t inpt, outpt;
    vect_t	inormal, onormal;

    if ( (pp=PartHeadp->pt_forw) == PartHeadp )
	return(0);		/* Nothing hit?? */

    if ( overlap_claimant_handling == 1 )
	rt_rebuild_overlaps( PartHeadp, ap, 1 );
    else if ( overlap_claimant_handling == 2 )
	rt_rebuild_overlaps( PartHeadp, ap, 0 );

    /* First, plot ray start to inhit */
    if ( R_DEBUG&RDEBUG_RAYPLOT )  {
	if ( pp->pt_inhit->hit_dist > 0.0001 )  {
	    VJOIN1( inpt, ap->a_ray.r_pt,
		    pp->pt_inhit->hit_dist, ap->a_ray.r_dir );
	    pl_color( plotfp, 0, 0, 255 );
	    pdv_3line( plotfp, ap->a_ray.r_pt, inpt );
	}
    }
    for (; pp != PartHeadp; pp = pp->pt_forw )  {
	matp_t inv_mat;
	Tcl_HashEntry *entry;

	bu_log("\n--- Hit region %s (in %s, out %s) reg_bit = %d\n",
	       pp->pt_regionp->reg_name,
	       pp->pt_inseg->seg_stp->st_name,
	       pp->pt_outseg->seg_stp->st_name,
	       pp->pt_regionp->reg_bit);

	entry = Tcl_FindHashEntry( (Tcl_HashTable *)ap->a_rt_i->Orca_hash_tbl,
				   (const char *)(size_t)pp->pt_regionp->reg_bit );
	if ( !entry ) {
	    inv_mat = (matp_t)NULL;
	}
	else {
	    inv_mat = (matp_t)Tcl_GetHashValue( entry );
	    bn_mat_print( "inv_mat", inv_mat );
	}

	if ( pp->pt_overlap_reg )
	{
	    struct region *pp_reg;
	    int j=-1;

	    bu_log( "    Claiming regions:\n" );
	    while ( (pp_reg=pp->pt_overlap_reg[++j]) )
		bu_log( "        %s\n", pp_reg->reg_name );
	}

	/* inhit info */
	stp = pp->pt_inseg->seg_stp;
	VJOIN1( inpt, ap->a_ray.r_pt, pp->pt_inhit->hit_dist, ap->a_ray.r_dir );
	RT_HIT_NORMAL( inormal, pp->pt_inhit, stp, &(ap->a_ray), pp->pt_inflip );
	RT_CURVATURE( &cur, pp->pt_inhit, pp->pt_inflip, stp );

	rt_pr_hit( "  In", pp->pt_inhit );
	VPRINT(    "  Ipoint", inpt );
	VPRINT(    "  Inormal", inormal );
	bu_log(    "   PDir (%g, %g, %g) c1=%g, c2=%g\n",
		   V3ARGS(cur.crv_pdir), cur.crv_c1, cur.crv_c2);

	if ( inv_mat ) {
	    point_t in_trans;

	    MAT4X3PNT( in_trans, inv_mat, inpt );
	    bu_log( "\ttransformed ORCA inhit = (%g %g %g)\n", V3ARGS( in_trans ) );
	}

	/* outhit info */
	stp = pp->pt_outseg->seg_stp;
	VJOIN1( outpt, ap->a_ray.r_pt, pp->pt_outhit->hit_dist, ap->a_ray.r_dir );
	RT_HIT_NORMAL( onormal, pp->pt_outhit, stp, &(ap->a_ray), pp->pt_outflip );
	RT_CURVATURE( &cur, pp->pt_outhit, pp->pt_outflip, stp );

	rt_pr_hit( "  Out", pp->pt_outhit );
	VPRINT(    "  Opoint", outpt );
	VPRINT(    "  Onormal", onormal );
	bu_log(    "   PDir (%g, %g, %g) c1=%g, c2=%g\n",
		   V3ARGS(cur.crv_pdir), cur.crv_c1, cur.crv_c2);

	if ( inv_mat ) {
	    point_t out_trans;
	    vect_t dir_trans;

	    MAT4X3PNT( out_trans, inv_mat, outpt );
	    MAT4X3VEC( dir_trans, inv_mat, ap->a_ray.r_dir );
	    VUNITIZE( dir_trans );
	    bu_log( "\ttranformed ORCA outhit = (%g %g %g)\n", V3ARGS( out_trans ) );
	    bu_log( "\ttransformed ORCA ray direction = (%g %g %g)\n", V3ARGS( dir_trans ) );
	}

	/* Plot inhit to outhit */
	if ( R_DEBUG&RDEBUG_RAYPLOT )  {
	    if ( (out = pp->pt_outhit->hit_dist) >= INFINITY )
		out = 10000;	/* to imply the direction */

	    VJOIN1( outpt,
		    ap->a_ray.r_pt, out,
		    ap->a_ray.r_dir );
	    pl_color( plotfp, 0, 255, 255 );
	    pdv_3line( plotfp, inpt, outpt );
	}

	{
	    struct region *regp = pp->pt_regionp;
	    int i;

	    if ( ap->attrs ) {
		bu_log( "\tattribute values:\n" );
		i = 0;
		while ( ap->attrs[i] && regp->attr_values[i] ) {
		    bu_log( "\t\t%s:\n", ap->attrs[i] );
		    bu_log( "\t\t\tstring rep = %s\n",
			    BU_MRO_GETSTRING(regp->attr_values[i]));
		    bu_log( "\t\t\tlong rep = %d\n",
			    BU_MRO_GETLONG(regp->attr_values[i]));
		    bu_log( "\t\t\tdouble rep = %f\n",
			    BU_MRO_GETDOUBLE(regp->attr_values[i]));
		    i++;
		}
	    }
	}
    }
    return(1);
}
Пример #4
0
static int
radhit( struct application *ap, struct partition *PartHeadp )
{
    register struct partition *pp;
    register struct hit *hitp;
    struct application sub_ap;
    struct rayinfo *rayp;
    fastf_t	f;
    vect_t	to_eye, work;
    int	depth;
    int	cpu_num;


    for ( pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw )
	if ( pp->pt_outhit->hit_dist >= 0.0 )  break;
    if ( pp == PartHeadp )  {
	bu_log("radhit:  no hit out front?\n");
	return 0;
    }

    if (R_DEBUG&RDEBUG_HITS)  {
	rt_pr_pt( ap->a_rt_i, pp );
    }

    hitp = pp->pt_inhit;
    if ( hitp->hit_dist >= INFINITY )  {
	bu_log("radhit:  entry beyond infinity\n");
	return 1;
    }
    /* Check to see if eye is "inside" the solid */
    if ( hitp->hit_dist < 0 )  {
	/* XXX */
	return 0;
    }

    if (R_DEBUG&RDEBUG_HITS)  {
	rt_pr_hit( " In", hitp );
    }

    if ( ap->a_resource == RESOURCE_NULL)
	cpu_num = 0;
    else
	cpu_num = ap->a_resource->re_cpu;

    rayp = &rayinfo[cpu_num][ ap->a_level +1 ];
    rayp->x = ap->a_x;
    rayp->y = ap->a_y;
    rayp->dist = hitp->hit_dist;
    rayp->reg = pp->pt_regionp->reg_regionid;
    rayp->sol = pp->pt_inseg->seg_stp->st_id;
    rayp->surf = hitp->hit_surfno;
    RT_HIT_NORMAL( rayp->norm, hitp, pp->pt_inseg->seg_stp, &(ap->a_ray), pp->pt_inflip );
    RT_CURVATURE( &(rayp->curvature), hitp, pp->pt_inflip, pp->pt_inseg->seg_stp );
    if ( VDOT( hitp->hit_normal, ap->a_ray.r_dir ) < 0 ) {
	bu_log(" debug: curvature flip\n");
	rayp->curvature.crv_c1 = - rayp->curvature.crv_c1;
	rayp->curvature.crv_c2 = - rayp->curvature.crv_c2;
    }
    VMOVE( rayp->ip, hitp->hit_point );
    VMOVE( rayp->dir, ap->a_ray.r_dir);

    /* Compute the specular direction */
    VREVERSE( to_eye, ap->a_ray.r_dir );
    f = 2 * VDOT( to_eye, rayp->norm );
    VSCALE( work, rayp->norm, f );
    /* I have been told this has unit length */
    VSUB2( rayp->spec, work, to_eye );
    VUNITIZE( rayp->spec );

    /* Save info for 1st ray */
    if ( ap->a_level == 0 ) {
	firstray[cpu_num] = ap->a_ray;	/* struct copy */
	rayp->sight = 1;	/* the 1st intersect is always visible */
    } else {
	/* Check for visibility */
	rayp->sight = isvisible( ap, hitp, rayp->norm );
    }

    /*
     * Shoot another ray in the specular direction.
     */
    if ( ap->a_level < numreflect-1 ) {
	sub_ap = *ap;	/* struct copy */
	sub_ap.a_level = ap->a_level+1;
	sub_ap.a_purpose = "secondary ray";
	VMOVE( sub_ap.a_ray.r_pt, hitp->hit_point );
	VMOVE( sub_ap.a_ray.r_dir, rayp->spec );
	depth = rt_shootray( &sub_ap );
    } else {
	depth = 0;
    }

    if ( ap->a_level == 0 ) {
	rayinfo[cpu_num][0].x = ap->a_x;
	rayinfo[cpu_num][0].y = ap->a_y;
	rayinfo[cpu_num][0].surf = depth+1;
	rayinfo[cpu_num][0].ip[0] = ap->a_ray.r_pt[0];
	rayinfo[cpu_num][0].ip[1] = ap->a_ray.r_pt[1];
	rayinfo[cpu_num][0].ip[2] = ap->a_ray.r_pt[2];
	radar_physics( cpu_num, depth + 1 );
#ifdef SAR
	dumpall( ap, cpu_num, depth + 1);
#endif
    }

    return depth+1;	/* report hit to main routine */
}