fix: some unused imports causing errors

This commit is contained in:
Youwen Wu 2024-02-26 23:59:46 -08:00
parent 8c0adca9b0
commit 21eb0411d1
Signed by: youwen5
GPG key ID: 865658ED1FE61EC3
2 changed files with 89 additions and 87 deletions

View file

@ -1,44 +1,45 @@
<script lang="ts"> <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 { Vector3 } from "three";
import { Vector3 } from 'three' import { onMount } from "svelte";
import { onMount } from 'svelte' import RobotDecimated from "../models/RobotDecimated.svelte";
import RobotDecimated from '../models/RobotDecimated.svelte'
function vectorFromObject() { function vectorFromObject() {
let ideal: Vector3 = new Vector3() let ideal: Vector3 = new Vector3();
$cameraControls.getPosition(ideal, true) $cameraControls.getPosition(ideal, true);
ideal.applyQuaternion($mesh.quaternion) ideal.applyQuaternion($mesh.quaternion);
ideal.add(new Vector3($mesh.position.x, $mesh.position.y, $mesh.position.z)) ideal.add(
return ideal new Vector3($mesh.position.x, $mesh.position.y, $mesh.position.z)
);
return ideal;
} }
const follow = (delta: number) => { const follow = (delta: number) => {
// the object's position is bound to the prop // the object's position is bound to the prop
if (!$mesh || !$cameraControls) return if (!$mesh || !$cameraControls) return;
// typescript HACKS! never do this! How does this work? who knows! // typescript HACKS! never do this! How does this work? who knows!
const robotPosition = vectorFromObject() const robotPosition = vectorFromObject();
const horizontalOffsetDistance = 12 // Distance behind the leading vector 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 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) const verticalOffset = new Vector3(0, -2.8, 0);
// Calculate the offset vector // Calculate the offset vector
const offsetVector = direction const offsetVector = direction
.normalize() .normalize()
.multiplyScalar(horizontalOffsetDistance) .multiplyScalar(horizontalOffsetDistance)
.add(verticalOffset) .add(verticalOffset);
// If the leading object is rotating, apply its rotation to the offset vector // If the leading object is rotating, apply its rotation to the offset vector
const rotatedOffsetVector = offsetVector.applyQuaternion($mesh.quaternion) const rotatedOffsetVector = offsetVector.applyQuaternion($mesh.quaternion);
// Calculate the trailing vector's position // Calculate the trailing vector's position
const trailingVector = robotPosition.clone().sub(rotatedOffsetVector) const trailingVector = robotPosition.clone().sub(rotatedOffsetVector);
$cameraControls.setLookAt( $cameraControls.setLookAt(
trailingVector.x, trailingVector.x,
@ -48,10 +49,10 @@
$mesh.position.y, $mesh.position.y,
$mesh.position.z, $mesh.position.z,
true true
) );
} };
useTask(delta => { useTask((delta) => {
// follow(delta) // follow(delta)
// $cameraControls.moveTo( // $cameraControls.moveTo(
// $mesh.position.x, // $mesh.position.x,
@ -59,7 +60,7 @@
// $mesh.position.z, // $mesh.position.z,
// true // true
// ) // )
}) });
onMount(() => { onMount(() => {
setTimeout(() => { setTimeout(() => {
@ -80,21 +81,21 @@
$mesh.position.y, $mesh.position.y,
$mesh.position.z, $mesh.position.z,
true true
) );
}, 8000) }, 8000);
}) });
</script> </script>
<T.PerspectiveCamera <T.PerspectiveCamera
makeDefault makeDefault
position={[10, 10, 10]} position={[10, 10, 10]}
on:create={({ ref }) => { on:create={({ ref }) => {
ref.lookAt(0, 1, 0) ref.lookAt(0, 1, 0);
}} }}
> >
<CameraControls <CameraControls
on:create={({ ref }) => { on:create={({ ref }) => {
$cameraControls = ref $cameraControls = ref;
}} }}
/> />
</T.PerspectiveCamera> </T.PerspectiveCamera>
@ -105,15 +106,17 @@
scale={[10, 10, 10]} scale={[10, 10, 10]}
position.y={0} position.y={0}
on:create={({ ref }) => { on:create={({ ref }) => {
$mesh = ref // @ts-expect-error
$mesh = ref;
}} }}
/> />
<Grid <Grid
sectionColor={'#ff3e00'} sectionColor={"#ff3e00"}
sectionThickness={1} sectionThickness={1}
fadeDistance={125} fadeDistance={100}
cellSize={6} cellSize={6}
cellColor={'#cccccc'} sectionSize={24}
cellColor={"#cccccc"}
infiniteGrid infiniteGrid
/> />

View file

@ -1,23 +1,22 @@
<script lang="ts"> <script lang="ts">
import { T, useTask } from '@threlte/core' import { T, useTask } from "@threlte/core";
import { ContactShadows, Float, Grid, OrbitControls } from '@threlte/extras' import { ContactShadows, Float, Grid, OrbitControls } from "@threlte/extras";
import Hornet from './models/Hornet.svelte' import Controls from "./Controls.svelte";
import Controls from './Controls.svelte'
import { import {
Vector3, Vector3,
type Camera, type Camera,
type Group, type Group,
type Object3D, type Object3D,
type Object3DEventMap, type Object3DEventMap,
} from 'three' } from "three";
import { import {
telemetryReadonlyStore, telemetryReadonlyStore,
telemetryStore, telemetryStore,
} from '../../stores/telemetryStore' } from "../../stores/telemetryStore";
import { get } from 'svelte/store' import { get } from "svelte/store";
import { Vector2 } from 'three' import { Vector2 } from "three";
import { SmoothMotionController } from './smoothMotionController' import { SmoothMotionController } from "./smoothMotionController";
import { onMount } from 'svelte' import { onMount } from "svelte";
/* This is the root scene where the robot visualization is built. /* This is the root scene where the robot visualization is built.
It renders an infinite grid (it's not actually infinite, but we shouldn't run out It renders an infinite grid (it's not actually infinite, but we shouldn't run out
@ -32,91 +31,91 @@
is the most esoteric and jank code ever written. is the most esoteric and jank code ever written.
*/ */
let shouldOrbit = true let shouldOrbit = true;
// CONSTANTS // CONSTANTS
const maxAngularVelocity = 2 // Max angular velocity, in radians per second const maxAngularVelocity = 2; // Max angular velocity, in radians per second
const stoppingThreshold = 0.005 // Threshold in radians for when to consider the rotation close enough to stop const stoppingThreshold = 0.005; // Threshold in radians for when to consider the rotation close enough to stop
// Proportional control factor // Proportional control factor
const kP = 2 // Adjust this value based on responsiveness and stability needs const kP = 2; // Adjust this value based on responsiveness and stability needs
// Sync robot orientation with target rotation // Sync robot orientation with target rotation
let targetRot = 0 let targetRot = 0;
// Updates rotation to match target with PID controller (intended to be invoked in useTask) // Updates rotation to match target with PID controller (intended to be invoked in useTask)
let rot = 0 // (initial) rotation in radians let rot = 0; // (initial) rotation in radians
let angularVelocity = 0 let angularVelocity = 0;
const updateRotation = (delta: number) => { const updateRotation = (delta: number) => {
let angleDifference = targetRot - rot let angleDifference = targetRot - rot;
// Normalize angle difference to the range [-π, π] // Normalize angle difference to the range [-π, π]
angleDifference = ((angleDifference + Math.PI) % (2 * Math.PI)) - Math.PI angleDifference = ((angleDifference + Math.PI) % (2 * Math.PI)) - Math.PI;
// Calculate the desired angular velocity based on the angle difference // Calculate the desired angular velocity based on the angle difference
let desiredVelocity = let desiredVelocity =
Math.sign(angleDifference) * Math.sign(angleDifference) *
Math.min(maxAngularVelocity, Math.abs(kP * angleDifference)) Math.min(maxAngularVelocity, Math.abs(kP * angleDifference));
// If the object is very close to the target, adjust the desired velocity to zero to prevent overshooting // If the object is very close to the target, adjust the desired velocity to zero to prevent overshooting
if (Math.abs(angleDifference) < stoppingThreshold) { if (Math.abs(angleDifference) < stoppingThreshold) {
desiredVelocity = 0 desiredVelocity = 0;
} }
// Adjust angular velocity towards desired velocity // Adjust angular velocity towards desired velocity
angularVelocity = desiredVelocity angularVelocity = desiredVelocity;
// Update rotation // Update rotation
rot += angularVelocity * delta rot += angularVelocity * delta;
// Normalize rot to the range [0, 2π] // Normalize rot to the range [0, 2π]
if (rot < 0) rot += 2 * Math.PI if (rot < 0) rot += 2 * Math.PI;
else if (rot > 2 * Math.PI) rot -= 2 * Math.PI else if (rot > 2 * Math.PI) rot -= 2 * Math.PI;
// Snap to the target rotation to prevent tiny oscillations if close enough // Snap to the target rotation to prevent tiny oscillations if close enough
if (Math.abs(angleDifference) < stoppingThreshold) { if (Math.abs(angleDifference) < stoppingThreshold) {
rot = targetRot rot = targetRot;
angularVelocity = 0 angularVelocity = 0;
}
} }
};
let robotPos: Vector3 = new Vector3(0, 0, 0) let robotPos: Vector3 = new Vector3(0, 0, 0);
const robotPosition = new Vector2(0, 0) // Initial position const robotPosition = new Vector2(0, 0); // Initial position
const initialVelocity = { x: 0, y: 0 } // Initial velocity const initialVelocity = { x: 0, y: 0 }; // Initial velocity
// The smooth motion controller utilizes a cubic hermite spline to interpolate between // The smooth motion controller utilizes a cubic hermite spline to interpolate between
// the current simulation velocity and the robot's actual velocity // the current simulation velocity and the robot's actual velocity
const controller = new SmoothMotionController(robotPosition, initialVelocity) const controller = new SmoothMotionController(robotPosition, initialVelocity);
onMount(() => { onMount(() => {
telemetryReadonlyStore.subscribe(value => { telemetryReadonlyStore.subscribe((value) => {
targetRot = (value['orientation'] * Math.PI) / 180 // convert deg to rad targetRot = (value["orientation"] * Math.PI) / 180; // convert deg to rad
controller.setTargetVelocity({ controller.setTargetVelocity({
x: value['chassis-x-speed'], x: value["chassis-x-speed"],
y: value['chassis-y-speed'], y: value["chassis-y-speed"],
}) });
shouldOrbit = value.gear === 'park' || value.gear === '-999' shouldOrbit = value.gear === "park" || value.gear === "-999";
if (shouldOrbit) { if (shouldOrbit) {
robotPos = new Vector3(0, 0, 0) robotPos = new Vector3(0, 0, 0);
controller.reset() controller.reset();
} }
}) });
}) });
useTask(delta => { useTask((delta) => {
if (!shouldOrbit) { if (!shouldOrbit) {
updateRotation(delta) updateRotation(delta);
controller.update(delta) controller.update(delta);
robotPos.x = controller.getPosition().x robotPos.x = controller.getPosition().x;
robotPos.z = controller.getPosition().y robotPos.z = controller.getPosition().y;
} }
}) });
let capsule: Group<Object3DEventMap> let capsule: Group<Object3DEventMap>;
let capRef: Group<Object3DEventMap> let capRef: Group<Object3DEventMap>;
$: if (capsule) { $: if (capsule) {
capRef = capsule capRef = capsule;
} }
</script> </script>
@ -145,11 +144,11 @@
<ContactShadows scale={10} blur={2} far={2.5} opacity={0.5} /> <ContactShadows scale={10} blur={2} far={2.5} opacity={0.5} />
<Hornet <!-- <Hornet
position.y={2} position.y={2}
position.z={robotPos.z} position.z={robotPos.z}
position.x={robotPos.x} position.x={robotPos.x}
scale={[0.8, 0.8, 0.8]} scale={[0.8, 0.8, 0.8]}
bind:ref={capsule} bind:ref={capsule}
rotation.y={rot} rotation.y={rot}
/> /> -->