three.js - 动态修改几何后,ray.interstectObjects 未正确相交

标签 three.js

在我动态修改对象的几何形状之前,我的 ray.intersectObjects 与场景中的对象配合得非常好。尽管渲染器将对象显示为正在修改(移动顶点和更改面),但在修改后的对象上尝试相交时,会产生奇怪的结果。即使在修改后的几何体上,我也需要相交!

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

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

显示问题的方向:

  1. 左键单击立方体以显示交点。只要 Three.js 看到相交,就会创建迷你球体。如果尚未选中,所选对象的颜色将变为黄色。

  2. 点击立方体的任意面。这将 A. 如果它还不是黄色,则将其变成黄色。 B. 它将选择立方体的面,尽管所选面看起来与立方体的其余部分没有任何不同。

  3. 按“向右”箭头键将所选面向右移动。这将动态改变立方体的几何形状。

现在试着点击立方体——尤其是在它被修改的区域。迷你球体将再次显示软件认为相交发生的位置。

这是相交代码:

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;
}

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

更新 (3/21/13)——我已按照建议迁移到 r57,更新后的代码如上所示。我还对其进行了调试,以便它至少可以像以前一样工作。所以现在几何图形仍然在视觉上动态变化,但是相交没有正确检测到变化。感谢@WestLangley 到目前为止令人鼓舞的帖子。

最佳答案

现在工作正常。以下是我的做法(感谢 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();

关于three.js - 动态修改几何后,ray.interstectObjects 未正确相交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15512089/

相关文章:

javascript - three.js中的透明阴影

three.js - 与平面相交的任意网格(在 THREEJS 中)

javascript - Three.js 碰撞并移除碰撞对象

html - 将一个动画maya模型转成json,配合三个js使用

javascript - 如何使用键盘拉伸(stretch)和压缩立方体的长宽高?

canvas - Three.js Canvas 渲染和透明度

javascript - 将 THREE.js 着色器转换为 PIXI.js

javascript - Three.js materialLoader 不加载嵌入的纹理图像

javascript - Angular或Three.js不是从服务器提取图像,而是从浏览器缓存中提取图像

javascript - 三、不同 Material 和定向光强的JS线