我正在使用Threejs进行集装箱货物装载互动计划。由于我的货物装载计划是一层一层的容器。所以我想将浏览器划分为多个场景。每个场景代表一个图层。每层都有自己的货箱布置,操作员可以进行一些调整。并且所有货箱都是立方体形状。
我的代码基于示例webgl_interactive_cubes_ortho.html(r82),我在示例中没有那么多立方体,因此我稍微修改了代码示例。
示例代码有效,但只有一个场景具有Viewport。由于我想垂直划分浏览器,所以我开始将高度划分为2个场景。然后我甚至将Viewport划分为2,在脚本中查看Render方法,然后我无法捕获鼠标按下事件中选择的对象。
我认为是因为鼠标点击和3D场景变换计算。无论如何,在我的情况下,我只想选择对象并拖放。任何人都可以帮助我选择对象并进行拖放操作?
/ 1 /
//var height = renderer.domElement.height/2; //only want to divide into two layers
/ 2 /
var container, stats;
var camera, scene, scene2, raycaster, renderer;
var cameras =[];
var mouse = new THREE.Vector2(), INTERSECTED,SELECTED;
var radius = 500, theta = 0;
var offset = new THREE.Vector3();
var frustumSize = 1000;
var cubesL0=[], cubesL1=[];
var plane = new THREE.Plane();
var intersection = new THREE.Vector3();
var scenes =[];
var aspect = window.innerWidth / window.innerHeight;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = '<a href="http://threejs.org" target="_blank">three.js</a> webgl - interactive cubes';
container.appendChild( info );
camera = new THREE.OrthographicCamera( frustumSize * aspect / - 2, frustumSize * aspect / 2, frustumSize /2 , frustumSize / -2, 1, 1000 );
scene = new THREE.Scene();
scene2 = new THREE.Scene();
var geometry = new THREE.BoxBufferGeometry( 150, 150, 150 );
for ( var i = 0; i < 2; i ++ ) {
var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: 0x000fff } ) );
if(i==0){
object.position.x = - 100;
object.position.y = - 100;
object.position.z = - 100;
}else{
object.position.x = 200;
object.position.y = -359;
object.position.z = -50;
}
scene.add( object );
scenes.push(scene);
cubesL0.push(object);
}
raycaster = new THREE.Raycaster();
renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0xf0f0f0 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = false;
container.appendChild(renderer.domElement);
stats = new Stats();
container.appendChild( stats.dom );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
var aspect = window.innerWidth / window.innerHeight;
camera.left = - frustumSize * aspect / 2;
camera.right = frustumSize * aspect / 2;
camera.top = frustumSize / 2;
camera.bottom = - frustumSize / 2;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = (- ( event.clientY / window.innerHeight) * 2 + 1);
console.log("mouse x:"+mouse.x+", mouse y:"+mouse.y);
raycaster.setFromCamera( mouse, camera );
if ( SELECTED ) {
if ( raycaster.ray.intersectPlane( plane, intersection ) ) {
SELECTED.position.copy( intersection.sub( offset ) );
}
return;
}
var intersects = raycaster.intersectObjects( cubesL0 );
if ( intersects.length > 0 ) {
console.log(" there is object going to move");
if ( INTERSECTED != intersects[ 0 ].object ) {
if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
INTERSECTED = intersects[ 0 ].object;
INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
plane.setFromNormalAndCoplanarPoint(
camera.getWorldDirection( plane.normal ),
INTERSECTED.position );
}
container.style.cursor = 'pointer';
} else {
if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
INTERSECTED = null;
container.style.cursor = 'auto';
}
}
function onDocumentMouseDown( event ) {
event.preventDefault();
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( cubesL0 );
var getTarget = true;
if ( intersects.length > 0 ) {
SELECTED = intersects[ 0 ].object;
if ( raycaster.ray.intersectPlane( plane, intersection ) ) {
offset.copy( intersection ).sub( SELECTED.position );
}
container.style.cursor = 'move';
}
}
function onDocumentMouseUp( event ) {
event.preventDefault();
console.log(" in mouse up event ");
if ( INTERSECTED ) {
SELECTED = null;
}
container.style.cursor = 'auto';
}
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
var width = renderer.domElement.width;
var height = renderer.domElement.height;
//var height = renderer.domElement.height/2; //only want to divide into two layers
var left = 0;
var bottom = 0;
renderer.setViewport( left, bottom, width, height );
renderer.setScissor( left, bottom, width, height );
renderer.render( scene, camera );
}
</script>
&#13;
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - interactive cubes</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="http://threejs.org/build/three.min.js"></script>
<script src="http://threejs.org/examples/js/libs/stats.min.js"></script>
</body>
</html>
&#13;