Hello everyone!
I am running into a roadblock on my three.js journey.
I wanted to create a stand-alone model viewer. I have learned a lot, but it appears that I still lack a great deal of knowledge that might be an easy task for all of you.
Therefore, I am looking for guidance for completing my project or can provide a functional code; and I would love to discuss compensation for whomever can help me achieve this.
I am interested in displaying a complex model (GLB) on iPad. Much like the Autodesk Online Viewer.
I would like to have the ability to highlight that part and display the part name (in a separate CSS window) when that specific part of the model is selected. (Touch interactions and/or submenu would be a plus!)
Due to the high number of parts in the model, the part name would need to be automated from the model. It’s been suggested that Ant Design or Material UI could be implemented for this.
Further details:
The model I have is fairly detailed with I high number of individual parts.
I currently have code exactly how I want to see the model, but I just don’t have the knowledge to highlight the model parts and complete the UI for the model tree.
If anyone would like to help, I would be forever grateful!
I don’t have allot but I would certainly discuss compensation if someone would like tackle the functional code.
Here’s my code below, and I can provide a link to the model if it helps:
Thank you all for your time
Blockquote
let container, scene, clock, camera, renderer, model;
function init(){
/* Container */
container = document.querySelector('.model-frame');
/* Scene */
scene = new THREE.Scene();
/*scene.background = new THREE.Color( 0xadb8bf );*/
/* Clock */
clock = new THREE.Clock();
const loadingManager = new THREE.LoadingManager( () => {
const loadingScreen = document.getElementById('loading-screen');
loadingScreen.classList.add('fade-out');
loadingScreen.addEventListener('transitionend',onTransitionEnd);
});
/* Camera */
const fov = 35
const aspect = container.clientWidth/container.clientHeight;
const macro = 0.1;
const tele = 1000;
camera = new THREE.PerspectiveCamera(fov,aspect,macro,tele);
camera.position.set(15,0,25);
camera.rotation.y = .55;
/* Lights */
am = new THREE.DirectionalLight(0xb9e4ee,2);
pm = new THREE.DirectionalLight(0x444444,3);
am.position.set(0,2,0);
pm.position.set(0,-2,0);
am.castShadow = true;
pm.castShadow = true;
scene.add(am,pm);
const kelvin = 0xc4c4c4;
const watt = 2;
primeLight = new THREE.PointLight(kelvin,watt);
primeLight.position.set(0,30,50);
rightRim = new THREE.PointLight(kelvin,watt);
rightRim.position.set(50,10,0);
leftRim = new THREE.PointLight(kelvin,watt);
leftRim.position.set(0,10,-50);
backRim = new THREE.PointLight(kelvin,watt);
backRim.position.set(-50,30,0);
scene.add(primeLight, rightRim, leftRim, backRim);
/* Maintenance */
/* Grid */
const grid = new THREE.GridHelper( 20, 20, 0xffffff, 0x555555 );
/* Light Placement */
var geometry = new THREE.BoxGeometry( 5,5,5 );
var material = new THREE.MeshPhongMaterial( { color: 0xbadbde, wireframe: false });
var cube = new THREE.Mesh( geometry, material );
cube.position.set(0,30,50);
var cube2 = new THREE.Mesh( geometry, material );
cube2.position.set(50,10,0);
var cube3 = new THREE.Mesh( geometry, material );
cube3.position.set(0,10,-50);
var cube4 = new THREE.Mesh( geometry, material );
cube4.position.set(-50,30,0);
/*scene.add( grid, cube, cube2, cube3, cube4 );*/
/* Renderer */
renderer = new THREE.WebGLRenderer({antialias:true,alpha:true});
renderer.toneMapping = THREE.ReinhardToneMapping;
renderer.toneMappingExposure = 1.75;
renderer.shadowMap.enabled = true;
renderer.setSize(container.clientWidth,container.clientHeight);
renderer.setPixelRatio(window.devicePixelRatio);
container.appendChild(renderer.domElement);
/* Controls */
controls = new THREE.OrbitControls(camera,renderer.domElement);
controls.minDistance = 10;
controls.maxDistance = 40;
/* GLTF */
let loader = new THREE.GLTFLoader( loadingManager );
loader.load('https://threejsfundamentals.org/threejs/resources/models/cartoon_lowpoly_small_city_free_pack/scene.gltf',function(gltf){
model = gltf.scene.children[0];
model.scale.set(.15,.15,.15);
model.position.set(5,-5.5,5);
model.traverse(n => {
if(n.isMesh) {
n.castShadow = true;
n.receiveShadow = true;
if(n.material.map)
n.material.map.anisotrophy = 16;
}
})
scene.add(model);
animate();
});
}
/* Logic */
function animate(){
controls.update();
renderer.render(scene,camera);
requestAnimationFrame(animate);
}
init();
function onWindowResize() {
camera.aspect = container.clientWidth / container.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(container.clientWidth, container.clientHeight);
}
window.addEventListener("resize", onWindowResize);
function onTransitionEnd( event ) {
event.target.remove();
}