2016-09-03 2 views
1

Я пытался реализовать функцию перетаскивания найти здесь ...три JS перетащить неперехваченный TypeError

http://www.smartjava.org/tjscb/07-animations-physics/07.08-drag-n-drop-object-around-scene.html

Всякий раз, когда я настроить его немного и использовать его в моем проекте я получаю следующее ..

«Uncaught TypeError: не удается прочитать свойство„точка“не определено»

всякий раз, когда я пытаюсь перетащить куб. Вращение не происходит, поэтому необходимо признать, что я пытаюсь перетащить объект и относится к этой строке кода.

«selectedObject.position.copy (пересекает [0] .point.sub (смещение)) «

Я предполагал, что, поскольку я новичок во всем этом, я перепутал, поэтому я скопировал весь код из приведенной выше ссылки на новую страницу (так должно быть идентично) и запустил ее, а я получить то же самое (все остальное работает хорошо)

Мне, вероятно, не хватает чего-то действительно глупого, я искал это и посмотрел на другие примеры того, как этого добиться, но так как я работал над книгой, которая объясняла все Я думал, что буду придерживаться есть, и также было бы хорошим опытом обучения, чтобы понять, почему его не работает. Если кто-то может мне точку в правильном направлении, я был бы признателен за это

<!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> 

ответ

0

"Uncaught TypeError: Cannot read property 'point' of undefined" "selectedObject.position.copy(intersects[0].point.sub(offset))"

Это означает, что intersects[0] не определено, что означает массив intersects не имеет ни одного элемента (длина = 0). Вы используете raycasting, и он работает неправильно.

Вы должны поделиться своим измененным кодом, чтобы мы могли проверить, что происходит в вашем raycasting.

Обновление: Я думаю, что ваша версия three.js больше 71, в то время как версия для трёх.js этого сайта - 71 или меньше. В 72-й версии, есть обновление в raycaster -

Ignore invisible objects. (@mrdoob, @tschw)

Таким образом, проблема здесь -

var intersects = raycaster.intersectObject(plane); 

Поскольку плоскость невидима, то intersectObject возвращается пустой массив.

Обход проблемы: Я нашел обходное решение. Вы можете удалить следующую строку -

plane.visible = false; 

Вы можете скрыть material плоскости вместо следующим образом -

plane = new THREE.Mesh(new THREE.PlaneGeometry(2000, 2000, 18, 18), new THREE.MeshBasicMaterial({ 
       color: 0xffff00, 
       opacity: 0.50, 
       transparent: true, 
       visible: false 
      })); 

В Таким образом, raycaster будет работать должным образом, и самолет будет невидим также.

+0

Спасибо, что нашли время ответить. Чтобы попробовать и устранить неполадки, я просто пытаюсь использовать код из приведенной выше ссылки, я скопировал то, что у меня есть, в свой первоначальный вопрос. Любые предложения были бы очень полезны – user2445278

+0

@ user2445278 Пожалуйста, проверьте обновление. –

+0

Это фантастика, и это сработало. Спасибо за вашу помощь ... я просмотрел журнал изменений, но не заметил этого (или, скорее всего, не знал, что искал!). Опять же, спасибо за помощь – user2445278

Смежные вопросы