finalised, bold and innovation fixed
This commit is contained in:
parent
ae39d5bbf4
commit
8390ac15b1
Binary file not shown.
201
src/main.js
201
src/main.js
|
@ -25,20 +25,24 @@ class SceneLoader {
|
||||||
this.loadedCount = 0;
|
this.loadedCount = 0;
|
||||||
this.totalModels = this.modelsToLoad.length;
|
this.totalModels = this.modelsToLoad.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoadingMessage(message) {
|
setLoadingMessage(message) {
|
||||||
this.loadingText.textContent = message;
|
this.loadingText.textContent = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProgress(progress) {
|
updateProgress(progress) {
|
||||||
const percentage = Math.round(progress * 100);
|
const percentage = Math.round(progress * 100);
|
||||||
this.loadingProgressBar.style.width = `${percentage}%`;
|
this.loadingProgressBar.style.width = `${percentage}%`;
|
||||||
this.loadingPercentage.textContent = `${percentage}%`;
|
this.loadingPercentage.textContent = `${percentage}%`;
|
||||||
}
|
}
|
||||||
|
|
||||||
hideLoadingScreen() {
|
hideLoadingScreen() {
|
||||||
this.loadingScreen.classList.add('hidden');
|
this.loadingScreen.classList.add('hidden');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.loadingScreen.style.display = 'none';
|
this.loadingScreen.style.display = 'none';
|
||||||
}, 800);
|
}, 800);
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadAllModels() {
|
async loadAllModels() {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const loader = new GLTFLoader();
|
const loader = new GLTFLoader();
|
||||||
|
@ -113,6 +117,9 @@ let mixer = null;
|
||||||
let nextMixer = null;
|
let nextMixer = null;
|
||||||
let autoRotationAngle = 0;
|
let autoRotationAngle = 0;
|
||||||
|
|
||||||
|
// Turntable animation settings
|
||||||
|
const turntableSpeed = 0.5; // Rotation speed (radians per second)
|
||||||
|
|
||||||
// Store preloaded models
|
// Store preloaded models
|
||||||
let preloadedModels = {};
|
let preloadedModels = {};
|
||||||
|
|
||||||
|
@ -120,7 +127,7 @@ let preloadedModels = {};
|
||||||
let boldRoughnessAnimation = {
|
let boldRoughnessAnimation = {
|
||||||
isActive: false,
|
isActive: false,
|
||||||
startTime: 0,
|
startTime: 0,
|
||||||
delayDuration: 1.0, // 1 second delay
|
delayDuration: 1.0, // 1 second delay (will be dynamic)
|
||||||
transitionDuration: 1.0, // 1 second transition
|
transitionDuration: 1.0, // 1 second transition
|
||||||
startRoughness: 0.5,
|
startRoughness: 0.5,
|
||||||
endRoughness: 0.05,
|
endRoughness: 0.05,
|
||||||
|
@ -225,12 +232,14 @@ const controls = new OrbitControls(camera, renderer.domElement);
|
||||||
controls.enableDamping = true;
|
controls.enableDamping = true;
|
||||||
controls.dampingFactor = 0.25;
|
controls.dampingFactor = 0.25;
|
||||||
controls.enableZoom = false; // Disable zoom
|
controls.enableZoom = false; // Disable zoom
|
||||||
|
|
||||||
// Add camera constraints to prevent extreme angles
|
// Add camera constraints to prevent extreme angles
|
||||||
controls.maxPolarAngle = Math.PI * 0.8; // Prevent looking too far up
|
controls.maxPolarAngle = Math.PI * 0.8; // Prevent looking too far up
|
||||||
controls.minPolarAngle = Math.PI * 0.2; // Prevent looking too far down
|
controls.minPolarAngle = Math.PI * 0.2; // Prevent looking too far down
|
||||||
console.log('Orbit controls initialized with camera constraints');
|
console.log('Orbit controls initialized with camera constraints');
|
||||||
|
|
||||||
// Material definitions
|
// Material definitions
|
||||||
|
|
||||||
// Bold glass material (starts rough, will transition to clear)
|
// Bold glass material (starts rough, will transition to clear)
|
||||||
const boldGlassMaterial = new THREE.MeshPhysicalMaterial({
|
const boldGlassMaterial = new THREE.MeshPhysicalMaterial({
|
||||||
color: 0xffffff,
|
color: 0xffffff,
|
||||||
|
@ -314,36 +323,29 @@ function calculateTransitionVectors() {
|
||||||
// Get camera's world direction
|
// Get camera's world direction
|
||||||
const cameraDirection = new THREE.Vector3();
|
const cameraDirection = new THREE.Vector3();
|
||||||
camera.getWorldDirection(cameraDirection);
|
camera.getWorldDirection(cameraDirection);
|
||||||
|
|
||||||
// Get world up vector
|
// Get world up vector
|
||||||
const worldUp = new THREE.Vector3(0, 1, 0);
|
const worldUp = new THREE.Vector3(0, 1, 0);
|
||||||
|
|
||||||
// Calculate camera's left vector - BACK TO ORIGINAL (this gave correct left direction)
|
// Calculate camera's left vector - BACK TO ORIGINAL (this gave correct left direction)
|
||||||
const cameraLeft = new THREE.Vector3();
|
const cameraLeft = new THREE.Vector3();
|
||||||
cameraLeft.crossVectors(worldUp, cameraDirection).normalize();
|
cameraLeft.crossVectors(worldUp, cameraDirection).normalize();
|
||||||
|
|
||||||
// Calculate camera's local up vector
|
// Calculate camera's local up vector
|
||||||
const cameraUp = new THREE.Vector3();
|
const cameraUp = new THREE.Vector3();
|
||||||
cameraUp.crossVectors(cameraLeft, cameraDirection).normalize();
|
cameraUp.crossVectors(cameraLeft, cameraDirection).normalize();
|
||||||
|
|
||||||
// Blend camera up with world up - BUT NEGATE to flip up/down direction
|
// Blend camera up with world up - BUT NEGATE to flip up/down direction
|
||||||
const blendedUp = new THREE.Vector3();
|
const blendedUp = new THREE.Vector3();
|
||||||
blendedUp.addVectors(
|
blendedUp.addVectors(
|
||||||
cameraUp.clone().multiplyScalar(0.5),
|
cameraUp.clone().multiplyScalar(0.5),
|
||||||
worldUp.clone().multiplyScalar(0.5)
|
worldUp.clone().multiplyScalar(0.5)
|
||||||
).normalize().negate(); // ADD .negate() here to flip up to down
|
).normalize().negate(); // ADD .negate() here to flip up to down
|
||||||
|
// Create diagonal vector (up-left)
|
||||||
// Create diagonal vector (up-left)
|
|
||||||
const diagonalUpLeft = new THREE.Vector3();
|
const diagonalUpLeft = new THREE.Vector3();
|
||||||
diagonalUpLeft.addVectors(
|
diagonalUpLeft.addVectors(
|
||||||
blendedUp.clone().multiplyScalar(0.5),
|
blendedUp.clone().multiplyScalar(0.5),
|
||||||
cameraLeft.clone().multiplyScalar(0.5)
|
cameraLeft.clone().multiplyScalar(0.5)
|
||||||
).normalize();
|
).normalize();
|
||||||
|
|
||||||
// Set transition vectors
|
// Set transition vectors
|
||||||
transitionUpVector = diagonalUpLeft.clone().multiplyScalar(transitionDistance);
|
transitionUpVector = diagonalUpLeft.clone().multiplyScalar(transitionDistance);
|
||||||
transitionDownVector = diagonalUpLeft.clone().multiplyScalar(-transitionDistance);
|
transitionDownVector = diagonalUpLeft.clone().multiplyScalar(-transitionDistance);
|
||||||
|
|
||||||
console.log('Diagonal transition vectors calculated with distance:', transitionDistance);
|
console.log('Diagonal transition vectors calculated with distance:', transitionDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,27 +361,24 @@ function applyMaterials(model, modelType) {
|
||||||
object.castShadow = true;
|
object.castShadow = true;
|
||||||
object.receiveShadow = true;
|
object.receiveShadow = true;
|
||||||
if (modelType === 'bold') {
|
if (modelType === 'bold') {
|
||||||
// Bold-specific material logic - apply bold glass material to Cube mesh
|
// Bold-specific material logic
|
||||||
if (modelType === 'bold') {
|
if (object.name === 'Cube') {
|
||||||
// Bold-specific material logic
|
console.log(` → Applying bold glass material to "${object.name}"`);
|
||||||
if (object.name === 'Cube') {
|
object.material = boldGlassMaterial.clone();
|
||||||
console.log(` → Applying bold glass material to "${object.name}"`);
|
object.material.side = THREE.DoubleSide;
|
||||||
object.material = boldGlassMaterial.clone();
|
object.material.depthWrite = false;
|
||||||
object.material.side = THREE.DoubleSide;
|
object.renderOrder = 2;
|
||||||
object.material.depthWrite = false;
|
// Store material reference for roughness animation
|
||||||
object.renderOrder = 2;
|
boldRoughnessAnimation.materials.push(object.material);
|
||||||
// Store material reference for roughness animation
|
} else if (object.name === 'Cubewire') {
|
||||||
boldRoughnessAnimation.materials.push(object.material);
|
console.log(` → Applying wireframe material to "${object.name}"`);
|
||||||
} else if (object.name === 'Cubewire') {
|
object.material = boldWireframeMaterial.clone();
|
||||||
console.log(` → Applying wireframe material to "${object.name}"`);
|
object.renderOrder = 1;
|
||||||
object.material = boldWireframeMaterial.clone();
|
} else {
|
||||||
object.renderOrder = 1;
|
console.log(` → Applying bold glass material (fallback) to "${object.name}"`);
|
||||||
} else {
|
object.material = boldGlassMaterial.clone();
|
||||||
console.log(` → Applying bold glass material (fallback) to "${object.name}"`);
|
// Store material reference for roughness animation
|
||||||
object.material = boldGlassMaterial.clone();
|
boldRoughnessAnimation.materials.push(object.material);
|
||||||
// Store material reference for roughness animation
|
|
||||||
boldRoughnessAnimation.materials.push(object.material);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (modelType === 'innovation') {
|
} else if (modelType === 'innovation') {
|
||||||
// Innovation-specific material logic
|
// Innovation-specific material logic
|
||||||
|
@ -536,6 +535,21 @@ function createModelFromPreloaded(modelType) {
|
||||||
return { model, animMixer };
|
return { model, animMixer };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start/restart bold roughness animation with optional delay control
|
||||||
|
function startBoldRoughnessAnimation(withDelay = true) {
|
||||||
|
console.log('Starting/restarting bold roughness animation');
|
||||||
|
// Reset all bold glass materials to starting roughness value
|
||||||
|
boldRoughnessAnimation.materials.forEach(material => {
|
||||||
|
material.roughness = boldRoughnessAnimation.startRoughness;
|
||||||
|
material.needsUpdate = true;
|
||||||
|
});
|
||||||
|
boldRoughnessAnimation.isActive = true;
|
||||||
|
boldRoughnessAnimation.startTime = performance.now();
|
||||||
|
// Set delayDuration based on withDelay parameter
|
||||||
|
boldRoughnessAnimation.delayDuration = withDelay ? 1.0 : 0.0;
|
||||||
|
console.log('Bold roughness animation started with delay:', withDelay);
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize first scene after all models are loaded
|
// Initialize first scene after all models are loaded
|
||||||
function initializeScene() {
|
function initializeScene() {
|
||||||
console.log('Initializing first scene (bold)');
|
console.log('Initializing first scene (bold)');
|
||||||
|
@ -543,10 +557,9 @@ function initializeScene() {
|
||||||
currentModel = model;
|
currentModel = model;
|
||||||
mixer = animMixer;
|
mixer = animMixer;
|
||||||
scene.add(currentModel);
|
scene.add(currentModel);
|
||||||
// Start the roughness animation for bold scene
|
// Start the roughness animation for bold scene with delay
|
||||||
boldRoughnessAnimation.isActive = true;
|
startBoldRoughnessAnimation(true);
|
||||||
boldRoughnessAnimation.startTime = performance.now();
|
console.log('Bold scene initialized');
|
||||||
console.log('Bold scene initialized and roughness animation started');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start innovation glass animation
|
// Start innovation glass animation
|
||||||
|
@ -627,23 +640,18 @@ function startTransition(direction = 1) {
|
||||||
const { model, animMixer } = createModelFromPreloaded(nextModelType);
|
const { model, animMixer } = createModelFromPreloaded(nextModelType);
|
||||||
nextModel = model;
|
nextModel = model;
|
||||||
nextMixer = animMixer;
|
nextMixer = animMixer;
|
||||||
// Start next model at the diagonal down position (camera-relative)
|
// Position next model based on transition direction
|
||||||
nextModel.position.copy(transitionDownVector);
|
if (transitionDirection === 1) {
|
||||||
nextModel.traverse((obj) => {
|
// Forward: next model starts from diagonal down position (bottom-right)
|
||||||
if (obj.material) {
|
nextModel.position.copy(transitionDownVector);
|
||||||
if (Array.isArray(obj.material)) {
|
console.log(`Next model positioned at diagonal down vector (bottom-right): x=${nextModel.position.x}, y=${nextModel.position.y}, z=${nextModel.position.z}`);
|
||||||
obj.material.forEach(mat => {
|
} else {
|
||||||
mat.transparent = true;
|
// Backward: next model starts from diagonal up position (top-left)
|
||||||
mat.opacity = 0;
|
nextModel.position.copy(transitionUpVector);
|
||||||
});
|
console.log(`Next model positioned at diagonal up vector (top-left): x=${nextModel.position.x}, y=${nextModel.position.y}, z=${nextModel.position.z}`);
|
||||||
} else {
|
}
|
||||||
obj.material.transparent = true;
|
// Add next model to scene without opacity changes - it will appear instantly when it enters the camera view
|
||||||
obj.material.opacity = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
scene.add(nextModel);
|
scene.add(nextModel);
|
||||||
console.log(`Next model positioned at diagonal down vector: x=${nextModel.position.x}, y=${nextModel.position.y}, z=${nextModel.position.z}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -656,42 +664,32 @@ function updateTransition(deltaTime) {
|
||||||
const easeInOut = (t) => t * t * (3 - 2 * t);
|
const easeInOut = (t) => t * t * (3 - 2 * t);
|
||||||
const easedProgress = easeInOut(transitionProgress);
|
const easedProgress = easeInOut(transitionProgress);
|
||||||
if (currentModel) {
|
if (currentModel) {
|
||||||
// Move current model along diagonal up-left vector
|
// Move current model along diagonal vector based on transition direction
|
||||||
const moveVector = transitionUpVector.clone().multiplyScalar(easedProgress);
|
let moveVector;
|
||||||
|
if (transitionDirection === 1) {
|
||||||
|
// Forward: current model moves top-left
|
||||||
|
moveVector = transitionUpVector.clone().multiplyScalar(easedProgress);
|
||||||
|
console.log('Current model moving top-left (forward transition)');
|
||||||
|
} else {
|
||||||
|
// Backward: current model moves bottom-right
|
||||||
|
moveVector = transitionDownVector.clone().multiplyScalar(easedProgress);
|
||||||
|
console.log('Current model moving bottom-right (backward transition)');
|
||||||
|
}
|
||||||
currentModel.position.copy(moveVector);
|
currentModel.position.copy(moveVector);
|
||||||
currentModel.traverse((obj) => {
|
|
||||||
if (obj.material) {
|
|
||||||
const targetOpacity = 1 - easedProgress;
|
|
||||||
if (Array.isArray(obj.material)) {
|
|
||||||
obj.material.forEach(mat => {
|
|
||||||
mat.transparent = true;
|
|
||||||
mat.opacity = targetOpacity;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
obj.material.transparent = true;
|
|
||||||
obj.material.opacity = targetOpacity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (nextModel) {
|
if (nextModel) {
|
||||||
// Move next model from diagonal down-left vector to center (0,0,0)
|
// Move next model from diagonal vector to center based on transition direction
|
||||||
const moveVector = transitionDownVector.clone().multiplyScalar(1 - easedProgress);
|
let moveVector;
|
||||||
|
if (transitionDirection === 1) {
|
||||||
|
// Forward: next model moves from bottom-right to center
|
||||||
|
moveVector = transitionDownVector.clone().multiplyScalar(1 - easedProgress);
|
||||||
|
console.log('Next model moving from bottom-right to center (forward transition)');
|
||||||
|
} else {
|
||||||
|
// Backward: next model moves from top-left to center
|
||||||
|
moveVector = transitionUpVector.clone().multiplyScalar(1 - easedProgress);
|
||||||
|
console.log('Next model moving from top-left to center (backward transition)');
|
||||||
|
}
|
||||||
nextModel.position.copy(moveVector);
|
nextModel.position.copy(moveVector);
|
||||||
nextModel.traverse((obj) => {
|
|
||||||
if (obj.material) {
|
|
||||||
const targetOpacity = easedProgress;
|
|
||||||
if (Array.isArray(obj.material)) {
|
|
||||||
obj.material.forEach(mat => {
|
|
||||||
mat.transparent = true;
|
|
||||||
mat.opacity = targetOpacity;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
obj.material.transparent = true;
|
|
||||||
obj.material.opacity = targetOpacity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
// Complete transition
|
// Complete transition
|
||||||
if (transitionProgress >= 1) {
|
if (transitionProgress >= 1) {
|
||||||
|
@ -713,29 +711,8 @@ function updateTransition(deltaTime) {
|
||||||
if (nextModel) {
|
if (nextModel) {
|
||||||
currentModel = nextModel;
|
currentModel = nextModel;
|
||||||
mixer = nextMixer;
|
mixer = nextMixer;
|
||||||
// Reset position and opacity
|
// Reset position to center
|
||||||
currentModel.position.set(0, 0, 0);
|
currentModel.position.set(0, 0, 0);
|
||||||
currentModel.traverse((obj) => {
|
|
||||||
if (obj.material) {
|
|
||||||
if (Array.isArray(obj.material)) {
|
|
||||||
obj.material.forEach(mat => {
|
|
||||||
mat.opacity = 1;
|
|
||||||
if (currentScene + transitionDirection === 3) { // Keep transparency for storytelling glass
|
|
||||||
mat.transparent = mat.transmission > 0;
|
|
||||||
} else {
|
|
||||||
mat.transparent = mat.transmission > 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
obj.material.opacity = 1;
|
|
||||||
if (currentScene + transitionDirection === 3) { // Keep transparency for storytelling glass
|
|
||||||
obj.material.transparent = obj.material.transmission > 0;
|
|
||||||
} else {
|
|
||||||
obj.material.transparent = obj.material.transmission > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
nextModel = null;
|
nextModel = null;
|
||||||
nextMixer = null;
|
nextMixer = null;
|
||||||
|
@ -743,8 +720,11 @@ function updateTransition(deltaTime) {
|
||||||
currentScene += transitionDirection; // Update scene based on direction
|
currentScene += transitionDirection; // Update scene based on direction
|
||||||
scrollDownCount = 0;
|
scrollDownCount = 0;
|
||||||
scrollUpCount = 0;
|
scrollUpCount = 0;
|
||||||
// Start innovation glass animation if we're now in the innovation scene
|
// Start animations based on current scene
|
||||||
if (currentScene === 1) {
|
if (currentScene === 0) {
|
||||||
|
// Restart bold roughness animation when returning to bold section WITHOUT delay
|
||||||
|
startBoldRoughnessAnimation(false);
|
||||||
|
} else if (currentScene === 1) {
|
||||||
startInnovationGlassAnimation();
|
startInnovationGlassAnimation();
|
||||||
}
|
}
|
||||||
console.log(`Diagonal transition complete. Current scene: ${currentScene}`);
|
console.log(`Diagonal transition complete. Current scene: ${currentScene}`);
|
||||||
|
@ -785,6 +765,13 @@ function animate() {
|
||||||
if (isTransitioning) {
|
if (isTransitioning) {
|
||||||
updateTransition(delta);
|
updateTransition(delta);
|
||||||
}
|
}
|
||||||
|
// Turntable rotation animation
|
||||||
|
if (currentModel) {
|
||||||
|
currentModel.rotation.y += turntableSpeed * delta;
|
||||||
|
}
|
||||||
|
if (nextModel) {
|
||||||
|
nextModel.rotation.y += turntableSpeed * delta;
|
||||||
|
}
|
||||||
// Update bold roughness animation
|
// Update bold roughness animation
|
||||||
if (boldRoughnessAnimation.isActive) {
|
if (boldRoughnessAnimation.isActive) {
|
||||||
const elapsed = (performance.now() - boldRoughnessAnimation.startTime) / 1000;
|
const elapsed = (performance.now() - boldRoughnessAnimation.startTime) / 1000;
|
||||||
|
@ -795,7 +782,7 @@ function animate() {
|
||||||
// Smooth easing function (ease-in-out)
|
// Smooth easing function (ease-in-out)
|
||||||
const easeInOut = (t) => t * t * (3 - 2 * t);
|
const easeInOut = (t) => t * t * (3 - 2 * t);
|
||||||
const easedProgress = easeInOut(transitionProgress);
|
const easedProgress = easeInOut(transitionProgress);
|
||||||
// Interpolate roughness from 0.25 to 0.05
|
// Interpolate roughness from 0.5 to 0.05
|
||||||
const currentRoughness = boldRoughnessAnimation.startRoughness +
|
const currentRoughness = boldRoughnessAnimation.startRoughness +
|
||||||
(boldRoughnessAnimation.endRoughness - boldRoughnessAnimation.startRoughness) * easedProgress;
|
(boldRoughnessAnimation.endRoughness - boldRoughnessAnimation.startRoughness) * easedProgress;
|
||||||
// Apply to all bold materials
|
// Apply to all bold materials
|
||||||
|
|
Loading…
Reference in a new issue