Absolute, world rotation values for a camera - three.js

I can only access rotation values for my camera relative to its last value or as 0 to -90, -90 to 0, 0 to 90 and 90 to 0.
I would like a straight up 0 to 360 or even a 0 to 180 and 0 to -180 so I can calculate the absolute rotation of my camera about the y axis at any time. No code as this is conceptual. Any assistance is gracefully received, likely a simple answer and I'm missing something and must say mrdoob, blooming legend thanks for all the hard work.

This post answered my question perfectly
How to derive "standard" rotations from three.js when using quaternions?
I may have missed some tools built into three that do this in a more efficient manner but this was bang on and gave me the absolute world camera orientation I was after.
#Martin thanks for chipping in bud

Related

Is "initialMovementHeading" limited in any way or can I just pick up to 360° direction? Can it be a bug?

I'm adding a couple of hosts on a map. I'd like to move one of them in direction e.g. -30° so I tested the function with 330° but it's only moving on the upper semi-plane considering [0°, 180°] the horizon. When I set 200°, 270°, etc I see the host moving in the upper direction, different degrees.
I looked into the classes and found in "inet/mobility/single/LinearMobility.cc" the method that I think handles the parameter.
https://github.com/inet-framework/inet/blob/master/src/inet/mobility/single/LinearMobility.cc
Following this tutorial: https://www.youtube.com/watch?v=9xDqjRd1DpA&list=PLaBPUIXZ8s4AwAk5EelikvvyG4EzX2hpx&index=5&t=181s
I also tried negative speed hoping to outsmart the problem but nothing.
Any hint? Did I just get wrong the function?
Thanks in advance.
It is not limited, you can pick any direction.
The angle is measured from the X axis clockwise (so 0 degree is to the right, 90 deg is downwards, 180 deg to the left, 270 deg upwards).
So in this sense, movement with any angle between 180 and 360 would be in the upper plane.

How to loop A-Frame animation forever using duration attribute

I have a earth object that I would like to rotate using animation in A-frame.
I just want the object to rotate forever and I don't know how to do it.
Below is my code thanks!
<a-sphere rotation="45 0 0" position="-44.277 50 -80.933" radius="30" src="images/earth.png" roughness="0.6">
<a-animation attribute="rotation"
easing="linear"
dur="10000"
to="0 360 0"
repeat="indefinite">
</a-animation>
</a-sphere>
That code is correct. It will take 10,000 ms (10 seconds) to complete 1 rotation, and it will repeat indefinitely ("forever"). I just tested the code and it works. If the earth.png texture isn't appearing, it may be difficult to see the sphere rotation. If you use the same code on an <a-box>, for example, it's much more obvious.
That said, since you have the rotation for the <a-sphere> set to 45 along the x axis and have the <a-animation> set to rotate to 360 over the y axis, it will not rotate in a linear fashion.
This can be remedied by adding a container <a-entity> element and setting the default position and rotation on that entity, removing it from the <a-sphere>, which will now be positioned relative to its container.
Here is demo: https://codepen.io/dansinni/pen/MVgqxd
Note that I had to use a different texture for the Earth.

Gimbal lock at y axis 90 degrees

I found a problem with rotations.
Using the transform controls helper, if I rotate a mesh on the Y axis, when I reach 90 degrees everything is flipped by -180 degrees.
I think this is due to the software avoiding gimbal lock, how to avoid it?
That is, I would like the x- and z-angles to remain 0 degrees in the display.
I tried even on the threejs editor (https://threejs.org/editor/) and it occurs even there.
Please help me :)!
What you are describing is has nothing to do with Gimbal lock.
three.js is quaternion-based. An equivalent Euler angle representation is provided for convenience.
Euler angles are not unique; there are many Euler angles that represent the same orientation. See this answer for info on how Euler angles work in three.js.
If you want to rotate an object on the y-axis only, and have object.rotation.y be continuous, you can do so by changing the rotation order like so:
object.rotation.order = 'YXZ';
three.js r.87

Can't center a 3D object on screen

Currently, I'm taking each corner of my object's bounding box and converting it to Normalized Device Coordinates (NDC) and I keep track of the maximum and minimum NDC. I then calculate the middle of the NDC, find it in the world and have my camera look at it.
<Determine max and minimum NDCs>
centerX = (maxX + minX) / 2;
centerY = (maxY + minY) / 2;
point.set(centerX, centerY, 0);
projector.unprojectVector(point, camera);
direction = point.sub(camera.position).normalize();
point = camera.position.clone().add(direction.multiplyScalar(distance));
camera.lookAt(point);
camera.updateMatrixWorld();
This is an approximate method correct? I have seen it suggested in a few places. I ask because every time I center my object the min and max NDCs should be equal when their are calculated again (before any other change is made) but they are not. I get close but not equal numbers (ignoring the negative sign) and as I step closer and closer the 'error' between the numbers grows bigger and bigger. IE the error for the first few centers are: 0.0022566539084770687, 0.00541687811360958, 0.011035676399427596, 0.025670088917273515, 0.06396864345885889, and so on.
Is there a step I'm missing that would cause this?
I'm using this code as part of a while loop to maximize and center the object on screen. (I'm programing it so that the user can enter a heading an elevation and the camera will be positioned so that it's viewing the object at that heading and elevation. After a few weeks I've determined that (for now) it's easier to do it this way.)
However, this seems to start falling apart the closer I move the camera to my object. For example, after a few iterations my max X NDC is 0.9989318709122867 and my min X NDC is -0.9552042384799428. When I look at the calculated point though, I look too far right and on my next iteration my max X NDC is 0.9420058636660581 and my min X NDC is 1.0128126740876888.
Your approach to this problem is incorrect. Rather than thinking about this in terms of screen coordinates, think about it terms of the scene.
You need to work out how much the camera needs to move so that a ray from it hits the centre of the object. Imagine you are standing in a field and opposite you are two people Alex and Burt, Burt is standing 2 meters to the right of Alex. You are currently looking directly at Alex but want to look at Burt without turning. If you know the distance and direction between them, 2 meters and to the right. You merely need to move that distance and direction, i.e. right and 2 meters.
In a mathematical context you need to do the following:
Get the centre of the object you are focusing on in 3d space, and then project a plane parallel to your camera, i.e. a tangent to the direction the camera is facing, which sits on that point.
Next from your camera raycast to the plane in the direction the camera is facing, the resultant difference between the centre point of the object and the point you hit the plane from the camera is the amount you need to move the camera. This should work irrespective of the direction or position of the camera and object.
You are playing the what came first problem. The chicken or the egg. Every time you change the camera attributes you are effectively changing where your object is projected in NDC space. So even though you think you are getting close, you will never get there.
Look at the problem from a different angle. Place your camera somewhere and try to make it as canonical as possible (ie give it a 1 aspect ratio) and place your object around the cameras z-axis. Is this not possible?

three.js - scaling/transforming of tube geometry

I've a tube geometry with 174 points, 12 radius segment, 100 radius and 174 segments.
When I double click at any part of a tube, the scaled portion of a tube with +/- 8 points will be displayed.
Now the issue is when I click at bending part of a tube, the scaled portion does not look as good as I click on a straight part of a tube.
Please find below the 2 images.
Please find jsfiddle here.
Please find below the code of scaling.
tube = new THREE.TubeGeometry(extrudePath, segments, 100, radiusSegments, closed, debug);
tube.dynamic = true;
tube.computeBoundingBox();
console.log(tube);
tube.scale.x = tube.boundingBox.max.x;
tube.scale.z = tube.boundingBox.max.z;
Is there anyway to scale it properly or transform that bending portion into cylinder so that it looks like the straight portion of a tube ?
I think the scaling you are doing is improper. Since the section you are trying to scale may not have its axis along the y axis, scaling the x and z parameters only will result in distortion. Is it possible to know the axis of the section? Then there are 2 ways -
1) Rotate the section so the axis is aligned with y axis, scale x and z coordinates and rotate the section back.
2) Come up with a formula to scale a cylinder with axis in arbitrary direction.
Since this is a very old question you probably have the answer already. Please let me know if I am wrong and what worked for you.

Resources