mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-25 21:31:32 +00:00
- Finish the merge of kexDoomMap into FLevel
This commit is contained in:
parent
be1ada81a6
commit
fe9368b048
9 changed files with 618 additions and 1299 deletions
|
@ -2,6 +2,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "framework/tarray.h"
|
||||
#include "lightmap/kexlib/math/mathlib.h"
|
||||
#undef MIN
|
||||
#undef MAX
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -228,12 +231,78 @@ struct vertex_t;
|
|||
struct surface_t;
|
||||
struct thingLight_t;
|
||||
|
||||
struct FloatVertex
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct leaf_t
|
||||
{
|
||||
vertex_t *vertex;
|
||||
FloatVertex vertex;
|
||||
MapSegGLEx *seg;
|
||||
};
|
||||
|
||||
struct lightDef_t
|
||||
{
|
||||
int doomednum;
|
||||
float height;
|
||||
float radius;
|
||||
float intensity;
|
||||
float falloff;
|
||||
bool bCeiling;
|
||||
kexVec3 rgb;
|
||||
};
|
||||
|
||||
struct mapDef_t
|
||||
{
|
||||
int map;
|
||||
int sunIgnoreTag;
|
||||
kexVec3 sunDir;
|
||||
kexVec3 sunColor;
|
||||
};
|
||||
|
||||
struct thingLight_t
|
||||
{
|
||||
IntThing *mapThing;
|
||||
kexVec2 origin;
|
||||
kexVec3 rgb;
|
||||
float intensity;
|
||||
float falloff;
|
||||
float height;
|
||||
float radius;
|
||||
bool bCeiling;
|
||||
IntSector *sector;
|
||||
MapSubsectorEx *ssect;
|
||||
};
|
||||
|
||||
struct surfaceLightDef
|
||||
{
|
||||
int tag;
|
||||
float outerCone;
|
||||
float innerCone;
|
||||
float falloff;
|
||||
float distance;
|
||||
float intensity;
|
||||
bool bIgnoreFloor;
|
||||
bool bIgnoreCeiling;
|
||||
bool bNoCenterPoint;
|
||||
kexVec3 rgb;
|
||||
};
|
||||
|
||||
enum mapFlags_t
|
||||
{
|
||||
ML_BLOCKING = 1, // Solid, is an obstacle.
|
||||
ML_BLOCKMONSTERS = 2, // Blocks monsters only.
|
||||
ML_TWOSIDED = 4, // Backside will not be present at all if not two sided.
|
||||
ML_TRANSPARENT1 = 2048, // 25% or 75% transcluency?
|
||||
ML_TRANSPARENT2 = 4096 // 25% or 75% transcluency?
|
||||
};
|
||||
|
||||
#define NO_SIDE_INDEX -1
|
||||
#define NO_LINE_INDEX 0xFFFF
|
||||
#define NF_SUBSECTOR 0x8000
|
||||
|
||||
struct FLevel
|
||||
{
|
||||
FLevel ();
|
||||
|
@ -277,30 +346,34 @@ struct FLevel
|
|||
|
||||
// Dlight helpers
|
||||
|
||||
leaf_t *leafs;
|
||||
uint8_t *mapPVS;
|
||||
leaf_t *leafs = nullptr;
|
||||
uint8_t *mapPVS = nullptr;
|
||||
|
||||
bool *bSkySectors;
|
||||
bool *bSSectsVisibleToSky;
|
||||
bool *bSkySectors = nullptr;
|
||||
bool *bSSectsVisibleToSky = nullptr;
|
||||
|
||||
int numLeafs;
|
||||
int numLeafs = 0;
|
||||
|
||||
int *segLeafLookup;
|
||||
int *ssLeafLookup;
|
||||
int *ssLeafCount;
|
||||
kexBBox *ssLeafBounds;
|
||||
int *segLeafLookup = nullptr;
|
||||
int *ssLeafLookup = nullptr;
|
||||
int *ssLeafCount = nullptr;
|
||||
kexBBox *ssLeafBounds = nullptr;
|
||||
|
||||
kexBBox *nodeBounds;
|
||||
kexBBox *nodeBounds = nullptr;
|
||||
|
||||
surface_t **segSurfaces[3];
|
||||
surface_t **leafSurfaces[2];
|
||||
surface_t **segSurfaces[3] = { nullptr, nullptr, nullptr };
|
||||
surface_t **leafSurfaces[2] = { nullptr, nullptr };
|
||||
|
||||
TArray<thingLight_t*> thingLights;
|
||||
TArray<kexLightSurface*> lightSurfaces;
|
||||
|
||||
void SetupDlight();
|
||||
void ParseConfigFile(const char *file);
|
||||
void CreateLights();
|
||||
void CleanupThingLights();
|
||||
|
||||
const kexVec3 &GetSunColor() const;
|
||||
const kexVec3 &GetSunDirection() const;
|
||||
|
||||
IntSideDef *GetSideDef(const MapSegGLEx *seg);
|
||||
IntSector *GetFrontSector(const MapSegGLEx *seg);
|
||||
IntSector *GetBackSector(const MapSegGLEx *seg);
|
||||
|
@ -308,8 +381,20 @@ struct FLevel
|
|||
MapSubsectorEx *PointInSubSector(const int x, const int y);
|
||||
bool PointInsideSubSector(const float x, const float y, const MapSubsectorEx *sub);
|
||||
bool LineIntersectSubSector(const kexVec3 &start, const kexVec3 &end, const MapSubsectorEx *sub, kexVec2 &out);
|
||||
vertex_t *GetSegVertex(int index);
|
||||
FloatVertex GetSegVertex(int index);
|
||||
bool CheckPVS(MapSubsectorEx *s1, MapSubsectorEx *s2);
|
||||
|
||||
private:
|
||||
void BuildNodeBounds();
|
||||
void BuildLeafs();
|
||||
void BuildPVS();
|
||||
void CheckSkySectors();
|
||||
|
||||
TArray<lightDef_t> lightDefs;
|
||||
TArray<surfaceLightDef> surfaceLightDefs;
|
||||
TArray<mapDef_t> mapDefs;
|
||||
|
||||
mapDef_t *mapDef = nullptr;
|
||||
};
|
||||
|
||||
const int BLOCKSIZE = 128;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "worker.h"
|
||||
#include "kexlib/binFile.h"
|
||||
#include "wad.h"
|
||||
#include "framework/templates.h"
|
||||
|
||||
//#define EXPORT_TEXELS_OBJ
|
||||
|
||||
|
@ -314,7 +315,7 @@ kexVec3 kexLightmapBuilder::LightTexelSample(kexTrace &trace, const kexVec3 &ori
|
|||
|
||||
dir.Normalize();
|
||||
|
||||
float r = MAX(radius - dist, 0);
|
||||
float r = MAX(radius - dist, 0.0f);
|
||||
|
||||
colorAdd = ((r * plane.Normal().Dot(dir)) / radius) * intensity;
|
||||
kexMath::Clamp(colorAdd, 0, 1);
|
||||
|
@ -651,11 +652,11 @@ void kexLightmapBuilder::LightSurface(const int surfid)
|
|||
// and against all nearby thing lights
|
||||
//
|
||||
|
||||
kexVec3 kexLightmapBuilder::LightCellSample(const int gridid, kexTrace &trace, const kexVec3 &origin, const mapSubSector_t *sub)
|
||||
kexVec3 kexLightmapBuilder::LightCellSample(const int gridid, kexTrace &trace, const kexVec3 &origin, const MapSubsectorEx *sub)
|
||||
{
|
||||
kexVec3 color;
|
||||
kexVec3 dir;
|
||||
mapSector_t *mapSector;
|
||||
IntSector *mapSector;
|
||||
float intensity;
|
||||
float radius;
|
||||
float dist;
|
||||
|
@ -787,7 +788,7 @@ void kexLightmapBuilder::LightGrid(const int gridid)
|
|||
int gx = (int)gridBlock.x;
|
||||
int gy = (int)gridBlock.y;
|
||||
kexTrace trace;
|
||||
mapSubSector_t *ss;
|
||||
MapSubsectorEx *ss;
|
||||
|
||||
// convert grid id to xyz coordinates
|
||||
mod = gridid;
|
||||
|
@ -858,7 +859,7 @@ void kexLightmapBuilder::LightGrid(const int gridid)
|
|||
// kexLightmapBuilder::CreateLightmaps
|
||||
//
|
||||
|
||||
void kexLightmapBuilder::CreateLightmaps(kexDoomMap &doomMap)
|
||||
void kexLightmapBuilder::CreateLightmaps(FLevel &doomMap)
|
||||
{
|
||||
map = &doomMap;
|
||||
|
||||
|
@ -916,7 +917,7 @@ void kexLightmapBuilder::CreateLightGrid()
|
|||
|
||||
// allocate data
|
||||
gridMap = (gridMap_t*)Mem_Calloc(sizeof(gridMap_t) * count, hb_static);
|
||||
gridSectors = (mapSubSector_t**)Mem_Calloc(sizeof(mapSubSector_t*) *
|
||||
gridSectors = (MapSubsectorEx**)Mem_Calloc(sizeof(MapSubsectorEx*) *
|
||||
(int)(gridBlock.x * gridBlock.y), hb_static);
|
||||
|
||||
// process all grid cells
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
void BuildSurfaceParams(surface_t *surface);
|
||||
void TraceSurface(surface_t *surface);
|
||||
void CreateLightGrid();
|
||||
void CreateLightmaps(kexDoomMap &doomMap);
|
||||
void CreateLightmaps(FLevel &doomMap);
|
||||
void LightSurface(const int surfid);
|
||||
void LightGrid(const int gridid);
|
||||
void WriteTexturesToTGA();
|
||||
|
@ -62,7 +62,7 @@ private:
|
|||
bool MakeRoomForBlock(const int width, const int height, int *x, int *y, int *num);
|
||||
kexBBox GetBoundsFromSurface(const surface_t *surface);
|
||||
kexVec3 LightTexelSample(kexTrace &trace, const kexVec3 &origin, surface_t *surface);
|
||||
kexVec3 LightCellSample(const int gridid, kexTrace &trace, const kexVec3 &origin, const mapSubSector_t *sub);
|
||||
kexVec3 LightCellSample(const int gridid, kexTrace &trace, const kexVec3 &origin, const MapSubsectorEx *sub);
|
||||
bool EmitFromCeiling(kexTrace &trace, const surface_t *surface, const kexVec3 &origin, const kexVec3 &normal, float *dist);
|
||||
void ExportTexelsToObjFile(FILE *f, const kexVec3 &org, int indices);
|
||||
void WriteBlock(FILE *f, const int i, const kexVec3 &org, int indices, kexBBox &box);
|
||||
|
@ -74,7 +74,7 @@ private:
|
|||
kexVec3 color;
|
||||
};
|
||||
|
||||
kexDoomMap *map;
|
||||
FLevel *map;
|
||||
kexArray<byte*> textures;
|
||||
int **allocBlocks;
|
||||
int numTextures;
|
||||
|
@ -82,7 +82,7 @@ private:
|
|||
int tracedTexels;
|
||||
int numLightGrids;
|
||||
gridMap_t *gridMap;
|
||||
mapSubSector_t **gridSectors;
|
||||
MapSubsectorEx **gridSectors;
|
||||
kexBBox worldGrid;
|
||||
kexBBox gridBound;
|
||||
kexVec3 gridBlock;
|
||||
|
|
|
@ -29,21 +29,8 @@
|
|||
|
||||
#include "surfaces.h"
|
||||
|
||||
struct surfaceLightDef
|
||||
{
|
||||
int tag;
|
||||
float outerCone;
|
||||
float innerCone;
|
||||
float falloff;
|
||||
float distance;
|
||||
float intensity;
|
||||
bool bIgnoreFloor;
|
||||
bool bIgnoreCeiling;
|
||||
bool bNoCenterPoint;
|
||||
kexVec3 rgb;
|
||||
};
|
||||
|
||||
struct FLevel;
|
||||
struct surfaceLightDef;
|
||||
class kexTrace;
|
||||
|
||||
class kexLightSurface
|
||||
|
|
|
@ -39,22 +39,188 @@
|
|||
static const kexVec3 defaultSunColor(1, 1, 1);
|
||||
static const kexVec3 defaultSunDirection(0.45f, 0.3f, 0.9f);
|
||||
|
||||
void FLevel::SetupDlight()
|
||||
{
|
||||
/*
|
||||
for (unsigned int i = 0; i < mapDefs.Size(); ++i)
|
||||
{
|
||||
if (mapDefs[i].map == wadFile.currentmap)
|
||||
{
|
||||
mapDef = &mapDefs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
mapDef = &mapDefs[0];
|
||||
|
||||
BuildNodeBounds();
|
||||
BuildLeafs();
|
||||
BuildPVS();
|
||||
CheckSkySectors();
|
||||
}
|
||||
|
||||
void FLevel::BuildNodeBounds()
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
kexVec3 point;
|
||||
float high = -M_INFINITY;
|
||||
float low = M_INFINITY;
|
||||
|
||||
nodeBounds = (kexBBox*)Mem_Calloc(sizeof(kexBBox) * NumGLNodes, hb_static);
|
||||
|
||||
for (i = 0; i < (int)Sectors.Size(); ++i)
|
||||
{
|
||||
if (Sectors[i].data.ceilingheight > high)
|
||||
{
|
||||
high = Sectors[i].data.ceilingheight;
|
||||
}
|
||||
if (Sectors[i].data.floorheight < low)
|
||||
{
|
||||
low = Sectors[i].data.floorheight;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NumGLNodes; ++i)
|
||||
{
|
||||
nodeBounds[i].Clear();
|
||||
|
||||
for (j = 0; j < 2; ++j)
|
||||
{
|
||||
point.Set(GLNodes[i].bbox[j][BOXLEFT], GLNodes[i].bbox[j][BOXBOTTOM], low);
|
||||
nodeBounds[i].AddPoint(point);
|
||||
point.Set(GLNodes[i].bbox[j][BOXRIGHT], GLNodes[i].bbox[j][BOXTOP], high);
|
||||
nodeBounds[i].AddPoint(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FLevel::BuildLeafs()
|
||||
{
|
||||
MapSubsectorEx *ss;
|
||||
leaf_t *lf;
|
||||
int i;
|
||||
int j;
|
||||
kexVec3 point;
|
||||
IntSector *sector;
|
||||
int count;
|
||||
|
||||
leafs = (leaf_t*)Mem_Calloc(sizeof(leaf_t*) * Sectors.Size() * 2, hb_static);
|
||||
numLeafs = NumGLSubsectors;
|
||||
|
||||
ss = GLSubsectors;
|
||||
|
||||
segLeafLookup = (int*)Mem_Calloc(sizeof(int) * Sectors.Size(), hb_static);
|
||||
ssLeafLookup = (int*)Mem_Calloc(sizeof(int) * NumGLSubsectors, hb_static);
|
||||
ssLeafCount = (int*)Mem_Calloc(sizeof(int) * NumGLSubsectors, hb_static);
|
||||
ssLeafBounds = (kexBBox*)Mem_Calloc(sizeof(kexBBox) * NumGLSubsectors, hb_static);
|
||||
|
||||
count = 0;
|
||||
|
||||
for (i = 0; i < NumGLSubsectors; ++i, ++ss)
|
||||
{
|
||||
ssLeafCount[i] = ss->numlines;
|
||||
ssLeafLookup[i] = ss->firstline;
|
||||
|
||||
ssLeafBounds[i].Clear();
|
||||
sector = GetSectorFromSubSector(ss);
|
||||
|
||||
if (ss->numlines)
|
||||
{
|
||||
for (j = 0; j < (int)ss->numlines; ++j)
|
||||
{
|
||||
MapSegGLEx *seg = &GLSegs[ss->firstline + j];
|
||||
lf = &leafs[count++];
|
||||
|
||||
segLeafLookup[ss->firstline + j] = i;
|
||||
|
||||
lf->vertex = GetSegVertex(seg->v1);
|
||||
lf->seg = seg;
|
||||
|
||||
point.Set(lf->vertex.x, lf->vertex.y, sector->data.floorheight);
|
||||
ssLeafBounds[i].AddPoint(point);
|
||||
|
||||
point.z = sector->data.ceilingheight;
|
||||
ssLeafBounds[i].AddPoint(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FLevel::BuildPVS()
|
||||
{
|
||||
// don't do anything if already loaded
|
||||
if (mapPVS != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int len = ((NumGLSubsectors + 7) / 8) * NumGLSubsectors;
|
||||
mapPVS = (byte*)Mem_Malloc(len, hb_static);
|
||||
memset(mapPVS, 0xff, len);
|
||||
}
|
||||
|
||||
void FLevel::CheckSkySectors()
|
||||
{
|
||||
char name[9];
|
||||
|
||||
bSkySectors = (bool*)Mem_Calloc(sizeof(bool) * Sectors.Size(), hb_static);
|
||||
bSSectsVisibleToSky = (bool*)Mem_Calloc(sizeof(bool) * NumGLSubsectors, hb_static);
|
||||
|
||||
for (int i = 0; i < NumGLSubsectors; ++i)
|
||||
{
|
||||
if (mapDef->sunIgnoreTag != 0 && Sectors[i].data.tag == mapDef->sunIgnoreTag)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
strncpy(name, Sectors[i].data.ceilingpic, 8);
|
||||
name[8] = 0;
|
||||
|
||||
if (!strncmp(name, "F_SKY001", 8))
|
||||
{
|
||||
bSkySectors[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// try to early out by quickly checking which subsector can potentially
|
||||
// see a sky sector
|
||||
for (int i = 0; i < NumGLSubsectors; ++i)
|
||||
{
|
||||
for (int j = 0; j < NumGLSubsectors; ++j)
|
||||
{
|
||||
IntSector *sec = GetSectorFromSubSector(&GLSubsectors[j]);
|
||||
|
||||
if (bSkySectors[sec - &Sectors[0]] == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CheckPVS(&GLSubsectors[i], &GLSubsectors[j]))
|
||||
{
|
||||
bSSectsVisibleToSky[i] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const kexVec3 &FLevel::GetSunColor() const
|
||||
{
|
||||
/*if (mapDef != NULL)
|
||||
if (mapDef != NULL)
|
||||
{
|
||||
return mapDef->sunColor;
|
||||
}*/
|
||||
}
|
||||
|
||||
return defaultSunColor;
|
||||
}
|
||||
|
||||
const kexVec3 &FLevel::GetSunDirection() const
|
||||
{
|
||||
/*if (mapDef != NULL)
|
||||
if (mapDef != NULL)
|
||||
{
|
||||
return mapDef->sunDir;
|
||||
}*/
|
||||
}
|
||||
|
||||
return defaultSunDirection;
|
||||
}
|
||||
|
@ -95,7 +261,7 @@ IntSector *FLevel::GetBackSector(const MapSegGLEx *seg)
|
|||
|
||||
if (line->flags & ML_TWOSIDED)
|
||||
{
|
||||
mapSideDef_t *backSide = &Sides[line->sidenum[seg->side ^ 1]];
|
||||
IntSideDef *backSide = &Sides[line->sidenum[seg->side ^ 1]];
|
||||
return &Sectors[backSide->sector];
|
||||
}
|
||||
|
||||
|
@ -104,12 +270,12 @@ IntSector *FLevel::GetBackSector(const MapSegGLEx *seg)
|
|||
|
||||
IntSector *FLevel::GetSectorFromSubSector(const MapSubsectorEx *sub)
|
||||
{
|
||||
mapSector_t *sector = NULL;
|
||||
IntSector *sector = NULL;
|
||||
|
||||
// try to find a sector that the subsector belongs to
|
||||
for (int i = 0; i < (int)sub->numlines; i++)
|
||||
{
|
||||
glSeg_t *seg = &GLSegs[sub->firstline + i];
|
||||
MapSegGLEx *seg = &GLSegs[sub->firstline + i];
|
||||
if (seg->side != NO_SIDE_INDEX)
|
||||
{
|
||||
sector = GetFrontSector(seg);
|
||||
|
@ -262,15 +428,17 @@ bool FLevel::LineIntersectSubSector(const kexVec3 &start, const kexVec3 &end, co
|
|||
return false;
|
||||
}
|
||||
|
||||
vertex_t *FLevel::GetSegVertex(int index)
|
||||
FloatVertex FLevel::GetSegVertex(int index)
|
||||
{
|
||||
if (index & 0x8000)
|
||||
{
|
||||
index = (index & 0x7FFF) + NumGLVertices;
|
||||
}
|
||||
|
||||
//return &GLVertices[index];
|
||||
return nullptr;
|
||||
FloatVertex v;
|
||||
v.x = F(GLVertices[index].x);
|
||||
v.y = F(GLVertices[index].y);
|
||||
return v;
|
||||
}
|
||||
|
||||
bool FLevel::CheckPVS(MapSubsectorEx *s1, MapSubsectorEx *s2)
|
||||
|
@ -286,622 +454,13 @@ bool FLevel::CheckPVS(MapSubsectorEx *s1, MapSubsectorEx *s2)
|
|||
return ((vis[n2 >> 3] & (1 << (n2 & 7))) != 0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
const kexVec3 kexDoomMap::defaultSunColor(1, 1, 1);
|
||||
const kexVec3 kexDoomMap::defaultSunDirection(0.45f, 0.3f, 0.9f);
|
||||
|
||||
//
|
||||
// kexDoomMap::kexDoomMap
|
||||
//
|
||||
|
||||
kexDoomMap::kexDoomMap()
|
||||
{
|
||||
this->mapLines = NULL;
|
||||
this->mapVerts = NULL;
|
||||
this->mapSides = NULL;
|
||||
this->mapSectors = NULL;
|
||||
this->mapSegs = NULL;
|
||||
this->mapSSects = NULL;
|
||||
this->nodes = NULL;
|
||||
this->leafs = NULL;
|
||||
this->segLeafLookup = NULL;
|
||||
this->ssLeafLookup = NULL;
|
||||
this->ssLeafCount = NULL;
|
||||
this->segSurfaces[0] = NULL;
|
||||
this->segSurfaces[1] = NULL;
|
||||
this->segSurfaces[2] = NULL;
|
||||
this->leafSurfaces[0] = NULL;
|
||||
this->leafSurfaces[1] = NULL;
|
||||
this->vertexes = NULL;
|
||||
this->mapPVS = NULL;
|
||||
this->mapDef = NULL;
|
||||
|
||||
this->numLeafs = 0;
|
||||
this->numLines = 0;
|
||||
this->numVerts = 0;
|
||||
this->numSides = 0;
|
||||
this->numSectors = 0;
|
||||
this->numSegs = 0;
|
||||
this->numSSects = 0;
|
||||
this->numNodes = 0;
|
||||
this->numVertexes = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::~kexDoomMap
|
||||
//
|
||||
|
||||
kexDoomMap::~kexDoomMap()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::BuildMapFromWad
|
||||
//
|
||||
|
||||
void kexDoomMap::BuildMapFromWad(kexWadFile &wadFile)
|
||||
{
|
||||
wadFile.GetMapLump<mapThing_t>(ML_THINGS, &mapThings, &numThings);
|
||||
wadFile.GetMapLump<mapVertex_t>(ML_VERTEXES, &mapVerts, &numVerts);
|
||||
wadFile.GetMapLump<mapLineDef_t>(ML_LINEDEFS, &mapLines, &numLines);
|
||||
wadFile.GetMapLump<mapSideDef_t>(ML_SIDEDEFS, &mapSides, &numSides);
|
||||
wadFile.GetMapLump<mapSector_t>(ML_SECTORS, &mapSectors, &numSectors);
|
||||
|
||||
wadFile.GetGLMapLump<glSeg_t>(ML_GL_SEGS, &mapSegs, &numSegs);
|
||||
wadFile.GetGLMapLump<mapSubSector_t>(ML_GL_SSECT, &mapSSects, &numSSects);
|
||||
wadFile.GetGLMapLump<mapNode_t>(ML_GL_NODES, &nodes, &numNodes);
|
||||
wadFile.GetGLMapLump<byte>(ML_GL_PVS, &mapPVS, 0);
|
||||
|
||||
if(mapSegs == NULL)
|
||||
{
|
||||
Error("kexDoomMap::BuildMapFromWad: SEGS lump not found\n");
|
||||
return;
|
||||
}
|
||||
if(mapSSects == NULL)
|
||||
{
|
||||
Error("kexDoomMap::BuildMapFromWad: SSECTORS lump not found\n");
|
||||
return;
|
||||
}
|
||||
if(nodes == NULL)
|
||||
{
|
||||
Error("kexDoomMap::BuildMapFromWad: NODES lump not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < mapDefs.Length(); ++i)
|
||||
{
|
||||
if(mapDefs[i].map == wadFile.currentmap)
|
||||
{
|
||||
mapDef = &mapDefs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("------------- Level Info -------------\n");
|
||||
printf("Vertices: %i\n", numVerts);
|
||||
printf("Segments: %i\n", numSegs);
|
||||
printf("Subsectors: %i\n", numSSects);
|
||||
|
||||
BuildVertexes(wadFile);
|
||||
BuildNodeBounds();
|
||||
BuildLeafs();
|
||||
BuildPVS();
|
||||
CheckSkySectors();
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::CheckSkySectors
|
||||
//
|
||||
|
||||
void kexDoomMap::CheckSkySectors()
|
||||
{
|
||||
char name[9];
|
||||
|
||||
bSkySectors = (bool*)Mem_Calloc(sizeof(bool) * numSectors, hb_static);
|
||||
bSSectsVisibleToSky = (bool*)Mem_Calloc(sizeof(bool) * numSSects, hb_static);
|
||||
|
||||
for(int i = 0; i < numSectors; ++i)
|
||||
{
|
||||
if(mapDef->sunIgnoreTag != 0 && mapSectors[i].tag == mapDef->sunIgnoreTag)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
strncpy(name, mapSectors[i].ceilingpic, 8);
|
||||
name[8] = 0;
|
||||
|
||||
if(!strncmp(name, "F_SKY001", 8))
|
||||
{
|
||||
bSkySectors[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// try to early out by quickly checking which subsector can potentially
|
||||
// see a sky sector
|
||||
for(int i = 0; i < numSSects; ++i)
|
||||
{
|
||||
for(int j = 0; j < numSSects; ++j)
|
||||
{
|
||||
mapSector_t *sec = GetSectorFromSubSector(&mapSSects[j]);
|
||||
|
||||
if(bSkySectors[sec - mapSectors] == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(CheckPVS(&mapSSects[i], &mapSSects[j]))
|
||||
{
|
||||
bSSectsVisibleToSky[i] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::BuildPVS
|
||||
//
|
||||
|
||||
void kexDoomMap::BuildPVS()
|
||||
{
|
||||
// don't do anything if already loaded
|
||||
if(mapPVS != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int len = ((numSSects + 7) / 8) * numSSects;
|
||||
mapPVS = (byte*)Mem_Malloc(len, hb_static);
|
||||
memset(mapPVS, 0xff, len);
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::CheckPVS
|
||||
//
|
||||
|
||||
bool kexDoomMap::CheckPVS(mapSubSector_t *s1, mapSubSector_t *s2)
|
||||
{
|
||||
byte *vis;
|
||||
int n1, n2;
|
||||
|
||||
n1 = s1 - mapSSects;
|
||||
n2 = s2 - mapSSects;
|
||||
|
||||
vis = &mapPVS[(((numSSects + 7) / 8) * n1)];
|
||||
|
||||
return ((vis[n2 >> 3] & (1 << (n2 & 7))) != 0);
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::BuildVertexes
|
||||
//
|
||||
|
||||
void kexDoomMap::BuildVertexes(kexWadFile &wadFile)
|
||||
{
|
||||
byte *data;
|
||||
int count;
|
||||
glVert_t *verts;
|
||||
lump_t *lump;
|
||||
|
||||
if(!(lump = wadFile.GetGLMapLump(static_cast<glMapLumps_t>(ML_GL_VERTS))))
|
||||
{
|
||||
Error("kexDoomMap::BuildVertexes: GL_VERTS lump not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
data = wadFile.GetLumpData(lump);
|
||||
|
||||
if(*((int*)data) != gNd2)
|
||||
{
|
||||
Error("kexDoomMap::BuildVertexes: GL_VERTS must be version 2 only");
|
||||
return;
|
||||
}
|
||||
|
||||
verts = (glVert_t*)(data + GL_VERT_OFFSET);
|
||||
count = (lump->size - GL_VERT_OFFSET) / sizeof(glVert_t);
|
||||
|
||||
numVertexes = numVerts + count;
|
||||
vertexes = (vertex_t*)Mem_Calloc(sizeof(vertex_t) * numVertexes, hb_static);
|
||||
|
||||
for(int i = 0; i < numVerts; i++)
|
||||
{
|
||||
vertexes[i].x = F(mapVerts[i].x << 16);
|
||||
vertexes[i].y = F(mapVerts[i].y << 16);
|
||||
}
|
||||
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
vertexes[numVerts + i].x = F(verts[i].x);
|
||||
vertexes[numVerts + i].y = F(verts[i].y);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::BuildNodeBounds
|
||||
//
|
||||
|
||||
void kexDoomMap::BuildNodeBounds()
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
kexVec3 point;
|
||||
float high = -M_INFINITY;
|
||||
float low = M_INFINITY;
|
||||
|
||||
nodeBounds = (kexBBox*)Mem_Calloc(sizeof(kexBBox) * numNodes, hb_static);
|
||||
|
||||
for(i = 0; i < numSectors; ++i)
|
||||
{
|
||||
if(mapSectors[i].ceilingheight > high)
|
||||
{
|
||||
high = mapSectors[i].ceilingheight;
|
||||
}
|
||||
if(mapSectors[i].floorheight < low)
|
||||
{
|
||||
low = mapSectors[i].floorheight;
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < numNodes; ++i)
|
||||
{
|
||||
nodeBounds[i].Clear();
|
||||
|
||||
for(j = 0; j < 2; ++j)
|
||||
{
|
||||
point.Set(nodes[i].bbox[j][BOXLEFT], nodes[i].bbox[j][BOXBOTTOM], low);
|
||||
nodeBounds[i].AddPoint(point);
|
||||
point.Set(nodes[i].bbox[j][BOXRIGHT], nodes[i].bbox[j][BOXTOP], high);
|
||||
nodeBounds[i].AddPoint(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::BuildLeafs
|
||||
//
|
||||
|
||||
void kexDoomMap::BuildLeafs()
|
||||
{
|
||||
mapSubSector_t *ss;
|
||||
leaf_t *lf;
|
||||
int i;
|
||||
int j;
|
||||
kexVec3 point;
|
||||
mapSector_t *sector;
|
||||
int count;
|
||||
|
||||
leafs = (leaf_t*)Mem_Calloc(sizeof(leaf_t*) * numSegs * 2, hb_static);
|
||||
numLeafs = numSSects;
|
||||
|
||||
ss = mapSSects;
|
||||
|
||||
segLeafLookup = (int*)Mem_Calloc(sizeof(int) * numSegs, hb_static);
|
||||
ssLeafLookup = (int*)Mem_Calloc(sizeof(int) * numSSects, hb_static);
|
||||
ssLeafCount = (int*)Mem_Calloc(sizeof(int) * numSSects, hb_static);
|
||||
ssLeafBounds = (kexBBox*)Mem_Calloc(sizeof(kexBBox) * numSSects, hb_static);
|
||||
|
||||
count = 0;
|
||||
|
||||
for(i = 0; i < numSSects; ++i, ++ss)
|
||||
{
|
||||
ssLeafCount[i] = ss->numsegs;
|
||||
ssLeafLookup[i] = ss->firstseg;
|
||||
|
||||
ssLeafBounds[i].Clear();
|
||||
sector = GetSectorFromSubSector(ss);
|
||||
|
||||
if(ss->numsegs)
|
||||
{
|
||||
for(j = 0; j < ss->numsegs; ++j)
|
||||
{
|
||||
glSeg_t *seg = &mapSegs[ss->firstseg + j];
|
||||
lf = &leafs[count++];
|
||||
|
||||
segLeafLookup[ss->firstseg + j] = i;
|
||||
|
||||
lf->vertex = GetSegVertex(seg->v1);
|
||||
lf->seg = seg;
|
||||
|
||||
point.Set(lf->vertex->x, lf->vertex->y, sector->floorheight);
|
||||
ssLeafBounds[i].AddPoint(point);
|
||||
|
||||
point.z = sector->ceilingheight;
|
||||
ssLeafBounds[i].AddPoint(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::GetSegVertex
|
||||
//
|
||||
|
||||
vertex_t *kexDoomMap::GetSegVertex(int index)
|
||||
{
|
||||
if(index & 0x8000)
|
||||
{
|
||||
index = (index & 0x7FFF) + numVerts;
|
||||
}
|
||||
|
||||
return &vertexes[index];
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::GetSideDef
|
||||
//
|
||||
|
||||
mapSideDef_t *kexDoomMap::GetSideDef(const glSeg_t *seg)
|
||||
{
|
||||
mapLineDef_t *line;
|
||||
|
||||
if(seg->linedef == NO_LINE_INDEX)
|
||||
{
|
||||
// skip minisegs
|
||||
return NULL;
|
||||
}
|
||||
|
||||
line = &mapLines[seg->linedef];
|
||||
return &mapSides[line->sidenum[seg->side]];
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::GetFrontSector
|
||||
//
|
||||
|
||||
mapSector_t *kexDoomMap::GetFrontSector(const glSeg_t *seg)
|
||||
{
|
||||
mapSideDef_t *side = GetSideDef(seg);
|
||||
|
||||
if(side == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &mapSectors[side->sector];
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::GetBackSector
|
||||
//
|
||||
|
||||
mapSector_t *kexDoomMap::GetBackSector(const glSeg_t *seg)
|
||||
{
|
||||
mapLineDef_t *line;
|
||||
|
||||
if(seg->linedef == NO_LINE_INDEX)
|
||||
{
|
||||
// skip minisegs
|
||||
return NULL;
|
||||
}
|
||||
|
||||
line = &mapLines[seg->linedef];
|
||||
|
||||
if(line->flags & ML_TWOSIDED)
|
||||
{
|
||||
mapSideDef_t *backSide = &mapSides[line->sidenum[seg->side^1]];
|
||||
return &mapSectors[backSide->sector];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::GetSectorFromSubSector
|
||||
//
|
||||
|
||||
mapSector_t *kexDoomMap::GetSectorFromSubSector(const mapSubSector_t *sub)
|
||||
{
|
||||
mapSector_t *sector = NULL;
|
||||
|
||||
// try to find a sector that the subsector belongs to
|
||||
for(int i = 0; i < sub->numsegs; i++)
|
||||
{
|
||||
glSeg_t *seg = &mapSegs[sub->firstseg + i];
|
||||
if(seg->side != NO_SIDE_INDEX)
|
||||
{
|
||||
sector = GetFrontSector(seg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sector;
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::PointInSubSector
|
||||
//
|
||||
|
||||
mapSubSector_t *kexDoomMap::PointInSubSector(const int x, const int y)
|
||||
{
|
||||
mapNode_t *node;
|
||||
int side;
|
||||
int nodenum;
|
||||
kexVec3 dp1;
|
||||
kexVec3 dp2;
|
||||
float d;
|
||||
|
||||
// single subsector is a special case
|
||||
if(!numNodes)
|
||||
{
|
||||
return &mapSSects[0];
|
||||
}
|
||||
|
||||
nodenum = numNodes - 1;
|
||||
|
||||
while(!(nodenum & NF_SUBSECTOR) )
|
||||
{
|
||||
node = &nodes[nodenum];
|
||||
|
||||
kexVec3 pt1(F(node->x << 16), F(node->y << 16), 0);
|
||||
kexVec3 pt2(F(node->dx << 16), F(node->dy << 16), 0);
|
||||
kexVec3 pos(F(x << 16), F(y << 16), 0);
|
||||
|
||||
dp1 = pt1 - pos;
|
||||
dp2 = (pt2 + pt1) - pos;
|
||||
d = dp1.Cross(dp2).z;
|
||||
|
||||
side = FLOATSIGNBIT(d);
|
||||
|
||||
nodenum = node->children[side ^ 1];
|
||||
}
|
||||
|
||||
return &mapSSects[nodenum & ~NF_SUBSECTOR];
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::PointInsideSubSector
|
||||
//
|
||||
|
||||
bool kexDoomMap::PointInsideSubSector(const float x, const float y, const mapSubSector_t *sub)
|
||||
{
|
||||
surface_t *surf;
|
||||
int i;
|
||||
kexVec2 p(x, y);
|
||||
kexVec2 dp1, dp2;
|
||||
kexVec2 pt1, pt2;
|
||||
|
||||
surf = leafSurfaces[0][sub - mapSSects];
|
||||
|
||||
// check to see if the point is inside the subsector leaf
|
||||
for(i = 0; i < surf->numVerts; i++)
|
||||
{
|
||||
pt1 = surf->verts[i].ToVec2();
|
||||
pt2 = surf->verts[(i+1)%surf->numVerts].ToVec2();
|
||||
|
||||
dp1 = pt1 - p;
|
||||
dp2 = pt2 - p;
|
||||
|
||||
if(dp1.CrossScalar(dp2) < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// this point is outside the subsector leaf
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::LineIntersectSubSector
|
||||
//
|
||||
|
||||
bool kexDoomMap::LineIntersectSubSector(const kexVec3 &start, const kexVec3 &end,
|
||||
const mapSubSector_t *sub, kexVec2 &out)
|
||||
{
|
||||
surface_t *surf;
|
||||
kexVec2 p1, p2;
|
||||
kexVec2 s1, s2;
|
||||
kexVec2 pt;
|
||||
kexVec2 v;
|
||||
float d, u;
|
||||
float newX;
|
||||
float ab;
|
||||
int i;
|
||||
|
||||
surf = leafSurfaces[0][sub - mapSSects];
|
||||
p1 = start.ToVec2();
|
||||
p2 = end.ToVec2();
|
||||
|
||||
for(i = 0; i < surf->numVerts; i++)
|
||||
{
|
||||
s1 = surf->verts[i].ToVec2();
|
||||
s2 = surf->verts[(i+1)%surf->numVerts].ToVec2();
|
||||
|
||||
if((p1 == p2) || (s1 == s2))
|
||||
{
|
||||
// zero length
|
||||
continue;
|
||||
}
|
||||
|
||||
if((p1 == s1) || (p2 == s1) || (p1 == s2) || (p2 == s2))
|
||||
{
|
||||
// shares end point
|
||||
continue;
|
||||
}
|
||||
|
||||
// translate to origin
|
||||
pt = p2 - p1;
|
||||
s1 -= p1;
|
||||
s2 -= p1;
|
||||
|
||||
// normalize
|
||||
u = pt.UnitSq();
|
||||
d = kexMath::InvSqrt(u);
|
||||
v = (pt * d);
|
||||
|
||||
// rotate points s1 and s2 so they're on the positive x axis
|
||||
newX = s1.Dot(v);
|
||||
s1.y = s1.CrossScalar(v);
|
||||
s1.x = newX;
|
||||
|
||||
newX = s2.Dot(v);
|
||||
s2.y = s2.CrossScalar(v);
|
||||
s2.x = newX;
|
||||
|
||||
if((s1.y < 0 && s2.y < 0) || (s1.y >= 0 && s2.y >= 0))
|
||||
{
|
||||
// s1 and s2 didn't cross
|
||||
continue;
|
||||
}
|
||||
|
||||
ab = s2.x + (s1.x - s2.x) * s2.y / (s2.y - s1.y);
|
||||
|
||||
if(ab < 0 || ab > (u * d))
|
||||
{
|
||||
// s1 and s2 crosses but outside of points p1 and p2
|
||||
continue;
|
||||
}
|
||||
|
||||
// intersected
|
||||
out = p1 + (v * ab);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::GetSunColor
|
||||
//
|
||||
|
||||
const kexVec3 &kexDoomMap::GetSunColor() const
|
||||
{
|
||||
if(mapDef != NULL)
|
||||
{
|
||||
return mapDef->sunColor;
|
||||
}
|
||||
|
||||
return defaultSunColor;
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::GetSunDirection
|
||||
//
|
||||
|
||||
const kexVec3 &kexDoomMap::GetSunDirection() const
|
||||
{
|
||||
if(mapDef != NULL)
|
||||
{
|
||||
return mapDef->sunDir;
|
||||
}
|
||||
|
||||
return defaultSunDirection;
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::ParseConfigFile
|
||||
//
|
||||
|
||||
void kexDoomMap::ParseConfigFile(const char *file)
|
||||
void FLevel::ParseConfigFile(const char *file)
|
||||
{
|
||||
kexLexer *lexer;
|
||||
|
||||
if (!(lexer = parser->Open(file)))
|
||||
{
|
||||
Error("kexDoomMap::ParseConfigFile: %s not found\n", file);
|
||||
Error("FLevel::ParseConfigFile: %s not found\n", file);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1070,13 +629,9 @@ void kexDoomMap::ParseConfigFile(const char *file)
|
|||
parser->Close();
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::CreateLights
|
||||
//
|
||||
|
||||
void kexDoomMap::CreateLights()
|
||||
void FLevel::CreateLights()
|
||||
{
|
||||
mapThing_t *thing;
|
||||
IntThing *thing;
|
||||
thingLight_t *thingLight;
|
||||
unsigned int j;
|
||||
int numSurfLights;
|
||||
|
@ -1085,13 +640,13 @@ void kexDoomMap::CreateLights()
|
|||
//
|
||||
// add lights from thing sources
|
||||
//
|
||||
for(int i = 0; i < numThings; ++i)
|
||||
for (int i = 0; i < (int)Things.Size(); ++i)
|
||||
{
|
||||
lightDef_t *lightDef = NULL;
|
||||
|
||||
thing = &mapThings[i];
|
||||
thing = &Things[i];
|
||||
|
||||
for(j = 0; j < lightDefs.Length(); ++j)
|
||||
for (j = 0; j < (int)lightDefs.Size(); ++j)
|
||||
{
|
||||
if (thing->type == lightDefs[j].doomednum)
|
||||
{
|
||||
|
@ -1108,7 +663,7 @@ void kexDoomMap::CreateLights()
|
|||
if (lightDef->radius >= 0)
|
||||
{
|
||||
// ignore if all skills aren't set
|
||||
if(!(thing->options & 7))
|
||||
if (!(thing->flags & 7))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -1130,7 +685,7 @@ void kexDoomMap::CreateLights()
|
|||
thingLights.Push(thingLight);
|
||||
}
|
||||
|
||||
printf("Thing lights: %i\n", thingLights.Length());
|
||||
printf("Thing lights: %i\n", thingLights.Size());
|
||||
|
||||
numSurfLights = 0;
|
||||
|
||||
|
@ -1141,15 +696,15 @@ void kexDoomMap::CreateLights()
|
|||
{
|
||||
surface_t *surface = surfaces[j];
|
||||
|
||||
for(unsigned int k = 0; k < surfaceLightDefs.Length(); ++k)
|
||||
for (unsigned int k = 0; k < surfaceLightDefs.Size(); ++k)
|
||||
{
|
||||
surfaceLightDef *surfaceLightDef = &surfaceLightDefs[k];
|
||||
|
||||
if (surface->type >= ST_MIDDLESEG && surface->type <= ST_LOWERSEG)
|
||||
{
|
||||
glSeg_t *seg = (glSeg_t*)surface->data;
|
||||
MapSegGLEx *seg = (MapSegGLEx*)surface->data;
|
||||
|
||||
if(mapLines[seg->linedef].tag == surfaceLightDef->tag)
|
||||
if (Lines[seg->linedef].args[1] == surfaceLightDef->tag)
|
||||
{
|
||||
kexLightSurface *lightSurface = new kexLightSurface;
|
||||
|
||||
|
@ -1161,8 +716,8 @@ void kexDoomMap::CreateLights()
|
|||
}
|
||||
else
|
||||
{
|
||||
mapSubSector_t *sub = surface->subSector;
|
||||
mapSector_t *sector = GetSectorFromSubSector(sub);
|
||||
MapSubsectorEx *sub = surface->subSector;
|
||||
IntSector *sector = GetSectorFromSubSector(sub);
|
||||
|
||||
if (!sector || surface->numVerts <= 0)
|
||||
{
|
||||
|
@ -1180,7 +735,7 @@ void kexDoomMap::CreateLights()
|
|||
continue;
|
||||
}
|
||||
|
||||
if(sector->tag == surfaceLightDef->tag)
|
||||
if (sector->data.tag == surfaceLightDef->tag)
|
||||
{
|
||||
kexLightSurface *lightSurface = new kexLightSurface;
|
||||
|
||||
|
@ -1196,16 +751,10 @@ void kexDoomMap::CreateLights()
|
|||
printf("Surface lights: %i\n", numSurfLights);
|
||||
}
|
||||
|
||||
//
|
||||
// kexDoomMap::CleanupThingLights
|
||||
//
|
||||
|
||||
void kexDoomMap::CleanupThingLights()
|
||||
void FLevel::CleanupThingLights()
|
||||
{
|
||||
for(unsigned int i = 0; i < thingLights.Length(); i++)
|
||||
for (unsigned int i = 0; i < thingLights.Size(); i++)
|
||||
{
|
||||
delete thingLights[i];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,306 +29,5 @@
|
|||
|
||||
#include "framework/zdray.h"
|
||||
#include "level/level.h"
|
||||
|
||||
typedef FLevel kexDoomMap;
|
||||
typedef MapSubsectorEx mapSubSector_t;
|
||||
typedef MapSegGLEx glSeg_t;
|
||||
typedef IntSideDef mapSideDef_t;
|
||||
typedef IntSector mapSector_t;
|
||||
|
||||
enum mapFlags_t
|
||||
{
|
||||
ML_BLOCKING = 1, // Solid, is an obstacle.
|
||||
ML_BLOCKMONSTERS = 2, // Blocks monsters only.
|
||||
ML_TWOSIDED = 4, // Backside will not be present at all if not two sided.
|
||||
ML_TRANSPARENT1 = 2048, // 25% or 75% transcluency?
|
||||
ML_TRANSPARENT2 = 4096 // 25% or 75% transcluency?
|
||||
};
|
||||
|
||||
#define NO_SIDE_INDEX -1
|
||||
#define NO_LINE_INDEX 0xFFFF
|
||||
#define NF_SUBSECTOR 0x8000
|
||||
|
||||
struct lightDef_t
|
||||
{
|
||||
int doomednum;
|
||||
float height;
|
||||
float radius;
|
||||
float intensity;
|
||||
float falloff;
|
||||
bool bCeiling;
|
||||
kexVec3 rgb;
|
||||
};
|
||||
|
||||
struct mapDef_t
|
||||
{
|
||||
int map;
|
||||
int sunIgnoreTag;
|
||||
kexVec3 sunDir;
|
||||
kexVec3 sunColor;
|
||||
};
|
||||
|
||||
struct thingLight_t
|
||||
{
|
||||
IntThing *mapThing;
|
||||
kexVec2 origin;
|
||||
kexVec3 rgb;
|
||||
float intensity;
|
||||
float falloff;
|
||||
float height;
|
||||
float radius;
|
||||
bool bCeiling;
|
||||
mapSector_t *sector;
|
||||
mapSubSector_t *ssect;
|
||||
};
|
||||
|
||||
#include "surfaces.h"
|
||||
#include "lightSurface.h"
|
||||
|
||||
#if 0
|
||||
|
||||
#include "wad.h"
|
||||
#include "surfaces.h"
|
||||
#include "lightSurface.h"
|
||||
|
||||
#define NO_SIDE_INDEX -1
|
||||
#define NO_LINE_INDEX 0xFFFF
|
||||
#define NF_SUBSECTOR 0x8000
|
||||
|
||||
enum
|
||||
{
|
||||
BOXTOP,
|
||||
BOXBOTTOM,
|
||||
BOXLEFT,
|
||||
BOXRIGHT
|
||||
};
|
||||
|
||||
enum mapFlags_t
|
||||
{
|
||||
ML_BLOCKING = 1, // Solid, is an obstacle.
|
||||
ML_BLOCKMONSTERS = 2, // Blocks monsters only.
|
||||
ML_TWOSIDED = 4, // Backside will not be present at all if not two sided.
|
||||
ML_TRANSPARENT1 = 2048, // 25% or 75% transcluency?
|
||||
ML_TRANSPARENT2 = 4096 // 25% or 75% transcluency?
|
||||
};
|
||||
|
||||
struct mapVertex_t
|
||||
{
|
||||
short x;
|
||||
short y;
|
||||
};
|
||||
|
||||
struct mapSideDef_t
|
||||
{
|
||||
short textureoffset;
|
||||
short rowoffset;
|
||||
char toptexture[8];
|
||||
char bottomtexture[8];
|
||||
char midtexture[8];
|
||||
short sector;
|
||||
};
|
||||
|
||||
struct mapLineDef_t
|
||||
{
|
||||
short v1;
|
||||
short v2;
|
||||
short flags;
|
||||
short special;
|
||||
short tag;
|
||||
short sidenum[2]; // sidenum[1] will be -1 if one sided
|
||||
};
|
||||
|
||||
struct mapSector_t
|
||||
{
|
||||
short floorheight;
|
||||
short ceilingheight;
|
||||
char floorpic[8];
|
||||
char ceilingpic[8];
|
||||
short lightlevel;
|
||||
short special;
|
||||
short tag;
|
||||
};
|
||||
|
||||
struct mapNode_t
|
||||
{
|
||||
// Partition line from (x,y) to x+dx,y+dy)
|
||||
short x;
|
||||
short y;
|
||||
short dx;
|
||||
short dy;
|
||||
|
||||
// Bounding box for each child,
|
||||
// clip against view frustum.
|
||||
short bbox[2][4];
|
||||
|
||||
// If NF_SUBSECTOR its a subsector,
|
||||
// else it's a node of another subtree.
|
||||
word children[2];
|
||||
};
|
||||
|
||||
struct mapSeg_t
|
||||
{
|
||||
word v1;
|
||||
word v2;
|
||||
short angle;
|
||||
word linedef;
|
||||
short side;
|
||||
short offset;
|
||||
};
|
||||
|
||||
struct mapSubSector_t
|
||||
{
|
||||
word numsegs;
|
||||
word firstseg;
|
||||
};
|
||||
|
||||
struct mapThing_t
|
||||
{
|
||||
short x;
|
||||
short y;
|
||||
short angle;
|
||||
short type;
|
||||
short options;
|
||||
};
|
||||
|
||||
struct glVert_t
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
struct glSeg_t
|
||||
{
|
||||
word v1;
|
||||
word v2;
|
||||
word linedef;
|
||||
int16_t side;
|
||||
word partner;
|
||||
};
|
||||
|
||||
struct vertex_t
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct leaf_t
|
||||
{
|
||||
vertex_t *vertex;
|
||||
glSeg_t *seg;
|
||||
};
|
||||
|
||||
struct lightDef_t
|
||||
{
|
||||
int doomednum;
|
||||
float height;
|
||||
float radius;
|
||||
float intensity;
|
||||
float falloff;
|
||||
bool bCeiling;
|
||||
kexVec3 rgb;
|
||||
};
|
||||
|
||||
struct mapDef_t
|
||||
{
|
||||
int map;
|
||||
int sunIgnoreTag;
|
||||
kexVec3 sunDir;
|
||||
kexVec3 sunColor;
|
||||
};
|
||||
|
||||
struct thingLight_t
|
||||
{
|
||||
mapThing_t *mapThing;
|
||||
kexVec2 origin;
|
||||
kexVec3 rgb;
|
||||
float intensity;
|
||||
float falloff;
|
||||
float height;
|
||||
float radius;
|
||||
bool bCeiling;
|
||||
mapSector_t *sector;
|
||||
mapSubSector_t *ssect;
|
||||
};
|
||||
|
||||
class kexDoomMap
|
||||
{
|
||||
public:
|
||||
kexDoomMap();
|
||||
~kexDoomMap();
|
||||
|
||||
void BuildMapFromWad(kexWadFile &wadFile);
|
||||
mapSideDef_t *GetSideDef(const glSeg_t *seg);
|
||||
mapSector_t *GetFrontSector(const glSeg_t *seg);
|
||||
mapSector_t *GetBackSector(const glSeg_t *seg);
|
||||
mapSector_t *GetSectorFromSubSector(const mapSubSector_t *sub);
|
||||
mapSubSector_t *PointInSubSector(const int x, const int y);
|
||||
bool PointInsideSubSector(const float x, const float y, const mapSubSector_t *sub);
|
||||
bool LineIntersectSubSector(const kexVec3 &start, const kexVec3 &end, const mapSubSector_t *sub, kexVec2 &out);
|
||||
vertex_t *GetSegVertex(int index);
|
||||
bool CheckPVS(mapSubSector_t *s1, mapSubSector_t *s2);
|
||||
|
||||
void ParseConfigFile(const char *file);
|
||||
void CreateLights();
|
||||
void CleanupThingLights();
|
||||
|
||||
const kexVec3 &GetSunColor() const;
|
||||
const kexVec3 &GetSunDirection() const;
|
||||
|
||||
mapThing_t *mapThings;
|
||||
mapLineDef_t *mapLines;
|
||||
mapVertex_t *mapVerts;
|
||||
mapSideDef_t *mapSides;
|
||||
mapSector_t *mapSectors;
|
||||
glSeg_t *mapSegs;
|
||||
mapSubSector_t *mapSSects;
|
||||
mapNode_t *nodes;
|
||||
leaf_t *leafs;
|
||||
vertex_t *vertexes;
|
||||
byte *mapPVS;
|
||||
|
||||
bool *bSkySectors;
|
||||
bool *bSSectsVisibleToSky;
|
||||
|
||||
int numThings;
|
||||
int numLines;
|
||||
int numVerts;
|
||||
int numSides;
|
||||
int numSectors;
|
||||
int numSegs;
|
||||
int numSSects;
|
||||
int numNodes;
|
||||
int numLeafs;
|
||||
int numVertexes;
|
||||
|
||||
int *segLeafLookup;
|
||||
int *ssLeafLookup;
|
||||
int *ssLeafCount;
|
||||
kexBBox *ssLeafBounds;
|
||||
|
||||
kexBBox *nodeBounds;
|
||||
|
||||
surface_t **segSurfaces[3];
|
||||
surface_t **leafSurfaces[2];
|
||||
|
||||
kexArray<thingLight_t*> thingLights;
|
||||
kexArray<kexLightSurface*> lightSurfaces;
|
||||
|
||||
private:
|
||||
void BuildLeafs();
|
||||
void BuildNodeBounds();
|
||||
void CheckSkySectors();
|
||||
void BuildVertexes(kexWadFile &wadFile);
|
||||
void BuildPVS();
|
||||
|
||||
kexArray<lightDef_t> lightDefs;
|
||||
kexArray<surfaceLightDef> surfaceLightDefs;
|
||||
kexArray<mapDef_t> mapDefs;
|
||||
|
||||
mapDef_t *mapDef;
|
||||
|
||||
static const kexVec3 defaultSunColor;
|
||||
static const kexVec3 defaultSunDirection;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,16 +42,14 @@ kexArray<surface_t*> surfaces;
|
|||
// Surface_AllocateFromSeg
|
||||
//
|
||||
|
||||
static void Surface_AllocateFromSeg(kexDoomMap &doomMap, glSeg_t *seg)
|
||||
static void Surface_AllocateFromSeg(FLevel &doomMap, MapSegGLEx *seg)
|
||||
{
|
||||
mapSideDef_t *side;
|
||||
IntSideDef *side;
|
||||
surface_t *surf;
|
||||
float top, bTop;
|
||||
float bottom, bBottom;
|
||||
mapSector_t *front;
|
||||
mapSector_t *back;
|
||||
vertex_t *v1;
|
||||
vertex_t *v2;
|
||||
IntSector *front;
|
||||
IntSector *back;
|
||||
|
||||
if(seg->linedef == NO_LINE_INDEX)
|
||||
{
|
||||
|
@ -65,8 +63,8 @@ static void Surface_AllocateFromSeg(kexDoomMap &doomMap, glSeg_t *seg)
|
|||
top = front->data.ceilingheight;
|
||||
bottom = front->data.floorheight;
|
||||
|
||||
v1 = doomMap.GetSegVertex(seg->v1);
|
||||
v2 = doomMap.GetSegVertex(seg->v2);
|
||||
FloatVertex v1 = doomMap.GetSegVertex(seg->v1);
|
||||
FloatVertex v2 = doomMap.GetSegVertex(seg->v2);
|
||||
|
||||
if(back)
|
||||
{
|
||||
|
@ -87,10 +85,10 @@ static void Surface_AllocateFromSeg(kexDoomMap &doomMap, glSeg_t *seg)
|
|||
surf->numVerts = 4;
|
||||
surf->verts = (kexVec3*)Mem_Calloc(sizeof(kexVec3) * 4, hb_static);
|
||||
|
||||
surf->verts[0].x = surf->verts[2].x = v1->x;
|
||||
surf->verts[0].y = surf->verts[2].y = v1->y;
|
||||
surf->verts[1].x = surf->verts[3].x = v2->x;
|
||||
surf->verts[1].y = surf->verts[3].y = v2->y;
|
||||
surf->verts[0].x = surf->verts[2].x = v1.x;
|
||||
surf->verts[0].y = surf->verts[2].y = v1.y;
|
||||
surf->verts[1].x = surf->verts[3].x = v2.x;
|
||||
surf->verts[1].y = surf->verts[3].y = v2.y;
|
||||
surf->verts[0].z = surf->verts[1].z = bottom;
|
||||
surf->verts[2].z = surf->verts[3].z = bBottom;
|
||||
|
||||
|
@ -101,7 +99,7 @@ static void Surface_AllocateFromSeg(kexDoomMap &doomMap, glSeg_t *seg)
|
|||
surf->subSector = &doomMap.GLSubsectors[doomMap.segLeafLookup[seg - doomMap.GLSegs]];
|
||||
|
||||
doomMap.segSurfaces[1][surf->typeIndex] = surf;
|
||||
surf->data = (glSeg_t*)seg;
|
||||
surf->data = (MapSegGLEx*)seg;
|
||||
|
||||
surfaces.Push(surf);
|
||||
}
|
||||
|
@ -130,10 +128,10 @@ static void Surface_AllocateFromSeg(kexDoomMap &doomMap, glSeg_t *seg)
|
|||
surf->numVerts = 4;
|
||||
surf->verts = (kexVec3*)Mem_Calloc(sizeof(kexVec3) * 4, hb_static);
|
||||
|
||||
surf->verts[0].x = surf->verts[2].x = v1->x;
|
||||
surf->verts[0].y = surf->verts[2].y = v1->y;
|
||||
surf->verts[1].x = surf->verts[3].x = v2->x;
|
||||
surf->verts[1].y = surf->verts[3].y = v2->y;
|
||||
surf->verts[0].x = surf->verts[2].x = v1.x;
|
||||
surf->verts[0].y = surf->verts[2].y = v1.y;
|
||||
surf->verts[1].x = surf->verts[3].x = v2.x;
|
||||
surf->verts[1].y = surf->verts[3].y = v2.y;
|
||||
surf->verts[0].z = surf->verts[1].z = bTop;
|
||||
surf->verts[2].z = surf->verts[3].z = top;
|
||||
|
||||
|
@ -145,7 +143,7 @@ static void Surface_AllocateFromSeg(kexDoomMap &doomMap, glSeg_t *seg)
|
|||
surf->subSector = &doomMap.GLSubsectors[doomMap.segLeafLookup[seg - doomMap.GLSegs]];
|
||||
|
||||
doomMap.segSurfaces[2][surf->typeIndex] = surf;
|
||||
surf->data = (glSeg_t*)seg;
|
||||
surf->data = (MapSegGLEx*)seg;
|
||||
|
||||
surfaces.Push(surf);
|
||||
}
|
||||
|
@ -161,10 +159,10 @@ static void Surface_AllocateFromSeg(kexDoomMap &doomMap, glSeg_t *seg)
|
|||
surf->numVerts = 4;
|
||||
surf->verts = (kexVec3*)Mem_Calloc(sizeof(kexVec3) * 4, hb_static);
|
||||
|
||||
surf->verts[0].x = surf->verts[2].x = v1->x;
|
||||
surf->verts[0].y = surf->verts[2].y = v1->y;
|
||||
surf->verts[1].x = surf->verts[3].x = v2->x;
|
||||
surf->verts[1].y = surf->verts[3].y = v2->y;
|
||||
surf->verts[0].x = surf->verts[2].x = v1.x;
|
||||
surf->verts[0].y = surf->verts[2].y = v1.y;
|
||||
surf->verts[1].x = surf->verts[3].x = v2.x;
|
||||
surf->verts[1].y = surf->verts[3].y = v2.y;
|
||||
surf->verts[0].z = surf->verts[1].z = bottom;
|
||||
surf->verts[2].z = surf->verts[3].z = top;
|
||||
|
||||
|
@ -175,7 +173,7 @@ static void Surface_AllocateFromSeg(kexDoomMap &doomMap, glSeg_t *seg)
|
|||
surf->subSector = &doomMap.GLSubsectors[doomMap.segLeafLookup[seg - doomMap.GLSegs]];
|
||||
|
||||
doomMap.segSurfaces[0][surf->typeIndex] = surf;
|
||||
surf->data = (glSeg_t*)seg;
|
||||
surf->data = (MapSegGLEx*)seg;
|
||||
|
||||
surfaces.Push(surf);
|
||||
}
|
||||
|
@ -188,11 +186,11 @@ static void Surface_AllocateFromSeg(kexDoomMap &doomMap, glSeg_t *seg)
|
|||
// unless slopes are involved....
|
||||
//
|
||||
|
||||
static void Surface_AllocateFromLeaf(kexDoomMap &doomMap)
|
||||
static void Surface_AllocateFromLeaf(FLevel &doomMap)
|
||||
{
|
||||
surface_t *surf;
|
||||
leaf_t *leaf;
|
||||
mapSector_t *sector = NULL;
|
||||
IntSector *sector = NULL;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
|
@ -230,8 +228,8 @@ static void Surface_AllocateFromLeaf(kexDoomMap &doomMap)
|
|||
{
|
||||
leaf = &doomMap.leafs[doomMap.ssLeafLookup[i] + (surf->numVerts - 1) - j];
|
||||
|
||||
surf->verts[j].x = leaf->vertex->x;
|
||||
surf->verts[j].y = leaf->vertex->y;
|
||||
surf->verts[j].x = leaf->vertex.x;
|
||||
surf->verts[j].y = leaf->vertex.y;
|
||||
surf->verts[j].z = sector->data.floorheight;
|
||||
}
|
||||
|
||||
|
@ -241,7 +239,7 @@ static void Surface_AllocateFromLeaf(kexDoomMap &doomMap)
|
|||
surf->typeIndex = i;
|
||||
|
||||
doomMap.leafSurfaces[0][i] = surf;
|
||||
surf->data = (mapSector_t*)sector;
|
||||
surf->data = (IntSector*)sector;
|
||||
|
||||
surfaces.Push(surf);
|
||||
|
||||
|
@ -260,8 +258,8 @@ static void Surface_AllocateFromLeaf(kexDoomMap &doomMap)
|
|||
{
|
||||
leaf = &doomMap.leafs[doomMap.ssLeafLookup[i] + j];
|
||||
|
||||
surf->verts[j].x = leaf->vertex->x;
|
||||
surf->verts[j].y = leaf->vertex->y;
|
||||
surf->verts[j].x = leaf->vertex.x;
|
||||
surf->verts[j].y = leaf->vertex.y;
|
||||
surf->verts[j].z = sector->data.ceilingheight;
|
||||
}
|
||||
|
||||
|
@ -271,7 +269,7 @@ static void Surface_AllocateFromLeaf(kexDoomMap &doomMap)
|
|||
surf->typeIndex = i;
|
||||
|
||||
doomMap.leafSurfaces[1][i] = surf;
|
||||
surf->data = (mapSector_t*)sector;
|
||||
surf->data = (IntSector*)sector;
|
||||
|
||||
surfaces.Push(surf);
|
||||
}
|
||||
|
@ -283,7 +281,7 @@ static void Surface_AllocateFromLeaf(kexDoomMap &doomMap)
|
|||
// Surface_AllocateFromMap
|
||||
//
|
||||
|
||||
void Surface_AllocateFromMap(kexDoomMap &doomMap)
|
||||
void Surface_AllocateFromMap(FLevel &doomMap)
|
||||
{
|
||||
doomMap.segSurfaces[0] = (surface_t**)Mem_Calloc(sizeof(surface_t*) * doomMap.NumGLSegs, hb_static);
|
||||
doomMap.segSurfaces[1] = (surface_t**)Mem_Calloc(sizeof(surface_t*) * doomMap.NumGLSegs, hb_static);
|
||||
|
|
|
@ -56,7 +56,7 @@ kexTrace::~kexTrace()
|
|||
// kexTrace::Init
|
||||
//
|
||||
|
||||
void kexTrace::Init(kexDoomMap &doomMap)
|
||||
void kexTrace::Init(FLevel &doomMap)
|
||||
{
|
||||
map = &doomMap;
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ void kexTrace::TraceSurface(surface_t *surface)
|
|||
|
||||
void kexTrace::TraceSubSector(int num)
|
||||
{
|
||||
mapSubSector_t *sub;
|
||||
MapSubsectorEx *sub;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
|
|
|
@ -197,7 +197,7 @@ int main(int argc, char **argv)
|
|||
{
|
||||
kexWadFile wadFile;
|
||||
kexWadFile outWadFile;
|
||||
kexDoomMap doomMap;
|
||||
FLevel doomMap;
|
||||
lump_t *lmLump;
|
||||
kexArray<int> ignoreLumps;
|
||||
kexLightmapBuilder builder;
|
||||
|
|
Loading…
Reference in a new issue