@ccp-nc/crystvis-js 0.4.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +16 -0
- package/.github/workflows/test-mocha.yml +30 -0
- package/.vscode/settings.json +4 -0
- package/LICENSE +21 -0
- package/README.html +1127 -0
- package/README.md +76 -0
- package/demo/demo.css +30 -0
- package/demo/index.html +76 -0
- package/demo/main.js +143 -0
- package/docs/.nojekyll +0 -0
- package/docs-tutorials/Events.md +57 -0
- package/docs-tutorials/Queries.md +50 -0
- package/fonts/Rubik/OFL.txt +93 -0
- package/fonts/Rubik/README.txt +77 -0
- package/fonts/Rubik/Rubik-Italic-VariableFont_wght.ttf +0 -0
- package/fonts/Rubik/Rubik-VariableFont_wght.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Black.ttf +0 -0
- package/fonts/Rubik/static/Rubik-BlackItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Bold.ttf +0 -0
- package/fonts/Rubik/static/Rubik-BoldItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-ExtraBold.ttf +0 -0
- package/fonts/Rubik/static/Rubik-ExtraBoldItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Italic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Light.ttf +0 -0
- package/fonts/Rubik/static/Rubik-LightItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Medium.ttf +0 -0
- package/fonts/Rubik/static/Rubik-MediumItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Regular.ttf +0 -0
- package/fonts/Rubik/static/Rubik-SemiBold.ttf +0 -0
- package/fonts/Rubik/static/Rubik-SemiBoldItalic.ttf +0 -0
- package/index.html +25 -0
- package/index.js +11 -0
- package/jsconf.json +14 -0
- package/lib/assets/fonts/Rubik-Medium.fnt +297 -0
- package/lib/assets/fonts/Rubik-Medium.png +0 -0
- package/lib/assets/fonts/bmpfonts.in.js +16 -0
- package/lib/assets/fonts/bmpfonts.js +9 -0
- package/lib/assets/fonts/font.js +82 -0
- package/lib/assets/fonts/index.js +14 -0
- package/lib/assets/fonts/threebmfont.js +28 -0
- package/lib/data.js +125 -0
- package/lib/formats/cell.js +114 -0
- package/lib/formats/cif.js +22 -0
- package/lib/formats/magres.js +337 -0
- package/lib/formats/xyz.js +124 -0
- package/lib/loader.js +87 -0
- package/lib/model.js +2076 -0
- package/lib/modelview.js +382 -0
- package/lib/nmrdata.js +2898 -0
- package/lib/orbit.js +1233 -0
- package/lib/primitives/atoms.js +261 -0
- package/lib/primitives/cell.js +160 -0
- package/lib/primitives/dither.js +156 -0
- package/lib/primitives/ellipsoid.js +183 -0
- package/lib/primitives/geometries.js +20 -0
- package/lib/primitives/index.js +48 -0
- package/lib/primitives/isosurface.js +171 -0
- package/lib/primitives/shapes.js +100 -0
- package/lib/primitives/sprites.js +172 -0
- package/lib/query.js +158 -0
- package/lib/render.js +440 -0
- package/lib/selbox.js +361 -0
- package/lib/shaders/aura.frag +26 -0
- package/lib/shaders/aura.vert +37 -0
- package/lib/shaders/dither.frag +42 -0
- package/lib/shaders/dither.vert +8 -0
- package/lib/shaders/index.in.js +17 -0
- package/lib/shaders/index.js +25 -0
- package/lib/shaders/msdf300.frag +25 -0
- package/lib/shaders/msdf300.vert +45 -0
- package/lib/tensor.js +227 -0
- package/lib/utils.js +168 -0
- package/lib/visualizer.js +480 -0
- package/package.json +106 -0
- package/scripts/build-bundle.js +17 -0
- package/scripts/build-fonts.js +43 -0
- package/scripts/build-resources.js +46 -0
- package/scripts/plugins-shim.js +10 -0
- package/test/chemdata.js +69 -0
- package/test/data/CHA.cif +74 -0
- package/test/data/H2O.xyz +8 -0
- package/test/data/H2_bound.xyz +4 -0
- package/test/data/ethanol.cell +25 -0
- package/test/data/ethanol.magres +238 -0
- package/test/data/example_single.cif +789 -0
- package/test/data/frac.cell +8 -0
- package/test/data/org.cif +427 -0
- package/test/data/pyridine.xyz +13 -0
- package/test/data/si8.xyz +10 -0
- package/test/loader.js +107 -0
- package/test/model.js +368 -0
- package/test/query.js +135 -0
- package/test/tensor.js +133 -0
- package/test/test-html/examples.js +1485 -0
- package/test/test-html/index.html +33 -0
- package/test/test-html/index.js +279 -0
- package/tools/compile_colors.py +120 -0
- package/tools/compile_periodic.py +96 -0
- package/tools/ptable.json +497 -0
- package/tools/test +5844 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Classes for Atom and Bond primitives
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import _ from 'lodash';
|
|
8
|
+
import * as THREE from 'three';
|
|
9
|
+
import {
|
|
10
|
+
unitSphere,
|
|
11
|
+
unitCylinder,
|
|
12
|
+
unitCircle
|
|
13
|
+
} from './geometries.js';
|
|
14
|
+
import * as Shaders from '../shaders/index.js';
|
|
15
|
+
|
|
16
|
+
// Basic materials
|
|
17
|
+
const _phong = new THREE.MeshPhongMaterial({});
|
|
18
|
+
|
|
19
|
+
class AtomMesh extends THREE.Mesh {
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Constructor for the AtomMesh object
|
|
23
|
+
*
|
|
24
|
+
* @param {Array} position Position of the atom
|
|
25
|
+
* @param {Number} radius Radius of the atom
|
|
26
|
+
* @param {Number} color Color of the atom (hex number)
|
|
27
|
+
*/
|
|
28
|
+
constructor(position, radius = 1, color = 0xffffff) {
|
|
29
|
+
|
|
30
|
+
var mat = _phong.clone();
|
|
31
|
+
mat.color = new THREE.Color(color);
|
|
32
|
+
|
|
33
|
+
super(unitSphere, mat);
|
|
34
|
+
|
|
35
|
+
this.scale.set(radius, radius, radius);
|
|
36
|
+
this.position.set(position[0], position[1], position[2]);
|
|
37
|
+
this.image = null;
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get atom_radius() {
|
|
42
|
+
return this.geometry.parameters.radius * this.scale.x;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
set atom_radius(r) {
|
|
46
|
+
var s = r / this.geometry.parameters.radius;
|
|
47
|
+
this.scale.set(s, s, s);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get atom_color() {
|
|
51
|
+
return this.material.color.getHex();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
set atom_color(c) {
|
|
55
|
+
this.material.color = new THREE.Color(c);
|
|
56
|
+
this.needsUpdate = true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
get atom_opacity() {
|
|
60
|
+
return this.material.opacity;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
set atom_opacity(o) {
|
|
64
|
+
this.material.transparent = (o < 1);
|
|
65
|
+
this.material.opacity = o;
|
|
66
|
+
this.needsUpdate = true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
class BondMesh extends THREE.Group {
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Constructor for the BondMesh object
|
|
75
|
+
*
|
|
76
|
+
* @param {Array} p0 Position of the first atom
|
|
77
|
+
* @param {Array} p1 Position of the second atom
|
|
78
|
+
* @param {Number} radius Radius of the bond
|
|
79
|
+
* @param {Number} color0 Color of the first atom (hex number)
|
|
80
|
+
* @param {Number} color1 Color of the second atom (hex number)
|
|
81
|
+
*/
|
|
82
|
+
constructor(p0, p1, radius = 1, color0 = 0xff0000, color1 = 0x00ff00) {
|
|
83
|
+
|
|
84
|
+
super();
|
|
85
|
+
|
|
86
|
+
p0 = new THREE.Vector3(p0[0], p0[1], p0[2]);
|
|
87
|
+
p1 = new THREE.Vector3(p1[0], p1[1], p1[2]);
|
|
88
|
+
|
|
89
|
+
var dp = p1.clone();
|
|
90
|
+
dp.sub(p0);
|
|
91
|
+
var l = dp.length();
|
|
92
|
+
|
|
93
|
+
// Halfpoint?
|
|
94
|
+
var hv = p0.clone();
|
|
95
|
+
hv.addScaledVector(dp, 0.5);
|
|
96
|
+
|
|
97
|
+
var rmat = new THREE.Matrix4();
|
|
98
|
+
rmat.lookAt(p0, p1, new THREE.Vector3(0, 0, 1));
|
|
99
|
+
|
|
100
|
+
var mat0 = _phong.clone();
|
|
101
|
+
mat0.color = new THREE.Color(color0);
|
|
102
|
+
var mat1 = _phong.clone();
|
|
103
|
+
mat1.color = new THREE.Color(color1);
|
|
104
|
+
|
|
105
|
+
var bond0 = new THREE.Mesh(unitCylinder, mat0);
|
|
106
|
+
bond0.scale.set(radius, radius, l / 2.0);
|
|
107
|
+
bond0.position.copy(p0.clone().addScaledVector(dp, 0.25));
|
|
108
|
+
bond0.setRotationFromMatrix(rmat);
|
|
109
|
+
var bond1 = new THREE.Mesh(unitCylinder, mat1);
|
|
110
|
+
bond1.scale.set(radius, radius, l / 2.0);
|
|
111
|
+
bond1.position.copy(p1.clone().addScaledVector(dp, -0.25));
|
|
112
|
+
bond1.setRotationFromMatrix(rmat);
|
|
113
|
+
|
|
114
|
+
this.add(bond0);
|
|
115
|
+
this.add(bond1);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
get bond_radius() {
|
|
119
|
+
return this.children[0].geometry.parameters.radiusTop * this.children[0].scale.x;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
set bond_radius(r) {
|
|
123
|
+
var r0 = this.children[0].geometry.parameters.radiusTop;
|
|
124
|
+
var s = r / r0;
|
|
125
|
+
var z = this.children[0].scale.z;
|
|
126
|
+
this.children[0].scale.set(s, s, z);
|
|
127
|
+
this.children[1].scale.set(s, s, z);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
get bond_color_1() {
|
|
131
|
+
return this.children[0].material.color.getHex();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
set bond_color_1(c) {
|
|
135
|
+
this.children[0].material.color = new THREE.Color(c);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
get bond_color_2() {
|
|
139
|
+
return this.children[1].material.color.getHex();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
set bond_color_2(c) {
|
|
143
|
+
this.children[1].material.color = new THREE.Color(c);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
get bond_opacity_1() {
|
|
147
|
+
return this.children[0].material.opacity;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
set bond_opacity_1(o) {
|
|
151
|
+
this.children[0].material.transparent = (o < 1);
|
|
152
|
+
this.children[0].material.opacity = o;
|
|
153
|
+
this.children[0].material.needsUpdate = true;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
get bond_opacity_2() {
|
|
157
|
+
return this.children[1].material.opacity;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
set bond_opacity_2(o) {
|
|
161
|
+
this.children[1].material.transparent = (o < 1);
|
|
162
|
+
this.children[1].material.opacity = o;
|
|
163
|
+
this.children[1].material.needsUpdate = true;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
class AuraMesh extends THREE.Mesh {
|
|
169
|
+
|
|
170
|
+
constructor(parameters = {}) {
|
|
171
|
+
|
|
172
|
+
var defaults = {
|
|
173
|
+
scale: 1,
|
|
174
|
+
radius: 1,
|
|
175
|
+
fill: 0xaaaa00,
|
|
176
|
+
border: 0xffff00,
|
|
177
|
+
opacity: 0.5,
|
|
178
|
+
borderFraction: 0.08
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
parameters = _.merge(defaults, parameters);
|
|
182
|
+
|
|
183
|
+
var mat = new THREE.RawShaderMaterial({
|
|
184
|
+
uniforms: {
|
|
185
|
+
targScale: new THREE.Uniform(parameters.scale),
|
|
186
|
+
targRadius: new THREE.Uniform(parameters.radius),
|
|
187
|
+
fill: new THREE.Uniform(new THREE.Color(parameters.fill)),
|
|
188
|
+
border: new THREE.Uniform(new THREE.Color(parameters.border)),
|
|
189
|
+
border_f: new THREE.Uniform(parameters.borderFraction),
|
|
190
|
+
opacity: new THREE.Uniform(parameters.opacity)
|
|
191
|
+
},
|
|
192
|
+
side: THREE.DoubleSide,
|
|
193
|
+
transparent: true,
|
|
194
|
+
vertexShader: Shaders.auraVertShader,
|
|
195
|
+
fragmentShader: Shaders.auraFragShader
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
super(unitCircle, mat);
|
|
199
|
+
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
get scale() {
|
|
203
|
+
return this.material.uniforms.targScale.value;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
set scale(s) {
|
|
207
|
+
this.material.uniforms.targScale.value = s;
|
|
208
|
+
this.material.uniformsNeedUpdate = true;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
get radius() {
|
|
212
|
+
return this.material.uniforms.targRadius.value;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
set radius(r) {
|
|
216
|
+
this.material.uniforms.targRadius.value = r;
|
|
217
|
+
this.material.uniformsNeedUpdate = true;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
get fill() {
|
|
221
|
+
return this.material.uniforms.fill.value.getHex();
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
set fill(c) {
|
|
225
|
+
this.material.uniforms.fill.value = new THREE.Color(c);
|
|
226
|
+
this.material.uniformsNeedUpdate = true;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
get border() {
|
|
230
|
+
return this.material.uniforms.border.value.getHex();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
set border(c) {
|
|
234
|
+
this.material.uniforms.border.value = new THREE.Color(c);
|
|
235
|
+
this.material.uniformsNeedUpdate = true;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
get borderFraction() {
|
|
239
|
+
return this.material.uniforms.border_f.value;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
set borderFraction(f) {
|
|
243
|
+
this.material.uniforms.border_f.value = f;
|
|
244
|
+
this.material.uniformsNeedUpdate = true;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
get opacity() {
|
|
248
|
+
return this.material.uniforms.opacity.value;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
set opacity(o) {
|
|
252
|
+
this.material.uniforms.opacity.value = o;
|
|
253
|
+
this.material.uniformsNeedUpdate = true;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export {
|
|
258
|
+
AtomMesh,
|
|
259
|
+
BondMesh,
|
|
260
|
+
AuraMesh
|
|
261
|
+
};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Classes for lattice box primitives
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import _ from 'lodash';
|
|
8
|
+
import * as THREE from 'three';
|
|
9
|
+
import { Vector3 } from 'three';
|
|
10
|
+
import { cellMatrix3 } from '../utils.js';
|
|
11
|
+
|
|
12
|
+
// Cell box
|
|
13
|
+
class BoxMesh extends THREE.LineSegments {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Constructor for BoxMesh primitive
|
|
17
|
+
*
|
|
18
|
+
* @param {Array} lattice Lattice parameters for the unit cell
|
|
19
|
+
* @param {Object} parameters Options:
|
|
20
|
+
* color
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
23
|
+
constructor(lattice, parameters = {}) {
|
|
24
|
+
|
|
25
|
+
const defaults = {
|
|
26
|
+
color: 0xffffff,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
parameters = _.merge(defaults, parameters);
|
|
30
|
+
|
|
31
|
+
if (lattice instanceof Array) {
|
|
32
|
+
lattice = cellMatrix3(lattice);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
var boxGeom = new THREE.BoxGeometry(1, 1, 1);
|
|
36
|
+
boxGeom = new THREE.EdgesGeometry(boxGeom); // Convert to wireframe
|
|
37
|
+
|
|
38
|
+
var boxMat = new THREE.LineBasicMaterial({
|
|
39
|
+
color: parameters.color,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
super(boxGeom, boxMat);
|
|
43
|
+
|
|
44
|
+
// Set the actual lattice basis
|
|
45
|
+
this.matrix.setFromMatrix3(lattice);
|
|
46
|
+
this.matrix.setPosition( (new Vector3(0.5, 0.5, 0.5)).applyMatrix3(lattice) );
|
|
47
|
+
this.matrixAutoUpdate = false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get color() {
|
|
51
|
+
return this.material.color.getHex();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
set color(c) {
|
|
55
|
+
this.material.color = new THREE.Color(c);
|
|
56
|
+
this.needsUpdate = true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Arrows for axes
|
|
63
|
+
class AxesMesh extends THREE.Group {
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Constructor for AxesMesh primitive
|
|
67
|
+
*
|
|
68
|
+
* @param {Array} lattice Lattice parameters for the unit cell
|
|
69
|
+
* @param {Object} parameters Options:
|
|
70
|
+
* linewidth
|
|
71
|
+
* xColor
|
|
72
|
+
* yColor
|
|
73
|
+
* zColor
|
|
74
|
+
*
|
|
75
|
+
*/
|
|
76
|
+
constructor(lattice, parameters = {}) {
|
|
77
|
+
|
|
78
|
+
var defaults = {
|
|
79
|
+
linewidth: 1.2,
|
|
80
|
+
xColor: 0xff0000,
|
|
81
|
+
yColor: 0x00ff00,
|
|
82
|
+
zColor: 0x0000ff
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
parameters = _.merge(defaults, parameters);
|
|
86
|
+
|
|
87
|
+
super();
|
|
88
|
+
|
|
89
|
+
if (lattice instanceof Array) {
|
|
90
|
+
var lc = lattice;
|
|
91
|
+
lattice = new THREE.Matrix3();
|
|
92
|
+
lattice.set(lc[0][0], lc[1][0], lc[2][0],
|
|
93
|
+
lc[0][1], lc[1][1], lc[2][1],
|
|
94
|
+
lc[0][2], lc[1][2], lc[2][2]);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
var origin = new THREE.Vector3(0, 0, 0);
|
|
98
|
+
var elems = lattice.elements;
|
|
99
|
+
|
|
100
|
+
var colors = [
|
|
101
|
+
parameters.xColor,
|
|
102
|
+
parameters.yColor,
|
|
103
|
+
parameters.zColor
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
for (var i = 0; i < 3; ++i) {
|
|
107
|
+
var dir = new THREE.Vector3(elems[3 * i],
|
|
108
|
+
elems[3 * i + 1],
|
|
109
|
+
elems[3 * i + 2]);
|
|
110
|
+
var l = dir.length() / 3.0;
|
|
111
|
+
dir.normalize();
|
|
112
|
+
var arr = new THREE.ArrowHelper(dir, origin, l, colors[i]);
|
|
113
|
+
arr.line.material.linewidth = parameters.linewidth;
|
|
114
|
+
this.add(arr);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
get xColor() {
|
|
119
|
+
return this.children[0].line.material.color.getHex();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
set xColor(c) {
|
|
123
|
+
this.children[0].line.material.color = new THREE.Color(c);
|
|
124
|
+
this.children[0].cone.material.color = new THREE.Color(c);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
get yColor() {
|
|
128
|
+
return this.children[1].line.material.color.getHex();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
set yColor(c) {
|
|
132
|
+
this.children[1].line.material.color = new THREE.Color(c);
|
|
133
|
+
this.children[1].cone.material.color = new THREE.Color(c);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
get zColor() {
|
|
137
|
+
return this.children[2].line.material.color.getHex();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
set zColor(c) {
|
|
141
|
+
this.children[2].line.material.color = new THREE.Color(c);
|
|
142
|
+
this.children[2].cone.material.color = new THREE.Color(c);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
get linewidth() {
|
|
146
|
+
return this.children[0].line.material.linewidth;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
set linewidth(lw) {
|
|
150
|
+
for (var i = 0; i < 3; ++i) {
|
|
151
|
+
this.children[i].line.material.linewidth = lw;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export {
|
|
158
|
+
BoxMesh,
|
|
159
|
+
AxesMesh
|
|
160
|
+
};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Functions for a dithering-based transparent material
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import _ from 'lodash';
|
|
9
|
+
import * as THREE from 'three';
|
|
10
|
+
import * as Shaders from '../shaders/index.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Recursive function to generate a power-of-two ordered dithering matrix
|
|
14
|
+
*
|
|
15
|
+
* @param {int} n Power of two index. The returned matrix will have a 2^n side.
|
|
16
|
+
*/
|
|
17
|
+
function makeDitherMatrix(n) {
|
|
18
|
+
var dM2 = [0., 0.5, 0.75, 0.25];
|
|
19
|
+
if (n <= 1) {
|
|
20
|
+
return dM2;
|
|
21
|
+
} else {
|
|
22
|
+
var M1 = [];
|
|
23
|
+
var M0 = makeDitherMatrix(n - 1);
|
|
24
|
+
var N0 = Math.pow(2, n - 1);
|
|
25
|
+
var N1 = Math.pow(2, n);
|
|
26
|
+
var N02 = Math.pow(2, 2 * n - 2);
|
|
27
|
+
var N12 = Math.pow(2, 2 * n);
|
|
28
|
+
for (var i = 0; i < N12; ++i) {
|
|
29
|
+
var x1 = i % N1;
|
|
30
|
+
var y1 = Math.floor(i / N1);
|
|
31
|
+
var x2 = Math.floor(x1 / N0);
|
|
32
|
+
var y2 = Math.floor(y1 / N0);
|
|
33
|
+
var v = M0[x1 % N0 + (y1 % N0) * N0] + dM2[x2 + 2 * y2] / N02;
|
|
34
|
+
M1.push(v);
|
|
35
|
+
}
|
|
36
|
+
return M1;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Generate an ordered dithering matrix in the form of a THREE.js DataTexture
|
|
42
|
+
*
|
|
43
|
+
* @param {int} n Power of two index. The returned matrix will have a 2^n side.
|
|
44
|
+
*/
|
|
45
|
+
function makeDitherTexture(n) {
|
|
46
|
+
// n is the power of two exponent
|
|
47
|
+
var N = Math.pow(2, n);
|
|
48
|
+
var dM = makeDitherMatrix(n);
|
|
49
|
+
dM = dM.map(function(x) {
|
|
50
|
+
return Math.floor((x + 0.5 / (N * N)) * 256);
|
|
51
|
+
});
|
|
52
|
+
dM = new Uint8Array(dM);
|
|
53
|
+
|
|
54
|
+
var tx = new THREE.DataTexture(dM, N, N, THREE.RedFormat);
|
|
55
|
+
tx.needsUpdate = true;
|
|
56
|
+
|
|
57
|
+
return tx;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Generate a pseudorandom shift for the dither texture. Designed to ensure
|
|
62
|
+
* reproducibility given a float seed
|
|
63
|
+
*
|
|
64
|
+
* @param {int} N Size of texture
|
|
65
|
+
* @param {float} seed Seed number used to generate the shift
|
|
66
|
+
*/
|
|
67
|
+
function rndShift(N, seed) {
|
|
68
|
+
var a = 349588123;
|
|
69
|
+
var b = 123958341;
|
|
70
|
+
var sx = Math.pow(Math.sin(a*seed+b), 2)*N;
|
|
71
|
+
var sy = Math.pow(Math.cos(b*seed+a), 2)*N;
|
|
72
|
+
return new THREE.Vector2(sx, sy);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
class DitherMaterial extends THREE.ShaderMaterial {
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Initialise a DitherMaterial, a material that offers transparency with a
|
|
79
|
+
* dithering method (and thus meshes better when multiple transparent
|
|
80
|
+
* surfaces are overlapping).
|
|
81
|
+
*
|
|
82
|
+
* @param {Object} parameters Options:
|
|
83
|
+
* - color
|
|
84
|
+
* - opacity
|
|
85
|
+
* - illumination
|
|
86
|
+
* - n (controls the size of the dither texture, mostly can be left alone)
|
|
87
|
+
* - netting (if true, uses a different dithering system, applying object instead of screen
|
|
88
|
+
* coordinates)
|
|
89
|
+
* - netScale (scaling factor for the object coordinates; only used if netting = true)
|
|
90
|
+
*/
|
|
91
|
+
constructor(parameters = {}) {
|
|
92
|
+
|
|
93
|
+
var defaults = {
|
|
94
|
+
color: 0xffffff,
|
|
95
|
+
opacity: 0.5,
|
|
96
|
+
illumination: 0.5,
|
|
97
|
+
n: 5,
|
|
98
|
+
netting: false,
|
|
99
|
+
netScale: 5.0,
|
|
100
|
+
shiftSeed: null
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
parameters = _.merge(defaults, parameters);
|
|
105
|
+
|
|
106
|
+
// Safety check to avoid completely bricking the user's memory
|
|
107
|
+
var n = Math.min(parameters.n, 10); // This way ditherTex will never be bigger than 1024x1024
|
|
108
|
+
var N = Math.pow(2, n);
|
|
109
|
+
var shift = rndShift(N, (parameters.shiftSeed == null? Math.random() : parameters.shiftSeed));
|
|
110
|
+
var ditherTex = makeDitherTexture(n);
|
|
111
|
+
|
|
112
|
+
super({
|
|
113
|
+
uniforms: {
|
|
114
|
+
color: new THREE.Uniform(new THREE.Color(parameters.color)),
|
|
115
|
+
opacity: new THREE.Uniform(parameters.opacity),
|
|
116
|
+
illum: new THREE.Uniform(parameters.illumination),
|
|
117
|
+
shift: new THREE.Uniform(shift),
|
|
118
|
+
ditherN: new THREE.Uniform(N),
|
|
119
|
+
ditherTex: new THREE.Uniform(ditherTex),
|
|
120
|
+
netting: new THREE.Uniform(parameters.netting),
|
|
121
|
+
netScale: new THREE.Uniform(parameters.netScale),
|
|
122
|
+
},
|
|
123
|
+
fragmentShader: Shaders.ditherFragShader,
|
|
124
|
+
vertexShader: Shaders.ditherVertShader,
|
|
125
|
+
depthTest: true,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
this.side = THREE.DoubleSide;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
get color() {
|
|
132
|
+
return this.uniforms.color.value.getHex();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
set color(c) {
|
|
136
|
+
this.uniforms.color.value = new THREE.Color(c);
|
|
137
|
+
this.uniformsNeedUpdate = true;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
get opacity() {
|
|
141
|
+
return this.uniforms.opacity.value;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
set opacity(o) {
|
|
145
|
+
if (this.uniforms) {
|
|
146
|
+
// This check is necessary since we're overriding the original
|
|
147
|
+
// property, otherwise we get an error when calling super()
|
|
148
|
+
this.uniforms.opacity.value = o;
|
|
149
|
+
this.uniformsNeedUpdate = true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export {
|
|
155
|
+
DitherMaterial
|
|
156
|
+
};
|