我有一个与我的raycaster相交的模特女巫。 raycaster返回正确的点,但是脸部法线向量不是我正在等待的。 Three.js内置了VertexNormalsHelper,当我使用它显示正确的法线时,但是当我创建两个立方体时,一个将位于交叉点的位置,另一个将位于法线向量,它将如下所示:
红色立方体是raycaster交叉点,蓝色立方体是面部法线
我的代码很简单只是一个简单的raycaster,我将点的位置复制到立方体。当我加载我的模型时,我更新了geomtery上的所有内容。我使用Orbitcontrols进行相机移动。
var intersects = this.checkIntersection(this.surfaceModel);
for (var i = 0; i < intersects.length; i++) {
var p = intersects[ 0 ].point;
var normal = intersects[ 0 ].face.normal.clone();
//Red & Blue cube position update
this.pointHelper_A.position.copy(p);
this.pointHelper_B.position.copy(normal);
这是VertexNormalsHelper打开时的图像,因此您可以看到法线正常:
答案 0 :(得分:0)
我已经阅读了VertexNormalsHelper的源代码,并且我已经创建了一个函数,它可以为您提供正常的面部向量。所以它可以告诉你这一点,但我不认为这是主要问题的真正解决方案,也有很多操作。
以下是代码:
(对象: THREE.Mesh , face: THREE.Face3 )
this.getFaceNormalPosition = function (object, face) {
var v1 = new THREE.Vector3();
var keys = ['a', 'b', 'c', 'd'];
object.updateMatrixWorld(true);
var size = (size !== undefined) ? size : 1;
var normalMatrix = new THREE.Matrix3();
normalMatrix.getNormalMatrix(object.matrixWorld);
var vertices = new THREE.Vector3();
var verts = object.geometry.vertices;
var faces = object.geometry.faces;
var worldMatrix = object.matrixWorld;
for (var j = 0, jl = face.vertexNormals.length; j < jl; j++) {
var vertexId = face[ keys[ j ] ];
var vertex = verts[ vertexId ];
var normal = face.vertexNormals[ j ];
vertices.copy(vertex).applyMatrix4(worldMatrix);
v1.copy(normal).applyMatrix3(normalMatrix).normalize().multiplyScalar(size);
v1.add(vertices);
}
return v1;
};
答案 1 :(得分:0)
我已经学会了一些矢量数学,所以法线矢量位于正确的位置。当您需要垂直于相交面的光线交点处的点时,您需要将faceNormalVector与标量相乘,这将是面与新点之间的距离,然后将此新矢量添加到交点。 / p>
答案 2 :(得分:0)
我有一个同样的问题,就是不了解自己的正常面孔。对我来说,解决方案是将法线与对象的法线矩阵相乘(不知道这是一回事)。这是一个用typescript编写的简单帮助程序类,将其移植到javascript并不难:
import { Vector3, Object3D, Matrix3, Face3 } from 'three';
export class Face3Utils {
private static _matrix3: Matrix3;
private static get matrix3(): Matrix3 {
if(this._matrix3 === undefined) {
this._matrix3 = new Matrix3();
}
return this._matrix3;
}
public static getWorldNormal(face: Face3, object: Object3D, normalVector?: Vector3): Vector3 {
if(normalVector === null || normalVector === undefined) {
normalVector = new Vector3();
}
object.updateMatrixWorld( true );
Face3Utils.matrix3.getNormalMatrix( object.matrixWorld );
normalVector.copy(face.normal).applyMatrix3( Face3Utils.matrix3 ).normalize();
return normalVector;
}
}