📄 mapdesc.cc
字号:
* or intersecting the viewing frustrum.
*--------------------------------------------------------------------------
*/
int
Mapdesc::cullCheck( REAL *pts, int order, int stride )
{
unsigned int inbits = mask;
unsigned int outbits = 0;
REAL *p = pts;
for( REAL *pend = p + order * stride; p != pend; p += stride ) {
unsigned int bits = clipbits( p );
outbits |= bits;
inbits &= bits;
if( ( outbits == (unsigned int)mask ) && ( inbits != (unsigned int)mask ) ) return CULL_ACCEPT;
}
if( outbits != (unsigned int)mask ) {
return CULL_TRIVIAL_REJECT;
} else if( inbits == (unsigned int)mask ) {
return CULL_TRIVIAL_ACCEPT;
} else {
return CULL_ACCEPT;
}
}
/*--------------------------------------------------------------------------
* xformSampling - transform a set of points that may be EITHER
* homogeneous or inhomogeneous depending on the map description
* into sampling space
*--------------------------------------------------------------------------
*/
void
Mapdesc::xformSampling( REAL *pts, int order, int stride, REAL *sp, int outstride )
{
xformMat( smat, pts, order, stride, sp, outstride );
}
void
Mapdesc::xformBounding( REAL *pts, int order, int stride, REAL *sp, int outstride )
{
xformMat( bmat, pts, order, stride, sp, outstride );
}
/*--------------------------------------------------------------------------
* xformCulling - transform a set of points that may be EITHER
* homogeneous or inhomogeneous depending on the map description
* into culling space
*--------------------------------------------------------------------------
*/
void
Mapdesc::xformCulling( REAL *pts, int order, int stride, REAL *cp, int outstride )
{
xformMat( cmat, pts, order, stride, cp, outstride );
}
/*--------------------------------------------------------------------------
* xformCulling - transform a set of points that may be EITHER
* homogeneous or inhomogeneous depending on the map description
* into culling space
*--------------------------------------------------------------------------
*/
void
Mapdesc::xformCulling( REAL *pts,
int uorder, int ustride,
int vorder, int vstride,
REAL *cp, int outustride, int outvstride )
{
xformMat( cmat, pts, uorder, ustride, vorder, vstride, cp, outustride, outvstride );
}
/*--------------------------------------------------------------------------
* xformSampling - transform a set of points that may be EITHER
* homogeneous or inhomogeneous depending on the map description
* into sampling space
*--------------------------------------------------------------------------
*/
void
Mapdesc::xformSampling( REAL *pts,
int uorder, int ustride,
int vorder, int vstride,
REAL *sp, int outustride, int outvstride )
{
xformMat( smat, pts, uorder, ustride, vorder, vstride, sp, outustride, outvstride );
}
void
Mapdesc::xformBounding( REAL *pts,
int uorder, int ustride,
int vorder, int vstride,
REAL *sp, int outustride, int outvstride )
{
xformMat( bmat, pts, uorder, ustride, vorder, vstride, sp, outustride, outvstride );
}
void
Mapdesc::xformMat(
Maxmatrix mat,
REAL * pts,
int order,
int stride,
REAL * cp,
int outstride )
{
if( isrational ) {
REAL *pend = pts + order * stride;
for( REAL *p = pts ; p != pend; p += stride ) {
xformRational( mat, cp, p );
cp += outstride;
}
} else {
REAL *pend = pts + order * stride;
for( REAL *p = pts ; p != pend; p += stride ) {
xformNonrational( mat, cp, p );
cp += outstride;
}
}
}
void
Mapdesc::xformMat( Maxmatrix mat, REAL *pts,
int uorder, int ustride,
int vorder, int vstride,
REAL *cp, int outustride, int outvstride )
{
if( isrational ) {
REAL *pend = pts + uorder * ustride;
for( REAL *p = pts ; p != pend; p += ustride ) {
REAL *cpts2 = cp;
REAL *qend = p + vorder * vstride;
for( REAL *q = p; q != qend; q += vstride ) {
xformRational( mat, cpts2, q );
cpts2 += outvstride;
}
cp += outustride;
}
} else {
REAL *pend = pts + uorder * ustride;
for( REAL *p = pts ; p != pend; p += ustride ) {
REAL *cpts2 = cp;
REAL *qend = p + vorder * vstride;
for( REAL *q = p; q != qend; q += vstride ) {
xformNonrational( mat, cpts2, q );
cpts2 += outvstride;
}
cp += outustride;
}
}
}
/*--------------------------------------------------------------------------
* subdivide - subdivide a curve along an isoparametric line
*--------------------------------------------------------------------------
*/
void
Mapdesc::subdivide( REAL *src, REAL *dst, REAL v, int stride, int order )
{
REAL mv = 1.0 - v;
for( REAL *send=src+stride*order; src!=send; send-=stride, dst+=stride ) {
copyPt( dst, src );
REAL *qpnt = src + stride;
for( REAL *qp=src; qpnt!=send; qp=qpnt, qpnt+=stride )
sumPt( qp, qp, qpnt, mv, v );
}
}
/*--------------------------------------------------------------------------
* subdivide - subdivide a patch along an isoparametric line
*--------------------------------------------------------------------------
*/
void
Mapdesc::subdivide( REAL *src, REAL *dst, REAL v,
int so, int ss, int to, int ts )
{
REAL mv = 1.0 - v;
for( REAL *slast = src+ss*so; src != slast; src += ss, dst += ss ) {
REAL *sp = src;
REAL *dp = dst;
for( REAL *send = src+ts*to; sp != send; send -= ts, dp += ts ) {
copyPt( dp, sp );
REAL *qp = sp;
for( REAL *qpnt = sp+ts; qpnt != send; qp = qpnt, qpnt += ts )
sumPt( qp, qp, qpnt, mv, v );
}
}
}
#define sign(x) ((x > 0) ? 1 : ((x < 0.0) ? -1 : 0))
/*--------------------------------------------------------------------------
* project - project a set of homogeneous coordinates into inhomogeneous ones
*--------------------------------------------------------------------------
*/
int
Mapdesc::project( REAL *src, int rstride, int cstride,
REAL *dest, int trstride, int tcstride,
int nrows, int ncols )
{
int s = sign( src[inhcoords] );
REAL *rlast = src + nrows * rstride;
REAL *trptr = dest;
for( REAL *rptr=src; rptr != rlast; rptr+=rstride, trptr+=trstride ) {
REAL *clast = rptr + ncols * cstride;
REAL *tcptr = trptr;
for( REAL *cptr = rptr; cptr != clast; cptr+=cstride, tcptr+=tcstride ) {
REAL *coordlast = cptr + inhcoords;
if( sign( *coordlast ) != s ) return 0;
REAL *tcoord = tcptr;
for( REAL *coord = cptr; coord != coordlast; coord++, tcoord++ ) {
*tcoord = *coord / *coordlast;
}
}
}
return 1;
}
/*--------------------------------------------------------------------------
* project - project a set of homogeneous coordinates into inhomogeneous ones
*--------------------------------------------------------------------------
*/
int
Mapdesc::project( REAL *src, int stride, REAL *dest, int tstride, int ncols )
{
int s = sign( src[inhcoords] );
REAL *clast = src + ncols * stride;
for( REAL *cptr = src, *tcptr = dest; cptr != clast; cptr+=stride, tcptr+=tstride ) {
REAL *coordlast = cptr + inhcoords;
if( sign( *coordlast ) != s ) return 0;
for( REAL *coord = cptr, *tcoord = tcptr; coord != coordlast; coord++, tcoord++ )
*tcoord = *coord / *coordlast;
}
return 1;
}
int
Mapdesc::bboxTooBig(
REAL *p,
int rstride,
int cstride,
int nrows,
int ncols,
REAL bb[2][MAXCOORDS] )
{
REAL bbpts[MAXORDER][MAXORDER][MAXCOORDS];
const int trstride = sizeof(bbpts[0]) / sizeof(REAL);
const int tcstride = sizeof(bbpts[0][0]) / sizeof(REAL);
// points have been transformed, therefore they are homogeneous
// project points
int val = project( p, rstride, cstride,
&bbpts[0][0][0], trstride, tcstride, nrows, ncols );
if( val == 0 ) return -1;
// compute bounding box
bbox( bb, &bbpts[0][0][0], trstride, tcstride, nrows, ncols );
// find out if bounding box can't fit in unit cube
if( bbox_subdividing == N_BBOXROUND ) {
for( int k=0; k != inhcoords; k++ )
if( ceilf(bb[1][k]) - floorf(bb[0][k]) > bboxsize[k] ) return 1;
} else {
for( int k=0; k != inhcoords; k++ )
if( bb[1][k] - bb[0][k] > bboxsize[k] ) return 1;
}
return 0;
}
void
Mapdesc::bbox(
REAL bb[2][MAXCOORDS],
REAL *p,
int rstride,
int cstride,
int nrows,
int ncols )
{
int k;
for( k=0; k != inhcoords; k++ )
bb[0][k] = bb[1][k] = p[k];
for( int i=0; i != nrows; i++ )
for( int j=0; j != ncols; j++ )
for( k=0; k != inhcoords; k++ ) {
REAL x = p[i*rstride + j*cstride + k];
if( x < bb[0][k] ) bb[0][k] = x;
else if( x > bb[1][k] ) bb[1][k] = x;
}
}
/*--------------------------------------------------------------------------
* calcVelocityRational - calculate upper bound on first partial derivative
* of a homogeneous set of points and bounds on each row of points.
*--------------------------------------------------------------------------
*/
REAL
Mapdesc::calcVelocityRational( REAL *p, int stride, int ncols )
{
REAL tmp[MAXORDER][MAXCOORDS];
assert( ncols <= MAXORDER );
const int tstride = sizeof(tmp[0]) / sizeof(REAL);
if( project( p, stride, &tmp[0][0], tstride, ncols ) ) {
return calcPartialVelocity( &tmp[0][0], tstride, ncols, 1, 1.0 );
} else { /* XXX */
return calcPartialVelocity( &tmp[0][0], tstride, ncols, 1, 1.0 );
}
}
/*--------------------------------------------------------------------------
* calcVelocityNonrational - calculate upper bound on first partial
* derivative of a inhomogeneous set of points.
*--------------------------------------------------------------------------
*/
REAL
Mapdesc::calcVelocityNonrational( REAL *pts, int stride, int ncols )
{
return calcPartialVelocity( pts, stride, ncols, 1, 1.0 );
}
int
Mapdesc::isProperty( long property )
{
switch ( property ) {
case N_PIXEL_TOLERANCE:
case N_ERROR_TOLERANCE:
case N_CULLING:
case N_BBOX_SUBDIVIDING:
case N_S_STEPS:
case N_T_STEPS:
case N_SAMPLINGMETHOD:
case N_CLAMPFACTOR:
case N_MINSAVINGS:
return 1;
default:
return 0;
}
}
REAL
Mapdesc::getProperty( long property )
{
switch ( property ) {
case N_PIXEL_TOLERANCE:
return pixel_tolerance;
case N_ERROR_TOLERANCE:
return error_tolerance;
case N_CULLING:
return culling_method;
case N_BBOX_SUBDIVIDING:
return bbox_subdividing;
case N_S_STEPS:
return s_steps;
case N_T_STEPS:
return t_steps;
case N_SAMPLINGMETHOD:
return sampling_method;
case N_CLAMPFACTOR:
return clampfactor;
case N_MINSAVINGS:
return minsavings;
default:
abort();
return -1; //not necessary, needed to shut up compiler
}
}
void
Mapdesc::setProperty( long property, REAL value )
{
switch ( property ) {
case N_PIXEL_TOLERANCE:
pixel_tolerance = value;
break;
case N_ERROR_TOLERANCE:
error_tolerance = value;
break;
case N_CULLING:
culling_method = value;
break;
case N_BBOX_SUBDIVIDING:
if( value <= 0.0 ) value = N_NOBBOXSUBDIVISION;
bbox_subdividing = value;
break;
case N_S_STEPS:
if( value < 0.0 ) value = 0.0;
s_steps = value;
maxrate = ( value < 0.0 ) ? 0.0 : value;
maxsrate = ( value < 0.0 ) ? 0.0 : value;
break;
case N_T_STEPS:
if( value < 0.0 ) value = 0.0;
t_steps = value;
maxtrate = ( value < 0.0 ) ? 0.0 : value;
break;
case N_SAMPLINGMETHOD:
sampling_method = value;
break;
case N_CLAMPFACTOR:
if( value <= 0.0 ) value = N_NOCLAMPING;
clampfactor = value;
break;
case N_MINSAVINGS:
if( value <= 0.0 ) value = N_NOSAVINGSSUBDIVISION;
minsavings = value;
break;
default:
abort();
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -