mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-16 09:21:12 +00:00
173 lines
3.1 KiB
C++
173 lines
3.1 KiB
C++
#ifndef __GL_CLIPPER
|
|
#define __GL_CLIPPER
|
|
|
|
#include "xs_Float.h"
|
|
#include "memarena.h"
|
|
#include "basics.h"
|
|
#include "vectors.h"
|
|
#include "binaryangle.h"
|
|
#include "intvec.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
|
|
vec2_t viewpoint;
|
|
bool blocked = false;
|
|
|
|
bool IsRangeVisible(binangle startangle, binangle endangle);
|
|
void RemoveRange(ClipNode * cn);
|
|
void AddClipRange(binangle startangle, binangle endangle);
|
|
void RemoveClipRange(binangle startangle, binangle endangle);
|
|
|
|
public:
|
|
|
|
Clipper();
|
|
|
|
void Clear();
|
|
static binangle AngleToPseudo(binangle ang);
|
|
|
|
void Free(ClipNode *node)
|
|
{
|
|
node->next = freelist;
|
|
freelist = node;
|
|
}
|
|
|
|
private:
|
|
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 DoRemoveClipRange(angle_t start, angle_t end);
|
|
|
|
public:
|
|
|
|
void SetViewpoint(const vec2_t &vp)
|
|
{
|
|
viewpoint = vp;
|
|
}
|
|
|
|
void SetSilhouette();
|
|
|
|
bool SafeCheckRange(binangle startAngle, binangle endAngle)
|
|
{
|
|
if(startAngle.asbam() > endAngle.asbam())
|
|
{
|
|
return (IsRangeVisible(startAngle, bamang(ANGLE_MAX)) || IsRangeVisible(bamang(0), endAngle));
|
|
}
|
|
|
|
return IsRangeVisible(startAngle, endAngle);
|
|
}
|
|
|
|
void SafeAddClipRange(binangle startangle, binangle endangle)
|
|
{
|
|
if(startangle.asbam() > endangle.asbam())
|
|
{
|
|
// The range has to added in two parts.
|
|
AddClipRange(startangle, bamang(ANGLE_MAX));
|
|
AddClipRange(bamang(0), endangle);
|
|
}
|
|
else
|
|
{
|
|
// Add the range as usual.
|
|
AddClipRange(startangle, endangle);
|
|
}
|
|
}
|
|
|
|
void SafeAddClipRange(const vec2_t& v1, const vec2_t& v2)
|
|
{
|
|
binangle a2 = PointToAngle(v1);
|
|
binangle a1 = PointToAngle(v2);
|
|
SafeAddClipRange(a1,a2);
|
|
}
|
|
|
|
void SafeRemoveClipRange(binangle startangle, binangle endangle)
|
|
{
|
|
if(startangle.asbam() > endangle.asbam())
|
|
{
|
|
// The range has to added in two parts.
|
|
RemoveClipRange(startangle, bamang(ANGLE_MAX));
|
|
RemoveClipRange(bamang(0), endangle);
|
|
}
|
|
else
|
|
{
|
|
// Add the range as usual.
|
|
RemoveClipRange(startangle, endangle);
|
|
}
|
|
}
|
|
|
|
void SetBlocked(bool on)
|
|
{
|
|
blocked = on;
|
|
}
|
|
|
|
bool IsBlocked() const
|
|
{
|
|
return blocked;
|
|
}
|
|
|
|
void DumpClipper();
|
|
|
|
binangle PointToAngle(const vec2_t& pos)
|
|
{
|
|
vec2_t vec = pos - viewpoint;
|
|
#if 0
|
|
|
|
if (vec.x == 0 && vec.y == 0)
|
|
{
|
|
return bamang(0);
|
|
}
|
|
else
|
|
{
|
|
double result = vec.y / double(abs(vec.x) + fabs(vec.y));
|
|
if (vec.x < 0)
|
|
{
|
|
result = 2. - result;
|
|
}
|
|
return bamang(xs_Fix<30>::ToFix(result));
|
|
}
|
|
#else
|
|
return bvectangbam(vec.x, vec.y);
|
|
#endif
|
|
}
|
|
|
|
|
|
};
|
|
|
|
#endif
|