Initial project import
This commit is contained in:
21
node_modules/meshline/LICENSE
generated
vendored
Normal file
21
node_modules/meshline/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 Jaume Sanchez
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
153
node_modules/meshline/README.md
generated
vendored
Normal file
153
node_modules/meshline/README.md
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
# MeshLine
|
||||
|
||||
A mesh replacement for `THREE.Line`. Instead of using GL_LINE, it uses a strip of billboarded triangles. This is a fork of [spite/THREE.MeshLine](https://github.com/spite/THREE.MeshLine), previously maintained by studio [Utsuboco](https://github.com/utsuboco).
|
||||
|
||||
<p align="center">
|
||||
<img width="32%" src="screenshots/demo.jpg" alt=""/>
|
||||
<img width="32%" src="screenshots/graph.jpg" alt=""/>
|
||||
<img width="32%" src="screenshots/spinner.jpg" alt=""/>
|
||||
<img width="32%" src="screenshots/svg.jpg" alt=""/>
|
||||
<img width="32%" src="screenshots/shape.jpg" alt=""/>
|
||||
<img width="32%" src="screenshots/birds.jpg" alt=""/>
|
||||
</p>
|
||||
|
||||
### How to use
|
||||
|
||||
```
|
||||
npm install meshline
|
||||
```
|
||||
|
||||
```jsx
|
||||
import * as THREE from 'three'
|
||||
import { MeshLineGeometry, MeshLineMaterial, raycast } from 'meshline'
|
||||
|
||||
const geometry = new MeshLineGeometry()
|
||||
geometry.setPoints([...])
|
||||
const material = new MeshLineMaterial({ ... })
|
||||
const mesh = new THREE.Mesh(geometry, material)
|
||||
mesh.raycast = raycast
|
||||
scene.add(mesh)
|
||||
```
|
||||
|
||||
#### Assign points
|
||||
|
||||
Create a `MeshLineGeometry` and pass a list of points into `.setPoints()`. Expected inputs are:
|
||||
|
||||
- `Float32Array`
|
||||
- `THREE.BufferGeometry`
|
||||
- `Array<THREE.Vector3 | THREE.Vector2 | [number, number, number] | [number, number] | number>`
|
||||
|
||||
```jsx
|
||||
const geometry = new MeshLineGeometry()
|
||||
|
||||
const points = []
|
||||
for (let j = 0; j < Math.PI; j += (2 * Math.PI) / 100)
|
||||
points.push(Math.cos(j), Math.sin(j), 0)
|
||||
|
||||
geometry.setPoints(points)
|
||||
```
|
||||
|
||||
Note: `.setPoints` accepts a second parameter, which is a function to define a variable width for each point along the line. By default that value is 1, making the line width 1 \* lineWidth.
|
||||
|
||||
```jsx
|
||||
// p is a decimal percentage of the number of points
|
||||
// ie. point 200 of 250 points, p = 0.8
|
||||
geometry.setPoints(points, (p) => 2) // makes width 2 * lineWidth
|
||||
geometry.setPoints(points, (p) => 1 - p) // makes width taper
|
||||
geometry.setPoints(points, (p) => 2 + Math.sin(50 * p)) // makes width sinusoidal
|
||||
```
|
||||
|
||||
#### Create a material
|
||||
|
||||
```jsx
|
||||
const material = new MeshLineMaterial(options)
|
||||
```
|
||||
|
||||
By default it's a white material of width 1 unit.
|
||||
|
||||
`MeshLineMaterial` has several attributes to control the appereance:
|
||||
|
||||
- `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)
|
||||
- `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` - constant lineWidth regardless of distance (1 is 1px on screen) (0 - attenuate, 1 - don't)
|
||||
- `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`.
|
||||
|
||||
#### Form a mesh
|
||||
|
||||
```jsx
|
||||
const mesh = new THREE.Mesh(geometry, material)
|
||||
scene.add(mesh)
|
||||
```
|
||||
|
||||
### Raycasting
|
||||
|
||||
Raycast can be optionally added by overwriting `mesh.raycast` with the one that meshline provides.
|
||||
|
||||
```jsx
|
||||
import { raycast } from 'meshline'
|
||||
|
||||
mesh.raycast = raycast
|
||||
```
|
||||
|
||||
### Declarative use
|
||||
|
||||
Meshline can be used declaritively in [react-three-fiber](https://github.com/pmndrs/react-three-fiber). `MeshLineGeometry` has a convenience setter/getter for `.setPoints()`, `points`.
|
||||
|
||||
```jsx
|
||||
import { Canvas, extend } from '@react-three/fiber'
|
||||
import { MeshLineGeometry, MeshLineMaterial, raycast } from 'meshline'
|
||||
|
||||
extend({ MeshLineGeometry, MeshLineMaterial })
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<Canvas>
|
||||
<mesh raycast={raycast} onPointerOver={console.log}>
|
||||
<meshLineGeometry points={[0, 0, 0, 1, 0, 0]} />
|
||||
<meshLineMaterial lineWidth={1} color="hotpink" />
|
||||
</mesh>
|
||||
</Canvas>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
#### Variable line widths
|
||||
|
||||
Variable line widths can be set for each point using the `widthCallback` prop.
|
||||
|
||||
```jsx
|
||||
<meshLineGeometry points={points} widthCallback={(p) => p * Math.random()} />
|
||||
```
|
||||
|
||||
#### Types
|
||||
|
||||
Add these declarations to your entry point.
|
||||
|
||||
```tsx
|
||||
import { Object3DNode, MaterialNode } from '@react-three/fiber'
|
||||
|
||||
declare module '@react-three/fiber' {
|
||||
interface ThreeElements {
|
||||
meshLineGeometry: Object3DNode<MeshLineGeometry, typeof MeshLineGeometry>
|
||||
meshLineMaterial: MaterialNode<MeshLineMaterial, typeof MeshLineMaterial>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 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/)
|
||||
40
node_modules/meshline/dist/MeshLineGeometry.d.ts
generated
vendored
Normal file
40
node_modules/meshline/dist/MeshLineGeometry.d.ts
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import * as THREE from 'three';
|
||||
export type PointsRepresentation = THREE.BufferGeometry | Float32Array | THREE.Vector3[] | THREE.Vector2[] | THREE.Vector3Tuple[] | THREE.Vector2Tuple[] | number[];
|
||||
export type WidthCallback = (p: number) => any;
|
||||
export declare class MeshLineGeometry extends THREE.BufferGeometry {
|
||||
type: string;
|
||||
isMeshLine: boolean;
|
||||
positions: number[];
|
||||
previous: number[];
|
||||
next: number[];
|
||||
side: number[];
|
||||
width: number[];
|
||||
indices_array: number[];
|
||||
uvs: number[];
|
||||
counters: number[];
|
||||
widthCallback: WidthCallback | null;
|
||||
_attributes: {
|
||||
position: THREE.BufferAttribute;
|
||||
previous: THREE.BufferAttribute;
|
||||
next: THREE.BufferAttribute;
|
||||
side: THREE.BufferAttribute;
|
||||
width: THREE.BufferAttribute;
|
||||
uv: THREE.BufferAttribute;
|
||||
index: THREE.BufferAttribute;
|
||||
counters: THREE.BufferAttribute;
|
||||
};
|
||||
_points: Float32Array | number[];
|
||||
points: Float32Array | number[];
|
||||
matrixWorld: THREE.Matrix4;
|
||||
constructor();
|
||||
setMatrixWorld(matrixWorld: THREE.Matrix4): void;
|
||||
setPoints(points: PointsRepresentation, wcb?: WidthCallback): void;
|
||||
compareV3(a: number, b: number): boolean;
|
||||
copyV3(a: number): THREE.Vector3Tuple;
|
||||
process(): void;
|
||||
/**
|
||||
* Fast method to advance the line by one position. The oldest position is removed.
|
||||
* @param position
|
||||
*/
|
||||
advance({ x, y, z }: THREE.Vector3): void;
|
||||
}
|
||||
41
node_modules/meshline/dist/MeshLineMaterial.d.ts
generated
vendored
Normal file
41
node_modules/meshline/dist/MeshLineMaterial.d.ts
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import * as THREE from 'three';
|
||||
export interface MeshLineMaterialParameters {
|
||||
lineWidth?: number;
|
||||
map?: THREE.Texture;
|
||||
useMap?: number;
|
||||
alphaMap?: THREE.Texture;
|
||||
useAlphaMap?: number;
|
||||
color?: string | THREE.Color | number;
|
||||
gradient?: string[] | THREE.Color[] | number[];
|
||||
opacity?: number;
|
||||
resolution: THREE.Vector2;
|
||||
sizeAttenuation?: number;
|
||||
dashArray?: number;
|
||||
dashOffset?: number;
|
||||
dashRatio?: number;
|
||||
useDash?: number;
|
||||
useGradient?: number;
|
||||
visibility?: number;
|
||||
alphaTest?: number;
|
||||
repeat?: THREE.Vector2;
|
||||
}
|
||||
export declare class MeshLineMaterial extends THREE.ShaderMaterial implements MeshLineMaterialParameters {
|
||||
lineWidth: number;
|
||||
map: THREE.Texture;
|
||||
useMap: number;
|
||||
alphaMap: THREE.Texture;
|
||||
useAlphaMap: number;
|
||||
color: THREE.Color;
|
||||
gradient: THREE.Color[];
|
||||
resolution: THREE.Vector2;
|
||||
sizeAttenuation: number;
|
||||
dashArray: number;
|
||||
dashOffset: number;
|
||||
dashRatio: number;
|
||||
useDash: number;
|
||||
useGradient: number;
|
||||
visibility: number;
|
||||
repeat: THREE.Vector2;
|
||||
constructor(parameters: MeshLineMaterialParameters);
|
||||
copy(source: MeshLineMaterial): this;
|
||||
}
|
||||
641
node_modules/meshline/dist/index.cjs
generated
vendored
Normal file
641
node_modules/meshline/dist/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,641 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
||||
var __publicField = (obj, key, value) => {
|
||||
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
||||
return value;
|
||||
};
|
||||
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
||||
const THREE = require("three");
|
||||
function _interopNamespace(e) {
|
||||
if (e && e.__esModule)
|
||||
return e;
|
||||
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
||||
if (e) {
|
||||
for (const k in e) {
|
||||
if (k !== "default") {
|
||||
const d = Object.getOwnPropertyDescriptor(e, k);
|
||||
Object.defineProperty(n, k, d.get ? d : {
|
||||
enumerable: true,
|
||||
get: () => e[k]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
n.default = e;
|
||||
return Object.freeze(n);
|
||||
}
|
||||
const THREE__namespace = /* @__PURE__ */ _interopNamespace(THREE);
|
||||
function memcpy(src, srcOffset, dst, dstOffset, length) {
|
||||
let i;
|
||||
src = src.subarray || src.slice ? src : src.buffer;
|
||||
dst = dst.subarray || dst.slice ? dst : dst.buffer;
|
||||
src = srcOffset ? src.subarray ? src.subarray(srcOffset, length && srcOffset + length) : src.slice(srcOffset, length && srcOffset + length) : src;
|
||||
if (dst.set) {
|
||||
dst.set(src, dstOffset);
|
||||
} else {
|
||||
for (i = 0; i < src.length; i++)
|
||||
dst[i + dstOffset] = src[i];
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
function convertPoints(points) {
|
||||
if (points instanceof Float32Array)
|
||||
return points;
|
||||
if (points instanceof THREE__namespace.BufferGeometry)
|
||||
return points.getAttribute("position").array;
|
||||
return points.map((p) => {
|
||||
const isArray = Array.isArray(p);
|
||||
return p instanceof THREE__namespace.Vector3 ? [p.x, p.y, p.z] : p instanceof THREE__namespace.Vector2 ? [p.x, p.y, 0] : isArray && p.length === 3 ? [p[0], p[1], p[2]] : isArray && p.length === 2 ? [p[0], p[1], 0] : p;
|
||||
}).flat();
|
||||
}
|
||||
class MeshLineGeometry extends THREE__namespace.BufferGeometry {
|
||||
constructor() {
|
||||
super();
|
||||
__publicField(this, "type", "MeshLine");
|
||||
__publicField(this, "isMeshLine", true);
|
||||
__publicField(this, "positions", []);
|
||||
__publicField(this, "previous", []);
|
||||
__publicField(this, "next", []);
|
||||
__publicField(this, "side", []);
|
||||
__publicField(this, "width", []);
|
||||
__publicField(this, "indices_array", []);
|
||||
__publicField(this, "uvs", []);
|
||||
__publicField(this, "counters", []);
|
||||
__publicField(this, "widthCallback", null);
|
||||
__publicField(this, "_attributes");
|
||||
__publicField(this, "_points", []);
|
||||
__publicField(this, "points");
|
||||
__publicField(this, "matrixWorld", new THREE__namespace.Matrix4());
|
||||
Object.defineProperties(this, {
|
||||
points: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this._points;
|
||||
},
|
||||
set(value) {
|
||||
this.setPoints(value, this.widthCallback);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
setMatrixWorld(matrixWorld) {
|
||||
this.matrixWorld = matrixWorld;
|
||||
}
|
||||
setPoints(points, wcb) {
|
||||
points = convertPoints(points);
|
||||
this._points = points;
|
||||
this.widthCallback = wcb != null ? wcb : null;
|
||||
this.positions = [];
|
||||
this.counters = [];
|
||||
if (points.length && points[0] instanceof THREE__namespace.Vector3) {
|
||||
for (let j = 0; j < points.length; j++) {
|
||||
const p = points[j];
|
||||
const c = j / (points.length - 1);
|
||||
this.positions.push(p.x, p.y, p.z);
|
||||
this.positions.push(p.x, p.y, p.z);
|
||||
this.counters.push(c);
|
||||
this.counters.push(c);
|
||||
}
|
||||
} else {
|
||||
for (let j = 0; j < points.length; j += 3) {
|
||||
const c = j / (points.length - 1);
|
||||
this.positions.push(points[j], points[j + 1], points[j + 2]);
|
||||
this.positions.push(points[j], points[j + 1], points[j + 2]);
|
||||
this.counters.push(c);
|
||||
this.counters.push(c);
|
||||
}
|
||||
}
|
||||
this.process();
|
||||
}
|
||||
compareV3(a, b) {
|
||||
const aa = a * 6;
|
||||
const ab = b * 6;
|
||||
return this.positions[aa] === this.positions[ab] && this.positions[aa + 1] === this.positions[ab + 1] && this.positions[aa + 2] === this.positions[ab + 2];
|
||||
}
|
||||
copyV3(a) {
|
||||
const aa = a * 6;
|
||||
return [this.positions[aa], this.positions[aa + 1], this.positions[aa + 2]];
|
||||
}
|
||||
process() {
|
||||
const l = this.positions.length / 6;
|
||||
this.previous = [];
|
||||
this.next = [];
|
||||
this.side = [];
|
||||
this.width = [];
|
||||
this.indices_array = [];
|
||||
this.uvs = [];
|
||||
let w;
|
||||
let 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 (let j = 0; j < l; j++) {
|
||||
this.side.push(1);
|
||||
this.side.push(-1);
|
||||
if (this.widthCallback)
|
||||
w = this.widthCallback(j / (l - 1));
|
||||
else
|
||||
w = 1;
|
||||
this.width.push(w);
|
||||
this.width.push(w);
|
||||
this.uvs.push(j / (l - 1), 0);
|
||||
this.uvs.push(j / (l - 1), 1);
|
||||
if (j < l - 1) {
|
||||
v = this.copyV3(j);
|
||||
this.previous.push(v[0], v[1], v[2]);
|
||||
this.previous.push(v[0], v[1], v[2]);
|
||||
const n = j * 2;
|
||||
this.indices_array.push(n, n + 1, n + 2);
|
||||
this.indices_array.push(n + 2, n + 1, n + 3);
|
||||
}
|
||||
if (j > 0) {
|
||||
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]);
|
||||
if (!this._attributes || this._attributes.position.count !== this.counters.length) {
|
||||
this._attributes = {
|
||||
position: new THREE__namespace.BufferAttribute(new Float32Array(this.positions), 3),
|
||||
previous: new THREE__namespace.BufferAttribute(new Float32Array(this.previous), 3),
|
||||
next: new THREE__namespace.BufferAttribute(new Float32Array(this.next), 3),
|
||||
side: new THREE__namespace.BufferAttribute(new Float32Array(this.side), 1),
|
||||
width: new THREE__namespace.BufferAttribute(new Float32Array(this.width), 1),
|
||||
uv: new THREE__namespace.BufferAttribute(new Float32Array(this.uvs), 2),
|
||||
index: new THREE__namespace.BufferAttribute(new Uint16Array(this.indices_array), 1),
|
||||
counters: new THREE__namespace.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.setAttribute("position", this._attributes.position);
|
||||
this.setAttribute("previous", this._attributes.previous);
|
||||
this.setAttribute("next", this._attributes.next);
|
||||
this.setAttribute("side", this._attributes.side);
|
||||
this.setAttribute("width", this._attributes.width);
|
||||
this.setAttribute("uv", this._attributes.uv);
|
||||
this.setAttribute("counters", this._attributes.counters);
|
||||
this.setAttribute("position", this._attributes.position);
|
||||
this.setAttribute("previous", this._attributes.previous);
|
||||
this.setAttribute("next", this._attributes.next);
|
||||
this.setAttribute("side", this._attributes.side);
|
||||
this.setAttribute("width", this._attributes.width);
|
||||
this.setAttribute("uv", this._attributes.uv);
|
||||
this.setAttribute("counters", this._attributes.counters);
|
||||
this.setIndex(this._attributes.index);
|
||||
this.computeBoundingSphere();
|
||||
this.computeBoundingBox();
|
||||
}
|
||||
advance({ x, y, z }) {
|
||||
const positions = this._attributes.position.array;
|
||||
const previous = this._attributes.previous.array;
|
||||
const next = this._attributes.next.array;
|
||||
const l = positions.length;
|
||||
memcpy(positions, 0, previous, 0, l);
|
||||
memcpy(positions, 6, positions, 0, l - 6);
|
||||
positions[l - 6] = x;
|
||||
positions[l - 5] = y;
|
||||
positions[l - 4] = z;
|
||||
positions[l - 3] = x;
|
||||
positions[l - 2] = y;
|
||||
positions[l - 1] = z;
|
||||
memcpy(positions, 6, next, 0, l - 6);
|
||||
next[l - 6] = x;
|
||||
next[l - 5] = y;
|
||||
next[l - 4] = z;
|
||||
next[l - 3] = x;
|
||||
next[l - 2] = y;
|
||||
next[l - 1] = z;
|
||||
this._attributes.position.needsUpdate = true;
|
||||
this._attributes.previous.needsUpdate = true;
|
||||
this._attributes.next.needsUpdate = true;
|
||||
}
|
||||
}
|
||||
const vertexShader = `
|
||||
#include <common>
|
||||
#include <logdepthbuf_pars_vertex>
|
||||
#include <fog_pars_vertex>
|
||||
#include <clipping_planes_pars_vertex>
|
||||
|
||||
attribute vec3 previous;
|
||||
attribute vec3 next;
|
||||
attribute float side;
|
||||
attribute float width;
|
||||
attribute float counters;
|
||||
|
||||
uniform vec2 resolution;
|
||||
uniform float lineWidth;
|
||||
uniform vec3 color;
|
||||
uniform float opacity;
|
||||
uniform float sizeAttenuation;
|
||||
|
||||
varying vec2 vUV;
|
||||
varying vec4 vColor;
|
||||
varying float vCounters;
|
||||
|
||||
vec2 fix(vec4 i, float aspect) {
|
||||
vec2 res = i.xy / i.w;
|
||||
res.x *= aspect;
|
||||
return res;
|
||||
}
|
||||
|
||||
void main() {
|
||||
float aspect = resolution.x / resolution.y;
|
||||
vColor = vec4(color, opacity);
|
||||
vUV = uv;
|
||||
vCounters = counters;
|
||||
|
||||
mat4 m = projectionMatrix * modelViewMatrix;
|
||||
vec4 finalPosition = m * vec4(position, 1.0) * aspect;
|
||||
vec4 prevPos = m * vec4(previous, 1.0);
|
||||
vec4 nextPos = m * vec4(next, 1.0);
|
||||
|
||||
vec2 currentP = fix(finalPosition, aspect);
|
||||
vec2 prevP = fix(prevPos, aspect);
|
||||
vec2 nextP = fix(nextPos, aspect);
|
||||
|
||||
float w = lineWidth * width;
|
||||
|
||||
vec2 dir;
|
||||
if (nextP == currentP) dir = normalize(currentP - prevP);
|
||||
else if (prevP == currentP) dir = normalize(nextP - currentP);
|
||||
else {
|
||||
vec2 dir1 = normalize(currentP - prevP);
|
||||
vec2 dir2 = normalize(nextP - currentP);
|
||||
dir = normalize(dir1 + dir2);
|
||||
|
||||
vec2 perp = vec2(-dir1.y, dir1.x);
|
||||
vec2 miter = vec2(-dir.y, dir.x);
|
||||
//w = clamp(w / dot(miter, perp), 0., 4. * lineWidth * width);
|
||||
}
|
||||
|
||||
//vec2 normal = (cross(vec3(dir, 0.), vec3(0., 0., 1.))).xy;
|
||||
vec4 normal = vec4(-dir.y, dir.x, 0., 1.);
|
||||
normal.xy *= .5 * w;
|
||||
//normal *= projectionMatrix;
|
||||
if (sizeAttenuation == 0.) {
|
||||
normal.xy *= finalPosition.w;
|
||||
normal.xy /= (vec4(resolution, 0., 1.) * projectionMatrix).xy * aspect;
|
||||
}
|
||||
|
||||
finalPosition.xy += normal.xy * side;
|
||||
gl_Position = finalPosition;
|
||||
#include <logdepthbuf_vertex>
|
||||
#include <fog_vertex>
|
||||
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
|
||||
#include <clipping_planes_vertex>
|
||||
#include <fog_vertex>
|
||||
}
|
||||
`;
|
||||
const version = /* @__PURE__ */ (() => parseInt(THREE__namespace.REVISION.replace(/\D+/g, "")))();
|
||||
const colorspace_fragment = version >= 154 ? "colorspace_fragment" : "encodings_fragment";
|
||||
const fragmentShader = `
|
||||
#include <fog_pars_fragment>
|
||||
#include <logdepthbuf_pars_fragment>
|
||||
#include <clipping_planes_pars_fragment>
|
||||
|
||||
uniform sampler2D map;
|
||||
uniform sampler2D alphaMap;
|
||||
uniform float useGradient;
|
||||
uniform float useMap;
|
||||
uniform float useAlphaMap;
|
||||
uniform float useDash;
|
||||
uniform float dashArray;
|
||||
uniform float dashOffset;
|
||||
uniform float dashRatio;
|
||||
uniform float visibility;
|
||||
uniform float alphaTest;
|
||||
uniform vec2 repeat;
|
||||
uniform vec3 gradient[2];
|
||||
|
||||
varying vec2 vUV;
|
||||
varying vec4 vColor;
|
||||
varying float vCounters;
|
||||
|
||||
void main() {
|
||||
#include <logdepthbuf_fragment>
|
||||
vec4 diffuseColor = vColor;
|
||||
if (useGradient == 1.) diffuseColor = vec4(mix(gradient[0], gradient[1], vCounters), 1.0);
|
||||
if (useMap == 1.) diffuseColor *= texture2D(map, vUV * repeat);
|
||||
if (useAlphaMap == 1.) diffuseColor.a *= texture2D(alphaMap, vUV * repeat).a;
|
||||
if (diffuseColor.a < alphaTest) discard;
|
||||
if (useDash == 1.) diffuseColor.a *= ceil(mod(vCounters + dashOffset, dashArray) - (dashArray * dashRatio));
|
||||
diffuseColor.a *= step(vCounters, visibility);
|
||||
#include <clipping_planes_fragment>
|
||||
gl_FragColor = diffuseColor;
|
||||
#include <fog_fragment>
|
||||
#include <tonemapping_fragment>
|
||||
#include <${colorspace_fragment}>
|
||||
}
|
||||
`;
|
||||
class MeshLineMaterial extends THREE__namespace.ShaderMaterial {
|
||||
constructor(parameters) {
|
||||
super({
|
||||
uniforms: {
|
||||
...THREE__namespace.UniformsLib.fog,
|
||||
lineWidth: { value: 1 },
|
||||
map: { value: null },
|
||||
useMap: { value: 0 },
|
||||
alphaMap: { value: null },
|
||||
useAlphaMap: { value: 0 },
|
||||
color: { value: new THREE__namespace.Color(16777215) },
|
||||
gradient: { value: [new THREE__namespace.Color(16711680), new THREE__namespace.Color(65280)] },
|
||||
opacity: { value: 1 },
|
||||
resolution: { value: new THREE__namespace.Vector2(1, 1) },
|
||||
sizeAttenuation: { value: 1 },
|
||||
dashArray: { value: 0 },
|
||||
dashOffset: { value: 0 },
|
||||
dashRatio: { value: 0.5 },
|
||||
useDash: { value: 0 },
|
||||
useGradient: { value: 0 },
|
||||
visibility: { value: 1 },
|
||||
alphaTest: { value: 0 },
|
||||
repeat: { value: new THREE__namespace.Vector2(1, 1) }
|
||||
},
|
||||
vertexShader,
|
||||
fragmentShader
|
||||
});
|
||||
__publicField(this, "lineWidth");
|
||||
__publicField(this, "map");
|
||||
__publicField(this, "useMap");
|
||||
__publicField(this, "alphaMap");
|
||||
__publicField(this, "useAlphaMap");
|
||||
__publicField(this, "color");
|
||||
__publicField(this, "gradient");
|
||||
__publicField(this, "resolution");
|
||||
__publicField(this, "sizeAttenuation");
|
||||
__publicField(this, "dashArray");
|
||||
__publicField(this, "dashOffset");
|
||||
__publicField(this, "dashRatio");
|
||||
__publicField(this, "useDash");
|
||||
__publicField(this, "useGradient");
|
||||
__publicField(this, "visibility");
|
||||
__publicField(this, "repeat");
|
||||
this.type = "MeshLineMaterial";
|
||||
Object.defineProperties(this, {
|
||||
lineWidth: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.lineWidth.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.lineWidth.value = value;
|
||||
}
|
||||
},
|
||||
map: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.map.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.map.value = value;
|
||||
}
|
||||
},
|
||||
useMap: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.useMap.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.useMap.value = value;
|
||||
}
|
||||
},
|
||||
alphaMap: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.alphaMap.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.alphaMap.value = value;
|
||||
}
|
||||
},
|
||||
useAlphaMap: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.useAlphaMap.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.useAlphaMap.value = value;
|
||||
}
|
||||
},
|
||||
color: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.color.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.color.value = value;
|
||||
}
|
||||
},
|
||||
gradient: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.gradient.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.gradient.value = value;
|
||||
}
|
||||
},
|
||||
opacity: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.opacity.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.opacity.value = value;
|
||||
}
|
||||
},
|
||||
resolution: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.resolution.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.resolution.value.copy(value);
|
||||
}
|
||||
},
|
||||
sizeAttenuation: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.sizeAttenuation.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.sizeAttenuation.value = value;
|
||||
}
|
||||
},
|
||||
dashArray: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.dashArray.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.dashArray.value = value;
|
||||
this.useDash = value !== 0 ? 1 : 0;
|
||||
}
|
||||
},
|
||||
dashOffset: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.dashOffset.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.dashOffset.value = value;
|
||||
}
|
||||
},
|
||||
dashRatio: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.dashRatio.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.dashRatio.value = value;
|
||||
}
|
||||
},
|
||||
useDash: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.useDash.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.useDash.value = value;
|
||||
}
|
||||
},
|
||||
useGradient: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.useGradient.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.useGradient.value = value;
|
||||
}
|
||||
},
|
||||
visibility: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.visibility.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.visibility.value = value;
|
||||
}
|
||||
},
|
||||
alphaTest: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.alphaTest.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.alphaTest.value = value;
|
||||
}
|
||||
},
|
||||
repeat: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.repeat.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.repeat.value.copy(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.setValues(parameters);
|
||||
}
|
||||
copy(source) {
|
||||
super.copy(source);
|
||||
this.lineWidth = source.lineWidth;
|
||||
this.map = source.map;
|
||||
this.useMap = source.useMap;
|
||||
this.alphaMap = source.alphaMap;
|
||||
this.useAlphaMap = source.useAlphaMap;
|
||||
this.color.copy(source.color);
|
||||
this.gradient = source.gradient;
|
||||
this.opacity = source.opacity;
|
||||
this.resolution.copy(source.resolution);
|
||||
this.sizeAttenuation = source.sizeAttenuation;
|
||||
this.dashArray = source.dashArray;
|
||||
this.dashOffset = source.dashOffset;
|
||||
this.dashRatio = source.dashRatio;
|
||||
this.useDash = source.useDash;
|
||||
this.useGradient = source.useGradient;
|
||||
this.visibility = source.visibility;
|
||||
this.alphaTest = source.alphaTest;
|
||||
this.repeat.copy(source.repeat);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
function raycast(raycaster, intersects) {
|
||||
const inverseMatrix = new THREE__namespace.Matrix4();
|
||||
const ray = new THREE__namespace.Ray();
|
||||
const sphere = new THREE__namespace.Sphere();
|
||||
const interRay = new THREE__namespace.Vector3();
|
||||
const geometry = this.geometry;
|
||||
sphere.copy(geometry.boundingSphere);
|
||||
sphere.applyMatrix4(this.matrixWorld);
|
||||
if (!raycaster.ray.intersectSphere(sphere, interRay))
|
||||
return;
|
||||
inverseMatrix.copy(this.matrixWorld).invert();
|
||||
ray.copy(raycaster.ray).applyMatrix4(inverseMatrix);
|
||||
const vStart = new THREE__namespace.Vector3();
|
||||
const vEnd = new THREE__namespace.Vector3();
|
||||
const interSegment = new THREE__namespace.Vector3();
|
||||
const step = this instanceof THREE__namespace.LineSegments ? 2 : 1;
|
||||
const index = geometry.index;
|
||||
const attributes = geometry.attributes;
|
||||
if (index !== null) {
|
||||
const indices = index.array;
|
||||
const positions = attributes.position.array;
|
||||
const widths = attributes.width.array;
|
||||
for (let i = 0, l = indices.length - 1; i < l; i += step) {
|
||||
const a = indices[i];
|
||||
const b = indices[i + 1];
|
||||
vStart.fromArray(positions, a * 3);
|
||||
vEnd.fromArray(positions, b * 3);
|
||||
const width = widths[Math.floor(i / 3)] != void 0 ? widths[Math.floor(i / 3)] : 1;
|
||||
const precision = raycaster.params.Line.threshold + this.material.lineWidth * width / 2;
|
||||
const precisionSq = precision * precision;
|
||||
const distSq = ray.distanceSqToSegment(vStart, vEnd, interRay, interSegment);
|
||||
if (distSq > precisionSq)
|
||||
continue;
|
||||
interRay.applyMatrix4(this.matrixWorld);
|
||||
const distance = raycaster.ray.origin.distanceTo(interRay);
|
||||
if (distance < raycaster.near || distance > raycaster.far)
|
||||
continue;
|
||||
intersects.push({
|
||||
distance,
|
||||
point: interSegment.clone().applyMatrix4(this.matrixWorld),
|
||||
index: i,
|
||||
face: null,
|
||||
faceIndex: void 0,
|
||||
object: this
|
||||
});
|
||||
i = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.MeshLineGeometry = MeshLineGeometry;
|
||||
exports.MeshLineMaterial = MeshLineMaterial;
|
||||
exports.raycast = raycast;
|
||||
3
node_modules/meshline/dist/index.d.ts
generated
vendored
Normal file
3
node_modules/meshline/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './MeshLineGeometry';
|
||||
export * from './MeshLineMaterial';
|
||||
export * from './raycast';
|
||||
622
node_modules/meshline/dist/index.js
generated
vendored
Normal file
622
node_modules/meshline/dist/index.js
generated
vendored
Normal file
@@ -0,0 +1,622 @@
|
||||
var __defProp = Object.defineProperty;
|
||||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
||||
var __publicField = (obj, key, value) => {
|
||||
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
||||
return value;
|
||||
};
|
||||
import * as THREE from "three";
|
||||
function memcpy(src, srcOffset, dst, dstOffset, length) {
|
||||
let i;
|
||||
src = src.subarray || src.slice ? src : src.buffer;
|
||||
dst = dst.subarray || dst.slice ? dst : dst.buffer;
|
||||
src = srcOffset ? src.subarray ? src.subarray(srcOffset, length && srcOffset + length) : src.slice(srcOffset, length && srcOffset + length) : src;
|
||||
if (dst.set) {
|
||||
dst.set(src, dstOffset);
|
||||
} else {
|
||||
for (i = 0; i < src.length; i++)
|
||||
dst[i + dstOffset] = src[i];
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
function convertPoints(points) {
|
||||
if (points instanceof Float32Array)
|
||||
return points;
|
||||
if (points instanceof THREE.BufferGeometry)
|
||||
return points.getAttribute("position").array;
|
||||
return points.map((p) => {
|
||||
const isArray = Array.isArray(p);
|
||||
return p instanceof THREE.Vector3 ? [p.x, p.y, p.z] : p instanceof THREE.Vector2 ? [p.x, p.y, 0] : isArray && p.length === 3 ? [p[0], p[1], p[2]] : isArray && p.length === 2 ? [p[0], p[1], 0] : p;
|
||||
}).flat();
|
||||
}
|
||||
class MeshLineGeometry extends THREE.BufferGeometry {
|
||||
constructor() {
|
||||
super();
|
||||
__publicField(this, "type", "MeshLine");
|
||||
__publicField(this, "isMeshLine", true);
|
||||
__publicField(this, "positions", []);
|
||||
__publicField(this, "previous", []);
|
||||
__publicField(this, "next", []);
|
||||
__publicField(this, "side", []);
|
||||
__publicField(this, "width", []);
|
||||
__publicField(this, "indices_array", []);
|
||||
__publicField(this, "uvs", []);
|
||||
__publicField(this, "counters", []);
|
||||
__publicField(this, "widthCallback", null);
|
||||
__publicField(this, "_attributes");
|
||||
__publicField(this, "_points", []);
|
||||
__publicField(this, "points");
|
||||
__publicField(this, "matrixWorld", new THREE.Matrix4());
|
||||
Object.defineProperties(this, {
|
||||
points: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this._points;
|
||||
},
|
||||
set(value) {
|
||||
this.setPoints(value, this.widthCallback);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
setMatrixWorld(matrixWorld) {
|
||||
this.matrixWorld = matrixWorld;
|
||||
}
|
||||
setPoints(points, wcb) {
|
||||
points = convertPoints(points);
|
||||
this._points = points;
|
||||
this.widthCallback = wcb != null ? wcb : null;
|
||||
this.positions = [];
|
||||
this.counters = [];
|
||||
if (points.length && points[0] instanceof THREE.Vector3) {
|
||||
for (let j = 0; j < points.length; j++) {
|
||||
const p = points[j];
|
||||
const c = j / (points.length - 1);
|
||||
this.positions.push(p.x, p.y, p.z);
|
||||
this.positions.push(p.x, p.y, p.z);
|
||||
this.counters.push(c);
|
||||
this.counters.push(c);
|
||||
}
|
||||
} else {
|
||||
for (let j = 0; j < points.length; j += 3) {
|
||||
const c = j / (points.length - 1);
|
||||
this.positions.push(points[j], points[j + 1], points[j + 2]);
|
||||
this.positions.push(points[j], points[j + 1], points[j + 2]);
|
||||
this.counters.push(c);
|
||||
this.counters.push(c);
|
||||
}
|
||||
}
|
||||
this.process();
|
||||
}
|
||||
compareV3(a, b) {
|
||||
const aa = a * 6;
|
||||
const ab = b * 6;
|
||||
return this.positions[aa] === this.positions[ab] && this.positions[aa + 1] === this.positions[ab + 1] && this.positions[aa + 2] === this.positions[ab + 2];
|
||||
}
|
||||
copyV3(a) {
|
||||
const aa = a * 6;
|
||||
return [this.positions[aa], this.positions[aa + 1], this.positions[aa + 2]];
|
||||
}
|
||||
process() {
|
||||
const l = this.positions.length / 6;
|
||||
this.previous = [];
|
||||
this.next = [];
|
||||
this.side = [];
|
||||
this.width = [];
|
||||
this.indices_array = [];
|
||||
this.uvs = [];
|
||||
let w;
|
||||
let 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 (let j = 0; j < l; j++) {
|
||||
this.side.push(1);
|
||||
this.side.push(-1);
|
||||
if (this.widthCallback)
|
||||
w = this.widthCallback(j / (l - 1));
|
||||
else
|
||||
w = 1;
|
||||
this.width.push(w);
|
||||
this.width.push(w);
|
||||
this.uvs.push(j / (l - 1), 0);
|
||||
this.uvs.push(j / (l - 1), 1);
|
||||
if (j < l - 1) {
|
||||
v = this.copyV3(j);
|
||||
this.previous.push(v[0], v[1], v[2]);
|
||||
this.previous.push(v[0], v[1], v[2]);
|
||||
const n = j * 2;
|
||||
this.indices_array.push(n, n + 1, n + 2);
|
||||
this.indices_array.push(n + 2, n + 1, n + 3);
|
||||
}
|
||||
if (j > 0) {
|
||||
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]);
|
||||
if (!this._attributes || this._attributes.position.count !== this.counters.length) {
|
||||
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.setAttribute("position", this._attributes.position);
|
||||
this.setAttribute("previous", this._attributes.previous);
|
||||
this.setAttribute("next", this._attributes.next);
|
||||
this.setAttribute("side", this._attributes.side);
|
||||
this.setAttribute("width", this._attributes.width);
|
||||
this.setAttribute("uv", this._attributes.uv);
|
||||
this.setAttribute("counters", this._attributes.counters);
|
||||
this.setAttribute("position", this._attributes.position);
|
||||
this.setAttribute("previous", this._attributes.previous);
|
||||
this.setAttribute("next", this._attributes.next);
|
||||
this.setAttribute("side", this._attributes.side);
|
||||
this.setAttribute("width", this._attributes.width);
|
||||
this.setAttribute("uv", this._attributes.uv);
|
||||
this.setAttribute("counters", this._attributes.counters);
|
||||
this.setIndex(this._attributes.index);
|
||||
this.computeBoundingSphere();
|
||||
this.computeBoundingBox();
|
||||
}
|
||||
advance({ x, y, z }) {
|
||||
const positions = this._attributes.position.array;
|
||||
const previous = this._attributes.previous.array;
|
||||
const next = this._attributes.next.array;
|
||||
const l = positions.length;
|
||||
memcpy(positions, 0, previous, 0, l);
|
||||
memcpy(positions, 6, positions, 0, l - 6);
|
||||
positions[l - 6] = x;
|
||||
positions[l - 5] = y;
|
||||
positions[l - 4] = z;
|
||||
positions[l - 3] = x;
|
||||
positions[l - 2] = y;
|
||||
positions[l - 1] = z;
|
||||
memcpy(positions, 6, next, 0, l - 6);
|
||||
next[l - 6] = x;
|
||||
next[l - 5] = y;
|
||||
next[l - 4] = z;
|
||||
next[l - 3] = x;
|
||||
next[l - 2] = y;
|
||||
next[l - 1] = z;
|
||||
this._attributes.position.needsUpdate = true;
|
||||
this._attributes.previous.needsUpdate = true;
|
||||
this._attributes.next.needsUpdate = true;
|
||||
}
|
||||
}
|
||||
const vertexShader = `
|
||||
#include <common>
|
||||
#include <logdepthbuf_pars_vertex>
|
||||
#include <fog_pars_vertex>
|
||||
#include <clipping_planes_pars_vertex>
|
||||
|
||||
attribute vec3 previous;
|
||||
attribute vec3 next;
|
||||
attribute float side;
|
||||
attribute float width;
|
||||
attribute float counters;
|
||||
|
||||
uniform vec2 resolution;
|
||||
uniform float lineWidth;
|
||||
uniform vec3 color;
|
||||
uniform float opacity;
|
||||
uniform float sizeAttenuation;
|
||||
|
||||
varying vec2 vUV;
|
||||
varying vec4 vColor;
|
||||
varying float vCounters;
|
||||
|
||||
vec2 fix(vec4 i, float aspect) {
|
||||
vec2 res = i.xy / i.w;
|
||||
res.x *= aspect;
|
||||
return res;
|
||||
}
|
||||
|
||||
void main() {
|
||||
float aspect = resolution.x / resolution.y;
|
||||
vColor = vec4(color, opacity);
|
||||
vUV = uv;
|
||||
vCounters = counters;
|
||||
|
||||
mat4 m = projectionMatrix * modelViewMatrix;
|
||||
vec4 finalPosition = m * vec4(position, 1.0) * aspect;
|
||||
vec4 prevPos = m * vec4(previous, 1.0);
|
||||
vec4 nextPos = m * vec4(next, 1.0);
|
||||
|
||||
vec2 currentP = fix(finalPosition, aspect);
|
||||
vec2 prevP = fix(prevPos, aspect);
|
||||
vec2 nextP = fix(nextPos, aspect);
|
||||
|
||||
float w = lineWidth * width;
|
||||
|
||||
vec2 dir;
|
||||
if (nextP == currentP) dir = normalize(currentP - prevP);
|
||||
else if (prevP == currentP) dir = normalize(nextP - currentP);
|
||||
else {
|
||||
vec2 dir1 = normalize(currentP - prevP);
|
||||
vec2 dir2 = normalize(nextP - currentP);
|
||||
dir = normalize(dir1 + dir2);
|
||||
|
||||
vec2 perp = vec2(-dir1.y, dir1.x);
|
||||
vec2 miter = vec2(-dir.y, dir.x);
|
||||
//w = clamp(w / dot(miter, perp), 0., 4. * lineWidth * width);
|
||||
}
|
||||
|
||||
//vec2 normal = (cross(vec3(dir, 0.), vec3(0., 0., 1.))).xy;
|
||||
vec4 normal = vec4(-dir.y, dir.x, 0., 1.);
|
||||
normal.xy *= .5 * w;
|
||||
//normal *= projectionMatrix;
|
||||
if (sizeAttenuation == 0.) {
|
||||
normal.xy *= finalPosition.w;
|
||||
normal.xy /= (vec4(resolution, 0., 1.) * projectionMatrix).xy * aspect;
|
||||
}
|
||||
|
||||
finalPosition.xy += normal.xy * side;
|
||||
gl_Position = finalPosition;
|
||||
#include <logdepthbuf_vertex>
|
||||
#include <fog_vertex>
|
||||
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
|
||||
#include <clipping_planes_vertex>
|
||||
#include <fog_vertex>
|
||||
}
|
||||
`;
|
||||
const version = /* @__PURE__ */ (() => parseInt(THREE.REVISION.replace(/\D+/g, "")))();
|
||||
const colorspace_fragment = version >= 154 ? "colorspace_fragment" : "encodings_fragment";
|
||||
const fragmentShader = `
|
||||
#include <fog_pars_fragment>
|
||||
#include <logdepthbuf_pars_fragment>
|
||||
#include <clipping_planes_pars_fragment>
|
||||
|
||||
uniform sampler2D map;
|
||||
uniform sampler2D alphaMap;
|
||||
uniform float useGradient;
|
||||
uniform float useMap;
|
||||
uniform float useAlphaMap;
|
||||
uniform float useDash;
|
||||
uniform float dashArray;
|
||||
uniform float dashOffset;
|
||||
uniform float dashRatio;
|
||||
uniform float visibility;
|
||||
uniform float alphaTest;
|
||||
uniform vec2 repeat;
|
||||
uniform vec3 gradient[2];
|
||||
|
||||
varying vec2 vUV;
|
||||
varying vec4 vColor;
|
||||
varying float vCounters;
|
||||
|
||||
void main() {
|
||||
#include <logdepthbuf_fragment>
|
||||
vec4 diffuseColor = vColor;
|
||||
if (useGradient == 1.) diffuseColor = vec4(mix(gradient[0], gradient[1], vCounters), 1.0);
|
||||
if (useMap == 1.) diffuseColor *= texture2D(map, vUV * repeat);
|
||||
if (useAlphaMap == 1.) diffuseColor.a *= texture2D(alphaMap, vUV * repeat).a;
|
||||
if (diffuseColor.a < alphaTest) discard;
|
||||
if (useDash == 1.) diffuseColor.a *= ceil(mod(vCounters + dashOffset, dashArray) - (dashArray * dashRatio));
|
||||
diffuseColor.a *= step(vCounters, visibility);
|
||||
#include <clipping_planes_fragment>
|
||||
gl_FragColor = diffuseColor;
|
||||
#include <fog_fragment>
|
||||
#include <tonemapping_fragment>
|
||||
#include <${colorspace_fragment}>
|
||||
}
|
||||
`;
|
||||
class MeshLineMaterial extends THREE.ShaderMaterial {
|
||||
constructor(parameters) {
|
||||
super({
|
||||
uniforms: {
|
||||
...THREE.UniformsLib.fog,
|
||||
lineWidth: { value: 1 },
|
||||
map: { value: null },
|
||||
useMap: { value: 0 },
|
||||
alphaMap: { value: null },
|
||||
useAlphaMap: { value: 0 },
|
||||
color: { value: new THREE.Color(16777215) },
|
||||
gradient: { value: [new THREE.Color(16711680), new THREE.Color(65280)] },
|
||||
opacity: { value: 1 },
|
||||
resolution: { value: new THREE.Vector2(1, 1) },
|
||||
sizeAttenuation: { value: 1 },
|
||||
dashArray: { value: 0 },
|
||||
dashOffset: { value: 0 },
|
||||
dashRatio: { value: 0.5 },
|
||||
useDash: { value: 0 },
|
||||
useGradient: { value: 0 },
|
||||
visibility: { value: 1 },
|
||||
alphaTest: { value: 0 },
|
||||
repeat: { value: new THREE.Vector2(1, 1) }
|
||||
},
|
||||
vertexShader,
|
||||
fragmentShader
|
||||
});
|
||||
__publicField(this, "lineWidth");
|
||||
__publicField(this, "map");
|
||||
__publicField(this, "useMap");
|
||||
__publicField(this, "alphaMap");
|
||||
__publicField(this, "useAlphaMap");
|
||||
__publicField(this, "color");
|
||||
__publicField(this, "gradient");
|
||||
__publicField(this, "resolution");
|
||||
__publicField(this, "sizeAttenuation");
|
||||
__publicField(this, "dashArray");
|
||||
__publicField(this, "dashOffset");
|
||||
__publicField(this, "dashRatio");
|
||||
__publicField(this, "useDash");
|
||||
__publicField(this, "useGradient");
|
||||
__publicField(this, "visibility");
|
||||
__publicField(this, "repeat");
|
||||
this.type = "MeshLineMaterial";
|
||||
Object.defineProperties(this, {
|
||||
lineWidth: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.lineWidth.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.lineWidth.value = value;
|
||||
}
|
||||
},
|
||||
map: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.map.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.map.value = value;
|
||||
}
|
||||
},
|
||||
useMap: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.useMap.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.useMap.value = value;
|
||||
}
|
||||
},
|
||||
alphaMap: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.alphaMap.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.alphaMap.value = value;
|
||||
}
|
||||
},
|
||||
useAlphaMap: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.useAlphaMap.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.useAlphaMap.value = value;
|
||||
}
|
||||
},
|
||||
color: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.color.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.color.value = value;
|
||||
}
|
||||
},
|
||||
gradient: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.gradient.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.gradient.value = value;
|
||||
}
|
||||
},
|
||||
opacity: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.opacity.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.opacity.value = value;
|
||||
}
|
||||
},
|
||||
resolution: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.resolution.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.resolution.value.copy(value);
|
||||
}
|
||||
},
|
||||
sizeAttenuation: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.sizeAttenuation.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.sizeAttenuation.value = value;
|
||||
}
|
||||
},
|
||||
dashArray: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.dashArray.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.dashArray.value = value;
|
||||
this.useDash = value !== 0 ? 1 : 0;
|
||||
}
|
||||
},
|
||||
dashOffset: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.dashOffset.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.dashOffset.value = value;
|
||||
}
|
||||
},
|
||||
dashRatio: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.dashRatio.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.dashRatio.value = value;
|
||||
}
|
||||
},
|
||||
useDash: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.useDash.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.useDash.value = value;
|
||||
}
|
||||
},
|
||||
useGradient: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.useGradient.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.useGradient.value = value;
|
||||
}
|
||||
},
|
||||
visibility: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.visibility.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.visibility.value = value;
|
||||
}
|
||||
},
|
||||
alphaTest: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.alphaTest.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.alphaTest.value = value;
|
||||
}
|
||||
},
|
||||
repeat: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.uniforms.repeat.value;
|
||||
},
|
||||
set(value) {
|
||||
this.uniforms.repeat.value.copy(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.setValues(parameters);
|
||||
}
|
||||
copy(source) {
|
||||
super.copy(source);
|
||||
this.lineWidth = source.lineWidth;
|
||||
this.map = source.map;
|
||||
this.useMap = source.useMap;
|
||||
this.alphaMap = source.alphaMap;
|
||||
this.useAlphaMap = source.useAlphaMap;
|
||||
this.color.copy(source.color);
|
||||
this.gradient = source.gradient;
|
||||
this.opacity = source.opacity;
|
||||
this.resolution.copy(source.resolution);
|
||||
this.sizeAttenuation = source.sizeAttenuation;
|
||||
this.dashArray = source.dashArray;
|
||||
this.dashOffset = source.dashOffset;
|
||||
this.dashRatio = source.dashRatio;
|
||||
this.useDash = source.useDash;
|
||||
this.useGradient = source.useGradient;
|
||||
this.visibility = source.visibility;
|
||||
this.alphaTest = source.alphaTest;
|
||||
this.repeat.copy(source.repeat);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
function raycast(raycaster, intersects) {
|
||||
const inverseMatrix = new THREE.Matrix4();
|
||||
const ray = new THREE.Ray();
|
||||
const sphere = new THREE.Sphere();
|
||||
const interRay = new THREE.Vector3();
|
||||
const geometry = this.geometry;
|
||||
sphere.copy(geometry.boundingSphere);
|
||||
sphere.applyMatrix4(this.matrixWorld);
|
||||
if (!raycaster.ray.intersectSphere(sphere, interRay))
|
||||
return;
|
||||
inverseMatrix.copy(this.matrixWorld).invert();
|
||||
ray.copy(raycaster.ray).applyMatrix4(inverseMatrix);
|
||||
const vStart = new THREE.Vector3();
|
||||
const vEnd = new THREE.Vector3();
|
||||
const interSegment = new THREE.Vector3();
|
||||
const step = this instanceof THREE.LineSegments ? 2 : 1;
|
||||
const index = geometry.index;
|
||||
const attributes = geometry.attributes;
|
||||
if (index !== null) {
|
||||
const indices = index.array;
|
||||
const positions = attributes.position.array;
|
||||
const widths = attributes.width.array;
|
||||
for (let i = 0, l = indices.length - 1; i < l; i += step) {
|
||||
const a = indices[i];
|
||||
const b = indices[i + 1];
|
||||
vStart.fromArray(positions, a * 3);
|
||||
vEnd.fromArray(positions, b * 3);
|
||||
const width = widths[Math.floor(i / 3)] != void 0 ? widths[Math.floor(i / 3)] : 1;
|
||||
const precision = raycaster.params.Line.threshold + this.material.lineWidth * width / 2;
|
||||
const precisionSq = precision * precision;
|
||||
const distSq = ray.distanceSqToSegment(vStart, vEnd, interRay, interSegment);
|
||||
if (distSq > precisionSq)
|
||||
continue;
|
||||
interRay.applyMatrix4(this.matrixWorld);
|
||||
const distance = raycaster.ray.origin.distanceTo(interRay);
|
||||
if (distance < raycaster.near || distance > raycaster.far)
|
||||
continue;
|
||||
intersects.push({
|
||||
distance,
|
||||
point: interSegment.clone().applyMatrix4(this.matrixWorld),
|
||||
index: i,
|
||||
face: null,
|
||||
faceIndex: void 0,
|
||||
object: this
|
||||
});
|
||||
i = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
MeshLineGeometry,
|
||||
MeshLineMaterial,
|
||||
raycast
|
||||
};
|
||||
3
node_modules/meshline/dist/raycast.d.ts
generated
vendored
Normal file
3
node_modules/meshline/dist/raycast.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import * as THREE from 'three';
|
||||
import type { MeshLineMaterial } from './MeshLineMaterial';
|
||||
export declare function raycast(this: THREE.Mesh<THREE.BufferGeometry, MeshLineMaterial>, raycaster: THREE.Raycaster, intersects: THREE.Intersection[]): void;
|
||||
38
node_modules/meshline/package.json
generated
vendored
Normal file
38
node_modules/meshline/package.json
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "meshline",
|
||||
"version": "3.3.1",
|
||||
"author": "Jaume Sanchez <the.spite@gmail.com> (https://www.clicktorelease.com)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/pmndrs/meshline/issues"
|
||||
},
|
||||
"homepage": "https://github.com/pmndrs/meshline#readme",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"devDependencies": {
|
||||
"@react-three/fiber": "^8.9.1",
|
||||
"@react-three/postprocessing": "^2.7.0",
|
||||
"@types/node": "^18.11.13",
|
||||
"@types/three": "^0.146.0",
|
||||
"@vitejs/plugin-react": "2",
|
||||
"leva": "^0.9.34",
|
||||
"maath": "^0.4.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"three": "^0.147.0",
|
||||
"typescript": "^4.9.3",
|
||||
"vite": "^3.2.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"three": ">=0.137"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite demo",
|
||||
"build": "vite build && tsc"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user