所以,我使用RayCaster
来解决问题TextGeometry
。我使用下面的函数createText()
将此文本呈现在画布上。这工作正常,它显示,它甚至将它添加到网格数组中RayCaster
它检查交集,但是,函数HandleSingleClick()
由于某种原因没有在TextGeometries上触发。
我已经测试过使用立方体,它确实有效。目的是如果单击TextGeometry,它会更改颜色以表示您单击它。但是,出于某种原因,以下脚本在文本方面不起作用。我可以确认网格正被添加到RayCaster检入的数组中,但是由于某种原因它没有被拾取。
import {
Font,
TextGeometry
} from '../js/libs/Three.es.js';
import FontJson from '../fonts/helvetiker_bold.typeface.json';
export default class TextExtension extends Autodesk.Viewing.Extension {
constructor(viewer, options) {
super()
this.viewer = viewer
}
load() {
console.log('Viewing.Extension.MeshSelection loaded')
this.viewer.addEventListener(
Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT, () => {
this.dbIds = this.getAllDbIds()
console.log(this.dbIds);
});
this.viewer.toolController.registerTool(this)
this.viewer.toolController.activateTool(
'MeshSelection')
this.intersectMeshes = [];
return true
}
/////////////////////////////////////////////////////////
// Tool Interface
//
/////////////////////////////////////////////////////////
getNames() {
return ['MeshSelection']
}
activate() {
}
deactivate() {
}
/////////////////////////////////////////////////////////
// Unload callback
//
/////////////////////////////////////////////////////////
unload() {
console.log('MeshSelection unloaded')
this.viewer.toolController.deactivateTool(
'MeshSelection')
this.viewer.toolController.unregisterTool(this)
return true
}
/////////////////////////////////////////////////////////
// Adds a box mesh with random size and position
// to the scene
//
/////////////////////////////////////////////////////////
addMesh() {
const geometry = new THREE.BoxGeometry(
Math.random() * 10 + 5.0,
Math.random() * 10 + 5.0,
Math.random() * 10 + 5.0)
const color = Math.floor(Math.random() * 16777215)
const material = this.createColorMaterial(color)
const mesh = new THREE.Mesh(geometry, material)
mesh.position.x = -50 + Math.random() * 25
mesh.position.y = -50 + Math.random() * 25
mesh.position.z = 1 + Math.random() * 1
this.viewer.impl.scene.add(mesh)
this.viewer.impl.sceneUpdated(true)
return mesh
}
/////////////////////////////////////////////////////////
// Creates color material from int
//
/////////////////////////////////////////////////////////
createColorMaterial(color) {
const material = new THREE.MeshPhongMaterial({
specular: new THREE.Color(color),
side: THREE.DoubleSide,
reflectivity: 0.0,
color
})
const materials = this.viewer.impl.getMaterials()
materials.addMaterial(
color.toString(16),
material,
true)
return material
}
/////////////////////////////////////////////////////////
// Creates Raycaster object from the pointer
//
/////////////////////////////////////////////////////////
pointerToRaycaster(domElement, camera, pointer) {
const pointerVector = new THREE.Vector3()
const pointerDir = new THREE.Vector3()
const ray = new THREE.Raycaster()
const rect = domElement.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))
}
return ray
}
/////////////////////////////////////////////////////////
// Click handler
//
/////////////////////////////////////////////////////////
handleSingleClick(event) {
console.log(this.intersectMeshes);
const pointer = event.pointers ?
event.pointers[0] :
event
console.log(pointer);
const rayCaster = this.pointerToRaycaster(
this.viewer.impl.canvas,
this.viewer.impl.camera,
pointer)
const intersectResults = rayCaster.intersectObjects(
this.intersectMeshes, true)
console.log(intersectResults);
const hitTest = this.viewer.model.rayIntersect(
rayCaster, true, this.dbIds)
const selections = intersectResults.filter((res) =>
(!hitTest || (hitTest.distance > res.distance))
)
if (selections.length) {
console.log('Custom meshes selected:')
console.log(selections)
selections[0].object.material.color = this.createColorMaterial(Math.floor(Math.random() * 16777215));
viewer.impl.sceneUpdated(true);
return true
}
return false
}
/////////////////////////////////////////////////////////
// Get list of all dbIds in the model
//
/////////////////////////////////////////////////////////
getAllDbIds() {
const {
instanceTree
} = this.viewer.model.getData()
const {
dbIdToIndex
} = instanceTree.nodeAccess
return Object.keys(dbIdToIndex).map((dbId) => {
return parseInt(dbId)
})
}
createColorMaterial(color) {
const material = new THREE.MeshPhongMaterial({
specular: new THREE.Color(color),
side: THREE.DoubleSide,
reflectivity: 0.0,
color
})
const materials = this.viewer.impl.getMaterials()
materials.addMaterial(
color.toString(),
material,
true)
return material
}
/////////////////////////////////////////////////////////
// Wraps TextGeometry object and adds a new mesh to
// the scene
/////////////////////////////////////////////////////////
createText(params, index) {
const geometry = new TextGeometry(params.text,
Object.assign({}, {
font: new Font(FontJson),
params
}))
geometry.computeBoundingBox();
const material = this.createColorMaterial(
params.color)
const text = new THREE.Mesh(
geometry, material)
text.scale.set(params.scale, params.scale, params.scale);
text.position.set(
params.position.x,
params.position.y,
10)
this.intersectMeshes[index] = text;
this.viewer.impl.scene.add(text);
this.viewer.impl.sceneUpdated(true)
}
}
Autodesk.Viewing.theExtensionManager.registerExtension(
'TextSpawner', TextExtension);
答案 0 :(得分:0)
您需要调试光线投射逻辑以找出正在发生的事情。在查看器使用的Three.js版本中,有一个chech来查看测试网格中的几何对象是否为实例THREE.BufferGeometry或THREE.Geometry,如果没有计算交集逻辑。
为了在添加尽可能少的代码时使其与之兼容,我使用了以下方法:
/////////////////////////////////////////////////////////
// Wraps TextGeometry object and adds a new mesh to
// the scene
/////////////////////////////////////////////////////////
createText (params) {
const textGeometry = new TextGeometry(params.text,
Object.assign({}, {
font: new Font(FontJson),
params
}))
// use a geometry recognized by the viewer
// THREE.js version
const geometry = new THREE.BufferGeometry
geometry.fromGeometry(textGeometry)
const material = this.createColorMaterial(
params.color)
const text = new THREE.Mesh(
geometry , material)
text.position.set(
params.position.x,
params.position.y,
params.position.z)
this.viewer.impl.scene.add(text)
this.viewer.impl.sceneUpdated(true)
return text
}