|
| 1 | +import * as THREE from 'three' |
| 2 | +import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js' |
| 3 | +import { createWaypointSprite, WAYPOINT_CONFIG } from '../renderer/viewer/three/waypointSprite' |
| 4 | + |
| 5 | +// Create scene, camera and renderer |
| 6 | +const scene = new THREE.Scene() |
| 7 | +const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000) |
| 8 | +const renderer = new THREE.WebGLRenderer({ antialias: true }) |
| 9 | +renderer.setSize(window.innerWidth, window.innerHeight) |
| 10 | +document.body.appendChild(renderer.domElement) |
| 11 | + |
| 12 | +// Add FirstPersonControls |
| 13 | +const controls = new FirstPersonControls(camera, renderer.domElement) |
| 14 | +controls.lookSpeed = 0.1 |
| 15 | +controls.movementSpeed = 10 |
| 16 | +controls.lookVertical = true |
| 17 | +controls.constrainVertical = true |
| 18 | +controls.verticalMin = 0.1 |
| 19 | +controls.verticalMax = Math.PI - 0.1 |
| 20 | + |
| 21 | +// Position camera |
| 22 | +camera.position.y = 1.6 // Typical eye height |
| 23 | +camera.lookAt(0, 1.6, -1) |
| 24 | + |
| 25 | +// Create a helper grid and axes |
| 26 | +const grid = new THREE.GridHelper(20, 20) |
| 27 | +scene.add(grid) |
| 28 | +const axes = new THREE.AxesHelper(5) |
| 29 | +scene.add(axes) |
| 30 | + |
| 31 | +// Create waypoint sprite via utility |
| 32 | +const waypoint = createWaypointSprite({ |
| 33 | + position: new THREE.Vector3(0, 0, -5), |
| 34 | + color: 0xff0000, |
| 35 | + label: 'Target', |
| 36 | +}) |
| 37 | +scene.add(waypoint.group) |
| 38 | + |
| 39 | +// Use built-in offscreen arrow from utils |
| 40 | +waypoint.enableOffscreenArrow(true) |
| 41 | +waypoint.setArrowParent(scene) |
| 42 | + |
| 43 | +// Animation loop |
| 44 | +function animate() { |
| 45 | + requestAnimationFrame(animate) |
| 46 | + |
| 47 | + const delta = Math.min(clock.getDelta(), 0.1) |
| 48 | + controls.update(delta) |
| 49 | + |
| 50 | + // Unified camera update (size, distance text, arrow, visibility) |
| 51 | + const sizeVec = renderer.getSize(new THREE.Vector2()) |
| 52 | + waypoint.updateForCamera(camera.position, camera, sizeVec.width, sizeVec.height) |
| 53 | + |
| 54 | + renderer.render(scene, camera) |
| 55 | +} |
| 56 | + |
| 57 | +// Handle window resize |
| 58 | +window.addEventListener('resize', () => { |
| 59 | + camera.aspect = window.innerWidth / window.innerHeight |
| 60 | + camera.updateProjectionMatrix() |
| 61 | + renderer.setSize(window.innerWidth, window.innerHeight) |
| 62 | +}) |
| 63 | + |
| 64 | +// Add clock for controls |
| 65 | +const clock = new THREE.Clock() |
| 66 | + |
| 67 | +animate() |
0 commit comments