2017-01-23 100 views
0

我一直在尝试对我在THREE.Scene中添加的对象执行光线投射,作为viewer.impl.sceneAfter提供(我已将此link作为教程用于添加支持透明度的对象)。在Autodesk Forge查看器中对Three.JS Object3D网格进行光线投射

为链接的文件规定:

不幸的是这有一个副作用:本地观众选择机制必须处理没有预计的属性网格。

它可以修复,但您可能需要编辑查看器的代码并加载自定义版本,请参阅下面的修复(viewer3D.js#L21962)。另一种选择是以与观看者相同的方式创建自定义几何体,以便它可以参与选择,但可能更多的工作。如果你有更好的修复,我很高兴听到它...

起初,我已经添加了,当我进行一个单一的点击动作这给了我一个错误定期THREE.Object3Ds:

wgs.js:1889 Uncaught TypeError: Cannot read property 'index' of undefined

我相信这是从观众的meshRayCast功能:

function meshRayCast(mesh, raycaster, intersects) { 

    init_three(); 

    var geometry = mesh.geometry; 

    if (!geometry) 
     return; 

    var material = mesh.material; 

    var side = material ? material.side : THREE.FrontSide; 

    var attributes = geometry.attributes; 

    inverseMatrix.getInverse(mesh.matrixWorld); 
    ray.copy(raycaster.ray).applyMatrix4(inverseMatrix); 

    var a, b, c, i, j, il; 
    var precision = raycaster.precision; 
    var positions, stride, intersectionPoint, distance; 

    if (attributes.index !== undefined) { <----RIGHT HERE 

从源代码中,我注意到,欧特克浏览器预计THREE.BufferGeometry,而不是常规几何形状,所以我利用BufferGeometries,已经摆脱了错误的上方singleClick创建Object3Ds测试,但它仍然不支持光线投射,即使我的自定义raycaster:

class SceneSelector { 
    constructor(viewer){ 
    this.raycaster = new THREE.Raycaster(); 
    this.viewer= viewer; 
    } 

    selectByType(type,vectorXY){ 
    const camera = this.viewer.getCamera(); 
    const direction = new THREE.Vector3(); 
    const pointerDir = new THREE.Vector3(); 

    if(camera.isPerspective){ 
     direction.set(vectorXY.x,vectorXY.y,0.5); 
     direction.unproject(camera); 
     this.raycaster.set(camera.position, 
         direction.sub(camera.position).normalize()); 
    } else { 
     direction.set(vectorXY.x,vectorXY.y,-1); 
     direction.unproject(camera); 
     this.raycaster.set(direction, 
         pointerDir.transformDirection(camera.matrixWorld)); 
    } 
    const filteredObjects = this.viewer.impl.sceneAfter.children.filter(obj=>{ 
     return obj.type == type; 
    }); 
    const intersects = this.raycaster.intersectObjects(filteredObjects,true); 
    return intersects ? intersects[0] : null; 
    } 
}; 

我测试过各种其他观众提供的光线投射功能,由link提供,这对我不起作用。

(总之)我的问题是:

  1. 有没有我可以执行光线投射在THREE.SceneAfter添加对象的任何方式?

  2. 看起来link表明我创建自定义几何的方式与查看器相同。有没有这方面的参考?

在此先感谢。

回答

1

自定义网格上的光线投射在我身边效果很好,所以请看看我的RotateTool。它使用重叠场景,我尝试在自定义网格上设置透明度,这很好。在下面的代码,如果我通过sceneAfter更换覆盖,它也工作正常,我可以使用raycaster小控件检测鼠标点击:

createGizmo (center, euler, size, radius, color, range, axis) { 

    var material = new GizmoMaterial({ 
     color: color 
    }) 

    var subMaterial = new GizmoMaterial({ 
     color: color 
    }) 

    var torusGizmo = new THREE.Mesh(
     new THREE.TorusGeometry(
     radius, size, 64, 64, range), 
     material) 

    var subTorus = new THREE.Mesh(
     new THREE.TorusGeometry(
     radius, size, 64, 64, 2 * Math.PI), 
     subMaterial) 

    subTorus.material.highlight(true) 

    var transform = new THREE.Matrix4() 

    var q = new THREE.Quaternion() 

    q.setFromEuler(euler) 

    var s = new THREE.Vector3(1, 1, 1) 

    transform.compose(center, q, s) 

    torusGizmo.applyMatrix(transform) 

    subTorus.applyMatrix(transform) 

    var plane = this.createBox(
     this.size * 100, 
     this.size * 100, 
     0.01) 

    plane.applyMatrix(transform) 

    subTorus.visible = false 

    //this.viewer.impl.addOverlay(
    // this.overlayScene, torusGizmo) 
    // 
    //this.viewer.impl.addOverlay(
    // this.overlayScene, subTorus) 

    this.viewer.impl.sceneAfter.add(torusGizmo) 
    this.viewer.impl.sceneAfter.add(subTorus) 

    torusGizmo.subGizmo = subTorus 
    torusGizmo.plane = plane 
    torusGizmo.axis = axis 

    return torusGizmo 
    } 

希望帮助

+0

非常感谢。我能解决这个问题。 – MazaYong

+0

Sweet .... :)! –