Multiplayer WebXR Project with Vite/Node/Three.js
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

102 lines
4.2 KiB

import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/Addons.js';
import { DRACOLoader } from 'three/examples/jsm/Addons.js';
import { createCustomJitterMaterial } from './materials/CustomJitterMaterial';
import { TextureLoader } from 'three';
export class ModelLoader {
constructor() {
}
loadDRACOModelURL(modelURL, textureURL, scale) {
return new Promise((resolve, reject) => {
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('/draco/');
loader.setDRACOLoader(dracoLoader);
const applyMaterial = (object, texture) => {
object.traverse((child) => {
if (child.isMesh) {
texture.encoding = THREE.sRGBEncoding;
texture.needsUpdate = true;
child.material = createCustomJitterMaterial(100, texture);
}
});
};
const processObject = (object, texture) => {
object.scale.copy(scale);
const box = new THREE.Box3().setFromObject(object);
const height = box.max.y - box.min.y;
object.position.y = height / 2;
object.position.x = 0;
applyMaterial(object, texture);
resolve(object);
};
if (textureURL) {
const textureLoader = new TextureLoader();
textureLoader.load(textureURL, function (baseTexture) {
baseTexture.flipY = false;
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = baseTexture.image.width;
canvas.height = baseTexture.image.height;
context.drawImage(baseTexture.image, 0, 0);
const drawableTexture = new THREE.CanvasTexture(canvas);
drawableTexture.flipY = false;
loader.load(modelURL, function (gltf) {
processObject(gltf.scene, drawableTexture);
}, undefined, function (error) {
reject(error);
});
}, undefined, function (error) {
reject(error);
});
} else {
loader.load(modelURL, function (gltf) {
let extractedTexture = null;
gltf.scene.traverse((child) => {
if (child.isMesh && child.material && child.material.map) {
if (!extractedTexture) {
extractedTexture = child.material.map;
}
}
});
let finalTexture;
if (extractedTexture && extractedTexture.image) {
// The texture from the GLTF is valid, make it a drawable CanvasTexture
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = extractedTexture.image.width;
canvas.height = extractedTexture.image.height;
context.drawImage(extractedTexture.image, 0, 0);
finalTexture = new THREE.CanvasTexture(canvas);
} else {
// fallback: create a white texture
const canvas = document.createElement('canvas');
canvas.width = 1024;
canvas.height = 1024;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#0044ffff';
ctx.fillRect(0, 0, 1024, 1024);
finalTexture = new THREE.CanvasTexture(canvas);
}
finalTexture.flipY = false;
processObject(gltf.scene, finalTexture);
}, undefined, function (error) {
reject(error);
});
}
});
}
}