three.js - scaling/transforming of tube geometry - three.js

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.

Related

Threejs Rotate around sphere normal to surface with heading

I have a scene where the user can rotate an object around the surface of the sphere, keeping its local Z axis normal to the surface. Heres a JS fiddle, with sliders at the top to rotate around the sphere.
https://jsfiddle.net/dftroy58/14/
This works fine, but now I want to be able to apply a heading to the object, essentially rotating it along its Z axis. At 0 degree heading, the Y axis should point up towards the north pole of the sphere.
I tried to set therotation.z of the object which works when the latitude is 0 degrees, but moving around the sphere, it then rotates where X becomes up at 90 degrees, -Y at 180 and -X at 270.
marker.rotation.z = THREE.Math.degToRad(Number.parseFloat(heading.value, 10));
With that line commented out, the Y axis always points up. How do I get it so I can set the local Z rotation such that it points to the north pole at 0 degrees, but is rotatable by the user?
I could solve this by instead of rotating the marker, change it to axesHelper.rotation.z. This ends up working, but I'd like to remove the axes helper and want to just understand these kind of transformations more.
// Works but I want to avoid this
axesHelper.rotation.z = THREE.Math.degToRad(Number.parseFloat(heading.value, 10));
How would I, without nesting another object, calculate the correct the Z rotation to keep the heading the same as you change latitude?

How do I place an element in front of the camera, facing it regardless of where it is?

I have this simple scene with a "tooltip" entity composed of some data, I'd like to know how to position it in front of the camera. The tooltip will have to face certain points a few meters away so the user can see it. It must obey camera direction (it can be gathered by calculating it from previousPoint to nextPoint where the camera will move), but only y axis (can't be tilted or anything like that).I tried digging through math but couldn't understand good enough to employ a solution for this little project; I appreciate all the help!
setTimeout(function(){
var camera = document.getElementById("cameraS");
var tt = document.getElementById("ttS");
var cameraPos = camera.getAttribute('position');
var ttPos = tt.getAttribute('position');
tt.setAttribute('position', cameraPos);
tt.setAttribute('rotation', {'y': -90});
}, 5000);
JSFiddle
EDIT
I made an image showing what I'm after: http://imgur.com/a/eDhqE
I have point A and point B; the camera will play an animation moving from previous point to the next, and upon reaching there the tooltip will be displayed a few meters away from the point (box) so we can see it. It must take camera orientation into consideration but it must be perpendicular to the ground (can't be tilted).
There is a command THREE.Object.lookAt(THREE.Vector3); that will rotate an object (assuming (0.0,1.0,0.0) is up) to face a vector. You can use this to have it face your camera.
If you only want Y rotation, you can copy the current rotation, then do look at, then copy the rotation.x and rotation.z from the previous frame rotation copy - so that way it'll only correct the y with .lookAt because you reset x and z.

Libgdx decal rotation around custom axis

I'm working app that uses Libgdx engine and decals in 3d space.
Now I need to rotate decals around X,Y,Z axis, but around custom pivot point that stands somewhere in the 3d space.
I found that decals have transformationOffset field, which might work with some calculations, but is Vector2 only. It means that I can move pivot point only over X and Y axis.
And when rotating decals over Y axis, wherever the pivot is, the result is the same.
decal.transformationOffset = new Vector2(0, -5);
decal.rotateX(newValues[0]);
decal.rotateY(newValues[1]);
decal.rotateZ(newValues[2]);
I need to move pivot over Z axis, too.
Is there some workaround for this issue?
Tnx!
EDIT:
I have succeded to rotate decal over pivot point in 3d space, but only if pivot's and decals's Z position is the same. If they are not I don't get what I've expected.
This is the code that works for pivot with same Z value:
decal.transformationOffset = new Vector2(pivotPosition.x - decal.getPosition().x, pivotPosition.y - decal.getPosition().y);
Tween.to(decal, DecalTween.XYZ_ROTATION, 5f).target(0, 360, 0).repeatYoyo(Tween.INFINITY, 0f).start(tweenManager);
And in tween I do this:
target.setRotationX(0);
target.setRotationY(0);
target.setRotationZ(0);
target.rotateX(newValues[0]);
target.rotateY(newValues[1]);
target.rotateZ(newValues[2]);
How to extend this to use and Z value for pivot. I'm trying to add and translation animation beside rotate to achive this, but the results is weird.
Tween.to(decal, DecalTween.MOVE_XYZ, 2.5f).target(decal.getPosition().x, decal.getPosition().y, pivotPosition.z - decal.getPosition().z).repeatYoyo(Tween.INFINITY, 0f).start(tweenManager);
decal.transformationOffset = new Vector2(pivotPosition.x - decal.getPosition().x, pivotPosition.y - decal.getPosition().y);
Tween.to(decal, DecalTween.XYZ_ROTATION, 5f).target(0, 360, 0).repeatYoyo(Tween.INFINITY, 0f).start(tweenManager);
Any idea how to combine translate and rotate animatio to get decal rotation in circle path over the pivot point?
I will answer my own question I guess.
I have extended Decal class, changed transformationOffset to Vector3.
Then in transformVertices I have added tz value, like there already was tx and ty. And add tz in calculation for vertex position.
Simple as that.
If anyone knows why is this left out from native libgdx support, please let me know.
Cheers.

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?

jmonkey rotate and change forward direction?

How does one rotate a model and change the forward direction of it with the rotation?
I rotate but it just rotates on the axis and the forward is still the same.
This is probably a noob question but it's been kicking me buttocks.
You can use look at method to rotate your spatial to a target point. Below sample makes a spatial look at camera with up vector 1,0,0
spatial_x.lookAt(cam.getLocation(),new Vector3f(1,0,0));
If you just want to rotate about x axis for 0.2 radians:
spatial_x.rotate(0.2,0,0);
Y axis for 1 radian and Z axis for 3 radians:
spatial_x.rotate(0,1,3);

Resources