Guest User

geo.c

a guest
Feb 6th, 2021
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.07 KB | None | 0 0
  1.  
  2.  
  3.  
  4. /*************************************************************************/
  5. /* */
  6. /* Copyright (c) 1994 Stanford University */
  7. /* */
  8. /* All rights reserved. */
  9. /* */
  10. /* Permission is given to use, copy, and modify this software for any */
  11. /* non-commercial purpose as long as this copyright notice is not */
  12. /* removed. All other uses, including redistribution in whole or in */
  13. /* part, are forbidden without prior written permission. */
  14. /* */
  15. /* This software is provided with absolutely no warranty and no */
  16. /* support. */
  17. /* */
  18. /*************************************************************************/
  19.  
  20.  
  21. /*
  22. * NAME
  23. * geo.c
  24. *
  25. * DESCRIPTION
  26. * This file contains routines that read both ascii and binary geometry
  27. * files, as well as routines to normalize, print, and make a linked
  28. * list of the geometry info.
  29. *
  30. */
  31.  
  32.  
  33. #include <stdio.h>
  34. #include <fcntl.h>
  35. #include <math.h>
  36. #include "rt.h"
  37.  
  38.  
  39.  
  40. /*
  41. * Allocate and initialize sphere function pointer array.
  42. */
  43.  
  44. static PPROCS SphProcs =
  45. {
  46. SphName,
  47. SphPrint,
  48. SphRead,
  49. NULL,
  50. SphTransform,
  51. SphIntersect,
  52. SphPeIntersect,
  53. SphNormal,
  54. SphDataNormalize,
  55. SphBoundBox
  56. };
  57.  
  58. /*
  59. * Allocate and initialize polygon function pointer array.
  60. */
  61.  
  62. static PPROCS PolyProcs =
  63. {
  64. PolyName,
  65. PolyPrint,
  66. PolyRead,
  67. NULL,
  68. PolyTransform,
  69. PolyIntersect,
  70. PolyPeIntersect,
  71. PolyNormal,
  72. PolyDataNormalize,
  73. PolyBoundBox
  74. };
  75.  
  76.  
  77.  
  78. /*
  79. * Allocate and initialize triangle function pointer array.
  80. */
  81.  
  82. static PPROCS TriProcs =
  83. {
  84. TriName,
  85. TriPrint,
  86. TriRead,
  87. NULL,
  88. TriTransform,
  89. TriIntersect,
  90. TriPeIntersect,
  91. TriNormal,
  92. TriDataNormalize,
  93. TriBoundBox
  94. };
  95.  
  96.  
  97.  
  98. /*
  99. * NAME
  100. * MakeElementArray - make array of all primitive elements
  101. *
  102. * SYNOPSIS
  103. * ELEMENT **MakeElementArray(totalElements)
  104. * INT *totalElements;
  105. *
  106. * RETURNS
  107. * Pointer to array of primitives.
  108. *
  109. */
  110.  
  111. ELEMENT **MakeElementArray(totalElements)
  112. INT *totalElements;
  113. {
  114. INT i;
  115. OBJECT *po; /* Ptr to object. */
  116. INT currArrayPosition = 0;
  117. ELEMENT **npepa;
  118.  
  119. po = gm->modelroot;
  120. *totalElements = 0;
  121.  
  122. while (po)
  123. {
  124. (*totalElements) += po->numelements;
  125. po = po->next;
  126. }
  127.  
  128. po = gm->modelroot;
  129. npepa = ObjectMalloc(OT_PEPARRAY, *totalElements);
  130.  
  131. while (po)
  132. {
  133. for (i = 0; i < po->numelements; i++)
  134. npepa[currArrayPosition++] = po->pelem + i;
  135.  
  136. po = po->next;
  137. }
  138.  
  139. return (npepa);
  140. }
  141.  
  142.  
  143.  
  144. /*
  145. * NAME
  146. * PrintGeo - print object geometry list
  147. *
  148. * SYNOPSIS
  149. * VOID PrintGeo(po)
  150. * OBJECT *po; // Ptr to object list to print.
  151. *
  152. * RETURNS
  153. * Nothing.
  154. */
  155.  
  156. VOID PrintGeo(po)
  157. OBJECT *po;
  158. {
  159. while (po)
  160. {
  161. fprintf(stdout, "Object %s\n", po->name);
  162. fprintf(stdout, "\tcolor %f %f %f %f %f %f\n",
  163. po->surf->fcolor[0], po->surf->fcolor[1],
  164. po->surf->fcolor[2], po->surf->bcolor[0],
  165. po->surf->bcolor[1], po->surf->bcolor[2]);
  166.  
  167. fprintf(stdout, "\tcoeffs %f %f %f %f %f\n",
  168. po->surf->kdiff, po->surf->kspec, po->surf->ktran,
  169. po->surf->refrindex, po->surf->kspecn);
  170.  
  171. (*po->procs->print)(po);
  172. po = po->next;
  173. }
  174. }
  175.  
  176.  
  177.  
  178. /*
  179. * NAME
  180. * NormalizeGeo - normalize geometry to be within unit cube
  181. *
  182. * SYNOPSIS
  183. * VOID NormalizeData(po, model, modelInvT)
  184. * OBJECT *po; // Ptr to object list to normalize.
  185. * MATRIX model; // Model matrix.
  186. * MATRIX modelInvT; // Model inverse transpose.
  187. *
  188. * RETURNS
  189. * Nothing.
  190. */
  191.  
  192. VOID NormalizeGeo(po, model, modelInvT)
  193. OBJECT *po;
  194. MATRIX model;
  195. MATRIX modelInvT;
  196. {
  197. REAL norm_minx; /* Normalize min values. */
  198. REAL norm_miny;
  199. REAL norm_minz;
  200. REAL norm_maxx; /* Normalize max values. */
  201. REAL norm_maxy;
  202. REAL norm_maxz;
  203. REAL scale_min; /* Object min max values. */
  204. REAL scale_max;
  205. REAL scale; /* Normalization scale val. */
  206. REAL trans; /* Normalization xlat val. */
  207. OBJECT *poHead; /* Ptr to head of object list*/
  208. MATRIX normMat; /* Normalization matrix. */
  209. MATRIX tempMat; /* Temporary work matrix. */
  210.  
  211.  
  212. poHead = po; /* Save ptr to head of list. */
  213.  
  214. if (! (TraversalType == TT_LIST && ModelNorm == FALSE) )
  215. {
  216. /* Find global bound box min/max. */
  217.  
  218. norm_minx = norm_miny = norm_minz = HUGE_REAL;
  219. norm_maxx = norm_maxy = norm_maxz = -HUGE_REAL;
  220.  
  221. while (po)
  222. {
  223. norm_minx = Min(norm_minx, po->bv.dnear[0]);
  224. norm_miny = Min(norm_miny, po->bv.dnear[1]);
  225. norm_minz = Min(norm_minz, po->bv.dnear[2]);
  226. norm_maxx = Max(norm_maxx, po->bv.dfar[0]);
  227. norm_maxy = Max(norm_maxy, po->bv.dfar[1]);
  228. norm_maxz = Max(norm_maxz, po->bv.dfar[2]);
  229.  
  230. po = po->next;
  231. }
  232.  
  233.  
  234. /* Compute scale factor. */
  235.  
  236. scale_min = Min(norm_minx, norm_miny);
  237. scale_min = Min(scale_min, norm_minz);
  238. scale_max = Max(norm_maxx, norm_maxy);
  239. scale_max = Max(scale_max, norm_maxz);
  240.  
  241. scale = 1.0/(scale_max - scale_min);
  242. trans = (-scale_min*scale);
  243.  
  244. Scale(tempMat, scale, scale, scale);
  245. Translate(normMat, trans, trans, trans);
  246. MatrixMult(normMat, tempMat, normMat);
  247.  
  248.  
  249. /* Now, normalize object data. */
  250.  
  251. po = poHead;
  252.  
  253. while (po)
  254. {
  255. (*po->procs->normalize)(po, normMat);
  256. po = po->next;
  257. }
  258. }
  259. }
  260.  
  261.  
  262.  
  263. /*
  264. * NAME
  265. * ReadGeoFile - read in the geometry file
  266. *
  267. * SYNOPSIS
  268. * VOID ReadGeoFile(GeoFileName)
  269. * CHAR *GeoFileName; // File to open.
  270. *
  271. * DESCRIPTION
  272. * Read in the model file - call primitive object routines to read in
  273. * their own data. Objects are put in a linked list.
  274. *
  275. * Transform objects by modeling transformation if any.
  276. *
  277. * If TT_LIST traversal, ModelNorm parameter indicates whether data will
  278. * be normalized.
  279. *
  280. * RETURNS
  281. * Nothing.
  282. */
  283.  
  284. VOID ReadGeoFile(GeoFileName)
  285. CHAR *GeoFileName;
  286. {
  287. INT i;
  288. INT dummy;
  289. INT stat; /* Input read counter. */
  290. CHAR comchar;
  291. CHAR primop; /* Primitive opcode. */
  292. CHAR objstr[NAME_LEN]; /* Object descriptions. */
  293. CHAR objname[NAME_LEN];
  294. FILE *pf; /* Ptr to geo file desc. */
  295. SURF *ps; /* Ptr to surface desc. */
  296. MATRIX model; /* Model matrix. */
  297. MATRIX modelInv; /* Model matrix inverse. */
  298. MATRIX modelInvT; /* Model matrix inv transpose*/
  299. OBJECT *po; /* Ptr to object. */
  300. OBJECT *prev; /* Ptr to previous object. */
  301. OBJECT *curr; /* Ptr to current object. */
  302. ELEMENT *pe; /* Ptr to the element list. */
  303.  
  304.  
  305. /* Open the model file. */
  306.  
  307. pf = fopen(GeoFileName, "r");
  308. if (!pf)
  309. {
  310. printf("Unable to open model file %s.\n", GeoFileName);
  311. exit(1);
  312. }
  313.  
  314.  
  315. /* Initialize pointers and counters. */
  316.  
  317. curr = NULL;
  318. prev = NULL;
  319. gm->modelroot = NULL;
  320. prim_obj_cnt = 0;
  321. prim_elem_cnt = 0;
  322.  
  323.  
  324. /* Retrieve model transform. */
  325.  
  326. MatrixCopy(model, View.model);
  327. MatrixInverse(modelInv, model);
  328. MatrixTranspose(modelInvT, modelInv);
  329.  
  330.  
  331. /* Check for comments. */
  332.  
  333. if ((comchar = getc(pf)) != '#')
  334. ungetc(comchar, pf);
  335. else
  336. {
  337. comchar = '\0'; /* Set to other than '#'. */
  338.  
  339. while (comchar != '#')
  340. if ((comchar = getc(pf)) == EOF)
  341. {
  342. fprintf(stderr, "Incorrect comment in geometry file.\n");
  343. exit(-1);
  344. }
  345. }
  346.  
  347.  
  348. /* Process the file data for each object. */
  349.  
  350. while ((stat = fscanf(pf, "%s %s", objstr, objname)) != EOF)
  351. {
  352. if (stat != 2 || strcmp(objstr, "object") != 0)
  353. {
  354. printf("Invalid object definition %s.\n", objstr);
  355. exit(-1);
  356. }
  357.  
  358.  
  359. /* Allocate next object and set list pointers. */
  360.  
  361. prim_obj_cnt++;
  362.  
  363. curr = GlobalMalloc(sizeof(OBJECT), "geo.c");
  364. curr->index = prim_obj_cnt;
  365. curr->next = NULL;
  366.  
  367. strcpy(curr->name, objname);
  368.  
  369. if (gm->modelroot == NULL)
  370. gm->modelroot = curr;
  371. else
  372. prev->next = curr;
  373.  
  374.  
  375. /* Get surface characteristics. */
  376.  
  377. ps = GlobalMalloc(sizeof(SURF), "geo.c");
  378. curr->surf = ps;
  379.  
  380. stat = fscanf(pf, "%lf %lf %lf %lf %lf %lf",
  381. &(ps->fcolor[0]), &(ps->fcolor[1]), &(ps->fcolor[2]),
  382. &(ps->bcolor[0]), &(ps->bcolor[1]), &(ps->bcolor[2]));
  383.  
  384. if (stat != 6)
  385. {
  386. printf("Object color incorrect.\n");
  387. exit(-1);
  388. }
  389.  
  390. stat = fscanf(pf, "%lf %lf %lf %lf %lf",
  391. &(ps->kdiff), &(ps->kspec), &(ps->ktran),
  392. &(ps->refrindex), &(ps->kspecn));
  393.  
  394. if (stat != 5)
  395. {
  396. printf("Object surface coefficients incorrect.\n");
  397. exit(-1);
  398. }
  399.  
  400.  
  401. /* Get texture and flag information. */
  402.  
  403. stat = fscanf(pf, "%ld %ld %ld %ld\n", &dummy, &dummy, &dummy, &dummy);
  404.  
  405. if (stat != 4)
  406. {
  407. printf("Texture and/or flag information not all present.\n");
  408. exit(-1);
  409. }
  410.  
  411.  
  412. /* Get primitive opcode. */
  413.  
  414. stat = fscanf(pf, "%c %ld", &primop, &(curr->numelements));
  415.  
  416. if (stat != 2)
  417. {
  418. printf("Object primitive opcode.\n");
  419. exit(-1);
  420. }
  421.  
  422. switch (primop)
  423. {
  424. case 's':
  425. curr->procs = &SphProcs;
  426. break;
  427.  
  428. case 'p':
  429. curr->procs = &PolyProcs;
  430. break;
  431.  
  432. case 't':
  433. curr->procs = &TriProcs;
  434. break;
  435.  
  436. case 'c':
  437. case 'q':
  438. printf("Code for cylinders and quadrics not implemented yet.\n");
  439. exit(-1);
  440.  
  441. default:
  442. printf("Invalid primitive type \'%c\'.\n", primop);
  443. exit(-1);
  444. }
  445.  
  446.  
  447. /* Allocate primitive elements and create indices. */
  448.  
  449. pe = GlobalMalloc(sizeof(ELEMENT)*curr->numelements, "geo.c");
  450. curr->pelem = pe;
  451.  
  452. prim_elem_cnt += curr->numelements;
  453.  
  454. for (i = 1; i <= curr->numelements; i++, pe++)
  455. pe->index = i;
  456.  
  457.  
  458. /* Read, transform, and compute bounding box for object. */
  459.  
  460. (*curr->procs->read)(curr, pf);
  461. (*curr->procs->transform)(curr, model, modelInvT);
  462. (*curr->procs->bbox)(curr);
  463.  
  464. prev = curr;
  465. }
  466.  
  467. NormalizeGeo(gm->modelroot, model, modelInvT);
  468. fclose(pf);
  469. }
  470.  
  471.  
Advertisement
Add Comment
Please, Sign In to add comment