Skip to content

Commit b0db0ea

Browse files
author
Parsa Azari
committed
Fix Three.js bundling: Remove external aliases, ensure proper dependency bundling
1 parent 163e3a1 commit b0db0ea

File tree

7 files changed

+118
-78
lines changed

7 files changed

+118
-78
lines changed

dist/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
66
<title>3D Portfolio</title>
77
<link rel="icon" type="image/x-icon" href="/3D-Portfolio/favicon.ico">
8+
<!-- Fixed deployment - v3 -->
89
<style>
910
body {
1011
margin: 0;
@@ -126,7 +127,7 @@
126127
transition: opacity 0.3s ease;
127128
}
128129
</style>
129-
<script type="module" crossorigin src="/3D-Portfolio/assets/index-QhzON4yl.js"></script>
130+
<script type="module" crossorigin src="/3D-Portfolio/assets/index-DCxxmV1z.js"></script>
130131
<link rel="stylesheet" crossorigin href="/3D-Portfolio/assets/index-BnuVihSM.css">
131132
</head>
132133

src/core/rendering/environments/SeveranceEnvironment.js

Lines changed: 66 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3968,13 +3968,19 @@ export class SeveranceEnvironment extends BaseEnvironment {
39683968
if (bulbMeshes.length === 0) {
39693969
// Try fallback: find mesh with high white/emissive material
39703970
lampMesh.traverse((child) => {
3971-
if (child.isMesh && child.material && child.material.emissive && child.material.emissive.getHex() === 0xffffff) {
3972-
bulbMeshes.push(child);
3971+
if (child.isMesh && child.material) {
3972+
// Look for bulb meshes by name or emissive property
3973+
const isLightBulb = child.name.toLowerCase().includes('bulb') ||
3974+
child.name.toLowerCase().includes('light') ||
3975+
(child.material.emissive && child.material.emissive.getHex() === 0xffffff);
3976+
if (isLightBulb) {
3977+
bulbMeshes.push(child);
3978+
}
39733979
}
39743980
});
39753981
}
39763982
if (bulbMeshes.length === 0) {
3977-
console.warn('[Lamp Shader] No bulb mesh found in lamp.glb. No shader applied.');
3983+
console.log('[Lamp Shader] No bulb mesh found in lamp.glb. Using standard material.');
39783984
} else {
39793985
const lampShaderMat = createLampLightShaderMaterial();
39803986
bulbMeshes.forEach(bulb => {
@@ -4679,7 +4685,9 @@ export class SeveranceEnvironment extends BaseEnvironment {
46794685
const textureLoader = new THREE.TextureLoader();
46804686

46814687
// Create the appropriate path based on posterTitle
4682-
const basePath = getAssetPath(`Images/performance/solo performances/${posterTitle.toLowerCase()}/`);
4688+
// Normalize title: convert to lowercase and replace spaces with hyphens
4689+
const normalizedTitle = posterTitle.toLowerCase().replace(/ /g, '-');
4690+
const basePath = getAssetPath(`Images/performance/solo-performances/${normalizedTitle}/`);
46834691
console.log(`Looking for images at path: ${basePath}`);
46844692

46854693
for (let i = 0; i < count; i++) {
@@ -4716,25 +4724,28 @@ export class SeveranceEnvironment extends BaseEnvironment {
47164724
// Get appropriate image filename based on gallery type
47174725
let imageName = null;
47184726

4719-
if (posterTitle === 'Circle of Confusion') {
4720-
// Files are named: photo_2025-05-01_17-25-22.jpg, photo_2025-05-01_17-25-22 (2).jpg, etc.
4721-
// Note: No (1) file, starts with no suffix then goes to (2)
4722-
if (i === 0) {
4723-
imageName = 'photo_2025-05-01_17-25-22.jpg';
4724-
} else if (i < 6) {
4725-
// Use (2) through (6) for indexes 1-5
4726-
imageName = `photo_2025-05-01_17-25-22 (${i+1}).jpg`;
4727-
}
4728-
} else if (posterTitle === 'Dissolve') {
4729-
// Files are named: سی پرفورمنس ،سی هنرمند، سی روز 3.jpg, سی پرفورمنس ،سی هنرمند، سی روز 3 (1).jpg, etc.
4730-
if (i === 0) {
4731-
imageName = 'سی پرفورمنس ،سی هنرمند، سی روز 3.jpg';
4732-
} else if (i < 18) { // We have up to (18)
4733-
imageName = `سی پرفورمنس ،سی هنرمند، سی روز 3 (${i}).jpg`;
4734-
}
4735-
} else if (posterTitle === 'Friends') {
4736-
// Files have various names, map them explicitly
4737-
const friendsImages = [
4727+
// Define simple image arrays for each gallery
4728+
const imageArrays = {
4729+
'Circle of Confusion': [
4730+
'photo_2025-05-01_17-25-22.jpg',
4731+
'photo_2025-05-01_17-25-22_(2).jpg',
4732+
'photo_2025-05-01_17-25-22_(3).jpg',
4733+
'photo_2025-05-01_17-25-22_(4).jpg',
4734+
'photo_2025-05-01_17-25-22_(5).jpg',
4735+
'photo_2025-05-01_17-25-22_(6).jpg'
4736+
],
4737+
'Dissolve': [
4738+
'dissolve-base.jpg',
4739+
'dissolve-1.jpg',
4740+
'dissolve-2.jpg',
4741+
'dissolve-3.jpg',
4742+
'dissolve-4.jpg',
4743+
'dissolve-5.jpg',
4744+
'dissolve-6.jpg',
4745+
'dissolve-7.jpg',
4746+
'dissolve-8.jpg'
4747+
],
4748+
'Friends': [
47384749
'photo_2025-05-01_17-29-01.jpg',
47394750
'M2RjNjJmMjZk.jpg',
47404751
'NzIwYjJkZmQ1.jpg',
@@ -4743,15 +4754,13 @@ export class SeveranceEnvironment extends BaseEnvironment {
47434754
'MGE1ZjJiODcw.jpg',
47444755
'YmQ4YmZlY2U4.jpg',
47454756
'N2MyYTc3OWFj.jpg',
4746-
'NDc1MWY3OGM2.jpg',
4747-
'M2MwYmIyMzY4.jpg',
4748-
'NDc2M2NhOTc3.jpg',
4749-
'MzkyNmRjZDFm.jpg',
4750-
'ZDY5ZmU5Njg2.jpg'
4751-
];
4752-
if (i < friendsImages.length) {
4753-
imageName = friendsImages[i];
4754-
}
4757+
'NDc1MWY3OGM2.jpg'
4758+
]
4759+
};
4760+
4761+
const availableImages = imageArrays[posterTitle] || [];
4762+
if (i < availableImages.length) {
4763+
imageName = availableImages[i];
47554764
}
47564765

47574766
let imageMaterial;
@@ -6334,7 +6343,8 @@ function createKrugerTextTexture(text, { width = 1024, height = 256, bgColor = '
63346343
// Helper function to get image paths for a given poster title
63356344
const getArtPosterImagePaths = (title) => {
63366345
// Path that matches the known directory structure
6337-
const correctBasePath = getAssetPath(`assets/Images/performance/solo performances/${title.toLowerCase()}/`);
6346+
const normalizedTitle = title.toLowerCase().replace(/ /g, '-');
6347+
const correctBasePath = getAssetPath(`assets/Images/performance/solo-performances/${normalizedTitle}/`);
63386348
const urls = [];
63396349
let count = 0;
63406350

@@ -6347,22 +6357,30 @@ const getArtPosterImagePaths = (title) => {
63476357
}
63486358

63496359
if (title === 'Circle of Confusion') {
6350-
count = 6;
6351-
const baseFileName = 'photo_2025-05-01_17-25-22';
6352-
for (let i = 0; i < count; i++) {
6353-
if (i === 0) {
6354-
pushUrl(`${correctBasePath}${baseFileName}.jpg`);
6355-
} else {
6356-
pushUrl(`${correctBasePath}${baseFileName} (${i + 1}).jpg`);
6357-
}
6358-
}
6360+
// Use the actual file names that exist in the directory
6361+
const circleImages = [
6362+
'photo_2025-05-01_17-25-22.jpg',
6363+
'photo_2025-05-01_17-25-22_(2).jpg',
6364+
'photo_2025-05-01_17-25-22_(3).jpg',
6365+
'photo_2025-05-01_17-25-22_(4).jpg',
6366+
'photo_2025-05-01_17-25-22_(5).jpg',
6367+
'photo_2025-05-01_17-25-22_(6).jpg'
6368+
];
6369+
circleImages.forEach(imgName => {
6370+
pushUrl(`${correctBasePath}${imgName}`);
6371+
});
63596372
} else if (title === 'Dissolve') {
6360-
count = 14; // Reduce to 14 images based on error messages
6361-
const baseFileName = 'سی پرفورمنس ،سی هنرمند، سی روز 3'; // Changed to use spaces instead of plus signs
6362-
pushUrl(`${correctBasePath}${baseFileName}.jpg`);
6363-
for (let i = 1; i < count; i++) {
6364-
pushUrl(`${correctBasePath}${baseFileName} (${i}).jpg`);
6365-
}
6373+
// Use the actual file names that exist in the directory
6374+
const dissolveImages = [
6375+
'dissolve-base.jpg', 'dissolve-1.jpg', 'dissolve-2.jpg', 'dissolve-3.jpg',
6376+
'dissolve-4.jpg', 'dissolve-5.jpg', 'dissolve-6.jpg', 'dissolve-7.jpg',
6377+
'dissolve-8.jpg', 'dissolve-9.jpg', 'dissolve-10.jpg', 'dissolve-11.jpg',
6378+
'dissolve-12.jpg', 'dissolve-13.jpg', 'dissolve-14.jpg', 'dissolve-15.jpg',
6379+
'dissolve-16.jpg', 'dissolve-17.jpg', 'dissolve-18.jpg'
6380+
];
6381+
dissolveImages.forEach(imgName => {
6382+
pushUrl(`${correctBasePath}${imgName}`);
6383+
});
63666384
} else if (title === 'Friends') {
63676385
const friendsImages = [
63686386
'photo_2025-05-01_17-29-01.jpg', 'M2RjNjJmMjZk.jpg', 'NzIwYjJkZmQ1.jpg',

src/core/rendering/materials/SeveranceMaterials.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,11 @@ export class SeveranceMaterials {
195195
return (x & (x - 1)) === 0;
196196
}
197197
if (!isPowerOfTwo(texture.image.width) || !isPowerOfTwo(texture.image.height)) {
198-
console.warn(`Texture ${name} (${path}) is not power-of-two. This may impact performance.`);
198+
// Silently handle non-power-of-two textures for better performance
199199
texture.generateMipmaps = false;
200200
texture.minFilter = THREE.LinearFilter;
201+
texture.wrapS = THREE.ClampToEdgeWrap;
202+
texture.wrapT = THREE.ClampToEdgeWrap;
201203
} else {
202204
texture.generateMipmaps = true;
203205
texture.minFilter = THREE.LinearMipmapLinearFilter;

src/main.js

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -348,21 +348,36 @@ class SeveranceApp {
348348
}
349349
}
350350

351-
// Always try to resume audio context on key press
352-
if (this.audioManager) {
353-
this.audioManager.resumeAudioContext().catch(err => {
354-
// Silent catch - no need to log every time
355-
});
356-
}
351+
// Setup one-time audio context initialization with user gesture
352+
this.tryResumeAudio();
357353
});
358354

359-
// Also resume audio context on any click
360-
document.addEventListener("click", () => {
361-
if (this.audioManager) {
362-
this.audioManager.resumeAudioContext().catch(err => {
363-
// Silent catch - no need to log every time
364-
});
355+
// Setup comprehensive audio context initialization
356+
this.setupAudioContextInitialization();
357+
}
358+
359+
setupAudioContextInitialization() {
360+
let audioContextInitialized = false;
361+
362+
this.tryResumeAudio = () => {
363+
if (!audioContextInitialized && this.audioManager) {
364+
this.audioManager.resumeAudioContext()
365+
.then(success => {
366+
if (success) {
367+
audioContextInitialized = true;
368+
console.log("AudioContext successfully initialized after user gesture");
369+
}
370+
})
371+
.catch(err => {
372+
// Silent catch - AudioContext failures are expected until user gesture
373+
});
365374
}
375+
};
376+
377+
// Try to initialize audio on various user interactions
378+
const events = ['click', 'keydown', 'touchstart', 'pointerdown'];
379+
events.forEach(eventType => {
380+
document.addEventListener(eventType, this.tryResumeAudio, { once: false });
366381
});
367382
}
368383

@@ -2602,14 +2617,17 @@ document.addEventListener("DOMContentLoaded", () => {
26022617
let isDragging = false;
26032618
let offsetX, offsetY;
26042619

2605-
document.getElementById('dev-terminal-header').addEventListener('mousedown', function(e) {
2606-
// Don't drag if clicking controls
2607-
if (e.target.classList.contains('terminal-btn')) return;
2608-
2609-
isDragging = true;
2610-
offsetX = e.clientX - overlay.getBoundingClientRect().left;
2611-
offsetY = e.clientY - overlay.getBoundingClientRect().top;
2612-
});
2620+
const terminalHeader = document.getElementById('dev-terminal-header');
2621+
if (terminalHeader) {
2622+
terminalHeader.addEventListener('mousedown', function(e) {
2623+
// Don't drag if clicking controls
2624+
if (e.target.classList.contains('terminal-btn')) return;
2625+
2626+
isDragging = true;
2627+
offsetX = e.clientX - overlay.getBoundingClientRect().left;
2628+
offsetY = e.clientY - overlay.getBoundingClientRect().top;
2629+
});
2630+
}
26132631

26142632
document.addEventListener('mousemove', function(e) {
26152633
if (!isDragging) return;

src/systems/movement/UnifiedMovementController.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -601,14 +601,14 @@ export class UnifiedMovementController {
601601
* @private - Renamed to indicate internal use
602602
*/
603603
_checkCollision(moveDelta, recursionDepth = 0) {
604-
if (recursionDepth >= this.collisionCheckSteps) {
604+
if (recursionDepth >= Math.min(this.collisionCheckSteps, 3)) {
605605
console.warn("[Collision] Max recursion depth reached, stopping movement.");
606606
return new THREE.Vector3(0, 0, 0); // Stop movement if too many bounces
607607
}
608608

609609
const moveLength = moveDelta.length();
610-
if (moveLength < 0.001) {
611-
return moveDelta; // Not moving significantly
610+
if (moveLength < 0.005 || recursionDepth > 0 && moveLength < 0.01) {
611+
return moveDelta; // Not moving significantly or small slide movement
612612
}
613613

614614
if (!this.environment || typeof this.environment.getCollidableWalls !== 'function') {

src/utils/assetPaths.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export function getAssetPath(path) {
1616
return `/3D-Portfolio/${cleanPath}`;
1717
}
1818

19-
// In development, use paths relative to the root
19+
// In development, serve directly from root (no base path)
2020
return `/${cleanPath}`;
2121
}
2222

@@ -35,7 +35,8 @@ export function getTexturePath(filename) {
3535
* @returns {string} - The complete shader path
3636
*/
3737
export function getShaderPath(filename) {
38-
return getAssetPath(`src/shaders/${filename}`);
38+
// Shaders are in public/shaders, not src/shaders
39+
return getAssetPath(`shaders/${filename}`);
3940
}
4041

4142
/**

vite.config.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { defineConfig } from "vite";
22
import { resolve } from "path";
33

4-
export default defineConfig({
5-
base: "/3D-Portfolio/", // GitHub Pages repository name
4+
export default defineConfig(({ command }) => ({
5+
base: command === 'build' ? "/3D-Portfolio/" : "/", // Only use base path in production
66
build: {
77
outDir: "dist",
88
assetsDir: "assets",
@@ -21,4 +21,4 @@ export default defineConfig({
2121
},
2222
assetsInclude: ["**/*.glsl"],
2323
publicDir: "public",
24-
});
24+
}));

0 commit comments

Comments
 (0)