2017-03-17 1 views
0

Wie der Titel sagt, würde ich gerne wissen, wie man zufällig erzeugte Netze an der y-Position plottet, die der entsprechenden Y-Position des Terrains in three.js entspricht. Ich habe mir die Dokumente angeschaut und fühle mich, als würde ein Rycaster funktionieren, aber ich kann nur Beispiele sehen, die die Erkennung als Mausereignis verwenden, und nicht vor dem Rendern, also bin ich mir nicht sicher, wie ich es implementieren soll.Wie plane ich zufällige Meshes auf einem Gelände mit einer Heightmap in three.js?

Hier ist mein Code für das Terrain, Heightmap und Mesh-Plotten bisher. Es funktioniert alles technisch, aber wie Sie sehen können, die platesAsses Meshes y-Positionen sitzen gerade auf Null gerade jetzt. Alle Einsichten würden sehr geschätzt werden, ich bin ziemlich neu bei three.js.

Terrain:

 var heightmaploader = new THREE.ImageLoader(); 
    heightmaploader.load(
     "assets/noisemaps/cloud.png", 
     function(img) { 
      data = getHeightData(img); 

      var terrainG = new THREE.PlaneBufferGeometry(700, 700, worldWidth - 1, worldDepth - 1); 
      terrainG.rotateX(-Math.PI/2); 

      var vertices = terrainG.attributes.position.array; 

      for (var i = 0, j = 0, l = vertices.length; i < l; i++, j += 3) { 
       vertices[j + 1] = data[i] * 5; 
      } 

      terrainG.computeFaceNormals(); 
      terrainG.computeVertexNormals(); 

      var material = new THREE.MeshLambertMaterial({ 
       map: terrainT, 
       //side: THREE.DoubleSide, 
       color: 0xffffff, 
       transparent: false, 
      }); 

      terrain = new THREE.Mesh(terrainG, material); 
      terrain.receiveShadow = true; 
      terrain.castShadow = true; 
      terrain.position.y = 0; 
      scene.add(terrain); 

      plotAsset('boulder-photo-01.png', 30, 18, data); 
      plotAsset('boulder-outline-01.png', 20, 20, data); 
      plotAsset('birch-outline-01.png', 10, 50, data); 
      plotAsset('tree-photo-01.png', 20, 50, data); 
      plotAsset('grass-outline-01.png', 10, 20, data); 
      plotAsset('grass-outline-02.png', 10, 20, data); 
     } 
    ); 

Plot Vermögen:

function plotAsset(texturefile, amount, size, array) { 
    console.log(array); 
    var loader = new THREE.TextureLoader(); 
    loader.load(
     "assets/textures/objects/" + texturefile, 
     function(texturefile) { 
      var geometry = new THREE.PlaneGeometry(size, size, 10, 1); 
      var material = new THREE.MeshBasicMaterial({ 
       color: 0xFFFFFF, 
       map: texturefile, 
       side: THREE.DoubleSide, 
       transparent: true, 
       depthWrite: false, 
       depthTest: false, 
       alphaTest: 0.5, 
      }); 

      var uniforms = { texture: { value: texturefile } }; 
      var vertexShader = document.getElementById('vertexShaderDepth').textContent; 
      var fragmentShader = document.getElementById('fragmentShaderDepth').textContent; 

      // add bunch o' stuff 
      for (var i = 0; i < amount; i++) { 
       var scale = Math.random() * (1 - 0.8 + 1) + 0.8; 
       var object = new THREE.Mesh(geometry, material); 
       var x = Math.random() * 400 - 400/2; 
       var z = Math.random() * 400 - 400/2; 
       object.rotation.y = 180 * Math.PI/180; 
       //object.position.y = size * scale/2; 
       object.position.x = x; 
       object.position.z = z; 
       object.position.y = 0; 
       object.castShadow = true; 

       object.scale.x = scale; // random scale 
       object.scale.y = scale; 
       object.scale.z = scale; 

       scene.add(object); 

       object.customDepthMaterial = new THREE.ShaderMaterial({ 
       uniforms: uniforms, 
       vertexShader: vertexShader, 
       fragmentShader: fragmentShader, 
       side: THREE.DoubleSide 
       }); 
      } 
     } 
    ); 
} 

Höhendaten:

function getHeightData(img) { 
    var canvas = document.createElement('canvas'); 
    canvas.width = 2048/8; 
    canvas.height = 2048/8; 
    var context = canvas.getContext('2d'); 

    var size = 2048/8 * 2048/8, 
     data = new Float32Array(size); 

    context.drawImage(img, 0, 0); 

    for (var i = 0; i < size; i++) { 
     data[i] = 0 
    } 

    var imgd = context.getImageData(0, 0, 2048/8, 2048/8); 
    var pix = imgd.data; 

    var j = 0; 
    for (var i = 0, n = pix.length; i < n; i += (4)) { 
     var all = pix[i] + pix[i + 1] + pix[i + 2]; 
     data[j++] = all/40; 
    } 

    return data; 
} 

Antwort

0

Ja, gut mit der THREE.Raycaster() funktioniert. Ein Rycaster hat die .set(origin, direction) Methode. Das einzige, was Sie hier tun müssen, ist, den Ursprungspunkt höher als den höchsten Punkt der Höhenkarte zu setzen.

var n = new THREE.Mesh(...); // the object we want to aling along y-axis 
var collider = new THREE.Raycaster(); 
var shiftY = new THREE.Vector3(); 
var colliderDir = new THREE.Vector3(0, -1, 0); // down along y-axis to the mesh of height map 

shiftY.set(n.position.x, 100, n.position.z); // set the point of the origin 
collider.set(shiftY, colliderDir); //set the ray of the raycaster 
colliderIntersects = collider.intersectObject(plane); // plane is the mesh of height map 
if (colliderIntersects.length > 0){ 
    n.position.y = colliderIntersects[0].point.y; // set the position of the object 
} 

jsfiddle Beispiel

+0

vielen Dank für Ihre Hilfe! – Kits87

+0

Gern geschehen) – prisoner849

Verwandte Themen