mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 17:01:51 +00:00
b492cbcebb
It renders walls, but y-panning is still broken.
159 lines
3.1 KiB
C++
159 lines
3.1 KiB
C++
#ifndef __GL_CLIPPER
|
|
#define __GL_CLIPPER
|
|
|
|
#include "xs_Float.h"
|
|
#include "memarena.h"
|
|
#include "basics.h"
|
|
#include "vectors.h"
|
|
|
|
class ClipNode
|
|
{
|
|
friend class Clipper;
|
|
|
|
ClipNode *prev, *next;
|
|
angle_t start, end;
|
|
|
|
bool operator== (const ClipNode &other)
|
|
{
|
|
return other.start == start && other.end == end;
|
|
}
|
|
};
|
|
|
|
|
|
class Clipper
|
|
{
|
|
static unsigned starttime;
|
|
FMemArena nodearena;
|
|
ClipNode * freelist = nullptr;
|
|
|
|
ClipNode * clipnodes = nullptr;
|
|
ClipNode * cliphead = nullptr;
|
|
ClipNode * silhouette = nullptr; // will be preserved even when RemoveClipRange is called
|
|
DVector2 viewpoint;
|
|
bool blocked = false;
|
|
|
|
bool IsRangeVisible(angle_t startangle, angle_t endangle);
|
|
void RemoveRange(ClipNode * cn);
|
|
void AddClipRange(angle_t startangle, angle_t endangle);
|
|
void RemoveClipRange(angle_t startangle, angle_t endangle);
|
|
void DoRemoveClipRange(angle_t start, angle_t end);
|
|
|
|
public:
|
|
|
|
Clipper();
|
|
|
|
void Clear();
|
|
static angle_t AngleToPseudo(angle_t ang);
|
|
|
|
void Free(ClipNode *node)
|
|
{
|
|
node->next = freelist;
|
|
freelist = node;
|
|
}
|
|
|
|
ClipNode * GetNew()
|
|
{
|
|
if (freelist)
|
|
{
|
|
ClipNode * p = freelist;
|
|
freelist = p->next;
|
|
return p;
|
|
}
|
|
else return (ClipNode*)nodearena.Alloc(sizeof(ClipNode));
|
|
}
|
|
|
|
ClipNode * NewRange(angle_t start, angle_t end)
|
|
{
|
|
ClipNode * c = GetNew();
|
|
|
|
c->start = start;
|
|
c->end = end;
|
|
c->next = c->prev = NULL;
|
|
return c;
|
|
}
|
|
|
|
void SetViewpoint(const DVector2 &vp)
|
|
{
|
|
viewpoint = vp;
|
|
}
|
|
|
|
void SetSilhouette();
|
|
|
|
bool SafeCheckRange(angle_t startAngle, angle_t endAngle)
|
|
{
|
|
if(startAngle > endAngle)
|
|
{
|
|
return (IsRangeVisible(startAngle, ANGLE_MAX) || IsRangeVisible(0, endAngle));
|
|
}
|
|
|
|
return IsRangeVisible(startAngle, endAngle);
|
|
}
|
|
|
|
void SafeAddClipRange(angle_t startangle, angle_t endangle)
|
|
{
|
|
if(startangle > endangle)
|
|
{
|
|
// The range has to added in two parts.
|
|
AddClipRange(startangle, ANGLE_MAX);
|
|
AddClipRange(0, endangle);
|
|
}
|
|
else
|
|
{
|
|
// Add the range as usual.
|
|
AddClipRange(startangle, endangle);
|
|
}
|
|
}
|
|
|
|
void SafeAddClipRange(const DVector2& v1, const DVector2& v2)
|
|
{
|
|
angle_t a2 = PointToPseudoAngle(v1.X, v1.Y);
|
|
angle_t a1 = PointToPseudoAngle(v2.X, v2.Y);
|
|
SafeAddClipRange(a1,a2);
|
|
}
|
|
|
|
void SafeAddClipRangeRealAngles(angle_t startangle, angle_t endangle)
|
|
{
|
|
SafeAddClipRange(AngleToPseudo(startangle), AngleToPseudo(endangle));
|
|
}
|
|
|
|
|
|
void SafeRemoveClipRange(angle_t startangle, angle_t endangle)
|
|
{
|
|
if(startangle > endangle)
|
|
{
|
|
// The range has to added in two parts.
|
|
RemoveClipRange(startangle, ANGLE_MAX);
|
|
RemoveClipRange(0, endangle);
|
|
}
|
|
else
|
|
{
|
|
// Add the range as usual.
|
|
RemoveClipRange(startangle, endangle);
|
|
}
|
|
}
|
|
|
|
void SafeRemoveClipRangeRealAngles(angle_t startangle, angle_t endangle)
|
|
{
|
|
SafeRemoveClipRange(AngleToPseudo(startangle), AngleToPseudo(endangle));
|
|
}
|
|
|
|
void SetBlocked(bool on)
|
|
{
|
|
blocked = on;
|
|
}
|
|
|
|
bool IsBlocked() const
|
|
{
|
|
return blocked;
|
|
}
|
|
|
|
angle_t PointToPseudoAngle(double x, double y);
|
|
|
|
inline angle_t GetClipAngle(const DVector2& v)
|
|
{
|
|
return PointToPseudoAngle(v.X, v.Y);
|
|
}
|
|
|
|
};
|
|
|
|
#endif
|