1. 程式人生 > >three.js 原始碼註釋(六十)objects/Line.js

three.js 原始碼註釋(六十)objects/Line.js


俺也是剛開始學,好多地兒肯定不對還請見諒.

以下程式碼是THREE.JS 原始碼檔案中objects/Line.js檔案的註釋.


/**
 * @author mrdoob / http://mrdoob.com/
 */
/*
///Line物件,建立一條線,或者一組線.
/// 用法:var geometry = new THREE.Geometry();				//建立geometry物件
///		 var material = new THREE.LineBasicMaterial({color: 0xffff00});	//建立材質物件,這裡有專門適用於line物件的材質物件LineBasicMaterial.
///		 geometry.verteces.push(new THREE.Vector3(-10,0,0),			//為geometry物件新增verteces頂點資料
///				new THREE.Vector3(0,10,0),
///				new THREE.Vector3(10,0,0)
///		 );
///		 var line = new THREE.Mesh(geometry, material,THREE.LineStrip);	//通過geometry的頂點資料建立材質為material,型別為THREE.LineStrip(不閉合的折線)的線.
///		 scene.add(line); 	//將線新增到場景中.
*/
///<summary>Line</summary>
///<param name ="geometry" type="THREE.Geometry">Geometry物件(燈籠的框架)</param>
///<param name ="material" type="THREE.Material">Material物件(材質物件)</param>
///<param name ="type" type="線型別常量">線型別常量,有不閉合折線(THREE.LineStrip),多組雙頂點線段(THREE.LinePieces)</param>
///<returns type="Mesh">返回Line物件</returns>
THREE.Line = function ( geometry, material, type ) {

	THREE.Object3D.call( this );	//呼叫Object3D物件的call方法,將原本屬於Object3D的方法交給當前物件Line來使用.

	this.geometry = geometry !== undefined ? geometry : new THREE.Geometry();	//將引數geometry賦值給line物件的geometry屬性
	this.material = material !== undefined ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } );	//將引數material賦值給line物件的material屬性,如果沒有傳遞material引數,將建立隨機顏色材質,賦值給當前mesh物件

	this.type = ( type !== undefined ) ? type : THREE.LineStrip;	//將引數type賦值給line對像的type屬性,如果沒有傳遞type引數,預設初始化為THREE.LineStrip型別.

};

THREE.LineStrip = 0;	//不閉合折線
THREE.LinePieces = 1;	//多組雙頂點線段
//TODO: 缺少THREE.LineLoop	//閉合折線.

/*************************************************
****下面是Line物件的方法屬性定義,繼承自Object3D
**************************************************/
THREE.Line.prototype = Object.create( THREE.Object3D.prototype );

/*
///raycast方法用來獲得當前物件與射線(引數raycaster)的交點.raycaster.intersectObject會呼叫這個方法。主要是用來進行碰撞檢測,
/// 在選擇場景中的物件時經常會用到,判斷當前滑鼠是否與物件重合用來選擇物件.
/// NOTE:raycast方法中引數intersects引數用來儲存交點的集合,格式如下
///	intersects.push( {
///
///				distance: distance,
///				point: intersectionPoint,
///				face: null,
///				faceIndex: null,
///				object: this
///
///			} );
///
*////<summary>raycast</summary>
///<param name ="raycaster" type="THREE.Raycaster">射線物件</param>
///<param name ="intersects" type="ObjectArray">交點的屬性集合</param>
///<returns type="ObjectArray">交點的屬性集合</returns>
THREE.Line.prototype.raycast = ( function () {

	var inverseMatrix = new THREE.Matrix4();
	var ray = new THREE.Ray();
	var sphere = new THREE.Sphere();

	return function ( raycaster, intersects ) {

		var precision = raycaster.linePrecision;	//射線和Line物件相交的精度因子。
		var precisionSq = precision * precision;	//精度因子的平方

		var geometry = this.geometry;

		if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();	//確保boundingSphere屬性不為null

		// Checking boundingSphere distance to ray
		//檢查線段的球體界限到射線的距離

		sphere.copy( geometry.boundingSphere );
		sphere.applyMatrix4( this.matrixWorld );

		if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) {		//如果幾何體的球體界限與射線不想交

			return;														    //返回

		}

		inverseMatrix.getInverse( this.matrixWorld );	//獲得當前物件的this.matrixWorld屬性的逆矩陣
		ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );	//給射線物件的原點,方向,乘以逆矩陣,

		/* if ( geometry instanceof THREE.BufferGeometry ) {

		} else */ if ( geometry instanceof THREE.Geometry ) {

			var vertices = geometry.vertices;
			var nbVertices = vertices.length;
			var interSegment = new THREE.Vector3();
			var interRay = new THREE.Vector3();
			var step = this.type === THREE.LineStrip ? 1 : 2;

			for ( var i = 0; i < nbVertices - 1; i = i + step ) {	//如果是不閉合折線,每次自變數+1,如果是多組雙頂點線段,自變數每次+2

				var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );	//distanceSqToSegment方法將返回有引數vertices[ i ], vertices[ i + 1 ]組成的線段到當前射線的最小距離.interRay, interSegment,分別用來儲存在射線上和線上段上的垂足

				if ( distSq > precisionSq ) continue;	//如果最小距離大於精度因子,退出迴圈.

				var distance = ray.origin.distanceTo( interRay );	//射線原點到射線到線段的垂足的距離.

				if ( distance < raycaster.near || distance > raycaster.far ) continue;	//如果距離小於射線的近端,或大於射線的遠端,跳出迴圈

				intersects.push( {		//將相交的物件,頂點索引,距離,交點儲存到intersects屬性陣列中

					distance: distance,		//距離
					// What do we want? intersection point on the ray or on the segment??
					// 我們要什麼,交點在射線上或者線上段上
					// point: raycaster.ray.at( distance ), 如果要在射線上,那就將raycaster.ray.at( distance )的賦值給point
					point: interSegment.clone().applyMatrix4( this.matrixWorld ),	//如果想要獲得交點線上段的位置,將interSegment.clone().applyMatrix4( this.matrixWorld )賦值給point
					face: null,			//面
					faceIndex: null,		//面所在屬性陣列中的索引
					object: this			//物件

				} );

			}

		}

	};

}() );

/*clone方法
///clone方法克隆一個Line網格物件.
*/
///<summary>clone</summary>
///<param name ="object" type="Object3D">接收克隆的Object3D物件</param>
///<returns type="Ray">返回Line網格物件.</returns>	
THREE.Line.prototype.clone = function ( object ) {

	if ( object === undefined ) object = new THREE.Line( this.geometry, this.material, this.type );

	THREE.Object3D.prototype.clone.call( this, object );	//繼承Object3D的clone方法

	return object;		//返回Mesh網格物件.

};



以下程式碼是THREE.JS 原始碼檔案中objects/Line.js檔案的註釋.