0

reddit ( https://www.reddit.com/r/gameideas/comments/3dsy8m/revolt/ )でゲームのアイデアをすばやくプロトタイプ化するために、シーン グラフを使用したクイック WebGL エンジンに取り組んでいます。さて、いくつかの基本的なレンダリングを行った後、シーン グラフ内のノードを変換するために使用する正しい順序、つまりほとんどの人に正しく見える順序を理解できません。

何が起こっているのかを説明するのは難しいですが、他のエンジンで起こるとほとんどの人が予想するような回転ではないことを理解していただければ幸いです。

これは、私が現在行っていることの簡略化されたバージョンです。

  • Mat4 = glMatrix 0.9.5
  • ユーティリティ = カスタム ユーティリティ

ノード(レンダリング):

@param {parentMatrix}

// Create Local Matrix
self.lMatrix = mat4.create();
mat4.identity(self.lMatrix);
mat4.translate(self.lMatrix, self.position);
mat4.rotate(self.lMatrix, self.rotation[0], [1, 0, 0]);
mat4.rotate(self.lMatrix, self.rotation[1], [0, 1, 0]);
mat4.rotate(self.lMatrix, self.rotation[2], [0, 0, 1]);

var wMatrix = mat4.create();
mat4.identity(wMatrix);
if(parentMatrix){
    mat4.multiply(self.lMatrix, parentMatrix, wMatrix);
}
else{
    mat4.set(self.lMatrix, wMatrix);
}
// Render
var children = this.children,
numChildren = children.length,
child;

for(var i = 0; i < numChildren; i++){
    child = children[i];
    child.render(wMatrix);
}

エンティティ(レンダリング):

@param {parentMatrix}

// Set Transformation matrix
var tMatrix = mat4.create();
mat4.identity(tMatrix);
mat4.translate(tMatrix, self.position);
mat4.rotate(tMatrix, self.rotation[0], [1, 0, 0]);
mat4.rotate(tMatrix, self.rotation[1], [0, 1, 0]);
mat4.rotate(tMatrix, self.rotation[2], [0, 0, 1]);
mat4.scale(tMatrix, self.scale || [1, 1, 1]);

var wMatrix = mat4.create();
mat4.identity(wMatrix);
mat4.multiply(tMatrix, parentMatrix, wMatrix);

Utils.loadTMatrix(wMatrix);
this.texture.bind();
this.mesh.render();
4

2 に答える 2

0

以前はマトリックスをキャッシュしていたため、望んでいた元の方法が見つかりませんでした。それを続けたいと思っていましたが、古いエンジンをゼロから再作成した後、はるかに簡単な方法を見つけました。

Engine.prototype.NODE.prototype.render = function(parentMatrix){
  var children = this.children,
      numChildren = children.length,
      child, pos, rot, scale;
  // If has set matrix to a copy of it
  if(parentMatrix){
    this.matrix = mat4.clone(parentMatrix);
  }
  else{
    // Else set it to a identity matrix
    mat4.identity(this.matrix);
  }
  // If matrix needs updating reconstruct it
  pos = [this.position.x,
         this.position.y,
         this.position.z];
  rot = [this.rotation.x,
         this.rotation.y,
         this.rotation.z];
  scale = [this.scale.x,
           this.scale.y,
           this.scale.z];
  // Recreate Transformation matrix
  mat4.translate(this.matrix, this.matrix, pos);
  mat4.rotate(this.matrix, this.matrix, rot[0], [1, 0, 0]);
  mat4.rotate(this.matrix, this.matrix, rot[1], [0, 1, 0]);
  mat4.rotate(this.matrix, this.matrix, rot[2], [0, 0, 1]);
  mat4.scale(this.matrix, this.matrix, scale);
  // Render Children with this matrix
  for(var i = 0; i < numChildren; i++){
    child = children[i];
    child.render(this.matrix);
  }
}

私が基本的に行っているのは、マトリックスに親がある場合 (ルート ノードではない)、その親のクローンとしてマトリックスを開始することです。それ以外の場合は、マトリックスを単位マトリックスに設定します。次に、通常の変換を適用します。マトリックスのキャッシュを継続する方法を見つけたら、できるだけ早くアップロードします。

于 2015-07-27T14:59:08.200 に答える
0

通常の順序は、SRT (スケール、回転、移動) です。

また、あなたができるかどうかはわかりません

mat4.rotate(tMatrix, self.rotation[0], [1, 0, 0]); mat4.rotate(tMatrix, self.rotation[1], [0, 1, 0]); mat4.rotate(tMatrix, self.rotation[2], [0, 0, 1]);

オイラー角を使用して、正しい結果の方向を取得します。私はオイラー角を使用しないので、詳細を完全には把握していません。私が間違っている場合は、誰かが私を修正してください。オイラー角と回転行列の変換については、 http ://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToMatrix/ のページを参照してください。

于 2015-07-25T19:19:51.037 に答える