亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

Three.js源碼閱讀筆記(2)

2024-09-06 12:41:05
字體:
來源:轉載
供稿:網友

THREE.Object3D = function () { THREE.Object3DLibrary.push( this ); this.id = THREE.Object3DIdCount ++; this.name = '; this.properties = {}; this.parent = undefined; this.children = []; this.up = new THREE.Vector3( 0, 1, 0 ); this.position = new THREE.Vector3(); this.rotation = new THREE.Vector3(); this.eulerOrder = THREE.Object3D.defaultEulerOrder; this.scale = new THREE.Vector3( 1, 1, 1 ); this.renderDepth = null; this.rotationAutoUpdate = true; this.matrix = new THREE.Matrix4(); this.matrixWorld = new THREE.Matrix4(); this.matrixRotationWorld = new THREE.Matrix4(); this.matrixAutoUpdate = true; this.matrixWorldNeedsUpdate = true; this.quaternion = new THREE.Quaternion(); this.useQuaternion = false; this.boundRadius = 0.0; this.boundRadiusScale = 1.0; this.visible = true; this.castShadow = false; this.receiveShadow = false; this.frustumCulled = true; this._vector = new THREE.Vector3();};

在介紹函數之前,需要先介紹一下這個類的幾個重要屬性。

屬性parent和children說明,通常需要使用樹來管理眾多Object3D對象。比如一輛行駛的汽車是一個Object3D對象,控制汽車行駛路線的邏輯在該對象內部實現,汽車的每個頂點經過模型矩陣的處理后,都位于正確的位置;但是汽車擺動的雨刮器,其不但隨著汽車行駛方向運動,而且自身相對汽車也在左右擺動,這個擺動的邏輯無法在汽車這個對象內部的實現。解決的方法是,將雨刮器設定為汽車的chidren,雨刮器內部的邏輯只負責其相對于汽車的擺動。在這種樹狀結構下,一個場景Scene實際上就是最頂端的Object3D,它的模型矩陣就是視圖矩陣(取決于相機)的逆矩陣。

屬性matrix和matrixWorld就很好理解了,matrix表示本地的模型矩陣,僅僅表示該對象的運動,而matrixWorld則需要依次向父親節點迭代,每一次迭代都左乘父親對象的本地模型矩陣,直到Scene對象——當然,實際上是左乘父親對象的全局模型矩陣。

屬性position、rotation、scale表示模型矩陣的三種變換部分,在Matrix4類中有相關說明。rotation和eulerOrder共同描述了一個旋轉狀態,quaternion也可以描述一個旋轉狀態,具體使用哪種方法要看useQuation的布爾值。

可以看到,關于該Object3D對象最重要的“變換狀態”信息實際上是存儲在兩個“備份”中的,一個是matrix對象,還有一個是position等屬性,兩部分應當保持一致,如果通過某種方法改變了一個備份,則另一個備份也應該在適當的時候更新。還有一些其他屬性從字面和類型上就能看出其含義,不再單獨列出了。下面說函數:

函數applyMatrix(matrix)將參數matrix左乘到this.matrix上,實際上就是對該Object3D對象實行某個變換(該變換可能要經過好幾步基本變換,但是已經存儲在參數matrix里面了)。注意,在對this.matrix執行完左乘之后,;立刻更新了position等參數的值。比起下面幾個變換函數,該函數更“高級”,允許開發者自由指定變換矩陣,而不是說“朝著x軸前進5單位距離”。

applyMatrix: function ( matrix ) { this.matrix.multiply( matrix, this.matrix ); this.scale.getScaleFromMatrix( this.matrix ); var mat = new THREE.Matrix4().extractRotation( this.matrix ); this.rotation.setEulerFromRotationMatrix( mat, this.eulerOrder ); this.position.getPositionFromMatrix( this.matrix ); },

函數translate(distance, axis)令該對象向axis軸指定的方向前進distance距離。函數translateX(distance),translateY(distance),translateZ(distance)令其向X,Y,Z軸前進distance距離。注意這些函數僅僅改變了position對象的值,而不曾改變matrix的值。

translate: function ( distance, axis ) { this.matrix.rotateAxis( axis ); this.position.addSelf( axis.multiplyScalar( distance ) ); },translateX: function ( distance ) { this.translate( distance, this._vector.set( 1, 0, 0 ) ); },

函數localToWorld(vector)將本地坐標轉化為世界坐標中,函數worldToLocal則正好相反。注意這里的vector本地坐標指的是未變換之前的坐標,也就是說雨刮器的默認位置的頂點坐標。

函數lookAt(eye,center,up)執行其matrix屬性對象的lookAt函數(之前介紹過,matrix4對象也有一個lookAt函數),一般用于相機對象。該函數僅僅改變了旋轉狀態,所以當matrix屬性對象執行完之后,如果屬性rotationAutoUpdate為真,則會更新rotation或quaternion的值,更新哪一個取決于屬性useQuation。

函數add(object)和函數remove(object)從當前Object3D對象中添加一個子對象,或刪除一個子對象,了解到場景中的眾多Object3D對象是用樹來管理的,這就很容易理解了。

函數traverse(callback)遍歷調用者和調用者的所有后代,callback參數是一個函數,被調用者和每一個后代對象調用callback(this)。

traverse: function ( callback ) { callback( this ); for ( var i = 0, l = this.children.length; i < l; i ++ ) { this.children[ i ].traverse( callback ); } },

函數getChildByName(name,recursive)通過字符串在調用者的子元素(recursive為false)或后代元素(recursive為true)中查詢屬性name符合的對象返回。

函數getDescendants(array)將調用者的所有后代對象全部push到數組array中。

函數updateMatrix()和updateMatrixWorld(force)將根據position,rotation或quaternion,scale參數更新matrix和matrixWorld。updateMatrixWorld還會更新所有后代元素的matrixWorld,如果force值為真或者調用者本身的matrixWorldNeedsUpdate值為真。在函數applyMatrix(matrix)中,改變了matrix值后立刻就更新了position,rotation等屬性,但在函數translate(distance,axis)中改變了position等變量(或者直接改變position等屬性)后并沒有立刻更新matrix值,這時應該手動調用updateMatrix()。這些細節值得注意,你也許會認為應該加入事件監聽,一旦一個值發生變化,其他所有的都會立刻更新,但我想在,可能是出于這方面的考慮:適當的時候更新會帶來更高的效率——比如可能會頻繁地改變rotation值,但是僅僅在使用matrix屬性之前,才對其進行更新。

updateMatrix: function () { this.matrix.setPosition( this.position ); if ( this.useQuaternion === false ) { this.matrix.setRotationFromEuler( this.rotation, this.eulerOrder ); } else { this.matrix.setRotationFromQuaternion( this.quaternion ); } if ( this.scale.x !== 1 || this.scale.y !== 1 || this.scale.z !== 1 ) { this.matrix.scale( this.scale ); this.boundRadiusScale = Math.max( this.scale.x, Math.max( this.scale.y, this.scale.z ) ); } this.matrixWorldNeedsUpdate = true; },updateMatrixWorld: function ( force ) { if ( this.matrixAutoUpdate === true ) this.updateMatrix(); if ( this.matrixWorldNeedsUpdate === true || force === true ) { if ( this.parent === undefined ) { this.matrixWorld.copy( this.matrix ); } else { this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix ); } this.matrixWorldNeedsUpdate = false; force = true; } for ( var i = 0, l = this.children.length; i < l; i ++ ) { this.children[ i ].updateMatrixWorld( force ); } },

函數deallocate手動將調用者占用的空間釋放掉,當不再需要該對象時這樣做。

Core::Projectors

管理投影矩陣的類,代碼太復雜了,我猜會涉及到render類里的操作,等到適當的時候再看吧。

Core::UV

該構造函數產生一個材質坐標類——就是材質上的坐標,往往與頂點對應起來,光柵化后每個像素都有一個材質坐標,再從材質上“取色”以實現紋理。

THREE.UV = function ( u, v ) { this.u = u || 0; this.v = v || 0;};

材質坐標類就是一個簡化的vector2類,除了屬性名稱不同而已。

Core::Ray Core::Rectangle Core:Spline

射線類,有原點、方向、遠近截斷點。在點光源中應該有應用。矩形類、曲線類,相對都比較簡單,也不那么“核心”,以后再看吧。

Core::Geometry

Geometry類也是非常重要的一類,表示一個由頂點和表面構成的幾何形體。

THREE.Geometry = function () { THREE.GeometryLibrary.push( this ); this.id = THREE.GeometryIdCount ++; this.name = '; this.vertices = []; this.colors = []; this.normals = []; this.faces = []; this.faceUvs = [[]]; this.faceVertexUvs = [[]]; this.morphTargets = []; this.morphColors = []; this.morphNormals = []; this.skinWeights = []; this.skinIndices = []; this.lineDistances = []; this.boundingBox = null; this.boundingSphere = null; this.hasTangents = false; this.dynamic = true; this.verticesNeedUpdate = false; this.elementsNeedUpdate = false; this.uvsNeedUpdate = false; this.normalsNeedUpdate = false; this.tangentsNeedUpdate = false; this.colorsNeedUpdate = false; this.lineDistancesNeedUpdate = false; this.buffersNeedUpdate = false;};

以下兩組屬性最重要:

屬性vertics是一個數組,每個元素是vector3類型的對象,表示一個頂點坐標。屬性colors和normals表示和頂點對應的顏色值和發現向量,只有在很少的情況下才使用,大部分情況下,頂點的顏色和發現時在“表面”中定義的——如果立方體的6面顏色各不相同,則每個頂點實在不同的面上是不同的顏色。

屬性faces是一個數組,每個元素是face4或face3類型的對象,之前介紹face3的時候說到,face中存儲的僅僅是頂點的索引值,通過索引值就可以在數組vertices中取到頂點的坐標值。

下面說函數:

applyMatrix(matrix)函數更新geometry中的所有頂點坐標和表面的法線向量,所做的實際上是用變換矩陣matrix對geometry形體進行空間變換。normalMatrix是參數matrix左上角3×3矩陣的逆轉置矩陣,該矩陣用來旋轉矢量(法線,而不是頂點坐標)。

applyMatrix: function ( matrix ) { var normalMatrix = new THREE.Matrix3(); normalMatrix.getInverse( matrix ).transpose(); for ( var i = 0, il = this.vertices.length; i < il; i ++ ) { var vertex = this.vertices[ i ]; matrix.multiplyVector3( vertex ); } for ( var i = 0, il = this.faces.length; i < il; i ++ ) { var face = this.faces[ i ]; normalMatrix.multiplyVector3( face.normal ).normalize(); for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { normalMatrix.multiplyVector3( face.vertexNormals[ j ] ).normalize(); } matrix.multiplyVector3( face.centroid ); } },

函數ComputeCentroid()計算幾何形體中每個表面的重心(不是幾何形體自己的重心)。這個函數似乎應當放到face類的原型上會更好,但是由于face類內部無法獲取點的坐標(除非再將點坐標數組的引用作為參數傳入構造函數,這樣代價就大了)而僅僅是索引值,所以只好在geometry類的原型上定義了。下面幾個函數都是類似的情況(事實上,face類幾乎沒有什么成員函數)。

函數computeFaceNormals()和computeVertexNormals(areaWeight)計算法線向量,前者影響的是face數組中每個元素的normal屬性,一個face只有1個;后者face數組中每個元素的vertexNormal屬性,一個face3型對象有3個,一個face4型對象有4個,但是需要注意的是,被多個表面共享的頂點,其法線向量只有一個,同時受到多個表面的影響。比如中心在原點,三組表面都垂直于軸的立方體,其第一象限中的頂點,法線向量是(1,1,1)的歸一化。雖然看上去不可思議,平面的頂點的法線居然不是垂直于平面的,但這種指定法線的方法在利用平面模擬曲面的時候有很好的效果。

函數createMorphNormal為每一個morph創建法線。morph應該是用作顯示固定連續動畫的變形效果。

函數mergeVertics將坐標值相同的點剔除,同時更新face對象中的點索引值。

Core::Quaternian

四維數旋轉類用另一種方式表達一個旋轉變換,相比用rotation,可以避免萬向節死鎖問題。

THREE.Quaternion = function( x, y, z, w ) { this.x = x || 0; this.y = y || 0; this.z = z || 0; this.w = ( w !== undefined ) ? w : 1;};

如果不談函數,Quaternian就是一個簡單的vector4類型對象。

函數setFromEuler(v,order)通過一次歐拉旋轉設置四維數旋轉。

函數setFromAxis(axis,angle)通過繞任意軸旋轉設定四維數旋轉。

函數setFromRotationMatrix(matrix)通過旋轉矩陣設置四維數旋轉。

還有一些和vector4類相同的函數這里就不列了。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲欧美日韩一区二区在线| 日韩国产激情在线| 国产精品第七十二页| 久久精品青青大伊人av| 狠狠躁夜夜躁久久躁别揉| 国产成人一区三区| 97视频在线播放| 国模极品一区二区三区| 久久久之久亚州精品露出| 国产精品视频成人| 亚洲精品大尺度| 欧美老女人在线视频| 日韩美女视频免费看| 欧美野外猛男的大粗鳮| 国产有码一区二区| 91香蕉嫩草神马影院在线观看| 精品自在线视频| 国产亚洲美女精品久久久| 欧美另类极品videosbest最新版本| 久久久久在线观看| 日韩在线精品视频| 97国产suv精品一区二区62| 久久在线精品视频| 91精品国产免费久久久久久| 另类专区欧美制服同性| 国产精品吹潮在线观看| 国产成人综合久久| 久久久精品美女| 亚洲精品理论电影| 国产黑人绿帽在线第一区| 亚洲自拍偷拍第一页| 色黄久久久久久| 欧美一级淫片videoshd| 色悠悠久久久久| 91欧美精品成人综合在线观看| 88国产精品欧美一区二区三区| 精品久久久久久久久久久久| 一区二区欧美久久| 色噜噜狠狠色综合网图区| 欧美在线播放视频| 精品久久久久久久中文字幕| 国内久久久精品| 欧美极品少妇xxxxⅹ裸体艺术| 91精品免费视频| 久久久91精品国产| xvideos亚洲人网站| 欧美一级淫片丝袜脚交| 国产精品视频午夜| 国产日韩欧美91| 精品久久久av| 96精品视频在线| 欧美性猛交视频| 亚洲天堂视频在线观看| 久久久久久国产精品三级玉女聊斋| 尤物yw午夜国产精品视频| 91欧美日韩一区| 日韩免费观看高清| 91在线观看欧美日韩| 最近中文字幕mv在线一区二区三区四区| 色偷偷噜噜噜亚洲男人的天堂| 欧美成人午夜视频| 欧美性猛交丰臀xxxxx网站| 国产精品久久久久久久电影| 久久久久成人网| 色yeye香蕉凹凸一区二区av| 久久影视电视剧凤归四时歌| 国产精品日韩在线播放| 精品日韩美女的视频高清| 国产精品久久久久久久久久久新郎| 欧美国产在线电影| 久久久久久成人精品| 国产成人精品一区| 日韩在线视频观看正片免费网站| 2020久久国产精品| 久久精品国产亚洲精品| 国产一区二区三区久久精品| 久久久久久18| 久久精品99无色码中文字幕| 一道本无吗dⅴd在线播放一区| 亚洲精品日韩在线| 亚洲人精选亚洲人成在线| 欧美在线视频网| 欧美成人精品激情在线观看| 欧美成人免费一级人片100| 最近2019年好看中文字幕视频| 国产福利精品av综合导导航| 2019国产精品自在线拍国产不卡| 久久99久久99精品免观看粉嫩| 欧美一区在线直播| 日韩av成人在线| 亚洲国产成人精品久久| 亚洲精品视频免费在线观看| 亚洲精品国精品久久99热一| 欧美精品一区二区三区国产精品| 国产精品美女久久久久av超清| 欧洲成人性视频| 欧美电影免费观看高清完整| 国产91精品久久久久久| 欧美三级xxx| 精品少妇一区二区30p| 国产精品视频yy9099| 久久影院免费观看| 91在线视频精品| 亚洲伦理中文字幕| 91精品国产高清久久久久久91| 色综合视频一区中文字幕| 6080yy精品一区二区三区| 欧美最猛性xxxxx免费| 日韩一区二区av| 日韩视频欧美视频| 日韩av网址在线| 欧美激情精品久久久| 91视频九色网站| 国产精品va在线播放我和闺蜜| 久久视频在线视频| 国产精品91久久久久久| 精品高清一区二区三区| 亚洲女人初尝黑人巨大| 国产精品电影久久久久电影网| 欧美一区亚洲一区| 欧美韩国理论所午夜片917电影| 国产一区二区激情| 国产伦精品一区二区三区精品视频| 国产丝袜精品第一页| 欧美与欧洲交xxxx免费观看| 欧美精品久久久久久久免费观看| 黑人巨大精品欧美一区二区| 欧美性猛交xxxx乱大交极品| 成人免费福利在线| 成人av番号网| 欧美国产日产韩国视频| 亚洲免费精彩视频| 久久亚洲一区二区三区四区五区高| 欧美视频专区一二在线观看| 97久久国产精品| 亚洲欧美综合v| 成人伊人精品色xxxx视频| 欧美成人在线网站| 久久天天躁狠狠躁老女人| 欧美激情xxxx性bbbb| 国产精品美乳一区二区免费| 97在线看免费观看视频在线观看| 成人xxxxx| 久久久久久久久久久免费| 夜夜嗨av一区二区三区四区| 欧美在线日韩在线| 日韩精品高清视频| 久久夜色精品国产亚洲aⅴ| 在线视频一区二区| 国产精品嫩草视频| 97超碰色婷婷| 国产成人福利夜色影视| 亚洲电影在线观看| 亚洲人高潮女人毛茸茸| 亚洲综合色激情五月| 狠狠躁18三区二区一区| 色偷偷亚洲男人天堂| 欧美麻豆久久久久久中文| 黄色精品一区二区| 久久久人成影片一区二区三区观看| 亚洲精品日韩在线| 57pao国产成人免费| 狠狠久久亚洲欧美专区| 欧美放荡办公室videos4k|