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.