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?