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 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 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 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 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 135 apiflt degtorad(apiflt deg) { 136 apiflt tmp; 137 tmp = deg * 3.1415926 / 180.0; 138 return tmp; 139 } 140 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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