/**********************************************************************************/
/*
*/
/* File: bsp.h
*/
/* Author: bkenwright@xbdev.net
*/
/* URL: www.xbdev.net
*/
/* Date: 22-12-2005 (xmas)
*/
/*
*/
/**********************************************************************************/
#ifndef
BSP_H
#define
BSP_H
#include
<d3dx9.h> //
DirectX Header Files
#pragma
comment(lib,
"d3d9.lib") // DirectX
Library Files
#pragma
comment(lib,
"d3dx9.lib") //
IDirect3DDevice* etc
#include
"common.h" //
SafeRelease(..)
#include
"dxdbg.h" //
Triangle3D(..)
//----------------------- Various BSP Lump Data
Types-----------------------------//
enum
BSP_TYPES
{
enEntities=0,
enTextures,
enPlanes,
enNodes,
enLeaves,
enLeafFaces,
enLeafBrushes,
enModels,
enBrushes,
enBrushSides,
enVertices,
enMeshIndices,
enEffect,
enFaces,
enLightmaps,
enLightVols,
enVisData
};
//------------------------- Various Structure Definitions
------------------------//
struct
stLump
{
int nFileofs;
// Offset to start of lump, relative to
//
beginning of file.
int nFileLen;
// Length of lump. Always a multiple of 4.
};
struct
stHeader
{
char cMagic[4];
int nVersion;
stLump Lumps[17];
};
//----------------------------- Lump Definitions
---------------------------------//
typedef
float Vector2[2];
typedef
float Vector3[3];
typedef
float Vector4[4];
typedef
float TexCoord[2];
typedef
int nBBox[6];
// Integer bounding box (mins, maxs)
typedef
float fBBox[6];
// Float bounding box
//Lump 0
//Entities
//char *entities; // A pointer to text
//Lump 1
//Shader Texture Info
struct
stShaderRef
{
char Name[64];
// Texture name
int nSurfaceFlags;
// Type of surface (See Surface Flags below)
int nContentFlags;
// Leaf content (See Content Flags below)
};
//Lump 2
//Planes
struct
stPlane
{
Vector3 Normal; // Normal vector for
plane
float fDist;
// Distance from plane to origin
};
//Lump 3
//Nodes
struct
stNode
{
int nPlane;
// Space partitioning plane
int nChildren[2];
// Back and front child nodes
nBBox BBoxI; // Bounding box of
node
};
//Lump 4
//Leaves
struct
stLeaf
{
int nCluster;
// Visibility cluster number
int nArea;
// Volume of the leaf
nBBox BBoxI; // Bounding box of
leaf
int nFirstFace,
NumFaces; // Lookup for
the face list (indexes
// are
for faces)
int nFirstBrush,
NumBrushes; // Lookup for
the brush list (indexes
// are
for brushes)
};
//Lump 5
//Leaf Faces
//int *pFaces; // a pointer to a series of indexes to
// a
face list
//Lump 6
//Leaf Brushes
//int *pBrushes; // a pointer to a series of indexes to
// a
brush list
//Lump 7
//Models
struct
stModel
{
fBBox BBoxF; // Bounding box of
model
int nFirstFace,
// First face for model
NumFaces; // Number of
faces for model
int nFirstBrush,
// First brush for model
NumBrushes; // Number of
brushes for model
};
//Lump 8
//Brushes
struct
stBrush
{
int nFirstSide,
// First brushside for brush
NumSides; // Number of
brushsides for brush
int nIndex;
// Texture index
};
//Lump 9
//Brush Sides
struct
stBrushSide
{
int PlaneNum;
// Lookup for plane
int nIndex;
// Texture index
};
//Lump 10
//Vertices
struct
stVertex
{
Vector3 vPoint; // Vertex Position
TexCoord Tex; // Texture
coordinates
TexCoord LightTexCoord; // Light Map texture
coordinates
Vector3 vNormal; // Normal vector (used for
lighting ?)
unsigned int
RGBA; // Vertex color. RGBA
};
//Lump 11
//MeshVert
//int nOffset; // Vertex index offset, relative to
first
//
vertex of corresponding face.
//Lump 12
//Effect
struct
stEffect
{
char cName[64];
// Effect shader.
int nBrush;
// Brush that generated this effect.
int Unknown;
// Always 5, except in q3dm8, which has
// one
effect with -1.
};
//Lump 13
//Faces
#pragma
pack(1)
struct
stFace // size 24*4
{
int nShader;
// Refers to a shader
int nEffect;
// Index into lump 12 (Effects), or -1
int nFaceType;
// Face type. 1=polygon, 2=patch, 3=mesh,
4=billboard
int FirstVert,
NumVerts; // Reference
to vertices
int nFirstMeshVerts,
// Index of first meshvert
// Every
three meshverts describe a triangle
NumMeshVerts; // Number of
meshverts
int LMIndex;
// Lightmap index.
int LMStart[2];
// X,Y Corner of this face's lightmap image in
lightmap.
int LMSize[2];
// Size of lightmap
float LMOrigin[3];
// World space origin of lightmap.
float LMVects[2][3];
// World space lightmap s and t unit vectors.
Vector3 vNormal; // Face normal
int nSize[2];
// Patch dimensions.
};
#pragma
pack()
//Lump 14
//Lightmaps
//unsigned char pMap[128][128][3]; // Lightmap color data. RGB.
//Lump 15
//Light Grid
//Unknown
//Lump 16
//Visibility Lists
struct
stVisibility
{
int NumVectors;
// Number of vectors.
int nSizeVector;
// Size of each vector, in bytes
unsigned char
*pData; // [NumVectors * nSizeVector];
//
Visibility data. One bit per cluster per vector
};
//Lump 17
//Number of Lumps
//Unknown
void
ErrLog(char *str);
// bsp.cpp
class
CBSP
{
stHeader m_Header;
stVertex *m_pVerts;
int m_nNumVerts;
stFace *m_pFaces;
int m_nNumFaces;
int *m_pMeshVerts;
int m_nNumMeshVerts;
public:
CBSP(char * szFile )
{
// Always initialize variables
m_nNumVerts = 0;
m_nNumFaces = 0;
m_nNumMeshVerts = 0;
// Always initialise pointers to NULL
m_pFaces = NULL;
m_pVerts = NULL;
m_pMeshVerts = NULL;
Create(szFile);
}
~CBSP(){
Release(); }
int GetNumFaces()
{
return m_nNumFaces;
}
bool Release()
{
delete[] m_pVerts;
m_pVerts=NULL;
delete[] m_pFaces;
m_pFaces=NULL;
delete[] m_pMeshVerts;
m_pMeshVerts=NULL;
m_nNumVerts = 0;
m_nNumFaces = 0;
m_nNumMeshVerts = 0;
return
true; // No
Error
}
bool Create(const
char * szBSPFile)
{
if( szBSPFile==NULL )
{
ErrLog("<->Error NULL File Pointer");
return
false;
}
Release();
ErrLog("<->Opening File\n\n");
// Open BSP File
FILE * fp = fopen(szBSPFile, "rb");
assert(fp);
// Temporary Buffer
fread(&m_Header, //
Buffer
1,
// Size
sizeof(stHeader),
// Number of times
fp);
// File Pointer
// Get the pointer to our array of
lumps
stLump * pLumps = m_Header.Lumps;
//------------------------------------Vertices------------------------------------//
stLump * pLump = &pLumps[enVertices];
fseek( fp,
pLump->nFileofs,
SEEK_SET );
m_pVerts = (stVertex*)new
char[pLump->nFileLen];
assert(m_pVerts);
fread( (void*)m_pVerts,
// Buffer
1,
// Size
pLump->nFileLen, //
Number of times
fp );
// File Pointer
m_nNumVerts = pLump->nFileLen / sizeof(stVertex);
// Record Information
char
buf[100]; // Temp text
buffer
sprintf(buf, "\n<?>Num Vertices: %d\n", m_nNumVerts);
ErrLog(buf);
//------------------------------------ Faces
-------------------------------------//
pLump = &pLumps[enFaces];
fseek( fp,
pLump->nFileofs,
SEEK_SET );
m_pFaces = (stFace*)new
char[pLump->nFileLen];
assert(m_pFaces);
fread( (void*)m_pFaces,
// Buffer
pLump->nFileLen, //
Size
1,
// Number of times
fp );
// File Pointer
m_nNumFaces = pLump->nFileLen / sizeof(stFace);
// Record Information
sprintf(buf, "\n<?>Num Faces: %d\n", m_nNumFaces);
ErrLog(buf);
//-------------------------------- Mesh Vert Tris
-------------------------------------//
pLump = &pLumps[enMeshIndices];
fseek( fp,
pLump->nFileofs,
SEEK_SET );
m_pMeshVerts = (int*)new
char[pLump->nFileLen];
assert(m_pMeshVerts);
fread( (void*)m_pMeshVerts,
// Buffer
pLump->nFileLen, //
Size
1,
// Number of times
fp );
// File Pointer
m_nNumMeshVerts = pLump->nFileLen /
sizeof(int);
// Record Information
sprintf(buf, "\n<?>Num Mesh Verts: %d\n", m_nNumMeshVerts);
ErrLog(buf);
ErrLog("\n<->Closing File\n");
// Close BSP File
fclose(fp);
return
true; // No
Error
}
void Render(IDirect3DDevice9 * pDevice)
{
for(int
i=0; i<m_nNumFaces; i++)
{
// If its not a tri mesh
if( m_pFaces[i].nFaceType
!= 1 ) continue;
int nFirstF =
m_pFaces[i].nFirstMeshVerts;
int nNumF =
m_pFaces[i].NumMeshVerts;
int nFirstV =
m_pFaces[i].FirstVert;
int nNumV =
m_pFaces[i].NumVerts;
for(int
j=0; j<nNumF; j+=3)
{
int i0 =
m_pMeshVerts[nFirstF+0];
int i1 =
m_pMeshVerts[nFirstF+1];
int i2 =
m_pMeshVerts[nFirstF+2];
float *pA =
m_pVerts[nFirstV + i0].vPoint;
float *pB =
m_pVerts[nFirstV + i1].vPoint;
float *pC =
m_pVerts[nFirstV + i2].vPoint;
Triangle3D(pDevice,
pA[0], pA[1], pA[2],
pB[0], pB[1], pB[2],
pC[0], pC[1], pC[2],
0xffffffff);
nFirstF+=3;
}
}
}
};//End
CBSP class
#endif
// BSP_H |