user3093627
user3093627

Reputation: 11

Three.js Raycaster.intersectObjects only detects intersection on front surface

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

Upvotes: 1

Views: 5007

Answers (2)

user5868931
user5868931

Reputation: 19

If double sided you'll have two intersections :

object.material.side = THREE.DoubleSide

Upvotes: 1

iwantoski
iwantoski

Reputation: 61

If you set:

object.material.side = THREE.DoubleSided

you should get hits on both surfaces.

Upvotes: 2

Related Questions