all sections added
This commit is contained in:
parent
b18d4c090b
commit
44234d4ee8
BIN
public/bold.glb
Normal file
BIN
public/bold.glb
Normal file
Binary file not shown.
Binary file not shown.
135
src/main.js
135
src/main.js
|
@ -18,7 +18,7 @@ const raycaster = new THREE.Raycaster();
|
||||||
const mouse = new THREE.Vector2();
|
const mouse = new THREE.Vector2();
|
||||||
|
|
||||||
// Transition state management
|
// Transition state management
|
||||||
let currentScene = 0; // 0: innovation, 1: agility, 2: storytelling
|
let currentScene = 0; // 0: bold, 1: innovation, 2: agility, 3: storytelling
|
||||||
let isTransitioning = false;
|
let isTransitioning = false;
|
||||||
let isTwisting = false;
|
let isTwisting = false;
|
||||||
let twistProgress = 0;
|
let twistProgress = 0;
|
||||||
|
@ -39,6 +39,17 @@ let mixer = null;
|
||||||
let nextMixer = null;
|
let nextMixer = null;
|
||||||
let autoRotationAngle = 0;
|
let autoRotationAngle = 0;
|
||||||
|
|
||||||
|
// Bold scene roughness animation state
|
||||||
|
let boldRoughnessAnimation = {
|
||||||
|
isActive: false,
|
||||||
|
startTime: 0,
|
||||||
|
delayDuration: 1.0, // 1 second delay
|
||||||
|
transitionDuration: 1.0, // 1 second transition
|
||||||
|
startRoughness: 0.9,
|
||||||
|
endRoughness: 0.05,
|
||||||
|
materials: [] // Store references to bold materials
|
||||||
|
};
|
||||||
|
|
||||||
// Renderer setup
|
// Renderer setup
|
||||||
const renderer = new THREE.WebGLRenderer({ antialias: true });
|
const renderer = new THREE.WebGLRenderer({ antialias: true });
|
||||||
|
|
||||||
|
@ -140,6 +151,26 @@ controls.dampingFactor = 0.25;
|
||||||
controls.enableZoom = false; // Disable zoom
|
controls.enableZoom = false; // Disable zoom
|
||||||
|
|
||||||
// Material definitions
|
// Material definitions
|
||||||
|
// Bold glass material (starts rough, will transition to clear)
|
||||||
|
const boldGlassMaterial = new THREE.MeshPhysicalMaterial({
|
||||||
|
color: 0xffffff,
|
||||||
|
metalness: 0.2,
|
||||||
|
roughness: 0.4, // Start with rough glass
|
||||||
|
transmission: 1,
|
||||||
|
ior: 2,
|
||||||
|
thickness: 2,
|
||||||
|
clearcoat: 1.0,
|
||||||
|
clearcoatRoughness: 0.1,
|
||||||
|
attenuationColor: new THREE.Color(0xffffff),
|
||||||
|
attenuationDistance: 0.8,
|
||||||
|
envMapIntensity: 0,
|
||||||
|
specularIntensity: 1.0,
|
||||||
|
specularColor: new THREE.Color(0x000000),
|
||||||
|
transparent: true,
|
||||||
|
depthWrite: false,
|
||||||
|
alphaTest: 0
|
||||||
|
});
|
||||||
|
|
||||||
// Clear thick glass for innovation
|
// Clear thick glass for innovation
|
||||||
const innovationGlassMaterial = new THREE.MeshPhysicalMaterial({
|
const innovationGlassMaterial = new THREE.MeshPhysicalMaterial({
|
||||||
color: 0xffffff,
|
color: 0xffffff,
|
||||||
|
@ -210,7 +241,25 @@ function applyMaterials(model, modelType) {
|
||||||
object.castShadow = true;
|
object.castShadow = true;
|
||||||
object.receiveShadow = true;
|
object.receiveShadow = true;
|
||||||
|
|
||||||
if (modelType === 'innovation') {
|
if (modelType === 'bold') {
|
||||||
|
// Bold-specific material logic - apply bold glass material to Cube mesh
|
||||||
|
if (object.name === 'Cube') {
|
||||||
|
console.log(` → Applying bold glass material to "${object.name}"`);
|
||||||
|
object.material = boldGlassMaterial.clone();
|
||||||
|
object.material.side = THREE.DoubleSide;
|
||||||
|
object.material.depthWrite = false;
|
||||||
|
object.renderOrder = 2;
|
||||||
|
|
||||||
|
// Store material reference for roughness animation
|
||||||
|
boldRoughnessAnimation.materials.push(object.material);
|
||||||
|
} else {
|
||||||
|
console.log(` → Applying bold glass material (fallback) to "${object.name}"`);
|
||||||
|
object.material = boldGlassMaterial.clone();
|
||||||
|
|
||||||
|
// Store material reference for roughness animation
|
||||||
|
boldRoughnessAnimation.materials.push(object.material);
|
||||||
|
}
|
||||||
|
} else if (modelType === 'innovation') {
|
||||||
// Innovation-specific material logic
|
// Innovation-specific material logic
|
||||||
const orangeMeshes = ['dblsc', 'ec', 'gemini', 'infinity', 'star', 'dpd'];
|
const orangeMeshes = ['dblsc', 'ec', 'gemini', 'infinity', 'star', 'dpd'];
|
||||||
const targetGlassNames = ['Cube.alt90.df'];
|
const targetGlassNames = ['Cube.alt90.df'];
|
||||||
|
@ -278,19 +327,16 @@ function centerAndFrameModel(model, targetCamera = camera) {
|
||||||
model.position.sub(center);
|
model.position.sub(center);
|
||||||
model.updateMatrixWorld(true);
|
model.updateMatrixWorld(true);
|
||||||
|
|
||||||
const size = box.getSize(new THREE.Vector3());
|
|
||||||
const maxDim = Math.max(size.x, size.y, size.z);
|
|
||||||
|
|
||||||
// Only set camera position if it's not already positioned (avoid reset during transitions)
|
// Only set camera position if it's not already positioned (avoid reset during transitions)
|
||||||
// Increased distance multiplier from 2 to 2.5 for further camera position
|
// Use fixed camera distance that's further away from the origin
|
||||||
if (!isTransitioning) {
|
if (!isTransitioning) {
|
||||||
const cameraDistance = maxDim * 2.5;
|
const fixedCameraDistance = 50; // Fixed distance, much further than before
|
||||||
targetCamera.position.set(0, 0, cameraDistance);
|
targetCamera.position.set(0, 0, fixedCameraDistance);
|
||||||
controls.target.set(0, 0, 0);
|
controls.target.set(0, 0, 0);
|
||||||
|
|
||||||
// Set distance limits to lock the camera at this distance
|
// Set distance limits to lock the camera at this distance
|
||||||
controls.minDistance = cameraDistance;
|
controls.minDistance = fixedCameraDistance;
|
||||||
controls.maxDistance = cameraDistance;
|
controls.maxDistance = fixedCameraDistance;
|
||||||
|
|
||||||
controls.update();
|
controls.update();
|
||||||
}
|
}
|
||||||
|
@ -304,7 +350,12 @@ function setupAnimations(model, gltf, modelType) {
|
||||||
gltf.animations.forEach((clip) => {
|
gltf.animations.forEach((clip) => {
|
||||||
const action = animMixer.clipAction(clip);
|
const action = animMixer.clipAction(clip);
|
||||||
|
|
||||||
if (modelType === 'innovation') {
|
if (modelType === 'bold') {
|
||||||
|
// Play once for bold
|
||||||
|
action.loop = THREE.LoopOnce;
|
||||||
|
action.clampWhenFinished = true;
|
||||||
|
action.play();
|
||||||
|
} else if (modelType === 'innovation') {
|
||||||
// PingPong loop for innovation
|
// PingPong loop for innovation
|
||||||
action.loop = THREE.LoopPingPong;
|
action.loop = THREE.LoopPingPong;
|
||||||
action.play();
|
action.play();
|
||||||
|
@ -351,11 +402,15 @@ function loadModel(filename, modelType, onLoadCallback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load initial innovation model
|
// Load initial bold model (now the first scene)
|
||||||
loadModel('innovation.glb', 'innovation', (model, animMixer) => {
|
loadModel('bold.glb', 'bold', (model, animMixer) => {
|
||||||
currentModel = model;
|
currentModel = model;
|
||||||
mixer = animMixer;
|
mixer = animMixer;
|
||||||
scene.add(currentModel);
|
scene.add(currentModel);
|
||||||
|
|
||||||
|
// Start the roughness animation for bold scene
|
||||||
|
boldRoughnessAnimation.isActive = true;
|
||||||
|
boldRoughnessAnimation.startTime = performance.now();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Twist animation function - Updated to twist around world center (0,0,0)
|
// Twist animation function - Updated to twist around world center (0,0,0)
|
||||||
|
@ -442,9 +497,9 @@ function resetMeshGeometry(mesh) {
|
||||||
function startTransition(direction = 1) {
|
function startTransition(direction = 1) {
|
||||||
if (isTransitioning) return;
|
if (isTransitioning) return;
|
||||||
|
|
||||||
// Check bounds
|
// Check bounds - now 4 scenes (0-3)
|
||||||
if (direction > 0 && currentScene >= 2) return; // Can't go forward from storytelling
|
if (direction > 0 && currentScene >= 3) return; // Can't go forward from storytelling
|
||||||
if (direction < 0 && currentScene <= 0) return; // Can't go backward from innovation
|
if (direction < 0 && currentScene <= 0) return; // Can't go backward from bold
|
||||||
|
|
||||||
isTransitioning = true;
|
isTransitioning = true;
|
||||||
isTwisting = true;
|
isTwisting = true;
|
||||||
|
@ -452,25 +507,31 @@ function startTransition(direction = 1) {
|
||||||
transitionStartTime = performance.now();
|
transitionStartTime = performance.now();
|
||||||
transitionDirection = direction;
|
transitionDirection = direction;
|
||||||
|
|
||||||
// Determine next model based on direction
|
// Determine next model based on direction and current scene
|
||||||
let nextModelFile = '';
|
let nextModelFile = '';
|
||||||
let nextModelType = '';
|
let nextModelType = '';
|
||||||
|
|
||||||
if (direction > 0) {
|
if (direction > 0) {
|
||||||
// Moving forward
|
// Moving forward
|
||||||
if (currentScene === 0) {
|
if (currentScene === 0) {
|
||||||
|
nextModelFile = 'innovation.glb';
|
||||||
|
nextModelType = 'innovation';
|
||||||
|
} else if (currentScene === 1) {
|
||||||
nextModelFile = 'agility.glb';
|
nextModelFile = 'agility.glb';
|
||||||
nextModelType = 'agility';
|
nextModelType = 'agility';
|
||||||
} else if (currentScene === 1) {
|
} else if (currentScene === 2) {
|
||||||
nextModelFile = 'storytelling.glb';
|
nextModelFile = 'storytelling.glb';
|
||||||
nextModelType = 'storytelling';
|
nextModelType = 'storytelling';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Moving backward
|
// Moving backward
|
||||||
if (currentScene === 1) {
|
if (currentScene === 1) {
|
||||||
|
nextModelFile = 'bold.glb';
|
||||||
|
nextModelType = 'bold';
|
||||||
|
} else if (currentScene === 2) {
|
||||||
nextModelFile = 'innovation.glb';
|
nextModelFile = 'innovation.glb';
|
||||||
nextModelType = 'innovation';
|
nextModelType = 'innovation';
|
||||||
} else if (currentScene === 2) {
|
} else if (currentScene === 3) {
|
||||||
nextModelFile = 'agility.glb';
|
nextModelFile = 'agility.glb';
|
||||||
nextModelType = 'agility';
|
nextModelType = 'agility';
|
||||||
}
|
}
|
||||||
|
@ -515,7 +576,7 @@ function updateTransition(deltaTime) {
|
||||||
|
|
||||||
if (currentModel) {
|
if (currentModel) {
|
||||||
// Move current model up and fade out
|
// Move current model up and fade out
|
||||||
currentModel.position.y = easedProgress * 10;
|
// currentModel.position.y = easedProgress * 10;
|
||||||
|
|
||||||
currentModel.traverse((obj) => {
|
currentModel.traverse((obj) => {
|
||||||
if (obj.material) {
|
if (obj.material) {
|
||||||
|
@ -580,7 +641,7 @@ function updateTransition(deltaTime) {
|
||||||
if (Array.isArray(obj.material)) {
|
if (Array.isArray(obj.material)) {
|
||||||
obj.material.forEach(mat => {
|
obj.material.forEach(mat => {
|
||||||
mat.opacity = 1;
|
mat.opacity = 1;
|
||||||
if (currentScene === 2) { // Keep transparency for storytelling glass
|
if (currentScene === 3) { // Keep transparency for storytelling glass
|
||||||
mat.transparent = mat.transmission > 0;
|
mat.transparent = mat.transmission > 0;
|
||||||
} else {
|
} else {
|
||||||
mat.transparent = mat.transmission > 0;
|
mat.transparent = mat.transmission > 0;
|
||||||
|
@ -588,7 +649,7 @@ function updateTransition(deltaTime) {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
obj.material.opacity = 1;
|
obj.material.opacity = 1;
|
||||||
if (currentScene === 2) { // Keep transparency for storytelling glass
|
if (currentScene === 3) { // Keep transparency for storytelling glass
|
||||||
obj.material.transparent = obj.material.transmission > 0;
|
obj.material.transparent = obj.material.transmission > 0;
|
||||||
} else {
|
} else {
|
||||||
obj.material.transparent = obj.material.transmission > 0;
|
obj.material.transparent = obj.material.transmission > 0;
|
||||||
|
@ -680,6 +741,36 @@ function animate() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update bold roughness animation
|
||||||
|
if (boldRoughnessAnimation.isActive) {
|
||||||
|
const elapsed = (performance.now() - boldRoughnessAnimation.startTime) / 1000;
|
||||||
|
|
||||||
|
if (elapsed >= boldRoughnessAnimation.delayDuration) {
|
||||||
|
// Delay period is over, start roughness transition
|
||||||
|
const transitionElapsed = elapsed - boldRoughnessAnimation.delayDuration;
|
||||||
|
const transitionProgress = Math.min(transitionElapsed / boldRoughnessAnimation.transitionDuration, 1);
|
||||||
|
|
||||||
|
// Smooth easing function (ease-in-out)
|
||||||
|
const easeInOut = (t) => t * t * (3 - 2 * t);
|
||||||
|
const easedProgress = easeInOut(transitionProgress);
|
||||||
|
|
||||||
|
// Interpolate roughness from 0.9 to 0.05
|
||||||
|
const currentRoughness = boldRoughnessAnimation.startRoughness +
|
||||||
|
(boldRoughnessAnimation.endRoughness - boldRoughnessAnimation.startRoughness) * easedProgress;
|
||||||
|
|
||||||
|
// Apply to all bold materials
|
||||||
|
boldRoughnessAnimation.materials.forEach(material => {
|
||||||
|
material.roughness = currentRoughness;
|
||||||
|
material.needsUpdate = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// End animation when complete
|
||||||
|
if (transitionProgress >= 1) {
|
||||||
|
boldRoughnessAnimation.isActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Turntable rotation for current model
|
// Turntable rotation for current model
|
||||||
if (currentModel && !isTransitioning) {
|
if (currentModel && !isTransitioning) {
|
||||||
autoRotationAngle += delta * 0.5;
|
autoRotationAngle += delta * 0.5;
|
||||||
|
|
Loading…
Reference in a new issue