Lasto
Lasto

Reputation: 127

Raycast doesnt hit mesh when casted from the inside

I have set up a simple scene where I have my camera inside a sphere geometry

var mat = new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('0.jpg') , overdraw:true,  color: 0xffffff, wireframe: false });
        var sphereGeo = new THREE.SphereGeometry(1000,50,50);
        var sphere = new THREE.Mesh(sphereGeo,mat);
        sphere.scale.x = -1;
        sphere.doubleSided = false;
        scene.add(sphere);

I set up a funcionality where I can look around inside that sphere and my point is to be able to cast a ray on mouse down, hit the sphere and get the coordinates where that hit occured. Im casting a ray but still the intersects are empty.

var vector = new THREE.Vector3();
      vector.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
      vector.unproject( camera );

      raycaster.ray.set( camera.position, vector.sub( camera.position ).normalize());

var intersects = raycaster.intersectObjects(scene.children, true);

Everything works with a test cube also put inside my sphere. My question is, does it matter whether you hit the object from the inside or no ? Because that is the only explanation that comes to my mind.

Thanks in advance.

Upvotes: 3

Views: 1684

Answers (2)

mrdoob
mrdoob

Reputation: 19592

sphere.doubleSided was changed to sphere.material.side = THREE.DoubleSide some years ago.

Upvotes: 7

Ali Hammoud
Ali Hammoud

Reputation: 335

It does matter if you hit the object from the inside. Usually a ray will pass through an "inverted" surface due to backface culling which happens on the pipeline level.

Inverted/flipped surfaces are usually ignored in both rendering and raycasting.

In your case, however, i'd go ahead and try setting sphere.doubleSided = false; to sphere.doubleSided = true;. This should make the raycast return the intersection point with your sphere. [shouldn't work with negative scale]

You can also enter the "dirty vertices" mode, and flip the normals manually:

mesh.geometry.dynamic = true
mesh.geometry.__dirtyVertices = true;
mesh.geometry.__dirtyNormals = true;

mesh.flipSided = true;

//flip every vertex normal in mesh by multiplying normal by -1
for(var i = 0; i<mesh.geometry.faces.length; i++) {
    mesh.geometry.faces[i].normal.x = -1*mesh.geometry.faces[i].normal.x;
    mesh.geometry.faces[i].normal.y = -1*mesh.geometry.faces[i].normal.y;
    mesh.geometry.faces[i].normal.z = -1*mesh.geometry.faces[i].normal.z;
}

mesh.geometry.computeVertexNormals();
mesh.geometry.computeFaceNormals();

I also suggest you set scale back to 1.0 instead of -1.0.

Let me know if it worked!

Upvotes: 0

Related Questions