Fix for a crash which happened when a document couldn't be opened.
[AROS-Contrib.git] / fish / surf / revolve.c
blobfdfc16a6f50d299e0f563fd4bb2b5f4c23bb3cda
1 #include <aros/oldprograms.h>
2 #include <stdio.h>
3 #include "fasttrig.h"
4 #include "bezpt.h"
5 #include "revolve.h"
6 #include "mytypes.h"
9 RevAxisType RevAxis;
11 void OutErr(char *);
13 extern struct Library * MathTransBase;
15 short RevMesh = DefRevMeshVal;
16 short RevImageR, /* revolution index */
17 RevImageB; /* bezier index */
19 static int RotRange = DefRotRange;
20 static int RotStart = DefRotStart;
21 static int SecAngle = DefTilt;
22 static float SurfDist = DefSurfDist;
23 static float ViewDist = DefViewDist;
24 static bool Perspective = DefPersp;
26 void SetPerspective( value)
27 int value;
29 Perspective = value;
34 void SetRevAxis( int value)
37 RevAxis = (value)? RevY : RevX;
41 void SetRotStart( value )
42 int value;
44 RotStart = value;
47 void SetRotRange( value )
48 int value;
50 RotRange = value;
53 void SetSecAng( value )
54 int value;
56 SecAngle = value;
59 void SetRevMesh( value )
60 int value;
62 RevMesh = value;
67 void SetSurfDist( value )
68 int value;
70 SurfDist = (float )value;
74 void SetViewDist( value )
75 int value;
77 ViewDist = (float )value;
82 static
83 float secsin, seccos; /* trig values of secondary angle */
85 static
86 int sizeptlist = 0;
88 static
89 PtGen *ptlist1 = 0,
90 *ptlist2 = 0;
92 static
93 int NumEnts; /* number of angle slices */
96 static
97 bool PrepRev()
99 NumEnts = RevMesh+1;
102 * allocate space 3d descriptions of a point revolved x degrees
104 if( NumEnts > sizeptlist ) {
105 if( ptlist1 ) free(ptlist1);
106 if( ptlist2 ) free(ptlist2);
108 ptlist1 =(PtGen *) malloc( NumEnts * sizeof(PtGen) );
109 ptlist2 =(PtGen *) malloc( NumEnts * sizeof(PtGen) );
110 if( !ptlist1 || !ptlist2 ) {
111 OutErr("PrepRev:not enough memory");
112 return(true);
117 if( InitFastTrig( RotStart, RotRange, NumEnts)) return(true);
118 secsin = sin((float)SecAngle*PI/180);
119 seccos = cos((float)SecAngle*PI/180);
120 return (false);
124 static
125 void CalcRing(ptlist, xpos, ypos)
126 register PtGen *ptlist;
127 float xpos, ypos;
129 int angle;
131 for( angle = 0; angle < NumEnts; angle++, ptlist++) {
132 float temp;
134 * calculate 3d coordinate of point revolved
136 if( RevAxis == RevX) {
137 ptlist->d3.y = ypos * fcos(angle);
138 temp = ypos * fsin(angle);
139 ptlist->d3.x = xpos* seccos - temp *secsin;
140 ptlist->d3.z = xpos * secsin + temp * seccos;
142 else {
143 ptlist->d3.x = xpos * fcos(angle);
144 temp = xpos * fsin( angle);
145 ptlist->d3.y = ypos * seccos + temp * secsin;
146 ptlist->d3.z = secsin * ypos - temp * seccos;
148 ptlist->d3.z -= SurfDist;
150 /* if( Perspective ) {
151 float PerspScale;
153 PerspScale = fabs(ViewDist / ptlist->d3.z);
154 ptlist->d3.x *= PerspScale;
155 ptlist->d3.y *= PerspScale;
159 * calculate the 2d screen coordinate equvalent
162 ptlist->d2.x = (short) ptlist->d3.x;
163 ptlist->d2.y = (short) ptlist->d3.y;
165 ptlist->d2.x = (short) (ptlist->d3.x + 0.5);
166 ptlist->d2.y = (short) (ptlist->d3.y + 0.5);
176 * return true on failure
178 bool Revolve(acceptfunc)
179 void (*acceptfunc)();
181 float tparm, deltat;
182 int subseg;
184 if( PrepRev() ) {
185 return(true);
188 deltat = 1.0/BezMesh;
189 RevImageB = 0;
190 ResetActSeg();
191 do {
192 float xpos, ypos;
195 InitCalcBez();
196 xpos = StartPtX(GetCurSeg());
197 ypos = StartPtY(GetCurSeg());
198 CalcRing(ptlist1, xpos, ypos );
199 for( subseg = 1; subseg <= BezMesh; subseg++ ) {
200 register PtGen *ptlista, *ptlistb;
201 register int numpoly;
203 tparm = subseg * deltat;
204 if( subseg & 1 ) {
205 ptlista = ptlist2; ptlistb = ptlist1;
207 else {
208 ptlista = ptlist1; ptlistb = ptlist2;
211 CalcBezPt(tparm, &xpos, &ypos );
212 CalcRing( ptlista, xpos, ypos );
213 RevImageR = 0;
214 for( numpoly = NumEnts -1; numpoly--; ) {
215 (* acceptfunc)(ptlistb, ptlista, ptlista+1, ptlistb+1);
216 ptlista++;
217 ptlistb++;
218 RevImageR++;
220 RevImageB++;
222 NextSeg();
224 } while( ActSeg );
225 return( false );
229 * write a ring of points
231 static void WriteRing(fileout, ptlist, numpnts)
232 FILE *fileout;
233 PtGen *ptlist;
234 int numpnts;
236 while( numpnts-- ) {
237 fprintf(fileout, "%f %f %f \n", ptlist->d3.x,
238 ptlist->d3.y, ptlist->d3.z );
239 ptlist++;
244 * write the list of vertices to file pointer
245 * this function performs a similar function to revolve
247 static void WriteRevolve(fileout)
248 FILE *fileout;
250 float tparm, deltat;
251 float OldSurfDist;
252 int subseg;
253 float xpos, ypos;
256 OldSurfDist = SurfDist;
257 SurfDist = 0;
258 deltat = 1.0/BezMesh;
259 RevImageB = 0;
260 ResetActSeg();
262 * write out the starting ring
264 InitCalcBez();
265 xpos = StartPtX(GetCurSeg());
266 ypos = StartPtY(GetCurSeg());
267 CalcRing(ptlist1, xpos, ypos );
268 WriteRing(fileout, ptlist1, NumEnts);
270 * loop to write out all the other rings
272 do {
274 InitCalcBez();
275 for( subseg = 1; subseg <= BezMesh; subseg++ ) {
276 tparm = subseg * deltat;
277 CalcBezPt(tparm, &xpos, &ypos );
278 CalcRing( ptlist1, xpos, ypos );
279 WriteRing(fileout, ptlist1, NumEnts);
280 RevImageB++;
282 NextSeg();
284 } while( ActSeg );
285 SurfDist = OldSurfDist;
287 return;
291 * this function writes a list of vertices to "filename"
293 void WriteData(filename)
294 char *filename;
296 FILE *fileout;
298 if(( GetNumSegs() < 1) || PrepRev()){
299 return;
302 fileout = fopen(filename,"w");
303 if(!fileout) {
304 OutErr("could not open data file");
305 return;
309 fprintf(fileout, "%d * number of Rings\n", BezRings());
310 fprintf(fileout, "%d * Rev mesh\n", RevMesh);
311 fprintf(fileout, "%d * Rotation range\n", RotRange);
312 WriteRevolve(fileout);
313 fprintf(fileout, "end\n");
314 fclose(fileout);