render.js (4851B)
1 function render(points, polygons, modes, rotation) { 2 //Modes: 0: polygon, 1-4: wall 3 rotation *= TWO_PI; 4 5 // extract points 6 polygons.forEach(function(polygon, index) { 7 polygons.push([]); 8 polygon.forEach(corner => { 9 polygons[polygons.length - 1].push(Object.assign({}, points[corner])); 10 }); 11 }); 12 polygons = polygons.slice(polygons.length / 2); 13 14 // sort the polygons 15 let rot = createVector(round(cos(rotation) * 1000) / 1000, round(-sin(rotation) * 1000) / 1000); 16 17 polygons.forEach((polygon, index) => { 18 let sum = createVector(0, 0); 19 polygon.forEach(corner => { 20 sum.x += corner.x; 21 sum.y += corner.y; 22 sum.z += corner.z; 23 }); 24 sum.x /= polygon.length; 25 sum.y /= polygon.length; 26 sum.z /= polygon.length; 27 polygon.average = Object.assign({}, sum); 28 polygon.depth = depth(polygon.average, rot); 29 polygon.mode = modes[index]; 30 polygon.size = (polygon.mode > 0) ? SIZE : 1; 31 polygon.depth *= polygon.size; 32 }); 33 34 polygons.sort(function(a, b) { 35 return a.depth - b.depth; 36 }); 37 38 // draw to the screen 39 polygons.forEach(polygon => { 40 if (polygon.mode !== 0) { 41 drawWall(polygon.mode, polygon, rotation); 42 } else { 43 drawPolygon(polygon, rotation); 44 } 45 }); 46 } 47 48 function depth(point, rotation) { 49 return -point.x * rotation.y - point.y * rotation.x; 50 } 51 52 function drawPolygon(points, rotation) { 53 points.forEach(function(item) { 54 let newVec = calc3D(item.x, item.y, item.z - ANGLE, rotation); 55 item.x = newVec.x; 56 item.y = newVec.y; 57 }); 58 beginShape(); 59 points.forEach(function(item) { 60 vertex(CENTER.x + item.x, CENTER.y - item.y - ANGLE + SIZE / 2 + addHeight); 61 }); 62 vertex(CENTER.x + points[0].x, CENTER.y - points[0].y - ANGLE + SIZE / 2 + addHeight); 63 endShape(); 64 } 65 66 function drawWall(side, points, rotation) { 67 let endX; 68 let startX; 69 let rot = createVector(round(cos(rotation) * 1000) / 1000, round(-sin(rotation) * 1000) / 1000); 70 let swap = depth(points[0], rot) > depth(points[points.length - 1], rot); 71 points.forEach(function(item, index) { 72 let newVec = calc3D(item.x, item.y, item.z - ANGLE, rotation); 73 item.x = newVec.x; 74 item.y = newVec.y; 75 if (index == 0) { 76 startX = newVec.x; 77 } 78 if (index == points.length - 1) { 79 endX = newVec.x; 80 } 81 }); 82 if (swap)[startX, endX] = [endX, startX]; 83 if ((abs(endX) - abs(startX)) < 0) { 84 beginShape(); 85 switch (side) { 86 case 1: 87 vertex(CENTER.x + points[0].x, 0); 88 break; 89 case 2: 90 vertex(WIDTH, CENTER.y - points[0].y - ANGLE + SIZE / 2 + addHeight); 91 break; 92 case 3: 93 vertex(CENTER.x + points[0].x, HEIGHT + addHeight); 94 break; 95 case 4: 96 vertex(0, CENTER.y - points[0].y - ANGLE + SIZE / 2 + addHeight); 97 break; 98 } 99 points.forEach(function(item) { 100 vertex(CENTER.x + item.x, CENTER.y - item.y - ANGLE + SIZE / 2 + addHeight); 101 }); 102 switch (side) { 103 case 1: 104 vertex(CENTER.x + points[points.length - 1].x, 0); 105 break; 106 case 2: 107 vertex(WIDTH, CENTER.y - points[points.length - 1].y - ANGLE + SIZE / 2 + addHeight); 108 break; 109 case 3: 110 vertex(CENTER.x + points[points.length - 1].x, HEIGHT + addHeight); 111 break; 112 case 4: 113 vertex(0, CENTER.y - points[points.length - 1].y - ANGLE + SIZE / 2 + addHeight); 114 break; 115 } 116 endShape(); 117 } 118 } 119 120 function calc3D(x, y, z, rotation) { 121 122 let rot = createVector(round(cos(rotation) * 1000) / 1000, round(-sin(rotation) * 1000) / 1000); 123 let out3D = createVector(x * rot.x - y * rot.y, x * rot.y + y * rot.x, z); 124 125 let zIsZero = false; 126 let xIsZero = false; 127 if (out3D.z === 0) { 128 out3D.z = 1; 129 zIsZero = true; 130 } 131 if (out3D.x === 0) { 132 out3D.x = 1; 133 xIsZero = true; 134 } 135 let start1 = CENTER_HORIZON; 136 let start2 = LEFT_HORIZON; 137 let end1 = createVector(out3D.x, out3D.z); 138 let end2 = createVector(out3D.x + out3D.y, out3D.z); 139 140 // Two lines f(x) = m * x + n 141 let m1 = (end1.y - start1.y) / (end1.x - start1.x); 142 let m2 = (end2.y - start2.y) / (end2.x - start2.x); 143 let n1 = end1.y - end1.x * m1; 144 let n2 = end2.y - end2.x * m2; 145 146 let crossX = (n2 - n1) / (m1 - m2); 147 let crossY = zIsZero ? 0 : crossX * m1 + n1; 148 if (xIsZero) { 149 crossX = 0; 150 } 151 return createVector(crossX, crossY); 152 }