Ejemplo n.º 1
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;
    }
}
Ejemplo n.º 2
0
/**
 * 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;
    }
}
/* planar image map */
color image_plane_texture(const vector * hit, const texture * tx, const ray * ry) {
  vector pnt;
  flt u, v, miprad, maxscale;
  standard_texture * tex = (standard_texture *) tx;
 
  pnt.x=hit->x - tex->ctr.x;
  pnt.y=hit->y - tex->ctr.y;
  pnt.z=hit->z - tex->ctr.z;

  VDOT(u, tex->uaxs, pnt);
  VDOT(v, tex->vaxs, pnt); 

  u = u * tex->scale.x;
  u = u + tex->rot.x;
  u = u - ((int) u);
  if (u < 0.0) u += 1.0;

  v = v * tex->scale.y;
  v = v + tex->rot.y;
  v = v - ((int) v);
  if (v < 0.0) v += 1.0;

  
  maxscale = (fabs(tex->scale.x) > fabs(tex->scale.y)) ? 
             tex->scale.x : tex->scale.y;

  miprad = 0.05 * ry->opticdist * fabs(maxscale);

  return MIPMap(tex->img, u, v, miprad);
}
Ejemplo n.º 4
0
Archivo: light.cpp Proyecto: adiog/tbb
static void light_intersect(point_light * l, ray * ry) {
  flt b, disc, t1, t2, temp;
  vector V;

  /* Lights do not cast shadows.. */
  if (ry->flags & RT_RAY_SHADOW)
    return;

  VSUB(l->ctr, ry->o, V);
  VDOT(b, V, ry->d); 
  VDOT(temp, V, V);  

  disc=b*b + l->rad*l->rad - temp;

  if (disc<=0.0) return;
  disc=sqrt(disc);

  t2=b+disc;
  if (t2 <= SPEPSILON) 
    return;
  add_intersection(t2, (object *) l, ry);  

  t1=b-disc;
  if (t1 > SPEPSILON) 
    add_intersection(t1, (object *) l, ry);  
}
Ejemplo n.º 5
0
/* planar image map */
color image_plane_texture(vector * hit, texture * tex, ray * ry) {
    vector pnt;
    flt u,v;

    pnt.x=hit->x - tex->ctr.x;
    pnt.y=hit->y - tex->ctr.y;
    pnt.z=hit->z - tex->ctr.z;

    VDOT(u, tex->uaxs, pnt);
    /*  VDOT(len, tex->uaxs, tex->uaxs);
      u = u / sqrt(len); */

    VDOT(v, tex->vaxs, pnt);
    /*  VDOT(len, tex->vaxs, tex->vaxs);
      v = v / sqrt(len); */


    u = u * tex->scale.x;
    u = u + tex->rot.x;
    u = fmod(u, 1.0);
    if (u < 0.0) u += 1.0;

    v = v * tex->scale.y;
    v = v + tex->rot.y;
    v = fmod(v, 1.0);
    if (v < 0.0) v += 1.0;

    return ImageMap((rawimage *)tex->img, u, v);
}
Ejemplo n.º 6
0
static void cylinder_intersect(const cylinder * cyl, ray * ry) {
  vector rc, n, D, O;  
  flt t, s, tin, tout, ln, d; 

  rc.x = ry->o.x - cyl->ctr.x;
  rc.y = ry->o.y - cyl->ctr.y;
  rc.z = ry->o.z - cyl->ctr.z; 

  VCross(&ry->d, &cyl->axis, &n);

  ln=SQRT(n.x*n.x + n.y*n.y + n.z*n.z);    /* finish length calculation */

  if (ln == 0.0) {  /* ray is parallel to the cylinder.. */
    VDOT(d, rc, cyl->axis);         
    D.x = rc.x - d * cyl->axis.x; 
    D.y = rc.y - d * cyl->axis.y;
    D.z = rc.z - d * cyl->axis.z;
    VDOT(d, D, D);
    d = SQRT(d);
    tin = -FHUGE;
    tout = FHUGE;
    /* if (d <= cyl->rad) then ray is inside cylinder.. else outside */
  }

  n.x /= ln;
  n.y /= ln;
  n.z /= ln;

  VDOT(d, rc, n);
  d = FABS(d); 

  if (d <= cyl->rad) {  /* ray intersects cylinder.. */
    VCross(&rc, &cyl->axis, &O);
    VDOT(t, O, n);
    t = - t / ln;
    VCross(&n, &cyl->axis, &O); 

    ln = SQRT(O.x*O.x + O.y*O.y + O.z*O.z);
    O.x /= ln;
    O.y /= ln;
    O.z /= ln;

    VDOT(s, ry->d, O);
    s = FABS(SQRT(cyl->rad*cyl->rad - d*d) / s);
    tin = t - s;
    ry->add_intersection(tin, (object *) cyl, ry); 
    tout = t + s;
    ry->add_intersection(tout, (object *) cyl, ry);
  }
}
Ejemplo n.º 7
0
static void fcylinder_intersect(cylinder * cyl, ray * ry) {
  vector rc, n, O, hit, tmp2, ctmp4;
  flt t, s, tin, tout, ln, d, tmp, tmp3;
 
  rc.x = ry->o.x - cyl->ctr.x;  
  rc.y = ry->o.y - cyl->ctr.y;
  rc.z = ry->o.z - cyl->ctr.z;
 
  VCross(&ry->d, &cyl->axis, &n);
 
  VDOT(ln, n, n);
  ln=sqrt(ln);    /* finish length calculation */
 
  if (ln == 0.0) {  /* ray is parallel to the cylinder.. */
    return;       /* in this case, we want to miss or go through the "hole" */
  }
 
  VNorm(&n);
  VDOT(d, rc, n);
  d = fabs(d);
 
  if (d <= cyl->rad) {  /* ray intersects cylinder.. */
    VCross(&rc, &cyl->axis, &O);
    VDOT(t, O, n);
    t = - t / ln;
    VCross(&n, &cyl->axis, &O);
    VNorm(&O);
    VDOT(s, ry->d, O);
    s = fabs(sqrt(cyl->rad*cyl->rad - d*d) / s);
    tin = t - s;

    RAYPNT(hit, (*ry), tin); 

    ctmp4=cyl->axis;
    VNorm(&ctmp4);

    tmp2.x = hit.x - cyl->ctr.x;   
    tmp2.y = hit.y - cyl->ctr.y;   
    tmp2.z = hit.z - cyl->ctr.z;   

    VDOT(tmp,  tmp2, ctmp4);
    VDOT(tmp3, cyl->axis, cyl->axis);

    if ((tmp > 0.0) && (tmp < sqrt(tmp3))) 
      add_intersection(tin, (object *) cyl, ry);
    tout = t + s;

    RAYPNT(hit, (*ry), tout); 

    tmp2.x = hit.x - cyl->ctr.x;   
    tmp2.y = hit.y - cyl->ctr.y;   
    tmp2.z = hit.z - cyl->ctr.z;   

    VDOT(tmp,  tmp2, ctmp4); 
    VDOT(tmp3, cyl->axis, cyl->axis);

    if ((tmp > 0.0) && (tmp < sqrt(tmp3))) 
      add_intersection(tout, (object *) cyl, ry);
  }
}
Ejemplo n.º 8
0
/*
 * R E F R A C T
 *
 * Compute the refracted ray 'v_2' from the incident ray 'v_1' with
 * the refractive indices 'ri_2' and 'ri_1' respectively.
 * Using Schnell's Law:
 *
 * theta_1 = angle of v_1 with surface normal
 * theta_2 = angle of v_2 with reversed surface normal
 * ri_1 * sin(theta_1) = ri_2 * sin(theta_2)
 *
 * sin(theta_2) = ri_1/ri_2 * sin(theta_1)
 *
 * The above condition is undefined for ri_1/ri_2 * sin(theta_1)
 * being greater than 1, and this represents the condition for total
 * reflection, the 'critical angle' is the angle theta_1 for which
 * ri_1/ri_2 * sin(theta_1) equals 1.
 *
 * Returns TRUE if refracted, FALSE if reflected.
 *
 * Note:  output (v_2) can be same storage as an input.
 */
HIDDEN int
rr_refract(vect_t v_1, vect_t norml, double ri_1, double ri_2, vect_t v_2)
{
    vect_t w, u;
    fastf_t beta;

    if (NEAR_ZERO(ri_1, 0.0001) || NEAR_ZERO(ri_2, 0.0001)) {
	bu_log("rr_refract:ri1=%g, ri2=%g\n", ri_1, ri_2);
	beta = 1;
    } else {
	beta = ri_1/ri_2;		/* temp */
	if (beta > 10000) {
	    bu_log("rr_refract:  beta=%g\n", beta);
	    beta = 1000;
	}
    }
    VSCALE(w, v_1, beta);
    VCROSS(u, w, norml);

    /*
     *	|w X norml| = |w||norml| * sin(theta_1)
     *	        |u| = ri_1/ri_2 * sin(theta_1) = sin(theta_2)
     */
    if ((beta = VDOT(u, u)) > 1.0) {
	/* Past critical angle, total reflection.
	 * Calculate reflected (bounced) incident ray.
	 */
	if (R_DEBUG&RDEBUG_REFRACT) bu_log("rr_refract: reflected.  ri1=%g ri2=%g beta=%g\n",
					   ri_1, ri_2, beta);
	VREVERSE(u, v_1);
	beta = 2 * VDOT(u, norml);
	VSCALE(w, norml, beta);
	VSUB2(v_2, w, u);
	return 0;		/* reflected */
    } else {
	/*
	 * 1 - beta = 1 - sin(theta_2)^^2
	 *	    = cos(theta_2)^^2.
	 * beta = -1.0 * cos(theta_2) - Dot(w, norml).
	 */
	if (R_DEBUG&RDEBUG_REFRACT) bu_log("rr_refract: refracted.  ri1=%g ri2=%g beta=%g\n",
					   ri_1, ri_2, beta);
	beta = -sqrt(1.0 - beta) - VDOT(w, norml);
	VSCALE(u, norml, beta);
	VADD2(v_2, w, u);
	return 1;		/* refracted */
    }
    /* NOTREACHED */
}
Ejemplo n.º 9
0
/**
 * Calculate a bounding RPP for an ARBN
 */
int
rt_arbn_bbox(struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *UNUSED(tol)) {
    size_t i, j, k;
    struct rt_arbn_internal *aip;
    RT_CK_DB_INTERNAL(ip);
    aip = (struct rt_arbn_internal *)ip->idb_ptr;
    RT_ARBN_CK_MAGIC(aip);

    VSETALL((*min), INFINITY);
    VSETALL((*max), -INFINITY);

    /* Discover all vertices, use to calculate RPP */
    for (i = 0; i < aip->neqn-2; i++) {
	for (j = i+1; j < aip->neqn-1; j++) {
	    double dot;

	    /* If normals are parallel, no intersection */
	    dot = VDOT(aip->eqn[i], aip->eqn[j]);
	    if (((dot) <= -SMALL_FASTF) ? (NEAR_EQUAL((dot), -1.0,  RT_DOT_TOL)) : (NEAR_EQUAL((dot), 1.0, RT_DOT_TOL))) continue;

	    /* Have an edge line, isect with higher numbered planes */
	    for (k = j + 1; k < aip->neqn; k++) {
		size_t m;
		size_t next_k;
		point_t pt;

		next_k = 0;

		if (bn_mkpoint_3planes(pt, aip->eqn[i], aip->eqn[j], aip->eqn[k]) < 0) continue;

		/* See if point is outside arb */
		for (m = 0; m < aip->neqn; m++) {
		    if (i == m || j == m || k == m)
			continue;
		    if (VDOT(pt, aip->eqn[m])-aip->eqn[m][3] > RT_LEN_TOL) {
			next_k = 1;
			break;
		    }
		}
		if (next_k != 0) continue;

		VMINMAX((*min), (*max), pt);
	    }
	}
    }

    return 0;
}
Ejemplo n.º 10
0
/**
 * Make sure that the lu and fu orientation flags are consistent with
 * the geometric arrangement of the vertices and the faceuse normal.
 */
void
nmg_ck_lu_orientation(struct loopuse *lu, const struct bn_tol *tolp)
{
    struct faceuse *fu;
    plane_t fu_peqn;
    plane_t lu_peqn;
    fastf_t dot;

    NMG_CK_LOOPUSE(lu);
    fu = lu->up.fu_p;		/* parent had better be faceuse */
    NMG_CK_FACEUSE(fu);

    NMG_GET_FU_PLANE(fu_peqn, fu);
    nmg_loop_plane_newell(lu, lu_peqn);

    dot = VDOT(fu_peqn, lu_peqn);

    if (NEAR_ZERO(dot, tolp->perp))
	return;		/* can't determine geometric orientation */


    if (dot < 0.0) {
	bu_log("nmg_ck_lu_orientation() lu=%p, dot=%g, fu_orient=%s, lu_orient=%s\n",
	       (void *)lu, dot,
	       nmg_orientation(fu->orientation),
	       nmg_orientation(lu->orientation)
	    );
	bu_bomb("nmg_ck_lu_orientation() loop orientation flags do not match geometry\n");
    }
}
Ejemplo n.º 11
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));
}
Ejemplo n.º 12
0
void
rt_arbn_volume(fastf_t *volume, 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;

    *volume = 0.0;
    /* allocate array of face structs */
    faces = (struct poly_face *)bu_calloc(aip->neqn, sizeof(struct poly_face), "rt_arbn_volume: 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_volume: pts");
    }
    rt_arbn_faces_area(faces, aip);
    for (i = 0; i < aip->neqn; i++) {
	vect_t tmp;

	/* calculate volume of pyramid */
	VSCALE(tmp, faces[i].plane_eqn, faces[i].area);
	*volume += VDOT(faces[i].pts[0], tmp)/3;
    }
    for (i = 0; i < aip->neqn; i++) {
	bu_free((char *)faces[i].pts, "rt_arbn_volume: pts");
    }
    bu_free((char *)faces, "rt_arbn_volume: faces");
}
Ejemplo n.º 13
0
static void cylinder_normal(cylinder * cyl, vector * pnt, ray * incident, vector * N) {
  vector a,b,c;
  flt t;

  VSub((vector *) pnt, &(cyl->ctr), &a);

  c=cyl->axis;

  VNorm(&c);
 
  VDOT(t, a, c);

  b.x = c.x * t + cyl->ctr.x; 
  b.y = c.y * t + cyl->ctr.y;
  b.z = c.z * t + cyl->ctr.z;

  VSub(pnt, &b, N); 
  VNorm(N);

  if (VDot(N, &(incident->d)) > 0.0)  { /* make cylinder double sided */
    N->x=-N->x;
    N->y=-N->y;
    N->z=-N->z;
  } 
}
Ejemplo n.º 14
0
/*
    computePlaneEq--takes as input a pointer 'polygon' to an
    arbitrary 3D polygon and returns in 'plane' the normalized
    (unit normal) plane equation of the polygon.
    Newell's method (see "Newell's Method for Computing the Plane
    Equation of a Polygon" in this volume) is used for the
    computation.
*/
static void computePlaneEq(Polygon* polygon, Plane plane)
{
    int i;
    Point refpt;
    Normal normal;
    float *u, *v, len;

    /* first, compute the normal of the input polygon */
    VZERO(normal);
    VZERO(refpt);
    for(i = 0; i < polygon->numVertices; i++) {
        u = polygon->vertices[i];
        v = polygon->vertices[(i + 1) % polygon->numVertices];
        normal[X] += (u[Y] - v[Y]) * (u[Z] + v[Z]);
        normal[Y] += (u[Z] - v[Z]) * (u[X] + v[X]);
        normal[Z] += (u[X] - v[X]) * (u[Y] + v[Y]);
        VINCR(refpt, u);
    }
    /* then, compute the normalized plane equation using the
       arithmetic average of the vertices of the input polygon to
       determine its last coefficient. Note that, for efficiency,
       'refpt' stores the sum of the vertices rather than the
       actual average; the division by 'polygon->numVertices' is
       carried out together with the normalization when computing
       'plane[D]'.
    */
    len = VNORM(normal);
    plane[X] = normal[X] / len;
    plane[Y] = normal[Y] / len;
    plane[Z] = normal[Z] / len;
    len *= polygon->numVertices;
    plane[D] = -VDOT(refpt, normal) / len;
}
Ejemplo n.º 15
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 ) );
}
Ejemplo n.º 16
0
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);
}
Ejemplo n.º 17
0
static void cylinder_normal(const cylinder * cyl, const vector * pnt, const ray * incident, vector * N) {
  vector a, b;
  flt t, invlen, invlen2;

  a.x = pnt->x - cyl->ctr.x;
  a.y = pnt->y - cyl->ctr.y;
  a.z = pnt->z - cyl->ctr.z;

  b=cyl->axis;

  invlen = 1.0 / SQRT(b.x*b.x + b.y*b.y + b.z*b.z);
  b.x *= invlen;
  b.y *= invlen;
  b.z *= invlen;
 
  VDOT(t, a, b);

  N->x = pnt->x - (b.x * t + cyl->ctr.x); 
  N->y = pnt->y - (b.y * t + cyl->ctr.y);
  N->z = pnt->z - (b.z * t + cyl->ctr.z);

  invlen2 = 1.0 / SQRT(N->x*N->x + N->y*N->y + N->z*N->z);
  N->x *= invlen2;
  N->y *= invlen2;
  N->z *= invlen2;

  /* Flip surface normal to point toward the viewer if necessary */
  if (VDot(N, &(incident->d)) > 0.0)  {
    N->x=-N->x;
    N->y=-N->y;
    N->z=-N->z;
  }
}
Ejemplo n.º 18
0
R8 SetCentroid( const IX nv, VERTEX3D *vs, VERTEX3D *ctd )
/* nv  - number of vertices of surface.
 * vs  - coordinates of vertices.
 * ctd - coordinates of centroid.
 */
  {
  VECTOR3D v;
  R8 r2, rr=0.0;
  IX j;

  ctd->x = ctd->y = ctd->z = 0.0;
  for( j=0; j<nv; j++ )
    {
    ctd->x += vs[j].x;
    ctd->y += vs[j].y;
    ctd->z += vs[j].z;
    }
  ctd->x /= (R8)nv;
  ctd->y /= (R8)nv;
  ctd->z /= (R8)nv;

  for( j=0; j<nv; j++ )
    {
    VECTOR( ctd, (vs+j), (&v) );
    r2 = VDOT( (&v), (&v) );
    if( r2 > rr ) rr = r2;
    }

  return sqrt( rr );

  }  /* end of SetCentroid */
Ejemplo n.º 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 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 );
}
Ejemplo n.º 20
0
/*
 * This is called (from viewshade() in shade.c) once for each hit point
 * to be shaded.  The purpose here is to fill in values in the shadework
 * structure.
 */
int
toon_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
{
    int i;
    struct toon_specific *toon_sp = (struct toon_specific *)dp;
    struct light_specific *lp;
    fastf_t cosi, scale;

    /* check the validity of the arguments we got */
    RT_AP_CHECK(ap);
    RT_CHECK_PT(pp);
    CK_TOON_SP(toon_sp);

    if (rdebug&RDEBUG_SHADE)
	bu_struct_print("toon_render Parameters:", toon_print_tab, (char *)toon_sp);

    /* if surface normal is nearly orthogonal to the ray, make a black line */
    if (VDOT(swp->sw_hit.hit_normal, ap->a_inv_dir) >= 0.8) {
	VSETALL(swp->sw_color, 0);
	return 1;
    }

    /* probably need to set some swp values here to avoid the infinite recursion
     * if specified lights exist. */
    light_obs(ap, swp, MFI_HIT);

    /* Consider effects of each light source */
    for (i=ap->a_rt_i->rti_nlights-1; i>=0; i--) {
	if ((lp = (struct light_specific *)swp->sw_visible[i]) == LIGHT_NULL)
	    continue;

	cosi = VDOT(swp->sw_hit.hit_normal, swp->sw_tolight);
	if (cosi <= 0.0) scale = 0.0;
	else if (cosi <= 0.5) scale = 0.5;
	else if (cosi <= 0.8) scale = 0.8;
	else scale = 1.0;
	VSCALE(swp->sw_color, swp->sw_color, scale);
	return 1;
    }

    /* no paths to light source, so just paint it black */
    VSETALL(swp->sw_color, 0);

    if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
	(void)rr_render(ap, pp, swp);
    return 1;
}
Ejemplo n.º 21
0
/**
 * Given two edgeuses with different edge geometry but
 * running between the same two vertices,
 * select the proper edge geometry to associate with.
 *
 * Really, there are 3 geometries to be compared here:
 * the vector between the two endpoints of this edge,
 * and the two edge_g structures.
 * Rather than always taking eu2 or eu1,
 * select the one that best fits this one edge.
 *
 * Consider fu1:
 *		         B
 *		         *
 *		        /|
 *		    eg2/ |
 *		      /  |
 *		    D/   |
 *		    *    |
 *		   /     |
 *		A *-*----* C
 *		    E eg1
 *
 * At the start of a face/face intersection, eg1 runs from A to C,
 * and eg2 runs ADB.  The line of intersection with the other face
 * (fu2, not drawn) lies along eg1.
 * Assume that edge AC needs to be broken at E,
 * where E is just a little more than tol->dist away from A.
 * Existing point D is found because it *is* within tol->dist of E,
 * thanks to the cosine of angle BAC.
 * So, edge AC is broken on vertex D, and the intersection list
 * contains vertexuses A, E, and C.
 *
 * Because D and E are the same point, fu1 has become a triangle with
 * a little "spike" on the end.  If this is handled simply by re-homing
 * edge AE to eg2, it may cause trouble, because eg1 now runs EC,
 * but the geometry for eg1 runs AC.  If there are other vertices on
 * edge eg1, the problem can not be resolved simply by recomputing the
 * geometry of eg1.
 * Since E (D) is within tolerance of eg1, it is not unreasonable
 * just to leave eg1 alone.
 *
 * The issue boils down to selecting whether the existing eg1 or eg2
 * best represents the direction of the little stub edge AD (shared with AE).
 * In this case, eg2 is the correct choice, as AD (and AE) lie on line AB.
 *
 * It would be disastrous to force *all* of eg1 to use the edge geometry
 * of eg2, as the two lines are very different.
 */
struct edge_g_lseg *
nmg_pick_best_edge_g(struct edgeuse *eu1, struct edgeuse *eu2, const struct bn_tol *tol)
{
    NMG_CK_EDGEUSE(eu1);
    NMG_CK_EDGEUSE(eu2);
    BN_CK_TOL(tol);

    NMG_CK_EDGE_G_LSEG(eu1->g.lseg_p);
    NMG_CK_EDGE_G_LSEG(eu2->g.lseg_p);
    if (eu2->g.lseg_p != eu1->g.lseg_p) {
	vect_t dir;
	vect_t dir_2;
	vect_t dir_1;
	fastf_t dot_2;
	fastf_t dot_1;

	VSUB2(dir, eu1->vu_p->v_p->vg_p->coord, eu1->eumate_p->vu_p->v_p->vg_p->coord);
	VUNITIZE(dir);
	VMOVE(dir_2, eu2->g.lseg_p->e_dir);
	VUNITIZE(dir_2);
	VMOVE(dir_1, eu1->g.lseg_p->e_dir);
	VUNITIZE(dir_1);

	dot_2 = fabs(VDOT(dir, dir_2));
	dot_1 = fabs(VDOT(dir, dir_1));

	/* Dot product of 1 means colinear.  Take largest dot. */
	if (dot_2 > dot_1) {
	    if (RTG.NMG_debug & DEBUG_BASIC) {
		bu_log("nmg_pick_best_edge_g() Make eu1 use geometry of eu2, s.d=%g, d.d=%g\n",
		       acos(dot_2)*RAD2DEG,
		       acos(dot_1)*RAD2DEG);
	    }
	    return eu2->g.lseg_p;
	} else {
	    if (RTG.NMG_debug & DEBUG_BASIC) {
		bu_log("nmg_pick_best_edge_g() Make eu2 use geometry of eu1, s.d=%g, d.d=%g\n",
		       acos(dot_2)*RAD2DEG,
		       acos(dot_1)*RAD2DEG);
	    }
	    return eu1->g.lseg_p;
	}
    }
    return eu1->g.lseg_p;	/* both the same */
}
Ejemplo n.º 22
0
int
coplanar_3d_to_2d(point2d_t **points_2d, const point_t *origin_pnt,
		     const vect_t *u_axis, const vect_t *v_axis,
		     const point_t *points_3d, int n)
{
    int i = 0;
    for (i = 0; i < n; i++) {
	vect_t temp, c, d;
	fastf_t u, v;
	VSUB2(temp, points_3d[i], *origin_pnt);
	VPROJECT(temp, *u_axis, c, d);
	u = (VDOT(c, *u_axis) > 0.0) ? (MAGNITUDE(c)) : (-1.0 * MAGNITUDE(c));
	v = (VDOT(d, *v_axis) > 0.0) ? (MAGNITUDE(d)) : (-1.0 * MAGNITUDE(d));
	V2SET((*points_2d)[i], u, v);
    }

    return 0;
}
Ejemplo n.º 23
0
int
bn_mat_ck(const char *title, const mat_t m)
{
    vect_t A, B, C;
    fastf_t fx, fy, fz;

    if (!m) {
	return 0;    /* implies identity matrix */
    }

    /* Validate that matrix preserves perpendicularity of axis by
     * checking that A.B == 0, B.C == 0, A.C == 0 XXX these vectors
     * should just be grabbed out of the matrix
     */
    VMOVE(A, &m[0]);
    VMOVE(B, &m[4]);
    VMOVE(C, &m[8]);

    fx = VDOT(A, B);
    fy = VDOT(B, C);
    fz = VDOT(A, C);

    /* NOTE: this tolerance cannot be any more tight than 0.00001 due
     * to default calculation tolerancing used by models.  Matrices
     * exported to disk outside of tolerance will fail import if
     * set too restrictive.
     */
    if (!NEAR_ZERO(fx, 0.00001)
	|| !NEAR_ZERO(fy, 0.00001)
	|| !NEAR_ZERO(fz, 0.00001)
	|| NEAR_ZERO(m[15], VDIVIDE_TOL)) {
	if (bu_debug & BU_DEBUG_MATH) {
	    bu_log("bn_mat_ck(%s):  bad matrix, does not preserve axis perpendicularity.\n  X.Y=%g, Y.Z=%g, X.Z=%g, s=%g\n", title, fx, fy, fz, m[15]);
	    bn_mat_print("bn_mat_ck() bad matrix", m);
	}

	if (bu_debug & (BU_DEBUG_MATH | BU_DEBUG_COREDUMP)) {
	    bu_debug |= BU_DEBUG_COREDUMP;
	    bu_bomb("bn_mat_ck() bad matrix\n");
	}
	return -1;	/* FAIL */
    }
    return 0;		/* OK */
}
int
rt_gen_elliptical_grid(struct xrays *rays, const struct xray *center_ray, const fastf_t *avec, const fastf_t *bvec, fastf_t gridsize)
{
    register struct xrays *xrayp;
    int count = 0;
    point_t C;
    vect_t dir;
    vect_t a_dir;
    vect_t b_dir;

    fastf_t a = MAGNITUDE(avec);
    fastf_t b = MAGNITUDE(bvec);
    fastf_t x, y;

    int acpr = a / gridsize;
    int bcpr = b / gridsize;

    VMOVE(a_dir, avec);
    VUNITIZE(a_dir);

    VMOVE(b_dir, bvec);
    VUNITIZE(b_dir);

    VMOVE(C, center_ray->r_pt);
    VMOVE(dir, center_ray->r_dir);
    /* make sure avec perpendicular to bvec perpendicular to ray direction */
    BU_ASSERT(NEAR_ZERO(VDOT(avec, bvec), VUNITIZE_TOL));
    BU_ASSERT(NEAR_ZERO(VDOT(avec, dir), VUNITIZE_TOL));

    for (y=gridsize * (-bcpr); y <= b; y=y+gridsize) {
	for (x= gridsize * (-acpr); x <= a; x=x+gridsize) {
	    if (((x*x)/(a*a) + (y*y)/(b*b)) < 1) {
		BU_ALLOC(xrayp, struct xrays);
		VJOIN2(xrayp->ray.r_pt, C, x, a_dir, y, b_dir);
		VMOVE(xrayp->ray.r_dir, dir);
		xrayp->ray.index = count++;
		xrayp->ray.magic = RT_RAY_MAGIC;
		BU_LIST_APPEND(&rays->l, &xrayp->l);
	    }
	}
    }
    return count;
}
Ejemplo n.º 25
0
R8 V1AIpart( const IX nv, const VERTEX3D p2[],
           const VERTEX3D *p1, const DIRCOS *u1 )
/*  nv   number of vertices/edges of surface (polygon) P2
 *  p2   coordinates of vertices of surface (polygon) P2
 *  p1   coordinates of surface (point) P1
 *  u1   components of unit vector normal to surface P1 */
  {
  IX n;  /* edge number */
  VECTOR3D A,  /* A = vector from P1 to P2[n-1]; |A| > 0 */
           B,  /* B = vector from P1 to P2[n]; |B| > 0 */
           C;  /* C = vector cross product of A and B */
  R8 UdotC; /* dot product of U and C; always >= 0 */
  R8 sum=0; /* sum of line integrals */

                            /* Initialization */
  n = nv - 1;
  VECTOR( p1, (p2+n), (&B) );           /* vector B */
                            /* For all edges of polygon p2: */
  for( n=0; n<nv; n++ )
    {
    VCOPY( (&B), (&A) );                /* A = old B */
    VECTOR( p1, (p2+n), (&B) );         /* vector B */
    VCROSS( (&A), (&B), (&C) );         /* C = A cross B */
    UdotC = VDOT( u1, (&C) );           /* U dot C */
    if( fabs(UdotC) > EPS2 )
      {
      R8 Clen = VLEN( (&C) );           /* | C | */
      if( Clen > EPS2 )
        {   /* gamma = angle between A and B; 0 < gamma < 180 */
        R8 gamma = PId2 - atan( VDOT( (&A), (&B) ) / Clen );
        sum += UdotC * gamma / Clen;
        }
      else
        error( 3, __FILE__, __LINE__, "View1AI failed, call George", "" );
      }
    }  /* end edge loop */

  sum *= PIt2inv;                 /* Divide by 2*pi */

  return sum;

  }  /* end of V1AIpart
Ejemplo n.º 26
0
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));
}
Ejemplo n.º 27
0
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");
}
Ejemplo n.º 28
0
void
bn_aet_vec(
    fastf_t *az,
    fastf_t *el,
    fastf_t *twist,
    fastf_t *vec_ae,
    fastf_t *vec_twist,
    fastf_t accuracy)
{
    vect_t zero_twist, ninety_twist;
    vect_t z_dir;

    /* Get az and el as usual */
    bn_ae_vec(az, el, vec_ae);

    /* stabilize fluctuation between 0 and 360
     * change azimuth near 360 to 0 */
    if (NEAR_EQUAL(*az, 360.0, accuracy)) {
	*az = 0.0;
    }

    /* if elevation is +/-90 set twist to zero and calculate azimuth */
    if (NEAR_EQUAL(*el, 90.0, accuracy) || NEAR_ZERO(*el + 90.0, accuracy)) {
	*twist = 0.0;
	*az = bn_atan2(-vec_twist[X], vec_twist[Y]) * RAD2DEG;
    } else {
	/* Calculate twist from vec_twist */
	VSET(z_dir, 0, 0, 1);
	VCROSS(zero_twist, z_dir, vec_ae);
	VUNITIZE(zero_twist);
	VCROSS(ninety_twist, vec_ae, zero_twist);
	VUNITIZE(ninety_twist);

	*twist = bn_atan2(VDOT(vec_twist, ninety_twist), VDOT(vec_twist, zero_twist)) * RAD2DEG;

	/* stabilize flutter between +/- 180 */
	if (NEAR_EQUAL(*twist, -180.0, accuracy)) {
	    *twist = 180.0;
	}
    }
}
Ejemplo n.º 29
0
static void sphere_intersect(sphere * spr, ray * ry) {
  flt b, disc, t1, t2, temp;
  vector V;

  VSUB(spr->ctr, ry->o, V);
  VDOT(b, V, ry->d); 
  VDOT(temp, V, V);  

  disc=b*b + spr->rad*spr->rad - temp;

  if (disc<=0.0) return;
  disc=sqrt(disc);

  t2=b+disc;
  if (t2 <= SPEPSILON) 
    return;
  add_intersection(t2, (object *) spr, ry);  

  t1=b-disc;
  if (t1 > SPEPSILON) 
    add_intersection(t1, (object *) spr, ry);  
}
Ejemplo n.º 30
0
void
paintSpallFb(struct application *ap)
{
    unsigned char pixel[3];
    int x, y;
    int err;
    fastf_t celldist;
#if DEBUG_SPALLFB
    brst_log("paintSpallFb: a_x=%d a_y=%d a_cumlen=%g cellsz=%g zoom=%d\n",
	     ap->a_x, ap->a_y, ap->a_cumlen, cellsz, zoom);
#endif
    pixel[RED] = ap->a_color[RED] * 255;
    pixel[GRN] = ap->a_color[GRN] * 255;
    pixel[BLU] = ap->a_color[BLU] * 255;
    gridToFb(ap->a_x, ap->a_y, &x, &y);
    CenterCell(x);	/* center of cell */
    CenterCell(y);
    celldist = ap->a_cumlen/cellsz * zoom;
    x = roundToInt(x + VDOT(ap->a_ray.r_dir, gridhor) * celldist);
    y = roundToInt(y + VDOT(ap->a_ray.r_dir, gridver) * celldist);
    bu_semaphore_acquire(RT_SEM_STATS);
    err = fb_write(fbiop, x, y, pixel, 1);
    bu_semaphore_release(RT_SEM_STATS);
#if DEBUG_SPALLFB
    brst_log("paintSpallFb:gridhor=<%g, %g, %g> gridver=<%g, %g, %g>\n",
	     gridhor[X], gridhor[Y], gridhor[Z],
	     gridver[X], gridver[Y], gridver[Z]);
    brst_log("paintSpallFb:fb_write(x=%d, y=%d, pixel={%d, %d, %d})\n",
	     x, y,
	     (int) pixel[RED],
	     (int) pixel[GRN],
	     (int) pixel[BLU]
	);
#endif
    if (err == -1)
	brst_log("Write failed to pixel <%d, %d> from cell <%d, %d>.\n",
		 x, y, ap->a_x, ap->a_y);
    return;
}