所以我的问题是我正在尝试从2d鼠标坐标中获取3d向量,并且我想使用3d位置使3d对象移至目前为止,我已经使对象沿您所拥有的最后一个方向移动移动了鼠标,但是它不会移到鼠标当前所在的实际位置,甚至不会最后移到仅将方向定位的位置
var scene;
var camera;
var renderer;
var geometry;
var material;
var sphere;
var cube;
var SphereColors = ["rgb(0, 255, 0)", "rgb(255, 255, 0)", "rgb(255, 0, 102)", "rgb(0, 0, 255)", "rgb(255, 51, 0)", "rgb(0, 255, 255)"];
var mouse = new THREE.Vector2();
var pos = new THREE.Vector3();
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.set(0, 2, 5);
camera.rotation.set(-0.1, 0, 0);
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
geometry = new THREE.SphereGeometry( 1, 32, 32 );
material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
sphere = new THREE.Mesh( geometry, material );
sphere.scale.set(0.8, 0.8, 0.8);
geometry = new THREE.BoxGeometry( 1, 1, 1 );
material = new THREE.MeshBasicMaterial( {color: "rgb(0, 102, 0)"} );
cube = new THREE.Mesh(geometry, material);
cube.scale.set(50, 1, 50);
scene.add( cube );
scene.add( sphere );
var controls = new THREE.OrbitControls( camera );
controls.target = sphere.position;
controls.maxPolarAngle = 1.2
controls.minPolarAngle = 0.2
controls.update();
var animate = function () {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
sphere.rotation.x += 0.01;
sphere.rotation.y += 0.01;
//camera.position.set(sphere.position.x + 1.5, sphere.position.y + 1, sphere.position.z + 1.5);
//camera.lookAt(sphere.position);
TWEEN.update();
};
animate();
function PickRandomColor() {
sphere.material.color = new THREE.Color(SphereColors[Math.floor(Math.random() * SphereColors.length)]);
}
setInterval(UpdatePosition, 100)
var speed = 0.4
function UpdatePosition() {
var tween = new TWEEN.Tween(sphere.position).to({ x: pos.x, y: 0, z: pos.z }, (sphere.position.distanceTo(pos) / speed) * 1000).start();
}
var raycaster = new THREE.Raycaster();
document.addEventListener( 'mousemove', UpdateMouse, false );
function UpdateMouse(e) {
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5);
vector.unproject( camera );
var dir = vector.sub( camera.position ).normalize();
var distance = - camera.position.z / dir.z;
//pos = camera.position.clone().add( dir.multiplyScalar( distance ) );
raycaster.setFromCamera( mouse, camera );
var inter = raycaster.intersectObjects(scene.children, true);
pos = inter[0].point
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/100/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.js"></script>
答案 0 :(得分:0)
您的代码中有2个问题:
THREE.Raycaster
可能无法命中任何对象,在这种情况下,.intersectObjects返回的对象列表为空。 var inter = raycaster.intersectObjects(scene.children, true);
if ( inter.length )
pos = inter[0].point
一方面,您想将球体移动到从相机位置通过光标(鼠标)位置的光线照射到曲面(立方体)的位置:
var tween = new TWEEN.Tween(sphere.position).to({ x: pos.x, y: 0, z: pos.z }, (sphere.position.distanceTo(pos) / speed) * 1000).start();
这导致球体稍微“跟随”鼠标。
另一方面,THREE.OrbitControls
应将球体保持在视口的中心:
var controls = new THREE.OrbitControls( camera );
controls.target = sphere.position;
请注意,当您执行controls.target = sphere.position;
时,controls.target
和sphere.position
将共享同一个THREE.Vector3
对象。
这导致球体似乎停留在原处。球体跟随鼠标,但是场景视图弥补了这一点,因为它跟随球体。
最终,球体更改了位置,但仍位于视图的中心。
.clone
在启动时THREE.OrbitControls
的目标位置的球体位置,但不要永久性地指向同一位置:
controls.target = sphere.position;
controls.target = sphere.position.clone();
请参见示例,其中我将建议的更改应用于原始代码:
var scene;
var camera;
var renderer;
var geometry;
var material;
var sphere;
var cube;
var SphereColors = ["rgb(0, 255, 0)", "rgb(255, 255, 0)", "rgb(255, 0, 102)", "rgb(0, 0, 255)", "rgb(255, 51, 0)", "rgb(0, 255, 255)"];
var mouse = new THREE.Vector2();
var pos = new THREE.Vector3();
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.set(0, 5, 5);
camera.rotation.set(-0.1, 0, 0);
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
geometry = new THREE.SphereGeometry( 1, 32, 32 );
material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
sphere = new THREE.Mesh( geometry, material );
sphere.scale.set(0.8, 0.8, 0.8);
geometry = new THREE.BoxGeometry( 1, 1, 1 );
material = new THREE.MeshBasicMaterial( {color: "rgb(0, 102, 0)"} );
cube = new THREE.Mesh(geometry, material);
cube.scale.set(50, 1, 50);
scene.add( cube );
scene.add( sphere );
var controls = new THREE.OrbitControls( camera );
controls.target = sphere.position.clone();
controls.maxPolarAngle = 1.2
controls.minPolarAngle = 0.2
controls.update();
var animate = function () {
sphere.rotation.x += 0.01;
sphere.rotation.y += 0.01;
TWEEN.update();
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
};
animate();
function PickRandomColor() {
sphere.material.color = new THREE.Color(SphereColors[Math.floor(Math.random() * SphereColors.length)]);
}
setInterval(UpdatePosition, 100)
var speed = 2.0
function UpdatePosition() {
var tween = new TWEEN.Tween(sphere.position).to({ x: pos.x, y: 0, z: pos.z }, (sphere.position.distanceTo(pos) / speed) * 1000).start();
}
var raycaster = new THREE.Raycaster();
document.addEventListener( 'mousemove', UpdateMouse, false );
function UpdateMouse(e) {
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
//var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5);
//vector.unproject( camera );
//var dir = vector.sub( camera.position ).normalize();
//var distance = - camera.position.z / dir.z;
//pos = camera.position.clone().add( dir.multiplyScalar( distance ) );
raycaster.setFromCamera( mouse, camera );
var inter = raycaster.intersectObjects(scene.children, true);
if ( inter.length )
pos = inter[0].point
}
window.onresize = function() {
var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/100/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.js"></script>