我有一个WebGl / ThreeJS应用程序,我有 3个WebGL渲染器,每个渲染器1个场景和1个画布。前2张画布还可以,它们工作正常。
另一个画布分为3个等维视口,在每个视口中我添加了一个不同位置的正交相机。
所以我希望能够在此场景中的对象上检测鼠标事件。我想独立地在所有视口中检测它们。所有这一切,因为我想在其中创建某些领域的拖放功能。
我创建我的正交相机,如上面的代码为每个相机(12,0,0)(0,12,0)(0,0,12)提供3个不同的位置,并给出视口的宽度,高度(不是画布):
var viewSize = 50 ;
var aspectRatio = width/height;
var camera = new THREE.OrthographicCamera( viewSize*aspectRatio / - 2, viewSize*aspectRatio / 2, viewSize / 2, viewSize / - 2, 0, 100);
camera.position.set(x,y,z);
camera.lookAt(new THREE.Vector3(0,0,0) );
在设置了摄像机/视口之后,基于这个非常有用的帖子:post,我为每个视口/摄像机创建并调用了一次此功能:
{
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
function MouseEvents( spheres, func, _camera, domElement ) {
this.plane = {'object3d' : undefined} ;
this.camera = _camera;
this.container = domElement;
this.objects = spheres;
var _this =this;
this.offset = new THREE.Vector3();
this.INTERSECTED;
this.SELECTED;
if(func === 'dragNdrop'){
this.plane.object3d = new THREE.Mesh(
new THREE.PlaneBufferGeometry( 10000, 10000, 2, 2 ),
new THREE.MeshBasicMaterial( { color: "#"+((1<<24)*Math.random()|0).toString(16) } )
);
this.plane.object3d.visible = true;
if(this.container === 'motifPosX' ) this.plane.object3d.position.z = -100;
if(this.container === 'motifPosY' ) this.plane.object3d.position.x = -100;
if(this.container === 'motifPosZ' ) this.plane.object3d.position.y = -100;
this.plane.object3d.lookAt(this.camera.position);
MotifExplorer.add(this.plane);
}
var mMoove = this.onDocumentMouseMove.bind(this) ;
var mDown = this.onDocumentMouseDown.bind(this) ;
var mUp = this.onDocumentMouseUp.bind(this) ;
document.getElementById(this.container).addEventListener("mousemove", mMoove, false);
document.getElementById(this.container).addEventListener("mousedown", mDown, false);
document.getElementById(this.container).addEventListener("mouseup", mUp, false);
};
MouseEvents.prototype.onDocumentMouseMove = function(event){
var _this = this;
event.preventDefault();
_this.plane.object3d.lookAt( _this.camera.position );
mouse.x = ( event.clientX / $('#'+_this.container).width() ) * 2 - 1;
mouse.y = - ( event.clientY / $('#'+_this.container).height() )* 2 + 1;
//
raycaster.setFromCamera( mouse, _this.camera );
if ( _this.SELECTED ) {
var intersects = raycaster.intersectObject( _this.plane.object3d );
_this.SELECTED.position.copy( intersects[ 0 ].point.sub( _this.offset ) );
return;
}
var intersects = raycaster.intersectObjects( _this.getAtoms() );
if ( intersects.length > 0 && intersects[0].object.parent.name ==='atom') {
if ( _this.INTERSECTED != intersects[0].object.parent ) {
_this.INTERSECTED = intersects[0].object.parent;
_this.plane.object3d.position.copy( _this.INTERSECTED.position );
}
document.getElementById(_this.container).style.cursor = 'pointer';
}
else {
_this.INTERSECTED = null;
document.getElementById(_this.container).style.cursor = 'auto';
}
}
MouseEvents.prototype.onDocumentMouseDown = function(event){
var _this =this;
event.preventDefault();
raycaster.setFromCamera( mouse, _this.camera );
var intersects = raycaster.intersectObjects( _this.getAtoms() );
if ( intersects.length > 0 && intersects[0].object.parent.name ==='atom') {
_this.SELECTED = intersects[0].object.parent;
var intersects = raycaster.intersectObject( _this.plane.object3d );
_this.offset.copy( intersects[ 0 ].point ).sub( _this.plane.object3d.position );
document.getElementById(_this.container).style.cursor = 'move';
}
}
MouseEvents.prototype.onDocumentMouseUp = function(event){
var _this =this;
event.preventDefault();
if ( _this.INTERSECTED ) {
_this.plane.object3d.position.copy( _this.INTERSECTED.position );
_this.SELECTED = null;
}
document.getElementById(_this.container).style.cursor = 'auto';
};
MouseEvents.prototype.getAtoms = function() {
var _this = this;
var objects = [];
MotifExplorer.getInstance().object3d.traverse (function (object) {
if (object.name === 'atom') {
for (var i = 0; i < object.children.length; i++) {
_this.objects.push(object.children[i]);
};
}
});
return _this.objects;
};
return MouseEvents;
});
所以一切都在控制台中没有任何错误,但鼠标悬停或点击无法检测到球体。我认为我的设置数字,鼠标坐标和画布尺寸有问题。
我想要注意的是,我还为每个视口独立设置了orbitControls,但是除了滚动缩放之外,我已经禁用了所有功能。
另外,当我添加一个球体时,如果我放大得太多以至于球体遍布视口,那么它实际上是可以通过该功能检测到的。
由于代码的复杂性和数量,我无法创建一个jsfiddle所以我附上这个图片只是为了给你一个想法: 这是一个非常具体的问题,所以感谢任何至少试图帮助我的人!
我忘了说,对于适合整个屏幕的1个渲染器/相机/画布,我能够制作一个可拖动的球体。我的问题是如何在具有特定尺寸的画布和3个视口/摄像机中使用此功能进行更改。