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 f35df0c898..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,6 +560,16 @@ 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()); @@ -557,6 +590,12 @@ public class Perspective minX - radius, minY - radius, maxX - minX + radius, maxY - minY + radius ); + + if (geometry.contains(clickableRect)) + { + continue; + } + geometry.add(new Area(clickableRect)); }