terrain-generator

digital terrain generation and animation
git clone https://tongong.net/git/terrain-generator.git
Log | Files | Refs | README

terrain.js (3680B)


      1 class Terrain {
      2 
      3     constructor(dimension, filled) {
      4         this.dimension = dimension;
      5         this.field = [];
      6 
      7         let length = dimension * 2 - 1;
      8         for (let i = 0; i < length; i++) {
      9             this.field.push([]);
     10             for (let j = 0; j < length; j++) {
     11                 this.field[i].push(filled ? Math.random() : 0.5);
     12             }
     13         }
     14     }
     15 
     16     transform(destination, speed) {
     17         let length = this.dimension * 2 - 1;
     18         for (let i = 0; i < length; i++) {
     19             for (let j = 0; j < length; j++) {
     20                 this.field[i][j] += (destination.field[i][j] - this.field[i][j]) * speed;
     21             }
     22         }
     23     }
     24 
     25     scaleUp() {
     26         let ret = new Terrain(this.dimension * 2 - 1, false);
     27 
     28         let length = this.dimension * 2 - 1;
     29         for (let i = 0; i < length; i++) {
     30             for (let j = 0; j < length; j++) {
     31                 ret.field[2 * i][2 * j] = this.field[i][j];
     32                 if (i < length - 1) {
     33                     ret.field[2 * i + 1][2 * j] = (this.field[i][j] + this.field[i + 1][j]) / 2;
     34                 }
     35                 if (j < length - 1) {
     36                     ret.field[2 * i][2 * j + 1] = (this.field[i][j] + this.field[i][j + 1]) / 2;
     37                 }
     38                 if (i < length - 1 && j < length - 1) {
     39                     ret.field[2 * i + 1][2 * j + 1] = (this.field[i][j] + this.field[i + 1][j + 1]) / 2;
     40                 }
     41             }
     42         }
     43 
     44         return ret;
     45     }
     46 
     47     addRandom(factor) {
     48         let ret = new Terrain(this.dimension, false);
     49 
     50         length = this.dimension * 2 - 1;
     51         for (let i = 0; i < length; i++) {
     52             for (let j = 0; j < length; j++) {
     53                 ret.field[i][j] = this.field[i][j] * (1 - factor) + Math.random() * factor;
     54             }
     55         }
     56         return ret;
     57     }
     58 
     59     render(scaleXY, scaleZ, rotation) {
     60         let points = [];
     61         let length = this.dimension * 2 - 1;
     62 
     63         //Terrain points
     64         for (let i = 0; i < length; i++) {
     65             for (let j = 0; j < length; j++) {
     66                 points.push(tri(createVector(
     67                     (j - this.dimension + 1) * scaleXY,
     68                     (i - this.dimension + 1) * scaleXY,
     69                     this.field[i][j] * scaleZ
     70                 )));
     71             }
     72         }
     73 
     74         //Terrain triangles
     75         let polygons = [];
     76         let modes = [];
     77         for (let i = 0; i < length - 1; i++) {
     78             for (let j = 0; j < length - 1; j++) {
     79                 if (j - i + 1 < this.dimension && i - j < this.dimension) {
     80                     modes.push(0, 0);
     81                     polygons.push([i * length + j, i * length + j + 1, (i + 1) * length + j + 1]);
     82                     polygons.push([j * length + i, (j + 1) * length + i, (j + 1) * length + i + 1]);
     83                 }
     84             }
     85         }
     86 
     87         //Walls
     88         let walls = [
     89             [],
     90             [],
     91             [],
     92             [],
     93             [],
     94             []
     95         ];
     96         for (let i = 0; i < this.dimension; i++) {
     97             walls[0].push(i);
     98             walls[1].push(i * length);
     99             walls[2].push(this.dimension + i * (length + 1) - 1);
    100             walls[3].push((this.dimension - 1) * length + i * (length + 1));
    101             walls[4].push(length * length - i - 1);
    102             walls[5].push(length * (length - i) - 1);
    103         }
    104         polygons.push(walls[0], walls[1], walls[2], walls[3], walls[4], walls[5]);
    105         modes.push(3, 3, 3, 3, 3, 3);
    106 
    107         render(points, polygons, modes, rotation);
    108     }
    109 }
    110 
    111 function tri(input) {
    112     return createVector(
    113         input.x - input.y / 2,
    114         input.y * sqrt(3 / 4),
    115         input.z
    116     );
    117 }