diff --git a/TiledCollisionEditor/TiledCollisionEditor.vcxproj b/TiledCollisionEditor/TiledCollisionEditor.vcxproj
index a5d9096..e7f2814 100644
--- a/TiledCollisionEditor/TiledCollisionEditor.vcxproj
+++ b/TiledCollisionEditor/TiledCollisionEditor.vcxproj
@@ -133,6 +133,10 @@
+
+
+
+
diff --git a/TiledCollisionEditor/TiledCollisionEditor.vcxproj.filters b/TiledCollisionEditor/TiledCollisionEditor.vcxproj.filters
index 45af918..64aac0f 100644
--- a/TiledCollisionEditor/TiledCollisionEditor.vcxproj.filters
+++ b/TiledCollisionEditor/TiledCollisionEditor.vcxproj.filters
@@ -45,6 +45,9 @@
Header Files
+
+ Header Files
+
diff --git a/TiledCollisionEditor/olcPGEX_ViewPort.h b/TiledCollisionEditor/olcPGEX_ViewPort.h
new file mode 100644
index 0000000..de30b71
--- /dev/null
+++ b/TiledCollisionEditor/olcPGEX_ViewPort.h
@@ -0,0 +1,721 @@
+#pragma once
+
+#include "pixelGameEngine.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Declarations
+namespace olc {
+ class ViewPort : public olc::PGEX {
+ public:
+ ViewPort();
+ ViewPort(std::vector vertices, vf2d offset = {0, 0});
+ virtual ~ViewPort();
+ void addPoint(vf2d point);
+ void clear();
+ void drawEdges();
+ void setOffset(vf2d offset);
+
+ static ViewPort rectViewPort(vf2d topLeft,
+ vf2d size,
+ olc::vf2d offset = {0, 0});
+
+ void DrawDecal(const olc::vf2d &pos,
+ olc::Decal *decal,
+ const olc::vf2d &scale = {1.0f, 1.0f},
+ const olc::Pixel &tint = olc::WHITE) const;
+ void DrawPartialDecal(const olc::vf2d &pos,
+ olc::Decal *decal,
+ const olc::vf2d &source_pos,
+ const olc::vf2d &source_size,
+ const olc::vf2d &scale = {1.0f, 1.0f},
+ const olc::Pixel &tint = olc::WHITE) const;
+ void DrawPartialDecal(const vf2d &pos,
+ const vf2d &size,
+ Decal *decal,
+ const vf2d source_pos,
+ const vf2d &source_size,
+ const Pixel &tint = olc::WHITE) const;
+ void DrawExplicitDecal(olc::Decal *decal,
+ const olc::vf2d *pos,
+ const olc::vf2d *uv,
+ const olc::Pixel *col,
+ uint32_t elements = 4) const;
+ void DrawWarpedDecal(Decal *decal,
+ const vf2d (&pos)[4],
+ const Pixel &tint = WHITE) const;
+ void DrawWarpedDecal(Decal *decal,
+ const vf2d *pos,
+ const Pixel &tint = WHITE) const;
+ void DrawWarpedDecal(Decal *decal,
+ const std::array &pos,
+ const Pixel &tint = WHITE) const;
+ void DrawPartialWarpedDecal(Decal *decal,
+ const vf2d (&pos)[4],
+ const vf2d &source_pos,
+ const vf2d &source_size,
+ const Pixel &tint = WHITE) const;
+ void DrawPartialWarpedDecal(Decal *decal,
+ const vf2d *pos,
+ const vf2d &source_pos,
+ const vf2d &source_size,
+ const Pixel &tint = WHITE) const;
+ void DrawPartialWarpedDecal(Decal *decal,
+ const std::array &pos,
+ const vf2d &source_pos,
+ const vf2d &source_size,
+ const Pixel &tint = WHITE) const;
+ void DrawRotatedDecal(const vf2d &pos,
+ Decal *decal,
+ const float fAngle,
+ const vf2d ¢er = {0.0f, 0.0f},
+ const vf2d &scale = {1.0f, 1.0f},
+ const Pixel &tint = WHITE) const;
+ void DrawPartialRotatedDecal(const vf2d &pos,
+ Decal *decal,
+ const float fAngle,
+ const vf2d ¢er,
+ const vf2d &source_pos,
+ const vf2d &source_size,
+ const vf2d &scale = {1.0f, 1.0f},
+ const Pixel &tint = WHITE) const;
+ void DrawRectDecal(const vf2d &pos,
+ const vf2d &size,
+ const Pixel col = WHITE) const;
+ void FillRectDecal(const vf2d &pos,
+ const vf2d &size,
+ const Pixel col = WHITE) const;
+ void GradientFillRectDecal(const vf2d &pos,
+ const vf2d &size,
+ const Pixel colTL,
+ const Pixel colBL,
+ const Pixel colBR,
+ const Pixel colTR) const;
+ void DrawPolygonDecal(Decal *decal,
+ const std::vector &pos,
+ const std::vector &uv,
+ const Pixel tint = WHITE) const;
+ void DrawPolygonDecal(Decal *decal,
+ const std::vector &pos,
+ const std::vector &depth,
+ const std::vector &uv,
+ const Pixel tint = WHITE) const;
+ void DrawPolygonDecal(Decal *decal,
+ const std::vector &pos,
+ const std::vector &uv,
+ const std::vector &tint) const;
+ void DrawLineDecal(const vf2d &pos1,
+ const vf2d &pos2,
+ Pixel p = WHITE) const;
+
+ private:
+ void drawClippedDecal(Decal *decal,
+ const vf2d *points,
+ const vf2d *uvs,
+ const Pixel *col,
+ uint32_t elements = 0) const;
+ void drawClippedPolygonDecal(Decal *decal,
+ const vf2d *points,
+ const vf2d *uvs,
+ const float *depth,
+ const Pixel tint,
+ uint32_t elements = 0) const;
+
+ static bool ccw(vf2d A,vf2d B,vf2d C);
+ static bool intersect(vf2d A,vf2d B,vf2d C,vf2d D);
+ static float lineSegmentIntersect(vf2d lineA,
+ vf2d lineB,
+ vf2d segmentA,
+ vf2d segmentB);
+ static float directionFromLine(vf2d lineA, vf2d lineB, vf2d point);
+
+ std::vector clipVertices;
+ olc::vf2d offset;
+ };
+} // namespace olc
+
+// Definitions
+
+#ifdef OLC_PGEX_VIEWPORT
+#undef OLC_PGEX_VIEWPORT
+
+olc::ViewPort::ViewPort() {
+}
+olc::ViewPort::~ViewPort() {
+}
+
+olc::ViewPort::ViewPort(std::vector vertices, olc::vf2d offset)
+ : clipVertices{vertices},
+ offset{offset} {
+}
+
+void olc::ViewPort::addPoint(vf2d point) {
+ clipVertices.push_back(point);
+}
+
+void olc::ViewPort::clear() {
+ clipVertices.clear();
+}
+
+void olc::ViewPort::drawEdges() {
+ for (auto i = 0u; i < clipVertices.size(); i++) {
+ auto current = clipVertices[i] + offset;
+ auto next = clipVertices[(i + 1) % clipVertices.size()] + offset;
+
+ pge->DrawLineDecal(current, next, olc::RED);
+ }
+}
+
+void olc::ViewPort::setOffset(vf2d offset) {
+ this->offset = offset;
+}
+
+olc::ViewPort
+ olc::ViewPort::rectViewPort(vf2d topLeft, vf2d size, olc::vf2d offset) {
+ return {{
+ topLeft,
+ {topLeft.x, topLeft.y + size.y},
+ topLeft + size,
+ {topLeft.x + size.x, topLeft.y},
+ },
+ offset};
+}
+
+void olc::ViewPort::DrawDecal(const olc::vf2d &pos,
+ olc::Decal *decal,
+ const olc::vf2d &scale,
+ const olc::Pixel &tint) const {
+ std::vector points{
+ pos,
+ {pos.x, pos.y + decal->sprite->height * scale.y},
+ {pos.x + decal->sprite->width * scale.x,
+ pos.y + decal->sprite->height * scale.y},
+ {pos.x + decal->sprite->width * scale.x, pos.y},
+ };
+ DrawWarpedDecal(decal, points.data(), tint);
+}
+
+void olc::ViewPort::DrawPartialDecal(const olc::vf2d &pos,
+ olc::Decal *decal,
+ const olc::vf2d &source_pos,
+ const olc::vf2d &source_size,
+ const olc::vf2d &scale,
+ const olc::Pixel &tint) const {
+ DrawPartialDecal(pos, source_size * scale, decal, source_pos, source_size, tint);
+}
+
+void olc::ViewPort::DrawPartialDecal(const vf2d &pos,
+ const vf2d &size,
+ Decal *decal,
+ const vf2d source_pos,
+ const vf2d &source_size,
+ const Pixel &tint) const {
+ std::vector points{
+ pos,
+ {pos.x, pos.y + size.y},
+ pos + size,
+ {pos.x + size.x, pos.y},
+ };
+ DrawPartialWarpedDecal(decal, points.data(), source_pos, source_size, tint);
+}
+
+void olc::ViewPort::DrawExplicitDecal(olc::Decal *decal,
+ const olc::vf2d *pos,
+ const olc::vf2d *uv,
+ const olc::Pixel *col,
+ uint32_t elements) const {
+ drawClippedDecal(decal, pos, uv, col, elements);
+}
+
+void olc::ViewPort::DrawWarpedDecal(Decal *decal,
+ const vf2d (&pos)[4],
+ const Pixel &tint) const {
+ DrawWarpedDecal(decal, (const vf2d *)pos, tint);
+}
+void olc::ViewPort::DrawWarpedDecal(Decal *decal,
+ const vf2d *pos,
+ const Pixel &tint) const {
+ std::vector w{ 1, 1, 1, 1 };
+ std::vector newPos;
+ newPos.resize(4);
+ std::vector uvs{
+ {0, 0},
+ {0, 1},
+ {1, 1},
+ {1, 0},
+ };
+ std::vector cols{
+ tint,
+ tint,
+ tint,
+ tint,
+ };
+
+ olc::vf2d vInvScreenSize={ 1.0f / pge->GetScreenSize().x, 1.0f / pge->GetScreenSize().y };
+
+ olc::vf2d center;
+ float rd = ((pos[2].x - pos[0].x) * (pos[3].y - pos[1].y) - (pos[3].x - pos[1].x) * (pos[2].y - pos[0].y));
+ if (rd != 0)
+ {
+ rd = 1.0f / rd;
+ float rn = ((pos[3].x - pos[1].x) * (pos[0].y - pos[1].y) - (pos[3].y - pos[1].y) * (pos[0].x - pos[1].x)) * rd;
+ float sn = ((pos[2].x - pos[0].x) * (pos[0].y - pos[1].y) - (pos[2].y - pos[0].y) * (pos[0].x - pos[1].x)) * rd;
+ if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f)) center = pos[0] + rn * (pos[2] - pos[0]);
+ float d[4]; for (int i = 0; i < 4; i++) d[i] = (pos[i] - center).mag();
+ for (int i = 0; i < 4; i++)
+ {
+ float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i + 2) & 3];
+ uvs[i] *= q; w[i] *= q;
+ }
+
+ drawClippedPolygonDecal(decal, pos, uvs.data(), w.data(), tint, 4);
+ }
+}
+void olc::ViewPort::DrawWarpedDecal(Decal *decal,
+ const std::array &pos,
+ const Pixel &tint) const {
+ DrawWarpedDecal(decal, pos.data(), tint);
+}
+
+void olc::ViewPort::DrawPartialWarpedDecal(Decal *decal,
+ const vf2d (&pos)[4],
+ const vf2d &source_pos,
+ const vf2d &source_size,
+ const Pixel &tint) const {
+ DrawPartialWarpedDecal(decal,
+ (const vf2d *)pos,
+ source_pos,
+ source_size,
+ tint);
+}
+
+void olc::ViewPort::DrawPartialWarpedDecal(Decal *decal,
+ const vf2d *pos,
+ const vf2d &source_pos,
+ const vf2d &source_size,
+ const Pixel &tint) const {
+ olc::vf2d sourceUvPos =
+ source_pos
+ / olc::vf2d{static_cast(decal->sprite->width),
+ static_cast(decal->sprite->height)};
+ olc::vf2d sourceUvSize =
+ source_size
+ / olc::vf2d{static_cast(decal->sprite->width),
+ static_cast(decal->sprite->height)};
+ std::vector uvs{
+ sourceUvPos,
+ {sourceUvPos.x, sourceUvPos.y + sourceUvSize.y},
+ sourceUvPos + sourceUvSize,
+ {sourceUvPos.x + sourceUvSize.x, sourceUvPos.y},
+ };
+ std::vector cols{
+ tint,
+ tint,
+ tint,
+ tint,
+ };
+
+ std::vectorws{1,1,1,1};
+
+ olc::vf2d center;
+ float rd = ((pos[2].x - pos[0].x) * (pos[3].y - pos[1].y) - (pos[3].x - pos[1].x) * (pos[2].y - pos[0].y));
+ if (rd != 0)
+ {
+ rd = 1.0f / rd;
+ float rn = ((pos[3].x - pos[1].x) * (pos[0].y - pos[1].y) - (pos[3].y - pos[1].y) * (pos[0].x - pos[1].x)) * rd;
+ float sn = ((pos[2].x - pos[0].x) * (pos[0].y - pos[1].y) - (pos[2].y - pos[0].y) * (pos[0].x - pos[1].x)) * rd;
+ if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f)) center = pos[0] + rn * (pos[2] - pos[0]);
+ float d[4]; for (int i = 0; i < 4; i++) d[i] = (pos[i] - center).mag();
+ for (int i = 0; i < 4; i++)
+ {
+ float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i + 2) & 3];
+ uvs[i] *= q; ws[i] *= q;
+ }
+
+ drawClippedPolygonDecal(decal, pos, uvs.data(), ws.data(), tint, 4);
+ }
+}
+
+void olc::ViewPort::DrawPartialWarpedDecal(Decal *decal,
+ const std::array &pos,
+ const vf2d &source_pos,
+ const vf2d &source_size,
+ const Pixel &tint) const {
+ DrawPartialWarpedDecal(decal, pos.data(), source_pos, source_size, tint);
+}
+
+void olc::ViewPort::DrawRotatedDecal(const vf2d &pos,
+ Decal *decal,
+ const float fAngle,
+ const vf2d ¢er,
+ const vf2d &scale,
+ const Pixel &tint) const {
+ auto sin = std::sin(fAngle);
+ auto cos = std::cos(fAngle);
+
+ std::vector points{
+ -center * scale,
+ olc::vf2d{-center.x, decal->sprite->height - center.y} * scale,
+ olc::vf2d{decal->sprite->width - center.x,
+ decal->sprite->height - center.y}
+ * scale,
+ olc::vf2d{decal->sprite->width - center.x, -center.y} * scale,
+ };
+
+ for (auto i = 0u; i < points.size(); i++) {
+ points[i] = pos
+ + olc::vf2d{points[i].x * cos - points[i].y * sin,
+ points[i].x * sin + points[i].y * cos};
+ }
+
+ DrawWarpedDecal(decal, points.data(), tint);
+}
+
+void olc::ViewPort::DrawPartialRotatedDecal(const vf2d &pos,
+ Decal *decal,
+ const float fAngle,
+ const vf2d ¢er,
+ const vf2d &source_pos,
+ const vf2d &source_size,
+ const vf2d &scale,
+ const Pixel &tint) const {
+ auto sin = std::sin(fAngle);
+ auto cos = std::cos(fAngle);
+
+ std::vector points{
+ -center * scale,
+ olc::vf2d{-center.x, source_size.y - center.y} * scale,
+ (source_size - center) * scale,
+ olc::vf2d{source_size.x - center.x, -center.y} * scale,
+ };
+
+ for (auto i = 0u; i < points.size(); i++) {
+ points[i] = pos
+ + olc::vf2d{points[i].x * cos - points[i].y * sin,
+ points[i].x * sin + points[i].y * cos};
+ }
+
+ DrawPartialWarpedDecal(decal, points.data(), source_pos, source_size, tint);
+}
+
+void olc::ViewPort::DrawRectDecal(const vf2d &pos,
+ const vf2d &size,
+ const Pixel col) const {
+ std::vector points{
+ pos,
+ {pos.x, pos.y + size.y},
+ pos + size,
+ {pos.x + size.x, pos.y},
+ };
+
+ // Ideally we use the wireframe mode just like the PGE,
+ // however we can't save the current decal mode which
+ // can impact some applications so instead we draw 4
+ // lines.
+
+ DrawLineDecal(points[0],points[1],col);
+ DrawLineDecal(points[1],points[2],col);
+ DrawLineDecal(points[2],points[3],col);
+ DrawLineDecal(points[3],points[0],col);
+}
+
+void olc::ViewPort::FillRectDecal(const vf2d &pos,
+ const vf2d &size,
+ const Pixel col) const {
+ std::vector points{
+ pos,
+ {pos.x, pos.y + size.y},
+ pos + size,
+ {pos.x + size.x, pos.y},
+ };
+ std::vector uvs{
+ {0, 0},
+ {0, 1},
+ {1, 1},
+ {1, 0},
+ };
+
+ DrawPolygonDecal(nullptr, points, uvs, col);
+}
+
+void olc::ViewPort::GradientFillRectDecal(const vf2d &pos,
+ const vf2d &size,
+ const Pixel colTL,
+ const Pixel colBL,
+ const Pixel colBR,
+ const Pixel colTR) const {
+ std::vector points{
+ pos,
+ {pos.x, pos.y + size.y},
+ pos + size,
+ {pos.x + size.x, pos.y},
+ };
+
+ std::vector uvs{
+ {0, 0},
+ {0, 1},
+ {1, 1},
+ {1, 0},
+ };
+
+ std::vector colors{
+ colTL,
+ colBL,
+ colBR,
+ colTR,
+ };
+
+ drawClippedDecal(nullptr, points.data(), uvs.data(), colors.data(), points.size());
+}
+
+void olc::ViewPort::DrawPolygonDecal(Decal *decal,
+ const std::vector &pos,
+ const std::vector &uv,
+ const Pixel tint) const {
+ std::vector colors;
+ colors.resize(pos.size());
+ for (auto i = 0u; i < colors.size(); i++) {
+ colors[i] = tint;
+ }
+
+ drawClippedDecal(decal, pos.data(), uv.data(), colors.data(), pos.size());
+}
+
+void olc::ViewPort::DrawPolygonDecal(Decal *decal,
+ const std::vector &pos,
+ const std::vector &depth,
+ const std::vector &uv,
+ const Pixel tint) const {
+ drawClippedPolygonDecal(decal, pos.data(), uv.data(), depth.data(), tint, pos.size());
+}
+
+void olc::ViewPort::DrawPolygonDecal(Decal *decal,
+ const std::vector &pos,
+ const std::vector &uv,
+ const std::vector &tint) const {
+ drawClippedDecal(decal, pos.data(), uv.data(), tint.data(), pos.size());
+}
+
+void olc::ViewPort::DrawLineDecal(const vf2d &pos1,
+ const vf2d &pos2,
+ Pixel p) const {
+ vf2d posA = pos1 + offset;
+ vf2d posB = pos2 + offset;
+
+ for (auto i = 0u; i < clipVertices.size(); i++) {
+ auto clipA = clipVertices[i] + offset;
+ auto clipB = clipVertices[(i + 1) % clipVertices.size()] + offset;
+
+ auto intersection = lineSegmentIntersect(clipA, clipB, posA, posB);
+ if (intersection < 0 || intersection > 1) {
+ continue;
+ }
+
+ auto clipDirection = directionFromLine(clipA, clipB, posA);
+ auto intersectionPoint = posA + (posB - posA) * intersection;
+
+ if (clipDirection >= 0) {
+ posA = intersectionPoint;
+ } else {
+ posB = intersectionPoint;
+ }
+ }
+
+
+ // Inside check. Draw a ray to the edge of the screen and count the times
+ // it intersects. When odd, we are inside a shape, when even we are outside
+ // of it.
+
+ vf2d leftEdgeA = {0.f,posA.y};
+ vf2d leftEdgeB = {0.f,posB.y};
+
+ int leftEdgeIntersectionsA = 0;
+ int leftEdgeIntersectionsB = 0;
+ for (auto i = 0u; i < clipVertices.size(); i++) {
+ auto clipA = clipVertices[i] + offset;
+ auto clipB = clipVertices[(i + 1) % clipVertices.size()] + offset;
+ auto leftEdgeIntersectA = intersect(clipA, clipB, leftEdgeA, posA);
+ auto leftEdgeIntersectB = intersect(clipA, clipB, leftEdgeB, posB);
+
+ if (leftEdgeIntersectA) {
+ leftEdgeIntersectionsA++;
+ }
+ if (leftEdgeIntersectB) {
+ leftEdgeIntersectionsB++;
+ }
+ }
+
+ // If we found an intersection, we are drawing this line.
+ //
+ // Otherwise, if either count is odd, one point is at
+ // least inside the shape, so render it.
+ if (leftEdgeIntersectionsA % 2 == 1 || leftEdgeIntersectionsB % 2 == 1) {
+ pge->DrawLineDecal(posA, posB, p);
+ }
+}
+
+void olc::ViewPort::drawClippedDecal(Decal *decal,
+ const vf2d *points,
+ const vf2d *uvs,
+ const Pixel *col,
+ uint32_t elements) const {
+ std::vector outputList{points, points + elements};
+ std::vector outputUvs{uvs, uvs + elements};
+ std::vector outputCols{col, col + elements};
+
+ for (auto i = 0u; i < clipVertices.size(); i++) {
+ auto clipA = clipVertices[i];
+ auto clipB = clipVertices[(i + 1) % 4];
+
+ auto inputList{outputList};
+ auto inputUvs{outputUvs};
+ auto inputCols{outputCols};
+ outputList.clear();
+ outputUvs.clear();
+ outputCols.clear();
+
+ for (auto i = 0u; i < inputList.size(); i++) {
+ auto polygonA = inputList[i];
+ auto polygonB = inputList[(i + 1) % inputList.size()];
+ auto uvA = inputUvs[i];
+ auto uvB = inputUvs[(i + 1) % inputList.size()];
+ auto colA = inputCols[i];
+ auto colB = inputCols[(i + 1) % inputList.size()];
+
+ auto intersection =
+ lineSegmentIntersect(clipA, clipB, polygonA, polygonB);
+ auto intersectionPoint =
+ polygonA + (polygonB - polygonA) * intersection;
+ auto intersectionUv = uvA + (uvB - uvA) * intersection;
+ auto intersectionCol = PixelLerp(colA, colB, intersection);
+
+ float aDirection = directionFromLine(clipA, clipB, polygonA);
+ float bDirection = directionFromLine(clipA, clipB, polygonB);
+
+ if (bDirection <= 0) {
+ if (aDirection > 0) {
+ outputList.push_back(intersectionPoint);
+ outputUvs.push_back(intersectionUv);
+ outputCols.push_back(intersectionCol);
+ }
+ outputList.push_back(polygonB);
+ outputUvs.push_back(uvB);
+ outputCols.push_back(colB);
+ } else if (aDirection <= 0) {
+ outputList.push_back(intersectionPoint);
+ outputUvs.push_back(intersectionUv);
+ outputCols.push_back(intersectionCol);
+ }
+ }
+ }
+
+ if (outputList.size() == 0) {
+ return;
+ }
+
+ for (auto &point : outputList) {
+ point += offset;
+ }
+
+ pge->DrawExplicitDecal(decal,
+ outputList.data(),
+ outputUvs.data(),
+ outputCols.data(),
+ outputList.size());
+}
+void olc::ViewPort::drawClippedPolygonDecal(Decal *decal,
+ const vf2d *points,
+ const vf2d *uvs,
+ const float *depth,
+ const Pixel tint,
+ uint32_t elements) const {
+ std::vector outputList{points, points + elements};
+ std::vector outputUvs{uvs, uvs + elements};
+ std::vector outputDepths{depth, depth + elements};
+
+ for (auto i = 0u; i < clipVertices.size(); i++) {
+ auto clipA = clipVertices[i];
+ auto clipB = clipVertices[(i + 1) % 4];
+
+ auto inputList{outputList};
+ auto inputUvs{outputUvs};
+ auto inputWs{outputDepths};
+ outputList.clear();
+ outputUvs.clear();
+ outputDepths.clear();
+
+ for (auto i = 0u; i < inputList.size(); i++) {
+ auto polygonA = inputList[i];
+ auto polygonB = inputList[(i + 1) % inputList.size()];
+ auto uvA = inputUvs[i];
+ auto uvB = inputUvs[(i + 1) % inputList.size()];
+ auto Wa = inputWs[i];
+ auto Wb = inputWs[(i + 1) % inputList.size()];
+
+ auto intersection =
+ lineSegmentIntersect(clipA, clipB, polygonA, polygonB);
+ auto intersectionPoint =
+ polygonA + (polygonB - polygonA) * intersection;
+ auto intersectionUv = uvA + (uvB - uvA) * intersection;
+ auto intersectionDepth = Wa + (Wb - Wa) * intersection;
+
+ float aDirection = directionFromLine(clipA, clipB, polygonA);
+ float bDirection = directionFromLine(clipA, clipB, polygonB);
+
+ if (bDirection <= 0) {
+ if (aDirection > 0) {
+ outputList.push_back(intersectionPoint);
+ outputUvs.push_back(intersectionUv);
+ outputDepths.push_back(intersectionDepth);
+ }
+ outputList.push_back(polygonB);
+ outputUvs.push_back(uvB);
+ outputDepths.push_back(Wb);
+ } else if (aDirection <= 0) {
+ outputList.push_back(intersectionPoint);
+ outputUvs.push_back(intersectionUv);
+ outputDepths.push_back(intersectionDepth);
+ }
+ }
+ }
+
+ for (auto &point : outputList) {
+ point += offset;
+ }
+
+ pge->DrawPolygonDecal(decal,
+ outputList,
+ outputDepths,
+ outputUvs,
+ tint);
+}
+
+bool olc::ViewPort::ccw(vf2d A,vf2d B,vf2d C) {
+ return (C.y-A.y) * (B.x-A.x) > (B.y-A.y) * (C.x-A.x);
+}
+
+bool olc::ViewPort::intersect(vf2d A,vf2d B,vf2d C,vf2d D) {
+ return ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D);
+}
+
+float olc::ViewPort::lineSegmentIntersect(vf2d lineA,
+ vf2d lineB,
+ vf2d segmentA,
+ vf2d segmentB) {
+ return ((lineA.x - segmentA.x) * (lineA.y - lineB.y)
+ - (lineA.y - segmentA.y) * (lineA.x - lineB.x))
+ / ((lineA.x - lineB.x) * (segmentA.y - segmentB.y)
+ - (lineA.y - lineB.y) * (segmentA.x - segmentB.x));
+}
+
+float olc::ViewPort::directionFromLine(vf2d lineA, vf2d lineB, vf2d point) {
+ return (lineB.x - lineA.x) * (point.y - lineA.y)
+ - (point.x - lineA.x) * (lineB.y - lineA.y);
+}
+
+#endif
\ No newline at end of file
diff --git a/TiledCollisionEditor/pixelGameEngine.cpp b/TiledCollisionEditor/pixelGameEngine.cpp
index da79b0e..a50f40f 100644
--- a/TiledCollisionEditor/pixelGameEngine.cpp
+++ b/TiledCollisionEditor/pixelGameEngine.cpp
@@ -5,4 +5,6 @@
#define OLC_PGEX_TRANSFORMEDVIEW
#include "olcPGEX_TransformedView.h"
#define OLC_PGEX_QUICKGUI
-#include "olcPGEX_QuickGUI.h"
\ No newline at end of file
+#include "olcPGEX_QuickGUI.h"
+#define OLC_PGEX_VIEWPORT
+#include "olcPGEX_ViewPort.h"
\ No newline at end of file