/* * M A K E _ N T S C _ X Y Z 2 R G B * * Create the map from * CIE XYZ perceptual space into * an idealized RGB space assuming NTSC primaries with D6500 white. * Only high-quality television-studio monitors are like this, but... */ void make_ntsc_xyz2rgb(fastf_t *xyz2rgb) { mat_t rgb2xyz; point_t tst, newpt; if (rt_clr__cspace_to_xyz(rgb_NTSC, rgb2xyz) == 0) bu_exit(EXIT_FAILURE, "make_ntsc_xyz2rgb() can't initialize color space\n"); bn_mat_inv(xyz2rgb, rgb2xyz); #if 1 /* Verify that it really works, I'm a skeptic */ VSET(tst, 1, 1, 1); MAT3X3VEC(newpt, rgb2xyz, tst); VPRINT("white_rgb (i)", tst); VPRINT("white_xyz (o)", newpt); VSET(tst, 0.313, 0.329, 0.358); MAT3X3VEC(newpt, xyz2rgb, tst); VPRINT("white_xyz (i)", tst); VPRINT("white_rgb (o)", newpt); VSET(tst, 1, 0, 0); MAT3X3VEC(newpt, rgb2xyz, tst); VPRINT("red_rgb (i)", tst); VPRINT("red_xyz (o)", newpt); VSET(tst, 0.670, 0.330, 0.000); MAT3X3VEC(newpt, xyz2rgb, tst); VPRINT("red_xyz (i)", tst); VPRINT("red_rgb (o)", newpt); VSET(tst, 0, 1, 0); MAT3X3VEC(newpt, rgb2xyz, tst); VPRINT("grn_rgb (i)", tst); VPRINT("grn_xyz (o)", newpt); VSET(tst, 0.210, 0.710, 0.080); MAT3X3VEC(newpt, xyz2rgb, tst); VPRINT("grn_xyz (i)", tst); VPRINT("grn_rgb (o)", newpt); VSET(tst, 0, 0, 1); MAT3X3VEC(newpt, rgb2xyz, tst); VPRINT("blu_rgb (i)", tst); VPRINT("blu_xyz (o)", newpt); VSET(tst, 0.140, 0.080, 0.780); MAT3X3VEC(newpt, xyz2rgb, tst); VPRINT("blu_xyz (i)", tst); VPRINT("blu_rgb (o)", newpt); #endif }
int main(int ac, char **av) { unsigned char rgb[4]; float src[3]; point_t dest; point_t xyz; size_t ret; if (ac > 1) bu_log("Usage: %s\n", av[0]); spectrum = bn_table_make_uniform(nsamp, min_nm, max_nm); BN_GET_TABDATA(curve, spectrum); rt_spect_make_CIE_XYZ(&cie_x, &cie_y, &cie_z, spectrum); make_ntsc_xyz2rgb(xyz2rgb); for (;;) { if (fread(rgb, 1, 3, stdin) != 3) break; if (feof(stdin)) break; VSET(src, rgb[0]/255., rgb[1]/255., rgb[2]/255.); rt_spect_reflectance_rgb(curve, src); spect_curve_to_xyz(xyz, curve, cie_x, cie_y, cie_z); MAT3X3VEC(dest, xyz2rgb, xyz); if (dest[0] > 1 || dest[1] > 1 || dest[2] > 1 || dest[0] < 0 || dest[1] < 0 || dest[2] < 0) { VPRINT("src ", src); VPRINT("dest", dest); } if (dest[0] > 1) dest[0] = 1; if (dest[1] > 1) dest[1] = 1; if (dest[2] > 1) dest[2] = 1; if (dest[0] < 0) dest[0] = 0; if (dest[1] < 0) dest[1] = 0; if (dest[2] < 0) dest[2] = 0; VSCALE(rgb, dest, 255.0); ret = fwrite(rgb, 1, 3, stdout); if (ret != 3) perror("fwrite"); } return 0; }
int main(int argc, char **argv) { void anim_dir2mat(fastf_t *, const fastf_t *, const fastf_t *), anim_y_p_r2mat(fastf_t *, double, double, double), anim_add_trans(fastf_t *, const fastf_t *, const fastf_t *), anim_mat_print(FILE *, const fastf_t *, int); int get_args(int argc, char **argv), track_prep(void), val, frame, go, i, count; fastf_t y_rot, distance, yaw, pitch, roll; vect_t p1, p2, p3, dir, dir2, wheel_now, wheel_prev; vect_t zero, position, vdelta, temp, to_track, to_front; mat_t mat_v, wmat, mat_x; FILE *stream; int last_frame; VSETALL(zero, 0.0); VSETALL(to_track, 0.0); VSETALL(centroid, 0.0); VSETALL(rcentroid, 0.0); init_dist = y_rot = radius= 0.0; first_frame = num_wheels = steer = axes = cent = links_placed=0; num_wheels = num_links = last_frame = 0; MAT_IDN(mat_v); MAT_IDN(mat_x); MAT_IDN(wmat); MAT_IDN(m_axes); MAT_IDN(m_rev_axes); if (!get_args(argc, argv)) { fprintf(stderr, "anim_hardtrack: argument error."); return(-1); } if (axes || cent ) { /* vehicle has own reference frame */ anim_add_trans(m_axes, centroid, zero); anim_add_trans(m_rev_axes, zero, rcentroid); } /* get track information from specified file */ if (!(stream = fopen(*(argv+bu_optind), "rb"))) { fprintf(stderr, "Anim_hardtrack: Could not open file %s.\n", *(argv+bu_optind)); return(0); } num_wheels = -1; if (radius) { while (!feof(stream)) { fscanf(stream, "%*f %*f %*f"); num_wheels++; } } else { while (!feof(stream)) { fscanf(stream, "%*f %*f %*f %*f"); num_wheels++; } } rewind(stream); /*allocate memory for track information*/ x = (struct all *) bu_calloc(num_wheels, sizeof(struct all), "struct all"); /*read rest of track info */ for (i=0;i<NW;i++) { fscanf(stream, "%lf %lf %lf", temp, temp+1, temp+2); if (radius) x[i].w.rad = radius; else fscanf(stream, "%lf", & x[i].w.rad); MAT4X3PNT(x[i].w.pos, m_rev_axes, temp); if (i==0) track_y = x[0].w.pos[1]; else x[i].w.pos[1] = track_y; } (void) fclose(stream); (void) track_prep(); if (get_circumf) { printf("%.10g\n", tracklen); return(0); } /* initialize to_track */ VSET(to_track, 0.0, track_y, 0.0); VSET(to_front, 1.0, 0.0, 0.0); if ((!print_link)&&(!print_wheel)) { fprintf(stderr, "anim_hardtrack: no ouput requested. Use -l or -w.\n"); bu_exit(0, NULL); } /* main loop */ distance = 0.0; if (!steer) frame = first_frame; else frame = first_frame-1; for (val = 3; val > 2; frame++) { go = 1; /*p2 is current position. p3 is next;p1 is previous*/ VMOVE(p1, p2); VMOVE(p2, p3); scanf("%*f");/*time stamp*/ val = scanf("%lf %lf %lf", p3, p3+1, p3 + 2); if (!steer) { scanf("%lf %lf %lf", &yaw, &pitch, &roll); anim_dy_p_r2mat(mat_v, yaw, pitch, roll); anim_add_trans(mat_v, p3, rcentroid); } else { /* analyze positions for steering */ /*get useful direction unit vectors*/ if (frame == first_frame) { /* first frame*/ VSUBUNIT(dir, p3, p2); VMOVE(dir2, dir); } else if (val < 3) { /*last frame*/ VSUBUNIT(dir, p2, p1); VMOVE(dir2, dir); } else if (frame > first_frame) { /*normal*/ VSUBUNIT(dir, p3, p1); VSUBUNIT(dir2, p2, p1);/*needed for vertical case*/ } else go = 0;/*first time through loop;no p2*/ /*create matrix which would move vehicle*/ anim_dir2mat(mat_v, dir, dir2); anim_add_trans(mat_v, p2, rcentroid); } /*determine distance traveled*/ VMOVE(wheel_prev, wheel_now); MAT4X3PNT(wheel_now, mat_v, to_track); if (frame > first_frame) { /* increment distance by distance moved */ VSUB2(vdelta, wheel_now, wheel_prev); MAT3X3VEC(temp, mat_v, to_front);/*new front of vehicle*/ distance += VDOT(temp, vdelta);/*portion of vdelta in line with track*/ } if (go) { if (print_mode==TRACK_ANIM) { printf("start %d;\nclean;\n", frame); } else if (print_mode==TRACK_ARCED) { if (frame != arced_frame) continue; last_frame = 1; } if (print_link) { for (count=0;count<num_links;count++) { (void) get_link(position, &y_rot, distance+tracklen*count/num_links+init_dist); anim_y_p_r2mat(wmat, 0.0, y_rot+r[count].ang, 0.0); anim_add_trans(wmat, position, r[count].pos); if ((axes || cent) && links_placed) { /* link moved from vehicle coords */ bn_mat_mul(mat_x, wmat, m_rev_axes); bn_mat_mul(wmat, m_axes, mat_x); } else if (axes || cent) { /* link moved to vehicle coords */ MAT_MOVE(mat_x, wmat); bn_mat_mul(wmat, m_axes, mat_x); } if (print_mode==TRACK_ANIM) { printf("anim %s.%d matrix %s\n", *(argv+link_nindex), count, link_cmd); anim_mat_printf(stdout, wmat, "%.10g ", "\n", ";\n"); } else if (print_mode==TRACK_ARCED) { printf("arced %s.%d matrix %s ", *(argv+link_nindex), count, link_cmd); anim_mat_printf(stdout, wmat, "%.10g ", "", "\n"); } } } if (print_wheel) { for (count = 0;count<num_wheels;count++) { anim_y_p_r2mat(wmat, 0.0, -distance/x[count].w.rad, 0.0); VREVERSE(temp, x[count].w.pos); anim_add_trans(wmat, x[count].w.pos, temp); if (axes || cent) { bn_mat_mul(mat_x, wmat, m_rev_axes); bn_mat_mul(wmat, m_axes, mat_x); } if (print_mode==TRACK_ANIM) { printf("anim %s.%d matrix %s\n", *(argv+wheel_nindex), count, wheel_cmd); anim_mat_printf(stdout, wmat, "%.10g ", "\n", ";\n"); } else if (print_mode==TRACK_ARCED) { printf("arced %s.%d matrix %s ", *(argv+wheel_nindex), count, wheel_cmd); anim_mat_printf(stdout, wmat, "%.10g ", "", "\n"); } } } if (print_mode==TRACK_ANIM) printf("end;\n"); } if (last_frame) break; } if (x) { bu_free(x, "struct all"); } if (r) { bu_free(r, "struct rlink"); } return( 0 ); }
/** * Calculate a bounding RPP for a superell */ int rt_superell_bbox(struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *UNUSED(tol)) { struct rt_superell_internal *eip; fastf_t magsq_a, magsq_b, magsq_c; vect_t Au, Bu, Cu; mat_t R; vect_t w1, w2, P; /* used for bounding RPP */ fastf_t f; eip = (struct rt_superell_internal *)ip->idb_ptr; RT_SUPERELL_CK_MAGIC(eip); magsq_a = MAGSQ(eip->a); magsq_b = MAGSQ(eip->b); magsq_c = MAGSQ(eip->c); /* Create unit length versions of A, B, C */ f = 1.0/sqrt(magsq_a); VSCALE(Au, eip->a, f); f = 1.0/sqrt(magsq_b); VSCALE(Bu, eip->b, f); f = 1.0/sqrt(magsq_c); VSCALE(Cu, eip->c, f); MAT_IDN(R); VMOVE(&R[0], Au); VMOVE(&R[4], Bu); VMOVE(&R[8], Cu); /* Compute bounding RPP */ VSET(w1, magsq_a, magsq_b, magsq_c); /* X */ VSET(P, 1.0, 0, 0); /* bounding plane normal */ MAT3X3VEC(w2, R, P); /* map plane to local coord syst */ VELMUL(w2, w2, w2); /* square each term */ f = VDOT(w1, w2); f = sqrt(f); (*min)[X] = eip->v[X] - f; /* V.P +/- f */ (*max)[X] = eip->v[X] + f; /* Y */ VSET(P, 0, 1.0, 0); /* bounding plane normal */ MAT3X3VEC(w2, R, P); /* map plane to local coord syst */ VELMUL(w2, w2, w2); /* square each term */ f = VDOT(w1, w2); f = sqrt(f); (*min)[Y] = eip->v[Y] - f; /* V.P +/- f */ (*max)[Y] = eip->v[Y] + f; /* Z */ VSET(P, 0, 0, 1.0); /* bounding plane normal */ MAT3X3VEC(w2, R, P); /* map plane to local coord syst */ VELMUL(w2, w2, w2); /* square each term */ f = VDOT(w1, w2); f = sqrt(f); (*min)[Z] = eip->v[Z] - f; /* V.P +/- f */ (*max)[Z] = eip->v[Z] + f; return 0; }
/** * In theory, the grid can be specified by providing any two of * these sets of parameters: * * number of pixels (width, height) * viewsize (in model units, mm) * number of grid cells (cell_width, cell_height) * * however, for now, it is required that the view size always be * specified, and one or the other parameter be provided. */ void grid_setup(void) { vect_t temp; mat_t toEye; if (viewsize <= 0.0) bu_exit(EXIT_FAILURE, "viewsize <= 0"); /* model2view takes us to eye_model location & orientation */ MAT_IDN(toEye); MAT_DELTAS_VEC_NEG(toEye, eye_model); Viewrotscale[15] = 0.5*viewsize; /* Viewscale */ bn_mat_mul(model2view, Viewrotscale, toEye); bn_mat_inv(view2model, model2view); /* Determine grid cell size and number of pixels */ if (cell_newsize) { if (cell_width <= 0.0) cell_width = cell_height; if (cell_height <= 0.0) cell_height = cell_width; width = (viewsize / cell_width) + 0.99; height = (viewsize / (cell_height*aspect)) + 0.99; cell_newsize = 0; } else { /* Chop -1.0..+1.0 range into parts */ cell_width = viewsize / width; cell_height = viewsize / (height*aspect); } /* * Optional GIFT compatibility, mostly for RTG3. Round coordinates * of lower left corner to fall on integer- valued coordinates, in * "gift_grid_rounding" units. */ if (gift_grid_rounding > 0.0) { point_t v_ll; /* view, lower left */ point_t m_ll; /* model, lower left */ point_t hv_ll; /* hv, lower left*/ point_t hv_wanted; vect_t hv_delta; vect_t m_delta; mat_t model2hv; mat_t hv2model; /* Build model2hv matrix, including mm2inches conversion */ MAT_COPY(model2hv, Viewrotscale); model2hv[15] = gift_grid_rounding; bn_mat_inv(hv2model, model2hv); VSET(v_ll, -1, -1, 0); MAT4X3PNT(m_ll, view2model, v_ll); MAT4X3PNT(hv_ll, model2hv, m_ll); VSET(hv_wanted, floor(hv_ll[X]), floor(hv_ll[Y]), floor(hv_ll[Z])); VSUB2(hv_delta, hv_ll, hv_wanted); MAT4X3PNT(m_delta, hv2model, hv_delta); VSUB2(eye_model, eye_model, m_delta); MAT_DELTAS_VEC_NEG(toEye, eye_model); bn_mat_mul(model2view, Viewrotscale, toEye); bn_mat_inv(view2model, model2view); } /* Create basis vectors dx and dy for emanation plane (grid) */ VSET(temp, 1, 0, 0); MAT3X3VEC(dx_unit, view2model, temp); /* rotate only */ VSCALE(dx_model, dx_unit, cell_width); VSET(temp, 0, 1, 0); MAT3X3VEC(dy_unit, view2model, temp); /* rotate only */ VSCALE(dy_model, dy_unit, cell_height); if (stereo) { /* Move left 2.5 inches (63.5mm) */ VSET(temp, -63.5*2.0/viewsize, 0, 0); bu_log("red eye: moving %f relative screen (left)\n", temp[X]); MAT4X3VEC(left_eye_delta, view2model, temp); VPRINT("left_eye_delta", left_eye_delta); } /* "Lower left" corner of viewing plane */ if (rt_perspective > 0.0) { fastf_t zoomout; zoomout = 1.0 / tan(DEG2RAD * rt_perspective / 2.0); VSET(temp, -1, -1/aspect, -zoomout); /* viewing plane */ /* * divergence is perspective angle divided by the number of * pixels in that angle. Extra factor of 0.5 is because * perspective is a full angle while divergence is the tangent * (slope) of a half angle. */ APP.a_diverge = tan(DEG2RAD * rt_perspective * 0.5 / width); APP.a_rbeam = 0; } else { /* all rays go this direction */ VSET(temp, 0, 0, -1); MAT4X3VEC(APP.a_ray.r_dir, view2model, temp); VUNITIZE(APP.a_ray.r_dir); VSET(temp, -1, -1/aspect, 0); /* eye plane */ APP.a_rbeam = 0.5 * viewsize / width; APP.a_diverge = 0; } if (ZERO(APP.a_rbeam) && ZERO(APP.a_diverge)) bu_exit(EXIT_FAILURE, "zero-radius beam"); MAT4X3PNT(viewbase_model, view2model, temp); if (jitter & JITTER_FRAME) { /* Move the frame in a smooth circular rotation in the plane */ fastf_t ang; /* radians */ fastf_t dx, dy; ang = curframe * frame_delta_t * M_2PI / 10; /* 10 sec period */ dx = cos(ang) * 0.5; /* +/- 1/4 pixel width in amplitude */ dy = sin(ang) * 0.5; VJOIN2(viewbase_model, viewbase_model, dx, dx_model, dy, dy_model); } if (cell_width <= 0 || cell_width >= INFINITY || cell_height <= 0 || cell_height >= INFINITY) { bu_log("grid_setup: cell size ERROR (%g, %g) mm\n", cell_width, cell_height); bu_exit(EXIT_FAILURE, "cell size"); } if (width <= 0 || height <= 0) { bu_log("grid_setup: ERROR bad image size (%zu, %zu)\n", width, height); bu_exit(EXIT_FAILURE, "bad size"); } }
/** * R E C _ B B O X * * Calculate the RPP for an REC */ int rt_rec_bbox(struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *UNUSED(tol)) { mat_t R; vect_t P, w1; fastf_t f, tmp, z; double magsq_h, magsq_a, magsq_b, magsq_c, magsq_d; double mag_h, mag_a, mag_b; struct rt_tgc_internal *tip; RT_CK_DB_INTERNAL(ip); tip = (struct rt_tgc_internal *)ip->idb_ptr; RT_TGC_CK_MAGIC(tip); mag_h = sqrt(magsq_h = MAGSQ(tip->h)); mag_a = sqrt(magsq_a = MAGSQ(tip->a)); mag_b = sqrt(magsq_b = MAGSQ(tip->b)); magsq_c = MAGSQ(tip->c); magsq_d = MAGSQ(tip->d); MAT_IDN(R); f = 1.0/mag_a; VSCALE(&R[0], tip->a, f); f = 1.0/mag_b; VSCALE(&R[4], tip->b, f); f = 1.0/mag_h; VSCALE(&R[8], tip->h, f); /* X */ VSET(P, 1.0, 0, 0); /* bounding plane normal */ MAT3X3VEC(w1, R, P); /* map plane into local coord syst */ /* 1st end ellipse (no Z part) */ tmp = magsq_a * w1[X] * w1[X] + magsq_b * w1[Y] * w1[Y]; if (tmp > SMALL) f = sqrt(tmp); /* XY part */ else f = 0; (*min)[X] = tip->v[X] - f; /* V.P +/- f */ (*max)[X] = tip->v[X] + f; /* 2nd end ellipse */ z = w1[Z] * mag_h; /* Z part */ tmp = magsq_c * w1[X] * w1[X] + magsq_d * w1[Y] * w1[Y]; if (tmp > SMALL) f = sqrt(tmp); /* XY part */ else f = 0; if (tip->v[X] - f + z < (*min)[X]) (*min)[X] = tip->v[X] - f + z; if (tip->v[X] + f + z > (*max)[X]) (*max)[X] = tip->v[X] + f + z; /* Y */ VSET(P, 0, 1.0, 0); /* bounding plane normal */ MAT3X3VEC(w1, R, P); /* map plane into local coord syst */ /* 1st end ellipse (no Z part) */ tmp = magsq_a * w1[X] * w1[X] + magsq_b * w1[Y] * w1[Y]; if (tmp > SMALL) f = sqrt(tmp); /* XY part */ else f = 0; (*min)[Y] = tip->v[Y] - f; /* V.P +/- f */ (*max)[Y] = tip->v[Y] + f; /* 2nd end ellipse */ z = w1[Z] * mag_h; /* Z part */ tmp = magsq_c * w1[X] * w1[X] + magsq_d * w1[Y] * w1[Y]; if (tmp > SMALL) f = sqrt(tmp); /* XY part */ else f = 0; if (tip->v[Y] - f + z < (*min)[Y]) (*min)[Y] = tip->v[Y] - f + z; if (tip->v[Y] + f + z > (*max)[Y]) (*max)[Y] = tip->v[Y] + f + z; /* Z */ VSET(P, 0, 0, 1.0); /* bounding plane normal */ MAT3X3VEC(w1, R, P); /* map plane into local coord syst */ /* 1st end ellipse (no Z part) */ tmp = magsq_a * w1[X] * w1[X] + magsq_b * w1[Y] * w1[Y]; if (tmp > SMALL) f = sqrt(tmp); /* XY part */ else f = 0; (*min)[Z] = tip->v[Z] - f; /* V.P +/- f */ (*max)[Z] = tip->v[Z] + f; /* 2nd end ellipse */ z = w1[Z] * mag_h; /* Z part */ tmp = magsq_c * w1[X] * w1[X] + magsq_d * w1[Y] * w1[Y]; if (tmp > SMALL) f = sqrt(tmp); /* XY part */ else f = 0; if (tip->v[Z] - f + z < (*min)[Z]) (*min)[Z] = tip->v[Z] - f + z; if (tip->v[Z] + f + z > (*max)[Z]) (*max)[Z] = tip->v[Z] + f + z; return 0; }