This is mgridraw.c in view mode; [Download] [Up]
#include "mgP.h" #include "mgriP.h" #include "polylistP.h" #include <stdlib.h> void mgri_polygon( int nv, HPoint3 *v, int nn, Point3 *n, int nc,ColorA *c ); void mgri_mesh( int wrap,int nu,int nv,HPoint3 *p, Point3 *n,ColorA *c ); void mgri_line( HPoint3 *p1, HPoint3 *p2 ); void mgri_polyline( int nv, HPoint3 *verts, int nc, ColorA *colors, int wrapped ); void mgri_polylist( int np, Poly *p, int nv, Vertex *v, int plflags ); void mgri_drawnormal(HPoint3 *p, Point3 *n, Color* c); void mgri_drawPline(HPoint3 *p1, HPoint3 *p2); /*----------------------------------------------------------------------- * Function: mgri_polygon * Description: draw a polygon * Author: wisdom * Date: Fri Jan 10 13:57:53 CST 1992 * Notes: See mg.doc. * */ void mgri_polygon(int nv, HPoint3 *V, int nn, Point3 *N, int nc, ColorA *C) { register int i, j; register HPoint3 *v; register Point3 *n; register Color *c; register ColorA *c4; HPoint3 hpt; int flag; int shading; int ninc; short colorsdefined; short normalsdefined; short attrblock = 0; flag = _mgc->astk->ap.flag; if ((_mgc->astk->mat.override & MTF_DIFFUSE) && !_mgc->astk->useshader) nc = 0; shading = _mgc->astk->ap.shading; ninc = (nn > 1); if(nc == 0) { C = (ColorA*)&_mgc->astk->ap.mat->diffuse; } CHECK_VCN(nv,nc,nn); /* check nv,nc,nn for overflow */ /* Process input into a form renderman likes */ /* Points */ /* NOTE: although ri reference states that points may be described */ /* with a 4-vector (x,y,z,w) ala the "Pw" token, I can't seem to get */ /* it to work with either Photorealistic or Quick Renderman. sw */ if(nv>0) for(i = 0; i < nv; i++) mgri_normalize(&V[i], ript[i]); if(flag & APF_FACEDRAW) { /* RGB Color */ if (nc>0) { if(nc==1) { RiAttributeBegin(); attrblock=1; RiColor(C); colorsdefined = 0; } else for(i = 0; i < nv; i++) { *(Color *)&ricolor[i] = *(Color *)&C[i]; colorsdefined = 1; } } else colorsdefined = 0; /* Opacity is not supported by QRMan, so it is not handled here */ /* Normals - do not supply with flat shading (constant */ /* interpolation) as this seems to confuse QRMAN */ normalsdefined = 0; if(shading!=APF_FLAT && shading!=APF_CONSTANT && nn>0) { for(i = 0; i < nv; i++) { if(nn>1) *(Point3 *)&rinormal[i] = N[i]; else bcopy((char *)N, (char *)rinormal[i], sizeof(float)*3); } normalsdefined = 1; } /* Define the polygon via the renderman interface */ if(!colorsdefined && normalsdefined) RiPolygon(nv, RI_P, (RtPointer)ript, RI_N, (RtPointer)rinormal, RI_NULL); else if(colorsdefined && !normalsdefined) RiPolygon(nv, RI_P, (RtPointer)ript, RI_CS, (RtPointer)ricolor, RI_NULL); else if(!colorsdefined && !normalsdefined) RiPolygon(nv, RI_P, (RtPointer)ript, RI_NULL); else RiPolygon(nv, RI_P, (RtPointer)ript, RI_CS, (RtPointer)ricolor, RI_N, (RtPointer)rinormal, RI_NULL); } /* Draw Edges */ if(flag & APF_EDGEDRAW) { Transform newbie; float dis; c = &_mgc->astk->ap.mat->edgecolor; RiAttributeBegin(); /* translate object slightly closer to camera */ mgri_closer(); /* now draw it */ RiColor((float *)c); RiGeometricRepresentation("lines"); RiPolygon(nv, RI_P, (RtPointer)ript, RI_NULL); RiAttributeEnd(); } /* Draw Normals */ if(flag & APF_NORMALDRAW) { Color *color = &_mgc->astk->mat.normalcolor; RiAttributeBegin(); RiSurface(RI_CONSTANT, RI_NULL); RiColor((float *)color); for (n = N, v = V, i = 0; i<nv; ++i, ++v, n += ninc) mgri_drawnormal(v, n, color); RiAttributeEnd(); } if(attrblock) RiAttributeEnd(); } /*----------------------------------------------------------------------- * Function: mgri_line * Description: draws a line * Author: wisdom * Date: Fri Jan 17 14:31:06 CST 1992 * Notes: see mg.doc */ void mgri_line( HPoint3 *p1, HPoint3 *p2) { /* lines in QuickRenderman inherit surface properties. */ /* we make sure they are drawn with a constant surface */ RiAttributeBegin(); RiSurface(RI_CONSTANT, RI_NULL); mgri_drawline(p1,p2,&_mgc->astk->mat.edgecolor); RiAttributeEnd(); } /* following passes lines through rman interface */ void mgri_plflush(void) { RiAttributeBegin(); RiShadingInterpolation(RI_SMOOTH); /* hack to color lines correctly */ RiSurface(RI_CONSTANT, RI_NULL); RiPointsLines(_mgric->plni, (RtPointer)plvca, (RtPointer)plvia, RI_P, (RtPointer)plp, RI_CS, (RtPointer)plc, RI_NULL); RiAttributeEnd(); _mgric->plni = 0; _mgric->plvi = 0; } /*----------------------------------------------------------------------- * Function: mgri_polyline * Description: draws a Polyline * Author: wisdom * Date: Fri Nov 5 14:29:45 CST 1993 * Notes: see mg.doc * Feeding too many verticees into the QRMAN 3.0 interface * can cause bad window server crashes. To avoid this, * all geometry is chunked into smaller pieces. No * sharing of verticees is done because there is no 'master * array' of verticees to facilitate this - this array is * broken down. So, we copy and assign verticees as needed. * In addition to breaking geometry down, this routine will * buffer smaller and individual geometry, avoiding a QRMAN * interface call until absolutely needed. This provides better * performance than multiple QRMAN interface calls. * NOTE: This will be re-written to take full advantage of * NS3.1 or greater */ void mgri_polyline( int nv, HPoint3 *V, int nc, ColorA *C, int flags ) { int i; ColorA *color; short colorsdefined = 0; RtColor wrapcolor[2]; RtPoint wrappoint[2]; int wrapped = flags & 1; Color *basecolor; short baseinc; // if(_mgric->plvi+nv > PLBUFFSIZE) { // /* We need to flush the buffers */ // mgri_plflush(); // } if(_mgc->astk->mat.override & MTF_EDGECOLOR) nc = 0; if(nc==0) { basecolor = (Color *)&_mgc->astk->mat.edgecolor; baseinc = 0; } else if(nc==1) { basecolor = (Color *)&C[0]; baseinc = 0; } else { basecolor = (Color *)&C[0]; baseinc = 1; } /* process points */ if(nv>1) { for(i = 0; i < nv-1; i++) { plvca[_mgric->plni++] = 2; plvia[_mgric->plvi] = _mgric->plvi; plvia[_mgric->plvi+1] = _mgric->plvi+1; mgri_normalize(&V[i], plp[_mgric->plvi]); mgri_normalize(&V[i+1], plp[_mgric->plvi+1]); *(Color *)&plc[_mgric->plvi] = *(Color *)basecolor; *(Color *)&plc[_mgric->plvi+1] = *(Color *)(basecolor+baseinc); _mgric->plvi+=2; basecolor += baseinc; if(_mgric->plvi> _mgric->plbuffsize) mgri_plflush(); } plvca[_mgric->plni++] = 2; plvia[_mgric->plvi] = _mgric->plvi; plvia[_mgric->plvi+1] = _mgric->plvi+1; mgri_normalize(&V[i-1], plp[_mgric->plvi]); mgri_normalize(&V[i], plp[_mgric->plvi+1]); *(Color *)&plc[_mgric->plvi] = *(Color *)basecolor; *(Color *)&plc[_mgric->plvi+1] = *(Color *)(basecolor+baseinc); _mgric->plvi+=2; basecolor += baseinc; } if(nv==1) { /* This is a single point. Notice that we do not define the * vertex only once. Tests indicate that color is not propperly * assigned to a point if only a single vertex is used to define * it. However, two equal verticees appears to overcome this * potential problem. */ plvca[_mgric->plni] = 2; plvia[_mgric->plvi] = _mgric->plvi; plvia[_mgric->plvi+1] = _mgric->plvi+1; mgri_normalize(&V[0], plp[_mgric->plvi]); *(Point3 *)&plp[_mgric->plvi+1] = *(Point3 *)&plp[_mgric->plvi]; /* mgri_normalize(&V[0], plp[_mgric->plvi+1]); */ *(Color *)&plc[_mgric->plvi] = *(Color *)basecolor; *(Color *)&plc[_mgric->plvi+1] = *(Color *)basecolor; _mgric->plni++; _mgric->plvi+=2; if(_mgric->plvi> _mgric->plbuffsize) mgri_plflush(); } else if(wrapped) { plvca[_mgric->plni] = 2; plvia[_mgric->plvi] = _mgric->plvi; plvia[_mgric->plvi+1] = _mgric->plvi+1; mgri_normalize(&V[0], plp[_mgric->plvi]); mgri_normalize(&V[nv-1], plp[_mgric->plvi+1]) *(Color *)&plc[_mgric->plvi] = *(Color *)basecolor; *(Color *)&plc[_mgric->plvi+1] = *(Color *)basecolor; _mgric->plni++; _mgric->plvi+=2; if(_mgric->plvi > _mgric->plbuffsize) mgri_plflush(); } } /*----------------------------------------------------------------------- * Function: mgri_polylist * Description: draws a Polylist: linked list of Polys * Author: wisdom * Date: Fri Nov 5 14:32:04 CST 1993 * Notes: * mgri_polylist provides three primary methods to draw polyhedra: * Currently, number 3 is used. * 1. Seperate Polygons * _mgric->polymode == MGRI_POLYGONS (OBSOLETE) * Advantage: Colors and Normals can be properly utilized. * Also, MUCH less likely to crash the Windowserver. * Disadvantage: *SLOW* * 2. (single/multiple) RiPointsPolygons call(s) * _mgric->polymode == MGRI_POINTSPOLYGONS * Advantage: An order of magnitude faster for large polyhedra. * Disadvantage: VERY unstable(NS3.0), but some failsafes are set * by default (via the context). When QRMan matures, all * safegaurds should be removed. Also, per polygon normals cannot * be realized by RiPointsPolygons so QRMan computes vertex * normals. * 3. Devided Polylist * _mgric->polymode == MGRI_DEVIDEDPOLYLIST * The geometry is broken into peices, and fed one piece * at a time through the QRMan interface. * */ void mgri_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; Color *color; ColorA *colorA; int colorsdefined; int normalsdefined; int nc = nv; int nn = nv; int nvert; int ppi; //points polygon index int pvi; //points vertex index static int first = 0; flag = _mgc->astk->ap.flag; shading = _mgc->astk->ap.shading; /* 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; */ //Following was added at the last second in attempt to make //overide work. I guess this has changed, I'm not sure if this //sniglet from the gl code is all that is needed switch(shading) { case APF_FLAT: plflags &= ~PL_HASVN; break; case APF_SMOOTH: plflags &= ~PL_HASPN; break; default: plflags &= ~(PL_HASVN|PL_HASPN); break; } if ((_mgc->astk->mat.override & MTF_DIFFUSE) && !_mgc->astk->useshader) plflags &= ~(PL_HASVCOL | PL_HASPCOL); CHECK_VCN(nv,nv,nn); if(_mgric->polymode == MGRI_POLYGONS) { if (flag & APF_FACEDRAW) { RiAttributeBegin(); for (p = P, i = 0; i < np; i++, p++) { /* per polygon color */ if (plflags & PL_HASPCOL) RiColor((float *)&p->pcol); /* Points */ for (j=0, v=p->v; j < p->n_vertices; j++, v++) { mgri_normalize(&(*v)->pt, ript[j]); } /* colors, if supplied */ if(plflags & PL_HASVCOL) { for (j=0, v=p->v; j < p->n_vertices; j++, v++) *(Color *)&ricolor[j] = *(Color *)&(*v)->vcol; colorsdefined=1; } else colorsdefined=0; /* Opacity is not yet supported by Quick Renderman */ /* Normals - do not supply with flat shading (constant */ /* interpolation) as this seems to confuse QRMAN */ normalsdefined=0; if(shading!=APF_FLAT) { if(plflags & PL_HASVN) { for (j=0, v=p->v; j < p->n_vertices; j++, v++) *(Point3 *)&rinormal[j] = (*v)->vn; normalsdefined=1; } else if(plflags & PL_HASPN) { for(j=0, v=p->v; j< p->n_vertices; j++, v++) *(Point3 *)&rinormal[j] = p->pn; normalsdefined=1; } } /* Define the polygon via the renderman interface */ if(!colorsdefined && normalsdefined) RiPolygon(p->n_vertices, RI_P, (RtPointer)ript, RI_N, (RtPointer)rinormal, RI_NULL); else if(colorsdefined && !normalsdefined) RiPolygon(p->n_vertices, RI_P, (RtPointer)ript, RI_CS, (RtPointer)ricolor, RI_NULL); else if(!colorsdefined && !normalsdefined) RiPolygon(p->n_vertices, RI_P, (RtPointer)ript, RI_NULL); else RiPolygon(p->n_vertices, RI_P, (RtPointer)ript, RI_CS, (RtPointer)ricolor, RI_N, (RtPointer)rinormal, RI_NULL); } /* for */ RiAttributeEnd(); } /* APF_FACEDRAW */ if (flag & APF_EDGEDRAW) { color = &_mgc->astk->ap.mat->edgecolor; RiAttributeBegin(); RiSurface(RI_CONSTANT, RI_NULL); RiColor((float *)color); mgri_closer(); /* the following can be made MUCH more efficient */ /* if we buffer groups of points (polygons) and */ /* draw all at once. */ for (p = P, i = 0; i < np; i++, p++) { for (j=0, v=p->v; j < (p->n_vertices-1); j++, v++) mgri_drawline((HPoint3 *)*v,(HPoint3 *)*(v+1),color); mgri_drawline((HPoint3 *)*v,(HPoint3 *)*(p->v),color); } RiAttributeEnd(); } /* APF_EDGEDRAW */ } /* MGRI_POLYGONS */ else if(_mgric->polymode == MGRI_POINTSPOLYGONS) { /* normalize all verticies (colors) */ if(plflags & PL_HASVCOL) { for(i=0, vp=V; i<nv; i++, vp++) { mgri_normalize(&(vp->pt), ript[i]); //*(Color *)&ricolor[i] = *(Color *)&(vp->vcol); } } else for(i=0,vp=V; i<nv; i++, vp++) mgri_normalize(&(vp->pt), ript[i]); /* check for rippi overflow */ if(np>rippis) { rippis = np + 500; rippi = (int *)realloc(rippi, rippis*sizeof(int)); } ppi = pvi = 0; if(flag & APF_FACEDRAW) { for(p = P, i=0; i < np; i++, p++, ppi++) { int nvert = p->n_vertices; if(ppi >= _mgric->fflushlimit) { RiPointsPolygons(ppi, rippi, ripvi, RI_P, ript, RI_CS, ricolor, RI_NULL); ppi = pvi = 0; } rippi[ppi] = nvert; /* check for ripvi overflow */ if(nvert+pvi > ripvis) { ripvis = nvert + pvi + 500; ripvi = (int *)realloc(ripvi, ripvis*sizeof(int)); } if(plflags & PL_HASPCOL) { for(j=0, v=p->v; j < nvert; j++, v++, pvi++) { ripvi[pvi] = (*v) - V; *(Color *)&ricolor[pvi] = *(Color *)&(p->pcol); } } else { for(j=0, v=p->v; j < nvert; j++, v++, pvi++) { ripvi[pvi] = (*v) - V; /* int index into vertex list */ *(Color *)&ricolor[pvi] = *(Color *)&(*v)->vcol; /* already done */ } } } /* for */ RiPointsPolygons(ppi, rippi, ripvi, RI_P, ript, RI_CS, ricolor, RI_NULL); } /* APF_FACEDRAW */ ppi = pvi = 0; if(flag & APF_EDGEDRAW) { RiAttributeBegin(); RiGeometricRepresentation(RI_LINES); RiColor((float *)&_mgc->astk->mat.edgecolor); for(p = P, i=0; i < np; i++, p++, ppi++) { int nvert = p->n_vertices; if(ppi > _mgric->lflushlimit) { RiPointsPolygons(ppi, rippi, ripvi, RI_P, ript, RI_NULL); ppi = pvi = 0; } rippi[ppi] = nvert; /* check for ripvi overflow */ if(nvert+pvi > ripvis) { ripvis = nvert + pvi + 500; ripvi = (int *)realloc(ripvi, ripvis*sizeof(int)); } if(plflags & PL_HASPCOL) { for(j=0, v=p->v; j < nvert; j++, v++, pvi++) { ripvi[pvi] = (*v) - V; } } else { for(j=0, v=p->v; j < nvert; j++, v++, pvi++) { ripvi[pvi] = (*v) - V; *(Color *)&ricolor[i] = *(Color *)&(*v)->vcol; //already done } } } /* for */ RiPointsPolygons(ppi, rippi, ripvi, RI_P, ript, RI_NULL); RiAttributeEnd(); } /* APF_EDGEDRAW */ } /* MGRI_POINTSPOLYGONS */ else if(_mgric->polymode == MGRI_DEVIDEDPOLYLIST) { /* create local buffers - these are fixed */ /* and need not be checked for overflow */ static RtPoint gp[GVMAXF+100]; /* vertices */ static RtPoint gn[GVMAXF+100]; /* normals */ static RtColor gc[GVMAXF+100]; /* colors */ static int gvc[GVMAXF]; /* polygon vertex count array */ static int gvi[GVMAXF+100]; /* vertex index array */ /* we will use ript for holding normalized vertices */ for(i=0,vp=V; i<nv; i++, vp++) mgri_normalize(&(vp->pt), ript[i]); ppi = pvi = 0; if(flag & APF_FACEDRAW && plflags & PL_HASVN && plflags & PL_HASPCOL) { for(p = P, i=0; i < np; i++, p++, ppi++) { nvert = p->n_vertices; if(pvi+nvert >= GVMAXF) { RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_N, gn, RI_CS, gc, RI_NULL); ppi = pvi = 0; } gvc[ppi] = nvert; for(j=0, v=p->v; j < nvert; j++, v++, pvi++) { gvi[pvi] = pvi; *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)]; *(Color *)&gc[pvi] = *(Color *)&(p->pcol); *(Point3 *)&gn[pvi] = *(Point3 *)&((*v)->vn); } } /* for */ RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_N, gn, RI_CS, gc, RI_NULL); } else if(flag & APF_FACEDRAW && plflags & PL_HASVN && plflags & PL_HASVCOL) { for(p = P, i=0; i < np; i++, p++, ppi++) { nvert = p->n_vertices; if(pvi+nvert >= GVMAXF) { RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_N, gn, RI_CS, gc, RI_NULL); ppi = pvi = 0; } gvc[ppi] = nvert; for(j=0, v=p->v; j < nvert; j++, v++, pvi++) { gvi[pvi] = pvi; *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)]; *(Point3 *)&gn[pvi] = *(Point3 *)&((*v)->vn); *(Color *)&gc[pvi] = *(Color *)&((*v)->vcol); } } /* for */ RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_N, gn, RI_CS, gc, RI_NULL); } else if(flag & APF_FACEDRAW && plflags & PL_HASVN) { for(p = P, i=0; i < np; i++, p++, ppi++) { nvert = p->n_vertices; if(pvi+nvert >= GVMAXF) { RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_N, gn, RI_NULL); ppi = pvi = 0; } gvc[ppi] = nvert; for(j=0, v=p->v; j < nvert; j++, v++, pvi++) { gvi[pvi] = pvi; *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)]; *(Point3 *)&gn[pvi] = *(Point3 *)&((*v)->vn); } } /* for */ RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_N, gn, RI_NULL); } else if(flag & APF_FACEDRAW && plflags & PL_HASPCOL) { for(p = P, i=0; i < np; i++, p++, ppi++) { nvert = p->n_vertices; if(pvi+nvert >= GVMAXF) { RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_CS, gc, RI_NULL); ppi = pvi = 0; } gvc[ppi] = nvert; for(j=0, v=p->v; j < nvert; j++, v++, pvi++) { gvi[pvi] = pvi; *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)]; *(Color *)&gc[pvi] = *(Color *)&(p->pcol); } } /* for */ RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_CS, gc, RI_NULL); } else if(flag & APF_FACEDRAW && plflags & PL_HASVCOL) { for(p = P, i=0; i < np; i++, p++, ppi++) { nvert = p->n_vertices; if(pvi+nvert >= GVMAXF) { RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_CS, gc, RI_NULL); ppi = pvi = 0; } gvc[ppi] = nvert; for(j=0, v=p->v; j < nvert; j++, v++, pvi++) { gvi[pvi] = pvi; *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)]; *(Color *)&gc[pvi] = *(Color *)&((*v)->vcol); } } /* for */ RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_CS, gc, RI_NULL); } else if(flag & APF_FACEDRAW) { for(p = P, i=0; i < np; i++, p++, ppi++) { nvert = p->n_vertices; if(pvi+nvert >= GVMAXF) { RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_NULL); ppi = pvi = 0; } gvc[ppi] = nvert; for(j=0, v=p->v; j < nvert; j++, v++, pvi++) { gvi[pvi] = pvi; *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)]; } } /* for */ RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_NULL); } ppi = pvi = 0; if(flag & APF_EDGEDRAW) { RiAttributeBegin(); RiGeometricRepresentation(RI_LINES); mgri_closer(); color = &_mgc->astk->ap.mat->edgecolor; RiColor((float *)color); for(p = P, i=0; i < np; i++, p++, ppi++) { int nvert = p->n_vertices; if(pvi+nvert >= GVMAXF) { RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_NULL); ppi = pvi = 0; } gvc[ppi] = nvert; for(j=0, v=p->v; j < nvert; j++, v++, pvi++) { gvi[pvi] = pvi; *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)]; } } /* for */ RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_NULL); RiAttributeEnd(); } } /* polylist methods share a common normal * drawing routine, if that's selected. However * since MGRI_POINTSPOLYGONS method relies on * qrman computing normals, showing these normals * in that mode is misleading. Suggestions? */ if (flag & APF_NORMALDRAW) { Color *color = &_mgc->astk->mat.normalcolor; RiAttributeBegin(); RiSurface(RI_CONSTANT, RI_NULL); RiColor((float *)color); 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++) mgri_drawnormal(&(*v)->pt, &p->pn, color); } else if (plflags & PL_HASVN) { for (vp = V, i = 0; i < nv; i++, vp++) { mgri_drawnormal(&vp->pt, &vp->vn, color); } } RiAttributeEnd(); } } /* 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? */ /* also, there is the fact that this function now requires a color */ void mgri_drawnormal(HPoint3 *p, Point3 *n, Color *theColor) { HPoint3 scaledn,end, tp; float scale; scale = _mgc->astk->ap.nscale; if (p->w < 0.0) return; HPt3Normalize(p, &tp); Pt3Mul(scale, n, &scaledn); scaledn.w = 0.0; HPt3Add(&tp, &scaledn, &end); mgri_drawline(&tp,&end,theColor); } void mgri_drawline(HPoint3 *p1, HPoint3 *p2, Color *theColor) { /* * Don't call this function directly unless you have set * a constant surface, otherwise the line will inherit the * current surface attributes. */ // following is special case for thick lines // disabled for now - this doesn't work well // if(_mgc->astk->ap.linewidth>1.0) // mgri_drawPline(p1, p2); //following is old way to draw lines // mgri_normalize(p1, ript[0]); // mgri_normalize(p2, ript[1]); // RiLine(2, RI_P, (RtPointer)ript, RI_NULL); //following is newer FASTER way to draw lines (buffering) //however, I'm not sure if the colors will work right plvca[_mgric->plni++] = 2; plvia[_mgric->plvi] = _mgric->plvi; plvia[_mgric->plvi+1] = _mgric->plvi+1; *(Color *)&plc[_mgric->plvi] = *(Color *)theColor; *(Color *)&plc[_mgric->plvi+1] = *(Color *)theColor; mgri_normalize(p1, plp[_mgric->plvi]); mgri_normalize(p2, plp[_mgric->plvi+1]); _mgric->plvi+=2; if(_mgric->plvi> _mgric->plbuffsize) mgri_plflush(); } /*----------------------------------------------------------------------- * Function: mgri_drawPline * Description: Experimental thick line drawing procedure * Author: wisdom * Date: Sat Feb 20 15:47:11 CST 1993 * Notes: */ void mgri_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(_mgc->O2S, p1, &s1); HPt3TransPt3(_mgc->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 */ for(i=0;i<4;i++) { HPt3Transform(_mgc->S2O, &pnts[i], &pnts[i]); HPt3Normalize(&pnts[i], &pnts[i]); } /* DRAW HERE */ RiPolygon(4, RI_P, (RtPointer)pnts, RI_NULL); } /*----------------------------------------------------------------------- * Function: mgri_drawpoint * Description: draws a point for rman. * Returns: nothing * Author: wisdom * Date: Fri Mar 13 15:04:01 CST 1992 * Notes: This is now done in mgri_polyline */ void mgri_drawpoint(HPoint3 *p) { mgri_normalize(p, ript[0]); //RiLine(1, RI_P, &ript, RI_NULL); << This won't draw point in right color! bcopy( ript[0], ript[1], sizeof(RtPoint)); RiLine(2, RI_P, (RtPointer)ript, RI_NULL); } void mgri_closer() { Transform Tscale, T1, T2, T3, Tcloser; float scaleby; if(!_mgc->zfnudge) return; scaleby = 1.-(_mgc->zfnudge*100.); TmScale(Tscale, scaleby, scaleby, scaleby); TmConcat(_mgc->xstk->T, _mgc->W2C, T1); TmConcat(T1, Tscale, T2); TmConcat(T2, _mgc->C2W, Tcloser); RiTransform(Tcloser); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.