找到一条线,然后它消失 - three.js

时间:2015-07-06 11:50:02

标签: camera three.js position line particles

我想在我场景中的轴上放置x,y,z标签(精灵)。问题是使用相机进行变焦,也会导致类似地移动粒子,使它们停留在“屏幕”的一侧。

所以我只是想找到一种方法来始终知道x,y,z的线条在相机之外的位置以更新标签的位置: fiddle(这里它们只是静态的)。

我可能需要的伪代码:

    function update() { 
      var pointInLinePosition = calculateLastVisiblePointOfXline();
      xSprite.position.set(pointInLinePosition.x, pointInLinePosition.y, pointInLinePosition.z);
    }

    function calculateLastVisiblePointOfXline(){
    } 

2 个答案:

答案 0 :(得分:0)

我找到了一个足够令人满意的解决方案(至少对我而言)但并不完美。

首先,我使用场景的相机创建了一个平截头体:

var frustum = new THREE.Frustum();
frustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse ) );

然后,我检查平截头体的任何平面是否与场景中的任何线相交:

for (var i = frustum.planes.length - 1; i >= 0; i--) { 

      var py = frustum.planes[i].intersectLine( new THREE.Line3( new THREE.Vector3(0,0,0), new THREE.Vector3(1000,0,0) ) ) ; 
      if(py !== undefined) {
        ySprite.position.x = py.x-1 ;  
      }

      var px = frustum.planes[i].intersectLine( new THREE.Line3( new THREE.Vector3(0,0,0), new THREE.Vector3(0,0,1000) ) ) ; 
      if(px !== undefined) {
        xSprite.position.z = px.z-1 ; 
      }

    };

如果有交叉点,我使用intersectLine()的返回值来更新标签的位置.trossLine()是交点。

这是更新的小提琴:fiddle

我希望有所帮助。在我的情况下它适合。

答案 1 :(得分:0)

交叉路口的正确测试还必须确保交叉点实际上在截头锥体内,因为截头锥体平面无限延伸,可能导致假阳性交叉点。

验证交叉口的一种天真的方法是检查交叉点到所有平面的距离。如果距离大于或等于零,则该点在平截头体内。

调整后的代码是从ThanosSar的答案中删除的:

const intersect = point => frustum.planes
    .map(plane =>
        plane.intersectLine(new THREE.Line3(new THREE.Vector3(0, 0, 0), point))
    )
    .filter(sect => sect != null)
    .filter(sect => frustum.planes.every(plane => plane.distanceToPoint(sect) >= -0.000001))[0];

const iy = intersect(new THREE.Vector3(1000, 0, 0));
if (iy != null)
    ySprite.position.x = iy.x - 1;

const ix = intersect(new THREE.Vector3(0, 0, 1000));
if (ix != null)
    xSprite.position.z = ix.z - 1;

(与>= -0.000001进行比较以解决浮点舍入错误)

Fiddle