1. 程式人生 > >three.js學習 函式使用方法散記3

three.js學習 函式使用方法散記3

二十三  通過json物件控制動畫

//SphereGeometry
				var sphereGeometry = new THREE.SphereGeometry( 5, 32, 32 );
				var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
				var sphereMesh = new THREE.Mesh( sphereGeometry, material );
				
				//Setup animation
				sphereMesh.animation = {
					"name"      : "Action",
					"fps"       : 25,
					"length"    : 2.0, 
					"hierarchy" : [
						{
							"parent" : -1, //root
							"keys"   : [
								{
									"time":0,
									"pos" :[0,0,0],
									"rot" :[0,0,0],
									"scl" :[1,1,1]
								},
								{
									"time":1.0,
									"pos" :[30,0,0]
								}
								,
								{
									"time":2.0,
									"pos" :[0,0,0]
								}
							]
						}
					]
				};
				//定義json物件
				ensureLoop( sphereMesh.animation );
				//保持迴圈 函式定義將下一個動作賦值為上一個動作
				THREE.AnimationHandler.add( sphereMesh.animation );
				//新增動畫監聽器								
				var sphereMeshAnimation = new THREE.Animation( sphereMesh, sphereMesh.animation.name )
				//定義動畫物件 
				sphereMeshAnimation.play();
				//動畫播放
				scene.add( sphereMesh );
ensure函式定義
var ensureLoop = function( animation ) {

				for ( var i = 0; i < animation.hierarchy.length; i ++ ) {
          
					var obj = animation.hierarchy[ i ];

					var first = obj.keys[ 0 ];
					var last = obj.keys[ obj.keys.length - 1 ];

					last.pos = first.pos;
					last.rot = first.rot;
					last.scl = first.scl;

				}

			};
還要在render函式裡呼叫

var delta = clock.getDelta();

THREE.AnimationHandler.update( delta );

二十四 flycontrols

controls = new THREE.FlyControls( camera );

				controls.movementSpeed = 1000;
				controls.domElement = container;
				controls.rollSpeed = Math.PI / 24;
				controls.autoForward = false;
				controls.dragToLook = false;

二十五 three.js 還支援or的模擬..很碉堡的樣子

二十六 給場景新增霧

scene = new THREE.Scene();
				scene.fog = new THREE.FogExp2( 0xcccccc, 0.002/*霧的濃度 越小越稀疏*/ );

二十七 用滑鼠控制場景obit contorl
controls = new THREE.OrbitControls( camera );
				controls.addEventListener( 'change', render );//render函式作為引數 "change"貌似是內定的  改成change1控制會失效

二十八 按照路徑控制鏡頭
controls = new THREE.PathControls( camera );

				controls.waypoints = [ [ -500, 0, 0 ], [ 0, 200, 0 ], [ 500, 0, 0 ] ];
                //傳入一些點 攝像頭會根據點的順序依次走 走完回到原點繼續走
				controls.duration = 28
                //攝像頭的移動速度 越小越快
				controls.useConstantSpeed = true;
				//controls.createDebugPath = true;
				//controls.createDebugDummy = true;
				controls.lookSpeed = 0.06;//滑鼠控制鏡頭觀察點速度
				controls.lookVertical = true;//允許滑鼠控制觀察點 上下移動
				controls.lookHorizontal = true;//....              左右移動
				controls.verticalAngleMap = { srcRange: [ 0, 2 * Math.PI ], dstRange: [ 1.1, 3.8 ] };
				controls.horizontalAngleMap = { srcRange: [ 0, 2 * Math.PI ], dstRange: [ 0.3, Math.PI - 0.3 ] };
				controls.lon = 180;//貌似影響著滑鼠控制的速度

				controls.init();
controls.animation.play();

render函式裡要呼叫 controls.update(delta);var delta = clock.getDelta(); var clock = new THREE.Clock();

二十九  滑鼠鎖定物件

controls = new THREE.PointerLockControls( camera );
				scene.add( controls.getObject() );

				ray = new THREE.Raycaster();//用以檢測controls物件 和場景物體的碰撞
				ray.ray.direction.set( 0, -1, 0 );//設定碰撞的方向
var objects  = [];					
objects.push( mesh );
function animate() {

				requestAnimationFrame( animate );

				//

				controls.isOnObject( false );//先設定沒有碰撞到物體

				ray.ray.origin.copy( controls.getObject().position );
				ray.ray.origin.y -= 10;//這兩個是獲得初始位置?

				var intersections = ray.intersectObjects( objects );//碰撞物件傳進引數

				if ( intersections.length > 0 ) {

					var distance = intersections[ 0 ].distance;

					if ( distance > 0 && distance < 10 ) {

						controls.isOnObject( true );//貌似這個為true  camera就會停下來  表現為碰撞到物體了

					}

				}

				controls.update( Date.now() - time );//以時間為標誌更新攝像頭的位置麼

				renderer.render( scene, camera );

				time = Date.now();

			}

三十 動態修改矩陣方法(來自misc-lookat例子)

var geometry = new THREE.CylinderGeometry( 0, 10, 100, 3 );//任意一個geometry
geometry.applyMatrix(new THREE.Matrix4().makeRotationFromEuler(new THREE.Euler(-Math.PI/2, Math.PI,0)));
//euler應該是返回一個原點指向引數的向量 前3個引數是x y z 以弧度為單位 然後傳入geometry的applyMatrix 通過matrix4的旋轉方法將geometry指向向量的方向 這裡用來初始化物體方向
scene.matrixAutoUpdate = false;//改由手動修改矩陣
for ( var i = 1, l = scene.children.length; i < l; i ++ ) {
scene.children[ i ].lookAt( sphere.position );//object.lookat 傳入向量可以使物體旋轉
				}
三十一 聲音使用
var Sound = function ( sources, radius, volume ) {

				var audio = document.createElement( 'audio' );//新建audio元素

				for ( var i = 0; i < sources.length; i ++ ) {

					var source = document.createElement( 'source' );
					source.src = sources[ i ];

					audio.appendChild( source );//新建source元素並新增到audio元素

				}

				this.position = new THREE.Vector3();

				this.play = function () {

					audio.play();//播放
                    
				}

				this.update = function ( camera ) {

					var distance = this.position.distanceTo( camera.position );

					if ( distance <= radius ) {

						audio.volume = volume * ( 1 - distance / radius );//用volume控制音量 這裡通過距離控制音量

					} else {

						audio.volume = 0;

					}

				}

			}

三十二 FirstPersonControls.js
controls = new THREE.FirstPersonControls( camera );

				controls.movementSpeed = 70;
				controls.lookSpeed = 0.05;
				controls.noFly =false;//這個不知何用
				controls.lookVertical = true;//設定是否允許攝像頭上下移動
				controls.handleResize();//用在視窗大小變換時候執行
var delta = clock.getDelta(),
					time = clock.getElapsedTime() * 5;

				controls.update( 0.02 );//這個引數越小鏡頭運動越快,,設定的是什麼= =

三十三 測試geometry的點和麵

		<script src="js/UVsUtils.js"></script>
function test(name, geometry) {
var d = document.createElement('div');
d.innerHTML = '<br><br>' + name + '<br>';
d.appendChild(THREE.UVsDebug(geometry));//傳入geometry物件 返回的是一個canvas 已畫出geometry的結構
document.body.appendChild(d);
}

三十四 webglrederer3 

<script src="js/renderers/WebGLRenderer3.js"></script>

renderer = new THREE.WebGLRenderer3( { contextAttributes: { antialias: false /*抗鋸齒*/ } } );

//提供引數設定屬性也許效能比較好?

三十五 著色器用法

var uniforms = { texture:  { type: "t", value: clothTexture } };
				var vertexShader = document.getElementById( 'vertexShaderDepth' ).textContent;//在script標籤設定id值.然後getelementbyid
				var fragmentShader = document.getElementById( 'fragmentShaderDepth' ).textContent;

				// cloth mesh

				object = new THREE.Mesh( clothGeometry, clothMaterial );
				object.position.set( 0, 0, 0 );
				object.castShadow = true;
				object.receiveShadow = true;
				scene.add( object );

				object.customDepthMaterial = new THREE.ShaderMaterial( { uniforms: uniforms, vertexShader: vertexShader, fragmentShader: fragmentShader } );//新增著色器把..
三十六  buffergeometry 用法

大概是新建一個buffergeometry 先初始化陣列 在往數組裡賦值   

執行前先載入..載入後處理速度較快

var triangles = 160000;

				var geometry = new THREE.BufferGeometry();

				geometry.addAttribute( 'index', Uint16Array, triangles * 3, 1);
				geometry.addAttribute( 'position', Float32Array, triangles * 3, 3 );
				geometry.addAttribute( 'normal', Float32Array, triangles * 3, 3 );
				geometry.addAttribute( 'color', Float32Array, triangles * 3, 3 );//新增屬性  應該類似初始化 未有值的..

				// break geometry into
				// chunks of 21,845 triangles (3 unique vertices per triangle)
				// for indices to fit into 16 bit integer number
				// floor(2^16 / 3) = 21845

				var chunkSize = 21845;//整體的大小?

				var indices = geometry.attributes.index.array;

				for ( var i = 0; i < indices.length; i ++ ) {

					indices[ i ] = i % ( 3 * chunkSize );//獲取索引陣列

				}

				var positions = geometry.attributes.position.array;
				var normals = geometry.attributes.normal.array;
				var colors = geometry.attributes.color.array;

				var color = new THREE.Color();

				var n = 800, n2 = n/2;	// triangles spread in the cube
				var d = 12, d2 = d/2;	// individual triangle size

				var pA = new THREE.Vector3();
				var pB = new THREE.Vector3();
				var pC = new THREE.Vector3();

				var cb = new THREE.Vector3();
				var ab = new THREE.Vector3();

				for ( var i = 0; i < positions.length; i += 9 ) {

					// positions

					var x = Math.random() * n - n2;
					var y = Math.random() * n - n2;
					var z = Math.random() * n - n2;

					var ax = x + Math.random() * d - d2;
					var ay = y + Math.random() * d - d2;
					var az = z + Math.random() * d - d2;

					var bx = x + Math.random() * d - d2;
					var by = y + Math.random() * d - d2;
					var bz = z + Math.random() * d - d2;

					var cx = x + Math.random() * d - d2;
					var cy = y + Math.random() * d - d2;
					var cz = z + Math.random() * d - d2;

					positions[ i ]     = ax;
					positions[ i + 1 ] = ay;
					positions[ i + 2 ] = az;

					positions[ i + 3 ] = bx;
					positions[ i + 4 ] = by;
					positions[ i + 5 ] = bz;

					positions[ i + 6 ] = cx;
					positions[ i + 7 ] = cy;
					positions[ i + 8 ] = cz;

					// flat face normals

					pA.set( ax, ay, az );
					pB.set( bx, by, bz );
					pC.set( cx, cy, cz );

					cb.subVectors( pC, pB );
					ab.subVectors( pA, pB );
					cb.cross( ab );

					cb.normalize();

					var nx = cb.x;
					var ny = cb.y;
					var nz = cb.z;

					normals[ i ]     = nx;
					normals[ i + 1 ] = ny;
					normals[ i + 2 ] = nz;

					normals[ i + 3 ] = nx;
					normals[ i + 4 ] = ny;
					normals[ i + 5 ] = nz;

					normals[ i + 6 ] = nx;
					normals[ i + 7 ] = ny;
					normals[ i + 8 ] = nz;

					// colors

					var vx = ( x / n ) + 0.5;
					var vy = ( y / n ) + 0.5;
					var vz = ( z / n ) + 0.5;

					color.setRGB( vx, vy, vz );

					colors[ i ]     = color.r;
					colors[ i + 1 ] = color.g;
					colors[ i + 2 ] = color.b;

					colors[ i + 3 ] = color.r;
					colors[ i + 4 ] = color.g;
					colors[ i + 5 ] = color.b;

					colors[ i + 6 ] = color.r;
					colors[ i + 7 ] = color.g;
					colors[ i + 8 ] = color.b;

				}

				geometry.offsets = [];

				var offsets = triangles / chunkSize;

				for ( var i = 0; i < offsets; i ++ ) {

					var offset = {
						start: i * chunkSize * 3,
						index: i * chunkSize * 3,
						count: Math.min( triangles - ( i * chunkSize ), chunkSize ) * 3
					};

					geometry.offsets.push( offset );

				}

				geometry.computeBoundingSphere();