three.js 源碼註釋(八十五)extras/geometries/PolyhedronGeometry.js

商域無疆 (http://blog.csdn.net/omni360/)

本文遵循“署名-非商業用途-保持一致”創作公用協議

轉載請保留此句:商域無疆 -  本博客專注於 敏捷開發及移動和物聯設備研究:數據可視化、GOLANG、Html5、WEBGL、THREE.JS否則,出自本博客的文章拒絕轉載或再轉載,謝謝合作。


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

以下代碼是THREE.JS 源碼文件中extras/geometries/PolyhedronGeometry.js文件的註釋.

更多更新在 : https://github.com/omni360/three.js.sourcecode


/**
 * @author clockworkgeek / https://github.com/clockworkgeek
 * @author timothypratley / https://github.com/timothypratley
 * @author WestLangley / http://github.com/WestLangley
*/
/*
///PolyhedronGeometry用來在三維空間內創建一個多面體對象,二十面體,八面體,四面體都會調用當前對象.
///
///	用法: 
///		  var vertices = [ 1,  1,  1,   - 1, - 1,  1,   - 1,  1, - 1,    1, - 1, - 1 ];
///		  var indices = [ 2,  1,  0,    0,  3,  2,    1,  3,  0,    2,  3,  1 ];
///		  var geometry = new THREE.PolyhedronGeometry(vertices,indices,70);	
/// 	  var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
/// 	  var icos = new THREE.Mesh(geometry,material);
/// 	  scene.add(icos);
*/
///<summary>PolyhedronGeometry</summary>
///<param name ="vertices" type="float">多面體頂點數組</param>
///<param name ="indices" type="float">多面體頂點索引順序</param>
///<param name ="radius" type="float">多面體半徑,默認初始化爲1</param>
///<param name ="detail" type="float">細節因子,默認爲0,當超過0將會有更多的頂點,當前的幾何體就不會是多面體,當參數detail大於1,將會變成一個球體.</param>
THREE.PolyhedronGeometry = function ( vertices, indices, radius, detail ) {

	THREE.Geometry.call( this );	//調用Geometry對象的call方法,將原本屬於Geometry的方法交給當前對象PolyhedronGeometry來使用.

	radius = radius || 1;	//多面體半徑,默認初始化爲1
	detail = detail || 0;	//細節因子,默認爲0,當超過0將會有更多的頂點,當前的幾何體就不會是多面體,當參數detail大於1,將會變成一個球體.

	var that = this;
	//計算頂點數據,壓入vertices數組.
	for ( var i = 0, l = vertices.length; i < l; i += 3 ) {

		prepare( new THREE.Vector3( vertices[ i ], vertices[ i + 1 ], vertices[ i + 2 ] ) );

	}

	var midpoints = [], p = this.vertices;

	var faces = [];
	//計算三角面.
	for ( var i = 0, j = 0, l = indices.length; i < l; i += 3, j ++ ) {

		var v1 = p[ indices[ i     ] ];
		var v2 = p[ indices[ i + 1 ] ];
		var v3 = p[ indices[ i + 2 ] ];

		faces[ j ] = new THREE.Face3( v1.index, v2.index, v3.index, [ v1.clone(), v2.clone(), v3.clone() ] );

	}

	var centroid = new THREE.Vector3();

	for ( var i = 0, l = faces.length; i < l; i ++ ) {

		subdivide( faces[ i ], detail );

	}


	// Handle case when face straddles the seam
	// 處理當面橫跨縫合線的特殊情況

	for ( var i = 0, l = this.faceVertexUvs[ 0 ].length; i < l; i ++ ) {

		var uvs = this.faceVertexUvs[ 0 ][ i ];

		var x0 = uvs[ 0 ].x;
		var x1 = uvs[ 1 ].x;
		var x2 = uvs[ 2 ].x;

		var max = Math.max( x0, Math.max( x1, x2 ) );
		var min = Math.min( x0, Math.min( x1, x2 ) );

		if ( max > 0.9 && min < 0.1 ) { // 0.9 is somewhat arbitrary

			if ( x0 < 0.2 ) uvs[ 0 ].x += 1;
			if ( x1 < 0.2 ) uvs[ 1 ].x += 1;
			if ( x2 < 0.2 ) uvs[ 2 ].x += 1;

		}

	}


	// Apply radius
	// 對頂點應用位置,乘以半徑值.

	for ( var i = 0, l = this.vertices.length; i < l; i ++ ) {

		this.vertices[ i ].multiplyScalar( radius );

	}


	// Merge vertices 合併頂點

	this.mergeVertices();	//去除多餘的頂點

	this.computeFaceNormals();	//計算面的法線

	this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius );	//計算球體邊界

	/*
	///prepare是計算頂點位置的具體實現,將傳入的向量(參數Vector3)投影到球體的表面
	*/
	///<summary>prepare</summary>
	///<param name ="radius" type="Vector3"></param>
	///<return type="Vector3">球體體半徑</param>
	// Project vector onto sphere's surface
	// 投影矢量到球體的表面.
	function prepare( vector ) {

		var vertex = vector.normalize().clone();
		vertex.index = that.vertices.push( vertex ) - 1;

		// Texture coords are equivalent to map coords, calculate angle and convert to fraction of a circle.
		// 紋理座標等於貼圖uv座標,計算角度並轉換爲圓的一部分.

		var u = azimuth( vector ) / 2 / Math.PI + 0.5;
		var v = inclination( vector ) / Math.PI + 0.5;
		vertex.uv = new THREE.Vector2( u, 1 - v );

		return vertex;	//返回對應的頂點

	}

	/*
	///make是細分曲面的具體實現,遞歸計算曲面頂點,轉換爲細分的三角形
	*/
	///<summary>make</summary>
	///<param name ="v1" type="Vector3">三角形的第一個頂點</param>
	///<param name ="v2" type="Vector3">三角形的第二個頂點</param>
	///<param name ="v3" type="Vector3">三角形的第三個頂點</param>
	// Approximate a curved face with recursively sub-divided triangles.
	//遞歸計算曲面頂點,轉換爲細分的三角形.
	function make( v1, v2, v3 ) {

		var face = new THREE.Face3( v1.index, v2.index, v3.index, [ v1.clone(), v2.clone(), v3.clone() ] );
		that.faces.push( face );

		centroid.copy( v1 ).add( v2 ).add( v3 ).divideScalar( 3 );

		var azi = azimuth( centroid );

		that.faceVertexUvs[ 0 ].push( [
			correctUV( v1.uv, v1, azi ),
			correctUV( v2.uv, v2, azi ),
			correctUV( v3.uv, v3, azi )
		] );

	}

	/*
	///make是細分曲面的具體實現,遞歸計算曲面頂點,轉換爲細分的三角形
	*/
	///<summary>make</summary>
	///<param name ="face" type="Face3">三角面</param>
	///<param name ="detail" type="float">細節因子,默認爲0,當超過0將會有更多的頂點,當前的幾何體就不會是多面體,當參數detail大於1,將會變成一個球體</param>
	// Analytically subdivide a face to the required detail level.
	//按照要求的細節因子,細分三角面.
	function subdivide( face, detail ) {

		var cols = Math.pow(2, detail);
		var cells = Math.pow(4, detail);
		var a = prepare( that.vertices[ face.a ] );
		var b = prepare( that.vertices[ face.b ] );
		var c = prepare( that.vertices[ face.c ] );
		var v = [];

		// Construct all of the vertices for this subdivision.
		// 構建所有的細分三角形頂點.

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

			v[ i ] = [];

			var aj = prepare( a.clone().lerp( c, i / cols ) );
			var bj = prepare( b.clone().lerp( c, i / cols ) );
			var rows = cols - i;

			for ( var j = 0; j <= rows; j ++) {

				if ( j == 0 && i == cols ) {

					v[ i ][ j ] = aj;

				} else {

					v[ i ][ j ] = prepare( aj.clone().lerp( bj, j / rows ) );

				}

			}

		}

		// Construct all of the faces.
		// 構建所有的三角面

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

			for ( var j = 0; j < 2 * (cols - i) - 1; j ++ ) {

				var k = Math.floor( j / 2 );

				if ( j % 2 == 0 ) {

					make(
						v[ i ][ k + 1],
						v[ i + 1 ][ k ],
						v[ i ][ k ]
					);

				} else {

					make(
						v[ i ][ k + 1 ],
						v[ i + 1][ k + 1],
						v[ i + 1 ][ k ]
					);

				}

			}

		}

	}


	/*
	///azimuth方法獲得一個點當從上面看時,繞y軸的角度.
	*/
	///<summary>azimuth</summary>
	///<param name ="vector" type="Vector3">三維向量</param>
	// Angle around the Y axis, counter-clockwise when looking from above.
	// 當從上面看時,繞y軸的角度.
	function azimuth( vector ) {

		return Math.atan2( vector.z, - vector.x );

	}

	/*
	///inclination方法獲得一個點在xz平面上的角度.
	*/
	///<summary>inclination</summary>
	///<param name ="vector" type="Vector3">三維向量</param>
	// Angle above the XZ plane.
	// 獲得一個點在xz平面上的角度.
	function inclination( vector ) {

		return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );

	}


	/*
	///inclination方法獲得一個點在xz平面上的角度.
	*/
	///<summary>inclination</summary>
	///<param name ="uv" type="Vector2">二維向量</param>
	///<param name ="vector" type="Vector3">三維向量</param>
	///<param name ="azimuth" type="Vector3">一個點當從上面看時,繞y軸的角度</param>
	// Texture fixing helper. Spheres have some odd behaviours.
	// 紋理替換輔助器,因爲多面體表面和球體相比有一些奇怪的棱角,這裏爲了讓紋理更好的適配多面體表面.
	function correctUV( uv, vector, azimuth ) {

		if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) uv = new THREE.Vector2( uv.x - 1, uv.y );
		if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) uv = new THREE.Vector2( azimuth / 2 / Math.PI + 0.5, uv.y );
		return uv.clone();

	}


};
/*************************************************
****下面是PolyhedronGeometry對象的方法屬性定義,繼承自Geometry對象.
**************************************************/
THREE.PolyhedronGeometry.prototype = Object.create( THREE.Geometry.prototype );


商域無疆 (http://blog.csdn.net/omni360/)

本文遵循“署名-非商業用途-保持一致”創作公用協議

轉載請保留此句:商域無疆 -  本博客專注於 敏捷開發及移動和物聯設備研究:數據可視化、GOLANG、Html5、WEBGL、THREE.JS否則,出自本博客的文章拒絕轉載或再轉載,謝謝合作。


以下代碼是THREE.JS 源碼文件中extras/geometries/PolyhedronGeometry.js文件的註釋.

更多更新在 : https://github.com/omni360/three.js.sourcecode

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章