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 "intvec.h"
|
2021-03-15 18:05:08 +00:00
|
|
|
|
|
|
|
class ClipNode
|
|
|
|
{
|
|
|
|
friend class Clipper;
|
2021-12-30 09:30:21 +00:00
|
|
|
|
2021-03-15 18:05:08 +00:00
|
|
|
ClipNode *prev, *next;
|
2021-04-24 10:08:38 +00:00
|
|
|
int start, end;
|
2021-12-19 17:53:53 +00:00
|
|
|
float topclip, bottomclip;
|
2021-03-15 18:05:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class Clipper
|
|
|
|
{
|
|
|
|
FMemArena nodearena;
|
|
|
|
ClipNode * freelist = nullptr;
|
|
|
|
|
|
|
|
ClipNode * cliphead = nullptr;
|
2022-08-27 09:47:20 +00:00
|
|
|
angle_t 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);
|
2021-12-20 11:49:44 +00:00
|
|
|
void AddWindowRange(int startangle, int endangle, float topclip, float bottomclip, float viewz);
|
2021-04-24 10:08:38 +00:00
|
|
|
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
|
|
|
|
2022-08-27 09:47:20 +00:00
|
|
|
void Clear(angle_t 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-12-19 17:53:53 +00:00
|
|
|
ClipNode * NewRange(int start, int end, float top, float bottom)
|
2021-03-15 18:05:08 +00:00
|
|
|
{
|
|
|
|
ClipNode * c = GetNew();
|
|
|
|
|
|
|
|
c->start = start;
|
|
|
|
c->end = end;
|
2021-12-19 17:53:53 +00:00
|
|
|
c->topclip = top;
|
|
|
|
c->bottomclip = bottom;
|
2021-03-15 18:05:08 +00:00
|
|
|
c->next = c->prev = NULL;
|
|
|
|
return c;
|
|
|
|
}
|
2021-03-22 22:40:25 +00:00
|
|
|
|
2021-12-20 14:34:50 +00:00
|
|
|
void RemoveRange(ClipNode* cn, bool free = true);
|
2021-12-20 11:49:44 +00:00
|
|
|
bool InsertRange(ClipNode* prev, ClipNode* node);
|
2021-12-20 14:34:50 +00:00
|
|
|
bool InsertBlockingRange(ClipNode* prev, ClipNode* node, int start, int end);
|
2021-12-20 11:49:44 +00:00
|
|
|
void SplitRange(ClipNode* node, int start, int end, float topclip, float bottomclip);
|
2021-12-21 08:09:23 +00:00
|
|
|
void ValidateList();
|
2021-12-19 17:53:53 +00:00
|
|
|
|
2021-03-22 22:40:25 +00:00
|
|
|
public:
|
2021-12-30 09:30:21 +00:00
|
|
|
|
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
|
|
|
{
|
2022-08-27 09:47:20 +00:00
|
|
|
visibleStart = a1 - a2;
|
|
|
|
visibleEnd = a1 + a2;
|
2021-03-15 18:05:08 +00:00
|
|
|
}
|
2022-08-27 09:47:20 +00:00
|
|
|
else visibleStart = visibleEnd = 0;
|
2021-03-15 18:05:08 +00:00
|
|
|
}
|
|
|
|
|
2022-08-27 09:47:20 +00:00
|
|
|
void RestrictVisibleRange(angle_t a1, angle_t 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
|
|
|
|
{
|
2022-08-27 09:47:20 +00:00
|
|
|
if (a1 - visibleStart < visibleEnd - visibleStart) visibleStart = a1;
|
|
|
|
if (a2 - visibleStart < visibleEnd - visibleStart) 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
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|