Giter Club home page Giter Club logo

three.meshline's Introduction

MeshLine

Mesh replacement for THREE.Line

Instead of using GL_LINE, it uses a strip of triangles billboarded. Some examples:

Demo Graph Spinner SVG Shape Shape

  • Demo: play with the different settings of materials
  • Graph: example of using MeshLine to plot graphs
  • Spinner: example of dynamic MeshLine with texture
  • SVG: example of MeshLine rendering SVG Paths
  • Shape: example of MeshLine created from a mesh
  • Birds: example of MeshLine.advance() by @caramelcode (Jared Sprague) and @mwcz (Michael Clayton)

How to use

  • Include script
  • Create an array of 3D coordinates
  • Create a MeshLine and assign the points
  • Create a MeshLineMaterial
  • Use MeshLine and MeshLineMaterial to create a THREE.Mesh

Include the script

Include script after THREE is included

<script src="THREE.MeshLine.js"></script>

or use npm to install it

npm i three.meshline

and include it in your code (don't forget to require three.js)

const THREE = require('three');
const MeshLine = require('three.meshline').MeshLine;
const MeshLineMaterial = require('three.meshline').MeshLineMaterial;
const MeshLineRaycast = require('three.meshline').MeshLineRaycast;

or

import * as THREE from 'three';
import { MeshLine, MeshLineMaterial, MeshLineRaycast } from 'three.meshline';
Create an array of 3D coordinates

First, create the list of numbers that will define the 3D points for the line.

const points = [];
for (let j = 0; j < Math.PI; j += (2 * Math.PI) / 100) {
  points.push(Math.cos(j), Math.sin(j), 0);
}

MeshLine also accepts a BufferGeometry looking up the vertices in it.

const points = [];
for (let j = 0; j < Math.PI; j += 2 * Math.PI / 100) {
  points.push(new THREE.Vector3(Math.cos(j), Math.sin(j), 0));
}
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const line = new MeshLine();
line.setGeometry(geometry);
Create a MeshLine and assign the points

Once you have that, you can create a new MeshLine, and call .setPoints() passing the list of points.

const line = new MeshLine();
line.setPoints(points);

Note: .setPoints accepts a second parameter, which is a function to define the width in each point along the line. By default that value is 1, making the line width 1 * lineWidth in the material.

// p is a decimal percentage of the number of points
// ie. point 200 of 250 points, p = 0.8
line.setPoints(geometry, p => 2); // makes width 2 * lineWidth
line.setPoints(geometry, p => 1 - p); // makes width taper
line.setPoints(geometry, p => 2 + Math.sin(50 * p)); // makes width sinusoidal
Create a MeshLineMaterial

A MeshLine needs a MeshLineMaterial:

const material = new MeshLineMaterial(OPTIONS);

By default it's a white material of width 1 unit.

MeshLineMaterial has several attributes to control the appereance of the MeshLine:

  • map - a THREE.Texture to paint along the line (requires useMap set to true)
  • useMap - tells the material to use map (0 - solid color, 1 use texture)
  • alphaMap - a THREE.Texture to use as alpha along the line (requires useAlphaMap set to true)
  • useAlphaMap - tells the material to use alphaMap (0 - no alpha, 1 modulate alpha)
  • repeat - THREE.Vector2 to define the texture tiling (applies to map and alphaMap - MIGHT CHANGE IN THE FUTURE)
  • color - THREE.Color to paint the line width, or tint the texture with
  • opacity - alpha value from 0 to 1 (requires transparent set to true)
  • alphaTest - cutoff value from 0 to 1
  • dashArray - the length and space between dashes. (0 - no dash)
  • dashOffset - defines the location where the dash will begin. Ideal to animate the line.
  • dashRatio - defines the ratio between that is visible or not (0 - more visible, 1 - more invisible).
  • resolution - THREE.Vector2 specifying the canvas size (REQUIRED)
  • sizeAttenuation - makes the line width constant regardless distance (1 unit is 1px on screen) (0 - attenuate, 1 - don't attenuate)
  • lineWidth - float defining width (if sizeAttenuation is true, it's world units; else is screen pixels)

If you're rendering transparent lines or using a texture with alpha map, you should set depthTest to false, transparent to true and blending to an appropriate blending mode, or use alphaTest.

Use MeshLine and MeshLineMaterial to create a THREE.Mesh

Finally, we create a mesh and add it to the scene:

const mesh = new THREE.Mesh(line, material);
scene.add(mesh);

You can optionally add raycast support with the following.

mesh.raycast = MeshLineRaycast;

Declarative use

THREE.meshline can be used declaritively. This is how it would look like in react-three-fiber. You can try it live here.

import { extend, Canvas } from 'react-three-fiber'
import { MeshLine, MeshLineMaterial, MeshLineRaycast } from 'three.meshline'

extend({ MeshLine, MeshLineMaterial })

function Line({ points, width, color }) {
  return (
    <Canvas>
      <mesh raycast={MeshLineRaycast}>
        <meshLine attach="geometry" points={points} />
        <meshLineMaterial
          attach="material"
          transparent
          depthTest={false}
          lineWidth={width}
          color={color}
          dashArray={0.05}
          dashRatio={0.95}
        />
      </mesh>
    </Canvas>
  )
}

Dynamic line widths can be set along each point using the widthCallback prop.

<meshLine attach='geometry' points={points} widthCallback={pointWidth => pointWidth * Math.random()} />

TODO

  • Better miters
  • Proper sizes

Support

Tested successfully on

  • Chrome OSX, Windows, Android
  • Firefox OSX, Windows, Anroid
  • Safari OSX, iOS
  • Internet Explorer 11 (SVG and Shape demo won't work because they use Promises)
  • Opera OSX, Windows

References

License

MIT licensed

Copyright (C) 2015-2016 Jaume Sanchez Elias, http://www.clicktorelease.com

three.meshline's People

Contributors

amcdnl avatar andreasplesch avatar axion014 avatar dhritzkiv avatar drcmda avatar jacobhamblin avatar jared-sprague avatar jeremboo avatar jeremyabel avatar johannesmp avatar kappys1 avatar neftaly avatar nzhuravlev avatar paulmatlashewski avatar ryanking1809 avatar spite avatar tankerxyz avatar zellski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

three.meshline's Issues

Updating MeshLineMaterials opacity

Is it possible to update the mesh line material's opacity after it has been created? (e.g in an animation). I can set the opacity at the start using the the transparent:true and the opacity params as you describe but if I try to update the opacity at a later time using either meshlinematerial.opacity = whatever, or mesh.material.opacity neither of these work.

Memory leak - maybe?

First of all, great job, it's a lovely addition to Three.js!

I'm not completely sure, but I think there may be a memory leak somewhere, I tested your spinner demo (basically holding down the mouse and releasing again after a few minutes), in Chrome the memory consumption just goes up and up, and never down again. On another project I'm working on this get's much more apparent since I'm updating the THREE.MeshLine geometry on every frame with the THREE.MeshLine.setGeometry() function.

Please see the attached screenshot for a memory profile, looks like it may have something to do with the WebGLBuffer objects?

Correct me if I'm wrong, just wanted to let you know as I guess you can figure whether there's any hold in this theory pretty fast :-)

screen shot 2016-01-04 at 16 15 02

scene.remove doesn't work?

//100 MeshLines have been added to a scene
//then I want to delete all of them from the scene:

scene.children.forEach(function(child) {
    scene.remove(child);
});

//only 50 are removed
//running it again
//only 25 are removed
//running it again
//only 13 are removed (see a pattern?)

The same result occurs with for loops and using scene.traverse. However, doing this:

scene.children.splice(0);

…does work. Weirdness. Try opening the main demo and copying+pasting the above pieces of code to see the results.

Am I doing something incorrectly?

r73

copyArray uses undefined array

this.attributes.index.copyArray(new Uint16Array(this.index));

should be:

this.attributes.index.copyArray(new Uint16Array(this.indices_array));

Otherwise Firefox crashes with invalid argument error because this.index is undefined.

Uncaught RangeError: Source is too large

Hi all, I followed the instructions, to create a MeshLine, but when i try to run "setGeometry" the following error rises up:

Uncaught RangeError: Source is too large

The steps to create the MeshLine are the following.

var geometry = new THREE.Geometry();
var line = new MeshLine();
geometry.vertices.push(new THREE.Vector3(-100,0.1,34));
geometry.vertices.push(new THREE.Vector3(70,0.1,-54));
line.setGeometry( geometry );
material = new MeshLineMaterial({
color:new THREE.Color("rgb(26, 188, 156)")
});
var mesh = new THREE.Mesh( geometry, material );

What am i doing wrong? I'm using THREE.js v84, Chrome 67.0.3396.99 on Mac OSX High Sierra.

Thank you very much!

Two additional demo files

@spite

I'm enjoying MeshLine. Thanks for this effort.

I have built two simple demos that could help new users start incorporating MeshLines into their code

MeshLine Basic Demo R1

  • Simple demo with quite minimal code just to get a most basic MeshLine up and running in your browser

MeshLine Experiments R1

  • Exploring the possibilities of MeshLine in more detail
  • Every example is a simple short function you could copy and paste into your own code
  • There's a ton more fun things that could be added...

The code in the second demo has a quirky/highly personal style. If there is interest in adding this file then I can 'normalize' the code.

Theo

(Feature request)Please add a feature to update the vertices

Hi,

I am just trying to draw a thick line then add, update or remove points from it dynamically at the run time.
just like this,

var line = new MeshLine();
var geo = new THREE.Geometry();
geo.vertices.push( new THREE.Vector3( -10, 10, 0 ) );
geo.vertices.push( new THREE.Vector3( 10, 10, 0 ) );
line.setGeometry( geo );

//Adding new vertices
var updatedGeo = new THREE.Geometry();
updatedGeo.vertices.push( new THREE.Vector3( -10, 10, 0 ) );
updatedGeo.vertices.push( new THREE.Vector3( 10, 10, 0 ) );
updatedGeo.vertices.push( new THREE.Vector3( 10, 15, 0 ) );
line.setGeometry( updatedGeo ); //This produces "Source too large error"

With the current implementation, I think it is not possible to add more vertices to the existing geometry( only two points are needed to draw a line, but I am trying to draw a line which will bend at different positions ). I don't know whether my assumptions are correct or not, but I think that the "MeshLine.prototype.process" function will check for the existence of a position attribute in the BufferGeometry and if it is already there, the function will just copy the vertices of the geometry passed to the setGeometry function to the existing position array.
In this case we won't be able to add new vertices as it will throw a "Source too large error" from the "MeshLine.prototype.process" function.

I made a quick and dirty modification to the code just to fullfill my needs,

I copied "LineMesh.prototype.process" function to implement a new function "prepareGeometry" which will replace the existing BufferGeometry attributes with new one created using the geometry passed to the setGeometry function. Now "LineMesh.prototype.prepareGeometry" will be called from the setGeometry function instead of "LineMesh.prototype.process".
Also I have added a "LineMesh.prototype.updateGeometry" function by modifying "LineMesh.prototype.setGeometry" which will update the existing vertices using the "LineMesh.prototype.process" method. The following code describes the changes made,

LineMesh.prototype.setGeometry = function( g, c ) {
    
	this.widthCallback = c;

	this.positions = [];
	this.counters = [];

	if( g instanceof THREE.Geometry ) {
		for( var j = 0; j < g.vertices.length; j++ ) {
			var v = g.vertices[ j ];
			var c = j/g.vertices.length;
			this.positions.push( v.x, v.y, v.z );
			this.positions.push( v.x, v.y, v.z );
			this.counters.push(c);
			this.counters.push(c);
		}
	}

	if( g instanceof THREE.BufferGeometry ) {
		// read attribute positions ?
	}

	if( g instanceof Float32Array || g instanceof Array ) {
		for( var j = 0; j < g.length; j += 3 ) {
			var c = j/g.length;
			this.positions.push( g[ j ], g[ j + 1 ], g[ j + 2 ] );
			this.positions.push( g[ j ], g[ j + 1 ], g[ j + 2 ] );
			this.counters.push(c);
			this.counters.push(c);
		}
	}

	//this.process();
	this.prepareGeometry();

}

LineMesh.prototype.updateGeometry = function( g, c ) {

	this.widthCallback = c;

	this.positions = [];
	this.counters = [];

	if( g instanceof THREE.Geometry ) {
		for( var j = 0; j < g.vertices.length; j++ ) {
			var v = g.vertices[ j ];
			var c = j/g.vertices.length;
			this.positions.push( v.x, v.y, v.z );
			this.positions.push( v.x, v.y, v.z );
			this.counters.push(c);
			this.counters.push(c);
		}
	}

	if( g instanceof THREE.BufferGeometry ) {
		// read attribute positions ?
	}

	if( g instanceof Float32Array || g instanceof Array ) {
		for( var j = 0; j < g.length; j += 3 ) {
			var c = j/g.length;
			this.positions.push( g[ j ], g[ j + 1 ], g[ j + 2 ] );
			this.positions.push( g[ j ], g[ j + 1 ], g[ j + 2 ] );
			this.counters.push(c);
			this.counters.push(c);
		}
	}

	this.process();

}

LineMesh.prototype.prepareGeometry = function() {
    
	var l = this.positions.length / 6;

	this.previous = [];
	this.next = [];
	this.side = [];
	this.width = [];
	this.indices_array = [];
	this.uvs = [];

	for( var j = 0; j < l; j++ ) {
		this.side.push( 1 );
		this.side.push( -1 );
	}

	var w;
	for( var j = 0; j < l; j++ ) {
		if( this.widthCallback ) w = this.widthCallback( j / ( l -1 ) );
		else w = 1;
		this.width.push( w );
		this.width.push( w );
	}

	for( var j = 0; j < l; j++ ) {
		this.uvs.push( j / ( l - 1 ), 0 );
		this.uvs.push( j / ( l - 1 ), 1 );
	}

	var v;

	if( this.compareV3( 0, l - 1 ) ){
		v = this.copyV3( l - 2 );
	} else {
		v = this.copyV3( 0 );
	}
	this.previous.push( v[ 0 ], v[ 1 ], v[ 2 ] );
	this.previous.push( v[ 0 ], v[ 1 ], v[ 2 ] );
	for( var j = 0; j < l - 1; j++ ) {
		v = this.copyV3( j );
		this.previous.push( v[ 0 ], v[ 1 ], v[ 2 ] );
		this.previous.push( v[ 0 ], v[ 1 ], v[ 2 ] );
	}

	for( var j = 1; j < l; j++ ) {
		v = this.copyV3( j );
		this.next.push( v[ 0 ], v[ 1 ], v[ 2 ] );
		this.next.push( v[ 0 ], v[ 1 ], v[ 2 ] );
	}

	if( this.compareV3( l - 1, 0 ) ){
		v = this.copyV3( 1 );
	} else {
		v = this.copyV3( l - 1 );
	}
	this.next.push( v[ 0 ], v[ 1 ], v[ 2 ] );
	this.next.push( v[ 0 ], v[ 1 ], v[ 2 ] );

	for( var j = 0; j < l - 1; j++ ) {
		var n = j * 2;
		this.indices_array.push( n, n + 1, n + 2 );
		this.indices_array.push( n + 2, n + 1, n + 3 );
	}

	if ( !this.attributes ){
		
	}

	this.attributes = {
		position: new THREE.BufferAttribute( new Float32Array( this.positions ), 3 ),
		previous: new THREE.BufferAttribute( new Float32Array( this.previous ), 3 ),
		next: new THREE.BufferAttribute( new Float32Array( this.next ), 3 ),
		side: new THREE.BufferAttribute( new Float32Array( this.side ), 1 ),
		width: new THREE.BufferAttribute( new Float32Array( this.width ), 1 ),
		uv: new THREE.BufferAttribute( new Float32Array( this.uvs ), 2 ),
		index: new THREE.BufferAttribute( new Uint16Array( this.indices_array ), 1 ),
		counters: new THREE.BufferAttribute( new Float32Array( this.counters ), 1 )
	}

	this.geometry.addAttribute( 'position', this.attributes.position );
	this.geometry.addAttribute( 'previous', this.attributes.previous );
	this.geometry.addAttribute( 'next', this.attributes.next );
	this.geometry.addAttribute( 'side', this.attributes.side );
	this.geometry.addAttribute( 'width', this.attributes.width );
	this.geometry.addAttribute( 'uv', this.attributes.uv );
	this.geometry.addAttribute( 'counters', this.attributes.counters );

	this.geometry.setIndex( this.attributes.index );

}

LineMesh.prototype.process = function() {

	var l = this.positions.length / 6;

	this.previous = [];
	this.next = [];
	this.side = [];
	this.width = [];
	this.indices_array = [];
	this.uvs = [];

	for( var j = 0; j < l; j++ ) {
		this.side.push( 1 );
		this.side.push( -1 );
	}

	var w;
	for( var j = 0; j < l; j++ ) {
		if( this.widthCallback ) w = this.widthCallback( j / ( l -1 ) );
		else w = 1;
		this.width.push( w );
		this.width.push( w );
	}

	for( var j = 0; j < l; j++ ) {
		this.uvs.push( j / ( l - 1 ), 0 );
		this.uvs.push( j / ( l - 1 ), 1 );
	}

	var v;

	if( this.compareV3( 0, l - 1 ) ){
		v = this.copyV3( l - 2 );
	} else {
		v = this.copyV3( 0 );
	}
	this.previous.push( v[ 0 ], v[ 1 ], v[ 2 ] );
	this.previous.push( v[ 0 ], v[ 1 ], v[ 2 ] );
	for( var j = 0; j < l - 1; j++ ) {
		v = this.copyV3( j );
		this.previous.push( v[ 0 ], v[ 1 ], v[ 2 ] );
		this.previous.push( v[ 0 ], v[ 1 ], v[ 2 ] );
	}

	for( var j = 1; j < l; j++ ) {
		v = this.copyV3( j );
		this.next.push( v[ 0 ], v[ 1 ], v[ 2 ] );
		this.next.push( v[ 0 ], v[ 1 ], v[ 2 ] );
	}

	if( this.compareV3( l - 1, 0 ) ){
		v = this.copyV3( 1 );
	} else {
		v = this.copyV3( l - 1 );
	}
	this.next.push( v[ 0 ], v[ 1 ], v[ 2 ] );
	this.next.push( v[ 0 ], v[ 1 ], v[ 2 ] );

	for( var j = 0; j < l - 1; j++ ) {
		var n = j * 2;
		this.indices_array.push( n, n + 1, n + 2 );
		this.indices_array.push( n + 2, n + 1, n + 3 );
	}

	if (!this.attributes) {
		this.attributes = {
			position: new THREE.BufferAttribute( new Float32Array( this.positions ), 3 ),
			previous: new THREE.BufferAttribute( new Float32Array( this.previous ), 3 ),
			next: new THREE.BufferAttribute( new Float32Array( this.next ), 3 ),
			side: new THREE.BufferAttribute( new Float32Array( this.side ), 1 ),
			width: new THREE.BufferAttribute( new Float32Array( this.width ), 1 ),
			uv: new THREE.BufferAttribute( new Float32Array( this.uvs ), 2 ),
			index: new THREE.BufferAttribute( new Uint16Array( this.indices_array ), 1 ),
			counters: new THREE.BufferAttribute( new Float32Array( this.counters ), 1 )
		}
	}
	else{
		this.attributes.position.copyArray(new Float32Array(this.positions));
		this.attributes.position.needsUpdate = true;
		this.attributes.previous.copyArray(new Float32Array(this.previous));
		this.attributes.previous.needsUpdate = true;
		this.attributes.next.copyArray(new Float32Array(this.next));
		this.attributes.next.needsUpdate = true;
		this.attributes.side.copyArray(new Float32Array(this.side));
		this.attributes.side.needsUpdate = true;
		this.attributes.width.copyArray(new Float32Array(this.width));
		this.attributes.width.needsUpdate = true;
		this.attributes.uv.copyArray(new Float32Array(this.uvs));
		this.attributes.uv.needsUpdate = true;
		this.attributes.index.copyArray(new Uint16Array(this.indices_array));
		this.attributes.index.needsUpdate = true;
	}

	this.geometry.addAttribute( 'position', this.attributes.position );
	this.geometry.addAttribute( 'previous', this.attributes.previous );
	this.geometry.addAttribute( 'next', this.attributes.next );
	this.geometry.addAttribute( 'side', this.attributes.side );
	this.geometry.addAttribute( 'width', this.attributes.width );
	this.geometry.addAttribute( 'uv', this.attributes.uv );
	this.geometry.addAttribute( 'counters', this.attributes.counters );

	this.geometry.setIndex( this.attributes.index );

}

In effect, we can call the "setGeometry" method if we wish to add new vertices or call the "updateGeometry" if we wish to update the existing vertices.

I know this is not the perfect implementation but it will be great if there is a feature to add, remove or update vertices.

Three.js fragment shader error

The demo emit this error, is this something that can be ignored?

THREE.WebGLProgram: gl.getProgramInfoLog() WARNING: Output of vertex shader 'vPosition' not read by fragment shader

MeshLine has a maximum size

I have an object that has 140,000 vertices and the MeshLine isn't drawing the entire object, but doesn't give an error or warning.

The size of the MeshLine seems to be limited to a geometry size of 2^15 (32,678) vertices as far as I can tell
See this example:
http://jsfiddle.net/tvdvd/16jnyf35/10/

I put a yellow ring where the size of the spiral hits 32,678 vertices. Try changing numVerts to above and below that number and the spiral doesnt grow beyond that number.

Seems like this is a WebGL limitation (65k vertices--https://stackoverflow.com/questions/4998278/is-there-a-limit-of-vertices-in-webgl). Maybe worth noting in the documentation.

Fails to render expected result with an OrthographicCamera

Just substituted the camera in your demo with an Orthographic one - and while it fails to render anything, it looks super interesting with circles enabled in the options.

Below is the changed code to main.js - which renders a blank screen:


var frustumSize = 600;
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var aspect = SCREEN_WIDTH / SCREEN_HEIGHT;

//var camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, .1, 1000 );
var camera = new THREE.OrthographicCamera( frustumSize * aspect / - 2, frustumSize * aspect / 2, frustumSize / 2, frustumSize / - 2, 150, 1000 );
camera.position.set( 0, -10, -10 );
camera.lookAt(new THREE.Vector3(0,0,0));

and that is the result with circles enabled in dat.gui interface:

screen shot 2017-05-31 at 16 17 27

support Curve geometry

I'm thinking to add suport for Curve geometry. Just adding something like

if (g instanceof Three.Curve)
verticies = g.getSpacedPoints()

Any reactions/thoughts before I proceed?

how to set texture repeat in MeshLine

I want draw a path use this, and fill it with a arrow texture .
But i cannot set repeat model like >>>>>>>>>>>> layout。
can you tell me how to mapping like this, stretch is not i want

thanks thanks

Drawing EdgesGeometry

Hi,

I'm having issues drawing EdgesGeometry with MeshLine, see first image. Second image uses LineSegments.

I'm using the following to get the positions:

let position = geometry.getAttribute("position").array;

for (let i = 0; i < position.length; i++)
{
	let counter = i / position.length;

	this.positions.push(position[i], position[i + 1], position[i + 2]);
	this.positions.push(position[i], position[i + 1], position[i + 2]);

	this.counters.push(counter);
	this.counters.push(counter);
}

Thanks,
Mike

edgesgeometry1
edgesgeometry2

Merging geometries

I had the idea of generating lots of lines (that have the same material properties), and merging them for use in one single Mesh in order to reduce the number of Mesh objects added to the scene (and therefore the number of draw calls).

However, simply trying that yielded… no results. (still, it was worth a shot) :)

Anyway – would it be possibly to perform a merge on MeshLine geometries? Or is it limited by how these lines work?

"MeshLine is not a constructor" when using require()

When I do this:

var THREE = require('three');
var MeshLine = require( 'three.meshline' );
var line = new MeshLine();

Which is what the readme says, right? Well, I get Uncaught TypeError: MeshLine is not a constructor

Both modules are installed and load properly. I noticed that some other THREE modules I've used ask for THREE to be sent as a parameter like this var name = require('name')(THREE); and I have a feeling it has to do with Line 9 of MeshLines not properly detecting my code's instance of THREE and requiring it's own

line 9: var THREE = root.THREE || has_require && require('three')

Failed to execute 'uniform3fv' on 'WebGLRenderingContext'

Uncaught TypeError: Failed to execute 'uniform3fv' on 'WebGLRenderingContext': No function was found that matched the signature provided.

I got this issue when i'm trying to create a basic line with MehsLine ...

`
import {MeshLine, MeshLineMaterial} from 'three.meshline'

createLine(){

    this.lineGeometry = new THREE.Geometry()
    this.lineGeometry.vertices.push(
            new THREE.Vector3(this.sprite.position.x, 0., this.sprite.position.z),
    );

    this.lineMesh = new MeshLine()
    this.lineMesh.setGeometry(this.lineGeometry)

    this.lineMaterial = new MeshLineMaterial({
        color : 0xffffff,
        lineWidth : 10.
    })

    this.line = new THREE.Mesh(this.lineMesh.geometry, this.lineMaterial)

    this.scene.add(this.line)
}

`

when i create my sprite, i want to draw a line, and when i move my sprite, i want to add dynamiclly vertices to draw dynamiclly the line following the position of the sprite.

But at this time, just draw a point is so hard ? Why i got this error ? Thx for answering 👍

Incorrect Line Width with sizeAttenuation in perspective camera

I am writing an application that uses a perspective camera to render line traces. I need them to be very specific widths and they should maintain the correct dimensions as the camera moves.

The current MeshLine 1.0.3 appears to create lines that taper in from the ends. The ends appear to be the correct width but the lines between are thinner. I have made sure that all of my verts have a 0 Z coordinate and the camera is aligned with the Z axis.

I was able to get mostly correct results using a different library, but it has a bug that doesn't allow me to clone the lines for rendering to texture very easily. The other library also seems to have issues with consistent width between camera distance which I currently work around with a multiplier to try and correct at distances I care about currently. The other lib is MeshLineAlt.

Here is my Material:

new MeshLine.MeshLineMaterial( {
            useMap: false,
            color: new THREE.Color( 0x000000 ),
            opacity: 1,
            lineWidth: width,
            resolution: this._lineResolution,
            sizeAttenuation: true,
            near: this._camera.near,
            far: this._camera.far
        });

Later in the file I create the lines where this.currentLine is the verts and this.currentLineMaterial is a material with the properties above:

        var g = new MeshLine.MeshLine();
        g.setGeometry( this.currentLine );

        var mesh = new THREE.Mesh( g.geometry, this.currentLineMaterial );

My camera is created like so:

new THREE.PerspectiveCamera(60, self._width / self._height, 1, 1000);

Here are a few screenshots showing the issue:

meshline-test

meshline-longtest

Here is the correct result of the short 2 segment line above rendered with the Other MeshLineAlt lib:

meshlinealt-test

The only change I need to make to get the correct results with the other library is to override the mesh created in the above snippet:

        var altMat = new THREE.MeshLineAltMaterial({});
        altMat.linewidth = this.currentLineWidth + (this.currentLineWidth * 0.48);
        //altMat.linecolor = new THREE.Vector3(1, 1, 1);
        mesh = new THREE.MeshLineAlt([ this.currentLine.vertices ], altMat);

Wagner Doesnt like THREE.MeshLine

Hi !

I get an error when I use it with... Wagner
[GroupMarkerNotSet(crbug.com/242999)!:D00486D2F37F0000]GL ERROR :GL_INVALID_OPERATION : glDrawElements: Source and destination textures of the draw are the same.

my render function is like that :
@renderer.autoClearColor = true
@composer.reset()
@composer.render( @scene, @CAMERA )
for pass in @passes
@composer.pass( pass )
@composer.toScreen()

I use the a simple code for the MeshLine ( following the step ni the README ) & no problem wihout wagner or wihout MeshLine but both together.. Bug oO

Did I do something wrong with wagner ?

Lines shift while using orbit controls

I'm drawing several flat lines with widths of about 3. The lines all have y=0.01 and are on top of a green rectangle with y=0. I'm using the standard OrbitControls. As I move the camera around, the flat lines all shift around in ways that don't make much sense:

output

It looks like the y-coordinates of the lines are changing as I move the camera. Why would this be happening?

Effected by fog

Is there any way to get the lines to be effected by scene fog?

p.s. This is a fantastic tool and very useful, thank you!

Issue with Orthographic camera?

Hi!

I am using this piece of code to change the view from Perspective to Orthographic and back:

function toggleCamera() {
    if (camera instanceof THREE.PerspectiveCamera) {
        camera = new THREE.OrthographicCamera(window.innerWidth / -16, window.innerWidth / 16, window.innerHeight / 16, window.innerHeight / -16, -200, 500);
        camera.position.set(0, 0, 500);
        camera.name = 'Camera';
        camera.up.set(0,0,1);
        camera.lookAt(scene.position);
    } else {
        camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 5000);
        camera.position.set(0, -1500/2, 1000/2);
        camera.up.set(0,0,1);
        camera.lookAt(scene.position);
        camera.name = 'Camera';
    }
	// the orbit controls to rotate the camera
	controls = new THREE.OrbitControls(camera, container);
	controls.enableDamping = true;
	controls.dampingFactor = 0.25;
	controls.rotateSpeed = 1.0;	     
}

I obtain the following:
perspectivecamera
orthographiccamera

where one can see that the orthographic has lines all around.

Is that a bug or me misusing the API?

BR
M

Add raycast support

Make something similar to THREE.Line, accounting for the size attenuation flag, variable width, etc. features.

Morph Targets

Awesome work.

Does THREE.MeshLine support morph targets? Would it be possible?

Vertex Colors

Does this support vertexColors? I have a circle that uses vertexColors to assign different colors based on if z is positive or negative. Is this possible using MeshLine?

Thanks!

Raycast lines?

Is it possible to get intersection information from MeshLines? It's possible I have something setup incorrectly, but it seems like I don't get results from intersectObjects on MeshLines, (I do with other meshes).

Updating line start and end point

Hi there, I'm new to 3JS, I managed to draw a simple straight line ok with MeshLine, next I need the start point and endpoint to animate in different directions.

geometry.vertices.push(new THREE.Vector3( 0, 0, 0));
geometry.vertices.push(new THREE.Vector3( 30, -30, -130 ));

I tried e.g "geometry.vertices[0].x += 1" on render udate with "this.geometry.verticesNeedUpdate = true"

But nothing happens, am I missing a trick or is it not possible to change a line shape once it has been initialized?

2 Vertice but Long Line Issue

Please see this fiddle and rotate the camera around the Y axis: http://jsfiddle.net/1xsy5e90/4/ . The top line should vanish after some rotation and the bottom one will "flicker".

We encountered this issue because we have the user draw a "measurement" which is a MeshLine by selecting start and end point. If you use these to create a MeshLine you get a very long edge which vanishes for certain camera rotations.

I tried adding a single vertex in the middle (manual subdivision) and it causes the flickering at the moment where the first line vanishes entirely (but at least it remains visible). Adding more subdivisions reduces the issue until the LineMesh is drawing as expected again.

In our case we have now solved it by subdividing the MeshLine in our code so that we get a minimum amount of vertices which seems to always work so far (basically we guarantee that no two vertices are further than one unit apart, where a unit is some arbitrary magic number which solves it for us).

I'm not sure if it is a bug, but a warning at least somewhere would be nice if this is working as intended.

Thank you!

THREE.AdditiveAlphaBlending removed from three.js

Hello!
I notice in your README and some of your demos you recommend using THREE.AdditiveAlphaBlending if transperant = true. However that blending mode has been removed from three.js. Just FYI you might want to update your README and demo references to it.
Thanks for a great library!

Why THREE.Line can't be merged with THREE.Mesh ?

Hello,

I saw in an old thread that we can't merge THREE.Line with THREE.Mesh but can I ask why? when I add a lot of lines into my application it will cause performance issue and that's why I need to merge them with the mesh. Any possibility of fixing that in the next updates?

wireframe for debugging

would be quite useful to have a debugging material that renders wireframe, to figure out which triangles are where.

more clarity on how to animate color

It wasn't clear this was possible at first because its not in the documentation or any examples and the sort of functions that regularly make this work (color.setHSL) don't work.

Anyway, a bit of hacking and I got it working. May be nice to add.

I hacked apart the internals a bit and just added these modified functions to my project

function hue2rgb( p, q, t ) {

				if ( t < 0 ) t += 1;
				if ( t > 1 ) t -= 1;
				if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;
				if ( t < 1 / 2 ) return q;
				if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );
				return p;

			}

			function setHSL( h, s, l ) {
				let r,g,b
				// h,s,l ranges are in 0.0 - 1.0
				h = ( ( h % 1 ) + 1 ) % 1 // _Math.euclideanModulo( h, 1 );
				s = Math.max( 0, Math.min( 1, s ) )//_Math.clamp( s, 0, 1 );
				l = Math.max( 0, Math.min( 1, l ) )//_Math.clamp( l, 0, 1 );

				if ( s === 0 ) {

					r = g = b = l;

				} else {

					var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );
					var q = ( 2 * l ) - p;

					r = hue2rgb( q, p, h + 1 / 3 );
					g = hue2rgb( q, p, h );
					b = hue2rgb( q, p, h - 1 / 3 );

				}

				return new THREE.Color(r,g,b);

			}

and use it like this:

function render() {
  var time = Date.now() * 0.00005;
  var h += ( 360 * ( 1.0 + time ) % 360 ) / 360;
  lineMaterial.uniforms.color.value = setHSL(h, 0.5, 0.5)

}

works great! demo:

color animated lines

Memory leak

It happens when I use function setGeometry in a real time (inside a redrawing function of my project). Can you fix it or explain other ways to update geometry of lines?

Confusing options documentation

In the Readme, there are confusing descriptions of the options.

One example:

sizeAttenuation - makes the line width constant regardless distance (1 unit is 1px on screen) (0 - attenuate, 1 - don't attenuate)`
lineWidth - float defining width (if sizeAttenuation is true, it's world units; else is screen pixels)

There's three things that are confusing here.

  1. The name sizeAttenuation, taken on its own, makes it sounds like true would enable attenuation, and false would disable it. That's apparently not the case: the parentheses section says 0/false enables attenuation, and 1/true disables attenuation. This "meaning opposite of what the name implies" gives uncertainty to the reader of whether it's actually reversed, or just a typo.
  2. Why does the parentheses say to use 0 or 1, when the line below it references sizeAttenuation as possibly being true? I'm guessing it accepts either 0/1 or true/false . However, if that's the case, you should pick one and use it consistently in the documentation instead of saying 0/1 some places and true/false others.
  3. Assuming the usages of 0/1 and true/false are standardized in the readme, and the "meaning reverse of the option name" is fixed, it seems like it would be good to standardize on true/false since it reinforces the assumption that the value directly maps in meaning to the option's name. In other words, "sizeAttenuation: true" is slightly more obvious in its function of enabling size-attenuation than "sizeAttentuation: 1". (since 0/1 gives the possibility that there's other options like 2 or 3, or that the meanings are reversed, as seems to currently be the case)

Also, it would be nice if the readme showed the default values for the options. As it stands, I have to manually set the values for options which are probably already the default, just because I don't know whether they're actually the default -- and other options depend on their being a certain value.

Example:
lineWidth: [...] (if sizeAttenuation is true, it's world units; else is screen pixels)
near: [...] (REQUIRED if sizeAttenuation set to false)
But I don't know whether sizeAttenuation defaults to true or false, so I have to set it manually to use either of the settings above, even though it shouldn't be necessary in one of those cases.

Draw tube with rounded corners

Hey there
I actually wrote the stackoverflow question mentioned in the other issue:
#19

I tried to get a result like the on in the picture of the post with your MeshLine.js, but What I currently get is something like this:

screen shot 2016-08-05 at 13 19 38

I disabled sizeAttenuation but it would still make this strange thickenings of the lines.
Is it maybe because my meshLine has different vertices and I am not creating one line for each segment, like you did it in your graph-example? (https://www.clicktorelease.com/code/THREE.MeshLine/demo/graph.html)

Or do you have any other hints on how I could get such a shape with rounded corners, which looks tube-like?

I would be very thankful for any help here. ✌️
Cheers

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.