Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

open-axiom repository from github

24005 views
1
/*
2
Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd.
3
All rights reserved.
4
Copyright (C) 2007-2008, Gabriel Dos Reis.
5
All rights reserved.
6
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions are
9
met:
10
11
- Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
14
- Redistributions in binary form must reproduce the above copyright
15
notice, this list of conditions and the following disclaimer in
16
the documentation and/or other materials provided with the
17
distribution.
18
19
- Neither the name of The Numerical Algorithms Group Ltd. nor the
20
names of its contributors may be used to endorse or promote products
21
derived from this software without specific prior written permission.
22
23
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
26
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
27
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
*/
35
36
#define _PROJECT3D_C
37
#include "openaxiom-c-macros.h"
38
#include <string.h>
39
40
#include "header.h"
41
#include "draw.h"
42
#include "mode.h" /* for #define components */
43
44
#include "all_3d.H1"
45
46
/*******************************************
47
* void project(aViewTriple,someXpoints,i) *
48
* *
49
* orthogonal projection for a point *
50
* setting the ith Xpoint as well *
51
*******************************************/
52
53
void
54
project(viewTriple * aViewTriple,XPoint *someXpoints,int i)
55
{
56
float Vtmp[4], V[4], V1[4];
57
58
V[0] = aViewTriple->x; V[1] = aViewTriple->y;
59
V[2] = aViewTriple->z; V[3] = 1.0;
60
61
if (isNaNPoint(V[0], V[1], V[2])) {
62
(someXpoints+i)->x = aViewTriple->px = NotPoint;
63
(someXpoints+i)->y = aViewTriple->py = NotPoint;
64
return;
65
}
66
67
V[0] -= viewport->transX; V[1] -= viewport->transY;
68
V[2] -= viewport->transZ;
69
vectorMatrix4(V,R1,Vtmp);
70
71
matrixMultiply4x4(S,R,transform);
72
vectorMatrix4(Vtmp,transform,V1);
73
74
aViewTriple->wx = V1[0]; aViewTriple->wy = V1[1];
75
aViewTriple->wz = V1[2];
76
77
V1[0] *= reScale; V1[1] *= reScale; V1[2] *= reScale;
78
79
aViewTriple->pz = V1[2];
80
if (viewData.perspective) {
81
V1[0] *= projPersp(aViewTriple->pz);
82
V1[1] *= projPersp(aViewTriple->pz);
83
}
84
85
matrixMultiply4x4(I,T,transform);
86
vectorMatrix4(V1,transform,V);
87
V[0] = V[0]*viewScale + xCenter;
88
V[1] = vwInfo.height - (V[1]*viewScale + yCenter);
89
90
(someXpoints+i)->x = aViewTriple->px = V[0];
91
(someXpoints+i)->y = aViewTriple->py = V[1];
92
}
93
94
95
/***************************************************
96
* void projectAPoint(aViewTriple) *
97
* *
98
* orthogonal projection for a point. sort of *
99
* like the above, but no Xpoint assignment *
100
***************************************************/
101
102
void
103
projectAPoint(viewTriple *aViewTriple)
104
{
105
float Vtmp[4], V[4], V1[4];
106
107
V[0] = aViewTriple->x; V[1] = aViewTriple->y;
108
V[2] = aViewTriple->z; V[3] = 1.0;
109
110
if (isNaNPoint(V[0], V[1], V[2])) {
111
aViewTriple->px = NotPoint;
112
aViewTriple->py = NotPoint;
113
return;
114
}
115
116
V[0] -= viewport->transX; V[1] -= viewport->transY;
117
V[2] -= viewport->transZ;
118
vectorMatrix4(V,R1,Vtmp);
119
120
matrixMultiply4x4(S,R,transform);
121
vectorMatrix4(Vtmp,transform,V1);
122
123
aViewTriple->wx = V1[0]; aViewTriple->wy = V1[1];
124
aViewTriple->wz = V1[2];
125
126
V1[0] *= reScale; V1[1] *= reScale; V1[2] *= reScale;
127
128
aViewTriple->pz = V1[2];
129
if (viewData.perspective) {
130
V1[0] *= projPersp(aViewTriple->pz);
131
V1[1] *= projPersp(aViewTriple->pz);
132
}
133
134
matrixMultiply4x4(I,T,transform);
135
vectorMatrix4(V1,transform,V);
136
V[0] = V[0]*viewScale + xCenter;
137
V[1] = vwInfo.height - (V[1]*viewScale + yCenter);
138
139
aViewTriple->px = V[0];
140
aViewTriple->py = V[1];
141
}
142
143
144
/***************************
145
* void projectAllPoints() *
146
***************************/
147
148
void
149
projectAllPoints(void)
150
{
151
152
int i,j,k;
153
LLPoint *anLLPoint;
154
LPoint *anLPoint;
155
int *anIndex;
156
157
anLLPoint = viewData.lllp.llp;
158
for (i=0; i<viewData.lllp.numOfComponents; i++,anLLPoint++) {
159
anLPoint = anLLPoint->lp;
160
for (j=0; j<anLLPoint->numOfLists; j++,anLPoint++) {
161
anIndex = anLPoint->indices;
162
for (k=0; k<anLPoint->numOfPoints; k++,anIndex++) {
163
projectAPoint(refPt3D(viewData,*anIndex));
164
} /* for points in LPoints (k) */
165
} /* for LPoints in LLPoints (j) */
166
} /* for LLPoints in LLLPoints (i) */
167
168
} /* projectAllPoints() */
169
170
171
/*******************************
172
* void projectAllPolys(pList) *
173
* *
174
* orthogonal projection of *
175
* all the polygons in a given *
176
* list in one go. pz holds *
177
* the projected depth info *
178
* for hidden surface removal. *
179
* Polygons totally outside of *
180
* the window dimensions after *
181
* projection are discarded *
182
* from the list. *
183
*******************************/
184
185
void
186
projectAllPolys (poly *pList)
187
{
188
189
int i,clipped,clippedPz;
190
float x0=0.0;
191
float y0=0.0;
192
float xA=0.0;
193
float yA=0.0;
194
float xB=0.0;
195
float yB=0.0;
196
int *anIndex;
197
viewTriple *aPt;
198
199
strcpy(control->message," Projecting Polygons ");
200
writeControlMessage();
201
202
projectAllPoints();
203
for (;pList != NIL(poly);pList=pList->next) {
204
/* totalClip==yes => partialClip==yes (of course) */
205
pList->totalClipPz = yes; /* start with 1, AND all points with Pz<0 */
206
pList->partialClipPz = no; /* start with 0, OR any points with Pz<0 */
207
pList->totalClip = yes; /* same idea, only wrt clip volume */
208
pList->partialClip = no;
209
for (i=0,anIndex=pList->indexPtr; i<pList->numpts; i++,anIndex++) {
210
aPt = refPt3D(viewData,*anIndex);
211
clipped = outsideClippedBoundary(aPt->x, aPt->y, aPt->z);
212
pList->totalClip = pList->totalClip && clipped;
213
pList->partialClip = pList->partialClip || clipped;
214
clippedPz = behindClipPlane(aPt->pz);
215
pList->totalClipPz = pList->totalClipPz && clippedPz;
216
pList->partialClipPz = pList->partialClipPz || clippedPz;
217
218
/* stuff for figuring out normalFacingOut, after the loop */
219
if (!i) {
220
x0 = aPt->px; y0 = aPt->py;
221
} else if (i==1) {
222
xA = x0 - aPt->px; yA = y0 - aPt->py;
223
x0 = aPt->px; y0 = aPt->py;
224
} else if (i==2) {
225
xB = aPt->px - x0; yB = aPt->py - y0;
226
}
227
} /* for i */
228
/* store face facing info */
229
/* For now, we shall give faces facing the user a factor of -1,
230
and faces facing away from the user a factor of +1. this is
231
to mimic the eye vector (pointing away from the user) dotted
232
into the surface normal.
233
This routine is being done because the surface normal in object
234
space does not transform over to image space linearly and so
235
has to be recalculated. but the triple product is zero in the
236
X and Y directions so we just take the Z component, of which,
237
we just examine the sign. */
238
if ((x0 = xA*yB - yA*xB) > machine0) pList->normalFacingOut = 1;
239
else if (x0 < machine0) pList->normalFacingOut = -1;
240
else pList->normalFacingOut = 0;
241
242
}
243
strcpy(control->message,viewport->title);
244
writeControlMessage();
245
246
} /* projectAllPolys */
247
248
249
250
/*******************************
251
* void projectAPoly(p) *
252
* *
253
* orthogonal projection of *
254
* all a polygon. pz holds *
255
* the projected depth info *
256
* for hidden surface removal *
257
*******************************/
258
259
260
void
261
projectAPoly (poly *p)
262
{
263
264
int i,clipped,clippedPz;
265
float Vtmp[4],V[4],V1[4];
266
float x0=0.0;
267
float y0=0.0;
268
float xA=0.0;
269
float yA=0.0;
270
float xB=0.0;
271
float yB=0.0;
272
273
int *anIndex;
274
viewTriple *aPt;
275
276
/* totalClip==yes => partialClip==yes */
277
p->totalClipPz = yes; /* start with 1, AND all points with Pz<0 */
278
p->partialClipPz = no; /* start with 0, OR any points with Pz<0 */
279
p->totalClip = yes; /* same idea, only with respect to clip volume */
280
p->partialClip = no;
281
for (i=0,anIndex=p->indexPtr; i<p->numpts; i++,anIndex++) {
282
aPt = refPt3D(viewData,*anIndex);
283
V[0] = aPt->x; V[1] = aPt->y; V[2] = aPt->z; V[3] = 1.0;
284
285
V[0] -= viewport->transX; V[1] -= viewport->transY;
286
V[2] -= viewport->transZ;
287
vectorMatrix4(V,R1,Vtmp);
288
289
matrixMultiply4x4(S,R,transform);
290
vectorMatrix4(Vtmp,transform,V1);
291
292
aPt->wx = V1[0]; aPt->wy = V1[1]; aPt->wz = V1[2];
293
294
V1[0] *= reScale; V1[1] *= reScale; V1[2] *= reScale;
295
296
aPt->pz = V1[2];
297
if (viewData.perspective) {
298
V1[0] *= projPersp(V1[2]);
299
V1[1] *= projPersp(V1[2]);
300
}
301
302
matrixMultiply4x4(I,T,transform);
303
vectorMatrix4(V1,transform,V);
304
V[0] = V[0]*viewScale + xCenter;
305
V[1] = vwInfo.height - (V[1]*viewScale + yCenter);
306
307
aPt->px = V[0]; aPt->py = V[1];
308
309
clipped = outsideClippedBoundary(aPt->x, aPt->y, aPt->z);
310
p->totalClip = p->totalClip && clipped;
311
p->partialClip = p->partialClip || clipped;
312
clippedPz = behindClipPlane(aPt->pz);
313
p->totalClipPz = p->totalClipPz && clippedPz;
314
p->partialClipPz = p->partialClipPz || clippedPz;
315
316
/* stuff for figuring out normalFacingOut, after the loop */
317
if (!i) {
318
x0 = aPt->px; y0 = aPt->py;
319
} else if (i==1) {
320
xA = x0 - aPt->px; yA = y0 - aPt->py;
321
x0 = aPt->px; y0 = aPt->py;
322
} else if (i==2) {
323
xB = aPt->px - x0; yB = aPt->py - y0;
324
}
325
}
326
327
if ((x0 = xA*yB - yA*xB) > machine0) p->normalFacingOut = 1;
328
else if (x0 < machine0) p->normalFacingOut = -1;
329
else p->normalFacingOut = 0;
330
331
} /* projectAPoly */
332
333
334
335
/**********************************
336
* void projectStuff(x,y,z,px,py) *
337
* *
338
* sort of like the project stuff *
339
* in tube.c but used exclusively *
340
* for the functions of two *
341
* variables. probably will need *
342
* to be changed later to be more *
343
* general (i.e. have everybody *
344
* use the viewTriple point *
345
* structure). *
346
**********************************/
347
348
void
349
projectStuff(float x,float y,float z,int *px,int *py,float *Pz)
350
{
351
float tempx,tempy,tempz,temps,V[4],V1[4],stuffScale=100.0;
352
353
tempx = viewport->scaleX;
354
tempy = viewport->scaleY;
355
tempz = viewport->scaleZ;
356
temps = viewScale;
357
358
if (viewport->scaleX > 5.0) viewport->scaleX = 5.0;
359
if (viewport->scaleY > 5.0) viewport->scaleY = 5.0;
360
if (viewport->scaleZ > 3.0) viewport->scaleZ = 3.0;
361
if (viewScale > 5.0) viewScale = 5.0;
362
363
V[0] = x; V[1] = y;
364
V[2] = z; V[3] = 1.0;
365
366
V[0] -= viewport->transX*stuffScale;
367
V[1] -= viewport->transY*stuffScale;
368
V[2] -= viewport->transZ*stuffScale;
369
370
matrixMultiply4x4(S,R,transform);
371
vectorMatrix4(V,transform,V1);
372
*Pz = V1[2];
373
374
if (viewData.perspective) {
375
V1[0] *= projPersp(V1[2]);
376
V1[1] *= projPersp(V1[2]);
377
}
378
379
matrixMultiply4x4(I,T,transform);
380
vectorMatrix4(V1,transform,V);
381
382
V[0] = V[0]*viewScale + xCenter;
383
V[1] = vwInfo.height - (V[1]*viewScale + yCenter);
384
385
*px = V[0];
386
*py = V[1];
387
388
viewport->scaleX = tempx;
389
viewport->scaleY = tempy;
390
viewport->scaleZ = tempz;
391
viewScale = temps;
392
}
393
394