Feature: Camera cuts and jumping after music kicks in
This commit is contained in:
parent
98f5f77890
commit
6952e6463b
@ -3,40 +3,6 @@ import { state } from '../state.js';
|
||||
import { updateScreenEffect } from '../scene/magic-mirror.js'
|
||||
import sceneFeatureManager from '../scene/SceneFeatureManager.js';
|
||||
|
||||
function updateCamera() {
|
||||
const globalTime = Date.now() * 0.0001;
|
||||
const lookAtTime = Date.now() * 0.0002;
|
||||
|
||||
// Base Camera Position in front of the TV
|
||||
const baseX = 0;
|
||||
const baseY = 3.6;
|
||||
const baseZ = -5.0;
|
||||
const camAmplitude = new THREE.Vector3(1.0, 1.0, 6.0);
|
||||
|
||||
// Base LookAt target (Center of the screen)
|
||||
const baseTargetX = 0;
|
||||
const baseTargetY = 1.6;
|
||||
const baseTargetZ = -30.0;
|
||||
const lookAmplitude = 8.0;
|
||||
|
||||
// Camera Position Offsets (Drift)
|
||||
const camOffsetX = Math.sin(globalTime * 3.1) * camAmplitude.x;
|
||||
const camOffsetY = Math.cos(globalTime * 2.5) * camAmplitude.y;
|
||||
const camOffsetZ = Math.cos(globalTime * 3.2) * camAmplitude.z;
|
||||
|
||||
state.camera.position.x = baseX + camOffsetX;
|
||||
state.camera.position.y = baseY + camOffsetY;
|
||||
state.camera.position.z = baseZ + camOffsetZ;
|
||||
|
||||
// LookAt Target Offsets (Subtle Gaze Shift)
|
||||
const lookOffsetX = Math.sin(lookAtTime * 1.5) * lookAmplitude;
|
||||
const lookOffsetZ = Math.cos(lookAtTime * 2.5) * lookAmplitude;
|
||||
const lookOffsetY = Math.cos(lookAtTime * 1.2) * lookAmplitude * 0.5;
|
||||
|
||||
// Apply lookAt to the subtly shifted target
|
||||
state.camera.lookAt(baseTargetX + lookOffsetX, baseTargetY + lookOffsetY, baseTargetZ + lookOffsetZ);
|
||||
}
|
||||
|
||||
function updateScreenLight() {
|
||||
if (state.isVideoLoaded && state.screenLight.intensity > 0) {
|
||||
const pulseTarget = state.originalScreenIntensity + (Math.random() - 0.5) * state.screenIntensityPulse;
|
||||
@ -81,7 +47,6 @@ export function animate() {
|
||||
|
||||
sceneFeatureManager.update(deltaTime);
|
||||
state.effectsManager.update();
|
||||
updateCamera();
|
||||
updateScreenLight();
|
||||
updateVideo();
|
||||
updateShaderTime();
|
||||
|
||||
142
party-cathedral/src/scene/camera-manager.js
Normal file
142
party-cathedral/src/scene/camera-manager.js
Normal file
@ -0,0 +1,142 @@
|
||||
import * as THREE from 'three';
|
||||
import { state } from '../state.js';
|
||||
import { SceneFeature } from './SceneFeature.js';
|
||||
import sceneFeatureManager from './SceneFeatureManager.js';
|
||||
|
||||
const minSwitchInterval = 2;
|
||||
const maxSwitchInterval = 10;
|
||||
|
||||
export class CameraManager extends SceneFeature {
|
||||
constructor() {
|
||||
super();
|
||||
this.cameras = [];
|
||||
this.activeCameraIndex = 0;
|
||||
this.switchInterval = 10; // seconds
|
||||
this.lastSwitchTime = 0;
|
||||
sceneFeatureManager.register(this);
|
||||
}
|
||||
|
||||
init() {
|
||||
// The main camera from init.js is our first camera
|
||||
const mainCamera = state.camera;
|
||||
this.cameras.push({
|
||||
camera: mainCamera,
|
||||
type: 'dynamic',
|
||||
name: 'MainDynamicCamera',
|
||||
update: this.updateDynamicCamera, // Assign its update function
|
||||
});
|
||||
|
||||
// --- Static Camera 1: Left Aisle View ---
|
||||
const staticCam1 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
|
||||
staticCam1.position.set(-5, 3, -13);
|
||||
staticCam1.lookAt(0, 2, -18); // Look at the stage
|
||||
this.cameras.push({
|
||||
camera: staticCam1,
|
||||
type: 'static',
|
||||
name: 'LeftAisleCam'
|
||||
});
|
||||
|
||||
// --- Static Camera 2: Right Aisle View ---
|
||||
const staticCam2 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
|
||||
staticCam2.position.set(5, 4, -12);
|
||||
staticCam2.lookAt(0, 1.5, -18); // Look at the stage
|
||||
this.cameras.push({
|
||||
camera: staticCam2,
|
||||
type: 'static',
|
||||
name: 'RightAisleCam'
|
||||
});
|
||||
|
||||
// --- Static Camera 3: Far-Back view ---
|
||||
const staticCam3 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
|
||||
staticCam3.position.set(0, 3, 12);
|
||||
staticCam3.lookAt(0, 1.5, -20); // Look at the stage
|
||||
this.cameras.push({
|
||||
camera: staticCam3,
|
||||
type: 'static',
|
||||
name: 'BackCam'
|
||||
});
|
||||
|
||||
// --- Static Camera 3: Back view ---
|
||||
const staticCam4 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
|
||||
staticCam4.position.set(0, 4, 0);
|
||||
staticCam4.lookAt(0, 1.5, -20); // Look at the stage
|
||||
this.cameras.push({
|
||||
camera: staticCam4,
|
||||
type: 'static',
|
||||
name: 'BackCam'
|
||||
});
|
||||
|
||||
// --- Add Debug Helpers ---
|
||||
if (state.debugCamera) {
|
||||
this.cameras.forEach(camData => {
|
||||
const helper = new THREE.CameraHelper(camData.camera);
|
||||
state.scene.add(helper);
|
||||
});
|
||||
}
|
||||
|
||||
this.lastSwitchTime = state.clock.getElapsedTime();
|
||||
this.switchCamera(4);
|
||||
}
|
||||
|
||||
// This is the logic moved from animate.js
|
||||
updateDynamicCamera() {
|
||||
const globalTime = Date.now() * 0.0001;
|
||||
const lookAtTime = Date.now() * 0.0002;
|
||||
|
||||
const baseX = 0, baseY = 3.6, baseZ = -5.0;
|
||||
const camAmplitude = new THREE.Vector3(1.0, 1.0, 6.0);
|
||||
|
||||
const baseTargetX = 0, baseTargetY = 1.6, baseTargetZ = -30.0;
|
||||
const lookAmplitude = 8.0;
|
||||
|
||||
const camOffsetX = Math.sin(globalTime * 3.1) * camAmplitude.x;
|
||||
const camOffsetY = Math.cos(globalTime * 2.5) * camAmplitude.y;
|
||||
const camOffsetZ = Math.cos(globalTime * 3.2) * camAmplitude.z;
|
||||
|
||||
state.camera.position.x = baseX + camOffsetX;
|
||||
state.camera.position.y = baseY + camOffsetY;
|
||||
state.camera.position.z = baseZ + camOffsetZ;
|
||||
|
||||
const lookOffsetX = Math.sin(lookAtTime * 1.5) * lookAmplitude;
|
||||
const lookOffsetZ = Math.cos(lookAtTime * 2.5) * lookAmplitude;
|
||||
const lookOffsetY = Math.cos(lookAtTime * 1.2) * lookAmplitude * 0.5;
|
||||
|
||||
state.camera.lookAt(baseTargetX + lookOffsetX, baseTargetY + lookOffsetY, baseTargetZ + lookOffsetZ);
|
||||
}
|
||||
|
||||
switchCamera(index) {
|
||||
if (index >= this.cameras.length || index < 0) return;
|
||||
|
||||
this.activeCameraIndex = index;
|
||||
const newCam = this.cameras[this.activeCameraIndex].camera;
|
||||
|
||||
// Copy properties from the new camera to the main state camera
|
||||
state.camera.position.copy(newCam.position);
|
||||
state.camera.rotation.copy(newCam.rotation);
|
||||
state.camera.fov = newCam.fov;
|
||||
state.camera.aspect = newCam.aspect;
|
||||
state.camera.near = newCam.near;
|
||||
state.camera.far = newCam.far;
|
||||
state.camera.updateProjectionMatrix();
|
||||
}
|
||||
|
||||
update(deltaTime) {
|
||||
const time = state.clock.getElapsedTime();
|
||||
|
||||
// Handle camera switching
|
||||
if (time > this.lastSwitchTime + this.switchInterval) {
|
||||
const newIndex = Math.floor(Math.random() * this.cameras.length);
|
||||
this.switchCamera(newIndex);
|
||||
this.lastSwitchTime = time;
|
||||
this.switchInterval = minSwitchInterval + Math.random() * (maxSwitchInterval - minSwitchInterval);
|
||||
}
|
||||
|
||||
// Update the currently active camera if it has an update function
|
||||
const activeCamData = this.cameras[this.activeCameraIndex];
|
||||
if (activeCamData.update) {
|
||||
activeCamData.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new CameraManager();
|
||||
@ -169,7 +169,8 @@ export class Dancers extends SceneFeature {
|
||||
mesh.position.y = dancerObj.baseY;
|
||||
}
|
||||
} else {
|
||||
if (state.music && state.music.beatIntensity > 0.8 && Math.random() < 0.2) {
|
||||
const musicTime = state.clock.getElapsedTime();
|
||||
if (state.music && state.music.beatIntensity > 0.8 && Math.random() < 0.2 && musicTime > 10) {
|
||||
dancerObj.isJumping = true;
|
||||
dancerObj.jumpStartTime = time;
|
||||
}
|
||||
|
||||
@ -259,7 +259,8 @@ export class MedievalMusicians extends SceneFeature {
|
||||
}
|
||||
} else {
|
||||
let currentJumpChance = jumpChance * deltaTime; // Base chance over time
|
||||
if (state.music && state.music.beatIntensity > 0.8) {
|
||||
const musicTime = state.clock.getElapsedTime();
|
||||
if (state.music && state.music.beatIntensity > 0.8 && musicTime > 15) {
|
||||
currentJumpChance = 0.1; // High, fixed chance on the beat
|
||||
}
|
||||
|
||||
|
||||
@ -69,7 +69,7 @@ export class PartyGuests extends SceneFeature {
|
||||
const pos = new THREE.Vector3(
|
||||
(Math.random() - 0.5) * 10,
|
||||
guestHeight / 2,
|
||||
(Math.random() * 20) - 6 // Position them in the main hall
|
||||
(Math.random() * 20) - 2 // Position them in the main hall
|
||||
);
|
||||
guest.position.copy(pos);
|
||||
state.scene.add(guest);
|
||||
@ -99,7 +99,7 @@ export class PartyGuests extends SceneFeature {
|
||||
|
||||
const time = state.clock.getElapsedTime();
|
||||
const moveSpeed = 1.0; // Move slower
|
||||
const movementArea = { x: 10, z: 30, y: 0, centerZ: 5 };
|
||||
const movementArea = { x: 10, z: 30, y: 0, centerZ: 2 };
|
||||
const jumpChance = 0.05; // Jump way more
|
||||
const jumpDuration = 0.5;
|
||||
const jumpHeight = 0.1;
|
||||
|
||||
@ -3,6 +3,7 @@ import { state } from '../state.js';
|
||||
import floorTextureUrl from '/textures/stone_floor.png';
|
||||
import sceneFeatureManager from './SceneFeatureManager.js';
|
||||
// Scene Features registered here:
|
||||
import { CameraManager } from './camera-manager.js';
|
||||
import { RoomWalls } from './room-walls.js';
|
||||
import { LightBall } from './light-ball.js';
|
||||
import { Pews } from './pews.js';
|
||||
@ -14,7 +15,6 @@ import { Dancers } from './dancers.js';
|
||||
import { MusicVisualizer } from './music-visualizer.js';
|
||||
import { RoseWindowLight } from './rose-window-light.js';
|
||||
import { RoseWindowLightshafts } from './rose-window-lightshafts.js';
|
||||
|
||||
// Scene Features ^^^
|
||||
|
||||
// --- Scene Modeling Function ---
|
||||
|
||||
@ -36,7 +36,8 @@ export function initState() {
|
||||
screenIntensityPulse: 0.2,
|
||||
roomSize: 5,
|
||||
roomHeight: 3,
|
||||
debugLight: false,
|
||||
debugLight: false, // Turn on light helpers
|
||||
debugCamera: false, // Turn on camera helpers
|
||||
|
||||
// DOM Elements
|
||||
container: document.body,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user