Three.js custom geometry raycaster catches wrong object - javascript

I need to use my own gemetry since the default cube does not look like it should in wireframe mode (now it is made of triangles instead of squares).
So I made my own geometry and it looks ok, but the raycaster does not work as good with my own objects as it does with the built-in cubes.
var cube = new THREE.Line( getCube( 5,5, 5), new THREE.LineDashedMaterial( { color: 0x000000,dashSize: 1, gapSize: 0.1, linewidth: 2 } ),THREE.LinePieces );
where getCube() returns
var geometry = new THREE.Geometry()
See example:
http://jsfiddle.net/QHjSM/12/
6 colour filled box on the top are the defalt THREE.CubeGeometry boxes, and selecting them with raycaster works perfect, 6 wireframe are my custom geometry.
Issues:
If you try to click outside the box, but pretty close to it it will catch the box, and if you click inside the box (in the middle of it) it will not catch it neither.
But the most annoying thing is that if you click inside one box, but close to another one sometimes it catches not the wrong one.
I'm not sure can it be done better, tried all the geometry.compute... methods, but still no effect.

Good day, your custom cubes are not in fact cubes. They are just a stack of lines with no cooresponding faces. Your selection is not returning as expected due to the fact that your "cubes" indeed have gapping holes right threw them. What you can do is in your getCube function after you've built the vertices you can then build all your faces in a similar way.
Have a look at this example: Issue with custom geometry and face normal
Generally you'll need to carefully pattern out every 3 set of vertices so that when you build the faces there in a clock-wise direction so that the normals will be computerd correctly. Here's a basic example of adding a face.
geometry.faces.push(new THREE.Face3(1,2,3));
BUT! Note that this will result in the same aforementioned diagonal lines through your wireframe. So, for your use case why not simply use both the basic cube mesh with picking and remove the wireframe then overlay the line drawn boxes as your custom wireframe. Best of both worlds.
FYI, you probably already know but Face4 is gone, so you'll need to use Face3 and some sort of custom wireframe to do this anyway.
Edit:
I did a little test to your fiddle, noticed something strange. Using the CanvasRender, even with the wireframe off the default cube you still see the diagonal lines! I try WebGLRenderer and it's fine. I'll have to look into that one further.
CanvasRenderer
http://jsfiddle.net/QHjSM/13/
WebGLRenderer
http://jsfiddle.net/QHjSM/14/
Me again, hmm it appears those ghosted face lines are visible in all the CanvasRenderer examples that use a MeshBasicMaterial on the Three.js site. The only thing I was able to do was simply reduce the opacity of the cube mesh material to 0.1 to lessen the effect. I suppose the only other method is to switch to the WebGLRenderer but I look forward to being wrong on this :) Here's the last test
http://jsfiddle.net/QHjSM/16/

Related

Three.js - Using box3 to scale and translate an object

I'm currently working on a piece of code that loads up a 3D image which initially isn't visible. It is supposed to be visible, however, after scaling and translating it, but no matter what I do, the screen remains black and I cannot see the 3D image.
I won't post the entire code but here's the section about the scaling and translating (the code portions that I've commented out is what I tried to implement as the solution):
const box = new THREE.Box3().setFromObject(object);
// object.scale.set( 2, 2, 2 );
// box.getCenter(object.position);
// object.geometry.center();
scene.add( object );
I'm confused whether I'm misunderstanding Box3, whether it has to do with the order in which I'm scaling/centering, or if it's my values, or something trivial that I'm forgetting to add.
EDIT: I believe that I need to properly size the bounding box around the image, and use that to scale the tiger. I'm still confused about this, because I assumed this line already did that:
const box = new THREE.Box3().setFromObject(object);
So I'm not sure how I can change the size of the bounding box so it is correct, and then scale it to the size I want.

ThreeJS/Panolens: direction of the camera when panorama entered?

I'm trying to throw an equirectangular image into Panolens and simply 1st get the same panorama viewer as can be visible below:
https://threejs.org/examples/webgl_panorama_equirectangular.html
https://www.chiefarchitect.com/products/360-panorama-viewer/
Since Panolens.js is a wrapper of Three.js I expected the same result as when I throw my image into the 1st link above. (drag & drop it) - camera looks into the center of the image.
What I get instead is : camera looks into the left most area of the panorama image.
I solve this using
panorama.addEventListener( 'enter-fade-start', function() {
viewer.getControl().target.set(10, -2, 0);
viewer.getControl().update();
//viewer.tweenControlCenter( new THREE.Vector3(2, -1, 1), 2000 );
});
But when I move to another panorama and come back, this code does not seem to have any effect (althought event is properly triggered).
How can I make the camera look into the same direction each time I come back to my panorama? (I'm switching between multiple panoramas).
Basically I don't seem to understand vectors properly and where 0,0,0 is each time I come back to panorama, since It seems to be working differently based on where the camera is facing.
Any tips/links/explanations very much welcome.
I over complicated things it seems. The solution is to only use:
viewer.tweenControlCenter( new THREE.Vector3(10, -2, 0), 0 );
inside "enter-fade-start". And that's it.
Much of docs is a bit misleading with saying you have to call .update() on control and setting .target properly etc, but that does not seem to work as I expected.
Relevant example also here: https://codepen.io/pchen66/pen/LLgxME

Apply a glow effect onto a THREE.TextGeometry object in Three.js

I have done quite a few hours of google search to see if this can be done
within the three.js environment.
I want to create a glow effect based on a TextGeometry and not a simple primitive like a sphere or cube object similar to the one in Lee StemKoski - shadow glow example below.
I have been reading and experimenting with Lee StemKoski examples
In particular with his Shader Glow example which as stated works well with simple objects but not with complex geometric shapes. Therefore I was wondering if there are any work arounds to this or other suggestions to how one could create a glow effect around text.
regards
w9914420
UPDATE: I decided to go with the mapping concept by attaching an image to the text I can create a glow effect. In this example I used a circle, but should not be too difficult to do a map for the text that I need.
UPDATE: 20/3/17 - So I had an attempt at using the theeX.atmosphere material to create that elusive text glow effect. Here are some of the results.
As you can see not quite there yet - the issue that I have is I am not able to smooth the vertices of the outer glow text more. I am not sure if it is possible any advice appreciated.
Native code used to create effect.
//normal text created
var geometry2 = threeLab.asset.simpleText('hello','my_font');
var materialme = new THREE.MeshNormalMaterial();
var mesh = new THREE.Mesh( geometry2, materialme );
this.scene.add( mesh );
// we create a secondary text object to use as glow
var geometry = threeLab.asset.simpleText('hello','my_font');
// clone for manipulation
var geoclone = geometry.clone();
//Thes functions are need to make it work in this case
geoclone.mergeVertices();
//geoclone.computeCentroids();
geoclone.computeVertexNormals();
geoclone.computeFaceNormals();
// part of threex library to make the glow scale and expand
THREEx.dilateGeometry(geoclone, 0.5);
var materialz = THREEx.createAtmosphereMaterial();
var meshHalo = new THREE.Mesh(geoclone, materialz );
//we have now our glow
this.scene.add( meshHalo );
So In the end I increased the bevelsegments of my secondary TextGeometry object which helped to smooth it. I was then able to encase my first text into the second like so:
With further tweaking I will be able to get the glow effect more subtle, but for now the effect works.
Thank you all for the input :)

three.js intersecting CircleGeometry works when using THREE.Line, but not when using THREE.Mesh

See following fiddle:
https://jsfiddle.net/1jmws2bp/
If you move the mouse over the line or the circle, it should change color to white (works for me, locally, in jsfiddle sometimes there is a bit of an offset, not entirely sure why).
Problem is, that if you change Line 22: to var circle = new THREE.Mesh(geometry, material) the circle is filled out (as intended), but if you now hover it now, it won't update color.
Why is that? If I manually add this:
scene.children[0].material.color.setHex(0xff0000);
it does work. So somehow it looks to me that with a Mesh the RayCaster does not see the intersection. (Verified by adding this line
alert("intersection"); after if (intersects.length > 0) no alert if I use Mesh instead of Line)
If you want to intersect mesh of circle, then remove the line geometry.vertices.shift(); from the newCircle() function.
When you call .shift(), you remove the first element from the array of vertices. Such "shifted" array in a geometry is acceptable for THREE.Line() as it needs vertices only, but not acceptable for THREE.Mesh(), which needs vertices and faces based on vertices.
And also, if you want to use THREE.Mesh() then change the material from THREE.LineBasicMaterial() to THREE.MeshBasicMaterial().

Folding rectangles to form a cube using three.js

I am trying to make a cube with given 6 faces lying on the surface as a cube net with one face movable. Something like this:
In the above picture, there are 6 faces, one face ( blue one) is movable.
One can rotate them up together along their edges to form a “net”.
Once they think they are finished, they can press a “fold it” button – all edges turn up 90 degrees to create the cube (or may not be a cube if he hasn't joined the blue face at proper position.)
Below is intermediate status after pressing "fold it" button.
After the faces are folded it should like this:
The corresponding animation is given here: http://www.mathematikus.de/10/
(somehow that link is not working on mac)
I am not sure how to go about this. Any help is appreciated.
Thanking you in advance.
You can use hierarchy of objects.
var obj1 = new THREE.Mesh(...);
var obj2 = new THREE.Mesh(...);
obj1.add(obj2);
There's a good example of it.
So, using this principle, I made animation for folding the cube, given in your question. Of course, this is not the ultimate solution, this is just a starting point.
jsfiddle example
upd: I've updated the fiddle. You can start folding by clicking the PressMe button. Animation made with Tween.js (see the foldTheCube() function)

Categories