three-stdlib 2.29.1 → 2.29.3
Sign up to get free protection for your applications and to get access to all the features.
- package/exporters/STLExporter.cjs +105 -86
- package/exporters/STLExporter.cjs.map +1 -1
- package/exporters/STLExporter.d.ts +21 -14
- package/exporters/STLExporter.js +105 -86
- package/exporters/STLExporter.js.map +1 -1
- package/lines/LineMaterial.cjs +27 -17
- package/lines/LineMaterial.cjs.map +1 -1
- package/lines/LineMaterial.js +27 -17
- package/lines/LineMaterial.js.map +1 -1
- package/package.json +1 -1
@@ -1,50 +1,60 @@
|
|
1
1
|
"use strict";
|
2
|
+
var __defProp = Object.defineProperty;
|
3
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
4
|
+
var __publicField = (obj, key, value) => {
|
5
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
6
|
+
return value;
|
7
|
+
};
|
2
8
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
3
9
|
const THREE = require("three");
|
10
|
+
const isMesh = (object) => object.isMesh;
|
4
11
|
class STLExporter {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
);
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
constructor() {
|
13
|
+
__publicField(this, "binary", false);
|
14
|
+
__publicField(this, "output", "");
|
15
|
+
__publicField(this, "offset", 80);
|
16
|
+
// skip header
|
17
|
+
__publicField(this, "objects", []);
|
18
|
+
__publicField(this, "triangles", 0);
|
19
|
+
__publicField(this, "vA", new THREE.Vector3());
|
20
|
+
__publicField(this, "vB", new THREE.Vector3());
|
21
|
+
__publicField(this, "vC", new THREE.Vector3());
|
22
|
+
__publicField(this, "cb", new THREE.Vector3());
|
23
|
+
__publicField(this, "ab", new THREE.Vector3());
|
24
|
+
__publicField(this, "normal", new THREE.Vector3());
|
25
|
+
}
|
26
|
+
parse(scene, options) {
|
27
|
+
this.binary = (options == null ? void 0 : options.binary) !== void 0 ? options == null ? void 0 : options.binary : false;
|
28
|
+
scene.traverse((object) => {
|
29
|
+
if (isMesh(object)) {
|
17
30
|
const geometry = object.geometry;
|
31
|
+
if (!geometry.isBufferGeometry) {
|
32
|
+
throw new Error("THREE.STLExporter: Geometry is not of type THREE.BufferGeometry.");
|
33
|
+
}
|
18
34
|
const index = geometry.index;
|
19
|
-
const positionAttribute = geometry.getAttribute("position");
|
20
|
-
|
21
|
-
|
35
|
+
const positionAttribute = geometry.getAttribute("position") || null;
|
36
|
+
if (!positionAttribute)
|
37
|
+
return;
|
38
|
+
this.triangles += index !== null ? index.count / 3 : positionAttribute.count / 3;
|
39
|
+
this.objects.push({
|
22
40
|
object3d: object,
|
23
41
|
geometry
|
24
42
|
});
|
25
43
|
}
|
26
44
|
});
|
27
|
-
|
28
|
-
|
29
|
-
if (binary === true) {
|
30
|
-
const bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
|
45
|
+
if (this.binary) {
|
46
|
+
const bufferLength = this.triangles * 2 + this.triangles * 3 * 4 * 4 + 80 + 4;
|
31
47
|
const arrayBuffer = new ArrayBuffer(bufferLength);
|
32
|
-
output = new DataView(arrayBuffer);
|
33
|
-
output.setUint32(offset, triangles, true);
|
34
|
-
offset += 4;
|
48
|
+
this.output = new DataView(arrayBuffer);
|
49
|
+
this.output.setUint32(this.offset, this.triangles, true);
|
50
|
+
this.offset += 4;
|
35
51
|
} else {
|
36
|
-
output = "";
|
37
|
-
output += "solid exported\n";
|
52
|
+
this.output = "";
|
53
|
+
this.output += "solid exported\n";
|
38
54
|
}
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
const cb = new THREE.Vector3();
|
43
|
-
const ab = new THREE.Vector3();
|
44
|
-
const normal = new THREE.Vector3();
|
45
|
-
for (let i = 0, il = objects.length; i < il; i++) {
|
46
|
-
const object = objects[i].object3d;
|
47
|
-
const geometry = objects[i].geometry;
|
55
|
+
for (let i = 0, il = this.objects.length; i < il; i++) {
|
56
|
+
const object = this.objects[i].object3d;
|
57
|
+
const geometry = this.objects[i].geometry;
|
48
58
|
const index = geometry.index;
|
49
59
|
const positionAttribute = geometry.getAttribute("position");
|
50
60
|
if (index !== null) {
|
@@ -52,73 +62,82 @@ class STLExporter {
|
|
52
62
|
const a = index.getX(j + 0);
|
53
63
|
const b = index.getX(j + 1);
|
54
64
|
const c = index.getX(j + 2);
|
55
|
-
writeFace(a, b, c, positionAttribute, object);
|
65
|
+
this.writeFace(a, b, c, positionAttribute, object);
|
56
66
|
}
|
57
67
|
} else {
|
58
68
|
for (let j = 0; j < positionAttribute.count; j += 3) {
|
59
69
|
const a = j + 0;
|
60
70
|
const b = j + 1;
|
61
71
|
const c = j + 2;
|
62
|
-
writeFace(a, b, c, positionAttribute, object);
|
72
|
+
this.writeFace(a, b, c, positionAttribute, object);
|
63
73
|
}
|
64
74
|
}
|
65
75
|
}
|
66
|
-
if (binary
|
67
|
-
output += "endsolid exported\n";
|
76
|
+
if (!this.binary) {
|
77
|
+
this.output += "endsolid exported\n";
|
68
78
|
}
|
69
|
-
return output;
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
vC.applyMatrix4(object.matrixWorld);
|
82
|
-
writeNormal(vA, vB, vC);
|
83
|
-
writeVertex(vA);
|
84
|
-
writeVertex(vB);
|
85
|
-
writeVertex(vC);
|
86
|
-
if (binary === true) {
|
87
|
-
output.setUint16(offset, 0, true);
|
88
|
-
offset += 2;
|
79
|
+
return this.output;
|
80
|
+
}
|
81
|
+
writeFace(a, b, c, positionAttribute, object) {
|
82
|
+
this.vA.fromBufferAttribute(positionAttribute, a);
|
83
|
+
this.vB.fromBufferAttribute(positionAttribute, b);
|
84
|
+
this.vC.fromBufferAttribute(positionAttribute, c);
|
85
|
+
if (object.isSkinnedMesh) {
|
86
|
+
const mesh = object;
|
87
|
+
if ("applyBoneTransform" in mesh) {
|
88
|
+
mesh.applyBoneTransform(a, this.vA);
|
89
|
+
mesh.applyBoneTransform(b, this.vB);
|
90
|
+
mesh.applyBoneTransform(c, this.vC);
|
89
91
|
} else {
|
90
|
-
|
91
|
-
|
92
|
+
mesh.boneTransform(a, this.vA);
|
93
|
+
mesh.boneTransform(b, this.vB);
|
94
|
+
mesh.boneTransform(c, this.vC);
|
92
95
|
}
|
93
96
|
}
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
output += " facet normal " + normal.x + " " + normal.y + " " + normal.z + "\n";
|
108
|
-
output += " outer loop\n";
|
109
|
-
}
|
97
|
+
this.vA.applyMatrix4(object.matrixWorld);
|
98
|
+
this.vB.applyMatrix4(object.matrixWorld);
|
99
|
+
this.vC.applyMatrix4(object.matrixWorld);
|
100
|
+
this.writeNormal(this.vA, this.vB, this.vC);
|
101
|
+
this.writeVertex(this.vA);
|
102
|
+
this.writeVertex(this.vB);
|
103
|
+
this.writeVertex(this.vC);
|
104
|
+
if (this.binary && this.output instanceof DataView) {
|
105
|
+
this.output.setUint16(this.offset, 0, true);
|
106
|
+
this.offset += 2;
|
107
|
+
} else {
|
108
|
+
this.output += " endloop\n";
|
109
|
+
this.output += " endfacet\n";
|
110
110
|
}
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
111
|
+
}
|
112
|
+
writeNormal(vA, vB, vC) {
|
113
|
+
this.cb.subVectors(vC, vB);
|
114
|
+
this.ab.subVectors(vA, vB);
|
115
|
+
this.cb.cross(this.ab).normalize();
|
116
|
+
this.normal.copy(this.cb).normalize();
|
117
|
+
if (this.binary && this.output instanceof DataView) {
|
118
|
+
this.output.setFloat32(this.offset, this.normal.x, true);
|
119
|
+
this.offset += 4;
|
120
|
+
this.output.setFloat32(this.offset, this.normal.y, true);
|
121
|
+
this.offset += 4;
|
122
|
+
this.output.setFloat32(this.offset, this.normal.z, true);
|
123
|
+
this.offset += 4;
|
124
|
+
} else {
|
125
|
+
this.output += ` facet normal ${this.normal.x} ${this.normal.y} ${this.normal.z}
|
126
|
+
`;
|
127
|
+
this.output += " outer loop\n";
|
128
|
+
}
|
129
|
+
}
|
130
|
+
writeVertex(vertex) {
|
131
|
+
if (this.binary && this.output instanceof DataView) {
|
132
|
+
this.output.setFloat32(this.offset, vertex.x, true);
|
133
|
+
this.offset += 4;
|
134
|
+
this.output.setFloat32(this.offset, vertex.y, true);
|
135
|
+
this.offset += 4;
|
136
|
+
this.output.setFloat32(this.offset, vertex.z, true);
|
137
|
+
this.offset += 4;
|
138
|
+
} else {
|
139
|
+
this.output += ` vertex ${vertex.x} ${vertex.y} ${vertex.z}
|
140
|
+
`;
|
122
141
|
}
|
123
142
|
}
|
124
143
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"STLExporter.cjs","sources":["../../src/exporters/STLExporter.
|
1
|
+
{"version":3,"file":"STLExporter.cjs","sources":["../../src/exporters/STLExporter.ts"],"sourcesContent":["import {\n BufferAttribute,\n BufferGeometry,\n InterleavedBufferAttribute,\n Mesh,\n Object3D,\n SkinnedMesh,\n Vector3,\n} from 'three'\n\nexport interface STLExporterOptionsBinary {\n binary: true\n}\n\nexport interface STLExporterOptionsString {\n binary?: false\n}\n\nexport interface STLExporterOptions {\n binary?: boolean\n}\n\nconst isMesh = (object: unknown): object is Mesh => (object as any).isMesh\n\nexport class STLExporter {\n private binary = false\n\n private output: string | DataView = ''\n private offset: number = 80 // skip header\n\n private objects: { object3d: Object3D; geometry: BufferGeometry }[] = []\n private triangles: number = 0\n\n private vA = new Vector3()\n private vB = new Vector3()\n private vC = new Vector3()\n private cb = new Vector3()\n private ab = new Vector3()\n private normal = new Vector3()\n\n parse(scene: Object3D, options: STLExporterOptionsBinary): DataView\n parse(scene: Object3D, options?: STLExporterOptionsString): string\n parse(scene: Object3D, options?: STLExporterOptions): string | DataView {\n this.binary = options?.binary !== undefined ? options?.binary : false\n\n scene.traverse((object: Object3D) => {\n if (isMesh(object)) {\n const geometry = object.geometry\n\n if (!geometry.isBufferGeometry) {\n throw new Error('THREE.STLExporter: Geometry is not of type THREE.BufferGeometry.')\n }\n\n const index = geometry.index\n const positionAttribute = geometry.getAttribute('position') || null\n if (!positionAttribute) return\n\n this.triangles += index !== null ? index.count / 3 : positionAttribute.count / 3\n\n this.objects.push({\n object3d: object,\n geometry: geometry,\n })\n }\n })\n\n if (this.binary) {\n const bufferLength = this.triangles * 2 + this.triangles * 3 * 4 * 4 + 80 + 4\n const arrayBuffer = new ArrayBuffer(bufferLength)\n this.output = new DataView(arrayBuffer)\n this.output.setUint32(this.offset, this.triangles, true)\n this.offset += 4\n } else {\n this.output = ''\n this.output += 'solid exported\\n'\n }\n\n for (let i = 0, il = this.objects.length; i < il; i++) {\n const object = this.objects[i].object3d\n const geometry = this.objects[i].geometry\n\n const index = geometry.index\n const positionAttribute = geometry.getAttribute('position')\n\n if (index !== null) {\n // indexed geometry\n for (let j = 0; j < index.count; j += 3) {\n const a = index.getX(j + 0)\n const b = index.getX(j + 1)\n const c = index.getX(j + 2)\n\n this.writeFace(a, b, c, positionAttribute, object as SkinnedMesh)\n }\n } else {\n // non-indexed geometry\n for (let j = 0; j < positionAttribute.count; j += 3) {\n const a = j + 0\n const b = j + 1\n const c = j + 2\n\n this.writeFace(a, b, c, positionAttribute, object as SkinnedMesh)\n }\n }\n }\n\n if (!this.binary) {\n this.output += 'endsolid exported\\n'\n }\n\n return this.output\n }\n\n private writeFace(\n a: number,\n b: number,\n c: number,\n positionAttribute: BufferAttribute | InterleavedBufferAttribute,\n object: SkinnedMesh,\n ): void {\n this.vA.fromBufferAttribute(positionAttribute, a)\n this.vB.fromBufferAttribute(positionAttribute, b)\n this.vC.fromBufferAttribute(positionAttribute, c)\n\n if (object.isSkinnedMesh) {\n const mesh = object as Omit<SkinnedMesh, 'boneTransform' | 'applyBoneTransform'> &\n (\n | {\n boneTransform(index: number, vector: Vector3): Vector3\n }\n | {\n applyBoneTransform(index: number, vector: Vector3): Vector3\n }\n )\n\n // r151 https://github.com/mrdoob/three.js/pull/25586\n if ('applyBoneTransform' in mesh) {\n mesh.applyBoneTransform(a, this.vA)\n mesh.applyBoneTransform(b, this.vB)\n mesh.applyBoneTransform(c, this.vC)\n } else {\n mesh.boneTransform(a, this.vA)\n mesh.boneTransform(b, this.vB)\n mesh.boneTransform(c, this.vC)\n }\n }\n\n this.vA.applyMatrix4(object.matrixWorld)\n this.vB.applyMatrix4(object.matrixWorld)\n this.vC.applyMatrix4(object.matrixWorld)\n\n this.writeNormal(this.vA, this.vB, this.vC)\n\n this.writeVertex(this.vA)\n this.writeVertex(this.vB)\n this.writeVertex(this.vC)\n\n if (this.binary && this.output instanceof DataView) {\n this.output.setUint16(this.offset, 0, true)\n this.offset += 2\n } else {\n this.output += '\\t\\tendloop\\n'\n this.output += '\\tendfacet\\n'\n }\n }\n\n private writeNormal(vA: Vector3, vB: Vector3, vC: Vector3): void {\n this.cb.subVectors(vC, vB)\n this.ab.subVectors(vA, vB)\n this.cb.cross(this.ab).normalize()\n\n this.normal.copy(this.cb).normalize()\n\n if (this.binary && this.output instanceof DataView) {\n this.output.setFloat32(this.offset, this.normal.x, true)\n this.offset += 4\n this.output.setFloat32(this.offset, this.normal.y, true)\n this.offset += 4\n this.output.setFloat32(this.offset, this.normal.z, true)\n this.offset += 4\n } else {\n this.output += `\\tfacet normal ${this.normal.x} ${this.normal.y} ${this.normal.z}\\n`\n this.output += '\\t\\touter loop\\n'\n }\n }\n\n private writeVertex(vertex: Vector3): void {\n if (this.binary && this.output instanceof DataView) {\n this.output.setFloat32(this.offset, vertex.x, true)\n this.offset += 4\n this.output.setFloat32(this.offset, vertex.y, true)\n this.offset += 4\n this.output.setFloat32(this.offset, vertex.z, true)\n this.offset += 4\n } else {\n this.output += `\\t\\t\\tvertex ${vertex.x} ${vertex.y} ${vertex.z}\\n`\n }\n }\n}\n"],"names":["Vector3"],"mappings":"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"}
|
@@ -1,21 +1,28 @@
|
|
1
|
-
import { Object3D } from 'three'
|
2
|
-
|
1
|
+
import { Object3D } from 'three';
|
3
2
|
export interface STLExporterOptionsBinary {
|
4
|
-
|
3
|
+
binary: true;
|
5
4
|
}
|
6
|
-
|
7
5
|
export interface STLExporterOptionsString {
|
8
|
-
|
6
|
+
binary?: false;
|
9
7
|
}
|
10
|
-
|
11
8
|
export interface STLExporterOptions {
|
12
|
-
|
9
|
+
binary?: boolean;
|
13
10
|
}
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
11
|
+
export declare class STLExporter {
|
12
|
+
private binary;
|
13
|
+
private output;
|
14
|
+
private offset;
|
15
|
+
private objects;
|
16
|
+
private triangles;
|
17
|
+
private vA;
|
18
|
+
private vB;
|
19
|
+
private vC;
|
20
|
+
private cb;
|
21
|
+
private ab;
|
22
|
+
private normal;
|
23
|
+
parse(scene: Object3D, options: STLExporterOptionsBinary): DataView;
|
24
|
+
parse(scene: Object3D, options?: STLExporterOptionsString): string;
|
25
|
+
private writeFace;
|
26
|
+
private writeNormal;
|
27
|
+
private writeVertex;
|
21
28
|
}
|
package/exporters/STLExporter.js
CHANGED
@@ -1,48 +1,58 @@
|
|
1
|
+
var __defProp = Object.defineProperty;
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
3
|
+
var __publicField = (obj, key, value) => {
|
4
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
5
|
+
return value;
|
6
|
+
};
|
1
7
|
import { Vector3 } from "three";
|
8
|
+
const isMesh = (object) => object.isMesh;
|
2
9
|
class STLExporter {
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
);
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
constructor() {
|
11
|
+
__publicField(this, "binary", false);
|
12
|
+
__publicField(this, "output", "");
|
13
|
+
__publicField(this, "offset", 80);
|
14
|
+
// skip header
|
15
|
+
__publicField(this, "objects", []);
|
16
|
+
__publicField(this, "triangles", 0);
|
17
|
+
__publicField(this, "vA", new Vector3());
|
18
|
+
__publicField(this, "vB", new Vector3());
|
19
|
+
__publicField(this, "vC", new Vector3());
|
20
|
+
__publicField(this, "cb", new Vector3());
|
21
|
+
__publicField(this, "ab", new Vector3());
|
22
|
+
__publicField(this, "normal", new Vector3());
|
23
|
+
}
|
24
|
+
parse(scene, options) {
|
25
|
+
this.binary = (options == null ? void 0 : options.binary) !== void 0 ? options == null ? void 0 : options.binary : false;
|
26
|
+
scene.traverse((object) => {
|
27
|
+
if (isMesh(object)) {
|
15
28
|
const geometry = object.geometry;
|
29
|
+
if (!geometry.isBufferGeometry) {
|
30
|
+
throw new Error("THREE.STLExporter: Geometry is not of type THREE.BufferGeometry.");
|
31
|
+
}
|
16
32
|
const index = geometry.index;
|
17
|
-
const positionAttribute = geometry.getAttribute("position");
|
18
|
-
|
19
|
-
|
33
|
+
const positionAttribute = geometry.getAttribute("position") || null;
|
34
|
+
if (!positionAttribute)
|
35
|
+
return;
|
36
|
+
this.triangles += index !== null ? index.count / 3 : positionAttribute.count / 3;
|
37
|
+
this.objects.push({
|
20
38
|
object3d: object,
|
21
39
|
geometry
|
22
40
|
});
|
23
41
|
}
|
24
42
|
});
|
25
|
-
|
26
|
-
|
27
|
-
if (binary === true) {
|
28
|
-
const bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
|
43
|
+
if (this.binary) {
|
44
|
+
const bufferLength = this.triangles * 2 + this.triangles * 3 * 4 * 4 + 80 + 4;
|
29
45
|
const arrayBuffer = new ArrayBuffer(bufferLength);
|
30
|
-
output = new DataView(arrayBuffer);
|
31
|
-
output.setUint32(offset, triangles, true);
|
32
|
-
offset += 4;
|
46
|
+
this.output = new DataView(arrayBuffer);
|
47
|
+
this.output.setUint32(this.offset, this.triangles, true);
|
48
|
+
this.offset += 4;
|
33
49
|
} else {
|
34
|
-
output = "";
|
35
|
-
output += "solid exported\n";
|
50
|
+
this.output = "";
|
51
|
+
this.output += "solid exported\n";
|
36
52
|
}
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
const cb = new Vector3();
|
41
|
-
const ab = new Vector3();
|
42
|
-
const normal = new Vector3();
|
43
|
-
for (let i = 0, il = objects.length; i < il; i++) {
|
44
|
-
const object = objects[i].object3d;
|
45
|
-
const geometry = objects[i].geometry;
|
53
|
+
for (let i = 0, il = this.objects.length; i < il; i++) {
|
54
|
+
const object = this.objects[i].object3d;
|
55
|
+
const geometry = this.objects[i].geometry;
|
46
56
|
const index = geometry.index;
|
47
57
|
const positionAttribute = geometry.getAttribute("position");
|
48
58
|
if (index !== null) {
|
@@ -50,73 +60,82 @@ class STLExporter {
|
|
50
60
|
const a = index.getX(j + 0);
|
51
61
|
const b = index.getX(j + 1);
|
52
62
|
const c = index.getX(j + 2);
|
53
|
-
writeFace(a, b, c, positionAttribute, object);
|
63
|
+
this.writeFace(a, b, c, positionAttribute, object);
|
54
64
|
}
|
55
65
|
} else {
|
56
66
|
for (let j = 0; j < positionAttribute.count; j += 3) {
|
57
67
|
const a = j + 0;
|
58
68
|
const b = j + 1;
|
59
69
|
const c = j + 2;
|
60
|
-
writeFace(a, b, c, positionAttribute, object);
|
70
|
+
this.writeFace(a, b, c, positionAttribute, object);
|
61
71
|
}
|
62
72
|
}
|
63
73
|
}
|
64
|
-
if (binary
|
65
|
-
output += "endsolid exported\n";
|
74
|
+
if (!this.binary) {
|
75
|
+
this.output += "endsolid exported\n";
|
66
76
|
}
|
67
|
-
return output;
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
vC.applyMatrix4(object.matrixWorld);
|
80
|
-
writeNormal(vA, vB, vC);
|
81
|
-
writeVertex(vA);
|
82
|
-
writeVertex(vB);
|
83
|
-
writeVertex(vC);
|
84
|
-
if (binary === true) {
|
85
|
-
output.setUint16(offset, 0, true);
|
86
|
-
offset += 2;
|
77
|
+
return this.output;
|
78
|
+
}
|
79
|
+
writeFace(a, b, c, positionAttribute, object) {
|
80
|
+
this.vA.fromBufferAttribute(positionAttribute, a);
|
81
|
+
this.vB.fromBufferAttribute(positionAttribute, b);
|
82
|
+
this.vC.fromBufferAttribute(positionAttribute, c);
|
83
|
+
if (object.isSkinnedMesh) {
|
84
|
+
const mesh = object;
|
85
|
+
if ("applyBoneTransform" in mesh) {
|
86
|
+
mesh.applyBoneTransform(a, this.vA);
|
87
|
+
mesh.applyBoneTransform(b, this.vB);
|
88
|
+
mesh.applyBoneTransform(c, this.vC);
|
87
89
|
} else {
|
88
|
-
|
89
|
-
|
90
|
+
mesh.boneTransform(a, this.vA);
|
91
|
+
mesh.boneTransform(b, this.vB);
|
92
|
+
mesh.boneTransform(c, this.vC);
|
90
93
|
}
|
91
94
|
}
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
output += " facet normal " + normal.x + " " + normal.y + " " + normal.z + "\n";
|
106
|
-
output += " outer loop\n";
|
107
|
-
}
|
95
|
+
this.vA.applyMatrix4(object.matrixWorld);
|
96
|
+
this.vB.applyMatrix4(object.matrixWorld);
|
97
|
+
this.vC.applyMatrix4(object.matrixWorld);
|
98
|
+
this.writeNormal(this.vA, this.vB, this.vC);
|
99
|
+
this.writeVertex(this.vA);
|
100
|
+
this.writeVertex(this.vB);
|
101
|
+
this.writeVertex(this.vC);
|
102
|
+
if (this.binary && this.output instanceof DataView) {
|
103
|
+
this.output.setUint16(this.offset, 0, true);
|
104
|
+
this.offset += 2;
|
105
|
+
} else {
|
106
|
+
this.output += " endloop\n";
|
107
|
+
this.output += " endfacet\n";
|
108
108
|
}
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
109
|
+
}
|
110
|
+
writeNormal(vA, vB, vC) {
|
111
|
+
this.cb.subVectors(vC, vB);
|
112
|
+
this.ab.subVectors(vA, vB);
|
113
|
+
this.cb.cross(this.ab).normalize();
|
114
|
+
this.normal.copy(this.cb).normalize();
|
115
|
+
if (this.binary && this.output instanceof DataView) {
|
116
|
+
this.output.setFloat32(this.offset, this.normal.x, true);
|
117
|
+
this.offset += 4;
|
118
|
+
this.output.setFloat32(this.offset, this.normal.y, true);
|
119
|
+
this.offset += 4;
|
120
|
+
this.output.setFloat32(this.offset, this.normal.z, true);
|
121
|
+
this.offset += 4;
|
122
|
+
} else {
|
123
|
+
this.output += ` facet normal ${this.normal.x} ${this.normal.y} ${this.normal.z}
|
124
|
+
`;
|
125
|
+
this.output += " outer loop\n";
|
126
|
+
}
|
127
|
+
}
|
128
|
+
writeVertex(vertex) {
|
129
|
+
if (this.binary && this.output instanceof DataView) {
|
130
|
+
this.output.setFloat32(this.offset, vertex.x, true);
|
131
|
+
this.offset += 4;
|
132
|
+
this.output.setFloat32(this.offset, vertex.y, true);
|
133
|
+
this.offset += 4;
|
134
|
+
this.output.setFloat32(this.offset, vertex.z, true);
|
135
|
+
this.offset += 4;
|
136
|
+
} else {
|
137
|
+
this.output += ` vertex ${vertex.x} ${vertex.y} ${vertex.z}
|
138
|
+
`;
|
120
139
|
}
|
121
140
|
}
|
122
141
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"STLExporter.js","sources":["../../src/exporters/STLExporter.
|
1
|
+
{"version":3,"file":"STLExporter.js","sources":["../../src/exporters/STLExporter.ts"],"sourcesContent":["import {\n BufferAttribute,\n BufferGeometry,\n InterleavedBufferAttribute,\n Mesh,\n Object3D,\n SkinnedMesh,\n Vector3,\n} from 'three'\n\nexport interface STLExporterOptionsBinary {\n binary: true\n}\n\nexport interface STLExporterOptionsString {\n binary?: false\n}\n\nexport interface STLExporterOptions {\n binary?: boolean\n}\n\nconst isMesh = (object: unknown): object is Mesh => (object as any).isMesh\n\nexport class STLExporter {\n private binary = false\n\n private output: string | DataView = ''\n private offset: number = 80 // skip header\n\n private objects: { object3d: Object3D; geometry: BufferGeometry }[] = []\n private triangles: number = 0\n\n private vA = new Vector3()\n private vB = new Vector3()\n private vC = new Vector3()\n private cb = new Vector3()\n private ab = new Vector3()\n private normal = new Vector3()\n\n parse(scene: Object3D, options: STLExporterOptionsBinary): DataView\n parse(scene: Object3D, options?: STLExporterOptionsString): string\n parse(scene: Object3D, options?: STLExporterOptions): string | DataView {\n this.binary = options?.binary !== undefined ? options?.binary : false\n\n scene.traverse((object: Object3D) => {\n if (isMesh(object)) {\n const geometry = object.geometry\n\n if (!geometry.isBufferGeometry) {\n throw new Error('THREE.STLExporter: Geometry is not of type THREE.BufferGeometry.')\n }\n\n const index = geometry.index\n const positionAttribute = geometry.getAttribute('position') || null\n if (!positionAttribute) return\n\n this.triangles += index !== null ? index.count / 3 : positionAttribute.count / 3\n\n this.objects.push({\n object3d: object,\n geometry: geometry,\n })\n }\n })\n\n if (this.binary) {\n const bufferLength = this.triangles * 2 + this.triangles * 3 * 4 * 4 + 80 + 4\n const arrayBuffer = new ArrayBuffer(bufferLength)\n this.output = new DataView(arrayBuffer)\n this.output.setUint32(this.offset, this.triangles, true)\n this.offset += 4\n } else {\n this.output = ''\n this.output += 'solid exported\\n'\n }\n\n for (let i = 0, il = this.objects.length; i < il; i++) {\n const object = this.objects[i].object3d\n const geometry = this.objects[i].geometry\n\n const index = geometry.index\n const positionAttribute = geometry.getAttribute('position')\n\n if (index !== null) {\n // indexed geometry\n for (let j = 0; j < index.count; j += 3) {\n const a = index.getX(j + 0)\n const b = index.getX(j + 1)\n const c = index.getX(j + 2)\n\n this.writeFace(a, b, c, positionAttribute, object as SkinnedMesh)\n }\n } else {\n // non-indexed geometry\n for (let j = 0; j < positionAttribute.count; j += 3) {\n const a = j + 0\n const b = j + 1\n const c = j + 2\n\n this.writeFace(a, b, c, positionAttribute, object as SkinnedMesh)\n }\n }\n }\n\n if (!this.binary) {\n this.output += 'endsolid exported\\n'\n }\n\n return this.output\n }\n\n private writeFace(\n a: number,\n b: number,\n c: number,\n positionAttribute: BufferAttribute | InterleavedBufferAttribute,\n object: SkinnedMesh,\n ): void {\n this.vA.fromBufferAttribute(positionAttribute, a)\n this.vB.fromBufferAttribute(positionAttribute, b)\n this.vC.fromBufferAttribute(positionAttribute, c)\n\n if (object.isSkinnedMesh) {\n const mesh = object as Omit<SkinnedMesh, 'boneTransform' | 'applyBoneTransform'> &\n (\n | {\n boneTransform(index: number, vector: Vector3): Vector3\n }\n | {\n applyBoneTransform(index: number, vector: Vector3): Vector3\n }\n )\n\n // r151 https://github.com/mrdoob/three.js/pull/25586\n if ('applyBoneTransform' in mesh) {\n mesh.applyBoneTransform(a, this.vA)\n mesh.applyBoneTransform(b, this.vB)\n mesh.applyBoneTransform(c, this.vC)\n } else {\n mesh.boneTransform(a, this.vA)\n mesh.boneTransform(b, this.vB)\n mesh.boneTransform(c, this.vC)\n }\n }\n\n this.vA.applyMatrix4(object.matrixWorld)\n this.vB.applyMatrix4(object.matrixWorld)\n this.vC.applyMatrix4(object.matrixWorld)\n\n this.writeNormal(this.vA, this.vB, this.vC)\n\n this.writeVertex(this.vA)\n this.writeVertex(this.vB)\n this.writeVertex(this.vC)\n\n if (this.binary && this.output instanceof DataView) {\n this.output.setUint16(this.offset, 0, true)\n this.offset += 2\n } else {\n this.output += '\\t\\tendloop\\n'\n this.output += '\\tendfacet\\n'\n }\n }\n\n private writeNormal(vA: Vector3, vB: Vector3, vC: Vector3): void {\n this.cb.subVectors(vC, vB)\n this.ab.subVectors(vA, vB)\n this.cb.cross(this.ab).normalize()\n\n this.normal.copy(this.cb).normalize()\n\n if (this.binary && this.output instanceof DataView) {\n this.output.setFloat32(this.offset, this.normal.x, true)\n this.offset += 4\n this.output.setFloat32(this.offset, this.normal.y, true)\n this.offset += 4\n this.output.setFloat32(this.offset, this.normal.z, true)\n this.offset += 4\n } else {\n this.output += `\\tfacet normal ${this.normal.x} ${this.normal.y} ${this.normal.z}\\n`\n this.output += '\\t\\touter loop\\n'\n }\n }\n\n private writeVertex(vertex: Vector3): void {\n if (this.binary && this.output instanceof DataView) {\n this.output.setFloat32(this.offset, vertex.x, true)\n this.offset += 4\n this.output.setFloat32(this.offset, vertex.y, true)\n this.offset += 4\n this.output.setFloat32(this.offset, vertex.z, true)\n this.offset += 4\n } else {\n this.output += `\\t\\t\\tvertex ${vertex.x} ${vertex.y} ${vertex.z}\\n`\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
package/lines/LineMaterial.cjs
CHANGED
@@ -35,14 +35,16 @@ class LineMaterial extends THREE.ShaderMaterial {
|
|
35
35
|
attribute vec3 instanceStart;
|
36
36
|
attribute vec3 instanceEnd;
|
37
37
|
|
38
|
-
#ifdef
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
38
|
+
#ifdef USE_COLOR
|
39
|
+
#ifdef USE_LINE_COLOR_ALPHA
|
40
|
+
varying vec4 vLineColor;
|
41
|
+
attribute vec4 instanceColorStart;
|
42
|
+
attribute vec4 instanceColorEnd;
|
43
|
+
#else
|
44
|
+
varying vec3 vLineColor;
|
45
|
+
attribute vec3 instanceColorStart;
|
46
|
+
attribute vec3 instanceColorEnd;
|
47
|
+
#endif
|
46
48
|
#endif
|
47
49
|
|
48
50
|
#ifdef WORLD_UNITS
|
@@ -89,7 +91,11 @@ class LineMaterial extends THREE.ShaderMaterial {
|
|
89
91
|
|
90
92
|
void main() {
|
91
93
|
|
92
|
-
|
94
|
+
#ifdef USE_COLOR
|
95
|
+
|
96
|
+
vLineColor = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;
|
97
|
+
|
98
|
+
#endif
|
93
99
|
|
94
100
|
#ifdef USE_DASH
|
95
101
|
|
@@ -295,10 +301,12 @@ class LineMaterial extends THREE.ShaderMaterial {
|
|
295
301
|
#include <logdepthbuf_pars_fragment>
|
296
302
|
#include <clipping_planes_pars_fragment>
|
297
303
|
|
298
|
-
#ifdef
|
299
|
-
|
300
|
-
|
301
|
-
|
304
|
+
#ifdef USE_COLOR
|
305
|
+
#ifdef USE_LINE_COLOR_ALPHA
|
306
|
+
varying vec4 vLineColor;
|
307
|
+
#else
|
308
|
+
varying vec3 vLineColor;
|
309
|
+
#endif
|
302
310
|
#endif
|
303
311
|
|
304
312
|
vec2 closestLineToLine(vec3 p1, vec3 p2, vec3 p3, vec3 p4) {
|
@@ -409,10 +417,12 @@ class LineMaterial extends THREE.ShaderMaterial {
|
|
409
417
|
#endif
|
410
418
|
|
411
419
|
vec4 diffuseColor = vec4( diffuse, alpha );
|
412
|
-
#ifdef
|
413
|
-
|
414
|
-
|
415
|
-
|
420
|
+
#ifdef USE_COLOR
|
421
|
+
#ifdef USE_LINE_COLOR_ALPHA
|
422
|
+
diffuseColor *= vLineColor;
|
423
|
+
#else
|
424
|
+
diffuseColor.rgb *= vLineColor;
|
425
|
+
#endif
|
416
426
|
#endif
|
417
427
|
|
418
428
|
#include <logdepthbuf_fragment>
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"LineMaterial.cjs","sources":["../../src/lines/LineMaterial.js"],"sourcesContent":["/**\n * parameters = {\n * color: <hex>,\n * linewidth: <float>,\n * dashed: <boolean>,\n * dashScale: <float>,\n * dashSize: <float>,\n * dashOffset: <float>,\n * gapSize: <float>,\n * resolution: <Vector2>, // to be set by renderer\n * }\n */\n\nimport { ShaderMaterial, UniformsLib, UniformsUtils, Vector2, REVISION } from 'three'\n\nclass LineMaterial extends ShaderMaterial {\n constructor(parameters) {\n super({\n type: 'LineMaterial',\n\n uniforms: UniformsUtils.clone(\n UniformsUtils.merge([\n UniformsLib.common,\n UniformsLib.fog,\n {\n worldUnits: { value: 1 },\n linewidth: { value: 1 },\n resolution: { value: new Vector2(1, 1) },\n dashOffset: { value: 0 },\n dashScale: { value: 1 },\n dashSize: { value: 1 },\n gapSize: { value: 1 }, // todo FIX - maybe change to totalSize\n },\n ]),\n ),\n\n vertexShader: /* glsl */ `\n\t\t\t\t#include <common>\n\t\t\t\t#include <fog_pars_vertex>\n\t\t\t\t#include <logdepthbuf_pars_vertex>\n\t\t\t\t#include <clipping_planes_pars_vertex>\n\n\t\t\t\tuniform float linewidth;\n\t\t\t\tuniform vec2 resolution;\n\n\t\t\t\tattribute vec3 instanceStart;\n\t\t\t\tattribute vec3 instanceEnd;\n\n\t\t\t\t#ifdef USE_LINE_COLOR_ALPHA\n\t\t\t\t\tvarying vec4 vLineColor;\n\t\t\t\t\tattribute vec4 instanceColorStart;\n\t\t\t\t\tattribute vec4 instanceColorEnd;\n\t\t\t\t#else\n\t\t\t\t\tvarying vec3 vLineColor;\n\t\t\t\t\tattribute vec3 instanceColorStart;\n\t\t\t\t\tattribute vec3 instanceColorEnd;\n\t\t\t\t#endif\n\n\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\tvarying vec4 worldPos;\n\t\t\t\t\tvarying vec3 worldStart;\n\t\t\t\t\tvarying vec3 worldEnd;\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t#else\n\n\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t#endif\n\n\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\tuniform float dashScale;\n\t\t\t\t\tattribute float instanceDistanceStart;\n\t\t\t\t\tattribute float instanceDistanceEnd;\n\t\t\t\t\tvarying float vLineDistance;\n\n\t\t\t\t#endif\n\n\t\t\t\tvoid trimSegment( const in vec4 start, inout vec4 end ) {\n\n\t\t\t\t\t// trim end segment so it terminates between the camera plane and the near plane\n\n\t\t\t\t\t// conservative estimate of the near plane\n\t\t\t\t\tfloat a = projectionMatrix[ 2 ][ 2 ]; // 3nd entry in 3th column\n\t\t\t\t\tfloat b = projectionMatrix[ 3 ][ 2 ]; // 3nd entry in 4th column\n\t\t\t\t\tfloat nearEstimate = - 0.5 * b / a;\n\n\t\t\t\t\tfloat alpha = ( nearEstimate - start.z ) / ( end.z - start.z );\n\n\t\t\t\t\tend.xyz = mix( start.xyz, end.xyz, alpha );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvLineColor = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tvLineDistance = ( position.y < 0.5 ) ? dashScale * instanceDistanceStart : dashScale * instanceDistanceEnd;\n\t\t\t\t\t\tvUv = uv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tfloat aspect = resolution.x / resolution.y;\n\n\t\t\t\t\t// camera space\n\t\t\t\t\tvec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );\n\t\t\t\t\tvec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );\n\n\t\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\t\tworldStart = start.xyz;\n\t\t\t\t\t\tworldEnd = end.xyz;\n\n\t\t\t\t\t#else\n\n\t\t\t\t\t\tvUv = uv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\t// special case for perspective projection, and segments that terminate either in, or behind, the camera plane\n\t\t\t\t\t// clearly the gpu firmware has a way of addressing this issue when projecting into ndc space\n\t\t\t\t\t// but we need to perform ndc-space calculations in the shader, so we must address this issue directly\n\t\t\t\t\t// perhaps there is a more elegant solution -- WestLangley\n\n\t\t\t\t\tbool perspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 ); // 4th entry in the 3rd column\n\n\t\t\t\t\tif ( perspective ) {\n\n\t\t\t\t\t\tif ( start.z < 0.0 && end.z >= 0.0 ) {\n\n\t\t\t\t\t\t\ttrimSegment( start, end );\n\n\t\t\t\t\t\t} else if ( end.z < 0.0 && start.z >= 0.0 ) {\n\n\t\t\t\t\t\t\ttrimSegment( end, start );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// clip space\n\t\t\t\t\tvec4 clipStart = projectionMatrix * start;\n\t\t\t\t\tvec4 clipEnd = projectionMatrix * end;\n\n\t\t\t\t\t// ndc space\n\t\t\t\t\tvec3 ndcStart = clipStart.xyz / clipStart.w;\n\t\t\t\t\tvec3 ndcEnd = clipEnd.xyz / clipEnd.w;\n\n\t\t\t\t\t// direction\n\t\t\t\t\tvec2 dir = ndcEnd.xy - ndcStart.xy;\n\n\t\t\t\t\t// account for clip-space aspect ratio\n\t\t\t\t\tdir.x *= aspect;\n\t\t\t\t\tdir = normalize( dir );\n\n\t\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\t\t// get the offset direction as perpendicular to the view vector\n\t\t\t\t\t\tvec3 worldDir = normalize( end.xyz - start.xyz );\n\t\t\t\t\t\tvec3 offset;\n\t\t\t\t\t\tif ( position.y < 0.5 ) {\n\n\t\t\t\t\t\t\toffset = normalize( cross( start.xyz, worldDir ) );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\toffset = normalize( cross( end.xyz, worldDir ) );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// sign flip\n\t\t\t\t\t\tif ( position.x < 0.0 ) offset *= - 1.0;\n\n\t\t\t\t\t\tfloat forwardOffset = dot( worldDir, vec3( 0.0, 0.0, 1.0 ) );\n\n\t\t\t\t\t\t// don't extend the line if we're rendering dashes because we\n\t\t\t\t\t\t// won't be rendering the endcaps\n\t\t\t\t\t\t#ifndef USE_DASH\n\n\t\t\t\t\t\t\t// extend the line bounds to encompass endcaps\n\t\t\t\t\t\t\tstart.xyz += - worldDir * linewidth * 0.5;\n\t\t\t\t\t\t\tend.xyz += worldDir * linewidth * 0.5;\n\n\t\t\t\t\t\t\t// shift the position of the quad so it hugs the forward edge of the line\n\t\t\t\t\t\t\toffset.xy -= dir * forwardOffset;\n\t\t\t\t\t\t\toffset.z += 0.5;\n\n\t\t\t\t\t\t#endif\n\n\t\t\t\t\t\t// endcaps\n\t\t\t\t\t\tif ( position.y > 1.0 || position.y < 0.0 ) {\n\n\t\t\t\t\t\t\toffset.xy += dir * 2.0 * forwardOffset;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// adjust for linewidth\n\t\t\t\t\t\toffset *= linewidth * 0.5;\n\n\t\t\t\t\t\t// set the world position\n\t\t\t\t\t\tworldPos = ( position.y < 0.5 ) ? start : end;\n\t\t\t\t\t\tworldPos.xyz += offset;\n\n\t\t\t\t\t\t// project the worldpos\n\t\t\t\t\t\tvec4 clip = projectionMatrix * worldPos;\n\n\t\t\t\t\t\t// shift the depth of the projected points so the line\n\t\t\t\t\t\t// segments overlap neatly\n\t\t\t\t\t\tvec3 clipPose = ( position.y < 0.5 ) ? ndcStart : ndcEnd;\n\t\t\t\t\t\tclip.z = clipPose.z * clip.w;\n\n\t\t\t\t\t#else\n\n\t\t\t\t\t\tvec2 offset = vec2( dir.y, - dir.x );\n\t\t\t\t\t\t// undo aspect ratio adjustment\n\t\t\t\t\t\tdir.x /= aspect;\n\t\t\t\t\t\toffset.x /= aspect;\n\n\t\t\t\t\t\t// sign flip\n\t\t\t\t\t\tif ( position.x < 0.0 ) offset *= - 1.0;\n\n\t\t\t\t\t\t// endcaps\n\t\t\t\t\t\tif ( position.y < 0.0 ) {\n\n\t\t\t\t\t\t\toffset += - dir;\n\n\t\t\t\t\t\t} else if ( position.y > 1.0 ) {\n\n\t\t\t\t\t\t\toffset += dir;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// adjust for linewidth\n\t\t\t\t\t\toffset *= linewidth;\n\n\t\t\t\t\t\t// adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...\n\t\t\t\t\t\toffset /= resolution.y;\n\n\t\t\t\t\t\t// select end\n\t\t\t\t\t\tvec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;\n\n\t\t\t\t\t\t// back to clip space\n\t\t\t\t\t\toffset *= clip.w;\n\n\t\t\t\t\t\tclip.xy += offset;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tgl_Position = clip;\n\n\t\t\t\t\tvec4 mvPosition = ( position.y < 0.5 ) ? start : end; // this is an approximation\n\n\t\t\t\t\t#include <logdepthbuf_vertex>\n\t\t\t\t\t#include <clipping_planes_vertex>\n\t\t\t\t\t#include <fog_vertex>\n\n\t\t\t\t}\n\t\t\t`,\n fragmentShader: /* glsl */ `\n\t\t\t\tuniform vec3 diffuse;\n\t\t\t\tuniform float opacity;\n\t\t\t\tuniform float linewidth;\n\n\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\tuniform float dashOffset;\n\t\t\t\t\tuniform float dashSize;\n\t\t\t\t\tuniform float gapSize;\n\n\t\t\t\t#endif\n\n\t\t\t\tvarying float vLineDistance;\n\n\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\tvarying vec4 worldPos;\n\t\t\t\t\tvarying vec3 worldStart;\n\t\t\t\t\tvarying vec3 worldEnd;\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t#else\n\n\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t#endif\n\n\t\t\t\t#include <common>\n\t\t\t\t#include <fog_pars_fragment>\n\t\t\t\t#include <logdepthbuf_pars_fragment>\n\t\t\t\t#include <clipping_planes_pars_fragment>\n\n\t\t\t\t#ifdef USE_LINE_COLOR_ALPHA\n\t\t\t\t\tvarying vec4 vLineColor;\n\t\t\t\t#else\n\t\t\t\t\tvarying vec3 vLineColor;\n\t\t\t\t#endif\n\n\t\t\t\tvec2 closestLineToLine(vec3 p1, vec3 p2, vec3 p3, vec3 p4) {\n\n\t\t\t\t\tfloat mua;\n\t\t\t\t\tfloat mub;\n\n\t\t\t\t\tvec3 p13 = p1 - p3;\n\t\t\t\t\tvec3 p43 = p4 - p3;\n\n\t\t\t\t\tvec3 p21 = p2 - p1;\n\n\t\t\t\t\tfloat d1343 = dot( p13, p43 );\n\t\t\t\t\tfloat d4321 = dot( p43, p21 );\n\t\t\t\t\tfloat d1321 = dot( p13, p21 );\n\t\t\t\t\tfloat d4343 = dot( p43, p43 );\n\t\t\t\t\tfloat d2121 = dot( p21, p21 );\n\n\t\t\t\t\tfloat denom = d2121 * d4343 - d4321 * d4321;\n\n\t\t\t\t\tfloat numer = d1343 * d4321 - d1321 * d4343;\n\n\t\t\t\t\tmua = numer / denom;\n\t\t\t\t\tmua = clamp( mua, 0.0, 1.0 );\n\t\t\t\t\tmub = ( d1343 + d4321 * ( mua ) ) / d4343;\n\t\t\t\t\tmub = clamp( mub, 0.0, 1.0 );\n\n\t\t\t\t\treturn vec2( mua, mub );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\t#include <clipping_planes_fragment>\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tif ( vUv.y < - 1.0 || vUv.y > 1.0 ) discard; // discard endcaps\n\n\t\t\t\t\t\tif ( mod( vLineDistance + dashOffset, dashSize + gapSize ) > dashSize ) discard; // todo - FIX\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tfloat alpha = opacity;\n\n\t\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\t\t// Find the closest points on the view ray and the line segment\n\t\t\t\t\t\tvec3 rayEnd = normalize( worldPos.xyz ) * 1e5;\n\t\t\t\t\t\tvec3 lineDir = worldEnd - worldStart;\n\t\t\t\t\t\tvec2 params = closestLineToLine( worldStart, worldEnd, vec3( 0.0, 0.0, 0.0 ), rayEnd );\n\n\t\t\t\t\t\tvec3 p1 = worldStart + lineDir * params.x;\n\t\t\t\t\t\tvec3 p2 = rayEnd * params.y;\n\t\t\t\t\t\tvec3 delta = p1 - p2;\n\t\t\t\t\t\tfloat len = length( delta );\n\t\t\t\t\t\tfloat norm = len / linewidth;\n\n\t\t\t\t\t\t#ifndef USE_DASH\n\n\t\t\t\t\t\t\t#ifdef USE_ALPHA_TO_COVERAGE\n\n\t\t\t\t\t\t\t\tfloat dnorm = fwidth( norm );\n\t\t\t\t\t\t\t\talpha = 1.0 - smoothstep( 0.5 - dnorm, 0.5 + dnorm, norm );\n\n\t\t\t\t\t\t\t#else\n\n\t\t\t\t\t\t\t\tif ( norm > 0.5 ) {\n\n\t\t\t\t\t\t\t\t\tdiscard;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t#endif\n\n\t\t\t\t\t\t#endif\n\n\t\t\t\t\t#else\n\n\t\t\t\t\t\t#ifdef USE_ALPHA_TO_COVERAGE\n\n\t\t\t\t\t\t\t// artifacts appear on some hardware if a derivative is taken within a conditional\n\t\t\t\t\t\t\tfloat a = vUv.x;\n\t\t\t\t\t\t\tfloat b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;\n\t\t\t\t\t\t\tfloat len2 = a * a + b * b;\n\t\t\t\t\t\t\tfloat dlen = fwidth( len2 );\n\n\t\t\t\t\t\t\tif ( abs( vUv.y ) > 1.0 ) {\n\n\t\t\t\t\t\t\t\talpha = 1.0 - smoothstep( 1.0 - dlen, 1.0 + dlen, len2 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t#else\n\n\t\t\t\t\t\t\tif ( abs( vUv.y ) > 1.0 ) {\n\n\t\t\t\t\t\t\t\tfloat a = vUv.x;\n\t\t\t\t\t\t\t\tfloat b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;\n\t\t\t\t\t\t\t\tfloat len2 = a * a + b * b;\n\n\t\t\t\t\t\t\t\tif ( len2 > 1.0 ) discard;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t#endif\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tvec4 diffuseColor = vec4( diffuse, alpha );\n\t\t\t\t\t#ifdef USE_LINE_COLOR_ALPHA\n\t\t\t\t\t\tdiffuseColor *= vLineColor;\n\t\t\t\t\t#else\n\t\t\t\t\t\tdiffuseColor.rgb *= vLineColor;\n\t\t\t\t\t#endif\n\n\t\t\t\t\t#include <logdepthbuf_fragment>\n\n\t\t\t\t\tgl_FragColor = diffuseColor;\n\n\t\t\t\t\t#include <tonemapping_fragment>\n\t\t\t\t\t#include <${parseInt(REVISION.replace(/\\D+/g, '')) >= 154 ? 'colorspace_fragment' : 'encodings_fragment'}>\n\t\t\t\t\t#include <fog_fragment>\n\t\t\t\t\t#include <premultiplied_alpha_fragment>\n\n\t\t\t\t}\n\t\t\t`,\n clipping: true, // required for clipping support\n })\n\n this.isLineMaterial = true\n\n this.onBeforeCompile = function () {\n if (this.transparent) {\n this.defines.USE_LINE_COLOR_ALPHA = '1'\n } else {\n delete this.defines.USE_LINE_COLOR_ALPHA\n }\n }\n\n Object.defineProperties(this, {\n color: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.diffuse.value\n },\n\n set: function (value) {\n this.uniforms.diffuse.value = value\n },\n },\n\n worldUnits: {\n enumerable: true,\n\n get: function () {\n return 'WORLD_UNITS' in this.defines\n },\n\n set: function (value) {\n if (value === true) {\n this.defines.WORLD_UNITS = ''\n } else {\n delete this.defines.WORLD_UNITS\n }\n },\n },\n\n linewidth: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.linewidth.value\n },\n\n set: function (value) {\n this.uniforms.linewidth.value = value\n },\n },\n\n dashed: {\n enumerable: true,\n\n get: function () {\n return Boolean('USE_DASH' in this.defines)\n },\n\n set(value) {\n if (Boolean(value) !== Boolean('USE_DASH' in this.defines)) {\n this.needsUpdate = true\n }\n\n if (value === true) {\n this.defines.USE_DASH = ''\n } else {\n delete this.defines.USE_DASH\n }\n },\n },\n\n dashScale: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.dashScale.value\n },\n\n set: function (value) {\n this.uniforms.dashScale.value = value\n },\n },\n\n dashSize: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.dashSize.value\n },\n\n set: function (value) {\n this.uniforms.dashSize.value = value\n },\n },\n\n dashOffset: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.dashOffset.value\n },\n\n set: function (value) {\n this.uniforms.dashOffset.value = value\n },\n },\n\n gapSize: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.gapSize.value\n },\n\n set: function (value) {\n this.uniforms.gapSize.value = value\n },\n },\n\n opacity: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.opacity.value\n },\n\n set: function (value) {\n this.uniforms.opacity.value = value\n },\n },\n\n resolution: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.resolution.value\n },\n\n set: function (value) {\n this.uniforms.resolution.value.copy(value)\n },\n },\n\n alphaToCoverage: {\n enumerable: true,\n\n get: function () {\n return Boolean('USE_ALPHA_TO_COVERAGE' in this.defines)\n },\n\n set: function (value) {\n if (Boolean(value) !== Boolean('USE_ALPHA_TO_COVERAGE' in this.defines)) {\n this.needsUpdate = true\n }\n\n if (value === true) {\n this.defines.USE_ALPHA_TO_COVERAGE = ''\n this.extensions.derivatives = true\n } else {\n delete this.defines.USE_ALPHA_TO_COVERAGE\n this.extensions.derivatives = false\n }\n },\n },\n })\n\n this.setValues(parameters)\n }\n}\n\nexport { LineMaterial }\n"],"names":["ShaderMaterial","UniformsUtils","UniformsLib","Vector2","REVISION"],"mappings":";;;AAeA,MAAM,qBAAqBA,MAAAA,eAAe;AAAA,EACxC,YAAY,YAAY;AACtB,UAAM;AAAA,MACJ,MAAM;AAAA,MAEN,UAAUC,MAAa,cAAC;AAAA,QACtBA,MAAAA,cAAc,MAAM;AAAA,UAClBC,MAAAA,YAAY;AAAA,UACZA,MAAAA,YAAY;AAAA,UACZ;AAAA,YACE,YAAY,EAAE,OAAO,EAAG;AAAA,YACxB,WAAW,EAAE,OAAO,EAAG;AAAA,YACvB,YAAY,EAAE,OAAO,IAAIC,MAAO,QAAC,GAAG,CAAC,EAAG;AAAA,YACxC,YAAY,EAAE,OAAO,EAAG;AAAA,YACxB,WAAW,EAAE,OAAO,EAAG;AAAA,YACvB,UAAU,EAAE,OAAO,EAAG;AAAA,YACtB,SAAS,EAAE,OAAO,EAAG;AAAA;AAAA,UACtB;AAAA,QACX,CAAS;AAAA,MACF;AAAA,MAED;AAAA;AAAA,QAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAuOzB;AAAA;AAAA,QAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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"}
|
1
|
+
{"version":3,"file":"LineMaterial.cjs","sources":["../../src/lines/LineMaterial.js"],"sourcesContent":["/**\n * parameters = {\n * color: <hex>,\n * linewidth: <float>,\n * dashed: <boolean>,\n * dashScale: <float>,\n * dashSize: <float>,\n * dashOffset: <float>,\n * gapSize: <float>,\n * resolution: <Vector2>, // to be set by renderer\n * }\n */\n\nimport { ShaderMaterial, UniformsLib, UniformsUtils, Vector2, REVISION } from 'three'\n\nclass LineMaterial extends ShaderMaterial {\n constructor(parameters) {\n super({\n type: 'LineMaterial',\n\n uniforms: UniformsUtils.clone(\n UniformsUtils.merge([\n UniformsLib.common,\n UniformsLib.fog,\n {\n worldUnits: { value: 1 },\n linewidth: { value: 1 },\n resolution: { value: new Vector2(1, 1) },\n dashOffset: { value: 0 },\n dashScale: { value: 1 },\n dashSize: { value: 1 },\n gapSize: { value: 1 }, // todo FIX - maybe change to totalSize\n },\n ]),\n ),\n\n vertexShader: /* glsl */ `\n\t\t\t\t#include <common>\n\t\t\t\t#include <fog_pars_vertex>\n\t\t\t\t#include <logdepthbuf_pars_vertex>\n\t\t\t\t#include <clipping_planes_pars_vertex>\n\n\t\t\t\tuniform float linewidth;\n\t\t\t\tuniform vec2 resolution;\n\n\t\t\t\tattribute vec3 instanceStart;\n\t\t\t\tattribute vec3 instanceEnd;\n\n\t\t\t\t#ifdef USE_COLOR\n\t\t\t\t\t#ifdef USE_LINE_COLOR_ALPHA\n\t\t\t\t\t\tvarying vec4 vLineColor;\n\t\t\t\t\t\tattribute vec4 instanceColorStart;\n\t\t\t\t\t\tattribute vec4 instanceColorEnd;\n\t\t\t\t\t#else\n\t\t\t\t\t\tvarying vec3 vLineColor;\n\t\t\t\t\t\tattribute vec3 instanceColorStart;\n\t\t\t\t\t\tattribute vec3 instanceColorEnd;\n\t\t\t\t\t#endif\n\t\t\t\t#endif\n\n\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\tvarying vec4 worldPos;\n\t\t\t\t\tvarying vec3 worldStart;\n\t\t\t\t\tvarying vec3 worldEnd;\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t#else\n\n\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t#endif\n\n\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\tuniform float dashScale;\n\t\t\t\t\tattribute float instanceDistanceStart;\n\t\t\t\t\tattribute float instanceDistanceEnd;\n\t\t\t\t\tvarying float vLineDistance;\n\n\t\t\t\t#endif\n\n\t\t\t\tvoid trimSegment( const in vec4 start, inout vec4 end ) {\n\n\t\t\t\t\t// trim end segment so it terminates between the camera plane and the near plane\n\n\t\t\t\t\t// conservative estimate of the near plane\n\t\t\t\t\tfloat a = projectionMatrix[ 2 ][ 2 ]; // 3nd entry in 3th column\n\t\t\t\t\tfloat b = projectionMatrix[ 3 ][ 2 ]; // 3nd entry in 4th column\n\t\t\t\t\tfloat nearEstimate = - 0.5 * b / a;\n\n\t\t\t\t\tfloat alpha = ( nearEstimate - start.z ) / ( end.z - start.z );\n\n\t\t\t\t\tend.xyz = mix( start.xyz, end.xyz, alpha );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\t#ifdef USE_COLOR\n\n\t\t\t\t\t\tvLineColor = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tvLineDistance = ( position.y < 0.5 ) ? dashScale * instanceDistanceStart : dashScale * instanceDistanceEnd;\n\t\t\t\t\t\tvUv = uv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tfloat aspect = resolution.x / resolution.y;\n\n\t\t\t\t\t// camera space\n\t\t\t\t\tvec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );\n\t\t\t\t\tvec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );\n\n\t\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\t\tworldStart = start.xyz;\n\t\t\t\t\t\tworldEnd = end.xyz;\n\n\t\t\t\t\t#else\n\n\t\t\t\t\t\tvUv = uv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\t// special case for perspective projection, and segments that terminate either in, or behind, the camera plane\n\t\t\t\t\t// clearly the gpu firmware has a way of addressing this issue when projecting into ndc space\n\t\t\t\t\t// but we need to perform ndc-space calculations in the shader, so we must address this issue directly\n\t\t\t\t\t// perhaps there is a more elegant solution -- WestLangley\n\n\t\t\t\t\tbool perspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 ); // 4th entry in the 3rd column\n\n\t\t\t\t\tif ( perspective ) {\n\n\t\t\t\t\t\tif ( start.z < 0.0 && end.z >= 0.0 ) {\n\n\t\t\t\t\t\t\ttrimSegment( start, end );\n\n\t\t\t\t\t\t} else if ( end.z < 0.0 && start.z >= 0.0 ) {\n\n\t\t\t\t\t\t\ttrimSegment( end, start );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// clip space\n\t\t\t\t\tvec4 clipStart = projectionMatrix * start;\n\t\t\t\t\tvec4 clipEnd = projectionMatrix * end;\n\n\t\t\t\t\t// ndc space\n\t\t\t\t\tvec3 ndcStart = clipStart.xyz / clipStart.w;\n\t\t\t\t\tvec3 ndcEnd = clipEnd.xyz / clipEnd.w;\n\n\t\t\t\t\t// direction\n\t\t\t\t\tvec2 dir = ndcEnd.xy - ndcStart.xy;\n\n\t\t\t\t\t// account for clip-space aspect ratio\n\t\t\t\t\tdir.x *= aspect;\n\t\t\t\t\tdir = normalize( dir );\n\n\t\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\t\t// get the offset direction as perpendicular to the view vector\n\t\t\t\t\t\tvec3 worldDir = normalize( end.xyz - start.xyz );\n\t\t\t\t\t\tvec3 offset;\n\t\t\t\t\t\tif ( position.y < 0.5 ) {\n\n\t\t\t\t\t\t\toffset = normalize( cross( start.xyz, worldDir ) );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\toffset = normalize( cross( end.xyz, worldDir ) );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// sign flip\n\t\t\t\t\t\tif ( position.x < 0.0 ) offset *= - 1.0;\n\n\t\t\t\t\t\tfloat forwardOffset = dot( worldDir, vec3( 0.0, 0.0, 1.0 ) );\n\n\t\t\t\t\t\t// don't extend the line if we're rendering dashes because we\n\t\t\t\t\t\t// won't be rendering the endcaps\n\t\t\t\t\t\t#ifndef USE_DASH\n\n\t\t\t\t\t\t\t// extend the line bounds to encompass endcaps\n\t\t\t\t\t\t\tstart.xyz += - worldDir * linewidth * 0.5;\n\t\t\t\t\t\t\tend.xyz += worldDir * linewidth * 0.5;\n\n\t\t\t\t\t\t\t// shift the position of the quad so it hugs the forward edge of the line\n\t\t\t\t\t\t\toffset.xy -= dir * forwardOffset;\n\t\t\t\t\t\t\toffset.z += 0.5;\n\n\t\t\t\t\t\t#endif\n\n\t\t\t\t\t\t// endcaps\n\t\t\t\t\t\tif ( position.y > 1.0 || position.y < 0.0 ) {\n\n\t\t\t\t\t\t\toffset.xy += dir * 2.0 * forwardOffset;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// adjust for linewidth\n\t\t\t\t\t\toffset *= linewidth * 0.5;\n\n\t\t\t\t\t\t// set the world position\n\t\t\t\t\t\tworldPos = ( position.y < 0.5 ) ? start : end;\n\t\t\t\t\t\tworldPos.xyz += offset;\n\n\t\t\t\t\t\t// project the worldpos\n\t\t\t\t\t\tvec4 clip = projectionMatrix * worldPos;\n\n\t\t\t\t\t\t// shift the depth of the projected points so the line\n\t\t\t\t\t\t// segments overlap neatly\n\t\t\t\t\t\tvec3 clipPose = ( position.y < 0.5 ) ? ndcStart : ndcEnd;\n\t\t\t\t\t\tclip.z = clipPose.z * clip.w;\n\n\t\t\t\t\t#else\n\n\t\t\t\t\t\tvec2 offset = vec2( dir.y, - dir.x );\n\t\t\t\t\t\t// undo aspect ratio adjustment\n\t\t\t\t\t\tdir.x /= aspect;\n\t\t\t\t\t\toffset.x /= aspect;\n\n\t\t\t\t\t\t// sign flip\n\t\t\t\t\t\tif ( position.x < 0.0 ) offset *= - 1.0;\n\n\t\t\t\t\t\t// endcaps\n\t\t\t\t\t\tif ( position.y < 0.0 ) {\n\n\t\t\t\t\t\t\toffset += - dir;\n\n\t\t\t\t\t\t} else if ( position.y > 1.0 ) {\n\n\t\t\t\t\t\t\toffset += dir;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// adjust for linewidth\n\t\t\t\t\t\toffset *= linewidth;\n\n\t\t\t\t\t\t// adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...\n\t\t\t\t\t\toffset /= resolution.y;\n\n\t\t\t\t\t\t// select end\n\t\t\t\t\t\tvec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;\n\n\t\t\t\t\t\t// back to clip space\n\t\t\t\t\t\toffset *= clip.w;\n\n\t\t\t\t\t\tclip.xy += offset;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tgl_Position = clip;\n\n\t\t\t\t\tvec4 mvPosition = ( position.y < 0.5 ) ? start : end; // this is an approximation\n\n\t\t\t\t\t#include <logdepthbuf_vertex>\n\t\t\t\t\t#include <clipping_planes_vertex>\n\t\t\t\t\t#include <fog_vertex>\n\n\t\t\t\t}\n\t\t\t`,\n fragmentShader: /* glsl */ `\n\t\t\t\tuniform vec3 diffuse;\n\t\t\t\tuniform float opacity;\n\t\t\t\tuniform float linewidth;\n\n\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\tuniform float dashOffset;\n\t\t\t\t\tuniform float dashSize;\n\t\t\t\t\tuniform float gapSize;\n\n\t\t\t\t#endif\n\n\t\t\t\tvarying float vLineDistance;\n\n\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\tvarying vec4 worldPos;\n\t\t\t\t\tvarying vec3 worldStart;\n\t\t\t\t\tvarying vec3 worldEnd;\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t#else\n\n\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t#endif\n\n\t\t\t\t#include <common>\n\t\t\t\t#include <fog_pars_fragment>\n\t\t\t\t#include <logdepthbuf_pars_fragment>\n\t\t\t\t#include <clipping_planes_pars_fragment>\n\n\t\t\t\t#ifdef USE_COLOR\n\t\t\t\t\t#ifdef USE_LINE_COLOR_ALPHA\n\t\t\t\t\t\tvarying vec4 vLineColor;\n\t\t\t\t\t#else\n\t\t\t\t\t\tvarying vec3 vLineColor;\n\t\t\t\t\t#endif\n\t\t\t\t#endif\n\n\t\t\t\tvec2 closestLineToLine(vec3 p1, vec3 p2, vec3 p3, vec3 p4) {\n\n\t\t\t\t\tfloat mua;\n\t\t\t\t\tfloat mub;\n\n\t\t\t\t\tvec3 p13 = p1 - p3;\n\t\t\t\t\tvec3 p43 = p4 - p3;\n\n\t\t\t\t\tvec3 p21 = p2 - p1;\n\n\t\t\t\t\tfloat d1343 = dot( p13, p43 );\n\t\t\t\t\tfloat d4321 = dot( p43, p21 );\n\t\t\t\t\tfloat d1321 = dot( p13, p21 );\n\t\t\t\t\tfloat d4343 = dot( p43, p43 );\n\t\t\t\t\tfloat d2121 = dot( p21, p21 );\n\n\t\t\t\t\tfloat denom = d2121 * d4343 - d4321 * d4321;\n\n\t\t\t\t\tfloat numer = d1343 * d4321 - d1321 * d4343;\n\n\t\t\t\t\tmua = numer / denom;\n\t\t\t\t\tmua = clamp( mua, 0.0, 1.0 );\n\t\t\t\t\tmub = ( d1343 + d4321 * ( mua ) ) / d4343;\n\t\t\t\t\tmub = clamp( mub, 0.0, 1.0 );\n\n\t\t\t\t\treturn vec2( mua, mub );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\t#include <clipping_planes_fragment>\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tif ( vUv.y < - 1.0 || vUv.y > 1.0 ) discard; // discard endcaps\n\n\t\t\t\t\t\tif ( mod( vLineDistance + dashOffset, dashSize + gapSize ) > dashSize ) discard; // todo - FIX\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tfloat alpha = opacity;\n\n\t\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\t\t// Find the closest points on the view ray and the line segment\n\t\t\t\t\t\tvec3 rayEnd = normalize( worldPos.xyz ) * 1e5;\n\t\t\t\t\t\tvec3 lineDir = worldEnd - worldStart;\n\t\t\t\t\t\tvec2 params = closestLineToLine( worldStart, worldEnd, vec3( 0.0, 0.0, 0.0 ), rayEnd );\n\n\t\t\t\t\t\tvec3 p1 = worldStart + lineDir * params.x;\n\t\t\t\t\t\tvec3 p2 = rayEnd * params.y;\n\t\t\t\t\t\tvec3 delta = p1 - p2;\n\t\t\t\t\t\tfloat len = length( delta );\n\t\t\t\t\t\tfloat norm = len / linewidth;\n\n\t\t\t\t\t\t#ifndef USE_DASH\n\n\t\t\t\t\t\t\t#ifdef USE_ALPHA_TO_COVERAGE\n\n\t\t\t\t\t\t\t\tfloat dnorm = fwidth( norm );\n\t\t\t\t\t\t\t\talpha = 1.0 - smoothstep( 0.5 - dnorm, 0.5 + dnorm, norm );\n\n\t\t\t\t\t\t\t#else\n\n\t\t\t\t\t\t\t\tif ( norm > 0.5 ) {\n\n\t\t\t\t\t\t\t\t\tdiscard;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t#endif\n\n\t\t\t\t\t\t#endif\n\n\t\t\t\t\t#else\n\n\t\t\t\t\t\t#ifdef USE_ALPHA_TO_COVERAGE\n\n\t\t\t\t\t\t\t// artifacts appear on some hardware if a derivative is taken within a conditional\n\t\t\t\t\t\t\tfloat a = vUv.x;\n\t\t\t\t\t\t\tfloat b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;\n\t\t\t\t\t\t\tfloat len2 = a * a + b * b;\n\t\t\t\t\t\t\tfloat dlen = fwidth( len2 );\n\n\t\t\t\t\t\t\tif ( abs( vUv.y ) > 1.0 ) {\n\n\t\t\t\t\t\t\t\talpha = 1.0 - smoothstep( 1.0 - dlen, 1.0 + dlen, len2 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t#else\n\n\t\t\t\t\t\t\tif ( abs( vUv.y ) > 1.0 ) {\n\n\t\t\t\t\t\t\t\tfloat a = vUv.x;\n\t\t\t\t\t\t\t\tfloat b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;\n\t\t\t\t\t\t\t\tfloat len2 = a * a + b * b;\n\n\t\t\t\t\t\t\t\tif ( len2 > 1.0 ) discard;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t#endif\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tvec4 diffuseColor = vec4( diffuse, alpha );\n\t\t\t\t\t#ifdef USE_COLOR\n\t\t\t\t\t\t#ifdef USE_LINE_COLOR_ALPHA\n\t\t\t\t\t\t\tdiffuseColor *= vLineColor;\n\t\t\t\t\t\t#else\n\t\t\t\t\t\t\tdiffuseColor.rgb *= vLineColor;\n\t\t\t\t\t\t#endif\n\t\t\t\t\t#endif\n\n\t\t\t\t\t#include <logdepthbuf_fragment>\n\n\t\t\t\t\tgl_FragColor = diffuseColor;\n\n\t\t\t\t\t#include <tonemapping_fragment>\n\t\t\t\t\t#include <${parseInt(REVISION.replace(/\\D+/g, '')) >= 154 ? 'colorspace_fragment' : 'encodings_fragment'}>\n\t\t\t\t\t#include <fog_fragment>\n\t\t\t\t\t#include <premultiplied_alpha_fragment>\n\n\t\t\t\t}\n\t\t\t`,\n clipping: true, // required for clipping support\n })\n\n this.isLineMaterial = true\n\n this.onBeforeCompile = function () {\n if (this.transparent) {\n this.defines.USE_LINE_COLOR_ALPHA = '1'\n } else {\n delete this.defines.USE_LINE_COLOR_ALPHA\n }\n }\n\n Object.defineProperties(this, {\n color: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.diffuse.value\n },\n\n set: function (value) {\n this.uniforms.diffuse.value = value\n },\n },\n\n worldUnits: {\n enumerable: true,\n\n get: function () {\n return 'WORLD_UNITS' in this.defines\n },\n\n set: function (value) {\n if (value === true) {\n this.defines.WORLD_UNITS = ''\n } else {\n delete this.defines.WORLD_UNITS\n }\n },\n },\n\n linewidth: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.linewidth.value\n },\n\n set: function (value) {\n this.uniforms.linewidth.value = value\n },\n },\n\n dashed: {\n enumerable: true,\n\n get: function () {\n return Boolean('USE_DASH' in this.defines)\n },\n\n set(value) {\n if (Boolean(value) !== Boolean('USE_DASH' in this.defines)) {\n this.needsUpdate = true\n }\n\n if (value === true) {\n this.defines.USE_DASH = ''\n } else {\n delete this.defines.USE_DASH\n }\n },\n },\n\n dashScale: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.dashScale.value\n },\n\n set: function (value) {\n this.uniforms.dashScale.value = value\n },\n },\n\n dashSize: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.dashSize.value\n },\n\n set: function (value) {\n this.uniforms.dashSize.value = value\n },\n },\n\n dashOffset: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.dashOffset.value\n },\n\n set: function (value) {\n this.uniforms.dashOffset.value = value\n },\n },\n\n gapSize: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.gapSize.value\n },\n\n set: function (value) {\n this.uniforms.gapSize.value = value\n },\n },\n\n opacity: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.opacity.value\n },\n\n set: function (value) {\n this.uniforms.opacity.value = value\n },\n },\n\n resolution: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.resolution.value\n },\n\n set: function (value) {\n this.uniforms.resolution.value.copy(value)\n },\n },\n\n alphaToCoverage: {\n enumerable: true,\n\n get: function () {\n return Boolean('USE_ALPHA_TO_COVERAGE' in this.defines)\n },\n\n set: function (value) {\n if (Boolean(value) !== Boolean('USE_ALPHA_TO_COVERAGE' in this.defines)) {\n this.needsUpdate = true\n }\n\n if (value === true) {\n this.defines.USE_ALPHA_TO_COVERAGE = ''\n this.extensions.derivatives = true\n } else {\n delete this.defines.USE_ALPHA_TO_COVERAGE\n this.extensions.derivatives = false\n }\n },\n },\n })\n\n this.setValues(parameters)\n }\n}\n\nexport { LineMaterial }\n"],"names":["ShaderMaterial","UniformsUtils","UniformsLib","Vector2","REVISION"],"mappings":";;;AAeA,MAAM,qBAAqBA,MAAAA,eAAe;AAAA,EACxC,YAAY,YAAY;AACtB,UAAM;AAAA,MACJ,MAAM;AAAA,MAEN,UAAUC,MAAa,cAAC;AAAA,QACtBA,MAAAA,cAAc,MAAM;AAAA,UAClBC,MAAAA,YAAY;AAAA,UACZA,MAAAA,YAAY;AAAA,UACZ;AAAA,YACE,YAAY,EAAE,OAAO,EAAG;AAAA,YACxB,WAAW,EAAE,OAAO,EAAG;AAAA,YACvB,YAAY,EAAE,OAAO,IAAIC,MAAO,QAAC,GAAG,CAAC,EAAG;AAAA,YACxC,YAAY,EAAE,OAAO,EAAG;AAAA,YACxB,WAAW,EAAE,OAAO,EAAG;AAAA,YACvB,UAAU,EAAE,OAAO,EAAG;AAAA,YACtB,SAAS,EAAE,OAAO,EAAG;AAAA;AAAA,UACtB;AAAA,QACX,CAAS;AAAA,MACF;AAAA,MAED;AAAA;AAAA,QAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MA6OzB;AAAA;AAAA,QAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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"}
|
package/lines/LineMaterial.js
CHANGED
@@ -33,14 +33,16 @@ class LineMaterial extends ShaderMaterial {
|
|
33
33
|
attribute vec3 instanceStart;
|
34
34
|
attribute vec3 instanceEnd;
|
35
35
|
|
36
|
-
#ifdef
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
36
|
+
#ifdef USE_COLOR
|
37
|
+
#ifdef USE_LINE_COLOR_ALPHA
|
38
|
+
varying vec4 vLineColor;
|
39
|
+
attribute vec4 instanceColorStart;
|
40
|
+
attribute vec4 instanceColorEnd;
|
41
|
+
#else
|
42
|
+
varying vec3 vLineColor;
|
43
|
+
attribute vec3 instanceColorStart;
|
44
|
+
attribute vec3 instanceColorEnd;
|
45
|
+
#endif
|
44
46
|
#endif
|
45
47
|
|
46
48
|
#ifdef WORLD_UNITS
|
@@ -87,7 +89,11 @@ class LineMaterial extends ShaderMaterial {
|
|
87
89
|
|
88
90
|
void main() {
|
89
91
|
|
90
|
-
|
92
|
+
#ifdef USE_COLOR
|
93
|
+
|
94
|
+
vLineColor = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;
|
95
|
+
|
96
|
+
#endif
|
91
97
|
|
92
98
|
#ifdef USE_DASH
|
93
99
|
|
@@ -293,10 +299,12 @@ class LineMaterial extends ShaderMaterial {
|
|
293
299
|
#include <logdepthbuf_pars_fragment>
|
294
300
|
#include <clipping_planes_pars_fragment>
|
295
301
|
|
296
|
-
#ifdef
|
297
|
-
|
298
|
-
|
299
|
-
|
302
|
+
#ifdef USE_COLOR
|
303
|
+
#ifdef USE_LINE_COLOR_ALPHA
|
304
|
+
varying vec4 vLineColor;
|
305
|
+
#else
|
306
|
+
varying vec3 vLineColor;
|
307
|
+
#endif
|
300
308
|
#endif
|
301
309
|
|
302
310
|
vec2 closestLineToLine(vec3 p1, vec3 p2, vec3 p3, vec3 p4) {
|
@@ -407,10 +415,12 @@ class LineMaterial extends ShaderMaterial {
|
|
407
415
|
#endif
|
408
416
|
|
409
417
|
vec4 diffuseColor = vec4( diffuse, alpha );
|
410
|
-
#ifdef
|
411
|
-
|
412
|
-
|
413
|
-
|
418
|
+
#ifdef USE_COLOR
|
419
|
+
#ifdef USE_LINE_COLOR_ALPHA
|
420
|
+
diffuseColor *= vLineColor;
|
421
|
+
#else
|
422
|
+
diffuseColor.rgb *= vLineColor;
|
423
|
+
#endif
|
414
424
|
#endif
|
415
425
|
|
416
426
|
#include <logdepthbuf_fragment>
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"LineMaterial.js","sources":["../../src/lines/LineMaterial.js"],"sourcesContent":["/**\n * parameters = {\n * color: <hex>,\n * linewidth: <float>,\n * dashed: <boolean>,\n * dashScale: <float>,\n * dashSize: <float>,\n * dashOffset: <float>,\n * gapSize: <float>,\n * resolution: <Vector2>, // to be set by renderer\n * }\n */\n\nimport { ShaderMaterial, UniformsLib, UniformsUtils, Vector2, REVISION } from 'three'\n\nclass LineMaterial extends ShaderMaterial {\n constructor(parameters) {\n super({\n type: 'LineMaterial',\n\n uniforms: UniformsUtils.clone(\n UniformsUtils.merge([\n UniformsLib.common,\n UniformsLib.fog,\n {\n worldUnits: { value: 1 },\n linewidth: { value: 1 },\n resolution: { value: new Vector2(1, 1) },\n dashOffset: { value: 0 },\n dashScale: { value: 1 },\n dashSize: { value: 1 },\n gapSize: { value: 1 }, // todo FIX - maybe change to totalSize\n },\n ]),\n ),\n\n vertexShader: /* glsl */ `\n\t\t\t\t#include <common>\n\t\t\t\t#include <fog_pars_vertex>\n\t\t\t\t#include <logdepthbuf_pars_vertex>\n\t\t\t\t#include <clipping_planes_pars_vertex>\n\n\t\t\t\tuniform float linewidth;\n\t\t\t\tuniform vec2 resolution;\n\n\t\t\t\tattribute vec3 instanceStart;\n\t\t\t\tattribute vec3 instanceEnd;\n\n\t\t\t\t#ifdef USE_LINE_COLOR_ALPHA\n\t\t\t\t\tvarying vec4 vLineColor;\n\t\t\t\t\tattribute vec4 instanceColorStart;\n\t\t\t\t\tattribute vec4 instanceColorEnd;\n\t\t\t\t#else\n\t\t\t\t\tvarying vec3 vLineColor;\n\t\t\t\t\tattribute vec3 instanceColorStart;\n\t\t\t\t\tattribute vec3 instanceColorEnd;\n\t\t\t\t#endif\n\n\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\tvarying vec4 worldPos;\n\t\t\t\t\tvarying vec3 worldStart;\n\t\t\t\t\tvarying vec3 worldEnd;\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t#else\n\n\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t#endif\n\n\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\tuniform float dashScale;\n\t\t\t\t\tattribute float instanceDistanceStart;\n\t\t\t\t\tattribute float instanceDistanceEnd;\n\t\t\t\t\tvarying float vLineDistance;\n\n\t\t\t\t#endif\n\n\t\t\t\tvoid trimSegment( const in vec4 start, inout vec4 end ) {\n\n\t\t\t\t\t// trim end segment so it terminates between the camera plane and the near plane\n\n\t\t\t\t\t// conservative estimate of the near plane\n\t\t\t\t\tfloat a = projectionMatrix[ 2 ][ 2 ]; // 3nd entry in 3th column\n\t\t\t\t\tfloat b = projectionMatrix[ 3 ][ 2 ]; // 3nd entry in 4th column\n\t\t\t\t\tfloat nearEstimate = - 0.5 * b / a;\n\n\t\t\t\t\tfloat alpha = ( nearEstimate - start.z ) / ( end.z - start.z );\n\n\t\t\t\t\tend.xyz = mix( start.xyz, end.xyz, alpha );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvLineColor = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tvLineDistance = ( position.y < 0.5 ) ? dashScale * instanceDistanceStart : dashScale * instanceDistanceEnd;\n\t\t\t\t\t\tvUv = uv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tfloat aspect = resolution.x / resolution.y;\n\n\t\t\t\t\t// camera space\n\t\t\t\t\tvec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );\n\t\t\t\t\tvec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );\n\n\t\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\t\tworldStart = start.xyz;\n\t\t\t\t\t\tworldEnd = end.xyz;\n\n\t\t\t\t\t#else\n\n\t\t\t\t\t\tvUv = uv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\t// special case for perspective projection, and segments that terminate either in, or behind, the camera plane\n\t\t\t\t\t// clearly the gpu firmware has a way of addressing this issue when projecting into ndc space\n\t\t\t\t\t// but we need to perform ndc-space calculations in the shader, so we must address this issue directly\n\t\t\t\t\t// perhaps there is a more elegant solution -- WestLangley\n\n\t\t\t\t\tbool perspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 ); // 4th entry in the 3rd column\n\n\t\t\t\t\tif ( perspective ) {\n\n\t\t\t\t\t\tif ( start.z < 0.0 && end.z >= 0.0 ) {\n\n\t\t\t\t\t\t\ttrimSegment( start, end );\n\n\t\t\t\t\t\t} else if ( end.z < 0.0 && start.z >= 0.0 ) {\n\n\t\t\t\t\t\t\ttrimSegment( end, start );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// clip space\n\t\t\t\t\tvec4 clipStart = projectionMatrix * start;\n\t\t\t\t\tvec4 clipEnd = projectionMatrix * end;\n\n\t\t\t\t\t// ndc space\n\t\t\t\t\tvec3 ndcStart = clipStart.xyz / clipStart.w;\n\t\t\t\t\tvec3 ndcEnd = clipEnd.xyz / clipEnd.w;\n\n\t\t\t\t\t// direction\n\t\t\t\t\tvec2 dir = ndcEnd.xy - ndcStart.xy;\n\n\t\t\t\t\t// account for clip-space aspect ratio\n\t\t\t\t\tdir.x *= aspect;\n\t\t\t\t\tdir = normalize( dir );\n\n\t\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\t\t// get the offset direction as perpendicular to the view vector\n\t\t\t\t\t\tvec3 worldDir = normalize( end.xyz - start.xyz );\n\t\t\t\t\t\tvec3 offset;\n\t\t\t\t\t\tif ( position.y < 0.5 ) {\n\n\t\t\t\t\t\t\toffset = normalize( cross( start.xyz, worldDir ) );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\toffset = normalize( cross( end.xyz, worldDir ) );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// sign flip\n\t\t\t\t\t\tif ( position.x < 0.0 ) offset *= - 1.0;\n\n\t\t\t\t\t\tfloat forwardOffset = dot( worldDir, vec3( 0.0, 0.0, 1.0 ) );\n\n\t\t\t\t\t\t// don't extend the line if we're rendering dashes because we\n\t\t\t\t\t\t// won't be rendering the endcaps\n\t\t\t\t\t\t#ifndef USE_DASH\n\n\t\t\t\t\t\t\t// extend the line bounds to encompass endcaps\n\t\t\t\t\t\t\tstart.xyz += - worldDir * linewidth * 0.5;\n\t\t\t\t\t\t\tend.xyz += worldDir * linewidth * 0.5;\n\n\t\t\t\t\t\t\t// shift the position of the quad so it hugs the forward edge of the line\n\t\t\t\t\t\t\toffset.xy -= dir * forwardOffset;\n\t\t\t\t\t\t\toffset.z += 0.5;\n\n\t\t\t\t\t\t#endif\n\n\t\t\t\t\t\t// endcaps\n\t\t\t\t\t\tif ( position.y > 1.0 || position.y < 0.0 ) {\n\n\t\t\t\t\t\t\toffset.xy += dir * 2.0 * forwardOffset;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// adjust for linewidth\n\t\t\t\t\t\toffset *= linewidth * 0.5;\n\n\t\t\t\t\t\t// set the world position\n\t\t\t\t\t\tworldPos = ( position.y < 0.5 ) ? start : end;\n\t\t\t\t\t\tworldPos.xyz += offset;\n\n\t\t\t\t\t\t// project the worldpos\n\t\t\t\t\t\tvec4 clip = projectionMatrix * worldPos;\n\n\t\t\t\t\t\t// shift the depth of the projected points so the line\n\t\t\t\t\t\t// segments overlap neatly\n\t\t\t\t\t\tvec3 clipPose = ( position.y < 0.5 ) ? ndcStart : ndcEnd;\n\t\t\t\t\t\tclip.z = clipPose.z * clip.w;\n\n\t\t\t\t\t#else\n\n\t\t\t\t\t\tvec2 offset = vec2( dir.y, - dir.x );\n\t\t\t\t\t\t// undo aspect ratio adjustment\n\t\t\t\t\t\tdir.x /= aspect;\n\t\t\t\t\t\toffset.x /= aspect;\n\n\t\t\t\t\t\t// sign flip\n\t\t\t\t\t\tif ( position.x < 0.0 ) offset *= - 1.0;\n\n\t\t\t\t\t\t// endcaps\n\t\t\t\t\t\tif ( position.y < 0.0 ) {\n\n\t\t\t\t\t\t\toffset += - dir;\n\n\t\t\t\t\t\t} else if ( position.y > 1.0 ) {\n\n\t\t\t\t\t\t\toffset += dir;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// adjust for linewidth\n\t\t\t\t\t\toffset *= linewidth;\n\n\t\t\t\t\t\t// adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...\n\t\t\t\t\t\toffset /= resolution.y;\n\n\t\t\t\t\t\t// select end\n\t\t\t\t\t\tvec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;\n\n\t\t\t\t\t\t// back to clip space\n\t\t\t\t\t\toffset *= clip.w;\n\n\t\t\t\t\t\tclip.xy += offset;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tgl_Position = clip;\n\n\t\t\t\t\tvec4 mvPosition = ( position.y < 0.5 ) ? start : end; // this is an approximation\n\n\t\t\t\t\t#include <logdepthbuf_vertex>\n\t\t\t\t\t#include <clipping_planes_vertex>\n\t\t\t\t\t#include <fog_vertex>\n\n\t\t\t\t}\n\t\t\t`,\n fragmentShader: /* glsl */ `\n\t\t\t\tuniform vec3 diffuse;\n\t\t\t\tuniform float opacity;\n\t\t\t\tuniform float linewidth;\n\n\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\tuniform float dashOffset;\n\t\t\t\t\tuniform float dashSize;\n\t\t\t\t\tuniform float gapSize;\n\n\t\t\t\t#endif\n\n\t\t\t\tvarying float vLineDistance;\n\n\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\tvarying vec4 worldPos;\n\t\t\t\t\tvarying vec3 worldStart;\n\t\t\t\t\tvarying vec3 worldEnd;\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t#else\n\n\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t#endif\n\n\t\t\t\t#include <common>\n\t\t\t\t#include <fog_pars_fragment>\n\t\t\t\t#include <logdepthbuf_pars_fragment>\n\t\t\t\t#include <clipping_planes_pars_fragment>\n\n\t\t\t\t#ifdef USE_LINE_COLOR_ALPHA\n\t\t\t\t\tvarying vec4 vLineColor;\n\t\t\t\t#else\n\t\t\t\t\tvarying vec3 vLineColor;\n\t\t\t\t#endif\n\n\t\t\t\tvec2 closestLineToLine(vec3 p1, vec3 p2, vec3 p3, vec3 p4) {\n\n\t\t\t\t\tfloat mua;\n\t\t\t\t\tfloat mub;\n\n\t\t\t\t\tvec3 p13 = p1 - p3;\n\t\t\t\t\tvec3 p43 = p4 - p3;\n\n\t\t\t\t\tvec3 p21 = p2 - p1;\n\n\t\t\t\t\tfloat d1343 = dot( p13, p43 );\n\t\t\t\t\tfloat d4321 = dot( p43, p21 );\n\t\t\t\t\tfloat d1321 = dot( p13, p21 );\n\t\t\t\t\tfloat d4343 = dot( p43, p43 );\n\t\t\t\t\tfloat d2121 = dot( p21, p21 );\n\n\t\t\t\t\tfloat denom = d2121 * d4343 - d4321 * d4321;\n\n\t\t\t\t\tfloat numer = d1343 * d4321 - d1321 * d4343;\n\n\t\t\t\t\tmua = numer / denom;\n\t\t\t\t\tmua = clamp( mua, 0.0, 1.0 );\n\t\t\t\t\tmub = ( d1343 + d4321 * ( mua ) ) / d4343;\n\t\t\t\t\tmub = clamp( mub, 0.0, 1.0 );\n\n\t\t\t\t\treturn vec2( mua, mub );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\t#include <clipping_planes_fragment>\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tif ( vUv.y < - 1.0 || vUv.y > 1.0 ) discard; // discard endcaps\n\n\t\t\t\t\t\tif ( mod( vLineDistance + dashOffset, dashSize + gapSize ) > dashSize ) discard; // todo - FIX\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tfloat alpha = opacity;\n\n\t\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\t\t// Find the closest points on the view ray and the line segment\n\t\t\t\t\t\tvec3 rayEnd = normalize( worldPos.xyz ) * 1e5;\n\t\t\t\t\t\tvec3 lineDir = worldEnd - worldStart;\n\t\t\t\t\t\tvec2 params = closestLineToLine( worldStart, worldEnd, vec3( 0.0, 0.0, 0.0 ), rayEnd );\n\n\t\t\t\t\t\tvec3 p1 = worldStart + lineDir * params.x;\n\t\t\t\t\t\tvec3 p2 = rayEnd * params.y;\n\t\t\t\t\t\tvec3 delta = p1 - p2;\n\t\t\t\t\t\tfloat len = length( delta );\n\t\t\t\t\t\tfloat norm = len / linewidth;\n\n\t\t\t\t\t\t#ifndef USE_DASH\n\n\t\t\t\t\t\t\t#ifdef USE_ALPHA_TO_COVERAGE\n\n\t\t\t\t\t\t\t\tfloat dnorm = fwidth( norm );\n\t\t\t\t\t\t\t\talpha = 1.0 - smoothstep( 0.5 - dnorm, 0.5 + dnorm, norm );\n\n\t\t\t\t\t\t\t#else\n\n\t\t\t\t\t\t\t\tif ( norm > 0.5 ) {\n\n\t\t\t\t\t\t\t\t\tdiscard;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t#endif\n\n\t\t\t\t\t\t#endif\n\n\t\t\t\t\t#else\n\n\t\t\t\t\t\t#ifdef USE_ALPHA_TO_COVERAGE\n\n\t\t\t\t\t\t\t// artifacts appear on some hardware if a derivative is taken within a conditional\n\t\t\t\t\t\t\tfloat a = vUv.x;\n\t\t\t\t\t\t\tfloat b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;\n\t\t\t\t\t\t\tfloat len2 = a * a + b * b;\n\t\t\t\t\t\t\tfloat dlen = fwidth( len2 );\n\n\t\t\t\t\t\t\tif ( abs( vUv.y ) > 1.0 ) {\n\n\t\t\t\t\t\t\t\talpha = 1.0 - smoothstep( 1.0 - dlen, 1.0 + dlen, len2 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t#else\n\n\t\t\t\t\t\t\tif ( abs( vUv.y ) > 1.0 ) {\n\n\t\t\t\t\t\t\t\tfloat a = vUv.x;\n\t\t\t\t\t\t\t\tfloat b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;\n\t\t\t\t\t\t\t\tfloat len2 = a * a + b * b;\n\n\t\t\t\t\t\t\t\tif ( len2 > 1.0 ) discard;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t#endif\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tvec4 diffuseColor = vec4( diffuse, alpha );\n\t\t\t\t\t#ifdef USE_LINE_COLOR_ALPHA\n\t\t\t\t\t\tdiffuseColor *= vLineColor;\n\t\t\t\t\t#else\n\t\t\t\t\t\tdiffuseColor.rgb *= vLineColor;\n\t\t\t\t\t#endif\n\n\t\t\t\t\t#include <logdepthbuf_fragment>\n\n\t\t\t\t\tgl_FragColor = diffuseColor;\n\n\t\t\t\t\t#include <tonemapping_fragment>\n\t\t\t\t\t#include <${parseInt(REVISION.replace(/\\D+/g, '')) >= 154 ? 'colorspace_fragment' : 'encodings_fragment'}>\n\t\t\t\t\t#include <fog_fragment>\n\t\t\t\t\t#include <premultiplied_alpha_fragment>\n\n\t\t\t\t}\n\t\t\t`,\n clipping: true, // required for clipping support\n })\n\n this.isLineMaterial = true\n\n this.onBeforeCompile = function () {\n if (this.transparent) {\n this.defines.USE_LINE_COLOR_ALPHA = '1'\n } else {\n delete this.defines.USE_LINE_COLOR_ALPHA\n }\n }\n\n Object.defineProperties(this, {\n color: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.diffuse.value\n },\n\n set: function (value) {\n this.uniforms.diffuse.value = value\n },\n },\n\n worldUnits: {\n enumerable: true,\n\n get: function () {\n return 'WORLD_UNITS' in this.defines\n },\n\n set: function (value) {\n if (value === true) {\n this.defines.WORLD_UNITS = ''\n } else {\n delete this.defines.WORLD_UNITS\n }\n },\n },\n\n linewidth: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.linewidth.value\n },\n\n set: function (value) {\n this.uniforms.linewidth.value = value\n },\n },\n\n dashed: {\n enumerable: true,\n\n get: function () {\n return Boolean('USE_DASH' in this.defines)\n },\n\n set(value) {\n if (Boolean(value) !== Boolean('USE_DASH' in this.defines)) {\n this.needsUpdate = true\n }\n\n if (value === true) {\n this.defines.USE_DASH = ''\n } else {\n delete this.defines.USE_DASH\n }\n },\n },\n\n dashScale: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.dashScale.value\n },\n\n set: function (value) {\n this.uniforms.dashScale.value = value\n },\n },\n\n dashSize: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.dashSize.value\n },\n\n set: function (value) {\n this.uniforms.dashSize.value = value\n },\n },\n\n dashOffset: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.dashOffset.value\n },\n\n set: function (value) {\n this.uniforms.dashOffset.value = value\n },\n },\n\n gapSize: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.gapSize.value\n },\n\n set: function (value) {\n this.uniforms.gapSize.value = value\n },\n },\n\n opacity: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.opacity.value\n },\n\n set: function (value) {\n this.uniforms.opacity.value = value\n },\n },\n\n resolution: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.resolution.value\n },\n\n set: function (value) {\n this.uniforms.resolution.value.copy(value)\n },\n },\n\n alphaToCoverage: {\n enumerable: true,\n\n get: function () {\n return Boolean('USE_ALPHA_TO_COVERAGE' in this.defines)\n },\n\n set: function (value) {\n if (Boolean(value) !== Boolean('USE_ALPHA_TO_COVERAGE' in this.defines)) {\n this.needsUpdate = true\n }\n\n if (value === true) {\n this.defines.USE_ALPHA_TO_COVERAGE = ''\n this.extensions.derivatives = true\n } else {\n delete this.defines.USE_ALPHA_TO_COVERAGE\n this.extensions.derivatives = false\n }\n },\n },\n })\n\n this.setValues(parameters)\n }\n}\n\nexport { LineMaterial }\n"],"names":[],"mappings":";AAeA,MAAM,qBAAqB,eAAe;AAAA,EACxC,YAAY,YAAY;AACtB,UAAM;AAAA,MACJ,MAAM;AAAA,MAEN,UAAU,cAAc;AAAA,QACtB,cAAc,MAAM;AAAA,UAClB,YAAY;AAAA,UACZ,YAAY;AAAA,UACZ;AAAA,YACE,YAAY,EAAE,OAAO,EAAG;AAAA,YACxB,WAAW,EAAE,OAAO,EAAG;AAAA,YACvB,YAAY,EAAE,OAAO,IAAI,QAAQ,GAAG,CAAC,EAAG;AAAA,YACxC,YAAY,EAAE,OAAO,EAAG;AAAA,YACxB,WAAW,EAAE,OAAO,EAAG;AAAA,YACvB,UAAU,EAAE,OAAO,EAAG;AAAA,YACtB,SAAS,EAAE,OAAO,EAAG;AAAA;AAAA,UACtB;AAAA,QACX,CAAS;AAAA,MACF;AAAA,MAED;AAAA;AAAA,QAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAuOzB;AAAA;AAAA,QAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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"}
|
1
|
+
{"version":3,"file":"LineMaterial.js","sources":["../../src/lines/LineMaterial.js"],"sourcesContent":["/**\n * parameters = {\n * color: <hex>,\n * linewidth: <float>,\n * dashed: <boolean>,\n * dashScale: <float>,\n * dashSize: <float>,\n * dashOffset: <float>,\n * gapSize: <float>,\n * resolution: <Vector2>, // to be set by renderer\n * }\n */\n\nimport { ShaderMaterial, UniformsLib, UniformsUtils, Vector2, REVISION } from 'three'\n\nclass LineMaterial extends ShaderMaterial {\n constructor(parameters) {\n super({\n type: 'LineMaterial',\n\n uniforms: UniformsUtils.clone(\n UniformsUtils.merge([\n UniformsLib.common,\n UniformsLib.fog,\n {\n worldUnits: { value: 1 },\n linewidth: { value: 1 },\n resolution: { value: new Vector2(1, 1) },\n dashOffset: { value: 0 },\n dashScale: { value: 1 },\n dashSize: { value: 1 },\n gapSize: { value: 1 }, // todo FIX - maybe change to totalSize\n },\n ]),\n ),\n\n vertexShader: /* glsl */ `\n\t\t\t\t#include <common>\n\t\t\t\t#include <fog_pars_vertex>\n\t\t\t\t#include <logdepthbuf_pars_vertex>\n\t\t\t\t#include <clipping_planes_pars_vertex>\n\n\t\t\t\tuniform float linewidth;\n\t\t\t\tuniform vec2 resolution;\n\n\t\t\t\tattribute vec3 instanceStart;\n\t\t\t\tattribute vec3 instanceEnd;\n\n\t\t\t\t#ifdef USE_COLOR\n\t\t\t\t\t#ifdef USE_LINE_COLOR_ALPHA\n\t\t\t\t\t\tvarying vec4 vLineColor;\n\t\t\t\t\t\tattribute vec4 instanceColorStart;\n\t\t\t\t\t\tattribute vec4 instanceColorEnd;\n\t\t\t\t\t#else\n\t\t\t\t\t\tvarying vec3 vLineColor;\n\t\t\t\t\t\tattribute vec3 instanceColorStart;\n\t\t\t\t\t\tattribute vec3 instanceColorEnd;\n\t\t\t\t\t#endif\n\t\t\t\t#endif\n\n\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\tvarying vec4 worldPos;\n\t\t\t\t\tvarying vec3 worldStart;\n\t\t\t\t\tvarying vec3 worldEnd;\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t#else\n\n\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t#endif\n\n\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\tuniform float dashScale;\n\t\t\t\t\tattribute float instanceDistanceStart;\n\t\t\t\t\tattribute float instanceDistanceEnd;\n\t\t\t\t\tvarying float vLineDistance;\n\n\t\t\t\t#endif\n\n\t\t\t\tvoid trimSegment( const in vec4 start, inout vec4 end ) {\n\n\t\t\t\t\t// trim end segment so it terminates between the camera plane and the near plane\n\n\t\t\t\t\t// conservative estimate of the near plane\n\t\t\t\t\tfloat a = projectionMatrix[ 2 ][ 2 ]; // 3nd entry in 3th column\n\t\t\t\t\tfloat b = projectionMatrix[ 3 ][ 2 ]; // 3nd entry in 4th column\n\t\t\t\t\tfloat nearEstimate = - 0.5 * b / a;\n\n\t\t\t\t\tfloat alpha = ( nearEstimate - start.z ) / ( end.z - start.z );\n\n\t\t\t\t\tend.xyz = mix( start.xyz, end.xyz, alpha );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\t#ifdef USE_COLOR\n\n\t\t\t\t\t\tvLineColor = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tvLineDistance = ( position.y < 0.5 ) ? dashScale * instanceDistanceStart : dashScale * instanceDistanceEnd;\n\t\t\t\t\t\tvUv = uv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tfloat aspect = resolution.x / resolution.y;\n\n\t\t\t\t\t// camera space\n\t\t\t\t\tvec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );\n\t\t\t\t\tvec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );\n\n\t\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\t\tworldStart = start.xyz;\n\t\t\t\t\t\tworldEnd = end.xyz;\n\n\t\t\t\t\t#else\n\n\t\t\t\t\t\tvUv = uv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\t// special case for perspective projection, and segments that terminate either in, or behind, the camera plane\n\t\t\t\t\t// clearly the gpu firmware has a way of addressing this issue when projecting into ndc space\n\t\t\t\t\t// but we need to perform ndc-space calculations in the shader, so we must address this issue directly\n\t\t\t\t\t// perhaps there is a more elegant solution -- WestLangley\n\n\t\t\t\t\tbool perspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 ); // 4th entry in the 3rd column\n\n\t\t\t\t\tif ( perspective ) {\n\n\t\t\t\t\t\tif ( start.z < 0.0 && end.z >= 0.0 ) {\n\n\t\t\t\t\t\t\ttrimSegment( start, end );\n\n\t\t\t\t\t\t} else if ( end.z < 0.0 && start.z >= 0.0 ) {\n\n\t\t\t\t\t\t\ttrimSegment( end, start );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// clip space\n\t\t\t\t\tvec4 clipStart = projectionMatrix * start;\n\t\t\t\t\tvec4 clipEnd = projectionMatrix * end;\n\n\t\t\t\t\t// ndc space\n\t\t\t\t\tvec3 ndcStart = clipStart.xyz / clipStart.w;\n\t\t\t\t\tvec3 ndcEnd = clipEnd.xyz / clipEnd.w;\n\n\t\t\t\t\t// direction\n\t\t\t\t\tvec2 dir = ndcEnd.xy - ndcStart.xy;\n\n\t\t\t\t\t// account for clip-space aspect ratio\n\t\t\t\t\tdir.x *= aspect;\n\t\t\t\t\tdir = normalize( dir );\n\n\t\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\t\t// get the offset direction as perpendicular to the view vector\n\t\t\t\t\t\tvec3 worldDir = normalize( end.xyz - start.xyz );\n\t\t\t\t\t\tvec3 offset;\n\t\t\t\t\t\tif ( position.y < 0.5 ) {\n\n\t\t\t\t\t\t\toffset = normalize( cross( start.xyz, worldDir ) );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\toffset = normalize( cross( end.xyz, worldDir ) );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// sign flip\n\t\t\t\t\t\tif ( position.x < 0.0 ) offset *= - 1.0;\n\n\t\t\t\t\t\tfloat forwardOffset = dot( worldDir, vec3( 0.0, 0.0, 1.0 ) );\n\n\t\t\t\t\t\t// don't extend the line if we're rendering dashes because we\n\t\t\t\t\t\t// won't be rendering the endcaps\n\t\t\t\t\t\t#ifndef USE_DASH\n\n\t\t\t\t\t\t\t// extend the line bounds to encompass endcaps\n\t\t\t\t\t\t\tstart.xyz += - worldDir * linewidth * 0.5;\n\t\t\t\t\t\t\tend.xyz += worldDir * linewidth * 0.5;\n\n\t\t\t\t\t\t\t// shift the position of the quad so it hugs the forward edge of the line\n\t\t\t\t\t\t\toffset.xy -= dir * forwardOffset;\n\t\t\t\t\t\t\toffset.z += 0.5;\n\n\t\t\t\t\t\t#endif\n\n\t\t\t\t\t\t// endcaps\n\t\t\t\t\t\tif ( position.y > 1.0 || position.y < 0.0 ) {\n\n\t\t\t\t\t\t\toffset.xy += dir * 2.0 * forwardOffset;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// adjust for linewidth\n\t\t\t\t\t\toffset *= linewidth * 0.5;\n\n\t\t\t\t\t\t// set the world position\n\t\t\t\t\t\tworldPos = ( position.y < 0.5 ) ? start : end;\n\t\t\t\t\t\tworldPos.xyz += offset;\n\n\t\t\t\t\t\t// project the worldpos\n\t\t\t\t\t\tvec4 clip = projectionMatrix * worldPos;\n\n\t\t\t\t\t\t// shift the depth of the projected points so the line\n\t\t\t\t\t\t// segments overlap neatly\n\t\t\t\t\t\tvec3 clipPose = ( position.y < 0.5 ) ? ndcStart : ndcEnd;\n\t\t\t\t\t\tclip.z = clipPose.z * clip.w;\n\n\t\t\t\t\t#else\n\n\t\t\t\t\t\tvec2 offset = vec2( dir.y, - dir.x );\n\t\t\t\t\t\t// undo aspect ratio adjustment\n\t\t\t\t\t\tdir.x /= aspect;\n\t\t\t\t\t\toffset.x /= aspect;\n\n\t\t\t\t\t\t// sign flip\n\t\t\t\t\t\tif ( position.x < 0.0 ) offset *= - 1.0;\n\n\t\t\t\t\t\t// endcaps\n\t\t\t\t\t\tif ( position.y < 0.0 ) {\n\n\t\t\t\t\t\t\toffset += - dir;\n\n\t\t\t\t\t\t} else if ( position.y > 1.0 ) {\n\n\t\t\t\t\t\t\toffset += dir;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// adjust for linewidth\n\t\t\t\t\t\toffset *= linewidth;\n\n\t\t\t\t\t\t// adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...\n\t\t\t\t\t\toffset /= resolution.y;\n\n\t\t\t\t\t\t// select end\n\t\t\t\t\t\tvec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;\n\n\t\t\t\t\t\t// back to clip space\n\t\t\t\t\t\toffset *= clip.w;\n\n\t\t\t\t\t\tclip.xy += offset;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tgl_Position = clip;\n\n\t\t\t\t\tvec4 mvPosition = ( position.y < 0.5 ) ? start : end; // this is an approximation\n\n\t\t\t\t\t#include <logdepthbuf_vertex>\n\t\t\t\t\t#include <clipping_planes_vertex>\n\t\t\t\t\t#include <fog_vertex>\n\n\t\t\t\t}\n\t\t\t`,\n fragmentShader: /* glsl */ `\n\t\t\t\tuniform vec3 diffuse;\n\t\t\t\tuniform float opacity;\n\t\t\t\tuniform float linewidth;\n\n\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\tuniform float dashOffset;\n\t\t\t\t\tuniform float dashSize;\n\t\t\t\t\tuniform float gapSize;\n\n\t\t\t\t#endif\n\n\t\t\t\tvarying float vLineDistance;\n\n\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\tvarying vec4 worldPos;\n\t\t\t\t\tvarying vec3 worldStart;\n\t\t\t\t\tvarying vec3 worldEnd;\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t\t#endif\n\n\t\t\t\t#else\n\n\t\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\t#endif\n\n\t\t\t\t#include <common>\n\t\t\t\t#include <fog_pars_fragment>\n\t\t\t\t#include <logdepthbuf_pars_fragment>\n\t\t\t\t#include <clipping_planes_pars_fragment>\n\n\t\t\t\t#ifdef USE_COLOR\n\t\t\t\t\t#ifdef USE_LINE_COLOR_ALPHA\n\t\t\t\t\t\tvarying vec4 vLineColor;\n\t\t\t\t\t#else\n\t\t\t\t\t\tvarying vec3 vLineColor;\n\t\t\t\t\t#endif\n\t\t\t\t#endif\n\n\t\t\t\tvec2 closestLineToLine(vec3 p1, vec3 p2, vec3 p3, vec3 p4) {\n\n\t\t\t\t\tfloat mua;\n\t\t\t\t\tfloat mub;\n\n\t\t\t\t\tvec3 p13 = p1 - p3;\n\t\t\t\t\tvec3 p43 = p4 - p3;\n\n\t\t\t\t\tvec3 p21 = p2 - p1;\n\n\t\t\t\t\tfloat d1343 = dot( p13, p43 );\n\t\t\t\t\tfloat d4321 = dot( p43, p21 );\n\t\t\t\t\tfloat d1321 = dot( p13, p21 );\n\t\t\t\t\tfloat d4343 = dot( p43, p43 );\n\t\t\t\t\tfloat d2121 = dot( p21, p21 );\n\n\t\t\t\t\tfloat denom = d2121 * d4343 - d4321 * d4321;\n\n\t\t\t\t\tfloat numer = d1343 * d4321 - d1321 * d4343;\n\n\t\t\t\t\tmua = numer / denom;\n\t\t\t\t\tmua = clamp( mua, 0.0, 1.0 );\n\t\t\t\t\tmub = ( d1343 + d4321 * ( mua ) ) / d4343;\n\t\t\t\t\tmub = clamp( mub, 0.0, 1.0 );\n\n\t\t\t\t\treturn vec2( mua, mub );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\t#include <clipping_planes_fragment>\n\n\t\t\t\t\t#ifdef USE_DASH\n\n\t\t\t\t\t\tif ( vUv.y < - 1.0 || vUv.y > 1.0 ) discard; // discard endcaps\n\n\t\t\t\t\t\tif ( mod( vLineDistance + dashOffset, dashSize + gapSize ) > dashSize ) discard; // todo - FIX\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tfloat alpha = opacity;\n\n\t\t\t\t\t#ifdef WORLD_UNITS\n\n\t\t\t\t\t\t// Find the closest points on the view ray and the line segment\n\t\t\t\t\t\tvec3 rayEnd = normalize( worldPos.xyz ) * 1e5;\n\t\t\t\t\t\tvec3 lineDir = worldEnd - worldStart;\n\t\t\t\t\t\tvec2 params = closestLineToLine( worldStart, worldEnd, vec3( 0.0, 0.0, 0.0 ), rayEnd );\n\n\t\t\t\t\t\tvec3 p1 = worldStart + lineDir * params.x;\n\t\t\t\t\t\tvec3 p2 = rayEnd * params.y;\n\t\t\t\t\t\tvec3 delta = p1 - p2;\n\t\t\t\t\t\tfloat len = length( delta );\n\t\t\t\t\t\tfloat norm = len / linewidth;\n\n\t\t\t\t\t\t#ifndef USE_DASH\n\n\t\t\t\t\t\t\t#ifdef USE_ALPHA_TO_COVERAGE\n\n\t\t\t\t\t\t\t\tfloat dnorm = fwidth( norm );\n\t\t\t\t\t\t\t\talpha = 1.0 - smoothstep( 0.5 - dnorm, 0.5 + dnorm, norm );\n\n\t\t\t\t\t\t\t#else\n\n\t\t\t\t\t\t\t\tif ( norm > 0.5 ) {\n\n\t\t\t\t\t\t\t\t\tdiscard;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t#endif\n\n\t\t\t\t\t\t#endif\n\n\t\t\t\t\t#else\n\n\t\t\t\t\t\t#ifdef USE_ALPHA_TO_COVERAGE\n\n\t\t\t\t\t\t\t// artifacts appear on some hardware if a derivative is taken within a conditional\n\t\t\t\t\t\t\tfloat a = vUv.x;\n\t\t\t\t\t\t\tfloat b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;\n\t\t\t\t\t\t\tfloat len2 = a * a + b * b;\n\t\t\t\t\t\t\tfloat dlen = fwidth( len2 );\n\n\t\t\t\t\t\t\tif ( abs( vUv.y ) > 1.0 ) {\n\n\t\t\t\t\t\t\t\talpha = 1.0 - smoothstep( 1.0 - dlen, 1.0 + dlen, len2 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t#else\n\n\t\t\t\t\t\t\tif ( abs( vUv.y ) > 1.0 ) {\n\n\t\t\t\t\t\t\t\tfloat a = vUv.x;\n\t\t\t\t\t\t\t\tfloat b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;\n\t\t\t\t\t\t\t\tfloat len2 = a * a + b * b;\n\n\t\t\t\t\t\t\t\tif ( len2 > 1.0 ) discard;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t#endif\n\n\t\t\t\t\t#endif\n\n\t\t\t\t\tvec4 diffuseColor = vec4( diffuse, alpha );\n\t\t\t\t\t#ifdef USE_COLOR\n\t\t\t\t\t\t#ifdef USE_LINE_COLOR_ALPHA\n\t\t\t\t\t\t\tdiffuseColor *= vLineColor;\n\t\t\t\t\t\t#else\n\t\t\t\t\t\t\tdiffuseColor.rgb *= vLineColor;\n\t\t\t\t\t\t#endif\n\t\t\t\t\t#endif\n\n\t\t\t\t\t#include <logdepthbuf_fragment>\n\n\t\t\t\t\tgl_FragColor = diffuseColor;\n\n\t\t\t\t\t#include <tonemapping_fragment>\n\t\t\t\t\t#include <${parseInt(REVISION.replace(/\\D+/g, '')) >= 154 ? 'colorspace_fragment' : 'encodings_fragment'}>\n\t\t\t\t\t#include <fog_fragment>\n\t\t\t\t\t#include <premultiplied_alpha_fragment>\n\n\t\t\t\t}\n\t\t\t`,\n clipping: true, // required for clipping support\n })\n\n this.isLineMaterial = true\n\n this.onBeforeCompile = function () {\n if (this.transparent) {\n this.defines.USE_LINE_COLOR_ALPHA = '1'\n } else {\n delete this.defines.USE_LINE_COLOR_ALPHA\n }\n }\n\n Object.defineProperties(this, {\n color: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.diffuse.value\n },\n\n set: function (value) {\n this.uniforms.diffuse.value = value\n },\n },\n\n worldUnits: {\n enumerable: true,\n\n get: function () {\n return 'WORLD_UNITS' in this.defines\n },\n\n set: function (value) {\n if (value === true) {\n this.defines.WORLD_UNITS = ''\n } else {\n delete this.defines.WORLD_UNITS\n }\n },\n },\n\n linewidth: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.linewidth.value\n },\n\n set: function (value) {\n this.uniforms.linewidth.value = value\n },\n },\n\n dashed: {\n enumerable: true,\n\n get: function () {\n return Boolean('USE_DASH' in this.defines)\n },\n\n set(value) {\n if (Boolean(value) !== Boolean('USE_DASH' in this.defines)) {\n this.needsUpdate = true\n }\n\n if (value === true) {\n this.defines.USE_DASH = ''\n } else {\n delete this.defines.USE_DASH\n }\n },\n },\n\n dashScale: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.dashScale.value\n },\n\n set: function (value) {\n this.uniforms.dashScale.value = value\n },\n },\n\n dashSize: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.dashSize.value\n },\n\n set: function (value) {\n this.uniforms.dashSize.value = value\n },\n },\n\n dashOffset: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.dashOffset.value\n },\n\n set: function (value) {\n this.uniforms.dashOffset.value = value\n },\n },\n\n gapSize: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.gapSize.value\n },\n\n set: function (value) {\n this.uniforms.gapSize.value = value\n },\n },\n\n opacity: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.opacity.value\n },\n\n set: function (value) {\n this.uniforms.opacity.value = value\n },\n },\n\n resolution: {\n enumerable: true,\n\n get: function () {\n return this.uniforms.resolution.value\n },\n\n set: function (value) {\n this.uniforms.resolution.value.copy(value)\n },\n },\n\n alphaToCoverage: {\n enumerable: true,\n\n get: function () {\n return Boolean('USE_ALPHA_TO_COVERAGE' in this.defines)\n },\n\n set: function (value) {\n if (Boolean(value) !== Boolean('USE_ALPHA_TO_COVERAGE' in this.defines)) {\n this.needsUpdate = true\n }\n\n if (value === true) {\n this.defines.USE_ALPHA_TO_COVERAGE = ''\n this.extensions.derivatives = true\n } else {\n delete this.defines.USE_ALPHA_TO_COVERAGE\n this.extensions.derivatives = false\n }\n },\n },\n })\n\n this.setValues(parameters)\n }\n}\n\nexport { LineMaterial }\n"],"names":[],"mappings":";AAeA,MAAM,qBAAqB,eAAe;AAAA,EACxC,YAAY,YAAY;AACtB,UAAM;AAAA,MACJ,MAAM;AAAA,MAEN,UAAU,cAAc;AAAA,QACtB,cAAc,MAAM;AAAA,UAClB,YAAY;AAAA,UACZ,YAAY;AAAA,UACZ;AAAA,YACE,YAAY,EAAE,OAAO,EAAG;AAAA,YACxB,WAAW,EAAE,OAAO,EAAG;AAAA,YACvB,YAAY,EAAE,OAAO,IAAI,QAAQ,GAAG,CAAC,EAAG;AAAA,YACxC,YAAY,EAAE,OAAO,EAAG;AAAA,YACxB,WAAW,EAAE,OAAO,EAAG;AAAA,YACvB,UAAU,EAAE,OAAO,EAAG;AAAA,YACtB,SAAS,EAAE,OAAO,EAAG;AAAA;AAAA,UACtB;AAAA,QACX,CAAS;AAAA,MACF;AAAA,MAED;AAAA;AAAA,QAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MA6OzB;AAAA;AAAA,QAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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"}
|