2013-12-12 2 views
1

Я создаю программу, которая населяет мир с помощью блоков на земле при щелчке мыши (координата основана на координате щелчка мыши, которую я вычислил). При создании нового блока он не должен пересекаться с уже сделанными заранее. Я проверил эту проверку с помощью THREE.Raycaster. В основном я бросаю лучи из центра блока во все направления его вершин.Three.js Raycaster.intersectObjects обнаруживает только пересечение на передней поверхности

var ln = preview.geometry.vertices.length; 

//for each vertices we throw a ray 
for(var i = 0; i < ln; i++){ 
    var pr_vertex = preview.geometry.vertices[i].clone(); 
    var gl_vertex = pr_vertex.applyMatrix4(preview.matrix); 
    var dr_vector = gl_vertex.sub(preview.position); 

    var ray = new THREE.Raycaster(preview.position, dr_vector.clone().normalize()); 
    var intersects = ray.intersectObjects(objmanager.getAllObject(), true); 

    //if there is intersection 
    if(intersects.length > 0 && intersects[0].distance < dr_vector.length()){ 
     //hide preview material 
     preview.material.opacity = 0; 
     //exit checking 
     break; 
    } 
} 

Предварительный просмотр - это название объекта. Этот код уже работал отлично. Проблема в том, что Raycaster.intersectObjects работал только тогда, когда луч пересекается с передним лицом испытуемого объекта. Я протестировал его, когда я запускал код, если луч запускался из-за объекта, он пересекался просто отлично. Но когда луч начал, если изнутри тестируемого блока, он не поймал пересечение с поверхностью тестируемого блока. Я предполагаю, что это происходит потому, что intersectObjects работает только с передней поверхностью тестируемого объекта. Это правда?

Интуитивно я попытался решить эту проблему, используя THREE.DoubleSide (создание двухсторонних объектов). Но это вызвало ошибку, поскольку шейдеру не удалось инициализировать.

Could not initialise shader 
VALIDATE_STATUS: false, gl error [0] three.js:25254 
    buildProgram three.js:25254 
    initMaterial three.js:23760 
    setProgram three.js:23830 
    renderBuffer three.js:22371 
    renderObjects three.js:23061 
    render three.js:22935 
    animLoop 

Я использую материал THREE.MeshLambertMaterial. Когда я использовал MeshBasicMaterial, Raycaster.intersectObjects просто не работал вообще.

Итак, теперь я попал в блокпост. Есть ли идея решить эту проблему? Либо это, либо мне пришлось бы проверять столкновение вручную с отдельными лицами каждого объекта (что, я боюсь, сильно ударит по производительности).

Благодарим вас заблаговременно.

===============

редактировать: Я забыл упомянуть, я использую новейшую версию three.js, которая должна быть около R63

+0

'THREE.DoubleSided' должны это сделать, [Raycaster.js] (https://github.com/mrdoob/three.js/blob /master/src/core/Raycaster.js) проверяет лица, которые имеют обратные стороны. –

+0

Как я уже сказал, когда я использовал material.side = THREE.DoubleSide, это вызвало ошибку в шейдере. Я не знал, почему эта ошибка возникает, потому что логически ее не должно быть. Я использую MeshLambertMaterial для этого, может быть, это так? – user3093627

+0

На этом этапе я предлагаю вам создать наименьший возможный пример, который показывает проблему, и файл отчета об ошибке в репозитории ThreeJS. –

ответ

0

Если вы установили:

object.material.side = THREE.DoubleSided 

Вы должны получить хиты на обеих поверхностях.

+0

Я попробовал этот метод, но при этом на моем объекте возникла ошибка в шейдере. Кстати, я использую MeshLambertMaterial. Я не знал, почему это привело к ошибке. – user3093627

0

Если Двухсторонняя вы будете иметь два пересечения:

object.material.side = THREE.DoubleSide