/**
 * For a hit on the surface of an METABALL, return the (u, v)
 * coordinates of the hit point, 0 <= u, v <= 1.
 *
 * u = azimuth
 * v = elevation
 */
void
rt_metaball_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
{
    struct rt_metaball_internal *metaball = (struct rt_metaball_internal *)stp->st_specific;
    vect_t work, pprime;
    fastf_t r;

    if (ap) RT_CK_APPLICATION(ap);
    if (stp) RT_CK_SOLTAB(stp);
    if (hitp) RT_CK_HIT(hitp);
    if (!uvp) return;
    if (!metaball) return;

    /* stuff stolen from sph */
    VSUB2(work, hitp->hit_point, stp->st_center);
    VSCALE(pprime, work, 1.0/MAGNITUDE(work));
    /* Assert that pprime has unit length */

    /* U is azimuth, atan() range: -pi to +pi */
    uvp->uv_u = bn_atan2(pprime[Y], pprime[X]) * M_1_2PI;
    if (uvp->uv_u < 0)
	uvp->uv_u += 1.0;
    /*
     * V is elevation, atan() range: -pi/2 to +pi/2, because sqrt()
     * ensures that X parameter is always >0
     */
    uvp->uv_v = bn_atan2(pprime[Z],
			 sqrt(pprime[X] * pprime[X] + pprime[Y] * pprime[Y])) * M_1_2PI;

    /* approximation: r / (circumference, 2 * pi * aradius) */
    r = ap->a_rbeam + ap->a_diverge * hitp->hit_dist;
    uvp->uv_du = uvp->uv_dv =
	M_1_2PI * r / stp->st_aradius;
    return;
}
int
rt_obj_shot(struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead)
{
    int id;
    const struct rt_functab *ft;

    if (!stp || !rp)
	return -1;

    RT_CK_SOLTAB(stp);
    RT_CK_RAY(rp);
    if (ap) RT_CK_APPLICATION(ap);

    id = stp->st_id;
    if (id < 0)
	return -2;

    ft = &OBJ[id];
    if (!ft)
	return -3;
    if (!ft->ft_shot)
	return -4;

    return ft->ft_shot(stp, rp, ap, seghead);
}
HIDDEN int
raydiff_miss(struct application *ap)
{
    RT_CK_APPLICATION(ap);

    return 0;
}
Example #4
0
int
rt_obj_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
{
    int id;
    const struct rt_functab *ft;

    if (!stp || !hitp || !uvp)
	return -1;

    RT_CK_SOLTAB(stp);
    RT_CK_HIT(hitp);
    if (ap) RT_CK_APPLICATION(ap);

    id = stp->st_id;
    if (id < 0)
	return -2;

    ft = &rt_functab[id];
    if (!ft)
	return -3;
    if (!ft->ft_uv)
	return -4;

    ft->ft_uv(ap, stp, hitp, uvp);
    return 0;
}
Example #5
0
File: xxx.c Project: kanzure/brlcad
/**
 * Intersect a ray with a xxx.  If an intersection occurs, a struct
 * seg will be acquired and filled in.
 *
 * Returns -
 * 0 MISS
 * >0 HIT
 */
int
rt_xxx_shot(struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead)
{
    struct xxx_specific *xxx;

    if (!stp) return -1;
    RT_CK_SOLTAB(stp);
    xxx = (struct xxx_specific *)stp->st_specific;
    if (!xxx) return -1;
    if (rp) RT_CK_RAY(rp);
    if (ap) RT_CK_APPLICATION(ap);
    if (!seghead) return -1;

/* the EXAMPLE_NEW_SEGMENT block shows how one might add a new result
 * if the ray did hit the primitive.  the segment values would need to
 * be adjusted accordingly to match real values instead of -1.
 */
#ifdef EXAMPLE_NEW_SEGMENT
    /* allocate a segment */
    RT_GET_SEG(segp, ap->a_resource);
    segp->seg_stp = stp; /* stash a pointer to the primitive */

    segp->seg_in.hit_dist = -1; /* XXX set to real distance to entry point */
    segp->seg_out.hit_dist = -1; /* XXX set to real distance to exit point */
    segp->seg_in.hit_surfno = -1; /* XXX set to a non-negative ID for entry surface */
    segp->seg_out.hit_surfno = -1;  /* XXX set to a non-negative ID for exit surface */

    /* add segment to list of those encountered for this primitive */
    BU_LIST_INSERT(&(seghead->l), &(segp->l));

    return 2; /* num surface intersections == in + out == 2 */
#endif

    return 0;			/* MISS */
}
/* don't care about misses */
HIDDEN int
ignore_miss(struct application *app)
{
    RT_CK_APPLICATION(app);
    //bu_log("miss!\n");
    return 0;
}
/* add all hit point info to info list */
HIDDEN int
add_hit_pnts(struct application *app, struct partition *partH, struct seg *UNUSED(segs))
{

    struct partition *pp;
    struct soltab *stp;
    /*point_t hit_pnt;
    vect_t hit_normal;*/
    struct rt_point_container *c = (struct rt_point_container *)(app->a_uptr);
    struct npoints *npt;

    if (c->pnt_cnt > c->capacity-1) {
	c->capacity *= 4;
	c->pts = (struct npoints *)bu_realloc((char *)c->pts, c->capacity * sizeof(struct npoints), "enlarge results array");
    }

    RT_CK_APPLICATION(app);
    /*struct bu_vls *fp = (struct bu_vls *)(app->a_uptr);*/

    /* add all hit points */
    for (pp = partH->pt_forw; pp != partH; pp = pp->pt_forw) {

	npt = &(c->pts[c->pnt_cnt]);

	/* add "in" hit point info */
	stp = pp->pt_inseg->seg_stp;

	/* hack fix for bad tgc surfaces */
	if (bu_strncmp("rec", stp->st_meth->ft_label, 3) == 0 || bu_strncmp("tgc", stp->st_meth->ft_label, 3) == 0) {

	    /* correct invalid surface number */
	    if (pp->pt_inhit->hit_surfno < 1 || pp->pt_inhit->hit_surfno > 3) {
		pp->pt_inhit->hit_surfno = 2;
	    }
	    if (pp->pt_outhit->hit_surfno < 1 || pp->pt_outhit->hit_surfno > 3) {
		pp->pt_outhit->hit_surfno = 2;
	    }
	}


	VJOIN1(npt->in.p, app->a_ray.r_pt, pp->pt_inhit->hit_dist, app->a_ray.r_dir);
	RT_HIT_NORMAL(npt->in.n, pp->pt_inhit, stp, &(app->a_ray), pp->pt_inflip);
	npt->in.is_set = 1;
	//bu_vls_printf(fp, "%f %f %f %f %f %f\n", hit_pnt[0], hit_pnt[1], hit_pnt[2], hit_normal[0], hit_normal[1], hit_normal[2]);
	/* add "out" hit point info (unless half-space) */
	stp = pp->pt_inseg->seg_stp;
	if (bu_strncmp("half", stp->st_meth->ft_label, 4) != 0) {
	    VJOIN1(npt->out.p, app->a_ray.r_pt, pp->pt_outhit->hit_dist, app->a_ray.r_dir);
	    RT_HIT_NORMAL(npt->out.n, pp->pt_outhit, stp, &(app->a_ray), pp->pt_outflip);
	    npt->out.is_set = 1;
	    //bu_vls_printf(fp, "%f %f %f %f %f %f\n", hit_pnt[0], hit_pnt[1], hit_pnt[2], hit_normal[0], hit_normal[1], hit_normal[2]);
	}
	c->pnt_cnt++;
    }
    return 1;
}
Example #8
0
/**
 * For a hit on the surface of an SUPERELL, return the (u, v) coordinates
 * of the hit point, 0 <= u, v <= 1.
 * u = azimuth
 * v = elevation
 */
void
rt_superell_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
{
    if (ap) RT_CK_APPLICATION(ap);
    if (!stp || !hitp || !uvp)
        return;
    RT_CK_SOLTAB(stp);
    RT_CK_HIT(hitp);

    bu_log("called rt_superell_uv()\n");
    return;
}
Example #9
0
/**
 * R T _ P G _ U V
 */
void
rt_pg_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
{
    if (ap) RT_CK_APPLICATION(ap);
    if (stp) RT_CK_SOLTAB(stp);
    if (hitp) RT_CK_HIT(hitp);
    if (!uvp)
	return;

    /* Do nothing.  Really, should do what ARB does. */
    uvp->uv_u = uvp->uv_v = 0;
    uvp->uv_du = uvp->uv_dv = 0;
}
Example #10
0
File: xxx.c Project: kanzure/brlcad
/**
 * For a hit on the surface of an xxx, return the (u, v) coordinates
 * of the hit point, 0 <= u, v <= 1.

 * u = azimuth,  v = elevation
 */
void
rt_xxx_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
{
    struct xxx_specific *xxx;

    if (ap) RT_CK_APPLICATION(ap);
    if (!stp || !uvp) return;
    RT_CK_SOLTAB(stp);
    if (hitp) RT_CK_HIT(hitp);

    xxx = (struct xxx_specific *)stp->st_specific;
    if (!xxx) return;
}
Example #11
0
/**
 * For a hit on a face of an ARB, return the (u, v) coordinates
 * of the hit point.  0 <= u, v <= 1.
 * u extends along the arb_U direction defined by B-A,
 * v extends along the arb_V direction defined by Nx(B-A).
 */
void
rt_arbn_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
{
    struct rt_arbn_internal *arbn = (struct rt_arbn_internal *)stp->st_specific;

    if (ap) RT_CK_APPLICATION(ap);
    RT_ARBN_CK_MAGIC(arbn);
    if (hitp) RT_CK_HIT(hitp);

    if (uvp) {
	uvp->uv_u = uvp->uv_v = 0;
	uvp->uv_du = uvp->uv_dv = 0;
    }
}
Example #12
0
File: hyp.c Project: kanzure/brlcad
/**
 * For a hit on the surface of an hyp, return the (u, v) coordinates
 * of the hit point, 0 <= u, v <= 1.
 *
 * u = azimuth
 * v = elevation
 */
void
rt_hyp_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
{
    struct hyp_specific *hyp =	(struct hyp_specific *)stp->st_specific;

    if (ap) RT_CK_APPLICATION(ap);

    /* u = (angle from semi-major axis on basic hyperboloid) / (2*pi) */
    uvp->uv_u = M_1_2PI
	* (atan2(-hitp->hit_vpriv[X] * hyp->hyp_r2, hitp->hit_vpriv[Y] * hyp->hyp_r1) + M_PI);

    /* v ranges (0, 1) on each plate */
    switch (hitp->hit_surfno) {
	case HYP_NORM_BODY:
	    /* v = (z + Hmag) / (2*Hmag) */
	    uvp->uv_v = (hitp->hit_vpriv[Z] + hyp->hyp_Hmag) / (2.0 * hyp->hyp_Hmag);
	    break;
	case HYP_NORM_TOP:
	    uvp->uv_v = 1.0 - sqrt(
		((hitp->hit_vpriv[X]*hitp->hit_vpriv[X])*hyp->hyp_rx
		 + (hitp->hit_vpriv[Y]*hitp->hit_vpriv[Y])*hyp->hyp_ry)
		/ (1 + (hitp->hit_vpriv[Z]*hitp->hit_vpriv[Z])*hyp->hyp_rz));
	    break;
	case HYP_NORM_BOTTOM:
	    uvp->uv_v = sqrt(
		((hitp->hit_vpriv[X]*hitp->hit_vpriv[X])*hyp->hyp_rx
		 + (hitp->hit_vpriv[Y]*hitp->hit_vpriv[Y])*hyp->hyp_ry)
		/ (1 + (hitp->hit_vpriv[Z]*hitp->hit_vpriv[Z])*hyp->hyp_rz));
	    break;
    }

    /* sanity checks */
    if (uvp->uv_u < 0.0)
	uvp->uv_u = 0.0;
    else if (uvp->uv_u > 1.0)
	uvp->uv_u = 1.0;
    if (uvp->uv_v < 0.0)
	uvp->uv_v = 0.0;
    else if (uvp->uv_v > 1.0)
	uvp->uv_v = 1.0;

    /* copied from g_ehy.c */
    uvp->uv_du = uvp->uv_dv = 0;
}
Example #13
0
/**
 * For a hit on the surface of an revolve, return the (u, v) coordinates
 * of the hit point, 0 <= u, v <= 1.

 * u = azimuth,  v = elevation
 */
void
rt_revolve_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
{
    struct revolve_specific *rev = (struct revolve_specific *)stp->st_specific;

    point_t hitpoint;
    fastf_t angle;
    uint32_t *lng;
    struct line_seg *lsg;

    /*
    struct carc_seg *csg;
    struct nurb_seg *nsg;
    struct bezier_seg *bsg;
    */

    if (ap) RT_CK_APPLICATION(ap);

    VJOIN1(hitpoint, hitp->hit_rayp->r_pt, hitp->hit_dist, hitp->hit_rayp->r_dir);

    switch (hitp->hit_surfno) {
	case START_FACE_POS:
	case START_FACE_NEG:
	case END_FACE_POS:
	case END_FACE_NEG:
	    uvp->uv_u = fabs((hitp->hit_vpriv[X] - rev->bounds[0]) / (rev->bounds[1] - rev->bounds[0]));
	    uvp->uv_v = fabs((hitp->hit_vpriv[Y] - rev->bounds[2]) / (rev->bounds[3] - rev->bounds[2]));
	    break;
	case HORIZ_SURF:
	    hitpoint[Z] = 0;

	    /* Y is the angle: [0, 2pi] */
	    uvp->uv_u = hitp->hit_vpriv[Y] / rev->ang;

	    /* X is the coord of the endpoint that we're connecting to the revolve axis */
	    uvp->uv_v = fabs((MAGNITUDE(hitpoint) - hitp->hit_vpriv[Z])
			     / (hitp->hit_vpriv[X]- hitp->hit_vpriv[Z]));
	    /* bu_log("\tmin: %3.2f\tmax: %3.2f\n", hitp->hit_vpriv[Z], hitp->hit_vpriv[X]); */
	    break;
	default:
	    angle = atan2(hitp->hit_vpriv[Y], hitp->hit_vpriv[X]);
	    if (angle < 0) angle += M_2PI;
	    uvp->uv_u = angle / rev->ang;

	    lng = (uint32_t *)rev->skt->curve.segment[hitp->hit_surfno];

	    switch (*lng) {
		case CURVE_LSEG_MAGIC:
		    lsg = (struct line_seg *)lng;
		    if (ZERO(1.0/hitp->hit_vpriv[Z])) {
			/* use hitpoint radius and sketch's X values */
			hitpoint[Z] = 0;
			uvp->uv_v = (MAGNITUDE(hitpoint) - rev->skt->verts[lsg->end][X]) /
			    (rev->skt->verts[lsg->start][X] - rev->skt->verts[lsg->end][X]);
		    } else {
			/* use hitpoint Z and sketch's Y values */
			uvp->uv_v = (hitpoint[Z] - rev->skt->verts[lsg->end][Y]) /
			    (rev->skt->verts[lsg->start][Y] - rev->skt->verts[lsg->end][Y]);
		    }
		    break;
		case CURVE_CARC_MAGIC:
		    /* csg = (struct carc_seg *)lng; */
		    break;
		case CURVE_BEZIER_MAGIC:
		    /* bsg = (struct bezier_seg *)lng; */
		    break;
		case CURVE_NURB_MAGIC:
		    /* nsg = (struct nurb_seg *)lng; */
		    break;
		default:
		    bu_log("rt_revolve_prep: ERROR: unrecognized segment type!\n");
		    break;
	    }

	    break;
    }
    if (uvp->uv_v > 1 || uvp->uv_v < 0 || uvp->uv_u > 1 || uvp->uv_u < 0) {
	bu_log("UV error:\t%d\t%2.2f\t%2.2f\t", hitp->hit_surfno, uvp->uv_u, uvp->uv_v);
	bu_log("\tX: (%3.2f, %3.2f)\tY: (%3.2f, %3.2f)\n", rev->bounds[0], rev->bounds[1], rev->bounds[2], rev->bounds[3]);
    }
    /* sanity checks */
    if (uvp->uv_u < 0.0)
	uvp->uv_u = 0.0;
    else if (uvp->uv_u > 1.0)
	uvp->uv_u = 1.0;
    if (uvp->uv_v < 0.0)
	uvp->uv_v = 0.0;
    else if (uvp->uv_v > 1.0)
	uvp->uv_v = 1.0;
}
Example #14
0
/**
 * R E C _ U V
 *
 * For a hit on the surface of an REC, return the (u, v) coordinates
 * of the hit point, 0 <= u, v <= 1.
 *
 * u is the rotation around the cylinder, and
 * v is the displacement along H.
 */
void
rt_rec_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
{
    struct rec_specific *rec =
	(struct rec_specific *)stp->st_specific;

    vect_t work;
    vect_t pprime;
    fastf_t len;
    fastf_t ratio;

    if (ap) RT_CK_APPLICATION(ap);

    /* hit_point is on surface;  project back to unit cylinder,
     * creating a vector from vertex to hit point.
     */
    VSUB2(work, hitp->hit_point, rec->rec_V);
    MAT4X3VEC(pprime, rec->rec_SoR, work);

    switch (hitp->hit_surfno) {
	case REC_NORM_BODY:
	    /* Skin.  x, y coordinates define rotation.  radius = 1 */
	    ratio = pprime[Y];
	    if (ratio > 1.0)
		ratio = 1.0;
	    if (ratio < -1.0)
		ratio = -1.0;
	    uvp->uv_u = acos(ratio) * bn_inv2pi;
	    uvp->uv_v = pprime[Z];		/* height */
	    break;
	case REC_NORM_TOP:
	    /* top plate */
	    len = sqrt(pprime[X]*pprime[X]+pprime[Y]*pprime[Y]);
	    ratio = pprime[Y]/len;
	    if (ratio > 1.0)
		ratio = 1.0;
	    if (ratio < -1.0)
		ratio = -1.0;
	    uvp->uv_u = acos(ratio) * bn_inv2pi;
	    uvp->uv_v = len;		/* rim v = 1 */
	    break;
	case REC_NORM_BOT:
	    /* bottom plate */
	    len = sqrt(pprime[X]*pprime[X]+pprime[Y]*pprime[Y]);
	    ratio = pprime[Y]/len;
	    if (ratio > 1.0)
		ratio = 1.0;
	    if (ratio < -1.0)
		ratio = -1.0;
	    uvp->uv_u = acos(ratio) * bn_inv2pi;
	    uvp->uv_v = 1 - len;	/* rim v = 0 */
	    break;
    }
    /* Handle other half of acos() domain */
    if (pprime[X] < 0)
	uvp->uv_u = 1.0 - uvp->uv_u;

    if (uvp->uv_u < 0) uvp->uv_u = 0;
    else if (uvp->uv_u > 1) uvp->uv_u = 1;
    if (uvp->uv_v < 0) uvp->uv_v = 0;
    else if (uvp->uv_v > 1) uvp->uv_v = 1;

    /* XXX uv_du should be relative to rotation, uv_dv relative to height */
    uvp->uv_du = uvp->uv_dv = 0;
}
Example #15
0
/**
 * R E C _ V S H O T
 *
 * This is the Becker vector version
 */
void
rt_rec_vshot(struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
    /* An array of solid pointers */
    /* An array of ray pointers */
    /* array of segs (results returned) */
    /* Number of ray/object pairs */

{
    int i;
    struct rec_specific *rec;
    vect_t dprime;		/* D' */
    vect_t pprime;		/* P' */
    fastf_t k1, k2;		/* distance constants of solution */
    vect_t xlated;		/* translated vector */
    struct hit hits[3];	/* 4 potential hit points */
    struct hit *hitp;	/* pointer to hit point */
    fastf_t b;		/* coeff of polynomial */
    fastf_t root;		/* root of radical */
    fastf_t dx2dy2;

    if (ap) RT_CK_APPLICATION(ap);

    /* for each ray/right_elliptical_cylinder pair */
    for (i = 0; i < n; i++) {
	if (stp[i] == 0) continue; /* stp[i] == 0 signals skip ray */

	rec = (struct rec_specific *)stp[i]->st_specific;
	hitp = &hits[0];

	/* out, Mat, vect */
	MAT4X3VEC(dprime, rec->rec_SoR, rp[i]->r_dir);
	VSUB2(xlated, rp[i]->r_pt, rec->rec_V);
	MAT4X3VEC(pprime, rec->rec_SoR, xlated);

	if (ZERO(dprime[X]) && ZERO(dprime[Y]))
	    goto check_plates;

	/* Find roots of eqn, using formula for quadratic w/ a=1 */
	b = 2 * (dprime[X]*pprime[X] + dprime[Y]*pprime[Y]) *
	    (dx2dy2 = 1 / (dprime[X]*dprime[X] + dprime[Y]*dprime[Y]));
	if ((root = b*b - 4 * dx2dy2 *
	     (pprime[X]*pprime[X] + pprime[Y]*pprime[Y] - 1)) <= 0)
	    goto check_plates;

	root = sqrt(root);
	k1 = (root-b) * 0.5;
	k2 = (root+b) * (-0.5);

	/*
	 * k1 and k2 are potential solutions to intersection with side.
	 * See if they fall in range.
	 */
	VJOIN1(hitp->hit_vpriv, pprime, k1, dprime);	/* hit' */
	if (hitp->hit_vpriv[Z] >= 0.0 && hitp->hit_vpriv[Z] <= 1.0) {
	    hitp->hit_dist = k1;
	    hitp->hit_surfno = REC_NORM_BODY;	/* compute N */
	    hitp++;
	}

	VJOIN1(hitp->hit_vpriv, pprime, k2, dprime);		/* hit' */
	if (hitp->hit_vpriv[Z] >= 0.0 && hitp->hit_vpriv[Z] <= 1.0) {
	    hitp->hit_dist = k2;
	    hitp->hit_surfno = REC_NORM_BODY;	/* compute N */
	    hitp++;
	}

	/*
	 * Check for hitting the end plates.
	 */
    check_plates:
	if (hitp < &hits[2]  &&  !ZERO(dprime[Z])) {
	    /* 0 or 1 hits so far, this is worthwhile */
	    k1 = -pprime[Z] / dprime[Z];	/* bottom plate */
	    k2 = (1.0 - pprime[Z]) / dprime[Z];	/* top plate */

	    VJOIN1(hitp->hit_vpriv, pprime, k1, dprime);/* hit' */
	    if (hitp->hit_vpriv[X] * hitp->hit_vpriv[X] +
		hitp->hit_vpriv[Y] * hitp->hit_vpriv[Y] <= 1.0) {
		hitp->hit_dist = k1;
		hitp->hit_surfno = REC_NORM_BOT;	/* -H */
		hitp++;
	    }

	    VJOIN1(hitp->hit_vpriv, pprime, k2, dprime);/* hit' */
	    if (hitp->hit_vpriv[X] * hitp->hit_vpriv[X] +
		hitp->hit_vpriv[Y] * hitp->hit_vpriv[Y] <= 1.0) {
		hitp->hit_dist = k2;
		hitp->hit_surfno = REC_NORM_TOP;	/* +H */
		hitp++;
	    }
	}

	if (hitp != &hits[2]) {
	    RT_REC_SEG_MISS(segp[i]);		/* MISS */
	} else {
	    segp[i].seg_stp = stp[i];

	    if (hits[0].hit_dist < hits[1].hit_dist) {
		/* entry is [0], exit is [1] */
		VMOVE(segp[i].seg_in.hit_vpriv, hits[0].hit_vpriv);
		segp[i].seg_in.hit_dist = hits[0].hit_dist;
		segp[i].seg_in.hit_surfno = hits[0].hit_surfno;
		VMOVE(segp[i].seg_out.hit_vpriv, hits[1].hit_vpriv);
		segp[i].seg_out.hit_dist = hits[1].hit_dist;
		segp[i].seg_out.hit_surfno = hits[1].hit_surfno;
	    } else {
		/* entry is [1], exit is [0] */
		VMOVE(segp[i].seg_in.hit_vpriv, hits[1].hit_vpriv);
		segp[i].seg_in.hit_dist = hits[1].hit_dist;
		segp[i].seg_in.hit_surfno = hits[1].hit_surfno;
		VMOVE(segp[i].seg_out.hit_vpriv, hits[0].hit_vpriv);
		segp[i].seg_out.hit_dist = hits[0].hit_dist;
		segp[i].seg_out.hit_surfno = hits[0].hit_surfno;
	    }
	}
    }
}