138 lines
3.7 KiB
JavaScript
138 lines
3.7 KiB
JavaScript
// https://github.com/MrForExample/ComfyUI-3D-Pack/blob/main/web/js/threeVisualizer.js
|
|
import * as THREE from "three";
|
|
import { api } from "../../../scripts/api.js";
|
|
|
|
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
|
|
import { RoomEnvironment } from "three/addons/environments/RoomEnvironment.js";
|
|
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
|
|
import { DRACOLoader } from "three/addons/loaders/DRACOLoader.js";
|
|
|
|
export function getRGBValue(colorString = "rgb(0, 0, 0)", scale01 = false) {
|
|
var color = colorString.split(/[\D]+/).filter(Boolean);
|
|
for (let index = 0; index < color.length; index++) {
|
|
color[index] = Number(color[index]);
|
|
}
|
|
|
|
if (scale01) {
|
|
for (let index = 0; index < color.length; index++) {
|
|
color[index] = color[index] / 255;
|
|
}
|
|
}
|
|
|
|
return color;
|
|
}
|
|
|
|
const visualizer = document.getElementById("visualizer");
|
|
const container = document.getElementById("container");
|
|
const progressDialog = document.getElementById("progress-dialog");
|
|
const progressIndicator = document.getElementById("progress-indicator");
|
|
// const colorPicker = document.getElementById("color-picker");
|
|
|
|
const renderer = new THREE.WebGLRenderer({ antialias: true });
|
|
renderer.setPixelRatio(window.devicePixelRatio);
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
container.appendChild(renderer.domElement);
|
|
|
|
const pmremGenerator = new THREE.PMREMGenerator(renderer);
|
|
|
|
// scene
|
|
const scene = new THREE.Scene();
|
|
scene.background = new THREE.Color(0x000000);
|
|
scene.environment = pmremGenerator.fromScene(
|
|
new RoomEnvironment(renderer),
|
|
0.04
|
|
).texture;
|
|
|
|
const ambientLight = new THREE.AmbientLight(0xffffff);
|
|
|
|
const camera = new THREE.PerspectiveCamera(
|
|
40,
|
|
window.innerWidth / window.innerHeight,
|
|
1,
|
|
100
|
|
);
|
|
camera.position.set(1.5, 0, 0);
|
|
camera.rotation.set(-1.4, 1.4, 1.4);
|
|
|
|
const controls = new OrbitControls(camera, renderer.domElement);
|
|
controls.target.set(0, 0, 0);
|
|
controls.update();
|
|
controls.enablePan = true;
|
|
controls.enableDamping = true;
|
|
|
|
// Handle window reseize event
|
|
window.onresize = function () {
|
|
camera.aspect = window.innerWidth / window.innerHeight;
|
|
camera.updateProjectionMatrix();
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
};
|
|
|
|
var lastFilepath = "";
|
|
var needUpdate = false;
|
|
|
|
const onProgress = function (xhr) {
|
|
if (xhr.lengthComputable) {
|
|
progressIndicator.value = (xhr.loaded / xhr.total) * 100;
|
|
}
|
|
};
|
|
|
|
const onError = function (e) {
|
|
console.error(e);
|
|
};
|
|
|
|
function animate() {
|
|
var filepath = visualizer.getAttribute("filepath");
|
|
if (filepath == lastFilepath) {
|
|
if (needUpdate) {
|
|
controls.update();
|
|
renderer.render(scene, camera);
|
|
}
|
|
requestAnimationFrame(animate);
|
|
} else {
|
|
needUpdate = false;
|
|
scene.clear();
|
|
progressDialog.open = true;
|
|
lastFilepath = filepath;
|
|
main(JSON.parse(lastFilepath));
|
|
}
|
|
}
|
|
|
|
async function main(params) {
|
|
if (params?.filename) {
|
|
const url = api
|
|
.apiURL("/view?" + new URLSearchParams(params))
|
|
.replace(/extensions.*\//, "");
|
|
const fileExt = params.filename.slice(params.filename.lastIndexOf(".") + 1);
|
|
|
|
if (fileExt == "glb") {
|
|
const dracoLoader = new DRACOLoader();
|
|
dracoLoader.setDecoderPath(
|
|
"https://unpkg.com/three@latest/examples/jsm/libs/draco/gltf/"
|
|
);
|
|
const loader = new GLTFLoader();
|
|
loader.setDRACOLoader(dracoLoader);
|
|
|
|
loader.load(
|
|
url,
|
|
function (gltf) {
|
|
const model = gltf.scene;
|
|
model.position.set(0, 0, 0);
|
|
model.scale.set(1, 1, 1);
|
|
scene.add(model);
|
|
},
|
|
onProgress,
|
|
onError
|
|
);
|
|
}
|
|
|
|
needUpdate = true;
|
|
} else {
|
|
scene.clear();
|
|
}
|
|
|
|
progressDialog.close();
|
|
animate();
|
|
}
|
|
|
|
main();
|