Three.js Three.Interaction Three.transformControls

时间:2019-05-21 15:53:11

标签: javascript three.js

我的项目有问题。 我使用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);
    }
  }
}

js小提琴:https://jsfiddle.net/h80g42wk/4/

1 个答案:

答案 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();
    }
}

JSFiddle Example