1 /*
2 Copyright (c) 2005-2021 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 /*
18 The original source for this example is
19 Copyright (c) 1994-2008 John E. Stone
20 All rights reserved.
21
22 Redistribution and use in source and binary forms, with or without
23 modification, are permitted provided that the following conditions
24 are met:
25 1. Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 2. Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in the
29 documentation and/or other materials provided with the distribution.
30 3. The name of the author may not be used to endorse or promote products
31 derived from this software without specific prior written permission.
32
33 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
34 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
37 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 SUCH DAMAGE.
44 */
45
46 /*
47 * parse.cpp - an UltraLame (tm) parser for simple data files...
48 */
49
50 // Try preventing lots of GCC warnings about ignored results of fscanf etc.
51 #ifdef __GNUC__
52 // Starting from 4.5, GCC has a suppression option
53 #pragma GCC diagnostic ignored "-Wunused-result"
54 #endif
55
56 #include <cstdio>
57 #include <cmath>
58 #include <cstring>
59 #include <cstdlib>
60 #include <cctype> /* needed for toupper(), macro.. */
61
62 #include "types.hpp"
63 #include "api.hpp" /* rendering API */
64
65 #define PARSE_INTERNAL
66 #include "parse.hpp" /* self protos */
67 #undef PARSE_INTERNAL
68
69 static texentry textable[NUMTEXS]; /* texture lookup table */
70 static texentry defaulttex; /* The default texture when a lookup fails */
71 static int numtextures; /* number of TEXDEF textures */
72 static int numobjectsparsed; /* total number of objects parsed so far */
73 static color scenebackcol; /* scene background color */
74
stringcmp(const char * a,const char * b)75 static int stringcmp(const char *a, const char *b) {
76 std::size_t i, s, l;
77
78 s = strlen(a);
79 l = strlen(b);
80
81 if (s != l)
82 return 1;
83
84 for (i = 0; i < s; i++) {
85 if (toupper(a[i]) != toupper(b[i])) {
86 return 1;
87 }
88 }
89 return 0;
90 }
91
reset_tex_table(void)92 static void reset_tex_table(void) {
93 apitexture apitex;
94
95 numtextures = 0;
96 memset(&textable, 0, sizeof(textable));
97
98 apitex.col.r = 1.0;
99 apitex.col.g = 1.0;
100 apitex.col.b = 1.0;
101 apitex.ambient = 0.1;
102 apitex.diffuse = 0.9;
103 apitex.specular = 0.0;
104 apitex.opacity = 1.0;
105 apitex.texturefunc = 0;
106
107 defaulttex.tex = rt_texture(&apitex);
108 }
109
add_texture(void * tex,char name[TEXNAMELEN])110 static errcode add_texture(void *tex, char name[TEXNAMELEN]) {
111 textable[numtextures].tex = tex;
112 strcpy(textable[numtextures].name, name);
113
114 numtextures++;
115 if (numtextures > NUMTEXS) {
116 fprintf(stderr, "Parse: %d textures allocated, texture slots full!\n", numtextures);
117 numtextures--; /* keep writing over last texture if we've run out.. */
118 return PARSEALLOCERR;
119 }
120
121 return PARSENOERR;
122 }
123
find_texture(char name[TEXNAMELEN])124 static void *find_texture(char name[TEXNAMELEN]) {
125 int i;
126
127 for (i = 0; i < numtextures; i++) {
128 if (strcmp(name, textable[i].name) == 0)
129 return textable[i].tex;
130 }
131 fprintf(stderr, "Undefined texture '%s', using default. \n", name);
132 return (defaulttex.tex);
133 }
134
degtorad(apiflt deg)135 apiflt degtorad(apiflt deg) {
136 apiflt tmp;
137 tmp = deg * 3.1415926 / 180.0;
138 return tmp;
139 }
140
degvectoradvec(vector * degvec)141 static void degvectoradvec(vector *degvec) {
142 vector tmp;
143
144 tmp.x = degtorad(degvec->x);
145 tmp.y = degtorad(degvec->y);
146 tmp.z = degtorad(degvec->z);
147 *degvec = tmp;
148 }
149
InitRot3d(RotMat * rot,apiflt x,apiflt y,apiflt z)150 static void InitRot3d(RotMat *rot, apiflt x, apiflt y, apiflt z) {
151 rot->rx1 = cos(y) * cos(z);
152 rot->rx2 = sin(x) * sin(y) * cos(z) - cos(x) * sin(z);
153 rot->rx3 = sin(x) * sin(z) + cos(x) * cos(z) * sin(y);
154
155 rot->ry1 = cos(y) * sin(z);
156 rot->ry2 = cos(x) * cos(z) + sin(x) * sin(y) * sin(z);
157 rot->ry3 = cos(x) * sin(y) * sin(z) - sin(x) * cos(z);
158
159 rot->rz1 = sin(y);
160 rot->rz2 = sin(x) * cos(y);
161 rot->rz3 = cos(x) * cos(y);
162 }
163
Rotate3d(RotMat * rot,vector * vec)164 static void Rotate3d(RotMat *rot, vector *vec) {
165 vector tmp;
166 tmp.x = (vec->x * (rot->rx1) + vec->y * (rot->rx2) + vec->z * (rot->rx3));
167 tmp.y = (vec->x * (rot->ry1) + vec->y * (rot->ry2) + vec->z * (rot->ry3));
168 tmp.z = (vec->x * (rot->rz1) + vec->y * (rot->rz2) + vec->z * (rot->rz3));
169 *vec = tmp;
170 }
171
Scale3d(vector * scale,vector * vec)172 static void Scale3d(vector *scale, vector *vec) {
173 vec->x = vec->x * scale->x;
174 vec->y = vec->y * scale->y;
175 vec->z = vec->z * scale->z;
176 }
177
Trans3d(vector * trans,vector * vec)178 static void Trans3d(vector *trans, vector *vec) {
179 vec->x += trans->x;
180 vec->y += trans->y;
181 vec->z += trans->z;
182 }
183
GetString(FILE * dfile,const char * string)184 static errcode GetString(FILE *dfile, const char *string) {
185 char data[255];
186
187 fscanf(dfile, "%s", data);
188 if (stringcmp(data, string) != 0) {
189 fprintf(stderr, "parse: Expected %s, got %s \n", string, data);
190 fprintf(stderr, "parse: Error while parsing object: %d \n", numobjectsparsed);
191 return PARSEBADSYNTAX;
192 }
193
194 return PARSENOERR;
195 }
196
readmodel(char * modelfile,SceneHandle scene)197 unsigned int readmodel(char *modelfile, SceneHandle scene) {
198 FILE *dfile;
199 errcode rc;
200
201 reset_tex_table();
202 dfile = nullptr;
203
204 dfile = fopen(modelfile, "r");
205 if (dfile == nullptr) {
206 return PARSEBADFILE;
207 }
208
209 rc = GetScenedefs(dfile, scene);
210 if (rc != PARSENOERR) {
211 fclose(dfile);
212 return rc;
213 }
214
215 scenebackcol.r = 0.0; /* default background is black */
216 scenebackcol.g = 0.0;
217 scenebackcol.b = 0.0;
218
219 numobjectsparsed = 0;
220 while ((rc = GetObject(dfile, scene)) == PARSENOERR) {
221 numobjectsparsed++;
222 }
223 fclose(dfile);
224
225 if (rc == PARSEEOF)
226 rc = PARSENOERR;
227
228 rt_background(scene, scenebackcol);
229
230 return rc;
231 }
232
GetScenedefs(FILE * dfile,SceneHandle scene)233 static errcode GetScenedefs(FILE *dfile, SceneHandle scene) {
234 vector Ccenter, Cview, Cup;
235 apiflt zoom, aspectratio;
236 int raydepth, antialiasing;
237 char outfilename[200];
238 int xres, yres, verbose;
239 float a, b, c;
240 errcode rc = PARSENOERR;
241
242 rc |= GetString(dfile, "BEGIN_SCENE");
243
244 rc |= GetString(dfile, "OUTFILE");
245 fscanf(dfile, "%s", outfilename);
246 #ifdef _WIN32
247 if (strcmp(outfilename, "/dev/null") == 0) {
248 strcpy(outfilename, "NUL:");
249 }
250 #endif
251
252 rc |= GetString(dfile, "RESOLUTION");
253 fscanf(dfile, "%d %d", &xres, &yres);
254
255 rc |= GetString(dfile, "VERBOSE");
256 fscanf(dfile, "%d", &verbose);
257
258 rt_scenesetup(scene, outfilename, xres, yres, verbose);
259
260 rc |= GetString(dfile, "CAMERA");
261
262 rc |= GetString(dfile, "ZOOM");
263 fscanf(dfile, "%f", &a);
264 zoom = a;
265
266 rc |= GetString(dfile, "ASPECTRATIO");
267 fscanf(dfile, "%f", &b);
268 aspectratio = b;
269
270 rc |= GetString(dfile, "ANTIALIASING");
271 fscanf(dfile, "%d", &antialiasing);
272
273 rc |= GetString(dfile, "RAYDEPTH");
274 fscanf(dfile, "%d", &raydepth);
275
276 rc |= GetString(dfile, "CENTER");
277 fscanf(dfile, "%f %f %f", &a, &b, &c);
278 Ccenter.x = a;
279 Ccenter.y = b;
280 Ccenter.z = c;
281
282 rc |= GetString(dfile, "VIEWDIR");
283 fscanf(dfile, "%f %f %f", &a, &b, &c);
284 Cview.x = a;
285 Cview.y = b;
286 Cview.z = c;
287
288 rc |= GetString(dfile, "UPDIR");
289 fscanf(dfile, "%f %f %f", &a, &b, &c);
290 Cup.x = a;
291 Cup.y = b;
292 Cup.z = c;
293
294 rc |= GetString(dfile, "END_CAMERA");
295
296 rt_camerasetup(scene, zoom, aspectratio, antialiasing, raydepth, Ccenter, Cview, Cup);
297
298 return rc;
299 }
300
GetObject(FILE * dfile,SceneHandle scene)301 static errcode GetObject(FILE *dfile, SceneHandle scene) {
302 char objtype[80];
303
304 fscanf(dfile, "%s", objtype);
305 if (!stringcmp(objtype, "END_SCENE")) {
306 return PARSEEOF; /* end parsing */
307 }
308 if (!stringcmp(objtype, "TEXDEF")) {
309 return GetTexDef(dfile);
310 }
311 if (!stringcmp(objtype, "TEXALIAS")) {
312 return GetTexAlias(dfile);
313 }
314 if (!stringcmp(objtype, "BACKGROUND")) {
315 return GetBackGnd(dfile);
316 }
317 if (!stringcmp(objtype, "CYLINDER")) {
318 return GetCylinder(dfile);
319 }
320 if (!stringcmp(objtype, "FCYLINDER")) {
321 return GetFCylinder(dfile);
322 }
323 if (!stringcmp(objtype, "POLYCYLINDER")) {
324 return GetPolyCylinder(dfile);
325 }
326 if (!stringcmp(objtype, "SPHERE")) {
327 return GetSphere(dfile);
328 }
329 if (!stringcmp(objtype, "PLANE")) {
330 return GetPlane(dfile);
331 }
332 if (!stringcmp(objtype, "RING")) {
333 return GetRing(dfile);
334 }
335 if (!stringcmp(objtype, "BOX")) {
336 return GetBox(dfile);
337 }
338 if (!stringcmp(objtype, "SCALARVOL")) {
339 return GetVol(dfile);
340 }
341 if (!stringcmp(objtype, "TRI")) {
342 return GetTri(dfile);
343 }
344 if (!stringcmp(objtype, "STRI")) {
345 return GetSTri(dfile);
346 }
347 if (!stringcmp(objtype, "LIGHT")) {
348 return GetLight(dfile);
349 }
350 if (!stringcmp(objtype, "SCAPE")) {
351 return GetLandScape(dfile);
352 }
353 if (!stringcmp(objtype, "TPOLYFILE")) {
354 return GetTPolyFile(dfile);
355 }
356
357 fprintf(stderr, "Found bad token: %s expected an object type\n", objtype);
358 return PARSEBADSYNTAX;
359 }
360
GetVector(FILE * dfile,vector * v1)361 static errcode GetVector(FILE *dfile, vector *v1) {
362 float a, b, c;
363
364 fscanf(dfile, "%f %f %f", &a, &b, &c);
365 v1->x = a;
366 v1->y = b;
367 v1->z = c;
368
369 return PARSENOERR;
370 }
371
GetColor(FILE * dfile,color * c1)372 static errcode GetColor(FILE *dfile, color *c1) {
373 float r, g, b;
374 int rc;
375
376 rc = GetString(dfile, "COLOR");
377 fscanf(dfile, "%f %f %f", &r, &g, &b);
378 c1->r = r;
379 c1->g = g;
380 c1->b = b;
381
382 return rc;
383 }
384
GetTexDef(FILE * dfile)385 static errcode GetTexDef(FILE *dfile) {
386 char texname[TEXNAMELEN];
387
388 fscanf(dfile, "%s", texname);
389 add_texture(GetTexBody(dfile), texname);
390
391 return PARSENOERR;
392 }
393
GetTexAlias(FILE * dfile)394 static errcode GetTexAlias(FILE *dfile) {
395 char texname[TEXNAMELEN];
396 char aliasname[TEXNAMELEN];
397
398 fscanf(dfile, "%s", texname);
399 fscanf(dfile, "%s", aliasname);
400 add_texture(find_texture(aliasname), texname);
401
402 return PARSENOERR;
403 }
404
GetTexture(FILE * dfile,void ** tex)405 static errcode GetTexture(FILE *dfile, void **tex) {
406 char tmp[255];
407 errcode rc = PARSENOERR;
408
409 fscanf(dfile, "%s", tmp);
410 if (!stringcmp("TEXTURE", tmp)) {
411 *tex = GetTexBody(dfile);
412 }
413 else
414 *tex = find_texture(tmp);
415
416 return rc;
417 }
418
GetTexBody(FILE * dfile)419 void *GetTexBody(FILE *dfile) {
420 char tmp[255];
421 float a, b, c, d, phong, phongexp, phongtype;
422 apitexture tex;
423 void *voidtex;
424 errcode rc;
425
426 rc = GetString(dfile, "AMBIENT");
427 fscanf(dfile, "%f", &a);
428 tex.ambient = a;
429
430 rc |= GetString(dfile, "DIFFUSE");
431 fscanf(dfile, "%f", &b);
432 tex.diffuse = b;
433
434 rc |= GetString(dfile, "SPECULAR");
435 fscanf(dfile, "%f", &c);
436 tex.specular = c;
437
438 rc |= GetString(dfile, "OPACITY");
439 fscanf(dfile, "%f", &d);
440 tex.opacity = d;
441
442 fscanf(dfile, "%s", tmp);
443 if (!stringcmp("PHONG", tmp)) {
444 fscanf(dfile, "%s", tmp);
445 if (!stringcmp("METAL", tmp)) {
446 phongtype = RT_PHONG_METAL;
447 }
448 else if (!stringcmp("PLASTIC", tmp)) {
449 phongtype = RT_PHONG_PLASTIC;
450 }
451 else {
452 phongtype = RT_PHONG_PLASTIC;
453 }
454
455 fscanf(dfile, "%f", &phong);
456 GetString(dfile, "PHONG_SIZE");
457 fscanf(dfile, "%f", &phongexp);
458 fscanf(dfile, "%s", tmp);
459 }
460 else {
461 phong = 0.0;
462 phongexp = 100.0;
463 phongtype = RT_PHONG_PLASTIC;
464 }
465
466 fscanf(dfile, "%f %f %f", &a, &b, &c);
467 tex.col.r = a;
468 tex.col.g = b;
469 tex.col.b = c;
470
471 rc |= GetString(dfile, "TEXFUNC");
472 fscanf(dfile, "%d", &tex.texturefunc);
473 if (tex.texturefunc >= 7) { /* if its an image map, we need a filename */
474 fscanf(dfile, "%s", tex.imap);
475 }
476 if (tex.texturefunc != 0) {
477 rc |= GetString(dfile, "CENTER");
478 rc |= GetVector(dfile, &tex.ctr);
479 rc |= GetString(dfile, "ROTATE");
480 rc |= GetVector(dfile, &tex.rot);
481 rc |= GetString(dfile, "SCALE");
482 rc |= GetVector(dfile, &tex.scale);
483 }
484 if (tex.texturefunc == 9) {
485 rc |= GetString(dfile, "UAXIS");
486 rc |= GetVector(dfile, &tex.uaxs);
487 rc |= GetString(dfile, "VAXIS");
488 rc |= GetVector(dfile, &tex.vaxs);
489 }
490
491 voidtex = rt_texture(&tex);
492 rt_tex_phong(voidtex, phong, phongexp, (int)phongtype);
493
494 return voidtex;
495 }
496
GetLight(FILE * dfile)497 static errcode GetLight(FILE *dfile) {
498 apiflt rad;
499 vector ctr;
500 apitexture tex;
501 float a;
502 errcode rc;
503
504 memset(&tex, 0, sizeof(apitexture));
505
506 rc = GetString(dfile, "CENTER");
507 rc |= GetVector(dfile, &ctr);
508 rc |= GetString(dfile, "RAD");
509 fscanf(dfile, "%f", &a); /* read in radius */
510 rad = a;
511
512 rc |= GetColor(dfile, &tex.col);
513
514 rt_light(rt_texture(&tex), ctr, rad);
515
516 return rc;
517 }
518
GetBackGnd(FILE * dfile)519 static errcode GetBackGnd(FILE *dfile) {
520 float r, g, b;
521
522 fscanf(dfile, "%f %f %f", &r, &g, &b);
523
524 scenebackcol.r = r;
525 scenebackcol.g = g;
526 scenebackcol.b = b;
527
528 return PARSENOERR;
529 }
530
GetCylinder(FILE * dfile)531 static errcode GetCylinder(FILE *dfile) {
532 apiflt rad;
533 vector ctr, axis;
534 void *tex;
535 float a;
536 errcode rc;
537
538 rc = GetString(dfile, "CENTER");
539 rc |= GetVector(dfile, &ctr);
540 rc |= GetString(dfile, "AXIS");
541 rc |= GetVector(dfile, &axis);
542 rc |= GetString(dfile, "RAD");
543 fscanf(dfile, "%f", &a);
544 rad = a;
545
546 rc |= GetTexture(dfile, &tex);
547 rt_cylinder(tex, ctr, axis, rad);
548
549 return rc;
550 }
551
GetFCylinder(FILE * dfile)552 static errcode GetFCylinder(FILE *dfile) {
553 apiflt rad;
554 vector ctr, axis;
555 vector pnt1, pnt2;
556 void *tex;
557 float a;
558 errcode rc;
559
560 rc = GetString(dfile, "BASE");
561 rc |= GetVector(dfile, &pnt1);
562 rc |= GetString(dfile, "APEX");
563 rc |= GetVector(dfile, &pnt2);
564
565 ctr = pnt1;
566 axis.x = pnt2.x - pnt1.x;
567 axis.y = pnt2.y - pnt1.y;
568 axis.z = pnt2.z - pnt1.z;
569
570 rc |= GetString(dfile, "RAD");
571 fscanf(dfile, "%f", &a);
572 rad = a;
573
574 rc |= GetTexture(dfile, &tex);
575 rt_fcylinder(tex, ctr, axis, rad);
576
577 return rc;
578 }
579
GetPolyCylinder(FILE * dfile)580 static errcode GetPolyCylinder(FILE *dfile) {
581 apiflt rad;
582 vector *temp;
583 void *tex;
584 float a;
585 int numpts, i;
586 errcode rc;
587
588 rc = GetString(dfile, "POINTS");
589 fscanf(dfile, "%d", &numpts);
590
591 temp = (vector *)malloc(numpts * sizeof(vector));
592
593 for (i = 0; i < numpts; i++) {
594 rc |= GetVector(dfile, &temp[i]);
595 }
596
597 rc |= GetString(dfile, "RAD");
598 fscanf(dfile, "%f", &a);
599 rad = a;
600
601 rc |= GetTexture(dfile, &tex);
602 rt_polycylinder(tex, temp, numpts, rad);
603
604 free(temp);
605
606 return rc;
607 }
608
GetSphere(FILE * dfile)609 static errcode GetSphere(FILE *dfile) {
610 apiflt rad;
611 vector ctr;
612 void *tex;
613 float a;
614 errcode rc;
615
616 rc = GetString(dfile, "CENTER");
617 rc |= GetVector(dfile, &ctr);
618 rc |= GetString(dfile, "RAD");
619 fscanf(dfile, "%f", &a);
620 rad = a;
621
622 rc |= GetTexture(dfile, &tex);
623
624 rt_sphere(tex, ctr, rad);
625
626 return rc;
627 }
628
GetPlane(FILE * dfile)629 static errcode GetPlane(FILE *dfile) {
630 vector normal;
631 vector ctr;
632 void *tex;
633 errcode rc;
634
635 rc = GetString(dfile, "CENTER");
636 rc |= GetVector(dfile, &ctr);
637 rc |= GetString(dfile, "NORMAL");
638 rc |= GetVector(dfile, &normal);
639 rc |= GetTexture(dfile, &tex);
640
641 rt_plane(tex, ctr, normal);
642
643 return rc;
644 }
645
GetVol(FILE * dfile)646 static errcode GetVol(FILE *dfile) {
647 vector min, max;
648 int x, y, z;
649 char fname[255];
650 void *tex;
651 errcode rc;
652
653 rc = GetString(dfile, "MIN");
654 rc |= GetVector(dfile, &min);
655 rc |= GetString(dfile, "MAX");
656 rc |= GetVector(dfile, &max);
657 rc |= GetString(dfile, "DIM");
658 fscanf(dfile, "%d %d %d ", &x, &y, &z);
659 rc |= GetString(dfile, "FILE");
660 fscanf(dfile, "%s", fname);
661 rc |= GetTexture(dfile, &tex);
662
663 rt_scalarvol(tex, min, max, x, y, z, fname, nullptr);
664
665 return rc;
666 }
667
GetBox(FILE * dfile)668 static errcode GetBox(FILE *dfile) {
669 vector min, max;
670 void *tex;
671 errcode rc;
672
673 rc = GetString(dfile, "MIN");
674 rc |= GetVector(dfile, &min);
675 rc |= GetString(dfile, "MAX");
676 rc |= GetVector(dfile, &max);
677 rc |= GetTexture(dfile, &tex);
678
679 rt_box(tex, min, max);
680
681 return rc;
682 }
683
GetRing(FILE * dfile)684 static errcode GetRing(FILE *dfile) {
685 vector normal;
686 vector ctr;
687 void *tex;
688 float a, b;
689 errcode rc;
690
691 rc = GetString(dfile, "CENTER");
692 rc |= GetVector(dfile, &ctr);
693 rc |= GetString(dfile, "NORMAL");
694 rc |= GetVector(dfile, &normal);
695 rc |= GetString(dfile, "INNER");
696 fscanf(dfile, " %f ", &a);
697 rc |= GetString(dfile, "OUTER");
698 fscanf(dfile, " %f ", &b);
699 rc |= GetTexture(dfile, &tex);
700
701 rt_ring(tex, ctr, normal, a, b);
702
703 return rc;
704 }
705
GetTri(FILE * dfile)706 static errcode GetTri(FILE *dfile) {
707 vector v0, v1, v2;
708 void *tex;
709 errcode rc;
710
711 rc = GetString(dfile, "V0");
712 rc |= GetVector(dfile, &v0);
713
714 rc |= GetString(dfile, "V1");
715 rc |= GetVector(dfile, &v1);
716
717 rc |= GetString(dfile, "V2");
718 rc |= GetVector(dfile, &v2);
719
720 rc |= GetTexture(dfile, &tex);
721
722 rt_tri(tex, v0, v1, v2);
723
724 return rc;
725 }
726
GetSTri(FILE * dfile)727 static errcode GetSTri(FILE *dfile) {
728 vector v0, v1, v2, n0, n1, n2;
729 void *tex;
730 errcode rc;
731
732 rc = GetString(dfile, "V0");
733 rc |= GetVector(dfile, &v0);
734
735 rc |= GetString(dfile, "V1");
736 rc |= GetVector(dfile, &v1);
737
738 rc |= GetString(dfile, "V2");
739 rc |= GetVector(dfile, &v2);
740
741 rc |= GetString(dfile, "N0");
742 rc |= GetVector(dfile, &n0);
743
744 rc |= GetString(dfile, "N1");
745 rc |= GetVector(dfile, &n1);
746
747 rc |= GetString(dfile, "N2");
748 rc |= GetVector(dfile, &n2);
749
750 rc |= GetTexture(dfile, &tex);
751
752 rt_stri(tex, v0, v1, v2, n0, n1, n2);
753
754 return rc;
755 }
756
GetLandScape(FILE * dfile)757 static errcode GetLandScape(FILE *dfile) {
758 void *tex;
759 vector ctr;
760 apiflt wx, wy;
761 int m, n;
762 float a, b;
763 errcode rc;
764
765 rc = GetString(dfile, "RES");
766 fscanf(dfile, "%d %d", &m, &n);
767
768 rc |= GetString(dfile, "SCALE");
769 fscanf(dfile, "%f %f", &a, &b);
770 wx = a;
771 wy = b;
772
773 rc |= GetString(dfile, "CENTER");
774 rc |= GetVector(dfile, &ctr);
775
776 rc |= GetTexture(dfile, &tex);
777
778 rt_landscape(tex, m, n, ctr, wx, wy);
779
780 return rc;
781 }
782
GetTPolyFile(FILE * dfile)783 static errcode GetTPolyFile(FILE *dfile) {
784 void *tex;
785 vector ctr, rot, scale;
786 vector v1, v2, v0;
787 char ifname[255];
788 FILE *ifp;
789 int v, totalpolys;
790 RotMat RotA;
791 errcode rc;
792
793 totalpolys = 0;
794
795 rc = GetString(dfile, "SCALE");
796 rc |= GetVector(dfile, &scale);
797
798 rc |= GetString(dfile, "ROT");
799 rc |= GetVector(dfile, &rot);
800
801 degvectoradvec(&rot);
802 InitRot3d(&RotA, rot.x, rot.y, rot.z);
803
804 rc |= GetString(dfile, "CENTER");
805 rc |= GetVector(dfile, &ctr);
806
807 rc |= GetString(dfile, "FILE");
808 fscanf(dfile, "%s", ifname);
809
810 rc |= GetTexture(dfile, &tex);
811
812 if ((ifp = fopen(ifname, "r")) == nullptr) {
813 fprintf(stderr, "Can't open data file %s for input!! Aborting...\n", ifname);
814 return PARSEBADSUBFILE;
815 }
816
817 while (!feof(ifp)) {
818 fscanf(ifp, "%d", &v);
819 if (v != 3) {
820 break;
821 }
822
823 totalpolys++;
824 v = 0;
825
826 rc |= GetVector(ifp, &v0);
827 rc |= GetVector(ifp, &v1);
828 rc |= GetVector(ifp, &v2);
829
830 Scale3d(&scale, &v0);
831 Scale3d(&scale, &v1);
832 Scale3d(&scale, &v2);
833
834 Rotate3d(&RotA, &v0);
835 Rotate3d(&RotA, &v1);
836 Rotate3d(&RotA, &v2);
837
838 Trans3d(&ctr, &v0);
839 Trans3d(&ctr, &v1);
840 Trans3d(&ctr, &v2);
841
842 rt_tri(tex, v1, v0, v2);
843 }
844
845 fclose(ifp);
846
847 return rc;
848 }
849