Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Vector {
- constructor(x, y, z) {
- this.x = x;
- this.y = y;
- this.z = z;
- }
- distance(v) {
- return Math.sqrt(
- Math.pow(this.x - v.x, 2) +
- Math.pow(this.y - v.y, 2) +
- Math.pow(this.z - v.z, 2)
- );
- }
- length() {
- return Math.sqrt(
- Math.pow(this.x, 2) +
- Math.pow(this.y, 2) +
- Math.pow(this.z, 2)
- );
- }
- normal() {
- var length = this.length();
- return new Vector(
- this.x / length,
- this.y / length,
- this.z / length
- );
- }
- dot(v) {
- return this.x * v.x + this.y * v.y + this.z * v.z;
- }
- }
- var mat4 = {
- create: function() {
- return new Float32Array([
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1
- ]);
- },
- perspective: function(fovy, aspect, near, far) {
- let f = 1.0 / Math.tan(fovy / 2);
- let nf = 1 / (near - far);
- return new Float32Array([
- f / aspect, 0, 0, 0,
- 0, f, 0, 0,
- 0, 0, (far + near) * nf, -1,
- 0, 0, 2 * far * near * nf, 0
- ]);
- },
- translate: function(x, y, z) {
- return new Float32Array([
- 1, 0, 0, x,
- 0, 1, 0, y,
- 0, 0, 1, z,
- 0, 0, 0, 1
- ]);
- },
- scale: function(x, y, z) {
- return new Float32Array([
- x, 0, 0, 0,
- 0, y, 0, 0,
- 0, 0, z, 0,
- 0, 0, 0, 1
- ]);
- },
- rotate: function(theta, x, y, z) {
- var s = Math.sin(theta);
- var c = Math.cos(theta); return new Float32Array([
- x * x * (1 - c) + c, x * y * (1 - c) - z * s, x * z * (1 - c) + y * s, 0,
- y * x * (1 - c) + z * s, y * y * (1 - c) + c, y * z * (1 - c) - x * s, 0,
- x * z * (1 - c) - y * s, y * z * (1 - c) + x * s, z * z * (1 - c) + c, 0,
- 0, 0, 0, 1
- ]);
- },
- multiply: function(a, b) {
- return new Float32Array([
- a[0 ] * b[0] + a[1 ] * b[4] + a[2 ] * b[8 ] + a[3 ] * b[12],
- a[0 ] * b[1] + a[1 ] * b[5] + a[2 ] * b[9 ] + a[3 ] * b[13],
- a[0 ] * b[2] + a[1 ] * b[6] + a[2 ] * b[10] + a[3 ] * b[14],
- a[0 ] * b[3] + a[1 ] * b[7] + a[2 ] * b[11] + a[3 ] * b[15],
- a[4 ] * b[0] + a[5 ] * b[4] + a[6 ] * b[8 ] + a[7 ] * b[12],
- a[4 ] * b[1] + a[5 ] * b[5] + a[6 ] * b[9 ] + a[7 ] * b[13],
- a[4 ] * b[2] + a[5 ] * b[6] + a[6 ] * b[10] + a[7 ] * b[14],
- a[4 ] * b[3] + a[5 ] * b[7] + a[6 ] * b[11] + a[7 ] * b[15],
- a[8 ] * b[0] + a[9 ] * b[4] + a[10] * b[8 ] + a[11] * b[12],
- a[8 ] * b[1] + a[9 ] * b[5] + a[10] * b[9 ] + a[11] * b[13],
- a[8 ] * b[2] + a[9 ] * b[6] + a[10] * b[10] + a[11] * b[14],
- a[8 ] * b[3] + a[9 ] * b[7] + a[10] * b[11] + a[11] * b[15],
- a[12] * b[0] + a[13] * b[4] + a[14] * b[8 ] + a[15] * b[12],
- a[12] * b[1] + a[13] * b[5] + a[14] * b[9 ] + a[15] * b[13],
- a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14],
- a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15]
- ]);
- },
- multiplyVector: function(m, v) {
- return new Float32Array([
- m[0 ] * v[0] + m[1 ] * v[1] + m[2 ] * v[2] + m[3 ] * v[3],
- m[4 ] * v[0] + m[5 ] * v[1] + m[6 ] * v[2] + m[7 ] * v[3],
- m[8 ] * v[0] + m[9 ] * v[1] + m[10] * v[2] + m[11] * v[3],
- m[12] * v[0] + m[13] * v[1] + m[14] * v[2] + m[15] * v[3],
- ]);
- }
- };
- class Obj {
- constructor(vertices, faces) {
- this.vertices = vertices;
- this.faces = faces;
- this.pos = new Vector(0, 0, 0);
- this.scale = new Vector(1, 1, 1);
- this.rot = new Vector(0, 0, 0);
- this.calculateNormals();
- }
- calculateNormals() {
- this.normals = [];
- for (var i=0; i<this.faces.length; i++) {
- var face = this.faces[i];
- var normal = new Vector(0, 0, 0);
- for (var j=0; j<face.length; j++) {
- var current = this.vertices[face[j]];
- var next = this.vertices[face[(j + 1) % face.length]];
- normal.x += (current[1] - next[1]) * (current[2] + next[2]);
- normal.y += (current[2] - next[2]) * (current[0] + next[0]);
- normal.z += (current[0] - next[0]) * (current[1] + next[1]);
- }
- this.normals[i] = normal.normal();
- }
- }
- }
- class Cube extends Obj {
- constructor(pos, scale) {
- var w = scale.x / 2;
- var h = scale.y / 2;
- var d = scale.z / 2;
- super([
- [pos.x - w, pos.y - h, pos.z + d],
- [pos.x - w, pos.y - h, pos.z - d],
- [pos.x + w, pos.y - h, pos.z - d],
- [pos.x + w, pos.y - h, pos.z + d],
- [pos.x + w, pos.y + h, pos.z + d],
- [pos.x + w, pos.y + h, pos.z - d],
- [pos.x - w, pos.y + h, pos.z - d],
- [pos.x - w, pos.y + h, pos.z + d]
- ], [
- [0, 1, 2, 3],
- [3, 2, 5, 4],
- [4, 5, 6, 7],
- [7, 6, 1, 0],
- [7, 0, 3, 4],
- [1, 6, 5, 2]
- ]);
- }
- }
- class Sphere extends Obj {
- constructor(radius, widthSegments, heightSegments) {
- var vertices = [];
- var faces = [];
- var index = 0;
- var grid = [];
- for (var iy=0; iy<=heightSegments; iy++) {
- var verticesRow = [];
- var v = iy / heightSegments;
- for (var ix=0; ix<=widthSegments; ix++) {
- var u = ix / widthSegments;
- vertices.push([
- -radius * Math.cos(u * Math.PI * 2) * Math.sin(v * Math.PI),
- radius * Math.cos(v * Math.PI),
- radius * Math.sin(u * Math.PI * 2) * Math.sin(v * Math.PI)
- ]);
- verticesRow.push(index++);
- }
- grid.push(verticesRow);
- }
- for (var iy=0; iy<heightSegments; iy++) {
- for (var ix=0; ix<widthSegments; ix++) {
- var a = grid[iy][ix + 1];
- var b = grid[iy][ix];
- var c = grid[iy + 1][ix];
- var d = grid[iy + 1][ix + 1];
- if (iy !== 0) faces.push([a, b, d]);
- if (iy !== heightSegments - 1) faces.push([b, c, d]);
- }
- }
- super(vertices, faces);
- }
- }
- var objects = [];
- /*objects.push(new Cube(
- new Vector(0, 0, 0),
- new Vector(1, 1, 1)
- ));*/
- objects.push(new Sphere(
- 1,
- 10,
- 10
- ));
- console.log(objects);
- var camera = {
- pos: new Vector(0, 40, 0),
- scale: new Vector(20, 20, 20),
- rot: new Vector(0, 0, 0)
- };
- function tick() {
- objects[0].rot.x = Date.now() / 1000;
- objects[0].rot.y = Date.now() / 1000;
- objects[0].pos.z = 0;
- //objects[1].pos.x = 2;
- //objects[1].pos.z = -2;
- //objects[1].rot.x = Date.now() / 1000;
- //camera.rot.y = Date.now() / 1000;
- //camera.pos.z = -400;
- }
- function rotateMatrix(rot) {
- var rotateX = mat4.rotate(rot.x, 1, 0, 0);
- var rotateY = mat4.rotate(rot.y, 0, 1, 0);
- var rotateZ = mat4.rotate(rot.z, 0, 0, 1);
- return mat4.multiply(mat4.multiply(rotateX, rotateY), rotateZ);
- }
- function transformMatrix(pos, scale, rot) {
- var translate = mat4.translate(pos.x, pos.y, pos.z);
- var scale = mat4.scale(scale.x, scale.y, scale.z);
- var rotate = rotateMatrix(rot);
- return mat4.multiply(mat4.multiply(translate, scale), rotate);
- }
- function update(my) {
- var polygons = [];
- //console.log(objects);
- tick();
- var perspective = mat4.perspective(1000, 1, 0.001, 1000);
- var cameraMatrix = transformMatrix(camera.pos, camera.scale, camera.rot);
- //matrix = mat4.multiply(matrix, perspective);
- objects.forEach(function(object) {
- var objectMatrix = transformMatrix(object.pos, object.scale, object.rot);
- var matrix = mat4.multiply(cameraMatrix, objectMatrix);
- var rotate = mat4.multiply(rotateMatrix(camera.rot), rotateMatrix(object.rot));
- for (var i=0; i<object.faces.length; i++) {
- var face = object.faces[i];
- var points = [];
- var z = 0;
- for (var j=0; j<face.length; j++) {
- var vertex = object.vertices[face[j]];
- vertex = mat4.multiplyVector(matrix, [vertex[0], vertex[1], vertex[2], 1]);
- z = Math.min(vertex[2], z);
- points.push({
- x: vertex[0],
- y: -vertex[1]
- });
- }
- var normal = object.normals[i];
- normal = mat4.multiplyVector(rotate, [normal.x, normal.y, normal.z, 1]);
- normal = new Vector(normal[0], normal[1], normal[2]);
- //console.log(normal);
- var shade = Math.floor(normal.dot(new Vector(0, 0, 1)) * 100 + 150);
- polygons.push({
- z: z,
- points: points,
- thickness: 1,
- rgba: [shade, shade, shade, 1],
- filled: true
- });
- }
- });
- polygons = polygons.sort(function(a, b) {
- return b.z - a.z;
- });
- return {
- polygons: polygons
- };
- }
Add Comment
Please, Sign In to add comment