Basically what i want to create:
I have a 3D map with objects, i want to select all objects that are in the 2D box x1,y1 to x2,y2 on my screen.
Any ideas how this has to be done, because i'm clueless on how to start.
Thanks in advance!
prevX
and prevY
is coordinate of mouse down:
function onDocumentMouseUp(event) {
event.preventDefault();
var x = (event.clientX / window.innerWidth) * 2 - 1;
var y = -(event.clientY / window.innerHeight) * 2 + 1;
var width = (x - prevX); //* window.innerWidth;
var height = (y - prevY); //* window.innerHeight;
var dx = prevX; //* window.innerWidth;
var dy = prevY; //* window.innerHeight;
console.log(
dx + ',' +
dy + "," +
(dx + width) + "," +
(dy + height) +
", width=" + width +
", height=" + height
);
var topLeftCorner3D = new THREE.Vector3(dx, dy, 1).unproject(
camera);
var topRightCorner3D = new THREE.Vector3(dx + width, dy, 1)
.unproject(camera);
var bottomLeftCorner3D = new THREE.Vector3(dx, dy + height,
1).unproject(camera);
var bottomRightCorner3D = new THREE.Vector3(dx + width, dy +
height, 1).unproject(camera);
var topPlane = new THREE.Plane();
var rightPlane = new THREE.Plane();
var bottomPlane = new THREE.Plane();
var leftPlane = new THREE.Plane();
topPlane.setFromCoplanarPoints(camera.position,
topLeftCorner3D, topRightCorner3D);
rightPlane.setFromCoplanarPoints(camera.position,
topRightCorner3D, bottomRightCorner3D);
bottomPlane.setFromCoplanarPoints(camera.position,
bottomRightCorner3D, bottomLeftCorner3D);
leftPlane.setFromCoplanarPoints(camera.position,
bottomLeftCorner3D, topLeftCorner3D);
//var frustum = new THREE.Frustum( topPlane, bottomPlane, leftPlane, rightPlane, nearPlane, farPlane);
function isObjectInFrustum(object3D) {
var sphere = object3D.geometry.boundingSphere;
var center = sphere.center;
var negRadius = -sphere.radius;
if (topPlane.distanceToPoint(center) < negRadius) { return false; }
if (bottomPlane.distanceToPoint(center) < negRadius) { return false; }
if (rightPlane.distanceToPoint(center) < negRadius) { return false; }
if (leftPlane.distanceToPoint(center) < negRadius) { return false; }
return true;
}
var matches = [];
for (var i = 0; i < window.objects.length; i++) {
if (isObjectInFrustum(window.objects[i])) {
window.objects[i].material = window.selectedMaterial;
}
}
}
You can use the bounding boxes of the objects. THREE.Geometry
contains a boundingBox
property. This is null
by default, you should compute it by calling computeBoundingBox()
directly.
scene.traverse( function ( node ) {
if ( node.geometry )
node.geometry.computeBoundingBox();
} );
Once you have the bounding boxes, the bounding box 2D coordinates are (if 'y' is the UP axis):
mesh.geometry.boundingBox.min.x
mesh.geometry.boundingBox.min.z
mesh.geometry.boundingBox.max.x
mesh.geometry.boundingBox.max.z
See http://threejs.org/docs/#Reference/Core/Geometry
(however, if you need the exact result for meshes that have non-rectangular shape, you need further computations)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With