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 = '' 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 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()