Three.js raycaster 相交对象 returns 奇怪的面法线
Three.js raycaster intersection object returns strange face normals
我有一个模型 与我的 raycaster 相交。 raycaster returns 正确的点,但面部法线向量不是我正在等待的。 Three.js 内置了 VertexNormalsHelper,当我使用它时它会显示正确的法线,但是当我创建两个立方体时,一个将位于交点位置,另一个将位于法向量处,就像这个:
红色立方体是raycaster交点,蓝色立方体是面法线
我的代码很简单,只是一个简单的光线投射器,我将点的位置复制到立方体。当我加载我的模型时,我会更新几何上的所有内容。我使用 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 时的图像,因此您可以看到此处的法线正常:
我已经阅读了 VertexNormalsHelper 的源代码,并从中创建了一个函数,它可以为您提供面的法向量。所以它可以告诉你这一点,但我认为这不是主要问题的真正解决方案,而且它有很多操作。
代码如下:
(对象: THREE.Mesh,
脸: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;
};
我学过一些向量数学,所以法向量在正确的位置。当你需要在垂直于相交面的光线交点处的一个点时,你需要将 faceNormalVector 乘以一个标量,这将是面和新点之间的距离,然后将这个新向量添加到交点。
我有同样的问题,就是不理解我得到的正常面孔。我的解决方案是将法线与对象的法线矩阵相乘(不知道那是一回事)。这是一个用 typescript 编写的简单助手 class,将其移植到 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;
}
}
我有一个模型 与我的 raycaster 相交。 raycaster returns 正确的点,但面部法线向量不是我正在等待的。 Three.js 内置了 VertexNormalsHelper,当我使用它时它会显示正确的法线,但是当我创建两个立方体时,一个将位于交点位置,另一个将位于法向量处,就像这个:
红色立方体是raycaster交点,蓝色立方体是面法线
我的代码很简单,只是一个简单的光线投射器,我将点的位置复制到立方体。当我加载我的模型时,我会更新几何上的所有内容。我使用 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 时的图像,因此您可以看到此处的法线正常:
我已经阅读了 VertexNormalsHelper 的源代码,并从中创建了一个函数,它可以为您提供面的法向量。所以它可以告诉你这一点,但我认为这不是主要问题的真正解决方案,而且它有很多操作。
代码如下:
(对象: THREE.Mesh, 脸: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;
};
我学过一些向量数学,所以法向量在正确的位置。当你需要在垂直于相交面的光线交点处的一个点时,你需要将 faceNormalVector 乘以一个标量,这将是面和新点之间的距离,然后将这个新向量添加到交点。
我有同样的问题,就是不理解我得到的正常面孔。我的解决方案是将法线与对象的法线矩阵相乘(不知道那是一回事)。这是一个用 typescript 编写的简单助手 class,将其移植到 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;
}
}