2017-05-15 65 views
0

我已經看過voxel js,但它似乎已經過時了,它使用了節點js,我不想使用它。我想使用for循環生成簡單的地形,以及我的創建塊的函數。如何使用三個js生成使用體素生成器的地形

這裏是我的功能:

function createBlock(block, x, y, z, top, bottom, front, back, left, right) { 
    var geometry; 
    var meshFaceMaterial; 
    var mesh; 
    var material; 
    var blockObj = {}; 
    if (top == true) { 
     geometry = new THREE.PlaneGeometry(1, 1); 
     material = new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture(blocks[block].top)}); 
     meshFaceMaterial = new THREE.MeshFaceMaterial(material); 
     mesh = new THREE.Mesh(geometry, meshFaceMaterial); 
     mesh.position.z = z; 
     mesh.position.x = x; 
     mesh.position.y = y+5; 
     mesh.rotation.x = (-90 * Math.PI)/180; 
     blockObj.top = mesh; 
    } 
    if (bottom == true) { 
     geometry = new THREE.PlaneGeometry(1, 1); 
     material = new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture(blocks[block].bottom)}); 
     meshFaceMaterial = new THREE.MeshFaceMaterial(material); 
     mesh = new THREE.Mesh(geometry, meshFaceMaterial); 
     mesh.position.z = z; 
     mesh.position.x = x; 
     mesh.position.y = y-5; 
     mesh.rotation.x = (90 * Math.PI)/180; 
     blockObj.bottom = mesh; 
    } 
    if (back == true) { 
     geometry = new THREE.PlaneGeometry(1, 1); 
     material = new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture(blocks[block].side)}); 
     meshFaceMaterial = new THREE.MeshFaceMaterial(material); 
     mesh = new THREE.Mesh(geometry, meshFaceMaterial); 
     mesh.position.z = z-5; 
     mesh.position.x = x; 
     mesh.position.y = y; 
     mesh.rotation.y = (180 * Math.PI)/180; 
     blockObj.back = mesh; 
    } 
    if (right == true) { 
     geometry = new THREE.PlaneGeometry(1, 1); 
     material = new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture(blocks[block].side)}); 
     meshFaceMaterial = new THREE.MeshFaceMaterial(material); 
     mesh = new THREE.Mesh(geometry, meshFaceMaterial); 
     mesh.position.z = z; 
     mesh.position.x = x+5; 
     mesh.position.y = y; 
     mesh.rotation.y = (90 * Math.PI)/180; 
     blockObj.right = mesh; 
    } 
    if (left == true) { 
     geometry = new THREE.PlaneGeometry(1, 1); 
     material = new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture(blocks[block].side)}); 
     meshFaceMaterial = new THREE.MeshFaceMaterial(material); 
     mesh = new THREE.Mesh(geometry, meshFaceMaterial); 
     mesh.position.z = z; 
     mesh.position.x = x-5; 
     mesh.position.y = y; 
     mesh.rotation.y = (-90 * Math.PI)/180; 
     blockObj.left = mesh; 
    } 
    if (front == true) { 
     geometry = new THREE.PlaneGeometry(1, 1); 
     material = new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture(blocks[block].side)}); 
     meshFaceMaterial = new THREE.MeshFaceMaterial(material); 
     mesh = new THREE.Mesh(geometry, meshFaceMaterial); 
     mesh.position.z = z+5; 
     mesh.position.x = x; 
     mesh.position.y = y; 
     blockObj.front = mesh; 
    } 

    blockObjects.push(blockObj); 

    return blockObj; 
} 

任何幫助,將不勝感激。

+0

什麼是不是在你的功能嗎?你有什麼結果嗎?你的問題是什麼? – HReynaud

+0

@HReynaud該函數可以正常工作。我只是無法使用它來製作體素地形。我已經看過地形生成的例子,但我不知道如何用我的函數來實現它。我需要在特定情況下使用我的函數,因爲我將塊數據保存到一個對象。你能幫我麼? – Rishi

+0

你想要地形看起來多麼隨意? – fmacdee

回答

1

這裏是一個算法,它創建立方體並用它們構建隨機地形。在這種情況下,我已經將地形高度變化固定爲比相鄰立方體高一個立方體高度。我爲每個立方體隨機生成一個綠色,但顯然你可以應用任何你想要的紋理。

var camera, scene, renderer; 
 
    var mesh; 
 

 
    var cubesize = 30; 
 
    var landscape_width = 30; 
 
    var landscape_length = 30; 
 
    var heights = []; 
 
    var camera_offset = cubesize * landscape_width *0.7; 
 
    var camera_height = cubesize * landscape_width/2; 
 

 
    function init() { 
 
     camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 1, 10000); 
 
     camera.position.set(0,camera_offset,camera_height); 
 
     camera.up = new THREE.Vector3(0,0,1); 
 
     camera.lookAt(new THREE.Vector3(0,0,0)); 
 
     scene = new THREE.Scene(); 
 

 
     geom = new THREE.CubeGeometry(cubesize, cubesize, cubesize); 
 
     cubes = new THREE.Object3D(); 
 
     scene.add(cubes); 
 

 
     var xoff = landscape_width * cubesize/2; 
 
     var yoff = landscape_length * cubesize/2; 
 
     for(var i=0; i<landscape_width; i++) heights[i,0] = 0; 
 
     for(var j=0; j<landscape_length; j++) heights[0,j] = 0; 
 

 
     for(var i=1; i<landscape_width; i++) { 
 
      var h = heights[i-1,0]; 
 
      for(var j=1; j< landscape_length; j++) { 
 
       var rand = Math.random(); 
 
       if(heights[i-1,j] == heights[i,j-1]) { // level ground, go up dn or stay 
 
        if(rand < 0.33) 
 
         heights[i,j] = heights[i-1,j] - cubesize; 
 
        else if (rand > 0.66) 
 
         heights[i,j] = heights[i-1,j] + cubesize; 
 
        else 
 
         heights[i,j] = heights[i-1,j];        
 
       } 
 
       else if(Math.abs(heights[i-1,j] - heights[i,j-1]) > cubesize) { // two edges are wide apart, split the difference 
 
        heights[i,j] = (heights[i-1,j] +heights[i,j-1])/2; 
 
       } 
 
       else { 
 
        if(rand > 0.5) 
 
         heights[i,j] = heights[i-1,j]; 
 
        else 
 
         heights[i,j] = heights[i,j-1];        
 
       } 
 

 
       var grayness = Math.random() * 0.5 + 0.25, 
 
        mat = new THREE.MeshBasicMaterial(), 
 
        cube = new THREE.Mesh(geom, mat); 
 
       mat.color.setRGB(0, grayness, 0); 
 
       cube.position.set(i*cubesize - xoff, j*cubesize - yoff, heights[i,j]); 
 
       cubes.add(cube);       
 
      } 
 
     } 
 

 
     renderer = new THREE.WebGLRenderer(); 
 
     renderer.setPixelRatio(window.devicePixelRatio); 
 
     renderer.setSize(window.innerWidth, window.innerHeight); 
 
     document.body.appendChild(renderer.domElement); 
 
     // 
 
     window.addEventListener('resize', onWindowResize, false); 
 
    } 
 
    function onWindowResize() { 
 
     camera.aspect = window.innerWidth/window.innerHeight; 
 
     camera.updateProjectionMatrix(); 
 
     renderer.setSize(window.innerWidth, window.innerHeight); 
 
    } 
 
    var angle = 0; 
 
    function animate() { 
 
     angle += 0.5; 
 
     var rads = angle * Math.PI /180; 
 
     camera.position.set(Math.cos(rads)*camera_offset,Math.sin(rads)*camera_offset,camera_height); 
 
     camera.lookAt(scene.position); 
 
     requestAnimationFrame(animate); 
 
     renderer.render(scene, camera); 
 
    } 
 

 
    init(); 
 

 
    animate();
body { 
 
     margin: 0px; 
 
     background-color: #000000; 
 
     overflow: hidden; 
 
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.js"></script>

+0

您在動畫循環中每秒鐘實例化多少'Vector3'?改爲使用'camera.lookAt(scene.position)'。 – WestLangley

+0

非常感謝您的幫助。我能夠使用你的算法並生成隨機地形:D – Rishi

+0

@WestLangley - 謝謝!做出了改變...... – fmacdee

1

如果我理解你的問題,你要求的循環會叫你在3軸x,y,z上的函數。

你可以做這樣的事情:

for (var i = 0; i < SIZEX; i++) { 
    for (var j = 0; j < SIZEY; j++) { 
    for (var k = 0; k < SIZEZ; k++) { 
     createBlock(block, i, j, k, (k == SIZEZ-1), (k == 0), (j == SIZEY-1), (j == 0), (i == SIZEX-1), (i == 0)); 
    } 
    } 
} 

此代碼將在3名維導航。 如果(k == SIZEZ-1)爲真,那麼top將在您的函數中爲true。所有其他人都一樣。

我不知道block是什麼。

我希望你在找什麼。

+0

我可以很容易地從三個維度調用我的功能。我想要這樣的地形:https://threejs.org/examples/?q=minecr#webgl_geometry_minecraft感謝您的幫助! – Rishi

+0

所以你的問題是關於地形生成算法。你可以看看這個:https://en.wikipedia.org/wiki/Diamond-square_algorithm。這些是複雜的數學問題,您必須將這些算法適用於您的應用程序。 – HReynaud

+0

好的,感謝您的幫助 – Rishi