-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTriangleGeometry.js
120 lines (70 loc) · 2.31 KB
/
TriangleGeometry.js
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
116
117
118
119
120
import { BufferGeometry } from '../core/BufferGeometry.js';
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
class TriangleGeometry extends BufferGeometry {
constructor( width = 1, height = Math.sqrt( 3 ) / 2, skew = 0, segments = 1 ) {
super();
this.type = 'TriangleGeometry';
segments = Math.max( Math.floor( segments ), 1 );
this.parameters = {
width: width,
height: height,
skew: skew,
segments: segments
};
// buffers
const indices = [];
const vertices = [];
const normals = [];
const uvs = [];
// vertex helper variables
const widthHalf = width / 2;
const skewHalf = skew / 2;
const offsetX = ( width + widthHalf + skewHalf ) / 3;
const offsetY = height / 3;
const length = Math.max( Math.abs( skewHalf ) + widthHalf, width );
const maxU = Math.min( length / height, 1);
const maxV = Math.min( height / length, 1);
const offsetU = skew + width > 0 ? ( 1 - maxU ) / 2 : ( length - width ) / length;
const offsetV = ( 1 - maxV ) / 2;
// vertices, normals, and uvs
for ( let i = 0; i < segments + 1; i ++ ) {
for ( let j = 0; j < i + 1; j ++ ) {
const normX = ( i + j ) / segments / 2;
const normY = ( i - j ) / segments;
const x = normX * width + normY * skewHalf;
const y = normY * height;
const u = maxU * x / length;
const v = maxV * y / height;
vertices.push( x - offsetX, y - offsetY, 0 );
normals.push( 0, 0, 1 );
uvs.push( u + offsetU, v + offsetV );
}
}
// indices
let stride = 1;
for ( let i = 0; i < segments; i ++ ) {
for ( let j = 0; j < i + 1; j ++ ) {
const a = i * ( i + 1 ) / 2 + j;
const b = i + stride + 1;
indices.push( a, b, i + stride );
if ( 0 < i && j < i ) {
indices.push( a, a + 1, b );
}
stride ++;
}
}
this.setIndex( indices );
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
}
copy( source ) {
super.copy( source );
this.parameters = Object.assign( {}, source.parameters );
return this;
}
static fromJSON( data ) {
return new TriangleGeometry( data.width, data.height, data.skew, data.segments );
}
}
export { TriangleGeometry };