int
render_spall_init(render_t *render, const char *buf)
{
    struct render_spall_s *d;
    vect_t *tri_list, *vec_list, normal, up;
    fastf_t plane[4], angle;
    int i;

    /* intentionally double for scan */
    double ray_pos[3], ray_dir[3];
    double scan;

    if (buf == NULL)
	return -1;

    render->work = render_spall_work;
    render->free = render_spall_free;

    bu_sscanf(buf, "(%lg %lg %lg) (%lg %lg %lg) %lg",
	      &ray_pos[0], &ray_pos[1], &ray_pos[2],
	      &ray_dir[0], &ray_dir[1], &ray_dir[2],
	      &scan);
    angle = scan; /* double to fastf_t */

    BU_ALLOC(render->data, struct render_spall_s);
    d = (struct render_spall_s *)render->data;

    VMOVE(d->ray_pos, ray_pos);
    VMOVE(d->ray_dir, ray_dir);

    tie_init(&d->tie, TESSELLATION, TIE_KDTREE_FAST);

    /* Calculate the normal to be used for the plane */
    up[0] = 0;
    up[1] = 0;
    up[2] = 1;

    VCROSS(normal,  ray_dir,  up);
    VUNITIZE(normal);

    /* Construct the plane */
    d->plane[0] = normal[0];
    d->plane[1] = normal[1];
    d->plane[2] = normal[2];
    plane[3] = VDOT(normal,  ray_pos); /* up is really new ray_pos */
    d->plane[3] = -plane[3];

    /******************/
    /* The spall Cone */
    /******************/
    vec_list = (vect_t *)bu_malloc(sizeof(vect_t) * TESSELLATION, "vec_list");
    tri_list = (vect_t *)bu_malloc(sizeof(vect_t) * TESSELLATION * 3, "tri_list");

    render_util_spall_vec(d->ray_dir, angle, TESSELLATION, vec_list);

    /* triangles to approximate */
    for (i = 0; i < TESSELLATION; i++) {
	VMOVE(tri_list[3*i+0], ray_pos);

	VSCALE(tri_list[3*i+1],  vec_list[i],  SPALL_LEN);
	VADD2(tri_list[3*i+1],  tri_list[3*i+1],  ray_pos);

	if (i == TESSELLATION - 1) {
	    VSCALE(tri_list[3*i+2],  vec_list[0],  SPALL_LEN);
	    VADD2(tri_list[3*i+2],  tri_list[3*i+2],  ray_pos);
	} else {
	    VSCALE(tri_list[3*i+2],  vec_list[i+1],  SPALL_LEN);
	    VADD2(tri_list[3*i+2],  tri_list[3*i+2],  ray_pos);
	}
    }

/*  tie_push(&d->tie, tri_list, TESSELLATION, NULL, 0);   */
    tie_prep(&d->tie);

    bu_free(vec_list, "vec_list");
    bu_free(tri_list, "tri_list");
    return 0;
}
示例#2
0
文件: cut.c 项目: cogitokat/brlcad
int
render_cut_init(render_t *render, const char *buf)
{
    int i;
    render_cut_t *d;
    static TIE_3 list[6];
	TIE_3 **tlist;
    vect_t up, ray_pos, ray_dir;
    fastf_t shot_len = 100, shot_width = .02;
    struct tie_id_s id;
    struct tie_ray_s ray;
    double step, f[6];

    if(buf == NULL)
	    return -1;

    sscanf(buf, "#(%lf %lf %lf) #(%lf %lf %lf)",
	    f, f+1, f+2,
	    f+3, f+3+1, f+3+2);
	VMOVE(ray_pos, f);
	VMOVE(ray_dir, f);
    VUNITIZE(ray_dir);

    shot_width = 0.01 * render->tie->radius;
    {
	vect_t v;

	VSUB2(v, ray_pos, render->tie->mid);
	shot_len = 2.0 * render->tie->radius + MAGNITUDE(v) - render->tie->radius;;
    }

    /*
     * fire through the entire geometry, marking each intersected mesh with
     * ADRT_MESH_HIT
     */
    VMOVE(ray.pos, ray_pos);
    VMOVE(ray.dir, ray_dir);
    ray.depth = 0;
    tie_work(render->tie, &ray, &id, render_cut_hit_cutline, &step);

    /* prepare cut stuff */
    tlist = (TIE_3 **)bu_malloc(sizeof(TIE_3 *) * 6, "cutting plane triangles");

    render->work = render_cut_work;
    render->free = render_cut_free;

    BU_ALLOC(render->data, render_cut_t);
    d = (render_cut_t *)render->data;

    VMOVE(d->ray_pos, ray_pos);
    VMOVE(d->ray_dir, ray_dir);

    /* Calculate the normal to be used for the plane */
    VSET(up, 0, 0, 1);
    VCROSS(d->plane,  ray_dir,  up);
    VUNITIZE(d->plane);

    /* Construct the plane */
    d->plane[3] = -VDOT( d->plane,  ray_pos); /* up is really new ray_pos */

    /* generate the shtuff for the blue line */
    tie_init(&d->tie, 2, TIE_KDTREE_FAST);

    /* Triangle 1 */
    VSET(list[0].v, ray_pos[0], ray_pos[1], ray_pos[2] - shot_width);
    VSET(list[1].v, ray_pos[0] + shot_len*ray_dir[0], ray_pos[1] + shot_len*ray_dir[1], ray_pos[2] + shot_len*ray_dir[2] - shot_width);
    VSET(list[2].v, ray_pos[0] + shot_len*ray_dir[0], ray_pos[1] + shot_len*ray_dir[1], ray_pos[2] + shot_len*ray_dir[2] + shot_width);

    /* Triangle 2 */
    VMOVE(list[3].v, ray_pos);
    list[3].v[2] -= shot_width;

    VSET(list[4].v, ray_pos[0] + shot_len*ray_dir[0], ray_pos[1] + shot_len*ray_dir[1], ray_pos[2] + shot_len*ray_dir[2] + shot_width);

    VMOVE(list[5].v, ray_pos);
    list[5].v[2] += shot_width;

    for(i=0;i<6;i++)
	tlist[i] = &list[i];

    tie_push(&d->tie, tlist, 2, NULL, 0);

    tie_prep(&d->tie);
    bu_free(tlist, "cutting plane triangles");
    return 0;
}