Feat/polish-mission1 #12
@@ -8,6 +8,10 @@ import { useLoggedGLTF } from "@/hooks/three/useLoggedGLTF";
|
|||||||
import { useClonedObject } from "@/hooks/three/useClonedObject";
|
import { useClonedObject } from "@/hooks/three/useClonedObject";
|
||||||
import { useDebugFolder } from "@/hooks/debug/useDebugFolder";
|
import { useDebugFolder } from "@/hooks/debug/useDebugFolder";
|
||||||
import { useEbikeSounds } from "@/hooks/ebike/useEbikeSounds";
|
import { useEbikeSounds } from "@/hooks/ebike/useEbikeSounds";
|
||||||
|
import {
|
||||||
|
getObjectBottomOffset,
|
||||||
|
useTerrainHeightSampler,
|
||||||
|
} from "@/hooks/three/useTerrainHeight";
|
||||||
import { animateCameraTransformTransition } from "@/world/GameCinematics";
|
import { animateCameraTransformTransition } from "@/world/GameCinematics";
|
||||||
import { useGameStore } from "@/managers/stores/useGameStore";
|
import { useGameStore } from "@/managers/stores/useGameStore";
|
||||||
import {
|
import {
|
||||||
@@ -32,6 +36,18 @@ export function Ebike({ position }: EbikeProps): React.JSX.Element {
|
|||||||
position: position,
|
position: position,
|
||||||
});
|
});
|
||||||
const model = useClonedObject(scene);
|
const model = useClonedObject(scene);
|
||||||
|
const terrainHeight = useTerrainHeightSampler();
|
||||||
|
const parkedPosition = useMemo<Vector3Tuple>(() => {
|
||||||
|
const [x, y, z] = position;
|
||||||
|
const height = terrainHeight.getHeight(x, z) ?? y;
|
||||||
|
const bottomOffset = getObjectBottomOffset(model, [
|
||||||
|
EBIKE_WORLD_SCALE,
|
||||||
|
EBIKE_WORLD_SCALE,
|
||||||
|
EBIKE_WORLD_SCALE,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return [x, height + bottomOffset, z];
|
||||||
|
}, [model, position, terrainHeight]);
|
||||||
const movementMode = useGameStore((state) => state.player.movementMode);
|
const movementMode = useGameStore((state) => state.player.movementMode);
|
||||||
const mainState = useGameStore((state) => state.mainState);
|
const mainState = useGameStore((state) => state.mainState);
|
||||||
const ebikeStep = useGameStore((state) => state.ebike.currentStep);
|
const ebikeStep = useGameStore((state) => state.ebike.currentStep);
|
||||||
@@ -64,19 +80,19 @@ export function Ebike({ position }: EbikeProps): React.JSX.Element {
|
|||||||
y: number;
|
y: number;
|
||||||
z: number;
|
z: number;
|
||||||
}>({
|
}>({
|
||||||
x: position[0],
|
x: parkedPosition[0],
|
||||||
y: position[1],
|
y: parkedPosition[1],
|
||||||
z: position[2],
|
z: parkedPosition[2],
|
||||||
});
|
});
|
||||||
const lastGpsUpdatePos = useRef<THREE.Vector3>(
|
const lastGpsUpdatePos = useRef<THREE.Vector3>(
|
||||||
new THREE.Vector3(...position),
|
new THREE.Vector3(...parkedPosition),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Use ref for internal state, and state for debug visualization (to avoid ref access during render)
|
// Use ref for internal state, and state for debug visualization (to avoid ref access during render)
|
||||||
const restingPositionRef = useRef<Vector3Tuple>([
|
const restingPositionRef = useRef<Vector3Tuple>([
|
||||||
position[0],
|
parkedPosition[0],
|
||||||
position[1],
|
parkedPosition[1],
|
||||||
position[2],
|
parkedPosition[2],
|
||||||
]);
|
]);
|
||||||
const restingRotationRef = useRef<number>(EBIKE_WORLD_ROTATION_Y);
|
const restingRotationRef = useRef<number>(EBIKE_WORLD_ROTATION_Y);
|
||||||
const forkRef = useRef<THREE.Object3D | null>(null);
|
const forkRef = useRef<THREE.Object3D | null>(null);
|
||||||
@@ -84,23 +100,27 @@ export function Ebike({ position }: EbikeProps): React.JSX.Element {
|
|||||||
// State for debug visualization (synced from refs during useFrame)
|
// State for debug visualization (synced from refs during useFrame)
|
||||||
const [showCameraPoints, setShowCameraPoints] = useState(true);
|
const [showCameraPoints, setShowCameraPoints] = useState(true);
|
||||||
const [debugRestingPosition, setDebugRestingPosition] =
|
const [debugRestingPosition, setDebugRestingPosition] =
|
||||||
useState<Vector3Tuple>([position[0], position[1], position[2]]);
|
useState<Vector3Tuple>([
|
||||||
|
parkedPosition[0],
|
||||||
|
parkedPosition[1],
|
||||||
|
parkedPosition[2],
|
||||||
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (movementMode === "ebike") return;
|
if (movementMode === "ebike") return;
|
||||||
|
|
||||||
restingPositionRef.current = position;
|
restingPositionRef.current = parkedPosition;
|
||||||
restingRotationRef.current = EBIKE_WORLD_ROTATION_Y;
|
restingRotationRef.current = EBIKE_WORLD_ROTATION_Y;
|
||||||
lastGpsUpdatePos.current.set(...position);
|
lastGpsUpdatePos.current.set(...parkedPosition);
|
||||||
|
|
||||||
if (groupRef.current) {
|
if (groupRef.current) {
|
||||||
groupRef.current.position.set(...position);
|
groupRef.current.position.set(...parkedPosition);
|
||||||
groupRef.current.rotation.set(0, EBIKE_WORLD_ROTATION_Y, 0);
|
groupRef.current.rotation.set(0, EBIKE_WORLD_ROTATION_Y, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.ebikeParkedPosition = position;
|
window.ebikeParkedPosition = parkedPosition;
|
||||||
window.ebikeParkedRotation = EBIKE_WORLD_ROTATION_Y;
|
window.ebikeParkedRotation = EBIKE_WORLD_ROTATION_Y;
|
||||||
}, [movementMode, position]);
|
}, [movementMode, parkedPosition]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (model) {
|
if (model) {
|
||||||
@@ -293,7 +313,7 @@ export function Ebike({ position }: EbikeProps): React.JSX.Element {
|
|||||||
{!repairGameOwnsEbikeModel ? (
|
{!repairGameOwnsEbikeModel ? (
|
||||||
<group
|
<group
|
||||||
ref={groupRef}
|
ref={groupRef}
|
||||||
position={position}
|
position={parkedPosition}
|
||||||
rotation={[0, EBIKE_WORLD_ROTATION_Y, 0]}
|
rotation={[0, EBIKE_WORLD_ROTATION_Y, 0]}
|
||||||
scale={EBIKE_WORLD_SCALE}
|
scale={EBIKE_WORLD_SCALE}
|
||||||
>
|
>
|
||||||
@@ -301,7 +321,7 @@ export function Ebike({ position }: EbikeProps): React.JSX.Element {
|
|||||||
<InteractableObject
|
<InteractableObject
|
||||||
kind="trigger"
|
kind="trigger"
|
||||||
label={interactionLabel}
|
label={interactionLabel}
|
||||||
position={position}
|
position={parkedPosition}
|
||||||
radius={5}
|
radius={5}
|
||||||
onPress={handleInteract}
|
onPress={handleInteract}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const EBIKE_DROP_PLAYER_TRANSFORM: CameraTransform = {
|
|||||||
rotation: [0, 0, 0],
|
rotation: [0, 0, 0],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EBIKE_WORLD_POSITION: Vector3Tuple = [57.9, 6.3, 58.35];
|
export const EBIKE_WORLD_POSITION: Vector3Tuple = [65, 0.8, 72];
|
||||||
export const EBIKE_WORLD_ROTATION_Y = -2.5;
|
export const EBIKE_WORLD_ROTATION_Y = -2.5;
|
||||||
export const EBIKE_WORLD_SCALE = 0.35;
|
export const EBIKE_WORLD_SCALE = 0.35;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export const PLAYER_EYE_HEIGHT = 1.75;
|
|||||||
export const PLAYER_CAPSULE_RADIUS = 0.35;
|
export const PLAYER_CAPSULE_RADIUS = 0.35;
|
||||||
|
|
||||||
export const PLAYER_WALK_SPEED = 5;
|
export const PLAYER_WALK_SPEED = 5;
|
||||||
export const PLAYER_EBIKE_SPEED = 20;
|
export const PLAYER_EBIKE_SPEED = 30;
|
||||||
export const PLAYER_AIR_CONTROL_FACTOR = 0.35;
|
export const PLAYER_AIR_CONTROL_FACTOR = 0.35;
|
||||||
export const PLAYER_JUMP_SPEED = 9;
|
export const PLAYER_JUMP_SPEED = 9;
|
||||||
export const PLAYER_GRAVITY = 30;
|
export const PLAYER_GRAVITY = 30;
|
||||||
@@ -16,8 +16,8 @@ export const PLAYER_FALL_RESPAWN_Y = -20;
|
|||||||
export const PLAYER_FALL_RESPAWN_DELAY = 3;
|
export const PLAYER_FALL_RESPAWN_DELAY = 3;
|
||||||
|
|
||||||
export const PLAYER_SPAWN_POSITION_GAME: Vector3Tuple = [
|
export const PLAYER_SPAWN_POSITION_GAME: Vector3Tuple = [
|
||||||
LA_FABRIK_PLAYER_SPAWN[0] + 5,
|
LA_FABRIK_PLAYER_SPAWN[0] + 1,
|
||||||
LA_FABRIK_PLAYER_SPAWN[1],
|
LA_FABRIK_PLAYER_SPAWN[1],
|
||||||
LA_FABRIK_PLAYER_SPAWN[2] + 5,
|
LA_FABRIK_PLAYER_SPAWN[2] - 1,
|
||||||
];
|
];
|
||||||
export const PLAYER_SPAWN_POSITION_PHYSICS: Vector3Tuple = [0, 3, 0];
|
export const PLAYER_SPAWN_POSITION_PHYSICS: Vector3Tuple = [0, 3, 0];
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ export const LA_FABRIK_HALF_EXTENTS = {
|
|||||||
x: 8.5,
|
x: 8.5,
|
||||||
z: 7.5,
|
z: 7.5,
|
||||||
} as const;
|
} as const;
|
||||||
export const LA_FABRIK_PLAYER_SPAWN: Vector3Tuple = [59.5, 7.8, 64.64];
|
export const LA_FABRIK_PLAYER_SPAWN: Vector3Tuple = [59.5, 6.3, 64.64];
|
||||||
export const LA_FABRIK_INITIAL_LOOK_AT: Vector3Tuple = [58, 7.8, 62.5];
|
export const LA_FABRIK_INITIAL_LOOK_AT: Vector3Tuple = [58, 7.3, 62.5];
|
||||||
export const LA_FABRIK_INTERIOR_LIGHT_POSITION: Vector3Tuple = [59.5, 9, 64.64];
|
export const LA_FABRIK_INTERIOR_LIGHT_POSITION: Vector3Tuple = [59.5, 9, 64.64];
|
||||||
|
|
||||||
export function isInsideLaFabrikFootprint(
|
export function isInsideLaFabrikFootprint(
|
||||||
|
|||||||
Reference in New Issue
Block a user