如何确定点是否被阻挡?

时间:2016-11-15 23:41:34

标签: javascript three.js

我正在粗略地讨论一个需要热点/注释出现在模型不同部分的项目;我正在使用THREE.Vector3将对象上的点的3D位置转换为2D以进行定位。

function createVector(x, y, z, r) {
    var p = new THREE.Vector3(x, y, z),
        vector = p.project(camera); 

    vector.x = (vector.x + 1) / 2 * $(window).width() - r;
    vector.y = -(vector.y - 1) / 2 * $(window).height() - r;

    return vector;
}

当我旋转和缩放时,这可以适当地定位它们,但是当它们的中心被遮挡时我想隐藏它们。我这样加载单个对象:

var mtlLoader = new THREE.MTLLoader();
mtlLoader.setBaseUrl('assets/');
mtlLoader.setPath('assets/');
mtlLoader.load('test.mtl', function (materials) {

    materials.preload();

    var objLoader = new THREE.OBJLoader();
    objLoader.setMaterials(materials);
    objLoader.setPath('assets/');
    objLoader.load('test.obj', function (object) {
        mesh = object;
        scene.add(object);
        objects.push( object );

    });

});

我找到了一些关于如何判断一个物体何时可见的答案,但只有一个关于一个点,这是一个关于性能的问题。

How to quickly find if a point is obscured in a complex scene?

// pos   = vector with (normalized) x, y coordinates on canvas
// dir   = vector from camera to target point

const raycaster = new THREE.Raycaster();
const d = dir.length(); // distance to point
let intersects = false;
raycaster.setFromCamera(pos, camera);
const intersections = raycaster.intersectObject(mesh, true);
if (intersections.length > 0 && intersections[0].distance < d)
    intersects = true;

// if ray intersects at a point closer than d, then the target point is obscured
// otherwise it is visible

性能对我来说不是一个问题,因为虽然我的模型很复杂,但我在更改期间隐藏了热点,然后在移动停止了四分之一秒后运行定位脚本。

但我的解释不起作用,说实话,我不知道为什么。我认为我的raycaster会从相机到热点,但它根本不会相交,但如果我取消投影并减去相机,它有时会工作一点。

$.each(annotations,function(k,v) {
    var v = annotations[k];
    nvectors[k] = new THREE.Vector3(v[0],v[1],v[2]);
    nvectors[k].unproject( camera );
    raycaster[k] = new THREE.Raycaster( camera.position, nvectors[k].sub(camera.position).normalize() );
    intersections[k] = raycaster[k].intersectObjects( objects, true );
    if (intersections[k].length > 0) {
    } else {
        $('a.annotation'+k).show();
    }
});

我在这里发布了一个完整的示例http://whatiknow.nicewebsite.info/,以显示模型。点0主要起作用,但点1根本不起作用(永远不会返回交叉点)。很抱歉,我没有发布到JSFiddle,无法解决跨域问题。

我的问题是,如何判断空间中的某个点何时被我的模型遮挡?

1 个答案:

答案 0 :(得分:0)

我想我已经把它整理出来了。我犯了两个主要的错误,一个是当我应该投射时我没有投射,第二个是我的Raycaster错了,我本应该使用setFromCamera。

使用WebGLRenderer 82:

$.each(annotations,function(k,v) {
    nvectors[k] = new THREE.Vector3(v[0],v[1],v[2]);

    nvectors[k].project( camera );

    raycaster[k] = new THREE.Raycaster();
    raycaster[k].setFromCamera( nvectors[k], camera );
    intersections[k] = raycaster[k].intersectObjects( objects, true );

    var dx = v[0] - camera.position.x;
    var dy = v[1] - camera.position.y;
    var dz = v[2] - camera.position.z;
    var d = (Math.sqrt( dx * dx + dy * dy + dz * dz ));
    if (intersections[k].length > 0 && intersections[k][0].distance < d) {
    } else {
        $('a.annotation'+k).show();
    }

});

老实说,我不明白它为什么会起作用,当我尝试并且未能过渡到Sprites时,我偶然发现了它。所以,如果有人想解释我的解决方案,那就太棒了。