【问题标题】:In the forge viewer I can add a new THREE.Object3D, but I can't select it in the viewer.在 forge 查看器中,我可以添加一个新的 THREE.Object3D,但我无法在查看器中选择它。
【发布时间】:2017-08-14 11:31:08
【问题描述】:

在 Forge Viewer 中,我编写了一个自定义处理程序。它有一个绑定的双击事件,当它与事件一起触发时,计算被点击的项目

const hitTest = this.viewer.clientToWorld(event.canvasX, event.canvasY, true);

对于普通的对象/网格/材质,可以正常工作,并返回 hitTest.dbId,加上一个 hitTest.point 对象指示我在 3D 空间中单击的位置。我使用该位置创建材质、网格和对象,然后添加到场景中。 (跳过了几个小步骤)

var material_orange = new THREE.MeshLambertMaterial({color: 0xFEBD17});
this.viewer.impl.matman().addMaterial('SBD-Material-' + 'orange', material_orange, true);
var sphereMesh =
         new THREE.Mesh(
                new THREE.SphereGeometry(niceRadius, 20),
                material_orange);
var sphereModel = new THREE.Object3D();
sphereModel.add(sphereMesh);
sphereModel.position.set(atPoint.x, atPoint.y, atPoint.z);

this.viewer.impl.scene.add(sphereModel);
this.viewer.impl.invalidate(true);

一切都很好。球体被添加到我的模型中。 (它是黑色的,我仍然无法弄清楚为什么......)但最大的问题是我无法点击球体。单击它会选择模型中的底层对象,通常是墙壁或地板。

是否需要使用 RayTrace 方法来获取场景中的对象?或者对象/网格/材质是否有一个属性可以使其可点击?观众更新?

【问题讨论】:

    标签: autodesk-forge


    【解决方案1】:

    此时,您必须创建一个继承Autodesk.Viewing.ToolInterface 的自有工具,并将您的点击逻辑放入handleSingleClick 函数中。下面是这个案例的一个例子:

    1. 自定义工具:

      class CustomTool extends Autodesk.Viewing.ToolInterface {
          constructor( viewer ) {
              super();
              this._viewer = viewer;
              this._active = false;
              this._names = [ 'CustomTool' ];
          }
      
          get viewer() {
              return this._viewer;
          }
      
          isActive() {
              return this._active;
          }
      
          handleSingleClick( event, button ) {
              const _viewer = this.viewer;
              const intersectObjects = (function () {
                  const pointerVector = new THREE.Vector3();
                  const pointerDir = new THREE.Vector3();
                  const ray = new THREE.Raycaster();
                  const camera = _viewer.impl.camera;
      
                  return function(pointer, objects, recursive) {
                      const rect = _viewer.impl.canvas.getBoundingClientRect();
                      const x = (( pointer.clientX - rect.left) / rect.width ) * 2 - 1;
                      const y = - (( pointer.clientY - rect.top) / rect.height ) * 2 + 1;
      
                      if (camera.isPerspective) {
                          pointerVector.set( x, y, 0.5 );
                          pointerVector.unproject( camera );
                          ray.set( camera.position, pointerVector.sub( camera.position ).normalize() );
                      } else {
                          pointerVector.set( x, y, -1 );
                          pointerVector.unproject( camera );
                          pointerDir.set( 0, 0, -1 );
                          ray.set( pointerVector, pointerDir.transformDirection( camera.matrixWorld ) );
                      }
      
                      const intersections = ray.intersectObjects( objects, recursive );
                      return intersections[0] ? intersections[0] : null;
                  };
              })();
      
              const pointer = event.pointers ? event.pointers[ 0 ] : event;
              // Intersect objects in the scene
              const result = intersectObjects( pointer, _viewer.impl.scene.children );
      
              if( result && result.object ) {
                  const mesh = result.object;
                  // Change object color
                  let curColor = mesh.material.color;
                  curColor = ( curColor.getHex() == 0xff0000 ? 0x00ff00 : 0xff0000 );
                  mesh.material.color.setHex( curColor );
      
                  // Refreah viewport
                  this.viewer.impl.invalidate( false, true, true );
              }
      
              return false;
          }
      }
      
    2. 查看器扩展管理此自定义工具:

      class CustomToolExtension extends Autodesk.Viewing.Extension {
          constructor( viewer, options ) {
              super( viewer, options );
              this._tool = undefined;
          }
      
          load() {
              // Construct an custom Tool instance
              this._tool = new CustomTool( this.viewer );
              // Register custom Tool into viewer.toolController
              this.viewer.toolController.registerTool( this._tool );
              // Activate the Tool
              this.viewer.toolController.activateTool( 'CustomTool' );
      
              return true;
          }
      
          unload() {
              // If tool has been activated, deactivate the tool.
              if( this._tool.isActive() ) {
                  this.viewer.toolController.deactivateTool( 'CustomTool' );
              }
             // Deregister custom Tool 
              this.viewer.toolController.deregisterTool( this._tool );
      
              return true;
          }
      }
      
      Autodesk.Viewing.theExtensionManager.registerExtension( 'Autodesk.ADN.Sample.CustomToolExtension', CustomToolExtension );
      

    希望对您有所帮助。

    【讨论】:

    • 您能告诉我们,CustomTool 类是如何将 Autodesk.Viewing.ToolInterface 作为其接口进行扩展的吗?
    • 在 JavaScript 中,没有接口,Autodesk.Viewing.ToolInterface 是一个预定义的对象 (ref) 作为查看器工具的基类。你可以直接创建类似CustomTool 的东西,不要扩展Autodesk.Viewing.ToolInterface
    猜你喜欢
    • 2023-03-06
    • 2019-10-31
    • 2021-12-06
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 2020-05-28
    • 2019-02-12
    • 2018-07-16
    相关资源
    最近更新 更多