Raycasting through a custom camera projection matrix - matrix

After modifying my main camera's projection matrix, the ScreenPointToRay method that use ray casting begin to fail, so the method which detect touched object use raycast fail too. Is there any way to use ScreenPointToRay method with a custom camera projection matrix?

If you made a custom camera projection matrix, then you probably know where is the user pointing to, how about casting a ray yourself and not using the helper?
If you have a problem with translation of the cursor to world position, there is a good approximation - take four angles on approxiamtely the edges of your camera's viewpoint (top of the viewport horizontal center, left of the viewport vertical center etc.) and interpolate between them.

Related

Convert screen space X,Y position into perspective projection with a specific z position

I'm using ThreeJS, but this is a general math question.
My end goal is to position an object in my scene using 2D screen space coordinates; however, I want a specific z position in the perspective projection.
As an example, I have a sphere that I want to place towards the bottom left of the screen while having the sphere be 5 units away from the camera. If the camera were to move, the sphere would maintain its perceived size and position.
I can't use an orthographic camera because the sphere needs to be able to move around in the perspective projection. At some point the sphere will be undocked from the screen and interact with the scene using physics.
I'm sure the solution is somewhere in the camera inverse matrix, however, that is beyond my abilities at the current moment.
Any help is greatly appreciated.
Thanks!
Your post includes too many questions, which is out of scope for StackOverflow. But I’ll try to answer just the main one:
Create a plane Mesh using PlaneGeometry.
Rotate it to face the camera, place it 5 units away from the camera.
Add it as a child with camera.add(plane); so whenever the camera moves, the plane moves with it.
Use a Raycaster’s .setfromCamera(cords, cam)
then
.intersectObject(plane)
method to convert x, y screen cords into an x, y, z world position where it
intersects the plane. You can read about it in the docs.
Once it’s working, make the plane invisible with visible = false
You can see the raycaster working in this official example: https://threejs.org/examples/#webgl_geometry_terrain_raycast

Three JS How to make ray or rays from camera to all object in rederer to check faceIndex

I have some project for child http://kinosura.kiev.ua/sova/ and i need to check faceIndex of all cubes in screen.
Now i use intersections array from mouse, but is working only when user pointer at the cube.
How to make ray or rays from camera to all object to check faceIndex ?
I try to make four rays to cubes but if i set cube.position as origin of like this:
raycaster.setFromCamera( cube1.positoin , camera )
I get empty array of intersections.
I also try to set static 2d vector as origin (get coordinate from mouse) but i have relative renderer size and this coordinate all time change... its not work(
Thanks for answer anyway.
I suggest that you try another approach It appears that your cubes do not cover one another, relative to the camera view. So use the surface normals, and compare them to the view direction to determine if they are facing the camera or facing away from the camera by a simple one-per-polygon dot product.
When you are creating your geometry, before adding it a THREE.Mesh call .generateFaceNormals() on it.
Instead of ray casting, iterate through all faces, grab the surface normal of the face, transform relative to the view (inverse transpose of the object's matrix), then dot(). might sound complicated, at first, but it's actually just a couple of steps and much faster than doing a lot of raycasts (which will probably include this anyway!)

How to copy the rotation value of a sprite to a plane?

I was wondering if there is a way to copy the rotational information of a sprite into a plane. It seems that for the sprite the rotation is set within the material and it is just one value. I tried copying the matrix of the sprite into that of the plane but had no luck.
Sprite rotation is defined in WebGL as you can read in SpritePlugin.js. Thus, if you wish to copy the rotation of an existing sprite in your scene, the easiest way may be to use quaternion. They allow better defining than x/y/z-angle defined ones (Euler rotations) as they ask for the rotation axis and the angle value. In your context, at each camera movement you modify a quaternion. You set it with quaternion.setFromAxisAngle(axis,angle). Then apply it to the plane with plane.setRotationFromQuaternion(quaternion).
Math side :
The axis would be the cross product between the vectors lastCameraPosition-sprite.position and actualCameraPosition-sprite.position,
the angle, the one between those vectors, got with the acos of their dot product divided by the product of their lengths.
For more about those maths, functions getMouseProjectionOnBall and rotateCamera in TrackBallControls are of great interest.
Hope it helped !

Three.js: cause an Object3D to travel parallel to my camera's X axis

Say I have a simple triangle as the only element/child in an Object3D class. I have a PerspectiveCamera looking at it, and I would like to have the Object3D travel down the camera's positive X axis, say, when I press a key.
How can I manipulate things so that the Object3D travels parallel along the camera's X axis? In looking at the inner workings of the PerspectiveCamera, I see members for things like matrixWorld and matrixWorldInverse but am not sure what they represent or how best to use them here.
Can I use the camera's matrixWorldInverse matrix to get the Object3D into camera coordinates, then move the object along the camera's x-axis (which I'm not sure how to find, as I don't see an entry for it in PerspectiveCamera, though I may not be seeing it) then multiply the Object3D by the 'matrixWorld' matrix again to move it back to world coordinates?
Have you tried making your object a child of your camera? Then any movement of the camera would affect your object. And if you place the camera lets say on the y-z plane of your object, then any movement of the object on its x-axis will also appear to be on the x-axis of the camera.

Working with Three.js

Context: trying to take THREE.js and use it to display conic sections.
Method: creating a mesh of vertices and then connect face4's to all of them. Used two faces to produce a front and back side so that when the conic section rotates it won't matter from which angle the camera views it.
Problems encountered: 1. Trying to find a good way to create a intuitive mouse rotation scheme. If you think in spherical coordinates, then it feels like just making up/down change phi and left/right change phi would work. But that requires that you can move the camera. As far as I can tell, there is no way to change actively change the rotation of anything besides the objects. Does anyone know how to change the rotation of the camera or scene? 2. Is there a way to graph functions that is better than creating a mesh? If the mesh has many points then it is too slow, and if the mesh has few points then you cannot easily make out the shape of the conic sections.
Any sort of help would be most excellent.
I'm still starting to learn Three.js, so I'm not sure about the second part of your question.
For the first part, to change the camera, there is a very good way, which could also include zooming and moving the scene: the trackball camera.
For the exact code and how to use it, you can view:
https://github.com/mrdoob/three.js/blob/master/examples/webgl_trackballcamera_earth.html
At the botton of this page (http://mrdoob.com/122/Threejs) you can see the example in action (the globe in the third row from the bottom).
There is an orbit control script for the three.js camera.
I'm not sure if I understand the rotation bit. You do want to rotate an object, but you are correct, the rotation is relative.
When you rotate or move your camera, a matrix is calculated for that position/rotation, and it does indeed rotate the scene while keeping the camera static.
This is irrelevant though, because you work in model/world space, and you position your camera in it, the engine takes care of the rotations under the hood.
What you probably want is to set up an object, hook up your rotation with spherical coordinates, and link your camera as a child to this object. The translation along the cameras Z axis relative to the object should mimic your dolly (zoom is FOV change).
You can rotate the camera by changing its position. See the code I pasted here: https://gamedev.stackexchange.com/questions/79219/three-js-camera-turning-leftside-right
As others are saying OrbitControls.js is an intuitive way for users to manage the camera.
I tackled many of the same issues when building formulatoy.net. I used Morphing Geometries since I found mapping 3d math functions to a UV surface to require v little code and it allowed an easy way to implement different coordinate systems (Cartesian, spherical, cylindrical).
You could use particles instead of a mesh I suppose but a mesh seems best. The lattice material is not too useful if you're trying to understand a surface mathematically. At this point I'm thinking of drawing my own X,Y lines on the surface (or phi, theta lines etc) to better demonstrate cross-sections.
Hope that helps.
You can use trackball controls by which you can zoom in and out of an object,rotate the object,pan it.In trackball controls you are moving the camera around the object.Object still rotates with respect to the screen or renderer centre (0,0,0).

Resources