- remove the dlight config file and switch to using UDMF properties on lines, sectors and things

This commit is contained in:
Magnus Norddahl 2018-10-30 19:10:50 +01:00
parent a51f51ff94
commit b0f846e200
10 changed files with 172 additions and 1587 deletions

View file

@ -155,7 +155,6 @@ set( SOURCES
src/lightmap/kexlib/binfile.cpp
src/lightmap/kexlib/kstring.cpp
src/lightmap/kexlib/memheap.cpp
src/lightmap/kexlib/parser.cpp
src/lightmap/kexlib/math/angle.cpp
src/lightmap/kexlib/math/bounds.cpp
src/lightmap/kexlib/math/mathlib.cpp
@ -199,7 +198,6 @@ set( HEADERS
src/lightmap/kexlib/binfile.h
src/lightmap/kexlib/kstring.h
src/lightmap/kexlib/memheap.h
src/lightmap/kexlib/parser.h
src/lightmap/kexlib/math/mathlib.h
)

View file

@ -1 +1,26 @@
# ZDRay
# ZDRay UDMF properties
linedef
{
lightcolor = <int> (color, default: white)
lightintensity = <float> (default: 1)
lightdistance = <float> (default: 0, no light)
}
thing
{
lightcolor = <int> (color)
lightintensity = <float> (default: 1)
lightdistance = <float> (default: 0, no light)
}
sector
{
lightcolorfloor = <int> (color, default: white)
lightintensityfloor = <float> (default: 1)
lightdistancefloor = <float> (default: 0, no light)
lightcolorceiling = <int> (color, default: white)
lightintensityceiling = <float> (default: 1)
lightdistanceceiling = <float> (default: 0, no light)
}

View file

@ -217,6 +217,8 @@ struct IntThing
char special;
char args[5];
float height; // UDMF
TArray<UDMFKey> props;
};
@ -374,7 +376,6 @@ struct FLevel
TArray<kexLightSurface*> lightSurfaces;
void SetupDlight();
void ParseConfigFile(const char *file);
void CreateLights();
void CleanupThingLights();
@ -395,12 +396,6 @@ private:
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;

View file

@ -597,14 +597,13 @@ void FProcessor::BuildNodes()
}
}
void FProcessor::BuildLightmaps(const char *configFile)
void FProcessor::BuildLightmaps()
{
LMBuilder.ambience = 0.0f;
LMBuilder.samples = Samples;
LMBuilder.textureWidth = LMDims;
LMBuilder.textureHeight = LMDims;
Level.ParseConfigFile(configFile);
Level.SetupDlight();
Surface_AllocateFromMap(Level);
Level.CreateLights();

View file

@ -38,7 +38,7 @@ public:
FProcessor(FWadReader &inwad, int lump);
void BuildNodes();
void BuildLightmaps(const char *configFile);
void BuildLightmaps();
void Write(FWadWriter &out);
private:

View file

@ -183,6 +183,10 @@ void FProcessor::ParseThing(IntThing *th)
{
th->type = (short)CheckInt(key);
}
if (!stricmp(key, "height"))
{
th->height = CheckFloat(key);
}
// now store the key in its unprocessed form
UDMFKey k = {key, value};

File diff suppressed because it is too large Load diff

View file

@ -1,172 +0,0 @@
//-----------------------------------------------------------------------------
// Note: this is a modified version of dlight. It is not the original software.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2013-2014 Samuel Villarreal
// svkaiser@gmail.com
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
#pragma once
#define MAX_NESTED_PARSERS 128
#define MAX_NESTED_FILENAMES 128
enum tokentype_t
{
TK_NONE,
TK_NUMBER,
TK_STRING,
TK_POUND,
TK_COLON,
TK_SEMICOLON,
TK_PERIOD,
TK_QUOTE,
TK_FORWARDSLASH,
TK_EQUAL,
TK_LBRACK,
TK_RBRACK,
TK_LPAREN,
TK_RPAREN,
TK_LSQBRACK,
TK_RSQBRACK,
TK_COMMA,
TK_IDENIFIER,
TK_DEFINE,
TK_UNDEF,
TK_INCLUDE,
TK_SETDIR,
TK_EOF
};
enum arraytype_t
{
AT_SHORT,
AT_INTEGER,
AT_FLOAT,
AT_DOUBLE,
AT_VECTOR
};
#define SC_TOKEN_LEN 512
struct sctokens
{
int id;
const char *token;
};
class kexLexer
{
public:
kexLexer(const char *filename, char *buf, int bufSize);
~kexLexer();
bool CheckState();
void CheckKeywords();
void MustMatchToken(int type);
void ExpectNextToken(int type);
bool Find();
char GetChar();
void Rewind();
void SkipLine();
bool Matches(const char *string);
int GetNumber();
double GetFloat();
kexVec3 GetVector3();
kexVec4 GetVector4();
kexVec3 GetVectorString3();
kexVec4 GetVectorString4();
void GetString();
int GetIDForTokenList(const sctokens *tokenlist, const char *token);
void ExpectTokenListID(const sctokens *tokenlist, int id);
void AssignFromTokenList(const sctokens *tokenlist,
char *str, int id, bool expect);
void AssignFromTokenList(const sctokens *tokenlist,
unsigned int *var, int id, bool expect);
void AssignFromTokenList(const sctokens *tokenlist,
unsigned short *var, int id, bool expect);
void AssignFromTokenList(const sctokens *tokenlist,
float *var, int id, bool expect);
void AssignVectorFromTokenList(const sctokens *tokenlist,
float *var, int id, bool expect);
void AssignFromTokenList(const sctokens *tokenlist,
arraytype_t type, void **data, int count,
int id, bool expect, kexHeapBlock &hb);
int LinePos() { return linepos; }
int RowPos() { return rowpos; }
int BufferPos() { return buffpos; }
int BufferSize() { return buffsize; }
char *Buffer() { return buffer; }
char *StringToken() { return stringToken; }
const char *Token() const { return token; }
const int TokenType() const { return tokentype; }
private:
void ClearToken();
void GetNumberToken(char initial);
void GetLetterToken(char initial);
void GetSymbolToken(char c);
void GetStringToken();
char token[SC_TOKEN_LEN];
char stringToken[MAX_FILEPATH];
char* buffer;
char* pointer_start;
char* pointer_end;
int linepos;
int rowpos;
int buffpos;
int buffsize;
int tokentype;
const char *name;
};
class kexParser
{
public:
kexParser();
~kexParser();
kexLexer *Open(const char *filename);
void Close();
void HandleError(const char *msg, ...);
void PushLexer(const char *filename, char *buf, int bufSize);
void PopLexer();
void PushFileName(const char *name);
void PopFileName();
byte *CharCode() { return charcode; }
const kexLexer *CurrentLexer() const { return currentLexer; }
private:
int OpenExternalFile(const char *name, byte **buffer) const;
const char *GetNestedFileName() const;
kexLexer *currentLexer;
kexLexer *lexers[MAX_NESTED_PARSERS];
int numLexers;
byte charcode[256];
char nestedFilenames[MAX_NESTED_FILENAMES][MAX_FILEPATH];
int numNestedFilenames;
};
extern kexParser *parser;

View file

@ -32,7 +32,6 @@
#include "common.h"
#include "wad.h"
#include "kexlib/parser.h"
#include "mapdata.h"
#include "lightsurface.h"
@ -41,18 +40,6 @@ 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();
@ -169,10 +156,8 @@ void FLevel::CheckSkySectors()
for (int i = 0; i < (int)Sectors.Size(); ++i)
{
if (mapDef && mapDef->sunIgnoreTag != 0 && Sectors[i].data.tag == mapDef->sunIgnoreTag)
{
continue;
}
//if (mapDef && mapDef->sunIgnoreTag != 0 && Sectors[i].data.tag == mapDef->sunIgnoreTag)
// continue;
strncpy(name, Sectors[i].data.ceilingpic, 8);
name[8] = 0;
@ -207,21 +192,11 @@ void FLevel::CheckSkySectors()
const kexVec3 &FLevel::GetSunColor() const
{
if (mapDef != NULL)
{
return mapDef->sunColor;
}
return defaultSunColor;
}
const kexVec3 &FLevel::GetSunDirection() const
{
if (mapDef != NULL)
{
return mapDef->sunDir;
}
return defaultSunDirection;
}
@ -458,187 +433,8 @@ bool FLevel::CheckPVS(MapSubsectorEx *s1, MapSubsectorEx *s2)
return ((vis[n2 >> 3] & (1 << (n2 & 7))) != 0);
}
void FLevel::ParseConfigFile(const char *file)
{
kexLexer *lexer;
if (!(lexer = parser->Open(file)))
{
Error("FLevel::ParseConfigFile: %s not found\n", file);
return;
}
while (lexer->CheckState())
{
lexer->Find();
// check for mapdef block
if (lexer->Matches("mapdef"))
{
mapDef_t mapDef;
mapDef.map = -1;
mapDef.sunIgnoreTag = 0;
lexer->ExpectNextToken(TK_LBRACK);
lexer->Find();
while (lexer->TokenType() != TK_RBRACK)
{
if (lexer->Matches("map"))
{
mapDef.map = lexer->GetNumber();
}
else if (lexer->Matches("sun_ignore_tag"))
{
mapDef.sunIgnoreTag = lexer->GetNumber();
}
else if (lexer->Matches("sun_direction"))
{
mapDef.sunDir = lexer->GetVectorString3();
}
else if (lexer->Matches("sun_color"))
{
mapDef.sunColor = lexer->GetVectorString3();
mapDef.sunColor /= 255.0f;
}
lexer->Find();
}
mapDefs.Push(mapDef);
}
// check for lightdef block
if (lexer->Matches("lightdef"))
{
lightDef_t lightDef;
lightDef.doomednum = -1;
lightDef.height = 0;
lightDef.intensity = 2;
lightDef.falloff = 1;
lightDef.bCeiling = false;
lexer->ExpectNextToken(TK_LBRACK);
lexer->Find();
while (lexer->TokenType() != TK_RBRACK)
{
if (lexer->Matches("doomednum"))
{
lightDef.doomednum = lexer->GetNumber();
}
else if (lexer->Matches("rgb"))
{
lightDef.rgb = lexer->GetVectorString3();
lightDef.rgb /= 255.0f;
}
else if (lexer->Matches("height"))
{
lightDef.height = (float)lexer->GetFloat();
}
else if (lexer->Matches("radius"))
{
lightDef.radius = (float)lexer->GetFloat();
}
else if (lexer->Matches("intensity"))
{
lightDef.intensity = (float)lexer->GetFloat();
}
else if (lexer->Matches("falloff"))
{
lightDef.falloff = (float)lexer->GetFloat();
}
else if (lexer->Matches("ceiling"))
{
lightDef.bCeiling = true;
}
lexer->Find();
}
lightDefs.Push(lightDef);
}
if (lexer->Matches("surfaceLight"))
{
surfaceLightDef surfaceLight;
surfaceLight.tag = 0;
surfaceLight.outerCone = 0.0f;
surfaceLight.innerCone = 0.0f;
surfaceLight.falloff = 1.0f;
surfaceLight.intensity = 1.0f;
surfaceLight.distance = 400.0f;
surfaceLight.bIgnoreCeiling = false;
surfaceLight.bIgnoreFloor = false;
surfaceLight.bNoCenterPoint = false;
surfaceLight.rgb.x = 1.0f;
surfaceLight.rgb.y = 1.0f;
surfaceLight.rgb.z = 1.0f;
lexer->ExpectNextToken(TK_LBRACK);
lexer->Find();
while (lexer->TokenType() != TK_RBRACK)
{
if (lexer->Matches("tag"))
{
surfaceLight.tag = lexer->GetNumber();
}
else if (lexer->Matches("rgb"))
{
surfaceLight.rgb = lexer->GetVectorString3();
surfaceLight.rgb /= 255.0f;
}
else if (lexer->Matches("cone_outer"))
{
surfaceLight.outerCone = (float)lexer->GetFloat() / 180.0f;
}
else if (lexer->Matches("cone_inner"))
{
surfaceLight.innerCone = (float)lexer->GetFloat() / 180.0f;
}
else if (lexer->Matches("falloff"))
{
surfaceLight.falloff = (float)lexer->GetFloat();
}
else if (lexer->Matches("intensity"))
{
surfaceLight.intensity = (float)lexer->GetFloat();
}
else if (lexer->Matches("distance"))
{
surfaceLight.distance = (float)lexer->GetFloat();
}
else if (lexer->Matches("bIgnoreCeiling"))
{
surfaceLight.bIgnoreCeiling = true;
}
else if (lexer->Matches("bIgnoreFloor"))
{
surfaceLight.bIgnoreFloor = true;
}
else if (lexer->Matches("bNoCenterPoint"))
{
surfaceLight.bNoCenterPoint = true;
}
lexer->Find();
}
surfaceLightDefs.Push(surfaceLight);
}
}
// we're done with the file
parser->Close();
}
void FLevel::CreateLights()
{
IntThing *thing;
thingLight_t *thingLight;
unsigned int j;
int numSurfLights;
@ -649,51 +445,52 @@ void FLevel::CreateLights()
//
for (int i = 0; i < (int)Things.Size(); ++i)
{
lightDef_t *lightDef = NULL;
IntThing *thing = &Things[i];
thing = &Things[i];
uint32_t lightcolor = 0xffffff;
float lightintensity = 1.0f;
float lightdistance = 0.0f;
for (j = 0; j < (int)lightDefs.Size(); ++j)
for (unsigned int propIndex = 0; propIndex < thing->props.Size(); propIndex++)
{
if (thing->type == lightDefs[j].doomednum)
const UDMFKey &key = thing->props[propIndex];
if (!stricmp(key.key, "lightcolor"))
{
lightDef = &lightDefs[j];
break;
lightcolor = atoi(key.value);
}
else if (!stricmp(key.key, "lightintensity"))
{
lightintensity = atof(key.value);
}
else if (!stricmp(key.key, "lightdistance"))
{
lightdistance = atof(key.value);
}
}
if (!lightDef)
if (lightdistance > 0.0f && lightintensity > 0.0f && lightcolor != 0)
{
continue;
}
if (lightDef->radius >= 0)
{
// ignore if all skills aren't set
if (!(thing->flags & 7))
{
continue;
}
}
int x = thing->x >> FRACBITS;
int y = thing->y >> FRACBITS;
thingLight = new thingLight_t;
thingLight = new thingLight_t();
thingLight->mapThing = thing;
thingLight->rgb = lightDef->rgb;
thingLight->intensity = lightDef->intensity;
thingLight->falloff = lightDef->falloff;
thingLight->radius = lightDef->radius >= 0 ? lightDef->radius : thing->angle;
thingLight->height = lightDef->height;
thingLight->bCeiling = lightDef->bCeiling;
thingLight->rgb.x = ((lightcolor >> 16) & 0xff) / 255.0f;
thingLight->rgb.y = ((lightcolor >> 8) & 0xff) / 255.0f;
thingLight->rgb.z = (lightcolor & 0xff) / 255.0f;
thingLight->intensity = lightintensity;
thingLight->falloff = 1.0f;
thingLight->radius = lightdistance;
thingLight->height = thing->height;
thingLight->bCeiling = false;
thingLight->ssect = PointInSubSector(x, y);
thingLight->sector = GetSectorFromSubSector(thingLight->ssect);
thingLight->origin.Set(x, y);
thingLights.Push(thingLight);
}
}
printf("Thing lights: %i\n", thingLights.Size());
@ -706,50 +503,123 @@ void FLevel::CreateLights()
{
surface_t *surface = surfaces[j];
for (unsigned int k = 0; k < surfaceLightDefs.Size(); ++k)
{
surfaceLightDef *surfaceLightDef = &surfaceLightDefs[k];
if (surface->type >= ST_MIDDLESEG && surface->type <= ST_LOWERSEG)
{
MapSegGLEx *seg = (MapSegGLEx*)surface->data;
IntLineDef *line = nullptr;
if (GLSegs[surface->typeIndex].linedef != NO_LINE_INDEX)
line = &Lines[GLSegs[surface->typeIndex].linedef];
if (Lines[seg->linedef].args[1] == surfaceLightDef->tag)
if (line)
{
kexLightSurface *lightSurface = new kexLightSurface;
uint32_t lightcolor = 0xffffff;
float lightintensity = 1.0f;
float lightdistance = 0.0f;
lightSurface->Init(*surfaceLightDef, surface, true, false);
for (unsigned int propIndex = 0; propIndex < line->props.Size(); propIndex++)
{
const UDMFKey &key = line->props[propIndex];
if (!stricmp(key.key, "lightcolor"))
{
lightcolor = atoi(key.value);
}
else if (!stricmp(key.key, "lightintensity"))
{
lightintensity = atof(key.value);
}
else if (!stricmp(key.key, "lightdistance"))
{
lightdistance = atof(key.value);
}
}
if (lightdistance > 0.0f && lightintensity > 0.0f && lightcolor != 0)
{
surfaceLightDef desc;
desc.tag = 0;
desc.outerCone = 0.0f;
desc.innerCone = 0.0f;
desc.falloff = 1.0f;
desc.intensity = lightintensity;
desc.distance = lightdistance;
desc.bIgnoreCeiling = false;
desc.bIgnoreFloor = false;
desc.bNoCenterPoint = false;
desc.rgb.x = ((lightcolor >> 16) & 0xff) / 255.0f;
desc.rgb.y = ((lightcolor >> 8) & 0xff) / 255.0f;
desc.rgb.z = (lightcolor & 0xff) / 255.0f;
kexLightSurface *lightSurface = new kexLightSurface();
lightSurface->Init(desc, surface, true, false);
lightSurface->CreateCenterOrigin();
lightSurfaces.Push(lightSurface);
numSurfLights++;
}
}
else
}
else if (surface->type == ST_FLOOR || surface->type == ST_CEILING)
{
MapSubsectorEx *sub = surface->subSector;
IntSector *sector = GetSectorFromSubSector(sub);
if (!sector || surface->numVerts <= 0)
if (sector && surface->numVerts > 0)
{
// eh....
continue;
uint32_t lightcolor = 0xffffff;
float lightintensity = 1.0f;
float lightdistance = 0.0f;
for (unsigned int propIndex = 0; propIndex < sector->props.Size(); propIndex++)
{
const UDMFKey &key = sector->props[propIndex];
if (surface->type == ST_FLOOR)
{
if (!stricmp(key.key, "lightcolorfloor"))
{
lightcolor = atoi(key.value);
}
else if (!stricmp(key.key, "lightintensityfloor"))
{
lightintensity = atof(key.value);
}
else if (!stricmp(key.key, "lightdistancefloor"))
{
lightdistance = atof(key.value);
}
}
else
{
if (!stricmp(key.key, "lightcolorceiling"))
{
lightcolor = atoi(key.value);
}
else if (!stricmp(key.key, "lightintensityceiling"))
{
lightintensity = atof(key.value);
}
else if (!stricmp(key.key, "lightdistanceceiling"))
{
lightdistance = atof(key.value);
}
}
}
if (surface->type == ST_CEILING && surfaceLightDef->bIgnoreCeiling)
if (lightdistance > 0.0f && lightintensity > 0.0f && lightcolor != 0)
{
continue;
}
surfaceLightDef desc;
desc.tag = 0;
desc.outerCone = 0.0f;
desc.innerCone = 0.0f;
desc.falloff = 1.0f;
desc.intensity = lightintensity;
desc.distance = lightdistance;
desc.bIgnoreCeiling = false;
desc.bIgnoreFloor = false;
desc.bNoCenterPoint = false;
desc.rgb.x = ((lightcolor >> 16) & 0xff) / 255.0f;
desc.rgb.y = ((lightcolor >> 8) & 0xff) / 255.0f;
desc.rgb.z = (lightcolor & 0xff) / 255.0f;
if (surface->type == ST_FLOOR && surfaceLightDef->bIgnoreFloor)
{
continue;
}
if (sector->data.tag == surfaceLightDef->tag)
{
kexLightSurface *lightSurface = new kexLightSurface;
lightSurface->Init(*surfaceLightDef, surface, false, surfaceLightDef->bNoCenterPoint);
kexLightSurface *lightSurface = new kexLightSurface();
lightSurface->Init(desc, surface, false, desc.bNoCenterPoint);
lightSurface->Subdivide(16);
lightSurfaces.Push(lightSurface);
numSurfLights++;

View file

@ -242,7 +242,7 @@ int main(int argc, char **argv)
START_COUNTER(t2a, t2b, t2c)
FProcessor builder(inwad, lump);
builder.BuildNodes();
builder.BuildLightmaps("lightconfig.txt");
builder.BuildLightmaps();
builder.Write(outwad);
END_COUNTER(t2a, t2b, t2c, " %.3f seconds.\n")