2 ** License Applicability. Except to the extent portions of this file are
3 ** made subject to an alternative license as permitted in the SGI Free
4 ** Software License B, Version 1.1 (the "License"), the contents of this
5 ** file are subject only to the provisions of the License. You may not use
6 ** this file except in compliance with the License. You may obtain a copy
7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10 ** http://oss.sgi.com/projects/FreeB
12 ** Note that, as provided in the License, the Software is distributed on an
13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21 ** Copyright in any portions created by third parties is as indicated
22 ** elsewhere herein. All Rights Reserved.
24 ** Additional Notice Provisions: The application programming interfaces
25 ** established by SGI in conjunction with the Original Code are The
26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31 ** published by SGI, but has not been independently verified as being
32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
41 #include "glimports.h"
49 #include "nurbsconsts.h"
50 #include "simplemath.h" //for glu_abs function in ::singleStep();
53 /*--------------------------------------------------------------------------
54 * Patch - copy patch from quilt and transform control points
55 *--------------------------------------------------------------------------
58 Patch::Patch( Quilt_ptr geo
, REAL
*pta
, REAL
*ptb
, Patch
*n
)
60 /* pspec[i].range is uninit here */
61 mapdesc
= geo
->mapdesc
;
62 cullval
= mapdesc
->isCulling() ? CULL_ACCEPT
: CULL_TRIVIAL_ACCEPT
;
63 notInBbox
= mapdesc
->isBboxSubdividing() ? 1 : 0;
64 needsSampling
= mapdesc
->isRangeSampling() ? 1 : 0;
65 pspec
[0].order
= geo
->qspec
[0].order
;
66 pspec
[1].order
= geo
->qspec
[1].order
;
67 pspec
[0].stride
= pspec
[1].order
* MAXCOORDS
;
68 pspec
[1].stride
= MAXCOORDS
;
70 /* transform control points to sampling and culling spaces */
72 geo
->select( pta
, ptb
);
73 ps
+= geo
->qspec
[0].offset
;
74 ps
+= geo
->qspec
[1].offset
;
75 ps
+= geo
->qspec
[0].index
* geo
->qspec
[0].order
* geo
->qspec
[0].stride
;
76 ps
+= geo
->qspec
[1].index
* geo
->qspec
[1].order
* geo
->qspec
[1].stride
;
79 mapdesc
->xformSampling( ps
, geo
->qspec
[0].order
, geo
->qspec
[0].stride
,
80 geo
->qspec
[1].order
, geo
->qspec
[1].stride
,
81 spts
, pspec
[0].stride
, pspec
[1].stride
);
84 if( cullval
== CULL_ACCEPT
) {
85 mapdesc
->xformCulling( ps
, geo
->qspec
[0].order
, geo
->qspec
[0].stride
,
86 geo
->qspec
[1].order
, geo
->qspec
[1].stride
,
87 cpts
, pspec
[0].stride
, pspec
[1].stride
);
91 mapdesc
->xformBounding( ps
, geo
->qspec
[0].order
, geo
->qspec
[0].stride
,
92 geo
->qspec
[1].order
, geo
->qspec
[1].stride
,
93 bpts
, pspec
[0].stride
, pspec
[1].stride
);
97 pspec
[0].range
[0] = geo
->qspec
[0].breakpoints
[geo
->qspec
[0].index
];
98 pspec
[0].range
[1] = geo
->qspec
[0].breakpoints
[geo
->qspec
[0].index
+1];
99 pspec
[0].range
[2] = pspec
[0].range
[1] - pspec
[0].range
[0];
101 pspec
[1].range
[0] = geo
->qspec
[1].breakpoints
[geo
->qspec
[1].index
];
102 pspec
[1].range
[1] = geo
->qspec
[1].breakpoints
[geo
->qspec
[1].index
+1];
103 pspec
[1].range
[2] = pspec
[1].range
[1] - pspec
[1].range
[0];
105 // may need to subdivide to match range of sub-patch
106 if( pspec
[0].range
[0] != pta
[0] ) {
107 assert( pspec
[0].range
[0] < pta
[0] );
108 Patch
lower( *this, 0, pta
[0], 0 );
112 if( pspec
[0].range
[1] != ptb
[0] ) {
113 assert( pspec
[0].range
[1] > ptb
[0] );
114 Patch
upper( *this, 0, ptb
[0], 0 );
117 if( pspec
[1].range
[0] != pta
[1] ) {
118 assert( pspec
[1].range
[0] < pta
[1] );
119 Patch
lower( *this, 1, pta
[1], 0 );
123 if( pspec
[1].range
[1] != ptb
[1] ) {
124 assert( pspec
[1].range
[1] > ptb
[1] );
125 Patch
upper( *this, 1, ptb
[1], 0 );
127 checkBboxConstraint();
131 /*--------------------------------------------------------------------------
132 * Patch - subdivide a patch along an isoparametric line
133 *--------------------------------------------------------------------------
136 Patch::Patch( Patch
& upper
, int param
, REAL value
, Patch
*n
)
138 Patch
& lower
= *this;
140 lower
.cullval
= upper
.cullval
;
141 lower
.mapdesc
= upper
.mapdesc
;
142 lower
.notInBbox
= upper
.notInBbox
;
143 lower
.needsSampling
= upper
.needsSampling
;
144 lower
.pspec
[0].order
= upper
.pspec
[0].order
;
145 lower
.pspec
[1].order
= upper
.pspec
[1].order
;
146 lower
.pspec
[0].stride
= upper
.pspec
[0].stride
;
147 lower
.pspec
[1].stride
= upper
.pspec
[1].stride
;
150 /* reset scale range */
153 REAL d
= (value
-upper
.pspec
[0].range
[0]) / upper
.pspec
[0].range
[2];
155 mapdesc
->subdivide( upper
.spts
, lower
.spts
, d
, pspec
[1].order
,
156 pspec
[1].stride
, pspec
[0].order
, pspec
[0].stride
);
158 if( cullval
== CULL_ACCEPT
)
159 mapdesc
->subdivide( upper
.cpts
, lower
.cpts
, d
, pspec
[1].order
,
160 pspec
[1].stride
, pspec
[0].order
, pspec
[0].stride
);
163 mapdesc
->subdivide( upper
.bpts
, lower
.bpts
, d
, pspec
[1].order
,
164 pspec
[1].stride
, pspec
[0].order
, pspec
[0].stride
);
166 lower
.pspec
[0].range
[0] = upper
.pspec
[0].range
[0];
167 lower
.pspec
[0].range
[1] = value
;
168 lower
.pspec
[0].range
[2] = value
- upper
.pspec
[0].range
[0];
169 upper
.pspec
[0].range
[0] = value
;
170 upper
.pspec
[0].range
[2] = upper
.pspec
[0].range
[1] - value
;
172 lower
.pspec
[1].range
[0] = upper
.pspec
[1].range
[0];
173 lower
.pspec
[1].range
[1] = upper
.pspec
[1].range
[1];
174 lower
.pspec
[1].range
[2] = upper
.pspec
[1].range
[2];
178 REAL d
= (value
-upper
.pspec
[1].range
[0]) / upper
.pspec
[1].range
[2];
180 mapdesc
->subdivide( upper
.spts
, lower
.spts
, d
, pspec
[0].order
,
181 pspec
[0].stride
, pspec
[1].order
, pspec
[1].stride
);
182 if( cullval
== CULL_ACCEPT
)
183 mapdesc
->subdivide( upper
.cpts
, lower
.cpts
, d
, pspec
[0].order
,
184 pspec
[0].stride
, pspec
[1].order
, pspec
[1].stride
);
186 mapdesc
->subdivide( upper
.bpts
, lower
.bpts
, d
, pspec
[0].order
,
187 pspec
[0].stride
, pspec
[1].order
, pspec
[1].stride
);
188 lower
.pspec
[0].range
[0] = upper
.pspec
[0].range
[0];
189 lower
.pspec
[0].range
[1] = upper
.pspec
[0].range
[1];
190 lower
.pspec
[0].range
[2] = upper
.pspec
[0].range
[2];
192 lower
.pspec
[1].range
[0] = upper
.pspec
[1].range
[0];
193 lower
.pspec
[1].range
[1] = value
;
194 lower
.pspec
[1].range
[2] = value
- upper
.pspec
[1].range
[0];
195 upper
.pspec
[1].range
[0] = value
;
196 upper
.pspec
[1].range
[2] = upper
.pspec
[1].range
[1] - value
;
201 // inherit bounding box
202 if( mapdesc
->isBboxSubdividing() && ! notInBbox
)
203 memcpy( lower
.bb
, upper
.bb
, sizeof( bb
) );
205 lower
.checkBboxConstraint();
206 upper
.checkBboxConstraint();
209 /*--------------------------------------------------------------------------
210 * clamp - clamp the sampling rate to a given maximum
211 *--------------------------------------------------------------------------
217 if( mapdesc
->clampfactor
!= N_NOCLAMPING
) {
218 pspec
[0].clamp( mapdesc
->clampfactor
);
219 pspec
[1].clamp( mapdesc
->clampfactor
);
224 Patchspec::clamp( REAL clampfactor
)
226 if( sidestep
[0] < minstepsize
)
227 sidestep
[0] = clampfactor
* minstepsize
;
228 if( sidestep
[1] < minstepsize
)
229 sidestep
[1] = clampfactor
* minstepsize
;
230 if( stepsize
< minstepsize
)
231 stepsize
= clampfactor
* minstepsize
;
235 Patch::checkBboxConstraint( void )
238 mapdesc
->bboxTooBig( bpts
, pspec
[0].stride
, pspec
[1].stride
,
239 pspec
[0].order
, pspec
[1].order
, bb
) != 1 ) {
247 if( mapdesc
->isBboxSubdividing() )
248 mapdesc
->surfbbox( bb
);
251 /*--------------------------------------------------------------------------
252 * getstepsize - compute the sampling density across the patch
253 * and determine if patch needs to be subdivided
254 *--------------------------------------------------------------------------
258 Patch::getstepsize( void )
260 pspec
[0].minstepsize
= pspec
[1].minstepsize
= 0;
261 pspec
[0].needsSubdivision
= pspec
[1].needsSubdivision
= 0;
263 if( mapdesc
->isConstantSampling() ) {
264 // fixed number of samples per patch in each direction
265 // maxsrate is number of s samples per patch
266 // maxtrate is number of t samples per patch
267 pspec
[0].getstepsize( mapdesc
->maxsrate
);
268 pspec
[1].getstepsize( mapdesc
->maxtrate
);
270 } else if( mapdesc
->isDomainSampling() ) {
271 // maxsrate is number of s samples per unit s length of domain
272 // maxtrate is number of t samples per unit t length of domain
273 pspec
[0].getstepsize( mapdesc
->maxsrate
* pspec
[0].range
[2] );
274 pspec
[1].getstepsize( mapdesc
->maxtrate
* pspec
[1].range
[2] );
276 } else if( ! needsSampling
) {
277 pspec
[0].singleStep();
278 pspec
[1].singleStep();
280 // upper bound on path length between sample points
281 REAL tmp
[MAXORDER
][MAXORDER
][MAXCOORDS
];
282 const int trstride
= sizeof(tmp
[0]) / sizeof(REAL
);
283 const int tcstride
= sizeof(tmp
[0][0]) / sizeof(REAL
);
285 assert( pspec
[0].order
<= MAXORDER
);
287 /* points have been transformed, therefore they are homogeneous */
289 int val
= mapdesc
->project( spts
, pspec
[0].stride
, pspec
[1].stride
,
290 &tmp
[0][0][0], trstride
, tcstride
,
291 pspec
[0].order
, pspec
[1].order
);
293 // control points cross infinity, therefore partials are undefined
294 pspec
[0].getstepsize( mapdesc
->maxsrate
);
295 pspec
[1].getstepsize( mapdesc
->maxtrate
);
297 REAL t1
= mapdesc
->getProperty( N_PIXEL_TOLERANCE
);
298 // REAL t2 = mapdesc->getProperty( N_ERROR_TOLERANCE );
299 pspec
[0].minstepsize
= ( mapdesc
->maxsrate
> 0.0 ) ?
300 (pspec
[0].range
[2] / mapdesc
->maxsrate
) : 0.0;
301 pspec
[1].minstepsize
= ( mapdesc
->maxtrate
> 0.0 ) ?
302 (pspec
[1].range
[2] / mapdesc
->maxtrate
) : 0.0;
303 if( mapdesc
->isParametricDistanceSampling() ||
304 mapdesc
->isObjectSpaceParaSampling() ) {
307 t2
= mapdesc
->getProperty( N_ERROR_TOLERANCE
);
309 // t2 is upper bound on the distance between surface and tessellant
311 REAL ss
= mapdesc
->calcPartialVelocity( ssv
, &tmp
[0][0][0], trstride
, tcstride
, pspec
[0].order
, pspec
[1].order
, 2, 0, pspec
[0].range
[2], pspec
[1].range
[2], 0 );
312 REAL st
= mapdesc
->calcPartialVelocity( 0, &tmp
[0][0][0], trstride
, tcstride
, pspec
[0].order
, pspec
[1].order
, 1, 1, pspec
[0].range
[2], pspec
[1].range
[2], -1 );
313 REAL tt
= mapdesc
->calcPartialVelocity( ttv
, &tmp
[0][0][0], trstride
, tcstride
, pspec
[0].order
, pspec
[1].order
, 0, 2, pspec
[0].range
[2], pspec
[1].range
[2], 1 );
314 //make sure that ss st and tt are nonnegative:
319 if( ss
!= 0.0 && tt
!= 0.0 ) {
320 /* printf( "ssv[0] %g ssv[1] %g ttv[0] %g ttv[1] %g\n",
321 ssv[0], ssv[1], ttv[0], ttv[1] ); */
322 REAL ttq
= sqrtf( (float) ss
);
323 REAL ssq
= sqrtf( (float) tt
);
324 REAL ds
= sqrtf( 4 * t2
* ttq
/ ( ss
* ttq
+ st
* ssq
) );
325 REAL dt
= sqrtf( 4 * t2
* ssq
/ ( tt
* ssq
+ st
* ttq
) );
326 pspec
[0].stepsize
= ( ds
< pspec
[0].range
[2] ) ? ds
: pspec
[0].range
[2];
327 REAL scutoff
= 2.0 * t2
/ ( pspec
[0].range
[2] * pspec
[0].range
[2]);
328 pspec
[0].sidestep
[0] = (ssv
[0] > scutoff
) ? sqrtf( 2.0 * t2
/ ssv
[0] ) : pspec
[0].range
[2];
329 pspec
[0].sidestep
[1] = (ssv
[1] > scutoff
) ? sqrtf( 2.0 * t2
/ ssv
[1] ) : pspec
[0].range
[2];
331 pspec
[1].stepsize
= ( dt
< pspec
[1].range
[2] ) ? dt
: pspec
[1].range
[2];
332 REAL tcutoff
= 2.0 * t2
/ ( pspec
[1].range
[2] * pspec
[1].range
[2]);
333 pspec
[1].sidestep
[0] = (ttv
[0] > tcutoff
) ? sqrtf( 2.0 * t2
/ ttv
[0] ) : pspec
[1].range
[2];
334 pspec
[1].sidestep
[1] = (ttv
[1] > tcutoff
) ? sqrtf( 2.0 * t2
/ ttv
[1] ) : pspec
[1].range
[2];
335 } else if( ss
!= 0.0 ) {
336 REAL x
= pspec
[1].range
[2] * st
;
337 REAL ds
= ( sqrtf( x
* x
+ 8.0 * t2
* ss
) - x
) / ss
;
338 pspec
[0].stepsize
= ( ds
< pspec
[0].range
[2] ) ? ds
: pspec
[0].range
[2];
339 REAL scutoff
= 2.0 * t2
/ ( pspec
[0].range
[2] * pspec
[0].range
[2]);
340 pspec
[0].sidestep
[0] = (ssv
[0] > scutoff
) ? sqrtf( 2.0 * t2
/ ssv
[0] ) : pspec
[0].range
[2];
341 pspec
[0].sidestep
[1] = (ssv
[1] > scutoff
) ? sqrtf( 2.0 * t2
/ ssv
[1] ) : pspec
[0].range
[2];
342 pspec
[1].singleStep();
343 } else if( tt
!= 0.0 ) {
344 REAL x
= pspec
[0].range
[2] * st
;
345 REAL dt
= ( sqrtf( x
* x
+ 8.0 * t2
* tt
) - x
) / tt
;
346 pspec
[0].singleStep();
347 REAL tcutoff
= 2.0 * t2
/ ( pspec
[1].range
[2] * pspec
[1].range
[2]);
348 pspec
[1].stepsize
= ( dt
< pspec
[1].range
[2] ) ? dt
: pspec
[1].range
[2];
349 pspec
[1].sidestep
[0] = (ttv
[0] > tcutoff
) ? sqrtf( 2.0 * t2
/ ttv
[0] ) : pspec
[1].range
[2];
350 pspec
[1].sidestep
[1] = (ttv
[1] > tcutoff
) ? sqrtf( 2.0 * t2
/ ttv
[1] ) : pspec
[1].range
[2];
352 if( 4.0 * t2
> st
* pspec
[0].range
[2] * pspec
[1].range
[2] ) {
353 pspec
[0].singleStep();
354 pspec
[1].singleStep();
356 REAL area
= 4.0 * t2
/ st
;
357 REAL ds
= sqrtf( area
* pspec
[0].range
[2] / pspec
[1].range
[2] );
358 REAL dt
= sqrtf( area
* pspec
[1].range
[2] / pspec
[0].range
[2] );
359 pspec
[0].stepsize
= ( ds
< pspec
[0].range
[2] ) ? ds
: pspec
[0].range
[2];
360 pspec
[0].sidestep
[0] = pspec
[0].range
[2];
361 pspec
[0].sidestep
[1] = pspec
[0].range
[2];
363 pspec
[1].stepsize
= ( dt
< pspec
[1].range
[2] ) ? dt
: pspec
[1].range
[2];
364 pspec
[1].sidestep
[0] = pspec
[1].range
[2];
365 pspec
[1].sidestep
[1] = pspec
[1].range
[2];
368 } else if( mapdesc
->isPathLengthSampling() ||
369 mapdesc
->isObjectSpacePathSampling()) {
370 // t1 is upper bound on path length
372 REAL ms
= mapdesc
->calcPartialVelocity( msv
, &tmp
[0][0][0], trstride
, tcstride
, pspec
[0].order
, pspec
[1].order
, 1, 0, pspec
[0].range
[2], pspec
[1].range
[2], 0 );
373 REAL mt
= mapdesc
->calcPartialVelocity( mtv
, &tmp
[0][0][0], trstride
, tcstride
, pspec
[0].order
, pspec
[1].order
, 0, 1, pspec
[0].range
[2], pspec
[1].range
[2], 1 );
374 REAL side_scale
= 1.0;
378 /* REAL d = t1 / ( ms * ms + mt * mt );*/
379 /* REAL ds = mt * d;*/
380 REAL ds
= t1
/ (2.0*ms
);
381 /* REAL dt = ms * d;*/
382 REAL dt
= t1
/ (2.0*mt
);
383 pspec
[0].stepsize
= ( ds
< pspec
[0].range
[2] ) ? ds
: pspec
[0].range
[2];
384 pspec
[0].sidestep
[0] = ( msv
[0] * pspec
[0].range
[2] > t1
) ? (side_scale
* t1
/ msv
[0]) : pspec
[0].range
[2];
385 pspec
[0].sidestep
[1] = ( msv
[1] * pspec
[0].range
[2] > t1
) ? (side_scale
* t1
/ msv
[1]) : pspec
[0].range
[2];
387 pspec
[1].stepsize
= ( dt
< pspec
[1].range
[2] ) ? dt
: pspec
[1].range
[2];
388 pspec
[1].sidestep
[0] = ( mtv
[0] * pspec
[1].range
[2] > t1
) ? (side_scale
*t1
/ mtv
[0]) : pspec
[1].range
[2];
389 pspec
[1].sidestep
[1] = ( mtv
[1] * pspec
[1].range
[2] > t1
) ? (side_scale
*t1
/ mtv
[1]) : pspec
[1].range
[2];
391 pspec
[0].stepsize
= ( t1
< ms
* pspec
[0].range
[2] ) ? (t1
/ ms
) : pspec
[0].range
[2];
392 pspec
[0].sidestep
[0] = ( msv
[0] * pspec
[0].range
[2] > t1
) ? (t1
/ msv
[0]) : pspec
[0].range
[2];
393 pspec
[0].sidestep
[1] = ( msv
[1] * pspec
[0].range
[2] > t1
) ? (t1
/ msv
[1]) : pspec
[0].range
[2];
395 pspec
[1].singleStep();
399 pspec
[0].singleStep();
401 pspec
[1].stepsize
= ( t1
< mt
* pspec
[1].range
[2] ) ? (t1
/ mt
) : pspec
[1].range
[2];
402 pspec
[1].sidestep
[0] = ( mtv
[0] * pspec
[1].range
[2] > t1
) ? (t1
/ mtv
[0]) : pspec
[1].range
[2];
403 pspec
[1].sidestep
[1] = ( mtv
[1] * pspec
[1].range
[2] > t1
) ? (t1
/ mtv
[1]) : pspec
[1].range
[2];
405 pspec
[0].singleStep();
406 pspec
[1].singleStep();
409 } else if( mapdesc
->isSurfaceAreaSampling() ) {
410 // t is the square root of area
413 REAL ms = mapdesc->calcPartialVelocity( msv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 1, 0, pspec[0].range[2], pspec[1].range[2], 0 );
414 REAL mt = mapdesc->calcPartialVelocity( mtv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 0, 1, pspec[0].range[2], pspec[1].range[2], 1 );
415 if( ms != 0.0 && mt != 0.0 ) {
416 REAL d = 1.0 / (ms * mt);
418 REAL ds = t * sqrtf( d * pspec[0].range[2] / pspec[1].range[2] );
419 REAL dt = t * sqrtf( d * pspec[1].range[2] / pspec[0].range[2] );
420 pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2];
421 pspec[0].sidestep[0] = ( msv[0] * pspec[0].range[2] > t ) ? (t / msv[0]) : pspec[0].range[2];
422 pspec[0].sidestep[1] = ( msv[1] * pspec[0].range[2] > t ) ? (t / msv[1]) : pspec[0].range[2];
424 pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2];
425 pspec[1].sidestep[0] = ( mtv[0] * pspec[1].range[2] > t ) ? (t / mtv[0]) : pspec[1].range[2];
426 pspec[1].sidestep[1] = ( mtv[1] * pspec[1].range[2] > t ) ? (t / mtv[1]) : pspec[1].range[2];
428 pspec[0].singleStep();
429 pspec[1].singleStep();
433 pspec
[0].singleStep();
434 pspec
[1].singleStep();
440 _glu_dprintf( "sidesteps %g %g %g %g, stepsize %g %g\n",
441 pspec
[0].sidestep
[0], pspec
[0].sidestep
[1],
442 pspec
[1].sidestep
[0], pspec
[1].sidestep
[1],
443 pspec
[0].stepsize
, pspec
[1].stepsize
);
446 if( mapdesc
->minsavings
!= N_NOSAVINGSSUBDIVISION
) {
447 REAL savings
= 1./(pspec
[0].stepsize
* pspec
[1].stepsize
) ;
448 savings
-= (2./( pspec
[0].sidestep
[0] + pspec
[0].sidestep
[1] )) *
449 (2./( pspec
[1].sidestep
[0] + pspec
[1].sidestep
[1] ));
451 savings
*= pspec
[0].range
[2] * pspec
[1].range
[2];
452 if( savings
> mapdesc
->minsavings
) {
453 pspec
[0].needsSubdivision
= pspec
[1].needsSubdivision
= 1;
457 if( pspec
[0].stepsize
< pspec
[0].minstepsize
) pspec
[0].needsSubdivision
= 1;
458 if( pspec
[1].stepsize
< pspec
[1].minstepsize
) pspec
[1].needsSubdivision
= 1;
459 needsSampling
= (needsSampling
? needsSamplingSubdivision() : 0);
463 Patchspec::singleStep()
465 stepsize
= sidestep
[0] = sidestep
[1] = glu_abs(range
[2]);
469 Patchspec::getstepsize( REAL max
) // max is number of samples for entire patch
471 stepsize
= ( max
>= 1.0 ) ? range
[2] / max
: range
[2];
472 if (stepsize
< 0.0) {
473 stepsize
= -stepsize
;
475 sidestep
[0] = sidestep
[1] = minstepsize
= stepsize
;
479 Patch::needsSamplingSubdivision( void )
481 return (pspec
[0].needsSubdivision
|| pspec
[1].needsSubdivision
) ? 1 : 0;
485 Patch::needsNonSamplingSubdivision( void )
491 Patch::needsSubdivision( int param
)
493 return pspec
[param
].needsSubdivision
;
497 Patch::cullCheck( void )
499 if( cullval
== CULL_ACCEPT
)
500 cullval
= mapdesc
->cullCheck( cpts
, pspec
[0].order
, pspec
[0].stride
,
501 pspec
[1].order
, pspec
[1].stride
);