Я создаю программу, которая населяет мир с помощью блоков на земле при щелчке мыши (координата основана на координате щелчка мыши, которую я вычислил). При создании нового блока он не должен пересекаться с уже сделанными заранее. Я проверил эту проверку с помощью 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
'THREE.DoubleSided' должны это сделать, [Raycaster.js] (https://github.com/mrdoob/three.js/blob /master/src/core/Raycaster.js) проверяет лица, которые имеют обратные стороны. –
Как я уже сказал, когда я использовал material.side = THREE.DoubleSide, это вызвало ошибку в шейдере. Я не знал, почему эта ошибка возникает, потому что логически ее не должно быть. Я использую MeshLambertMaterial для этого, может быть, это так? – user3093627
На этом этапе я предлагаю вам создать наименьший возможный пример, который показывает проблему, и файл отчета об ошибке в репозитории ThreeJS. –