【问题标题】:How can I determine if a point is obstructed from view?如何确定某个点是否被视线遮挡?
【发布时间】:2016-11-18 03:20:16
【问题描述】:

我正在粗略设计一个项目,该项目需要热点/注释出现在模型的不同部分;我正在使用 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

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

但我的解释不起作用,老实说,我不知道为什么。我以为我的光线投射器会从相机到热点,但它根本不会相交,但如果我取消投影并减去 camera.position,它有时会在一个点上起作用。

$.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,无法解决跨域问题。

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

【问题讨论】:

    标签: javascript three.js


    【解决方案1】:

    我想我已经解决了。我犯了两个主要错误,一个是我应该投射的时候没有投射,第二个是我的 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 时偶然发现的。因此,如果有人想解释我的解决方案,那就太好了。

    【讨论】:

      猜你喜欢
      • 2016-08-13
      • 1970-01-01
      • 2011-03-07
      • 1970-01-01
      • 2021-07-01
      • 2010-11-21
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      相关资源
      最近更新 更多