package iron.culling; class ContributionCull { public static var minPixelRadius: Float = 2.0; public static var enabled: Bool = false; public static function passes( centerX: Float, centerY: Float, centerZ: Float, radius: Float, camX: Float, camY: Float, camZ: Float, focalLengthPx: Float ): Bool { if (!enabled || minPixelRadius <= 0.0 || focalLengthPx <= 0.0) return true; var dx = centerX - camX; var dy = centerY - camY; var dz = centerZ - camZ; var dist = Math.sqrt(dx * dx + dy * dy + dz * dz); if (dist <= radius) return true; var projectedRadiusPx = focalLengthPx * radius / dist; return projectedRadiusPx >= minPixelRadius; } public static function passesNode( node: BVHNode, camX: Float, camY: Float, camZ: Float, focalLengthPx: Float ): Bool { if (!enabled || minPixelRadius <= 0.0 || focalLengthPx <= 0.0) return true; var cx = (node.minX + node.maxX) * 0.5; var cy = (node.minY + node.maxY) * 0.5; var cz = (node.minZ + node.maxZ) * 0.5; var ex = (node.maxX - node.minX) * 0.5; var ey = (node.maxY - node.minY) * 0.5; var ez = (node.maxZ - node.minZ) * 0.5; var radius = Math.sqrt(ex * ex + ey * ey + ez * ez); if (camX >= node.minX && camX <= node.maxX && camY >= node.minY && camY <= node.maxY && camZ >= node.minZ && camZ <= node.maxZ) { return true; } var dx = cx - camX; var dy = cy - camY; var dz = cz - camZ; var dist = Math.sqrt(dx * dx + dy * dy + dz * dz); if (dist <= radius) return true; var projectedRadiusPx = focalLengthPx * radius / dist; return projectedRadiusPx >= minPixelRadius; } public static function computeFocalLengthPx(fov: Float, screenHeight: Int): Float { return screenHeight / (2.0 * Math.tan(fov * 0.5)); } }