| 41 | out[2 + offset] = (data[n].get(o + 2).toInt() and 255) / 255f |
| 42 | } |
| 43 | |
| 44 | fun buildImage(fn: String, w: Int, h: Int, func: (Float, Float, Float, Vec3) -> Unit) { |
| 45 | |
| 46 | val o = ByteBuffer.allocateDirect(3 * w * h).order(ByteOrder.nativeOrder()) |
| 47 | |
| 48 | val b = object : ThreadLocal<FloatArray>() { |
| 49 | override fun initialValue(): FloatArray { |
| 50 | return FloatArray(24) |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | val pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 2) |
| 55 | |
| 56 | for (y in 0 until h) { |
| 57 | pool.submit { |
| 58 | print("$y / $h ") |
| 59 | val oo = b.get() |
| 60 | val a = Vec3() |
| 61 | try { |
| 62 | for (x in 0 until w) { |
| 63 | |
| 64 | func(x / w.toFloat(), y / h.toFloat(), 0.5f, a) |
| 65 | accessI(a.x.toFloat(), a.y.toFloat(), a.z.toFloat(), oo) |
| 66 | |
| 67 | o.put(3 * y * w + 3 * x + 0, (Math.max(0f, Math.min(1f, oo[0])) * 255).toInt().toByte()) |
| 68 | o.put(3 * y * w + 3 * x + 1, (Math.max(0f, Math.min(1f, oo[1])) * 255).toInt().toByte()) |
| 69 | o.put(3 * y * w + 3 * x + 2, (Math.max(0f, Math.min(1f, oo[2])) * 255).toInt().toByte()) |
| 70 | |
| 71 | } |
| 72 | } catch (e: Exception) { |
| 73 | e.printStackTrace() |
| 74 | } |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | pool.shutdown() |
| 79 | pool.awaitTermination(1, TimeUnit.HOURS) |
| 80 | |
| 81 | FastJPEG().compress(fn, o, w, h) |
| 82 | } |
| 83 | |
| 84 | |