我的项目有问题。 我使用three.interaction来获取某些对象的click事件,并向其添加transformControls。
问题在于:我认为转换控件会阻止其他对象中的click事件,因为它会阻止raycast。
一些解决方案?
var camera, scene, renderer;
var geometry, material, mesh;
var transformControls;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
camera.position.z = 1;
scene = new THREE.Scene();
geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
material = new THREE.MeshNormalMaterial();
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const interaction = new THREE.Interaction(renderer, scene, camera);
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
mesh.on('click', function (ev) {
click(ev);
});
mesh1 = new THREE.Mesh( geometry, material );
scene.add( mesh1 );
mesh1.position.set(0.3, 0, 0);
mesh1.on('click', function (ev) {
click(ev);
});
}
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
function render() {
renderer.render(scene, camera);
}
function click(ev){
console.log("click");
var transformControls = scene.getObjectByName("transformControls", true);
var objControlled = scene.getObjectByName("objControlled", true);
if (transformControls === undefined || transformControls === null) {
transformControls = new THREE.TransformControls(camera, renderer.domElement);
transformControls.addEventListener('change', render);
transformControls.name = "transformControls";
scene.add(transformControls);
}
if (objControlled === undefined || objControlled === null) {
try {
transformControls.attach(ev.data.target);
ev.data.target.name = "objControlled";
}
catch (err) {
console.log(err);
}
}
else {
try {
transformControls.detach(objControlled);
objControlled.name = "oldControlled";
transformControls.attach(ev.data.target);
ev.data.target.name = "objControlled";
}
catch (err) {
console.log(err);
}
}
}
答案 0 :(得分:1)
您不需要扩展名THREE.Interaction
即可获得所需的行为。
可以轻松获得结果,将事件侦听器绑定到画布并自己管理射线广播。我可能会说它比使用所述扩展程序还要容易。
通过这种方式,您可以控制要让raycast检查相交的对象。
将对象添加到组实例中,以限制要进行射线投射的对象。
mesh = new THREE.Mesh( geometry, material );
mesh1 = new THREE.Mesh( geometry, material );
group = new THREE.Group();
group.add( mesh, mesh1 );
scene.add( group );
只需将mousedown
事件绑定到您的canvas元素,然后在函数回调中对组进行raycast并将控件附加到对象(如果尚未附加到对象)。
// on initialization
renderer.domElement.addEventListener( 'mousedown', clickEvent );
// inside mousedown callback
var intersects = raycaster.intersectObject( group, true );
if ( intersects.length > 0 ) {
let object = intersects[0].object;
if ( control.object === undefined || control.object !== object ) {
control.attach( object );
render();
}
}