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