2021-03-15 18:05:08 +00:00
|
|
|
#ifndef __GL_CLIPPER
|
|
|
|
#define __GL_CLIPPER
|
|
|
|
|
|
|
|
#include "xs_Float.h"
|
|
|
|
#include "memarena.h"
|
|
|
|
#include "basics.h"
|
|
|
|
#include "vectors.h"
|
2021-03-22 22:40:25 +00:00
|
|
|
#include "binaryangle.h"
|
|
|
|
#include "intvec.h"
|
2021-03-15 18:05:08 +00:00
|
|
|
|
|
|
|
class ClipNode
|
|
|
|
{
|
|
|
|
friend class Clipper;
|
|
|
|
|
|
|
|
ClipNode *prev, *next;
|
2021-04-24 10:08:38 +00:00
|
|
|
int start, end;
|
2021-03-15 18:05:08 +00:00
|
|
|
|
|
|
|
bool operator== (const ClipNode &other)
|
|
|
|
{
|
|
|
|
return other.start == start && other.end == end;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class Clipper
|
|
|
|
{
|
|
|
|
FMemArena nodearena;
|
|
|
|
ClipNode * freelist = nullptr;
|
|
|
|
|
|
|
|
ClipNode * clipnodes = nullptr;
|
|
|
|
ClipNode * cliphead = nullptr;
|
2021-03-22 22:40:25 +00:00
|
|
|
vec2_t viewpoint;
|
2021-04-24 10:08:38 +00:00
|
|
|
void RemoveRange(ClipNode* cn);
|
|
|
|
binangle visibleStart, visibleEnd;
|
2021-03-15 18:05:08 +00:00
|
|
|
|
|
|
|
public:
|
2021-04-24 10:08:38 +00:00
|
|
|
bool IsRangeVisible(int startangle, int endangle);
|
|
|
|
void AddClipRange(int startangle, int endangle);
|
|
|
|
void RemoveClipRange(int startangle, int endangle);
|
2021-03-15 18:05:08 +00:00
|
|
|
|
2021-04-24 10:08:38 +00:00
|
|
|
public:
|
2021-03-15 18:05:08 +00:00
|
|
|
|
2021-04-24 10:08:38 +00:00
|
|
|
void Clear(binangle rangestart);
|
2021-03-15 18:05:08 +00:00
|
|
|
|
|
|
|
void Free(ClipNode *node)
|
|
|
|
{
|
|
|
|
node->next = freelist;
|
|
|
|
freelist = node;
|
|
|
|
}
|
|
|
|
|
2021-03-22 22:40:25 +00:00
|
|
|
private:
|
2021-03-15 18:05:08 +00:00
|
|
|
ClipNode * GetNew()
|
|
|
|
{
|
|
|
|
if (freelist)
|
|
|
|
{
|
|
|
|
ClipNode * p = freelist;
|
|
|
|
freelist = p->next;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
else return (ClipNode*)nodearena.Alloc(sizeof(ClipNode));
|
|
|
|
}
|
|
|
|
|
2021-04-24 10:08:38 +00:00
|
|
|
ClipNode * NewRange(int start, int end)
|
2021-03-15 18:05:08 +00:00
|
|
|
{
|
|
|
|
ClipNode * c = GetNew();
|
|
|
|
|
|
|
|
c->start = start;
|
|
|
|
c->end = end;
|
|
|
|
c->next = c->prev = NULL;
|
|
|
|
return c;
|
|
|
|
}
|
2021-03-22 22:40:25 +00:00
|
|
|
|
|
|
|
public:
|
2021-03-15 18:05:08 +00:00
|
|
|
|
2021-03-22 22:40:25 +00:00
|
|
|
void SetViewpoint(const vec2_t &vp)
|
2021-03-15 18:05:08 +00:00
|
|
|
{
|
|
|
|
viewpoint = vp;
|
|
|
|
}
|
|
|
|
|
2021-04-24 10:08:38 +00:00
|
|
|
void SetVisibleRange(angle_t a1, angle_t a2)
|
2021-03-15 18:05:08 +00:00
|
|
|
{
|
2021-04-24 10:08:38 +00:00
|
|
|
if (a2 != 0xffffffff)
|
2021-03-15 18:05:08 +00:00
|
|
|
{
|
2021-04-24 10:08:38 +00:00
|
|
|
visibleStart = bamang(a1 - a2);
|
|
|
|
visibleEnd = bamang(a1 + a2);
|
2021-03-15 18:05:08 +00:00
|
|
|
}
|
2021-04-24 10:08:38 +00:00
|
|
|
else visibleStart = visibleEnd = bamang(0);
|
2021-03-15 18:05:08 +00:00
|
|
|
}
|
|
|
|
|
2021-04-24 10:08:38 +00:00
|
|
|
void RestrictVisibleRange(binangle a1, binangle a2)
|
2021-03-15 18:05:08 +00:00
|
|
|
{
|
2021-04-24 10:08:38 +00:00
|
|
|
if (visibleStart == visibleEnd)
|
2021-03-15 18:05:08 +00:00
|
|
|
{
|
2021-04-24 10:08:38 +00:00
|
|
|
visibleStart = a1;
|
|
|
|
visibleEnd = a2;
|
2021-03-15 18:05:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-04-24 10:08:38 +00:00
|
|
|
if (a1.asbam() - visibleStart.asbam() < visibleEnd.asbam() - visibleStart.asbam()) visibleStart = a1;
|
|
|
|
if (a2.asbam() - visibleStart.asbam() < visibleEnd.asbam() - visibleStart.asbam()) visibleStart = a2;
|
2021-03-15 18:05:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-23 20:23:49 +00:00
|
|
|
void DumpClipper();
|
2021-03-15 18:05:08 +00:00
|
|
|
|
2021-04-10 08:56:11 +00:00
|
|
|
binangle PointToAngle(const vec2_t& pos)
|
|
|
|
{
|
|
|
|
vec2_t vec = pos - viewpoint;
|
|
|
|
return bvectangbam(vec.x, vec.y);
|
|
|
|
}
|
|
|
|
|
2021-03-15 18:05:08 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|