0

我正在开发一个带有场景图的快速 WebGL 引擎,以便在 reddit ( https://www.reddit.com/r/gameideas/comments/3dsy8m/revolt/ ) 上快速制作我的游戏创意原型。现在,在我完成了一些基本渲染之后,我无法确定正确的顺序,以及对大多数人来说看起来正确的顺序,我应该使用它来转换场景图中的节点。

很难解释正在发生的事情,但我希望你能理解它并没有像大多数人期望它在任何其他引擎中发生的那样旋转。

这是我目前正在做的事情的简化版本。

  • Mat4 = glMatrix 0.9.5
  • 实用程序 = 自定义实用程序

节点(渲染):

@param {父矩阵}

// 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 {父矩阵}

// 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

通常的顺序是 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 回答
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 回答