Skip to content

Commit

Permalink
rename package to @lume/three-meshline, update to newer language feat…
Browse files Browse the repository at this point in the history
…ures (classes, ES Modules, etc), and remove deprecated features
  • Loading branch information
trusktr committed Jan 13, 2023
1 parent b49ae60 commit 6bdf950
Show file tree
Hide file tree
Showing 7 changed files with 915 additions and 850 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
MIT License

Copyright (c) 2016 Jaume Sanchez
Copyright (c) 2022 LUME contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
267 changes: 150 additions & 117 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# MeshLine
Mesh replacement for ```THREE.Line```
# @lume/three-meshline

Provides a Mesh-based replacement for `THREE.Line` from
[Three.js](http://threejs.org), allowing line thicknesses of any size
(`THREE.Line` is limited to 1 pixel width), and other features.

> **Note** This is forked from
> [`three.meshline`](https://github.com/lume/three-meshline), as that project has
> been dormant. The version of this starts at 2.0 because it modernizes the code
> base in ways that make it a breaking change, and removes deprecated features.
Instead of using GL_LINE, it uses a strip of triangles billboarded. Some examples:

Expand All @@ -10,193 +18,218 @@ Instead of using GL_LINE, it uses a strip of triangles billboarded. Some example
[![Shape](screenshots/shape.jpg)](http://spite.github.io/THREE.MeshLine/demo/shape.html)
[![Shape](screenshots/birds.jpg)](http://spite.github.io/THREE.MeshLine/demo/birds.html)

* [Demo](http://spite.github.io/THREE.MeshLine/demo/index.html): play with the different settings of materials
* [Graph](http://spite.github.io/THREE.MeshLine/demo/graph.html): example of using ```MeshLine``` to plot graphs
* [Spinner](http://spite.github.io/THREE.MeshLine/demo/spinner.html): example of dynamic ```MeshLine``` with texture
* [SVG](http://spite.github.io/THREE.MeshLine/demo/svg.html): example of ```MeshLine``` rendering SVG Paths
* [Shape](http://spite.github.io/THREE.MeshLine/demo/shape.html): example of ```MeshLine``` created from a mesh
* [Birds](http://spite.github.io/THREE.MeshLine/demo/birds.html): example of ```MeshLine.advance()``` by @caramelcode (Jared Sprague) and @mwcz (Michael Clayton)
- [Demo](http://spite.github.io/THREE.MeshLine/demo/index.html): play with the
different settings of materials
- [Graph](http://spite.github.io/THREE.MeshLine/demo/graph.html): example of
using `MeshLine` to plot graphs
- [Spinner](http://spite.github.io/THREE.MeshLine/demo/spinner.html): example of
dynamic `MeshLine` with texture
- [SVG](http://spite.github.io/THREE.MeshLine/demo/svg.html): example of
`MeshLine` rendering SVG Paths
- [Shape](http://spite.github.io/THREE.MeshLine/demo/shape.html): example of
`MeshLine` created from a mesh
- [Birds](http://spite.github.io/THREE.MeshLine/demo/birds.html): example of
`MeshLine.advance()` by @caramelcode (Jared Sprague) and @mwcz (Michael Clayton)

### How to use ####
### 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 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 ####
#### Install

First install `three-meshline`:

Include script after THREE is included
```js
<script src="THREE.MeshLine.js"></script>
```
or use npm to install it
npm i three-meshline
```
npm i three.meshline

Add the importmap to your HTML (you may skip this if you're using a build tool):

```html
<script src="./node_modules/three-meshline/importmap.js"></script>
```
and include it in your code (don't forget to require three.js)
```js
const THREE = require('three');
const MeshLine = require('three.meshline').MeshLine;
const MeshLineMaterial = require('three.meshline').MeshLineMaterial;
const MeshLineRaycast = require('three.meshline').MeshLineRaycast;

If your browser doesn't support importmaps yet, you'll need to embed the importmap manually in your HTML along with an importmap polyfill like so:

```html
<script async src="https://ga.jspm.io/npm:es-module-shims@1.6.3/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "/node_modules/three/build/three.module.js",
"three/": "/node_modules/three/",
"three-meshline": "../src/THREE.MeshLine.js",
"three-meshline/": "../"
}
}
</script>
```
or

Finally import into your code:

```js
import * as THREE from 'three';
import { MeshLine, MeshLineMaterial, MeshLineRaycast } from 'three.meshline';
import {MeshLine, MeshLineMaterial, MeshLineRaycast} from 'three-meshline'
```

##### Create an array of 3D coordinates #####
<!-- Alternatively, without installing locally and using the import from
node_modules, use the one from https://....... -->

##### Create an array of 3D coordinates

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

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

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

```js
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 #####
##### 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.

```js
const line = new MeshLine();
line.setPoints(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.

```js
// 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
line.setPoints(geometry, p => 2) // makes width 2 * lineWidth
line.setPoints(geometry, p => 1 - p) // makes width taper from the beginning
line.setPoints(geometry, p => 1 - (1 - p)) // makes width taper from the end
line.setPoints(geometry, p => 2 + Math.sin(50 * p)) // makes width sinusoidal
```

##### Create a MeshLineMaterial #####
##### Create a MeshLineMaterial

A ```MeshLine``` needs a ```MeshLineMaterial```:
A `MeshLine` needs a `MeshLineMaterial`:

```js
const material = new MeshLineMaterial(OPTIONS);
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 #####
`MeshLineMaterial` accepts `options` to control the appereance of the `MeshLine`:

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

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:

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

You can optionally add raycast support with the following.

```js
mesh.raycast = MeshLineRaycast;
mesh.raycast = MeshLineRaycast.bind(null, mesh)
```

### Declarative use ###
### Declarative use

#### react-three-fiber

THREE.meshline can be used declaritively. This is how it would look like in [react-three-fiber](https://github.com/drcmda/react-three-fiber). You can try it live [here](https://codesandbox.io/s/react-three-fiber-three.meshline-example-vl221).
THREE.meshline can be used declaritively. This is how it would look like in
[react-three-fiber](https://github.com/drcmda/react-three-fiber). You can try it
live
[here](https://codesandbox.io/s/react-three-fiber-three.meshline-example-vl221).

<p align="center">
<a href="https://codesandbox.io/s/react-three-fiber-threejs-meshline-example-vl221"><img width="432" height="240" src="https://imgur.com/mZikTAH.gif" /></a>
<a href="https://codesandbox.io/s/threejs-meshline-custom-spring-3-ypkxx"><img width="432" height="240" src="https://imgur.com/g8ts0vJ.gif" /></a>
</p>

```jsx
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>
)
import {extend, Canvas} from 'react-three-fiber'
import {MeshLine, MeshLineMaterial, MeshLineRaycast} from '@lume/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.

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

### TODO ###
### TODO

* Better miters
* Proper sizes
- Better miters

### Support ###
### 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
- Chrome OSX, Windows, Android
- Firefox OSX, Windows, Anroid
- Safari OSX, iOS

### References ###
### References

* [Drawing lines is hard](http://mattdesl.svbtle.com/drawing-lines-is-hard)
* [WebGL rendering of solid trails](http://codeflow.org/entries/2012/aug/05/webgl-rendering-of-solid-trails/)
* [Drawing Antialiased Lines with OpenGL](https://www.mapbox.com/blog/drawing-antialiased-lines/)
- [Drawing lines is hard](http://mattdesl.svbtle.com/drawing-lines-is-hard)
- [WebGL rendering of solid trails](http://codeflow.org/entries/2012/aug/05/webgl-rendering-of-solid-trails/)
- [Drawing Antialiased Lines with OpenGL](https://www.mapbox.com/blog/drawing-antialiased-lines/)

#### License ####
#### License

MIT licensed

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

0 comments on commit 6bdf950

Please sign in to comment.