mirror of
https://github.com/DaanVandenBosch/phantasmal-world.git
synced 2025-04-04 06:28:28 +08:00
You can now force panning/rotating mode by holding ctrl while clicking and dragging the mouse.
This commit is contained in:
parent
585ce44667
commit
d6751b0151
@ -1,8 +1,11 @@
|
||||
package world.phantasmal.web.core.rendering
|
||||
|
||||
import org.w3c.dom.HTMLCanvasElement
|
||||
import org.w3c.dom.pointerevents.PointerEvent
|
||||
import world.phantasmal.core.disposable.Disposable
|
||||
import world.phantasmal.core.disposable.TrackedDisposable
|
||||
import world.phantasmal.web.externals.three.*
|
||||
import world.phantasmal.webui.dom.disposableListener
|
||||
import world.phantasmal.webui.obj
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.floor
|
||||
@ -15,7 +18,10 @@ class OrbitalCameraInputManager(
|
||||
screenSpacePanning: Boolean,
|
||||
enableRotate: Boolean = true,
|
||||
) : TrackedDisposable(), InputManager {
|
||||
private val controls = OrbitControls(camera, canvas)
|
||||
private lateinit var controls: OrbitControls
|
||||
|
||||
@Suppress("JoinDeclarationAndAssignment")
|
||||
private val pointerDownListener: Disposable
|
||||
|
||||
var enabled: Boolean
|
||||
get() = controls.enabled
|
||||
@ -24,12 +30,38 @@ class OrbitalCameraInputManager(
|
||||
}
|
||||
|
||||
init {
|
||||
// Switch mouse button actions when certain modifier keys are pressed to counteract
|
||||
// OrbitControls switching left and right click behavior in that case.
|
||||
pointerDownListener = canvas.disposableListener<PointerEvent>("pointerdown", {
|
||||
if (it.ctrlKey || it.metaKey || it.shiftKey) {
|
||||
controls.mouseButtons = obj {
|
||||
LEFT = MOUSE.ROTATE
|
||||
MIDDLE = MOUSE.DOLLY
|
||||
RIGHT = MOUSE.PAN
|
||||
}
|
||||
} else {
|
||||
controls.mouseButtons = obj {
|
||||
LEFT = MOUSE.PAN
|
||||
MIDDLE = MOUSE.DOLLY
|
||||
RIGHT = MOUSE.ROTATE
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Ensure OrbitControls is instantiated after the pointerdown event listener is attached.
|
||||
controls = OrbitControls(camera, canvas)
|
||||
|
||||
controls.mouseButtons = obj {
|
||||
LEFT = MOUSE.PAN
|
||||
MIDDLE = MOUSE.DOLLY
|
||||
RIGHT = MOUSE.ROTATE
|
||||
}
|
||||
|
||||
controls.touches = obj {
|
||||
ONE = TOUCH.PAN
|
||||
TWO = TOUCH.DOLLY_ROTATE
|
||||
}
|
||||
|
||||
camera.position.copy(position)
|
||||
controls.screenSpacePanning = screenSpacePanning
|
||||
controls.enableRotate = enableRotate
|
||||
@ -40,6 +72,7 @@ class OrbitalCameraInputManager(
|
||||
|
||||
override fun dispose() {
|
||||
controls.dispose()
|
||||
pointerDownListener.dispose()
|
||||
super.dispose()
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,11 @@ external interface OrbitControlsMouseButtons {
|
||||
var RIGHT: MOUSE
|
||||
}
|
||||
|
||||
external interface OrbitControlsMouseTouches {
|
||||
var ONE: TOUCH
|
||||
var TWO: TOUCH
|
||||
}
|
||||
|
||||
external class OrbitControls(`object`: Camera, domElement: HTMLElement = definedExternally) {
|
||||
var enabled: Boolean
|
||||
var enablePan: Boolean
|
||||
@ -23,6 +28,8 @@ external class OrbitControls(`object`: Camera, domElement: HTMLElement = defined
|
||||
|
||||
var mouseButtons: OrbitControlsMouseButtons
|
||||
|
||||
var touches: OrbitControlsMouseTouches
|
||||
|
||||
fun update(): Boolean
|
||||
|
||||
fun saveState()
|
||||
|
@ -744,6 +744,13 @@ external enum class MOUSE {
|
||||
PAN,
|
||||
}
|
||||
|
||||
external enum class TOUCH {
|
||||
ROTATE,
|
||||
PAN,
|
||||
DOLLY_PAN,
|
||||
DOLLY_ROTATE,
|
||||
}
|
||||
|
||||
external class Raycaster(
|
||||
origin: Vector3 = definedExternally,
|
||||
direction: Vector3 = definedExternally,
|
||||
|
@ -73,7 +73,7 @@ class QuestInputManager(
|
||||
renderContext.canvas.observeEntityDrop(::onEntityDrop),
|
||||
)
|
||||
|
||||
// Ensure OrbitalCameraControls attaches its listeners after ours.
|
||||
// Ensure OrbitalCameraControls attaches its listeners after we've attached ours.
|
||||
cameraInputManager = OrbitalCameraInputManager(
|
||||
renderContext.canvas,
|
||||
renderContext.camera,
|
||||
|
@ -19,9 +19,18 @@ class IdleState(
|
||||
private var shouldCheckHighlight = false
|
||||
|
||||
override fun processEvent(event: Evt): State {
|
||||
// Don't highlight or manipulate entities in forced panning/rotating mode.
|
||||
val forcedPanningRotatingMode = when (event) {
|
||||
is KeyboardEvt -> event.key == "Control"
|
||||
is PointerEvt -> event.ctrlKey
|
||||
else -> false
|
||||
}
|
||||
|
||||
when (event) {
|
||||
is KeyboardEvt -> {
|
||||
if (entityManipulationEnabled) {
|
||||
if (forcedPanningRotatingMode) {
|
||||
ctx.setHighlightedEntity(null)
|
||||
} else if (entityManipulationEnabled) {
|
||||
val quest = ctx.quest.value
|
||||
val entity = ctx.selectedEntity.value
|
||||
|
||||
@ -32,7 +41,9 @@ class IdleState(
|
||||
}
|
||||
|
||||
is PointerDownEvt -> {
|
||||
val pick = pickEntity(event.pointerDevicePosition)
|
||||
val pick =
|
||||
if (forcedPanningRotatingMode) null
|
||||
else pickEntity(event.pointerDevicePosition)
|
||||
|
||||
when (event.buttons) {
|
||||
1 -> {
|
||||
@ -93,8 +104,12 @@ class IdleState(
|
||||
is PointerMoveEvt -> {
|
||||
if (!panning && !rotating && !zooming) {
|
||||
// User is hovering.
|
||||
pointerDevicePosition.copy(event.pointerDevicePosition)
|
||||
shouldCheckHighlight = true
|
||||
if (forcedPanningRotatingMode) {
|
||||
ctx.setHighlightedEntity(null)
|
||||
} else {
|
||||
pointerDevicePosition.copy(event.pointerDevicePosition)
|
||||
shouldCheckHighlight = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user