I have a camera (pos, dir)
and
I have an object (x,y,z)
How can I detect when the object can see with my camera?
You don't have enough info. You need to know camera frustum. Than you calculate if the object is inside frustum. Learn more here:
http://www.lighthouse3d.com/tutorials/view-frustum-culling/
http://www.songho.ca/opengl/gl_transform.html
Related
My Three.js app has a static perspective camera looking on (0,0,0). How can I find the x/y coordinates in the y=0 plane of the corners of the camera's viewfield? The app covers the entire web browser, so this would correspond to the corners of the web browser. I want to render 3D models between those corners.
I want to render 3D models between those corners.
Just having the mentioned corner points is not sufficient to determine whether the user can see an object or not. The camera also has a near/far plane and also a perspective which you should take into account.
I suggest you use a different workflow and create an instance of THREE.Frustum based on the camera's projection screen matrix. The code looks like so:
const frustum = new THREE.Frustum();
const projScreenMatrix = new THREE.Matrix4();
projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
frustum.setFromProjectionMatrix( _projScreenMatrix );
You can then use methods like Frustum.intersectsObject() or Frustum.intersectsSprite() to determine whether 3D objects are in the view frustum or not.
This is actually the way WebGLRenderer performs view frustum culling.
I need to get the camera up direction and i've tried many ways with no luck, i'm not an expert of quaternions so i'm doubting i did it right.
I've tried:
camera.up
camera.up.applyMatrix4(camera.matrixWorld);
new THREE.Vertex3(0,1,0).applyMatrix4(camera.matrixWorld);
camera.up.normalize().applyMatrix4(camera.matrixWorld);
after this i create two planes passing by two points of my interest, and add the plane helper to the scene and i can see they are very far from where i was expecting them. (i'm expecting two planes that looks like the top and bottom of the camera frustum).
P.s. the camera is a shadow camera of a directional light so an orthographic camera, and i manipulate the directional light position and target before doing this operation, but i've called updateMatrixWorld on the light, on it's target and the camera, on the camera i've called also updateProjectionMatrix... still no results
I've made a sandbox to see what i've tried till now, and better visualize what i want to achieve:
https://codesandbox.io/embed/throbbing-cache-j5yse
once i manage to get the green arrow to point to the top of the blue triangle of the camera helper i'm good to go
In the normal render flow, shadow camera matrices are updated as part of rendering the shadow map (WebGLShadowMap.render).
However, if you want the updated matrix values before the render, then you'll need to update them manually (you already understand this part).
The shadow camera is a property of (not a child of) the DirectionalLight. As such, it doesn't follow the same rules as other scene objects when it comes to updating its matrices (because it's not really a child of the scene). Instead, you need to call the shadow property's updateMatrices method (inherited from LightShadow.updateMatrices).
const dl = new THREE.DirectionalLight(0xffffff, 1)
dl.shadow.updateMatrices(dl) // <<------------------------ Updates the shadow camera
This updates the shadow camera with information from the DirectionalLight's own matrix, and its target's matrix, to properly orient the shadow camera.
Finally, it looks like you're trying to get the "world up" of the camera. Personally, I'd use the convenience function localToWorld:
let up = new THREE.Vector3(0, 1, 0)
dl.shadow.camera.localToWorld(up) // destructively converts "up" from local-to-camera into world coordinates
via trial and errors i've figured out that what gave me the correct result was:
calling
directionalLight.shadow.updateMatrices(...)
and then
new THREE.Vector3(0,1,0).applyQuaternion(directionalLight.shadow.camera.quaternion)
It seems like this would be a pretty common problem, but I can't find an example online and I'm too much of a math noob...
Using ThreeJS, I have a library to do spatial audio positioning (https://github.com/tmwoz/hrtf-panner-js) based on user position, but my code assumes the camera looks straight ahead and doesn't move. Since my camera is moving, I need to get the xyz position of a 3D object in relation to the camera's position and orientation.
//finds the object in world coordinates
var p = new THREE.Vector3();
p.setFromMatrixPosition(visual.object.matrixWorld);
this.audioTrack.updateHrtf(p.x, p.y, p.z);
How do a translate the object into camera-space coordinates? Thanks for your help!
Note: I know that the WebAudio API has a mechanism to do this simply, but it doesn't have the power of the HRTF (Head Related Transfer Function) library, which sounds much better.
To transform a Vector3 vec from world space to camera space, do this:
camera.matrixWorldInverse.getInverse( camera.matrixWorld );
vec.applyMatrix4( camera.matrixWorldInverse );
three.js r.73
I've been struggling with an application where I'm trying to set the camera rotation initially so when the scene is loaded, you'll be looking where we want you to look.
The backstory, I'm creating a panorama viewer where the panorama is applied to a mesh with a sphere geometry.
The problem I'm having is I don't seem to be able to set the camera rotation. I've tried multiple attempts, but none have been working. I attempted setting the camera rotation after creating the camera, and I tried applying the target of my orbitcontrols and setting the object rotation in the orbit controls. I haven't had any luck yet with just setting an initial camera rotation.
I'm really hoping at this point that this is due to something minor that I'm over looking.
Here's a source: http://www.freeptools.com/mapster/testing-360s2.php
It shows the camera itself AND the orbit controls object. It also shows what their target is I'm setting, and what they really are. So far I haven't been able to get this to accept anything I give it.
THREE.js OrbitControls take over the camera completely, so you should not use that in conjunction with updating camera rotations.
Instead, OrbitControls has methods that help you do this: https://github.com/mrdoob/three.js/blob/master/examples/js/controls/OrbitControls.js
orbitControls.rotateLeft( angle );
orbitControls.rotateUp( angle );
In addition, you can move orbitControls.target around (it's a THREE.Vector3) and the camera will just look to that direction.
I am using the version THREE.js57. I want to hide selected face at run time. Is this possible in three.js
Thanks & Regards
Indeed this is possible, you'll want to look into the Raycaster library, here's the high level steps
unproject your mouse click coordinates into the 3D scene.
cast rays into your scene and return an intersected array of collided objects
this intersected object will have the affected face and faceIndex as parameters
on collision turn the face # faceIndex transparency to 0
Have a look at these doc pages:
http://threejs.org/docs/#Reference/Core/Projector
http://threejs.org/docs/#Reference/Core/Raycaster
And this example for a start:
https://github.com/mrdoob/three.js/blob/master/examples/canvas_interactive_cubes.html
Edit:
Alright, well to then hide the face you can have a peak at this other SO post:
Can I hide faces of a mesh in three.js?
The gist is you have a multimaterial object, the first material is your default, and a second material that's fully opaque. Then when you intersect you set the face to use the second materialIndex. Anyway, the above link should do the job. Off to up vote that response. :)