1
votes

I am creating a program which populate a world with blocks on the ground upon mouse click (the coordinate is based on the mouse click coordinate, which I've calculated). When creating a new block, it should not intersects with the ones already made beforehand. I achieved this checking with THREE.Raycaster. Basically I cast rays from the block's center in all direction of its vertices.

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;
    }
}

preview is the name of the object. This code already worked perfectly. The problem is, Raycaster.intersectObjects only worked when the ray intersects with the front face of the tested object. I've tested it when I ran the code, if the ray start from outside the tested object, they intersected just fine. But when the ray started if from the inside of the tested block, it didn't catch the intersection with the tested block's surface. I presume that this happens because intersectObjects only worked with the tested object's front surface. Is this true?

Intuitively, I tried to solve this problem using THREE.DoubleSide (making a double-sided objects). But it produced an error because the shader failed to initialize.

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

I'm using THREE.MeshLambertMaterial. When I used MeshBasicMaterial, the Raycaster.intersectObjects just didn't work at all.

So I hit a roadblock now. Is there any idea to solve this problem? Either that, or I would have to test the collision manually with each objects' individual faces (which I'm afraid would hit the performance hard).

Thank you in advance.

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

edit: I forgot to mention, I'm using the newest three.js version, which should be around r63

2
THREE.DoubleSided should do it, Raycaster.js does check for faces that have back sides.Dan Ross
As I've said, when I used material.side = THREE.DoubleSide, it produced an error in the shader. I didn't know why this error is produced because logically it shouldn't be. I'm using MeshLambertMaterial for this, perhaps it is that?user3093627
At this point, I would suggest that you create the smallest possible example that shows the problem and file a bug report at the ThreeJS repo.Dan Ross

2 Answers

1
votes

If you set:

object.material.side = THREE.DoubleSided

you should get hits on both surfaces.

1
votes

If double sided you'll have two intersections :

object.material.side = THREE.DoubleSide