File size: 2,842 Bytes
a28eca3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { Color } from 'three';
import { attribute, cameraProjectionMatrix, dot, float, Fn, modelViewMatrix, modelViewProjection, NodeMaterial, normalize, positionGeometry, sign, uniform, varyingProperty, vec2, vec4 } from 'three/tsl';

class LDrawConditionalLineMaterial extends NodeMaterial {

	static get type() {

		return 'LDrawConditionalLineMaterial';

	}

	constructor( parameters ) {

		super();

		const vertexNode = /*@__PURE__*/ Fn( () => {

			const control0 = attribute( 'control0', 'vec3' );
			const control1 = attribute( 'control1', 'vec3' );
			const direction = attribute( 'direction', 'vec3' );

			const mvp = cameraProjectionMatrix.mul( modelViewMatrix );

			// Transform the line segment ends and control points into camera clip space

			const c0 = mvp.mul( vec4( control0, 1 ) ).toVar();
			const c1 = mvp.mul( vec4( control1, 1 ) ).toVar();
			const p0 = mvp.mul( vec4( positionGeometry, 1 ) ).toVar();
			const p1 = mvp.mul( vec4( positionGeometry.add( direction ), 1 ) ).toVar();

			c0.xy.divAssign( c0.w );
			c1.xy.divAssign( c1.w );
			p0.xy.divAssign( p0.w );
			p1.xy.divAssign( p1.w );

			// Get the direction of the segment and an orthogonal vector

			const dir = p1.xy.sub( p0.xy ).toVar();
			const norm = vec2( dir.y.negate(), dir.x ).toVar();

			// Get control point directions from the line
			const c0dir = c0.xy.sub( p1.xy ).toVar();
			const c1dir = c1.xy.sub( p1.xy ).toVar();

			// If the vectors to the controls points are pointed in different directions away
			// from the line segment then the line should not be drawn.
			const d0 = dot( normalize( norm ), normalize( c0dir ) ).toVar();
			const d1 = dot( normalize( norm ), normalize( c1dir ) ).toVar();
			const discardFlag = sign( d0 ).notEqual( sign( d1 ) ).select( float( 1 ), float( 0 ) );

			varyingProperty( 'float', 'discardFlag' ).assign( discardFlag );

			return modelViewProjection;

		} )();

		const fragmentNode = /*@__PURE__*/ Fn( () => {

			const discardFlag = varyingProperty( 'float', 'discardFlag' );

			discardFlag.greaterThan( float( 0.5 ) ).discard();

			return vec4( this._diffuseUniform, this._opacityUniform );

		} )();

		this.vertexNode = vertexNode;
		this.fragmentNode = fragmentNode;

		this._diffuseUniform = uniform( new Color() );
		this._opacityUniform = uniform( 1 );

		//

		Object.defineProperties( this, {

			opacity: {
				get: function () {

					return this._opacityUniform.value;

				},

				set: function ( value ) {

					this._opacityUniform.value = value;

				}
			},

			color: {
				get: function () {

					return this._diffuseUniform.value;

				},

				set: function ( value ) {

					this._diffuseUniform.value.copy( value );

				}
			}

		} );

		this.setValues( parameters );
		this.isLDrawConditionalLineMaterial = true;

	}

}

export { LDrawConditionalLineMaterial };