From 6e07ce8f0c6c77b61cfa2f8be54781160018ff91 Mon Sep 17 00:00:00 2001 From: dos-reis Date: Sun, 9 Mar 2008 03:47:21 +0000 Subject: * graph/: Depamphletize. * include/addfile.h: Move from hyper. * include/addfile.H1: Move external declarations into addfile.h. Remove. --- src/graph/view3D/project3d.c | 425 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 425 insertions(+) create mode 100644 src/graph/view3D/project3d.c (limited to 'src/graph/view3D/project3d.c') diff --git a/src/graph/view3D/project3d.c b/src/graph/view3D/project3d.c new file mode 100644 index 00000000..4108ec0e --- /dev/null +++ b/src/graph/view3D/project3d.c @@ -0,0 +1,425 @@ +/* + Copyright (C) 1991-2002, The Numerical ALgorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of The Numerical ALgorithms Group Ltd. nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define _PROJECT3D_C +#include "axiom-c-macros.h" +#include + +#include "header.h" +#include "draw.h" +#include "mode.h" /* for #define components */ + +#include "all_3d.H1" + +/******************************************* + * void project(aViewTriple,someXpoints,i) * + * * + * orthogonal projection for a point * + * setting the ith Xpoint as well * + *******************************************/ + +void +#ifdef _NO_PROTO +project(aViewTriple,someXpoints,i) +viewTriple *aViewTriple; +XPoint *someXpoints; +int i; +#else +project(viewTriple * aViewTriple,XPoint *someXpoints,int i) +#endif +{ + float Vtmp[4], V[4], V1[4]; + + V[0] = aViewTriple->x; V[1] = aViewTriple->y; + V[2] = aViewTriple->z; V[3] = 1.0; + + if (isNaNPoint(V[0], V[1], V[2])) { + (someXpoints+i)->x = aViewTriple->px = NotPoint; + (someXpoints+i)->y = aViewTriple->py = NotPoint; + return; + } + + V[0] -= viewport->transX; V[1] -= viewport->transY; + V[2] -= viewport->transZ; + vectorMatrix4(V,R1,Vtmp); + + matrixMultiply4x4(S,R,transform); + vectorMatrix4(Vtmp,transform,V1); + + aViewTriple->wx = V1[0]; aViewTriple->wy = V1[1]; + aViewTriple->wz = V1[2]; + + V1[0] *= reScale; V1[1] *= reScale; V1[2] *= reScale; + + aViewTriple->pz = V1[2]; + if (viewData.perspective) { + V1[0] *= projPersp(aViewTriple->pz); + V1[1] *= projPersp(aViewTriple->pz); + } + + matrixMultiply4x4(I,T,transform); + vectorMatrix4(V1,transform,V); + V[0] = V[0]*viewScale + xCenter; + V[1] = vwInfo.height - (V[1]*viewScale + yCenter); + + (someXpoints+i)->x = aViewTriple->px = V[0]; + (someXpoints+i)->y = aViewTriple->py = V[1]; +} + + +/*************************************************** + * void projectAPoint(aViewTriple) * + * * + * orthogonal projection for a point. sort of * + * like the above, but no Xpoint assignment * + ***************************************************/ + +void +#ifdef _NO_PROTO +projectAPoint(aViewTriple) + viewTriple *aViewTriple; +#else +projectAPoint(viewTriple *aViewTriple) +#endif +{ + float Vtmp[4], V[4], V1[4]; + + V[0] = aViewTriple->x; V[1] = aViewTriple->y; + V[2] = aViewTriple->z; V[3] = 1.0; + + if (isNaNPoint(V[0], V[1], V[2])) { + aViewTriple->px = NotPoint; + aViewTriple->py = NotPoint; + return; + } + + V[0] -= viewport->transX; V[1] -= viewport->transY; + V[2] -= viewport->transZ; + vectorMatrix4(V,R1,Vtmp); + + matrixMultiply4x4(S,R,transform); + vectorMatrix4(Vtmp,transform,V1); + + aViewTriple->wx = V1[0]; aViewTriple->wy = V1[1]; + aViewTriple->wz = V1[2]; + + V1[0] *= reScale; V1[1] *= reScale; V1[2] *= reScale; + + aViewTriple->pz = V1[2]; + if (viewData.perspective) { + V1[0] *= projPersp(aViewTriple->pz); + V1[1] *= projPersp(aViewTriple->pz); + } + + matrixMultiply4x4(I,T,transform); + vectorMatrix4(V1,transform,V); + V[0] = V[0]*viewScale + xCenter; + V[1] = vwInfo.height - (V[1]*viewScale + yCenter); + + aViewTriple->px = V[0]; + aViewTriple->py = V[1]; +} + + +/*************************** + * void projectAllPoints() * + ***************************/ + +void +#ifdef _NO_PROTO +projectAllPoints() +#else +projectAllPoints(void) +#endif +{ + + int i,j,k; + LLPoint *anLLPoint; + LPoint *anLPoint; + int *anIndex; + + anLLPoint = viewData.lllp.llp; + for (i=0; ilp; + for (j=0; jnumOfLists; j++,anLPoint++) { + anIndex = anLPoint->indices; + for (k=0; knumOfPoints; k++,anIndex++) { + projectAPoint(refPt3D(viewData,*anIndex)); + } /* for points in LPoints (k) */ + } /* for LPoints in LLPoints (j) */ + } /* for LLPoints in LLLPoints (i) */ + +} /* projectAllPoints() */ + + +/******************************* + * void projectAllPolys(pList) * + * * + * orthogonal projection of * + * all the polygons in a given * + * list in one go. pz holds * + * the projected depth info * + * for hidden surface removal. * + * Polygons totally outside of * + * the window dimensions after * + * projection are discarded * + * from the list. * + *******************************/ + +void +#ifdef _NO_PROTO +projectAllPolys (pList) + poly *pList; +#else +projectAllPolys (poly *pList) +#endif +{ + + int i,clipped,clippedPz; + float x0=0.0; + float y0=0.0; + float xA=0.0; + float yA=0.0; + float xB=0.0; + float yB=0.0; + int *anIndex; + viewTriple *aPt; + + strcpy(control->message," Projecting Polygons "); + writeControlMessage(); + + projectAllPoints(); + for (;pList != NIL(poly);pList=pList->next) { + /* totalClip==yes => partialClip==yes (of course) */ + pList->totalClipPz = yes; /* start with 1, AND all points with Pz<0 */ + pList->partialClipPz = no; /* start with 0, OR any points with Pz<0 */ + pList->totalClip = yes; /* same idea, only wrt clip volume */ + pList->partialClip = no; + for (i=0,anIndex=pList->indexPtr; inumpts; i++,anIndex++) { + aPt = refPt3D(viewData,*anIndex); + clipped = outsideClippedBoundary(aPt->x, aPt->y, aPt->z); + pList->totalClip = pList->totalClip && clipped; + pList->partialClip = pList->partialClip || clipped; + clippedPz = behindClipPlane(aPt->pz); + pList->totalClipPz = pList->totalClipPz && clippedPz; + pList->partialClipPz = pList->partialClipPz || clippedPz; + + /* stuff for figuring out normalFacingOut, after the loop */ + if (!i) { + x0 = aPt->px; y0 = aPt->py; + } else if (i==1) { + xA = x0 - aPt->px; yA = y0 - aPt->py; + x0 = aPt->px; y0 = aPt->py; + } else if (i==2) { + xB = aPt->px - x0; yB = aPt->py - y0; + } + } /* for i */ + /* store face facing info */ + /* For now, we shall give faces facing the user a factor of -1, + and faces facing away from the user a factor of +1. this is + to mimic the eye vector (pointing away from the user) dotted + into the surface normal. + This routine is being done because the surface normal in object + space does not transform over to image space linearly and so + has to be recalculated. but the triple product is zero in the + X and Y directions so we just take the Z component, of which, + we just examine the sign. */ + if ((x0 = xA*yB - yA*xB) > machine0) pList->normalFacingOut = 1; + else if (x0 < machine0) pList->normalFacingOut = -1; + else pList->normalFacingOut = 0; + + } + strcpy(control->message,viewport->title); + writeControlMessage(); + +} /* projectAllPolys */ + + + +/******************************* + * void projectAPoly(p) * + * * + * orthogonal projection of * + * all a polygon. pz holds * + * the projected depth info * + * for hidden surface removal * + *******************************/ + + +void +#ifdef _NO_PROTO +projectAPoly (p) + poly *p; +#else +projectAPoly (poly *p) +#endif +{ + + int i,clipped,clippedPz; + float Vtmp[4],V[4],V1[4]; + float x0=0.0; + float y0=0.0; + float xA=0.0; + float yA=0.0; + float xB=0.0; + float yB=0.0; + + int *anIndex; + viewTriple *aPt; + +/* totalClip==yes => partialClip==yes */ + p->totalClipPz = yes; /* start with 1, AND all points with Pz<0 */ + p->partialClipPz = no; /* start with 0, OR any points with Pz<0 */ + p->totalClip = yes; /* same idea, only with respect to clip volume */ + p->partialClip = no; + for (i=0,anIndex=p->indexPtr; inumpts; i++,anIndex++) { + aPt = refPt3D(viewData,*anIndex); + V[0] = aPt->x; V[1] = aPt->y; V[2] = aPt->z; V[3] = 1.0; + + V[0] -= viewport->transX; V[1] -= viewport->transY; + V[2] -= viewport->transZ; + vectorMatrix4(V,R1,Vtmp); + + matrixMultiply4x4(S,R,transform); + vectorMatrix4(Vtmp,transform,V1); + + aPt->wx = V1[0]; aPt->wy = V1[1]; aPt->wz = V1[2]; + + V1[0] *= reScale; V1[1] *= reScale; V1[2] *= reScale; + + aPt->pz = V1[2]; + if (viewData.perspective) { + V1[0] *= projPersp(V1[2]); + V1[1] *= projPersp(V1[2]); + } + + matrixMultiply4x4(I,T,transform); + vectorMatrix4(V1,transform,V); + V[0] = V[0]*viewScale + xCenter; + V[1] = vwInfo.height - (V[1]*viewScale + yCenter); + + aPt->px = V[0]; aPt->py = V[1]; + + clipped = outsideClippedBoundary(aPt->x, aPt->y, aPt->z); + p->totalClip = p->totalClip && clipped; + p->partialClip = p->partialClip || clipped; + clippedPz = behindClipPlane(aPt->pz); + p->totalClipPz = p->totalClipPz && clippedPz; + p->partialClipPz = p->partialClipPz || clippedPz; + + /* stuff for figuring out normalFacingOut, after the loop */ + if (!i) { + x0 = aPt->px; y0 = aPt->py; + } else if (i==1) { + xA = x0 - aPt->px; yA = y0 - aPt->py; + x0 = aPt->px; y0 = aPt->py; + } else if (i==2) { + xB = aPt->px - x0; yB = aPt->py - y0; + } + } + + if ((x0 = xA*yB - yA*xB) > machine0) p->normalFacingOut = 1; + else if (x0 < machine0) p->normalFacingOut = -1; + else p->normalFacingOut = 0; + +} /* projectAPoly */ + + + +/********************************** + * void projectStuff(x,y,z,px,py) * + * * + * sort of like the project stuff * + * in tube.c but used exclusively * + * for the functions of two * + * variables. probably will need * + * to be changed later to be more * + * general (i.e. have everybody * + * use the viewTriple point * + * structure). * + **********************************/ + +void +#ifdef _NO_PROTO +projectStuff(x,y,z,px,py,Pz) + float x,y,z; + int *px,*py; + float *Pz; +#else +projectStuff(float x,float y,float z,int *px,int *py,float *Pz) +#endif +{ + float tempx,tempy,tempz,temps,V[4],V1[4],stuffScale=100.0; + + tempx = viewport->scaleX; + tempy = viewport->scaleY; + tempz = viewport->scaleZ; + temps = viewScale; + + if (viewport->scaleX > 5.0) viewport->scaleX = 5.0; + if (viewport->scaleY > 5.0) viewport->scaleY = 5.0; + if (viewport->scaleZ > 3.0) viewport->scaleZ = 3.0; + if (viewScale > 5.0) viewScale = 5.0; + + V[0] = x; V[1] = y; + V[2] = z; V[3] = 1.0; + + V[0] -= viewport->transX*stuffScale; + V[1] -= viewport->transY*stuffScale; + V[2] -= viewport->transZ*stuffScale; + + matrixMultiply4x4(S,R,transform); + vectorMatrix4(V,transform,V1); + *Pz = V1[2]; + + if (viewData.perspective) { + V1[0] *= projPersp(V1[2]); + V1[1] *= projPersp(V1[2]); + } + + matrixMultiply4x4(I,T,transform); + vectorMatrix4(V1,transform,V); + + V[0] = V[0]*viewScale + xCenter; + V[1] = vwInfo.height - (V[1]*viewScale + yCenter); + + *px = V[0]; + *py = V[1]; + + viewport->scaleX = tempx; + viewport->scaleY = tempy; + viewport->scaleZ = tempz; + viewScale = temps; +} -- cgit v1.2.3