Three.js raycaster交叉点对象返回奇怪的面部法线

时间:2015-04-08 09:11:08

标签: javascript three.js

我有一个与我的raycaster相交的模特女巫。 raycaster返回正确的点,但是脸部法线向量不是我正在等待的。 Three.js内置了VertexNormalsHelper,当我使用它显示正确的法线时,但是当我创建两个立方体时,一个将位于交叉点的位置,另一个将位于法线向量,它将如下所示:

enter image description here

红色立方体是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打开时的图像,因此您可以看到法线正常:

enter image description here

3 个答案:

答案 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;
    }
}