mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-12-03 17:32:54 +00:00
- pass 'level' as a parameter to AABBTree. Also renamed a few things to make the code easier to read.
This commit is contained in:
parent
a0ce8f2988
commit
3328821a98
5 changed files with 46 additions and 40 deletions
|
@ -27,14 +27,15 @@
|
|||
namespace hwrenderer
|
||||
{
|
||||
|
||||
LevelAABBTree::LevelAABBTree()
|
||||
LevelAABBTree::LevelAABBTree(FLevelLocals *lev)
|
||||
{
|
||||
Level = lev;
|
||||
// Calculate the center of all lines
|
||||
TArray<FVector2> centroids;
|
||||
for (unsigned int i = 0; i < level.lines.Size(); i++)
|
||||
for (unsigned int i = 0; i < Level->lines.Size(); i++)
|
||||
{
|
||||
FVector2 v1 = { (float)level.lines[i].v1->fX(), (float)level.lines[i].v1->fY() };
|
||||
FVector2 v2 = { (float)level.lines[i].v2->fX(), (float)level.lines[i].v2->fY() };
|
||||
FVector2 v1 = { (float)Level->lines[i].v1->fX(), (float)Level->lines[i].v1->fY() };
|
||||
FVector2 v2 = { (float)Level->lines[i].v2->fX(), (float)Level->lines[i].v2->fY() };
|
||||
centroids.Push((v1 + v2) * 0.5f);
|
||||
}
|
||||
|
||||
|
@ -45,7 +46,7 @@ LevelAABBTree::LevelAABBTree()
|
|||
int staticroot = nodes.Size() - 1;
|
||||
|
||||
dynamicStartNode = nodes.Size();
|
||||
dynamicStartLine = lines.Size();
|
||||
dynamicStartLine = treelines.Size();
|
||||
|
||||
// Create the dynamic subtree
|
||||
if (GenerateTree(¢roids[0], true))
|
||||
|
@ -64,11 +65,11 @@ LevelAABBTree::LevelAABBTree()
|
|||
}
|
||||
|
||||
// Add the lines referenced by the leaf nodes
|
||||
lines.Resize(mapLines.Size());
|
||||
treelines.Resize(mapLines.Size());
|
||||
for (unsigned int i = 0; i < mapLines.Size(); i++)
|
||||
{
|
||||
const auto &line = level.lines[mapLines[i]];
|
||||
auto &treeline = lines[i];
|
||||
const auto &line = Level->lines[mapLines[i]];
|
||||
auto &treeline = treelines[i];
|
||||
|
||||
treeline.x = (float)line.v1->fX();
|
||||
treeline.y = (float)line.v1->fY();
|
||||
|
@ -81,11 +82,12 @@ bool LevelAABBTree::GenerateTree(const FVector2 *centroids, bool dynamicsubtree)
|
|||
{
|
||||
// Create a list of level lines we want to add:
|
||||
TArray<int> line_elements;
|
||||
for (unsigned int i = 0; i < level.lines.Size(); i++)
|
||||
auto &maplines = Level->lines;
|
||||
for (unsigned int i = 0; i < maplines.Size(); i++)
|
||||
{
|
||||
if (!level.lines[i].backsector)
|
||||
if (!maplines[i].backsector)
|
||||
{
|
||||
bool isPolyLine = level.lines[i].sidedef[0] && (level.lines[i].sidedef[0]->Flags & WALLF_POLYOBJ);
|
||||
bool isPolyLine = maplines[i].sidedef[0] && (maplines[i].sidedef[0]->Flags & WALLF_POLYOBJ);
|
||||
if (isPolyLine && dynamicsubtree)
|
||||
{
|
||||
line_elements.Push(mapLines.Size());
|
||||
|
@ -116,7 +118,7 @@ bool LevelAABBTree::Update()
|
|||
bool modified = false;
|
||||
for (unsigned int i = dynamicStartLine; i < mapLines.Size(); i++)
|
||||
{
|
||||
const auto &line = level.lines[mapLines[i]];
|
||||
const auto &line = Level->lines[mapLines[i]];
|
||||
|
||||
AABBTreeLine treeline;
|
||||
treeline.x = (float)line.v1->fX();
|
||||
|
@ -124,7 +126,7 @@ bool LevelAABBTree::Update()
|
|||
treeline.dx = (float)line.v2->fX() - treeline.x;
|
||||
treeline.dy = (float)line.v2->fY() - treeline.y;
|
||||
|
||||
if (memcmp(&lines[i], &treeline, sizeof(AABBTreeLine)))
|
||||
if (memcmp(&treelines[i], &treeline, sizeof(AABBTreeLine)))
|
||||
{
|
||||
TArray<int> path = FindNodePath(i, nodes.Size() - 1);
|
||||
if (path.Size())
|
||||
|
@ -151,7 +153,7 @@ bool LevelAABBTree::Update()
|
|||
cur.aabb_bottom = MAX(left.aabb_bottom, right.aabb_bottom);
|
||||
}
|
||||
|
||||
lines[i] = treeline;
|
||||
treelines[i] = treeline;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
@ -163,8 +165,8 @@ 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)
|
||||
if (n.aabb_left > treelines[line].x || n.aabb_right < treelines[line].x ||
|
||||
n.aabb_top > treelines[line].y || n.aabb_bottom < treelines[line].y)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
@ -273,7 +275,7 @@ double LevelAABBTree::IntersectRayLine(const DVector2 &ray_start, const DVector2
|
|||
// This algorithm is homemade - I would not be surprised if there's a much faster method out there.
|
||||
|
||||
const double epsilon = 0.0000001;
|
||||
const AABBTreeLine &line = lines[line_index];
|
||||
const AABBTreeLine &line = treelines[line_index];
|
||||
|
||||
DVector2 raynormal = DVector2(raydelta.Y, -raydelta.X);
|
||||
|
||||
|
@ -303,15 +305,16 @@ int LevelAABBTree::GenerateTreeNode(int *lines, int num_lines, const FVector2 *c
|
|||
// Find bounding box and median of the lines
|
||||
FVector2 median = FVector2(0.0f, 0.0f);
|
||||
FVector2 aabb_min, aabb_max;
|
||||
aabb_min.X = (float)level.lines[mapLines[lines[0]]].v1->fX();
|
||||
aabb_min.Y = (float)level.lines[mapLines[lines[0]]].v1->fY();
|
||||
auto &maplines = Level->lines;
|
||||
aabb_min.X = (float)maplines[mapLines[lines[0]]].v1->fX();
|
||||
aabb_min.Y = (float)maplines[mapLines[lines[0]]].v1->fY();
|
||||
aabb_max = aabb_min;
|
||||
for (int i = 0; i < num_lines; i++)
|
||||
{
|
||||
float x1 = (float)level.lines[mapLines[lines[i]]].v1->fX();
|
||||
float y1 = (float)level.lines[mapLines[lines[i]]].v1->fY();
|
||||
float x2 = (float)level.lines[mapLines[lines[i]]].v2->fX();
|
||||
float y2 = (float)level.lines[mapLines[lines[i]]].v2->fY();
|
||||
float x1 = (float)maplines[mapLines[lines[i]]].v1->fX();
|
||||
float y1 = (float)maplines[mapLines[lines[i]]].v1->fY();
|
||||
float x2 = (float)maplines[mapLines[lines[i]]].v2->fX();
|
||||
float y2 = (float)maplines[mapLines[lines[i]]].v2->fY();
|
||||
|
||||
aabb_min.X = MIN(aabb_min.X, x1);
|
||||
aabb_min.X = MIN(aabb_min.X, x2);
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "tarray.h"
|
||||
#include "vectors.h"
|
||||
|
||||
struct FLevelLocals;
|
||||
|
||||
namespace hwrenderer
|
||||
{
|
||||
|
||||
|
@ -35,12 +37,12 @@ struct AABBTreeLine
|
|||
float dx, dy;
|
||||
};
|
||||
|
||||
// Axis aligned bounding box tree used for ray testing lines.
|
||||
// Axis aligned bounding box tree used for ray testing treelines.
|
||||
class LevelAABBTree
|
||||
{
|
||||
public:
|
||||
// Constructs a tree for the current level
|
||||
LevelAABBTree();
|
||||
LevelAABBTree(FLevelLocals *lev);
|
||||
|
||||
// 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);
|
||||
|
@ -48,14 +50,14 @@ public:
|
|||
bool Update();
|
||||
|
||||
const void *Nodes() const { return nodes.Data(); }
|
||||
const void *Lines() const { return lines.Data(); }
|
||||
const void *Lines() const { return treelines.Data(); }
|
||||
size_t NodesSize() const { return nodes.Size() * sizeof(AABBTreeNode); }
|
||||
size_t LinesSize() const { return lines.Size() * sizeof(AABBTreeLine); }
|
||||
size_t LinesSize() const { return treelines.Size() * sizeof(AABBTreeLine); }
|
||||
|
||||
const void *DynamicNodes() const { return nodes.Data() + dynamicStartNode; }
|
||||
const void *DynamicLines() const { return lines.Data() + dynamicStartLine; }
|
||||
const void *DynamicLines() const { return treelines.Data() + dynamicStartLine; }
|
||||
size_t DynamicNodesSize() const { return (nodes.Size() - dynamicStartNode) * sizeof(AABBTreeNode); }
|
||||
size_t DynamicLinesSize() const { return (lines.Size() - dynamicStartLine) * sizeof(AABBTreeLine); }
|
||||
size_t DynamicLinesSize() const { return (treelines.Size() - dynamicStartLine) * sizeof(AABBTreeLine); }
|
||||
size_t DynamicNodesOffset() const { return dynamicStartNode * sizeof(AABBTreeNode); }
|
||||
size_t DynamicLinesOffset() const { return dynamicStartLine * sizeof(AABBTreeLine); }
|
||||
|
||||
|
@ -69,7 +71,7 @@ private:
|
|||
double IntersectRayLine(const DVector2 &ray_start, const DVector2 &ray_end, int line_index, const DVector2 &raydelta, double rayd, double raydist2);
|
||||
|
||||
// Generate a tree node and its children recursively
|
||||
int GenerateTreeNode(int *lines, int num_lines, const FVector2 *centroids, int *work_buffer);
|
||||
int GenerateTreeNode(int *treelines, int num_lines, const FVector2 *centroids, int *work_buffer);
|
||||
|
||||
TArray<int> FindNodePath(unsigned int line, unsigned int node);
|
||||
|
||||
|
@ -77,12 +79,13 @@ private:
|
|||
TArray<AABBTreeNode> nodes;
|
||||
|
||||
// Line segments for the leaf nodes in the tree.
|
||||
TArray<AABBTreeLine> lines;
|
||||
TArray<AABBTreeLine> treelines;
|
||||
|
||||
int dynamicStartNode = 0;
|
||||
int dynamicStartLine = 0;
|
||||
|
||||
TArray<int> mapLines;
|
||||
FLevelLocals *Level;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -141,23 +141,23 @@ void IShadowMap::CollectLights()
|
|||
}
|
||||
}
|
||||
|
||||
bool IShadowMap::ValidateAABBTree()
|
||||
bool IShadowMap::ValidateAABBTree(FLevelLocals *Level)
|
||||
{
|
||||
// Just comparing the level info is not enough. If two MAPINFO-less levels get played after each other,
|
||||
// they can both refer to the same default level info.
|
||||
if (level.info != mLastLevel && (level.nodes.Size() != mLastNumNodes || level.segs.Size() != mLastNumSegs))
|
||||
if (Level->info != mLastLevel && (Level->nodes.Size() != mLastNumNodes || Level->segs.Size() != mLastNumSegs))
|
||||
{
|
||||
mAABBTree.reset();
|
||||
|
||||
mLastLevel = level.info;
|
||||
mLastNumNodes = level.nodes.Size();
|
||||
mLastNumSegs = level.segs.Size();
|
||||
mLastLevel = Level->info;
|
||||
mLastNumNodes = Level->nodes.Size();
|
||||
mLastNumSegs = Level->segs.Size();
|
||||
}
|
||||
|
||||
if (mAABBTree)
|
||||
return true;
|
||||
|
||||
mAABBTree.reset(new hwrenderer::LevelAABBTree());
|
||||
mAABBTree.reset(new hwrenderer::LevelAABBTree(Level));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ void IShadowMap::UploadLights()
|
|||
|
||||
void IShadowMap::UploadAABBTree()
|
||||
{
|
||||
if (!ValidateAABBTree())
|
||||
if (!ValidateAABBTree(&level))
|
||||
{
|
||||
if (!mNodesBuffer)
|
||||
mNodesBuffer = screen->CreateDataBuffer(2, true);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
struct FDynamicLight;
|
||||
struct level_info_t;
|
||||
class IDataBuffer;
|
||||
struct FLevelLocals;
|
||||
|
||||
class IShadowMap
|
||||
{
|
||||
|
@ -33,7 +34,7 @@ public:
|
|||
|
||||
protected:
|
||||
void CollectLights();
|
||||
bool ValidateAABBTree();
|
||||
bool ValidateAABBTree(FLevelLocals *lev);
|
||||
|
||||
// Upload the AABB-tree to the GPU
|
||||
void UploadAABBTree();
|
||||
|
|
|
@ -117,7 +117,6 @@ static void PlayerLandedOnThing (AActor *mo, AActor *onmobj);
|
|||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
extern int BotWTG;
|
||||
EXTERN_CVAR (Int, cl_rockettrails)
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue