Окрашивание отдельных треугольников в TriangleMesh с помощью карты текстур является неточным - PullRequest
1 голос
/ 20 сентября 2019

Проблема, с которой я столкнулся, заключается в том, что я хочу раскрасить сложные модели (+ 4k треугольников), не разбивая модели на множество объектов TriangleMesh.

Насколько я понимаю, это можно сделать только путем сопоставления цветов на изображении, а затем вычисления текстурных координат каждого цветового пикселя на изображении.Что я сделал ниже:

        val uniqueColors = colors.toHashSet()
        val colorTexCoordsMap = HashMap<Color, FloatArray>()

        val atlas = WritableImage(uniqueColors.size, 1)

        for((index, color) in uniqueColors.withIndex()) {
            colorTexCoordsMap[color] = floatArrayOf(index.toDouble().div(uniqueColors.size).toFloat(), 0.5f)
            atlas.pixelWriter.setColor(index, 0, color)
        }

        atlasMaterialProperty.set(PhongMaterial().also {
            it.diffuseMap = atlas
        })

        val out = File("model-${definition.id}-${uniqueColors.size}-atlas.png")
        val bim = SwingFXUtils.fromFXImage(atlas, null)
        ImageIO.write(bim, "png", out)

        for(face in 0 until definition.faceCount){
            val color = colors[face]
            val uv = colorTexCoordsMap[color]!!
            val vertex1 = definition.faceVertexIndices1[face]
            val vertex2 = definition.faceVertexIndices2[face]
            val vertex3 = definition.faceVertexIndices3[face]
            val vx1 = definition.vertexPositionsX[vertex1]
            val vy1 = definition.vertexPositionsY[vertex1]
            val vz1 = definition.vertexPositionsZ[vertex1]
            val vx2 = definition.vertexPositionsX[vertex2]
            val vy2 = definition.vertexPositionsY[vertex2]
            val vz2 = definition.vertexPositionsZ[vertex2]
            val vx3 = definition.vertexPositionsX[vertex3]
            val vy3 = definition.vertexPositionsY[vertex3]
            val vz3 = definition.vertexPositionsZ[vertex3]
            val vertex1Index = cacheVertex(vertex1, vx1, vy1, vz1)
            val vertex2Index = cacheVertex(vertex2, vx2, vy2, vz2)
            val vertex3Index = cacheVertex(vertex3, vx3, vy3, vz3)
            val texIndex = cacheUV(uv[0], uv[1])

            faces.addAll(
                vertex1Index, texIndex,
                vertex2Index, texIndex,
                vertex3Index, texIndex
            )
            faceSmoothingGroups.addAll(0)
        }

Я ожидал, что цвета будут отображаться точно, но это не так.Я думаю, что это связано с тем, что часть деления не очень точная, и поэтому в моделях, которые используют много цветов, иногда уф-координата больше не отображается на предполагаемый цвет в сгенерированном изображении.

В текущем коде генерируется изображение с высотой = 1 и шириной = цвет_счетом.Таким образом, каждое значение x представляет индекс цвета.Я также попытался сгенерировать больше прямоугольных палитр, чтобы уменьшить количество делений, это помогло в некоторых случаях, но не в других, в зависимости от того, сколько цветов присутствует в модели.

Редактировать: заставил работать со следующимикод:

        for((index, color) in uniqueColors.withIndex()) {
            val u = (index.toDouble() / uniqueColors.size + (1.0 / uniqueColors.size / 2.0)).toFloat()
            val v = 0.5f
            val texIndex = cacheUV(u, v)
            colorTexCoordsMap[color] = texIndex
            atlas.pixelWriter.setColor(index, 0, color)
        }
...