Advertisement
Guest User

LSB file reader

a guest
Oct 24th, 2013
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 32.98 KB | None | 0 0
  1. /*
  2.  * Copyright (c) 1993 Lightscape Graphics Software, Ltd.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software
  5.  * and its documentation for any purpose is hereby granted without
  6.  * fee, provided that (i) the above copyright notices and this
  7.  * permission notice appear in all copies of the software and related
  8.  * documentation, and (ii) the name of Lightscape Graphics Software may not be
  9.  * used in any advertising or publicity relating to the software
  10.  * without the specific, prior written permission of
  11.  * Lightscape Graphics Software.
  12.  *
  13.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL LIGHTSCAPE GRAPHICS SOFTWARE BE LIABLE FOR ANY SPECIAL,
  18.  * INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
  19.  * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
  21.  * THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
  22.  * OR PERFORMANCE OF THIS SOFTWARE.
  23.  *
  24.  */
  25.  
  26. /*
  27.  * pflsb.c:
  28.  */
  29.  
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <ctype.h>
  34. #include <math.h>
  35. #include <limits.h>
  36.  
  37. #ifndef __linux__
  38. #ifdef  _POSIX_SOURCE
  39. extern char *strdup (const char *s1);
  40. #endif
  41. #endif
  42.  
  43. #include <Performer/pf.h>
  44. #include <Performer/pfdu.h>
  45. #include <Performer/pfdb/pflsb.h>
  46.  
  47. #ifndef P_32_SWAP
  48. #define P_32_SWAP(a) {                          \
  49.     uint _tmp = *(uint *)a;             \
  50.     ((char *)a)[0] = ((char *)&_tmp)[3];                \
  51.     ((char *)a)[1] = ((char *)&_tmp)[2];                \
  52.     ((char *)a)[2] = ((char *)&_tmp)[1];                \
  53.     ((char *)a)[3] = ((char *)&_tmp)[0];                \
  54. }
  55. #endif  /* P_32_SWAP */
  56.  
  57. #ifndef P_16_SWAP
  58. #define P_16_SWAP(a) {                          \
  59.     ushort _tmp = *(ushort *)a;             \
  60.     ((char *)a)[0] = ((char *)&_tmp)[1];                \
  61.     ((char *)a)[1] = ((char *)&_tmp)[0];                \
  62. }
  63. #endif  /* P_16_SWAP */
  64.  
  65.  
  66. void swapLSBpatchVertex(LSBpatchVertex *data)
  67. {
  68. #ifdef __i386__
  69.     int i;
  70.     for(i=0; i<3; i++)
  71.         P_32_SWAP(&data->color[i]);
  72. #endif
  73. }
  74.  
  75. void swapLSBtopPatchVertexTextured(LSBtopPatchVertexTextured *data)
  76. {
  77. #ifdef __i386__
  78.     int i;
  79.     for(i=0; i<3; i++)
  80.         P_32_SWAP(&data->coord[i]);
  81.     for(i=0; i<3; i++)
  82.         P_32_SWAP(&data->color[i]);
  83.     for(i=0; i<2; i++)
  84.         P_32_SWAP(&data->uv[i]);
  85. #endif
  86. }
  87.  
  88. void swapLSBpatchLeaf(LSBpatchLeaf *data)
  89. {
  90. #ifdef __i386__
  91.     int i;
  92.     for(i=0; i<4; i++)
  93.         P_16_SWAP(&data->vertices[i]);
  94.     for(i=0; i<4; i++)
  95.         P_16_SWAP(&data->midVertices[i]);
  96. #endif
  97. }
  98.  
  99. void swapLSBpatchClusterLong(LSBpatchClusterLong *data)
  100. {
  101. #ifdef __i386__
  102.     int i;
  103.  
  104.     for(i=0; i<4; i++)
  105.         P_32_SWAP(&data->plane[i]);
  106.  
  107.     P_32_SWAP(&data->materialId);
  108.     P_32_SWAP(&data->layerId);
  109.     P_32_SWAP(&data->textureId);
  110.     P_32_SWAP(&data->numTopNodes);
  111.     P_32_SWAP(&data->numNodes);
  112.     P_32_SWAP(&data->numTopVertices);
  113.     P_32_SWAP(&data->numVertices);
  114. #endif
  115. }
  116.  
  117. void swapLSBpatchCluster(LSBpatchCluster *data)
  118. {
  119. #ifdef __i386__
  120.     int i;
  121.  
  122.     for(i=0; i<4; i++)
  123.         P_32_SWAP(&data->plane[i]);
  124.  
  125.     P_32_SWAP(&data->materialId);
  126.     P_32_SWAP(&data->layerId);
  127.     P_32_SWAP(&data->textureId);
  128.     P_16_SWAP(&data->numTopNodes);
  129.     P_16_SWAP(&data->numNodes);
  130.     P_16_SWAP(&data->numTopVertices);
  131.     P_16_SWAP(&data->numVertices);
  132. #endif
  133. }
  134.  
  135. void swapLSBheader(LSBheader *data)
  136. {
  137. #ifdef __i386__
  138.     int i;
  139.  
  140.     P_16_SWAP(&data->LSBversion);
  141.     P_16_SWAP(&data->fileFlags);
  142.     P_32_SWAP(&data->numPatchClusters);
  143.     P_32_SWAP(&data->numTopNodes);
  144.     P_32_SWAP(&data->numNodes);
  145.     P_32_SWAP(&data->numTopPatchVertices);
  146.     P_32_SWAP(&data->numPatchVertices);
  147.     P_32_SWAP(&data->numMaterials);
  148.     P_32_SWAP(&data->numLayers);
  149.     P_32_SWAP(&data->numTextures);
  150. #endif
  151. }
  152.  
  153. void swapLSBtopPatchVertex(LSBtopPatchVertex *data)
  154. {
  155. #ifdef __i386__
  156.     int i;
  157.     for(i=0; i<3; i++)
  158.         P_32_SWAP(&data->coord[i]);
  159.     for(i=0; i<3; i++)
  160.         P_32_SWAP(&data->color[i]);
  161. #endif
  162. }
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170. /* global data used by loader */
  171. static int   numTris        = 0;
  172. static int   numQuads       = 0;
  173. static pfdGeom  *geom           = NULL;
  174. static int   geomSize       = 256;
  175. static int   clustersPerGeode   = 0;
  176. static pfGroup  *groupNode      = NULL;
  177. static float     spatialSize        = 0.0f;
  178. static int   spatialCount       = 0;
  179. static char *defaultLayerName   = "default";
  180. static int   useLongData        = 0;
  181.  
  182. #define TRI(_a, _b, _c) {\
  183.     geom->primtype = PFGS_POLYS;\
  184.     geom->numVerts = 3;\
  185.     pfCopyVec4(geom->colors[0], colors[(_a)]);\
  186.     pfCopyVec4(geom->colors[1], colors[(_b)]);\
  187.     pfCopyVec4(geom->colors[2], colors[(_c)]);\
  188.     pfCopyVec3(geom->coords[0], coords[(_a)]);\
  189.     pfCopyVec3(geom->coords[1], coords[(_b)]);\
  190.     pfCopyVec3(geom->coords[2], coords[(_c)]);\
  191.     if (geom->tbind[0] == PFGS_PER_VERTEX) \
  192.         {\
  193.         pfCopyVec2(geom->texCoords[0][0], texCoords[(_a)]);\
  194.         pfCopyVec2(geom->texCoords[0][1], texCoords[(_b)]);\
  195.         pfCopyVec2(geom->texCoords[0][2], texCoords[(_c)]);\
  196.         }\
  197.     pfdAddBldrGeom(geom, 1);\
  198.     numTris++;\
  199.     }
  200.  
  201. #define QUAD(_a, _b, _c, _d) {\
  202.     geom->primtype = PFGS_POLYS;\
  203.     geom->numVerts = 4;\
  204.     pfCopyVec4(geom->colors[0], colors[(_a)]);\
  205.     pfCopyVec4(geom->colors[1], colors[(_b)]);\
  206.     pfCopyVec4(geom->colors[2], colors[(_c)]);\
  207.     pfCopyVec4(geom->colors[3], colors[(_d)]);\
  208.     pfCopyVec3(geom->coords[0], coords[(_a)]);\
  209.     pfCopyVec3(geom->coords[1], coords[(_b)]);\
  210.     pfCopyVec3(geom->coords[2], coords[(_c)]);\
  211.     pfCopyVec3(geom->coords[3], coords[(_d)]);\
  212.     if (geom->tbind[0] == PFGS_PER_VERTEX) \
  213.         {\
  214.         pfCopyVec2(geom->texCoords[0][0], texCoords[(_a)]);\
  215.         pfCopyVec2(geom->texCoords[0][1], texCoords[(_b)]);\
  216.         pfCopyVec2(geom->texCoords[0][2], texCoords[(_c)]);\
  217.         pfCopyVec2(geom->texCoords[0][3], texCoords[(_d)]);\
  218.         }\
  219.     pfdAddBldrGeom(geom, 1);\
  220.     numQuads++;\
  221.     }
  222.  
  223. #define VI(_n)  (node->vertices[_n]->index)
  224. #define CI(_n)  (((LSpatchVertex *)(node->children[_n]))->index)
  225.  
  226. static void
  227. makeTri(
  228.     LSpatchNode *node,
  229.     pfVec4 *colors,
  230.     pfVec3 *coords,
  231.     pfVec2 *texCoords)
  232. {
  233.     unsigned int mask, leafType;
  234.     LSpatchNode **child;
  235.     int t;
  236.  
  237.     geom->cbind = PFGS_PER_VERTEX;
  238.     geom->nbind = PFGS_OFF;
  239.     geom->tbind[0] = (texCoords == NULL) ? PFGS_OFF : PFGS_PER_VERTEX;
  240.     for(t = 1; t < 4; t++)
  241.         geom->tbind[t] = PFGS_OFF;
  242.  
  243.     if (node->isLeaf)
  244.     {
  245.     leafType = 0;
  246.     child = node->children;
  247.     mask   = 1; if (*child++ != NULL) leafType |= mask;
  248.     mask <<= 1; if (*child++ != NULL) leafType |= mask;
  249.     mask <<= 1; if (*child   != NULL) leafType |= mask;
  250.  
  251.     switch (leafType)
  252.     {
  253.     case 0:
  254.         TRI(VI(0), VI(1), VI(2));
  255.         break;
  256.         case 1:
  257.         TRI(VI(0), CI(0), VI(2));
  258.         TRI(CI(0), VI(1), VI(2));
  259.         break;
  260.         case 2:
  261.         TRI(VI(1), CI(1), VI(0));
  262.         TRI(CI(1), VI(2), VI(0));
  263.         break;
  264.         case 3:
  265.         TRI(VI(0), CI(0), CI(1));
  266.         TRI(CI(0), VI(1), CI(1));
  267.         TRI(CI(1), VI(2), VI(0));
  268.         break;
  269.         case 4:
  270.         TRI(VI(2), CI(2), VI(1));
  271.         TRI(CI(2), VI(0), VI(1));
  272.         break;
  273.         case 5:
  274.         TRI(VI(2), CI(2), CI(0));
  275.         TRI(CI(2), VI(0), CI(0));
  276.         TRI(CI(0), VI(1), VI(2));
  277.         break;
  278.         case 6:
  279.         TRI(VI(1), CI(1), CI(2));
  280.         TRI(CI(1), VI(2), CI(2));
  281.         TRI(CI(2), VI(0), VI(1));
  282.         break;
  283.         case 7:
  284.         TRI(VI(0), CI(0), CI(2));
  285.         TRI(CI(0), VI(1), CI(1));
  286.         TRI(CI(1), VI(2), CI(2));
  287.         TRI(CI(0), CI(1), CI(2));
  288.         break;
  289.     }
  290.     }
  291.     else
  292.     {
  293.     /* just emit this node without recursion */
  294.     TRI(VI(0), VI(1), VI(2));
  295.     }
  296. }
  297.  
  298. static void
  299. makeQuad(
  300.     LSpatchNode *node,
  301.     pfVec4 *colors,
  302.     pfVec3 *coords,
  303.     pfVec2 *texCoords)
  304. {
  305.     unsigned int mask, leafType;
  306.     LSpatchNode **child;
  307.  
  308.     geom->cbind = PFGS_PER_VERTEX;
  309.     geom->nbind = PFGS_OFF;
  310.     geom->tbind[0] = (texCoords == NULL) ? PFGS_OFF : PFGS_PER_VERTEX;
  311.  
  312.     if (node->isLeaf)
  313.     {
  314.     leafType = 0;
  315.     child = node->children;
  316.     mask   = 1; if (*child++ != NULL) leafType |= mask;
  317.     mask <<= 1; if (*child++ != NULL) leafType |= mask;
  318.     mask <<= 1; if (*child++ != NULL) leafType |= mask;
  319.     mask <<= 1; if (*child   != NULL) leafType |= mask;
  320.  
  321.     switch (leafType)
  322.     {
  323.         case 0:
  324.         QUAD(VI(0), VI(1), VI(2), VI(3));
  325.         break;
  326.         case 1:
  327.         QUAD(VI(0), CI(0), VI(2), VI(3));
  328.         TRI(CI(0), VI(1), VI(2));
  329.         break;
  330.         case 2:
  331.         QUAD(VI(1), CI(1), VI(3), VI(0));
  332.         TRI(CI(1), VI(2), VI(3));
  333.         break;
  334.         case 3:
  335.         TRI(VI(0), CI(0), VI(3));
  336.         TRI(CI(0), VI(1), CI(1));
  337.         QUAD(CI(0), CI(1), VI(2), VI(3));
  338.         break;
  339.         case 4:
  340.         QUAD(VI(2), CI(2), VI(0), VI(1));
  341.         TRI(CI(2), VI(3), VI(0));
  342.         break;
  343.         case 5:
  344.         QUAD(VI(0), CI(0), CI(2), VI(3));
  345.         QUAD(CI(0), VI(1), VI(2), CI(2));
  346.         break;
  347.         case 6:
  348.         TRI(VI(1), CI(1), VI(0));
  349.         TRI(CI(1), VI(2), CI(2));
  350.         QUAD(CI(1), CI(2), VI(3), VI(0));
  351.         break;
  352.         case 7:
  353.         QUAD(VI(0), CI(0), CI(2), VI(3));
  354.         QUAD(CI(0), CI(1), VI(2), CI(2));
  355.         TRI(CI(0), VI(1), CI(1));
  356.         break;
  357.         case 8:
  358.         QUAD(VI(3), CI(3), VI(1), VI(2));
  359.         TRI(CI(3), VI(0), VI(1));
  360.         break;
  361.         case 9:
  362.         TRI(VI(3), CI(3), VI(2));
  363.         TRI(CI(3), VI(0), CI(0));
  364.         QUAD(CI(3), CI(0), VI(1), VI(2));
  365.         break;
  366.         case 10:
  367.         QUAD(VI(1), CI(1), CI(3), VI(0));
  368.         QUAD(CI(1), VI(2), VI(3), CI(3));
  369.         break;
  370.         case 11:
  371.         QUAD(VI(3), CI(3), CI(1), VI(2));
  372.         QUAD(CI(3), CI(0), VI(1), CI(1));
  373.         TRI(CI(3), VI(0), CI(0));
  374.         break;
  375.         case 12:
  376.         TRI(VI(2), CI(2), VI(1));
  377.         TRI(CI(2), VI(3), CI(3));
  378.         QUAD(CI(2), CI(3), VI(0), VI(1));
  379.         break;
  380.         case 13:
  381.         QUAD(VI(2), CI(2), CI(0), VI(1));
  382.         QUAD(CI(2), CI(3), VI(0), CI(0));
  383.         TRI(CI(2), VI(3), CI(3));
  384.         break;
  385.         case 14:
  386.         QUAD(VI(1), CI(1), CI(3), VI(0));
  387.         QUAD(CI(1), CI(2), VI(3), CI(3));
  388.         TRI(CI(1), VI(2), CI(2));
  389.         break;
  390.         case 15:
  391.         QUAD(VI(0), CI(0), CI(2), CI(3));
  392.         TRI(CI(2), VI(3), CI(3));
  393.         QUAD(VI(1), CI(1), CI(2), CI(0));
  394.         TRI(CI(1), VI(2), CI(2));
  395.         break;
  396.     }
  397.     }
  398.     else
  399.     {
  400.     /* just emit this node without recursion */
  401.     TRI(VI(0), VI(1), VI(3));
  402.     TRI(VI(1), VI(2), VI(3));
  403.     }
  404. }
  405.  
  406. static void
  407. buildPolygons(
  408.     int recursionDepth,
  409.     int recursionLimit,
  410.     LSpatchNode *node,
  411.     pfVec4 *colors,
  412.     pfVec3 *coords,
  413.     pfVec2 *texCoords)
  414. {
  415.     if (node->isLeaf || recursionDepth >= recursionLimit)
  416.     {
  417.     if (NODE_IS_TRIANGLE(node))
  418.         makeTri( node, colors, coords, texCoords);
  419.     else
  420.         makeQuad(node, colors, coords, texCoords);
  421.     }
  422.     else
  423.     {
  424.     int i;
  425.     for (i = 0; i < 4; i++)
  426.         buildPolygons(recursionDepth+1, recursionLimit,
  427.         node->children[i], colors, coords, texCoords);
  428.     }
  429. }
  430.  
  431. static int
  432. loadPatchVertex(
  433.     FILE *fp,
  434.     pfVec4 *color)
  435. {
  436.     LSBpatchVertex lsbPatchVertex;
  437.  
  438.     if (fread((void *)(&lsbPatchVertex),
  439.     sizeof(LSBpatchVertex), 1, fp) <= 0)
  440.     return 0;
  441.  
  442.     swapLSBpatchVertex(&lsbPatchVertex);
  443.     pfCopyVec3(*color, lsbPatchVertex.color);
  444.     (*color)[3] = 1.0f;
  445.  
  446.     return 1;
  447. }
  448.  
  449. static int
  450. loadTopPatchVertex(
  451.     FILE *fp,
  452.     pfVec4 *color,
  453.     pfVec3 *coord,
  454.     pfVec2 *texCoord)
  455. {
  456.     if (texCoord != NULL)
  457.     {
  458.     LSBtopPatchVertexTextured lsbPatchVertexTextured;
  459.     if (fread((void *)(&lsbPatchVertexTextured),
  460.         sizeof(LSBtopPatchVertexTextured), 1, fp) <= 0)
  461.         return 0;
  462.  
  463.     swapLSBtopPatchVertexTextured(&lsbPatchVertexTextured);
  464.     pfCopyVec3(*coord, lsbPatchVertexTextured.coord);
  465.     pfCopyVec3(*color, lsbPatchVertexTextured.color);
  466.     (*color)[3] = 1.0f;
  467.     pfCopyVec2(*texCoord, lsbPatchVertexTextured.uv);
  468.     }
  469.     else
  470.     {
  471.     LSBtopPatchVertex lsbPatchVertex;
  472.     if (fread((void *)(&lsbPatchVertex),
  473.         sizeof(LSBtopPatchVertex), 1, fp) <= 0)
  474.         return 0;
  475.  
  476.     swapLSBtopPatchVertex(&lsbPatchVertex);
  477.     pfCopyVec3(*coord, lsbPatchVertex.coord);
  478.     pfCopyVec3(*color, lsbPatchVertex.color);
  479.     (*color)[3] = 1.0f;
  480.     }
  481.  
  482.     return 1;
  483. }
  484.  
  485. static int
  486. readPatchLeaf(
  487.     FILE *fp,
  488.     unsigned int *verts,
  489.     unsigned int *midVerts)
  490. {
  491.     LSBpatchLeaf lsbPatchLeaf;
  492.     LSBpatchLeaf lsbPatchLeafLong;
  493.  
  494.     if (useLongData)
  495.     {
  496.     if (fread((void *)(&lsbPatchLeaf),
  497.         sizeof(LSBpatchLeaf), 1, fp) <= 0)
  498.         return 0;
  499.  
  500.     swapLSBpatchLeaf(&lsbPatchLeaf);
  501.     verts[0] = lsbPatchLeafLong.vertices[0];
  502.     verts[1] = lsbPatchLeafLong.vertices[1];
  503.     verts[2] = lsbPatchLeafLong.vertices[2];
  504.     verts[3] = lsbPatchLeafLong.vertices[3];
  505.     midVerts[0] = lsbPatchLeafLong.midVertices[0];
  506.     midVerts[1] = lsbPatchLeafLong.midVertices[1];
  507.     midVerts[2] = lsbPatchLeafLong.midVertices[2];
  508.     midVerts[3] = lsbPatchLeafLong.midVertices[3];
  509.     }
  510.     else
  511.     {
  512.     if (fread((void *)(&lsbPatchLeaf),
  513.         sizeof(LSBpatchLeaf), 1, fp) <= 0)
  514.         return 0;
  515.  
  516.     swapLSBpatchLeaf(&lsbPatchLeaf);
  517.     verts[0] = lsbPatchLeaf.vertices[0];
  518.     verts[1] = lsbPatchLeaf.vertices[1];
  519.     verts[2] = lsbPatchLeaf.vertices[2];
  520.     verts[3] = lsbPatchLeaf.vertices[3];
  521.     midVerts[0] = lsbPatchLeaf.midVertices[0];
  522.     midVerts[1] = lsbPatchLeaf.midVertices[1];
  523.     midVerts[2] = lsbPatchLeaf.midVertices[2];
  524.     midVerts[3] = lsbPatchLeaf.midVertices[3];
  525.     }
  526.  
  527.     return 1;
  528. }
  529.  
  530. static LSpatchNode *
  531. loadPatchNodes(
  532.     FILE *fp,
  533.     LSpatchNode *root,
  534.     LSpatchNode **nodes,
  535.     LSpatchVertex *vertices)
  536. {
  537.     int i, n;
  538.     LSpatchNode *node;
  539.     unsigned int verts[4], midVerts[4];
  540.  
  541.     switch (getc(fp))
  542.     {
  543.     case 'i':
  544.     if (root != NULL)
  545.         node = root;
  546.     else
  547.     {
  548.         node = *nodes;
  549.         (*nodes)++;
  550.     }
  551.  
  552.     for (i = 0; i < 4; i++)
  553.     {
  554.         node->children[i] = loadPatchNodes(fp, NULL, nodes, vertices);
  555.         if (node->children[i] == NULL)
  556.         {
  557.         node = NULL;
  558.         break;
  559.         }
  560.     }
  561.  
  562.     if (node != NULL)
  563.     {
  564.         node->isLeaf = 0;
  565.         if (NODE_IS_TRIANGLE(node->children[0]))
  566.         {
  567.         for (i = 0; i < 3; i++)
  568.             node->vertices[i] = node->children[i]->vertices[i];
  569.         node->vertices[3] = NULL;
  570.         }
  571.         else
  572.         for (i = 0; i < 4; i++)
  573.             node->vertices[i] = node->children[i]->vertices[i];
  574.     }
  575.     break;
  576.  
  577.     case 'l' :
  578.     if (!readPatchLeaf(fp, verts, midVerts))
  579.         return NULL;
  580.  
  581.     if (root != NULL)
  582.         node = root;
  583.     else
  584.     {
  585.         node = *nodes;
  586.         (*nodes)++;
  587.     }
  588.  
  589.     node->isLeaf = 1;
  590.     node->children[3] = NULL;
  591.     node->vertices[3] = NULL;
  592.     n = ((verts[3] == 0) ? 3 : 4);
  593.     for (i = 0; i < n; i++)
  594.     {
  595.         node->vertices[i] = &(vertices[verts[i] - 1]);
  596.         node->children[i] = (midVerts[i] == 0)
  597.         ? NULL
  598.         : (LSpatchNode *)(&(vertices[midVerts[i] - 1]));
  599.     }
  600.     break;
  601.  
  602.     default :
  603.     node = NULL;
  604.     break;
  605.     }
  606.  
  607.     return node;
  608. }
  609.  
  610. static int
  611. readPatchCluster(FILE *fp,
  612.     unsigned short *flags,
  613.     pfVec4 *plane,
  614.     unsigned int *materialId,
  615.     unsigned int *layerId,
  616.     unsigned int *textureId,
  617.     unsigned int *numTopNodes,
  618.     unsigned int *numNodes,
  619.     unsigned int *numTopVerts,
  620.     unsigned int *numVertices)
  621. {
  622.     unsigned short clustFlags;
  623.     unsigned short junk;
  624.  
  625.     if (fread((void *)(&clustFlags), sizeof(unsigned short), 1, fp) <= 0)
  626.     return(0);
  627.     if (fread((void *)(&junk),       sizeof(unsigned short), 1, fp) <= 0)
  628.     return(0);
  629.  
  630. #ifdef __i386__
  631.     P_16_SWAP(&clustFlags);
  632.     P_16_SWAP(&junk);
  633. #endif
  634.  
  635.     if (clustFlags & LSB_BIG_CLUSTER)
  636.     {
  637.     LSBpatchClusterLong lsbLongCluster;
  638.     useLongData = 1;
  639.  
  640.     if(fread((void *)(&lsbLongCluster.plane),
  641.         (long)(sizeof(LSBpatchClusterLong))-4, 1, fp) <= 0)
  642.         return 0;
  643.  
  644.     swapLSBpatchClusterLong(&lsbLongCluster);
  645.     *flags = clustFlags;
  646.     pfSetVec4(*plane,
  647.         lsbLongCluster.plane[0],
  648.         lsbLongCluster.plane[1],
  649.         lsbLongCluster.plane[2],
  650.         lsbLongCluster.plane[3]);
  651.     *materialId  = lsbLongCluster.materialId;
  652.     *layerId     = lsbLongCluster.layerId;
  653.     *textureId   = lsbLongCluster.textureId;
  654.     *numTopNodes = lsbLongCluster.numTopNodes;
  655.     *numNodes    = lsbLongCluster.numNodes;
  656.     *numTopVerts = lsbLongCluster.numTopVertices;
  657.     *numVertices = lsbLongCluster.numVertices;
  658.     }
  659.     else
  660.     {
  661.         LSBpatchCluster lsbPatchCluster;
  662.     useLongData = 0;
  663.  
  664.     if (fread((void *)(&lsbPatchCluster.plane),
  665.         (long)(sizeof(LSBpatchCluster))-4, 1, fp) <= 0)
  666.         return(0);
  667.  
  668.     swapLSBpatchCluster(&lsbPatchCluster);
  669.     *flags = clustFlags;
  670.     pfSetVec4(*plane,
  671.             lsbPatchCluster.plane[0],
  672.         lsbPatchCluster.plane[1],
  673.             lsbPatchCluster.plane[2],
  674.         lsbPatchCluster.plane[3]);
  675.     *materialId  = lsbPatchCluster.materialId;
  676.     *layerId     = lsbPatchCluster.layerId;
  677.     *textureId   = lsbPatchCluster.textureId;
  678.     *numTopNodes = lsbPatchCluster.numTopNodes;
  679.     *numNodes    = lsbPatchCluster.numNodes;
  680.     *numTopVerts = lsbPatchCluster.numTopVertices;
  681.     *numVertices = lsbPatchCluster.numVertices;
  682.     }
  683.  
  684.     return 1;
  685. }
  686.  
  687. static void
  688. initPatchNodes(
  689.     LSpatchNode *node,
  690.     pfVec3 *coords,
  691.     pfVec2 *texCoords)
  692. {
  693.     unsigned int i, j, n;
  694.     LSpatchVertex *v;
  695.  
  696.     if (!node->isLeaf)
  697.     {
  698.     n = NUM_NODE_VERTICES(node);
  699.     for (i = 0; i < n; i++)
  700.     {
  701.         j = (i + 1) % n;
  702.         v = node->children[i]->vertices[j];
  703.         if (v->flags)
  704.         {
  705.         v->flags = 0;
  706.  
  707.         pfCombineVec3(coords[v->index],
  708.             0.5, coords[node->vertices[i]->index],
  709.             0.5, coords[node->vertices[j]->index]);
  710.  
  711.         if (texCoords != NULL)
  712.             pfCombineVec2(texCoords[v->index],
  713.             0.5, texCoords[node->vertices[i]->index],
  714.             0.5, texCoords[node->vertices[j]->index]);
  715.         }
  716.     }
  717.  
  718.     if (NODE_IS_RECT(node))
  719.     {
  720.         v = node->children[2]->vertices[0];
  721.         v->flags = 0;
  722.         pfCombineVec3(coords[v->index],
  723.         0.5, coords[node->children[0]->vertices[1]->index],
  724.         0.5, coords[node->children[2]->vertices[3]->index]);
  725.         if (texCoords != NULL)
  726.         {
  727.         pfCombineVec2(texCoords[v->index],
  728.             0.5, texCoords[node->children[0]->vertices[1]->index],
  729.             0.5, texCoords[node->children[2]->vertices[3]->index]);
  730.         }
  731.     }
  732.  
  733.     for (i = 0; i < 4; i++)
  734.         initPatchNodes(node->children[i], coords, texCoords);
  735.     }
  736. }
  737.  
  738. static int
  739. readClusters(
  740.     FILE *fp,
  741.     LSBheader *lsbHeader,
  742.     LSmaterial *materials,
  743.     LSlayer *layers,
  744.     LStexture *textures,
  745.     int recursionLimit
  746.     )
  747. {
  748.     unsigned short flags;
  749.     unsigned int i, j, k;
  750.     unsigned int materialId, layerId, textureId;
  751.     unsigned int numOtherVertices, numTopVerts, numVerts, numTopNodes, numNodes;
  752.     pfVec4 plane, *curColor;
  753.     pfVec3 *curCoord;
  754.     pfVec2 *curTexCoord;
  755.     LSpatchVertex *curVertex;
  756.     LSpatchNode *curTopNode, *curNode;
  757.     LSpatchCluster thisPatchCluster;
  758.     LSpatchCluster *curCluster = &thisPatchCluster;
  759.  
  760.     int      nodeCount  = 256;
  761.     int      vertexCount    = 256;
  762.     LSpatchNode *nodes      = pfCalloc(nodeCount,   sizeof(LSpatchNode),   NULL);
  763.     LSpatchVertex  
  764.         *vertices   = pfCalloc(vertexCount, sizeof(LSpatchVertex), NULL);
  765.     pfVec4  *pfColors   = pfCalloc(vertexCount, sizeof(pfVec4),        NULL);
  766.     pfVec3  *pfCoords   = pfCalloc(vertexCount, sizeof(pfVec3),        NULL);
  767.     pfVec2  *pfTexCoords    = pfCalloc(vertexCount, sizeof(pfVec2),        NULL);
  768.  
  769.     for (i = 0; i < lsbHeader->numPatchClusters; i++)
  770.     {
  771.     if (!readPatchCluster(fp, &flags, &plane, &materialId, &layerId,
  772.         &textureId, &numTopNodes, &numNodes, &numTopVerts, &numVerts))
  773.     {
  774.         if (nodes       != NULL) pfFree(nodes);
  775.         if (vertices    != NULL) pfFree(vertices);
  776.         if (pfColors    != NULL) pfFree(pfColors);
  777.         if (pfCoords    != NULL) pfFree(pfCoords);
  778.         if (pfTexCoords != NULL) pfFree(pfTexCoords);
  779.         return 0;
  780.     }
  781.  
  782.     curCluster->flags = flags;
  783.     pfCopyVec4(curCluster->plane, plane);
  784.  
  785.     if (materialId == 0)
  786.         curCluster->material = NULL;
  787.     else
  788.         curCluster->material = &(materials[materialId - 1]);
  789.  
  790.     /* specify layer for this cluster */
  791. #ifdef  BUILD_LAYERS_INDEPENDENTLY
  792.     if (layerId == 0)
  793.     {
  794.         curCluster->layer = NULL;
  795.         pfdSelectBldrName(defaultLayerName);
  796.     }
  797.     else
  798.     {
  799.         curCluster->layer = &(layers[layerId - 1]);
  800.         pfdSelectBldrName(curCluster->layer->name);
  801.     }
  802. #endif
  803.  
  804.     /* specify texture for this cluster */
  805.     if (textureId == 0)
  806.     {
  807.         curCluster->texture = NULL;
  808.         pfdBldrStateAttr(PFSTATE_TEXTURE, NULL);
  809.         pfdBldrStateMode(PFSTATE_ENTEXTURE, PFTR_OFF);
  810.     }
  811.     else
  812.     {
  813.         pfTexture *tex = (pfTexture *)
  814.         pfdGetTemplateObject(pfGetTexClassType());
  815.         curCluster->texture = &(textures[textureId - 1]);
  816.         pfTexName(tex, curCluster->texture->name);
  817.         pfdBldrStateAttr(PFSTATE_TEXTURE, tex);
  818.         pfdBldrStateMode(PFSTATE_ENTEXTURE, PFTR_ON);
  819.     }
  820.  
  821.     /* update vertex-count array sizes and pointers */
  822.     if (vertexCount < numVerts)
  823.     {
  824.         vertexCount = numVerts;
  825.         pfColors = pfRealloc(pfColors, vertexCount*sizeof(pfVec4));
  826.         if (pfColors == NULL)
  827.         return 0;
  828.         pfCoords = pfRealloc(pfCoords, vertexCount*sizeof(pfVec3));
  829.         if (pfCoords == NULL)
  830.         return 0;
  831.         pfTexCoords = pfRealloc(pfTexCoords, vertexCount*sizeof(pfVec2));
  832.         if (pfTexCoords == NULL)
  833.         return 0;
  834.         vertices = pfRealloc(vertices, numVerts*sizeof(LSpatchVertex));
  835.         if (vertices == NULL)
  836.         return 0;
  837.     }
  838.     curColor    = pfColors;
  839.     curCoord    = pfCoords;
  840.     curVertex   = vertices;
  841.  
  842.     curTexCoord = (curCluster->flags & LSB_TEXTURED) ? pfTexCoords : NULL;
  843.  
  844.     /* update node-count array sizes and pointers */
  845.     if (nodeCount < numNodes)
  846.     {
  847.         nodeCount = numNodes;
  848.         nodes = pfRealloc(nodes, numNodes*sizeof(LSpatchNode));
  849.         if (nodes == NULL)
  850.         return 0;
  851.     }
  852.     curTopNode = nodes;
  853.  
  854.     numOtherVertices = numVerts - numTopVerts;
  855.     for (j = 0; j < numOtherVertices; j++, curColor++, curCoord++, curVertex++)
  856.     {
  857.         if (!loadPatchVertex(fp, curColor))
  858.         return 0;
  859.         curVertex->flags = 1; /* means that geometry needs to be initialized */
  860.         curVertex->index = j;
  861.         if (curCluster->flags & LSB_TEXTURED)
  862.         curTexCoord++;
  863.     }
  864.     for (j = 0; j < numTopVerts; j++, curColor++, curCoord++, curVertex++)
  865.     {
  866.         if (!loadTopPatchVertex(fp, curColor, curCoord, curTexCoord))
  867.         return 0;
  868.         curVertex->flags = 0;
  869.         curVertex->index = numOtherVertices + j;
  870.         if (curCluster->flags & LSB_TEXTURED)
  871.         curTexCoord++;
  872.     }
  873.  
  874.     /* temporary node info */
  875.     curNode = nodes + numTopNodes;
  876.     for (j = 0; j < numTopNodes; j++, curTopNode++)
  877.         if (!loadPatchNodes(fp, curTopNode, &curNode, vertices))
  878.         return 0;
  879.  
  880.     /* initialize geometry */
  881.     for (j = 0, curTopNode = nodes; j < numTopNodes; j++, curTopNode++)
  882.         initPatchNodes(curTopNode, pfCoords, pfTexCoords);
  883.  
  884.     /* create geometry */
  885.     if (curCluster->flags & LSB_TEXTURED)
  886.         for (k = 0, curTopNode = nodes; k < numTopNodes; k++, curTopNode++)
  887.         buildPolygons(0, recursionLimit, curTopNode, pfColors, pfCoords, pfTexCoords);
  888.     else
  889.         for (k = 0, curTopNode = nodes; k < numTopNodes; k++, curTopNode++)
  890.         buildPolygons(0, recursionLimit, curTopNode, pfColors, pfCoords, NULL);
  891.  
  892.     /* go ahead and build this cluster's geometry */
  893.     if ((clustersPerGeode > 0) &&
  894.         ( ((clustersPerGeode == 1) || ((i > 0) && (i % clustersPerGeode) == 0)) ||
  895.           (i == lsbHeader->numPatchClusters - 1)) )
  896.         pfAddChild(groupNode, pfdBuild());
  897.     }
  898.  
  899.     if (nodes       != NULL) pfFree(nodes);
  900.     if (vertices    != NULL) pfFree(vertices);
  901.     if (pfColors    != NULL) pfFree(pfColors);
  902.     if (pfCoords    != NULL) pfFree(pfCoords);
  903.     if (pfTexCoords != NULL) pfFree(pfTexCoords);
  904.  
  905.     return 1;
  906. }
  907.  
  908. static int
  909. readSignature(FILE *fp)
  910. {
  911.     char line[256];
  912.     static char *signature = LSB_SIGNATURE;
  913.  
  914.     /* read LSB signature */
  915.     if (fgets(line, 256, fp) == NULL)
  916.     return 0;
  917.     if (strncmp(signature, line, strlen(signature)) != 0)
  918.     return 0;
  919.  
  920.     /* scan past signature data */
  921.     do
  922.     {
  923.     if (fgets(line, 256, fp) == NULL)
  924.         return 0;
  925.     }
  926.     while (line[0] != LSB_BEGIN_CHAR);
  927.  
  928.     /* indicate success */
  929.     return 1;
  930. }
  931.  
  932. static int
  933. readHeader(FILE *fp, LSBheader *header)
  934. {
  935.     if (fread((void *)header, sizeof(LSBheader), 1, fp) <= 0)
  936.     return 0;
  937.  
  938.     swapLSBheader(header);
  939.     /* indicate success */
  940.     return 1;
  941. }
  942.  
  943. static int
  944. readMaterials(FILE *fp, void *arena, unsigned int nmaterials,
  945.     LSmaterial **materials)
  946. {
  947.     unsigned int i;
  948.     char line[256];
  949.  
  950.     /* check input arguments */
  951.     if (nmaterials < 1 || materials == NULL)
  952.     return 1;
  953.  
  954.     /* allocate an array of LSmaterial structures */
  955.     *materials = (LSmaterial *)
  956.     pfCalloc(nmaterials, sizeof(LSmaterial), arena);
  957.     if (*materials == NULL)
  958.     return 0;
  959.  
  960.     /* read material information */
  961.     pfNotify(PFNFY_DEBUG, PFNFY_PRINT, "Materials");
  962.     for (i = 0; i < nmaterials; i++)
  963.     {
  964.     if (fgets(line, 256, fp) == NULL)
  965.           return 0;
  966.  
  967.     line[strlen(line) - 1] = '\0';
  968.     (*materials)[i].name = strdup(line);
  969.  
  970.     pfNotify(PFNFY_DEBUG, PFNFY_PRINT, " %2d: %s", i, line);
  971.     }
  972.  
  973.     /* indicate success */
  974.     return 1;
  975. }
  976.  
  977. static int
  978. deallocateMaterials(unsigned int nmaterials, LSmaterial **materials)
  979. {
  980.     unsigned int i;
  981.  
  982.     /* no materials means nothing to deallocate */
  983.     if (nmaterials < 1 || materials == NULL || *materials == NULL)
  984.     return 1;
  985.  
  986.     /* delete each material's data */
  987.     for (i = 0; i < nmaterials; i++)
  988.     if ((*materials)[i].name != NULL)
  989.         free((*materials)[i].name);
  990.  
  991.     /* reset material array pointer */
  992.     pfFree(*materials);
  993.     *materials = NULL;
  994.  
  995.     /* indicate success */
  996.     return 1;
  997. }
  998.  
  999. static int
  1000. readLayers(FILE *fp, void *arena, unsigned int nlayers, LSlayer **layers)
  1001. {
  1002.     unsigned int i;
  1003.     char line[256];
  1004.  
  1005.     /* check input arguments */
  1006.     if (nlayers < 1 || layers == NULL)
  1007.     return 1;
  1008.  
  1009.     /* allocate an array of LSlayer structures */
  1010.     *layers = (LSlayer *)pfCalloc(nlayers, sizeof(LSlayer), arena);
  1011.     if (*layers == NULL)
  1012.     return 0;
  1013.  
  1014.     /* read layer information */
  1015.     pfNotify(PFNFY_DEBUG, PFNFY_PRINT, "Layers");
  1016.     for (i = 0; i < nlayers; i++)
  1017.     {
  1018.     if (fgets(line, 256, fp) == NULL)
  1019.         return 0;
  1020.  
  1021.     line[strlen(line) - 1] = '\0';
  1022.     (*layers)[i].name = strdup(line);
  1023.  
  1024.     pfNotify(PFNFY_DEBUG, PFNFY_PRINT, " %2d: %s", i, line);
  1025.     }
  1026.  
  1027.     /* indicate success */
  1028.     return 1;
  1029. }
  1030.  
  1031. static int
  1032. deallocateLayers(unsigned int nlayers, LSlayer **layers)
  1033. {
  1034.     unsigned int i;
  1035.  
  1036.     /* no layers means nothing to deallocate */
  1037.     if (layers == NULL || *layers == NULL)
  1038.     return 1;
  1039.  
  1040.     /* delete each layer's data */
  1041.     for (i = 0; i < nlayers; i++)
  1042.     if ((*layers)[i].name != NULL)
  1043.         free((*layers)[i].name);
  1044.  
  1045.     /* reset layer array pointer */
  1046.     pfFree(*layers);
  1047.     *layers = NULL;
  1048.  
  1049.     /* indicate success */
  1050.     return 1;
  1051. }
  1052.  
  1053. static int
  1054. readTextures(FILE *fp, void *arena, unsigned int ntextures,
  1055.     LStexture **textures)
  1056. {
  1057.     unsigned int i;
  1058.     char line[256];
  1059.  
  1060.     /* check input arguments */
  1061.     if (ntextures < 1 || textures == NULL)
  1062.     return 1;
  1063.  
  1064.     /* allocate an array of LStexture structures */
  1065.     *textures = (LStexture *)pfCalloc(ntextures, sizeof(LStexture), arena);
  1066.     if (*textures == NULL)
  1067.     return 0;
  1068.  
  1069.     /* read texture information */
  1070.     pfNotify(PFNFY_DEBUG, PFNFY_PRINT, "Textures");
  1071.     for (i = 0; i < ntextures; i++)
  1072.     {
  1073.     if (fgets(line, 256, fp) == NULL)
  1074.         return 0;
  1075.  
  1076.     line[strlen(line) - 1] = '\0';
  1077.     (*textures)[i].name = strdup(line);
  1078.  
  1079.     pfNotify(PFNFY_DEBUG, PFNFY_PRINT, " %2d: %s", i, line);
  1080.     }
  1081.  
  1082.     /* indicate success */
  1083.     return 1;
  1084. }
  1085.  
  1086. static int
  1087. deallocateTextures(unsigned int ntextures, LStexture **textures)
  1088. {
  1089.     unsigned int i;
  1090.  
  1091.     /* no textures means nothing to deallocate */
  1092.     if (textures == NULL || *textures == NULL)
  1093.     return 1;
  1094.  
  1095.     /* delete each textures's data */
  1096.     for (i = 0; i < ntextures; i++)
  1097.     if ((*textures)[i].name != NULL)
  1098.         free((*textures)[i].name);
  1099.  
  1100.     /* reset texture array pointer */
  1101.     pfFree(*textures);
  1102.     *textures = NULL;
  1103.  
  1104.     /* indicate success */
  1105.     return 1;
  1106. }
  1107.  
  1108. /*
  1109.  * pfdLoadFile_lsb -- Load Lightscape ".lsb" files into IRIS Performer
  1110.  */
  1111.  
  1112. extern pfNode *
  1113. pfdLoadFile_lsb (char *fileName)
  1114. {
  1115.     FILE        *lsbFile    = NULL;
  1116.     pfNode      *node       = NULL;
  1117.     LSmaterial      *materials  = NULL;
  1118.     LSlayer     *layers     = NULL;
  1119.     LStexture       *textures   = NULL;
  1120.     LSpatchCluster  *clusters   = NULL;
  1121.     LSBheader        lsbHeader;
  1122.     int          recursionLimit = 0;
  1123.     char        *ep     = NULL;
  1124.  
  1125.     double startTime    = pfGetTime();
  1126.     double elapsedTime  = 0.0;
  1127.  
  1128.     /* restore builder to initial state */
  1129.     pfdResetBldrGeometry();
  1130.     pfdResetBldrState();
  1131.  
  1132.     /* open ".lsb" file */
  1133.     if ((lsbFile = pfdOpenFile(fileName)) == NULL)
  1134.     {
  1135.     pfNotify(PFNFY_WARN, PFNFY_RESOURCE,
  1136.         "pfdLoadFile_lsb: error opening file \"%s\"", fileName);
  1137.     return NULL;
  1138.     }
  1139.  
  1140.     /* read ".lsb" file "signature" section */
  1141.     if (!readSignature(lsbFile))
  1142.     {
  1143.     pfNotify(PFNFY_WARN, PFNFY_RESOURCE,
  1144.         "pfdLoadFile_lsb: error reading signature from \"%s\"", fileName);
  1145.     fclose(lsbFile);
  1146.     return NULL;
  1147.     }
  1148.  
  1149.     /* read ".lsb" file "header" section */
  1150.     if (!readHeader(lsbFile, &lsbHeader))
  1151.     {
  1152.     pfNotify(PFNFY_WARN, PFNFY_RESOURCE,
  1153.         "pfdLoadFile_lsb: error reading header from \"%s\"", fileName);
  1154.     fclose(lsbFile);
  1155.     return NULL;
  1156.     }
  1157.  
  1158.     /* update recursion limit from environment variable */
  1159.     if ((ep = getenv("LS_RECURSION_LIMIT")) != NULL)
  1160.     sscanf(ep, "%d", &recursionLimit);
  1161.  
  1162.     /* update clusters-per-geode from environment variable */
  1163.     if ((ep = getenv("LS_CLUSTERS_PER_GEODE")) != NULL)
  1164.     sscanf(ep, "%d", &clustersPerGeode);
  1165.  
  1166.     /* update spatial size from environment variable */
  1167.     if ((ep = getenv("LS_SPATIAL_SIZE")) != NULL)
  1168.     sscanf(ep, "%f", &spatialSize);
  1169.  
  1170.     /* update spatial count from environment variable */
  1171.     if ((ep = getenv("LS_SPATIAL_COUNT")) != NULL)
  1172.     sscanf(ep, "%d", &spatialCount);
  1173.  
  1174.     /* update file search path from environment variable */
  1175.     if ((ep = getenv("LS_TEXTURE_PATH")) != NULL)
  1176.     {
  1177.     const char *op = pfGetFilePath();
  1178.     char *np = NULL;
  1179.     if (op == NULL)
  1180.         op = "";
  1181.     np = (char *)pfMalloc(strlen(op) + 1 + strlen(ep) + 1, NULL);
  1182.     strcpy(np, ep);
  1183.     strcat(np, ":");
  1184.     strcat(np, op);
  1185.     pfFilePath(np);
  1186.     pfFree(np);
  1187.     }
  1188.  
  1189.     /* disable lighting (that's what radiosity is all about ;-) */
  1190.     pfdBldrStateMode(PFSTATE_ENLIGHTING, PF_OFF);
  1191.     pfdBldrStateMode(PFSTATE_CULLFACE, PFCF_BACK);
  1192.  
  1193.     /* disable undesired automatic builder actions */
  1194.     pfdBldrMode(PFDBLDR_AUTO_NORMALS, PF_OFF);
  1195.     pfdBldrMode(PFDBLDR_AUTO_ORIENT,  PF_OFF);
  1196.  
  1197.     /* parent group for "build-clumps-of-clusters" mode */
  1198.     if (clustersPerGeode > 0)
  1199.     groupNode = pfNewGroup();
  1200.  
  1201.     /* reset global geometry counters */
  1202.     numTris  = 0;
  1203.     numQuads = 0;
  1204.    
  1205.     /* allocate geometry buffer structure */
  1206.     geom = pfdNewGeom(geomSize = 256);
  1207.  
  1208.     /* read ".lsb" file materials, layers, textures, and clusters */
  1209.     if (readMaterials(lsbFile, NULL, lsbHeader.numMaterials, &materials) &&
  1210.     readLayers   (lsbFile, NULL, lsbHeader.numLayers,    &layers)    &&
  1211.     readTextures (lsbFile, NULL, lsbHeader.numTextures,  &textures)  &&
  1212.     readClusters (lsbFile, &lsbHeader, materials, layers, textures, recursionLimit))
  1213.     {
  1214.     /* build scene graph of file's primitives unless it's already built */
  1215.     if (clustersPerGeode > 0)
  1216.         node = (pfNode *)groupNode;
  1217.     else
  1218.         node = pfdBuild();
  1219.  
  1220.     /* construct spatial octree hierarchy from geosets in scene graph */
  1221.     if (spatialSize != 0.0f || spatialCount != 0)
  1222.     {
  1223.         pfGroup *group = pfNewGroup();
  1224.         pfAddChild(group, node);
  1225.         node = (pfNode *)pfdSpatialize(group, spatialSize, spatialCount);
  1226.     }
  1227.  
  1228.     /* use file name name for top-level pfNode */
  1229.     if (node != NULL)
  1230.         pfNodeName(node, fileName);
  1231.  
  1232.     /* print statistics */
  1233.     pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "pfdLoadFile_lsb: %s", fileName);
  1234.     pfNotify(PFNFY_INFO,   PFNFY_MORE,  "  Configuration Data:");
  1235.     if (ep != NULL)
  1236.         pfNotify(PFNFY_INFO,   PFNFY_MORE,  "    Texture path:       %s", ep);
  1237.     if (recursionLimit > 0)
  1238.         pfNotify(PFNFY_INFO,   PFNFY_MORE,  "    Recursion limit:    %8ld",
  1239.         recursionLimit);
  1240.     if (clustersPerGeode > 0)
  1241.         pfNotify(PFNFY_INFO,   PFNFY_MORE,  "    Clusters per geode: %8ld",
  1242.         clustersPerGeode);
  1243.     if (lsbHeader.numMaterials != 0)
  1244.         pfNotify(PFNFY_INFO,   PFNFY_MORE,  "    Input materials:    %8ld",
  1245.         lsbHeader.numMaterials);
  1246.     if (lsbHeader.numLayers != 0)
  1247.         pfNotify(PFNFY_INFO,   PFNFY_MORE,  "    Input layers:       %8ld",
  1248.         lsbHeader.numLayers);
  1249.     if (lsbHeader.numTextures != 0)
  1250.         pfNotify(PFNFY_INFO,   PFNFY_MORE,  "    Input textures:     %8ld",
  1251.         lsbHeader.numTextures);
  1252.     if (lsbHeader.numPatchClusters != 0)
  1253.         pfNotify(PFNFY_INFO,   PFNFY_MORE,  "    Input clusters:     %8ld",
  1254.         lsbHeader.numPatchClusters);
  1255.     if (numTris != 0 || numQuads != 0)
  1256.         pfNotify(PFNFY_INFO,   PFNFY_MORE,  "  Input Data:");
  1257.     if (numTris != 0)
  1258.         pfNotify(PFNFY_INFO,   PFNFY_MORE,  "    Input triangles:    %8ld",
  1259.         numTris);
  1260.     if (numQuads != 0)
  1261.         pfNotify(PFNFY_INFO,   PFNFY_MORE,  "    Input quads:        %8ld",
  1262.         numQuads);
  1263.     }
  1264.  
  1265.     /* close input file */
  1266.     fclose(lsbFile);
  1267.  
  1268.     /* release allocated storage */
  1269.     deallocateMaterials(lsbHeader.numMaterials,      &materials);
  1270.     deallocateLayers   (lsbHeader.numLayers,         &layers);
  1271.     deallocateTextures (lsbHeader.numTextures,       &textures);
  1272.  
  1273.     /* release storage allocated for geometric primitives */
  1274.     pfdDelGeom(geom);
  1275.  
  1276.     /* release storage allocated by the builder */
  1277.     pfdResetBldrGeometry();
  1278.  
  1279.     /* return root node to caller */
  1280.     return node;
  1281. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement