source: other-projects/playing-in-the-street/summer-2013/trunk/Playing-in-the-Street-WPF/Content/Web/mrdoob-three.js-4862f5f/src/extras/geometries/PolyhedronGeometry.js@ 28897

Last change on this file since 28897 was 28897, checked in by davidb, 10 years ago

GUI front-end to server base plus web page content

File size: 4.4 KB
Line 
1/**
2 * @author clockworkgeek / https://github.com/clockworkgeek
3 * @author timothypratley / https://github.com/timothypratley
4 * @author WestLangley / http://github.com/WestLangley
5*/
6
7THREE.PolyhedronGeometry = function ( vertices, faces, radius, detail ) {
8
9 THREE.Geometry.call( this );
10
11 radius = radius || 1;
12 detail = detail || 0;
13
14 var that = this;
15
16 for ( var i = 0, l = vertices.length; i < l; i ++ ) {
17
18 prepare( new THREE.Vector3( vertices[ i ][ 0 ], vertices[ i ][ 1 ], vertices[ i ][ 2 ] ) );
19
20 }
21
22 var midpoints = [], p = this.vertices;
23
24 var f = [];
25 for ( var i = 0, l = faces.length; i < l; i ++ ) {
26
27 var v1 = p[ faces[ i ][ 0 ] ];
28 var v2 = p[ faces[ i ][ 1 ] ];
29 var v3 = p[ faces[ i ][ 2 ] ];
30
31 f[ i ] = new THREE.Face3( v1.index, v2.index, v3.index, [ v1.clone(), v2.clone(), v3.clone() ] );
32
33 }
34
35 for ( var i = 0, l = f.length; i < l; i ++ ) {
36
37 subdivide(f[ i ], detail);
38
39 }
40
41
42 // Handle case when face straddles the seam
43
44 for ( var i = 0, l = this.faceVertexUvs[ 0 ].length; i < l; i ++ ) {
45
46 var uvs = this.faceVertexUvs[ 0 ][ i ];
47
48 var x0 = uvs[ 0 ].x;
49 var x1 = uvs[ 1 ].x;
50 var x2 = uvs[ 2 ].x;
51
52 var max = Math.max( x0, Math.max( x1, x2 ) );
53 var min = Math.min( x0, Math.min( x1, x2 ) );
54
55 if ( max > 0.9 && min < 0.1 ) { // 0.9 is somewhat arbitrary
56
57 if ( x0 < 0.2 ) uvs[ 0 ].x += 1;
58 if ( x1 < 0.2 ) uvs[ 1 ].x += 1;
59 if ( x2 < 0.2 ) uvs[ 2 ].x += 1;
60
61 }
62
63 }
64
65
66 // Apply radius
67
68 for ( var i = 0, l = this.vertices.length; i < l; i ++ ) {
69
70 this.vertices[ i ].multiplyScalar( radius );
71
72 }
73
74
75 // Merge vertices
76
77 this.mergeVertices();
78
79 this.computeCentroids();
80
81 this.computeFaceNormals();
82
83 this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius );
84
85
86 // Project vector onto sphere's surface
87
88 function prepare( vector ) {
89
90 var vertex = vector.normalize().clone();
91 vertex.index = that.vertices.push( vertex ) - 1;
92
93 // Texture coords are equivalent to map coords, calculate angle and convert to fraction of a circle.
94
95 var u = azimuth( vector ) / 2 / Math.PI + 0.5;
96 var v = inclination( vector ) / Math.PI + 0.5;
97 vertex.uv = new THREE.Vector2( u, 1 - v );
98
99 return vertex;
100
101 }
102
103
104 // Approximate a curved face with recursively sub-divided triangles.
105
106 function make( v1, v2, v3 ) {
107
108 var face = new THREE.Face3( v1.index, v2.index, v3.index, [ v1.clone(), v2.clone(), v3.clone() ] );
109 face.centroid.add( v1 ).add( v2 ).add( v3 ).divideScalar( 3 );
110 that.faces.push( face );
111
112 var azi = azimuth( face.centroid );
113
114 that.faceVertexUvs[ 0 ].push( [
115 correctUV( v1.uv, v1, azi ),
116 correctUV( v2.uv, v2, azi ),
117 correctUV( v3.uv, v3, azi )
118 ] );
119
120 }
121
122
123 // Analytically subdivide a face to the required detail level.
124
125 function subdivide(face, detail ) {
126
127 var cols = Math.pow(2, detail);
128 var cells = Math.pow(4, detail);
129 var a = prepare( that.vertices[ face.a ] );
130 var b = prepare( that.vertices[ face.b ] );
131 var c = prepare( that.vertices[ face.c ] );
132 var v = [];
133
134 // Construct all of the vertices for this subdivision.
135
136 for ( var i = 0 ; i <= cols; i ++ ) {
137
138 v[ i ] = [];
139
140 var aj = prepare( a.clone().lerp( c, i / cols ) );
141 var bj = prepare( b.clone().lerp( c, i / cols ) );
142 var rows = cols - i;
143
144 for ( var j = 0; j <= rows; j ++) {
145
146 if ( j == 0 && i == cols ) {
147
148 v[ i ][ j ] = aj;
149
150 } else {
151
152 v[ i ][ j ] = prepare( aj.clone().lerp( bj, j / rows ) );
153
154 }
155
156 }
157
158 }
159
160 // Construct all of the faces.
161
162 for ( var i = 0; i < cols ; i ++ ) {
163
164 for ( var j = 0; j < 2 * (cols - i) - 1; j ++ ) {
165
166 var k = Math.floor( j / 2 );
167
168 if ( j % 2 == 0 ) {
169
170 make(
171 v[ i ][ k + 1],
172 v[ i + 1 ][ k ],
173 v[ i ][ k ]
174 );
175
176 } else {
177
178 make(
179 v[ i ][ k + 1 ],
180 v[ i + 1][ k + 1],
181 v[ i + 1 ][ k ]
182 );
183
184 }
185
186 }
187
188 }
189
190 }
191
192
193 // Angle around the Y axis, counter-clockwise when looking from above.
194
195 function azimuth( vector ) {
196
197 return Math.atan2( vector.z, -vector.x );
198
199 }
200
201
202 // Angle above the XZ plane.
203
204 function inclination( vector ) {
205
206 return Math.atan2( -vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
207
208 }
209
210
211 // Texture fixing helper. Spheres have some odd behaviours.
212
213 function correctUV( uv, vector, azimuth ) {
214
215 if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) uv = new THREE.Vector2( uv.x - 1, uv.y );
216 if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) uv = new THREE.Vector2( azimuth / 2 / Math.PI + 0.5, uv.y );
217 return uv.clone();
218
219 }
220
221
222};
223
224THREE.PolyhedronGeometry.prototype = Object.create( THREE.Geometry.prototype );
Note: See TracBrowser for help on using the repository browser.