1
\documentclass{article}
4
\title{\$SPAD/src/graph/view3D project3d.c}
5
\author{The Axiom Team}
15
Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
18
Redistribution and use in source and binary forms, with or without
19
modification, are permitted provided that the following conditions are
22
- Redistributions of source code must retain the above copyright
23
notice, this list of conditions and the following disclaimer.
25
- Redistributions in binary form must reproduce the above copyright
26
notice, this list of conditions and the following disclaimer in
27
the documentation and/or other materials provided with the
30
- Neither the name of The Numerical ALgorithms Group Ltd. nor the
31
names of its contributors may be used to endorse or promote products
32
derived from this software without specific prior written permission.
34
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
35
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
36
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
37
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
38
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
39
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
40
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
41
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
42
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
43
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56
#include "mode.h" /* for #define components */
60
/*******************************************
61
* void project(aViewTriple,someXpoints,i) *
63
* orthogonal projection for a point *
64
* setting the ith Xpoint as well *
65
*******************************************/
69
project(aViewTriple,someXpoints,i)
70
viewTriple *aViewTriple;
74
project(viewTriple * aViewTriple,XPoint *someXpoints,int i)
77
float Vtmp[4], V[4], V1[4];
79
V[0] = aViewTriple->x; V[1] = aViewTriple->y;
80
V[2] = aViewTriple->z; V[3] = 1.0;
82
if (isNaNPoint(V[0], V[1], V[2])) {
83
(someXpoints+i)->x = aViewTriple->px = NotPoint;
84
(someXpoints+i)->y = aViewTriple->py = NotPoint;
88
V[0] -= viewport->transX; V[1] -= viewport->transY;
89
V[2] -= viewport->transZ;
90
vectorMatrix4(V,R1,Vtmp);
92
matrixMultiply4x4(S,R,transform);
93
vectorMatrix4(Vtmp,transform,V1);
95
aViewTriple->wx = V1[0]; aViewTriple->wy = V1[1];
96
aViewTriple->wz = V1[2];
98
V1[0] *= reScale; V1[1] *= reScale; V1[2] *= reScale;
100
aViewTriple->pz = V1[2];
101
if (viewData.perspective) {
102
V1[0] *= projPersp(aViewTriple->pz);
103
V1[1] *= projPersp(aViewTriple->pz);
106
matrixMultiply4x4(I,T,transform);
107
vectorMatrix4(V1,transform,V);
108
V[0] = V[0]*viewScale + xCenter;
109
V[1] = vwInfo.height - (V[1]*viewScale + yCenter);
111
(someXpoints+i)->x = aViewTriple->px = V[0];
112
(someXpoints+i)->y = aViewTriple->py = V[1];
116
/***************************************************
117
* void projectAPoint(aViewTriple) *
119
* orthogonal projection for a point. sort of *
120
* like the above, but no Xpoint assignment *
121
***************************************************/
125
projectAPoint(aViewTriple)
126
viewTriple *aViewTriple;
128
projectAPoint(viewTriple *aViewTriple)
131
float Vtmp[4], V[4], V1[4];
133
V[0] = aViewTriple->x; V[1] = aViewTriple->y;
134
V[2] = aViewTriple->z; V[3] = 1.0;
136
if (isNaNPoint(V[0], V[1], V[2])) {
137
aViewTriple->px = NotPoint;
138
aViewTriple->py = NotPoint;
142
V[0] -= viewport->transX; V[1] -= viewport->transY;
143
V[2] -= viewport->transZ;
144
vectorMatrix4(V,R1,Vtmp);
146
matrixMultiply4x4(S,R,transform);
147
vectorMatrix4(Vtmp,transform,V1);
149
aViewTriple->wx = V1[0]; aViewTriple->wy = V1[1];
150
aViewTriple->wz = V1[2];
152
V1[0] *= reScale; V1[1] *= reScale; V1[2] *= reScale;
154
aViewTriple->pz = V1[2];
155
if (viewData.perspective) {
156
V1[0] *= projPersp(aViewTriple->pz);
157
V1[1] *= projPersp(aViewTriple->pz);
160
matrixMultiply4x4(I,T,transform);
161
vectorMatrix4(V1,transform,V);
162
V[0] = V[0]*viewScale + xCenter;
163
V[1] = vwInfo.height - (V[1]*viewScale + yCenter);
165
aViewTriple->px = V[0];
166
aViewTriple->py = V[1];
170
/***************************
171
* void projectAllPoints() *
172
***************************/
178
projectAllPoints(void)
187
anLLPoint = viewData.lllp.llp;
188
for (i=0; i<viewData.lllp.numOfComponents; i++,anLLPoint++) {
189
anLPoint = anLLPoint->lp;
190
for (j=0; j<anLLPoint->numOfLists; j++,anLPoint++) {
191
anIndex = anLPoint->indices;
192
for (k=0; k<anLPoint->numOfPoints; k++,anIndex++) {
193
projectAPoint(refPt3D(viewData,*anIndex));
194
} /* for points in LPoints (k) */
195
} /* for LPoints in LLPoints (j) */
196
} /* for LLPoints in LLLPoints (i) */
198
} /* projectAllPoints() */
201
/*******************************
202
* void projectAllPolys(pList) *
204
* orthogonal projection of *
205
* all the polygons in a given *
206
* list in one go. pz holds *
207
* the projected depth info *
208
* for hidden surface removal. *
209
* Polygons totally outside of *
210
* the window dimensions after *
211
* projection are discarded *
213
*******************************/
217
projectAllPolys (pList)
220
projectAllPolys (poly *pList)
224
int i,clipped,clippedPz;
225
float x0, y0, xA, yA, xB, yB;
229
strcpy(control->message," Projecting Polygons ");
230
writeControlMessage();
233
for (;pList != NIL(poly);pList=pList->next) {
234
/* totalClip==yes => partialClip==yes (of course) */
235
pList->totalClipPz = yes; /* start with 1, AND all points with Pz<0 */
236
pList->partialClipPz = no; /* start with 0, OR any points with Pz<0 */
237
pList->totalClip = yes; /* same idea, only wrt clip volume */
238
pList->partialClip = no;
239
for (i=0,anIndex=pList->indexPtr; i<pList->numpts; i++,anIndex++) {
240
aPt = refPt3D(viewData,*anIndex);
241
clipped = outsideClippedBoundary(aPt->x, aPt->y, aPt->z);
242
pList->totalClip = pList->totalClip && clipped;
243
pList->partialClip = pList->partialClip || clipped;
244
clippedPz = behindClipPlane(aPt->pz);
245
pList->totalClipPz = pList->totalClipPz && clippedPz;
246
pList->partialClipPz = pList->partialClipPz || clippedPz;
248
/* stuff for figuring out normalFacingOut, after the loop */
250
x0 = aPt->px; y0 = aPt->py;
252
xA = x0 - aPt->px; yA = y0 - aPt->py;
253
x0 = aPt->px; y0 = aPt->py;
255
xB = aPt->px - x0; yB = aPt->py - y0;
258
/* store face facing info */
259
/* For now, we shall give faces facing the user a factor of -1,
260
and faces facing away from the user a factor of +1. this is
261
to mimic the eye vector (pointing away from the user) dotted
262
into the surface normal.
263
This routine is being done because the surface normal in object
264
space does not transform over to image space linearly and so
265
has to be recalculated. but the triple product is zero in the
266
X and Y directions so we just take the Z component, of which,
267
we just examine the sign. */
268
if ((x0 = xA*yB - yA*xB) > machine0) pList->normalFacingOut = 1;
269
else if (x0 < machine0) pList->normalFacingOut = -1;
270
else pList->normalFacingOut = 0;
273
strcpy(control->message,viewport->title);
274
writeControlMessage();
276
} /* projectAllPolys */
280
/*******************************
281
* void projectAPoly(p) *
283
* orthogonal projection of *
284
* all a polygon. pz holds *
285
* the projected depth info *
286
* for hidden surface removal *
287
*******************************/
295
projectAPoly (poly *p)
299
int i,clipped,clippedPz;
300
float Vtmp[4],V[4],V1[4],
301
x0, y0, xA, yA, xB, yB;
305
/* totalClip==yes => partialClip==yes */
306
p->totalClipPz = yes; /* start with 1, AND all points with Pz<0 */
307
p->partialClipPz = no; /* start with 0, OR any points with Pz<0 */
308
p->totalClip = yes; /* same idea, only with respect to clip volume */
310
for (i=0,anIndex=p->indexPtr; i<p->numpts; i++,anIndex++) {
311
aPt = refPt3D(viewData,*anIndex);
312
V[0] = aPt->x; V[1] = aPt->y; V[2] = aPt->z; V[3] = 1.0;
314
V[0] -= viewport->transX; V[1] -= viewport->transY;
315
V[2] -= viewport->transZ;
316
vectorMatrix4(V,R1,Vtmp);
318
matrixMultiply4x4(S,R,transform);
319
vectorMatrix4(Vtmp,transform,V1);
321
aPt->wx = V1[0]; aPt->wy = V1[1]; aPt->wz = V1[2];
323
V1[0] *= reScale; V1[1] *= reScale; V1[2] *= reScale;
326
if (viewData.perspective) {
327
V1[0] *= projPersp(V1[2]);
328
V1[1] *= projPersp(V1[2]);
331
matrixMultiply4x4(I,T,transform);
332
vectorMatrix4(V1,transform,V);
333
V[0] = V[0]*viewScale + xCenter;
334
V[1] = vwInfo.height - (V[1]*viewScale + yCenter);
336
aPt->px = V[0]; aPt->py = V[1];
338
clipped = outsideClippedBoundary(aPt->x, aPt->y, aPt->z);
339
p->totalClip = p->totalClip && clipped;
340
p->partialClip = p->partialClip || clipped;
341
clippedPz = behindClipPlane(aPt->pz);
342
p->totalClipPz = p->totalClipPz && clippedPz;
343
p->partialClipPz = p->partialClipPz || clippedPz;
345
/* stuff for figuring out normalFacingOut, after the loop */
347
x0 = aPt->px; y0 = aPt->py;
349
xA = x0 - aPt->px; yA = y0 - aPt->py;
350
x0 = aPt->px; y0 = aPt->py;
352
xB = aPt->px - x0; yB = aPt->py - y0;
356
if ((x0 = xA*yB - yA*xB) > machine0) p->normalFacingOut = 1;
357
else if (x0 < machine0) p->normalFacingOut = -1;
358
else p->normalFacingOut = 0;
364
/**********************************
365
* void projectStuff(x,y,z,px,py) *
367
* sort of like the project stuff *
368
* in tube.c but used exclusively *
369
* for the functions of two *
370
* variables. probably will need *
371
* to be changed later to be more *
372
* general (i.e. have everybody *
373
* use the viewTriple point *
375
**********************************/
379
projectStuff(x,y,z,px,py,Pz)
384
projectStuff(float x,float y,float z,int *px,int *py,float *Pz)
387
float tempx,tempy,tempz,temps,V[4],V1[4],stuffScale=100.0;
389
tempx = viewport->scaleX;
390
tempy = viewport->scaleY;
391
tempz = viewport->scaleZ;
394
if (viewport->scaleX > 5.0) viewport->scaleX = 5.0;
395
if (viewport->scaleY > 5.0) viewport->scaleY = 5.0;
396
if (viewport->scaleZ > 3.0) viewport->scaleZ = 3.0;
397
if (viewScale > 5.0) viewScale = 5.0;
400
V[2] = z; V[3] = 1.0;
402
V[0] -= viewport->transX*stuffScale;
403
V[1] -= viewport->transY*stuffScale;
404
V[2] -= viewport->transZ*stuffScale;
406
matrixMultiply4x4(S,R,transform);
407
vectorMatrix4(V,transform,V1);
410
if (viewData.perspective) {
411
V1[0] *= projPersp(V1[2]);
412
V1[1] *= projPersp(V1[2]);
415
matrixMultiply4x4(I,T,transform);
416
vectorMatrix4(V1,transform,V);
418
V[0] = V[0]*viewScale + xCenter;
419
V[1] = vwInfo.height - (V[1]*viewScale + yCenter);
424
viewport->scaleX = tempx;
425
viewport->scaleY = tempy;
426
viewport->scaleZ = tempz;
431
\begin{thebibliography}{99}
433
\end{thebibliography}