static void hit_octant(struct application *ap, register Octree *op, register Octree **lpp, fastf_t *inv_dir, int level) { for (; op != OCTREE_NULL; op = op->o_sibling ) { fastf_t octnt_min[3], octnt_max[3]; fastf_t delta = modl_radius / pow_Of_2( level ); /* See if ray hits the octant RPP. */ octnt_min[X] = op->o_points->c_point[X] - delta; octnt_min[Y] = op->o_points->c_point[Y] - delta; octnt_min[Z] = op->o_points->c_point[Z] - delta; octnt_max[X] = op->o_points->c_point[X] + delta; octnt_max[Y] = op->o_points->c_point[Y] + delta; octnt_max[Z] = op->o_points->c_point[Z] + delta; if ( rt_in_rpp( &ap->a_ray, inv_dir, octnt_min, octnt_max ) ) { /* Hit octant. */ if ( op->o_child == OCTREE_NULL ) { /* We are at a leaf node. */ if ( ap->a_uvec[0] > ap->a_ray.r_min ) { /* Closest, so far. */ ap->a_uvec[0] = ap->a_ray.r_min; ap->a_level = level; *lpp = op; } } else /* We must descend to lower level. */ hit_octant( ap, op->o_child, lpp, inv_dir, level+1 ); } } /* No more octants at this level. */ return; }
Octree * new_Octant(Octree *parentp, Octree **childpp, int bitv, int level) { register Octree *childp; fastf_t delta = modl_radius / pow_Of_2( level ); register float *origin = parentp->o_points->c_point; /* Create child node, filling in parent's pointer. */ if ( ! NewOctree( *childpp ) ) { Malloc_Bomb(sizeof(Octree)); fatal_error = TRUE; return OCTREE_NULL; } /* Fill in fields in child node. */ childp = *childpp; childp->o_bitv = bitv; childp->o_temp = ABSOLUTE_ZERO; /* Unclaimed by temperature. */ childp->o_triep = TRIE_NULL; /* Unclaimed by region. */ childp->o_sibling = OCTREE_NULL; /* End of sibling chain. */ childp->o_child = OCTREE_NULL; /* No children yet. */ /* Create list node for origin of leaf octant. */ if ( ! NewPoint( childp->o_points ) ) { Malloc_Bomb(sizeof(PtList)); fatal_error = TRUE; return OCTREE_NULL; } childp->o_points->c_next = PTLIST_NULL; /* End of pt. chain. */ /* Compute origin relative to parent, based on bit vector. */ if ( bitv & 1<<X ) childp->o_points->c_point[X] = origin[X] + delta; else childp->o_points->c_point[X] = origin[X] - delta; if ( bitv & 1<<Y ) childp->o_points->c_point[Y] = origin[Y] + delta; else childp->o_points->c_point[Y] = origin[Y] - delta; if ( bitv & 1<<Z ) childp->o_points->c_point[Z] = origin[Z] + delta; else childp->o_points->c_point[Z] = origin[Z] - delta; return childp; }
int f_IR_Model(struct application *ap, Octree *op) { fastf_t octnt_min[3], octnt_max[3]; fastf_t delta = modl_radius / pow_Of_2(ap->a_level); fastf_t point[3] = VINIT_ZERO; /* Intersection point. */ fastf_t norml[3] = VINIT_ZERO; /* Unit normal at point. */ /* Push ray origin along ray direction to intersection point. */ VJOIN1(point, ap->a_ray.r_pt, ap->a_uvec[0], ap->a_ray.r_dir); /* Compute octant RPP. */ octnt_min[X] = op->o_points->c_point[X] - delta; octnt_min[Y] = op->o_points->c_point[Y] - delta; octnt_min[Z] = op->o_points->c_point[Z] - delta; octnt_max[X] = op->o_points->c_point[X] + delta; octnt_max[Y] = op->o_points->c_point[Y] + delta; octnt_max[Z] = op->o_points->c_point[Z] + delta; if (NEAR_EQUAL(point[X], octnt_min[X], epsilon)) /* Intersection point lies on plane whose normal is the negative X-axis. */ { norml[X] = -1.0; norml[Y] = 0.0; norml[Z] = 0.0; } else if (NEAR_EQUAL(point[X], octnt_max[X], epsilon)) /* Intersection point lies on plane whose normal is the positive X-axis. */ { norml[X] = 1.0; norml[Y] = 0.0; norml[Z] = 0.0; } else if (NEAR_EQUAL(point[Y], octnt_min[Y], epsilon)) /* Intersection point lies on plane whose normal is the negative Y-axis. */ { norml[X] = 0.0; norml[Y] = -1.0; norml[Z] = 0.0; } else if (NEAR_EQUAL(point[Y], octnt_max[Y], epsilon)) /* Intersection point lies on plane whose normal is the positive Y-axis. */ { norml[X] = 0.0; norml[Y] = 1.0; norml[Z] = 0.0; } else if (NEAR_EQUAL(point[Z], octnt_min[Z], epsilon)) /* Intersection point lies on plane whose normal is the negative Z-axis. */ { norml[X] = 0.0; norml[Y] = 0.0; norml[Z] = -1.0; } else if (NEAR_EQUAL(point[Z], octnt_max[Z], epsilon)) /* Intersection point lies on plane whose normal is the positive Z-axis. */ { norml[X] = 0.0; norml[Y] = 0.0; norml[Z] = 1.0; } { /* Factor in reflectance from "ambient" light source. */ fastf_t intensity = VDOT(norml, lgts[0].dir); /* Calculate index into false-color table. */ int lgtindex = op->o_temp - ir_min; if (lgtindex > ir_max_index) { bu_log("Temperature (%d) above range of data.\n", op->o_temp); return -1; } if (lgtindex < 0) /* Un-assigned octants get colored grey. */ ap->a_color[0] = ap->a_color[1] = ap->a_color[2] = intensity; else { /* Lookup false-coloring for octant's temperature. */ intensity *= RGB_INVERSE; ap->a_color[0] = (fastf_t) (ir_table[lgtindex][RED]) * intensity; ap->a_color[1] = (fastf_t) (ir_table[lgtindex][GRN]) * intensity; ap->a_color[2] = (fastf_t) (ir_table[lgtindex][BLU]) * intensity; } } return 1; }