int BrlCadInterface::hit(application *ap, struct partition *PartHeadp, seg *segs) { register struct partition *pp; register struct hit *hitp; register struct soltab *stp; struct curvature cur; point_t pt; vect_t inormal; vect_t onormal; double curv; int N = 0; //for (pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw) { pp = PartHeadp->pt_forw; { ++N; hitp = pp->pt_inhit; stp = pp->pt_inseg->seg_stp; VJOIN1(pt, ap->a_ray.r_pt, hitp->hit_dist, ap->a_ray.r_dir); RT_HIT_NORMAL(inormal, hitp, stp, &(ap->a_ray), pp->pt_inflip); RT_CURVATURE(&cur, hitp, pp->pt_inflip, stp); curv = max(fabs(cur.crv_c1), fabs(cur.crv_c2)); m_InRadius = 1.0/max(1e-10, curv); m_XIn[0] = pt[0]; m_XIn[1] = pt[1]; m_XIn[2] = pt[2]; m_InNormal[0] = inormal[0]; m_InNormal[1] = inormal[1]; m_InNormal[2] = inormal[2]; hitp = pp->pt_outhit; stp = pp->pt_outseg->seg_stp; VJOIN1(pt, ap->a_ray.r_pt, hitp->hit_dist, ap->a_ray.r_dir); RT_HIT_NORMAL( onormal, hitp, stp, &(ap->a_ray), pp->pt_outflip ); RT_CURVATURE(&cur, hitp, pp->pt_inflip, stp); curv = max(fabs(cur.crv_c1), fabs(cur.crv_c2)); m_OutRadius = 1.0/max(1e-10, curv); m_XOut[0] = pt[0]; m_XOut[1] = pt[1]; m_XOut[2] = pt[2]; m_OutNormal[0] = onormal[0]; m_OutNormal[1] = onormal[1]; m_OutNormal[2] = onormal[2]; } m_Hit = true; return(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; }
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); }
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 */ }
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 */ }