67 lines
2 KiB
TypeScript
67 lines
2 KiB
TypeScript
import * as THREE from 'three'
|
|
import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'
|
|
import { createWaypointSprite, WAYPOINT_CONFIG } from '../renderer/viewer/three/waypointSprite'
|
|
|
|
// Create scene, camera and renderer
|
|
const scene = new THREE.Scene()
|
|
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
|
|
const renderer = new THREE.WebGLRenderer({ antialias: true })
|
|
renderer.setSize(window.innerWidth, window.innerHeight)
|
|
document.body.appendChild(renderer.domElement)
|
|
|
|
// Add FirstPersonControls
|
|
const controls = new FirstPersonControls(camera, renderer.domElement)
|
|
controls.lookSpeed = 0.1
|
|
controls.movementSpeed = 10
|
|
controls.lookVertical = true
|
|
controls.constrainVertical = true
|
|
controls.verticalMin = 0.1
|
|
controls.verticalMax = Math.PI - 0.1
|
|
|
|
// Position camera
|
|
camera.position.y = 1.6 // Typical eye height
|
|
camera.lookAt(0, 1.6, -1)
|
|
|
|
// Create a helper grid and axes
|
|
const grid = new THREE.GridHelper(20, 20)
|
|
scene.add(grid)
|
|
const axes = new THREE.AxesHelper(5)
|
|
scene.add(axes)
|
|
|
|
// Create waypoint sprite via utility
|
|
const waypoint = createWaypointSprite({
|
|
position: new THREE.Vector3(0, 0, -5),
|
|
color: 0xff0000,
|
|
label: 'Target',
|
|
})
|
|
scene.add(waypoint.group)
|
|
|
|
// Use built-in offscreen arrow from utils
|
|
waypoint.enableOffscreenArrow(true)
|
|
waypoint.setArrowParent(scene)
|
|
|
|
// Animation loop
|
|
function animate() {
|
|
requestAnimationFrame(animate)
|
|
|
|
const delta = Math.min(clock.getDelta(), 0.1)
|
|
controls.update(delta)
|
|
|
|
// Unified camera update (size, distance text, arrow, visibility)
|
|
const sizeVec = renderer.getSize(new THREE.Vector2())
|
|
waypoint.updateForCamera(camera.position, camera, sizeVec.width, sizeVec.height)
|
|
|
|
renderer.render(scene, camera)
|
|
}
|
|
|
|
// Handle window resize
|
|
window.addEventListener('resize', () => {
|
|
camera.aspect = window.innerWidth / window.innerHeight
|
|
camera.updateProjectionMatrix()
|
|
renderer.setSize(window.innerWidth, window.innerHeight)
|
|
})
|
|
|
|
// Add clock for controls
|
|
const clock = new THREE.Clock()
|
|
|
|
animate()
|