ben

Members
  • Content count

    120
  • Joined

  • Last visited

  • Days Won

    1

Community Reputation

1 Neutral

About ben

  • Rank
    Advanced Member

Profile Information

  • Gender Not Telling
  1. The right (=generic) way to do backface culling is indeed dot producting the normal vector with the view vector, or (same thing, different pov), look at the z component of the normal vector in the viewspace. But normal vectors are not provided with the model in my example... The cross product technique of neam (look at the ordering of vertices in a triangle on the screen: clockwise means visible, ccw means hidden) works when the model is designed for it, which isn't the case here. To be honest, I just built a quick model for a demo, not planning on backface culling. Now, we should aim at something more precise in order to get one of these methods to work (preferrably the second one, which is computationnaly cheaper), but I'm out of time at the moment.
  2. good luck and have fun -- being a bit of a masochist myself, i went for the "who needs a stock cross compiler when you can make your own" option, which definitely was not a good choice for the comfort of development !
  3. they should be in the html files. i cannot check on github right now, but i copy it below -- it definitely shows a rabbit in my firefox. about the proj_matrices.vhd files, it just contains the values for the projection matrices : if you do not need the animation, you can use a fixed matrix, as in the html demo. <html> <head> <title>3d</title> <script type="text/javascript"> /***************************************************************/ /* fixed points operations */ /***************************************************************/ // from -1024 to 1023.99, with a fixed precision of 1/256 const intBits = 10; const fracBits = 8; var mask = (1<<(intBits+fracBits))-1; var sign = (1<<(intBits+fracBits-1)); var sign_mask = ~mask; function fromNum(n) { var c = (n*(1<<fracBits))&mask; if (c&sign) { c |= sign_mask; } return c; } function round(a) { return a>>fracBits; } function add(a, { var c = (a+&mask; if (c&sign) { c |= sign_mask; } return c; } function sub(a, { var c = (a-&mask; if (c&sign) { c |= sign_mask; } return c; } function mul(a, { if (a&sign) { a |= sign_mask; } if (b&sign) { b |= sign_mask; } var c = ((a* >> fracBits)&mask; if (c&sign) { c |= sign_mask; } return c; } function div(a, { if (a&sign) { a |= sign_mask; } if (b&sign) { b |= sign_mask; } var c = ((a<<fracBits) / &mask; if (c&sign) { c |= sign_mask; } return c; } /******************************************************************/ /* matrix operations */ /* note: we use floating point arithmetic, and convert in the end */ /******************************************************************/ function matrix_mult(a, { var r = []; for (var i=0; i<4; i++) { r[i] = []; for (var j=0; j<4; j++) { r[i][j] = a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j] + a[i][3]*b[3][j]; } } return r; } function identity_matrix() { var r = []; for (var i=0; i<4; i++) { r[i] = []; for (var j=0; j<4; j++) { r[i][j] = (i==j)?1:0; } } return r; } function translation_matrix(dx,dy,dz) { var r = identity_matrix(); r[0][3] = dx; r[1][3] = dy; r[2][3] = dz; return r; } function rotation_matrix(x,y,z,angle) { var r = Math.sqrt(x*x+y*y+z*z); x /= r; y /= r; z /= r; var c = Math.cos(angle); var s = Math.sin(angle); var r = []; for (var i=0; i<4; i++) { r[i] = []; for (var j=0; j<4; j++) { r[i][j] = 0; } } r[0][0] = x*x*(1-c) + c; r[0][1] = x*y*(1-c) - z*s; r[0][2] = x*z*(1-c) + y*s; r[1][0] = y*x*(1-c) + z*s; r[1][1] = y*y*(1-c) + c; r[1][2] = y*z*(1-c) - x*s; r[2][0] = z*x*(1-c) - y*s; r[2][1] = z*y*(1-c) + x*s; r[2][2] = z*z*(1-c) + c; r[3][3] = 1; return r; } // frustum matrix function projection_matrix(zNear,zFar) { var matrix = []; for (var i=0; i<4; i++) { matrix[i] = []; for (var j=0; j<4; j++) { matrix[i][j] = 0; } } matrix[0][0] = zNear; matrix[1][1] = zNear; matrix[2][2] = (zFar+zNear)/(zNear-zFar); matrix[2][3] = (2*zFar*zNear)/(zNear-zFar); matrix[3][2] = -1; return matrix; } // converts a matrix to the fixed point format function conv_matrix(matrix) { for (var i=0; i<4; i++) { for (var j=0; j<4; j++) { matrix[i][j] = fromNum(matrix[i][j]); } } } /******************************************************************/ /* transform raw geometry data into screen coordinates points */ /* and easy to render triangles */ /******************************************************************/ // apply the projection matrix, multiply by 128 to be adequate for a 256*256 display function transform_points(matrix, points) { var screen_points = []; for (var i in points) { var p = points[i]; var x = add(add(add(mul(matrix[0][0],p.x), mul(matrix[0][1],p.y)), mul(matrix[0][2],p.z)), matrix[0][3]); var y = add(add(add(mul(matrix[1][0],p.x), mul(matrix[1][1],p.y)), mul(matrix[1][2],p.z)), matrix[1][3]); var z = add(add(add(mul(matrix[2][0],p.x), mul(matrix[2][1],p.y)), mul(matrix[2][2],p.z)), matrix[2][3]); var w = add(add(add(mul(matrix[3][0],p.x), mul(matrix[3][1],p.y)), mul(matrix[3][2],p.z)), matrix[3][3]); x = div(x,w); y = div(y,w); z = div(z,w); x = mul(x,fromNum(128)); y = mul(y,fromNum(128)); z = mul(z,fromNum(128)); screen_points[i] = {x:x, y:y, z:z}; } return screen_points; } // prepare the triangles for a per-line rendering function transform_triangles(screen_points, triangles) { var screen_triangles = []; for (var i in triangles) { var t = triangles[i]; var a = screen_points[t.a]; var b = screen_points[t.b]; var c = screen_points[t.c]; // sort points var tmp; if (b.y<a.y) { tmp=a; a=b; b=tmp; }; if (c.y<b.y) { tmp=b; b=c; c=tmp; }; if (b.y<a.y) { tmp=a; a=b; b=tmp; }; var y0 = round(a.y); var y1 = round(b.y); var y2 = round(c.y); var dx01 = div(sub(b.x,a.x),sub(b.y,a.y)); var dx02 = div(sub(c.x,a.x),sub(c.y,a.y)); var dx12 = div(sub(c.x,b.x),sub(c.y,b.y)); var dz01 = div(sub(b.z,a.z),sub(b.y,a.y)); var dz02 = div(sub(c.z,a.z),sub(c.y,a.y)); var dz12 = div(sub(c.z,b.z),sub(c.y,b.y));// if (y0!=y1) { if ((b.y-a.y)>fromNum(1)) { screen_triangles.push({ y0: y0, y1: y1, dir: 0, x: a.x, z: a.z, dx0: (dx01<dx02) ? dx01 : dx02, dx1: (dx01<dx02) ? dx02 : dx01, dz0: (dx01<dx02) ? dz01 : dz02, dz1: (dx01<dx02) ? dz02 : dz01, color:t.d }); }// if (y1!=y2) { if ((c.y-b.y)>fromNum(1)) { screen_triangles.push({ y0: y1, y1: y2, dir: 1, x: c.x, z: c.z, dx0: (dx02>dx12) ? dx02 : dx12, dx1: (dx02>dx12) ? dx12 : dx02, dz0: (dx02>dx12) ? dz02 : dz12, dz1: (dx02>dx12) ? dz12 : dz02, color:t.d }); } } return screen_triangles; } /******************************************************************/ /* drawing process */ /******************************************************************/ // draw a segment from xl to xr on the current line function draw_segment(zbuffer,cbuffer,y, xl,xr,zl,dz,color) { xl += 128; xr += 128; var z = zl; for (var x=xl; x<=xr; x++) { var oldz = zbuffer[x]; if (oldz<z) { zbuffer[x] = z; cbuffer[x] = color; } z = add(z,dz); } } // clears a line, and draws all triangles that intersect it function draw_line(screen_triangles, zbuffer,cbuffer,y) { for (var x=0; x<256; x++) { zbuffer[x] = fromNum(0); cbuffer[x] = 0; } for (var i in screen_triangles) { var t = screen_triangles[i]; if ((t.y0<=y) && (y<t.y1)) { var dy = y - (t.dir?t.y1:t.y0); var xl = add(t.x, dy*t.dx0); var xr = add(t.x, dy*t.dx1); var zl = add(t.z, dy*t.dz0); var zr = add(t.z, dy*t.dz1); var dz = div(sub(zr,zl),sub(xr,xl)); draw_segment(zbuffer,cbuffer,y, round(xl),round(xr),zl,dz,t.color); } } } /******************************************************************/ /* wrap up */ /******************************************************************/ function run() { // get the html5 context var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); var data = context.createImageData(256,256); // prepare the projection matrix var matrix = identity_matrix(); matrix = matrix_mult(rotation_matrix(0,1,0,31*(2*Math.PI/64)), matrix); matrix = matrix_mult(rotation_matrix(1,0,0,-0.5), matrix); matrix = matrix_mult(translation_matrix(0,0,10), matrix); matrix = matrix_mult(projection_matrix(5,50), matrix); conv_matrix(matrix); // process the raw data var screen_points = transform_points(matrix, points); var screen_triangles = transform_triangles(screen_points, triangles); // draw lines var cbuffer = []; var zbuffer = []; for (var y=128-128; y<256; y++) { draw_line(screen_triangles, zbuffer,cbuffer,y-128); for (var x=0; x<256; x++) { var c = palette[cbuffer[x]]; data.data[4*(x + 256*y) + 0] = (c>>16)&0xff; data.data[4*(x + 256*y) + 1] = (c>> 8)&0xff; data.data[4*(x + 256*y) + 2] = (c>> 0)&0xff; data.data[4*(x + 256*y) + 3] = 0xff; } } // display result context.putImageData(data,0,0); } // test mesh : a cubevar points = [ { x:0x00014, y:0x000d6, z:0x3ff8c }, { x:0x00012, y:0x000c4, z:0x3ff98 }, { x:0x3fffa, y:0x000aa, z:0x3ffc4 }, { x:0x3ffda, y:0x00094, z:0x3ffe4 }, { x:0x3ffb4, y:0x00082, z:0x3fff8 }, { x:0x3ff92, y:0x00068, z:0x00012 }, { x:0x3ff9c, y:0x00040, z:0x00014 }, { x:0x3ffaa, y:0x0003a, z:0x00048 }, { x:0x3ffae, y:0x00022, z:0x0007e }, { x:0x3ffac, y:0x3fffc, z:0x000a8 }, { x:0x3ffac, y:0x3ffd0, z:0x000ba }, { x:0x3ffac, y:0x3ffa0, z:0x000b6 }, { x:0x3ffa6, y:0x3ff72, z:0x000b4 }, { x:0x3ff98, y:0x3ff4a, z:0x000a0 }, { x:0x3ff78, y:0x3ff30, z:0x000a0 }, { x:0x3ff60, y:0x3ff10, z:0x000b0 }, { x:0x3ff7e, y:0x3ff32, z:0x000a0 }, { x:0x00004, y:0x000b8, z:0x3ffae }, { x:0x3fffa, y:0x000fc, z:0x3ffb6 }, { x:0x3ffe4, y:0x000c4, z:0x3ffd4 }, { x:0x3ffc2, y:0x000a2, z:0x0000c }, { x:0x3ff92, y:0x0008a, z:0x00032 }, { x:0x3ff88, y:0x00068, z:0x0005e }, { x:0x3ff8e, y:0x0004c, z:0x0007e }, { x:0x3ff90, y:0x0002c, z:0x00092 }, { x:0x3ff8a, y:0x00006, z:0x0009c }, { x:0x3ff8a, y:0x3ffde, z:0x000b6 }, { x:0x3ff90, y:0x3ffb6, z:0x000c4 }, { x:0x3ff94, y:0x3ff8a, z:0x000ba }, { x:0x3ff92, y:0x3ff60, z:0x00098 }, { x:0x3ff7c, y:0x3ff30, z:0x0008c }, { x:0x3ff62, y:0x3ff14, z:0x000aa }, { x:0x3ff7e, y:0x3ff2e, z:0x000b0 }, { x:0x3ff9e, y:0x3ff4a, z:0x000a2 }, { x:0x3ffea, y:0x000a0, z:0x3ffd6 }, { x:0x3ffca, y:0x000d0, z:0x3ffc6 }, { x:0x3ffbc, y:0x000cc, z:0x00002 }, { x:0x3ff8e, y:0x00098, z:0x00030 }, { x:0x3ff74, y:0x0008c, z:0x00088 }, { x:0x3ff64, y:0x00064, z:0x000aa }, { x:0x3ff62, y:0x0003a, z:0x000c6 }, { x:0x3ff68, y:0x00012, z:0x000b8 }, { x:0x3ff62, y:0x3ffea, z:0x000b0 }, { x:0x3ff6a, y:0x3ffbc, z:0x000c4 }, { x:0x3ff78, y:0x3ff90, z:0x000bc }, { x:0x3ff8a, y:0x3ff6c, z:0x0009a }, { x:0x3ff86, y:0x3ff32, z:0x00082 }, { x:0x3ff5e, y:0x3ff14, z:0x000a0 }, { x:0x3ff82, y:0x3ff18, z:0x000ca }, { x:0x3ff9e, y:0x3ff3a, z:0x000aa }, { x:0x3ffa6, y:0x3ff72, z:0x000b4 }, { x:0x3ffc6, y:0x0008c, z:0x3ffe8 }, { x:0x3ffa6, y:0x000b0, z:0x3ffde }, { x:0x3ff90, y:0x000ae, z:0x00018 }, { x:0x3ff5c, y:0x00096, z:0x00058 }, { x:0x3ff3e, y:0x00086, z:0x0009e }, { x:0x3ff2c, y:0x0005a, z:0x000d2 }, { x:0x3ff32, y:0x0001e, z:0x000da }, { x:0x3ff44, y:0x3fffa, z:0x000b0 }, { x:0x3ff42, y:0x3ffc6, z:0x000ac }, { x:0x3ff56, y:0x3ff94, z:0x000b0 }, { x:0x3ff74, y:0x3ff6e, z:0x00098 }, { x:0x3ff8a, y:0x3ff40, z:0x0007c }, { x:0x3ff5a, y:0x3ff10, z:0x0008a }, { x:0x3ff84, y:0x3ff04, z:0x000bc }, { x:0x3ffa4, y:0x3ff2c, z:0x000b4 }, { x:0x3ffac, y:0x3ff6a, z:0x000b2 }, { x:0x3ffb0, y:0x3ff9e, z:0x000b8 }, { x:0x3ff9e, y:0x00076, z:0x3fffe }, { x:0x3ff88, y:0x00098, z:0x3fff6 }, { x:0x3ff66, y:0x00094, z:0x00030 }, { x:0x3ff2a, y:0x00092, z:0x00058 }, { x:0x3ff10, y:0x0006c, z:0x00086 }, { x:0x3ff08, y:0x00034, z:0x000a2 }, { x:0x3ff1a, y:0x00000, z:0x0009c }, { x:0x3ff24, y:0x3ffd2, z:0x0008c }, { x:0x3ff32, y:0x3ff98, z:0x0008e }, { x:0x3ff5a, y:0x3ff6c, z:0x00082 }, { x:0x3ff88, y:0x3ff50, z:0x00074 }, { x:0x3ff66, y:0x3ff16, z:0x00070 }, { x:0x3ff84, y:0x3ff06, z:0x000a0 }, { x:0x3ffb4, y:0x3ff26, z:0x000b4 }, { x:0x3ffb4, y:0x3ff5a, z:0x000b2 }, { x:0x3ffbc, y:0x3ff98, z:0x000ba }, { x:0x3ffae, y:0x3ffce, z:0x000b4 }, { x:0x3ff76, y:0x00076, z:0x3fffc }, { x:0x3ff62, y:0x0008e, z:0x00008 }, { x:0x3ff38, y:0x00094, z:0x00020 }, { x:0x3ff10, y:0x00078, z:0x00034 }, { x:0x3ff06, y:0x00044, z:0x0004c }, { x:0x3ff06, y:0x00010, z:0x00062 }, { x:0x3ff16, y:0x3ffe0, z:0x00064 }, { x:0x3ff1e, y:0x3ffa2, z:0x00064 }, { x:0x3ff46, y:0x3ff6e, z:0x00060 }, { x:0x3ff7c, y:0x3ff52, z:0x00056 }, { x:0x3ff7a, y:0x3ff1e, z:0x0005c }, { x:0x3ff82, y:0x3ff04, z:0x0008c }, { x:0x3ffb2, y:0x3ff14, z:0x000b8 }, { x:0x3ffcc, y:0x3ff52, z:0x000a4 }, { x:0x3ffc8, y:0x3ff88, z:0x000b2 }, { x:0x3ffbe, y:0x3ffc8, z:0x000be }, { x:0x3ffb0, y:0x3fffc, z:0x000a6 }, { x:0x3ff66, y:0x00090, z:0x3ffd8 }, { x:0x3ff4e, y:0x000a4, z:0x3ffe6 }, { x:0x3ff36, y:0x00084, z:0x3fff6 }, { x:0x3ff20, y:0x00058, z:0x00006 }, { x:0x3ff10, y:0x00024, z:0x00014 }, { x:0x3ff1a, y:0x3ffee, z:0x00028 }, { x:0x3ff12, y:0x3ffb0, z:0x00034 }, { x:0x3ff34, y:0x3ff76, z:0x0003a }, { x:0x3ff70, y:0x3ff52, z:0x00034 }, { x:0x3ff86, y:0x3ff26, z:0x0004a }, { x:0x3ff7e, y:0x3ff02, z:0x0007c }, { x:0x3ffb6, y:0x3ff0a, z:0x000ba }, { x:0x3ffdc, y:0x3ff38, z:0x000b6 }, { x:0x3ffe6, y:0x3ff74, z:0x000be }, { x:0x3ffd8, y:0x3ffae, z:0x000c2 }, { x:0x3ffc8, y:0x3fff0, z:0x000ae }, { x:0x3ffae, y:0x00020, z:0x0007c }, { x:0x3ff66, y:0x000a6, z:0x3ffa8 }, { x:0x3ff40, y:0x000b4, z:0x3ffb2 }, { x:0x3ff3c, y:0x00086, z:0x3ffc4 }, { x:0x3ff42, y:0x0004c, z:0x3ffe6 }, { x:0x3ff32, y:0x00006, z:0x3fffa }, { x:0x3ff20, y:0x3ffc4, z:0x3fff8 }, { x:0x3ff2c, y:0x3ff88, z:0x0000a }, { x:0x3ff64, y:0x3ff58, z:0x00018 }, { x:0x3ff64, y:0x3ff26, z:0x0002a }, { x:0x3ff76, y:0x3ff02, z:0x0005c }, { x:0x3ffb6, y:0x3ff04, z:0x000a2 }, { x:0x3ffdc, y:0x3ff14, z:0x000e6 }, { x:0x3fffa, y:0x3ff4e, z:0x000d8 }, { x:0x3fff4, y:0x3ff94, z:0x000ee }, { x:0x3ffea, y:0x3ffd2, z:0x000c6 }, { x:0x3ffd6, y:0x00010, z:0x00092 }, { x:0x3ffae, y:0x00036, z:0x0004a }, { x:0x3ff64, y:0x000ba, z:0x3ff70 }, { x:0x3ff32, y:0x000bc, z:0x3ff72 }, { x:0x3ff42, y:0x00080, z:0x3ff96 }, { x:0x3ff52, y:0x0003a, z:0x3ffde }, { x:0x3ff40, y:0x3ffec, z:0x3ffda }, { x:0x3ff3a, y:0x3ffa6, z:0x3ffd2 }, { x:0x3ff58, y:0x3ff6c, z:0x3fff2 }, { x:0x3ff72, y:0x3ff2e, z:0x00004 }, { x:0x3ff56, y:0x3ff02, z:0x00010 }, { x:0x3ffa0, y:0x3ff04, z:0x0004c }, { x:0x3ffd8, y:0x3ff10, z:0x0009a }, { x:0x0000c, y:0x3ff12, z:0x000dc }, { x:0x0001a, y:0x3ff5c, z:0x000f0 }, { x:0x00018, y:0x3ffb0, z:0x000f8 }, { x:0x00008, y:0x3ffee, z:0x000ba }, { x:0x3ffe2, y:0x00024, z:0x00072 }, { x:0x3ffa4, y:0x0003c, z:0x00014 }, { x:0x3ff64, y:0x000ca, z:0x3ff3a }, { x:0x3ff46, y:0x000c2, z:0x3ff3e }, { x:0x3ff50, y:0x00078, z:0x3ff8a }, { x:0x3ff60, y:0x00028, z:0x3ffe0 }, { x:0x3ff54, y:0x3ffda, z:0x3ffc4 }, { x:0x3ff5e, y:0x3ff90, z:0x3ffbc }, { x:0x3ff82, y:0x3ff5a, z:0x3ffe6 }, { x:0x3ff84, y:0x3ff1a, z:0x3ffdc }, { x:0x3ff94, y:0x3ff00, z:0x3fffc }, { x:0x3ffcc, y:0x3ff02, z:0x0003a }, { x:0x00000, y:0x3ff12, z:0x0008a }, { x:0x00030, y:0x3ff16, z:0x000cc }, { x:0x00046, y:0x3ff68, z:0x000f2 }, { x:0x00040, y:0x3ffc6, z:0x000ec }, { x:0x00020, y:0x0000e, z:0x000b0 }, { x:0x3fff4, y:0x00036, z:0x00054 }, { x:0x3ffc0, y:0x0002e, z:0x3ffee }, { x:0x3ff72, y:0x000c6, z:0x3ff08 }, { x:0x3ff56, y:0x000aa, z:0x3ff20 }, { x:0x3ff56, y:0x00072, z:0x3ffb2 }, { x:0x3ff68, y:0x00018, z:0x3ffdc }, { x:0x3ff6c, y:0x3ffce, z:0x3ffb6 }, { x:0x3ff86, y:0x3ff88, z:0x3ffb8 }, { x:0x3ffaa, y:0x3ff48, z:0x3ffd8 }, { x:0x3ffa0, y:0x3ff10, z:0x3ffa8 }, { x:0x3ffc2, y:0x3ff10, z:0x3ffd6 }, { x:0x3fff8, y:0x3ff10, z:0x00026 }, { x:0x0002c, y:0x3ff12, z:0x00078 }, { x:0x00058, y:0x3ff1a, z:0x000c2 }, { x:0x0006a, y:0x3ff76, z:0x000e0 }, { x:0x00062, y:0x3ffd8, z:0x000d0 }, { x:0x00042, y:0x00028, z:0x00096 }, { x:0x00012, y:0x00040, z:0x0002e }, { x:0x3ffd8, y:0x00018, z:0x3ffd0 }, { x:0x3ff66, y:0x000ca, z:0x3ff40 }, { x:0x3ff5a, y:0x0008a, z:0x3ff3e }, { x:0x3ff5c, y:0x00068, z:0x3ffd6 }, { x:0x3ff70, y:0x0000e, z:0x3ffcc }, { x:0x3ff82, y:0x3ffc6, z:0x3ffa6 }, { x:0x3ffa6, y:0x3ff84, z:0x3ffb8 }, { x:0x3ffce, y:0x3ff48, z:0x3ffcc }, { x:0x3ffc8, y:0x3ff16, z:0x3ff84 }, { x:0x3fff4, y:0x3ff0c, z:0x3ffb6 }, { x:0x00020, y:0x3ff12, z:0x00006 }, { x:0x00052, y:0x3ff02, z:0x0005e }, { x:0x00080, y:0x3ff1c, z:0x000b0 }, { x:0x00086, y:0x3ff7e, z:0x000c4 }, { x:0x00086, y:0x3ffe2, z:0x000b8 }, { x:0x00068, y:0x00036, z:0x00072 }, { x:0x00032, y:0x0003e, z:0x00004 }, { x:0x3fff2, y:0x00000, z:0x3ffae }, { x:0x3ff62, y:0x000b6, z:0x3ff70 }, { x:0x3ff62, y:0x00088, z:0x3ff72 }, { x:0x3ff66, y:0x0005c, z:0x3ffe6 }, { x:0x3ff7c, y:0x00008, z:0x3ffc0 }, { x:0x3ff9a, y:0x3ffc4, z:0x3ffaa }, { x:0x3ffc2, y:0x3ff8e, z:0x3ffae }, { x:0x3ffd8, y:0x3ff5a, z:0x3ff94 }, { x:0x3fffc, y:0x3ff2a, z:0x3ff8c }, { x:0x00026, y:0x3ff02, z:0x3ffa4 }, { x:0x0004e, y:0x3ff0c, z:0x3ffec }, { x:0x00072, y:0x3ff08, z:0x0003e }, { x:0x0009a, y:0x3ff26, z:0x0008e }, { x:0x000a6, y:0x3ff7e, z:0x000a6 }, { x:0x000a6, y:0x3ffe0, z:0x00098 }, { x:0x0008a, y:0x0002a, z:0x0004a }, { x:0x00054, y:0x0002e, z:0x3ffe2 }, { x:0x00018, y:0x3ffee, z:0x3ffa4 }, { x:0x3ff68, y:0x000a6, z:0x3ffa6 }, { x:0x3ff66, y:0x00080, z:0x3ffa8 }, { x:0x3ff72, y:0x0004a, z:0x3ffea }, { x:0x3ff8e, y:0x00002, z:0x3ffb8 }, { x:0x3ffb0, y:0x3ffcc, z:0x3ffa4 }, { x:0x3ffd0, y:0x3ff9a, z:0x3ff80 }, { x:0x3fff0, y:0x3ff72, z:0x3ff64 }, { x:0x00020, y:0x3ff4c, z:0x3ff78 }, { x:0x0004c, y:0x3ff26, z:0x3ff9c }, { x:0x00074, y:0x3ff0c, z:0x3ffce }, { x:0x0009a, y:0x3ff06, z:0x0001e }, { x:0x000bc, y:0x3ff1c, z:0x0006e }, { x:0x000ba, y:0x3ff68, z:0x00082 }, { x:0x000be, y:0x3ffc8, z:0x00076 }, { x:0x000a8, y:0x0000a, z:0x00034 }, { x:0x0007c, y:0x00016, z:0x3ffd6 }, { x:0x0003e, y:0x3ffda, z:0x3ffa2 }, { x:0x3ff66, y:0x0008c, z:0x3ffda }, { x:0x3ff64, y:0x00070, z:0x3ffdc }, { x:0x3ff7e, y:0x00038, z:0x3ffec }, { x:0x3ffa2, y:0x00006, z:0x3ffbe }, { x:0x3ffc6, y:0x3ffd6, z:0x3ffa6 }, { x:0x3ffe6, y:0x3ffba, z:0x3ff70 }, { x:0x00012, y:0x3ff96, z:0x3ff66 }, { x:0x0003e, y:0x3ff74, z:0x3ff76 }, { x:0x0006c, y:0x3ff54, z:0x3ff8c }, { x:0x00094, y:0x3ff38, z:0x3ffbc }, { x:0x000b4, y:0x3ff26, z:0x3fff0 }, { x:0x000dc, y:0x3ff28, z:0x0003a }, { x:0x000de, y:0x3ff58, z:0x00080 }, { x:0x000ca, y:0x3ffa0, z:0x0005e }, { x:0x000c2, y:0x3ffe0, z:0x00024 }, { x:0x0009e, y:0x3fff4, z:0x3ffd6 }, { x:0x0006c, y:0x3ffd4, z:0x3ffa2 }, { x:0x3ff74, y:0x00078, z:0x3fffc }, { x:0x3ff86, y:0x00054, z:0x3fffa }, { x:0x3ff98, y:0x00032, z:0x3ffe4 }, { x:0x3ffba, y:0x0000e, z:0x3ffc2 }, { x:0x3ffde, y:0x3ffea, z:0x3ffa2 }, { x:0x00002, y:0x3ffd2, z:0x3ff86 }, { x:0x0002e, y:0x3ffc0, z:0x3ff72 }, { x:0x0005a, y:0x3ffa2, z:0x3ff7e }, { x:0x00082, y:0x3ff8a, z:0x3ff96 }, { x:0x000a2, y:0x3ff70, z:0x3ffbc }, { x:0x000ba, y:0x3ff5a, z:0x3fff2 }, { x:0x000ea, y:0x3ff4e, z:0x00004 }, { x:0x000fa, y:0x3ff5a, z:0x0004e }, { x:0x000dc, y:0x3ff82, z:0x00054 }, { x:0x000cc, y:0x3ffb0, z:0x00024 }, { x:0x000b8, y:0x3ffca, z:0x3ffe4 }, { x:0x00092, y:0x3ffc4, z:0x3ffb0 }, { x:0x3ff94, y:0x0006a, z:0x00012 }, { x:0x3ffa0, y:0x0003e, z:0x00010 }, { x:0x3ffbe, y:0x00030, z:0x3ffec }, { x:0x3ffd8, y:0x00018, z:0x3ffce }, { x:0x3fff2, y:0x00000, z:0x3ffb0 }, { x:0x00018, y:0x3ffee, z:0x3ffa2 }, { x:0x0003e, y:0x3ffdc, z:0x3ffa0 }, { x:0x0006a, y:0x3ffd2, z:0x3ffa2 }, { x:0x00094, y:0x3ffc4, z:0x3ffae }, { x:0x000b2, y:0x3ffaa, z:0x3ffc6 }, { x:0x000c6, y:0x3ff96, z:0x3fff4 }, { x:0x000d2, y:0x3ff80, z:0x0001c }, { x:0x000fa, y:0x3ff76, z:0x0002e }, { x:0x000fa, y:0x3ff78, z:0x0002e }, { x:0x000ce, y:0x3ff7e, z:0x0001a }, { x:0x000c0, y:0x3ff9a, z:0x3fff2 }, { x:0x000b4, y:0x3ffac, z:0x3ffc8 },];var triangles = [ { a:0x000, b:0x011, c:0x012, d:0x001 }, { a:0x000, b:0x012, c:0x001, d:0x003 }, { a:0x001, b:0x012, c:0x013, d:0x001 }, { a:0x001, b:0x013, c:0x002, d:0x003 }, { a:0x002, b:0x013, c:0x014, d:0x001 }, { a:0x002, b:0x014, c:0x003, d:0x003 }, { a:0x003, b:0x014, c:0x015, d:0x001 }, { a:0x003, b:0x015, c:0x004, d:0x003 }, { a:0x004, b:0x015, c:0x016, d:0x001 }, { a:0x004, b:0x016, c:0x005, d:0x003 }, { a:0x005, b:0x016, c:0x017, d:0x001 }, { a:0x005, b:0x017, c:0x006, d:0x003 }, { a:0x006, b:0x017, c:0x018, d:0x001 }, { a:0x006, b:0x018, c:0x007, d:0x003 }, { a:0x007, b:0x018, c:0x019, d:0x001 }, { a:0x007, b:0x019, c:0x008, d:0x003 }, { a:0x008, b:0x019, c:0x01a, d:0x001 }, { a:0x008, b:0x01a, c:0x009, d:0x003 }, { a:0x009, b:0x01a, c:0x01b, d:0x001 }, { a:0x009, b:0x01b, c:0x00a, d:0x003 }, { a:0x00a, b:0x01b, c:0x01c, d:0x001 }, { a:0x00a, b:0x01c, c:0x00b, d:0x003 }, { a:0x00b, b:0x01c, c:0x01d, d:0x001 }, { a:0x00b, b:0x01d, c:0x00c, d:0x003 }, { a:0x00c, b:0x01d, c:0x01e, d:0x001 }, { a:0x00c, b:0x01e, c:0x00d, d:0x003 }, { a:0x00d, b:0x01e, c:0x01f, d:0x001 }, { a:0x00d, b:0x01f, c:0x00e, d:0x003 }, { a:0x00e, b:0x01f, c:0x020, d:0x001 }, { a:0x00e, b:0x020, c:0x00f, d:0x003 }, { a:0x00f, b:0x020, c:0x021, d:0x001 }, { a:0x00f, b:0x021, c:0x010, d:0x003 }, { a:0x011, b:0x022, c:0x023, d:0x001 }, { a:0x011, b:0x023, c:0x012, d:0x003 }, { a:0x012, b:0x023, c:0x024, d:0x001 }, { a:0x012, b:0x024, c:0x013, d:0x003 }, { a:0x013, b:0x024, c:0x025, d:0x001 }, { a:0x013, b:0x025, c:0x014, d:0x003 }, { a:0x014, b:0x025, c:0x026, d:0x001 }, { a:0x014, b:0x026, c:0x015, d:0x003 }, { a:0x015, b:0x026, c:0x027, d:0x001 }, { a:0x015, b:0x027, c:0x016, d:0x003 }, { a:0x016, b:0x027, c:0x028, d:0x001 }, { a:0x016, b:0x028, c:0x017, d:0x003 }, { a:0x017, b:0x028, c:0x029, d:0x001 }, { a:0x017, b:0x029, c:0x018, d:0x003 }, { a:0x018, b:0x029, c:0x02a, d:0x001 }, { a:0x018, b:0x02a, c:0x019, d:0x003 }, { a:0x019, b:0x02a, c:0x02b, d:0x001 }, { a:0x019, b:0x02b, c:0x01a, d:0x003 }, { a:0x01a, b:0x02b, c:0x02c, d:0x001 }, { a:0x01a, b:0x02c, c:0x01b, d:0x003 }, { a:0x01b, b:0x02c, c:0x02d, d:0x001 }, { a:0x01b, b:0x02d, c:0x01c, d:0x003 }, { a:0x01c, b:0x02d, c:0x02e, d:0x001 }, { a:0x01c, b:0x02e, c:0x01d, d:0x003 }, { a:0x01d, b:0x02e, c:0x02f, d:0x001 }, { a:0x01d, b:0x02f, c:0x01e, d:0x003 }, { a:0x01e, b:0x02f, c:0x030, d:0x001 }, { a:0x01e, b:0x030, c:0x01f, d:0x003 }, { a:0x01f, b:0x030, c:0x031, d:0x001 }, { a:0x01f, b:0x031, c:0x020, d:0x003 }, { a:0x020, b:0x031, c:0x032, d:0x001 }, { a:0x020, b:0x032, c:0x021, d:0x003 }, { a:0x022, b:0x033, c:0x034, d:0x001 }, { a:0x022, b:0x034, c:0x023, d:0x003 }, { a:0x023, b:0x034, c:0x035, d:0x001 }, { a:0x023, b:0x035, c:0x024, d:0x003 }, { a:0x024, b:0x035, c:0x036, d:0x001 }, { a:0x024, b:0x036, c:0x025, d:0x003 }, { a:0x025, b:0x036, c:0x037, d:0x001 }, { a:0x025, b:0x037, c:0x026, d:0x003 }, { a:0x026, b:0x037, c:0x038, d:0x001 }, { a:0x026, b:0x038, c:0x027, d:0x003 }, { a:0x027, b:0x038, c:0x039, d:0x001 }, { a:0x027, b:0x039, c:0x028, d:0x003 }, { a:0x028, b:0x039, c:0x03a, d:0x001 }, { a:0x028, b:0x03a, c:0x029, d:0x003 }, { a:0x029, b:0x03a, c:0x03b, d:0x001 }, { a:0x029, b:0x03b, c:0x02a, d:0x003 }, { a:0x02a, b:0x03b, c:0x03c, d:0x001 }, { a:0x02a, b:0x03c, c:0x02b, d:0x003 }, { a:0x02b, b:0x03c, c:0x03d, d:0x001 }, { a:0x02b, b:0x03d, c:0x02c, d:0x003 }, { a:0x02c, b:0x03d, c:0x03e, d:0x001 }, { a:0x02c, b:0x03e, c:0x02d, d:0x003 }, { a:0x02d, b:0x03e, c:0x03f, d:0x001 }, { a:0x02d, b:0x03f, c:0x02e, d:0x003 }, { a:0x02e, b:0x03f, c:0x040, d:0x001 }, { a:0x02e, b:0x040, c:0x02f, d:0x003 }, { a:0x02f, b:0x040, c:0x041, d:0x001 }, { a:0x02f, b:0x041, c:0x030, d:0x003 }, { a:0x030, b:0x041, c:0x042, d:0x001 }, { a:0x030, b:0x042, c:0x031, d:0x003 }, { a:0x031, b:0x042, c:0x043, d:0x001 }, { a:0x031, b:0x043, c:0x032, d:0x003 }, { a:0x033, b:0x044, c:0x045, d:0x001 }, { a:0x033, b:0x045, c:0x034, d:0x003 }, { a:0x034, b:0x045, c:0x046, d:0x001 }, { a:0x034, b:0x046, c:0x035, d:0x003 }, { a:0x035, b:0x046, c:0x047, d:0x001 }, { a:0x035, b:0x047, c:0x036, d:0x003 }, { a:0x036, b:0x047, c:0x048, d:0x001 }, { a:0x036, b:0x048, c:0x037, d:0x003 }, { a:0x037, b:0x048, c:0x049, d:0x001 }, { a:0x037, b:0x049, c:0x038, d:0x003 }, { a:0x038, b:0x049, c:0x04a, d:0x001 }, { a:0x038, b:0x04a, c:0x039, d:0x003 }, { a:0x039, b:0x04a, c:0x04b, d:0x001 }, { a:0x039, b:0x04b, c:0x03a, d:0x003 }, { a:0x03a, b:0x04b, c:0x04c, d:0x001 }, { a:0x03a, b:0x04c, c:0x03b, d:0x003 }, { a:0x03b, b:0x04c, c:0x04d, d:0x001 }, { a:0x03b, b:0x04d, c:0x03c, d:0x003 }, { a:0x03c, b:0x04d, c:0x04e, d:0x001 }, { a:0x03c, b:0x04e, c:0x03d, d:0x003 }, { a:0x03d, b:0x04e, c:0x04f, d:0x001 }, { a:0x03d, b:0x04f, c:0x03e, d:0x003 }, { a:0x03e, b:0x04f, c:0x050, d:0x001 }, { a:0x03e, b:0x050, c:0x03f, d:0x003 }, { a:0x03f, b:0x050, c:0x051, d:0x001 }, { a:0x03f, b:0x051, c:0x040, d:0x003 }, { a:0x040, b:0x051, c:0x052, d:0x001 }, { a:0x040, b:0x052, c:0x041, d:0x003 }, { a:0x041, b:0x052, c:0x053, d:0x001 }, { a:0x041, b:0x053, c:0x042, d:0x003 }, { a:0x042, b:0x053, c:0x054, d:0x001 }, { a:0x042, b:0x054, c:0x043, d:0x003 }, { a:0x044, b:0x055, c:0x056, d:0x001 }, { a:0x044, b:0x056, c:0x045, d:0x003 }, { a:0x045, b:0x056, c:0x057, d:0x001 }, { a:0x045, b:0x057, c:0x046, d:0x003 }, { a:0x046, b:0x057, c:0x058, d:0x001 }, { a:0x046, b:0x058, c:0x047, d:0x003 }, { a:0x047, b:0x058, c:0x059, d:0x001 }, { a:0x047, b:0x059, c:0x048, d:0x003 }, { a:0x048, b:0x059, c:0x05a, d:0x001 }, { a:0x048, b:0x05a, c:0x049, d:0x003 }, { a:0x049, b:0x05a, c:0x05b, d:0x001 }, { a:0x049, b:0x05b, c:0x04a, d:0x003 }, { a:0x04a, b:0x05b, c:0x05c, d:0x001 }, { a:0x04a, b:0x05c, c:0x04b, d:0x003 }, { a:0x04b, b:0x05c, c:0x05d, d:0x001 }, { a:0x04b, b:0x05d, c:0x04c, d:0x003 }, { a:0x04c, b:0x05d, c:0x05e, d:0x001 }, { a:0x04c, b:0x05e, c:0x04d, d:0x003 }, { a:0x04d, b:0x05e, c:0x05f, d:0x001 }, { a:0x04d, b:0x05f, c:0x04e, d:0x003 }, { a:0x04e, b:0x05f, c:0x060, d:0x001 }, { a:0x04e, b:0x060, c:0x04f, d:0x003 }, { a:0x04f, b:0x060, c:0x061, d:0x001 }, { a:0x04f, b:0x061, c:0x050, d:0x003 }, { a:0x050, b:0x061, c:0x062, d:0x001 }, { a:0x050, b:0x062, c:0x051, d:0x003 }, { a:0x051, b:0x062, c:0x063, d:0x001 }, { a:0x051, b:0x063, c:0x052, d:0x003 }, { a:0x052, b:0x063, c:0x064, d:0x001 }, { a:0x052, b:0x064, c:0x053, d:0x003 }, { a:0x053, b:0x064, c:0x065, d:0x001 }, { a:0x053, b:0x065, c:0x054, d:0x003 }, { a:0x055, b:0x066, c:0x067, d:0x001 }, { a:0x055, b:0x067, c:0x056, d:0x003 }, { a:0x056, b:0x067, c:0x068, d:0x001 }, { a:0x056, b:0x068, c:0x057, d:0x003 }, { a:0x057, b:0x068, c:0x069, d:0x001 }, { a:0x057, b:0x069, c:0x058, d:0x003 }, { a:0x058, b:0x069, c:0x06a, d:0x001 }, { a:0x058, b:0x06a, c:0x059, d:0x003 }, { a:0x059, b:0x06a, c:0x06b, d:0x001 }, { a:0x059, b:0x06b, c:0x05a, d:0x003 }, { a:0x05a, b:0x06b, c:0x06c, d:0x001 }, { a:0x05a, b:0x06c, c:0x05b, d:0x003 }, { a:0x05b, b:0x06c, c:0x06d, d:0x001 }, { a:0x05b, b:0x06d, c:0x05c, d:0x003 }, { a:0x05c, b:0x06d, c:0x06e, d:0x001 }, { a:0x05c, b:0x06e, c:0x05d, d:0x003 }, { a:0x05d, b:0x06e, c:0x06f, d:0x001 }, { a:0x05d, b:0x06f, c:0x05e, d:0x003 }, { a:0x05e, b:0x06f, c:0x070, d:0x001 }, { a:0x05e, b:0x070, c:0x05f, d:0x003 }, { a:0x05f, b:0x070, c:0x071, d:0x001 }, { a:0x05f, b:0x071, c:0x060, d:0x003 }, { a:0x060, b:0x071, c:0x072, d:0x001 }, { a:0x060, b:0x072, c:0x061, d:0x003 }, { a:0x061, b:0x072, c:0x073, d:0x001 }, { a:0x061, b:0x073, c:0x062, d:0x003 }, { a:0x062, b:0x073, c:0x074, d:0x001 }, { a:0x062, b:0x074, c:0x063, d:0x003 }, { a:0x063, b:0x074, c:0x075, d:0x001 }, { a:0x063, b:0x075, c:0x064, d:0x003 }, { a:0x064, b:0x075, c:0x076, d:0x001 }, { a:0x064, b:0x076, c:0x065, d:0x003 }, { a:0x066, b:0x077, c:0x078, d:0x001 }, { a:0x066, b:0x078, c:0x067, d:0x003 }, { a:0x067, b:0x078, c:0x079, d:0x001 }, { a:0x067, b:0x079, c:0x068, d:0x003 }, { a:0x068, b:0x079, c:0x07a, d:0x001 }, { a:0x068, b:0x07a, c:0x069, d:0x003 }, { a:0x069, b:0x07a, c:0x07b, d:0x001 }, { a:0x069, b:0x07b, c:0x06a, d:0x003 }, { a:0x06a, b:0x07b, c:0x07c, d:0x001 }, { a:0x06a, b:0x07c, c:0x06b, d:0x003 }, { a:0x06b, b:0x07c, c:0x07d, d:0x001 }, { a:0x06b, b:0x07d, c:0x06c, d:0x003 }, { a:0x06c, b:0x07d, c:0x07e, d:0x001 }, { a:0x06c, b:0x07e, c:0x06d, d:0x003 }, { a:0x06d, b:0x07e, c:0x07f, d:0x001 }, { a:0x06d, b:0x07f, c:0x06e, d:0x003 }, { a:0x06e, b:0x07f, c:0x080, d:0x001 }, { a:0x06e, b:0x080, c:0x06f, d:0x003 }, { a:0x06f, b:0x080, c:0x081, d:0x001 }, { a:0x06f, b:0x081, c:0x070, d:0x003 }, { a:0x070, b:0x081, c:0x082, d:0x001 }, { a:0x070, b:0x082, c:0x071, d:0x003 }, { a:0x071, b:0x082, c:0x083, d:0x001 }, { a:0x071, b:0x083, c:0x072, d:0x003 }, { a:0x072, b:0x083, c:0x084, d:0x001 }, { a:0x072, b:0x084, c:0x073, d:0x003 }, { a:0x073, b:0x084, c:0x085, d:0x001 }, { a:0x073, b:0x085, c:0x074, d:0x003 }, { a:0x074, b:0x085, c:0x086, d:0x001 }, { a:0x074, b:0x086, c:0x075, d:0x003 }, { a:0x075, b:0x086, c:0x087, d:0x001 }, { a:0x075, b:0x087, c:0x076, d:0x003 }, { a:0x077, b:0x088, c:0x089, d:0x001 }, { a:0x077, b:0x089, c:0x078, d:0x003 }, { a:0x078, b:0x089, c:0x08a, d:0x001 }, { a:0x078, b:0x08a, c:0x079, d:0x003 }, { a:0x079, b:0x08a, c:0x08b, d:0x001 }, { a:0x079, b:0x08b, c:0x07a, d:0x003 }, { a:0x07a, b:0x08b, c:0x08c, d:0x001 }, { a:0x07a, b:0x08c, c:0x07b, d:0x003 }, { a:0x07b, b:0x08c, c:0x08d, d:0x001 }, { a:0x07b, b:0x08d, c:0x07c, d:0x003 }, { a:0x07c, b:0x08d, c:0x08e, d:0x001 }, { a:0x07c, b:0x08e, c:0x07d, d:0x003 }, { a:0x07d, b:0x08e, c:0x08f, d:0x001 }, { a:0x07d, b:0x08f, c:0x07e, d:0x003 }, { a:0x07e, b:0x08f, c:0x090, d:0x001 }, { a:0x07e, b:0x090, c:0x07f, d:0x003 }, { a:0x07f, b:0x090, c:0x091, d:0x001 }, { a:0x07f, b:0x091, c:0x080, d:0x003 }, { a:0x080, b:0x091, c:0x092, d:0x001 }, { a:0x080, b:0x092, c:0x081, d:0x003 }, { a:0x081, b:0x092, c:0x093, d:0x001 }, { a:0x081, b:0x093, c:0x082, d:0x003 }, { a:0x082, b:0x093, c:0x094, d:0x001 }, { a:0x082, b:0x094, c:0x083, d:0x003 }, { a:0x083, b:0x094, c:0x095, d:0x001 }, { a:0x083, b:0x095, c:0x084, d:0x003 }, { a:0x084, b:0x095, c:0x096, d:0x001 }, { a:0x084, b:0x096, c:0x085, d:0x003 }, { a:0x085, b:0x096, c:0x097, d:0x001 }, { a:0x085, b:0x097, c:0x086, d:0x003 }, { a:0x086, b:0x097, c:0x098, d:0x001 }, { a:0x086, b:0x098, c:0x087, d:0x003 }, { a:0x088, b:0x099, c:0x09a, d:0x001 }, { a:0x088, b:0x09a, c:0x089, d:0x003 }, { a:0x089, b:0x09a, c:0x09b, d:0x001 }, { a:0x089, b:0x09b, c:0x08a, d:0x003 }, { a:0x08a, b:0x09b, c:0x09c, d:0x001 }, { a:0x08a, b:0x09c, c:0x08b, d:0x003 }, { a:0x08b, b:0x09c, c:0x09d, d:0x001 }, { a:0x08b, b:0x09d, c:0x08c, d:0x003 }, { a:0x08c, b:0x09d, c:0x09e, d:0x001 }, { a:0x08c, b:0x09e, c:0x08d, d:0x003 }, { a:0x08d, b:0x09e, c:0x09f, d:0x001 }, { a:0x08d, b:0x09f, c:0x08e, d:0x003 }, { a:0x08e, b:0x09f, c:0x0a0, d:0x001 }, { a:0x08e, b:0x0a0, c:0x08f, d:0x003 }, { a:0x08f, b:0x0a0, c:0x0a1, d:0x001 }, { a:0x08f, b:0x0a1, c:0x090, d:0x003 }, { a:0x090, b:0x0a1, c:0x0a2, d:0x001 }, { a:0x090, b:0x0a2, c:0x091, d:0x003 }, { a:0x091, b:0x0a2, c:0x0a3, d:0x001 }, { a:0x091, b:0x0a3, c:0x092, d:0x003 }, { a:0x092, b:0x0a3, c:0x0a4, d:0x001 }, { a:0x092, b:0x0a4, c:0x093, d:0x003 }, { a:0x093, b:0x0a4, c:0x0a5, d:0x001 }, { a:0x093, b:0x0a5, c:0x094, d:0x003 }, { a:0x094, b:0x0a5, c:0x0a6, d:0x001 }, { a:0x094, b:0x0a6, c:0x095, d:0x003 }, { a:0x095, b:0x0a6, c:0x0a7, d:0x001 }, { a:0x095, b:0x0a7, c:0x096, d:0x003 }, { a:0x096, b:0x0a7, c:0x0a8, d:0x001 }, { a:0x096, b:0x0a8, c:0x097, d:0x003 }, { a:0x097, b:0x0a8, c:0x0a9, d:0x001 }, { a:0x097, b:0x0a9, c:0x098, d:0x003 }, { a:0x099, b:0x0aa, c:0x0ab, d:0x001 }, { a:0x099, b:0x0ab, c:0x09a, d:0x003 }, { a:0x09a, b:0x0ab, c:0x0ac, d:0x001 }, { a:0x09a, b:0x0ac, c:0x09b, d:0x003 }, { a:0x09b, b:0x0ac, c:0x0ad, d:0x001 }, { a:0x09b, b:0x0ad, c:0x09c, d:0x003 }, { a:0x09c, b:0x0ad, c:0x0ae, d:0x001 }, { a:0x09c, b:0x0ae, c:0x09d, d:0x003 }, { a:0x09d, b:0x0ae, c:0x0af, d:0x001 }, { a:0x09d, b:0x0af, c:0x09e, d:0x003 }, { a:0x09e, b:0x0af, c:0x0b0, d:0x001 }, { a:0x09e, b:0x0b0, c:0x09f, d:0x003 }, { a:0x09f, b:0x0b0, c:0x0b1, d:0x001 }, { a:0x09f, b:0x0b1, c:0x0a0, d:0x003 }, { a:0x0a0, b:0x0b1, c:0x0b2, d:0x001 }, { a:0x0a0, b:0x0b2, c:0x0a1, d:0x003 }, { a:0x0a1, b:0x0b2, c:0x0b3, d:0x001 }, { a:0x0a1, b:0x0b3, c:0x0a2, d:0x003 }, { a:0x0a2, b:0x0b3, c:0x0b4, d:0x001 }, { a:0x0a2, b:0x0b4, c:0x0a3, d:0x003 }, { a:0x0a3, b:0x0b4, c:0x0b5, d:0x001 }, { a:0x0a3, b:0x0b5, c:0x0a4, d:0x003 }, { a:0x0a4, b:0x0b5, c:0x0b6, d:0x001 }, { a:0x0a4, b:0x0b6, c:0x0a5, d:0x003 }, { a:0x0a5, b:0x0b6, c:0x0b7, d:0x001 }, { a:0x0a5, b:0x0b7, c:0x0a6, d:0x003 }, { a:0x0a6, b:0x0b7, c:0x0b8, d:0x001 }, { a:0x0a6, b:0x0b8, c:0x0a7, d:0x003 }, { a:0x0a7, b:0x0b8, c:0x0b9, d:0x001 }, { a:0x0a7, b:0x0b9, c:0x0a8, d:0x003 }, { a:0x0a8, b:0x0b9, c:0x0ba, d:0x001 }, { a:0x0a8, b:0x0ba, c:0x0a9, d:0x003 }, { a:0x0aa, b:0x0bb, c:0x0bc, d:0x001 }, { a:0x0aa, b:0x0bc, c:0x0ab, d:0x003 }, { a:0x0ab, b:0x0bc, c:0x0bd, d:0x001 }, { a:0x0ab, b:0x0bd, c:0x0ac, d:0x003 }, { a:0x0ac, b:0x0bd, c:0x0be, d:0x001 }, { a:0x0ac, b:0x0be, c:0x0ad, d:0x003 }, { a:0x0ad, b:0x0be, c:0x0bf, d:0x001 }, { a:0x0ad, b:0x0bf, c:0x0ae, d:0x003 }, { a:0x0ae, b:0x0bf, c:0x0c0, d:0x001 }, { a:0x0ae, b:0x0c0, c:0x0af, d:0x003 }, { a:0x0af, b:0x0c0, c:0x0c1, d:0x001 }, { a:0x0af, b:0x0c1, c:0x0b0, d:0x003 }, { a:0x0b0, b:0x0c1, c:0x0c2, d:0x001 }, { a:0x0b0, b:0x0c2, c:0x0b1, d:0x003 }, { a:0x0b1, b:0x0c2, c:0x0c3, d:0x001 }, { a:0x0b1, b:0x0c3, c:0x0b2, d:0x003 }, { a:0x0b2, b:0x0c3, c:0x0c4, d:0x001 }, { a:0x0b2, b:0x0c4, c:0x0b3, d:0x003 }, { a:0x0b3, b:0x0c4, c:0x0c5, d:0x001 }, { a:0x0b3, b:0x0c5, c:0x0b4, d:0x003 }, { a:0x0b4, b:0x0c5, c:0x0c6, d:0x001 }, { a:0x0b4, b:0x0c6, c:0x0b5, d:0x003 }, { a:0x0b5, b:0x0c6, c:0x0c7, d:0x001 }, { a:0x0b5, b:0x0c7, c:0x0b6, d:0x003 }, { a:0x0b6, b:0x0c7, c:0x0c8, d:0x001 }, { a:0x0b6, b:0x0c8, c:0x0b7, d:0x003 }, { a:0x0b7, b:0x0c8, c:0x0c9, d:0x001 }, { a:0x0b7, b:0x0c9, c:0x0b8, d:0x003 }, { a:0x0b8, b:0x0c9, c:0x0ca, d:0x001 }, { a:0x0b8, b:0x0ca, c:0x0b9, d:0x003 }, { a:0x0b9, b:0x0ca, c:0x0cb, d:0x001 }, { a:0x0b9, b:0x0cb, c:0x0ba, d:0x003 }, { a:0x0bb, b:0x0cc, c:0x0cd, d:0x001 }, { a:0x0bb, b:0x0cd, c:0x0bc, d:0x003 }, { a:0x0bc, b:0x0cd, c:0x0ce, d:0x001 }, { a:0x0bc, b:0x0ce, c:0x0bd, d:0x003 }, { a:0x0bd, b:0x0ce, c:0x0cf, d:0x001 }, { a:0x0bd, b:0x0cf, c:0x0be, d:0x003 }, { a:0x0be, b:0x0cf, c:0x0d0, d:0x001 }, { a:0x0be, b:0x0d0, c:0x0bf, d:0x003 }, { a:0x0bf, b:0x0d0, c:0x0d1, d:0x001 }, { a:0x0bf, b:0x0d1, c:0x0c0, d:0x003 }, { a:0x0c0, b:0x0d1, c:0x0d2, d:0x001 }, { a:0x0c0, b:0x0d2, c:0x0c1, d:0x003 }, { a:0x0c1, b:0x0d2, c:0x0d3, d:0x001 }, { a:0x0c1, b:0x0d3, c:0x0c2, d:0x003 }, { a:0x0c2, b:0x0d3, c:0x0d4, d:0x001 }, { a:0x0c2, b:0x0d4, c:0x0c3, d:0x003 }, { a:0x0c3, b:0x0d4, c:0x0d5, d:0x001 }, { a:0x0c3, b:0x0d5, c:0x0c4, d:0x003 }, { a:0x0c4, b:0x0d5, c:0x0d6, d:0x001 }, { a:0x0c4, b:0x0d6, c:0x0c5, d:0x003 }, { a:0x0c5, b:0x0d6, c:0x0d7, d:0x001 }, { a:0x0c5, b:0x0d7, c:0x0c6, d:0x003 }, { a:0x0c6, b:0x0d7, c:0x0d8, d:0x001 }, { a:0x0c6, b:0x0d8, c:0x0c7, d:0x003 }, { a:0x0c7, b:0x0d8, c:0x0d9, d:0x001 }, { a:0x0c7, b:0x0d9, c:0x0c8, d:0x003 }, { a:0x0c8, b:0x0d9, c:0x0da, d:0x001 }, { a:0x0c8, b:0x0da, c:0x0c9, d:0x003 }, { a:0x0c9, b:0x0da, c:0x0db, d:0x001 }, { a:0x0c9, b:0x0db, c:0x0ca, d:0x003 }, { a:0x0ca, b:0x0db, c:0x0dc, d:0x001 }, { a:0x0ca, b:0x0dc, c:0x0cb, d:0x003 }, { a:0x0cc, b:0x0dd, c:0x0de, d:0x001 }, { a:0x0cc, b:0x0de, c:0x0cd, d:0x003 }, { a:0x0cd, b:0x0de, c:0x0df, d:0x001 }, { a:0x0cd, b:0x0df, c:0x0ce, d:0x003 }, { a:0x0ce, b:0x0df, c:0x0e0, d:0x001 }, { a:0x0ce, b:0x0e0, c:0x0cf, d:0x003 }, { a:0x0cf, b:0x0e0, c:0x0e1, d:0x001 }, { a:0x0cf, b:0x0e1, c:0x0d0, d:0x003 }, { a:0x0d0, b:0x0e1, c:0x0e2, d:0x001 }, { a:0x0d0, b:0x0e2, c:0x0d1, d:0x003 }, { a:0x0d1, b:0x0e2, c:0x0e3, d:0x001 }, { a:0x0d1, b:0x0e3, c:0x0d2, d:0x003 }, { a:0x0d2, b:0x0e3, c:0x0e4, d:0x001 }, { a:0x0d2, b:0x0e4, c:0x0d3, d:0x003 }, { a:0x0d3, b:0x0e4, c:0x0e5, d:0x001 }, { a:0x0d3, b:0x0e5, c:0x0d4, d:0x003 }, { a:0x0d4, b:0x0e5, c:0x0e6, d:0x001 }, { a:0x0d4, b:0x0e6, c:0x0d5, d:0x003 }, { a:0x0d5, b:0x0e6, c:0x0e7, d:0x001 }, { a:0x0d5, b:0x0e7, c:0x0d6, d:0x003 }, { a:0x0d6, b:0x0e7, c:0x0e8, d:0x001 }, { a:0x0d6, b:0x0e8, c:0x0d7, d:0x003 }, { a:0x0d7, b:0x0e8, c:0x0e9, d:0x001 }, { a:0x0d7, b:0x0e9, c:0x0d8, d:0x003 }, { a:0x0d8, b:0x0e9, c:0x0ea, d:0x001 }, { a:0x0d8, b:0x0ea, c:0x0d9, d:0x003 }, { a:0x0d9, b:0x0ea, c:0x0eb, d:0x001 }, { a:0x0d9, b:0x0eb, c:0x0da, d:0x003 }, { a:0x0da, b:0x0eb, c:0x0ec, d:0x001 }, { a:0x0da, b:0x0ec, c:0x0db, d:0x003 }, { a:0x0db, b:0x0ec, c:0x0ed, d:0x001 }, { a:0x0db, b:0x0ed, c:0x0dc, d:0x003 }, { a:0x0dd, b:0x0ee, c:0x0ef, d:0x001 }, { a:0x0dd, b:0x0ef, c:0x0de, d:0x003 }, { a:0x0de, b:0x0ef, c:0x0f0, d:0x001 }, { a:0x0de, b:0x0f0, c:0x0df, d:0x003 }, { a:0x0df, b:0x0f0, c:0x0f1, d:0x001 }, { a:0x0df, b:0x0f1, c:0x0e0, d:0x003 }, { a:0x0e0, b:0x0f1, c:0x0f2, d:0x001 }, { a:0x0e0, b:0x0f2, c:0x0e1, d:0x003 }, { a:0x0e1, b:0x0f2, c:0x0f3, d:0x001 }, { a:0x0e1, b:0x0f3, c:0x0e2, d:0x003 }, { a:0x0e2, b:0x0f3, c:0x0f4, d:0x001 }, { a:0x0e2, b:0x0f4, c:0x0e3, d:0x003 }, { a:0x0e3, b:0x0f4, c:0x0f5, d:0x001 }, { a:0x0e3, b:0x0f5, c:0x0e4, d:0x003 }, { a:0x0e4, b:0x0f5, c:0x0f6, d:0x001 }, { a:0x0e4, b:0x0f6, c:0x0e5, d:0x003 }, { a:0x0e5, b:0x0f6, c:0x0f7, d:0x001 }, { a:0x0e5, b:0x0f7, c:0x0e6, d:0x003 }, { a:0x0e6, b:0x0f7, c:0x0f8, d:0x001 }, { a:0x0e6, b:0x0f8, c:0x0e7, d:0x003 }, { a:0x0e7, b:0x0f8, c:0x0f9, d:0x001 }, { a:0x0e7, b:0x0f9, c:0x0e8, d:0x003 }, { a:0x0e8, b:0x0f9, c:0x0fa, d:0x001 }, { a:0x0e8, b:0x0fa, c:0x0e9, d:0x003 }, { a:0x0e9, b:0x0fa, c:0x0fb, d:0x001 }, { a:0x0e9, b:0x0fb, c:0x0ea, d:0x003 }, { a:0x0ea, b:0x0fb, c:0x0fc, d:0x001 }, { a:0x0ea, b:0x0fc, c:0x0eb, d:0x003 }, { a:0x0eb, b:0x0fc, c:0x0fd, d:0x001 }, { a:0x0eb, b:0x0fd, c:0x0ec, d:0x003 }, { a:0x0ec, b:0x0fd, c:0x0fe, d:0x001 }, { a:0x0ec, b:0x0fe, c:0x0ed, d:0x003 }, { a:0x0ee, b:0x0ff, c:0x100, d:0x001 }, { a:0x0ee, b:0x100, c:0x0ef, d:0x003 }, { a:0x0ef, b:0x100, c:0x101, d:0x001 }, { a:0x0ef, b:0x101, c:0x0f0, d:0x003 }, { a:0x0f0, b:0x101, c:0x102, d:0x001 }, { a:0x0f0, b:0x102, c:0x0f1, d:0x003 }, { a:0x0f1, b:0x102, c:0x103, d:0x001 }, { a:0x0f1, b:0x103, c:0x0f2, d:0x003 }, { a:0x0f2, b:0x103, c:0x104, d:0x001 }, { a:0x0f2, b:0x104, c:0x0f3, d:0x003 }, { a:0x0f3, b:0x104, c:0x105, d:0x001 }, { a:0x0f3, b:0x105, c:0x0f4, d:0x003 }, { a:0x0f4, b:0x105, c:0x106, d:0x001 }, { a:0x0f4, b:0x106, c:0x0f5, d:0x003 }, { a:0x0f5, b:0x106, c:0x107, d:0x001 }, { a:0x0f5, b:0x107, c:0x0f6, d:0x003 }, { a:0x0f6, b:0x107, c:0x108, d:0x001 }, { a:0x0f6, b:0x108, c:0x0f7, d:0x003 }, { a:0x0f7, b:0x108, c:0x109, d:0x001 }, { a:0x0f7, b:0x109, c:0x0f8, d:0x003 }, { a:0x0f8, b:0x109, c:0x10a, d:0x001 }, { a:0x0f8, b:0x10a, c:0x0f9, d:0x003 }, { a:0x0f9, b:0x10a, c:0x10b, d:0x001 }, { a:0x0f9, b:0x10b, c:0x0fa, d:0x003 }, { a:0x0fa, b:0x10b, c:0x10c, d:0x001 }, { a:0x0fa, b:0x10c, c:0x0fb, d:0x003 }, { a:0x0fb, b:0x10c, c:0x10d, d:0x001 }, { a:0x0fb, b:0x10d, c:0x0fc, d:0x003 }, { a:0x0fc, b:0x10d, c:0x10e, d:0x001 }, { a:0x0fc, b:0x10e, c:0x0fd, d:0x003 }, { a:0x0fd, b:0x10e, c:0x10f, d:0x001 }, { a:0x0fd, b:0x10f, c:0x0fe, d:0x003 }, { a:0x0ff, b:0x110, c:0x111, d:0x001 }, { a:0x0ff, b:0x111, c:0x100, d:0x003 }, { a:0x100, b:0x111, c:0x112, d:0x001 }, { a:0x100, b:0x112, c:0x101, d:0x003 }, { a:0x101, b:0x112, c:0x113, d:0x001 }, { a:0x101, b:0x113, c:0x102, d:0x003 }, { a:0x102, b:0x113, c:0x114, d:0x001 }, { a:0x102, b:0x114, c:0x103, d:0x003 }, { a:0x103, b:0x114, c:0x115, d:0x001 }, { a:0x103, b:0x115, c:0x104, d:0x003 }, { a:0x104, b:0x115, c:0x116, d:0x001 }, { a:0x104, b:0x116, c:0x105, d:0x003 }, { a:0x105, b:0x116, c:0x117, d:0x001 }, { a:0x105, b:0x117, c:0x106, d:0x003 }, { a:0x106, b:0x117, c:0x118, d:0x001 }, { a:0x106, b:0x118, c:0x107, d:0x003 }, { a:0x107, b:0x118, c:0x119, d:0x001 }, { a:0x107, b:0x119, c:0x108, d:0x003 }, { a:0x108, b:0x119, c:0x11a, d:0x001 }, { a:0x108, b:0x11a, c:0x109, d:0x003 }, { a:0x109, b:0x11a, c:0x11b, d:0x001 }, { a:0x109, b:0x11b, c:0x10a, d:0x003 }, { a:0x10a, b:0x11b, c:0x11c, d:0x001 }, { a:0x10a, b:0x11c, c:0x10b, d:0x003 }, { a:0x10b, b:0x11c, c:0x11d, d:0x001 }, { a:0x10b, b:0x11d, c:0x10c, d:0x003 }, { a:0x10c, b:0x11d, c:0x11e, d:0x001 }, { a:0x10c, b:0x11e, c:0x10d, d:0x003 }, { a:0x10d, b:0x11e, c:0x11f, d:0x001 }, { a:0x10d, b:0x11f, c:0x10e, d:0x003 }, { a:0x10e, b:0x11f, c:0x120, d:0x001 }, { a:0x10e, b:0x120, c:0x10f, d:0x003 },]; var palette = [ 0x000000, 0x0000ff, 0x00ff00, 0x00ffff, 0xff0000, 0xff00ff, 0xffff00, 0xffffff, 0x000000, 0x0000ff, 0x00ff00, 0x00ffff, 0xff0000, 0xff00ff, 0xffff00, 0xffffff ]; </script> </head> <body onload="run()" style="text-align:center"> <canvas id="canvas" width="256" height="256"/> </body></html>
  4. a,b and c are the indices of the points in "points" array. d is the color : 1 for blue, 2 for green and 4 for red (only 1=blue and 3=cyan used here) i agree using "d" after a,b and c for something totally different was a bad choice ! sorry about it.
  5. I guess all SVGA monitors actually display 50MHz+ color info: you would need a *very* steep low pass filter to filter out the high frequencies while keeping the 25MHz signal. Without having done serious tests, I'd say 10x oversampling (250MHz) + a first order low pass filter is a minimum if you want a reliable image, not depending on the monitor. It's worth a try, though, I might be totally wrong. My two cents: use both the R ladder and low frequency sigma-delta, for example to double the precision (oscillate at 100MHz between two values to get a halftone) For the record: I tried several "flickering" tricks (change pixel value on each frame), but that's quickly painful for the eyes, even if you use a checker pattern.
  6. papilio_clk = 32MHz vga_clk= 25.175 MHz gpu_clk = 4xvga_clk = ~100MHz
  7. for the genesis, do not remove the z80: if i remember well, it is often used as the sound coprocessor (which might explain why the sound is often missing)
  8. if you use a AVR sketch, then what you upload is a (parallel) implementation of an AVR with the AVR code. The simulated AVR will run the sketch just as a normal one would do, that is in a sequential fashion. So, the simple answer is no: you'll have to write HDL code to really use the parallel features of the FPGA.
  9. maybe you can have a look at the amber ARMv2 core, in OpenCores. There's a cache in there -- not that I really looked into it, though, it might just be rubbish for you.
  10. I'm looking into getting suska, an fpga implementation of the atari ste, to work on the papilio (see http://www.experiment-s.de/en/). Seems feasible but, on the papilio plus, the size of the sram (512kB) and the size of the atari rom (256kB) will leave only 256kB of user ram, making the whole thing a bit useless (virtually all atari st machines had at least 512kB of ram...) So I'd be *very* interested in getting one of these Papilio Pro boards... please keep us posted about the progress on the seeed studio front. BTW, what about your project of a new, simplified arcade megawing ?
  11. Forth on a Papilio

    I wanted to add cheap, generic interactivity to VHDL projects, to replace AVR8 sketches, which are great but expensive, and not extendable "in situ" (you need to compile the new sketch and flash your FPGA) My goal is to provide a full Forth system, that allows the control and programming of FPGA projects through a UART console, without taking too much of the FPGA resources. Forth is good for that because it is very simple, produces very compact code (99% calls to subroutines) and allows the on-the-fly compling of new code on a live system. To keep things small and fast, I designed a custom processor, with two stacks and only two general purpose registers, with a simple, RISC-like, machine code. The "machine" itself is very small (~7% of a Papilio 500), and uses only 3 ram blocks (1 for stacks, 2 for program/data memory) It seems to work fine, except for the custom UART, which is still a bit buggy (timing problems -- a shame at 9600 bauds...) It's designed to be easily extensible, using memory mapped devices, so you can use it as an interface to your cores. The Forth system itself is still very beta, but you can already define words and do some simple arithmetic and io. I implemented a basic "compiler/assembler" and a simulator (both in Java). Next steps are 1) complete the Forth system and 2) debug the thing thoroughly so it can be used seriously. V0 is on GitHub, at https://github.com/b...9/Papilio-Forth And more info on Forth on http://www.softsynth...rth/pf_tut.php. Ben
  12. I did actually port the J1 processos on the Papilio, and reimplemented some of the Forth core words -- still beta, though : http://forum.gadgetfactory.net/index.php?/topic/1279-forth-on-a-papilio/
  13. Who would be interested in trying to get a doom engine running on a papilio plus ? some info on the rendering process at http://fabiensanglard.net/doomIphone/doomClassicRenderer.php Walls should be "easy", but floors and ceilings look way more complicated (I'm concerned about the flood-fill algorithm used in the original code). Plenty of challenges there : - simultaneous access to ram for data and texture access, back buffer write and screen display -- Atari ST style multiplexing might be the key, maybe a wishbone-like arbiter ; - complex data structures handling in VHDL (with pipelining if we aim at a 60 Hz refresh) ; - 16.16 fixed integer computations -- that does not fit in the 18 bit of the DSP block... A (not so) quick check lets me belive that there is enough space in the sram chip for : - 2 vga screen buffers (128kB - 64kB each) if we keep the HRES a bit low 256*240 - the level structures (~50kB for the first level) -- maybe we can put some of it in block ram - the textures (~100kB for the same level) - some space for intermediate structures (floors and ceilings, 65kB in the original code) I'm more concerned about the size of precomputed tables -- can they fit in the ram blocks ? Right now, I'm looking into a Java implementation, to see how all this actually fits together.
  14. Be my guest ! To be accurate : I do not double the ram clock, I used an inverted clock, so the rising edge of the ram clock happens right in the middle of the logic clock cycle (at the falling edge) I actually thought that this was the right way to use BRAMs, but I must have got it wrong : I obviously need to dig into the Xilinx manuals... EDIT : checking on the manuals, you actually need to set the address (and data for write) some time before clk and keep it stable for some time afterwards. And the BRAM has a built-in clock inverter. So this is a right way to use BRAM, if not *the* right way for single clock accesses. BUT, against all general rules about clocks, you should use a *gated clock* ("not clk") instead of a global inverted clock, as it seems the synthesis tools use the built-in inverter, and that makes the clock skew much better, and the clock uncertainty a little better : reverting to gated clocks changed the worst slack from -2ns to -0.2ns... (which is still wrong, but not that bad)
  15. just looked at the timing report, to check which paths were not routed within spec. It appears these are paths from BRAM to a 9 bit compare, because I use inverted clock for BRAM and a regular clock for the registers that use the compare results -- so the constraint for the output path is 200MHz instead of 100MHz. Any ideas about how to keep the constraint low without putting a register out of the bram ? (As this is in a critical loop, I really need to test a value at *every* cycle.) I tried using a in-phase clock for the BRAM, but this gives unstable data, so I switched to 180° phased clock. Using a 90° phased clock makes it a little better -- that is p&R is still failing but the offset is not that bad. Note that the thing seems to work perfectly in real life: the Xilinx toolchain timings must be tighter than reality (which is sensible)