11< html >
2- < head >
3- < title > My first three.js app</ title >
4- < style >
5- body { margin : 0 ; }
6- canvas { display : block; }
7- </ style >
8- </ head >
9- < body >
10- < script src ="js/three.js "> </ script >
11- < script >
12- var scene = new THREE . Scene ( ) ;
13- var camera = new THREE . PerspectiveCamera ( 75 , window . innerWidth / window . innerHeight , 0.1 , 1000 ) ;
14-
15- var renderer = new THREE . WebGLRenderer ( ) ;
16- renderer . setSize ( window . innerWidth , window . innerHeight ) ;
17- document . body . appendChild ( renderer . domElement ) ;
18-
19- var geometry = new THREE . BoxGeometry ( ) ;
20- var material = new THREE . MeshBasicMaterial ( { color : 0x00ff00 } ) ;
21- var cube = new THREE . Mesh ( geometry , material ) ;
22- scene . add ( cube ) ;
23-
24- camera . position . z = 5 ;
25-
26- var animate = function ( ) {
27- requestAnimationFrame ( animate ) ;
28-
29- cube . rotation . x += 0.01 ;
30- cube . rotation . y += 0.01 ;
31-
32- renderer . render ( scene , camera ) ;
33- } ;
34-
35- animate ( ) ;
36- </ script >
37- </ body >
2+ < head >
3+ < title > Minecraft Renderer</ title >
4+ < style >
5+ body { margin : 0 ; }
6+ canvas { display : block; width : 100% ;height : 100% ;}
7+
8+ </ style >
9+ </ head >
10+ < body >
11+ < canvas id ="c "> </ canvas >
12+ < script src ="js/jq.js "> </ script >
13+ < script src ="js/1pc.js "> </ script >
14+ < script type ="module ">
15+
16+ import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/build/three.module.js' ;
17+ import { BufferGeometryUtils } from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/utils/BufferGeometryUtils.js' ;
18+ var canvas , renderer , scene , camera ;
19+
20+
21+ init ( )
22+ animate ( )
23+
24+ class Terrain {
25+ constructor ( options ) {
26+ this . textureAtlas = options . textureAtlas ;
27+ this . textureRows = options . textureRows ;
28+ this . textureCols = options . textureCols ;
29+ this . cellSize = options . cellSize ;
30+ this . cells = { } ;
31+ this . cells_meshes = { } ;
32+ }
33+ parseVec ( x , y , z ) {
34+ return `${ x } :${ y } :${ z } ` ;
35+ }
36+ computeVoxelOffset ( x , y , z ) {
37+ const { cellSize} = this ;
38+ x = THREE . MathUtils . euclideanModulo ( x , cellSize ) | 0 ;
39+ y = THREE . MathUtils . euclideanModulo ( y , cellSize ) | 0 ;
40+ z = THREE . MathUtils . euclideanModulo ( z , cellSize ) | 0 ;
41+ return [ x , y , z ]
42+ }
43+ computeCellId ( x , y , z ) {
44+ const { cellSize} = this ;
45+ const cellX = Math . floor ( x / cellSize ) ;
46+ const cellY = Math . floor ( y / cellSize ) ;
47+ const cellZ = Math . floor ( z / cellSize ) ;
48+ return `${ cellX } :${ cellY } :${ cellZ } `
49+ }
50+ getCellForVoxel ( x , y , z ) {
51+ return this . cells [ this . computeCellId ( x , y , z ) ] ;
52+ }
53+ setVoxel ( x , y , z , v ) {
54+ var voxel = this . computeVoxelOffset ( x , y , z ) ;
55+ var cellId = this . computeCellId ( x , y , z ) ;
56+ if ( this . cells [ cellId ] != undefined ) {
57+ this . cells [ cellId ] [ this . parseVec ( ...voxel ) ] = v ;
58+ } else {
59+ this . cells [ cellId ] = { } ;
60+ this . cells [ cellId ] [ this . parseVec ( ...voxel ) ] = v ;
61+ }
62+ this . cells [ cellId ] . needsUpdate = true ;
63+ }
64+ getVoxel ( x , y , z ) {
65+ var voxel = this . computeVoxelOffset ( x , y , z ) ;
66+ var cellId = this . computeCellId ( x , y , z ) ;
67+ if ( this . cells [ cellId ] != undefined ) {
68+ var val = this . cells [ cellId ] [ this . parseVec ( ...voxel ) ] ;
69+ if ( val != undefined ) {
70+ return val ;
71+ } else {
72+ return 0 ;
73+ }
74+ } else {
75+ return 0 ;
76+ }
77+
78+ }
79+ updateCellGeometry ( x , y , z ) {
80+ const { textureAtlas} = this ;
81+ if ( this . cells [ this . parseVec ( x , y , z ) ] == undefined || this . cells [ this . parseVec ( x , y , z ) ] . needsUpdate ) {
82+ var mesh = this . cells_meshes [ this . parseVec ( x , y , z ) ] ;
83+ var geometry = this . generateCellGeometry ( x , y , z ) ;
84+ if ( geometry != null ) {
85+ if ( mesh != undefined ) {
86+ mesh . geometry = geometry ;
87+ } else {
88+ var geometry = geometry ;
89+ var mesh = new THREE . Mesh ( geometry , new THREE . MeshLambertMaterial ( { map : textureAtlas , side : 0 } ) ) ;
90+ scene . add ( mesh )
91+ this . cells_meshes [ this . parseVec ( x , y , z ) ] = mesh ;
92+ }
93+ }
94+ try {
95+ this . cells [ this . parseVec ( x , y , z ) ] . needsUpdate = false ;
96+ } catch ( e ) { }
97+
98+ }
99+
100+ }
101+ generateCellGeometry ( x , y , z ) {
102+ const { textureAtlas, cellSize} = this ;
103+ var geometries = [ ] ;
104+ // Object.forEach(this.cells)
105+ for ( var i = 0 ; i < cellSize ; i ++ ) {
106+ for ( var j = 0 ; j < cellSize ; j ++ ) {
107+ for ( var k = 0 ; k < cellSize ; k ++ ) {
108+ var voxelGeometries = this . generateVoxelGeometry ( x * cellSize + i , y * cellSize + j , z * cellSize + k ) ;
109+ // console.log(voxelGeometries)
110+ for ( var l = 0 ; l < voxelGeometries . length ; l ++ ) {
111+ geometries . push ( voxelGeometries [ l ] ) ;
112+ }
113+
114+ }
115+ }
116+ }
117+ // console.log(geometries)
118+ if ( geometries . length != 0 ) {
119+ var geometry = BufferGeometryUtils . mergeBufferGeometries ( geometries ) ;
120+ geometry . computeBoundingSphere ( ) ;
121+ } else {
122+ var geometry = null ;
123+ }
124+
125+
126+ return geometry ;
127+ }
128+ generateVoxelGeometry ( x , y , z ) {
129+ // console.log(x,y,z)
130+ var voxel = this . getVoxel ( x , y , z ) ;
131+ var matrix = new THREE . Matrix4 ( ) ;
132+ matrix . makeTranslation ( x , y , z ) ;
133+ if ( voxel == 1 ) {
134+ var geometries = [ ] ;
135+ if ( this . getVoxel ( x - 1 , y , z ) == 0 ) {
136+ var nxGeometry = this . generateFace ( "nx" ) ;
137+ geometries . push ( nxGeometry . applyMatrix4 ( matrix ) )
138+ }
139+ if ( this . getVoxel ( x + 1 , y , z ) == 0 ) {
140+ var pxGeometry = this . generateFace ( "px" ) ;
141+ geometries . push ( pxGeometry . applyMatrix4 ( matrix ) )
142+ }
143+ if ( this . getVoxel ( x , y - 1 , z ) == 0 ) {
144+ var nyGeometry = this . generateFace ( "ny" ) ;
145+ geometries . push ( nyGeometry . applyMatrix4 ( matrix ) )
146+ }
147+ if ( this . getVoxel ( x , y + 1 , z ) == 0 ) {
148+ var pyGeometry = this . generateFace ( "py" ) ;
149+ geometries . push ( pyGeometry . applyMatrix4 ( matrix ) )
150+ }
151+ if ( this . getVoxel ( x , y , z - 1 ) == 0 ) {
152+ var nzGeometry = this . generateFace ( "nz" ) ;
153+ geometries . push ( nzGeometry . applyMatrix4 ( matrix ) )
154+ }
155+ if ( this . getVoxel ( x , y , z + 1 ) == 0 ) {
156+ var pzGeometry = this . generateFace ( "pz" ) ;
157+ geometries . push ( pzGeometry . applyMatrix4 ( matrix ) )
158+ }
159+ // geometries.push( nxGeometry.applyMatrix4( matrix ) )
160+ // geometries.push( pxGeometry.applyMatrix4( matrix ) )
161+ // geometries.push( nyGeometry.applyMatrix4( matrix ) )
162+ // geometries.push( pyGeometry.applyMatrix4( matrix ) )
163+ // geometries.push( nzGeometry.applyMatrix4( matrix ) )
164+ // geometries.push( pzGeometry.applyMatrix4( matrix ) )
165+ return geometries ;
166+ } else {
167+ return [ ]
168+ }
169+ }
170+ generateFace ( type ) {
171+ var geometry = new THREE . PlaneBufferGeometry ( 1 , 1 ) ;
172+ if ( type == "px" ) {
173+ geometry . rotateY ( Math . PI / 2 ) ;
174+ geometry . translate ( 0.5 , 0 , 0 ) ;
175+ }
176+ if ( type == "nx" ) {
177+ geometry . rotateY ( - Math . PI / 2 ) ;
178+ geometry . translate ( - 0.5 , 0 , 0 ) ;
179+ }
180+ if ( type == "py" ) {
181+ geometry . rotateX ( - Math . PI / 2 ) ;
182+ geometry . translate ( 0 , 0.5 , 0 ) ;
183+ }
184+ if ( type == "ny" ) {
185+ geometry . rotateX ( Math . PI / 2 ) ;
186+ geometry . translate ( 0 , - 0.5 , 0 ) ;
187+ }
188+ if ( type == "pz" ) {
189+ geometry . translate ( 0 , 0 , 0.5 ) ;
190+ }
191+ if ( type == "nz" ) {
192+ geometry . rotateY ( Math . PI ) ;
193+ geometry . translate ( 0 , 0 , - 0.5 ) ;
194+ }
195+ var rx = Math . floor ( Math . random ( ) * 4 )
196+ var ry = 15
197+ this . setUv ( geometry , rx , ry , 180 )
198+ return geometry ;
199+ }
200+ setUv ( geometry , x , y , rotation = 0 ) {
201+ const { textureRows, textureCols} = this ;
202+ var textureSizeX = 1 / textureRows ;
203+ var textureSizeY = 1 / textureCols ;
204+ if ( rotation == 0 ) {
205+ geometry . attributes . uv . array [ 0 ] = textureSizeX * x ;
206+ geometry . attributes . uv . array [ 1 ] = textureSizeY * y ;
207+
208+ geometry . attributes . uv . array [ 2 ] = textureSizeX + textureSizeX * x ;
209+ geometry . attributes . uv . array [ 3 ] = 0 + textureSizeY * y ;
210+
211+ geometry . attributes . uv . array [ 4 ] = 0 + textureSizeX * x ;
212+ geometry . attributes . uv . array [ 5 ] = textureSizeY + textureSizeY * y ;
213+
214+ geometry . attributes . uv . array [ 6 ] = textureSizeX + textureSizeX * x ;
215+ geometry . attributes . uv . array [ 7 ] = textureSizeY + textureSizeY * y ;
216+ } else if ( rotation == 180 ) {
217+ geometry . attributes . uv . array [ 4 ] = textureSizeX * x ;
218+ geometry . attributes . uv . array [ 5 ] = textureSizeY * y ;
219+
220+ geometry . attributes . uv . array [ 6 ] = textureSizeX + textureSizeX * x ;
221+ geometry . attributes . uv . array [ 7 ] = 0 + textureSizeY * y ;
222+
223+ geometry . attributes . uv . array [ 0 ] = 0 + textureSizeX * x ;
224+ geometry . attributes . uv . array [ 1 ] = textureSizeY + textureSizeY * y ;
225+
226+ geometry . attributes . uv . array [ 2 ] = textureSizeX + textureSizeX * x ;
227+ geometry . attributes . uv . array [ 3 ] = textureSizeY + textureSizeY * y ;
228+ }
229+ }
230+ }
231+
232+
233+ var texture = new THREE . TextureLoader ( ) . load ( 'atla.png' ) ;
234+ texture . magFilter = THREE . NearestFilter ;
235+ var world = new Terrain ( {
236+ textureAtlas :texture ,
237+ textureRows :16 ,
238+ textureCols :16 ,
239+ cellSize :16 ,
240+ } )
241+
242+ var vari = 50
243+ for ( let y = 0 ; y < vari ; ++ y ) {
244+ for ( let z = 0 ; z < vari ; ++ z ) {
245+ for ( let x = 0 ; x < vari ; ++ x ) {
246+ const height = ( Math . sin ( x / vari * Math . PI * 2 ) + Math . sin ( z / vari * Math . PI * 3 ) ) * ( vari / 6 ) + ( vari / 2 ) ;
247+ if ( y < height ) {
248+ world . setVoxel ( x , y , z , 1 ) ;
249+ }
250+ }
251+ }
252+ }
253+ // console.log(world.cells["0:0:0"])
254+ for ( var i = 0 ; i < 5 ; i ++ ) {
255+ for ( var j = 0 ; j < 5 ; j ++ ) {
256+ for ( var k = 0 ; k < 5 ; k ++ ) {
257+ world . updateCellGeometry ( i , j , k ) ;
258+ }
259+ }
260+ }
261+
262+ // world.generateMeshForCell(0,0,1);
263+
264+ function init ( ) {
265+ canvas = document . querySelector ( '#c' ) ;
266+ renderer = new THREE . WebGLRenderer ( {
267+ canvas
268+ } ) ;
269+
270+ scene = new THREE . Scene ( ) ;
271+ scene . background = new THREE . Color ( 'lightblue' ) ;
272+
273+ camera = new THREE . PerspectiveCamera ( 75 , 2 , 0.1 , 1000 ) ;
274+ camera . rotation . order = "YXZ"
275+ camera . position . set ( 25 , 25 , 25 )
276+ FirstPersonControls ( canvas , camera , 0.04 )
277+
278+
279+ var ambientLight = new THREE . AmbientLight ( 0xcccccc ) ;
280+ scene . add ( ambientLight ) ;
281+ }
282+
283+
284+ function animate ( ) {
285+ render ( )
286+ requestAnimationFrame ( animate )
287+ }
288+
289+ function resizeRendererToDisplaySize ( renderer ) {
290+ const canvas = renderer . domElement ;
291+ const width = canvas . clientWidth ;
292+ const height = canvas . clientHeight ;
293+ const needResize = canvas . width !== width || canvas . height !== height ;
294+ if ( needResize ) {
295+ renderer . setSize ( width , height , false ) ;
296+ }
297+ return needResize ;
298+ }
299+
300+ function render ( ) {
301+ if ( resizeRendererToDisplaySize ( renderer ) ) {
302+ const canvas = renderer . domElement ;
303+ camera . aspect = canvas . clientWidth / canvas . clientHeight ;
304+ camera . updateProjectionMatrix ( ) ;
305+ }
306+ renderer . render ( scene , camera ) ;
307+ }
308+
309+
310+
311+
312+
313+
314+ </ script >
315+ </ body >
38316</ html >
0 commit comments