Ejemplo n.º 1
0
/* Find convex hull vertex to complete triangle (oriented call) */
static RBFNODE *
find_chull_vert(const RBFNODE *rbf0, const RBFNODE *rbf1)
{
	FVECT	vmid, vejn, vp;
	RBFNODE	*rbf, *rbfbest = NULL;
	double	dprod, area2, bestarea2 = FHUGE, bestdprod = -.5;

	VSUB(vejn, rbf1->invec, rbf0->invec);
	VADD(vmid, rbf0->invec, rbf1->invec);
	if (normalize(vejn) == 0 || normalize(vmid) == 0)
		return(NULL);
						/* XXX exhaustive search */
	/* Find triangle with minimum rotation from perpendicular */
	for (rbf = dsf_list; rbf != NULL; rbf = rbf->next) {
		if ((rbf == rbf0) | (rbf == rbf1))
			continue;
		tri_orient(vp, rbf0->invec, rbf1->invec, rbf->invec);
		if (DOT(vp, vmid) <= FTINY)
			continue;		/* wrong orientation */
		area2 = .25*DOT(vp,vp);
		VSUB(vp, rbf->invec, vmid);
		dprod = -DOT(vp, vejn);
		VSUM(vp, vp, vejn, dprod);	/* above guarantees non-zero */
		dprod = DOT(vp, vmid) / VLEN(vp);
		if (dprod <= bestdprod + FTINY*(1 - 2*(area2 < bestarea2)))
			continue;		/* found better already */
		if (overlaps_tri(rbf0, rbf1, rbf))
			continue;		/* overlaps another triangle */
		rbfbest = rbf;
		bestdprod = dprod;		/* new one to beat */
		bestarea2 = area2;
	}
	return(rbfbest);
}
Ejemplo n.º 2
0
static int
ambcollision(				/* proposed direciton collides? */
	AMBHEMI	*hp,
	int	i,
	int	j,
	FVECT	dv
)
{
	double	cos_thresh;
	int	ii, jj;
					/* min. spacing = 1/4th division */
	cos_thresh = (PI/4.)/(double)hp->ns;
	cos_thresh = 1. - .5*cos_thresh*cos_thresh;
					/* check existing neighbors */
	for (ii = i-1; ii <= i+1; ii++) {
		if (ii < 0) continue;
		if (ii >= hp->ns) break;
		for (jj = j-1; jj <= j+1; jj++) {
			AMBSAMP	*ap;
			FVECT	avec;
			double	dprod;
			if (jj < 0) continue;
			if (jj >= hp->ns) break;
			if ((ii==i) & (jj==j)) continue;
			ap = &ambsam(hp,ii,jj);
			if (ap->d <= .5/FHUGE)
				continue;	/* no one home */
			VSUB(avec, ap->p, hp->rp->rop);
			dprod = DOT(avec, dv);
			if (dprod >= cos_thresh*VLEN(avec))
				return(1);	/* collision */
		}
	}
	return(0);			/* nothing to worry about */
}
Ejemplo n.º 3
0
Archivo: rbt.c Proyecto: DeadZen/qse
QSE_INLINE void qse_rbt_freepair (rbt_t* rbt, pair_t* pair)
{
	if (rbt->style->freeer[QSE_RBT_KEY] != QSE_NULL)
		rbt->style->freeer[QSE_RBT_KEY] (rbt, KPTR(pair), KLEN(pair));
	if (rbt->style->freeer[QSE_RBT_VAL] != QSE_NULL)
		rbt->style->freeer[QSE_RBT_VAL] (rbt, VPTR(pair), VLEN(pair));
	QSE_MMGR_FREE (rbt->mmgr, pair);
}
Ejemplo n.º 4
0
static void
add_holo(		/* register a new holodeck section */
	HDGRID	*hdg,
	char	*gfn,
	char	*pfn
)
{
	VIEW	nv;
	double	d;
	register int	hd;

	for (hd = 0; hd < HDMAX && hdlist[hd] != NULL; hd++)
		;
	if (hd >= HDMAX)
		error(INTERNAL, "too many holodeck sections in add_holo");
	hdlist[hd] = (HOLO *)malloc(sizeof(HOLO));
	if (hdlist[hd] == NULL)
		error(SYSTEM, "out of memory in add_holo");
	memcpy((void *)hdlist[hd], (void *)hdg, sizeof(HDGRID));
	hdcompgrid(hdlist[hd]);
	hdgfn[hd] = savestr(gfn);
	hdpfn[hd] = pfn && *pfn ? savestr(pfn) : (char *)NULL;
	if (hd)
		return;
					/* set initial viewpoint */
	nv = odev.v;
	VSUM(nv.vp, hdlist[0]->orig, hdlist[0]->xv[0], 0.5);
	VSUM(nv.vp, nv.vp, hdlist[0]->xv[1], 0.5);
	VSUM(nv.vp, nv.vp, hdlist[0]->xv[2], 0.5);
	fcross(nv.vdir, hdlist[0]->xv[1], hdlist[0]->xv[2]);
	VCOPY(nv.vup, hdlist[0]->xv[2]);
	if (do_outside) {
		normalize(nv.vdir);
		d = VLEN(hdlist[0]->xv[1]);
		d += VLEN(hdlist[0]->xv[2]);
		VSUM(nv.vp, nv.vp, nv.vdir, -d);
	}
	new_view(&nv);
}
Ejemplo n.º 5
0
void
hdcompgrid(			/* compute derived grid vector and index */
	HOLO	*hp
)
{
	double	d;
	int	i, j;
				/* initialize depth map */
	if (hd_depthmap[0] < 1.) {
		d = 1. + .5/DCLIN;
		for (i = 0; i < DCINF-DCLIN; i++) {
			hd_depthmap[i] = d;
			d *= 1. + 1./DCLIN;
		}
		logstep = log(1. + 1./DCLIN);
	}
				/* compute grid coordinate vectors */
	for (i = 0; i < 3; i++) {
		fcross(hp->wg[i], hp->xv[(i+1)%3], hp->xv[(i+2)%3]);
		d = DOT(hp->wg[i],hp->xv[i]);
		if ((d <= FTINY) & (d >= -FTINY))
			error(USER, "degenerate holodeck section");
		d = hp->grid[i] / d;
		hp->wg[i][0] *= d; hp->wg[i][1] *= d; hp->wg[i][2] *= d;
	}
				/* compute linear depth range */
	hp->tlin = VLEN(hp->xv[0]) + VLEN(hp->xv[1]) + VLEN(hp->xv[2]);
				/* compute wall super-indices from grid */
	hp->wi[0] = 1;		/**** index values begin at 1 ****/
	for (i = 1; i < 6; i++) {
		hp->wi[i] = 0;
		for (j = i; j < 6; j++)
			hp->wi[i] += hp->grid[hdwg0[j]] * hp->grid[hdwg1[j]];
		hp->wi[i] *= hp->grid[hdwg0[i-1]] * hp->grid[hdwg1[i-1]];
		hp->wi[i] += hp->wi[i-1];
	}
}
Ejemplo n.º 6
0
static double
l_psize(char *nm)		/* compute pixel size in steradians */
{
	static unsigned long	ltick[MAXINP];
	static double	psize[MAXINP];
	FVECT	dir0, org, dirx, diry;
	RREAL	locx[2], locy[2];
	double	d;
	int	fn;
	register int	i;

	d = argument(1);
	if (d <= -0.5 || d >= nfiles+0.5) {
		errno = EDOM;
		return(0.0);
	}
	if (d < 0.5)
		return((double)nfiles);
	fn = d - 0.5;
	if (ltick[fn] != eclock) {		/* need to compute? */
		psize[fn] = 0.0;
		if (input[fn].vw.type == 0)
			errno = EDOM;
		else if (input[fn].vw.type != VT_PAR &&
				funvalue(vray[6], 1, &d) >= -FTINY) {
			for (i = 0; i < 3; i++)
				dir0[i] = funvalue(vray[3+i], 1, &d);
			pix2loc(locx, &input[fn].rs, xscan+1, ymax-1-yscan);
			pix2loc(locy, &input[fn].rs, xscan, ymax-yscan);
			if (viewray(org, dirx, &input[fn].vw,
					locx[0], locx[1]) >= -FTINY &&
					viewray(org, diry, &input[fn].vw,
					locy[0], locy[1]) >= -FTINY) {
						/* approximate solid angle */
				for (i = 0; i < 3; i++) {
					dirx[i] -= dir0[i];
					diry[i] -= dir0[i];
				}
				fcross(dir0, dirx, diry);
				psize[fn] = VLEN(dir0);
			}
		}
		ltick[fn] = eclock;
	}
	return(psize[fn]);
}
Ejemplo n.º 7
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.º 8
0
int
i_cyl(			/* translate a cylinder description */
	int	ac,
	char	**av
)
{
	register C_VERTEX	*v1, *v2;
	FVECT	va;
	double	length, angle;

	if (ac != 4)
		return(MG_EARGC);
	flush_cache();		/* flush vertex cache */
	printf("%sSeparator {\n", tabs);
	indent(1);
				/* put out current material */
	if (put_material() < 0)
		return(MG_EBADMAT);
				/* get endpoints */
	if (((v1 = c_getvert(av[1])) == NULL) | ((v2 = c_getvert(av[3])) == NULL))
		return(MG_EUNDEF);
				/* get radius */
	if (!isflt(av[2]))
		return(MG_ETYPE);
				/* compute transform */
	va[0] = v2->p[0] - v1->p[0];
	va[1] = v2->p[1] - v1->p[1];
	va[2] = v2->p[2] - v1->p[2];
	length = VLEN(va);
	angle = Acos(va[1]/length);
	printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs,
			.5*(v1->p[0]+v2->p[0]), .5*(v1->p[1]+v2->p[1]),
			.5*(v1->p[2]+v2->p[2]));
	printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs,
			va[2], 0., -va[0], angle);
				/* open-ended */
	printf("%sCylinder { parts SIDES height %13.9g radius %s }\n", tabs,
			length, av[2]);
	indent(0);
	printf("%s}\n", tabs);
	return(MG_OK);
}
Ejemplo n.º 9
0
int
gc_set_config_repl(generic_cache_t *gc, const char *repl)
{
    repl_interface_t *ri;
    int i = 0;

    if (!VLEN(repl_policies)) {
        SIM_log_error(&gc->log, GC_Log_Repl,
                      "Cache has no replacement policies registered.");
        return -1;
    }

    ri = VGET(repl_policies, i);
    while (ri != NULL) {
        if (strcmp(repl, ri->get_name()) == 0) {
            MM_FREE(gc->config.repl_data);
            memcpy(&gc->config.repl_fun, ri, sizeof(*ri));
            gc->config.repl_data =
                gc->config.repl_fun.new_instance(gc);
            gc->config.repl_fun.update_config(
                gc->config.repl_data, gc);
            return 0;
        }
        i++;
        ri = VGET(repl_policies, i);
    }

    SIM_log_info(1, &gc->log, GC_Log_Repl,
                 "replacement: possible values are :");

    i = 0;
    ri = VGET(repl_policies, i);
    while (ri != NULL) {
        SIM_log_info(1, &gc->log, GC_Log_Repl, "   %s",
                     ri->get_name());
        i++;
        ri = VGET(repl_policies, i);
    }
    return -1;
}
Ejemplo n.º 10
0
void HUDPosition(LWViewportInfo *ViewGlobal, int view, LWDVector pos, const LWDVector dir)
{
    int type, ax = 0;
    double Near, Far, norm, z;

    type = ViewGlobal->type(view);
    ViewGlobal->clip(view, &Near, &Far);
    ViewGlobal->pos(view, pos);
    switch(type)
    {
    case LVVIEWT_BACK:
    case LVVIEWT_FRONT:
        ax++; // fallthrough: ax-> 2
    case LVVIEWT_TOP:
    case LVVIEWT_BOTTOM:
        ax++; // fallthrough: ax-> 1
    case LVVIEWT_RIGHT:
    case LVVIEWT_LEFT:
        pos[ax] = 0.5*(Near+Far);
        break;

    case LVVIEWT_PERSPECTIVE:
    case LVVIEWT_LIGHT:
    case LVVIEWT_CAMERA:
        z = HUD_Depth(ViewGlobal, view);
        norm = VLEN(dir);
        if(norm>0)
            norm = 1.0/norm;
        norm *= z;
        VADDS(pos, dir, norm);
        break;
    case LVVIEWT_SCHEMATIC:
    case LVVIEWT_NONE:
    default:
        VCLR(pos);
        break;
    }
}
Ejemplo n.º 11
0
R8 Triangle( VERTEX3D *p1, VERTEX3D *p2, VERTEX3D *p3, void *dc, IX dcflag )
/* p1  - X, Y, & Z coordinates of point P1.
 * p2  - X, Y, & Z coordinates of point P2.
 * p3  - X, Y, & Z coordinates of point P3.
 *  c  - X, Y, & Z components of direction cosines vector "C".
 */
  {
  VECTOR3D a, b, *c=(void *)dc;
  R8 r;  /* length of "C" (= twice the area of triangle P1-P2-P3) */

  VECTOR( p2, p3, (&a) );
  VECTOR( p2, p1, (&b) );
  VCROSS( (&a), (&b), c );
  r = VLEN( c );
  if( dcflag )   /* compute direction cosines */
    {
    if( r <= 1.e-12 )
      {
      fprintf( _ulog, "Vertices:\n" );
      fprintf( _ulog, "  %f  %f  %f\n", p1->x, p1->y, p1->z );
      fprintf( _ulog, "  %f  %f  %f\n", p2->x, p2->y, p2->z );
      fprintf( _ulog, "  %f  %f  %f\n", p3->x, p3->y, p3->z );
      error( 3, __FILE__,  __LINE__,
        "Vertices give invalid area, surface ", IntStr(dcflag), "" );
      }
    c->x /= r;   /* reduce C to unit length */
    c->y /= r;
    c->z /= r;
    }

#ifdef XXX
  fprintf( _ulog, " DC: %f %f %f; A: %f\n", c->x, c->y, c->z, 0.5*r );
#endif

  return (0.5f * r);

  }  /* end of Triangle */
Ejemplo n.º 12
0
void
viewloc(			/* find image location for point */
FVECT  ip,
VIEW  *v,
FVECT  p
)
{
	double  d, d2;
	FVECT  disp;

	VSUB(disp, p, v->vp);

	switch (v->type) {
	case VT_PAR:			/* parallel view */
		ip[2] = DOT(disp,v->vdir) - v->vfore;
		break;
	case VT_PER:			/* perspective view */
		d = DOT(disp,v->vdir);
		ip[2] = VLEN(disp);
		if (d < 0.0) {		/* fold pyramid */
			ip[2] = -ip[2];
			d = -d;
		}
		if (d > FTINY) {
			d = 1.0/d;
			disp[0] *= d;
			disp[1] *= d;
			disp[2] *= d;
		}
		ip[2] *= (1.0 - v->vfore*d);
		break;
	case VT_HEM:			/* hemispherical fisheye */
		d = normalize(disp);
		if (DOT(disp,v->vdir) < 0.0)
			ip[2] = -d;
		else
			ip[2] = d;
		ip[2] -= v->vfore;
		break;
	case VT_CYL:			/* cylindrical panorama */
		d = DOT(disp,v->hvec);
		d2 = DOT(disp,v->vdir);
		ip[0] = 180.0/PI * atan2(d,d2) / v->horiz + 0.5 - v->hoff;
		d = 1.0/sqrt(d*d + d2*d2);
		ip[1] = DOT(disp,v->vvec)*d/v->vn2 + 0.5 - v->voff;
		ip[2] = VLEN(disp);
		ip[2] *= (1.0 - v->vfore*d);
		return;
	case VT_ANG:			/* angular fisheye */
		ip[0] = 0.5 - v->hoff;
		ip[1] = 0.5 - v->voff;
		ip[2] = normalize(disp) - v->vfore;
		d = DOT(disp,v->vdir);
		if (d >= 1.0-FTINY)
			return;
		if (d <= -(1.0-FTINY)) {
			ip[0] += 180.0/v->horiz;
			return;
		}
		d = (180.0/PI)*acos(d) / sqrt(1.0 - d*d);
		ip[0] += DOT(disp,v->hvec)*d/v->horiz;
		ip[1] += DOT(disp,v->vvec)*d/v->vert;
		return;
	case VT_PLS:			/* planispheric fisheye */
		ip[0] = 0.5 - v->hoff;
		ip[1] = 0.5 - v->voff;
		ip[2] = normalize(disp) - v->vfore;
		d = DOT(disp,v->vdir);
		if (d >= 1.0-FTINY)
			return;
		if (d <= -(1.0-FTINY))
			return;		/* really an error */
		ip[0] += DOT(disp,v->hvec)/((1. + d)*sqrt(v->hn2));
		ip[1] += DOT(disp,v->vvec)/((1. + d)*sqrt(v->vn2));
		return;
	}
	ip[0] = DOT(disp,v->hvec)/v->hn2 + 0.5 - v->hoff;
	ip[1] = DOT(disp,v->vvec)/v->vn2 + 0.5 - v->voff;
}
Ejemplo n.º 13
0
IX Subsurface( SRFDAT3X *srf, SRFDAT3X sub[] )
  {
  IX nSubSrf;       /* number of subsurfaces */
  VERTEX3D tmpVrt;  /* temporary vertex */
  VECTOR3D edge[4]; /* quadrilateral edge vectors */
  R8 edgeLength[4]; /* lengths of edges */
  R8 cosAngle[4];   /* cosines of angles */
  IX obtuse=0;      /* identifies obtuse angles */
  IX i, j, k;

  if( srf->shape > 0 )     /* triangle or parallelogram */
    {
    memcpy( sub+0, srf, sizeof(SRFDAT3X) );    /* no subdivision */
    sub[0].nr = 0;
    nSubSrf = 1;
    }
  else if( srf->nv==4 )    /* convex quadrilateral */
    {
    for( j=0,i=1; j<4; j++,i++ )  /* compute edge vectors and lengths */
      {
      i &= 3;   /* equivalent to: if( i==4 ) i = 0; in this context */
      VECTOR( (srf->v+i), (srf->v+j), (edge+j) );
      edgeLength[j] = VLEN( (edge+j) );
      }
    for( k=1,j=0,i=3; j<4; j++,i++,k*=2 )  /* compute corner angles */
      {
      i &= 3;                /* A dot B = |A|*|B|*cos(angle) */
      cosAngle[j] = -VDOT( (edge+j), (edge+i) )
        / ( edgeLength[j] * edgeLength[i] );
      if( cosAngle[j] < 0.0 )  /* angle > 90 if cos(angle) < 0 */
        obtuse += k;
      }
#if( DEBUG > 1 )
    for( j=0; j<4; j++ )
      {
      fprintf( _ulog, " edge %d: (%f %f %f) L %f, C %f (%.3f deg)\n", j+1,
         edge[j].x, edge[j].y, edge[j].z,
         edgeLength[j], cosAngle[j], acos(cosAngle[j])*RTD );
      }
    fprintf( _ulog, " quadrilateral, case %d\n", obtuse );
    fflush( _ulog );
#endif
    switch (obtuse) /* divide based on number and positions of obtuse angles */
      {
      case 0:       /* rectangle */
        memcpy( sub+0, srf, sizeof(SRFDAT3X) );    /* no subdivision */
        sub[0].nr = 0;
        nSubSrf = 1;
        break;
      case 1:       /* only angle 0 is obtuse */
      case 4:       /* only angle 2 is obtuse */
      case 5:       /* angles 0 and 2 are obtuse */
      case 7:       /* angles 0, 1, and 2 are obtuse */
      case 13:      /* angles 0, 2, and 3 are obtuse */
        VCOPY( (srf->v+0), (sub[0].v+0) );
        VCOPY( (srf->v+1), (sub[0].v+1) );
        VCOPY( (srf->v+2), (sub[0].v+2) );
        VCOPY( (srf->v+2), (sub[1].v+0) );
        VCOPY( (srf->v+3), (sub[1].v+1) );
        VCOPY( (srf->v+0), (sub[1].v+2) );
        nSubSrf = 2;
        break;
      case 2:       /* only angle 1 is obtuse */
      case 8:       /* only angle 3 is obtuse */
      case 10:      /* angles 1 and 3 are obtuse */
      case 11:      /* angles 0, 1, and 3 are obtuse */
      case 14:      /* angles 1, 2, and 3 are obtuse */
        VCOPY( (srf->v+1), (sub[0].v+0) );
        VCOPY( (srf->v+2), (sub[0].v+1) );
        VCOPY( (srf->v+3), (sub[0].v+2) );
        VCOPY( (srf->v+3), (sub[1].v+0) );
        VCOPY( (srf->v+0), (sub[1].v+1) );
        VCOPY( (srf->v+1), (sub[1].v+2) );
        nSubSrf = 2;
        break;
      case 3:       /* angles 0 and 1 are obtuse */
        tmpVrt.x = 0.5f * (srf->v[2].x + srf->v[3].x );
        tmpVrt.y = 0.5f * (srf->v[2].y + srf->v[3].y );
        tmpVrt.z = 0.5f * (srf->v[2].z + srf->v[3].z );
        VCOPY( (srf->v+3), (sub[0].v+0) );
        VCOPY( (srf->v+0), (sub[0].v+1) );
        VCOPY(  (&tmpVrt), (sub[0].v+2) );
        VCOPY( (srf->v+0), (sub[1].v+0) );
        VCOPY( (srf->v+1), (sub[1].v+1) );
        VCOPY(  (&tmpVrt), (sub[1].v+2) );
        VCOPY( (srf->v+1), (sub[2].v+0) );
        VCOPY( (srf->v+2), (sub[2].v+1) );
        VCOPY(  (&tmpVrt), (sub[2].v+2) );
        nSubSrf = 3;
        break;
      case 6:       /* angles 1 and 2 are obtuse */
        tmpVrt.x = 0.5f * (srf->v[0].x + srf->v[3].x );
        tmpVrt.y = 0.5f * (srf->v[0].y + srf->v[3].y );
        tmpVrt.z = 0.5f * (srf->v[0].z + srf->v[3].z );
        VCOPY( (srf->v+0), (sub[0].v+0) );
        VCOPY( (srf->v+1), (sub[0].v+1) );
        VCOPY(  (&tmpVrt), (sub[0].v+2) );
        VCOPY( (srf->v+1), (sub[1].v+0) );
        VCOPY( (srf->v+2), (sub[1].v+1) );
        VCOPY(  (&tmpVrt), (sub[1].v+2) );
        VCOPY( (srf->v+2), (sub[2].v+0) );
        VCOPY( (srf->v+3), (sub[2].v+1) );
        VCOPY(  (&tmpVrt), (sub[2].v+2) );
        nSubSrf = 3;
        break;
      case 9:       /* angles 0 and 3 are obtuse */
        tmpVrt.x = 0.5f * (srf->v[1].x + srf->v[2].x );
        tmpVrt.y = 0.5f * (srf->v[1].y + srf->v[2].y );
        tmpVrt.z = 0.5f * (srf->v[1].z + srf->v[2].z );
        VCOPY( (srf->v+2), (sub[0].v+0) );
        VCOPY( (srf->v+3), (sub[0].v+1) );
        VCOPY(  (&tmpVrt), (sub[0].v+2) );
        VCOPY( (srf->v+3), (sub[1].v+0) );
        VCOPY( (srf->v+0), (sub[1].v+1) );
        VCOPY(  (&tmpVrt), (sub[1].v+2) );
        VCOPY( (srf->v+0), (sub[2].v+0) );
        VCOPY( (srf->v+1), (sub[2].v+1) );
        VCOPY(  (&tmpVrt), (sub[2].v+2) );
        nSubSrf = 3;
        break;
      case 12:      /* angles 2 and 3 are obtuse */
        tmpVrt.x = 0.5f * (srf->v[0].x + srf->v[1].x );
        tmpVrt.y = 0.5f * (srf->v[0].y + srf->v[1].y );
        tmpVrt.z = 0.5f * (srf->v[0].z + srf->v[1].z );
        VCOPY( (srf->v+1), (sub[0].v+0) );
        VCOPY( (srf->v+2), (sub[0].v+1) );
        VCOPY(  (&tmpVrt), (sub[0].v+2) );
        VCOPY( (srf->v+2), (sub[1].v+0) );
        VCOPY( (srf->v+3), (sub[1].v+1) );
        VCOPY(  (&tmpVrt), (sub[1].v+2) );
        VCOPY( (srf->v+3), (sub[2].v+0) );
        VCOPY( (srf->v+0), (sub[2].v+1) );
        VCOPY(  (&tmpVrt), (sub[2].v+2) );
        nSubSrf = 3;
        break;
      case 15:      /* invalid configuration */
        error( 2, __FILE__, __LINE__, "Invalid configuration", "" );
        break;
      default:
        error( 2, __FILE__, __LINE__, "Invalid switch: ", IntStr(obtuse), "" );
      } /* end switch */
    if( obtuse > 0 )    /* complete subdivision data */
      for( j=0; j<nSubSrf; j++ )
        {
        sub[j].nr = j;
        sub[j].nv = 3;
        SetCentroid( 3, sub[j].v, &sub[j].ctd );
        sub[j].area = Triangle( sub[j].v+0, sub[j].v+1, sub[j].v+2, &tmpVrt, 0 );
        memcpy( &sub[j].dc, &srf->dc, sizeof(DIRCOS) );
        }
    }
  else if( srf->nv==5 )
    {
    for( j=0,i=1; j<5; j++,i++ )
      {
      if( i==5 ) i = 0;
      VCOPY( (&srf->ctd), (sub[j].v+0) );
      VCOPY(  (srf->v+j), (sub[j].v+1) );
      VCOPY(  (srf->v+i), (sub[j].v+2) );
      sub[j].nr = j;
      sub[j].nv = 3;
      SetCentroid( 3, sub[j].v, &sub[j].ctd );
      sub[j].area = Triangle( sub[j].v+0, sub[j].v+1, sub[j].v+2, &tmpVrt, 0 );
      memcpy( &sub[j].dc, &srf->dc, sizeof(DIRCOS) );
      }
    nSubSrf = 5;
    }
  else
    error( 3, __FILE__, __LINE__,
      "Invalid number of vertices", IntStr(srf->nv), "" );

  return nSubSrf;

  }  /* end Subsurface */
Ejemplo n.º 14
0
Archivo: rbt.c Proyecto: DeadZen/qse
QSE_INLINE pair_t* qse_rbt_allocpair (
	rbt_t* rbt, void* kptr, size_t klen, void* vptr, size_t vlen)
{
	pair_t* n;

	copier_t kcop = rbt->style->copier[QSE_RBT_KEY];
	copier_t vcop = rbt->style->copier[QSE_RBT_VAL];

	size_t as = SIZEOF(pair_t);
	if (kcop == QSE_RBT_COPIER_INLINE) as += KTOB(rbt,klen);
	if (vcop == QSE_RBT_COPIER_INLINE) as += VTOB(rbt,vlen);

	n = (pair_t*) QSE_MMGR_ALLOC (rbt->mmgr, as);
	if (n == QSE_NULL) return QSE_NULL;

	n->color = QSE_RBT_RED;
	n->parent = QSE_NULL;
	n->child[LEFT] = &rbt->xnil;
	n->child[RIGHT] = &rbt->xnil;

	KLEN(n) = klen;
	if (kcop == QSE_RBT_COPIER_SIMPLE)
	{
		KPTR(n) = kptr;
	}
	else if (kcop == QSE_RBT_COPIER_INLINE)
	{
		KPTR(n) = n + 1;
		if (kptr) QSE_MEMCPY (KPTR(n), kptr, KTOB(rbt,klen));
	}
	else
	{
		KPTR(n) = kcop (rbt, kptr, klen);
		if (KPTR(n) == QSE_NULL)
		{
			QSE_MMGR_FREE (rbt->mmgr, n);
			return QSE_NULL;
		}
	}

	VLEN(n) = vlen;
	if (vcop == QSE_RBT_COPIER_SIMPLE)
	{
		VPTR(n) = vptr;
	}
	else if (vcop == QSE_RBT_COPIER_INLINE)
	{
		VPTR(n) = n + 1;
		if (kcop == QSE_RBT_COPIER_INLINE)
			VPTR(n) = (byte_t*)VPTR(n) + KTOB(rbt,klen);
		if (vptr) QSE_MEMCPY (VPTR(n), vptr, VTOB(rbt,vlen));
	}
	else
	{
		VPTR(n) = vcop (rbt, vptr, vlen);
		if (VPTR(n) != QSE_NULL)
		{
			if (rbt->style->freeer[QSE_RBT_KEY] != QSE_NULL)
				rbt->style->freeer[QSE_RBT_KEY] (rbt, KPTR(n), KLEN(n));
			QSE_MMGR_FREE (rbt->mmgr, n);
			return QSE_NULL;
		}
	}

	return n;
}
Ejemplo n.º 15
0
Archivo: rbt.c Proyecto: DeadZen/qse
static pair_t* change_pair_val (
	rbt_t* rbt, pair_t* pair, void* vptr, size_t vlen)
{
	if (VPTR(pair) == vptr && VLEN(pair) == vlen)
	{
		/* if the old value and the new value are the same,
		 * it just calls the handler for this condition.
		 * No value replacement occurs. */
		if (rbt->style->keeper != QSE_NULL)
		{
			rbt->style->keeper (rbt, vptr, vlen);
		}
	}
	else
	{
		copier_t vcop = rbt->style->copier[QSE_RBT_VAL];
		void* ovptr = VPTR(pair);
		size_t ovlen = VLEN(pair);

		/* place the new value according to the copier */
		if (vcop == QSE_RBT_COPIER_SIMPLE)
		{
			VPTR(pair) = vptr;
			VLEN(pair) = vlen;
		}
		else if (vcop == QSE_RBT_COPIER_INLINE)
		{
			if (ovlen == vlen)
			{
				if (vptr) QSE_MEMCPY (VPTR(pair), vptr, VTOB(rbt,vlen));
			}
			else
			{
				/* need to reconstruct the pair */
				pair_t* p = qse_rbt_allocpair (rbt,
					KPTR(pair), KLEN(pair),
					vptr, vlen);
				if (p == QSE_NULL) return QSE_NULL;

				p->color = pair->color;
				p->left = pair->left;
				p->right = pair->right;
				p->parent = pair->parent;

				if (pair->parent)
				{
					if (pair->parent->left == pair)
					{
						pair->parent->left = p;
					}
					else
					{
						QSE_ASSERT (pair->parent->right == pair);
						pair->parent->right = p;
					}
				}
				if (!IS_NIL(rbt,pair->left)) pair->left->parent = p;
				if (!IS_NIL(rbt,pair->right)) pair->right->parent = p;

				if (pair == rbt->root) rbt->root = p;

				qse_rbt_freepair (rbt, pair);
				return p;
			}
		}
		else
		{
			void* nvptr = vcop (rbt, vptr, vlen);
			if (nvptr == QSE_NULL) return QSE_NULL;
			VPTR(pair) = nvptr;
			VLEN(pair) = vlen;
		}

		/* free up the old value */
		if (rbt->style->freeer[QSE_RBT_VAL] != QSE_NULL)
		{
			rbt->style->freeer[QSE_RBT_VAL] (rbt, ovptr, ovlen);
		}
	}

	return pair;
}