1 /****************************************************************************************/
\r
4 /* Author: John Pollard */
\r
5 /* Description: Saves non GFX data to GFX data (GFX data is data on disk) */
\r
7 /* The contents of this file are subject to the Genesis3D Public License */
\r
8 /* Version 1.01 (the "License"); you may not use this file except in */
\r
9 /* compliance with the License. You may obtain a copy of the License at */
\r
10 /* http://www.genesis3d.com */
\r
12 /* Software distributed under the License is distributed on an "AS IS" */
\r
13 /* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */
\r
14 /* the License for the specific language governing rights and limitations */
\r
15 /* under the License. */
\r
17 /* The Original Code is Genesis3D, released March 25, 1999. */
\r
18 /*Genesis3D Version 1.1 released November 15, 1999 */
\r
19 /* Copyright (C) 1999 WildTangent, Inc. All Rights Reserved */
\r
21 /****************************************************************************************/
\r
22 #include <Windows.h>
\r
26 #include "GBSPPrep.h"
\r
27 #include "GBSPFile.h"
\r
28 #include "Poly.h" // For Planes, and NumPlanes
\r
30 #include "Map.h" // For texture
\r
31 #include "Texture.h"
\r
32 #include "Portals.h"
\r
38 geBoolean SaveGFXModelData(geVFile *f);
\r
39 geBoolean SaveGFXNodes(geVFile *f);
\r
40 geBoolean SaveGFXPortals(geVFile *f);
\r
41 geBoolean SaveGFXBNodes(geVFile *f);
\r
42 geBoolean SaveGFXLeafs(geVFile *f);
\r
43 geBoolean SaveGFXClusters(geVFile *f); // CHANGE: CLUSTER
\r
44 geBoolean SaveGFXAreasAndPortals(geVFile *f);
\r
45 geBoolean SaveGFXFaces(geVFile *f);
\r
46 geBoolean SaveGFXLeafSides(geVFile *f);
\r
47 geBoolean SaveGFXVerts(geVFile *f);
\r
48 geBoolean SaveGFXVertIndexList(geVFile *f);
\r
49 geBoolean SaveGFXPlanes(geVFile *f);
\r
50 geBoolean SaveGFXTextures(geVFile *f);
\r
51 geBoolean SaveGFXEntData(geVFile *f);
\r
52 geBoolean SaveGFXMotionData(geVFile *VFile);
\r
56 int32 NumSolidLeafs;
\r
58 geBoolean ConvertGBSPToFile(char *FileName)
\r
63 strcpy(VisFile, FileName);
\r
65 if (!FixModelTJunctions())
\r
67 GHook.Error("ConvertGBSPToFile: FixModelTJunctions failed.\n");
\r
71 GFXVertIndexList = GE_RAM_ALLOCATE_ARRAY(int32,TotalIndexVerts);
\r
72 NumGFXVerts = NumWeldedVerts;
\r
73 GFXVerts = WeldedVerts;
\r
75 // Go through all the bsp models and setup data that the gfxmodels need
\r
76 if (!PrepAllGBSPModels())
\r
78 GHook.Error("ConvertGBSPToFile: Could not Prep Models.\n");
\r
82 f = geVFile_OpenNewSystem(NULL, GE_VFILE_TYPE_DOS, FileName, NULL, GE_VFILE_OPEN_CREATE);
\r
86 GHook.Error("ConvertGBSPToFile: geVFile_OpenNewSystem failed.\n");
\r
90 strcpy(GBSPHeader.TAG, "GBSP");
\r
91 GBSPHeader.TAG[4] = NULL;
\r
93 GBSPHeader.Version = GBSP_VERSION;
\r
95 // Record the time the bsp was saved...
\r
96 GetSystemTime(&GBSPHeader.BSPTime);
\r
98 Chunk.Type = GBSP_CHUNK_HEADER;
\r
99 Chunk.Size = sizeof(GBSP_Header);
\r
100 Chunk.Elements = 1;
\r
101 WriteChunk(&Chunk, (void*)&GBSPHeader, f);
\r
103 // HACK! Just point these to the GBSP versions, but reset them below...
\r
104 NumGFXLeafSides = NumLeafSides;
\r
105 GFXLeafSides = (GFX_LeafSide*)LeafSides;
\r
107 //GHook.Printf("Saving GFX Model Data\n");
\r
108 if (!SaveGFXModelData(f))
\r
110 GHook.Error("ConvertGBSPToFile: SaveGFXModelData failed.\n");
\r
113 if (!SaveGFXNodes(f))
\r
115 if (!SaveGFXLeafs(f))
\r
117 GHook.Error("ConvertGBSPToFile: SaveGFXLeafs failed.\n");
\r
120 if (!SaveGFXClusters(f))
\r
122 if (!SaveGFXAreasAndPortals(f))
\r
124 if (!SaveGFXLeafSides(f))
\r
126 if (!SaveGFXFaces(f))
\r
128 if (!SaveGFXPlanes(f))
\r
130 if (!SaveGFXVerts(f))
\r
132 if (!SaveGFXVertIndexList(f))
\r
134 if (!SaveGFXTextures(f))
\r
136 if (!SaveGFXEntData(f))
\r
138 if (!SaveGFXMotionData(f))
\r
141 Chunk.Type = GBSP_CHUNK_END;
\r
142 Chunk.Elements = 0;
\r
144 WriteChunk(&Chunk, NULL, f);
\r
148 GHook.Printf(" --- Save GBSP File --- \n");
\r
150 GHook.Printf("Num Models : %5i, %6i\n", NumBSPModels, NumBSPModels*sizeof(GFX_Model));
\r
151 GHook.Printf("Num Nodes : %5i, %6i\n", NumGFXNodes, NumGFXNodes*sizeof(GFX_Node));
\r
152 GHook.Printf("Num Solid Leafs : %5i, %6i\n", NumSolidLeafs, NumSolidLeafs*sizeof(GFX_Leaf));
\r
153 GHook.Printf("Num Total Leafs : %5i, %6i\n", NumGFXLeafs, NumGFXLeafs*sizeof(GFX_Leaf));
\r
154 GHook.Printf("Num Clusters : %5i, %6i\n", NumGFXClusters, NumGFXClusters*sizeof(GFX_Cluster));
\r
155 GHook.Printf("Num Areas : %5i, %6i\n", NumGFXAreas-1, (NumGFXAreas-1)*sizeof(GFX_Area));
\r
156 GHook.Printf("Num Area Portals : %5i, %6i\n", NumGFXAreaPortals, NumGFXAreaPortals*sizeof(GFX_AreaPortal));
\r
157 GHook.Printf("Num Leafs Sides : %5i, %6i\n", NumGFXLeafSides, NumGFXLeafSides*sizeof(GFX_LeafSide));
\r
158 GHook.Printf("Num Planes : %5i, %6i\n", NumPlanes, NumPlanes*sizeof(GBSP_Plane));
\r
159 GHook.Printf("Num Faces : %5i, %6i\n", NumGFXFaces, NumGFXFaces*sizeof(GFX_Face));
\r
160 GHook.Printf("Num Leaf Faces : %5i, %6i\n", NumGFXLeafFaces, NumGFXLeafFaces*sizeof(int32));
\r
161 GHook.Printf("Num Vert Index : %5i, %6i\n", NumGFXVertIndexList, NumGFXVertIndexList*sizeof(int32));
\r
162 GHook.Printf("Num Verts : %5i, %6i\n", NumGFXVerts, NumGFXVerts*sizeof(geVec3d));
\r
163 GHook.Printf("Num FaceInfo : %5i, %6i\n", NumGFXTexInfo, NumGFXTexInfo*sizeof(GFX_TexInfo));
\r
164 GHook.Printf("Num Textures : %5i, %6i\n", NumGFXTextures, NumGFXTextures*sizeof(GFX_Texture));
\r
165 GHook.Printf("Motion Data Size : %6i\n", NumGFXMotionBytes);
\r
166 GHook.Printf("Tex Data Size : %6i\n", NumGFXTexData);
\r
168 geRam_Free(GFXVertIndexList);
\r
169 GFXVertIndexList = NULL;
\r
170 NumGFXVertIndexList = 0;
\r
172 //geRam_Free(GFXVerts);
\r
177 // Reset these back, since we did not actually create them, we just
\r
178 // pointed them to the GBSP_LeafSide structure version (same structure size/type)
\r
179 GFXLeafSides = NULL;
\r
180 NumGFXLeafSides = 0;
\r
187 geBoolean SaveGFXModelData(geVFile *f)
\r
193 Chunk.Type = GBSP_CHUNK_MODELS;
\r
194 Chunk.Size = sizeof(GFX_Model);
\r
195 Chunk.Elements = NumBSPModels;
\r
197 WriteChunk(&Chunk, NULL, f);
\r
199 for (i=0; i< NumBSPModels; i++)
\r
201 // FIXME: Make a (BSPModel ---> GFXModel) function
\r
202 GModel.RootNode[0] = BSPModels[i].RootNodeID[0];
\r
203 GModel.Origin = BSPModels[i].Origin;
\r
204 GModel.Mins = BSPModels[i].Mins;
\r
205 GModel.Maxs = BSPModels[i].Maxs;
\r
206 GModel.RootNode[1] = BSPModels[i].RootNodeID[1];
\r
207 GModel.FirstFace = BSPModels[i].FirstFace;
\r
208 GModel.NumFaces = BSPModels[i].NumFaces;
\r
209 GModel.FirstLeaf = BSPModels[i].FirstLeaf;
\r
210 GModel.NumLeafs = BSPModels[i].NumLeafs;
\r
211 GModel.FirstCluster = BSPModels[i].FirstCluster;
\r
212 GModel.NumClusters = BSPModels[i].NumClusters;
\r
213 GModel.Areas[0] = BSPModels[i].Areas[0];
\r
214 GModel.Areas[1] = BSPModels[i].Areas[1];
\r
215 if (geVFile_Write(f, &GModel, sizeof(GFX_Model)) != GE_TRUE)
\r
217 GHook.Error("SaveGFXModelData: There was an error writing the model.\n");
\r
225 geBoolean SaveGFXNodes_r(GBSP_Node *Node, geVFile *f)
\r
229 if (Node->PlaneNum == PLANENUM_LEAF)
\r
232 GNode.Children[0] = Node->ChildrenID[0];
\r
233 GNode.Children[1] = Node->ChildrenID[1];
\r
234 GNode.NumFaces = Node->NumFaces;
\r
235 GNode.FirstFace = Node->FirstFace;
\r
236 GNode.PlaneNum = Node->PlaneNum;
\r
237 GNode.Mins = Node->Mins;
\r
238 GNode.Maxs = Node->Maxs;
\r
240 if (geVFile_Write(f, &GNode, sizeof(GFX_Node)) != GE_TRUE)
\r
242 GHook.Error("SaveGFXNodes_r: There was an error writing the node.\n");
\r
246 if (!SaveGFXNodes_r(Node->Children[0], f))
\r
249 if (!SaveGFXNodes_r(Node->Children[1], f))
\r
255 geBoolean SaveGFXNodes(geVFile *f)
\r
260 Chunk.Type = GBSP_CHUNK_NODES;
\r
261 Chunk.Size = sizeof(GFX_Node);
\r
262 Chunk.Elements = NumGFXNodes;
\r
264 WriteChunk(&Chunk, NULL, f);
\r
266 for (i=0; i< NumBSPModels; i++)
\r
268 if (!SaveGFXNodes_r(BSPModels[i].RootNode[0], f))
\r
275 geBoolean SaveGFXPortals_r(GBSP_Node *Node, geVFile *f)
\r
277 GBSP_Portal *Portal;
\r
278 GFX_Portal GPortal;
\r
283 if (Node->PlaneNum == PLANENUM_LEAF)
\r
285 if (Node->Contents & BSP_CONTENTS_SOLID2)
\r
288 for (Portal = Node->Portals; Portal; Portal = Portal->Next[Side])
\r
290 Side = (Portal->Nodes[1] == Node);
\r
292 if (!(Portal->Nodes[0]->Contents & BSP_CONTENTS_SOLID2) &&
\r
293 !(Portal->Nodes[1]->Contents & BSP_CONTENTS_SOLID2))
\r
295 Poly = Portal->Poly;
\r
296 geVec3d_Clear(&Origin);
\r
297 for (i=0; i< Poly->NumVerts; i++)
\r
298 geVec3d_Add(&Origin, &Poly->Verts[i], &Origin);
\r
299 for (i=0; i<3; i++)
\r
300 VectorToSUB(Origin, i) /= Poly->NumVerts;
\r
302 GPortal.Origin = Origin;
\r
303 GPortal.LeafTo = Portal->Nodes[!Side]->PortalLeafNum;
\r
305 if (geVFile_Write(f, &GPortal, sizeof(GFX_Portal)) != GE_TRUE)
\r
307 GHook.Error("SaveGFXPortals_r: There was an error writing the portal.\n");
\r
315 if (!SaveGFXPortals_r(Node->Children[0], f))
\r
318 if (!SaveGFXPortals_r(Node->Children[1], f))
\r
324 geBoolean SaveGFXPortals(geVFile *f)
\r
329 Chunk.Type = GBSP_CHUNK_PORTALS;
\r
330 Chunk.Size = sizeof(GFX_Portal);
\r
331 Chunk.Elements = NumGFXPortals;
\r
333 WriteChunk(&Chunk, NULL, f);
\r
335 for (i=0; i< NumBSPModels; i++)
\r
337 if (!SaveGFXPortals_r(BSPModels[i].RootNode[0], f))
\r
344 geBoolean SaveGFXBNodes_r(GBSP_Node *Node, geVFile *f)
\r
348 if (Node->PlaneNum == PLANENUM_LEAF)
\r
351 GBNode.Children[0] = Node->ChildrenID[0];
\r
352 GBNode.Children[1] = Node->ChildrenID[1];
\r
353 GBNode.PlaneNum = Node->PlaneNum;
\r
354 //GBNode.PlaneSide = Node->PlaneSide;
\r
356 if (geVFile_Write(f, &GBNode, sizeof(GFX_BNode)) != GE_TRUE)
\r
358 GHook.Error("SaveGFXBNodes_r: There was an error writing the node.\n");
\r
362 if (!SaveGFXBNodes_r(Node->Children[0], f))
\r
364 if (!SaveGFXBNodes_r(Node->Children[1], f))
\r
370 geBoolean SaveGFXBNodes(geVFile *f)
\r
375 Chunk.Type = GBSP_CHUNK_BNODES;
\r
376 Chunk.Size = sizeof(GFX_BNode);
\r
377 Chunk.Elements = NumGFXBNodes;
\r
379 WriteChunk(&Chunk, NULL, f);
\r
381 for (i=0; i< NumBSPModels; i++)
\r
382 if (!SaveGFXBNodes_r(BSPModels[i].RootNode[1], f))
\r
388 int32 TotalLeafSize;
\r
390 //========================================================================================
\r
392 //========================================================================================
\r
393 geBoolean SaveGFXLeafs_r(GBSP_Node *Node, geVFile *f)
\r
398 if (Node->PlaneNum == PLANENUM_LEAF)
\r
400 GLeaf.Contents = Node->Contents;
\r
403 if (!GLeaf.Contents)
\r
404 GLeaf.Contents = BSP_CONTENTS_AIR;
\r
407 GLeaf.Mins = Node->Mins;
\r
408 GLeaf.Maxs = Node->Maxs;
\r
410 GLeaf.FirstFace = NumGFXLeafFaces;
\r
411 GLeaf.FirstPortal = Node->FirstPortal;
\r
412 GLeaf.NumPortals = Node->NumPortals;
\r
414 GLeaf.Cluster = Node->Cluster; // CHANGE: CLUSTER
\r
415 GLeaf.Area = Node->Area;
\r
417 GLeaf.FirstSide = Node->FirstSide;
\r
418 GLeaf.NumSides = Node->NumSides;
\r
420 GLeaf.NumFaces = 0;
\r
422 for (i=0; i< Node->NumLeafFaces; i++)
\r
424 if (!Node->LeafFaces[i]->Visible)
\r
427 // Don't output mark face if it was skipped in the face output stage
\r
428 // (or it will reference an invalid face...)
\r
429 if (Node->LeafFaces[i]->NumIndexVerts <= 0)
\r
432 GFXLeafFaces[NumGFXLeafFaces] = Node->LeafFaces[i]->OutputNum;
\r
438 TotalLeafSize += sizeof(GFX_Leaf);
\r
440 if (geVFile_Write(f, &GLeaf, sizeof(GFX_Leaf)) != GE_TRUE)
\r
442 GHook.Error("SaveGFXLeafs_r: There was an error writing the leaf.\n");
\r
448 if (!SaveGFXLeafs_r(Node->Children[0], f))
\r
450 if (!SaveGFXLeafs_r(Node->Children[1], f))
\r
456 //========================================================================================
\r
458 //========================================================================================
\r
459 geBoolean SaveGFXLeafs(geVFile *f)
\r
464 Chunk.Type = GBSP_CHUNK_LEAFS;
\r
465 Chunk.Size = sizeof(GFX_Leaf);
\r
466 Chunk.Elements = NumGFXLeafs;
\r
468 WriteChunk(&Chunk, NULL, f);
\r
472 // NumGFXLeafFaces was counted earlier in the PrepGfxNodes Stage
\r
473 GFXLeafFaces = GE_RAM_ALLOCATE_ARRAY(int32,NumGFXLeafFaces);
\r
475 NumGFXLeafFaces = 0; // We must reset this...
\r
477 for (i=0; i< NumBSPModels; i++)
\r
479 // Save all the leafs for this model
\r
480 if (!SaveGFXLeafs_r(BSPModels[i].RootNode[0], f))
\r
482 GHook.Error("SaveGFXLeafs: SaveGFXLeafs_r failed.\n");
\r
487 if (TotalLeafSize != Chunk.Size * Chunk.Elements)
\r
489 GHook.Error("SaveGFXLeafs: Leaf sizes don't match.\n");
\r
490 // return GE_FALSE;
\r
493 // Save gfx leaf faces here...
\r
494 Chunk.Type = GBSP_CHUNK_LEAF_FACES;
\r
495 Chunk.Size = sizeof(int32);
\r
496 Chunk.Elements = NumGFXLeafFaces;
\r
498 WriteChunk(&Chunk, GFXLeafFaces, f);
\r
504 //========================================================================================
\r
506 //========================================================================================
\r
507 geBoolean SaveGFXClusters(geVFile *f)
\r
511 GFX_Cluster GCluster;
\r
513 NumGFXClusters = NumLeafClusters;
\r
514 Chunk.Type = GBSP_CHUNK_CLUSTERS;
\r
515 Chunk.Size = sizeof(GFX_Cluster);
\r
516 Chunk.Elements = NumGFXClusters;
\r
518 WriteChunk(&Chunk, NULL, f);
\r
520 for (i=0; i< NumGFXClusters; i++)
\r
522 GCluster.VisOfs = -1;
\r
524 if (geVFile_Write(f, &GCluster, sizeof(GFX_Cluster)) != GE_TRUE)
\r
526 GHook.Error("SaveGFXClusters: There was an error saving the cluster.\n");
\r
533 //========================================================================================
\r
534 // SaveGFXAreasAndPortals
\r
535 //========================================================================================
\r
536 geBoolean SaveGFXAreasAndPortals(geVFile *f)
\r
541 // Save the areas first
\r
543 Chunk.Type = GBSP_CHUNK_AREAS;
\r
544 Chunk.Size = sizeof(GFX_Area);
\r
545 Chunk.Elements = NumGFXAreas;
\r
547 WriteChunk(&Chunk, GFXAreas, f);
\r
550 // Then, save the areaportals
\r
552 Chunk.Type = GBSP_CHUNK_AREA_PORTALS;
\r
553 Chunk.Size = sizeof(GFX_AreaPortal);
\r
554 Chunk.Elements = NumGFXAreaPortals;
\r
556 WriteChunk(&Chunk, GFXAreaPortals, f);
\r
561 //========================================================================================
\r
563 //========================================================================================
\r
564 geBoolean SaveGFXFaces_r(GBSP_Node *Node, geVFile *f)
\r
569 if (Node->PlaneNum == PLANENUM_LEAF)
\r
572 for (Face = Node->Faces; Face; Face = Face->Next)
\r
574 if (!Face->Visible)
\r
577 if (Face->Merged || Face->Split[0] || Face->Split[1])
\r
580 if (Face->NumIndexVerts > 0)
\r
582 GFace.FirstVert = Face->FirstIndexVert;
\r
583 GFace.NumVerts = Face->NumIndexVerts;
\r
584 GFace.PlaneNum = Face->PlaneNum;
\r
585 GFace.PlaneSide = Face->PlaneSide;
\r
586 GFace.TexInfo = Face->TexInfo;
\r
587 #pragma message ("Make LWidth/Height correct!")
\r
590 GFace.LightOfs = -1; // No light info yet
\r
591 GFace.LTypes[0] = 255; // Of course, no styles yet either
\r
592 GFace.LTypes[1] = 255;
\r
593 GFace.LTypes[2] = 255;
\r
594 GFace.LTypes[3] = 255;
\r
596 if (geVFile_Write(f, &GFace, sizeof(GFX_Face)) != GE_TRUE)
\r
598 GHook.Error("SaveGFXFace_r: There was an error writing the face.\n");
\r
604 if (!SaveGFXFaces_r(Node->Children[0], f))
\r
607 if (!SaveGFXFaces_r(Node->Children[1], f))
\r
613 //========================================================================================
\r
615 //========================================================================================
\r
616 geBoolean SaveGFXFaces(geVFile *f)
\r
621 Chunk.Type = GBSP_CHUNK_FACES;
\r
622 Chunk.Size = sizeof(GFX_Face);
\r
623 Chunk.Elements = NumGFXFaces;
\r
625 WriteChunk(&Chunk, NULL, f);
\r
627 for (i=0; i< NumBSPModels; i++)
\r
628 if (!SaveGFXFaces_r(BSPModels[i].RootNode[0], f))
\r
634 //========================================================================================
\r
636 //========================================================================================
\r
637 geBoolean SaveGFXPlanes(geVFile *f)
\r
643 NumGFXPlanes = NumPlanes;
\r
644 Chunk.Type = GBSP_CHUNK_PLANES;
\r
645 Chunk.Size = sizeof(GFX_Plane);
\r
646 Chunk.Elements = NumGFXPlanes;
\r
648 WriteChunk(&Chunk, NULL, f);
\r
650 for (i=0; i< NumGFXPlanes; i++)
\r
652 GPlane.Normal = Planes[i].Normal;
\r
653 GPlane.Dist = Planes[i].Dist;
\r
654 GPlane.Type = Planes[i].Type;
\r
656 if (geVFile_Write(f, &GPlane, sizeof(GFX_Plane)) != GE_TRUE)
\r
658 GHook.Error("SaveGFXPlanes: There was an error saving the plane.\n");
\r
666 //========================================================================================
\r
667 // SaveGFXLeafSides
\r
668 //========================================================================================
\r
669 geBoolean SaveGFXLeafSides(geVFile *f)
\r
673 Chunk.Type = GBSP_CHUNK_LEAF_SIDES;
\r
674 Chunk.Size = sizeof(GFX_LeafSide);
\r
675 Chunk.Elements = NumGFXLeafSides;
\r
677 if (!WriteChunk(&Chunk, GFXLeafSides, f))
\r
679 GHook.Error("There was an error writing the verts.\n");
\r
686 //========================================================================================
\r
688 //========================================================================================
\r
689 geBoolean SaveGFXVerts(geVFile *f)
\r
693 Chunk.Type = GBSP_CHUNK_VERTS;
\r
694 Chunk.Size = sizeof(geVec3d);
\r
695 Chunk.Elements = NumGFXVerts;
\r
697 if (!WriteChunk(&Chunk, GFXVerts, f))
\r
699 GHook.Error("There was an error writing the verts.\n");
\r
706 //========================================================================================
\r
707 // SaveGFXVertIndexList
\r
708 //========================================================================================
\r
709 geBoolean SaveGFXVertIndexList(geVFile *f)
\r
713 Chunk.Type = GBSP_CHUNK_VERT_INDEX;
\r
714 Chunk.Size = sizeof(int32);
\r
715 Chunk.Elements = NumGFXVertIndexList;
\r
717 if (!WriteChunk(&Chunk, GFXVertIndexList, f))
\r
719 GHook.Error("SaveGFXvertIndexList: There was an error saving the VertIndexList.\n");
\r
726 //========================================================================================
\r
728 //========================================================================================
\r
729 void PrepGFXNode(GBSP_Node *Node)
\r
737 Node->FirstFace = NumGFXFaces;
\r
739 for (Face = Node->Faces; Face; Face = Face->Next)
\r
741 if (!Face->Visible)
\r
744 if (Face->Merged || Face->Split[0] || Face->Split[1])
\r
747 // Skip output of face, if IndexVerts not > 0
\r
748 // NOTE - The leaf faces output stage will also skip these same faces...
\r
749 if (Face->NumIndexVerts <= 0)
\r
752 Face->FirstIndexVert = NumGFXVertIndexList;
\r
753 Face->OutputNum = NumGFXFaces;
\r
755 Verts = Face->Poly->Verts;
\r
757 for (i=0; i< Face->NumIndexVerts; i++)
\r
759 GFXVertIndexList[NumGFXVertIndexList] = Face->IndexVerts[i];
\r
761 NumGFXVertIndexList++;
\r
767 Node->NumFaces = NumFaces;
\r
770 //========================================================================================
\r
772 // Store current nodes for model in GFXNodes/GFXLeafs so they can be saved to disk
\r
773 //========================================================================================
\r
774 int32 PrepGFXNodes_r(int32 Original, GBSP_Node *Node)
\r
778 // Prep the leaf and it's portals
\r
779 if (Node->PlaneNum == PLANENUM_LEAF)
\r
781 if (Node->Contents & BSP_CONTENTS_SOLID2)
\r
782 NumSolidLeafs++; // Remember how many solid leafs there are
\r
784 Node->NumPortals = 0;
\r
785 Node->FirstPortal = -1;
\r
787 // To be able to save out portal LeafTo's
\r
788 Node->PortalLeafNum = NumGFXLeafs;
\r
790 // Count num gfx leaf faces here, so we know how big to make the array
\r
791 // later, when they are saved out...
\r
792 NumGFXLeafFaces += Node->NumLeafFaces;
\r
796 GBSP_Portal *Portal;
\r
799 // Setup leaf portals
\r
800 Node->FirstPortal = NumGFXPortals;
\r
801 for (Portal = Node->Portals; Portal; Portal = Portal->Next[Side])
\r
803 Side = (Portal->Nodes[1] == Node);
\r
805 if (!(Portal->Nodes[0]->Contents & BSP_CONTENTS_SOLID2) &&
\r
806 !(Portal->Nodes[1]->Contents & BSP_CONTENTS_SOLID2))
\r
808 Node->NumPortals++;
\r
815 // Increase the number of leafs
\r
818 return -(NumGFXLeafs);
\r
821 CurrentNode = NumGFXNodes;
\r
827 Node->ChildrenID[0] = PrepGFXNodes_r(Node->ChildrenID[0], Node->Children[0]);
\r
828 Node->ChildrenID[1] = PrepGFXNodes_r(Node->ChildrenID[1], Node->Children[1]);
\r
830 return CurrentNode;
\r
833 //typedef unsigned char RawPalette[256*3];
\r
835 geBoolean SaveGFXTextures(geVFile *f)
\r
839 uint8 Data[256*256*4];
\r
840 int32 Size, Width, Height, Offset, i;
\r
842 DRV_Palette Palette;
\r
845 File = ValueForKey(&Entities[0], "TextureLib");
\r
846 if (!File || !File[0])
\r
848 GHook.Error("SaveGFXTextures: No TextureLib specified in map file.\n");
\r
852 if (!InitTextureLib(File))
\r
857 geVFile_Tell(f, &Pos1);
\r
859 Chunk.Type = GBSP_CHUNK_TEXDATA;
\r
861 Chunk.Elements = 1;
\r
863 WriteChunk(&Chunk, NULL, f);
\r
865 //GHook.Printf("Num Textures: %i\n", NumTextures);
\r
867 for (i=0; i< NumTextures; i++)
\r
869 //GHook.Printf("Texture : %i, %s\n", i, Textures[i].Name);
\r
871 if (!GetTexture(Textures[i].Name, Data, &Size, &Width, &Height, f))
\r
874 Textures[i].Width = Width;
\r
875 Textures[i].Height = Height;
\r
876 Textures[i].Offset = NumGFXTexData;
\r
877 Textures[i].PaletteIndex = i;
\r
879 NumGFXTexData += Size;
\r
882 geVFile_Tell(f, &Pos2);
\r
884 geVFile_Seek(f, Pos1, GE_VFILE_SEEKSET);
\r
886 Chunk.Type = GBSP_CHUNK_TEXDATA;
\r
888 Chunk.Elements = NumGFXTexData;
\r
889 WriteChunk(&Chunk, NULL, f);
\r
891 geVFile_Seek(f, Pos2, GE_VFILE_SEEKSET);
\r
893 // Now save textures
\r
894 NumGFXTextures = NumTextures;
\r
896 Chunk.Type = GBSP_CHUNK_TEXTURES;
\r
897 Chunk.Size = sizeof(GFX_Texture);
\r
898 Chunk.Elements = NumGFXTextures;
\r
900 WriteChunk(&Chunk, NULL, f);
\r
902 if (geVFile_Write(f, (GFX_Texture*)Textures, sizeof(GFX_Texture) * NumGFXTextures) != GE_TRUE)
\r
904 GHook.Error("SaveGFXTexture: There was an error saving the texture.\n");
\r
907 // added transparent textures
\r
908 for(i=0;i<NumTexInfo;i++)
\r
910 TexNum = TexInfo[i].Texture;
\r
911 if(HasTextureAlpha(Textures[TexNum].Name)==GE_TRUE)
\r
913 TexInfo[i].Flags |= TEXINFO_TRANS;
\r
914 TexInfo[i].Alpha = 255.0f;
\r
917 // end transparent textures
\r
919 // Now save tex info
\r
920 NumGFXTexInfo = NumTexInfo;
\r
922 Chunk.Type = GBSP_CHUNK_TEXINFO;
\r
923 Chunk.Size = sizeof(GFX_TexInfo);
\r
924 Chunk.Elements = NumGFXTexInfo;
\r
926 WriteChunk(&Chunk, NULL, f);
\r
928 if (geVFile_Write(f, (GFX_TexInfo*)TexInfo, sizeof(GFX_TexInfo) * NumGFXTexInfo) != GE_TRUE)
\r
930 GHook.Error("SaveGFXTexture: There was an error saving the tex info.\n");
\r
934 // Save all of the palettes out, too
\r
935 Chunk.Type = GBSP_CHUNK_PALETTES;
\r
936 Chunk.Size = 256 * 3 * sizeof(unsigned char);
\r
937 Chunk.Elements = NumTextures;
\r
939 WriteChunk(&Chunk, NULL, f);
\r
941 for (i=0; i< NumTextures; i++)
\r
943 //GHook.Printf("Texture : %i, %s\n", i, Textures[i].Name);
\r
945 if (!GetTexturePalette(Textures[i].Name, Palette))
\r
948 if (geVFile_Write(f, &Palette[0], sizeof(Palette)) != GE_TRUE)
\r
950 GHook.Error("There was an error saving the palettes");
\r
955 ShutdownTextureLib();
\r
960 //========================================================================================
\r
962 //========================================================================================
\r
963 geBoolean SaveGFXEntData(geVFile *f)
\r
965 geVFile_MemoryContext Context;
\r
969 // Start an empty memory file
\r
970 Context.Data = NULL;
\r
971 Context.DataLength = 0;
\r
973 MemFile = geVFile_OpenNewSystem(NULL, GE_VFILE_TYPE_MEMORY, NULL, &Context, GE_VFILE_OPEN_CREATE);
\r
978 // Fill this file with the entitydata
\r
979 if (!SaveEntityData(MemFile))
\r
981 geVFile_Close(MemFile);
\r
982 GHook.Error("SaveGFXEntData: SaveEntityData failed.\n");
\r
986 // Update the context with this data
\r
987 if (!geVFile_UpdateContext(MemFile, &Context, sizeof(Context)))
\r
989 geVFile_Close(MemFile);
\r
993 // Write the chunk out
\r
994 Chunk.Type = GBSP_CHUNK_ENTDATA;
\r
995 Chunk.Size = sizeof(uint8);
\r
996 Chunk.Elements = Context.DataLength;
\r
998 if (!WriteChunk(&Chunk, Context.Data, f))
\r
1000 GHook.Error("SaveEntData: There was an error saving the EntData.\n");
\r
1004 geVFile_Close(MemFile);
\r
1009 //========================================================================================
\r
1010 //========================================================================================
\r
1011 void BeginGBSPModels(void)
\r
1013 NumLeafClusters = 0;
\r
1014 NumSolidLeafs = 0;
\r
1016 NumLeafBevels = 0;
\r
1018 // Clear all gfx variables
\r
1019 NumGFXPortals = 0;
\r
1025 NumGFXVertIndexList = 0;
\r
1026 NumGFXLeafFaces = 0;
\r
1030 void FinalizeNodeMinMax(GBSP_Node *RootNode);
\r
1032 //========================================================================================
\r
1034 //========================================================================================
\r
1035 geBoolean PrepGBSPModel(GBSP_Model *Model, geBoolean SaveVis)
\r
1037 // Save vis file for vising model 0
\r
1040 // Create vis portals
\r
1041 if (!CreatePortals(Model->RootNode[0], Model, GE_TRUE))
\r
1043 GHook.Printf("PrepGBSPModel: Could not create VIS portals.\n");
\r
1048 Model->FirstCluster = NumLeafClusters;
\r
1050 if (!CreateLeafClusters(Model->RootNode[0]))
\r
1052 GHook.Error("Could not create leaf clusters.\n");
\r
1056 Model->NumClusters = NumLeafClusters - Model->FirstCluster;
\r
1058 if (!SavePortalFile(Model, VisFile))
\r
1061 // Free vis portals...
\r
1062 if (!FreePortals(Model->RootNode[0]))
\r
1064 GHook.Printf("PrepGBSPModel: Could not free portals.\n");
\r
1069 else // Models > 0 are assumed simple and no vising performed, clusters are not needed either...
\r
1071 Model->FirstCluster = -1;
\r
1072 Model->NumClusters = 0;
\r
1075 // Create the REAL structural portals
\r
1076 if (!CreatePortals(Model->RootNode[0], Model, GE_FALSE))
\r
1078 GHook.Printf("PrepGBSPModel: Could not create REAL portals.\n");
\r
1082 // Create the leaf collision hulls for bevel bbox collisions
\r
1083 if (!CreateLeafSides(Model->RootNode[0]))
\r
1085 GHook.Error("Could not create leaf sides.\n");
\r
1089 // Create the area leafs
\r
1090 if (Model == BSPModels) // Only world needs areas set...
\r
1091 if (!CreateAreas(Model->RootNode[0]))
\r
1093 GHook.Error("Could not create Areas.\n");
\r
1098 Model->FirstFace = NumGFXFaces;
\r
1099 Model->FirstLeaf = NumGFXLeafs;
\r
1101 // Prep the nodes, so we can save them out later to disk
\r
1102 Model->RootNodeID[0] = PrepGFXNodes_r(Model->RootNodeID[0], Model->RootNode[0]);
\r
1104 Model->NumFaces = NumGFXFaces - Model->FirstFace;
\r
1105 Model->NumLeafs = NumGFXLeafs - Model->FirstLeaf;
\r
1110 geBoolean PrepAllGBSPModels(void)
\r
1114 // Restore verbose since BSP stage turns it off for entities
\r
1115 Verbose = OriginalVerbose;
\r
1117 for (i=0; i< NumBSPModels; i++)
\r
1119 // Turn it back off for entities if asked to do so...
\r
1120 if (i > 0 && !EntityVerbose)
\r
1121 Verbose = GE_FALSE;
\r
1123 if (!PrepGBSPModel(&BSPModels[i], i == 0))
\r
1125 GHook.Error("PrepAllGBSPModels: Could not prep model %i.\n", i);
\r