three.js Blender export, object path&rotation - rotation

If someone could help me solve a problem. I wantto get a JSON with animation, traveling at a certain path.
var up = new THREE.Vector3(0,1,0);
var pt,radians,tangent;
var axis = new THREE.Vector3();
var pot = new THREE.SplineCurve3([
new THREE.Vector3(640,360,510),
new THREE.Vector3(650,360,520),
new THREE.Vector3(0,20,0)]);
....
pt = pot.getPoint(stevec);
meshK.position.set(pt.x,pt.y,pt.z);
tangent=pot.getTangent(stevec).normalize();
axis.crossVectors(up,tangent).normalize();
radians=Math.acos(up.dot(tangent));
meshK.quaternion.setFromAxisAngle(axis,radians);
//meshK.eulerOrder='ZYX';
stevec+=0.001;
I'm trying to get a plane like object to fly a certain path.
Thanks

The solution was to add the initial rotation after quaternion is set. I also had to export the JSON with flipYZ flag.

Related

How can I get camera world direction with webxr?

I would like to use camera.getWorldDirection() and access to the head-mounted display directions. I was able to do this with the previous webVR API. When I use the new HelioWebXRPolyfill.js from THREE, I am not able to receive current positions.
According to the WebXR Device API, this should be done using the XRViewerPose object.
This feature is only working using HTTPS.
It seems that calling renderer.xr.getCamera() isn't fully copying the various camera member properties that camera.getWorldDirection() is expecting to find. I'm not sure where this problem originates (perhaps the polyfill?), but you can get around it by computing direction yourself :
let xrCamera = this.renderer.xr.getCamera(sceneCamera)
let e = xrCamera.matrixWorld.elements
let direction = new THREE.Vector3(-e[8], -e[9], -e[10]).normalize()
I came up with a simple fix. Just parent a box to the camera and use the camera box in place of the camera.
camera.add( camerabox );
This doesn't work:
var direction = new THREE.Vector3();
camera.getWorldDirection( direction );
This DOES work:
var direction = new THREE.Vector3();
camerabox.getWorldDirection( direction );
global variable
var cameraVector = new THREE.Vector3(); //define once and reuse it!
in your render loop
let xrCamera = renderer.xr.getCamera(camera);
xrCamera.getWorldDirection(cameraVector);
//heading vector for webXR camera now within cameraVector

threejs - creating 3d perspective for a line

I'm working on an app where I visualize ATV trails in a 3d perspective (NAIP imagery draped over elevation data). I am using three.js for the rendering engine.
In the above image, the white line you see is just a THREE.Line instance, where I convert a trails gps coordinates into threejs coordinates. I'd like to add more of 3d perspective to this line. I tried implementing a THREE.TubeGeometry where the path was a THREE.CatmullRomCurve3 using the same Vector3 points as how I built the line you see in the image above. That did not produce a desirable result...
From the many, many THREE examples I have looked at, I really think an extruded geometry would achieve the look I am after... But I cant for the life of me figure out how to extrude a geometry for the line. Any suggestions/thoughts?
UPDATE 1:
Here is my desired look (same trail - no imagery). This image was produced in QGIS using the Q2Threejs plugin
UPDATE 2: Here is a code of how I have attempted to create a tubegeometry. Maybe I am messing something up in there...
// trailVectors are an array of Vector3 - same as ones used to create line
var trailCurve = new THREE.CatmullRomCurve3(trailVectors);
var tubeGeometry = new THREE.TubeGeometry(trailCurve,80,1,15,false);
var material = new THREE.MeshBasicMaterial({color:0x00ff00});
var tubeMesh = new THREE.Mesh(tubeGeometry,material);
var wireframeMaterial = new THREE.LineBasicMaterial({color:0xffffff,lineWidth:2});
var wireframe = new THREE.Mesh(tubeGeometry,wireframeMaterial);
tubeMesh.add(wireframe);
scene.add(tubeMesh);
UPDATE 3
THREE.TubeGeometry(trailCurve,80,4,2,false) per mzartman request
I think that you should be able to achieve what you want with a TubeGeometry. I think the big thing is that your example (from the picture shown) has more than 2 radius segments. That gives it the tubular shape and makes it look sort of like a blob. If you set the radial segment count to 2 (as it's shown below) then I think it would look a lot better.
tubeGeometry = new THREE.TubeBufferGeometry(
[YOUR_PATH_HERE],
params.extrusionSegments, // <--- Edit this for higher resolution on the spline
3, // <--- This defines the height
2, // <--- This 2 keeps 2D (i.e. not a tube!!!!)
true );
var mesh = new THREE.Mesh( geometry, material );
var wireframe = new THREE.Mesh( geometry, wireframeMaterial );
mesh.add( wireframe );
scene.add( mesh );
Update:
I think that you might do better with a material that shows some shadow like the MeshPhong. Also, to do the wireframe you want to add it as an option in the material initialization. Give it a show with the following:
var tubeGeometry = new THREE.TubeGeometry(curve,80,1,2,false);
var material = new THREE.MeshPhongMaterial({color:0x00ff00, wireframe: true});
var tubeMesh = new THREE.Mesh(tubeGeometry,material);
scene.add(tubeMesh);

Why am I still getting gimbal lock in THREE.js with the following code that utilizes quaternions?

I am trying to have the camera orbit around an arbitrary axis in world space. I've already spent so many hours trying to solve this issue without luck. I do not want to add a library like THREE.OrbitControls just to have this feature. Can anyone tell me what I'm doing wrong in the following code?
Camera.prototype.orbit = function(axis, spd, pt) {
var axis = axis.normalize(),
currCamQuaternion = new THREE.Quaternion(this.position.x, this.position.y, this.position.z, 0),
rotQuaternion = new THREE.Quaternion();
rotQuaternion.setFromAxisAngle(axis, spd);
var halfCamQuaternion = rotQuaternion.clone().multiply(currCamQuaternion),
fullCamQuaternion = halfCamQuaternion.clone().multiply(rotQuaternion.clone().conjugate());
this.position.copy(new THREE.Vector3(fullCamQuaternion.x, fullCamQuaternion.y, fullCamQuaternion.z));
this.lookAt(pt);
}

Making portals with ThreeJS

Im trying to make portals with ThreeJS. I found this page Mini-Portals That explains how to make portals with OpenGL. So i tried to replicate the portal view function in TJS. Now this is my result:
The left portal(right camera) is normal camera and right portal(left camera) is the view matrix gotten from tutorial. As you can see the portal view on the right is quite weird.
The main issue here is that the scaling of the images is all wrong and the angle im seeing the images in portal is wrong. Currently its flat and show where i pointed the camera, but what i want is portal where the scaling is correct(image on portal is same scale as the world itself) and what is see in portal depends on the angle where im watching.
What am i doing wrong and what should i do to fix it?
For people who want a great Portal system with Three.js :
https://github.com/markotaht/Portals
Its been a while. But i have found a way to do what i needed. The 4th parameter in not needed. Basically i send camera, and my 2 portal objects(Meshes) to my function. Instead of using the matrix multiplication way(does not work in ThreeJS because ThreeJS does some weird stuff with it) I split the matrices into pieces. Then manually calculate the new position and rotation and construct the new matrix from it. And i set this new matrix as my cameras worldMatrix. Voila a working portal. Next step is oblique view fusrum, because we want our nearplane to be the portal otherwise we can have some objects between the camera and portal.
And the rendering procedure itself uses stencil buffer to render the portals correctly. If anyone needs, this will help you: https://th0mas.nl/2013/05/19/rendering-recursive-portals-with-opengl/
function portal_view(camera, src_portal, dst_portal, kordaja) {
src_portal.updateMatrixWorld()
dst_portal.updateMatrixWorld()
camera.updateMatrixWorld()
var camerapos = new THREE.Vector3();
var camerarot = new THREE.Quaternion();
var camerascale = new THREE.Vector3();
camera.matrix.decompose(camerapos,camerarot,camerascale);
var srcpos = new THREE.Vector3();
var srcquat = new THREE.Quaternion();
var srcscale = new THREE.Vector3();
src_portal.matrix.decompose(srcpos, srcquat, srcscale);
var destquat = new THREE.Quaternion();
var destpos = new THREE.Vector3();
var destscale = new THREE.Vector3();
dst_portal.matrix.decompose(destpos,destquat,destscale);
var diff = camerapos.clone().sub(srcpos);
var ydiff = src_portal.rotation.y - dst_portal.rotation.y - Math.PI;
diff.applyAxisAngle(new THREE.Vector3(0,1,0),-ydiff);
var newcampos = diff.add(destpos);
var yrotvec = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,1,0),-ydiff);
console.log(yrotvec)
srcquat = srcquat.multiply(destquat.inverse());
camerarot = camerarot.multiply(yrotvec);
var inverse_view_to_source = new THREE.Matrix4();
inverse_view_to_source.compose(newcampos,camerarot,camerascale);
return inverse_view_to_source;
}
NOTE:
I moved my answer to the answers so i can mark an answer.

How to fix tiny holes in the Mesh after subtract operation with Three.CSG

I have a Box Mesh where I subtract another Box with Three.CSG to create a wall with a window.
After doing so, there are tiny holes in the Mesh alongside the cut. They are not visible alle the time, but show up when moving around.
How to close these holes?
This is part of the code how I am creating the Mesh:
var wallBsp = new ThreeBSP( myWallMesh );
var subMesh = new THREE.Mesh( mygeo );
var subBsp = new ThreeBSP( subMesh );
var subtract_bsp = wall_bsp.subtract( subBsp );
var result = subtract_bsp.toMesh();
result.material.shading = THREE.FlatShading;
result.geometry.computeVertexNormals();
Update
I have created a jsfiddle, but it is difficult to reproduce the error, I couldnt make it visible there: http://jsfiddle.net/L0rdzbej/23/
However, you can see the full application here.
Like #gaitat suggested, geometry.mergeVertices() does not look like it changes anything for me. Chandler Prall hinted at the source where precisionPoints, which is a variable inside the mergeVertices function, could solve this. Depending on the scale of the scene its value should be lower or negative, but I had no success so far.

Resources