package xyz.r0r5chach.dermy_app.map import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.PerspectiveCamera import com.badlogic.gdx.graphics.g3d.ModelInstance import com.badlogic.gdx.graphics.g3d.model.MeshPart import com.badlogic.gdx.graphics.g3d.utils.CameraInputController import com.badlogic.gdx.math.Intersector import com.badlogic.gdx.math.Vector3 import xyz.r0r5chach.dermy_app.map.locations.BodyPart import xyz.r0r5chach.dermy_app.map.locations.Location import xyz.r0r5chach.dermy_app.map.locations.Side import kotlin.math.abs import kotlin.properties.Delegates class MapCameraController( camera: PerspectiveCamera?, var modelInstance: ModelInstance? ) : CameraInputController(camera) { private var initialX: Int = 0 private var initialY: Int = 0 private var selectedLocation: Location by Delegates.observable(Location(Side.NONE, BodyPart.NONE)) { _, _, newValue -> notifyObservers(newValue) } private val observers = mutableListOf<(Location) -> Unit>() init { this.pinchZoomFactor = 25f } fun addObserver(observer: (Location) -> Unit) { observers.add(observer) } private fun notifyObservers(newValue: Location) { for (observer in observers) { observer(newValue) } } override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { initialX = screenX initialY = screenY return super.touchDown(screenX, screenY, pointer, button) } override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { if (abs((initialX - screenX).toDouble()) < 10 && abs((initialY - screenY).toDouble()) < 10) { handleClick() } return super.touchUp(screenX, screenY, pointer, button) } private fun handleClick() { if (modelInstance != null) { val selectionRay = camera.getPickRay(Gdx.input.x.toFloat(), Gdx.input.y.toFloat()) var closestDistance = Float.MAX_VALUE var closestPart: MeshPart? = null val meshes = modelInstance!!.model.meshParts for (part in meshes) { val bounds = part.mesh.calculateBoundingBox() bounds.mul(modelInstance!!.transform) val intersection = Vector3() if (Intersector.intersectRayBounds(selectionRay, bounds, intersection)) { val distance = selectionRay.origin.dst(intersection) if (distance < closestDistance) { closestDistance = distance closestPart = part } } } val id = closestPart?.id val side = when (id?.get(0)) { 'L' -> Side.LEFT 'R' -> Side.RIGHT else -> Side.LEFT } val bodyPart = BodyPart.valueOf(id!!.substring(1).uppercase()) selectedLocation = Location(side, bodyPart) } } }