Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a custom mesh on THREE.JS?

I've asked this and got the answer:

var geom = new THREE.Geometry();  var v1 = new THREE.Vector3(0,0,0); var v2 = new THREE.Vector3(0,500,0); var v3 = new THREE.Vector3(0,500,500);  geom.vertices.push(new THREE.Vertex(v1)); geom.vertices.push(new THREE.Vertex(v2)); geom.vertices.push(new THREE.Vertex(v3));  var object = new THREE.Mesh( geom, new THREE.MeshNormalMaterial() ); scene.addObject(object); 

I expected this to work but it didn't.

like image 899
MaiaVictor Avatar asked Feb 12 '12 21:02

MaiaVictor


People also ask

What is a mesh in three js?

A Three. js Mesh is a base class that inherits from Object3d and is used to instantiate polygonal objects by combining a Geometry with a Material. Mesh is also the base class for the more advanced MorphAnimMesh and SkinnedMesh classes.

How do I get bounding box 3 in JavaScript?

If you want the bounding box position and size as the object appears in the scene, try the BoundingBoxHelper: var helper = new THREE. BoundingBoxHelper(someObject3D, 0xff0000); helper. update(); // If you want a visible bounding box scene.


1 Answers

You've added vertices, but forgot to put those vertices into a face and add that to the geometry:

geom.faces.push( new THREE.Face3( 0, 1, 2 ) ); 

so your snippet becomes:

var geom = new THREE.Geometry();  var v1 = new THREE.Vector3(0,0,0); var v2 = new THREE.Vector3(0,500,0); var v3 = new THREE.Vector3(0,500,500);  geom.vertices.push(v1); geom.vertices.push(v2); geom.vertices.push(v3);  geom.faces.push( new THREE.Face3( 0, 1, 2 ) );  var object = new THREE.Mesh( geom, new THREE.MeshNormalMaterial() ); scene.addObject(object); 

The idea is that a Face3 instance references 3 vertices(the x,y,z coords you've added previously to the geometry) by using the indices of the vertices in the list/array. Currently you only have 3 vertices and you want to connect them,so your face references index 0,1 and 2 in the vertices array.

Since you're using a mesh normals material, you might want to compute normals for the geometry. Also, make sure your object can be visible (is not to big or to close to the camera to be clipped out, is facing the right direction - towards the camera, etc.) Since you're drawing in the YZ plane, to see your triangle, something like this should work:

var geom = new THREE.Geometry();  var v1 = new THREE.Vector3(0,0,0); var v2 = new THREE.Vector3(0,500,0); var v3 = new THREE.Vector3(0,500,500);  geom.vertices.push(v1); geom.vertices.push(v2); geom.vertices.push(v3);                  geom.faces.push( new THREE.Face3( 0, 1, 2 ) ); geom.computeFaceNormals();                  var object = new THREE.Mesh( geom, new THREE.MeshNormalMaterial() );                  object.position.z = -100;//move a bit back - size of 500 is a bit big object.rotation.y = -Math.PI * .5;//triangle is pointing in depth, rotate it -90 degrees on Y                  scene.add(object); 

Update: THREE.Geometry and THREE.Face3 are deprecated: THREE.BufferGeometry is recommended instead.

const geometry = new THREE.BufferGeometry();  const positions = [ 0,   0, 0,    // v1 0, 500, 0,   // v2 0, 500, 500  // v3 ];  geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); geometry.computeVertexNormals();  const object = new THREE.Mesh( geometry, new THREE.MeshNormalMaterial() ); scene.add(object); 

In short, as opposed to providing vertex positions and Face3 objects with 3 vertex indices now you would use a flat array in x1, y1, z1, x2, y2, z2, ..., xn, yn, zn order (every 3 x,y,z triplets in order define a face).

Additionally, it's possible to compute and provide vertex colours and normals. There are plenty of three.js example to start with, including:

  • webgl_buffergeometry
  • webgl_buffergeometry_indexed

webgl_buffergeometry three.js triangles example

webgl_buffergeometry_indexed three.js subdivided plane example

like image 123
George Profenza Avatar answered Sep 21 '22 11:09

George Profenza