【问题标题】:How to determine if plane is in Three.js camera Frustum如何确定平面是否在 Three.js 相机 Frustum 中
【发布时间】:2019-02-19 00:14:35
【问题描述】:

如果飞机在相机的视锥体内,我很难创建一个返回 true 的函数。我找到了这篇文章,on github,但无论对象是否在截锥体中,配方总是返回 false。

有人已经智能地实现了这一点吗?非常感谢。

【问题讨论】:

    标签: three.js


    【解决方案1】:

    也许矩阵没有更新?

    camera.updateMatrix(); // make sure camera's local matrix is updated
    camera.updateMatrixWorld(); // make sure camera's world matrix is updated
    camera.matrixWorldInverse.getInverse( camera.matrixWorld );
    
    plane.updateMatrix(); // make sure plane's local matrix is updated
    plane.updateMatrixWorld(); // make sure plane's world matrix is updated
    
    var frustum = new THREE.Frustum();
    frustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ) );
    alert( frustum.contains( plane ) );
    

    【讨论】:

    • 我想知道截锥体是否包含整个立方体,但使用此方法不起作用...我可以使用什么方法? (我在documentation 中没有看到任何列表)
    • 您可以在该时间点拍摄对象的画布快照,以获得对象的平面透视图。找到构成该多边形快照的线。您已经知道相机 frutum 矩阵的坐标。现在你有一个多边形内部,或另一个多边形的外部/重叠。使用“多边形中的多边形”检测算法,即扫描线算法来获得您需要的东西!
    • @mrdoob 为什么不按照以下答案中的建议添加道具“inFrustum”?这样我们就可以使用上一帧的截锥体测试状态,而无需重新计算。
    【解决方案2】:

    如果我错了,请纠正我,但为什么要计算第二次截锥体?

    我正在处理一个复杂的项目,而接受的答案对我来说并不是最佳解决方案。我认为没有必要重新计算 aleady 的计算结果。出于我的目的,我修改了我的 three.js 的副本,如果在截锥体中检测到某些东西,我会提出一个标志。稍后只需检查您的对象是否 object.inFrustum === true

    下面一行

    if ( webglObjects && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {
    

    添加

    object.inFrustum = true;
    

    还在 if 块结束的地方添加一个相反的标志

    else {
        object.inFrustum = false;
    }
    

    我在 r70 中的最终结果完美运行:

    if ( webglObjects && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {
    
        object.inFrustum = true; // The line to add
    
        for ( var i = 0, l = webglObjects.length; i < l; i ++ ) {
    
            var webglObject = webglObjects[i];
    
            unrollBufferMaterial( webglObject );
    
            webglObject.render = true;
    
            if ( _this.sortObjects === true ) {
    
                _vector3.setFromMatrixPosition( object.matrixWorld );
                _vector3.applyProjection( _projScreenMatrix );
    
                webglObject.z = _vector3.z;
    
            }
    
        }
    
    } else { // Create second condition like that
        object.inFrustum = false;
    }
    

    【讨论】:

    • 您是否尝试过提出问题或为此创建 PR?这超级有用!
    • @hpalu 谢谢,但我认为它取决于相机,并且在对象上设置时可能被认为过于宽泛。也许该参数应该称为“inPreviousFrameFrustum”。我的三个 repo 分支中有很多小变化,我真的应该开始做一些 PR
    猜你喜欢
    • 2013-09-20
    • 2018-03-01
    • 1970-01-01
    • 2016-04-24
    • 2012-07-21
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 2019-03-20
    相关资源
    最近更新 更多