spite / THREE.MeshLine

Mesh replacement for THREE.Line
MIT License
2.16k stars 380 forks source link

It's called THREE.MeshLine but really wraps a THREE.BufferGeometry? What gives? #1

Open spite opened 8 years ago

spite commented 8 years ago

Yes, I know. Originally it was supposed to encapsulate all the features of a THREE.Mesh with its own geometry and attributes, but it got complicated. Next refactor should have a proper THREE.Mesh as result.

Makio64 commented 8 years ago

What about just rename to : LineGeometry, keep MeshLineMaterial and not encapsulate the Mesh functionality ?

I'm actually working with it and use differents custom LineGeometry / MeshLineMaterial to realize various effects, create a normal Three.Mesh feel natural & more flexible.

Also on a bit different topics but still in the refractoring, MeshLine/LineGeometry can have directly the "points", functionWidth in his constructor to get more friendly.

spite commented 8 years ago

I think MeshLine is too different from Mesh to be able to work interchangeably. It does a series of operations a set some uniforms/attributes that are specific to it.

Do you have an example of what you propose?

SuberFu commented 8 years ago

It's a bit late (or very late). But due to an oversight, I reimplemented a version of MeshLine with the idea of keeping as close to the THREE.js's pattern of "create object, add it to scene, changes are updated nearly automatically". So the pattern I use might be a good example for use. THREE.MeshLineAlt (funny story, I actually started out that project without knowing yours exists, and managed to use the exact same naming as yours). Overall, my implementation go through the following.

  1. A BufferMeshLineGeometry class that inherits from BufferGeometry. Its purpose is to automatically "convert" a THREE.Geometry object into the form needed for mesh lines (each vertices are converted to 4 points, to allow "free" bevel join at the joints. The exceptions are the end points, which are converted to 2 points).
  2. A custom THREE.MeshLine class that inherits from THREE.Mesh. It takes a THREE.Geometry (cannot be BufferGeometry) + a THREE.MeshLineMaterial
  3. The THREE.MeshLineMaterial is essentially my implementation equivalent of your THREE.MeshLineMaterial (mine is pretty simple).

The THREE.MeshLine object, once populated with at least a THREE.Geometry, can be added directly to the THREE.js's scene object, and changes to geometry object will reflect in the viewer. This is accomplished (albeit currently in a fairly inefficient manner of reconstructing the attribute buffer each time) by the following.

  1. In THREE.BufferMeshLineGeometry, updateFromObject and fromGeometry is overriden to convert geometry into the proper format. updateFromObject, in particular, is used by THREE.js's renderer to trigger update to the geometry. For efficiency, the fromGeometry only updates the positions if "verticesNeedUpdate" is set, and same for colors.
  2. The THREE.MeshLine, geometry received will have its "_bufferGeometry" set to a new THREE.BufferMeshLineGeometry. This is because the part of the three.js renderer handling the update do the following.

A. For the object (in our exapmle, THREE.MeshLine), check if the geometry is a THREE.Geometry (if it's a THREE.BufferGeometry instead, it doesn't do any update and use it as is, hence when my version cannot take a THREE.BufferGeometry).

B. If it's a THREE.Geometry, check if it has _bufferGeometry set. If not, set _bufferGeometry to a new THREE.BufferGeometry (the setting of _bufferGeometry in 2 is meant to bypass this, so three.js don't use the default BufferGeometry for it).

C. Given the _bufferGeometry, invoke updateFromObject (the one THREE.BufferMeshLineGeometry overrides).