three.js 运行3D模型
HTML
<!DOCTYPE html> <html style="height: 100%;"> <head> <title>model_load</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style> *{ margin:0; padding:0; } #canvas_view { width: 100%; height: 80%; cursor: pointer; position: relative; /*background-image:url(img/bg.png);*/ } .box{ height: 20%; background: #EDEDED; display: flex; } .box div{ width: 50%; height: 100%; } .box>.left>p{ margin:15px auto; } .box>.left{ border-right:1px solid #4D4D4D; } .box>.left>input{ display:block;margin:15px auto; } </style> // 运行模型所需要的第三方 js 文件 <script src="js/threejs/three.js"></script> <script src="js/threejs/Detector.js"></script> <script src="js/threejs/stats.min.js"></script> <script src="js/threejs/ColladaLoader.js"></script><!--3D模型加载器--> <script src="js/threejs/DDSLoader.js"></script> <script src="js/threejs/OrbitControls.js"></script> <script src="js/threejs/VTKloader.js"></script> <script src="js/threejs/TrackballControls.js"></script> <script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.min.js"></script> </head> <body style="height: 100%;"> // 初始化 canvas <div id="canvas_view"> <div id="text_title" style="position: absolute;width:100%;height:20px;margin-top:200px;text-align: center;">请上传模型</div> </div> <div class="box"> <div class="left"> <p> 上传模型:</p> <div class="model_box" style="width:90%;padding: 10px 20px;height: auto;"> <button class="model" style="display: none;"></button> </div> </div> <div class="right" style="overflow: scroll"> <div class="bg_color_box" style="width: 100%;height:50px;background:lightcoral;display: flex;"> <div style="text-align: center;line-height: 50px;">设置背景颜色:</div> <div style="line-height: 50px;text-align: left;"> <input type="color" class="bg_color" value="#c0c0c0"> </div> </div> <!--循环--> <div class="show_element" style="width: 100%;display: none;"> <div style="border-bottom: 2px solid #ccc;width: 100%;height: 86px;display: flex;"> <div class="model_text" style="width: 100px;text-align: center;line-height: 86px;"></div> <div id="model_text2" style="flex: 1"> <div style="width: 100%;height:45px;"> <div style="width: 100%;height:auto;padding:10px 0;display: flex;"> <span> 设置颜色: </span> <input type="color" class="color" value="#400000" style="display: block;margin:0;"> </div> </div> <div style="width: 100%;height: 45px;"> <div style="width: 100%;height:auto;padding:10px 0;display: flex;"> <span> 设置透明度: </span> <input type="range" class="range" value="80" style="background: red;"> </div> </div> </div> </div> </div> </div> </div> //加载模型 构造函数的方法 <script src="resources/model.js"></script> //初始化 调用 函数 <script src="resources/controller.js"></script> </body> </html>
model.js 实例指向的原型方法
/** * -------------- on 2018/8/7. */ function init() { //创建渲染器 width = document.getElementById("canvas_view").width=document.documentElement.clientWidth; height = document.getElementById("canvas_view").height=document.documentElement.clientHeight*0.8; renderer = new THREE.WebGLRenderer({ antialias : true//抗锯齿属性 }); renderer.setPixelRatio( window.devicePixelRatio ); //设置渲染器宽高 renderer.setSize(width, height); //add到页面中 document.getElementById('canvas_view').appendChild(renderer.domElement); //设置渲染器背景颜色和透明度 renderer.setClearColor('#c0c0c0', 1); //更改背景颜色============================= $(".bg_color_box .bg_color").change(function () { var color = this.value; renderer.setClearColor(color, 1); }); //创建相机 camera = new THREE.PerspectiveCamera(45, width / height, 0.01, 2000); //定义相机的位置 camera.position.x = 0; camera.position.y = 0; camera.position.z = 3; //设置相机的方向 camera.up.x = 0; camera.up.y = 1; camera.up.z = 0; camera.lookAt({ x : 0, y : 0, z : 0 }); //控制器 controls = new THREE.TrackballControls( camera ,renderer.domElement ); this.screen.left = 0; this.screen.top = 0; this.screen.width = document.documentElement.clientWidth; this.screen.height = document.documentElement.clientHeight*0.8; //创建场景 scene = new THREE.Scene(); scene.add( camera ); //添加三维辅助线 var axisHelper = new THREE.AxisHelper(500); scene.add(axisHelper); } //创建光源,AmbientLight, function light_fn() { //环境光 light = new THREE.AmbientLight(0xFF0000); //定义光源位置 light.position.set(100, 100, 200); //添加到场景 scene.add(light); //方向光 var dirLight = new THREE.DirectionalLight( 0xffffff ); dirLight.position.set( 200, 200, 1000 ).normalize(); camera.add( dirLight ); camera.add( dirLight.target ); } //创建实物 function initObject() { //统一文件路径 var str = "../model/", //后缀名 suffix = ".vtk", //表示加载每个文件的按钮【tumors:非文件名,仅仅代表按钮,很多小肿瘤的按钮集合】 arr_link = ["liver-1","couinaud-1","couinaud-2","couinaud-3","couinaud-4", "couinaud-5", "couinaud-6","couinaud-7","couinaud-8","tumor-3","tumors"], //肿瘤文件名 tumors = ["tumor-1","tumor-2","tumor-4","tumor-5","tumor-6", "tumor-7","tumor-8","tumor-9","tumor-10","tumor-11"]; //克隆按钮 for(var a in arr_link){ $(".left div .model").css("display","inline"); if(a>="1"){$(".left div .model:eq(0)").clone(true).appendTo('.model_box')} $(".left div .model:eq(-1)").text(arr_link[a]); } var model_arr = []; var idx; var url; var urls; $(".model").click(function () { idx = model_arr.indexOf($(this).index()); if(idx<0){ model_arr.push($(this).index()); if(arr_link[$(this).index()] == "tumors"){ for(var d in tumors){ urls = str + tumors[d] + suffix; loader_model(urls,$(this).index(),d);//加载单个模型 } arr_fn($(this).index(),model_arr);//加一个设置盘 }else{ url = str + arr_link[$(this).index()] + suffix;//拼接字符串 loader_model(url,$(this).index());//加载单个模型 arr_fn($(this).index(),model_arr);//加一个设置盘 } }else{alert("不可重复上传");} }); //克隆节点 function arr_fn(idx,arr) { var text_title = document.getElementById("text_title"); if(text_title) text_title.parentNode.removeChild(text_title);//删除"请上传模型"文本; //true 深度克隆事件 $(".show_element").css("display","inline"); if(arr.length>1){$(".show_element:eq(0)").clone(true).appendTo('.right');} var text = $(".left div .model:eq("+idx+")").text(); $(".show_element:eq(-1) .model_text").text(text);//给text赋值【eq(-1)获取最后一个元素】 $(".show_element:eq(-1) .color").val("#400000");//初始化颜色 $(".show_element:eq(-1) .range").val("80");//初始化透明度 } //颜色设置 $(".show_element .color").change(function () { var str = "请先上传模型"; var idx; var model_idx = $(this).parents("#model_text2").siblings(".model_text").html(); for(var b in arr_link){ if(model_idx==arr_link[b]){ idx=b; } } if(arr_link[Number(idx)] == "tumors"){ for(var e in tumors){ var num_t = Number(e)+1; var vars_name_t = "tumor"+num_t; if(eval(vars_name_t)){eval(vars_name_t).color.set( this.value );}else{alert(str)} } }else{ var num = Number(idx)+1; var vars_name = "material"+num; if(eval(vars_name)){eval(vars_name).color.set( this.value );}else{alert(str)} } }); //透明度设置 $(".show_element .range").change(function () { var range = Number($(this).val())/100; var str = "请先上传模型"; var idx; var model_idx = $(this).parents("#model_text2").siblings(".model_text").html(); for(var c in arr_link){ if(model_idx==arr_link[c]){ idx=c; } } if(arr_link[Number(idx)] == "tumors"){ for(var e in tumors){ var num_t = Number(e)+1; var vars_name_t = "tumor"+num_t; if(eval(vars_name_t)){eval(vars_name_t).opacity = range;}else{alert(str)} } }else{ var num = Number(idx)+1; var vars_name = "material"+num; if(eval(vars_name)){eval(vars_name).opacity = range;}else{alert(str)} } }); //加载模型函数 function loader_model(url,idx,tumors_idx) { var loader = new THREE.VTKLoader(); loader.load( url, function ( geometry ) { geometry.computeVertexNormals(); var mesh; var material = new THREE.MeshPhongMaterial( { color: "#400000",//模型颜色 opacity: 0.8,//模型透明度 depthWrite: false, transparent: true, polygonOffset: true, polygonOffsetFactor: 1, // positive value pushes polygon further away polygonOffsetUnits: 1 } ); if(tumors_idx){ //变量拼接 // var num_t = Number(tumors_idx)+1; // var vars_name_t = "tumor"+num_t; // var vars_name1_t = eval(vars_name_t); // eval(vars_name_t) = material;mesh = new THREE.Mesh( geometry, vars_name1_t ); switch (Number(tumors_idx)+1){ case 1:tumor1=material;mesh = new THREE.Mesh( geometry, tumor1 );break; case 2:tumor2=material;mesh = new THREE.Mesh( geometry, tumor2 );break; case 3:tumor3=material;mesh = new THREE.Mesh( geometry, tumor3 );break; case 4:tumor4=material;mesh = new THREE.Mesh( geometry, tumor4 );break; case 5:tumor5=material;mesh = new THREE.Mesh( geometry, tumor5 );break; case 6:tumor6=material;mesh = new THREE.Mesh( geometry, tumor6 );break; case 7:tumor7=material;mesh = new THREE.Mesh( geometry, tumor7 );break; case 8:tumor8=material;mesh = new THREE.Mesh( geometry, tumor8 );break; case 9:tumor9=material;mesh = new THREE.Mesh( geometry, tumor9 );break; case 10:tumor10=material;mesh = new THREE.Mesh( geometry, tumor10 );break; } }else{ //变量拼接 // var num = Number(idx)+1; // var vars_name = "material"+num; // var vars_name1 = eval(vars_name); // eval(vars_name) = material;mesh = new THREE.Mesh( geometry, vars_name1 ); switch (Number(idx)+1){ case 1:material1=material;mesh = new THREE.Mesh( geometry, material1 );break; case 2:material2=material;mesh = new THREE.Mesh( geometry, material2 );break; case 3:material3=material;mesh = new THREE.Mesh( geometry, material3 );break; case 4:material4=material;mesh = new THREE.Mesh( geometry, material4 );break; case 5:material5=material;mesh = new THREE.Mesh( geometry, material5 );break; case 6:material6=material;mesh = new THREE.Mesh( geometry, material6 );break; case 7:material7=material;mesh = new THREE.Mesh( geometry, material7 );break; case 8:material8=material;mesh = new THREE.Mesh( geometry, material8 );break; case 9:material9=material;mesh = new THREE.Mesh( geometry, material9 );break; case 10:material10=material;mesh = new THREE.Mesh( geometry, material10 );break; case 11:material11=material;mesh = new THREE.Mesh( geometry, material11 );break; } } mesh.position.set( -1, -1, -0.5 ); mesh.scale.multiplyScalar( 0.01 ); scene.add( mesh ); } ); //事件("事件名",事件处理函数,useCapture) window.addEventListener( 'resize', onWindowResize, false ); } //点击事件的处理函数 function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight*0.8; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight*0.8 ); controls.handleResize(); } } //每帧都渲染一次场景与相机到渲染器中 function animation() { renderer.render(scene, camera); controls.update(); //循环执行animation函数 requestAnimationFrame(animation); }
contorler.js 初始化函数
/** * -------------- on 2018/8/7. */ //全局变量 var renderer,width,height,camera,scene,light,controls,stats, //材质/变量【器官】 material1,material2,material3,material4,material5,material6,material7,material8, material9,material10,material11, //材质/变量【肿瘤】 tumor1,tumor2,tumor3,tumor4,tumor5,tumor6,tumor7,tumor8,tumor9,tumor10; if ( ! Detector.webgl ) Detector.addGetWebGLMessage(); //初始化 init(); //创建光源 light_fn(); //创建实物 initObject(); //每帧渲染一次 animation();
如果错误,请指出。谢谢