1 /* Copyright (C) 1992-1998 The Geometry Center
2 * Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips
3 *
4 * This file is part of Geomview.
5 *
6 * Geomview is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * Geomview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with Geomview; see the file COPYING. If not, write
18 * to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
19 * USA, or visit http://www.gnu.org.
20 */
21
22 #if HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
26 #if 0
27 static char copyright[] = "Copyright (C) 1992-1998 The Geometry Center\n\
28 Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips";
29 #endif
30
31 #include "mgP.h"
32 #include "mgpsP.h"
33 #include "polylistP.h"
34 #include "mgpswindows.h"
35
36
37 /* Author: Daeron Meyer */
38
39 void mgps_polygon( int nv, HPoint3 *v, int nn, Point3 *n,
40 int nc, ColorA *c );
41 void mgps_mesh(int wrap, int nu, int nv, HPoint3 *p, Point3 *n, Point3 *nq,
42 ColorA *c );
43 void mgps_line( HPoint3 *p1, HPoint3 *p2 );
44 void mgps_polyline( int nv, HPoint3 *verts, int nc, ColorA *colors,
45 int wrap );
46 void mgps_polylist( int np, Poly *p, int nv, Vertex *v,
47 int pl_flags );
48 void mgps_drawnormal(HPoint3 *p, Point3 *n);
49
50 void mgps_closer();
51 void mgps_farther();
52
53 static ColorA *C2;
54
55 /*-----------------------------------------------------------------------
56 * Function: mgps_polygon
57 * Description: draw a polygon
58 * Author: Daeron Meyer
59 * Notes: See mg.doc.
60 *
61 */
62 void
mgps_polygon(int nv,HPoint3 * V,int nn,Point3 * N,int nc,ColorA * C)63 mgps_polygon(int nv, HPoint3 *V,
64 int nn, Point3 *N,
65 int nc, ColorA *C)
66 {
67 int count;
68 HPoint3 *v;
69 Point3 *n;
70 int flag, ninc, smooth;
71
72 /* fprintf(stderr,"X11: draw a polygon\n"); */
73
74 flag = _mgc->astk->ap.flag;
75 if ((_mgc->astk->mat.override & MTF_DIFFUSE) &&
76 !(_mgc->astk->flags & MGASTK_SHADER)) nc = 0;
77 ninc = (nn > 1);
78 smooth = IS_SMOOTH(_mgc->astk->ap.shading);
79 /*
80 fprintf(stderr,"cinc = %d, nc = %d, nn = %d\n", cinc, nc, nn);
81 */
82 if (nc == 0)
83 C = (ColorA*)&_mgc->astk->ap.mat->diffuse;
84
85 if ((flag & APF_FACEDRAW) && (flag & APF_EDGEDRAW)) {
86 /* put polygon in display list */
87
88 if (smooth && (nc > 0))
89 mgps_add(MGX_BGNSEPOLY, 0, NULL, NULL);
90 else
91 mgps_add(MGX_BGNEPOLY, 0, NULL, NULL);
92
93 mgps_add(MGX_ECOLOR, 0, NULL, &_mgc->astk->ap.mat->edgecolor);
94 /* edge color */
95 mgps_add(MGX_COLOR, 0, NULL, C); /* face color */
96
97 if (smooth)
98 mgps_add(MGX_CVERTEX, nv, V, C);
99 else
100 mgps_add(MGX_VERTEX, nv, V, NULL);
101
102 mgps_add(MGX_END, 0, NULL, NULL);
103 }
104 else
105 if (flag & APF_FACEDRAW) {
106 /* put polygon in display list */
107 if (smooth)
108 mgps_add(MGX_BGNSPOLY, 0, NULL, NULL);
109 else
110 mgps_add(MGX_BGNPOLY, 0, NULL, NULL);
111
112 mgps_add(MGX_COLOR, 0, NULL, C);
113
114 if (smooth && (nc > 0))
115 mgps_add(MGX_CVERTEX, nv, V, C);
116 else
117 mgps_add(MGX_VERTEX, nv, V, NULL);
118
119 mgps_add(MGX_END, 0, NULL, NULL);
120 }
121 else
122 if (flag & APF_EDGEDRAW) {
123 mgps_add(MGX_BGNLINE, 0, NULL, NULL);
124 mgps_add(MGX_ECOLOR, 0, NULL, &_mgc->astk->ap.mat->edgecolor);
125 mgps_add(MGX_VERTEX, nv, V, NULL);
126 mgps_add(MGX_VERTEX, 1, V, NULL);
127 mgps_add(MGX_END, 0, NULL, NULL);
128 }
129
130 if (flag & APF_NORMALDRAW)
131 {
132 mgps_closer();
133 mgps_add(MGX_ECOLOR, 0, NULL, &_mgc->astk->ap.mat->normalcolor);
134 for (n = N, v = V, count = 0; count<nv; ++count, ++v, n += ninc)
135 mgps_drawnormal(v, n);
136 mgps_farther();
137 }
138 }
139
140 /*-----------------------------------------------------------------------
141 * Function: mgps_line
142 * Description: draw a line (one color)
143 * Author: Daeron Meyer
144 * Notes: See mg.doc.
145 *
146 */
mgps_line(HPoint3 * p1,HPoint3 * p2)147 void mgps_line( HPoint3 *p1, HPoint3 *p2 )
148 {
149
150 /* fprintf(stderr,"X11: draw a line\n"); */
151
152 /* put a line in the display list */
153
154 mgps_add(MGX_BGNLINE, 0, NULL, NULL);
155 mgps_add(MGX_VERTEX, 1, p1, NULL);
156 mgps_add(MGX_VERTEX, 1, p2, NULL);
157 mgps_add(MGX_END, 0, NULL, NULL);
158
159 }
160
161 /* Construct a prototype polygonal outline for creating fat points.
162 * Curiously, we can do this independently of the position of the point,
163 * if we operate in homogeneous space.
164 */
165
166 /*-----------------------------------------------------------------------
167 * Function: mgps_fatpoint
168 * Description: draw a point (possible width > 1)
169 * Author: Daeron Meyer
170 * Notes: See mg.doc.
171 *
172 */
mgps_fatpoint(HPoint3 * v)173 void mgps_fatpoint(HPoint3 *v)
174 {
175 HPoint3 a;
176 HPoint3 *p, *q;
177 float vw;
178
179 /* fprintf(stderr,"X11: make a fat-point\n"); */
180
181 if (!(_mgc->has & HAS_POINT))
182 mg_makepoint();
183
184 /* Compute w component of point after projection to screen */
185 vw = v->x * _mgc->O2S[0][3] + v->y * _mgc->O2S[1][3]
186 + v->z * _mgc->O2S[2][3] + v->w * _mgc->O2S[3][3];
187 if (vw <= 0) return;
188
189 #define PUT(p) \
190 a.x = v->x + p->x*vw; a.y = v->y + p->y*vw; \
191 a.z = v->z + p->z*vw; a.w = v->w + p->w*vw; \
192 mgps_add(MGX_VERTEX, 1, &a, NULL);
193
194 p = VVEC(_mgc->point, HPoint3);
195 q = p + VVCOUNT(_mgc->point);
196
197 mgps_add(MGX_BGNPOLY, 0, NULL, NULL);
198 do
199 {
200 PUT(p);
201 } while (++p < q);
202 mgps_add(MGX_END, 0, NULL, NULL);
203
204 }
205
206
207 /*-----------------------------------------------------------------------
208 * Function: mgps_polyline
209 * Description: draw a polyline (possibly more than 2 vertices)
210 * Author: Daeron Meyer
211 * Notes: See mg.doc.
212 *
213 */
214
mgps_polyline(int nv,HPoint3 * v,int nc,ColorA * c,int wrapped)215 void mgps_polyline( int nv, HPoint3 *v, int nc, ColorA *c, int wrapped )
216 {
217 int remain;
218 /* fprintf(stderr,"X11: draw a polyline\n"); */
219
220 if (!(wrapped & 2)) {
221 if (_mgpsc->znudge) mgps_closer();
222 }
223 if (nv == 1)
224 {
225 if (nc > 0)
226 mgps_add(MGX_ECOLOR, 0, NULL, c);
227
228 if (_mgc->astk->ap.linewidth > 1)
229 {
230 mgps_add(MGX_COLOR, 0, NULL, c);
231 mgps_fatpoint(v);
232 }
233 else
234 {
235 mgps_add(MGX_BGNSLINE, 0, NULL, NULL);
236 mgps_add(MGX_CVERTEX, 1, v, c);
237 mgps_add(MGX_END, 0, NULL, NULL);
238 }
239 }
240 else
241 if (nv > 0)
242 {
243 mgps_add(MGX_BGNSLINE, 0, NULL, NULL);
244
245 if (wrapped & 1)
246 {
247 if (nc > 0)
248 {
249 mgps_add(MGX_ECOLOR, 0, NULL, (c + nc - 1));
250 mgps_add(MGX_CVERTEX, 1, (v + nv - 1), (c + nc - 1));
251 }
252 else
253 mgps_add(MGX_CVERTEX, 1, (v + nv - 1), c);
254 }
255
256 for (;;)
257 {
258 remain = nv > 254 ? 254 : nv;
259 nv -= remain;
260 do
261 {
262 if (--nc > 0)
263 {
264 mgps_add(MGX_ECOLOR, 0, NULL, c);
265 mgps_add(MGX_CVERTEX, 1, v++, c++);
266 }
267 else
268 mgps_add(MGX_CVERTEX, 1, v++, c);
269
270 } while (--remain > 0);
271 if (nv == 0)
272 break;
273 if (nc > 0)
274 mgps_add(MGX_ECOLOR, 0, NULL, c);
275 mgps_add(MGX_CVERTEX, 1, v, c);
276 mgps_add(MGX_END, 0, NULL, NULL);
277 mgps_add(MGX_BGNSLINE, 0, NULL, NULL);
278 }
279 mgps_add(MGX_END, 0, NULL, NULL);
280 }
281 if (!(wrapped & 4) && _mgpsc->znudge)
282 mgps_farther();
283 }
284
285
286 /*-----------------------------------------------------------------------
287 * Function: mgps_polylist
288 * Description: draws a Polylist: collection of Polys
289 * Author: Daeron Meyer
290 * Notes: see mg.doc
291 */
mgps_polylist(int np,Poly * _p,int nv,Vertex * V,int pl_flags)292 void mgps_polylist( int np, Poly *_p, int nv, Vertex *V, int pl_flags )
293 {
294 int i, j;
295 Poly *p;
296 Vertex **v, *vp, **vh;
297 struct mgastk *ma = _mgc->astk;
298 int plflags = pl_flags;
299 int flag, shading;
300 int nonsurf = -1;
301
302 flag = ma->ap.flag;
303 shading = ma->ap.shading;
304
305 /* fprintf(stderr,"X11: draw a polylist %d\n",np); */
306
307 switch(shading) {
308 case APF_FLAT:
309 plflags &= ~PL_HASVN;
310 if (plflags & PL_HASPCOL) {
311 plflags &= ~PL_HASVCOL;
312 }
313 break;
314 case APF_SMOOTH: plflags &= ~PL_HASPN; break;
315 case APF_VCFLAT: plflags &= ~PL_HASVN; break;
316 default: plflags &= ~(PL_HASVN|PL_HASPN); break;
317 }
318
319 if ((_mgc->astk->mat.override & MTF_DIFFUSE) &&
320 !(_mgc->astk->flags & MGASTK_SHADER))
321 plflags &= ~(PL_HASVCOL | PL_HASPCOL);
322
323 if (flag & APF_FACEDRAW)
324 {
325 for (p = _p, i = 0; i < np; i++, p++)
326 {
327
328 v = p->v;
329 if ((j = p->n_vertices) <= 2)
330 nonsurf = i;
331 else
332 {
333 if (flag & APF_EDGEDRAW)
334 {
335 if (shading == APF_FLAT || shading == APF_CONSTANT) {
336 mgps_add(MGX_BGNEPOLY, 0, NULL, NULL);
337 } else
338 if (plflags & PL_HASVCOL)
339 mgps_add(MGX_BGNSEPOLY, 0, NULL, NULL);
340 else
341 mgps_add(MGX_BGNEPOLY, 0, NULL, NULL);
342 mgps_add(MGX_ECOLOR, 0, NULL, &_mgc->astk->ap.mat->edgecolor);
343 }
344 else
345 {
346 if (shading == APF_FLAT || shading == APF_CONSTANT) {
347 mgps_add(MGX_BGNPOLY, 0, NULL, NULL);
348 } else
349 if (plflags & PL_HASVCOL)
350 mgps_add(MGX_BGNSPOLY, 0, NULL, NULL);
351 else
352 mgps_add(MGX_BGNPOLY, 0, NULL, NULL);
353 }
354
355 if (plflags & PL_HASPCOL)
356 mgps_add(MGX_COLOR, 0, NULL, &p->pcol);
357 else
358 if (plflags & PL_HASVCOL) /* if we have per vertex */
359 mgps_add(MGX_COLOR, 0, NULL, &(*v)->vcol);
360 else
361 mgps_add(MGX_COLOR, 0, NULL, &(ma->ap.mat->diffuse));
362 vh = v;
363 do
364 {
365 if (plflags & PL_HASVCOL) mgps_add(MGX_CVERTEX, 1, &(*v)->pt, &(*v)->vcol);
366 else
367 mgps_add(MGX_CVERTEX, 1, &(*v)->pt, &(*vh)->vcol);
368
369 v++;
370 } while (--j > 0);
371
372 mgps_add(MGX_END, 0, NULL, NULL);
373 }
374 }
375 }
376 if (flag & (APF_EDGEDRAW | APF_NORMALDRAW) || nonsurf > 0)
377 {
378 if (_mgpsc->znudge) mgps_closer();
379
380 if (flag & APF_EDGEDRAW && !(flag & APF_FACEDRAW))
381 {
382 mgps_add(MGX_ECOLOR, 0, NULL, &_mgc->astk->ap.mat->edgecolor);
383 for (p = _p, i = 0; i < np; i++, p++)
384 {
385 mgps_add(MGX_BGNLINE, 0, NULL, NULL);
386 for (j = 0, v = p->v; j < p->n_vertices; j++, v++)
387 mgps_add(MGX_VERTEX, 1, &(*v)->pt, NULL);
388 mgps_add(MGX_VERTEX, 1, &(*(p->v))->pt, NULL);
389 mgps_add(MGX_END, 0, NULL, NULL);
390 }
391
392 }
393
394 if (flag & APF_NORMALDRAW)
395 {
396 mgps_add(MGX_ECOLOR, 0, NULL, &_mgc->astk->ap.mat->normalcolor);
397 if (pl_flags & PL_HASPN)
398 {
399 for (p = _p, i = 0; i < np; i++, p++)
400 {
401 for (j = 0, v = p->v; j < p->n_vertices; j++, v++)
402 mgps_drawnormal(&(*v)->pt, &p->pn);
403 }
404 }
405 else
406 if (pl_flags & PL_HASVN)
407 {
408 for (vp = V, i = 0; i < nv; i++, vp++)
409 mgps_drawnormal(&vp->pt, &vp->vn);
410 }
411 }
412
413 for (p = _p, i = 0; i <= nonsurf; p++, i++)
414 {
415 v = p->v;
416 switch (j = p->n_vertices)
417 {
418 case 1:
419 mgps_add(MGX_BGNLINE, 0, NULL, NULL);
420 if (pl_flags & PL_HASVCOL)
421 mgps_add(MGX_ECOLOR, 0, NULL, &(*v)->vcol);
422 mgps_add(MGX_VERTEX, 1, &(*v)->pt, NULL);
423 mgps_add(MGX_END, 0, NULL, NULL);
424 break;
425 case 2:
426 mgps_add(MGX_BGNLINE, 0, NULL, NULL);
427 do
428 {
429 if (pl_flags & PL_HASVCOL)
430 mgps_add(MGX_ECOLOR, 0, NULL, &(*v)->vcol);
431 mgps_add(MGX_VERTEX, 1, &(*v)->pt, NULL);
432 v++;
433 } while (--j > 0);
434 mgps_add(MGX_END, 0, NULL, NULL);
435 break;
436 }
437 }
438 if (_mgpsc->znudge) mgps_farther();
439 }
440 }
441
442 #define HAS_N 1
443 #define HAS_C 2
444 #define HAS_SMOOTH 4
445
446 /*-----------------------------------------------------------------------
447 * Function: mgpspolymeshrow
448 * Description: draw one row of a mesh
449 * Author: Daeron Meyer
450 * Notes: See mg.doc.
451 *
452 */
mgpspolymeshrow(int wrap,int has,int off,int count,HPoint3 * P,Point3 * N,ColorA * C,int flag,float * CE,int first)453 void mgpspolymeshrow(int wrap, int has, int off, int count, HPoint3 *P,
454 Point3 *N, ColorA *C, int flag, float *CE, int first)
455 {
456 int k;
457 int edges = flag & APF_EDGEDRAW;
458 int faces = flag & APF_FACEDRAW;
459
460 if (wrap & MM_UWRAP)
461 {
462 k = count - 1;
463 if (edges && faces)
464 {
465 if (has & HAS_SMOOTH)
466 mgps_add(MGX_BGNSEPOLY, 0, NULL, NULL);
467 else
468 mgps_add(MGX_BGNEPOLY, 0, NULL, NULL);
469
470 mgps_add(MGX_ECOLOR, 0, NULL, CE);
471 }
472 else
473 if (faces)
474 {
475 if (has & HAS_SMOOTH)
476 mgps_add(MGX_BGNSPOLY, 0, NULL, NULL);
477 else
478 mgps_add(MGX_BGNPOLY, 0, NULL, NULL);
479 }
480 else
481 {
482 mgps_add(MGX_BGNLINE, 0, NULL, NULL);
483 mgps_add(MGX_ECOLOR, 0, NULL, CE);
484 }
485 if (C)
486 {
487 mgps_add(MGX_COLOR, 0, NULL, C+off+k);
488 C2 = C+off+k;
489 }
490 else
491 mgps_add(MGX_COLOR, 0, NULL, C2);
492
493 if (has & HAS_SMOOTH)
494 {
495 if (C)
496 {
497 mgps_add(MGX_CVERTEX, 1, P+off+k, C+off+k);
498 mgps_add(MGX_CVERTEX, 1, P+k, C+k);
499 mgps_add(MGX_CVERTEX, 1, P, C);
500 mgps_add(MGX_CVERTEX, 1, P+off, C+off);
501 C2 = C+off;
502 }
503 else
504 {
505 mgps_add(MGX_CVERTEX, 1, P+off+k, C2);
506 mgps_add(MGX_CVERTEX, 1, P+k, C2);
507 mgps_add(MGX_CVERTEX, 1, P, C2);
508 mgps_add(MGX_CVERTEX, 1, P+off, C2);
509 }
510 }
511 else
512 {
513 mgps_add(MGX_VERTEX, 1, P+off+k, NULL);
514 mgps_add(MGX_VERTEX, 1, P+k, NULL);
515 mgps_add(MGX_VERTEX, 1, P, NULL);
516 mgps_add(MGX_VERTEX, 1, P+off, NULL);
517 }
518 mgps_add(MGX_END, 0, NULL, NULL);
519 }
520 k = count;
521 do
522 {
523 if (edges && faces)
524 {
525 if (has & HAS_SMOOTH)
526 mgps_add(MGX_BGNSEPOLY, 0, NULL, NULL);
527 else
528 mgps_add(MGX_BGNEPOLY, 0, NULL, NULL);
529
530 mgps_add(MGX_ECOLOR, 0, NULL, CE);
531 }
532 else
533 if (faces)
534 {
535 if (has & HAS_SMOOTH)
536 mgps_add(MGX_BGNSPOLY, 0, NULL, NULL);
537 else
538 mgps_add(MGX_BGNPOLY, 0, NULL, NULL);
539 }
540 else
541 {
542 mgps_add(MGX_BGNLINE, 0, NULL, NULL);
543 mgps_add(MGX_ECOLOR, 0, NULL, CE);
544 /* ADDED */
545 if (first)
546 mgps_add(MGX_VERTEX, 1, P+1+off, NULL);
547 /* END */
548 }
549
550 if (C)
551 {
552 mgps_add(MGX_COLOR, 0, NULL, C+off);
553 C2 = C+off;
554 }
555
556 if (has & HAS_SMOOTH)
557 {
558 if (C) { mgps_add(MGX_CVERTEX, 1, P+off, C+off); C2 = C; }
559 else mgps_add(MGX_CVERTEX, 1, P+off, C2);
560 if (C) { mgps_add(MGX_CVERTEX, 1, P++, C++); C2 = C; }
561 else mgps_add(MGX_CVERTEX, 1, P++, C2);
562 if (C) { mgps_add(MGX_CVERTEX, 1, P, C); C2 = C; }
563 else mgps_add(MGX_CVERTEX, 1, P, C2);
564 if (C) { mgps_add(MGX_CVERTEX, 1, P+off, C+off); C2 = C; }
565 else mgps_add(MGX_CVERTEX, 1, P+off, C2);
566 }
567 else
568 {
569 mgps_add(MGX_VERTEX, 1, P+off, NULL);
570 if (C) C++;
571 if (N) N++;
572 mgps_add(MGX_VERTEX, 1, P++, NULL);
573 mgps_add(MGX_VERTEX, 1, P, NULL);
574 mgps_add(MGX_VERTEX, 1, P+off, NULL);
575 }
576
577 mgps_add(MGX_END, 0, NULL, NULL);
578
579 } while (--k > 1);
580
581 }
582
583 /*-----------------------------------------------------------------------
584 * Function: mgpssubmesh
585 * Description: divide up mesh and draw by rows
586 * Author: Daeron Meyer
587 * Notes: See mg.doc.
588 *
589 */
mgpssubmesh(int wrap,int nu,int nv,int umin,int umax,int vmin,int vmax,HPoint3 * meshP,Point3 * meshN,ColorA * meshC)590 void mgpssubmesh(int wrap, int nu, int nv, int umin, int umax, int vmin,
591 int vmax, HPoint3 *meshP, Point3 *meshN, ColorA *meshC)
592 {
593 int v;
594 int ucnt;
595 HPoint3 *P;
596 Point3 *N;
597 ColorA *C;
598 int prev;
599 int du;
600 int i;
601 int has;
602 Appearance *ap;
603
604
605 if (nu <= 0 || nv <= 0)
606 return;
607
608 ap = &_mgc->astk->ap;
609 if ((_mgc->astk->mat.override & MTF_DIFFUSE) &&
610 !(_mgc->astk->flags & MGASTK_SHADER))
611 meshC = 0;
612
613 has = 0;
614 if (meshN && !(_mgc->astk->flags & MGASTK_SHADER))
615 has = HAS_N;
616 if (meshC)
617 has |= HAS_C;
618 if (IS_SMOOTH(ap->shading))
619 has |= HAS_SMOOTH;
620
621 if ( ap->flag & (APF_FACEDRAW | APF_EDGEDRAW) ) /* BUG? */
622 {
623 if (!(has & HAS_C))
624 mgps_add(MGX_COLOR, 0, NULL, &ap->mat->diffuse);
625
626 C2 = (ColorA *) &ap->mat->diffuse;
627
628 v = vmax - vmin + 1;
629 du = umin + vmin * nu;
630
631 if (wrap & MM_VWRAP)
632 {
633 prev = nu * (v - 1);
634 }
635 else
636 {
637 du += nu;
638 prev = -nu;
639 v--;
640 }
641
642 do
643 {
644 P = meshP + du;
645 N = meshN + du;
646 C = meshC + du;
647 ucnt = umax - umin + 1;
648 mgpspolymeshrow(wrap, has, prev, ucnt, P,
649 has & HAS_N ? N : NULL,
650 has & HAS_C ? C : NULL,
651 ap->flag, (float *)&ap->mat->edgecolor, (int)(v!=1));
652
653 prev = -nu;
654 du += nu;
655 } while (--v > 0);
656 }
657
658 if (ap->flag & APF_NORMALDRAW && meshN != NULL)
659 {
660 mgps_add(MGX_ECOLOR, 0, NULL, &ap->mat->normalcolor);
661
662 if (_mgpsc->znudge)
663 mgps_closer();
664 for (i = nu*nv, P = meshP, N = meshN; --i >= 0; P++, N++)
665 mgps_drawnormal(P, N);
666 if (_mgpsc->znudge)
667 mgps_farther();
668 }
669 }
670
671 /*-----------------------------------------------------------------------
672 * Function: mgps_mesh
673 * Description: draw a mesh
674 * Author: Daeron Meyer
675 * Notes: See mg.doc.
676 *
677 */
mgps_mesh(int wrap,int nu,int nv,HPoint3 * P,Point3 * N,Point3 * NQ,ColorA * C)678 void mgps_mesh(int wrap, int nu, int nv, HPoint3 *P, Point3 *N, Point3 *NQ,
679 ColorA *C )
680 {
681 mgpssubmesh( wrap, nu, nv, 0, nu-1, 0, nv-1, P, N, C);
682 }
683
684 /*-----------------------------------------------------------------------*
685 * end of mesh drawing functions: *
686 *-----------------------------------------------------------------------*/
687
688 /*
689 * Z-shift routines: for moving edges closer than faces, etc.
690 */
691 void
mgps_init_zrange()692 mgps_init_zrange()
693 {
694 _mgpsc->znudge = 1;
695 _mgpsc->znudgeby = 0.0;
696 }
697
698 void
mgps_closer()699 mgps_closer()
700 {
701 /* _mgpsc->znudgeby = 0.001; */
702 }
703
704 void
mgps_farther()705 mgps_farther()
706 {
707 _mgpsc->znudgeby = 0.0;
708 }
709
710 void
mgps_findcam()711 mgps_findcam()
712 {
713 }
714
715 /* There is a basic problem now with 4-d points and 3-d normal vectors.
716 For now, we'll just ignore the 4-th coordinate of the point when
717 computing the tip of the normal vector. This will work OK with all
718 existing models, but for genuine 4-d points it won't work. But,
719 come to think of it, what is the correct interpretation of the
720 normal vector when the points live in 4-d?
721 */
722 void
mgps_drawnormal(HPoint3 * p,Point3 * n)723 mgps_drawnormal(HPoint3 *p, Point3 *n)
724 {
725 Point3 tp;
726 HPoint3 end;
727 Pt3Coord scale, w, s;
728
729 /* fprintf(stderr,"X11: draw a normal\n"); */
730 if (p->w <= 0.0) return;
731 if (p->w != 1) {
732 HPt3ToPt3(p, &tp);
733 p = (HPoint3 *)(void *)&tp;
734 }
735
736 scale = _mgc->astk->ap.nscale;
737 if (_mgc->astk->ap.flag & APF_EVERT) {
738 HPoint3 *cp = &_mgc->cpos;
739 if (!(_mgc->has & HAS_CPOS)) {
740 mg_findcam();
741 }
742 if ((w = cp->w) != 1.0 && w != 0.0) {
743 s = (p->x*w-cp->x)*n->x + (p->y*w-cp->y)*n->y + (p->z*w-cp->z)*n->z;
744 } else {
745 s = (p->x-cp->x)*n->x + (p->y-cp->y)*n->y + (p->z-cp->z)*n->z;
746 }
747 if (s > 0) {
748 scale = -scale;
749 }
750 }
751 end.x = p->x + scale*n->x;
752 end.y = p->y + scale*n->y;
753 end.z = p->z + scale*n->z;
754 end.w = 1.0;
755 mgps_add(MGX_BGNLINE, 0, NULL, NULL);
756 mgps_add(MGX_VERTEX, 1, p, NULL);
757 mgps_add(MGX_VERTEX, 1, &end, NULL);
758 mgps_add(MGX_END, 0, NULL, NULL);
759
760 }
761