void render_flos_work(render_t *render, tie_t *tie, tie_ray_t *ray, TIE_3 *pixel) { tie_id_t id, tid; adrt_mesh_t *mesh; TIE_3 vec; tfloat angle; render_flos_t *rd; rd = (render_flos_t *)render->data; if ((mesh = (adrt_mesh_t *)tie_work(tie, ray, &id, render_hit, NULL))) { MATH_VEC_SET((*pixel), 0.0, 0.5, 0.0); } else { return; } MATH_VEC_SUB(vec, ray->pos, id.pos); MATH_VEC_UNITIZE(vec); MATH_VEC_DOT(angle, vec, id.norm); /* Determine if direct line of sight to fragment */ ray->pos = rd->frag_pos; MATH_VEC_SUB(ray->dir, id.pos, rd->frag_pos); MATH_VEC_UNITIZE(ray->dir); if (tie_work(tie, ray, &tid, render_hit, NULL)) { if (fabs (id.pos.v[0] - tid.pos.v[0]) < TIE_PREC && fabs (id.pos.v[1] - tid.pos.v[1]) < TIE_PREC && fabs (id.pos.v[2] - tid.pos.v[2]) < TIE_PREC) { MATH_VEC_SET((*pixel), 1.0, 0.0, 0.0); } } MATH_VEC_MUL_SCALAR((*pixel), (*pixel), (0.5+angle*0.5)); }
void render_flos_work(render_t *render, struct tie_s *tie, struct tie_ray_s *ray, vect_t *pixel) { struct tie_id_s id, tid; vect_t vec; fastf_t angle; struct render_flos_s *rd; rd = (struct render_flos_s *)render->data; if (tie_work(tie, ray, &id, render_hit, NULL) != NULL) { VSET(*pixel, 0.0, 0.5, 0.0); } else return; VSUB2(vec, ray->pos, id.pos); VUNITIZE(vec); angle = VDOT(vec, id.norm); /* Determine if direct line of sight to fragment */ VMOVE(ray->pos, rd->frag_pos); VSUB2(ray->dir, id.pos, rd->frag_pos); VUNITIZE(ray->dir); if (tie_work(tie, ray, &tid, render_hit, NULL)) { if (fabs (id.pos[0] - tid.pos[0]) < TIE_PREC && fabs (id.pos[1] - tid.pos[1]) < TIE_PREC && fabs (id.pos[2] - tid.pos[2]) < TIE_PREC) { VSET(*pixel, 1.0, 0.0, 0.0); } } VSCALE(*pixel, *pixel, (0.5+angle*0.5)); }
void render_surfel_work(render_t *render, struct tie_s *tie, struct tie_ray_s *ray, vect_t *pixel) { render_surfel_t *d; struct tie_id_s id; uint32_t i; fastf_t dist_sq; d = (render_surfel_t *)render->data; if (tie_work(tie, ray, &id, render_hit, NULL) != NULL) { for (i = 0; i < d->num; i++) { dist_sq = (d->list[i].pos[0]-id.pos[0]) * (d->list[i].pos[0]-id.pos[0]) + (d->list[i].pos[1]-id.pos[1]) * (d->list[i].pos[1]-id.pos[1]) + (d->list[i].pos[2]-id.pos[2]) * (d->list[i].pos[2]-id.pos[2]); if (dist_sq < d->list[i].radius*d->list[i].radius) { VMOVE(*pixel, d->list[i].color); break; } } VSET(*pixel, 0.8, 0.8, 0.8); } }
void render_surfel_work(render_t *render, tie_t *tie, tie_ray_t *ray, TIE_3 *pixel) { render_surfel_t *d; tie_id_t id; adrt_mesh_t *mesh; uint32_t i; tfloat dist_sq; d = (render_surfel_t *)render->data; if ((mesh = (adrt_mesh_t *)tie_work(tie, ray, &id, render_hit, NULL))) { for (i = 0; i < d->num; i++) { dist_sq = (d->list[i].pos.v[0]-id.pos.v[0]) * (d->list[i].pos.v[0]-id.pos.v[0]) + (d->list[i].pos.v[1]-id.pos.v[1]) * (d->list[i].pos.v[1]-id.pos.v[1]) + (d->list[i].pos.v[2]-id.pos.v[2]) * (d->list[i].pos.v[2]-id.pos.v[2]); if (dist_sq < d->list[i].radius*d->list[i].radius) { *pixel = d->list[i].color; break; } } MATH_VEC_SET((*pixel), 0.8, 0.8, 0.8); } }
void render_spall_work(render_t *render, struct tie_s *tie, struct tie_ray_s *ray, vect_t *pixel) { struct render_spall_s *rd; struct render_spall_hit_s hit; vect_t color; struct tie_id_s id; tfloat t, dot; rd = (struct render_spall_s *)render->data; /* Draw spall Cone */ if (tie_work(&rd->tie, ray, &id, render_arrow_hit, NULL)) { *pixel[0] = (tfloat)0.4; *pixel[1] = (tfloat)0.4; *pixel[2] = (tfloat)0.4; } /* * I don't think this needs to be done for every pixel? * Flip plane normal to face us. */ t = ray->pos[0]*rd->plane[0] + ray->pos[1]*rd->plane[1] + ray->pos[2]*rd->plane[2] + rd->plane[3]; hit.mod = t < 0 ? 1 : -1; /* * Optimization: * First intersect this ray with the plane and fire the ray from there * Plane: Ax + By + Cz + D = 0 * Ray = O + td * t = -(Pn · R0 + D) / (Pn · Rd) * */ t = (rd->plane[0]*ray->pos[0] + rd->plane[1]*ray->pos[1] + rd->plane[2]*ray->pos[2] + rd->plane[3]) / (rd->plane[0]*ray->dir[0] + rd->plane[1]*ray->dir[1] + rd->plane[2]*ray->dir[2]); /* Ray never intersects plane */ if (t > 0) return; ray->pos[0] += -t * ray->dir[0]; ray->pos[1] += -t * ray->dir[1]; ray->pos[2] += -t * ray->dir[2]; hit.plane[0] = rd->plane[0]; hit.plane[1] = rd->plane[1]; hit.plane[2] = rd->plane[2]; hit.plane[3] = rd->plane[3]; /* Render Geometry */ if (!tie_work(tie, ray, &id, render_spall_hit, &hit)) return; /* * If the point after the splitting plane is an outhit, fill it in as if it were solid. * If the point after the splitting plane is an inhit, then just shade as usual. */ dot = VDOT(ray->dir, hit.id.norm); /* flip normal */ dot = fabs(dot); if (hit.mesh->flags == 1) { VSET(color, 0.9, 0.2, 0.2); } else { /* Mix actual color with white 4:1, shade 50% darker */ VSET(color, 1.0, 1.0, 1.0); VSCALE(color, color, 3.0); VADD2(color, color, hit.mesh->attributes->color.v); VSCALE(color, color, 0.125); } #if 0 if (dot < 0) { #endif /* Shade using inhit */ VSCALE(color, color, (dot*0.50)); VADD2(*pixel, *pixel, color); #if 0 } else { /* shade solid */ VSUB2(vec, ray->pos, hit.id.pos); VUNITIZE(vec); angle = vec[0]*hit.mod*-hit.plane[0] + vec[1]*-hit.mod*hit.plane[1] + vec[2]*-hit.mod*hit.plane[2]; VSCALE((*pixel), color, (angle*0.50)); } #endif *pixel[0] += (tfloat)0.1; *pixel[1] += (tfloat)0.1; *pixel[2] += (tfloat)0.1; }
void render_cut_work(render_t *render, struct tie_s *tiep, struct tie_ray_s *ray, vect_t *pixel) { render_cut_t *rd; render_cut_hit_t hit; vect_t color; struct tie_id_s id; tfloat t, dot; rd = (render_cut_t *)render->data; /* Draw Arrow - Blue */ if (tie_work(&rd->tie, ray, &id, render_arrow_hit, NULL)) { VSET(*pixel, 0.0, 0.0, 1.0); return; } /* * I don't think this needs to be done for every pixel? * Flip plane normal to face us. */ t = ray->pos[0]*rd->plane[0] + ray->pos[1]*rd->plane[1] + ray->pos[2]*rd->plane[2] + rd->plane[3]; hit.mod = t < 0 ? 1 : -1; /* * Optimization: * First intersect this ray with the plane and fire the ray from there * Plane: Ax + By + Cz + D = 0 * Ray = O + td * t = -(Pn · R0 + D) / (Pn · Rd) */ t = (rd->plane[0]*ray->pos[0] + rd->plane[1]*ray->pos[1] + rd->plane[2]*ray->pos[2] + rd->plane[3]) / (rd->plane[0]*ray->dir[0] + rd->plane[1]*ray->dir[1] + rd->plane[2]*ray->dir[2]); /* Ray never intersects plane */ if (t > 0) return; ray->pos[0] += -t * ray->dir[0]; ray->pos[1] += -t * ray->dir[1]; ray->pos[2] += -t * ray->dir[2]; HMOVE(hit.plane, rd->plane); /* Render Geometry */ if (!tie_work(tiep, ray, &id, render_cut_hit, &hit)) return; /* * If the point after the splitting plane is an outhit, fill it in as if it were solid. * If the point after the splitting plane is an inhit, then just shade as usual. */ /* flipped normal */ dot = fabs(VDOT( ray->dir, hit.id.norm)); if (hit.mesh->flags & (ADRT_MESH_SELECT|ADRT_MESH_HIT)) { VSET(color, hit.mesh->flags & ADRT_MESH_HIT ? (tfloat)0.9 : (tfloat)0.2, (tfloat)0.2, hit.mesh->flags & ADRT_MESH_SELECT ? (tfloat)0.9 : (tfloat)0.2); } else { /* Mix actual color with white 4:1, shade 50% darker */ #if 0 VSET(color, 1.0, 1.0, 1.0); VSCALE(color, color, 3.0); VADD2(color, color, hit.mesh->attributes->color); VSCALE(color, color, 0.125); #else VSET(color, (tfloat)0.8, (tfloat)0.8, (tfloat)0.7); #endif } #if 0 if (dot < 0) { #endif /* Shade using inhit */ VSCALE((*pixel), color, (dot*0.90)); #if 0 } else { TIE_3 vec; fastf_t angle; /* shade solid */ VSUB2(vec, ray->pos, hit.id.pos); VUNITIZE(vec); angle = vec[0]*hit.mod*-hit.plane[0] + vec[1]*-hit.mod*hit.plane[1] + vec[2]*-hit.mod*hit.plane[2]; VSCALE((*pixel), color, (angle*0.90)); } #endif *pixel[0] += (tfloat)0.1; *pixel[1] += (tfloat)0.1; *pixel[2] += (tfloat)0.1; }
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; }