我想完成一个可以在 Three.js 中完成但不能在 Autodesk Forge 查看器中完成的功能。这是测试的链接:http: //app.netonapp.com/JavaScript/Three.js/select_inner_objects.html
要求是选择对象内的对象。这项工作可以在上面的演示中使用 THREE.Raycaster 来完成,使用 raycaster 来检测光线通过线上的所有元素。然后我可以在另一个对象后面或内部获取对象。
我在 Autodesk Forge 查看器中尝试了这个概念,但没有成功。这是代码:
// Change this to:
// true to use original Three.js
// false to use Autodesk Forge Viewer API
var useThreeJS = true;
var container = $('div.canvas-wrap')[0];
container.addEventListener('mousedown', function (event) {
if (useThreeJS) {
var canvas = _viewer.impl.canvas;
var containerWidth = canvas.clientWidth;
var containerHeight = canvas.clientHeight;
var camera = _viewer.getCamera();
var mouse = mouse || new THREE.Vector3();
var raycaster = raycaster || new THREE.Raycaster();
mouse.x = 2 * (event.clientX / containerWidth) - 1;
mouse.y = 1 - 2 * (event.clientY / containerHeight);
mouse.unproject(camera);
raycaster.set(camera.position, mouse.sub(camera.position).normalize());
var intersects = raycaster.intersectObjects(objects);
if (intersects.length == 1) {
var obj = intersects[0].object;
obj.material.color.setRGB(1.0 - i / intersects.length, 0, 0);
} else if (intersects.length > 1) {
// Exclude the first which is the outer object (i == 0)
for (var i = 1; i < intersects.length; i++) {
var obj = intersects[i].object;
obj.material.color.setRGB(1.0 - i / intersects.length, 0, 0);
}
}
} else {
var vp = _viewer.impl.clientToViewport(event.canvasX, event.canvasY);
var renderer = _viewer.impl.renderer();
var dbId = renderer.idAtPixel(vp.x, vp.y);
if (dbId) {
console.debug("Selected Id: " + dbId);
_viewer.select(dbId);
_viewer.impl.invalidate(true);
}
}
}, false);
我发现 Forge 查看器的viewer.impl.renderer().idAtPixel
方法非常适合在拾取像素处获取元素。但是,我希望它做更多的事情,在拾取像素处选择所有元素(在下面或嵌套)。如何使用 Forge Viewer API 做到这一点?