geometry.mergeVertices() only at render time - javascript

Is it possible to merge vertices only at render time? I'm doing a series of morphs which requires the vertex list to stay the same, however I want to merge the vertices to get a smooth reflection on a cube camera. Any one aware of a command similar to unmerge vertices?

Have you tried doing it? It should work.
You'll need to call
geometry.verticesNeedUpdate()
geometry.elementsNeedUpdate()
to tell three.js that the vertices and faces, respectively, have changed. There are other update functions you may need to call too (for instance if normals have changed). More details here: https://github.com/mrdoob/three.js/wiki/Updates
Note the comment on that page that the total number of vertices can't change. This may require you to do the merge on a temp geometry and then copy the vertices to your rendered geometry.

Alright, this is not in the documentation section, but you need to use the explode modifier as demonstrated in this example: http://threejs.org/examples/#webgl_geometry_tessellation
var explodeModifier = new THREE.ExplodeModifier();
explodeModifier.modify( geometry );
geometry.computeFaceNormals();
geometry.computeVertexNormals();
//This will undo the geometry.mergeVertices();

Related

Mesh is not updating when changed from gui in threejs

I made a line mesh with elliptical shape, representing the orbit wiht eccentricity e, and semi-major axis a. The mesh is a child of a group called orbitGroup that contains other objects.
Also, I added a gui to change this parameters. Every time gui changes it calls the next function:
function ElementsUpdate(){
scene.remove(orbitGroup);
orbitGroup.remove(Orbit);
Orbit = undefined;
Orbit = new THREE.Line( GetGeometryOrbit(GetOrbitLine(a,e,100)), materialOrbit);
orbitGroup.add(Orbit);
scene.add(orbitGroup);
}
The mesh (Orbit) is being created successfully. However the it does not update. I'm aware that setGeometry method is not working anymore. Any solution? I am replacing the mesh because replacing only the geometry seems to be more complicated.
Thanks beforehand for the help.
The project is in this link
You should be able to replace the vertex (position) buffer and call it a day.
function ElementsUpdate(){
let points = GetOrbitLine(a,e,100).getPoints(); // THREE.Curve.getPoints
Orbit.geometry.setFromPoints( points ); // replaces the position buffer
}
Curve.getPoints gives you an array of the points on your elipse.
BufferBgeometry.setFromPoints replaces the position buffer, derived from your array of points.
Because it replaces the buffer (and the BufferAttribute) You should not need to mark anything as needing re-sent to the GPU.

Three.js: how to force update matrix after cloning? (to use with CSG ThreeBSP)

I'm trying to clone and then scale a mesh, but scaling does not seem to be working immediately on the cloned object, for programming purposes using CSG ThreeBSP. I think I should call a function after the scaling to force the matrix or other internal variables to recalculate immediately and not to wait for the full update loop on render side.
My code looks something like this:
var someMesh2 = someMesh1.clone();
someMesh2.scale.set(2,2,2);
someProgrammingOperation(someMesh2);
//It turns out that internally, someMesh2 still has the same properties (matrix?) as someMesh1 :(
What am I missing? Suggestions are also welcomed :)
object.matrix is updated for you by the renderer whenever you call renderer.render().
If you need to update the object matrix manually, call
object.updateMatrix();
and it will update the matrix from the current values of object.position, object.quaternion, and object.scale.
(Note that object.rotation and object.quaternion remain synchronized. When you update one, the other updates automatically.)
three.js r.84
In the end, my problem was that the CSG ThreeBSP object needed to work based on the Geometry of the object, not in the Mesh itself. I applied the scaling on the Geometry and it worked as expected.
There is a caveat though, that one should be careful as with the meshes and geometries instances, therefore is needed to do some cloning in order to keep the original objects as they were, as in the following example:
var clonedMesh = original.mesh.clone()
var clonedGeometry = clonedMesh.geometry.clone()
clonedMesh.geometry = clonedGeometry
clonedMesh.geometry.scale(2,2,2)
var someBsp = new ThreeBSP( clonedMesh )
var newMesh = someBspBsp.toMesh()
someScene.add newMesh

ThreeJS: How to remove vertices?

Adding new vertices to a three.js mesh goes by mesh.geometry.vertices.push(new THREE.Vector3(x, y, z)), but how do I remove them?
"geometry" is an array, so I thought, I could remove vertices with:
mesh.geometry.vertices.splice(vertexIndex, 1)
mesh.geometry.verticesNeedUpdate = true;
But when I do that, that whole thing breaks with three.js internal error messages that say: "Uncaught TypeError: Cannot read property 'x' of undefined" inside three.min.js.
I searched their wiki, their github issues. And can't find an answer to this. The mesh is a simple BoxGeometry, so not even a custom one.
In threejs each face is made of 3 vertices. Here is an example to make it clearer. Here is how you create a geometry in r71 :
geometry=new THREE.Geometry();
geometry.vertices.push(// few vertices with random coordinates
new THREE.Vector3(12,15,5),//index:0 -- the numbers are (x,y,z) coordinates
new THREE.Vector3(10,15,5),//index:1
new THREE.Vector3(12,10,2),//index:2
new THREE.Vector3(10,10,2)//index:3
);
geometry.faces.push(
new THREE.Face3(0,1,2),//those numbers are indices of vertices in the previous array
new THREE.Face3(0,3,2)
);
geometry.computeFaceNormals();// we won't care about this here
(I did not care about the values so i do not know which shape it can give)
What you can see is that two arrays are built : vertices and faces. Now what happens at each frame is that each face is 'drawed' with the position of its vertices.
You ask what is wrong by deleting a vertex in the geometry.vertices array : let's imagine the second vertex above is deleted. The array now looks like this :
geometry.vertices=[
THREE.Vector3(12,15,5),//index:0
THREE.Vector3(12,10,2),//new index:1
THREE.Vector3(10,10,2)//new index:2
];
There is no more vertex at index 3. So when the GPU will draw the next frame, if a face points to it (here the second face) it will try to access its coordinates (first x before y and z). That is why the console returns that it cannot read x of undefined.
Here was a long explanation of the error. You can see the vertex deletion also shifted the array so faces do not have the correct shape, and their normals do not correspond anymore. The worst is that the buffer will have to change and that is simply not allowed, as stated there for example :
Dynamically Adding Vertices to a Line in Three.js
Adding geometry to a three.js mesh after render
The solution is to use tricks, as quoted : modify your vertex coordinates, hide faces... this depends on what you want to do.
If your scene has not much vertices you can also remove the previous mesh and create a new one with a new geometry, without one vertex and with a corrected face array.

ThreeJS: loading OBJ files keeping quadrilateral faces

Is it possible to load an OBJ file under ThreeJS keeping the quadrilateral faces? Here is an example:
http://www.professores.im-uff.mat.br/hjbortol/disciplinas/2014.2/hwc00001/test/threejs/viewer-04/viewer-04-b.html
Note that each quadrilateral face is rendered as two triangles in wireframe. I would like to keep the original quadrilateral faces, as shown here (in Java):
http://www.uff.br/cdme/triplets/triplets-html/triplets-en.html
And what about a general n-polygon face in OBJ files? Is it possible to keep it?
Thanks, Humberto.
Unfortunately everything gets translated to triangles. However, you may be able to achieve the results you are after with this code:
var edges = new THREE.EdgesHelper( mesh );
scene.add( edges );

Making a rotation around a point

I'm using THREE API in order to realize some animations in my app. Now i have a real problem : i'd like making spherical rotation around a specific point. The "rotate" method included in mesh objects allow me to make them, but the center of the rotation is (by default i guess) the center of the mesh.
Then, i only rotate my objects around themself...
I have already found some examples, but they don't solve my problem. I tried to create objects 3D parents like groups, and tried to make the rotation around this groups after having translated them, but this still does not work...
Can you please give me a hand about that ?
I'm so sorry, i found my problem... Making a jsfiddle made me realize i forgot to instanciate my parent as " a new Object 3D() ", that was why i didn't see any objects in my scene when i used animation on my parent... i give you a short part of my code anyway dedicated to interested people finding any help :
// mesh
mesh = new THREE.Mesh( geometry, material );
parent = new THREE.Object3D();
parent.add(mesh);
// if i want my rotation point situated at (300;0;0)
parent.position.set(300,0,0);
mesh.position.set(-300, 0, 0);
scene.add(parent);
http://jsfiddle.net/KqTg8/6/
Thank you

Categories