1. 程式人生 > >three.js 原始碼註釋(五十九)objects/Mesh.js

three.js 原始碼註釋(五十九)objects/Mesh.js


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

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


/**
 * @author mrdoob / http://mrdoob.com/
 * @author alteredq / http://alteredqualia.com/
 * @author mikael emtinger / http://gomo.se/
 * @author jonobr1 / http://jonobr1.com/
 */

/*
///Mesh物件,最終的網格物件,有高人把圖形學建模比作是製作燈籠,先用Geometry建立燈籠的框架,然後將材質material貼在框架上,最後形成的總體燈籠,就是Mesh物件.下面看一下Mesh物件的用法和具體實現.
/// 用法:var geometry = new THREE.Geometry(1,1,1);				//建立geometry物件(燈籠的框架),
///																//有一下可選物件BoxGeometry,CircleGeometry,CubeGeometry,CylinderGeometry,DodecahedronGeometry,ExtrudeGeometry,IcosahedronGeometry,
///																//LatheGeometry,OctahedronGeometry,ParametricGeometry,PlaneGeometry,PolyhedronGeometry,RingGeometry,ShapeGeometry,SphereGeometry,
///																//TetrahedronGeometry,TextGeometry,TorusGeometry,TorusKnotGeometry,TubeGeometry
///		 var material = new THREE.Material({color: 0xffff00});	//建立材質物件(燈籠的表面)
///																//有以下可選物件LineBasicMaterial,LineDashedMaterial,Material,MeshBasicMaterial,MeshDepthMaterial,MeshFaceMaterial,
///																//MeshLambertMaterial,MeshNormalMaterial,MeshPhongMaterial,PointCloudMaterial,RawShaderMaterial,ShaderMaterial,
///																//SpriteCanvasMaterial,SpriteMaterial
///		 var mesh = new THREE.Mesh(geometry, material);	//建立mesh(燈籠)物件,並將geometry物件(燈籠的框架)和material物件(燈籠的表面)傳遞給mesh(燈籠)物件
///		 scene.add(mesh); 	//將mesh(燈籠)新增到場景中.
*/
///<summary>Mesh</summary>
///<param name ="geometry" type="THREE.Geometry">Geometry物件(燈籠的框架)</param>
///<param name ="material" type="THREE.Material">Material物件(材質物件)</param>
///<returns type="Mesh">返回Mesh物件</returns>
THREE.Mesh = function ( geometry, material ) {

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

	this.geometry = geometry !== undefined ? geometry : new THREE.Geometry();	//將引數geometry賦值給mesh物件的geometry屬性
	this.material = material !== undefined ? material : new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } );		//將引數material賦值給mesh物件的material屬性

/*
///MorphTargets
///原文地址:http://www.tuicool.com/articles/rYzuuu
///先睹為快
///
///MorphTargets允許物體發生變形。如果該物體的geometry有 $n$ 個頂點,那麼MorphTargets允許你再指定 $n$ 個, $2n$ 個, $3n$ 個甚至更多個頂點
///(比如,$ p\cdot n$ 個),同時mesh物件提供一個數組morphTargetInfluences(公式中$ f_{j} $表示morphTargetInfluences[j]),具有 $p$ 個元素,
///每個元素取值在0-1之間。渲染這個物體的時候,某個頂點 $V_{i}$ 的位置其實變了,成了:
///
///$$V_{i}=V_{i}+\sum_{j=0}^{p}f_{j}\cdot (V_{j,i}-V_{i})$$
///
///舉個簡單的例子,一個立方體有8個頂點, MorphTargets又指定了8個頂點,立方體的一個頂點為(1,1,1),而在 MorphTargets中與之對應的頂點為(2,2,2),
///那麼當 morphTargetInfluences[0]為0.5的時候,實際渲染的時候該頂點的位置就成了(1.5,1.5,1.5)。這樣做的好處是顯而易見的,你可以通過簡單地調整
/// morphTargetInfluences陣列來使物體形變,只要之前你設定好了。
///
///向物體加入morphTargets的方法很簡單:
///
///var geometry = new THREE.CubeGeometry(100,100,100);
///   var material = new THREE.MeshLambertMaterial({color:0xffffff, morphTargets:true});
///
///    var vertices = [];
///    for(var i=0; i<geometry.vertices.length; i++)
///    {
///       var f = 2;
///        vertices.push(geometry.vertices[i].clone());
///        vertices[i].x *= f;
///        vertices[i].y *= f;
///        vertices[i].z *= f;
///    }
///    geometry.morphTargets.push({name:'target0', vertices:vertices});
/// 在其他什麼地方(比如animate()或render()方法中)改變morphTargetInfluences,實在方便
///
///var s = 0;
///function render()
///{
///    s += 0.03;
///    mesh.morphTargetInfluences[0] = Math.abs(Math.sin(s));
///    ...
///}
///最關鍵的問題是,我相信,這個功能是通過著色器來完成的。我閱讀過一些簡單的著色器,因此我發現在著色器中完成這件事實在太合適了。
///如果某個geometry有幾千甚至上萬個頂點,使用JavaScript逐個計算變形後頂點的位置會造成很大壓力,而顯示卡大規模平行計算的能力很適合處理這個任務
///(畢竟每個頂點是獨立地)。
 */

	this.updateMorphTargets();	//更新目標變形,不影響geometry物件。

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

/*
///updateMorphTargets方法將geometry物件的morphTargets屬性複製到this.morphTargetInfluences屬性,不影響geometry物件本身。
*/
///<summary>updateMorphTargets</summary>
///<returns type="Mesh">返回新的Mesh物件</returns>
THREE.Mesh.prototype.updateMorphTargets = function () {

	if ( this.geometry.morphTargets !== undefined && this.geometry.morphTargets.length > 0 ) {	//判斷geometry物件是否有目標變形陣列。

		this.morphTargetBase = - 1;		//給Mesh物件設定morphTargetBase屬性,並初始化為-1.
		this.morphTargetForcedOrder = [];	//給Mesh物件設定morphTargetForcedOrder屬性陣列,初始化[].
		this.morphTargetInfluences = [];	//給Mesh物件設定morphTargetInfluences屬性陣列,初始化為[].	
		this.morphTargetDictionary = {};	//給Mesh物件設定morphTargetDictionary屬性,初始化為}{}.

		for ( var m = 0, ml = this.geometry.morphTargets.length; m < ml; m ++ ) {	//遍歷geometry物件

			this.morphTargetInfluences.push( 0 );		
			this.morphTargetDictionary[ this.geometry.morphTargets[ m ].name ] = m;		//將geometry.morphTargets屬性陣列中的值,一一賦值給morphTargetDictionary[]屬性陣列。

		}

	}

};
/*
///getMorphTargetIndexByName方法通過引數name獲得儲存在morphTargetDictionary[]屬性陣列中的變形目標索引或者說是。
*/
///<summary>getMorphTargetIndexByName</summary>
///<param name ="name" type="String">MorphTarget儲存的名字</param>
///<returns type="Mesh">返回引數name所對應的頂點</returns>
THREE.Mesh.prototype.getMorphTargetIndexByName = function ( name ) {

	if ( this.morphTargetDictionary[ name ] !== undefined ) {	//如果morphTargetDictionary[name]屬性物件存在

		return this.morphTargetDictionary[ name ];	//返回該物件。

	}

	console.log( 'THREE.Mesh.getMorphTargetIndexByName: morph target ' + name + ' does not exist. Returning 0.' );	//提示使用者,該物件不存在。返回值是0.

	return 0;

};

/*
///raycast方法用來獲得當前物件與射線(引數raycaster)的交點.raycaster.intersectObject會呼叫這個方法。主要是用來進行碰撞檢測,
/// 在選擇場景中的物件時經常會用到,判斷當前滑鼠是否與物件重合用來選擇物件.
/// NOTE:raycast方法中引數intersects引數用來儲存交點的集合,格式如下
///	intersects.push( {
///
///				distance: distance,
///				point: intersectionPoint,
///				indices: [ a, b, c ],
///				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.Mesh.prototype.raycast = ( function () {

	var inverseMatrix = new THREE.Matrix4();	//宣告一個4x4矩陣,用來放置逆矩陣
	var ray = new THREE.Ray();			//宣告全域性射線物件
	var sphere = new THREE.Sphere();		//宣告全域性球體物件

	var vA = new THREE.Vector3();			//宣告3維向量,vA
	var vB = new THREE.Vector3();			//宣告3維向量,vB
	var vC = new THREE.Vector3();			//宣告3維向量,vC

	return function ( raycaster, intersects ) {	

		var geometry = this.geometry;

		// Checking boundingSphere distance to ray
		// 檢查geometry物件的球體邊界到射線的距離。

		if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();

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

		if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) {	//呼叫光線跟蹤的isIntersectionSphere方法,判斷geometry物件的球體邊界是否與射線相交。

			return;		//如果不相交,返回。

		}

		// Check boundingBox before continuing
		//檢查geometry物件的立方體邊界到射線距離

		inverseMatrix.getInverse( this.matrixWorld );
		ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );

		if ( geometry.boundingBox !== null ) {

			if ( ray.isIntersectionBox( geometry.boundingBox ) === false )  {	//呼叫光線跟蹤的isIntersectionBox方法,判斷geometry物件的立方體邊界是否與射線相交。

				return;

			}

		}
		//如果geometry物件是BufferGeometry物件
		if ( geometry instanceof THREE.BufferGeometry ) {

			var material = this.material;

			if ( material === undefined ) return;	//如果沒有材質,返回

			var attributes = geometry.attributes;

			var a, b, c;
			var precision = raycaster.precision;	//精度因子

			if ( attributes.index !== undefined ) {		//如果bufferGeometry物件的attributes.index屬性不為undefined

				var indices = attributes.index.array;
				var positions = attributes.position.array;
				var offsets = geometry.offsets;

				if ( offsets.length === 0 ) {

					offsets = [ { start: 0, count: indices.length, index: 0 } ];

				}

				for ( var oi = 0, ol = offsets.length; oi < ol; ++oi ) {	//根據定義bufferGeomentry存放的格式,遍歷attributes屬性.找到頂點資料儲存區域

					var start = offsets[ oi ].start;
					var count = offsets[ oi ].count;
					var index = offsets[ oi ].index;

					for ( var i = start, il = start + count; i < il; i += 3 ) {	//根據定義bufferGeomentry存放的格式,遍歷attributes屬性.找到頂點資料

						a = index + indices[ i ];
						b = index + indices[ i + 1 ];
						c = index + indices[ i + 2 ];

						vA.set(
							positions[ a * 3 ],
							positions[ a * 3 + 1 ],
							positions[ a * 3 + 2 ]
						);
						vB.set(
							positions[ b * 3 ],
							positions[ b * 3 + 1 ],
							positions[ b * 3 + 2 ]
						);
						vC.set(
							positions[ c * 3 ],
							positions[ c * 3 + 1 ],
							positions[ c * 3 + 2 ]
						);


						if ( material.side === THREE.BackSide ) {	//如果材質的side屬性為BackSide

							var intersectionPoint = ray.intersectTriangle( vC, vB, vA, true );	//呼叫intersectTriangle方法判斷是否與引數VC,VB,VA組成的Triangle三角形物件相交,如果相交返回交點.如果不想交返回null,這裡最後一個引數true,表示判斷背面

						} else {

							var intersectionPoint = ray.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide );		//呼叫intersectTriangle方法判斷是否與引數VA,VB,VC組成的Triangle三角形物件相交,如果相交返回交點.如果不想交返回null,這裡最後一個引數,表示判斷正面

						}

						if ( intersectionPoint === null ) continue;		//如果沒有交點,跳出迴圈

						intersectionPoint.applyMatrix4( this.matrixWorld );		//將非null的交點應用世界座標變換

						var distance = raycaster.ray.origin.distanceTo( intersectionPoint );	//計算射線原點到交點的距離

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

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

							distance: distance,		//距離
							point: intersectionPoint,	//交點
							indices: [ a, b, c ],	//頂點在attribute屬性中的索引
							face: null,				//面
							faceIndex: null,		//面所在屬性陣列中的索引
							object: this 			//物件

						} );

					}

				}

			} else {		//如果bufferGeometry物件的attributes.index屬性為undefined

				var positions = attributes.position.array;

				for ( var i = 0, j = 0, il = positions.length; i < il; i += 3, j += 9 ) {	//找到所有的頂點位置屬性

					a = i;
					b = i + 1;
					c = i + 2;

					vA.set(
						positions[ j ],
						positions[ j + 1 ],
						positions[ j + 2 ]
					);
					vB.set(
						positions[ j + 3 ],
						positions[ j + 4 ],
						positions[ j + 5 ]
					);
					vC.set(
						positions[ j + 6 ],
						positions[ j + 7 ],
						positions[ j + 8 ]
					);


					if ( material.side === THREE.BackSide ) {	//如果材質的side屬性為BackSide

						var intersectionPoint = ray.intersectTriangle( vC, vB, vA, true );	//呼叫intersectTriangle方法判斷是否與引數VC,VB,VA組成的Triangle三角形物件相交,如果相交返回交點.如果不想交返回null,這裡最後一個引數true,表示判斷背面

					} else {

						var intersectionPoint = ray.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide );		//呼叫intersectTriangle方法判斷是否與引數VA,VB,VC組成的Triangle三角形物件相交,如果相交返回交點.如果不想交返回null,這裡最後一個引數,表示判斷正面

					}

					if ( intersectionPoint === null ) continue;		//如果沒有交點,跳出迴圈

					intersectionPoint.applyMatrix4( this.matrixWorld );	//將非null的交點應用世界座標變換

					var distance = raycaster.ray.origin.distanceTo( intersectionPoint );	//計算射線原點到交點的距離

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

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

						distance: distance,	//距離
						point: intersectionPoint,	//交點
						indices: [ a, b, c ],	//頂點在attribute屬性中的索引
						face: null,			//面
						faceIndex: null,		//面所在屬性陣列中的索引
						object: this 			//物件

					} );

				}

			}

		} else if ( geometry instanceof THREE.Geometry ) {	//如果geometry物件是THREE.Geometry型別

			var isFaceMaterial = this.material instanceof THREE.MeshFaceMaterial;
			var objectMaterials = isFaceMaterial === true ? this.material.materials : null;

			var a, b, c, d;
			var precision = raycaster.precision;	//精度因子

			var vertices = geometry.vertices;		

			for ( var f = 0, fl = geometry.faces.length; f < fl; f ++ ) {	//遍歷geometry物件的所有面

				var face = geometry.faces[ f ];

				var material = isFaceMaterial === true ? objectMaterials[ face.materialIndex ] : this.material;

				if ( material === undefined ) continue;	//如果沒有材質,跳出迴圈

				a = vertices[ face.a ];
				b = vertices[ face.b ];
				c = vertices[ face.c ];

				if ( material.morphTargets === true ) {		//如果有變性目標屬性

					var morphTargets = geometry.morphTargets;
					var morphInfluences = this.morphTargetInfluences;

					vA.set( 0, 0, 0 );
					vB.set( 0, 0, 0 );
					vC.set( 0, 0, 0 );

					for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {		//將所有的頂點按照變形資料做變換

						var influence = morphInfluences[ t ];

						if ( influence === 0 ) continue;

						var targets = morphTargets[ t ].vertices;

						vA.x += ( targets[ face.a ].x - a.x ) * influence;
						vA.y += ( targets[ face.a ].y - a.y ) * influence;
						vA.z += ( targets[ face.a ].z - a.z ) * influence;

						vB.x += ( targets[ face.b ].x - b.x ) * influence;
						vB.y += ( targets[ face.b ].y - b.y ) * influence;
						vB.z += ( targets[ face.b ].z - b.z ) * influence;

						vC.x += ( targets[ face.c ].x - c.x ) * influence;
						vC.y += ( targets[ face.c ].y - c.y ) * influence;
						vC.z += ( targets[ face.c ].z - c.z ) * influence;

					}

					vA.add( a );
					vB.add( b );
					vC.add( c );

					a = vA;
					b = vB;
					c = vC;

				}

				if ( material.side === THREE.BackSide ) {	//如果材質的side屬性為BackSide

					var intersectionPoint = ray.intersectTriangle( c, b, a, true );	//呼叫intersectTriangle方法判斷是否與引數VC,VB,VA組成的Triangle三角形物件相交,如果相交返回交點.如果不想交返回null,這裡最後一個引數true,表示判斷背面

				} else {

					var intersectionPoint = ray.intersectTriangle( a, b, c, material.side !== THREE.DoubleSide );		//呼叫intersectTriangle方法判斷是否與引數VA,VB,VC組成的Triangle三角形物件相交,如果相交返回交點.如果不想交返回null,這裡最後一個引數,表示判斷正面

				}

				if ( intersectionPoint === null ) continue;		//如果沒有交點,跳出迴圈

				intersectionPoint.applyMatrix4( this.matrixWorld );	//將非null的交點應用世界座標變換

				var distance = raycaster.ray.origin.distanceTo( intersectionPoint );	//計算射線原點到交點的距離

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

				intersects.push( {

					distance: distance,	//距離
					point: intersectionPoint,	//交點
					face: face,	//面
					faceIndex: f,	//面索引
					object: this 	//物件

				} );

			}

		}

	};

}() );

/*clone方法
///clone方法克隆一個Mesh網格物件.
*/
///<summary>clone</summary>
///<param name ="object" type="Object3D">接收克隆的Object3D物件</param>
///<param name ="recursive" type="boolean">是否對子物件一一進行克隆</param>
///<returns type="Ray">返回Mesh網格物件.</returns>	
THREE.Mesh.prototype.clone = function ( object, recursive ) {

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

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

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

};



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

相關推薦

three.js 原始碼註釋objects/Mesh.js

俺也是剛開始學,好多地兒肯定不對還請見諒. 以下程式碼是THREE.JS 原始碼檔案中objects/Mesh.js檔案的註釋. /** * @author mrdoob / http://mrdoob.com/ * @author alteredq / htt

three.js 原始碼註釋Material /MeshNormalMaterial.js

俺也是剛開始學,好多地兒肯定不對還請見諒. 以下程式碼是THREE.JS 原始碼檔案中Material/MeshNormalMaterial.js檔案的註釋. /** * @author mrdoob / http://mrdoob.com/ * * para

three.js 原始碼註釋Material /MeshDepthMaterial.js

俺也是剛開始學,好多地兒肯定不對還請見諒. 以下程式碼是THREE.JS 原始碼檔案中materials/MeshDepthMaterial.js檔案的註釋. /** * @author mrdoob / http://mrdoob.com/ * @author

three.js 原始碼註釋Core/Object3D.js

俺也是剛開始學,好多地兒肯定不對還請見諒. 以下程式碼是THREE.JS 原始碼檔案中Core/Object3D.js檔案的註釋. /** * @author mrdoob / http://mrdoob.com/ * @author mikael emting

three.js 原始碼註釋Core/BufferGeometry.js

俺也是剛開始學,好多地兒肯定不對還請見諒. 以下程式碼是THREE.JS 原始碼檔案中Core/BufferGeometry.js檔案的註釋. /** * @author alteredq / http://alteredqualia.com/ */ /* //

three.js 原始碼註釋Light/AreaLight.js

俺也是剛開始學,好多地兒肯定不對還請見諒. 以下程式碼是THREE.JS 原始碼檔案中Light/AreaLight.js檔案的註釋. /** * @author MPanknin / http://www.redplant.de/ * @author alte

three.js 原始碼註釋Texture/Texture.js

俺也是剛開始學,好多地兒肯定不對還請見諒. 以下程式碼是THREE.JS 原始碼檔案中Texture/Texture.js檔案的註釋. /** * @author mrdoob / http://mrdoob.com/ * @author alteredq /

three.js 原始碼註釋Material /MeshPhongMaterial.js

俺也是剛開始學,好多地兒肯定不對還請見諒. 以下程式碼是THREE.JS 原始碼檔案中materials/MeshPhongMaterial.js檔案的註釋. /** * @author mrdoob / http://mrdoob.com/ * @author

three.js 原始碼註釋extras/geometries/ParametricGeometry.js

俺也是剛開始學,好多地兒肯定不對還請見諒. 以下程式碼是THREE.JS 原始碼檔案中extras/geometries/ParametricGeometry.js檔案的註釋. /** * @author zz85 / https://github.com/zz8

three.js 原始碼註釋extras/geometries/IcosahedronGeometry.js

俺也是剛開始學,好多地兒肯定不對還請見諒. 以下程式碼是THREE.JS 原始碼檔案中extras/geometries/IcosahedronGeometry.js檔案的註釋. /** * @author timothypratley / https://git

three.js 原始碼註釋objects/Line.js

俺也是剛開始學,好多地兒肯定不對還請見諒. 以下程式碼是THREE.JS 原始碼檔案中objects/Line.js檔案的註釋. /** * @author mrdoob / http://mrdoob.com/ */ /* ///Line物件,建立一條線,或者

Linux學習總結shell 腳本3-for while 循環

shell 循環 for while 1 for 循環 語法: for 變量名 in 條件;do ...; done舉例1 #!/bin/bash sum=0 for i in `seq 1 100`;do sum=$[$sum+$i] done echo $sum 舉例2找到/123 目錄

ElasticSearch最佳入門實踐基於scoll技術滾動搜尋大量資料

如果一次性要查出來比如10萬條資料,那麼效能會很差,此時一般會採取用scoll滾動查詢,一批一批的查,直到所有資料都查詢完處理完 使用scoll滾動搜尋,可以先搜尋一批資料,然後下次再搜尋一批資料,以此類推,直到搜尋出全部的資料來 scoll搜尋會在第一次搜尋的

Java程式設計師從笨鳥到菜鳥JSON

stringify() 和 parse() 的區別 序列化 stringify():將 javascript 物件序列化為 Json 字串 反序列化 parse(): 將 Json 字串解析為原生的 JavaScript 物件

Java基礎-集合工具類Java類集框架

1:Stack棧 棧是一種先進後出的資料結構。例如:在文字編輯器上都有撤銷功能,那麼每次使用的時候,最後一次的編輯操作永遠是最先撤銷的,那麼這個功能就是利用棧來實現的,棧的基本操作形式如下。 案例:實現棧的操作 import java.util.Stack;

Android原始碼解析-->應用程式返回按鍵執行流程

從這篇文章中我們開始分析android系統的事件分發流程,其實網上已經有了很多關於android系統的事件分發流程的文章,奈何看了很多但是印象還不是很深,所以這裡總結一番。 android系統的事件分發流程分為很多部分: Native層 –> V

OpenCV學習筆記——marker檢測識別"Master OpenCV"chp.2

第二章原本是講如何將基於標定的增強現實在ios平臺實現,包括以下4個方面: 1、在ios平臺建立opencv工程 2、Marker檢測識別 3、攝像機標定及Marker姿態估計 4、在Marker基礎上渲染一個3維虛擬物體 這裡面第一部分是IOS平臺的開發,我不是太關注,略

Java程式設計師從笨鳥到菜鳥之細談Hibernatehibernate查詢排序和元件對映

 上一篇:          在實際開發過程中,有很多使用者需要時要把查詢出來的結果進行排序顯示,而不是在資料庫裡面那樣順序混亂那樣的顯示,這樣的話我們不得不要對資料進行排序了,hibernate對資料排序提供了很好的支援,hibernate提供了兩種對查詢到得資料結

Java開發筆記Java8之後的擴展接口

com 完整 不遠 urn 遊泳 java8 調用接口 基本 中國 前面介紹了接口的基本用法,有心的朋友可能註意到這麽一句話“在Java8以前,接口內部的所有方法都必須是抽象方法”,如此說來,在Java8之後,接口的內部方法也可能不是抽象方法了嗎?之所以Java8對接口的定

Coding and Paper Letter

開發十年,就只剩下這套架構體系了! >>>