Three.js源碼閱讀筆記(基礎(chǔ)的核心Core對(duì)象)
更新時(shí)間:2012年12月27日 16:48:50 作者:
Three.js是一個(gè)比較偉大的webgl開源庫(kù),它簡(jiǎn)化了瀏覽器3D編程,使得使用JavaScript在瀏覽器中創(chuàng)建復(fù)雜的場(chǎng)景變得容易很多接下來先從最基礎(chǔ)的核心(Core)對(duì)象開始,感興趣的朋友可以參考下
Three.js是一個(gè)比較偉大的webgl開源庫(kù),它簡(jiǎn)化了瀏覽器3D編程,使得使用JavaScript在瀏覽器中創(chuàng)建復(fù)雜的場(chǎng)景變得容易很多。Github上眾多webgl demo令我興奮不已,躍躍欲試。由于這個(gè)庫(kù)還處在開發(fā)階段,因此資料非常匱乏,愛好者大部分時(shí)間不得不通過閱讀該庫(kù)的源碼進(jìn)行學(xué)習(xí),我現(xiàn)在也準(zhǔn)備這樣做。
這是第一篇筆記,先從最基礎(chǔ)的核心(Core)對(duì)象開始。
Core::Vector2
該構(gòu)造函數(shù)用來創(chuàng)建一個(gè)表示二維向量的對(duì)象
THREE.Vector2 = function ( x, y ) {
this.x = x || 0;
this.y = y || 0;
};
Vector2對(duì)象的功能函數(shù)采用定義構(gòu)造函數(shù)的原型對(duì)象來實(shí)現(xiàn),形如:
THREE.Vector2.prototype = {
constructor: THREE.Vector2,
set: function ( x, y ) {
this.x = x;
this.y = y;
return this;
},
copy: function ( v ) {
this.x = v.x;
this.y = v.y;
return this;
},
...... // 更多的函數(shù)
};
函數(shù)set(x,y)用以指定向量的值,調(diào)用者本身的x,y值被影響了,而該方法本身又返回調(diào)用者本身,這種情況很常見,以下不再說明。通過文字能夠表述清楚功能的函數(shù)不再引用源代碼,這一點(diǎn)以下也不再說明。
函數(shù)copy(v)用來將向量v復(fù)制進(jìn)調(diào)用者。
函數(shù)add(a,b)和函數(shù)sub(a,b)分別表示對(duì)向量a,b相加和相減。
函數(shù)addSelf(v)和subSelf(v)分別表示對(duì)調(diào)用者本身加上或減去向量v。
函數(shù)multiplyScale(s)和divideScale(s)分別表示對(duì)調(diào)用者本身乘以或除以s。
函數(shù)lerpSelf(v,alpha)將調(diào)用者向v所指的方向旋轉(zhuǎn)alpha,當(dāng)alpha為1時(shí),調(diào)用者最終等于v,而當(dāng)alpha=0時(shí),調(diào)用者還等于原來。
lerpSelf: function ( v, alpha ) {
this.x += ( v.x - this.x ) * alpha;
this.y += ( v.y - this.y ) * alpha;
return this;
},
函數(shù)negate()對(duì)調(diào)用者取反。
函數(shù)dot(v)返回float類型的調(diào)用者和向量v的點(diǎn)乘。
函數(shù)lengthSq()和函數(shù)length()返回float類型的調(diào)用者長(zhǎng)度平方或長(zhǎng)度。
函數(shù)normalize()將調(diào)用者本身歸一化。
函數(shù)distanceToSquared(v)和distanceTo(v)將返回調(diào)用者和向量v的距離。這里的距離其實(shí)是兩向量起點(diǎn)都在原點(diǎn)時(shí),終點(diǎn)之間的距離,也就是向量this-v的長(zhǎng)度。
函數(shù)setLength(s)將向量的長(zhǎng)度縮放至為s,方向不變。
函數(shù)equals(v)判斷調(diào)用者與向量v的值是否相同。
函數(shù)isZero()判斷調(diào)用者是否是零向量。
函數(shù)clone()返回一個(gè)與調(diào)用者值一樣的新向量,相當(dāng)于將其復(fù)制出去,注意與copy(v)的區(qū)別。
Core::Vector3
該構(gòu)造函數(shù)創(chuàng)建一個(gè)表示三維向量的對(duì)象
THREE.Vector3 = function ( x, y, z ) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
};
三維向量和二維向量有許多共通之處,比如set,add,dot,length,clone等,此處盡數(shù)略去,只記錄三維向量比二維向量多出的部分函數(shù)。
函數(shù)setX(x),setY(y)和setZ(z)用來單獨(dú)設(shè)置某一分量的值。
函數(shù)cross(a,b)和crossSelf(v)分別使調(diào)用者變?yōu)閍,b的叉乘或者調(diào)用者本身與v的叉乘。叉乘是一個(gè)向量,垂直于參與叉乘的兩個(gè)向量并呈右手螺旋法則。
函數(shù)getPositionFromMatrix(m),getRotationFromMatrix(m),getScaleFromMatrix(m)從4×4的模型矩陣中提取位置分量,旋轉(zhuǎn)分量和縮放分量。模型矩陣表示了一系列平移、旋轉(zhuǎn)、縮放變換的疊加效果。(這里第二個(gè)函數(shù)出現(xiàn)在文檔中,在源碼中被另外兩個(gè)函數(shù)代替了,也許還沒來得及更新)。
函數(shù)angleTo(v)計(jì)算調(diào)用者和向量v的夾角。
Core::Vector4
該構(gòu)造函數(shù)創(chuàng)建一個(gè)表示四維向量的對(duì)象
THREE.Vector4 = function ( x, y, z, w ) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
this.w = ( w !== undefined ) ? w : 1;
};
四維向量用來表示齊次坐標(biāo),其函數(shù)和Vector2,Vector3中的函數(shù)功能重合,僅僅是多一個(gè)分量而已,這里不再記錄。
Core::Matrix3
該構(gòu)造函數(shù)創(chuàng)建一個(gè)表示3×3矩陣的對(duì)象
THREE.Matrix3 = function () {
this.elements = new Float32Array(9);
};
3×3矩陣有9個(gè)元素,存儲(chǔ)在矩陣對(duì)象的屬性elements中,elements是一個(gè)數(shù)組。
函數(shù)getInverse(m)返回矩陣m的逆矩陣,同時(shí)改變調(diào)用者本身。
函數(shù)transpose()轉(zhuǎn)置調(diào)用者。
函數(shù)transposeToArray(r)將調(diào)用者轉(zhuǎn)置進(jìn)數(shù)組r而不改變自身。(這個(gè)地方似乎源碼錯(cuò)了,var m=this.m應(yīng)該為var m=this.elements。)
Core::Matrix4
該構(gòu)造函數(shù)創(chuàng)建一個(gè)表示4×4矩陣的對(duì)象,4×4矩陣在三維圖形學(xué)中非常重要,模型矩陣、視圖矩陣和投影矩陣都是這樣的矩陣。
THREE.Matrix4 = function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
this.elements = new Float32Array( 16 );
this.set(
( n11 !== undefined ) ? n11 : 1, n12 || 0, n13 || 0, n14 || 0,
n21 || 0, ( n22 !== undefined ) ? n22 : 1, n23 || 0, n24 || 0,
n31 || 0, n32 || 0, ( n33 !== undefined ) ? n33 : 1, n34 || 0,
n41 || 0, n42 || 0, n43 || 0, ( n44 !== undefined ) ? n44 : 1
);
};
在Matrix3對(duì)象中出現(xiàn)的幾個(gè)函數(shù)在Matrix4中有相同的作用,這里也略去。
函數(shù)identity()將對(duì)象重置為單位陣。
函數(shù)lookAt(eye,center,up)將對(duì)象設(shè)定為一個(gè)視圖矩陣,參數(shù)都是Vector3對(duì)象,該矩陣只會(huì)用到eye和center的相對(duì)位置。該視圖矩陣表示,攝像機(jī)在eye位置看向center位置,且向上的向量(這一點(diǎn)稍后解釋)為up時(shí)的視圖矩陣。視圖矩陣又可以看做攝像機(jī)的模型矩陣,所以該函數(shù)產(chǎn)生的矩陣又可以表示以下變換:將物體從原點(diǎn)平移至位置center-eye,再將其旋轉(zhuǎn)至向上的向量為up。向上的向量up用來固定相機(jī),可以想象當(dāng)相機(jī)固定在一點(diǎn),鏡頭朝向固定方向的時(shí)候,還是可以在一個(gè)維度里自由旋轉(zhuǎn)的,up向量固定相機(jī)的這個(gè)維度。
lookAt: function ( eye, target, up ) {
var te = this.elements;
var x = THREE.Matrix4.__v1; // 空Vector3對(duì)象,下同
var y = THREE.Matrix4.__v2;
var z = THREE.Matrix4.__v3;
z.sub( eye, target ).normalize();
if ( z.length() === 0 ) {
z.z = 1;
}
x.cross( up, z ).normalize();
if ( x.length() === 0 ) {
z.x += 0.0001;
x.cross( up, z ).normalize();
}
y.cross( z, x );
te[0] = x.x; te[4] = y.x; te[8] = z.x;
te[1] = x.y; te[5] = y.y; te[9] = z.y;
te[2] = x.z; te[6] = y.z; te[10] = z.z;
return this;
},
函數(shù)multiply(a,b),multiplySelf(v)和multiplyToArray(a,b,r)將兩個(gè)矩陣相乘。
函數(shù)multiplyScale(s)將對(duì)象所有16個(gè)元素都乘以s。
函數(shù)multiplyVector3(v)和multiplyVector4(v)將對(duì)象矩陣左乘四維行向量,返回vector3和vector4類型的行向量。如果對(duì)象矩陣是模型視圖矩陣,輸入的向量是點(diǎn)位置信息,則輸出的向量則是經(jīng)過模型變換和相機(jī)變換后,該點(diǎn)相對(duì)于相機(jī)的位置。輸入vector3類型向量時(shí),自動(dòng)補(bǔ)足為齊次坐標(biāo),返回時(shí)再砍掉第四個(gè)分量成為普通坐標(biāo)。
函數(shù)rotateAxis(v)使用對(duì)象矩陣左上角的3×3子矩陣左乘行向量v,得到一個(gè)新的行向量并歸一化,返回這個(gè)新行向量。該函數(shù)同時(shí)更新了向量v的值。模型視圖矩陣左上角3×3的子矩陣包含了模型矩陣中的旋轉(zhuǎn)信息,將該子矩陣左乘一個(gè)向量,得到的新向量實(shí)際上就是原向量經(jīng)過旋轉(zhuǎn)(該旋轉(zhuǎn)效果來自于模型矩陣)得到的。因此該函數(shù)名為rotateAxis。
rotateAxis: function ( v ) {
var te = this.elements;
var vx = v.x, vy = v.y, vz = v.z;
v.x = vx * te[0] + vy * te[4] + vz * te[8];
v.y = vx * te[1] + vy * te[5] + vz * te[9];
v.z = vx * te[2] + vy * te[6] + vz * te[10];
v.normalize();
return v;
},
函數(shù)crossVector(v)計(jì)算矩陣對(duì)象(調(diào)用者)和v的叉乘,實(shí)際上就是對(duì)象矩陣左乘四維行向量v,返回向量。這個(gè)具體是做什么的,我還沒弄明白。
crossVector: function ( a ) {
var te = this.elements;
var v = new THREE.Vector4();
v.x = te[0] * a.x + te[4] * a.y + te[8] * a.z + te[12] * a.w;
v.y = te[1] * a.x + te[5] * a.y + te[9] * a.z + te[13] * a.w;
v.z = te[2] * a.x + te[6] * a.y + te[10] * a.z + te[14] * a.w;
v.w = ( a.w ) ? te[3] * a.x + te[7] * a.y + te[11] * a.z + te[15] * a.w : 1;
return v;
},
函數(shù)determinant()計(jì)算矩陣的行列式值。
函數(shù)flattenToArray(flat)和函數(shù)flattenToArrayOfset(flat,offset)將矩陣轉(zhuǎn)存到一維數(shù)組中,前一個(gè)函數(shù)從flat[0]存儲(chǔ)到flat[15],后一個(gè)函數(shù)允許指定開始存儲(chǔ)的位置,從flat[offset]存儲(chǔ)到flat[offset+15]。
函數(shù)getPosition()和函數(shù)setPosition()用來獲取或設(shè)置矩陣對(duì)象的位置分量。正如旋轉(zhuǎn)分量存儲(chǔ)在左上角3×3的子矩陣中,位置分量存儲(chǔ)在第四行前三個(gè)分量上,即element[12], element[13], element[14]中。
函數(shù)getColumeX(),getColumeY(),getColumeZ()分別提取左上角3×3子矩陣的三列。
函數(shù)compose(translate,rotation,scale)將對(duì)象矩陣設(shè)置為由vector3類型translate對(duì)象表示的平移、由matrix3類型rotation對(duì)象表示的旋轉(zhuǎn)、由vector3類型scale對(duì)象表示的縮放這三個(gè)變換組合到一起的變換矩陣。實(shí)際上就是講其直接填充到模型矩陣的相應(yīng)子空間。
函數(shù)decompose(translate,rotation,scale)將矩陣對(duì)象拆開到三個(gè)對(duì)象中,和上一個(gè)函數(shù)正好相反。
函數(shù)extractPosition(m)和extractRotation(m)將矩陣對(duì)象m中表示位置或旋轉(zhuǎn)的分量抽取到調(diào)用者對(duì)象中,比如兩個(gè)物體經(jīng)過多次各不相同的變換,只需要一個(gè)物體的模型視圖矩陣extractRotation另一個(gè)物體的模型視圖矩陣,則調(diào)用者就和另外一個(gè)物體保持著變換之處相同的旋轉(zhuǎn)方位。
函數(shù)translate(v)是模型矩陣最基本的變換之一:平移變換,將模型矩陣從屬的物體平移向量v。
函數(shù)rotateX(angle),rotateY(angle),rotateZ(angle)分別將模型矩陣從屬的物體繞X,Y,Z軸旋轉(zhuǎn)角度angle。
函數(shù)rotateByAxis(axis, angle)將模型矩陣從屬的物體繞一個(gè)任意軸axis旋轉(zhuǎn)角度angle,這是上面兩條所涉及的變換的多次疊加(疊加參數(shù)由當(dāng)前位置和axis參數(shù)決定),我在《模型視圖矩陣和投影矩陣:webgl筆記(1)》中曾討論到繞任意軸旋轉(zhuǎn)的問題。
這里不應(yīng)該有一個(gè)scale(s)函數(shù)嗎?可是我在源碼中沒找到。
函數(shù)makeTranslate(x,y,z),makeRotationX(theta),makeRotationY(theta),makeRotationZ(theta),makeRotationAxis(axis,angle),makeScale(s)函數(shù)將對(duì)象矩陣直接重置為單位陣經(jīng)過一次平移、或繞某軸旋轉(zhuǎn)、或單純某次縮放后的矩陣。該函數(shù)更新對(duì)象本身的值,而且更新的結(jié)果與對(duì)象之前的值毫無關(guān)聯(lián)(這也是make前綴函數(shù)的特點(diǎn))。
函數(shù)makeFrustum(...),makePerspective(...),makeOrthographic(...)也是用來初始化新矩陣,具體含義到相機(jī)類里面再討論,我想相機(jī)類的構(gòu)造函數(shù)里一定會(huì)調(diào)用這些函數(shù)的。
函數(shù)clone()將矩陣對(duì)象復(fù)制出來并返回。
Core::Face3
該函數(shù)創(chuàng)建一個(gè)三角形平面對(duì)象
THREE.Face3 = function ( a, b, c, normal, color, materialIndex ) {
this.a = a;
this.b = b;
this.c = c;
this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
this.vertexNormals = normal instanceof Array ? normal : [ ];
this.color = color instanceof THREE.Color ? color : new THREE.Color();
this.vertexColors = color instanceof Array ? color : [];
this.vertexTangents = [];
this.materialIndex = materialIndex;
this.centroid = new THREE.Vector3();
};
對(duì)象的a,b,c值是三個(gè)頂點(diǎn)的索引(后面會(huì)說到,Mesh對(duì)象中將所有點(diǎn)存儲(chǔ)為一個(gè)數(shù)組);顧名思義normal是法線;color是顏色;materialIndex是頂點(diǎn)材質(zhì)索引:這幾個(gè)參數(shù)即可以傳入vector3類型又可以傳入數(shù)組類型。
clone(x)方法返回一個(gè)新的,具有相同值的對(duì)象。
Core::Face4
該函數(shù)創(chuàng)建一個(gè)四個(gè)頂點(diǎn)的面,和Face3幾乎一樣,略去。
Core::Math
THREE.Math是一個(gè)“靜態(tài)類”,沒有構(gòu)造函數(shù)因此也不需要通過new關(guān)鍵字初始化。該類提供一些必要的數(shù)學(xué)工具。
函數(shù)clamp(x,a,b)將x夾在區(qū)間[a,b]中。clampBottom(x,a)的作用類似,只不過只夾一邊。
函數(shù)mapLinear(x,a1,a2,b1,b2)計(jì)算出一個(gè)值y,使得點(diǎn)(x,y)落在(a1,a2)和(b1,b2)連成的直線上。
mapLinear: function ( x, a1, a2, b1, b2 ) {
return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
},
函數(shù)random16(),randInt(low,high),randFloat(low,high),randFloatSpread(range)分別產(chǎn)生[0,1]區(qū)間的16位隨機(jī)浮點(diǎn)數(shù),[low,high]區(qū)間隨機(jī)整數(shù),[low,high]區(qū)間隨機(jī)浮點(diǎn)數(shù),[-range/2,range/2]區(qū)間隨機(jī)浮點(diǎn)數(shù)。
函數(shù)sigh(x)根據(jù)x的符號(hào)返回+1或-1。
Core::Clock
該構(gòu)造函數(shù)創(chuàng)建時(shí)鐘(確切的說是秒表)對(duì)象
THREE.Clock = function ( autoStart ) {
this.autoStart = ( autoStart !== undefined ) ? autoStart : true;
this.startTime = 0;
this.oldTime = 0;
this.elapsedTime = 0;
this.running = false;
};
函數(shù)start()和stop()用來開始計(jì)時(shí)或停止計(jì)時(shí)。
函數(shù)getDelta()返回調(diào)用該函數(shù)時(shí)距離上一次調(diào)用該函數(shù)時(shí)的時(shí)間長(zhǎng)度,如果是第一次調(diào)用該函數(shù),則返回此時(shí)距離開始計(jì)時(shí)時(shí)的時(shí)間長(zhǎng)度。如果autoStart值為真,若在調(diào)用getDelta()函數(shù)時(shí)尚未調(diào)用start()函數(shù)或者已經(jīng)調(diào)用過stop()函數(shù),則自動(dòng)開始計(jì)時(shí)并返回0。如果autoStart()值為假,則在調(diào)用start()之前或stop()之后,調(diào)用getDelta()返回0。
函數(shù)getElapsedTime()返回調(diào)用該函數(shù)時(shí)距離開始計(jì)時(shí)時(shí)的時(shí)間。
Core::Color
該構(gòu)造函數(shù)構(gòu)造一個(gè)表示顏色的對(duì)象
THREE.Color = function ( hex ) {
if ( hex !== undefined ) this.setHex( hex );
return this;
};
函數(shù)setHex(hex)以十六進(jìn)制序列設(shè)置對(duì)象的r,g,b屬性。實(shí)際上在對(duì)象中,最終是以這三個(gè)屬性存儲(chǔ)顏色的。
setHex: function ( hex ) {
hex = Math.floor( hex );
this.r = ( hex >> 16 & 255 ) / 255;
this.g = ( hex >> 8 & 255 ) / 255;
this.b = ( hex & 255 ) / 255;
return this;
},
函數(shù)setRGB(r,g,b)和setHSV(h,s,v)以RGB值或HSV值設(shè)置對(duì)象。
函數(shù)getHex()返回16進(jìn)制顏色值。
函數(shù)copyGammaToLinear(color),copyLinearToGamma(color)將color的rgb值分別平方或開方,賦給調(diào)用者對(duì)象。
函數(shù)convertGammaToLinear()和convertLinearToGamma()分別對(duì)調(diào)用者自身的rgb值平方或開放。
這是第一篇筆記,先從最基礎(chǔ)的核心(Core)對(duì)象開始。
Core::Vector2
該構(gòu)造函數(shù)用來創(chuàng)建一個(gè)表示二維向量的對(duì)象
復(fù)制代碼 代碼如下:
THREE.Vector2 = function ( x, y ) {
this.x = x || 0;
this.y = y || 0;
};
Vector2對(duì)象的功能函數(shù)采用定義構(gòu)造函數(shù)的原型對(duì)象來實(shí)現(xiàn),形如:
復(fù)制代碼 代碼如下:
THREE.Vector2.prototype = {
constructor: THREE.Vector2,
set: function ( x, y ) {
this.x = x;
this.y = y;
return this;
},
copy: function ( v ) {
this.x = v.x;
this.y = v.y;
return this;
},
...... // 更多的函數(shù)
};
函數(shù)set(x,y)用以指定向量的值,調(diào)用者本身的x,y值被影響了,而該方法本身又返回調(diào)用者本身,這種情況很常見,以下不再說明。通過文字能夠表述清楚功能的函數(shù)不再引用源代碼,這一點(diǎn)以下也不再說明。
函數(shù)copy(v)用來將向量v復(fù)制進(jìn)調(diào)用者。
函數(shù)add(a,b)和函數(shù)sub(a,b)分別表示對(duì)向量a,b相加和相減。
函數(shù)addSelf(v)和subSelf(v)分別表示對(duì)調(diào)用者本身加上或減去向量v。
函數(shù)multiplyScale(s)和divideScale(s)分別表示對(duì)調(diào)用者本身乘以或除以s。
函數(shù)lerpSelf(v,alpha)將調(diào)用者向v所指的方向旋轉(zhuǎn)alpha,當(dāng)alpha為1時(shí),調(diào)用者最終等于v,而當(dāng)alpha=0時(shí),調(diào)用者還等于原來。
復(fù)制代碼 代碼如下:
lerpSelf: function ( v, alpha ) {
this.x += ( v.x - this.x ) * alpha;
this.y += ( v.y - this.y ) * alpha;
return this;
},
函數(shù)negate()對(duì)調(diào)用者取反。
函數(shù)dot(v)返回float類型的調(diào)用者和向量v的點(diǎn)乘。
函數(shù)lengthSq()和函數(shù)length()返回float類型的調(diào)用者長(zhǎng)度平方或長(zhǎng)度。
函數(shù)normalize()將調(diào)用者本身歸一化。
函數(shù)distanceToSquared(v)和distanceTo(v)將返回調(diào)用者和向量v的距離。這里的距離其實(shí)是兩向量起點(diǎn)都在原點(diǎn)時(shí),終點(diǎn)之間的距離,也就是向量this-v的長(zhǎng)度。
函數(shù)setLength(s)將向量的長(zhǎng)度縮放至為s,方向不變。
函數(shù)equals(v)判斷調(diào)用者與向量v的值是否相同。
函數(shù)isZero()判斷調(diào)用者是否是零向量。
函數(shù)clone()返回一個(gè)與調(diào)用者值一樣的新向量,相當(dāng)于將其復(fù)制出去,注意與copy(v)的區(qū)別。
Core::Vector3
該構(gòu)造函數(shù)創(chuàng)建一個(gè)表示三維向量的對(duì)象
復(fù)制代碼 代碼如下:
THREE.Vector3 = function ( x, y, z ) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
};
三維向量和二維向量有許多共通之處,比如set,add,dot,length,clone等,此處盡數(shù)略去,只記錄三維向量比二維向量多出的部分函數(shù)。
函數(shù)setX(x),setY(y)和setZ(z)用來單獨(dú)設(shè)置某一分量的值。
函數(shù)cross(a,b)和crossSelf(v)分別使調(diào)用者變?yōu)閍,b的叉乘或者調(diào)用者本身與v的叉乘。叉乘是一個(gè)向量,垂直于參與叉乘的兩個(gè)向量并呈右手螺旋法則。
函數(shù)getPositionFromMatrix(m),getRotationFromMatrix(m),getScaleFromMatrix(m)從4×4的模型矩陣中提取位置分量,旋轉(zhuǎn)分量和縮放分量。模型矩陣表示了一系列平移、旋轉(zhuǎn)、縮放變換的疊加效果。(這里第二個(gè)函數(shù)出現(xiàn)在文檔中,在源碼中被另外兩個(gè)函數(shù)代替了,也許還沒來得及更新)。
函數(shù)angleTo(v)計(jì)算調(diào)用者和向量v的夾角。
Core::Vector4
該構(gòu)造函數(shù)創(chuàng)建一個(gè)表示四維向量的對(duì)象
復(fù)制代碼 代碼如下:
THREE.Vector4 = function ( x, y, z, w ) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
this.w = ( w !== undefined ) ? w : 1;
};
四維向量用來表示齊次坐標(biāo),其函數(shù)和Vector2,Vector3中的函數(shù)功能重合,僅僅是多一個(gè)分量而已,這里不再記錄。
Core::Matrix3
該構(gòu)造函數(shù)創(chuàng)建一個(gè)表示3×3矩陣的對(duì)象
THREE.Matrix3 = function () {
this.elements = new Float32Array(9);
};
3×3矩陣有9個(gè)元素,存儲(chǔ)在矩陣對(duì)象的屬性elements中,elements是一個(gè)數(shù)組。
函數(shù)getInverse(m)返回矩陣m的逆矩陣,同時(shí)改變調(diào)用者本身。
函數(shù)transpose()轉(zhuǎn)置調(diào)用者。
函數(shù)transposeToArray(r)將調(diào)用者轉(zhuǎn)置進(jìn)數(shù)組r而不改變自身。(這個(gè)地方似乎源碼錯(cuò)了,var m=this.m應(yīng)該為var m=this.elements。)
Core::Matrix4
該構(gòu)造函數(shù)創(chuàng)建一個(gè)表示4×4矩陣的對(duì)象,4×4矩陣在三維圖形學(xué)中非常重要,模型矩陣、視圖矩陣和投影矩陣都是這樣的矩陣。
復(fù)制代碼 代碼如下:
THREE.Matrix4 = function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
this.elements = new Float32Array( 16 );
this.set(
( n11 !== undefined ) ? n11 : 1, n12 || 0, n13 || 0, n14 || 0,
n21 || 0, ( n22 !== undefined ) ? n22 : 1, n23 || 0, n24 || 0,
n31 || 0, n32 || 0, ( n33 !== undefined ) ? n33 : 1, n34 || 0,
n41 || 0, n42 || 0, n43 || 0, ( n44 !== undefined ) ? n44 : 1
);
};
在Matrix3對(duì)象中出現(xiàn)的幾個(gè)函數(shù)在Matrix4中有相同的作用,這里也略去。
函數(shù)identity()將對(duì)象重置為單位陣。
函數(shù)lookAt(eye,center,up)將對(duì)象設(shè)定為一個(gè)視圖矩陣,參數(shù)都是Vector3對(duì)象,該矩陣只會(huì)用到eye和center的相對(duì)位置。該視圖矩陣表示,攝像機(jī)在eye位置看向center位置,且向上的向量(這一點(diǎn)稍后解釋)為up時(shí)的視圖矩陣。視圖矩陣又可以看做攝像機(jī)的模型矩陣,所以該函數(shù)產(chǎn)生的矩陣又可以表示以下變換:將物體從原點(diǎn)平移至位置center-eye,再將其旋轉(zhuǎn)至向上的向量為up。向上的向量up用來固定相機(jī),可以想象當(dāng)相機(jī)固定在一點(diǎn),鏡頭朝向固定方向的時(shí)候,還是可以在一個(gè)維度里自由旋轉(zhuǎn)的,up向量固定相機(jī)的這個(gè)維度。
復(fù)制代碼 代碼如下:
lookAt: function ( eye, target, up ) {
var te = this.elements;
var x = THREE.Matrix4.__v1; // 空Vector3對(duì)象,下同
var y = THREE.Matrix4.__v2;
var z = THREE.Matrix4.__v3;
z.sub( eye, target ).normalize();
if ( z.length() === 0 ) {
z.z = 1;
}
x.cross( up, z ).normalize();
if ( x.length() === 0 ) {
z.x += 0.0001;
x.cross( up, z ).normalize();
}
y.cross( z, x );
te[0] = x.x; te[4] = y.x; te[8] = z.x;
te[1] = x.y; te[5] = y.y; te[9] = z.y;
te[2] = x.z; te[6] = y.z; te[10] = z.z;
return this;
},
函數(shù)multiply(a,b),multiplySelf(v)和multiplyToArray(a,b,r)將兩個(gè)矩陣相乘。
函數(shù)multiplyScale(s)將對(duì)象所有16個(gè)元素都乘以s。
函數(shù)multiplyVector3(v)和multiplyVector4(v)將對(duì)象矩陣左乘四維行向量,返回vector3和vector4類型的行向量。如果對(duì)象矩陣是模型視圖矩陣,輸入的向量是點(diǎn)位置信息,則輸出的向量則是經(jīng)過模型變換和相機(jī)變換后,該點(diǎn)相對(duì)于相機(jī)的位置。輸入vector3類型向量時(shí),自動(dòng)補(bǔ)足為齊次坐標(biāo),返回時(shí)再砍掉第四個(gè)分量成為普通坐標(biāo)。
函數(shù)rotateAxis(v)使用對(duì)象矩陣左上角的3×3子矩陣左乘行向量v,得到一個(gè)新的行向量并歸一化,返回這個(gè)新行向量。該函數(shù)同時(shí)更新了向量v的值。模型視圖矩陣左上角3×3的子矩陣包含了模型矩陣中的旋轉(zhuǎn)信息,將該子矩陣左乘一個(gè)向量,得到的新向量實(shí)際上就是原向量經(jīng)過旋轉(zhuǎn)(該旋轉(zhuǎn)效果來自于模型矩陣)得到的。因此該函數(shù)名為rotateAxis。
復(fù)制代碼 代碼如下:
rotateAxis: function ( v ) {
var te = this.elements;
var vx = v.x, vy = v.y, vz = v.z;
v.x = vx * te[0] + vy * te[4] + vz * te[8];
v.y = vx * te[1] + vy * te[5] + vz * te[9];
v.z = vx * te[2] + vy * te[6] + vz * te[10];
v.normalize();
return v;
},
函數(shù)crossVector(v)計(jì)算矩陣對(duì)象(調(diào)用者)和v的叉乘,實(shí)際上就是對(duì)象矩陣左乘四維行向量v,返回向量。這個(gè)具體是做什么的,我還沒弄明白。
復(fù)制代碼 代碼如下:
crossVector: function ( a ) {
var te = this.elements;
var v = new THREE.Vector4();
v.x = te[0] * a.x + te[4] * a.y + te[8] * a.z + te[12] * a.w;
v.y = te[1] * a.x + te[5] * a.y + te[9] * a.z + te[13] * a.w;
v.z = te[2] * a.x + te[6] * a.y + te[10] * a.z + te[14] * a.w;
v.w = ( a.w ) ? te[3] * a.x + te[7] * a.y + te[11] * a.z + te[15] * a.w : 1;
return v;
},
函數(shù)determinant()計(jì)算矩陣的行列式值。
函數(shù)flattenToArray(flat)和函數(shù)flattenToArrayOfset(flat,offset)將矩陣轉(zhuǎn)存到一維數(shù)組中,前一個(gè)函數(shù)從flat[0]存儲(chǔ)到flat[15],后一個(gè)函數(shù)允許指定開始存儲(chǔ)的位置,從flat[offset]存儲(chǔ)到flat[offset+15]。
函數(shù)getPosition()和函數(shù)setPosition()用來獲取或設(shè)置矩陣對(duì)象的位置分量。正如旋轉(zhuǎn)分量存儲(chǔ)在左上角3×3的子矩陣中,位置分量存儲(chǔ)在第四行前三個(gè)分量上,即element[12], element[13], element[14]中。
函數(shù)getColumeX(),getColumeY(),getColumeZ()分別提取左上角3×3子矩陣的三列。
函數(shù)compose(translate,rotation,scale)將對(duì)象矩陣設(shè)置為由vector3類型translate對(duì)象表示的平移、由matrix3類型rotation對(duì)象表示的旋轉(zhuǎn)、由vector3類型scale對(duì)象表示的縮放這三個(gè)變換組合到一起的變換矩陣。實(shí)際上就是講其直接填充到模型矩陣的相應(yīng)子空間。
函數(shù)decompose(translate,rotation,scale)將矩陣對(duì)象拆開到三個(gè)對(duì)象中,和上一個(gè)函數(shù)正好相反。
函數(shù)extractPosition(m)和extractRotation(m)將矩陣對(duì)象m中表示位置或旋轉(zhuǎn)的分量抽取到調(diào)用者對(duì)象中,比如兩個(gè)物體經(jīng)過多次各不相同的變換,只需要一個(gè)物體的模型視圖矩陣extractRotation另一個(gè)物體的模型視圖矩陣,則調(diào)用者就和另外一個(gè)物體保持著變換之處相同的旋轉(zhuǎn)方位。
函數(shù)translate(v)是模型矩陣最基本的變換之一:平移變換,將模型矩陣從屬的物體平移向量v。
函數(shù)rotateX(angle),rotateY(angle),rotateZ(angle)分別將模型矩陣從屬的物體繞X,Y,Z軸旋轉(zhuǎn)角度angle。
函數(shù)rotateByAxis(axis, angle)將模型矩陣從屬的物體繞一個(gè)任意軸axis旋轉(zhuǎn)角度angle,這是上面兩條所涉及的變換的多次疊加(疊加參數(shù)由當(dāng)前位置和axis參數(shù)決定),我在《模型視圖矩陣和投影矩陣:webgl筆記(1)》中曾討論到繞任意軸旋轉(zhuǎn)的問題。
這里不應(yīng)該有一個(gè)scale(s)函數(shù)嗎?可是我在源碼中沒找到。
函數(shù)makeTranslate(x,y,z),makeRotationX(theta),makeRotationY(theta),makeRotationZ(theta),makeRotationAxis(axis,angle),makeScale(s)函數(shù)將對(duì)象矩陣直接重置為單位陣經(jīng)過一次平移、或繞某軸旋轉(zhuǎn)、或單純某次縮放后的矩陣。該函數(shù)更新對(duì)象本身的值,而且更新的結(jié)果與對(duì)象之前的值毫無關(guān)聯(lián)(這也是make前綴函數(shù)的特點(diǎn))。
函數(shù)makeFrustum(...),makePerspective(...),makeOrthographic(...)也是用來初始化新矩陣,具體含義到相機(jī)類里面再討論,我想相機(jī)類的構(gòu)造函數(shù)里一定會(huì)調(diào)用這些函數(shù)的。
函數(shù)clone()將矩陣對(duì)象復(fù)制出來并返回。
Core::Face3
該函數(shù)創(chuàng)建一個(gè)三角形平面對(duì)象
復(fù)制代碼 代碼如下:
THREE.Face3 = function ( a, b, c, normal, color, materialIndex ) {
this.a = a;
this.b = b;
this.c = c;
this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
this.vertexNormals = normal instanceof Array ? normal : [ ];
this.color = color instanceof THREE.Color ? color : new THREE.Color();
this.vertexColors = color instanceof Array ? color : [];
this.vertexTangents = [];
this.materialIndex = materialIndex;
this.centroid = new THREE.Vector3();
};
對(duì)象的a,b,c值是三個(gè)頂點(diǎn)的索引(后面會(huì)說到,Mesh對(duì)象中將所有點(diǎn)存儲(chǔ)為一個(gè)數(shù)組);顧名思義normal是法線;color是顏色;materialIndex是頂點(diǎn)材質(zhì)索引:這幾個(gè)參數(shù)即可以傳入vector3類型又可以傳入數(shù)組類型。
clone(x)方法返回一個(gè)新的,具有相同值的對(duì)象。
Core::Face4
該函數(shù)創(chuàng)建一個(gè)四個(gè)頂點(diǎn)的面,和Face3幾乎一樣,略去。
Core::Math
THREE.Math是一個(gè)“靜態(tài)類”,沒有構(gòu)造函數(shù)因此也不需要通過new關(guān)鍵字初始化。該類提供一些必要的數(shù)學(xué)工具。
函數(shù)clamp(x,a,b)將x夾在區(qū)間[a,b]中。clampBottom(x,a)的作用類似,只不過只夾一邊。
函數(shù)mapLinear(x,a1,a2,b1,b2)計(jì)算出一個(gè)值y,使得點(diǎn)(x,y)落在(a1,a2)和(b1,b2)連成的直線上。
復(fù)制代碼 代碼如下:
mapLinear: function ( x, a1, a2, b1, b2 ) {
return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
},
函數(shù)random16(),randInt(low,high),randFloat(low,high),randFloatSpread(range)分別產(chǎn)生[0,1]區(qū)間的16位隨機(jī)浮點(diǎn)數(shù),[low,high]區(qū)間隨機(jī)整數(shù),[low,high]區(qū)間隨機(jī)浮點(diǎn)數(shù),[-range/2,range/2]區(qū)間隨機(jī)浮點(diǎn)數(shù)。
函數(shù)sigh(x)根據(jù)x的符號(hào)返回+1或-1。
Core::Clock
該構(gòu)造函數(shù)創(chuàng)建時(shí)鐘(確切的說是秒表)對(duì)象
復(fù)制代碼 代碼如下:
THREE.Clock = function ( autoStart ) {
this.autoStart = ( autoStart !== undefined ) ? autoStart : true;
this.startTime = 0;
this.oldTime = 0;
this.elapsedTime = 0;
this.running = false;
};
函數(shù)start()和stop()用來開始計(jì)時(shí)或停止計(jì)時(shí)。
函數(shù)getDelta()返回調(diào)用該函數(shù)時(shí)距離上一次調(diào)用該函數(shù)時(shí)的時(shí)間長(zhǎng)度,如果是第一次調(diào)用該函數(shù),則返回此時(shí)距離開始計(jì)時(shí)時(shí)的時(shí)間長(zhǎng)度。如果autoStart值為真,若在調(diào)用getDelta()函數(shù)時(shí)尚未調(diào)用start()函數(shù)或者已經(jīng)調(diào)用過stop()函數(shù),則自動(dòng)開始計(jì)時(shí)并返回0。如果autoStart()值為假,則在調(diào)用start()之前或stop()之后,調(diào)用getDelta()返回0。
函數(shù)getElapsedTime()返回調(diào)用該函數(shù)時(shí)距離開始計(jì)時(shí)時(shí)的時(shí)間。
Core::Color
該構(gòu)造函數(shù)構(gòu)造一個(gè)表示顏色的對(duì)象
復(fù)制代碼 代碼如下:
THREE.Color = function ( hex ) {
if ( hex !== undefined ) this.setHex( hex );
return this;
};
函數(shù)setHex(hex)以十六進(jìn)制序列設(shè)置對(duì)象的r,g,b屬性。實(shí)際上在對(duì)象中,最終是以這三個(gè)屬性存儲(chǔ)顏色的。
復(fù)制代碼 代碼如下:
setHex: function ( hex ) {
hex = Math.floor( hex );
this.r = ( hex >> 16 & 255 ) / 255;
this.g = ( hex >> 8 & 255 ) / 255;
this.b = ( hex & 255 ) / 255;
return this;
},
函數(shù)setRGB(r,g,b)和setHSV(h,s,v)以RGB值或HSV值設(shè)置對(duì)象。
函數(shù)getHex()返回16進(jìn)制顏色值。
函數(shù)copyGammaToLinear(color),copyLinearToGamma(color)將color的rgb值分別平方或開方,賦給調(diào)用者對(duì)象。
函數(shù)convertGammaToLinear()和convertLinearToGamma()分別對(duì)調(diào)用者自身的rgb值平方或開放。
相關(guān)文章
JavaScript Math.floor方法(對(duì)數(shù)值向下取整)
這篇文章主要介紹了Math.floor 方法用于對(duì)數(shù)值向下取整,即得到小于或等于該數(shù)值的最大整數(shù),需要的朋友可以參考下2015-01-01Javascript模塊化編程(三)require.js的用法及功能介紹
這個(gè)系列的第一部分和第二部分,介紹了Javascript模塊原型和理論概念,今天介紹如何將它們用于實(shí)戰(zhàn)。我采用的是一個(gè)非常流行的庫(kù)require.js感興趣的朋友可以了解下啊2013-01-01THREE.JS入門教程(4)創(chuàng)建粒子系統(tǒng)
Three.js是一個(gè)偉大的開源WebGL庫(kù),WebGL允許JavaScript操作GPU,在瀏覽器端實(shí)現(xiàn)真正意義的3D本文將介紹創(chuàng)建一個(gè)粒子系統(tǒng)/風(fēng)格/引入物理等等,感興趣的朋友可以了解下哦,希望本文對(duì)你有所幫助2013-01-01JavaScript中把數(shù)字轉(zhuǎn)換為字符串的程序代碼
本篇文章是對(duì)JavaScript中把數(shù)字轉(zhuǎn)換為字符串的實(shí)現(xiàn)代碼進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06onkeyup,onkeydown和onkeypress的區(qū)別介紹
三者在事件的響應(yīng)上還有一點(diǎn)不同,就是onkeydown 、onkeypress事件響應(yīng)的時(shí)候輸入的字符并沒有被系統(tǒng)接受,而響應(yīng)onkeyup的時(shí)候,輸入流已經(jīng)被系統(tǒng)接受2013-10-10