ホームページ > ウェブフロントエンド > jsチュートリアル > Three.jsソースコード読解メモ(Object3Dクラス)_基礎知識

Three.jsソースコード読解メモ(Object3Dクラス)_基礎知識

WBOY
リリース: 2016-05-16 17:45:18
オリジナル
1198 人が閲覧しました

これは Three.js ソース コードの読み取りメモの 2 番目の記事です。早速始めましょう。
Core::Object3D
Object3D は、Three.js フレームワークで最も重要なクラスであると思われます。シーン クラス、ジオメトリ クラス、クラス、照明クラスなど: これらはすべて 3D 空間内のオブジェクトであるため、Object3D クラスと呼ばれます。 Object3D コンストラクターは次のとおりです:

コードをコピー コードは次のとおりです:

THREE。 Object3D = function () {
THREE.Object3DLibrary.push( this );
this.name = ''; 🎜>this.parent = 未定義;
this.children = [];
this.up = new THREE.Vector3( 0, 1, 0 ); ;
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.matrixWorld = new THREE.Matrix4(); new THREE.Matrix4( );
this.matrixAutoUpdate = true;
this.quaternion = new THREE.Quaternion = false; >this.boundRadius = 0.0;
this.visible = true;
this.receiveShadow = false; true;
this._vector = new THREE.Vector3();
};


関数を導入する前に、このクラスのいくつかの重要な属性を導入する必要があります。
属性の親と子の説明。多くの Object3D オブジェクトを管理するには、通常、ツリーを使用する必要があります。たとえば、移動する車は Object3D オブジェクトであり、車の走行ルートを制御するロジックはモデル マトリックスによって処理された後にオブジェクト内に実装されますが、ワイパー ブレードはそのオブジェクト内に実装されます。車は車の方向に動くだけでなく、車に対して左右に揺れます。この揺れのロジックは車のオブジェクト内に実装できません。解決策は、ワイパーを車の子供に合わせて設定することであり、ワイパー内部のロジックは車に対するワイパーの揺れのみを担当します。このツリー構造では、シーン Scene が実際には最上位の Object3D であり、そのモデル行列はビュー行列の逆行列になります (カメラによって異なります)。

MATRIX 属性と MATRIXWORLD 属性は、オブジェクトの動きのみを表すローカル モデル行列を表し、MatrixWorld は親ノードに順番に乗算する必要があります。親オブジェクトのローカル値。シーン オブジェクトまでのモデル マトリックス。もちろん、実際には親オブジェクトのグローバル モデル マトリックスが乗算されます。

属性の位置、回転、およびスケールは、Matrix4 クラスで説明されているモデル行列の 3 つの変換部分を表します。回転と eulerOrder は一緒に回転状態を記述し、クォータニオンも回転状態を記述できます。使用する具体的なメソッドは us​​eQuation のブール値によって異なります。

Object3D オブジェクトに関する最も重要な「変換状態」情報は、実際には 2 つの「バックアップ」に保存されていることがわかります。1 つは行列オブジェクトで、もう 1 つは位置とその他の属性の 2 つの部分です。あるバックアップが何らかの方法で変更された場合、他のバックアップもやがて更新される必要があります。他にも、文字通りおよび型的に意味がわかるプロパティがいくつかありますが、個別にリストされていません。以下の関数について説明します。
関数 applyMatrix(matrix) は、左側のパラメーター行列に this.matrix を乗算します。実際に、Object3D オブジェクトに対して特定の変換を実行します (この変換にはいくつかの基本的な変換手順が必要になる場合がありますが、パラメータマトリックスに保存されています)。 this.matrix に対して左乗算を実行すると、位置などのパラメータの値がすぐに更新されることに注意してください。この関数は、以下の変換関数と比較してより「高度」であり、開発者は「X 軸に向かって 5 単位進める」という代わりに、変換行列を自由に指定できます。



コードをコピー


コードは次のとおりです。


applyMatrix: function (行列) {
this.matrix.multiply(行列, 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 axisで指定された方向に距離だけ移動させます。関数translateX(距離)、translateY(距離)、およびtranslateZ(距離)を使用すると、X、Y、Z軸に距離だけ進みます。これらの関数は位置オブジェクトの値のみを変更し、行列の値は変更しないことに注意してください。
コードをコピー コードは次のとおりです。

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 は反対。ここでのベクトルのローカル座標は、変換前の座標、つまりワイパーのデフォルト位置の頂点座標を指すことに注意してください。

関数 lookAt(eye,center,up) は、一般にカメラ オブジェクトに使用されるマトリックス属性オブジェクトの lookAt 関数を実行します (前に紹介したように、matrix4 オブジェクトにも lookAt 関数があります)。この関数は回転状態のみを変更するため、行列属性オブジェクトが実行されると、属性 RotationAutoUpdate が true の場合、回転またはクォータニオンの値が更新されます。どちらが更新されるかは属性 useQation によって異なります。
関数add(object)と関数remove(object)は、現在のObject3Dオブジェクトからサブオブジェクトを追加したり、サブオブジェクトを削除したりします。シーン内の多くのObject3Dオブジェクトがツリーを使用して管理されていることが容易に理解できます。 。

関数 traverse(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) に一致するオブジェクトをクエリします。属性名を返します。

関数 getDescendants(array) は、呼び出し元のすべての子孫オブジェクトを配列 array にプッシュします。
関数 updateMatrix() と updateMatrixWorld(force) は、位置、回転または四元数、スケール パラメーターに従って行列と行列ワールドを更新します。 updateMatrixWorld は、force 値が true であるか、呼び出し元自身の matrixWorldNeedsUpdate 値が true である場合、すべての子孫要素の matrixWorld も更新します。 applyMatrix(matrix)関数では、行列の値を変更した直後に位置、回転などの属性が更新されますが、translate(距離、軸)関数では、位置などの変数が変更されます(または、位置などの属性が変更されます)。直接変更される) ため、すぐには更新されません。行列の値を更新するには、updateMatrix() を手動で呼び出す必要があります。これらの詳細は注目に値します。イベント リスナーを追加すると、1 つの値が変更されると、他のすべての値がすぐに更新されると考えられます。これは、適切なタイミングで更新することで効率が向上するためであると考えられます。 - たとえば、回転値は頻繁に変更される可能性がありますが、マトリックス属性は使用する前にのみ更新されます。

コードをコピー コードは次のとおりです。
updateMatrix: function () {
this.matrix .setPosition( this.position );
if ( this.useQuaternion === false ) {
this.matrix.setRotationFromEuler( this.rotation, this.eulerOrder );
🎜>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 || 強制 === true ) {
if ( this.parent === 未定義 ) {
this.matrixWorld.copy( this.matrix );
} else {
this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
}
this.matrixWorldNeedsUpdate = false;
}
for ( var i = 0, l = this.children.length; i < l; i ) {
this.children[ i ].updateMatrixWorld(force );
}
},


関数 deallocate は、オブジェクトが不要になったときに、呼び出し元が占有していたスペースを手動で解放します。
Core::Projectors
射影行列を管理するクラス。コードが複雑すぎるので、適切なタイミングで見てみましょう。
Core::UV
このコンストラクターは、マテリアル座標クラス (多くの場合、頂点に対応するマテリアル上の座標) を生成します。次に、「pick.素材から「色」を決めて質感を実現します。
コードをコピー コードは次のとおりです。

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


マテリアル座標クラスは、簡略化された Vector2 クラスです。属性名以外はただ違います。

Core::Ray Core::Rectangle Core:Spline
原点、方向、遠方および近方のカットオフ ポイントを備えた Ray クラス。点光源にも応用できるはずです。長方形と曲線のタイプは比較的単純で、それほど「核心」ではありません。後で見てみましょう。
Core::Geometry
Geometry クラスも非常に重要なクラスであり、頂点と面で構成される幾何学的形状を表します。

THREE.Geometry = function () {
THREE .GeometryLibrary.push( this );
this.id = THREE.GeometryIdCount;
this.vertices = []; ];
this.normals = [];
this.faceUvs = [[]]; .morphTargets = [];
this.morphNormals = [];
this.skinIndices = []; .lineDistances = [];
this.boundingSphere = null;
this.dynamic = true; ;
this.elementsNeedUpdate = false;
this.tangentsNeedUpdate = false; >this.buffersNeedUpdate = false;



次の 2 つの属性セットが最も重要です
:
属性の頂点は配列です。頂点座標を表すvector3型のオブジェクトです。属性の色と法線は、頂点に対応する色の値と検出ベクトルを表します。ほとんどの場合、頂点の色と検出ベクトルは「表面」で定義されます。立方体の側面 色が異なるため、各頂点は実際には異なる面では異なる色になります。

属性facesは配列であり、各要素はface4またはface3タイプのオブジェクトです。以前にface3を紹介したときに、faceは頂点のインデックス値のみを格納し、インデックス値は次のとおりであると述べました。配列の頂点で使用される頂点の座標値を取得します。


以下は関数
です:
applyMatrix(matrix) 関数は、ジオメトリ内のすべての頂点座標とサーフェスの法線ベクトルを更新します。実際には、変換行列が使用されます。マトリックスを使用してジオメトリをジオメトリに適用すると、形状が空間変換されます。 NormalMatrix は、パラメータ行列の左上隅にある 3×3 行列の逆転置行列です。この行列は、ベクトル (頂点座標ではなく法線) を回転するために使用されます。




コードをコピー

コードは次のとおりです。
applyMatrix: function (行列) {
varnormalMatrix = new THREE.Matrix3();
normalMatrix.getInverse(行列).transpose();
for ( var i = 0, il = this.vertices.length; i var vertex = this.vertices[ i ];
matrix.multiplyVector3( vertex ); } for ( var i = 0, il = this.faces.length; i var face = this.faces[ i ];
normalMatrix.multiplyVector3( face.normal ).normalize();
for ( var j = 0, jl = face.vertexNormals.length ; j normalMatrix.multiplyVector3( face.vertexNormals[ j ] ).normalize(); matrix.multiplyVector3( face.centroid ); >}、
関数 ComputeCentroid() は、ジオメトリ内の各サーフェスの重心を計算します (ジオメトリ自体の重心ではありません)。この関数は face クラスのプロトタイプに配置した方がよいように思えますが、点の座標は face クラスの内部で取得できないため (点の座標配列への参照がパラメーターとしてコンストラクターに渡されない限り、これは非常にコストがかかります)、これは単なるインデックス値であるため、ジオメトリ クラスのプロトタイプで定義する必要があります。以下の関数も同様の状況です (実際、face クラスにはメンバー関数がほとんどありません)。

関数 computeFaceNormals() と computeVertexNormals(areaWeight) は法線ベクトルを計算します。前者は面配列内の各要素の法線属性に影響し、後者は各要素の vertexNormal に影響します。 face 配列の属性は、face3 タイプのオブジェクトには 3 つ、face4 タイプのオブジェクトには 4 つあります。ただし、複数のサーフェスで共有される頂点は 1 つの法線ベクトルのみを持ち、同時に複数のサーフェスの影響を受けることに注意してください。 。たとえば、原点に中心があり、軸に垂直な 3 組の表面を持つ立方体の場合、第 1 象限の頂点の法線ベクトルは (1,1,1) の正規化です。平面の頂点の法線が平面に対して垂直でないのは信じられないことですが、この法線指定方法は、平面を使用して曲面をシミュレートする場合に効果があります。

関数 createMorphNormal は、各モーフの法線を作成します。モーフは、固定連続アニメーションの変形効果を表示するために使用する必要があります。
関数 mergeVertics は、同じ座標値を持つポイントを削除し、面オブジェクト内のポイント インデックス値を更新します。
Core::Quaternian
4 次元回転クラスは、回転を使用する場合と比較して、別の方法で回転変換を表現することで、ジンバルのデッドロックの問題を回避できます。
コードをコピー コードは次のとおりです。

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


関数について話さない限り、Quaternian は単純な Vector4 型のオブジェクトです。
関数 setFromEuler(v,order) は、オイラー回転を通じて 4 次元の回転を設定します。
関数 setFromAxis(axis,angle) は、任意の軸の周りを回転することで 4 次元の回転を設定します。
関数 setFromRotationMatrix(matrix) は、回転行列を介して 4 次元の回転を設定します。
vector4 クラスと同じで、ここにリストされていない関数もいくつかあります。
関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート