예제 #1
0
static int
move_walk(ClientData UNUSED(clientData), Tcl_Interp *interp, int UNUSED(objc), Tcl_Obj *const *objv)
{
    struct isst_s *isst;
    Togl *togl;
    vect_t vec;
    int flag;

    if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK)
	return TCL_ERROR;

    isst = (struct isst_s *) Togl_GetClientData(togl);

    if (Tcl_GetIntFromObj(interp, objv[2], &flag) != TCL_OK)
	return TCL_ERROR;

    if (flag >= 0) {
	VSUB2(vec, isst->camera.focus, isst->camera.pos);
	VSCALE(vec, vec, 0.1 * isst->tie->radius);
	VADD2(isst->camera.pos, isst->camera.pos, vec);
	VADD2(isst->camera.focus, isst->camera.focus, vec);
    } else {
	VSUB2(vec, isst->camera.pos, isst->camera.focus);
	VSCALE(vec, vec, 0.1 * isst->tie->radius);
	VADD2(isst->camera.pos, isst->camera.pos, vec);
	VADD2(isst->camera.focus, isst->camera.focus, vec);
    }
    isst->dirty = 1;
    return TCL_OK;
}
예제 #2
0
void
Normals(void)
{
    struct points *ptr;


    if ( root == NULL )
	return;

    ptr = root->next;
    if ( ptr == NULL )
	return;

    VSUB2( root->nnext, ptr->p, root->p );
    VUNITIZE( root->nnext );

    while ( ptr->next != NULL )
    {
	VREVERSE( ptr->nprev, ptr->prev->nnext );
	VSUB2( ptr->nnext, ptr->next->p, ptr->p );
	VUNITIZE( ptr->nnext );
	VCROSS( ptr->norm, ptr->nprev, ptr->nnext );
	VUNITIZE( ptr->norm );
	VADD2( ptr->nmitre, ptr->nprev, ptr->nnext );
	VUNITIZE( ptr->nmitre );
	VCROSS( ptr->mnorm, ptr->norm, ptr->nmitre );
	VUNITIZE( ptr->mnorm );
	if ( VDOT( ptr->mnorm, ptr->nnext ) > 0.0 )
	    VREVERSE( ptr->mnorm, ptr->mnorm );
	ptr->alpha = acos( VDOT( ptr->nnext, ptr->nprev ) );
	ptr = ptr->next;
    }
}
예제 #3
0
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));
}
예제 #4
0
파일: poly.c 프로젝트: cogitokat/brlcad
/**
 * R T _ P G _ P L O T _ P O L Y
 *
 * Convert to vlist, draw as polygons.
 */
int
rt_pg_plot_poly(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *UNUSED(tol))
{
    size_t i;
    size_t p;	/* current polygon number */
    struct rt_pg_internal *pgp;

    BU_CK_LIST_HEAD(vhead);
    RT_CK_DB_INTERNAL(ip);
    pgp = (struct rt_pg_internal *)ip->idb_ptr;
    RT_PG_CK_MAGIC(pgp);

    for (p = 0; p < pgp->npoly; p++) {
	struct rt_pg_face_internal *pp;
	vect_t aa, bb, norm;

	pp = &pgp->poly[p];
	if (pp->npts < 3)
	    continue;
	VSUB2(aa, &pp->verts[3*(0)], &pp->verts[3*(1)]);
	VSUB2(bb, &pp->verts[3*(0)], &pp->verts[3*(2)]);
	VCROSS(norm, aa, bb);
	VUNITIZE(norm);
	RT_ADD_VLIST(vhead, norm, BN_VLIST_POLY_START);

	RT_ADD_VLIST(vhead, &pp->verts[3*(pp->npts-1)], BN_VLIST_POLY_MOVE);
	for (i=0; i < pp->npts-1; i++) {
	    RT_ADD_VLIST(vhead, &pp->verts[3*i], BN_VLIST_POLY_DRAW);
	}
	RT_ADD_VLIST(vhead, &pp->verts[3*(pp->npts-1)], BN_VLIST_POLY_END);
    }
    return 0;		/* OK */
}
예제 #5
0
파일: vutil.c 프로젝트: kanzure/brlcad
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;
}
inline void
rt_metaball_norm_internal(vect_t *n, point_t *p, struct rt_metaball_internal *mb)
{
    struct wdb_metaballpt *mbpt;
    vect_t v;
    fastf_t a;

    VSETALL(*n, 0.0);

    switch (mb->method) {
	case METABALL_METABALL: bu_log("Sorry, strict metaballs are not yet implemented\n");
	    break;
	case METABALL_ISOPOTENTIAL:
	    for (BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_ctrl_head)) {
		VSUB2(v, *p, mbpt->coord);
		a = MAGSQ(v);
		VJOIN1(*n, *n, fabs(mbpt->fldstr)*mbpt->fldstr / (SQ(a)), v);	/* f/r^4 */
	    }
	    break;
	case METABALL_BLOB:
	    for (BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_ctrl_head)) {
		VSUB2(v, *p, mbpt->coord);
		a = MAGSQ(v);
		VJOIN1(*n, *n, 2.0*mbpt->sweat/SQ(mbpt->fldstr)*exp(mbpt->sweat*(1-(a/SQ(mbpt->fldstr)))) , v);
	    }
	    break;
	default: bu_log("unknown metaball method\n"); break;
    }
    VUNITIZE(*n);
}
예제 #7
0
파일: camera.c 프로젝트: kanzure/brlcad
static void
render_camera_prep_ortho(render_camera_t *camera)
{
    vect_t look, up, side, temp;
    tfloat angle, s, c;

    /* Generate standard up vector */
    up[0] = 0;
    up[1] = 0;
    up[2] = 1;

    /* Generate unitized lookector */
    VSUB2(look, camera->focus, camera->pos);
    VUNITIZE(look);

    /* Make unitized up vector perpendicular to lookector */
    VMOVE(temp, look);
    angle = VDOT(up, temp);
    VSCALE(temp, temp, angle);
    VSUB2(up, up, temp);
    VUNITIZE(up);

    /* Generate a temporary side vector */
    VCROSS(side, up, look);

    /* Apply tilt to up vector - negate angle to make positive angles clockwise */
    s = sin(-camera->tilt * DEG2RAD);
    c = cos(-camera->tilt * DEG2RAD);
    VSCALE(up, up, c);
    VSCALE(side, side, s);
    VADD2(up, up, side);

    /* Create final side vector */
    VCROSS(side, up, look);

    /* look direction */
    VMOVE(camera->view_list[0].top_l, look);

    /* gridsize is millimeters along the horizontal axis to display */
    /* left (side) */
    VSCALE(temp, side, (camera->aspect * camera->gridsize * 0.5));
    VADD2(camera->view_list[0].pos, camera->pos, temp);
    /* and (up) */
    VSCALE(temp, up, (camera->gridsize * 0.5));
    VADD2(camera->view_list[0].pos, camera->view_list[0].pos, temp);

    /* compute step vectors for camera position */

    /* X */
    VSCALE(camera->view_list[0].step_x, side, (-camera->gridsize * camera->aspect / (tfloat)camera->w));

    /* Y */
    VSCALE(camera->view_list[0].step_y, up, (-camera->gridsize / (tfloat)camera->h));
}
예제 #8
0
파일: track.c 프로젝트: cciechad/brlcad
void
top(fastf_t *vec1, fastf_t *vec2, fastf_t *t)
{
    fastf_t	tooch, mag;
    vect_t	del, tvec;
    int i, j;

    tooch = t[2] * .25;
    del[0] = vec2[0] - vec1[0];
    del[1] = 0.0;
    del[2] = vec2[2] - vec1[2];
    mag = MAGNITUDE( del );
    VSCALE(tvec, del, tooch/mag);
    VSUB2(&sol.s_values[0], vec1, tvec);
    VADD2(del, del, tvec);
    VADD2(&sol.s_values[3], del, tvec);
    tvec[0] = tvec[2] = 0.0;
    tvec[1] = t[1] - t[0];
    VCROSS(del, tvec, &sol.s_values[3]);
    mag = MAGNITUDE( del );
    if (del[2] < 0)
	mag *= -1.0;
    VSCALE(&sol.s_values[9], del, t[2]/mag);
    VADD2(&sol.s_values[6], &sol.s_values[3], &sol.s_values[9]);
    VMOVE(&sol.s_values[12], tvec);

    for (i=3; i<=9; i+=3) {
	j = i + 12;
	VADD2(&sol.s_values[j], &sol.s_values[i], tvec);
    }
}
예제 #9
0
void
make_room(char *rname, fastf_t *imin, fastf_t *imax, fastf_t *thickness, struct wmember *headp)

    /* Interior RPP min point */


{
    struct wmember head;
    char	name[32];
    vect_t	omin;
    vect_t	omax;

    BU_LIST_INIT( &head.l );

    VSUB2( omin, imin, thickness );
    VADD2( omax, imax, thickness );

    snprintf( name, 32, "o%s", rname );
    mk_rpp( outfp, name, omin, omax );
    (void)mk_addmember( name, &head.l, NULL, WMOP_UNION );

    snprintf( name, 32, "i%s", rname );
    mk_rpp( outfp, name, imin, imax );
    mk_addmember( name, &head.l, NULL, WMOP_SUBTRACT );

    mk_lfcomb( outfp, rname, &head, 1 );
    (void)mk_addmember( rname, &(headp->l), NULL, WMOP_UNION );
}
/**
 * For a hit on the surface of an METABALL, return the (u, v)
 * coordinates of the hit point, 0 <= u, v <= 1.
 *
 * u = azimuth
 * v = elevation
 */
void
rt_metaball_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
{
    struct rt_metaball_internal *metaball = (struct rt_metaball_internal *)stp->st_specific;
    vect_t work, pprime;
    fastf_t r;

    if (ap) RT_CK_APPLICATION(ap);
    if (stp) RT_CK_SOLTAB(stp);
    if (hitp) RT_CK_HIT(hitp);
    if (!uvp) return;
    if (!metaball) return;

    /* stuff stolen from sph */
    VSUB2(work, hitp->hit_point, stp->st_center);
    VSCALE(pprime, work, 1.0/MAGNITUDE(work));
    /* Assert that pprime has unit length */

    /* U is azimuth, atan() range: -pi to +pi */
    uvp->uv_u = bn_atan2(pprime[Y], pprime[X]) * M_1_2PI;
    if (uvp->uv_u < 0)
	uvp->uv_u += 1.0;
    /*
     * V is elevation, atan() range: -pi/2 to +pi/2, because sqrt()
     * ensures that X parameter is always >0
     */
    uvp->uv_v = bn_atan2(pprime[Z],
			 sqrt(pprime[X] * pprime[X] + pprime[Y] * pprime[Y])) * M_1_2PI;

    /* approximation: r / (circumference, 2 * pi * aradius) */
    r = ap->a_rbeam + ap->a_diverge * hitp->hit_dist;
    uvp->uv_du = uvp->uv_dv =
	M_1_2PI * r / stp->st_aradius;
    return;
}
void writeCylinder
(
    rt_wdb* wdbp,
    Form&   form,
    bool    translate
) {
    char   name[NAMELEN + 1];
    vect_t base, height;

    if (translate) {
      VADD2(base, form.data.pt[0], form.tr_vec);
    } else {
      VMOVE(base, form.data.pt[0]);
    }

    VSUB2(height, form.data.pt[1], form.data.pt[0]);

    VSCALE(base, base, IntavalUnitInMm);
    VSCALE(height, height, IntavalUnitInMm);

    fastf_t radius = form.radius1 * IntavalUnitInMm;

    sprintf(name, "s%lu.rcc", (long unsigned)++rcc_counter);
    mk_rcc(wdbp, name, base, height, radius);
    addToRegion(form.compnr, name);

    if (form.s_compnr >= 1000)
	excludeFromRegion(form.s_compnr, name);
}
예제 #12
0
파일: clip.c 프로젝트: kanzure/brlcad
/**
 * Clip a ray against a rectangular parallelepiped (RPP) that has faces
 * parallel to the coordinate planes (a clipping RPP).  The RPP is
 * defined by a minimum point and a maximum point.
 *
 * Returns -
 * 0 if ray does not hit RPP,
 * !0 if ray hits RPP.
 *
 * Implicit Return -
 * if !0 was returned, "a" and "b" have been clipped to the RPP.
 */
int
vclip(vect_t a, vect_t b, fastf_t *min, fastf_t *max)
{
    static vect_t diff;
    static double sv;
    static double st;
    static double mindist, maxdist;
    fastf_t *pt = &a[0];
    fastf_t *dir = &diff[0];
    int i;

    mindist = -CLIP_DISTANCE;
    maxdist = CLIP_DISTANCE;
    VSUB2(diff, b, a);

    for (i=0; i < 3; i++, pt++, dir++, max++, min++) {
	if (*dir < -EPSILON) {
	    if ((sv = (*min - *pt) / *dir) < 0.0)
		return 0;	/* MISS */
	    if (maxdist > sv)
		maxdist = sv;
	    if (mindist < (st = (*max - *pt) / *dir))
		mindist = st;
	}  else if (*dir > EPSILON) {
	    if ((st = (*max - *pt) / *dir) < 0.0)
		return 0;	/* MISS */
	    if (maxdist > st)
		maxdist = st;
	    if (mindist < ((sv = (*min - *pt) / *dir)))
		mindist = sv;
	} else {
	    /*
	     * If direction component along this axis is NEAR 0,
	     * (i.e., this ray is aligned with this axis), merely
	     * check against the boundaries.
	     */
	    if ((*min > *pt) || (*max < *pt))
		return 0;	/* MISS */;
	}
    }
    if (mindist >= maxdist)
	return 0;	/* MISS */

    if (mindist > 1 || maxdist < 0)
	return 0;	/* MISS */

    if (mindist <= 0 && maxdist >= 1)
	return 1;	/* HIT, no clipping needed */

    /* Don't grow one end of a contained segment */
    if (mindist < 0)
	mindist = 0;
    if (maxdist > 1)
	maxdist = 1;

    /* Compute actual intercept points */
    VJOIN1(b, a, maxdist, diff);		/* b must go first */
    VJOIN1(a, a, mindist, diff);
    return 1;		/* HIT */
}
예제 #13
0
/*
 *  Determine whether the current hitpoint along a series of
 *  reflections is visible from the origin of the ray.
 *  (which is the location of our "point" eye for now)
 *
 *  Strategy: we shoot back toward the origin of the ray
 *   If we don't hit anything (i.e. miss) we made it.
 *   If we hit something we made it if that distance is greater
 *   than the distance back to the eye.
 */
static int
isvisible( struct application *ap, struct hit *hitp, const vect_t norm )
{
    int cpu_num;
    struct application sub_ap;
    vect_t	rdir;

    if ( ap->a_resource == RESOURCE_NULL)
	cpu_num = 0;
    else
	cpu_num = ap->a_resource->re_cpu;

    /* compute the ray direction */
    VSUB2( rdir, firstray[cpu_num].r_pt, hitp->hit_point );
    VUNITIZE( rdir );
    if ( VDOT(rdir, norm) < 0 )
	return 0;	/* backfacing */

    sub_ap = *ap;	/* struct copy */
    sub_ap.a_level = ap->a_level+1;
    sub_ap.a_onehit = 1;
    sub_ap.a_purpose = "sight";
    sub_ap.a_hit = hiteye;
    sub_ap.a_miss = hittrue;
    /*
     * New origin is one unit in the ray direction in
     * order to get away from the surface we intersected.
     */
    VADD2( sub_ap.a_ray.r_pt, hitp->hit_point, rdir );
    VMOVE( sub_ap.a_ray.r_dir, rdir );

    return rt_shootray( &sub_ap );
}
예제 #14
0
파일: wray.c 프로젝트: cogitokat/brlcad
/*
 * W R A Y
 */
void
wray(struct partition *pp, struct application *ap, FILE *fp, const vect_t inormal)
{
    struct vldray vldray;
    register struct hit *hitp= pp->pt_inhit;

    VMOVE(&(vldray.ox), hitp->hit_point);
    VSUB2(&(vldray.rx), pp->pt_outhit->hit_point,
	  hitp->hit_point);

    WRAY_NORMAL(vldray, inormal);

    vldray.pa = vldray.pe = vldray.pc = vldray.sc = 0;	/* no curv */

    /* Air is marked by zero or negative region ID codes.
     * When air is encountered, the air code is taken from reg_aircode.
     * The negative of the air code is used for the "ob" field, to
     * distinguish air from other regions.
     */
    if ((vldray.ob = pp->pt_regionp->reg_regionid) <= 0)
	vldray.ob = -(pp->pt_regionp->reg_aircode);

    WRAY_TAG(vldray, ap);

    if (fwrite(&vldray, sizeof(struct vldray), 1, fp) != 1)
	bu_bomb("rway:  write error");
}
예제 #15
0
파일: rec.c 프로젝트: cogitokat/brlcad
/**
 * R E C _ C U R V E
 *
 * Return the "curvature" of the cylinder.  If an endplate,
 * pick a principle direction orthogonal to the normal, and
 * indicate no curvature.  Otherwise, compute curvature.
 * Normal must have been computed before calling this routine.
 */
void
rt_rec_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp)
{
    struct rec_specific *rec =
	(struct rec_specific *)stp->st_specific;
    vect_t uu;
    fastf_t ax, bx, q;

    switch (hitp->hit_surfno) {
	case REC_NORM_BODY:
	    /* This could almost certainly be simpler if we used
	     * inverse A rather than inverse A squared, right Ed?
	     */
	    VMOVE(cvp->crv_pdir, rec->rec_Hunit);
	    VSUB2(uu, hitp->hit_point, rec->rec_V);
	    cvp->crv_c1 = 0;
	    ax = VDOT(uu, rec->rec_A) * rec->rec_iAsq;
	    bx = VDOT(uu, rec->rec_B) * rec->rec_iBsq;
	    q = sqrt(ax * ax * rec->rec_iAsq + bx * bx * rec->rec_iBsq);
	    cvp->crv_c2 = - rec->rec_iAsq * rec->rec_iBsq / (q*q*q);
	    break;
	case REC_NORM_TOP:
	case REC_NORM_BOT:
	    bn_vec_ortho(cvp->crv_pdir, hitp->hit_normal);
	    cvp->crv_c1 = cvp->crv_c2 = 0;
	    break;
	default:
	    bu_log("rt_rec_curve: bad surfno %d\n", hitp->hit_surfno);
	    break;
    }
}
예제 #16
0
파일: vutil.c 프로젝트: kanzure/brlcad
/*
 * Map "display plate coordinates" (which can just be the screen viewing cube),
 * into [-1, +1] coordinates, with perspective.
 * Per "High Resolution Virtual Reality" by Michael Deering,
 * Computer Graphics 26, 2, July 1992, pp 195-201.
 *
 * L is lower left corner of screen, H is upper right corner.
 * L[Z] is the front (near) clipping plane location.
 * H[Z] is the back (far) clipping plane location.
 *
 * This corresponds to the SGI "window()" routine, but taking into account
 * skew due to the eyepoint being offset parallel to the image plane.
 *
 * The gist of the algorithm is to translate the display plate to the
 * view center, shear the eye point to (0, 0, 1), translate back,
 * then apply an off-axis perspective projection.
 *
 * Another (partial) reference is "A comparison of stereoscopic cursors
 * for the interactive manipulation of B-splines" by Barham & McAllister,
 * SPIE Vol 1457 Stereoscopic Display & Applications, 1991, pg 19.
 */
void
ged_deering_persp_mat(fastf_t *m, const fastf_t *l, const fastf_t *h, const fastf_t *eye)
/* lower left corner of screen */
/* upper right (high) corner of screen */
/* eye location.  Traditionally at (0, 0, 1) */
{
    vect_t diff;	/* H - L */
    vect_t sum;	/* H + L */

    VSUB2(diff, h, l);
    VADD2(sum, h, l);

    m[0] = 2 * eye[Z] / diff[X];
    m[1] = 0;
    m[2] = (sum[X] - 2 * eye[X]) / diff[X];
    m[3] = -eye[Z] * sum[X] / diff[X];

    m[4] = 0;
    m[5] = 2 * eye[Z] / diff[Y];
    m[6] = (sum[Y] - 2 * eye[Y]) / diff[Y];
    m[7] = -eye[Z] * sum[Y] / diff[Y];

    /* Multiplied by -1, to do right-handed Z coords */
    m[8] = 0;
    m[9] = 0;
    m[10] = -(sum[Z] - 2 * eye[Z]) / diff[Z];
    m[11] = -(-eye[Z] + 2 * h[Z] * eye[Z]) / diff[Z];

    m[12] = 0;
    m[13] = 0;
    m[14] = -1;
    m[15] = eye[Z];

    /* XXX May need to flip Z ? (lefthand to righthand?) */
}
예제 #17
0
파일: g-dxf.c 프로젝트: kanzure/brlcad
static int
find_closest_color(float color[3])
{
    int icolor[3];
    int i;
    int dist_sq;
    int color_num;

    VSCALE(icolor, color, 255);

    color_num = 0;
    dist_sq = MAGSQ(icolor);

    for (i = 1; i < 256; i++) {
	int tmp_dist;
	int diff[3];

	VSUB2(diff, icolor, &rgb[i*3]);
	tmp_dist = MAGSQ(diff);
	if (tmp_dist < dist_sq) {
	    dist_sq = tmp_dist;
	    color_num = i;
	}
    }

    return color_num;
}
예제 #18
0
파일: hideline.c 프로젝트: cciechad/brlcad
static int
hit_headon(struct application *ap, struct partition *PartHeadp)
{
    register char diff_solid;
    vect_t	diff;
    register fastf_t len;

    if (PartHeadp->pt_forw->pt_forw != PartHeadp)
	Tcl_AppendResult(interp, "hit_headon: multiple partitions\n", (char *)NULL);

    VJOIN1(PartHeadp->pt_forw->pt_inhit->hit_point, ap->a_ray.r_pt,
	   PartHeadp->pt_forw->pt_inhit->hit_dist, ap->a_ray.r_dir);
    VSUB2(diff, PartHeadp->pt_forw->pt_inhit->hit_point, aim_point);

    diff_solid = (FIRST_SOLID(sp) !=
		  PartHeadp->pt_forw->pt_inseg->seg_stp->st_dp);
    len = MAGNITUDE(diff);

    if (	NEAR_ZERO(len, epsilon)
		||
		( diff_solid &&
		  VDOT(diff, ap->a_ray.r_dir) > 0 )
	)
	return(1);
    else
	return(0);
}
예제 #19
0
/*
 *  Determine whether the current hitpoint along a series of
 *  reflections is visible from the origin of the ray.
 *  (which is the location of our "point" eye for now)
 *
 *  Strategy: we shoot back toward the origin of the ray
 *   If we don't hit anything (i.e. miss) we made it.
 *   If we hit something we made it if that distance is greater
 *   than the distance back to the eye.
 */
static int
isvisible(struct application *ap, struct hit *hitp, const fastf_t *norm)
{
    struct application sub_ap;
    vect_t	rdir;

    /* compute the ray direction */
    VSUB2( rdir, firstray.r_pt, hitp->hit_point );
    VUNITIZE( rdir );
    if ( VDOT(rdir, norm) < 0 )
	return( 0 );	/* backfacing */

    sub_ap = *ap;	/* struct copy */
    sub_ap.a_level = ap->a_level+1;
    sub_ap.a_onehit = 1;
    sub_ap.a_hit = hiteye;
    sub_ap.a_miss = hittrue;
    /*
     * New origin is one unit in the ray direction in
     * order to get away from the surface we intersected.
     */
    VADD2( sub_ap.a_ray.r_pt, hitp->hit_point, rdir );
    VMOVE( sub_ap.a_ray.r_dir, rdir );

    return( rt_shootray( &sub_ap ) );
}
예제 #20
0
파일: tri_tri.c 프로젝트: cogitokat/brlcad
void calc_isect2(point_t VTX0, point_t VTX1, point_t VTX2, fastf_t VV0, fastf_t VV1,
		 fastf_t VV2, fastf_t D0, fastf_t D1, fastf_t D2, fastf_t *isect0,
		 fastf_t *isect1, point_t isectpoint0, point_t isectpoint1)
{
    fastf_t tmp=D0/(D0-D1);
    point_t diff;
    *isect0=VV0+(VV1-VV0)*tmp;
    VSUB2(diff, VTX1, VTX0);
    VSCALE(diff, diff, tmp);
    VADD2(isectpoint0, diff, VTX0);
    tmp=D0/(D0-D2);
    *isect1=VV0+(VV2-VV0)*tmp;
    VSUB2(diff, VTX2, VTX0);
    VSCALE(diff, diff, tmp);
    VADD2(isectpoint1, VTX0, diff);
}
예제 #21
0
static int
isst_load_g(ClientData UNUSED(clientData), Tcl_Interp *interp, int objc,
	    Tcl_Obj *const *objv)
{
    struct isst_s *isst;
    char **argv;
    int argc;
    double az, el;
    struct bu_vls tclstr = BU_VLS_INIT_ZERO;
    vect_t vec;
    Togl   *togl;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 1, objv, "load_g pathname object");
	return TCL_ERROR;
    }

    if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
	return TCL_ERROR;
    }

    isst = (struct isst_s *) Togl_GetClientData(togl);

    argv = (char **)malloc(sizeof(char *) * (strlen(Tcl_GetString(objv[3])) + 1));	/* allocate way too much. */
    argc = bu_argv_from_string(argv, strlen(Tcl_GetString(objv[3])), Tcl_GetString(objv[3]));

    load_g(isst->tie, Tcl_GetString(objv[2]), argc, (const char **)argv, &(isst->meshes));
    free(argv);

    VSETALL(isst->camera.pos, isst->tie->radius);
    VMOVE(isst->camera.focus, isst->tie->mid);
    VMOVE(isst->camera_pos_init, isst->camera.pos);
    VMOVE(isst->camera_focus_init, isst->camera.focus);

    /* Set the initial az and el values in Tcl/Tk */
    VSUB2(vec, isst->camera.pos, isst->camera.focus);
    VUNITIZE(vec);
    AZEL_FROM_V3DIR(az, el, vec);
    az = az * -DEG2RAD;
    el = el * -DEG2RAD;
    bu_vls_sprintf(&tclstr, "%f", az);
    Tcl_SetVar(interp, "az", bu_vls_addr(&tclstr), 0);
    bu_vls_sprintf(&tclstr, "%f", el);
    Tcl_SetVar(interp, "el", bu_vls_addr(&tclstr), 0);
    bu_vls_free(&tclstr);

    render_phong_init(&isst->camera.render, NULL);

    isst->ogl = 1;
    isst->w = Togl_Width(togl);
    isst->h = Togl_Height(togl);

    resize_isst(isst);

    isst->t1 = bu_gettime();
    isst->t2 = bu_gettime();

    return TCL_OK;
}
예제 #22
0
파일: nastran-g.c 프로젝트: cciechad/brlcad
HIDDEN void
get_cbar(void)
{
    int eid, pid;
    int g1, g2;
    point_t pt1, pt2;
    fastf_t radius;
    vect_t height;
    struct pbar *pb;
    char cbar_name[NAMESIZE+1];

    eid = atoi( curr_rec[1] );

    pid = atoi( curr_rec[2] );
    if ( !pid )
    {
	if ( bar_def_pid )
	    pid = bar_def_pid;
	else
	    pid = eid;
    }

    g1 = atoi( curr_rec[3] );

    g2 = atoi( curr_rec[4] );

    get_grid( g1, pt1 );
    get_grid( g2, pt2 );

    for ( BU_LIST_FOR( pb, pbar, &pbar_head.l ) )
    {
	if ( pb->pid == pid )
	    break;
    }

    if ( BU_LIST_IS_HEAD( &pb->l, &pbar_head.l ) )
    {
	log_line( "Non-existent PID referenced in CBAR" );
	return;
    }

    VSCALE( pt1, pt1, conv[units] );
    VSCALE( pt2, pt2, conv[units] );

    radius = sqrt( pb->area/bn_pi );
    radius = radius * conv[units];

    VSUB2( height, pt2, pt1 );

    sprintf( cbar_name, "cbar.%d", eid );
    mk_rcc( fpout, cbar_name, pt1, height, radius );

    mk_addmember( cbar_name, &pb->head.l, NULL, WMOP_UNION );
}
예제 #23
0
파일: arbn.c 프로젝트: kanzure/brlcad
void
rt_arbn_centroid(point_t *cent, const struct rt_db_internal *ip)
{
    struct poly_face *faces;
    struct rt_arbn_internal *aip = (struct rt_arbn_internal *)ip->idb_ptr;
    size_t i;
    point_t arbit_point = VINIT_ZERO;
    fastf_t volume = 0.0;

    *cent[0] = 0.0;
    *cent[1] = 0.0;
    *cent[2] = 0.0;

    if (cent == NULL)
	return;

    /* allocate array of face structs */
    faces = (struct poly_face *)bu_calloc(aip->neqn, sizeof(struct poly_face), "rt_arbn_centroid: faces");
    for (i = 0; i < aip->neqn; i++) {
	/* allocate array of pt structs, max number of verts per faces = (# of faces) - 1 */
	faces[i].pts = (point_t *)bu_calloc(aip->neqn - 1, sizeof(point_t), "rt_arbn_centroid: pts");
    }
    rt_arbn_faces_area(faces, aip);
    for (i = 0; i < aip->neqn; i++) {
	bn_polygon_centroid(&faces[i].cent, faces[i].npts, (const point_t *) faces[i].pts);
	VADD2(arbit_point, arbit_point, faces[i].cent);

    }
    VSCALE(arbit_point, arbit_point, (1/aip->neqn));

    for (i = 0; i < aip->neqn; i++) {
	vect_t tmp = VINIT_ZERO;
	/* calculate volume */
	VSCALE(tmp, faces[i].plane_eqn, faces[i].area);
	faces[i].vol_pyramid = (VDOT(faces[i].pts[0], tmp)/3);
	volume += faces[i].vol_pyramid;
	/*Vector from arbit_point to centroid of face, results in h of pyramid */
	VSUB2(faces[i].cent_pyramid, faces[i].cent, arbit_point);
	/*centroid of pyramid is 1/4 up from the bottom */
	VSCALE(faces[i].cent_pyramid, faces[i].cent_pyramid, 0.75f);
	/* now cent_pyramid is back in the polyhedron */
	VADD2(faces[i].cent_pyramid, faces[i].cent_pyramid, arbit_point);
	/* weight centroid of pyramid by pyramid's volume */
	VSCALE(faces[i].cent_pyramid, faces[i].cent_pyramid, faces[i].vol_pyramid);
	/* add cent_pyramid to the centroid of the polyhedron */
	VADD2(*cent, *cent, faces[i].cent_pyramid);
    }
    /* reverse the weighting */
    VSCALE(*cent, *cent, (1/volume));
    for (i = 0; i < aip->neqn; i++) {
	bu_free((char *)faces[i].pts, "rt_arbn_centroid: pts");
    }
    bu_free((char *)faces, "rt_arbn_centroid: faces");
}
예제 #24
0
파일: nastran-g.c 프로젝트: kanzure/brlcad
HIDDEN int
convert_cs(struct coord_sys *cs)
{
    struct coord_sys *cs2;
    point_t tmp_orig, tmp_pt1, tmp_pt2;
    VSETALL(tmp_orig, 0.0);
    VSETALL(tmp_pt1, 0.0);
    VSETALL(tmp_pt2, 0.0);

    if (!cs->rid)
	return 0;

    for (BU_LIST_FOR(cs2, coord_sys, &coord_head.l)) {
	if (cs2->cid != cs->rid)
	    continue;
	break;
    }

    if (BU_LIST_IS_HEAD(&cs2->l, &coord_head.l)) {
	bu_exit(1, "A coordinate system is defined in terms of a non-existent coordinate system!!!\n");
    }

    if (convert_pt(cs->origin, cs2, tmp_orig))
	return 1;

    if (convert_pt(cs->v1, cs2, tmp_pt1))
	return 1;

    if (convert_pt(cs->v2, cs2, tmp_pt2))
	return 1;

    VMOVE(cs->origin, tmp_orig);
    VSUB2(cs->v3, tmp_pt1, cs->origin);
    VUNITIZE(cs->v3);
    VSUB2(cs->v1, tmp_pt2, cs->origin);
    VCROSS(cs->v2, cs->v3, cs->v1);
    VUNITIZE(cs->v2);
    VCROSS(cs->v1, cs->v3, cs->v2);
    cs->rid = 0;
    return 0;
}
예제 #25
0
void compute_normal(struct rt_bot_internal *bot, int p1, int p2,
		    int p3, float *dest)
{
    float v1[3];
    float v2[3];
    float v3[3];
    float vec1[3];
    float vec2[3];
    float fnorm[3];
    float temp[3];
    float *np1, *np2, *np3;

    /* get face normal */
    get_vertex(bot, p1, v1);
    if (flip_normals) {
	get_vertex(bot, p3, v2);
	get_vertex(bot, p2, v3);
    } else {
	get_vertex(bot, p2, v2);
	get_vertex(bot, p3, v3);
    }

    VSUB2(vec1, v1, v2);
    VSUB2(vec2, v1, v3);
    VCROSS(fnorm, vec1, vec2);
    VUNITIZE(fnorm);

    /* average existing normal with face normal per vertex */
    np1 = dest + 3*p1;
    np2 = dest + 3*p2;
    np3 = dest + 3*p3;
    VADD2(temp, fnorm, np1);
    VUNITIZE(temp);
    VMOVE(np1, temp);
    VADD2(temp, fnorm, np2);
    VUNITIZE(temp);
    VMOVE(np2, temp);
    VADD2(temp, fnorm, np3);
    VUNITIZE(temp);
    VMOVE(np3, temp);
}
예제 #26
0
파일: nmg_pt_fu.c 프로젝트: kanzure/brlcad
/**
 * Classify a point vs a vertex (touching/missed)
 */
static int
nmg_class_pt_vu(struct fpi *fpi, struct vertexuse *vu)
{
    vect_t delta;
    struct ve_dist *ved;

    NMG_CK_VERTEXUSE(vu);

    /* see if we've classified this vertex WRT the point already */
    for (BU_LIST_FOR(ved, ve_dist, &fpi->ve_dh)) {
	NMG_CK_VED(ved);
	if (ved->magic_p == &vu->v_p->magic) {
	    goto found;
	}
    }

    /* if we get here, we didn't find the vertex in the list of
     * previously classified geometry.  Create an entry in the
     * face's list of processed geometry.
     */
    VSUB2(delta, vu->v_p->vg_p->coord, fpi->pt);

    BU_ALLOC(ved, struct ve_dist);
    ved->magic_p = &vu->v_p->magic;
    ved->dist = MAGNITUDE(delta);
    if (ved->dist < fpi->tol->dist_sq) {
	ved->status = NMG_FPI_TOUCHED;
	if (fpi->hits == NMG_FPI_PERGEOM) {
	    /* need to cast vu_func pointer for actual use as a function */
	    void (*cfp)(struct vertexuse *, point_t, const char*);
	    cfp = (void (*)(struct vertexuse *, point_t, const char *))fpi->vu_func;
	    cfp(vu, fpi->pt, fpi->priv);
	}
    } else ved->status = NMG_FPI_MISSED;

    ved->v1 = ved->v2 = vu->v_p;

    BU_LIST_MAGIC_SET(&ved->l, NMG_VE_DIST_MAGIC);
    BU_LIST_APPEND(&fpi->ve_dh, &ved->l);
found:

    if (fpi->vu_func  &&
	ved->status == NMG_FPI_TOUCHED &&
	fpi->hits == NMG_FPI_PERUSE) {
	/* need to cast vu_func pointer for actual use as a function */
	void (*cfp)(struct vertexuse *, point_t, const char*);
	cfp = (void (*)(struct vertexuse *, point_t, const char *))fpi->vu_func;
	cfp(vu, fpi->pt, fpi->priv);
    }

    return ved->status;
}
예제 #27
0
파일: poly.c 프로젝트: cogitokat/brlcad
/**
 * R T _ P G F A C E
 *
 * This function is called with pointers to 3 points,
 * and is used to prepare PG faces.
 * ap, bp, cp point to vect_t points.
 *
 * Return -
 * 0 if the 3 points didn't form a plane (e.g., colinear, etc.).
 * # pts (3) if a valid plane resulted.
 */
HIDDEN int
rt_pgface(struct soltab *stp, fastf_t *ap, fastf_t *bp, fastf_t *cp, const struct bn_tol *tol)
{
    struct tri_specific *trip;
    vect_t work;
    fastf_t m1, m2, m3, m4;

    BU_GET(trip, struct tri_specific);
    VMOVE(trip->tri_A, ap);
    VSUB2(trip->tri_BA, bp, ap);
    VSUB2(trip->tri_CA, cp, ap);
    VCROSS(trip->tri_wn, trip->tri_BA, trip->tri_CA);

    /* Check to see if this plane is a line or pnt */
    m1 = MAGNITUDE(trip->tri_BA);
    m2 = MAGNITUDE(trip->tri_CA);
    VSUB2(work, bp, cp);
    m3 = MAGNITUDE(work);
    m4 = MAGNITUDE(trip->tri_wn);
    if (m1 < tol->dist || m2 < tol->dist ||
	m3 < tol->dist || m4 < tol->dist) {
	BU_PUT(trip, struct tri_specific);
	if (RT_G_DEBUG & DEBUG_ARB8)
	    bu_log("pg(%s): degenerate facet\n", stp->st_name);
	return 0;			/* BAD */
    }

    /* wn is a normal of not necessarily unit length.
     * N is an outward pointing unit normal.
     * We depend on the points being given in CCW order here.
     */
    VMOVE(trip->tri_N, trip->tri_wn);
    VUNITIZE(trip->tri_N);

    /* Add this face onto the linked list for this solid */
    trip->tri_forw = (struct tri_specific *)stp->st_specific;
    stp->st_specific = (genptr_t)trip;
    return 3;				/* OK */
}
fastf_t
rt_metaball_point_value_iso(const point_t *p, const struct bu_list *points)
{
    struct wdb_metaballpt *mbpt;
    fastf_t ret = 0.0;
    point_t v;

    for (BU_LIST_FOR(mbpt, wdb_metaballpt, points)) {
	VSUB2(v, mbpt->coord, *p);
	ret += fabs(mbpt->fldstr) * mbpt->fldstr / MAGSQ(v);	/* f/r^2 */
    }
    return ret;
}
예제 #29
0
파일: bottess.c 프로젝트: kanzure/brlcad
int
soup_add_face_precomputed(struct soup_s *s, point_t a, point_t b , point_t c, plane_t d, uint32_t foo)
{
    struct face_s *f;
    vect_t e1, e2, x;

    VSUB2(e1, b, a);
    VSUB2(e2, c, a);
    VCROSS(x, e1, e2);

    /* grow face array if needed */
    if (s->nfaces >= s->maxfaces)
	s->faces = (struct face_s *)bu_realloc(s->faces, (s->maxfaces += faces_per_page) * sizeof(struct face_s), "bot soup faces");
    f = s->faces + s->nfaces;

    VMOVE(f->vert[0], a);
    if (VDOT(x, d) <= 0) {
	VMOVE(f->vert[1], b);
	VMOVE(f->vert[2], c);
    } else {
	VMOVE(f->vert[1], c);
	VMOVE(f->vert[2], b);
    }

    HMOVE(f->plane, d);

    /* solve the bounding box (should this be VMINMAX?) */
    VMOVE(f->min, f->vert[0]); VMOVE(f->max, f->vert[0]);
    VMIN(f->min, f->vert[1]); VMAX(f->max, f->vert[1]);
    VMIN(f->min, f->vert[2]); VMAX(f->max, f->vert[2]);
    /* fluff the bounding box for fp fuzz */
    f->min[X]-=.1; f->min[Y]-=.1; f->min[Z]-=.1;
    f->max[X]+=.1; f->max[Y]+=.1; f->max[Z]+=.1;

    f->foo = foo;

    s->nfaces++;
    return 0;
}
예제 #30
0
/**
 *@brief
 * Draw a vector between points "from" and "to", with the option of
 * having an arrowhead on either or both ends.
 *
 * The fromheadfract and toheadfract values indicate the length of the
 * arrowheads relative to the length of the vector to-from.  A typical
 * value is 0.1, making the head 10% of the size of the vector.  The
 * sign of the "fract" values indicates the pointing direction.
 * Positive points towards the "to" point, negative points towards
 * "from".  Upon return, the virtual pen is left at the "to" position.
 */
void
tp_3vector(FILE *plotfp, fastf_t *from, fastf_t *to, double fromheadfract, double toheadfract)
{
    register fastf_t len;
    register fastf_t hooklen;
    vect_t diff;
    vect_t c1, c2;
    vect_t h1, h2;
    vect_t backup;
    point_t tip;

    pdv_3line(plotfp, from, to);
    /* "pen" is left at "to" position */

    VSUB2(diff, to, from);
    if ((len = MAGNITUDE(diff)) < SMALL)  return;
    VSCALE(diff, diff, 1/len);
    bn_vec_ortho(c1, diff);
    VCROSS(c2, c1, diff);

    if (!ZERO(fromheadfract)) {
	hooklen = fromheadfract*len;
	VSCALE(backup, diff, -hooklen);

	VSCALE(h1, c1, hooklen);
	VADD3(tip, from, h1, backup);
	pdv_3move(plotfp, from);
	pdv_3cont(plotfp, tip);

	VSCALE(h2, c2, hooklen);
	VADD3(tip, from, h2, backup);
	pdv_3move(plotfp, tip);
    }
    if (!ZERO(toheadfract)) {
	hooklen = toheadfract*len;
	VSCALE(backup, diff, -hooklen);

	VSCALE(h1, c1, hooklen);
	VADD3(tip, to, h1, backup);
	pdv_3move(plotfp, to);
	pdv_3cont(plotfp, tip);

	VSCALE(h2, c2, hooklen);
	VADD3(tip, to, h2, backup);
	pdv_3move(plotfp, tip);
    }
    /* Be certain "pen" is left at "to" position */
    if (!ZERO(fromheadfract) || !ZERO(toheadfract))
	pdv_3cont(plotfp, to);

}