在动态修改几何体后,ray.interstectObjects未正确相交

时间:2013-03-19 22:55:10

标签: three.js

我的ray.intersectObjects可以很好地处理场景中的对象,直到我动态修改对象的几何体。虽然渲染器将对象显示为已修改(顶点移动并且面更改),但是当对修改的对象尝试交叉时,它会产生奇怪的结果。我需要相交才能在修改过的几何体上工作!

为了帮助调试和跟踪交叉在我的场景中的工作方式,我添加了一个函数:makeMiniSphere()。这会在场景中发生交叉点时生成新的球体对象。使用它,您可以看到修改立方体后,有时交叉点击立方体,有时它会直接通过(主要是已修改的面)。这不是一个随机问题,但是您在修改后的多维数据集周围点击的次数越多,您就越能看到模式的发展。几乎就像场景视觉效果的渲染器知道多维数据集被修改的方向一样,但是ray.intersectObjects认为它已被修改为不同的方向!

以下是测试网站的链接:http://www.littledrop.net/html/cadiverse/HelloWorld.html

显示问题的说明:

  1. 左键单击立方体以显示交叉点。在Three.js看到相交的任何地方都会创建迷你球体。如果尚未选择,则所选对象的颜色将变为黄色。

  2. 单击多维数据集的任何面。这将A.如果它还不是黄色,则将其变为黄色。 B.它将选择立方体的面,尽管选定的面看起来与立方体的其余部分没有任何不同。

  3. 按“向右”箭头键将所选面向右移动。这将动态更改多维数据集的几何形状。

  4. 现在尝试单击多维数据集 - 尤其是在已修改的区域中。 Mini球体将再次显示软件认为交叉点发生的位置。

    以下是交叉代码:

    function onDocumentMouseDown (event)
    {
    // the following line would stop any other event handler from firing
    // (such as the mouse's TrackballControls)
    //event.preventDefault();   
    mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
    document.getElementById('message1').innerHTML = window.innerHeight;
    var isinworkingarea = window.innerHeight-menubarh;
    
    if (event.clientY<=isinworkingarea)
    {
        var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
        projector.unprojectVector( vector, camera );
        //var ray = new THREE.ReusableRay();
        var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
        // create an array containing all objects in the scene with which the ray intersects
        //  use this to select anything in the scene: 
        var intersects = ray.intersectObjects( scene.children );
        if ( intersects.length > 0 )
        {
            if (cadjectNow)
                cadjects[cadjectNow].material.color.setHex(cadjects[cadjectNow].oldColor);
            if (intersects[0].object.cadNum)                                                
                cadjectNow = intersects[0].object.cadNum;
            SELECTEDface=intersects[0].face;
            if (cadjectNow)
                cadjects[cadjectNow].material.color.setHex( selectColor );
            document.getElementById('message1').innerHTML = cadjects[cadjectNum].cadNum;
    
            ///// Information about selected /////
            var facestring = intersects[0].face.a  + " " + intersects[0].face.b + " " + intersects[0].face.c;
            if(intersects[0].face instanceof THREE.Face4) 
            {
                facestring=facestring + " " + intersects[0].face.d;
            }
    
            copyGeometry=cadjects[cadjectNow].geometry;
            //makeCopy(copyGeometry,cadjects[cadjectNow].position.x,cadjects[cadjectNow].position.y,cadjects[cadjectNow].position.z);
            makeMiniSphere(intersects[0].point.x, intersects[0].point.y, intersects[0].point.z);
    
            document.getElementById('message1').innerHTML = facestring;
            //document.getElementById('message2').innerHTML = cadjects[cadjectNow].geometry.vertices[SELECTEDface.a].x + " " + cadjects[cadjectNow].geometry.vertices[intersects[0].face.a].y + " " + cadjects[cadjectNow].geometry.vertices[intersects[0].face.a].z;
            document.getElementById('message2').innerHTML = intersects[0].point.x + " " + intersects[0].point.y + " " + intersects[0].point.z;
    
        }
    }
    }
    

    以下是修改代码:

    if ( keyboard.pressed("right"))
    {
        document.getElementById('message1').innerHTML = mouseMode;
        cadjects[cadjectNow].geometry.vertices[SELECTEDface.a].x+=10;
        cadjects[cadjectNow].geometry.vertices[SELECTEDface.b].x+=10;
        cadjects[cadjectNow].geometry.vertices[SELECTEDface.c].x+=10;
        if(SELECTEDface instanceof THREE.Face4) 
        {
            cadjects[cadjectNow].geometry.vertices[SELECTEDface.d].x+=10;
        }
        cadjects[cadjectNow].geometry.verticesNeedUpdate = true;
        cadjects[cadjectNow].geometry.elementsNeedUpdate = true;
        cadjects[cadjectNow].geometry.normalsNeedUpdate = true;
    }
    

    感谢所有发布过去问题并给出答案的人。通过仔细阅读过去的问题,我已经能够做到这一点 - 所以你们已经得到了很大的帮助。在此先感谢您的帮助。 (因为这是我在这里发布的第一个问题,关于如何更好地提出问题的任何建议也非常受欢迎。)

    更新(2013年3月21日) - 我按照建议迁移到r57,上面显示了更新的代码。我也调试了它,它至少和以前一样好。所以现在几何体仍然在视觉上动态地改变,但是交叉点没有正确地检测到变化。感谢@WestLangley到目前为止令人鼓舞的帖子。

2 个答案:

答案 0 :(得分:7)

现在正常工作。我是这样做的(感谢Westlangley的指导)。

  1. 将Three.js升级到最新版本(来自r49的r57)。
  2. 迁移我现有的代码以使用r57。
  3. 删除所有尝试更新对象的旧代码。
  4. 在“修改对象”部分添加了以下代码:

    cadjects [cadjectNow] .geometry.verticesNeedUpdate = true; cadjects [cadjectNow] .geometry.normalsNeedUpdate = true; cadjects [cadjectNow] .geometry.computeFaceNormals(); cadjects [cadjectNow] .geometry.computeVertexNormals(); cadjects [cadjectNow] .geometry.computeBoundingSphere();

答案 1 :(得分:1)

我在修改BufferGeometry时遇到类似的问题。

用顶点位置修改数组后,我通过调用geometry.computeBoundingSphere()geometry.computeBoundingBox()进行了光线投射。

不需要设置verticesNeedUpdate

运行r112。