DayDun

Manylands 3d

Aug 27th, 2018
2,764
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class Vector {
  2.     constructor(x, y, z) {
  3.         this.x = x;
  4.         this.y = y;
  5.         this.z = z;
  6.     }
  7.    
  8.     distance(v) {
  9.         return Math.sqrt(
  10.             Math.pow(this.x - v.x, 2) +
  11.             Math.pow(this.y - v.y, 2) +
  12.             Math.pow(this.z - v.z, 2)
  13.         );
  14.     }
  15.    
  16.     length() {
  17.         return Math.sqrt(
  18.             Math.pow(this.x, 2) +
  19.             Math.pow(this.y, 2) +
  20.             Math.pow(this.z, 2)
  21.         );
  22.     }
  23.    
  24.     normal() {
  25.         var length = this.length();
  26.         return new Vector(
  27.             this.x / length,
  28.             this.y / length,
  29.             this.z / length
  30.         );
  31.     }
  32.    
  33.     dot(v) {
  34.         return this.x * v.x + this.y * v.y + this.z * v.z;
  35.     }
  36. }
  37.  
  38. var mat4 = {
  39.     create: function() {
  40.         return new Float32Array([
  41.             1, 0, 0, 0,
  42.             0, 1, 0, 0,
  43.             0, 0, 1, 0,
  44.             0, 0, 0, 1
  45.         ]);
  46.     },
  47.     perspective: function(fovy, aspect, near, far) {
  48.         let f = 1.0 / Math.tan(fovy / 2);
  49.         let nf = 1 / (near - far);
  50.         return new Float32Array([
  51.             f / aspect, 0, 0, 0,
  52.             0, f, 0, 0,
  53.             0, 0, (far + near) * nf, -1,
  54.             0, 0, 2 * far * near * nf, 0
  55.         ]);
  56.     },
  57.     translate: function(x, y, z) {
  58.         return new Float32Array([
  59.             1, 0, 0, x,
  60.             0, 1, 0, y,
  61.             0, 0, 1, z,
  62.             0, 0, 0, 1
  63.         ]);
  64.     },
  65.     scale: function(x, y, z) {
  66.         return new Float32Array([
  67.             x, 0, 0, 0,
  68.             0, y, 0, 0,
  69.             0, 0, z, 0,
  70.             0, 0, 0, 1
  71.         ]);
  72.     },
  73.     rotate: function(theta, x, y, z) {
  74.         var s = Math.sin(theta);
  75.         var c = Math.cos(theta);        return new Float32Array([
  76.             x * x * (1 - c) + c,     x * y * (1 - c) - z * s, x * z * (1 - c) + y * s, 0,
  77.             y * x * (1 - c) + z * s, y * y * (1 - c) + c,     y * z * (1 - c) - x * s, 0,
  78.             x * z * (1 - c) - y * s, y * z * (1 - c) + x * s, z * z * (1 - c) + c,     0,
  79.             0,                       0,                       0,                       1
  80.         ]);
  81.     },
  82.     multiply: function(a, b) {
  83.         return new Float32Array([
  84.             a[0 ] * b[0] + a[1 ] * b[4] + a[2 ] * b[8 ] + a[3 ] * b[12],
  85.             a[0 ] * b[1] + a[1 ] * b[5] + a[2 ] * b[9 ] + a[3 ] * b[13],
  86.             a[0 ] * b[2] + a[1 ] * b[6] + a[2 ] * b[10] + a[3 ] * b[14],
  87.             a[0 ] * b[3] + a[1 ] * b[7] + a[2 ] * b[11] + a[3 ] * b[15],
  88.             a[4 ] * b[0] + a[5 ] * b[4] + a[6 ] * b[8 ] + a[7 ] * b[12],
  89.             a[4 ] * b[1] + a[5 ] * b[5] + a[6 ] * b[9 ] + a[7 ] * b[13],
  90.             a[4 ] * b[2] + a[5 ] * b[6] + a[6 ] * b[10] + a[7 ] * b[14],
  91.             a[4 ] * b[3] + a[5 ] * b[7] + a[6 ] * b[11] + a[7 ] * b[15],
  92.             a[8 ] * b[0] + a[9 ] * b[4] + a[10] * b[8 ] + a[11] * b[12],
  93.             a[8 ] * b[1] + a[9 ] * b[5] + a[10] * b[9 ] + a[11] * b[13],
  94.             a[8 ] * b[2] + a[9 ] * b[6] + a[10] * b[10] + a[11] * b[14],
  95.             a[8 ] * b[3] + a[9 ] * b[7] + a[10] * b[11] + a[11] * b[15],
  96.             a[12] * b[0] + a[13] * b[4] + a[14] * b[8 ] + a[15] * b[12],
  97.             a[12] * b[1] + a[13] * b[5] + a[14] * b[9 ] + a[15] * b[13],
  98.             a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14],
  99.             a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15]
  100.         ]);
  101.     },
  102.     multiplyVector: function(m, v) {
  103.             return new Float32Array([
  104.             m[0 ] * v[0] + m[1 ] * v[1] + m[2 ] * v[2] + m[3 ] * v[3],
  105.             m[4 ] * v[0] + m[5 ] * v[1] + m[6 ] * v[2] + m[7 ] * v[3],
  106.             m[8 ] * v[0] + m[9 ] * v[1] + m[10] * v[2] + m[11] * v[3],
  107.             m[12] * v[0] + m[13] * v[1] + m[14] * v[2] + m[15] * v[3],
  108.         ]);
  109.     }
  110. };
  111.  
  112. class Obj {
  113.     constructor(vertices, faces) {
  114.         this.vertices = vertices;
  115.         this.faces = faces;
  116.        
  117.         this.pos = new Vector(0, 0, 0);
  118.         this.scale = new Vector(1, 1, 1);
  119.         this.rot = new Vector(0, 0, 0);
  120.        
  121.         this.calculateNormals();
  122.     }
  123.    
  124.     calculateNormals() {
  125.         this.normals = [];
  126.         for (var i=0; i<this.faces.length; i++) {
  127.             var face = this.faces[i];
  128.             var normal = new Vector(0, 0, 0);
  129.             for (var j=0; j<face.length; j++) {
  130.                 var current = this.vertices[face[j]];
  131.                 var next = this.vertices[face[(j + 1) % face.length]];
  132.                
  133.                 normal.x += (current[1] - next[1]) * (current[2] + next[2]);
  134.                 normal.y += (current[2] - next[2]) * (current[0] + next[0]);
  135.                 normal.z += (current[0] - next[0]) * (current[1] + next[1]);
  136.             }
  137.             this.normals[i] = normal.normal();
  138.         }
  139.     }
  140. }
  141.  
  142. class Cube extends Obj {
  143.     constructor(pos, scale) {
  144.         var w = scale.x / 2;
  145.         var h = scale.y / 2;
  146.         var d = scale.z / 2;
  147.         super([
  148.             [pos.x - w, pos.y - h, pos.z + d],
  149.             [pos.x - w, pos.y - h, pos.z - d],
  150.             [pos.x + w, pos.y - h, pos.z - d],
  151.             [pos.x + w, pos.y - h, pos.z + d],
  152.             [pos.x + w, pos.y + h, pos.z + d],
  153.             [pos.x + w, pos.y + h, pos.z - d],
  154.             [pos.x - w, pos.y + h, pos.z - d],
  155.             [pos.x - w, pos.y + h, pos.z + d]
  156.         ], [
  157.             [0, 1, 2, 3],
  158.             [3, 2, 5, 4],
  159.             [4, 5, 6, 7],
  160.             [7, 6, 1, 0],
  161.             [7, 0, 3, 4],
  162.             [1, 6, 5, 2]
  163.         ]);
  164.     }
  165. }
  166.  
  167. class Sphere extends Obj {
  168.     constructor(radius, widthSegments, heightSegments) {
  169.         var vertices = [];
  170.         var faces = [];
  171.         var index = 0;
  172.         var grid = [];
  173.         for (var iy=0; iy<=heightSegments; iy++) {
  174.             var verticesRow = [];
  175.             var v = iy / heightSegments;
  176.            
  177.             for (var ix=0; ix<=widthSegments; ix++) {
  178.                 var u = ix / widthSegments;
  179.                
  180.                 vertices.push([
  181.                     -radius * Math.cos(u * Math.PI * 2) * Math.sin(v * Math.PI),
  182.                     radius * Math.cos(v * Math.PI),
  183.                     radius * Math.sin(u * Math.PI * 2) * Math.sin(v * Math.PI)
  184.                 ]);
  185.                
  186.                 verticesRow.push(index++);
  187.             }
  188.            
  189.             grid.push(verticesRow);
  190.         }
  191.        
  192.         for (var iy=0; iy<heightSegments; iy++) {
  193.             for (var ix=0; ix<widthSegments; ix++) {
  194.                 var a = grid[iy][ix + 1];
  195.                 var b = grid[iy][ix];
  196.                 var c = grid[iy + 1][ix];
  197.                 var d = grid[iy + 1][ix + 1];
  198.                
  199.                 if (iy !== 0) faces.push([a, b, d]);
  200.                 if (iy !== heightSegments - 1) faces.push([b, c, d]);
  201.             }
  202.         }
  203.        
  204.         super(vertices, faces);
  205.     }
  206. }
  207.  
  208. var objects = [];
  209.  
  210. /*objects.push(new Cube(
  211.     new Vector(0, 0, 0),
  212.     new Vector(1, 1, 1)
  213. ));*/
  214. objects.push(new Sphere(
  215.     1,
  216.     10,
  217.     10
  218. ));
  219.  
  220. console.log(objects);
  221.  
  222. var camera = {
  223.     pos: new Vector(0, 40, 0),
  224.     scale: new Vector(20, 20, 20),
  225.     rot: new Vector(0, 0, 0)
  226. };
  227.  
  228. function tick() {
  229.     objects[0].rot.x = Date.now() / 1000;
  230.     objects[0].rot.y = Date.now() / 1000;
  231.     objects[0].pos.z = 0;
  232.    
  233.     //objects[1].pos.x = 2;
  234.     //objects[1].pos.z = -2;
  235.     //objects[1].rot.x = Date.now() / 1000;
  236.    
  237.     //camera.rot.y = Date.now() / 1000;
  238.     //camera.pos.z = -400;
  239. }
  240.  
  241. function rotateMatrix(rot) {
  242.     var rotateX = mat4.rotate(rot.x, 1, 0, 0);
  243.     var rotateY = mat4.rotate(rot.y, 0, 1, 0);
  244.     var rotateZ = mat4.rotate(rot.z, 0, 0, 1);
  245.     return mat4.multiply(mat4.multiply(rotateX, rotateY), rotateZ);
  246. }
  247.  
  248. function transformMatrix(pos, scale, rot) {
  249.     var translate = mat4.translate(pos.x, pos.y, pos.z);
  250.     var scale = mat4.scale(scale.x, scale.y, scale.z);
  251.     var rotate = rotateMatrix(rot);
  252.     return mat4.multiply(mat4.multiply(translate, scale), rotate);
  253. }
  254.  
  255. function update(my) {
  256.     var polygons = [];
  257.    
  258.     //console.log(objects);
  259.    
  260.     tick();
  261.    
  262.     var perspective = mat4.perspective(1000, 1, 0.001, 1000);
  263.     var cameraMatrix = transformMatrix(camera.pos, camera.scale, camera.rot);
  264.     //matrix = mat4.multiply(matrix, perspective);
  265.    
  266.     objects.forEach(function(object) {
  267.         var objectMatrix = transformMatrix(object.pos, object.scale, object.rot);
  268.         var matrix = mat4.multiply(cameraMatrix, objectMatrix);
  269.         var rotate = mat4.multiply(rotateMatrix(camera.rot), rotateMatrix(object.rot));
  270.        
  271.         for (var i=0; i<object.faces.length; i++) {
  272.             var face = object.faces[i];
  273.             var points = [];
  274.             var z = 0;
  275.             for (var j=0; j<face.length; j++) {
  276.                 var vertex = object.vertices[face[j]];
  277.                 vertex = mat4.multiplyVector(matrix, [vertex[0], vertex[1], vertex[2], 1]);
  278.                
  279.                 z = Math.min(vertex[2], z);
  280.                
  281.                 points.push({
  282.                     x: vertex[0],
  283.                     y: -vertex[1]
  284.                 });
  285.             }
  286.             var normal = object.normals[i];
  287.             normal = mat4.multiplyVector(rotate, [normal.x, normal.y, normal.z, 1]);
  288.             normal = new Vector(normal[0], normal[1], normal[2]);
  289.             //console.log(normal);
  290.             var shade = Math.floor(normal.dot(new Vector(0, 0, 1)) * 100 + 150);
  291.             polygons.push({
  292.                 z: z,
  293.                 points: points,
  294.                 thickness: 1,
  295.                 rgba: [shade, shade, shade, 1],
  296.                 filled: true
  297.             });
  298.         }
  299.     });
  300.    
  301.     polygons = polygons.sort(function(a, b) {
  302.         return b.z - a.z;
  303.     });
  304.  
  305.     return {
  306.         polygons: polygons
  307.     };
  308. }
Add Comment
Please, Sign In to add comment