Skip to content

Commit

Permalink
Made Hover safely movable
Browse files Browse the repository at this point in the history
Problem: maybe we should make it independent on Document
  • Loading branch information
ioan-chera committed Nov 7, 2023
1 parent 7eb7bd0 commit 6c4ada5
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 109 deletions.
178 changes: 71 additions & 107 deletions src/e_hover.cc
Original file line number Diff line number Diff line change
Expand Up @@ -174,134 +174,100 @@ struct opp_test_state_t

};


class fastopp_node_c
void fastopp_node_c::Subdivide()
{
public:
int lo, hi; // coordinate range
int mid;

fastopp_node_c * lo_child = nullptr;
fastopp_node_c * hi_child = nullptr;

std::vector<int> lines;
if (hi - lo <= FASTOPP_DIST)
return;

const Document &doc;
lo_child = std::make_unique<fastopp_node_c>(lo, mid, doc);
hi_child = std::make_unique<fastopp_node_c>(mid, hi, doc);
}

public:
fastopp_node_c(int _low, int _high, const Document &doc) :
lo(_low), hi(_high), mid((_low + _high) / 2), doc(doc)
void fastopp_node_c::AddLine_X(int ld, int x1, int x2)
{
if (lo_child && (x1 > lo_child->lo) &&
(x2 < lo_child->hi))
{
Subdivide();
lo_child->AddLine_X(ld, x1, x2);
return;
}

~fastopp_node_c()
if (hi_child && (x1 > hi_child->lo) &&
(x2 < hi_child->hi))
{
delete lo_child;
delete hi_child;
hi_child->AddLine_X(ld, x1, x2);
return;
}

private:
void Subdivide()
{
if (hi - lo <= FASTOPP_DIST)
return;

lo_child = new fastopp_node_c(lo, mid, doc);
hi_child = new fastopp_node_c(mid, hi, doc);
}
lines.push_back(ld);
}

public:
/* horizontal tree */
void fastopp_node_c::AddLine_X(int ld)
{
const auto &L = doc.linedefs[ld];

void AddLine_X(int ld, int x1, int x2)
{
if (lo_child && (x1 > lo_child->lo) &&
(x2 < lo_child->hi))
{
lo_child->AddLine_X(ld, x1, x2);
return;
}
// can ignore purely vertical lines
if (doc.isVertical(*L))
return;

if (hi_child && (x1 > hi_child->lo) &&
(x2 < hi_child->hi))
{
hi_child->AddLine_X(ld, x1, x2);
return;
}
double x1 = std::min(doc.getStart(*L).x(), doc.getEnd(*L).x());
double x2 = std::max(doc.getStart(*L).x(), doc.getEnd(*L).x());

lines.push_back(ld);
}
AddLine_X(ld, (int)floor(x1), (int)ceil(x2));
}

void AddLine_X(int ld)
void fastopp_node_c::AddLine_Y(int ld, int y1, int y2)
{
if (lo_child && (y1 > lo_child->lo) &&
(y2 < lo_child->hi))
{
const auto &L = doc.linedefs[ld];

// can ignore purely vertical lines
if (doc.isVertical(*L))
return;

double x1 = std::min(doc.getStart(*L).x(), doc.getEnd(*L).x());
double x2 = std::max(doc.getStart(*L).x(), doc.getEnd(*L).x());

AddLine_X(ld, (int)floor(x1), (int)ceil(x2));
lo_child->AddLine_Y(ld, y1, y2);
return;
}

/* vertical tree */

void AddLine_Y(int ld, int y1, int y2)
if (hi_child && (y1 > hi_child->lo) &&
(y2 < hi_child->hi))
{
if (lo_child && (y1 > lo_child->lo) &&
(y2 < lo_child->hi))
{
lo_child->AddLine_Y(ld, y1, y2);
return;
}

if (hi_child && (y1 > hi_child->lo) &&
(y2 < hi_child->hi))
{
hi_child->AddLine_Y(ld, y1, y2);
return;
}

lines.push_back(ld);
hi_child->AddLine_Y(ld, y1, y2);
return;
}

void AddLine_Y(int ld)
{
const auto &L = doc.linedefs[ld];
lines.push_back(ld);
}

// can ignore purely horizonal lines
if (doc.isHorizontal(*L))
return;
void fastopp_node_c::AddLine_Y(int ld)
{
const auto &L = doc.linedefs[ld];

double y1 = std::min(doc.getStart(*L).y(), doc.getEnd(*L).y());
double y2 = std::max(doc.getStart(*L).y(), doc.getEnd(*L).y());
// can ignore purely horizonal lines
if (doc.isHorizontal(*L))
return;

AddLine_Y(ld, (int)floor(y1), (int)ceil(y2));
}
double y1 = std::min(doc.getStart(*L).y(), doc.getEnd(*L).y());
double y2 = std::max(doc.getStart(*L).y(), doc.getEnd(*L).y());

void Process(opp_test_state_t& test, double coord) const
{
for (unsigned int k = 0 ; k < lines.size() ; k++)
test.ProcessLine(lines[k]);
AddLine_Y(ld, (int)floor(y1), (int)ceil(y2));
}

if (! lo_child)
return;
void fastopp_node_c::Process(opp_test_state_t& test, double coord) const
{
for (unsigned int k = 0 ; k < lines.size() ; k++)
test.ProcessLine(lines[k]);

// the AddLine() methods ensure that lines are not added
// into a child bucket unless the end points are completely
// inside it -- and one unit away from the extremes.
//
// hence we never need to recurse down BOTH sides here.
if (! lo_child)
return;

if (coord < (double)mid)
lo_child->Process(test, coord);
else
hi_child->Process(test, coord);
}
};
// the AddLine() methods ensure that lines are not added
// into a child bucket unless the end points are completely
// inside it -- and one unit away from the extremes.
//
// hence we never need to recurse down BOTH sides here.

if (coord < (double)mid)
lo_child->Process(test, coord);
else
hi_child->Process(test, coord);
}

// result: -1 for back, +1 for front, 0 for _exactly_on_ the line
Side PointOnLineSide(double x, double y, double lx1, double ly1, double lx2, double ly2)
Expand Down Expand Up @@ -644,8 +610,8 @@ void Hover::fastOpposite_begin()

inst.CalculateLevelBounds();

m_fastopp_X_tree = new fastopp_node_c(static_cast<int>(inst.Map_bound1.x - 8), static_cast<int>(inst.Map_bound2.x + 8), doc);
m_fastopp_Y_tree = new fastopp_node_c(static_cast<int>(inst.Map_bound1.y - 8), static_cast<int>(inst.Map_bound2.y + 8), doc);
m_fastopp_X_tree.emplace(static_cast<int>(inst.Map_bound1.x - 8), static_cast<int>(inst.Map_bound2.x + 8), doc);
m_fastopp_Y_tree.emplace(static_cast<int>(inst.Map_bound1.y - 8), static_cast<int>(inst.Map_bound2.y + 8), doc);

for(int n = 0; n < doc.numLinedefs(); n++)
{
Expand All @@ -660,10 +626,8 @@ void Hover::fastOpposite_begin()
void Hover::fastOpposite_finish()
{
SYS_ASSERT(m_fastopp_X_tree || m_fastopp_Y_tree);
delete m_fastopp_X_tree;
m_fastopp_X_tree = nullptr;
delete m_fastopp_Y_tree;
m_fastopp_Y_tree = nullptr;
m_fastopp_X_tree.reset();
m_fastopp_Y_tree.reset();
}

//
Expand Down
41 changes: 39 additions & 2 deletions src/e_hover.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "DocumentModule.h"
#include "m_vector.h"
#include "objid.h"
#include "tl/optional.hpp"
#include <vector>

class bitvec_c;
Expand Down Expand Up @@ -59,6 +60,42 @@ Objid getNearestSector(const Document &doc, const v2double_t &pos);
bool isPointOutsideOfMap(const Document &doc, const v2double_t &v);
}

struct opp_test_state_t;
class fastopp_node_c
{
public:
int lo, hi; // coordinate range
int mid;

std::unique_ptr<fastopp_node_c> lo_child;
std::unique_ptr<fastopp_node_c> hi_child;

std::vector<int> lines;

const Document &doc;

public:
fastopp_node_c(int _low, int _high, const Document &doc) :
lo(_low), hi(_high), mid((_low + _high) / 2), doc(doc)
{
Subdivide();
}

private:
void Subdivide();

public:
/* horizontal tree */
void AddLine_X(int ld, int x1, int x2);
void AddLine_X(int ld);

/* vertical tree */
void AddLine_Y(int ld, int y1, int y2);
void AddLine_Y(int ld);

void Process(opp_test_state_t& test, double coord) const;
};

//
// The hover module
//
Expand All @@ -81,8 +118,8 @@ class Hover : public DocumentModule
private:
void findCrossingLines(crossing_state_c &cross, const v2double_t &pos1, int possible_v1, const v2double_t &pos2, int possible_v2) const;

fastopp_node_c *m_fastopp_X_tree = nullptr;
fastopp_node_c *m_fastopp_Y_tree = nullptr;
tl::optional<fastopp_node_c> m_fastopp_X_tree;
tl::optional<fastopp_node_c> m_fastopp_Y_tree;
};

// result: -1 for back, +1 for front, 0 for _exactly_on_ the line
Expand Down

0 comments on commit 6c4ada5

Please sign in to comment.