Skip to content

Commit a7351c8

Browse files
committed
voxele
1 parent ad7abfe commit a7351c8

File tree

8 files changed

+409
-36
lines changed

8 files changed

+409
-36
lines changed

atla.png

44.4 KB
Loading

atlas-mc.jpg

32.8 KB
Loading

atlas.png

3.81 KB
Loading

atlasx.png

201 KB
Loading

atlasz.png

109 KB
Loading

index.html

Lines changed: 314 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,316 @@
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

Comments
 (0)