1 /****************************************************************************************/
\r
4 /* Author: John Pollard */
\r
5 /* Description: Module distributes code to all the other modules */
\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
30 #include "Portals.h"
\r
37 #include "GBSPFile.h"
\r
42 GBSP_Model BSPModels[MAX_BSP_MODELS];
\r
45 geBoolean Verbose = GE_TRUE;
\r
46 geBoolean OriginalVerbose;
\r
47 geBoolean EntityVerbose = GE_FALSE;
\r
52 geBoolean ProcessEntities(void);
\r
53 void FreeBSP_r(GBSP_Node *Node);
\r
55 //=======================================================================================
\r
56 // InsertModelNumbers
\r
57 //=======================================================================================
\r
58 geBoolean InsertModelNumbers(void)
\r
65 for (i=0; i< NumEntities; i++)
\r
70 if (!Entities[i].Brushes2) // No model if no brushes
\r
73 Entities[i].ModelNum = NumModels;
\r
77 sprintf(ModelNum, "%i", NumModels);
\r
78 SetKeyValue(&Entities[i], "Model", ModelNum);
\r
85 //========================================================================================
\r
87 //========================================================================================
\r
88 geBoolean CreateBSP(char *FileName, BspParms *Parms)
\r
90 OriginalVerbose = Verbose = Parms->Verbose;
\r
91 EntityVerbose = Parms->EntityVerbose;
\r
93 gCountVerts = GE_TRUE;
\r
96 NumLeafClusters = 0;
\r
100 if (!LoadBrushFile(FileName))
\r
106 InsertModelNumbers();
\r
110 if (!ProcessEntities())
\r
120 //========================================================================================
\r
122 // Updates the entities only...
\r
123 //========================================================================================
\r
124 geBoolean UpdateEntities(char *MapName, char *BSPName)
\r
126 GHook.Printf("--- Update Entities --- \n");
\r
128 if (!LoadBrushFile(MapName))
\r
129 goto ExitWithError;
\r
131 InsertModelNumbers();
\r
133 // Load the old .BSP
\r
134 if (!LoadGBSPFile(BSPName))
\r
136 GHook.Error("UpdateEntities: Could not load .bsp file.\n");
\r
137 goto ExitWithError;
\r
140 // Destroy any old GFXEntData in the .BSP file
\r
143 geRam_Free(GFXEntData);
\r
148 if (!ConvertEntitiesToGFXEntData())
\r
150 GHook.Error("UpdateEntities: ConvertEntitiesToGFXEntData failed.\n");
\r
155 if (!SaveGBSPFile(BSPName))
\r
157 GHook.Error("UpdateEntities: SaveGBSPFile failed.\n");
\r
158 goto ExitWithError;
\r
161 FreeAllEntities(); // Free any entities that might be left behind
\r
162 FreeGBSPFile(); // Free any GFX BSP data left over
\r
166 FreeAllEntities(); // Free any entities that might be left behind
\r
167 FreeGBSPFile(); // Free any GFX BSP data left over
\r
171 //========================================================================================
\r
173 //========================================================================================
\r
174 GBSP_Node *AllocNode(void)
\r
178 Node = GE_RAM_ALLOCATE_STRUCT(GBSP_Node);
\r
182 GHook.Error("AllocNode: Out of memory!\n");
\r
186 memset(Node, 0, sizeof(GBSP_Node));
\r
191 //========================================================================================
\r
193 //========================================================================================
\r
194 void FreeNode(GBSP_Node *Node)
\r
196 GBSP_Face *Face, *Next;
\r
197 GBSP_Brush *Brush, *NextB;
\r
199 if (Node->LeafFaces)
\r
200 geRam_Free(Node->LeafFaces);
\r
202 for (Face = Node->Faces; Face; Face = Next)
\r
208 for (Brush = Node->BrushList; Brush; Brush = NextB)
\r
210 NextB = Brush->Next;
\r
218 //========================================================================================
\r
220 //========================================================================================
\r
221 geBoolean FreeAllGBSPData(void)
\r
225 for (i=0; i< NumBSPModels; i++)
\r
227 if (!FreePortals(BSPModels[i].RootNode[0]))
\r
229 GHook.Error("FreeAllGBSPData: Could not free portals.\n");
\r
232 FreeBSP_r(BSPModels[i].RootNode[0]);
\r
234 memset(&BSPModels[i], 0, sizeof(GBSP_Model));
\r
240 //========================================================================================
\r
242 //========================================================================================
\r
243 void CleanupGBSP(void)
\r
253 GBSP_Plane Planes[MAX_BSP_PLANES];
\r
254 int32 NumPlanes = 0;
\r
256 //====================================================================================
\r
258 // Expects at least 3 verts
\r
259 //====================================================================================
\r
260 void PlaneFromVerts(geVec3d *Verts, GBSP_Plane *Plane)
\r
262 geVec3d Vect1, Vect2;
\r
264 geVec3d_Subtract(&Verts[0], &Verts[1], &Vect1);
\r
265 geVec3d_Subtract(&Verts[2], &Verts[1], &Vect2);
\r
267 geVec3d_CrossProduct(&Vect1, &Vect2, &Plane->Normal);
\r
268 geVec3d_Normalize(&Plane->Normal);
\r
270 Plane->Dist = geVec3d_DotProduct(&Verts[0], &Plane->Normal);
\r
272 Plane->Type = geVec3d_PlaneType(&Plane->Normal);
\r
275 //====================================================================================
\r
277 //====================================================================================
\r
278 void SidePlane(GBSP_Plane *Plane, int32 *Side)
\r
282 *Side = 0; // Default to same direction
\r
284 Plane->Type = geVec3d_PlaneType(&Plane->Normal);
\r
286 Type = Plane->Type % PLANE_ANYX;
\r
288 // Point the major axis in the positive direction
\r
289 if (VectorToSUB(Plane->Normal, Type) < 0)
\r
291 geVec3d_Inverse(&Plane->Normal);
\r
292 Plane->Dist = -Plane->Dist;
\r
293 *Side = 1; // Flip if direction is opposite match
\r
297 #define NORMAL_EPSILON (geFloat)0.00001
\r
299 //====================================================================================
\r
301 //====================================================================================
\r
302 geBoolean PlaneEqual(GBSP_Plane *Plane1, GBSP_Plane *Plane2)
\r
304 if (fabs(Plane1->Normal.X - Plane2->Normal.X) < NORMAL_EPSILON &&
\r
305 fabs(Plane1->Normal.Y - Plane2->Normal.Y) < NORMAL_EPSILON &&
\r
306 fabs(Plane1->Normal.Z - Plane2->Normal.Z) < NORMAL_EPSILON &&
\r
307 fabs(Plane1->Dist - Plane2->Dist) < DIST_EPSILON )
\r
313 //====================================================================================
\r
315 //====================================================================================
\r
316 void SnapVector(geVec3d *Normal)
\r
320 for (i=0 ; i<3 ; i++)
\r
322 if ( fabs(VectorToSUB(*Normal,i) - (geFloat)1) < ANGLE_EPSILON )
\r
324 geVec3d_Clear(Normal);
\r
325 VectorToSUB(*Normal,i) = (geFloat)1;
\r
329 if ( fabs(VectorToSUB(*Normal,i) - (geFloat)-1) < ANGLE_EPSILON )
\r
331 geVec3d_Clear(Normal);
\r
332 VectorToSUB(*Normal,i) = (geFloat)-1;
\r
338 //====================================================================================
\r
340 //====================================================================================
\r
341 geFloat RoundInt(geFloat In)
\r
343 return (geFloat)floor(In + (geFloat)0.5);
\r
346 //====================================================================================
\r
348 //====================================================================================
\r
349 void SnapPlane(geVec3d *Normal, geFloat *Dist)
\r
351 SnapVector (Normal);
\r
353 if (fabs(*Dist-RoundInt(*Dist)) < DIST_EPSILON)
\r
354 *Dist = RoundInt(*Dist);
\r
358 //=======================================================================================
\r
360 //=======================================================================================
\r
361 void PlaneInverse(GBSP_Plane *Plane)
\r
363 geVec3d_Inverse(&Plane->Normal);
\r
364 Plane->Dist = -Plane->Dist;
\r
368 //====================================================================================
\r
370 //====================================================================================
\r
371 int32 FindPlane(GBSP_Plane *Plane, int32 *Side)
\r
374 GBSP_Plane *Plane2;
\r
378 SnapPlane(&Plane->Normal, &Plane->Dist);
\r
382 SidePlane(&Plane1, Side); // Find axis, and flip if necessary, to make major axis positive
\r
386 for (i=0; i< NumPlanes; i++) // Try to return a plane allready in the list
\r
388 if (PlaneEqual(&Plane1, Plane2))
\r
394 if (NumPlanes >= MAX_BSP_PLANES)
\r
396 GHook.Error("Max BSP Planes.\n");
\r
400 Planes[NumPlanes++] = Plane1;
\r
405 //=======================================================================================
\r
406 //=======================================================================================
\r
407 geFloat _fastcall Plane_PointDistanceFast(GBSP_Plane *Plane, geVec3d *Point)
\r
409 geFloat Dist,Dist2;
\r
411 Dist2 = Plane->Dist;
\r
413 switch (Plane->Type)
\r
417 Dist = (Point->X - Dist2);
\r
420 Dist = (Point->Y - Dist2);
\r
423 Dist = (Point->Z - Dist2);
\r
427 Dist = geVec3d_DotProduct(Point, &Plane->Normal) - Dist2;
\r