Three.js - how to set childnode position based on parent rotation? - javascript

I have a THREE.Group() object which contains several child nodes. I also have a raycaster that is connected to users mouse pointer so that the user can select objects in the group by clicking on them. The user can control the position and rotation of the object relative to the camera using their mouse (like orbit controls but instead of the camera moving, the group is moving/rotating).
My issue is that once some rotation has been applied to the group of child nodes, the raycaster stops working correctly. it will select an object that is no where near the mouse position. Im assuming this is just because the childnodes are just inheriting their position/rotation from the parent node, and not actually changing their own position/rotation matrices?
Is there a way to fix this?

Related

Create Trioka Text that move with Object3D in Threejs

My application consists few hundreds of threejs box mesh moving randomly, each with different attributes (e.g. box id etc.). I would like to create an attribute label/tag for each box, and have these labels move along with the box it is associated with.
I tried to have this done by creating a text mesh using Text() constructor in troika-three-text, and group the text mesh with one of the box instances. But an error appears saying text mesh is not an Object3D, thus cannot be called for 'group' function. Similar error received when I tried to move the text mesh with .position.x/y/z function. According to documentation, it seems Troika text mesh can only be repositioned by accessing anchorX and anchorY properties, but how about movement in Z axis? Appreciate if I could have advise on the steps required to associate troika 3d text to a moving 3D object in threejs.
Thank you.

Three.js - Is there any way to use a selection box with the Raycaster?

I have a GLTF scene where I've experimented with the example selection box (code) to select multiple meshes.
However, the results are inaccurate because it picks based on the centroid of each mesh and also gets meshes that are not visible by the camera (viewing one side of a house model selects all the walls in the direction of the box).
I've also experimented using the Raycaster, and it works great for picking with the mouse/pointer.
Is there any way to use a selection box or two Vector3 (starting and ending point of the box) with the Raycaster?
You can use a Raycaster to create a Frustum.
Create two Plane objects to represent your camera's near anf far planes.
Use the Raycaster to intersect your selection area's start/end points against the Plane objects.
Use the intersection points to define the Frustum.
Use Frustum.containsPoint and Frustum.intersectsObject to see if a particular object is within your selection area.

HTML pan and tilt input control

I'd like to create an input that allows the user to drag a dot around a box and will output the 2D coordinates of that dot inside the box. This will be used to drive pan and tilt values. The picture below shows the functionality I'd like from another application:
I'd like to use this in a web application with HTML and Javascript. The center (0,0) coordinate should be in the middle of the box (where the crosshairs meet in the example above). May I have some guidance as to how to start going about creating this type of thing?
This can be done in pure HTML and JS, although this problem is not a simple one so I'll just point you in the right direction.
First create a container (div) to represent the 2D grid, and dot using HTML/CSS. You can calculate the co-ordinates of the dot in relation to the container using HTMLElement.offsetTop() (although this will be co-ordinates from the top-left of the container, so you will need to do some maths if you want it to be from a different point).
For the actual dragging to happen, you will need to add mouse events (would be easiest to use jQuery for this), such as mousedown, mousemove and mouseup.
Your mousedown event will check that the mouse is over the dot when pressed, and if so, set a 'dragging' flag to true.
Your mousemove will check the cursor position whenever moved (if dragging === true), and use the mouse position to calculate co-ordinates in relation to the box (using the mouse's position in relation to the box position, which will require some maths skills). You can also alter the position of the dot to follow your mouse with CSS (if the dot has position:absolute style applied, you will set the top and left properties using HTMLElement.style.
Finally, mouseup will set the 'dragging' flag to false.
Like I said, this will take some time to implement and you may not do it exactly like this, but here's a basic example.

three.js drag and drop tracking

I want to track objects in dragging and dropping to have info about from where the object is dragged and to where it is dropped, how can I make that possible?
The actual cause is that I'am developing a game where I should track the source and destination points, I should verify success only if the any shape is taken and placed from and to a particular place only.
raycaster gives a intersection array but that is to intersection from cursor, not any other object.
This page from script tutorials can be taken for example : https://www.script-tutorials.com/demos/467/index.html

How can I implement ZoomAll functionality from any camera angle in Three.js?

I have a scene with many Object3D objects containing blocks, cylinders and meshes. I also have a perspective camera and use trackballcontrols. What I need is a way to set the camera position without modifying the FOV or the camera angle and insure that all objects in the scene are visible on screen. I have successfully done this with preset top, bottom, left and right views using the bounding box of the entire scene, but I need this to work from any camera angle since the user can rotate the view using trackball controls into any position.
If there were a way to get a 2d bounding rectangle based on the camera position, target and the list of objects, I think I could get it to work, but I am having trouble finding how to do this.
The functionality would work like this: With a scene containing many objects, the user rotates the camera with the mouse to some arbitrary position and then clicks a "Zoom All" button. Then, the camera is zoomed(moved) out or in(keeping FOV constant) to make all objects fit to the screen.
How about rotate and translate the whole szene, so that the camera lies on an axis looking at the origin.
From there get the bounding box, calculate the needed distance for the camera and translate the camera.
Then rotate and translate the whole szene back.

Categories