1

I'm roughing out a project that will require hotspots/annotations to appear over different parts of a model; I'm using THREE.Vector3 to translate the 3D location of points on the object to 2D for positioning.

function createVector(x, y, z, r) {
    var p = new THREE.Vector3(x, y, z),
        vector = p.project(camera); 

    vector.x = (vector.x + 1) / 2 * $(window).width() - r;
    vector.y = -(vector.y - 1) / 2 * $(window).height() - r;

    return vector;
}

This works to position them appropriately when I rotate and zoom, but I would like to hide them when their centers are obstructed from view. I load the single object as so:

var mtlLoader = new THREE.MTLLoader();
mtlLoader.setBaseUrl('assets/');
mtlLoader.setPath('assets/');
mtlLoader.load('test.mtl', function (materials) {

    materials.preload();

    var objLoader = new THREE.OBJLoader();
    objLoader.setMaterials(materials);
    objLoader.setPath('assets/');
    objLoader.load('test.obj', function (object) {
        mesh = object;
        scene.add(object);
        objects.push( object );

    });

});

I found some answers regarding how to tell when an object is visible, but only one regarding a point, and it was a question about performance.

How to quickly find if a point is obscured in a complex scene?

// pos   = vector with (normalized) x, y coordinates on canvas
// dir   = vector from camera to target point

const raycaster = new THREE.Raycaster();
const d = dir.length(); // distance to point
let intersects = false;
raycaster.setFromCamera(pos, camera);
const intersections = raycaster.intersectObject(mesh, true);
if (intersections.length > 0 && intersections[0].distance < d)
    intersects = true;

// if ray intersects at a point closer than d, then the target point is obscured
// otherwise it is visible

Performance isn't as much of an issue for me, since though my model is complex, I hide the hotspots during change, and then run the positioning script once movement has stopped for a quarter second.

But my interpretation is not working, and honestly I don't have a clue why. I thought my raycaster would be from the camera to the hotspot point, but that never intersects at all, but it works sometimes for one point if I unproject and subtract the camera.position.

$.each(annotations,function(k,v) {
    var v = annotations[k];
    nvectors[k] = new THREE.Vector3(v[0],v[1],v[2]);
    nvectors[k].unproject( camera );
    raycaster[k] = new THREE.Raycaster( camera.position, nvectors[k].sub(camera.position).normalize() );
    intersections[k] = raycaster[k].intersectObjects( objects, true );
    if (intersections[k].length > 0) {
    } else {
        $('a.annotation'+k).show();
    }
});

I've posted a complete example here, http://whatiknow.nicewebsite.info/ , to show the model as well. Point 0 works mostly, but Point 1 never works at all (never returns an intersection). Sorry that I didn't post to JSFiddle, couldn't get cross domain issues resolved.

My question is, how can I tell when a point in space is obscured by my model?

Community
  • 1
  • 1
Mason
  • 305
  • 2
  • 7

1 Answers1

0

I think I've sorted it out. I was making two primary mistakes, one was that I was unprojecting when I should have been projecting, and the second is that my Raycaster was wrong, I should have been using setFromCamera.

Using WebGLRenderer 82:

$.each(annotations,function(k,v) {
    nvectors[k] = new THREE.Vector3(v[0],v[1],v[2]);

    nvectors[k].project( camera );

    raycaster[k] = new THREE.Raycaster();
    raycaster[k].setFromCamera( nvectors[k], camera );
    intersections[k] = raycaster[k].intersectObjects( objects, true );

    var dx = v[0] - camera.position.x;
    var dy = v[1] - camera.position.y;
    var dz = v[2] - camera.position.z;
    var d = (Math.sqrt( dx * dx + dy * dy + dz * dz ));
    if (intersections[k].length > 0 && intersections[k][0].distance < d) {
    } else {
        $('a.annotation'+k).show();
    }

});

Honestly, I don't understand why it works, I figured it out by accident when I was trying and failing to transition to Sprites. So if anyone would like to explain my solution, that would be awesome.

Mason
  • 305
  • 2
  • 7