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.
40 #include "glimports.h"
47 #include "knotvector.h"
48 #include "patchlist.h"
49 #include "math.h" //fglu_abs()
50 #include "simplemath.h" //min()
52 /* local preprocessor definitions */
53 #define DEF_PATCH_STEPSIZE .4
54 #define fsizeof(x) (sizeof(x)/sizeof(REAL))
57 Quilt::Quilt( Mapdesc
*_mapdesc
)
63 Quilt::deleteMe( Pool
& p
)
65 for( Quiltspec
*q
=qspec
; q
!= eqspec
; q
++ ) {
67 if( q
->breakpoints
) delete[] q
->breakpoints
; q
->breakpoints
= 0;
70 delete[] q
->breakpoints
;
76 if( cpts
) delete[] cpts
;
78 PooledObj::deleteMe( p
);
85 int nc
= mapdesc
->getNcoords();
87 ps
+= qspec
[0].offset
;
88 ps
+= qspec
[1].offset
;
89 for( int i
=0; i
!= qspec
[0].order
* qspec
[0].width
; i
++ ) {
90 for( int j
= 0; j
!= qspec
[1].order
* qspec
[1].width
; j
++ ) {
91 for( int k
=0; k
< nc
; k
++ )
92 _glu_dprintf( "%g ", ps
[i
*qspec
[0].stride
+ j
*qspec
[1].stride
+ k
] );
101 /*--------------------------------------------------------------------------
102 * Quilt::select - find which map in each quilt contains the points
103 * pta and ptb with pta[i] < ptb[i]
104 *--------------------------------------------------------------------------
108 Quilt::select( REAL
*pta
, REAL
*ptb
)
110 int dim
= eqspec
- qspec
;
112 for( i
=0; i
<dim
; i
++) {
113 for( j
=qspec
[i
].width
-1; j
>=0; j
-- )
114 if( (qspec
[i
].breakpoints
[j
] <= pta
[i
] ) &&
115 (ptb
[i
] <= qspec
[i
].breakpoints
[j
+1] ) )
123 Quilt::download( Backend
&backend
)
125 if( getDimension() == 2 ) {
127 ps
+= qspec
[0].offset
;
128 ps
+= qspec
[1].offset
;
129 ps
+= qspec
[0].index
* qspec
[0].order
* qspec
[0].stride
;
130 ps
+= qspec
[1].index
* qspec
[1].order
* qspec
[1].stride
;
131 backend
.surfpts( mapdesc
->getType(), ps
,
136 qspec
[0].breakpoints
[qspec
[0].index
],
137 qspec
[0].breakpoints
[qspec
[0].index
+1],
138 qspec
[1].breakpoints
[qspec
[1].index
],
139 qspec
[1].breakpoints
[qspec
[1].index
+1] );
142 ps
+= qspec
[0].offset
;
143 ps
+= qspec
[0].index
* qspec
[0].order
* qspec
[0].stride
;
144 backend
.curvpts( mapdesc
->getType(), ps
,
147 qspec
[0].breakpoints
[qspec
[0].index
],
148 qspec
[0].breakpoints
[qspec
[0].index
+1] );
152 /*--------------------------------------------------------------------------
153 * Quilt::downloadAll - download each map that contains the current patch
154 *--------------------------------------------------------------------------
158 Quilt::downloadAll( REAL
*pta
, REAL
*ptb
, Backend
&backend
)
160 for( Quilt
*m
= this; m
; m
=m
->next
) {
161 m
->select( pta
, ptb
);
162 m
->download( backend
);
166 /*--------------------------------------------------------------------------
167 * Quilt::isCulled - determine if an entire quilt is trivially rejected.
168 *--------------------------------------------------------------------------
172 Quilt::isCulled( void )
174 if( mapdesc
->isCulling() )
175 return mapdesc
->xformAndCullCheck( cpts
+ qspec
[0].offset
+ qspec
[1].offset
,
176 qspec
[0].order
* qspec
[0].width
, qspec
[0].stride
,
177 qspec
[1].order
* qspec
[1].width
, qspec
[1].stride
);
182 /*---------------------------------------------------------------------------
183 * Quilt::getRange - retrieve the valid paramater range of a set of quilts
184 *---------------------------------------------------------------------------
187 Quilt::getRange( REAL
*from
, REAL
*to
, Flist
& slist
, Flist
&tlist
)
189 getRange( from
, to
, 0, slist
);
190 getRange( from
, to
, 1, tlist
);
193 /*---------------------------------------------------------------------------
194 * Quilt::getRange - retrieve the valid paramater range of a set of quilts
195 *---------------------------------------------------------------------------
198 Quilt::getRange( REAL
*from
, REAL
*to
, int i
, Flist
&list
)
201 from
[i
] = maps
->qspec
[i
].breakpoints
[0];
202 to
[i
] = maps
->qspec
[i
].breakpoints
[maps
->qspec
[i
].width
];
205 for( m
=maps
; m
; m
=m
->next
) {
206 if( m
->qspec
[i
].breakpoints
[0] > from
[i
] )
207 from
[i
] = m
->qspec
[i
].breakpoints
[0];
208 if( m
->qspec
[i
].breakpoints
[m
->qspec
[i
].width
] < to
[i
] )
209 to
[i
] = m
->qspec
[i
].breakpoints
[m
->qspec
[i
].width
];
210 maxpts
+= m
->qspec
[i
].width
+ 1;
215 for( m
=maps
; m
; m
=m
->next
)
216 for( int j
=0; j
<=m
->qspec
[i
].width
; j
++ ) {
217 list
.add( m
->qspec
[i
].breakpoints
[j
] );
221 list
.taper( from
[i
], to
[i
] );
225 Quilt::getRange( REAL
*from
, REAL
*to
, Flist
& slist
)
227 getRange( from
, to
, 0, slist
);
231 Quilt::findRates( Flist
& slist
, Flist
& tlist
, REAL rate
[2] )
233 findSampleRates( slist
, tlist
);
234 rate
[0] = qspec
[0].step_size
;
235 rate
[1] = qspec
[1].step_size
;
237 for( Quilt
*q
= next
; q
; q
= q
->next
) {
238 q
->findSampleRates( slist
, tlist
);
239 if( q
->qspec
[0].step_size
< rate
[0] )
240 rate
[0] = q
->qspec
[0].step_size
;
241 if( q
->qspec
[1].step_size
< rate
[1] )
242 rate
[1] = q
->qspec
[1].step_size
;
247 Quilt::findSampleRates( Flist
& slist
, Flist
& tlist
)
249 qspec
[0].step_size
= DEF_PATCH_STEPSIZE
*
250 (qspec
[0].breakpoints
[qspec
[0].width
] - qspec
[0].breakpoints
[0]);
251 qspec
[1].step_size
= DEF_PATCH_STEPSIZE
*
252 (qspec
[1].breakpoints
[qspec
[1].width
] - qspec
[1].breakpoints
[0]);
254 for( int i
= slist
.start
; i
< slist
.end
-1; i
++ ) {
255 for( int j
= tlist
.start
; j
< tlist
.end
-1; j
++ ) {
258 pta
[0] = slist
.pts
[i
];
259 ptb
[0] = slist
.pts
[i
+1];
260 pta
[1] = tlist
.pts
[j
];
261 ptb
[1] = tlist
.pts
[j
+1];
262 Patchlist
patchlist( this, pta
, ptb
);
263 patchlist
.getstepsize();
266 float edge_len_s
= min(glu_abs(ptb
[0]-pta
[0]),1.0);
267 float edge_len_t
= min(glu_abs(ptb
[1]-pta
[1]),1.0);
269 if( patchlist
.getStepsize(0)/edge_len_s
< qspec
[0].step_size
)
270 qspec
[0].step_size
= patchlist
.getStepsize(0)/edge_len_s
;
271 if( patchlist
.getStepsize(1)/edge_len_t
< qspec
[1].step_size
)
272 qspec
[1].step_size
= patchlist
.getStepsize(1)/edge_len_t
;