var container = document.getElementById("container"); var view = document.getElementById("main_viewer"); function getUrlParams() { const urlSearchParams = new URLSearchParams(window.location.search); return Object.fromEntries(urlSearchParams); } if (!Detector.webgl) Detector.addGetWebGLMessage(); var camera, camerHelper, scene, renderer, loader, stats, controls, transformControls, numOfMeshes = 0, model, modelDuplicate, sample_model, wireframe, mat, scale, delta; const manager = new THREE.LoadingManager(); var modelLoaded = false, sample_model_loaded = false; var modelWithTextures = false, fbxLoaded = false, gltfLoaded = false; var bg_Texture = false; var glow_value, selectedObject, composer, effectFXAA, position, outlinePass, ssaaRenderPass; var clock = new THREE.Clock(); var ambient, directionalLight, directionalLight2, directionalLight3, pointLight, bg_colour; var backgroundScene, backgroundCamera, backgroundMesh; var amb = document.getElementById("ambient_light"); var rot1 = document.getElementById("rotation"); var wire = document.getElementById("wire_check"); var model_wire = document.getElementById("model_wire"); var phong = document.getElementById("phong_check"); var xray = document.getElementById("xray_check"); var glow = document.getElementById("glow_check"); var grid = document.getElementById("grid"); var polar_grid = document.getElementById("polar_grid"); var axis = document.getElementById("axis"); var bBox = document.getElementById("bBox"); var transform = document.getElementById("transform"); var smooth = document.getElementById("smooth"); var outline = document.getElementById("outline"); var statsNode = document.getElementById("stats"); //ANIMATION GLOBALS var animations = {}, animationsSelect = document.getElementById("animationSelect"), animsDiv = document.getElementById("anims"), mixer, currentAnimation, actions = {}; //X-RAY SHADER MATERIAL //http://free-tutorials.org/shader-x-ray-effect-with-three-js/ var materials = { default_material: new THREE.MeshLambertMaterial({ side: THREE.DoubleSide }), default_material2: new THREE.MeshLambertMaterial({ side: THREE.DoubleSide }), wireframeMaterial: new THREE.MeshPhongMaterial({ side: THREE.DoubleSide, wireframe: true, shininess: 100, specular: 0x000, emissive: 0x000, flatShading: false, depthWrite: true, depthTest: true, }), wireframeMaterial2: new THREE.LineBasicMaterial({ wireframe: true, color: 0xffffff, }), wireframeAndModel: new THREE.LineBasicMaterial({ color: 0xffffff }), phongMaterial: new THREE.MeshPhongMaterial({ color: 0x555555, specular: 0xffffff, shininess: 10, flatShading: false, side: THREE.DoubleSide, skinning: true, }), xrayMaterial: new THREE.ShaderMaterial({ uniforms: { p: { type: "f", value: 3 }, glowColor: { type: "c", value: new THREE.Color(0x84ccff) }, }, vertexShader: document.getElementById("vertexShader").textContent, fragmentShader: document.getElementById("fragmentShader").textContent, side: THREE.DoubleSide, blending: THREE.AdditiveBlending, transparent: true, depthWrite: false, }), }; var clock = new THREE.Clock(); var winDims = [window.innerWidth * 0.8, window.innerHeight * 0.89]; //size of renderer function onload() { // 是否显示菜单 //window.addEventListener('resize', onWindowResize, false); const dataStr = getUrlParams(); if (!dataStr.target) { document.getElementById("fullscreen").style.display = "block"; document.getElementById("customSlide").style.display = "block"; document.getElementById("collapse_side").style.display = "block"; } else { document.getElementById("fullscreen").style.display = "none"; } switchScene(0); animate(); } function initScene(index) { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 500000 ); camera.position.set(0, 0, 20); //Setup renderer //renderer = new THREE.CanvasRenderer({ alpha: true }); renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor(0x292121); //565646, 29212 view.appendChild(renderer.domElement); THREEx.WindowResize(renderer, camera); ambient = new THREE.AmbientLight(0x404040); $("#ambient_light").change(function () { if (amb.checked) { scene.add(ambient); } else { scene.remove(ambient); } }); /*LIGHTS*/ directionalLight = new THREE.DirectionalLight(0xffeedd); directionalLight.position.set(0, 0, 1).normalize(); scene.add(directionalLight); directionalLight2 = new THREE.DirectionalLight(0xffeedd); directionalLight2.position.set(0, 0, -1).normalize(); scene.add(directionalLight2); directionalLight3 = new THREE.DirectionalLight(0xffeedd); directionalLight3.position.set(0, 1, 0).normalize(); scene.add(directionalLight3); var ambientLight = new THREE.AmbientLight(0x808080, 0.2); //Grey colour, low intensity scene.add(ambientLight); pointLight = new THREE.PointLight(0xcccccc, 0.5); camera.add(pointLight); scene.add(camera); controls = new THREE.OrbitControls(camera, renderer.domElement); controls.enableDamping = true; controls.dampingFactor = 0.09; controls.rotateSpeed = 0.09; transformControls = new THREE.TransformControls(camera, renderer.domElement); transformControls.addEventListener("change", render); scene.add(transformControls); transformControls.addEventListener("mouseDown", function () { controls.enabled = false; }); transformControls.addEventListener("mouseUp", function () { controls.enabled = true; }); window.addEventListener("keydown", function (event) { switch (event.keyCode) { case 82: // R key pressed - set rotate mode transformControls.setMode("rotate"); break; case 84: // T key pressed - set translate mode transformControls.setMode("translate"); break; case 83: // S key pressed - set scale mode transformControls.setMode("scale"); break; } }); //Colour changer, to set background colour of renderer to user chosen colour $(".bg_select").spectrum({ color: "#fff", change: function (color) { $("#basic_log").text("Hex Colour Selected: " + color.toHexString()); //Log information var bg_value = $(".bg_select").spectrum("get").toHexString(); //Get the colour selected renderer.setClearColor(bg_value); //Set renderer colour to the selected hex value ssaaRenderPass.clearColor = bg_value; document.body.style.background = bg_value; //Set body of document to selected colour }, }); // postprocessing var renderPass = new THREE.RenderPass(scene, camera); var fxaaPass = new THREE.ShaderPass(THREE.FXAAShader); var pixelRatio = renderer.getPixelRatio(); fxaaPass.material.uniforms["resolution"].value.x = 1 / (window.innerWidth * pixelRatio); fxaaPass.material.uniforms["resolution"].value.y = 1 / (window.innerHeight * pixelRatio); fxaaPass.renderToScreen = true; outlinePass = new THREE.OutlinePass( new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera ); outlinePass.edgeStrength = 1.5; outlinePass.edgeGlow = 2; composer = new THREE.EffectComposer(renderer); composer.addPass(renderPass); composer.addPass(outlinePass); composer.addPass(fxaaPass); /*LOAD SAMPLE MODELS*/ const dataS = getUrlParams(); // const str = dataS.domain + '/file/api/ApiDownload?md5=' + dataS.md5 let str = ""; let exd = dataS.exd; if (dataS.token != null || dataS.token != undefined) { str = dataS.domain + `/file/api/ApiDownloadForAuthorize?md5=${dataS.md5}&token=${dataS.token}`; } else { str = dataS.domain + `/file/api/ApiDownload?md5=${dataS.md5}`; } var modelList = [ { name: dataS.name, url: str, }, ]; var sceneInfo = modelList[index]; //index from array of sample models in html select options if (exd == "obj") { loader = new THREE.OBJLoader(manager); } if (exd == "fbx" || !exd) { loader = new THREE.FBXLoader(manager); } var url = sceneInfo.url; //progress/loading bar var onProgress = function (data) { if (data.lengthComputable) { //if size of file transfer is known var percentage = Math.round((data.loaded * 100) / data.total); statsNode.innerHTML = "Loaded : " + percentage + "%" + " of " + sceneInfo.name + "
" + ''; $(".progress").css({ width: percentage + "%" }); $(".progress").val(percentage); } }; var onError = function (xhr) { console.log("ERROR"); }; loader.load( url, function (data) { sample_model = data; sample_model_loaded = true; sample_model.traverse(function (child) { if (child instanceof THREE.Mesh) { numOfMeshes++; var geometry = child.geometry; stats(sceneInfo.name, geometry, numOfMeshes); child.material = materials.default_material; var wireframe2 = new THREE.WireframeGeometry(child.geometry); var edges = new THREE.LineSegments( wireframe2, materials.wireframeAndModel ); materials.wireframeAndModel.visible = false; sample_model.add(edges); setWireFrame(child); setWireframeAndModel(child); setPhong(child); setXray(child); } }); setCamera(sample_model); setSmooth(sample_model); setBoundBox(sample_model); setPolarGrid(sample_model); setGrid(sample_model); setAxis(sample_model); scaleUp(sample_model); scaleDown(sample_model); selectedObject = sample_model; outlinePass.selectedObjects = [selectedObject]; outlinePass.enabled = false; scene.add(sample_model); }, onProgress, onError ); $("#transform").on("change", function () { if (transform.checked) { document.getElementById("transformKey").style.display = "block"; if (modelLoaded) { transformControls.attach(model); } else if (sample_model_loaded) { transformControls.attach(sample_model); } } else { document.getElementById("transformKey").style.display = "none"; transformControls.detach(scene); } }); } function getUrlParams() { const urlSearchParams = new URLSearchParams(window.location.search); return Object.fromEntries(urlSearchParams); } function toggleFullscreen(elem) { elem = elem || document.documentElement; if ( !document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) { THREEx.FullScreen.request(container); setTimeout(() => { onload(); }, 200); } else { THREEx.FullScreen.cancel(); // if (document.exitFullscreen) { // document.exitFullscreen() // } else if (document.msExitFullscreen) { // document.msExitFullscreen() // //renderer.setSize(winDims[0], winDims[1]); //Reset renderer size on fullscreen exit // } else if (document.mozCancelFullScreen) { // document.mozCancelFullScreen() // //renderer.setSize(winDims[0], winDims[1]); // } else if (document.webkitExitFullscreen) { // document.webkitExitFullscreen() // // renderer.setSize(winDims[0], winDims[1]); // } } } document.getElementById("fullscreenBtn").addEventListener("click", function () { toggleFullscreen(document.getElementById("container")); }); function removeModel() { scene.remove(model); scale = 1; numOfMeshes = 0; modelLoaded = false; modelWithTextures = false; fbxLoaded = false; gltfLoaded = false; if (ambient) { scene.remove(ambient); } $("#point_light").slider("value", 0.5); pointLight.intensity = 0.5; camera.position.set(0, 0, 20); //Reset camera to initial position controls.reset(); //Reset controls, for when previous object has been moved around e.g. larger object = larger rotation statsNode.innerHTML = ""; //Reset stats box (faces, vertices etc) $("#red, #green, #blue, #ambient_red, #ambient_green, #ambient_blue").slider( "value", 127 ); //Reset colour sliders amb.checked = false; rot1.checked = false; wire.checked = false; model_wire.checked = false; phong.checked = false; xray.checked = false; glow.checked = false; grid.checked = false; polar_grid.checked = false; axis.checked = false; bBox.checked = false; smooth.checked = false; (transform.checked = false), (smooth.disabled = false); //Uncheck any checked boxes transformControls.detach(scene); document.getElementById("smooth-model").innerHTML = "Smooth Model"; $("#rot_slider").slider({ disabled: true, //disable the rotation slider }); controls.autoRotate = false; //Stop model auto rotating if doing so on new file select $("#shine").slider("value", 10); //Set phong shine level back to initial $('input[name="rotate"]').prop("checked", false); //uncheck rotate x, y or z checkboxes animsDiv.style.display = "none"; //Hide animation
} $("#remove").click(function () { removeModel(); }); $("#red, #green, #blue, #ambient_red, #ambient_green, #ambient_blue").slider({ change: function (event, ui) { console.log(ui.value); render(); }, }); var rotVal = [40, 80, 110, 140, 170, 200, 240, 280, 340, 400, 520]; //Rotation speeds low - high var rotation_speed; $("#rot_slider").slider({ orientation: "horizontal", range: "min", max: rotVal.length - 1, value: 0, disabled: true, slide: function (event, ui) { rotation_speed = rotVal[ui.value]; //Set speed variable to the current selected value of slider }, }); $("#rotation").change(function () { if (rot1.checked) { rotation_speed = rotVal[$("#rot_slider").slider("value")]; //set the speed to the current slider value on initial use controls.autoRotate = true; $("#rot_slider").slider({ disabled: false, change: function (event, ui) { console.log(rotVal[ui.value]); controls.autoRotate = true; controls.autoRotateSpeed = delta * rotation_speed; }, }); } else { controls.autoRotate = false; $("#rot_slider").slider({ disabled: true, //disable the slider from being able to rotate object when rotation toggle is off }); } }); function setColours() { var colour = getColours( $("#red").slider("value"), $("#green").slider("value"), $("#blue").slider("value") ); directionalLight.color.setRGB(colour[0], colour[1], colour[2]); directionalLight2.color.setRGB(colour[0], colour[1], colour[2]); directionalLight3.color.setRGB(colour[0], colour[1], colour[2]); var colour = getColours( $("#ambient_red").slider("value"), $("#ambient_green").slider("value"), $("#ambient_blue").slider("value") ); ambient.color.setRGB(colour[0], colour[1], colour[2]); } function getColours(r, g, b) { var colour = [r.valueOf() / 255, g.valueOf() / 255, b.valueOf() / 255]; return colour; } function render() { setColours(); // renderer.render(scene, camera); } function animate() { delta = clock.getDelta(); requestAnimationFrame(animate); if (mixer) { mixer.update(delta); } controls.update(delta); composer.render(); render(); } function switchScene(index) { clear(); initScene(index); var elt = document.getElementById("scenes_list"); elt.selectedIndex = index; } function selectModel() { var select = document.getElementById("scenes_list"); var index = select.selectedIndex; if (index >= 0) { removeModel(); switchScene(index); } } function clear() { if (view && renderer) { view.removeChild(renderer.domElement); document.body.style.background = "#292121"; } } onload();