【发布时间】:2016-09-04 08:20:56
【问题描述】:
我一直在尝试实现此处的拖放功能...
http://www.smartjava.org/tjscb/07-animations-physics/07.08-drag-n-drop-object-around-scene.html
每当我稍微定制它并在我的项目中使用它时,我都会得到以下结果..
"Uncaught TypeError: Cannot read property 'point' of undefined"
每当我尝试拖动立方体时。旋转没有发生,所以它必须认识到我正在尝试拖动一个对象并且它与这行代码有关..
"selectedObject.position.copy(intersects[0].point.sub(offset))"
我假设因为我对所有这些都是新手,所以我把上面链接中的所有代码复制到一个新页面中(所以应该是相同的)并运行它,我得到了同样的东西(其他一切都很好)
我可能遗漏了一些非常愚蠢的东西,我已经搜索过这个并查看了有关如何实现此目标的其他示例,但是由于我正在阅读一本书,该书解释了我认为我会坚持的所有内容,以及它找出它为什么不起作用的一个很好的学习经验。如果有人能指出我正确的方向,我将不胜感激
<!DOCTYPE html>
<html>
<head>
<title>07.08 - Drag and drop object around scene</title>
<script type="text/javascript" src="js/threejs/three.min.js"></script>
<script type="text/javascript" src ="js/threejs/OrbitControls.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
<script>
// global variables
var renderer;
var scene;
var camera;
var cube;
var control;
var orbit;
// used for drag and drop
var plane;
var selectedObject;
var offset = new THREE.Vector3();
var objects = [];
// based on http://mrdoob.github.io/three.js/examples/webgl_interactive_draggablecubes.html
function init() {
// create a scene, that will hold all our elements such as objects, cameras and lights.
scene = new THREE.Scene();
// create a camera, which defines where we're looking at.
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// create a render, sets the background color and the size
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xffffff, 1.0);
renderer.setSize(window.innerWidth, window.innerHeight);
plane = new THREE.Mesh(new THREE.PlaneGeometry(2000, 2000, 18, 18), new THREE.MeshBasicMaterial({
color: 0x00ff00,
opacity: 0.25,
transparent: true
}));
plane.visible = false;
scene.add(plane);
var dirLight = new THREE.DirectionalLight();
dirLight.position.set(25, 23, 15);
scene.add(dirLight);
var dirLight2 = new THREE.DirectionalLight();
dirLight2.position.set(-25, 23, 15);
scene.add(dirLight2);
for (var i = 0; i < 200; i++) {
// create a cube and add to scene
var cubeGeometry = new THREE.BoxGeometry(2, 2, 2);
var cubeMaterial = new THREE.MeshLambertMaterial({color: Math.random() * 0xffffff});
cubeMaterial.transparent = true;
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
objects.push(cube);
cube.scale.x = Math.random() + 0.5 * 2;
cube.scale.y = Math.random() + 0.5 * 2;
cube.scale.z = Math.random() + 0.5 * 2;
cube.position.x = Math.random() * 50 - 25;
cube.position.y = Math.random() * 50 - 25;
cube.position.z = Math.random() * 50 - 25;
cube.rotation.x = Math.random() * Math.PI * 2;
cube.rotation.y = Math.random() * Math.PI * 2;
cube.rotation.z = Math.random() * Math.PI * 2;
scene.add(cube);
}
// position and point the camera to the center of the scene
camera.position.x = 35;
camera.position.y = 35;
camera.position.z = 53;
camera.lookAt(scene.position);
// add some controls so we can rotate
orbit = new THREE.OrbitControls(camera);
// add the output of the renderer to the html element
document.body.appendChild(renderer.domElement);
// call the render function
render();
}
function render() {
renderer.render(scene, camera);
orbit.update();
requestAnimationFrame(render);
}
document.onmousemove = function (event) {
// make sure we don't access anything else
event.preventDefault();
// get the mouse positions
var mouse_x = ( event.clientX / window.innerWidth ) * 2 - 1;
var mouse_y = -( event.clientY / window.innerHeight ) * 2 + 1;
// get the 3D position and create a raycaster
var vector = new THREE.Vector3(mouse_x, mouse_y, 0.5);
vector.unproject(camera);
var raycaster = new THREE.Raycaster(camera.position,
vector.sub(camera.position).normalize());
// first check if we've already selected an object by clicking
if (selectedObject) {
// check the position where the plane is intersected
var intersects = raycaster.intersectObject(plane);
// reposition the selectedobject based on the intersection with the plane
selectedObject.position.copy(intersects[0].point.sub(offset));
} else {
// if we haven't selected an object, we check if we might need
// to reposition our plane. We need to do this here, since
// we need to have this position before the onmousedown
// to calculate the offset.
var intersects = raycaster.intersectObjects(objects);
if (intersects.length > 0) {
// now reposition the plane to the selected objects position
plane.position.copy(intersects[0].object.position);
// and align with the camera.
plane.lookAt(camera.position);
}
}
};
document.onmousedown = function (event) {
// get the mouse positions
var mouse_x = ( event.clientX / window.innerWidth ) * 2 - 1;
var mouse_y = -( event.clientY / window.innerHeight ) * 2 + 1;
// use the projector to check for intersections. First thing to do is unproject
// the vector.
var vector = new THREE.Vector3(mouse_x, mouse_y, 0.5);
// we do this by using the unproject function which converts the 2D mouse
// position to a 3D vector.
vector.unproject(camera);
// now we cast a ray using this vector and see what is hit.
var raycaster = new THREE.Raycaster(camera.position,
vector.sub(camera.position).normalize());
// intersects contains an array of objects that might have been hit
var intersects = raycaster.intersectObjects(objects);
if (intersects.length > 0) {
orbit.enabled = false;
// the first one is the object we'll be moving around
selectedObject = intersects[0].object;
// and calculate the offset
var intersects = raycaster.intersectObject(plane);
offset.copy(intersects[0].point).sub(plane.position);
}
};
document.onmouseup = function (event) {
orbit.enabled = true;
selectedObject = null;
}
// calls the init function when the window is done loading.
window.onload = init;
</script>
</head>
<body>
</body>
</html>
【问题讨论】:
标签: three.js