/* * PVVMUD a 3D MUD * Copyright (C) 1998-1999 Programvareverkstedet (pvv@pvv.org) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "globals.h" #include "writebog.h" #include "namedb.H" CNameDB * nameDB; void countElements(TreeNode_t * node, WORD * numV, WORD * numN, WORD * numTC, WORD * numP){ if (node == NULL) return; switch (node->nodeKind){ case FileK: case GeometryK: countElements(node->child[0],numV,numN,numTC,numP); countElements(node->child[1],numV,numN,numTC,numP); break; case VertexListK: case NormalListK: case TexCoordListK: countElements(node->child[0],numV,numN,numTC,numP); countElements(node->sibling,numV,numN,numTC,numP); break; case VertexK: (*numV)++; countElements(node->sibling,numV,numN,numTC,numP); break; case NormalK: (*numN)++; countElements(node->sibling,numV,numN,numTC,numP); break; case TexCoordK: (*numTC)++; countElements(node->sibling,numV,numN,numTC,numP); break; case PolyK: (*numP)++; countElements(node->sibling,numV,numN,numTC,numP); break; } } void writeVertex(TreeNode_t * node, FILE * bogfile ){ if (node == NULL) return; switch (node->nodeKind){ case GeometryK: writeVertex(node->child[0],bogfile); break; case VertexListK: writeVertex(node->child[0],bogfile); writeVertex(node->sibling,bogfile); break; case NormalListK: case TexCoordListK: writeVertex(node->sibling,bogfile); break; case VertexK: fprintf(bogfile,"%f %f %f\n", node->child[0]->attr.value, node->child[1]->attr.value, node->child[2]->attr.value); writeVertex(node->sibling,bogfile); break; } } void writeNormal(TreeNode_t * node, FILE * bogfile ){ if (node == NULL) return; switch (node->nodeKind){ case GeometryK: writeNormal(node->child[0],bogfile); break; case NormalListK: writeNormal(node->child[0],bogfile); writeNormal(node->sibling,bogfile); break; case VertexListK: case TexCoordListK: writeNormal(node->sibling,bogfile); break; case NormalK: fprintf(bogfile,"%f %f %f\n", node->child[0]->attr.value, node->child[1]->attr.value, node->child[2]->attr.value); writeNormal(node->sibling,bogfile); break; } } void writeTexCoord(TreeNode_t * node, FILE * bogfile ){ if (node == NULL) return; switch (node->nodeKind){ case GeometryK: writeTexCoord(node->child[0],bogfile); break; case TexCoordListK: writeTexCoord(node->child[0],bogfile); writeTexCoord(node->sibling,bogfile); break; case VertexListK: case NormalListK: writeTexCoord(node->sibling,bogfile); break; case TexCoordK: fprintf(bogfile,"%f %f\n", node->child[0]->attr.value, node->child[1]->attr.value); writeTexCoord(node->sibling,bogfile); break; } } void writePolygonType(TreeNode_t * node, FILE * bogfile ){ if (node == NULL) return; if (node->nodeKind == PolyTypeK){ fprintf(bogfile,"%i ",node->attr.polyType); } else writePolygonType(node->sibling,bogfile); } void writePolygonMaterial(TreeNode_t * node, FILE * bogfile ){ if (node == NULL) return; if (node->nodeKind == MaterialK){ fprintf(bogfile,"%i ",nameDB->insert(node->attr.name)); } else writePolygonMaterial(node->sibling,bogfile); } void writePolygonVertices(TreeNode_t * node, FILE * bogfile ){ if (node == NULL) return; switch (node->nodeKind){ case VertexIndexListK: writePolygonVertices(node->child[0],bogfile); break; case IndexK: fprintf(bogfile,"%i ",node->attr.index); if (node->sibling == NULL) fprintf(bogfile,"\n"); break; } writePolygonVertices(node->sibling,bogfile); } void writePolygonNormals(TreeNode_t * node, FILE * bogfile ){ if (node == NULL) return; switch (node->nodeKind){ case NormalIndexListK: writePolygonNormals(node->child[0],bogfile); break; case IndexK: fprintf(bogfile,"%i ",node->attr.index); if (node->sibling == NULL) fprintf(bogfile,"\n"); break; } writePolygonNormals(node->sibling,bogfile); } void writePolygonTexCoords(TreeNode_t * node, FILE * bogfile ){ if (node == NULL) return; switch (node->nodeKind){ case TexCoordIndexListK: writePolygonTexCoords(node->child[0],bogfile); break; case IndexK: fprintf(bogfile,"%i ",node->attr.index); if (node->sibling == NULL) fprintf(bogfile,"\n"); break; } writePolygonTexCoords(node->sibling,bogfile); } void countIndex(TreeNode_t * node, WORD * numI){ if (node == NULL) return; switch (node->nodeKind){ case IndexK: (*numI)++; break; } countIndex(node->sibling,numI); } void countPolygon(TreeNode_t * node, WORD * numV, WORD * numN, WORD * numTC){ if (node == NULL) return; switch (node->nodeKind){ case VertexIndexListK: countIndex(node->child[0],numV); break; case NormalIndexListK: countIndex(node->child[0],numN); break; case TexCoordIndexListK: countIndex(node->child[0],numTC); break; } countPolygon(node->sibling,numV,numN,numTC); } void writePolygon(TreeNode_t * node, FILE * bogfile ){ WORD numV,numN,numTC; if (node == NULL) return; switch (node->nodeKind){ case GeometryK: writePolygon(node->child[1],bogfile); break; case PolyK: writePolygonType(node->child[0],bogfile); writePolygonMaterial(node->child[0],bogfile); numV = numN = numTC = 0; countPolygon(node->child[0],&numV,&numN,&numTC); fprintf(bogfile,"%i %i %i\n",numV,numN,numTC); writePolygonVertices(node->child[0],bogfile); writePolygonNormals(node->child[0],bogfile); writePolygonTexCoords(node->child[0],bogfile); writePolygon(node->sibling,bogfile); break; } } void countObjects(TreeNode_t * node,WORD * numO){ if (node == NULL) return; switch (node->nodeKind){ case FileK: countObjects(node->child[1],numO); break; case GeometryK: (*numO)++; countObjects(node->sibling,numO); break; default: printf("Error: countObjects not supposed to encounter this node!\n"); } } void writeObjects(TreeNode_t * node,FILE * bogfile, WORD objectId){ WORD numVertices,numNormals,numTexCoords,numPolygons; if (node == NULL) return; switch (node->nodeKind){ case FileK: writeObjects(node->child[1],bogfile,objectId); break; case GeometryK: numVertices = 0; numNormals = 0; numTexCoords = 0; numPolygons = 0; countElements(node,&numVertices,&numNormals,&numTexCoords,&numPolygons); fprintf(bogfile,"%i %i %i %i %i\n", objectId,numVertices,numNormals,numTexCoords,numPolygons); writeVertex(node,bogfile); writeNormal(node,bogfile); writeTexCoord(node,bogfile); writePolygon(node,bogfile); writeObjects(node->sibling,bogfile,objectId+1); break; default: printf("Error: writeObjects not supposed to encounter this node!\n"); } } void writebogfile(TreeNode_t * node, FILE * bogfile, FILE * ndbfile ){ WORD numObjects; numObjects = 0; nameDB = new CNameDB; countObjects(node,&numObjects); fprintf(bogfile,"BOG 1 %i\n",numObjects); writeObjects(node,bogfile,0); nameDB->writeNDB(ndbfile); delete nameDB; }