Port over doom level mesh

This commit is contained in:
Magnus Norddahl 2023-10-10 22:11:30 +02:00
parent 1391957a42
commit 2c6d4f6f22
6 changed files with 190 additions and 191 deletions

View file

@ -1802,6 +1802,14 @@ public:
FVector3 Normal() const { return FVector3(a, b, c); }
void FlipVert()
{
a = -a;
b = -b;
c = -c;
d = -d;
}
float a, b, c, d;
};

View file

@ -6,6 +6,7 @@
#include "framework/templates.h"
#include "framework/zstring.h"
#include "framework/vectors.h"
#include "lightmapper/textureid.h"
#include <memory>
#include <cmath>
#include <optional>
@ -77,6 +78,8 @@ struct SideDefSampleProps
};
struct IntLineDef;
struct IntSector;
class FTextureID;
struct IntSideDef
{
@ -90,17 +93,23 @@ struct IntSideDef
int sector;
int lightdef;
IntSector* sectordef;
IntLineDef *line;
SideDefSampleProps sampling;
TArray<UDMFKey> props;
DoomLevelMeshSurface* lightmap;
FTextureID GetTexture(WallPart part) { return FNullTextureID(); }
float GetTextureYOffset(WallPart part) { return 0.0f; }
float GetTextureYScale(WallPart part) { return 1.0f; }
inline int GetSampleDistance(WallPart part) const;
inline int GetSectorGroup() const;
int Index(const FLevel& level) const;
FVector2 V1(const FLevel& level) const;
FVector2 V2(const FLevel& level) const;
};
struct MapLineDef
@ -137,6 +146,7 @@ struct IntLineDef
TArray<UDMFKey> props;
TArray<int> ids;
IntSideDef* sidedef[2] = { nullptr, nullptr };
IntSector *frontsector = nullptr, *backsector = nullptr;
SideDefSampleProps sampling;
@ -184,6 +194,8 @@ struct IntSector
bool controlsector;
TArray<IntSector*> x3dfloors;
bool HasLightmaps = false;
union
{
bool skyPlanes[2];
@ -197,6 +209,8 @@ struct IntSector
int group = 0;
FTextureID GetTexture(SecPlaneType plane) { return FNullTextureID(); }
// Utility functions
inline const char* GetTextureName(int plane) const { return plane != PLANE_FLOOR ? data.ceilingpic : data.floorpic; }
@ -236,10 +250,16 @@ struct MapSubsector
uint16_t firstline;
};
struct MapSegGLEx;
struct IntSector;
struct MapSubsectorEx
{
uint32_t numlines;
uint32_t firstline;
MapSegGLEx* GetFirstLine(const FLevel& level) const;
IntSector* GetSector(const FLevel& level) const;
};
struct MapSeg
@ -460,11 +480,57 @@ struct ThingLight
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?
ML_TRANSPARENT2 = 4096, // 25% or 75% transcluency?
ML_BLOCKING = 0x00000001, // solid, is an obstacle
ML_BLOCKMONSTERS = 0x00000002, // blocks monsters only
ML_TWOSIDED = 0x00000004, // backside will not be present at all if not two sided
// If a texture is pegged, the texture will have
// the end exposed to air held constant at the
// top or bottom of the texture (stairs or pulled
// down things) and will move with a height change
// of one of the neighbor sectors.
// Unpegged textures always have the first row of
// the texture at the top pixel of the line for both
// top and bottom textures (use next to windows).
ML_DONTPEGTOP = 0x00000008, // upper texture unpegged
ML_DONTPEGBOTTOM = 0x00000010, // lower texture unpegged
ML_SECRET = 0x00000020, // don't map as two sided: IT'S A SECRET!
ML_SOUNDBLOCK = 0x00000040, // don't let sound cross two of these
ML_DONTDRAW = 0x00000080, // don't draw on the automap
ML_MAPPED = 0x00000100, // set if already drawn in automap
ML_REPEAT_SPECIAL = 0x00000200, // special is repeatable
// 0x400, 0x800 and 0x1000 are ML_SPAC_MASK, they can be used for internal things but not for real map flags.
ML_ADDTRANS = 0x00000400, // additive translucency (can only be set internally)
ML_COMPATSIDE = 0x00000800, // for compatible PointOnLineSide checks. Using the global compatibility check would be a bit expensive for this check.
// Extended flags
ML_NOSKYWALLS = 0x00001000, // Don't draw sky above or below walls
ML_MONSTERSCANACTIVATE = 0x00002000, // [RH] Monsters (as well as players) can activate the line
ML_BLOCK_PLAYERS = 0x00004000,
ML_BLOCKEVERYTHING = 0x00008000, // [RH] Line blocks everything
ML_ZONEBOUNDARY = 0x00010000,
ML_RAILING = 0x00020000,
ML_BLOCK_FLOATERS = 0x00040000,
ML_CLIP_MIDTEX = 0x00080000, // Automatic for every Strife line
ML_WRAP_MIDTEX = 0x00100000,
ML_3DMIDTEX = 0x00200000,
ML_CHECKSWITCHRANGE = 0x00400000,
ML_FIRSTSIDEONLY = 0x00800000, // activated only when crossed from front side
ML_BLOCKPROJECTILE = 0x01000000,
ML_BLOCKUSE = 0x02000000, // blocks all use actions through this line
ML_BLOCKSIGHT = 0x04000000, // blocks monster line of sight
ML_BLOCKHITSCAN = 0x08000000, // blocks hitscan attacks
ML_3DMIDTEX_IMPASS = 0x10000000, // [TP] if 3D midtex, behaves like a height-restricted ML_BLOCKING
ML_REVEALED = 0x20000000, // set if revealed in automap
ML_DRAWFULLHEIGHT = 0x40000000, // Draw the full height of the upper/lower sections
ML_PORTALCONNECT = 0x80000000, // for internal use only: This line connects to a sector with a linked portal (used to speed up sight checks.)
// Flag words may not exceed 32 bit due to VM limitations.
ML2_BLOCKLANDMONSTERS = 0x1, // MBF21
};
#define NO_SIDE_INDEX -1
@ -523,11 +589,11 @@ struct FLevel
const FVector3 &GetSunColor() const;
const FVector3 &GetSunDirection() const;
IntSector *GetFrontSector(const IntSideDef *side);
IntSector *GetBackSector(const IntSideDef *side);
IntSector *GetSectorFromSubSector(const MapSubsectorEx *sub);
IntSector* GetFrontSector(const IntSideDef* side) const;
IntSector* GetBackSector(const IntSideDef* side) const;
IntSector* GetSectorFromSubSector(const MapSubsectorEx* sub) const;
MapSubsectorEx *PointInSubSector(const int x, const int y);
FloatVertex GetSegVertex(unsigned int index);
FloatVertex GetSegVertex(unsigned int index) const;
int FindFirstSectorFromTag(int tag);
unsigned FindFirstLineId(int lineId);
@ -546,3 +612,9 @@ const int BLOCKFRACBITS = FRACBITS+7;
inline int IntSector::Index(const FLevel& level) const { return (int)(ptrdiff_t)(this - level.Sectors.Data()); }
inline int IntSideDef::Index(const FLevel& level) const { return (int)(ptrdiff_t)(this - level.Sides.Data()); }
inline int IntLineDef::Index(const FLevel& level) const { return (int)(ptrdiff_t)(this - level.Lines.Data()); }
inline MapSegGLEx* MapSubsectorEx::GetFirstLine(const FLevel& level) const { return firstline != NO_INDEX ? &level.GLSegs[firstline] : nullptr; }
inline IntSector* MapSubsectorEx::GetSector(const FLevel& level) const { return level.GetSectorFromSubSector(this); }
inline FVector2 IntSideDef::V1(const FLevel& level) const { auto v = level.GetSegVertex(sectordef == line->frontsector ? line->v1 : line->v2); return FVector2(v.x, v.y); }
inline FVector2 IntSideDef::V2(const FLevel& level) const { auto v = level.GetSegVertex(sectordef == line->frontsector ? line->v2 : line->v1); return FVector2(v.x, v.y); }

View file

@ -624,7 +624,10 @@ void FLevel::PostLoadInitialization()
Sectors[i].controlsector = false;
for (unsigned int i = 0; i < Sides.Size(); i++)
{
Sides[i].line = nullptr;
Sides[i].sectordef = &Sectors[Sides[i].sector];
}
for (unsigned int i = 0; i < Lines.Size(); i++)
{
@ -670,8 +673,11 @@ void FLevel::PostLoadInitialization()
sector.lines.Push(line);
line->frontsector = (line->sidenum[0] != NO_INDEX) ? &Sectors[Sides[line->sidenum[0]].sector] : nullptr;
line->backsector = (line->sidenum[1] != NO_INDEX) ? &Sectors[Sides[line->sidenum[1]].sector] : nullptr;
line->sidedef[0] = (line->sidenum[0] != NO_INDEX) ? &Sides[line->sidenum[0]] : nullptr;
line->sidedef[1] = (line->sidenum[1] != NO_INDEX) ? &Sides[line->sidenum[1]] : nullptr;
line->frontsector = line->sidedef[0] ? &Sectors[line->sidedef[0]->sector] : nullptr;
line->backsector = line->sidedef[1] ? &Sectors[line->sidedef[1]->sector] : nullptr;
}
// Find plane portals

View file

@ -146,12 +146,12 @@ const FVector3 &FLevel::GetSunDirection() const
return defaultSunDirection;
}
IntSector *FLevel::GetFrontSector(const IntSideDef *side)
IntSector *FLevel::GetFrontSector(const IntSideDef *side) const
{
return &Sectors[side->sector];
}
IntSector *FLevel::GetBackSector(const IntSideDef *side)
IntSector *FLevel::GetBackSector(const IntSideDef *side) const
{
IntLineDef *line = side->line;
if (!(line->flags & ML_TWOSIDED))
@ -169,7 +169,7 @@ IntSector *FLevel::GetBackSector(const IntSideDef *side)
return GetFrontSector(&Sides[sidenum]);
}
IntSector *FLevel::GetSectorFromSubSector(const MapSubsectorEx *sub)
IntSector *FLevel::GetSectorFromSubSector(const MapSubsectorEx *sub) const
{
for (int i = 0; i < (int)sub->numlines; i++)
{
@ -223,7 +223,7 @@ MapSubsectorEx *FLevel::PointInSubSector(const int x, const int y)
return &GLSubsectors[nodenum & ~NFX_SUBSECTOR];
}
FloatVertex FLevel::GetSegVertex(unsigned int index)
FloatVertex FLevel::GetSegVertex(unsigned int index) const
{
FloatVertex v;
v.x = F(GLVertices[index].x);

View file

@ -1,5 +1,6 @@
#include "doom_levelmesh.h"
#include "level/level.h"
#include <algorithm>
#include <map>
@ -157,7 +158,7 @@ void DoomLevelSubmesh::CreatePortals(FLevel& doomMap)
bool hasPortal = [&]() {
if (surface.Type == ST_FLOOR || surface.Type == ST_CEILING)
{
return !surface.Subsector->sector->GetPortalDisplacement(surface.Type == ST_FLOOR ? IntSector::floor : IntSector::ceiling).isZero();
return !surface.Subsector->sector->GetPortalDisplacement(surface.Type == ST_FLOOR ? PLANE_FLOOR : PLANE_CEILING).isZero();
}
else if (surface.Type == ST_MIDDLESIDE)
{
@ -174,7 +175,7 @@ void DoomLevelSubmesh::CreatePortals(FLevel& doomMap)
if (surface.Type == ST_FLOOR || surface.Type == ST_CEILING)
{
auto d = surface.Subsector->sector->GetPortalDisplacement(surface.Type == ST_FLOOR ? IntSector::floor : IntSector::ceiling);
auto d = surface.Subsector->sector->GetPortalDisplacement(surface.Type == ST_FLOOR ? PLANE_FLOOR : PLANE_CEILING);
matrix.translate((float)d.X, (float)d.Y, 0.0f);
}
else if (surface.Type == ST_MIDDLESIDE)
@ -221,7 +222,7 @@ void DoomLevelSubmesh::CreatePortals(FLevel& doomMap)
portal.targetSectorGroup = [&]() {
if (surface.Type == ST_FLOOR || surface.Type == ST_CEILING)
{
auto plane = surface.Type == ST_FLOOR ? IntSector::floor : IntSector::ceiling;
auto plane = surface.Type == ST_FLOOR ? PLANE_FLOOR : PLANE_CEILING;
auto portalDestination = surface.Subsector->sector->GetPortal(plane)->mDestination;
if (portalDestination)
{
@ -258,7 +259,6 @@ void DoomLevelSubmesh::CreatePortals(FLevel& doomMap)
#endif
}
#if 0
void DoomLevelSubmesh::BindLightmapSurfacesToGeometry(FLevel& doomMap)
{
// You have no idea how long this took me to figure out...
@ -284,83 +284,14 @@ void DoomLevelSubmesh::BindLightmapSurfacesToGeometry(FLevel& doomMap)
surface.TexCoords = (float*)&LightmapUvs[surface.startUvIndex];
}
// Link surfaces
for (auto& surface : Surfaces)
{
if (surface.Type == ST_FLOOR || surface.Type == ST_CEILING)
{
surface.Subsector = &doomMap.GLSubsectors[surface.TypeIndex];
if (surface.Subsector->firstline && surface.Subsector->firstline->sidedef)
surface.Subsector->firstline->sidedef->sector->HasLightmaps = true;
SetSubsectorLightmap(&surface);
}
else
{
surface.Side = &doomMap.Sides[surface.TypeIndex];
SetSideLightmap(doomMap, &surface);
}
}
}
void DoomLevelSubmesh::SetSubsectorLightmap(FLevel& doomMap, DoomLevelMeshSurface* surface)
{
if (!surface->ControlSector)
{
int index = surface->Type == ST_CEILING ? 1 : 0;
surface->Subsector->lightmap[index][0] = surface;
}
else
{
int index = surface->Type == ST_CEILING ? 0 : 1;
const auto& ffloors = surface->Subsector->sector->e->XFloor.ffloors;
for (unsigned int i = 0; i < ffloors.Size(); i++)
{
if (ffloors[i]->model == surface->ControlSector)
{
surface->Subsector->lightmap[index][i + 1] = surface;
}
}
}
}
void DoomLevelSubmesh::SetSideLightmap(FLevel& doomMap, DoomLevelMeshSurface* surface)
{
if (!surface->ControlSector)
{
if (surface->Type == ST_UPPERSIDE)
{
surface->Side->lightmap[0] = surface;
}
else if (surface->Type == ST_MIDDLESIDE)
{
surface->Side->lightmap[1] = surface;
surface->Side->lightmap[2] = surface;
}
else if (surface->Type == ST_LOWERSIDE)
{
surface->Side->lightmap[3] = surface;
}
}
else
{
const auto& ffloors = doomMap.Sectors[surface->Side->sector].x3dfloors;
for (unsigned int i = 0; i < ffloors.Size(); i++)
{
if (ffloors[i]->model == surface->ControlSector)
{
surface->Side->lightmap[4 + i] = surface;
}
}
}
}
void DoomLevelSubmesh::CreateLinePortalSurface(FLevel& doomMap, IntSideDef* side)
{
IntSector* front = &doomMap.Sectors[side->sector];
FVector2 v1 = ToFVector2(side->V1()->fPos());
FVector2 v2 = ToFVector2(side->V2()->fPos());
FVector2 v1 = side->V1(doomMap);
FVector2 v2 = side->V2(doomMap);
float v1Top = (float)front->ceilingplane.ZatPoint(v1);
float v1Bottom = (float)front->floorplane.ZatPoint(v1);
@ -381,8 +312,8 @@ void DoomLevelSubmesh::CreateLinePortalSurface(FLevel& doomMap, IntSideDef* side
surf.Submesh = this;
surf.Type = ST_MIDDLESIDE;
surf.TypeIndex = side->Index(doomMap);
surf.bSky = front->GetTexture(IntSector::floor) == skyflatnum || front->GetTexture(IntSector::ceiling) == skyflatnum;
surf.sampleDimension = side->textures[ETexpart::Mid].LightmapSampleDistance;
surf.bSky = front->skyFloor || front->skyCeiling; // front->GetTexture(PLANE_FLOOR) == skyflatnum || front->GetTexture(PLANE_CEILING) == skyflatnum;
surf.sampleDimension = side->GetSampleDistance(WallPart::MIDDLE);
surf.startVertIndex = MeshVertices.Size();
surf.numVerts = 4;
@ -394,7 +325,7 @@ void DoomLevelSubmesh::CreateLinePortalSurface(FLevel& doomMap, IntSideDef* side
surf.plane = ToPlane(verts[0], verts[1], verts[2], verts[3]);
surf.sectorGroup = sectorGroup[front->Index(doomMap)];
SetSideTextureUVs(surf, side, ETexpart::Top, v1Top, v1Bottom, v2Top, v2Bottom);
SetSideTextureUVs(surf, side, WallPart::TOP, v1Top, v1Bottom, v2Top, v2Bottom);
Surfaces.Push(surf);
}
@ -404,22 +335,19 @@ void DoomLevelSubmesh::CreateSideSurfaces(FLevel& doomMap, IntSideDef* side)
IntSector* front = &doomMap.Sectors[side->sector];
IntSector* back = (side->line->frontsector == front) ? side->line->backsector : side->line->frontsector;
FVector2 v1 = ToFVector2(side->line->V1()->fPos());
FVector2 v2 = ToFVector2(side->line->V2()->fPos());
if (side->line->frontsector != front)
std::swap(v1, v2);
FVector2 v1 = side->V1(doomMap);
FVector2 v2 = side->V2(doomMap);
float v1Top = (float)front->ceilingplane.ZatPoint(v1);
float v1Bottom = (float)front->floorplane.ZatPoint(v1);
float v2Top = (float)front->ceilingplane.ZatPoint(v2);
float v2Bottom = (float)front->floorplane.ZatPoint(v2);
if (side->line->getPortal() && side->line->frontsector == front)
/*if (side->line->getPortal() && side->line->frontsector == front)
{
CreateLinePortalSurface(doomMap, side);
}
else if (side->line->special == Line_Horizon && front != back)
else*/ if (side->line->special == Line_Horizon && front != back)
{
CreateLineHorizonSurface(doomMap, side);
}
@ -429,7 +357,7 @@ void DoomLevelSubmesh::CreateSideSurfaces(FLevel& doomMap, IntSideDef* side)
}
else
{
if (side->textures[ETexpart::Mid].texture.isValid())
if (side->GetTexture(WallPart::MIDDLE).isValid())
{
CreateMidWallSurface(doomMap, side);
}
@ -457,8 +385,8 @@ void DoomLevelSubmesh::CreateLineHorizonSurface(FLevel& doomMap, IntSideDef* sid
{
IntSector* front = &doomMap.Sectors[side->sector];
FVector2 v1 = ToFVector2(side->V1()->fPos());
FVector2 v2 = ToFVector2(side->V2()->fPos());
FVector2 v1 = side->V1(doomMap);
FVector2 v2 = side->V2(doomMap);
float v1Top = (float)front->ceilingplane.ZatPoint(v1);
float v1Bottom = (float)front->floorplane.ZatPoint(v1);
@ -469,8 +397,8 @@ void DoomLevelSubmesh::CreateLineHorizonSurface(FLevel& doomMap, IntSideDef* sid
surf.Submesh = this;
surf.Type = ST_MIDDLESIDE;
surf.TypeIndex = side->Index(doomMap);
surf.bSky = front->GetTexture(IntSector::floor) == skyflatnum || front->GetTexture(IntSector::ceiling) == skyflatnum;
surf.sampleDimension = side->textures[ETexpart::Mid].LightmapSampleDistance;
surf.bSky = front->skyFloor || front->skyCeiling; // front->GetTexture(PLANE_FLOOR) == skyflatnum || front->GetTexture(PLANE_CEILING) == skyflatnum;
surf.sampleDimension = side->GetSampleDistance(WallPart::MIDDLE);
FVector3 verts[4];
verts[0].X = verts[2].X = v1.X;
@ -492,7 +420,7 @@ void DoomLevelSubmesh::CreateLineHorizonSurface(FLevel& doomMap, IntSideDef* sid
surf.plane = ToPlane(verts[0], verts[1], verts[2], verts[3]);
surf.sectorGroup = sectorGroup[front->Index(doomMap)];
SetSideTextureUVs(surf, side, ETexpart::Top, v1Top, v1Bottom, v2Top, v2Bottom);
SetSideTextureUVs(surf, side, WallPart::TOP, v1Top, v1Bottom, v2Top, v2Bottom);
Surfaces.Push(surf);
}
@ -500,16 +428,9 @@ void DoomLevelSubmesh::CreateLineHorizonSurface(FLevel& doomMap, IntSideDef* sid
void DoomLevelSubmesh::CreateFrontWallSurface(FLevel& doomMap, IntSideDef* side)
{
IntSector* front = &doomMap.Sectors[side->sector];
/*
bool isPolyLine = !!(side->Flags & WALLF_POLYOBJ);
if (isPolyLine)
{
MapSubsectorEx* subsector = level.PointInRenderSubsector((side->V1()->fPos() + side->V2()->fPos()) * 0.5);
front = subsector->sector;
}
*/
FVector2 v1 = ToFVector2(side->V1()->fPos());
FVector2 v2 = ToFVector2(side->V2()->fPos());
FVector2 v1 = side->V1(doomMap);
FVector2 v2 = side->V2(doomMap);
float v1Top = (float)front->ceilingplane.ZatPoint(v1);
float v1Bottom = (float)front->floorplane.ZatPoint(v1);
@ -540,12 +461,12 @@ void DoomLevelSubmesh::CreateFrontWallSurface(FLevel& doomMap, IntSideDef* side)
surf.plane = ToPlane(verts[0], verts[1], verts[2], verts[3]);
surf.Type = ST_MIDDLESIDE;
surf.TypeIndex = side->Index(doomMap);
surf.sampleDimension = side->textures[ETexpart::Mid].LightmapSampleDistance;
surf.sampleDimension = side->GetSampleDistance(WallPart::MIDDLE);
surf.ControlSector = nullptr;
surf.sectorGroup = sectorGroup[front->Index(doomMap)];
surf.texture = side->textures[ETexpart::Mid].texture;
surf.texture = side->GetTexture(WallPart::MIDDLE);
SetSideTextureUVs(surf, side, ETexpart::Top, v1Top, v1Bottom, v2Top, v2Bottom);
SetSideTextureUVs(surf, side, WallPart::TOP, v1Top, v1Bottom, v2Top, v2Bottom);
Surfaces.Push(surf);
}
@ -554,8 +475,8 @@ void DoomLevelSubmesh::CreateMidWallSurface(FLevel& doomMap, IntSideDef* side)
{
IntSector* front = &doomMap.Sectors[side->sector];
FVector2 v1 = ToFVector2(side->V1()->fPos());
FVector2 v2 = ToFVector2(side->V2()->fPos());
FVector2 v1 = side->V1(doomMap);
FVector2 v2 = side->V2(doomMap);
float v1Top = (float)front->ceilingplane.ZatPoint(v1);
float v1Bottom = (float)front->floorplane.ZatPoint(v1);
@ -568,42 +489,42 @@ void DoomLevelSubmesh::CreateMidWallSurface(FLevel& doomMap, IntSideDef* side)
verts[1].X = verts[3].X = v2.X;
verts[1].Y = verts[3].Y = v2.Y;
const auto& texture = side->textures[ETexpart::Mid].texture;
const auto& texture = side->GetTexture(WallPart::MIDDLE);
if ((side->Flags & WALLF_WRAP_MIDTEX) || (side->line->flags & WALLF_WRAP_MIDTEX))
//if ((side->Flags & WALLF_WRAP_MIDTEX) || (side->line->flags & WALLF_WRAP_MIDTEX))
{
verts[0].Z = v1Bottom;
verts[1].Z = v2Bottom;
verts[2].Z = v1Top;
verts[3].Z = v2Top;
}
else
/*else
{
int offset = 0;
auto gameTexture = TexMan.GetGameTexture(texture);
float mid1Top = (float)(gameTexture->GetDisplayHeight() / side->textures[ETexpart::Mid].yScale);
float mid2Top = (float)(gameTexture->GetDisplayHeight() / side->textures[ETexpart::Mid].yScale);
float mid1Top = (float)(gameTexture->GetDisplayHeight() / side->GetTextureYScale(WallPart::MIDDLE));
float mid2Top = (float)(gameTexture->GetDisplayHeight() / side->GetTextureYScale(WallPart::MIDDLE));
float mid1Bottom = 0;
float mid2Bottom = 0;
float yTextureOffset = (float)(side->textures[ETexpart::Mid].yOffset / gameTexture->GetScaleY());
float yTextureOffset = (float)(side->GetTextureYOffset(WallPart::MIDDLE) / gameTexture->GetScaleY());
if (side->line->flags & ML_DONTPEGBOTTOM)
{
yTextureOffset += (float)side->sector->planes[IntSector::floor].TexZ;
yTextureOffset += (float)side->sectordef->planes[PLANE_FLOOR].TexZ;
}
else
{
yTextureOffset += (float)(side->sector->planes[IntSector::ceiling].TexZ - gameTexture->GetDisplayHeight() / side->textures[ETexpart::Mid].yScale);
yTextureOffset += (float)(side->sectordef->planes[PLANE_CEILING].TexZ - gameTexture->GetDisplayHeight() / side->GetTextureYScale(WallPart::MIDDLE));
}
verts[0].Z = std::min(std::max(yTextureOffset + mid1Bottom, v1Bottom), v1Top);
verts[1].Z = std::min(std::max(yTextureOffset + mid2Bottom, v2Bottom), v2Top);
verts[2].Z = std::max(std::min(yTextureOffset + mid1Top, v1Top), v1Bottom);
verts[3].Z = std::max(std::min(yTextureOffset + mid2Top, v2Top), v2Bottom);
}
}*/
// mid texture
DoomLevelMeshSurface surf;
@ -629,13 +550,13 @@ void DoomLevelSubmesh::CreateMidWallSurface(FLevel& doomMap, IntSideDef* side)
surf.Type = ST_MIDDLESIDE;
surf.TypeIndex = side->Index(doomMap);
surf.sampleDimension = side->textures[ETexpart::Mid].LightmapSampleDistance;
surf.sampleDimension = side->GetSampleDistance(WallPart::MIDDLE);
surf.ControlSector = nullptr;
surf.sectorGroup = sectorGroup[front->Index(doomMap)];
surf.texture = texture;
surf.alpha = float(side->line->alpha);
// surf.alpha = float(side->line->alpha);
SetSideTextureUVs(surf, side, ETexpart::Top, verts[2].Z, verts[0].Z, verts[3].Z, verts[1].Z);
SetSideTextureUVs(surf, side, WallPart::TOP, verts[2].Z, verts[0].Z, verts[3].Z, verts[1].Z);
Surfaces.Push(surf);
}
@ -645,8 +566,8 @@ void DoomLevelSubmesh::Create3DFloorWallSurfaces(FLevel& doomMap, IntSideDef* si
IntSector* front = &doomMap.Sectors[side->sector];
IntSector* back = (side->line->frontsector == front) ? side->line->backsector : side->line->frontsector;
FVector2 v1 = ToFVector2(side->V1()->fPos());
FVector2 v2 = ToFVector2(side->V2()->fPos());
FVector2 v1 = side->V1(doomMap);
FVector2 v2 = side->V2(doomMap);
float v1Top = (float)front->ceilingplane.ZatPoint(v1);
float v1Bottom = (float)front->floorplane.ZatPoint(v1);
@ -674,14 +595,14 @@ void DoomLevelSubmesh::Create3DFloorWallSurfaces(FLevel& doomMap, IntSideDef* si
surf.Submesh = this;
surf.Type = ST_MIDDLESIDE;
surf.TypeIndex = side->Index(doomMap);
surf.ControlSector = xfloor->model;
surf.ControlSector = xfloor;
surf.bSky = false;
surf.sampleDimension = side->textures[ETexpart::Mid].LightmapSampleDistance;
surf.sampleDimension = side->GetSampleDistance(WallPart::MIDDLE);
float blZ = (float)xfloor->model->floorplane.ZatPoint(v1);
float brZ = (float)xfloor->model->floorplane.ZatPoint(v2);
float tlZ = (float)xfloor->model->ceilingplane.ZatPoint(v1);
float trZ = (float)xfloor->model->ceilingplane.ZatPoint(v2);
float blZ = (float)xfloor->floorplane.ZatPoint(v1);
float brZ = (float)xfloor->floorplane.ZatPoint(v2);
float tlZ = (float)xfloor->ceilingplane.ZatPoint(v1);
float trZ = (float)xfloor->ceilingplane.ZatPoint(v2);
FVector3 verts[4];
verts[0].X = verts[2].X = v2.X;
@ -702,9 +623,9 @@ void DoomLevelSubmesh::Create3DFloorWallSurfaces(FLevel& doomMap, IntSideDef* si
surf.plane = ToPlane(verts[0], verts[1], verts[2], verts[3]);
surf.sectorGroup = sectorGroup[front->Index(doomMap)];
surf.texture = side->textures[ETexpart::Mid].texture;
surf.texture = side->GetTexture(WallPart::MIDDLE);
SetSideTextureUVs(surf, side, ETexpart::Top, tlZ, blZ, trZ, brZ);
SetSideTextureUVs(surf, side, WallPart::TOP, tlZ, blZ, trZ, brZ);
Surfaces.Push(surf);
}
@ -715,8 +636,8 @@ void DoomLevelSubmesh::CreateTopWallSurface(FLevel& doomMap, IntSideDef* side)
IntSector* front = &doomMap.Sectors[side->sector];
IntSector* back = (side->line->frontsector == front) ? side->line->backsector : side->line->frontsector;
FVector2 v1 = ToFVector2(side->V1()->fPos());
FVector2 v2 = ToFVector2(side->V2()->fPos());
FVector2 v1 = side->V1(doomMap);
FVector2 v2 = side->V2(doomMap);
float v1Top = (float)front->ceilingplane.ZatPoint(v1);
float v2Top = (float)front->ceilingplane.ZatPoint(v2);
@ -750,12 +671,12 @@ void DoomLevelSubmesh::CreateTopWallSurface(FLevel& doomMap, IntSideDef* side)
surf.Type = ST_UPPERSIDE;
surf.TypeIndex = side->Index(doomMap);
surf.bSky = bSky;
surf.sampleDimension = side->textures[ETexpart::Top].LightmapSampleDistance;
surf.sampleDimension = side->GetSampleDistance(WallPart::TOP);
surf.ControlSector = nullptr;
surf.sectorGroup = sectorGroup[front->Index(doomMap)];
surf.texture = side->textures[ETexpart::Top].texture;
surf.texture = side->GetTexture(WallPart::TOP);
SetSideTextureUVs(surf, side, ETexpart::Top, v1Top, v1TopBack, v2Top, v2TopBack);
SetSideTextureUVs(surf, side, WallPart::TOP, v1Top, v1TopBack, v2Top, v2TopBack);
Surfaces.Push(surf);
}
@ -768,8 +689,8 @@ void DoomLevelSubmesh::CreateBottomWallSurface(FLevel& doomMap, IntSideDef* side
IntSector* front = &doomMap.Sectors[side->sector];
IntSector* back = (side->line->frontsector == front) ? side->line->backsector : side->line->frontsector;
FVector2 v1 = ToFVector2(side->V1()->fPos());
FVector2 v2 = ToFVector2(side->V2()->fPos());
FVector2 v1 = side->V1(doomMap);
FVector2 v2 = side->V2(doomMap);
float v1Bottom = (float)front->floorplane.ZatPoint(v1);
float v2Bottom = (float)front->floorplane.ZatPoint(v2);
@ -799,17 +720,17 @@ void DoomLevelSubmesh::CreateBottomWallSurface(FLevel& doomMap, IntSideDef* side
surf.Type = ST_LOWERSIDE;
surf.TypeIndex = side->Index(doomMap);
surf.bSky = false;
surf.sampleDimension = side->textures[ETexpart::Bottom].LightmapSampleDistance;
surf.sampleDimension = side->GetSampleDistance(WallPart::BOTTOM);
surf.ControlSector = nullptr;
surf.sectorGroup = sectorGroup[front->Index(doomMap)];
surf.texture = side->textures[ETexpart::Bottom].texture;
surf.texture = side->GetTexture(WallPart::BOTTOM);
SetSideTextureUVs(surf, side, ETexpart::Bottom, v1BottomBack, v1Bottom, v2BottomBack, v2Bottom);
SetSideTextureUVs(surf, side, WallPart::BOTTOM, v1BottomBack, v1Bottom, v2BottomBack, v2Bottom);
Surfaces.Push(surf);
}
void DoomLevelSubmesh::SetSideTextureUVs(DoomLevelMeshSurface& surface, IntSideDef* side, ETexpart texpart, float v1TopZ, float v1BottomZ, float v2TopZ, float v2BottomZ)
void DoomLevelSubmesh::SetSideTextureUVs(DoomLevelMeshSurface& surface, IntSideDef* side, WallPart texpart, float v1TopZ, float v1BottomZ, float v2TopZ, float v2BottomZ)
{
MeshVertexUVs.Reserve(4);
FVector2* uvs = &MeshVertexUVs[surface.startVertIndex];
@ -831,8 +752,8 @@ void DoomLevelSubmesh::SetSideTextureUVs(DoomLevelMeshSurface& surface, IntSideD
uvs[3].X = endU;
// To do: the ceiling version is apparently used in some situation related to 3d floors (rover->top.isceiling)
//float offset = tci.RowOffset((float)side->GetTextureYOffset(texpart)) + tci.RowOffset((float)side->GetTextureYOffset(texpart)) + (float)side->sector->GetPlaneTexZ(IntSector::ceiling);
float offset = tci.RowOffset((float)side->GetTextureYOffset(texpart)) + tci.RowOffset((float)side->GetTextureYOffset(texpart)) + (float)side->sector->GetPlaneTexZ(IntSector::floor);
//float offset = tci.RowOffset((float)side->GetTextureYOffset(texpart)) + tci.RowOffset((float)side->GetTextureYOffset(texpart)) + (float)side->sector->GetPlaneTexZ(PLANE_CEILING);
float offset = tci.RowOffset((float)side->GetTextureYOffset(texpart)) + tci.RowOffset((float)side->GetTextureYOffset(texpart)) + (float)side->sector->GetPlaneTexZ(PLANE_FLOOR);
uvs[0].Y = tci.FloatToTexV(offset - v1BottomZ);
uvs[1].Y = tci.FloatToTexV(offset - v2BottomZ);
@ -858,7 +779,7 @@ void DoomLevelSubmesh::CreateFloorSurface(FLevel& doomMap, MapSubsectorEx* sub,
if (!controlSector)
{
plane = sector->floorplane;
surf.bSky = IsSkySector(sector, IntSector::floor);
surf.bSky = IsSkySector(sector, PLANE_FLOOR);
}
else
{
@ -869,12 +790,13 @@ void DoomLevelSubmesh::CreateFloorSurface(FLevel& doomMap, MapSubsectorEx* sub,
surf.numVerts = sub->numlines;
surf.startVertIndex = MeshVertices.Size();
surf.texture = (controlSector ? controlSector : sector)->planes[IntSector::floor].Texture;
surf.texture = (controlSector ? controlSector : sector)->GetTexture(PLANE_FLOOR);
FGameTexture* txt = TexMan.GetGameTexture(surf.texture);
float w = txt->GetDisplayWidth();
float h = txt->GetDisplayHeight();
VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, IntSector::floor);
//VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, PLANE_FLOOR);
VSMatrix mat; mat.loadIdentity();
MeshVertices.Resize(surf.startVertIndex + surf.numVerts);
MeshVertexUVs.Resize(surf.startVertIndex + surf.numVerts);
@ -885,7 +807,8 @@ void DoomLevelSubmesh::CreateFloorSurface(FLevel& doomMap, MapSubsectorEx* sub,
for (int j = 0; j < surf.numVerts; j++)
{
MapSegGLEx* seg = &doomMap.GLSegs[sub->firstline + (surf.numVerts - 1) - j];
FVector2 v1 = ToFVector2(seg->v1->fPos());
auto v = doomMap.GetSegVertex(seg->v1);
FVector2 v1(v.x, v.y);
verts[j].X = v1.X;
verts[j].Y = v1.Y;
@ -896,9 +819,9 @@ void DoomLevelSubmesh::CreateFloorSurface(FLevel& doomMap, MapSubsectorEx* sub,
surf.Type = ST_FLOOR;
surf.TypeIndex = typeIndex;
surf.sampleDimension = (controlSector ? controlSector : sector)->planes[IntSector::floor].LightmapSampleDistance;
surf.sampleDimension = (controlSector ? controlSector : sector)->sampleDistanceFloor;
surf.ControlSector = controlSector;
surf.plane = FVector4((float)plane.Normal().X, (float)plane.Normal().Y, (float)plane.Normal().Z, -(float)plane.D);
surf.plane = FVector4((float)plane.Normal().X, (float)plane.Normal().Y, (float)plane.Normal().Z, -(float)plane.d);
surf.sectorGroup = sectorGroup[sector->Index(doomMap)];
Surfaces.Push(surf);
@ -913,7 +836,7 @@ void DoomLevelSubmesh::CreateCeilingSurface(FLevel& doomMap, MapSubsectorEx* sub
if (!controlSector)
{
plane = sector->ceilingplane;
surf.bSky = IsSkySector(sector, IntSector::ceiling);
surf.bSky = IsSkySector(sector, PLANE_CEILING);
}
else
{
@ -924,12 +847,13 @@ void DoomLevelSubmesh::CreateCeilingSurface(FLevel& doomMap, MapSubsectorEx* sub
surf.numVerts = sub->numlines;
surf.startVertIndex = MeshVertices.Size();
surf.texture = (controlSector ? controlSector : sector)->planes[IntSector::ceiling].Texture;
surf.texture = (controlSector ? controlSector : sector)->GetTexture(PLANE_CEILING);
FGameTexture* txt = TexMan.GetGameTexture(surf.texture);
float w = txt->GetDisplayWidth();
float h = txt->GetDisplayHeight();
VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, IntSector::ceiling);
//VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, PLANE_CEILING);
VSMatrix mat; mat.loadIdentity();
MeshVertices.Resize(surf.startVertIndex + surf.numVerts);
MeshVertexUVs.Resize(surf.startVertIndex + surf.numVerts);
@ -940,7 +864,8 @@ void DoomLevelSubmesh::CreateCeilingSurface(FLevel& doomMap, MapSubsectorEx* sub
for (int j = 0; j < surf.numVerts; j++)
{
MapSegGLEx* seg = &doomMap.GLSegs[sub->firstline + j];
FVector2 v1 = ToFVector2(seg->v1->fPos());
auto v = doomMap.GetSegVertex(seg->v1);
FVector2 v1 = FVector2(v.x, v.y);
verts[j].X = v1.X;
verts[j].Y = v1.Y;
@ -951,7 +876,7 @@ void DoomLevelSubmesh::CreateCeilingSurface(FLevel& doomMap, MapSubsectorEx* sub
surf.Type = ST_CEILING;
surf.TypeIndex = typeIndex;
surf.sampleDimension = (controlSector ? controlSector : sector)->planes[IntSector::ceiling].LightmapSampleDistance;
surf.sampleDimension = (controlSector ? controlSector : sector)->sampleDistanceCeiling;
surf.ControlSector = controlSector;
surf.plane = FVector4((float)plane.Normal().X, (float)plane.Normal().Y, (float)plane.Normal().Z, -(float)plane.d);
surf.sectorGroup = sectorGroup[sector->Index(doomMap)];
@ -961,7 +886,7 @@ void DoomLevelSubmesh::CreateCeilingSurface(FLevel& doomMap, MapSubsectorEx* sub
void DoomLevelSubmesh::CreateSubsectorSurfaces(FLevel& doomMap)
{
for (unsigned int i = 0; i < doomMap.NumGLSubsectors; i++)
for (int i = 0; i < doomMap.NumGLSubsectors; i++)
{
MapSubsectorEx* sub = &doomMap.GLSubsectors[i];
@ -970,7 +895,7 @@ void DoomLevelSubmesh::CreateSubsectorSurfaces(FLevel& doomMap)
continue;
}
IntSector* sector = sub->sector;
IntSector* sector = sub->GetSector(doomMap);
if (!sector)
continue;
@ -979,37 +904,35 @@ void DoomLevelSubmesh::CreateSubsectorSurfaces(FLevel& doomMap)
for (unsigned int j = 0; j < sector->x3dfloors.Size(); j++)
{
CreateFloorSurface(doomMap, sub, sector, sector->x3dfloors[j]->model, i);
CreateCeilingSurface(doomMap, sub, sector, sector->x3dfloors[j]->model, i);
CreateFloorSurface(doomMap, sub, sector, sector->x3dfloors[j], i);
CreateCeilingSurface(doomMap, sub, sector, sector->x3dfloors[j], i);
}
}
}
bool DoomLevelSubmesh::IsTopSideSky(IntSector* frontsector, IntSector* backsector, IntSideDef* side)
{
return IsSkySector(frontsector, IntSector::ceiling) && IsSkySector(backsector, IntSector::ceiling);
return IsSkySector(frontsector, PLANE_CEILING) && IsSkySector(backsector, PLANE_CEILING);
}
bool DoomLevelSubmesh::IsTopSideVisible(IntSideDef* side)
{
auto tex = TexMan.GetGameTexture(side->GetTexture(ETexpart::Top), true);
auto tex = TexMan.GetGameTexture(side->GetTexture(WallPart::TOP), true);
return tex && tex->isValid();
}
bool DoomLevelSubmesh::IsBottomSideVisible(IntSideDef* side)
{
auto tex = TexMan.GetGameTexture(side->GetTexture(ETexpart::Bottom), true);
auto tex = TexMan.GetGameTexture(side->GetTexture(WallPart::BOTTOM), true);
return tex && tex->isValid();
}
bool DoomLevelSubmesh::IsSkySector(IntSector* sector, int plane)
bool DoomLevelSubmesh::IsSkySector(IntSector* sector, SecPlaneType plane)
{
// plane is either IntSector::ceiling or IntSector::floor
return sector->GetTexture(plane) == skyflatnum;
// plane is either PLANE_CEILING or PLANE_FLOOR
return plane == PLANE_CEILING ? sector->skyCeiling : sector->skyFloor; //return sector->GetTexture(plane) == skyflatnum;
}
#endif
bool DoomLevelSubmesh::IsDegenerate(const FVector3& v0, const FVector3& v1, const FVector3& v2)
{
// A degenerate triangle has a zero cross product for two of its sides.

View file

@ -28,13 +28,6 @@ enum DoomLevelMeshSurfaceType
ST_FLOOR
};
enum class ETexpart
{
Mid,
Top,
Bottom
};
struct DoomLevelMeshSurface : public LevelMeshSurface
{
DoomLevelMeshSurfaceType Type = ST_UNKNOWN;
@ -82,10 +75,7 @@ private:
void CreateMidWallSurface(FLevel& doomMap, IntSideDef* side);
void CreateBottomWallSurface(FLevel& doomMap, IntSideDef* side);
void Create3DFloorWallSurfaces(FLevel& doomMap, IntSideDef* side);
void SetSideTextureUVs(DoomLevelMeshSurface& surface, IntSideDef* side, ETexpart texpart, float v1TopZ, float v1BottomZ, float v2TopZ, float v2BottomZ);
void SetSubsectorLightmap(FLevel& doomMap, DoomLevelMeshSurface* surface);
void SetSideLightmap(FLevel& doomMap, DoomLevelMeshSurface* surface);
void SetSideTextureUVs(DoomLevelMeshSurface& surface, IntSideDef* side, WallPart texpart, float v1TopZ, float v1BottomZ, float v2TopZ, float v2BottomZ);
void SetupLightmapUvs(FLevel& doomMap);
@ -94,7 +84,7 @@ private:
static bool IsTopSideSky(IntSector* frontsector, IntSector* backsector, IntSideDef* side);
static bool IsTopSideVisible(IntSideDef* side);
static bool IsBottomSideVisible(IntSideDef* side);
static bool IsSkySector(IntSector* sector, int plane);
static bool IsSkySector(IntSector* sector, SecPlaneType plane);
static FVector4 ToPlane(const FVector3& pt1, const FVector3& pt2, const FVector3& pt3)
{