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; }
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; }