Skip to content

Commit

Permalink
feat: support first-person view
Browse files Browse the repository at this point in the history
  • Loading branch information
piellardj authored and Sceat committed Apr 21, 2024
1 parent 53c7b28 commit 74aaa26
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/core/game/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ export default function create_pools(scene) {
height,
radius,
mixer,
object3d: origin,
jump_time: 0,
audio: null,
action: null,
Expand Down
55 changes: 43 additions & 12 deletions src/core/modules/game_camera.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { on } from 'events'

import { aiter } from 'iterator-helper'
import CameraControls from 'camera-controls'
import { clamp, smootherstep } from 'three/src/math/MathUtils'

import { abortable } from '../utils/iterator'
import { current_character } from '../game/game.js'

const CAMERA_MIN_ZOOM = 4
const CAMERA_MAX_ZOOM = 500
const CAMERA_MIN_DISTANCE = 0.001
const CAMERA_DISTANCE_STEP = 1
const CAMERA_MAX_DISTANCE = 50

/** @type {Type.Module} */
export default function () {
Expand All @@ -23,8 +25,16 @@ export default function () {
if (!free_camera) {
const { x, y, z } = player.position

camera_controls.moveTo(x, y, z, true)
camera_controls.setTarget(x, y, z, true)
const center_camera_on_head =
1 - smootherstep(camera_controls.distance, 0, 10)
const head_height = 1
const y_shift = head_height * center_camera_on_head
camera_controls.moveTo(x, y + y_shift, z, true)
camera_controls.setTarget(x, y + y_shift, z, true)

if (typeof player.object3d !== 'undefined') {
player.object3d.visible = camera_controls.distance > 0.75
}
}
camera_controls.update(delta)
},
Expand All @@ -49,24 +59,36 @@ export default function () {

camera_controls.dollyDragInverted = true
camera_controls.dollyToCursor = true
camera_controls.maxDistance = CAMERA_MAX_ZOOM
camera_controls.minDistance = CAMERA_MIN_ZOOM
camera_controls.maxDistance = CAMERA_MAX_DISTANCE
camera_controls.minDistance = CAMERA_MIN_DISTANCE
camera_controls.smoothTime = 0.1

camera_controls.mouseButtons.wheel = CameraControls.ACTION.DOLLY

camera_controls.dolly(8)
camera_controls.dollyTo(8)
camera_controls.rotate(0, 1)

set_camera_padding(200, 0, 0, 0)

// let is_dragging = false

const set_distance = distance => {
distance = clamp(distance, CAMERA_MIN_DISTANCE, CAMERA_MAX_DISTANCE)
distance = Math.round(distance)
camera_controls.dollyTo(distance, true)
}

const on_mouse_down = () => {
// is_dragging = true
renderer.domElement.requestPointerLock()
}

const on_mouse_wheel = event => {
const delta_abs = Math.max(
CAMERA_DISTANCE_STEP,
0.5 * camera_controls.distance,
)
const delta = delta_abs * Math.sign(event.deltaY)
set_distance(camera_controls.distance + delta)
}

renderer.domElement.addEventListener('mousedown', on_mouse_down, {
signal,
})
Expand All @@ -89,14 +111,23 @@ export default function () {
'mousedown',
on_mouse_down,
)
renderer.domElement.removeEventListener('wheel', on_mouse_wheel)
set_camera_padding(0, 0, 0, 0)
camera_controls.mouseButtons.right = CameraControls.ACTION.OFFSET
camera_controls.mouseButtons.wheel = CameraControls.ACTION.DOLLY
} else {
camera_controls.maxDistance = CAMERA_MAX_ZOOM
camera_controls.minDistance = CAMERA_MIN_ZOOM
camera_controls.maxDistance = CAMERA_MAX_DISTANCE
camera_controls.minDistance = CAMERA_MIN_DISTANCE
renderer.domElement.addEventListener('mousedown', on_mouse_down, {
signal,
})
renderer.domElement.addEventListener('wheel', on_mouse_wheel, {
signal,
})
set_camera_padding(200, 0, 0, 0)
set_distance(camera_controls.distance)
camera_controls.mouseButtons.right = CameraControls.ACTION.ROTATE
camera_controls.mouseButtons.wheel = CameraControls.ACTION.NONE
}
}
return free_camera
Expand Down
1 change: 1 addition & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ declare namespace Type {
title: import('troika-three-text').Text
position: import('three').Vector3
target_position: Position | null
object3d?: import('three').Object3D
set_low_priority?: (skip: boolean) => void
apply_state: (entity: Partial<ThreeEntity>) => void
move: (position: Position) => void
Expand Down

0 comments on commit 74aaa26

Please sign in to comment.