This commit is contained in:
Youwen Wu 2024-02-26 15:16:30 -08:00
parent 97d4590da4
commit d646c928d2
3 changed files with 95 additions and 24 deletions

View file

@ -1,9 +1,87 @@
<script> <script lang="ts">
import { T, useTask } from '@threlte/core' import { T, useTask } from '@threlte/core'
import { Grid } from '@threlte/extras' import { Grid } from '@threlte/extras'
import CameraControls from './CameraControls.svelte' import CameraControls from './CameraControls.svelte'
import { cameraControls, mesh } from './utils/cameraStore' import { cameraControls, mesh } from './utils/cameraStore'
import Hornet from '../models/Hornet.svelte' import Hornet from '../models/Hornet.svelte'
import { Vector3 } from 'three'
import { onMount } from 'svelte'
function vectorFromObject() {
let ideal: Vector3 = new Vector3()
$cameraControls.getPosition(ideal, true)
ideal.applyQuaternion($mesh.quaternion)
ideal.add(new Vector3($mesh.position.x, $mesh.position.y, $mesh.position.z))
return ideal
}
const follow = (delta: number) => {
// the object's position is bound to the prop
if (!$mesh || !$cameraControls) return
// typescript HACKS! never do this! How does this work? who knows!
const robotPosition = vectorFromObject()
const horizontalOffsetDistance = 12 // Distance behind the leading vector
const direction = new Vector3(0, 0, 1) // Default forward direction in Three.js is negative z-axis, so behind is positive z-axis
const verticalOffset = new Vector3(0, -2.8, 0)
// Calculate the offset vector
const offsetVector = direction
.normalize()
.multiplyScalar(horizontalOffsetDistance)
.add(verticalOffset)
// If the leading object is rotating, apply its rotation to the offset vector
const rotatedOffsetVector = offsetVector.applyQuaternion($mesh.quaternion)
// Calculate the trailing vector's position
const trailingVector = robotPosition.clone().sub(rotatedOffsetVector)
$cameraControls.setLookAt(
trailingVector.x,
trailingVector.y,
trailingVector.z,
$mesh.position.x,
$mesh.position.y,
$mesh.position.z,
true
)
}
useTask(delta => {
// follow(delta)
// $cameraControls.moveTo(
// $mesh.position.x,
// $mesh.position.y,
// $mesh.position.z,
// true
// )
})
onMount(() => {
setTimeout(() => {
// $cameraControls.setLookAt(
// $mesh.position.x,
// $mesh.position.y,
// $mesh.position.z,
// $mesh.position.x,
// $mesh.position.y,
// $mesh.position.z,
// true
// )
$cameraControls.setLookAt(
30,
20,
-40,
$mesh.position.x,
$mesh.position.y,
$mesh.position.z,
true
)
}, 8000)
})
</script> </script>
<T.PerspectiveCamera <T.PerspectiveCamera
@ -17,7 +95,6 @@
on:create={({ ref }) => { on:create={({ ref }) => {
$cameraControls = ref $cameraControls = ref
}} }}
autoRotate
/> />
</T.PerspectiveCamera> </T.PerspectiveCamera>

View file

@ -1,6 +1,8 @@
import type CameraControls from 'camera-controls' import type CameraControls from 'camera-controls'
import { writable } from 'svelte/store' import { writable } from 'svelte/store'
import Hornet from '../../models/Hornet.svelte' import Hornet from '../../models/Hornet.svelte'
import type { Mesh, Object3DEventMap } from 'three'
import type { Group } from 'three/examples/jsm/libs/tween.module.js'
export const cameraControls = writable<CameraControls>() export const cameraControls = writable<CameraControls>()
export const mesh = writable() export const mesh = writable<Mesh>()

View file

@ -19,28 +19,20 @@
camera = $cameraControls._camera camera = $cameraControls._camera
} }
// function vectorFromObject(vec: { x: number; y: number; z: number }) {
// const { x, y, z } = vec
// const ideal = new Vector3(x, y, z)
// ideal.applyQuaternion($mesh.quaternion)
// ideal.add(new Vector3($mesh.position.x, $mesh.position.y, $mesh.position.z))
// return ideal
// }
onMount(() => { onMount(() => {
setTimeout(() => { // setTimeout(() => {
// $cameraControls.moveTo(3, 5, 2, true) // // $cameraControls.moveTo(3, 5, 2, true)
// $cameraControls.setOrbitPoint(20, 20, 20) // // $cameraControls.setOrbitPoint(20, 20, 20)
$cameraControls.setLookAt( // $cameraControls.setLookAt(
3, // 3,
5, // 5,
2, // 2,
$mesh.position.x, // $mesh.position.x,
$mesh.position.y, // $mesh.position.y,
$mesh.position.z, // $mesh.position.z,
true // true
) // )
}, 8000) // }, 8000)
}) })
</script> </script>