コード例 #1
0
int
handle_main_ray(struct application *ap, register struct partition *PartHeadp,
		struct seg *segp)
{
    register struct partition *pp;
    register struct hit *hitp; /* which hit */

    struct application a2;
    struct cell me;
    struct cell below;
    struct cell left;

    struct cell above;
    struct cell right;

    double intensity = 1.0;

    int edge = 0;
    int cpu;
    int oc = 1;

    RGBpixel col;

    RT_APPLICATION_INIT(&a2);
    memset(&me, 0, sizeof(struct cell));
    memset(&below, 0, sizeof(struct cell));
    memset(&left, 0, sizeof(struct cell));

    cpu = ap->a_resource->re_cpu;

    if (PartHeadp == NULL || segp == NULL) {
	/* The main shotline missed.  pack the application struct
	 */
	me.c_ishit    = 0;
	me.c_dist   = MISS_DIST;
	me.c_id	    = MISS_ID;
	me.c_region = 0;
	VSETALL(me.c_hit, MISS_DIST);
	VSETALL(me.c_normal, 0);
	VMOVE(me.c_rdir, ap->a_ray.r_dir);
    } else {
	pp = PartHeadp->pt_forw;
	hitp = pp->pt_inhit;
	/*
	 * Stuff the information for this cell.
	 */
	me.c_ishit    = 1;
	me.c_id = pp->pt_regionp->reg_regionid;
	me.c_dist = hitp->hit_dist;
	me.c_region = pp->pt_regionp;
	VMOVE(me.c_rdir, ap->a_ray.r_dir);
	VJOIN1(me.c_hit, ap->a_ray.r_pt, hitp->hit_dist, ap->a_ray.r_dir);
	RT_HIT_NORMAL(me.c_normal, hitp,
		      pp->pt_inseg->seg_stp, &(ap->a_ray), pp->pt_inflip);
    }

    /*
     * Now, fire a ray for both the cell below and if necessary, the
     * cell to the left.
     */
    a2.a_hit = rayhit2;
    a2.a_miss = raymiss2;
    a2.a_onehit = 1;
    a2.a_rt_i = ap->a_rt_i;
    a2.a_resource = ap->a_resource;
    a2.a_logoverlap = ap->a_logoverlap;

    VSUB2(a2.a_ray.r_pt, ap->a_ray.r_pt, dy_model); /* below */
    VMOVE(a2.a_ray.r_dir, ap->a_ray.r_dir);
    a2.a_uptr = (void *)&below;
    rt_shootray(&a2);

    if (ap->a_x == 0) {
	/*
	 * For the first pixel in a scanline, we have to shoot to the
	 * left.  For each pixel afterword, we save the current cell
	 * info to be used as the left side cell info for the
	 * following pixel
	 */
	VSUB2(a2.a_ray.r_pt, ap->a_ray.r_pt, dx_model); /* left */
	VMOVE(a2.a_ray.r_dir, ap->a_ray.r_dir);
	a2.a_uptr = (void *)&left;
	rt_shootray(&a2);
    } else {
	left.c_ishit = saved[cpu]->c_ishit;
	left.c_id = saved[cpu]->c_id;
	left.c_dist = saved[cpu]->c_dist;
	left.c_region = saved[cpu]->c_region;
	VMOVE(left.c_rdir, saved[cpu]->c_rdir);
	VMOVE(left.c_hit, saved[cpu]->c_hit);
	VMOVE(left.c_normal, saved[cpu]->c_normal);
    }

    if (both_sides) {
	VADD2(a2.a_ray.r_pt, ap->a_ray.r_pt, dy_model); /* above */
	VMOVE(a2.a_ray.r_dir, ap->a_ray.r_dir);
	a2.a_uptr = (void *)&above;
	rt_shootray(&a2);

	VADD2(a2.a_ray.r_pt, ap->a_ray.r_pt, dx_model); /* right */
	VMOVE(a2.a_ray.r_dir, ap->a_ray.r_dir);
	a2.a_uptr = (void *)&right;
	rt_shootray(&a2);
    }


    /*
     * Is this pixel an edge?
     */
    if (both_sides) {
	edge = is_edge(&intensity, ap, &me, &left, &below, &right, &above);
    } else {
	edge = is_edge(&intensity, ap, &me, &left, &below, NULL, NULL);
    }

    /*
     * Does this pixel occlude the second geometry?  Note that we must
     * check on edges as well since right side and top edges are
     * actually misses.
     */
    if (occlusion_mode != OCCLUSION_MODE_NONE)
	if (me.c_ishit || edge)
	    oc = occludes(ap, &me);

    /*
     * Perverse Pixel Painting Paradigm(tm) If a pixel should be
     * written to the fb, writeable is set.
     */
    if (occlusion_mode == OCCLUSION_MODE_EDGES)
	writeable[cpu][ap->a_x] = (edge && oc);
    else if (occlusion_mode == OCCLUSION_MODE_HITS)
	writeable[cpu][ap->a_x] = ((me.c_ishit || edge) && oc);
    else if (occlusion_mode == OCCLUSION_MODE_DITHER) {
	if (edge && oc)
	    writeable[cpu][ap->a_x] = 1;
	else if (me.c_ishit && oc) {
	    /*
	     * Dither mode.
	     *
	     * For occluding non-edges, only write every other pixel.
	     */
	    if (oc == 1 && ((ap->a_x + ap->a_y) % 2) == 0)
		writeable[cpu][ap->a_x] = 1;
	    else if (oc == 2)
		writeable[cpu][ap->a_x] = 1;
	    else
		writeable[cpu][ap->a_x] = 0;
	} else {
	    writeable[cpu][ap->a_x] = 0;
	}
    } else {
	if (edge)
	    writeable[cpu][ap->a_x] = 1;
	else
	    writeable[cpu][ap->a_x] = 0;
    }

    if (edge) {
	if (both_sides) {
	    choose_color(col, intensity, &me, &left, &below, &right, &above);
	} else {
	    choose_color(col, intensity, &me, &left, &below, NULL, NULL);
	}

	scanline[cpu][ap->a_x*3+RED] = col[RED];
	scanline[cpu][ap->a_x*3+GRN] = col[GRN];
	scanline[cpu][ap->a_x*3+BLU] = col[BLU];
    } else {
	scanline[cpu][ap->a_x*3+RED] = bgcolor[RED];
	scanline[cpu][ap->a_x*3+GRN] = bgcolor[GRN];
	scanline[cpu][ap->a_x*3+BLU] = bgcolor[BLU];
    }

    /*
     * Save the cell info for the next pixel.
     */
    saved[cpu]->c_ishit = me.c_ishit;
    saved[cpu]->c_id = me.c_id;
    saved[cpu]->c_dist = me.c_dist;
    saved[cpu]->c_region = me.c_region;
    VMOVE(saved[cpu]->c_rdir, me.c_rdir);
    VMOVE(saved[cpu]->c_hit, me.c_hit);
    VMOVE(saved[cpu]->c_normal, me.c_normal);

    return edge;
}
コード例 #2
0
bool OctreeProjectedPolygon::occludes(const BoundingBox& boxOccludee) const {
    OctreeProjectedPolygon testee(boxOccludee);
    return occludes(testee);
}
コード例 #3
0
bool CubeProjectedPolygon::occludes(const BoundingRectangle& boxOccludee) const {
    CubeProjectedPolygon testee(boxOccludee);
    return occludes(testee);
}