在 Forge 查看器中,我可以添加一个新的 THREE.Object3D,但我不能在查看器中 select 它。
In the forge viewer I can add a new THREE.Object3D, but I can't select it in the viewer.
在 Forge Viewer 中,我编写了一个自定义处理程序。它有一个绑定的双击事件,当它触发该事件时,计算被点击的项目
const hitTest = this.viewer.clientToWorld(event.canvasX, event.canvasY, true);
对于正常的 object/mesh/material,它工作正常,返回 hitTest.dbId,加上一个 hitTest.point 对象指示我在 3D space 中单击的位置。我使用该位置创建一个 material、网格和对象,然后添加到场景中。 (跳过了几个小步骤)
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 方法来获取场景中的对象?或者是否有 属性 到 object/mesh/material 使其可点击?查看器更新?
此时,您必须创建一个继承Autodesk.Viewing.ToolInterface
的自有工具,并将您的点击逻辑放在handleSingleClick
函数中。这是这种情况的示例:
自定义工具:
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;
}
}
查看器扩展管理此自定义工具:
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 );
希望对您有所帮助。
在 Forge Viewer 中,我编写了一个自定义处理程序。它有一个绑定的双击事件,当它触发该事件时,计算被点击的项目
const hitTest = this.viewer.clientToWorld(event.canvasX, event.canvasY, true);
对于正常的 object/mesh/material,它工作正常,返回 hitTest.dbId,加上一个 hitTest.point 对象指示我在 3D space 中单击的位置。我使用该位置创建一个 material、网格和对象,然后添加到场景中。 (跳过了几个小步骤)
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 方法来获取场景中的对象?或者是否有 属性 到 object/mesh/material 使其可点击?查看器更新?
此时,您必须创建一个继承Autodesk.Viewing.ToolInterface
的自有工具,并将您的点击逻辑放在handleSingleClick
函数中。这是这种情况的示例:
自定义工具:
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; } }
查看器扩展管理此自定义工具:
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 );
希望对您有所帮助。