2016-05-25 64 views
0

私は、回転と位置のデータをエンコードする4x4変換行列を含む配列を持っています(この行列はOctaveの有効な変換を表しています)。この配列の内容を使用するthree.jsオブジェクト(Object3D)のmatrixWorldプロパティを設定します。つまり、変換マトリックスに基づいてオブジェクトの位置と回転を設定します。three.jsオブジェクトのmatrixWorldプロパティを設定する

three.jsドキュメントとここに尋ねた様々な質問(例えば、this onethis one)からthis pageによれば、鍵がfalseにnameOfObject.matrixAutoUpdateを設定することがあるようです。しかし、これを考慮して、nameOfObject.matrixWorldを設定するさまざまなアプローチを試しましたが、オブジェクトのレンダリング場所を変更するものはありません。matrixWorldが4x4アイデンティティの場合のように、回転のない原点に残りますマトリックス。ここで

は(render()が呼び出される前に、このコードは更新方法の中にある)私が試したものです:

// Setting up a three.js matrix 
var tempMatrix = new THREE.Matrix4(); 
tempMatrix.fromArray(arrayContainingTransformationMatrix); 

// Values are set as expected 
console.log(tempMatrix.elements); 

// Note that the approaches below were tried one at a time 

// First approach (doesn't work) 
nameOfObject.matrixAutoUpdate = false; 
nameOfObject.matrixWorld.copy(tempMatrix); 

// Second approach (also doesn't work) 
// Based on the second SO question linked above 
nameOfObject.matrixAutoUpdate = false; 
nameOfObject.matrix.copy(tempMatrix); 
nameOfObject.updateMatrixWorld(true); 

// Third approach (this doesn't work either, unfortunately) 
nameOfObject.matrixAutoUpdate = false; 
nameOfObject.matrixWorld.fromArray(arrayContainingTransformationMatrix); 

// Appears to be set correctly regardless of which approach is used 
console.log(sphere1.matrixWorld.elements); 

いくつかの注意事項:

  • 私はそれが実際には必要ありませんことを期待したいですすべての繰り返しの中でmatrixAutoUpdateをfalseに設定することができますが、今のところ私はそれを安全に行うために行っています。
  • matrixWorldを変更する代わりに、nameOfObject.positionを変換行列の4列目の値に基づいて変更すると、オブジェクトの位置が予期したとおりに変わるため、レンダリングの問題には見えません。
  • positionrotationのプロパティに基づいて行列を手動で設定するときには、updateMatrix()を呼び出さないでください。私はupdateMatrixWorld()も同様の考慮事項になると思うだろうが、私はそれが何をしているかについて多くの議論をしていない。

ご了承ください。最悪の場合、私はソースを見ていきますが、three.jsはそれまでのところ使いやすいものでした。

+0

オブジェクトの行列のみを設定できます。オブジェクトのワールドマトリックスを設定することはできません。これはあなたの質問ですか? "どのように' object.matrix'を設定して、特定の 'object.matrixWorld'(オブジェクトの親の変換を考慮に入れます)になるように設定できますか? – WestLangley

+0

オブジェクトのワールドマトリックスが読み取り専用の場合、それは私の質問に答えます。私は 'matrixWorld'プロパティが[Object3D docs](http://threejs.org/docs/index.html#Reference/Core/Object3D)の" readonly "とラベル付けされていないため、設定できると仮定しました。他の読み取り専用プロパティ、例えば 'id'は" readonly "で始まります)。 –

+1

読み取り専用ではありません。レンダラーはそれをリセットしています。 – WestLangley

答えて

0

今のところ、オブジェクトのmatrixプロパティ(オブジェクトの親に対する相対的なローカル変換)を設定することで、望ましい結果を得ることができました。オブジェクトの親がsceneあるので、このようなコードは動作します:

scene.add(nameOfObject); 

// Using this transformation matrix (translation of two units along the x axis): 
// 1 0 0 2 
// 0 1 0 0 
// 0 0 1 0 
// 0 0 0 1 

// Column-major version of the transformation 
var tempArrayCM = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 1]; 
// Per the docs, Matrix4.fromArray() uses column-major format 

// Row-major version of the transformation 
var matrixT = new THREE.Matrix4(); 
matrixT.set(1, 0, 0, 2, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); 
// Per the docs, Matrix4.set() uses row-major format 

nameOfObject.matrixAutoUpdate = false; 

nameOfObject.matrix.fromArray(tempArrayCM); // This works 

//nameOfObject.matrix.copy(matrixT); // This also works 

//nameOfObject.matrixWorld.fromArray(tempArrayCM); // No effect 

//nameOfObject.matrixWorld.copy(matrixT); // No effect 

それだけでは動作しませんmatrixWorldを設定するようです。問題のオブジェクトがsceneの子であるといいですが、オブジェクトがsceneの子の子であり、その親とは独立した世界の位置を設定する必要がある場合、これは問題を引き起こすと想像することができます(編集:attachおよびdetachの方法はSceneUtilsであり、これは間接的ではあるが)。

これは実際にはオブジェクトの親がsceneの場合にのみ適用される回避策なので、答えとしてマークしません。

脇アン:私はMatrix4.set()は行優先順が、Matrix4.fromArray()Matrix4.elements利用の列優先順序を使用していること、それは少し奇妙見つけます。

+0

ループ内に.updateMatrix()が必要です。 – dcromley

+0

いいえ、その省略は[私が読んだこと](http://threejs.org/docs/#Manual/Introduction/Matrix_transformations) 'updateMatrix()'(つまり、 'position'と' rotation'プロパティを使って計算されたものを上書きするので、手動で 'matrix'を設定します)。 –

+1

'Matrix4.set()'は行優先順位を使用しているので、コードは4行でブロックとして印刷すると人間が読むことができます。 'Matrix4.elements'は、webGLと互換性があるように列優先順位を使います。 'Matrix4.fromArray()'は、 'Matrix4.elements'と互換性があるように列優先順位を使います。 – WestLangley

関連する問題