1. 程式人生 > >47 Three.js使用THREE.ParametricGeometry生成平面圖形、波浪圖形、和克萊因瓶

47 Three.js使用THREE.ParametricGeometry生成平面圖形、波浪圖形、和克萊因瓶

var renderer; function initRender() { renderer = new THREE.WebGLRenderer({antialias:true}); //renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0)); //設定背景顏色 renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); } var
camera; function initCamera() { camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 10000); camera.position.set(0, 0, 150); } var scene; function initScene() { scene = new THREE.Scene(); } var light; function initLight() { scene.add(new
THREE.AmbientLight(0x404040)); light = new THREE.DirectionalLight(0xffffff); light.position.set(1,1,1); scene.add(light); } //建立平面模型的方法 var plane = function (u, v) { var x = u*50; var y = 0; var z = v*50; return new THREE.Vector3(x, y, z); }; //建立波浪圖形的方法
var radialWave = function (u, v) { var r = 50; var x = Math.sin(u) * r; var z = Math.sin(v / 2) * 2 * r; var y = (Math.sin(u * 4 * Math.PI) + Math.cos(v * 2 * Math.PI)) * 2.8; return new THREE.Vector3(x, y, z); }; var klein = function (u, v) { u *= Math.PI; v *= 2 * Math.PI; u = u * 2; var x, y, z; if (u < Math.PI) { x = 3 * Math.cos(u) * (1 + Math.sin(u)) + (2 * (1 - Math.cos(u) / 2)) * Math.cos(u) * Math.cos(v); z = -8 * Math.sin(u) - 2 * (1 - Math.cos(u) / 2) * Math.sin(u) * Math.cos(v); } else { x = 3 * Math.cos(u) * (1 + Math.sin(u)) + (2 * (1 - Math.cos(u) / 2)) * Math.cos(v + Math.PI); z = -8 * Math.sin(u); } y = -2 * (1 - Math.cos(u) / 2) * Math.sin(v); return new THREE.Vector3(x, y, z); }; function initModel() { //軸輔助 (每一個軸的長度) object = new THREE.AxisHelper( 50 ); scene.add( object ); var mesh = createMesh(new THREE.ParametricGeometry(klein, 12, 12)); scene.add(mesh); } //生成模型 function createMesh(geom) { //設定當前的模型矩陣沿xy軸偏移,讓圖片處於顯示中心 geom.applyMatrix(new THREE.Matrix4().makeTranslation(0, 0, 0)); // 建立法向量紋理 var meshMaterial = new THREE.MeshNormalMaterial({ flatShading: THREE.FlatShading, transparent: true, opacity: 0.9 }); // 建立一個線框紋理 var wireFrameMat = new THREE.MeshBasicMaterial(); wireFrameMat.wireframe = true; // 建立模型 var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial,wireFrameMat]); return mesh; } //初始化效能外掛 var stats; function initStats() { stats = new Stats(); document.body.appendChild(stats.dom); } //使用者互動外掛 滑鼠左鍵按住旋轉,右鍵按住平移,滾輪縮放 var controls; function initControls() { controls = new THREE.OrbitControls( camera, renderer.domElement ); // 如果使用animate方法時,將此函式刪除 //controls.addEventListener( 'change', render ); // 使動畫迴圈使用時阻尼或自轉 意思是否有慣性 controls.enableDamping = true; //動態阻尼係數 就是滑鼠拖拽旋轉靈敏度 //controls.dampingFactor = 0.25; //是否可以縮放 controls.enableZoom = true; //是否自動旋轉 controls.autoRotate = false; //設定相機距離原點的最遠距離 controls.minDistance = 20; //設定相機距離原點的最遠距離 controls.maxDistance = 10000; //是否開啟右鍵拖拽 controls.enablePan = true; } //生成gui設定配置項 var gui; function initGui() { //宣告一個儲存需求修改的相關資料的物件 gui = {}; var datGui = new dat.GUI(); //將設定屬性新增到gui當中,gui.add(物件,屬性,最小值,最大值) //呼叫生成一次圖形 gui.asGeom(); } function render() { renderer.render( scene, camera ); } //視窗變動觸發的函式 function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); render(); renderer.setSize( window.innerWidth, window.innerHeight ); } function animate() { //更新控制器 controls.update(); render(); //更新效能外掛 stats.update(); requestAnimationFrame(animate); } function draw() { initRender(); initScene(); initCamera(); initLight(); initModel(); initControls(); initStats(); //initGui(); animate(); window.onresize = onWindowResize; }