fix: close phase 2 journey blockers
This commit is contained in:
@@ -121,7 +121,10 @@ export function createSceneController(options: SceneControllerOptions): SceneCon
|
||||
rootResources.releaseAnimationFrame(frameId);
|
||||
if (overlay !== 'active' || machine.snapshot().kind !== 'running' || !current) return;
|
||||
try {
|
||||
const frameStartedAt = scheduler.now();
|
||||
current.runtime.render(latestJourney, now);
|
||||
const frameEndedAt = scheduler.now();
|
||||
options.onFrameRendered?.(frameStartedAt, frameEndedAt);
|
||||
} catch {
|
||||
enterStatic('render-failure');
|
||||
return;
|
||||
@@ -332,7 +335,7 @@ export function createSceneController(options: SceneControllerOptions): SceneCon
|
||||
pauseReason = 'freeze';
|
||||
break;
|
||||
case 'paused':
|
||||
pauseReason = 'freeze';
|
||||
if (pauseReason !== 'visitor') pauseReason = 'freeze';
|
||||
break;
|
||||
case 'lost':
|
||||
clearRestoreWatchdog();
|
||||
@@ -351,11 +354,17 @@ export function createSceneController(options: SceneControllerOptions): SceneCon
|
||||
const persisted = Boolean((event as Event & { persisted?: boolean }).persisted);
|
||||
if (!persisted || overlay !== 'frozen') return;
|
||||
overlay = 'active';
|
||||
const lifecycle = machine.snapshot();
|
||||
if (!(options.motionAllowed?.() ?? true)) {
|
||||
if (
|
||||
lifecycle.kind === 'paused'
|
||||
&& current !== null
|
||||
&& !lifecycle.resumeNeedsLoad
|
||||
&& pauseReason === 'visitor'
|
||||
) return;
|
||||
enterStatic('motion-disallowed');
|
||||
return;
|
||||
}
|
||||
const lifecycle = machine.snapshot();
|
||||
if (page.visibilityState !== 'visible') return;
|
||||
if (lifecycle.kind === 'paused' && pauseReason === 'freeze') {
|
||||
pauseReason = null;
|
||||
|
||||
@@ -52,6 +52,7 @@ export interface SceneControllerOptions {
|
||||
scheduler?: SceneScheduler;
|
||||
page?: ScenePageEnvironment;
|
||||
motionAllowed?: () => boolean;
|
||||
onFrameRendered?: ((start: number, end: number) => unknown) | undefined;
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,11 @@ import type { SceneResourceBag } from '@/scene/resources';
|
||||
|
||||
export function createCar(resources: SceneResourceBag) {
|
||||
const group = new THREE.Group();
|
||||
group.position.set(0, 0.72, 4.4);
|
||||
group.position.set(0, 0.69, 0.5);
|
||||
group.scale.set(0.9, 0.65, 0.78);
|
||||
|
||||
const bodyMaterial = resources.own('material', new THREE.MeshStandardMaterial({
|
||||
color: 0x111722,
|
||||
color: 0x202938,
|
||||
roughness: 0.28,
|
||||
metalness: 0.78,
|
||||
}));
|
||||
@@ -16,6 +17,12 @@ export function createCar(resources: SceneResourceBag) {
|
||||
metalness: 0.35,
|
||||
}));
|
||||
const tailMaterial = resources.own('material', new THREE.MeshBasicMaterial({ color: 0xff315f }));
|
||||
const silhouetteMaterial = resources.own('material', new THREE.MeshBasicMaterial({ color: 0x405875 }));
|
||||
const fasciaMaterial = resources.own('material', new THREE.MeshStandardMaterial({
|
||||
color: 0x151c28,
|
||||
roughness: 0.42,
|
||||
metalness: 0.62,
|
||||
}));
|
||||
const underglowMaterial = resources.own('material', new THREE.MeshBasicMaterial({
|
||||
color: 0x28d8ef,
|
||||
transparent: true,
|
||||
@@ -39,6 +46,38 @@ export function createCar(resources: SceneResourceBag) {
|
||||
rearLight.position.set(0, 0.04, 3.08);
|
||||
group.add(rearLight);
|
||||
|
||||
const rearProfile = new THREE.Shape();
|
||||
rearProfile.moveTo(-2.5, -0.32);
|
||||
rearProfile.lineTo(-2.32, 0.28);
|
||||
rearProfile.lineTo(-1.42, 0.72);
|
||||
rearProfile.lineTo(1.42, 0.72);
|
||||
rearProfile.lineTo(2.32, 0.28);
|
||||
rearProfile.lineTo(2.5, -0.32);
|
||||
rearProfile.closePath();
|
||||
const silhouetteGeometry = resources.own('geometry', new THREE.ShapeGeometry(rearProfile));
|
||||
const silhouette = new THREE.Mesh(silhouetteGeometry, silhouetteMaterial);
|
||||
silhouette.name = 'rear-silhouette';
|
||||
silhouette.position.z = 2.98;
|
||||
group.add(silhouette);
|
||||
|
||||
const fasciaGeometry = resources.own('geometry', new THREE.BoxGeometry(4.3, 0.38, 0.22));
|
||||
const fascia = new THREE.Mesh(fasciaGeometry, fasciaMaterial);
|
||||
fascia.position.set(0, -0.12, 2.94);
|
||||
group.add(fascia);
|
||||
|
||||
const shoulderGeometry = resources.own('geometry', new THREE.BoxGeometry(5.05, 0.18, 1.1));
|
||||
const shoulders = new THREE.Mesh(shoulderGeometry, bodyMaterial);
|
||||
shoulders.position.set(0, 0.18, 2.48);
|
||||
group.add(shoulders);
|
||||
|
||||
const accentMaterial = resources.own('material', new THREE.MeshBasicMaterial({ color: 0x28d8ef }));
|
||||
const accentGeometry = resources.own('geometry', new THREE.BoxGeometry(0.36, 0.1, 0.08));
|
||||
for (const x of [-2.02, 2.02]) {
|
||||
const accent = new THREE.Mesh(accentGeometry, accentMaterial);
|
||||
accent.position.set(x, -0.15, 3.11);
|
||||
group.add(accent);
|
||||
}
|
||||
|
||||
const glowGeometry = resources.own('geometry', new THREE.PlaneGeometry(4.2, 6.2));
|
||||
const underglow = new THREE.Mesh(glowGeometry, underglowMaterial);
|
||||
underglow.rotation.x = -Math.PI / 2;
|
||||
@@ -60,7 +99,7 @@ export function createCar(resources: SceneResourceBag) {
|
||||
group,
|
||||
update(speed: number, acceleration: number, elapsedSeconds: number) {
|
||||
const response = Math.min(1, Math.max(0, acceleration));
|
||||
group.position.y = 0.72 + Math.sin(elapsedSeconds * (2.2 + speed)) * (0.012 + response * 0.018);
|
||||
group.position.y = 0.69 + Math.sin(elapsedSeconds * (2.2 + speed)) * (0.012 + response * 0.018);
|
||||
group.rotation.z = Math.sin(elapsedSeconds * 1.4) * 0.003 * response;
|
||||
tailMaterial.color.setRGB(1, 0.12 + response * 0.08, 0.28 + response * 0.08);
|
||||
underglowMaterial.opacity = 0.32 + Math.min(0.3, speed * 0.2);
|
||||
|
||||
@@ -19,6 +19,13 @@ const skyColors: Readonly<Record<EnvironmentChapter, number>> = {
|
||||
destination: 0x2b2035,
|
||||
};
|
||||
|
||||
export function createChaseCamera(aspect = 1) {
|
||||
const camera = new THREE.PerspectiveCamera(52, aspect, 0.1, 320);
|
||||
camera.position.set(0, 4.8, 12.5);
|
||||
camera.lookAt(0, 1.6, -22);
|
||||
return camera;
|
||||
}
|
||||
|
||||
export async function createProceduralSceneGeneration(
|
||||
context: SceneBuildContext,
|
||||
): Promise<SceneGeneration> {
|
||||
@@ -42,9 +49,7 @@ export async function createProceduralSceneGeneration(
|
||||
const background = new THREE.Color(skyColors['deep-night']);
|
||||
scene.background = background;
|
||||
scene.fog = new THREE.FogExp2(0x080c18, 0.012);
|
||||
const camera = new THREE.PerspectiveCamera(52, 1, 0.1, 320);
|
||||
camera.position.set(0, 4.8, 12.5);
|
||||
camera.lookAt(0, 1.6, -22);
|
||||
const camera = createChaseCamera();
|
||||
|
||||
const ambient = new THREE.HemisphereLight(0x6aa9c5, 0x100812, 1.25);
|
||||
scene.add(ambient);
|
||||
|
||||
Reference in New Issue
Block a user