mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-22 12:01:09 +00:00
Add support for Sector_SetPortal
This commit is contained in:
parent
4605f06308
commit
e9bf098195
4 changed files with 108 additions and 3 deletions
|
@ -153,11 +153,23 @@ struct IntSector
|
||||||
struct { bool skyFloor, skyCeiling; };
|
struct { bool skyFloor, skyCeiling; };
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const char* GetTextureName(int plane) const { return plane != PLANE_FLOOR ? data.ceilingpic : data.floorpic; }
|
|
||||||
|
|
||||||
TArray<UDMFKey> props;
|
TArray<UDMFKey> props;
|
||||||
|
|
||||||
TArray<IntLineDef*> lines;
|
TArray<IntLineDef*> lines;
|
||||||
|
|
||||||
|
// Utility functions
|
||||||
|
inline const char* GetTextureName(int plane) const { return plane != PLANE_FLOOR ? data.ceilingpic : data.floorpic; }
|
||||||
|
|
||||||
|
inline bool HasTag(int sectorTag) const
|
||||||
|
{
|
||||||
|
if (tags.Size() <= 0 && sectorTag == 0)
|
||||||
|
return true;
|
||||||
|
for (auto tag : tags)
|
||||||
|
{
|
||||||
|
if (tag == sectorTag) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MapSubsector
|
struct MapSubsector
|
||||||
|
|
|
@ -1015,7 +1015,7 @@ std::vector<PortalInfo> GPURaytracer::CreatePortalInfo()
|
||||||
|
|
||||||
for (const auto& surface : mesh->surfaces)
|
for (const auto& surface : mesh->surfaces)
|
||||||
{
|
{
|
||||||
if (surface->portalDestinationIndex >= 0)
|
if (surface->portalIndex >= 0)
|
||||||
{
|
{
|
||||||
PortalInfo info;
|
PortalInfo info;
|
||||||
info.Transformation = mesh->portals[surface->portalIndex]->transformation;
|
info.Transformation = mesh->portals[surface->portalIndex]->transformation;
|
||||||
|
|
|
@ -510,6 +510,92 @@ int LevelMesh::CreateLinePortal(FLevel& doomMap, const IntLineDef& srcLine, cons
|
||||||
return int(portals.size() - 1);
|
return int(portals.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LevelMesh::CheckAndMakePortal(FLevel& doomMap, MapSubsectorEx* sub, IntSector* sector, int typeIndex, int plane)
|
||||||
|
{
|
||||||
|
const auto& lines = doomMap.GetSectorFromSubSector(sub)->lines;
|
||||||
|
|
||||||
|
for (const auto& line : lines)
|
||||||
|
{
|
||||||
|
if (line->special == Sector_SetPortal && line->args[0] && line->args[2] == plane && !line->args[3] && sector->HasTag(line->args[0]))
|
||||||
|
{
|
||||||
|
const IntLineDef* dstLine = nullptr;
|
||||||
|
|
||||||
|
// Find the other portal line
|
||||||
|
for (const auto &targetLine : doomMap.Lines)
|
||||||
|
{
|
||||||
|
if (targetLine.special == Sector_SetPortal && targetLine.args[2] == plane && targetLine.args[3] && line->args[0] == targetLine.args[0])
|
||||||
|
{
|
||||||
|
dstLine = &targetLine;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dstLine)
|
||||||
|
{
|
||||||
|
return CreatePlanePortal(doomMap, *line, *dstLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LevelMesh::CreatePlanePortal(FLevel& doomMap, const IntLineDef& srcLine, const IntLineDef& dstLine)
|
||||||
|
{
|
||||||
|
auto portal = std::make_unique<Portal>();
|
||||||
|
|
||||||
|
// Calculate portal transformation
|
||||||
|
{
|
||||||
|
FloatVertex srcV1 = doomMap.GetSegVertex(srcLine.v1);
|
||||||
|
FloatVertex srcV2 = doomMap.GetSegVertex(srcLine.v2);
|
||||||
|
FloatVertex dstV1 = doomMap.GetSegVertex(dstLine.v1);
|
||||||
|
FloatVertex dstV2 = doomMap.GetSegVertex(dstLine.v2);
|
||||||
|
|
||||||
|
int alignment = srcLine.args[2];
|
||||||
|
|
||||||
|
double srcAZ = 0;
|
||||||
|
double srcBZ = 0;
|
||||||
|
double dstAZ = 0;
|
||||||
|
double dstBZ = 0;
|
||||||
|
|
||||||
|
const auto* srcFront = srcLine.frontsector;
|
||||||
|
const auto* dstFront = dstLine.frontsector;
|
||||||
|
|
||||||
|
if (alignment == 0) // floor
|
||||||
|
{
|
||||||
|
srcAZ = srcFront->floorplane.zAt(srcV1.x, srcV1.y);
|
||||||
|
srcBZ = srcFront->floorplane.zAt(srcV2.x, srcV2.y);
|
||||||
|
dstAZ = dstFront->ceilingplane.zAt(dstV1.x, dstV1.y);
|
||||||
|
dstBZ = dstFront->ceilingplane.zAt(dstV2.x, dstV2.y);
|
||||||
|
}
|
||||||
|
else // ceiling
|
||||||
|
{
|
||||||
|
srcAZ = srcFront->ceilingplane.zAt(srcV1.x, srcV1.y);
|
||||||
|
srcBZ = srcFront->ceilingplane.zAt(srcV2.x, srcV2.y);
|
||||||
|
dstAZ = dstFront->floorplane.zAt(dstV1.x, dstV1.y);
|
||||||
|
dstBZ = dstFront->floorplane.zAt(dstV2.x, dstV2.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
const vec3 vecSrcA = vec3(vec2(srcV1.x, srcV1.y), srcAZ);
|
||||||
|
const vec3 vecSrcB = vec3(vec2(srcV2.x, srcV2.y), srcAZ);
|
||||||
|
const vec3 vecDstA = vec3(vec2(dstV1.x, dstV1.y), dstAZ);
|
||||||
|
const vec3 vecDstB = vec3(vec2(dstV2.x, dstV2.y), dstBZ);
|
||||||
|
|
||||||
|
// Translation
|
||||||
|
vec3 originSrc = (vecSrcB + vecSrcA) * 0.5f;
|
||||||
|
vec3 originDst = (vecDstB + vecDstA) * 0.5f;
|
||||||
|
|
||||||
|
vec3 translation = originDst - originSrc;
|
||||||
|
|
||||||
|
// printf("Portal translation: %.3f %.3f %.3f\n", translation.x, translation.y, translation.z);
|
||||||
|
|
||||||
|
portal->transformation = mat4::translate(translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
portals.push_back(std::move(portal));
|
||||||
|
return int(portals.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side)
|
void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side)
|
||||||
{
|
{
|
||||||
IntSector *front;
|
IntSector *front;
|
||||||
|
@ -585,6 +671,8 @@ void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side)
|
||||||
surf->portalDestinationIndex = destLineIndex;
|
surf->portalDestinationIndex = destLineIndex;
|
||||||
|
|
||||||
surf->portalIndex = CreateLinePortal(doomMap, *side->line, doomMap.Lines[destLineIndex]);
|
surf->portalIndex = CreateLinePortal(doomMap, *side->line, doomMap.Lines[destLineIndex]);
|
||||||
|
|
||||||
|
surfaces.push_back(std::move(surf));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -874,6 +962,7 @@ void LevelMesh::CreateFloorSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSect
|
||||||
if (!is3DFloor)
|
if (!is3DFloor)
|
||||||
{
|
{
|
||||||
surf->plane = sector->floorplane;
|
surf->plane = sector->floorplane;
|
||||||
|
surf->portalIndex = CheckAndMakePortal(doomMap, sub, sector, typeIndex, PLANE_FLOOR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -912,6 +1001,7 @@ void LevelMesh::CreateCeilingSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSe
|
||||||
if (!is3DFloor)
|
if (!is3DFloor)
|
||||||
{
|
{
|
||||||
surf->plane = sector->ceilingplane;
|
surf->plane = sector->ceilingplane;
|
||||||
|
surf->portalIndex = CheckAndMakePortal(doomMap, sub, sector, typeIndex, PLANE_CEILING);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -160,5 +160,8 @@ private:
|
||||||
|
|
||||||
static bool IsDegenerate(const vec3 &v0, const vec3 &v1, const vec3 &v2);
|
static bool IsDegenerate(const vec3 &v0, const vec3 &v1, const vec3 &v2);
|
||||||
|
|
||||||
|
int CheckAndMakePortal(FLevel& doomMap, MapSubsectorEx* sub, IntSector* sector, int typeIndex, int plane);
|
||||||
|
|
||||||
int CreateLinePortal(FLevel &doomMap, const IntLineDef& srcLine, const IntLineDef& dstLine);
|
int CreateLinePortal(FLevel &doomMap, const IntLineDef& srcLine, const IntLineDef& dstLine);
|
||||||
|
int CreatePlanePortal(FLevel &doomMap, const IntLineDef& srcLine, const IntLineDef& dstLine);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue