2017-02-16 37 views
0

Я пытаюсь сделать серию кубов, которые можно щелкнуть, чтобы выделить их. Это позволит мне изменить свой цвет или добавить текстуру или каким-то образом манипулировать ими. Я просмотрел исходный код всех интерактивных примеров на https://threejs.org/examples/, и кажется, что каждый пример использует несколько иной способ создания и выбора объектов в сцене. Я не привык использовать javascript, хотя, возможно, мне не хватает чего-то простого.three.js, выбрав детей Object3D с помощью raycaster.intersectObject

Я создаю Object3D класс под названием блоки для хранения всех кубов

blocks = new THREE.Object3D() 

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

function stack(mx,my,mz){ 
     for (var i = 0; i < 9; i++){ 
      line(mx,my,mz); 
      mz += 3; 
     } 
    } 

    function line(mx,my,mz){ 
     for (var i = 0;i<9;i++){ 
      var block = new THREE.Mesh(Geometry, Material); 
      block.position.x = mx; 
      block.position.y = my; 
      block.position.z = mz; 

      blocks.add(block); 
      mx+=3; 
     } 
    } 
    stack(mx,my,mz) 
    scene.add(blocks) 

Когда я запускаю этот код, я вижу, как они отображаются. Я использую raycaster для .intersectObjects(), который требует массив объектов. Здесь я сталкиваюсь с проблемой выбора только одного объекта.

function onDocumentMouseDown(event) { 

    var vector = new THREE.Vector3((event.clientX/window.innerWidth) * 2 - 1, -(event.clientY/window.innerHeight) * 2 + 1, 0.5); 
    projector.unprojectVector(vector, camera); 
    var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize()); 
    **var intersects = raycaster.intersectObjects(blocks.children, true);** 

    if (intersects.length > 0) { 
     intersects[0].object.material.transparent = true; 
     other code stuff blah blah blah 
    { 

Это сделает всех детей доступными для клика, но они имеют тот же .id, что и первый созданный объект. поэтому, если я пытаюсь выполнить .getObjectById(), чтобы что-то изменить, это не сработает.

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

var intersects = raycaster.intersectObjects(blocks, true); 

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

for (var i=0, i<9, i++){ 
    var window["cube" + i] = new THREE.Mesh(Geometry, Material) 
    { 

Главный Вопрос: Как я могу итеративно создать несколько меша (достаточно, что статически печатающего каждый переменный будет опрометчивым) контролируемым образом, что я могу выбрать их и манипулировать ими по отдельности, а не в группе?

ответ

1

Я думаю, что причина, почему вы встретили эту проблему вы ссылаетесь же Material построить свой Mesh, ты пересекаться один объект в blocks.children, но при изменении некоторых свойств материала других сетки, которые используют этот материал будет меняться слишком ,

function line(mx,my,mz){ 
    for (var i = 0;i<9;i++){ 
     material = new THREE.MeshLambertMaterial({color: 0xffffff}); 
     var block = new THREE.Mesh(Geometry, material); 
     block.position.x = mx; 
     block.position.y = my; 
     block.position.z = mz; 

     blocks.add(block); 
     mx+=3; 
    } 
} 

Это работает для меня.

+0

Спасибо! работал в первый раз. –