Example #1
0
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;
}
Example #2
0
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;
}