|
5 | 5 | <meta charset="utf-8"> |
6 | 6 | <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> |
7 | 7 | <link type="text/css" rel="stylesheet" href="main.css"> |
8 | | - <style> |
9 | | - body { |
10 | | - background-color: #f0f0f0; |
11 | | - color: #444; |
12 | | - } |
13 | | - a { |
14 | | - color: #08f; |
15 | | - } |
16 | | - </style> |
17 | 8 | </head> |
18 | 9 | <body> |
19 | 10 | <div id="info"> |
20 | | - <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - subdivision modifier<br/ > |
21 | | - Original Geometry: <span id="original-vertex-count"></span> vertices and <span id="original-face-count"></span> faces<br/ > |
22 | | - Smooth Geometry: <span id="smooth-vertex-count"></span> vertices and <span id="smooth-face-count"></span> faces<br/ > |
| 11 | + <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - subdivision modifier |
23 | 12 | </div> |
24 | 13 |
|
25 | 14 | <script type="module"> |
26 | 15 |
|
27 | 16 | import * as THREE from '../build/three.module.js'; |
28 | 17 |
|
29 | | - import Stats from './jsm/libs/stats.module.js'; |
30 | | - |
31 | 18 | import { GUI } from './jsm/libs/dat.gui.module.js'; |
32 | 19 | import { OrbitControls } from './jsm/controls/OrbitControls.js'; |
33 | 20 | import { SubdivisionModifier } from './jsm/modifiers/SubdivisionModifier.js'; |
34 | 21 |
|
35 | | - let camera, scene, renderer, stats, smoothMesh, wireframe; |
36 | | - |
37 | | - const smoothMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true, vertexColors: true } ); |
38 | | - const wireframeMaterial = new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, opacity: 0.15, transparent: true } ); |
| 22 | + let camera, scene, renderer, smoothMesh; |
39 | 23 |
|
40 | | - const faceIndices = [ 'a', 'b', 'c' ]; |
| 24 | + const material = new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true } ); |
| 25 | + const wireframeMaterial = new THREE.LineBasicMaterial(); |
41 | 26 |
|
42 | 27 | const params = { |
43 | 28 | subdivisions: 2 |
|
51 | 36 | camera.position.z = 100; |
52 | 37 |
|
53 | 38 | scene = new THREE.Scene(); |
54 | | - scene.background = new THREE.Color( 0xf0f0f0 ); |
55 | 39 |
|
56 | | - const light = new THREE.PointLight( 0xffffff, 1.5 ); |
57 | | - light.position.set( 1000, 1000, 2000 ); |
| 40 | + scene.add( new THREE.AmbientLight( 0xffffff, 0.2 ) ); |
| 41 | + |
| 42 | + const light = new THREE.PointLight( 0xffffff, 0.8 ); |
| 43 | + light.position.set( 0, 50, 100 ); |
58 | 44 | scene.add( light ); |
59 | 45 |
|
60 | 46 | const loader = new THREE.BufferGeometryLoader(); |
61 | | - loader.load( 'models/json/WaltHeadLo_buffergeometry.json', function ( bufferGeometry ) { |
62 | | - |
63 | | - // converting to legacy THREE.Geometry because SubdivisionModifier only returns THREE.Geometry |
| 47 | + loader.load( 'models/json/WaltHeadLo_buffergeometry.json', function ( geometry ) { |
64 | 48 |
|
65 | | - const geometry = new THREE.Geometry().fromBufferGeometry( bufferGeometry ); |
66 | | - geometry.mergeVertices(); |
67 | | - |
68 | | - const material = new THREE.MeshBasicMaterial( { color: 0xcccccc, wireframe: true } ); |
69 | | - const mesh = new THREE.Mesh( bufferGeometry, material ); |
| 49 | + const mesh = new THREE.Mesh( geometry, material ); |
| 50 | + mesh.position.x = 32; |
70 | 51 | scene.add( mesh ); |
71 | 52 |
|
| 53 | + const wireframe = new THREE.WireframeGeometry( geometry ); |
| 54 | + const line = new THREE.LineSegments( wireframe, wireframeMaterial ); |
| 55 | + mesh.add( line ); |
| 56 | + |
72 | 57 | const gui = new GUI(); |
73 | 58 |
|
74 | 59 | gui.add( params, 'subdivisions', 0, 3 ).step( 1 ).onChange( function ( subdivisions ) { |
75 | 60 |
|
76 | 61 | subdivide( geometry, subdivisions ); |
| 62 | + render(); |
77 | 63 |
|
78 | 64 | } ); |
79 | 65 |
|
80 | 66 | // |
81 | 67 |
|
82 | 68 | subdivide( geometry, params.subdivisions ); |
83 | | - animate(); |
| 69 | + |
| 70 | + render(); |
84 | 71 |
|
85 | 72 | } ); |
86 | 73 |
|
|
89 | 76 | renderer.setSize( window.innerWidth, window.innerHeight ); |
90 | 77 | document.body.appendChild( renderer.domElement ); |
91 | 78 |
|
92 | | - stats = new Stats(); |
93 | | - document.body.appendChild( stats.dom ); |
94 | | - |
95 | 79 | // |
96 | 80 |
|
97 | 81 | const controls = new OrbitControls( camera, renderer.domElement ); |
| 82 | + controls.addEventListener( 'change', render ); |
98 | 83 | controls.minDistance = 50; |
99 | 84 | controls.maxDistance = 400; |
100 | 85 |
|
101 | 86 | window.addEventListener( 'resize', onWindowResize, false ); |
102 | 87 |
|
103 | | - // |
104 | | - |
105 | | - smoothMesh = new THREE.Mesh( undefined, smoothMaterial ); |
106 | | - wireframe = new THREE.Mesh( undefined, wireframeMaterial ); |
107 | | - scene.add( smoothMesh, wireframe ); |
108 | | - |
109 | 88 | } |
110 | 89 |
|
111 | 90 | function subdivide( geometry, subdivisions ) { |
|
114 | 93 |
|
115 | 94 | const smoothGeometry = modifier.modify( geometry ); |
116 | 95 |
|
117 | | - // colorify faces |
118 | | - |
119 | | - for ( let i = 0; i < smoothGeometry.faces.length; i ++ ) { |
120 | | - |
121 | | - const face = smoothGeometry.faces[ i ]; |
| 96 | + if ( smoothMesh !== undefined ) { |
122 | 97 |
|
123 | | - for ( let j = 0; j < 3; j ++ ) { |
| 98 | + smoothMesh.geometry.dispose(); |
| 99 | + smoothMesh.children[ 0 ].geometry.dispose(); |
124 | 100 |
|
125 | | - const vertexIndex = face[ faceIndices[ j ] ]; |
126 | | - const vertex = smoothGeometry.vertices[ vertexIndex ]; |
127 | | - |
128 | | - const hue = ( vertex.y / 200 ) + 0.5; |
129 | | - const color = new THREE.Color().setHSL( hue, 1, 0.5 ); |
130 | | - face.vertexColors[ j ] = color; |
131 | | - |
132 | | - } |
| 101 | + scene.remove( smoothMesh ); |
133 | 102 |
|
134 | 103 | } |
135 | 104 |
|
136 | | - // convert to THREE.BufferGeometry |
137 | | - |
138 | | - if ( smoothMesh.geometry ) smoothMesh.geometry.dispose(); |
139 | | - |
140 | | - smoothMesh.geometry = new THREE.BufferGeometry().fromGeometry( smoothGeometry ); |
141 | | - wireframe.geometry = smoothMesh.geometry; |
| 105 | + smoothMesh = new THREE.Mesh( smoothGeometry, material ); |
| 106 | + smoothMesh.position.x = - 32; |
142 | 107 |
|
143 | | - // |
| 108 | + const wireframe = new THREE.WireframeGeometry( smoothGeometry ); |
| 109 | + const line = new THREE.LineSegments( wireframe, wireframeMaterial ); |
| 110 | + smoothMesh.add( line ); |
144 | 111 |
|
145 | | - updateUI( geometry, smoothGeometry ); |
146 | | - |
147 | | - } |
148 | | - |
149 | | - function updateUI( originalGeometry, smoothGeometry ) { |
150 | | - |
151 | | - document.getElementById( 'original-vertex-count' ).textContent = originalGeometry.vertices.length; |
152 | | - document.getElementById( 'original-face-count' ).textContent = originalGeometry.faces.length; |
153 | | - |
154 | | - document.getElementById( 'smooth-vertex-count' ).textContent = smoothGeometry.vertices.length; |
155 | | - document.getElementById( 'smooth-face-count' ).textContent = smoothGeometry.faces.length; |
| 112 | + scene.add( smoothMesh ); |
156 | 113 |
|
157 | 114 | } |
158 | 115 |
|
|
163 | 120 |
|
164 | 121 | renderer.setSize( window.innerWidth, window.innerHeight ); |
165 | 122 |
|
166 | | - } |
167 | | - |
168 | | - // |
169 | | - |
170 | | - function animate() { |
171 | | - |
172 | | - requestAnimationFrame( animate ); |
173 | | - |
174 | 123 | render(); |
175 | | - stats.update(); |
176 | 124 |
|
177 | 125 | } |
178 | 126 |
|
|
0 commit comments