diff --git a/runelite-api/src/main/java/net/runelite/api/Perspective.java b/runelite-api/src/main/java/net/runelite/api/Perspective.java index c9655f825a..2aa46c04eb 100644 --- a/runelite-api/src/main/java/net/runelite/api/Perspective.java +++ b/runelite-api/src/main/java/net/runelite/api/Perspective.java @@ -494,6 +494,29 @@ public class Perspective return clickBox; } + /** + * Determine if a triangle goes counter clockwise + * + * @return Returns true if the triangle goes counter clockwise and should be culled, otherwise false + */ + private static boolean cullFace(int x1, int y1, int x2, int y2, int x3, int y3) + { + return (y2 - y1) * (x3 - x2) - (x2 - x1) * (y3 - y2) < 0; + } + + /** + * Determine if a given point is off-screen. + * + * @param client + * @param point + * @return + */ + private static boolean isOffscreen(@Nonnull Client client, @Nonnull Point point) + { + return (point.getX() < 0 || point.getX() >= client.getViewportWidth()) + && (point.getY() < 0 || point.getY() >= client.getViewportHeight()); + } + private static Area get2DGeometry( @Nonnull Client client, @Nonnull List triangles, @@ -537,26 +560,42 @@ public class Perspective continue; } + if (cullFace(a.getX(), a.getY(), b.getX(), b.getY(), c.getX(), c.getY())) + { + continue; + } + + if (isOffscreen(client, a) && isOffscreen(client, b) && isOffscreen(client, c)) + { + continue; + } + int minX = Math.min(Math.min(a.getX(), b.getX()), c.getX()); int minY = Math.min(Math.min(a.getY(), b.getY()), c.getY()); // For some reason, this calculation is always 4 pixels short of the actual in-client one - int maxX = Math.max(Math.max(a.getX(), b.getX()), c.getX()) + client.getViewportXOffset(); - int maxY = Math.max(Math.max(a.getY(), b.getY()), c.getY()) + client.getViewportYOffset(); + int maxX = Math.max(Math.max(a.getX(), b.getX()), c.getX()) + 4; + int maxY = Math.max(Math.max(a.getY(), b.getY()), c.getY()) + 4; // ...and the rectangles in the fixed client are shifted 4 pixels right and down if (!client.isResized()) { - minX += 4; - minY += 4; - maxX += 4; - maxY += 4; + minX += client.getViewportXOffset(); + minY += client.getViewportYOffset(); + maxX += client.getViewportXOffset(); + maxY += client.getViewportYOffset(); } Rectangle clickableRect = new Rectangle( minX - radius, minY - radius, maxX - minX + radius, maxY - minY + radius ); + + if (geometry.contains(clickableRect)) + { + continue; + } + geometry.add(new Area(clickableRect)); } diff --git a/runelite-api/src/main/java/net/runelite/api/model/Triangle.java b/runelite-api/src/main/java/net/runelite/api/model/Triangle.java index 39178b1db5..daf59c2489 100644 --- a/runelite-api/src/main/java/net/runelite/api/model/Triangle.java +++ b/runelite-api/src/main/java/net/runelite/api/model/Triangle.java @@ -36,13 +36,6 @@ public class Triangle private final Vertex b; private final Vertex c; - public Triangle(Vertex a, Vertex b, Vertex c) - { - this.a = a; - this.b = b; - this.c = c; - } - /** * Rotates the triangle by the given orientation. * diff --git a/runelite-api/src/main/java/net/runelite/api/model/Vertex.java b/runelite-api/src/main/java/net/runelite/api/model/Vertex.java index af99f157b0..b59a7d7891 100644 --- a/runelite-api/src/main/java/net/runelite/api/model/Vertex.java +++ b/runelite-api/src/main/java/net/runelite/api/model/Vertex.java @@ -37,13 +37,6 @@ public class Vertex private final int y; private final int z; - public Vertex(int x, int y, int z) - { - this.x = x; - this.y = y; - this.z = z; - } - /** * Rotates the triangle by the given orientation. *