mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-24 21:01:15 +00:00
Implement sector groups
This commit is contained in:
parent
cb9416269e
commit
0a9c2cf131
5 changed files with 95 additions and 25 deletions
|
@ -70,6 +70,8 @@ struct IntSideDef
|
|||
inline int GetSampleDistanceBottom() const { return sampleDistanceBottom ? sampleDistanceBottom : sampleDistance; }
|
||||
|
||||
TArray<UDMFKey> props;
|
||||
|
||||
inline int GetSectorGroup() const;
|
||||
};
|
||||
|
||||
struct MapLineDef
|
||||
|
@ -107,6 +109,8 @@ struct IntLineDef
|
|||
TArray<int> ids;
|
||||
|
||||
IntSector *frontsector = nullptr, *backsector = nullptr;
|
||||
|
||||
inline int GetSectorGroup() const;
|
||||
};
|
||||
|
||||
struct MapSector
|
||||
|
@ -158,6 +162,8 @@ struct IntSector
|
|||
TArray<IntLineDef*> lines;
|
||||
TArray<IntLineDef*> portals;
|
||||
|
||||
int group = 0;
|
||||
|
||||
// Utility functions
|
||||
inline const char* GetTextureName(int plane) const { return plane != PLANE_FLOOR ? data.ceilingpic : data.floorpic; }
|
||||
|
||||
|
@ -173,6 +179,16 @@ struct IntSector
|
|||
}
|
||||
};
|
||||
|
||||
inline int IntLineDef::GetSectorGroup() const
|
||||
{
|
||||
return frontsector ? frontsector->group : (backsector ? backsector->group : 0);
|
||||
}
|
||||
|
||||
inline int IntSideDef::GetSectorGroup() const
|
||||
{
|
||||
return line ? line->GetSectorGroup() : 0;
|
||||
}
|
||||
|
||||
struct MapSubsector
|
||||
{
|
||||
uint16_t numlines;
|
||||
|
@ -329,7 +345,9 @@ struct ThingLight
|
|||
IntSector *sector;
|
||||
MapSubsectorEx *ssect;
|
||||
|
||||
// Portal related functionality
|
||||
vec3 relativePosition = vec3(0);
|
||||
int sectorGroup = 0;
|
||||
|
||||
// Portal aware position
|
||||
vec3 LightRelativeOrigin() const
|
||||
|
|
|
@ -691,6 +691,41 @@ void FLevel::PostLoadInitialization()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Discover islands of sectors
|
||||
{
|
||||
int groupId = 0;
|
||||
std::vector<IntSector*> candidates;
|
||||
|
||||
for (auto& sector : Sectors)
|
||||
{
|
||||
if (!sector.group)
|
||||
{
|
||||
sector.group = ++groupId;
|
||||
candidates.push_back(§or);
|
||||
|
||||
while (!candidates.empty())
|
||||
{
|
||||
auto* sector = candidates[candidates.size() - 1];
|
||||
candidates.pop_back();
|
||||
|
||||
for (const auto& line : sector->lines)
|
||||
{
|
||||
if (line->frontsector && !line->frontsector->group)
|
||||
{
|
||||
line->frontsector->group = groupId;
|
||||
candidates.push_back(line->frontsector);
|
||||
}
|
||||
if (line->backsector && !line->backsector->group)
|
||||
{
|
||||
line->backsector->group = groupId;
|
||||
candidates.push_back(line->backsector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FProcessor::BuildNodes()
|
||||
|
|
|
@ -290,6 +290,7 @@ void FLevel::CreateLights()
|
|||
thingLight.sector = GetSectorFromSubSector(thingLight.ssect);
|
||||
thingLight.origin.x = x;
|
||||
thingLight.origin.y = y;
|
||||
thingLight.sectorGroup = thingLight.sector->group;
|
||||
|
||||
ThingLights.Push(thingLight);
|
||||
}
|
||||
|
|
|
@ -147,7 +147,6 @@ LevelMesh::LevelMesh(FLevel &doomMap, int sampleDistance, int textureSize)
|
|||
|
||||
Collision = std::make_unique<TriangleMeshShape>(MeshVertices.Data(), MeshVertices.Size(), MeshElements.Data(), MeshElements.Size());
|
||||
|
||||
printf("Building light list...\n\n");
|
||||
BuildLightLists(doomMap);
|
||||
/*
|
||||
std::map<int, int> lightStats;
|
||||
|
@ -166,7 +165,8 @@ int depth = 0;
|
|||
|
||||
void LevelMesh::PropagateLight(FLevel& doomMap, ThingLight *light)
|
||||
{
|
||||
if (depth > 4)
|
||||
// Because of sectorGroups, this will unlikely get this deep anyway
|
||||
if (depth > 32)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -180,35 +180,43 @@ void LevelMesh::PropagateLight(FLevel& doomMap, ThingLight *light)
|
|||
{
|
||||
Surface* surface = surfaces[MeshSurfaces[triangleIndex]].get();
|
||||
|
||||
if (surface->portalIndex >= 0)
|
||||
auto surfaceSectorGroup = surface->type == ST_CEILING || surface->type == ST_FLOOR ?
|
||||
doomMap.GetSectorFromSubSector(&doomMap.GLSubsectors[surface->typeIndex])->group : (doomMap.Sides[surface->typeIndex].GetSectorGroup());
|
||||
|
||||
// Reject any surface which isn't physically connected to the sector group in which the light resided
|
||||
if (light->sectorGroup == surfaceSectorGroup)
|
||||
{
|
||||
auto portal = portals[surface->portalIndex].get();
|
||||
if (surface->portalIndex >= 0)
|
||||
{
|
||||
|
||||
if (touchedPortals.insert(*portal).second)
|
||||
{
|
||||
auto fakeLight = std::make_unique<ThingLight>(*light);
|
||||
auto portal = portals[surface->portalIndex].get();
|
||||
|
||||
fakeLight->relativePosition = portal->TransformPosition(light->LightRelativeOrigin());
|
||||
if (touchedPortals.insert(*portal).second)
|
||||
{
|
||||
auto fakeLight = std::make_unique<ThingLight>(*light);
|
||||
|
||||
PropagateLight(doomMap, fakeLight.get());
|
||||
portalsToErase.insert(*portal);
|
||||
portalLights.push_back(std::move(fakeLight));
|
||||
fakeLight->relativePosition = portal->TransformPosition(light->LightRelativeOrigin());
|
||||
fakeLight->sectorGroup = portal->targetSectorGroup;
|
||||
|
||||
PropagateLight(doomMap, fakeLight.get());
|
||||
portalsToErase.insert(*portal);
|
||||
portalLights.push_back(std::move(fakeLight));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add light to the list if it isn't already there
|
||||
bool found = false;
|
||||
for (ThingLight* light2 : surface->LightList)
|
||||
{
|
||||
if (light2 == light)
|
||||
// Add light to the list if it isn't already there
|
||||
bool found = false;
|
||||
for (ThingLight* light2 : surface->LightList)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
if (light2 == light)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
surface->LightList.push_back(light);
|
||||
}
|
||||
if (!found)
|
||||
surface->LightList.push_back(light);
|
||||
|
||||
}
|
||||
|
||||
for (auto& portal : portalsToErase)
|
||||
|
@ -220,10 +228,13 @@ void LevelMesh::PropagateLight(FLevel& doomMap, ThingLight *light)
|
|||
|
||||
void LevelMesh::BuildLightLists(FLevel& doomMap)
|
||||
{
|
||||
for (ThingLight& light : map->ThingLights)
|
||||
for (unsigned i = 0; i < map->ThingLights.Size(); ++i)
|
||||
{
|
||||
PropagateLight(doomMap, &light);
|
||||
printf("Building light lists: %u / %u\r", i, map->ThingLights.Size());
|
||||
PropagateLight(doomMap, &map->ThingLights[i]);
|
||||
}
|
||||
|
||||
printf("Building light lists: %u / %u\n", map->ThingLights.Size(), map->ThingLights.Size());
|
||||
}
|
||||
|
||||
// Determines a lightmap block in which to map to the lightmap texture.
|
||||
|
@ -548,6 +559,8 @@ int LevelMesh::CreateLinePortal(FLevel& doomMap, const IntLineDef& srcLine, cons
|
|||
// printf("Portal translation: %.3f %.3f %.3f\n", translation.x, translation.y, translation.z);
|
||||
|
||||
portal->transformation = mat4::translate(translation);
|
||||
portal->sourceSectorGroup = srcLine.GetSectorGroup();
|
||||
portal->targetSectorGroup = dstLine.GetSectorGroup();
|
||||
}
|
||||
|
||||
portals.push_back(std::move(portal));
|
||||
|
@ -632,6 +645,8 @@ int LevelMesh::CreatePlanePortal(FLevel& doomMap, const IntLineDef& srcLine, con
|
|||
// printf("Portal translation: %.3f %.3f %.3f\n", translation.x, translation.y, translation.z);
|
||||
|
||||
portal->transformation = mat4::translate(translation);
|
||||
portal->sourceSectorGroup = srcLine.GetSectorGroup();
|
||||
portal->targetSectorGroup = dstLine.GetSectorGroup();
|
||||
}
|
||||
|
||||
portals.push_back(std::move(portal));
|
||||
|
|
|
@ -63,6 +63,8 @@ enum SurfaceType
|
|||
struct Portal
|
||||
{
|
||||
mat4 transformation = mat4::identity();
|
||||
int sourceSectorGroup = 0;
|
||||
int targetSectorGroup = 0;
|
||||
|
||||
inline vec3 TransformPosition(const vec3& pos) const
|
||||
{
|
||||
|
@ -99,7 +101,6 @@ struct RejectRecursivePortals
|
|||
{
|
||||
bool operator()(const Portal& a, const Portal& b) const
|
||||
{
|
||||
static_assert(sizeof(Portal) == sizeof(float) * 4 * 4);
|
||||
return !(a.IsInversePortal(b) || a.IsEqualPortal(b)) && std::memcmp(&a.transformation, &b.transformation, sizeof(mat4)) < 0;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue