Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Three.js 使用applyMatrix-ThreeJS后的模型位置和旋转_Three.js - Fatal编程技术网

Three.js 使用applyMatrix-ThreeJS后的模型位置和旋转

Three.js 使用applyMatrix-ThreeJS后的模型位置和旋转,three.js,Three.js,我最近创建了一个侧面的圆柱体。然后,我通过计算每个面tris的中心点,将一个立方体添加到它的每个分段中,并使其与立方体完美配合 我现在正试图用模型替换立方体。该模型是一个平坦的地面,因此本质上是一个立方体。我遇到了一些问题 第一个问题是,当我将地面模型添加到圆柱体时,由于圆柱体位于其一侧,因此地面0,0,0的翻转不正确。我通过执行以下操作修复了此问题: ground.model.scene.applyMatrix(new THREE.Matrix4().makeRotationZ(Math.PI

我最近创建了一个侧面的圆柱体。然后,我通过计算每个面tris的中心点,将一个立方体添加到它的每个分段中,并使其与立方体完美配合

我现在正试图用模型替换立方体。该模型是一个平坦的地面,因此本质上是一个立方体。我遇到了一些问题

第一个问题是,当我将地面模型添加到圆柱体时,由于圆柱体位于其一侧,因此地面0,0,0的翻转不正确。我通过执行以下操作修复了此问题:

ground.model.scene.applyMatrix(new THREE.Matrix4().makeRotationZ(Math.PI / 2));
ground.model.scene.applyMatrix(new THREE.Matrix4().makeRotationY(Math.PI));
然而,在我的逻辑中,下一步对立方体非常有效,那就是使用“查看并传递面法线”和“传递当前面的位置”计算旋转,并计算两个面的中心点。因为我的圆柱体的每个面都由两个三角形组成,所以我可以用这种方式欺骗它

这些函数如下所示:

averageFaceNormals(index){
   
      var faceAvg = new THREE.Vector3();

      faceAvg.x = (this.cylinder.geometry.faces[index].normal.x +
        this.cylinder.geometry.faces[index+1].normal.x) / 2;
     
      faceAvg.y = (this.cylinder.geometry.faces[index].normal.y +
        this.cylinder.geometry.faces[index+1].normal.y) / 2;

      faceAvg.z = (this.cylinder.geometry.faces[index].normal.z +
        this.cylinder.geometry.faces[index+1].normal.z) / 2;

      return faceAvg;
  }

calculateFacePositions(index){
  var geo = this.cylinder.geometry;

  var faceA = this.cylinder.geometry.faces[index];

  var verticesA = geo.vertices;
  var v1A = verticesA[faceA.a];
  var v2A = verticesA[faceA.b];
  var v3A = verticesA[faceA.c];

  var centroidA = new THREE.Vector3();
  centroidA.x = ( v1A.x + v2A.x + v3A.x ) / 3;
  centroidA.y = ( v1A.y + v2A.y + v3A.y ) / 3;
  centroidA.z = ( v1A.z + v2A.z + v3A.z ) / 3;
  
  var faceB = this.cylinder.geometry.faces[index+1];

  var verticesB = geo.vertices;
  var v1B = verticesB[faceB.a];
  var v2B = verticesB[faceB.b];
  var v3B = verticesB[faceB.c];

  var centroidB = new THREE.Vector3();
  centroidB.x = ( v1B.x + v2B.x + v3B.x ) / 3;
  centroidB.y = ( v1B.y + v2B.y + v3B.y ) / 3;
  centroidB.z = ( v1B.z + v2B.z + v3B.z ) / 3;

  var centroidAverage = new THREE.Vector3();
  centroidAverage.addVectors(centroidA, centroidB);
  centroidAverage.x = centroidAverage.x / 2;
  centroidAverage.y = centroidAverage.y / 2;
  centroidAverage.z = centroidAverage.z / 2;

  return centroidAverage;
}
 for(var i = 0; i < this.cylinder.geometry.faces.length; i+=2){
      var ground = new Ground("ground", this.preload);
      var afn = this.averageFaceNormals(i);
      ground.model.scene.up = afn.clone().normalize();
      ground.model.scene.lookAt(new Vector3(afn.x,afn.y,afn.z));
      ground.model.scene.position.copy(this.calculateFacePositions(i));

      this.cylinder.add(ground.model.scene);
    }
这就是我添加地面瓷砖的地方,我注释掉了负责旋转和位置的两条线,因为它们不再适用于我的模型,而是适用于我一直使用的立方体测试对象。我是不是忽略了什么?地面瓷砖会生成,但就像我所做的矩阵更改被“注视”和“位置”副本覆盖一样

 for(var i = 0; i < this.cylinder.geometry.faces.length; i+=2){
      var ground = new Ground("ground", this.preload);
      ground.model.scene.applyMatrix(new THREE.Matrix4().makeRotationZ(Math.PI / 2));
      ground.model.scene.applyMatrix(new THREE.Matrix4().makeRotationY(Math.PI));
      //ground.model.scene.lookAt(this.averageFaceNormals(i));
      //ground.model.scene.position.copy(this.calculateFacePositions(i));
      this.cylinder.add(ground.model.scene);
    }
for(变量i=0;i
编辑:所以我目前已经取得了一些进展,似乎用更少的代码工作得更好,但我已经更改了我的放置循环,如下所示:

averageFaceNormals(index){
   
      var faceAvg = new THREE.Vector3();

      faceAvg.x = (this.cylinder.geometry.faces[index].normal.x +
        this.cylinder.geometry.faces[index+1].normal.x) / 2;
     
      faceAvg.y = (this.cylinder.geometry.faces[index].normal.y +
        this.cylinder.geometry.faces[index+1].normal.y) / 2;

      faceAvg.z = (this.cylinder.geometry.faces[index].normal.z +
        this.cylinder.geometry.faces[index+1].normal.z) / 2;

      return faceAvg;
  }

calculateFacePositions(index){
  var geo = this.cylinder.geometry;

  var faceA = this.cylinder.geometry.faces[index];

  var verticesA = geo.vertices;
  var v1A = verticesA[faceA.a];
  var v2A = verticesA[faceA.b];
  var v3A = verticesA[faceA.c];

  var centroidA = new THREE.Vector3();
  centroidA.x = ( v1A.x + v2A.x + v3A.x ) / 3;
  centroidA.y = ( v1A.y + v2A.y + v3A.y ) / 3;
  centroidA.z = ( v1A.z + v2A.z + v3A.z ) / 3;
  
  var faceB = this.cylinder.geometry.faces[index+1];

  var verticesB = geo.vertices;
  var v1B = verticesB[faceB.a];
  var v2B = verticesB[faceB.b];
  var v3B = verticesB[faceB.c];

  var centroidB = new THREE.Vector3();
  centroidB.x = ( v1B.x + v2B.x + v3B.x ) / 3;
  centroidB.y = ( v1B.y + v2B.y + v3B.y ) / 3;
  centroidB.z = ( v1B.z + v2B.z + v3B.z ) / 3;

  var centroidAverage = new THREE.Vector3();
  centroidAverage.addVectors(centroidA, centroidB);
  centroidAverage.x = centroidAverage.x / 2;
  centroidAverage.y = centroidAverage.y / 2;
  centroidAverage.z = centroidAverage.z / 2;

  return centroidAverage;
}
 for(var i = 0; i < this.cylinder.geometry.faces.length; i+=2){
      var ground = new Ground("ground", this.preload);
      var afn = this.averageFaceNormals(i);
      ground.model.scene.up = afn.clone().normalize();
      ground.model.scene.lookAt(new Vector3(afn.x,afn.y,afn.z));
      ground.model.scene.position.copy(this.calculateFacePositions(i));

      this.cylinder.add(ground.model.scene);
    }
for(变量i=0;i
现在看起来像这样

看起来好像我只需要让每个地面翻转一个旋转值到0,但我不知道该怎么做。复制/设置似乎不起作用,我不确定是否需要使用EULER或向量

这可能是显而易见的,但这是我第一次使用ThreeJS,所以感谢您对我的支持

编辑#2:好吧,我已经取得了更大的进步,让地砖按照我的需要铺设!现在我注意到,似乎我的一半瓷砖被翻转放置在X上,这会导致一半圆柱体无法正确对齐

我的最新安置代码:

for(var i = 0; i < this.cylinder.geometry.faces.length; i+=2){
      var ground = new Ground("ground", this.preload);
      var afn = this.averageFaceNormals(i);
      ground.model.scene.up = afn.clone().normalize();
      ground.model.scene.lookAt(afn);
      ground.model.scene.rotateX(Math.PI/2);
      ground.model.scene.position.copy(this.calculateFacePositions(i));
      this.cylinder.add(ground.model.scene);
    }
for(变量i=0;i
这是我气缸两侧的中间标记处的外观: