Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

562 lines
16 KiB

  1. /**************************************************************************
  2. * *
  3. * Copyright (C) 1992, Silicon Graphics, Inc. *
  4. * *
  5. * These coded instructions, statements, and computer programs contain *
  6. * unpublished proprietary information of Silicon Graphics, Inc., and *
  7. * are protected by Federal copyright law. They may not be disclosed *
  8. * to third parties or copied or duplicated in any form, in whole or *
  9. * in part, without the prior written consent of Silicon Graphics, Inc. *
  10. * *
  11. **************************************************************************/
  12. /*
  13. * arctessellator.c++ - $Revision: 1.6 $
  14. * Derrick Burns - 1991
  15. */
  16. #include "glimport.h"
  17. #include "mystdio.h"
  18. #include "myassert.h"
  19. #include "arctess.h"
  20. #include "bufpool.h"
  21. #include "simplema.h"
  22. #include "bezierar.h"
  23. #include "trimvert.h"
  24. #include "trimpool.h"
  25. #define NOELIMINATION
  26. #define steps_function(large, small, rate) (max(1, 1+ (int) ((large-small)/rate)));
  27. /*-----------------------------------------------------------------------------
  28. * ArcTessellator - construct an ArcTessellator
  29. *-----------------------------------------------------------------------------
  30. */
  31. ArcTessellator::ArcTessellator( TrimVertexPool& t, Pool& p )
  32. : trimvertexpool(t), pwlarcpool(p)
  33. {
  34. }
  35. /*-----------------------------------------------------------------------------
  36. * ~ArcTessellator - destroy an ArcTessellator
  37. *-----------------------------------------------------------------------------
  38. */
  39. ArcTessellator::~ArcTessellator( void )
  40. {
  41. }
  42. /*-----------------------------------------------------------------------------
  43. * bezier - construct a bezier arc and attach it to an Arc
  44. *-----------------------------------------------------------------------------
  45. */
  46. void
  47. ArcTessellator::bezier( Arc *arc, REAL s1, REAL s2, REAL t1, REAL t2 )
  48. {
  49. assert( arc != 0 );
  50. assert( ! arc->isTessellated() );
  51. #ifndef NDEBUG
  52. switch( arc->getside() ) {
  53. case arc_left:
  54. assert( s1 == s2 );
  55. assert( t2 < t1 );
  56. break;
  57. case arc_right:
  58. assert( s1 == s2 );
  59. assert( t1 < t2 );
  60. break;
  61. case arc_top:
  62. assert( t1 == t2 );
  63. assert( s2 < s1 );
  64. break;
  65. case arc_bottom:
  66. assert( t1 == t2 );
  67. assert( s1 < s2 );
  68. break;
  69. case arc_none:
  70. (void) abort();
  71. break;
  72. }
  73. #endif
  74. TrimVertex *p = trimvertexpool.get(2);
  75. arc->pwlArc = new(pwlarcpool) PwlArc( 2, p );
  76. p[0].param[0] = s1;
  77. p[0].param[1] = t1;
  78. p[1].param[0] = s2;
  79. p[1].param[1] = t2;
  80. assert( (s1 == s2) || (t1 == t2) );
  81. arc->setbezier();
  82. }
  83. /*-----------------------------------------------------------------------------
  84. * pwl_left - construct a left boundary pwl arc and attach it to an arc
  85. *-----------------------------------------------------------------------------
  86. */
  87. void
  88. ArcTessellator::pwl_left( Arc *arc, REAL s, REAL t1, REAL t2, REAL rate )
  89. {
  90. assert( t2 < t1 );
  91. /* if(rate <= 0.06) rate = 0.06;*/
  92. /* int nsteps = 1 + (int) ((t1 - t2) / rate ); */
  93. int nsteps = steps_function(t1, t2, rate);
  94. REAL stepsize = (t1 - t2) / (REAL) nsteps;
  95. TrimVertex *newvert = trimvertexpool.get( nsteps+1 );
  96. for( int i = nsteps; i > 0; i-- ) {
  97. newvert[i].param[0] = s;
  98. newvert[i].param[1] = t2;
  99. t2 += stepsize;
  100. }
  101. newvert[i].param[0] = s;
  102. newvert[i].param[1] = t1;
  103. arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_left );
  104. }
  105. /*-----------------------------------------------------------------------------
  106. * pwl_right - construct a right boundary pwl arc and attach it to an arc
  107. *-----------------------------------------------------------------------------
  108. */
  109. void
  110. ArcTessellator::pwl_right( Arc *arc, REAL s, REAL t1, REAL t2, REAL rate )
  111. {
  112. assert( t1 < t2 );
  113. /* if(rate <= 0.06) rate = 0.06;*/
  114. /* int nsteps = 1 + (int) ((t2 - t1) / rate ); */
  115. int nsteps = steps_function(t2,t1,rate);
  116. REAL stepsize = (t2 - t1) / (REAL) nsteps;
  117. TrimVertex *newvert = trimvertexpool.get( nsteps+1 );
  118. for( int i = 0; i < nsteps; i++ ) {
  119. newvert[i].param[0] = s;
  120. newvert[i].param[1] = t1;
  121. t1 += stepsize;
  122. }
  123. newvert[i].param[0] = s;
  124. newvert[i].param[1] = t2;
  125. arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_right );
  126. }
  127. /*-----------------------------------------------------------------------------
  128. * pwl_top - construct a top boundary pwl arc and attach it to an arc
  129. *-----------------------------------------------------------------------------
  130. */
  131. void
  132. ArcTessellator::pwl_top( Arc *arc, REAL t, REAL s1, REAL s2, REAL rate )
  133. {
  134. assert( s2 < s1 );
  135. /* if(rate <= 0.06) rate = 0.06;*/
  136. /* int nsteps = 1 + (int) ((s1 - s2) / rate ); */
  137. int nsteps = steps_function(s1,s2,rate);
  138. REAL stepsize = (s1 - s2) / (REAL) nsteps;
  139. TrimVertex *newvert = trimvertexpool.get( nsteps+1 );
  140. for( int i = nsteps; i > 0; i-- ) {
  141. newvert[i].param[0] = s2;
  142. newvert[i].param[1] = t;
  143. s2 += stepsize;
  144. }
  145. newvert[i].param[0] = s1;
  146. newvert[i].param[1] = t;
  147. arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_top );
  148. }
  149. /*-----------------------------------------------------------------------------
  150. * pwl_bottom - construct a bottom boundary pwl arc and attach it to an arc
  151. *-----------------------------------------------------------------------------
  152. */
  153. void
  154. ArcTessellator::pwl_bottom( Arc *arc, REAL t, REAL s1, REAL s2, REAL rate )
  155. {
  156. assert( s1 < s2 );
  157. /* if(rate <= 0.06) rate = 0.06;*/
  158. /* int nsteps = 1 + (int) ((s2 - s1) / rate ); */
  159. int nsteps = steps_function(s2,s1,rate);
  160. REAL stepsize = (s2 - s1) / (REAL) nsteps;
  161. TrimVertex *newvert = trimvertexpool.get( nsteps+1 );
  162. for( int i = 0; i < nsteps; i++ ) {
  163. newvert[i].param[0] = s1;
  164. newvert[i].param[1] = t;
  165. s1 += stepsize;
  166. }
  167. newvert[i].param[0] = s2;
  168. newvert[i].param[1] = t;
  169. arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_bottom );
  170. }
  171. /*-----------------------------------------------------------------------------
  172. * pwl - construct a pwl arc and attach it to an arc
  173. *-----------------------------------------------------------------------------
  174. */
  175. void
  176. ArcTessellator::pwl( Arc *arc, REAL s1, REAL s2, REAL t1, REAL t2, REAL rate )
  177. {
  178. /* if(rate <= 0.06) rate = 0.06;*/
  179. int snsteps = 1 + (int) (abs(s2 - s1) / rate );
  180. int tnsteps = 1 + (int) (abs(t2 - t1) / rate );
  181. int nsteps = max(1,max( snsteps, tnsteps ));
  182. REAL sstepsize = (s2 - s1) / (REAL) nsteps;
  183. REAL tstepsize = (t2 - t1) / (REAL) nsteps;
  184. TrimVertex *newvert = trimvertexpool.get( nsteps+1 );
  185. for( long i = 0; i < nsteps; i++ ) {
  186. newvert[i].param[0] = s1;
  187. newvert[i].param[1] = t1;
  188. s1 += sstepsize;
  189. t1 += tstepsize;
  190. }
  191. newvert[i].param[0] = s2;
  192. newvert[i].param[1] = t2;
  193. /* arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_bottom ); */
  194. arc->pwlArc = new(pwlarcpool) PwlArc( nsteps+1, newvert );
  195. arc->clearbezier();
  196. arc->clearside( );
  197. }
  198. /*-----------------------------------------------------------------------------
  199. * tessellateLinear - constuct a linear pwl arc and attach it to an Arc
  200. *-----------------------------------------------------------------------------
  201. */
  202. void
  203. ArcTessellator::tessellateLinear( Arc *arc, REAL geo_stepsize, REAL arc_stepsize, int isrational )
  204. {
  205. assert( arc->pwlArc == NULL );
  206. REAL s1, s2, t1, t2;
  207. REAL stepsize = geo_stepsize * arc_stepsize;
  208. BezierArc *b = arc->bezierArc;
  209. if( isrational ) {
  210. s1 = b->cpts[0] / b->cpts[2];
  211. t1 = b->cpts[1] / b->cpts[2];
  212. s2 = b->cpts[b->stride+0] / b->cpts[b->stride+2];
  213. t2 = b->cpts[b->stride+1] / b->cpts[b->stride+2];
  214. } else {
  215. s1 = b->cpts[0];
  216. t1 = b->cpts[1];
  217. s2 = b->cpts[b->stride+0];
  218. t2 = b->cpts[b->stride+1];
  219. }
  220. if( s1 == s2 )
  221. if( t1 < t2 )
  222. pwl_right( arc, s1, t1, t2, stepsize );
  223. else
  224. pwl_left( arc, s1, t1, t2, stepsize );
  225. else if( t1 == t2 )
  226. if( s1 < s2 )
  227. pwl_bottom( arc, t1, s1, s2, stepsize );
  228. else
  229. pwl_top( arc, t1, s1, s2, stepsize );
  230. else
  231. pwl( arc, s1, s2, t1, t2, stepsize );
  232. }
  233. /*-----------------------------------------------------------------------------
  234. * tessellateNonlinear - constuct a nonlinear pwl arc and attach it to an Arc
  235. *-----------------------------------------------------------------------------
  236. */
  237. void
  238. ArcTessellator::tessellateNonlinear( Arc *arc, REAL geo_stepsize, REAL arc_stepsize, int isrational )
  239. {
  240. assert( arc->pwlArc == NULL );
  241. REAL stepsize = geo_stepsize * arc_stepsize;
  242. int nsteps = 1 + (int) (1.0/stepsize);
  243. TrimVertex *vert = trimvertexpool.get( nsteps+1 );
  244. REAL dp = 1.0/nsteps;
  245. BezierArc *bezierArc = arc->bezierArc;
  246. arc->pwlArc = new(pwlarcpool) PwlArc();
  247. arc->pwlArc->pts = vert;
  248. if( isrational ) {
  249. REAL pow_u[MAXORDER], pow_v[MAXORDER], pow_w[MAXORDER];
  250. trim_power_coeffs( bezierArc, pow_u, 0 );
  251. trim_power_coeffs( bezierArc, pow_v, 1 );
  252. trim_power_coeffs( bezierArc, pow_w, 2 );
  253. /* compute first point exactly */
  254. REAL *b = bezierArc->cpts;
  255. vert->param[0] = b[0]/b[2];
  256. vert->param[1] = b[1]/b[2];
  257. /* strength reduction on p = dp * step would introduce error */
  258. int step;
  259. int ocanremove = 0;
  260. register long order = bezierArc->order;
  261. for( step=1, ++vert; step<nsteps; step++, vert++ ) {
  262. register REAL p = dp * step;
  263. register REAL u = pow_u[0];
  264. register REAL v = pow_v[0];
  265. register REAL w = pow_w[0];
  266. for( register int i = 1; i < order; i++ ) {
  267. u = u * p + pow_u[i];
  268. v = v * p + pow_v[i];
  269. w = w * p + pow_w[i];
  270. }
  271. vert->param[0] = u/w;
  272. vert->param[1] = v/w;
  273. #ifndef NOELIMINATION
  274. REAL ds = abs(vert[0].param[0] - vert[-1].param[0]);
  275. REAL dt = abs(vert[0].param[1] - vert[-1].param[1]);
  276. int canremove = (ds<geo_stepsize && dt<geo_stepsize) ? 1 : 0;
  277. REAL ods=0.0, odt=0.0;
  278. if( ocanremove && canremove ) {
  279. REAL nds = ds + ods;
  280. REAL ndt = dt + odt;
  281. if( nds<geo_stepsize && ndt<geo_stepsize ) {
  282. // remove previous point
  283. --vert;
  284. vert[0].param[0] = vert[1].param[0];
  285. vert[0].param[1] = vert[1].param[1];
  286. ods = nds;
  287. odt = ndt;
  288. ocanremove = 1;
  289. } else {
  290. ocanremove = canremove;
  291. ods = ds;
  292. odt = dt;
  293. }
  294. } else {
  295. ocanremove = canremove;
  296. ods = ds;
  297. odt = dt;
  298. }
  299. #endif
  300. }
  301. /* compute last point exactly */
  302. b += (order - 1) * bezierArc->stride;
  303. vert->param[0] = b[0]/b[2];
  304. vert->param[1] = b[1]/b[2];
  305. } else {
  306. REAL pow_u[MAXORDER], pow_v[MAXORDER];
  307. trim_power_coeffs( bezierArc, pow_u, 0 );
  308. trim_power_coeffs( bezierArc, pow_v, 1 );
  309. /* compute first point exactly */
  310. REAL *b = bezierArc->cpts;
  311. vert->param[0] = b[0];
  312. vert->param[1] = b[1];
  313. /* strength reduction on p = dp * step would introduce error */
  314. int step;
  315. int ocanremove = 0;
  316. register long order = bezierArc->order;
  317. for( step=1, ++vert; step<nsteps; step++, vert++ ) {
  318. register REAL p = dp * step;
  319. register REAL u = pow_u[0];
  320. register REAL v = pow_v[0];
  321. for( register int i = 1; i < bezierArc->order; i++ ) {
  322. u = u * p + pow_u[i];
  323. v = v * p + pow_v[i];
  324. }
  325. vert->param[0] = u;
  326. vert->param[1] = v;
  327. #ifndef NOELIMINATION
  328. REAL ds = abs(vert[0].param[0] - vert[-1].param[0]);
  329. REAL dt = abs(vert[0].param[1] - vert[-1].param[1]);
  330. int canremove = (ds<geo_stepsize && dt<geo_stepsize) ? 1 : 0;
  331. REAL ods=0.0, odt=0.0;
  332. if( ocanremove && canremove ) {
  333. REAL nds = ds + ods;
  334. REAL ndt = dt + odt;
  335. if( nds<geo_stepsize && ndt<geo_stepsize ) {
  336. // remove previous point
  337. --vert;
  338. vert[0].param[0] = vert[1].param[0];
  339. vert[0].param[1] = vert[1].param[1];
  340. ods = nds;
  341. odt = ndt;
  342. ocanremove = 1;
  343. } else {
  344. ocanremove = canremove;
  345. ods = ds;
  346. odt = dt;
  347. }
  348. } else {
  349. ocanremove = canremove;
  350. ods = ds;
  351. odt = dt;
  352. }
  353. #endif
  354. }
  355. /* compute last point exactly */
  356. b += (order - 1) * bezierArc->stride;
  357. vert->param[0] = b[0];
  358. vert->param[1] = b[1];
  359. }
  360. arc->pwlArc->npts = vert - arc->pwlArc->pts + 1;
  361. /*
  362. for( TrimVertex *vt=pwlArc->pts; vt != vert-1; vt++ ) {
  363. if( tooclose( vt[0].param[0], vt[1].param[0] ) )
  364. vt[1].param[0] = vt[0].param[0];
  365. if( tooclose( vt[0].param[1], vt[1].param[1] ) )
  366. vt[1].param[1] = vt[0].param[1];
  367. }
  368. */
  369. }
  370. #ifdef NT
  371. REAL ArcTessellator::gl_Bernstein[][MAXORDER][MAXORDER] = {
  372. #else
  373. const REAL ArcTessellator::gl_Bernstein[][MAXORDER][MAXORDER] = {
  374. #endif
  375. {
  376. {1, 0, 0, 0, 0, 0, 0, 0 },
  377. {0, 0, 0, 0, 0, 0, 0, 0 },
  378. {0, 0, 0, 0, 0, 0, 0, 0 },
  379. {0, 0, 0, 0, 0, 0, 0, 0 },
  380. {0, 0, 0, 0, 0, 0, 0, 0 },
  381. {0, 0, 0, 0, 0, 0, 0, 0 },
  382. {0, 0, 0, 0, 0, 0, 0, 0 },
  383. {0, 0, 0, 0, 0, 0, 0, 0 }
  384. },
  385. {
  386. {-1, 1, 0, 0, 0, 0, 0, 0 },
  387. {1, 0, 0, 0, 0, 0, 0, 0 },
  388. {0, 0, 0, 0, 0, 0, 0, 0 },
  389. {0, 0, 0, 0, 0, 0, 0, 0 },
  390. {0, 0, 0, 0, 0, 0, 0, 0 },
  391. {0, 0, 0, 0, 0, 0, 0, 0 },
  392. {0, 0, 0, 0, 0, 0, 0, 0 },
  393. {0, 0, 0, 0, 0, 0, 0, 0 }
  394. },
  395. {
  396. {1, -2, 1, 0, 0, 0, 0, 0 },
  397. {-2, 2, 0, 0, 0, 0, 0, 0 },
  398. {1, 0, 0, 0, 0, 0, 0, 0 },
  399. {0, 0, 0, 0, 0, 0, 0, 0 },
  400. {0, 0, 0, 0, 0, 0, 0, 0 },
  401. {0, 0, 0, 0, 0, 0, 0, 0 },
  402. {0, 0, 0, 0, 0, 0, 0, 0 },
  403. {0, 0, 0, 0, 0, 0, 0, 0 }
  404. },
  405. {
  406. {-1, 3, -3, 1, 0, 0, 0, 0 },
  407. {3, -6, 3, 0, 0, 0, 0, 0 },
  408. {-3, 3, 0, 0, 0, 0, 0, 0 },
  409. {1, 0, 0, 0, 0, 0, 0, 0 },
  410. {0, 0, 0, 0, 0, 0, 0, 0 },
  411. {0, 0, 0, 0, 0, 0, 0, 0 },
  412. {0, 0, 0, 0, 0, 0, 0, 0 },
  413. {0, 0, 0, 0, 0, 0, 0, 0 }
  414. },
  415. {
  416. {1, -4, 6, -4, 1, 0, 0, 0 },
  417. {-4, 12, -12, 4, 0, 0, 0, 0 },
  418. {6, -12, 6, 0, 0, 0, 0, 0 },
  419. {-4, 4, 0, 0, 0, 0, 0, 0 },
  420. {1, 0, 0, 0, 0, 0, 0, 0 },
  421. {0, 0, 0, 0, 0, 0, 0, 0 },
  422. {0, 0, 0, 0, 0, 0, 0, 0 },
  423. {0, 0, 0, 0, 0, 0, 0, 0 }
  424. },
  425. {
  426. {-1, 5, -10, 10, -5, 1, 0, 0 },
  427. {5, -20, 30, -20, 5, 0, 0, 0 },
  428. {-10, 30, -30, 10, 0, 0, 0, 0 },
  429. {10, -20, 10, 0, 0, 0, 0, 0 },
  430. {-5, 5, 0, 0, 0, 0, 0, 0 },
  431. {1, 0, 0, 0, 0, 0, 0, 0 },
  432. {0, 0, 0, 0, 0, 0, 0, 0 },
  433. {0, 0, 0, 0, 0, 0, 0, 0 }
  434. },
  435. {
  436. {1, -6, 15, -20, 15, -6, 1, 0 },
  437. {-6, 30, -60, 60, -30, 6, 0, 0 },
  438. {15, -60, 90, -60, 15, 0, 0, 0 },
  439. {-20, 60, -60, 20, 0, 0, 0, 0 },
  440. {15, -30, 15, 0, 0, 0, 0, 0 },
  441. {-6, 6, 0, 0, 0, 0, 0, 0 },
  442. {1, 0, 0, 0, 0, 0, 0, 0 },
  443. {0, 0, 0, 0, 0, 0, 0, 0 }
  444. },
  445. {
  446. {-1, 7, -21, 35, -35, 21, -7, 1 },
  447. {7, -42, 105, -140, 105, -42, 7, 0 },
  448. {-21, 105, -210, 210, -105, 21, 0, 0 },
  449. {35, -140, 210, -140, 35, 0, 0, 0 },
  450. {-35, 105, -105, 35, 0, 0, 0, 0 },
  451. {21, -42, 21, 0, 0, 0, 0, 0 },
  452. {-7, 7, 0, 0, 0, 0, 0, 0 },
  453. {1, 0, 0, 0, 0, 0, 0, 0 }
  454. }};
  455. /*-----------------------------------------------------------------------------
  456. * trim_power_coeffs - compute power basis coefficients from bezier coeffients
  457. *-----------------------------------------------------------------------------
  458. */
  459. void
  460. ArcTessellator::trim_power_coeffs( BezierArc *bez_arc, REAL *p, int coord )
  461. {
  462. register int stride = bez_arc->stride;
  463. register int order = bez_arc->order;
  464. register REAL *base = bez_arc->cpts + coord;
  465. #ifdef NT
  466. REAL (*mat)[MAXORDER][MAXORDER] = &gl_Bernstein[order-1];
  467. REAL (*lrow)[MAXORDER] = &(*mat)[order];
  468. REAL (*row)[MAXORDER] = &(*mat)[0];
  469. for( ; row != lrow; row++ ) {
  470. register REAL s = (REAL)0.0;
  471. register REAL *point = base;
  472. register REAL *mlast = *row + order;
  473. for( REAL *m = *row; m != mlast; m++, point += stride )
  474. s += *(m) * (*point);
  475. *(p++) = s;
  476. }
  477. #else
  478. REAL const (*mat)[MAXORDER][MAXORDER] = &gl_Bernstein[order-1];
  479. REAL const (*lrow)[MAXORDER] = &(*mat)[order];
  480. for( REAL const (*row)[MAXORDER] = &(*mat)[0]; row != lrow; row++ ) {
  481. register REAL s = 0.0;
  482. register REAL *point = base;
  483. register REAL const *mlast = *row + order;
  484. for( REAL const *m = *row; m != mlast; m++, point += stride )
  485. s += *(m) * (*point);
  486. *(p++) = s;
  487. }
  488. #endif
  489. }