Ejemplo n.º 1
0
void
bn_wrt_point_direc(mat_t out, const mat_t change, const mat_t in, const point_t point, const vect_t direc, const struct bn_tol *tol)
{
    static mat_t t1;
    static mat_t pt_to_origin, origin_to_pt;
    static mat_t d_to_zaxis, zaxis_to_d;
    static vect_t zaxis;

    /* build "point to origin" matrix */
    MAT_IDN(pt_to_origin);
    MAT_DELTAS_VEC_NEG(pt_to_origin, point);

    /* build "origin to point" matrix */
    MAT_IDN(origin_to_pt);
    MAT_DELTAS_VEC_NEG(origin_to_pt, point);

    /* build "direc to zaxis" matrix */
    VSET(zaxis, 0.0, 0.0, 1.0);
    bn_mat_fromto(d_to_zaxis, direc, zaxis, tol);

    /* build "zaxis to direc" matrix */
    bn_mat_inv(zaxis_to_d, d_to_zaxis);

    /* apply change matrix...
     * t1 = change * d_to_zaxis * pt_to_origin * in
     */
    bn_mat_mul4(t1, change, d_to_zaxis, pt_to_origin, in);

    /* apply origin_to_pt matrix:
     * out = origin_to_pt * zaxis_to_d *
     * change * d_to_zaxis * pt_to_origin * in
     */
    bn_mat_mul3(out, origin_to_pt, zaxis_to_d, t1);
}
Ejemplo n.º 2
0
int
_ged_do_tra(struct ged *gedp,
            char coord,
            vect_t tvec,
            int (*func)())
{
    point_t delta;
    point_t work;
    point_t vc, nvc;

    if (func != (int (*)())0)
        return (*func)(gedp, coord, tvec);

    switch (coord) {
    case 'm':
        VSCALE(delta, tvec, -gedp->ged_wdbp->dbip->dbi_base2local);
        MAT_DELTAS_GET_NEG(vc, gedp->ged_gvp->gv_center);
        break;
    case 'v':
    default:
        VSCALE(tvec, tvec, -2.0*gedp->ged_wdbp->dbip->dbi_base2local*gedp->ged_gvp->gv_isize);
        MAT4X3PNT(work, gedp->ged_gvp->gv_view2model, tvec);
        MAT_DELTAS_GET_NEG(vc, gedp->ged_gvp->gv_center);
        VSUB2(delta, work, vc);
        break;
    }

    VSUB2(nvc, vc, delta);
    MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, nvc);
    ged_view_update(gedp->ged_gvp);

    return GED_OK;
}
Ejemplo n.º 3
0
int
_ged_do_slew(struct ged *gedp, vect_t svec)
{
    point_t model_center;

    MAT4X3PNT(model_center, gedp->ged_gvp->gv_view2model, svec);
    MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, model_center);
    ged_view_update(gedp->ged_gvp);

    return GED_OK;
}
Ejemplo n.º 4
0
void
bn_mat_xform_about_pt(mat_t mat, const mat_t xform, const point_t pt)
{
    mat_t xlate;
    mat_t tmp;

    MAT_IDN(xlate);
    MAT_DELTAS_VEC_NEG(xlate, pt);

    bn_mat_mul(tmp, xform, xlate);

    MAT_DELTAS_VEC(xlate, pt);
    bn_mat_mul(mat, xlate, tmp);
}
Ejemplo n.º 5
0
int
bn_mat_scale_about_pt(mat_t mat, const point_t pt, const double scale)
{
    mat_t xlate;
    mat_t s;
    mat_t tmp;

    MAT_IDN(xlate);
    MAT_DELTAS_VEC_NEG(xlate, pt);

    MAT_IDN(s);
    if (ZERO(scale)) {
	MAT_ZERO(mat);
	return -1;			/* ERROR */
    }
    s[15] = 1 / scale;

    bn_mat_mul(tmp, s, xlate);

    MAT_DELTAS_VEC(xlate, pt);
    bn_mat_mul(mat, xlate, tmp);
    return 0;				/* OK */
}
Ejemplo n.º 6
0
   -x# -y# -z#    Rotation about axis in degrees\n\
   -X# -Y# -Z#    Translation along axis\n\
   -s#            Scale factor\n\
   -a# -e#        Azimuth/Elevation from front view\n\
		  (usually first, in this order, implies -M)\n\
   -g             MGED front view to display coordinates (usually last)\n\
   -M             Autoscale space command like RT model RPP\n\
   -m#            Takes a 4X4 matrix as an argument\n\
   -v             Verbose\n\
   -S#            Space: takes a quoted string of six floats\n";

/*
 *			M O D E L _ R P P
 *
 *  Process a space command.
 *  Behavior depends on setting of several flags.
 *
 *  Implicit Returns -
 *	In all cases, sets space_min and space_max.
 */
int
model_rpp(const fastf_t *min, const fastf_t *max)
{

    if ( space_set )  {
	fprintf(stderr, "plrot:  additional SPACE command ignored\n");
	fprintf(stderr, "got: space (%g, %g, %g) (%g, %g, %g)\n",
		V3ARGS(min), V3ARGS(max) );
	fprintf(stderr, "still using: space (%g, %g, %g) (%g, %g, %g)\n",
		V3ARGS(space_min), V3ARGS(space_max) );
	return 0;
    }

    if ( rpp )  {
	point_t	rot_center;		/* center of rotation */
	mat_t	xlate;
	mat_t	resize;
	mat_t	t1, t2;

	VADD2SCALE( rot_center, min, max, 0.5 );

	/* Create the matrix which encodes this */
	MAT_IDN( xlate );
	MAT_DELTAS_VEC_NEG( xlate, rot_center);
	MAT_IDN( resize );
	resize[15] = 1/scale;
	bn_mat_mul( t1, resize, xlate );
	bn_mat_mul( t2, rmat, t1 );
	MAT_COPY( rmat, t2 );
	if ( verbose )  {
	    bn_mat_print("rmat", rmat);
	}

	if ( Mflag )  {
	    /*  Don't rebound, just expand size of space
	     *  around center point.
	     *  Has advantage of the output space() not being
	     *  affected by changes in rotation,
	     *  which may be significant for animation scripts.
	     */
	    vect_t	diag;
	    double	v;

	    VSUB2( diag, max, min );
	    v = MAGNITUDE(diag)*0.5 + 0.5;
	    VSET( space_min, -v, -v, -v );
	    VSET( space_max,  v,  v,  v );
	} else {
	    /* re-bound the space() rpp with a tighter one
	     * after rotating & scaling it.
	     */
	    bn_rotate_bbox( space_min, space_max, rmat, min, max );
	}
	space_set = 1;
    } else {
	VMOVE( space_min, min );
	VMOVE( space_max, max );
	space_set = 1;
    }

    if ( forced_space )  {
	/* Put forced space back */
	VMOVE( space_min, forced_space_min );
	VMOVE( space_max, forced_space_max );
	space_set = 1;
    }

    if ( verbose )  {
	fprintf(stderr, "got: space (%g, %g, %g) (%g, %g, %g)\n",
		V3ARGS(min), V3ARGS(max) );
	fprintf(stderr, "put: space (%g, %g, %g) (%g, %g, %g)\n",
		V3ARGS(space_min), V3ARGS(space_max) );
    }

    return( 1 );
}
Ejemplo n.º 7
0
int
ged_pov(struct ged *gedp, int argc, const char *argv[])
{
    vect_t center;
    quat_t quat;
    vect_t eye_pos;

    /* intentionally double for scan */
    double scale;
    double perspective;

    static const char *usage = "center quat scale eye_pos perspective";

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_VIEW(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(gedp->ged_result_str, 0);

    /* must be wanting help */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_HELP;
    }

    if (argc != 6) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    /***************** Get the arguments *******************/

    if (bn_decode_vect(center, argv[1]) != 3) {
	bu_vls_printf(gedp->ged_result_str, "ged_pov: bad center - %s\n", argv[1]);
	return TCL_ERROR;
    }

    if (bn_decode_quat(quat, argv[2]) != 4) {
	bu_vls_printf(gedp->ged_result_str, "ged_pov: bad quat - %s\n", argv[2]);
	return TCL_ERROR;
    }

    if (sscanf(argv[3], "%lf", &scale) != 1) {
	bu_vls_printf(gedp->ged_result_str, "ged_pov: bad scale - %s\n", argv[3]);
	return TCL_ERROR;
    }

    if (bn_decode_vect(eye_pos, argv[4]) != 3) {
	bu_vls_printf(gedp->ged_result_str, "ged_pov: bad eye position - %s\n", argv[4]);
	return TCL_ERROR;
    }

    if (sscanf(argv[5], "%lf", &perspective) != 1) {
	bu_vls_printf(gedp->ged_result_str, "ged_pov: bad perspective - %s\n", argv[5]);
	return TCL_ERROR;
    }

    /***************** Use the arguments *******************/

    VSCALE(center, center, gedp->ged_wdbp->dbip->dbi_local2base);
    MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, center);
    quat_quat2mat(gedp->ged_gvp->gv_rotation, quat);
    gedp->ged_gvp->gv_scale = gedp->ged_wdbp->dbip->dbi_local2base * scale;
    VSCALE(eye_pos, eye_pos, gedp->ged_wdbp->dbip->dbi_local2base);
    VMOVE(gedp->ged_gvp->gv_eye_pos, eye_pos);
    gedp->ged_gvp->gv_perspective = perspective;

    ged_view_update(gedp->ged_gvp);

    return GED_OK;
}
Ejemplo n.º 8
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");
    }
}
Ejemplo n.º 9
0
int
_ged_do_rot(struct ged *gedp,
            char coord,
            mat_t rmat,
            int (*func)())
{
    mat_t temp1, temp2;

    if (func != (int (*)())0)
        return (*func)(gedp, coord, gedp->ged_gvp->gv_rotate_about, rmat);

    switch (coord) {
    case 'm':
        /* transform model rotations into view rotations */
        bn_mat_inv(temp1, gedp->ged_gvp->gv_rotation);
        bn_mat_mul(temp2, gedp->ged_gvp->gv_rotation, rmat);
        bn_mat_mul(rmat, temp2, temp1);
        break;
    case 'v':
    default:
        break;
    }

    /* Calculate new view center */
    if (gedp->ged_gvp->gv_rotate_about != 'v') {
        point_t rot_pt;
        point_t new_origin;
        mat_t viewchg, viewchginv;
        point_t new_cent_view;
        point_t new_cent_model;

        switch (gedp->ged_gvp->gv_rotate_about) {
        case 'e':
            VSET(rot_pt, 0.0, 0.0, 1.0);
            break;
        case 'k':
            MAT4X3PNT(rot_pt, gedp->ged_gvp->gv_model2view, gedp->ged_gvp->gv_keypoint);
            break;
        case 'm':
            /* rotate around model center (0, 0, 0) */
            VSET(new_origin, 0.0, 0.0, 0.0);
            MAT4X3PNT(rot_pt, gedp->ged_gvp->gv_model2view, new_origin);
            break;
        default:
            return GED_ERROR;
        }

        bn_mat_xform_about_pt(viewchg, rmat, rot_pt);
        bn_mat_inv(viewchginv, viewchg);

        /* Convert origin in new (viewchg) coords back to old view coords */
        VSET(new_origin, 0.0, 0.0, 0.0);
        MAT4X3PNT(new_cent_view, viewchginv, new_origin);
        MAT4X3PNT(new_cent_model, gedp->ged_gvp->gv_view2model, new_cent_view);
        MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, new_cent_model);
    }

    /* pure rotation */
    bn_mat_mul2(rmat, gedp->ged_gvp->gv_rotation);
    ged_view_update(gedp->ged_gvp);

    return GED_OK;
}
Ejemplo n.º 10
0
/*
 * Process a space command.
 * Behavior depends on setting of several flags.
 *
 * Implicit Returns -
 * In all cases, sets space_min and space_max.
 */
int
model_rpp(const fastf_t *min, const fastf_t *max)
{

    if (space_set) {
	bu_log("plot3rot:  additional SPACE command ignored\n");
	bu_log("got: space (%g, %g, %g) (%g, %g, %g)\n",
	       V3ARGS(min), V3ARGS(max));
	bu_log("still using: space (%g, %g, %g) (%g, %g, %g)\n",
	       V3ARGS(space_min), V3ARGS(space_max));
	return 0;
    }

    if (rpp) {
	point_t rot_center;		/* center of rotation */
	mat_t xlate;
	mat_t resize;
	mat_t t1, t2;

	VADD2SCALE(rot_center, min, max, 0.5);

	/* Create the matrix which encodes this */
	MAT_IDN(xlate);
	MAT_DELTAS_VEC_NEG(xlate, rot_center);
	MAT_IDN(resize);
	resize[15] = 1/scale;
	bn_mat_mul(t1, resize, xlate);
	bn_mat_mul(t2, rmat, t1);
	MAT_COPY(rmat, t2);
	if (verbose) {
	    bn_mat_print("rmat", rmat);
	}

	if (Mflag) {
	    /* Don't rebound, just expand size of space
	     * around center point.
	     * Has advantage of the output space() not being
	     * affected by changes in rotation,
	     * which may be significant for animation scripts.
	     */
	    vect_t diag;
	    double v;

	    VSUB2(diag, max, min);
	    v = MAGNITUDE(diag)*0.5 + 0.5;
	    VSET(space_min, -v, -v, -v);
	    VSET(space_max,  v,  v,  v);
	} else {
	    /* re-bound the space() rpp with a tighter one
	     * after rotating & scaling it.
	     */
	    bn_rotate_bbox(space_min, space_max, rmat, min, max);
	}
	space_set = 1;
    } else {
	VMOVE(space_min, min);
	VMOVE(space_max, max);
	space_set = 1;
    }

    if (forced_space) {
	/* Put forced space back */
	VMOVE(space_min, forced_space_min);
	VMOVE(space_max, forced_space_max);
	space_set = 1;
    }

    if (verbose) {
	bu_log("got: space (%g, %g, %g) (%g, %g, %g)\n",
	       V3ARGS(min), V3ARGS(max));
	bu_log("put: space (%g, %g, %g) (%g, %g, %g)\n",
	       V3ARGS(space_min), V3ARGS(space_max));
    }

    return 1;
}