This is mgribdraw.c in view mode; [Download] [Up]
#include "mgP.h" #include "mgribP.h" #include "mgribtoken.h" #include "polylistP.h" #define MAXCLINE 999999 void mgrib_drawPline(HPoint3 *p1, HPoint3 *p2); void mgrib_drawCline(HPoint3 *p1, HPoint3 *p2); void mgrib_polygon( int nv, HPoint3 *v, int nn, Point3 *n, int nc,ColorA *c ); void mgrib_mesh( int wrap,int nu,int nv,HPoint3 *p, Point3 *n,ColorA *c ); void mgrib_line( HPoint3 *p1, HPoint3 *p2 ); void mgrib_polyline( int nv, HPoint3 *verts, int nc, ColorA *colors, int wrapped ); void mgrib_polylist( int np, Poly *p, int nv, Vertex *v, int plflags ); void mgrib_drawnormal(HPoint3 *p, Point3 *n); /*----------------------------------------------------------------------- * Function: mgrib_polygon * Description: draw a polygon * Author: wisdom * Date: Thu Aug 26 13:46:25 CDT 1993 * Notes: See mg.doc. * */ void mgrib_polygon(int nv, HPoint3 *V, int nn, Point3 *N, int nc, ColorA *C) { register int i; register HPoint3 *v; register Point3 *n; register Color *c; register ColorA *c4; HPoint3 hpt; int flag; int shading; int matover; int ninc; flag = _mgc->astk->ap.flag; shading = _mgc->astk->ap.shading; matover = _mgc->astk->mat.override; ninc = (nn > 1); if ((matover & MTF_DIFFUSE) && !_mgc->astk->useshader) nc = 0; mrti(mr_polygon,mr_NULL); /* Points */ if(nv>0 && (flag & APF_FACEDRAW)) { mrti(mr_P,mr_buildarray, nv*3, mr_NULL); for(i = 0; i < nv; i++) { /* we cannot descibe a polygon using Pw, so we normalize */ HPt3Normalize(&V[i], &hpt); mrti(mr_subarray3, &hpt, mr_NULL); } } /* Supply Color (explicit) */ if (nc>0 && (flag & APF_FACEDRAW) && !(flag & APF_CONSTANT)) { /* note:color should already be set in case of APF_CONSTANT,no? */ mrti(mr_Cs, mr_buildarray, nv*3, mr_NULL); for(i = 0; i < nv; i++) { if(nc>1) c4 = &C[i]; else c4 = C; mrti(mr_subarray3, (float *)c4, mr_NULL); } } /* Supply Transparency */ if(nc>0 && flag & APF_TRANSP && !(matover & MTF_ALPHA)) { mrti(mr_Os, mr_buildarray, nv*3, mr_NULL); for(i = 0; i < nv; i++) { float opacity[3]; if(nc>1) c4 = &C[i]; else c4 = C; opacity[0]=opacity[1]=opacity[2]=c4->a; mrti(mr_subarray3, opacity, mr_NULL); } } /* Supply Normals */ if (nn>0 && (flag & APF_FACEDRAW) && !(flag & APF_CONSTANT)) { mrti(mr_N, mr_buildarray, nv*3, mr_NULL); for(i = 0; i < nv; i++) { if(nn>1) n = &N[i]; else n = N; mrti(mr_subarray3, n, mr_NULL); } } /* Draw Edges */ if(flag & APF_EDGEDRAW) { c = &_mgc->astk->ap.mat->edgecolor; mrti(mr_attributebegin, mr_surface, mr_constant, mr_color, mr_parray, 3, c, mr_opacity, mr_array, 3, 1., 1., 1., mr_NULL); for(i=0;i<nv-1;i++) mgrib_drawline(&V[i],&V[i+1]); mgrib_drawline(&V[i],&V[0]); mrti(mr_attributeend, mr_NULL); } /* Draw Normals */ if(flag & APF_NORMALDRAW) { for (n = N, v = V, i = 0; i<nv; ++i, ++v, n += ninc) mgrib_drawnormal(v, n); } } /*----------------------------------------------------------------------- * Function: mgrib_line * Description: draws a line * Author: wisdom * Date: Fri Jan 17 14:31:06 CST 1992 * Notes: see mg.doc */ void mgrib_line( HPoint3 *p1, HPoint3 *p2 ) { mrti(mr_attributebegin, mr_surface, mr_constant, mr_NULL); mgrib_drawline(p1,p2); mrti(mr_attributeend, mr_NULL); } /*----------------------------------------------------------------------- * Function: mgrib_drawline, mgrib_drawPline, mgrib_drawCline, bounded * Description: draws a line for rman. * Returns: nothing * Author: wisdom, gunn, slevy, munzner * Date: Tue Feb 18 14:20:29 CST 1992 * Notes: */ void mgrib_drawline(HPoint3 *p1, HPoint3 *p2) { if(_mgribc->line_mode==MG_RIBPOLYGON) mgrib_drawPline(p1,p2); if(_mgribc->line_mode==MG_RIBCYLINDER) mgrib_drawCline(p1,p2); if(_mgribc->line_mode==MG_RIBPRMANLINE) NotImplemented("MG_RIBPRMANLINE"); } void mgrib_drawPline(HPoint3 *p1, HPoint3 *p2) { Transform V; Transform P2S,O2S, O2P, P2O, S2O; int xsize, ysize; HPoint3 pnts[4], pnts2[4]; HPoint3 s1, s2; int i; float dx,dy,k, len; /* This code will simulate line drawing in Photorman */ /* create obj->proj transform */ CamView(_mgc->cam, V); /* world->proj */ TmConcat(_mgc->xstk->T, V, O2P); /* obj->proj */ /* create obj->screen transform */ WnGet(_mgc->win, WN_XSIZE, &xsize); WnGet(_mgc->win, WN_YSIZE, &ysize); TmScale(P2S, (float)xsize, (float)ysize, 1.0); TmConcat(O2P, P2S, O2S); /* translate & dehomogenize line endpoints from object to screen */ HPt3TransPt3(O2S, p1, &s1); HPt3TransPt3(O2S, p2, &s2); dy = s2.y - s1.y; dx = s2.x - s1.x; len = hypot(dy,dx); k = _mgc->astk->ap.linewidth / len; pnts[0].x = s1.x -dy * k; pnts[0].y = s1.y +dx * k; pnts[1].x = s1.x +dy * k; pnts[1].y = s1.y -dx * k; pnts[2].x = s2.x +dy * k; pnts[2].y = s2.y -dx * k; pnts[3].x = s2.x -dy * k; pnts[3].y = s2.y +dx * k; pnts[0].z = s1.z; pnts[1].z = s1.z; pnts[2].z = s2.z; pnts[3].z = s2.z; for (i=0; i<4; ++i) pnts[i].w = 1.0; /* now project back... */ /* first, find S2O transform */ TmInvert(O2S, S2O); /* now transform screen coords to object coords */ /* DRAW HERE */ mrti(mr_polygon, mr_P, mr_buildarray, 4*3, mr_NULL); for(i=0;i<4;i++) { HPoint3 pt; HPt3Transform(S2O, &pnts[i], &pt); HPt3Normalize(&pt, &pt); mrti(mr_subarray3, &pt, mr_NULL); } } void mgrib_drawCline(HPoint3 *p1, HPoint3 *p2) { Pt3Coord angle,length; Point3 t,xn,yn,axis; Point3 start, end; HPoint3 Hstart, Hend; static float unitz[3] = {0.0, 0.0, 1.0}; float radius = .005; float size; int bounded(Point3 *p); HPt3Normalize(p1, &Hstart); HPt3Normalize(p2, &Hend); start.x = Hstart.x; start.y = Hstart.y; start.z = Hstart.z; end.x = Hend.x; end.y = Hend.y; end.z = Hend.z; if (! Pt3Equal(&start,&end)) { size = radius*_mgc->astk->ap.linewidth; Pt3Sub(&end,&start,&t); length = Pt3Length(&t); Pt3Cross((Point3*)unitz,&t,&axis); Pt3Unit(&t); angle = Pt3Dot((Point3*)unitz,&t); angle = acos(angle); mrti(mr_transformbegin, mr_NULL); if (bounded(&start)) mrti(mr_translate, mr_float, start.x, mr_float, start.y, mr_float, start.z, mr_NULL); if ( (t.x == 0.0) && (t.y == 0.0) && (t.z < 0.0)) { /* if along negative z axis cross product is 0 but rotation by 180 degrees is necessary (angle is computed correctly) */ axis.y = 1.0; } if (bounded(&axis)) mrti(mr_rotate, mr_float, DEGREES(angle), mr_float, axis.x, mr_float, axis.y, mr_float, axis.z, mr_NULL); if (length < MAXCLINE) mrti(mr_cylinder, mr_float, size, mr_float, 0., mr_float, length, mr_float, 360., mr_NULL); mrti(mr_transformend, mr_NULL); } } int bounded(p) Point3 *p; { if (! Pt3Equal(p,&Pt3Origin)) { if (p->x < MAXCLINE && p->y < MAXCLINE && p->z < MAXCLINE) return 1; } else { return 0; } } /*----------------------------------------------------------------------- * Function: mgrib_polyline * Description: draws a Polyline * Author: wisdom * Date: Fri Jan 17 14:31:06 CST 1992 * Notes: see mg.doc */ void mgrib_polyline( int nv, HPoint3 *v, int nc, ColorA *c, int wrapped ) { ColorA *color; mrti(mr_attributebegin, mr_surface, mr_constant, mr_NULL); if(nc==0) mrti(mr_color, mr_parray, 3, &_mgc->astk->mat.edgecolor, mr_NULL); if(nc==1) mrti(mr_color, mr_parray, 3, c, mr_NULL); if(nv == 1) { mgrib_drawpoint(v); } else { if(wrapped & 1) { if(nc > 1) { color = c + nc - 1; mrti(mr_color, mr_parray, 3, color, mr_NULL); } mgrib_drawline(v + nv - 1,v); } while(--nv > 0) { if(nc > 1) { color = c++; mrti(mr_color, mr_parray, 3, color, mr_NULL); } mgrib_drawline(v,(v+1)); v++; } } mrti(mr_attributeend, mr_NULL); } /*----------------------------------------------------------------------- * Function: mgrib_drawpoint * Description: draws a point for rman. * Returns: nothing * Author: wisdom * Date: Fri Mar 13 15:04:01 CST 1992 * Notes: */ void mgrib_drawpoint(HPoint3 *p) { float radius = 0.005; float size = radius*_mgc->astk->ap.linewidth; mrti(mr_transformbegin, mr_NULL); mrti(mr_translate, mr_float, p->x, mr_float, p->y, mr_float, p->z, mr_NULL); mrti(mr_sphere, mr_float, size, mr_float, size, mr_float, -size, mr_float, 360., mr_NULL); mrti(mr_transformend, mr_NULL); } /*----------------------------------------------------------------------- * Function: mgrib_polylist * Description: draws a Polylist: linked list of Polys * Author: wisdom * Date: Wed Jan 22 16:07:03 CST 1992 * Notes: see mg.doc */ void mgrib_polylist( int np, Poly *P, int nv, Vertex *V, int plflags ) { register int i,j; register Poly *p; register Vertex **v, *vp; register Point3 *n; HPoint3 hpt; int flag,shading,matover; Color *color; ColorA *colorA; flag = _mgc->astk->ap.flag; shading = _mgc->astk->ap.shading; matover = _mgc->astk->mat.override; if((matover & MTF_DIFFUSE) && !_mgc->astk->useshader) plflags &= ~(PL_HASVCOL | PL_HASPCOL); if (shading & APF_CONSTANT) plflags &= ~(PL_HASVN|PL_HASPN); else if (shading & APF_FLAT) plflags &= ~PL_HASVN; else if (shading & APF_SMOOTH) plflags &= ~PL_HASPN; if (flag & APF_FACEDRAW) { mrti(mr_attributebegin, mr_NULL); for (p = P, i = 0; i < np; i++, p++) { /* per polygon color */ if (plflags & PL_HASPCOL) { mrti(mr_color, mr_parray, 3, &p->pcol, mr_NULL); /* then per-polygon transparency, if defined */ if (flag & APF_TRANSP && !(matover & MTF_ALPHA)) { mrti(mr_Os, mr_array, 3, p->pcol.a, p->pcol.a, p->pcol.a, mr_NULL); } } switch (p->n_vertices) { case 1: v = p->v; mrti(mr_attributebegin, mr_NULL); if(plflags & PL_HASVCOL) mrti(mr_color, mr_parray, 3, &(*v)->vcol, mr_NULL); mrti(mr_surface, mr_constant, mr_opacity, mr_array, 3, 1., 1., 1., mr_NULL); mgrib_drawpoint((HPoint3 *)(*v)); mrti(mr_attributeend, mr_NULL); break; case 2: v = p->v; mrti(mr_attributebegin, mr_NULL); if(plflags & PL_HASVCOL) mrti(mr_color, mr_parray, 3, &(*v)->vcol, mr_NULL); mrti(mr_surface, mr_constant, mr_opacity, mr_array, 3, 1., 1., 1., mr_NULL); mgrib_drawline((HPoint3 *)*v,(HPoint3*)*(v+1)); mrti(mr_attributeend, mr_NULL); break; default: mrti(mr_polygon, mr_NULL); /* do points */ mrti(mr_P, mr_buildarray, p->n_vertices*3, mr_NULL); for (j=0, v=p->v; j < p->n_vertices; j++, v++) { HPt3Normalize(&(*v)->pt, &hpt); mrti(mr_subarray3, &hpt, mr_NULL); } /* colors, if supplied */ if(plflags & PL_HASVCOL) { mrti(mr_Cs, mr_buildarray, p->n_vertices*3, mr_NULL); for (j=0, v=p->v; j < p->n_vertices; j++, v++) { mrti(mr_subarray3, &(*v)->vcol, mr_NULL); } /* then per-vertex transparency, if defined */ if(flag & APF_TRANSP && !(matover & MTF_ALPHA)) { mrti(mr_Os, mr_buildarray, p->n_vertices*3, mr_NULL); for (j=0, v=p->v; j < p->n_vertices; j++, v++) { float opacity[3]; opacity[0]=opacity[1]=opacity[2]=(*v)->vcol.a; mrti(mr_subarray3, opacity, mr_NULL); } } } /* now normals, if supplied */ if(plflags & PL_HASVN) { mrti(mr_N, mr_buildarray, p->n_vertices*3, mr_NULL); for (j=0, v=p->v; j < p->n_vertices; j++, v++) { mrti(mr_subarray3, &((*v)->vn), mr_NULL); } } else if(plflags & PL_HASPN) { mrti(mr_N, mr_buildarray, p->n_vertices*3, mr_NULL); for(j=0, v=p->v; j< p->n_vertices; j++, v++) { mrti(mr_subarray3, &(p->pn), mr_NULL); } } break; } } mrti(mr_attributeend, mr_NULL); } if (flag & APF_EDGEDRAW) { color = &_mgc->astk->ap.mat->edgecolor; mrti(mr_attributebegin, mr_surface, mr_constant, mr_color, mr_parray, 3, color, mr_opacity, mr_array, 3, 1., 1., 1., mr_NULL); for (p = P, i = 0; i < np; i++, p++) { for (j=0, v=p->v; j < (p->n_vertices-1); j++, v++) { mgrib_drawline((HPoint3 *)*v,(HPoint3*)*(v+1)); } mgrib_drawline((HPoint3 *)*v,(HPoint3 *)*(p->v)); } mrti(mr_attributeend,mr_NULL); } if (flag & APF_NORMALDRAW) { /* since mg_drawnormal handles attributes and stacking, we do nothing here */ if (plflags & PL_HASPN) { for (p = P, i = 0; i < np; i++, p++) { for (j=0, v=p->v; j < p->n_vertices; j++, v++) { mgrib_drawnormal(&(*v)->pt, &p->pn); } } } else if (plflags & PL_HASVN) { for (vp = V, i = 0; i < nv; i++, vp++) { mgrib_drawnormal(&vp->pt, &vp->vn); } } } } /* There is a basic problem now with 4-d points and 3-d normal vectors. For now, we'll just ignore the 4-th coordinate of the point when computing the tip of the normal vector. This will work OK with all existing models, but for genuine 4-d points it won't work. But, come to think of it, what is the correct interpretation of the normal vector when the points live in 4-d? */ void mgrib_drawnormal(HPoint3 *p, Point3 *n) { HPoint3 end, tp; float scale; Color *color; if (p->w <= 0.0) return; scale = p->w * _mgc->astk->ap.nscale; end.x = p->x + scale*n->x; end.y = p->y + scale*n->y; end.z = p->z + scale*n->z; end.w = p->w; color = &_mgc->astk->mat.normalcolor; mrti(mr_attributebegin, mr_surface, mr_constant, mr_color, mr_parray, 3, color, mr_opacity, mr_array, 3, 1., 1., 1., mr_NULL); mgrib_drawline(&tp,&end); mrti(mr_attributeend, mr_NULL); } void mgrib_bezier( int du, int dv, int dimn, float *CtrlPnts, float *txmapst, ColorA *c ) { int i, ip, nu, nv; static float *uknot=NULL, *vknot=NULL; static size_t ulen=0,vlen=0; size_t nulen=0, nvlen=0; int flag = _mgc->astk->ap.flag; int matover = _mgc->astk->mat.override; du += 1; dv += 1; nu = du; nv = dv; ip = nu * nv * dimn; if(!uknot) { ulen=nu+du; uknot=(float *)malloc(ulen*sizeof(float)); } if(!vknot) { vlen=nv+dv; vknot=(float *)malloc(vlen*sizeof(float)); } nulen=nu+du; nvlen=nv+dv; if(nulen>ulen) uknot=(float *)realloc(uknot,(ulen=nulen)*sizeof(float)); if(nvlen>vlen) vknot=(float *)realloc(vknot,(vlen=nvlen)*sizeof(float)); /* uknot = (float *)malloc((nu+du)*sizeof(float)); */ for(i=0;i<nu;i++) uknot[i] = 0; for(i=nu;i<(nu+du);i++) uknot[i] = 1; /* vknot = (float *)malloc((nv+dv)*sizeof(float)); */ for(i=0;i<nv;i++) vknot[i] = 0; for(i=nv;i<(nv+dv);i++) vknot[i] = 1; mrti(mr_nupatch, mr_int, nu, mr_int, du, mr_NULL); mrti(mr_parray, (nu+du), uknot, mr_NULL); mrti(mr_int, 0, mr_int, (nu-1), mr_int, nv, mr_int, dv, mr_NULL); mrti(mr_parray, (nv+dv), vknot, mr_NULL); mrti(mr_int, 0, mr_int, nv -1, mr_NULL); mrti(dimn == 3 ? mr_P : mr_Pw, mr_parray, ip, CtrlPnts, mr_NULL); /* free(uknot); */ /* free(vknot); */ if(c && !( (matover & MTF_DIFFUSE) && !_mgc->astk->useshader) ) { mrti(mr_Cs, mr_buildarray, 12, mr_NULL); for (i = 0; i < 4; i++) { mrti(mr_subarray3, (float *)&c[i], mr_NULL); } if(flag & APF_TRANSP && !(matover & MTF_ALPHA)) { float opacity[3]; opacity[0]=opacity[1]=opacity[2]=c[i].a; mrti(mr_Os, mr_buildarray, 12, mr_NULL); for (i = 0; i < 4; i++) { mrti(mr_subarray3, opacity, mr_NULL); } } } if(txmapst) { mrti(mr_nl, mr_st, mr_parray, 8, txmapst, mr_NULL); } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.