private void aabbCompute() { float minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE; for (final FloatArray polygon : polygons) { float[] vertices = polygon.elements(); for (int vertexIndex = 0, vertexCount = polygon.size(); vertexIndex < vertexCount; vertexIndex += 2) { final float x = vertices[vertexIndex]; final float y = vertices[vertexIndex + 1]; minX = Math.min(minX, x); minY = Math.min(minY, y); maxX = Math.max(maxX, x); maxY = Math.max(maxY, y); } } this.minX = minX; this.minY = minY; this.maxX = maxX; this.maxY = maxY; }
/** Returns true if the polygon contains the line segment. */ public boolean intersectsSegment( @Nonnull final FloatArray polygon, final float x1, final float y1, final float x2, final float y2) { final float[] vertices = polygon.elements(); final int vertexCount = polygon.size(); float width12 = x1 - x2, height12 = y1 - y2; float det1 = x1 * y2 - y1 * x2; float x3 = vertices[vertexCount - 2], y3 = vertices[vertexCount - 1]; for (int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex += 2) { float x4 = vertices[vertexIndex], y4 = vertices[vertexIndex + 1]; float det2 = x3 * y4 - y3 * x4; float width34 = x3 - x4, height34 = y3 - y4; float det3 = width12 * height34 - height12 * width34; float x = (det1 * width34 - width12 * det2) / det3; if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) { float y = (det1 * height34 - height12 * det2) / det3; if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) return true; } x3 = x4; y3 = y4; } return false; }
public void update(Skeleton skeleton, boolean updateAabb) { final Array<BoundingBoxAttachment> boundingBoxes = this.boundingBoxes; final Array<FloatArray> polygons = this.polygons; final Array<Slot> slots = skeleton.slots; boundingBoxes.clear(); polygonPool.retAll(polygons); polygons.clear(); for (final Slot slot : slots) { final Attachment attachment = slot.attachment; if (attachment instanceof BoundingBoxAttachment) { final BoundingBoxAttachment boundingBox = (BoundingBoxAttachment) attachment; boundingBoxes.push(boundingBox); final FloatArray polygon = polygonPool.get(); polygons.push(polygon); final int vertexCount = boundingBox.vertices().length; polygon.size(vertexCount); boundingBox.computeWorldVertices(slot.bone, polygon.elements()); } } if (updateAabb) { aabbCompute(); } }
/** Returns true if the polygon contains the point. */ public boolean containsPoint(@Nonnull final FloatArray polygon, final float x, final float y) { final float[] vertices = polygon.elements(); final int vertexCount = polygon.size(); int prevIndex = vertexCount - 2; boolean inside = false; for (int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex += 2) { final float vertexY = vertices[vertexIndex + 1]; final float prevY = vertices[prevIndex + 1]; if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) { final float vertexX = vertices[vertexIndex]; if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x) { inside = !inside; } } prevIndex = vertexIndex; } return inside; }