Skip to content

Commit

Permalink
Fixed: Deep water in TNT map 02
Browse files Browse the repository at this point in the history
Link visplanes based on the analysis done by the id Tech 1 map importer.

IssueID #2254
  • Loading branch information
skyjake committed Dec 12, 2019
1 parent dcb9cc7 commit ca6a409
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 35 deletions.
2 changes: 1 addition & 1 deletion doomsday/apps/api/api_mapedit.h
Expand Up @@ -100,7 +100,7 @@ DENG_API_TYPEDEF(MPE)
*/
int (*LineCreate)(int v1, int v2, int frontSector, int backSector, int flags, int archiveIndex);
void (*LineAddSide)(int line, int side, short flags, const char *topMaterial, float topOffsetX, float topOffsetY, float topRed, float topGreen, float topBlue, const char *middleMaterial, float middleOffsetX, float middleOffsetY, float middleRed, float middleGreen, float middleBlue, float middleAlpha, const char *bottomMaterial, float bottomOffsetX, float bottomOffsetY, float bottomRed, float bottomGreen, float bottomBlue, int archiveIndex);
int (*SectorCreate)(float lightlevel, float red, float green, float blue, int archiveIndex);
int (*SectorCreate)(float lightlevel, float red, float green, float blue, int archiveIndex, int visPlaneLinkIndex);
int (*PlaneCreate)(int sector, coord_t height, const char *materialUri, float matOffsetX, float matOffsetY, float r, float g, float b, float a, float normalX, float normalY, float normalZ, int archiveIndex);
int (*PolyobjCreate)(int const *lines, int linecount, int tag, int sequenceType, coord_t originX, coord_t originY, int archiveIndex);
dd_bool (*GameObjProperty)(char const *objName, int idx, char const *propName, valuetype_t type, void *data);
Expand Down
2 changes: 2 additions & 0 deletions doomsday/apps/client/include/client/clientsubsector.h
Expand Up @@ -248,6 +248,8 @@ class ClientSubsector : public Subsector, public ILightSource

//- Visual Planes (mapped) --------------------------------------------------------------

void linkVisPlanes(ClientSubsector &target);

/**
* Returns the total number of @em visual planes in the subsector.
*/
Expand Down
5 changes: 3 additions & 2 deletions doomsday/apps/client/include/world/map.h
Expand Up @@ -945,8 +945,9 @@ class Map : public world::BaseMap
/**
* @see isEditable()
*/
Sector *createSector(de::dfloat lightLevel, de::Vector3f const &lightColor,
de::dint archiveIndex = MapElement::NoIndex);
Sector *createSector(float lightLevel, const de::Vector3f &lightColor,
int archiveIndex = MapElement::NoIndex,
int visPlaneLinkIndex= MapElement::NoIndex);

/**
* Provides a list of all the editable lines in the map.
Expand Down
6 changes: 6 additions & 0 deletions doomsday/apps/client/include/world/sector.h
Expand Up @@ -197,6 +197,10 @@ class Sector : public world::MapElement
*/
Plane *addPlane(de::Vector3f const &normal, de::ddouble height);

void setVisPlaneLink(int sectorArchiveIndex);

int visPlaneLink() const;

//- Subsectors --------------------------------------------------------------------------

typedef std::function<world::Subsector * (QVector<world::ConvexSubspace *> const &)> SubsectorConstructor;
Expand Down Expand Up @@ -233,6 +237,8 @@ class Sector : public world::MapElement
*/
de::dint subsectorCount() const;

world::Subsector &subsector(int index) const;

/**
* Iterate Subsectors of the sector.
*
Expand Down
8 changes: 5 additions & 3 deletions doomsday/apps/client/src/api_mapedit.cpp
Expand Up @@ -194,6 +194,8 @@ dd_bool MPE_End()
if(!editMapInited)
return false;



/*
* Log warnings about any issues we encountered during conversion of
* the basic map data elements.
Expand Down Expand Up @@ -328,12 +330,12 @@ int MPE_PlaneCreate(int sectorIdx, coord_t height, const char *materialUri,
}

#undef MPE_SectorCreate
int MPE_SectorCreate(float lightlevel, float red, float green, float blue,
int archiveIndex)
int MPE_SectorCreate(float lightlevel, float red, float green, float blue, int archiveIndex,
int visPlaneLinkIndex)
{
ERROR_IF_NOT_INITIALIZED();
return editMap->createSector(lightlevel, Vector3f(red, green, blue),
archiveIndex)->indexInMap();
archiveIndex, visPlaneLinkIndex)->indexInMap();
}

#undef MPE_PolyobjCreate
Expand Down
6 changes: 6 additions & 0 deletions doomsday/apps/client/src/client/clientsubsector.cpp
Expand Up @@ -1570,6 +1570,12 @@ bool ClientSubsector::hasSkyCeiling() const
return hasSkyPlane(Sector::Ceiling);
}

void ClientSubsector::linkVisPlanes(ClientSubsector &target)
{
d->map(Sector::Floor, &target, true);
d->map(Sector::Ceiling, &target, true);
}

dint ClientSubsector::visPlaneCount() const
{
return sector().planeCount();
Expand Down
29 changes: 22 additions & 7 deletions doomsday/apps/client/src/world/base/map.cpp
Expand Up @@ -3977,25 +3977,19 @@ bool Map::endEditing()
//
// Collate sectors:
DENG2_ASSERT(d->sectors.isEmpty());
#ifdef DENG2_QT_4_7_OR_NEWER
d->sectors.reserve(d->editable.sectors.count());
#endif
d->sectors.append(d->editable.sectors);
d->editable.sectors.clear();

// Collate lines:
DENG2_ASSERT(d->lines.isEmpty());
#ifdef DENG2_QT_4_7_OR_NEWER
d->lines.reserve(d->editable.lines.count());
#endif
d->lines.append(d->editable.lines);
d->editable.lines.clear();

// Collate polyobjs:
DENG2_ASSERT(d->polyobjs.isEmpty());
#ifdef DENG2_QT_4_7_OR_NEWER
d->polyobjs.reserve(d->editable.polyobjs.count());
#endif
while (!d->editable.polyobjs.isEmpty())
{
d->polyobjs.append(d->editable.polyobjs.takeFirst());
Expand Down Expand Up @@ -4047,8 +4041,11 @@ bool Map::endEditing()
}

// Finish sectors.
std::map<int, Sector *> sectorsByArchiveIndex;
for (Sector *sector : d->sectors)
{
sectorsByArchiveIndex[sector->indexInArchive()] = sector;

d->buildSubsectors(*sector);
sector->buildSides();
sector->chainSoundEmitters();
Expand All @@ -4057,6 +4054,22 @@ bool Map::endEditing()
// Finish planes.
for (Sector *sector : d->sectors)
{
#if defined (__CLIENT__)
if (sector->visPlaneLink() != MapElement::NoIndex)
{
if (Sector *target = sectorsByArchiveIndex[sector->visPlaneLink()])
{
// Use the first subsector as the target.
auto &targetSub = target->subsector(0).as<ClientSubsector>();

// Linking is done for each subsector separately. (Necessary, though?)
sector->forAllSubsectors([&targetSub](Subsector &sub) {
sub.as<ClientSubsector>().linkVisPlanes(targetSub);
return LoopContinue;
});
}
}
#endif
sector->forAllPlanes([] (Plane &plane)
{
plane.updateSoundEmitterOrigin();
Expand Down Expand Up @@ -4111,7 +4124,8 @@ Line *Map::createLine(Vertex &v1, Vertex &v2, int flags, Sector *frontSector,
return line;
}

Sector *Map::createSector(dfloat lightLevel, Vector3f const &lightColor, dint archiveIndex)
Sector *Map::createSector(float lightLevel, const Vector3f &lightColor, int archiveIndex,
int visPlaneLinkIndex)
{
if (!d->editingEnabled)
/// @throw EditError Attempted when not editing.
Expand All @@ -4122,6 +4136,7 @@ Sector *Map::createSector(dfloat lightLevel, Vector3f const &lightColor, dint ar

sector->setMap(this);
sector->setIndexInArchive(archiveIndex);
sector->setVisPlaneLink(visPlaneLinkIndex);

/// @todo Don't do this here.
sector->setIndexInMap(d->editable.sectors.count() - 1);
Expand Down
18 changes: 17 additions & 1 deletion doomsday/apps/client/src/world/base/sector.cpp
Expand Up @@ -138,7 +138,7 @@ DENG2_PIMPL(Sector)
QVector<LineSide *> sides; ///< All line sides referencing the sector (not owned).
Subsectors subsectors; ///< Traversable subsectors of the sector.
ThinkerT<SoundEmitter> emitter; ///< Head of the sound emitter chain.

int visPlaneLinkSector = MapElement::NoIndex;
dfloat lightLevel = 0; ///< Ambient light level.
Vector3f lightColor; ///< Ambient light color.

Expand Down Expand Up @@ -339,6 +339,16 @@ Plane *Sector::addPlane(Vector3f const &normal, ddouble height)
return plane;
}

void Sector::setVisPlaneLink(int sectorArchiveIndex)
{
d->visPlaneLinkSector = sectorArchiveIndex;
}

int Sector::visPlaneLink() const
{
return d->visPlaneLinkSector;
}

bool Sector::hasSubsectors() const
{
return !d->subsectors.isEmpty();
Expand All @@ -349,6 +359,12 @@ dint Sector::subsectorCount() const
return d->subsectors.count();
}

Subsector &Sector::subsector(int index) const
{
DENG2_ASSERT(index >= 0 && index < d->subsectors.count());
return *d->subsectors.at(index);
}

LoopResult Sector::forAllSubsectors(const std::function<LoopResult(Subsector &)> &callback) const
{
for (Subsector *subsec : d->subsectors)
Expand Down
43 changes: 23 additions & 20 deletions doomsday/apps/plugins/importidtech1/src/mapimporter.cpp
Expand Up @@ -19,10 +19,6 @@
*/

#include "mapimporter.h"
#include <vector>
#include <list>
#include <set>
#include <QVector>
#include <de/libcore.h>
#include <de/Error>
#include <de/ByteRefArray>
Expand All @@ -32,12 +28,21 @@
#include <de/Vector>
#include "importidtech1.h"

#include <QVector>

#include <vector>
#include <list>
#include <set>
#include <tuple>

using namespace de;

namespace idtech1 {
namespace internal {

/**
* Intersect an unbounded line with a bounded line segment.
*
* @todo This is from libgloom (geomath.h); should not duplicate it here but use
* that one in the future when it is available.
*
Expand Down Expand Up @@ -328,7 +333,7 @@ struct SectorDef : public Id1MapElement
// Internal bookkeeping:
std::set<int> lines;
int hackFlags = 0;
int srContainedBySector = -1; // self-referencing sector contained by a normal sector
int visPlaneLinkSector = -1; // self-referencing sector contained by a normal sector

SectorDef(MapImporter &map) : Id1MapElement(map) {}

Expand Down Expand Up @@ -863,7 +868,7 @@ DENG2_PIMPL(MapImporter)
return sides[line.sides[0]].sector;
}

int vertexMinY(const SectorDef &sector) const
int findMinYVertexIndex(const SectorDef &sector) const
{
double minY = std::numeric_limits<double>::max();
int minYIndex = -1;
Expand Down Expand Up @@ -898,14 +903,13 @@ DENG2_PIMPL(MapImporter)

return {true, t, lineNormal.dot(dir) < 0 ? LineDef::Front : LineDef::Back};
}

return {false, 0.0, LineDef::Front};
}

void locateContainingSector(SectorDef &sector)
{
// Find the topmost vertex.
const Vector2d start = vertices[vertexMinY(sector)].pos;
const Vector2d start = vertices[findMinYVertexIndex(sector)].pos;
const Vector2d end = start - Vector2d(0.001, -1.0);

std::pair<double, int> nearestContainer{std::numeric_limits<double>::max(), -1};
Expand All @@ -926,8 +930,6 @@ DENG2_PIMPL(MapImporter)

if (hit && t > 0.0 && t < nearestContainer.first)
{
qDebug("inters %f, side:%d", t, side);

const int sector = sides[line.sideIndex(side)].sector;
if (sector >= 0 && !sectors[sector].hackFlags)
{
Expand All @@ -939,8 +941,8 @@ DENG2_PIMPL(MapImporter)

if (nearestContainer.second >= 0)
{
sector.srContainedBySector = nearestContainer.second;
qDebug("sector %i contained by %i", indexOf(sector), sector.srContainedBySector);
sector.visPlaneLinkSector = nearestContainer.second;
qDebug("sector %i contained by %i", indexOf(sector), sector.visPlaneLinkSector);
}
}

Expand Down Expand Up @@ -1263,23 +1265,24 @@ DENG2_PIMPL(MapImporter)

DENG2_FOR_EACH(Sectors, i, sectors)
{
dint idx = MPE_SectorCreate(dfloat(i->lightLevel) / 255.0f, 1, 1, 1, i->index);
dint idx = MPE_SectorCreate(
dfloat(i->lightLevel) / 255.0f, 1, 1, 1, i->index, i->visPlaneLinkSector);

MPE_PlaneCreate(idx, i->floorHeight, materials.find(i->floorMaterial).toUtf8(),
0, 0, 1, 1, 1, 1, 0, 0, 1, -1);
MPE_PlaneCreate(idx, i->ceilHeight, materials.find(i->ceilMaterial).toUtf8(),
0, 0, 1, 1, 1, 1, 0, 0, -1, -1);

MPE_GameObjProperty("XSector", idx, "Tag", DDVT_SHORT, &i->tag);
MPE_GameObjProperty("XSector", idx, "Type", DDVT_SHORT, &i->type);
MPE_GameObjProperty("XSector", idx, "Tag", DDVT_SHORT, &i->tag);
MPE_GameObjProperty("XSector", idx, "Type", DDVT_SHORT, &i->type);

if(format == Id1MapRecognizer::Doom64Format)
{
MPE_GameObjProperty("XSector", idx, "Flags", DDVT_SHORT, &i->d64flags);
MPE_GameObjProperty("XSector", idx, "CeilingColor", DDVT_SHORT, &i->d64ceilingColor);
MPE_GameObjProperty("XSector", idx, "FloorColor", DDVT_SHORT, &i->d64floorColor);
MPE_GameObjProperty("XSector", idx, "UnknownColor", DDVT_SHORT, &i->d64unknownColor);
MPE_GameObjProperty("XSector", idx, "WallTopColor", DDVT_SHORT, &i->d64wallTopColor);
MPE_GameObjProperty("XSector", idx, "Flags", DDVT_SHORT, &i->d64flags);
MPE_GameObjProperty("XSector", idx, "CeilingColor", DDVT_SHORT, &i->d64ceilingColor);
MPE_GameObjProperty("XSector", idx, "FloorColor", DDVT_SHORT, &i->d64floorColor);
MPE_GameObjProperty("XSector", idx, "UnknownColor", DDVT_SHORT, &i->d64unknownColor);
MPE_GameObjProperty("XSector", idx, "WallTopColor", DDVT_SHORT, &i->d64wallTopColor);
MPE_GameObjProperty("XSector", idx, "WallBottomColor", DDVT_SHORT, &i->d64wallBottomColor);
}
}
Expand Down
2 changes: 1 addition & 1 deletion doomsday/apps/plugins/importudmf/src/importudmf.cpp
Expand Up @@ -183,7 +183,7 @@ static int importMapHook(int /*hookType*/, int /*parm*/, void *context)

int lightlevel = block.contains("lightlevel")? block["lightlevel"].toInt() : 160;

MPE_SectorCreate(float(lightlevel)/255.f, 1.f, 1.f, 1.f, index);
MPE_SectorCreate(float(lightlevel)/255.f, 1.f, 1.f, 1.f, index, -1);

MPE_PlaneCreate(index,
block["heightfloor"].toDouble(),
Expand Down

0 comments on commit ca6a409

Please sign in to comment.