Files
web3d/WebGl/draw/webgl_draw.js
T
2023-09-27 11:29:35 +02:00

485 lines
16 KiB
JavaScript

import * as THREE from '../threeJsLib/three.module.js';
import { OrbitControls } from '../jsm/controls/OrbitControls.js';
import { ThreeMFLoader } from '../jsm/loaders/3MFLoader.js';
// VARIABILI DI CONTROLLO
var m_divStartDimX = 500;
var m_divStartDimY = 400;
var fName = "Cubo.3mf";
var m_fileSource = '';
var m_bZoom = true;
var m_bPan = true;
var m_bRot = true;
var m_bAutoRot = false;
var m_bGrid_v1 = true ;
var m_nCameraStartPos = 8 ;
//var useInSlider = false;
var m_nCamPos = 0;
var m_nStartL = 0;
var m_nEndL = 0;
var m_bIsOrtographic = true ;
var counter = 0;
let activeCamera, scene, renderer, controls, ORIG, perspectiveCamera, orthographicCamera;
var layer_list = [];
const GLBox3D = new THREE.Box3(); // Box3D globale delle geometrie
//init();
class webgl_original {
async initcall({ _dimX, _dimY, _fileName, _showInfiniteGrid}) {
m_divStartDimX = _dimX;
m_divStartDimY = _dimY;
fName = _fileName;
m_bGrid_v1 = _showInfiniteGrid;
//console.log(fName)
setLoaders();
await init();
}
setCameraType(){
toggleCamera( perspectiveCamera, orthographicCamera);
}
refreshcall(nStart, nEnd) {
refreshElement(nStart, nEnd);
}
resetCamera() {
SetCameraPos( m_nCameraStartPos, ORIG) ;
}
}
export { webgl_original }
function toggleCamera( perspectiveCamera, orthographicCamera) { // <-----------------
var cameraPosition = activeCamera.position.clone() ;
var cameraMatrix = activeCamera.matrix.clone() ;
var ControlsTarget = controls.target.clone() ;
var ControlsPosition = controls.position0.clone() ;
if ( m_bIsOrtographic == true) {
m_bIsOrtographic = false ;
activeCamera = perspectiveCamera ;
activeCamera.position.copy( cameraPosition) ;
activeCamera.matrix.copy( cameraMatrix) ;
} else {
m_bIsOrtographic = true ;
activeCamera = orthographicCamera ;
activeCamera.position.copy( cameraPosition) ;
activeCamera.matrix.copy( cameraMatrix) ;
}
activeCamera.updateProjectionMatrix() ;
controls.object = activeCamera ;
controls.target = ControlsTarget ;
controls.position0 = ControlsPosition ;
controls.update() ;
render() ;
}
function setLoaders() {
//<input type="range" class="form-range" id="customRange1">
const mother = document.getElementById('WebGL-3mfExport');
const spinContainer = document.createElement('div');
const sliderInput = document.createElement('input');
const elParent = document.createElement('div');
const elChild1 = document.createElement('div');
const elChild2 = document.createElement('div');
const elChild3 = document.createElement('div');
const elChild4 = document.createElement('div');
const elChild5 = document.createElement('div');
const elChild6 = document.createElement('div');
const loadTxt = document.createElement('div');
//if (useInSlider) {
mother.appendChild(sliderInput);
sliderInput.setAttribute('id', 'refre_slider');
sliderInput.setAttribute('hidden', true);
sliderInput.type = 'range';
sliderInput.min = '0';
//}
mother.appendChild(spinContainer);
//document.body.appendChild(spinContainer);
spinContainer.appendChild(elParent);
spinContainer.appendChild(loadTxt);
elParent.appendChild(elChild1);
elParent.appendChild(elChild2);
elParent.appendChild(elChild3);
elParent.appendChild(elChild4);
elParent.appendChild(elChild5);
elParent.appendChild(elChild6);
loadTxt.setAttribute('id', 'loadTxt');
spinContainer.setAttribute('id', 'spinContainer');
var st = 'height: ' + m_divStartDimY + 'px ; width: ' + m_divStartDimX + 'px ; background-color: #a0a0a0';
spinContainer.setAttribute("style", st);
elParent.setAttribute('id', 'sp');
elParent.classList.add('spinner');
loadTxt.style.padding = '30px 0 0 0'
loadTxt.innerText = 'Loading...';
loadTxt.style.fontSize = '50px';
loadTxt.style.fontFamily = 'Helvetica';
spinContainer.style.display = 'flex';
spinContainer.style.alignItems = 'center';
spinContainer.style.justifyContent = 'center';
spinContainer.style.flexDirection = 'column';
elParent.style.width = '70.4px';
elParent.style.height = '70.4px';
elParent.style.setProperty('--clr', 'rgb(247, 197, 159)');
elParent.style.setProperty('--clr-alpha', 'rgb(247, 197, 159,.1)');
elParent.style.transformStyle = 'preserve-3d';
elParent.animate([
// key frames
{ transform: 'rotate(45deg) rotateX(-25deg) rotateY(25deg)' },
{ transform: 'rotate(45deg) rotateX(-385deg) rotateY(25deg)' },
{ transform: 'rotate(45deg) rotateX(-385deg) rotateY(385deg)' }
], {
// sync options
duration: 2600,
iterations: Infinity,
easing: 'ease',
rangeStart: "cover 0%",
rangeEnd: "cover 100%"
});
var cDiv = elParent.children;
for (var i = 0; i < cDiv.length; i++) {
if (cDiv[i].tagName == "DIV") { //or use toUpperCase()
cDiv[i].style.height = '100%';
cDiv[i].style.position = 'absolute';
cDiv[i].style.width = '100%';
cDiv[i].style.border = '#afc5d6';
cDiv[i].style.backgroundSize = 'contain';
cDiv[i].style.backgroundImage = 'url(./styles/LogoClassic_NoText.png)'
}
}
elChild1.style.transform = 'translateZ(-35.2px) rotateY(180deg)';
elChild2.style.transform = 'rotateY(-270deg) translateX(50%)';
elChild2.style.transformOrigin = 'top right';
elChild3.style.transform = 'rotateY(270deg) translateX(-50%)';
elChild3.style.transformOrigin = 'center left';
elChild4.style.transform = 'rotateX(90deg) translateY(-50%)';
elChild4.style.transformOrigin = 'top center';
elChild5.style.transform = 'rotateX(-90deg) translateY(50%)';
elChild5.style.transformOrigin = 'bottom center';
elChild6.style.transform = 'translateZ(35.2px)';
}
function init() {
const manager = new THREE.LoadingManager();
const loader = new ThreeMFLoader(manager);
let startTime = performance.now();
return new Promise(() => {
setTimeout(() => {
loader.load('./models/3mf/' + fName, function (object) {
object.rotation.set(-Math.PI / 2, 0, 0);
object.traverse(function (child) {
child.castShadow = true;
});
for (var i = 0; i < object.children.length; ++i) {
var child = object.children[i];
child.rotation.set(-Math.PI / 2, 0, 0);
layer_list.push(child);
}
//console.log(layer_list);
AdaptSeceneToContest();
// Adapting Scene to contest
let endTime = performance.now();
let timeElapsed = endTime - startTime;
console.log('init in : ' + timeElapsed)
});
}, 0);
});
}
function AdaptSeceneToContest() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0xa0a0a0);
//if (useInSlider) {
document.getElementById("refre_slider").max = layer_list[layer_list.length - 1].children[0].nLayer;
document.getElementById("refre_slider").value = layer_list[layer_list.length - 1].children[0].nLayer;
document.getElementById("refre_slider").removeAttribute('hidden');
//}
for (var i = 0; i < layer_list.length; ++i) {
const Objbox = new THREE.Box3().setFromObject(layer_list[i]);
GLBox3D.union(Objbox);
layer_list[i].children[0].material.side = THREE.DoubleSide;
if (typeof layer_list[i].children[0].nLayer !== "undefined") {
scene.add(layer_list[i]);
}
}
const BoxHelper = new THREE.Box3Helper(GLBox3D, 0xffff00);
// setting camera position
const vtCenter = new THREE.Vector3(0, 0, 0);
GLBox3D.getCenter(vtCenter);
const vtPosition = vtCenter.clone().multiplyScalar(5);
const vtBoxDim = new THREE.Vector3(0, 0, 0);
GLBox3D.getSize(vtBoxDim);
// camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 30000);
// camera.position.set(2 * vtBoxDim.x, 2 * vtBoxDim.y, 2 * vtBoxDim.z);
// camera.lookAt(vtCenter.x, vtCenter.y, vtCenter.z);
// scene.add(camera);
perspectiveCamera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 300000 );
//perspectiveCamera.up = new THREE.Vector3( 0, 0, 1) ;
orthographicCamera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2,
window.innerHeight / 2, window.innerHeight / - 2,
-300000, 300000) ;
//orthographicCamera.up = new THREE.Vector3( 0, 0, 1) ;
if ( ! m_bIsOrtographic)
activeCamera = perspectiveCamera ;
else
activeCamera = orthographicCamera ;
activeCamera.position.set( 2 * vtBoxDim.x, 2 * vtBoxDim.y, 2 * vtBoxDim.z) ;
activeCamera.lookAt( vtCenter.x, vtCenter.y, vtCenter.z) ;
scene.add( activeCamera) ;
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x8d8d8d);
hemiLight.position.set(vtCenter.x, vtCenter.y + 2 * vtBoxDim.y, vtCenter.z);
scene.add(hemiLight);
var HemisphereLightHelper = new THREE.Mesh(new THREE.SphereGeometry(15, 30, 15),
new THREE.MeshStandardMaterial({ color: 0xffffff, emissive: 0x404040 }));
HemisphereLightHelper.position.set(vtCenter.x, vtCenter.y + 2 * vtBoxDim.y, vtCenter.z);
const dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(vtPosition.x, vtPosition.y, vtPosition.z);
dirLight.castShadow = true;
dirLight.shadow.camera.top = 50;
dirLight.shadow.camera.bottom = - 25;
dirLight.shadow.camera.left = - 25;
dirLight.shadow.camera.right = 25;
dirLight.shadow.camera.near = 0.1;
dirLight.shadow.camera.far = 200;
dirLight.shadow.mapSize.set(1024, 1024);
scene.add(dirLight);
const DirLighthelper = new THREE.DirectionalLightHelper(dirLight, 100);
const ground = new THREE.Mesh(new THREE.PlaneGeometry(10000, 10000),
new THREE.MeshPhongMaterial({ color: 0x36454F, depthWrite: true, }));
ground.rotation.x = - Math.PI / 2;
ground.position.y = -0.5;
ground.receiveShadow = true;
ground.material.opacity = 0.25;
ground.material.transparent = true;
ground.material.side = THREE.DoubleSide;
//scene.add( ground);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
var container = document.getElementById('WebGL-3mfExport');
container.style.height = '100%';
container.style.width = '100%';
renderer.setSize(m_divStartDimX, m_divStartDimY);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
container.appendChild(renderer.domElement);
var cont = document.getElementById('spinContainer');
container.removeChild(cont);
controls = new OrbitControls(activeCamera, renderer.domElement);
controls.addEventListener('change', render);
controls.update();
window.addEventListener('resize', onWindowResize);
// calcolo origine
const points_array = [ new THREE.Vector3( 0, 0, 0)] ;
var ORIG_Geometry = new THREE.BufferGeometry() ;
ORIG_Geometry.setFromPoints( points_array) ;
var ORIG_Material = new THREE.PointsMaterial({ size: 5, sizeAttenuation : true, color : new THREE.Color( 0x000000)});
ORIG = new THREE.Points( ORIG_Geometry, ORIG_Material) ;
SetOrig( ORIG) ;
// creazione sistema di riferimento nell'origine
const axesHelper = new THREE.AxesHelper( 75 ) ;
axesHelper.rotation.set( -Math.PI/2, 0 ,0) ;
axesHelper.position.set( ORIG.position.x, ORIG.position.y, ORIG.position.z) ;
scene.add( axesHelper );
// creazione della griglia (V1 = finita, V2 = infinita)
const size = 1000000 ;
const divisions = 10000 ;
if ( ! m_bGrid_v1) {
// GRIGLIA INFINITA
const gridHelper = new THREE.GridHelper( size, divisions) ;
gridHelper.position.set( ORIG.position.x, ORIG.position.y, ORIG.position.z) ;
gridHelper.material.transparent = true ;
gridHelper.material.opacity = 0.25 ;
setFog() ;
scene.add( gridHelper) ;
}
else {
// GRIGLIA FINITA
// prendo dimensione del Box
var dDimX = Math.abs( GLBox3D.max.x - GLBox3D.min.x) ;
var dDimY = Math.abs( GLBox3D.max.y - GLBox3D.min.y) ;
var dDimZ = Math.abs( GLBox3D.max.z - GLBox3D.min.z) ;
var dDim = 1.5 * Math.sqrt( dDimX * dDimX + dDimY * dDimY + dDimZ * dDimZ) ;
const gridHelper = new THREE.GridHelper( dDim, Math.ceil( 0.1 * dDim)) ;
gridHelper.position.set( ORIG.position.x + 0.5 * dDim , ORIG.position.y, ORIG.position.z - 0.5 * dDim) ;
gridHelper.material.transparent = true ;
gridHelper.material.opacity = 0.45 ;
scene.add( gridHelper) ;
}
render();
// TEST ===================================
setCameraZoom(m_bZoom);
setCameraPan(m_bPan);
setCameraRot(m_bRot);
setCameraAutoRot(m_bAutoRot);
SetCameraPos( m_nCameraStartPos, ORIG) ;
// =========================================
//console.log('aggiunto 1');
}
function refreshElement(nStart, nEnd) {
//console.log(parseInt(nStart));
for (var i = 0; i < layer_list.length; ++i) {
if (parseInt(layer_list[i].children[0].nLayer) >= parseInt(nStart) &&
parseInt(layer_list[i].children[0].nLayer) <= parseInt(nEnd)) {
layer_list[i].visible = true;
}
else {
layer_list[i].visible = false;
}
}
render();
}
// Utility functions
function onWindowResize() {
}
function render() {
renderer.render(scene, activeCamera);
}
function setCameraZoom(bZoom) {
controls.enableZoom = bZoom;
}
function setCameraPan(bPan) {
controls.enablePan = bPan;
}
function setCameraRot(bRot) {
controls.enableRotate = bRot;
}
function setCameraAutoRot(bAutoRot) {
controls.autoRotate = bAutoRot;
}
function SetCameraPos( nPos, ORIG) {
var nTraslFactor = 3.5 ;
var x ; var y ; var z ;
y = GLBox3D.max.y ; // fixed
switch( nPos) {
case 0 :
x = GLBox3D.min.x ;
z = 0.5 * ( GLBox3D.min.z + GLBox3D.max.z) ;
break ;
case 1 :
x = GLBox3D.min.x ;
z = GLBox3D.max.z ;
break ;
case 2 :
x = 0.5 * ( GLBox3D.min.x + GLBox3D.max.x) ;
z = GLBox3D.max.z ;
break ;
case 3 :
x = GLBox3D.max.x ;
z = GLBox3D.max.z ;
break ;
case 4 :
x = GLBox3D.max.x ;
z = 0.5 * ( GLBox3D.min.z + GLBox3D.max.z) ;
break ;
case 5 :
x = GLBox3D.max.x ;
z = GLBox3D.min.z ;
break ;
case 6 :
x = 0.5 * ( GLBox3D.min.x + GLBox3D.max.x) ;
z = GLBox3D.min.z ;
break ;
case 7 :
x = GLBox3D.min.x ;
z = GLBox3D.min.z ;
break ;
case 8 : // optimal
x = ( ORIG.position.x + 1.0 * Math.abs( GLBox3D.max.x - GLBox3D.min.x)) ;
z = ( ORIG.position.z + 1.0 * Math.abs( GLBox3D.max.z - GLBox3D.min.z)) ;
break ;
default :
return ;
}
var vtPos = new THREE.Vector3( x, y, z) ;
const vtCenter = new THREE.Vector3( 0, 0, 0) ; GLBox3D.getCenter( vtCenter) ;
var vtDirOut = new THREE.Vector3( vtPos.x - vtCenter.x, vtPos.y - vtCenter.y, vtPos.z - vtCenter.z) ;
vtDirOut.x *= nTraslFactor ; vtDirOut.y *= nTraslFactor ; vtDirOut.z *= nTraslFactor ;
//vtDirOut *= nTraslFactor ;
//x *= nTraslFactor ;
//y *= nTraslFactor ;
//z *= nTraslFactor ;
activeCamera.position.set( x + vtDirOut.x, y + vtDirOut.y, z + vtDirOut.z) ;
controls.target.set( vtCenter.x, vtCenter.y, vtCenter.z) ;
console.log( controls) ;
controls.update() ;
}
function SetOrig( ORIG) {
// qui in qualche modo imposto l'origine, ora impostata secondo il BozHelper
// ---- codice da cambiare
var posX = GLBox3D.min.x - 0.3 * ( GLBox3D.max.x - GLBox3D.min.x) ;
var posY = 0 ;
var posZ = GLBox3D.min.z + 1.3 * ( GLBox3D.max.z - GLBox3D.min.z) ;
//ORIG.geometry.translate( posX, posY, posZ) ;
ORIG.position.set( posX, posY, posZ) ;
// -----------------------
//scene.add( ORIG) ;
}
function setFog() {
var dNear = GLBox3D.max.x + 3 * ( GLBox3D.max.x - GLBox3D.min.x) ;
var dFar = 10000 ;
scene.fog = new THREE.Fog( 0xa0a0a0, 20000, 30000);
}