All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.ru.casperix.demo_platform.point.PointController.kt Maven / Gradle / Ivy

There is a newer version: 1.2.0
Show newest version
package ru.casperix.demo_platform.point


import ru.casperix.demo_platform.renderer.RenderConfig
import ru.casperix.demo_platform.renderer.RenderConfig.POINT_BACK
import ru.casperix.demo_platform.renderer.RenderConfig.POINT_DEFAULT
import ru.casperix.demo_platform.renderer.RenderConfig.POINT_FOCUSED
import ru.casperix.demo_platform.renderer.RenderConfig.lineThick
import ru.casperix.demo_platform.renderer.RenderConfig.pointDiameter
import ru.casperix.input.*
import ru.casperix.math.color.Colors
import ru.casperix.math.geometry.Line2f
import ru.casperix.math.vector.float32.Vector2f
import ru.casperix.renderer.Renderer2D
import ru.casperix.renderer.material.SimpleMaterial
import ru.casperix.signals.concrete.Signal

@ExperimentalUnsignedTypes
class PointController {
    val BACK_COLORS = listOf(Colors.RED, Colors.LIME, Colors.BLUE, Colors.YELLOW, Colors.CYAN, Colors.FUCHSIA, Colors.WHITE)

    var girdAlignStep: Float? = null
    var drawBack = true

    val groups = mutableListOf>()
    var focused: Point? = null
    var selected: Point? = null

    var pointDragged = Signal()


    operator fun plusAssign(points: List) {
        groups += points
    }

    fun input(event: InputEvent) {
        if (event is PointerEvent) {
            val cursor = screenToScene(event.position)

            if (event is PointerDown) {
                selected = getNearPoint(event.position)
            } else if (event is PointerMove) {
                selected?.also {
                    it.position = solvePosition(cursor)
                    pointDragged.set(it)
                }
            } else if (event is PointerUp) {
                selected = null
            } else {
                focused = getNearPoint(event.position)
            }

        }

    }

    private fun solvePosition(position: Vector2f): Vector2f {
        val girdAlignStep = girdAlignStep ?: return position
        return (position / girdAlignStep).round() * girdAlignStep
    }

    private fun getNearPoint(screenPosition: Vector2f): Point? {
        val camera = RenderConfig.camera
        val range = camera.zoom * 100f
        val cursor = screenToScene(screenPosition)
        val points = groups.flatten()
        return points
            .map { Pair(it, it.position.distTo(cursor)) }
            .filter { it.second < range }
            .minByOrNull { it.second }?.first
    }

    private fun screenToScene(value: Vector2f): Vector2f {
        val camera = RenderConfig.camera
        return camera.transform.unproject(value)
    }

    fun render(renderer: Renderer2D) {

        if (drawBack) {
            groups.forEach { group ->
                group.forEachIndexed { index, point ->
                    val a = group[index]
                    val b = group[(index + 1) % group.size]
                    renderer.drawLine(POINT_BACK, Line2f(a.position, b.position), lineThick * 8f)
                }
            }
        }

        groups.forEach { group ->
            group.forEachIndexed { index, point ->
                val backColor = BACK_COLORS[index % BACK_COLORS.size]

                val color = if (selected == point || focused == point) {
                    POINT_FOCUSED
                } else {
                    POINT_DEFAULT
                }
                renderer.drawCircle(
                    SimpleMaterial(backColor),
                    point.position,
                    pointDiameter * 0.75f,
                    pointDiameter * 1f
                )
                renderer.drawCircle(
                    SimpleMaterial(color),
                    point.position,
                    pointDiameter * 0f,
                    pointDiameter * 0.75f
                )

//                if (point.mode == PointMode.DIRECTION) {
//                    renderer.drawLine(CONTROL_POINT_BACK, Line2f(Vector2f.ZERO, point.position), lineThick * 8f)
//                }
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy