mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 23:01:50 +00:00
- dynamically update polyobj lines
This commit is contained in:
parent
1e741446d7
commit
094ef39d5f
3 changed files with 89 additions and 3 deletions
|
@ -44,6 +44,8 @@ LevelAABBTree::LevelAABBTree()
|
|||
{
|
||||
if (!level.lines[i].backsector)
|
||||
{
|
||||
if (level.lines[i].sidedef[0] && (level.lines[i].sidedef[0]->Flags & WALLF_POLYOBJ))
|
||||
polylines.Push(i);
|
||||
line_elements.Push(i);
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +71,82 @@ LevelAABBTree::LevelAABBTree()
|
|||
}
|
||||
}
|
||||
|
||||
bool LevelAABBTree::Update()
|
||||
{
|
||||
bool modified = false;
|
||||
for (unsigned int ii = 0; ii < polylines.Size(); ii++)
|
||||
{
|
||||
int i = polylines[ii];
|
||||
const auto &line = level.lines[i];
|
||||
|
||||
AABBTreeLine treeline;
|
||||
treeline.x = (float)line.v1->fX();
|
||||
treeline.y = (float)line.v1->fY();
|
||||
treeline.dx = (float)line.v2->fX() - treeline.x;
|
||||
treeline.dy = (float)line.v2->fY() - treeline.y;
|
||||
|
||||
if (memcmp(&lines[i], &treeline, sizeof(AABBTreeLine)))
|
||||
{
|
||||
TArray<int> path = FindNodePath(i, nodes.Size() - 1);
|
||||
if (path.Size())
|
||||
{
|
||||
float x1 = (float)level.lines[i].v1->fX();
|
||||
float y1 = (float)level.lines[i].v1->fY();
|
||||
float x2 = (float)level.lines[i].v2->fX();
|
||||
float y2 = (float)level.lines[i].v2->fY();
|
||||
|
||||
int nodeIndex = path[0];
|
||||
nodes[nodeIndex].aabb_left = MIN(x1, x2);
|
||||
nodes[nodeIndex].aabb_right = MAX(x1, x2);
|
||||
nodes[nodeIndex].aabb_top = MIN(y1, y2);
|
||||
nodes[nodeIndex].aabb_bottom = MAX(y1, y2);
|
||||
|
||||
for (unsigned int j = 1; j < path.Size(); j++)
|
||||
{
|
||||
auto &cur = nodes[path[j]];
|
||||
const auto &left = nodes[cur.left_node];
|
||||
const auto &right = nodes[cur.right_node];
|
||||
cur.aabb_left = MIN(left.aabb_left, right.aabb_left);
|
||||
cur.aabb_top = MIN(left.aabb_top, right.aabb_top);
|
||||
cur.aabb_right = MAX(left.aabb_right, right.aabb_right);
|
||||
cur.aabb_bottom = MAX(left.aabb_bottom, right.aabb_bottom);
|
||||
}
|
||||
|
||||
lines[i] = treeline;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
TArray<int> LevelAABBTree::FindNodePath(unsigned int line, unsigned int node)
|
||||
{
|
||||
const AABBTreeNode &n = nodes[node];
|
||||
|
||||
if (n.aabb_left > lines[line].x || n.aabb_right < lines[line].x ||
|
||||
n.aabb_top > lines[line].y || n.aabb_bottom < lines[line].y)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
TArray<int> path;
|
||||
if (n.line_index == -1)
|
||||
{
|
||||
path = FindNodePath(line, n.left_node);
|
||||
if (path.Size() == 0)
|
||||
path = FindNodePath(line, n.right_node);
|
||||
|
||||
if (path.Size())
|
||||
path.Push(node);
|
||||
}
|
||||
else if (n.line_index == line)
|
||||
{
|
||||
path.Push(node);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
double LevelAABBTree::RayTest(const DVector3 &ray_start, const DVector3 &ray_end)
|
||||
{
|
||||
// Precalculate some of the variables used by the ray/line intersection test
|
||||
|
|
|
@ -51,6 +51,8 @@ public:
|
|||
// Shoot a ray from ray_start to ray_end and return the closest hit as a fractional value between 0 and 1. Returns 1 if no line was hit.
|
||||
double RayTest(const DVector3 &ray_start, const DVector3 &ray_end);
|
||||
|
||||
bool Update();
|
||||
|
||||
private:
|
||||
// Test if a ray overlaps an AABB node or not
|
||||
bool OverlapRayAABB(const DVector2 &ray_start2d, const DVector2 &ray_end2d, const AABBTreeNode &node);
|
||||
|
@ -60,6 +62,10 @@ private:
|
|||
|
||||
// Generate a tree node and its children recursively
|
||||
int GenerateTreeNode(int *lines, int num_lines, const FVector2 *centroids, int *work_buffer);
|
||||
|
||||
TArray<int> FindNodePath(unsigned int line, unsigned int node);
|
||||
|
||||
TArray<int> polylines;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -156,7 +156,7 @@ bool IShadowMap::ValidateAABBTree()
|
|||
}
|
||||
|
||||
if (mAABBTree)
|
||||
return true;
|
||||
return mAABBTree->Update();
|
||||
|
||||
mAABBTree.reset(new hwrenderer::LevelAABBTree());
|
||||
return false;
|
||||
|
@ -197,10 +197,12 @@ void IShadowMap::UploadAABBTree()
|
|||
{
|
||||
if (!ValidateAABBTree())
|
||||
{
|
||||
mNodesBuffer = screen->CreateDataBuffer(2, true);
|
||||
if (!mNodesBuffer)
|
||||
mNodesBuffer = screen->CreateDataBuffer(2, true);
|
||||
mNodesBuffer->SetData(sizeof(hwrenderer::AABBTreeNode) * mAABBTree->nodes.Size(), &mAABBTree->nodes[0]);
|
||||
|
||||
mLinesBuffer = screen->CreateDataBuffer(3, true);
|
||||
if (!mLinesBuffer)
|
||||
mLinesBuffer = screen->CreateDataBuffer(3, true);
|
||||
mLinesBuffer->SetData(sizeof(hwrenderer::AABBTreeLine) * mAABBTree->lines.Size(), &mAABBTree->lines[0]);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue