Advertisement
Guest User

Untitled

a guest
Jun 12th, 2023
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Game Maker 26.33 KB | Source Code | 0 0
  1. /// @function cube(data, i, j, k, cs)
  2. /// @description A struct to represent a cube in the noise array
  3. /// @param data a pointer to the noise array
  4. /// @param i coords of the cube in the noise array
  5. /// @param j
  6. /// @param k
  7. /// @param cs the size of the cube.
  8. function cube(data, i, j, k, cs) constructor{
  9.     // this array holds the noise values at each corner of the cube
  10.     values = [data[i    ][j    ][k    ],
  11.               data[i + 1][j    ][k    ],
  12.               data[i + 1][j + 1][k    ],
  13.               data[i    ][j + 1][k    ],
  14.               data[i    ][j    ][k + 1],
  15.               data[i + 1][j    ][k + 1],
  16.               data[i + 1][j + 1][k + 1],
  17.               data[i    ][j + 1][k + 1]];
  18.     // this array holds vectors for each corner of the cube
  19.     points = [new vec3d((i + 0) * cs, (j + 0) * cs, (k + 0) * cs),
  20.               new vec3d((i + 1) * cs, (j + 0) * cs, (k + 0) * cs),
  21.               new vec3d((i + 1) * cs, (j + 1) * cs, (k + 0) * cs),
  22.               new vec3d((i + 0) * cs, (j + 1) * cs, (k + 0) * cs),
  23.               new vec3d((i + 0) * cs, (j + 0) * cs, (k + 1) * cs),
  24.               new vec3d((i + 1) * cs, (j + 0) * cs, (k + 1) * cs),
  25.               new vec3d((i + 1) * cs, (j + 1) * cs, (k + 1) * cs),
  26.               new vec3d((i + 0) * cs, (j + 1) * cs, (k + 1) * cs)];
  27.    
  28. }
  29.  
  30. /// @function marcher(d, cs, iv, vb, vf)
  31. /// @description a struct that does the marching cube algorithm
  32. /// @param d the noise array
  33. /// @param cs the cube size
  34. /// @param iv the isovalue
  35. /// @param vb the vertex buffer
  36. /// @param the vertex buffer format
  37. function marcher(d, cs, iv, vb, vf) constructor{
  38.     data = d;
  39.     cube_size = cs;
  40.     isovalue = iv;
  41.     vbuff = vb;
  42.     vform = vf;
  43.    
  44.     /*
  45.     static cube_corners = [new vec3d(0, 0, 0),
  46.                            new vec3d(1, 0, 0),
  47.                            new vec3d(1, 1, 0),
  48.                            new vec3d(0, 1, 0),
  49.                            new vec3d(0, 0, 1),
  50.                            new vec3d(1, 0, 1),
  51.                            new vec3d(1, 1, 1),
  52.                            new vec3d(0, 1, 1)];
  53.     */
  54.     // this table holds hex values for determining which edges of the cube get intersected by triangles
  55.     static edge_table = [0x0  , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
  56.                     0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
  57.                     0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
  58.                     0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
  59.                     0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
  60.                     0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
  61.                     0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
  62.                     0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
  63.                     0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
  64.                     0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
  65.                     0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
  66.                     0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
  67.                     0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
  68.                     0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
  69.                     0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
  70.                     0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
  71.                     0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
  72.                     0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
  73.                     0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
  74.                     0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
  75.                     0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
  76.                     0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
  77.                     0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
  78.                     0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
  79.                     0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
  80.                     0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
  81.                     0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
  82.                     0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
  83.                     0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
  84.                     0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
  85.                     0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
  86.                     0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 ]
  87.    
  88.     // this table is for making triangles...
  89. /// @function get_cube_index(c, isovalue)
  90.     /// @description returns a number that determines what cube configuration is used
  91.     /// @param c the cube.
  92.     /// @param isovalue the isovalue
  93.     static get_cube_index = function(c, isovalue){
  94.         var index = 0;
  95.         if(c.values[0] < isovalue) index |= 1;
  96.         if(c.values[1] < isovalue) index |= 2;
  97.         if(c.values[2] < isovalue) index |= 4;
  98.         if(c.values[3] < isovalue) index |= 8;
  99.         if(c.values[4] < isovalue) index |= 16;
  100.         if(c.values[5] < isovalue) index |= 32;
  101.         if(c.values[6] < isovalue) index |= 64;
  102.         if(c.values[7] < isovalue) index |= 128;
  103.         return index;
  104.     }
  105.    
  106.     /// @function point_lerp(p1, p2, val1, val2, isoval)
  107.     /// @description does a linear interpolation between 2 points in 3d space
  108.     /// @param p1 the first point
  109.     /// @param p2 the second point
  110.     /// @param val1 the noise value at p1
  111.     /// @param val2 the noise value at p2
  112.     /// @param isoval the isovalue that we interpolate at.
  113.     static point_lerp = function(p1, p2, val1, val2, isoval){
  114.         var lerp_factor = (isoval - val1)/(val2 - val1);
  115.         var temp = p2.subtract(p1);
  116.         temp.multiply_self(lerp_factor);
  117.         temp.add_self(p1);
  118.         return temp;
  119.         // use this line to get a blockier mesh
  120.         //return p1.add(p2).multiply(0.5);
  121.     }
  122.    
  123.    
  124.     /// @function triangulate(c, isoval)
  125.     /// @description returns a list of points representing triangles that make up each cube.
  126.     /// @param c the cube to be triangulated
  127.     /// @param isoval the isovalue to make triangles at.
  128.     static triangulate = function(c, isoval){
  129.         var index = get_cube_index(c, isoval);
  130.         var edge_code = edge_table[index];
  131.         var tri_code = tri_table[index];
  132.         // create a list of vertices
  133.         var vert_list = [];
  134.         if(edge_code &    1){ vert_list[ 0] = point_lerp(c.points[0], c.points[1], c.values[0], c.values[1], isoval); }
  135.         if(edge_code &    2){ vert_list[ 1] = point_lerp(c.points[1], c.points[2], c.values[1], c.values[2], isoval); }
  136.         if(edge_code &    4){ vert_list[ 2] = point_lerp(c.points[2], c.points[3], c.values[2], c.values[3], isoval); }
  137.         if(edge_code &    8){ vert_list[ 3] = point_lerp(c.points[3], c.points[0], c.values[3], c.values[0], isoval); }
  138.         if(edge_code &   16){ vert_list[ 4] = point_lerp(c.points[4], c.points[5], c.values[4], c.values[5], isoval); }
  139.         if(edge_code &   32){ vert_list[ 5] = point_lerp(c.points[5], c.points[6], c.values[5], c.values[6], isoval); }
  140.         if(edge_code &   64){ vert_list[ 6] = point_lerp(c.points[6], c.points[7], c.values[6], c.values[7], isoval); }
  141.         if(edge_code &  128){ vert_list[ 7] = point_lerp(c.points[7], c.points[4], c.values[7], c.values[4], isoval); }
  142.         if(edge_code &  256){ vert_list[ 8] = point_lerp(c.points[0], c.points[4], c.values[0], c.values[4], isoval); }
  143.         if(edge_code &  512){ vert_list[ 9] = point_lerp(c.points[1], c.points[5], c.values[1], c.values[5], isoval); }
  144.         if(edge_code & 1024){ vert_list[10] = point_lerp(c.points[2], c.points[6], c.values[2], c.values[6], isoval); }
  145.         if(edge_code & 2048){ vert_list[11] = point_lerp(c.points[3], c.points[7], c.values[3], c.values[7], isoval); }
  146.         // create a list of triangles
  147.         var tri_list = [];
  148.         for(var i = 0; tri_code[i] != -1; i += 3){
  149.             tri_list[i div 3] = [vert_list[tri_code[i]], vert_list[tri_code[i + 1]], vert_list[tri_code[i + 2]]];
  150.         }
  151.         return tri_list;
  152.     }
  153.    
  154.     /// @function march()
  155.     /// @description run the marching cubes algorithm
  156.     static march = function(){
  157.         // get the dimensions of the noise array
  158.         var cubes_wide = array_length(data) - 1;
  159.         var cubes_long = array_length(data[0]) - 1;
  160.         var cubes_high = array_length(data[0][0]) - 1;
  161.        
  162.         // start the vertex buffer
  163.         vertex_begin(vbuff, vform);
  164.         // iterate through the noise array
  165.         for(var i = 0; i < cubes_wide; i++){
  166.             for(var j = 0; j < cubes_long; j++){
  167.                 for(var k = 0; k < cubes_high; k++){
  168.                     // create a cube at the current position in the noise array
  169.                     var c = new cube(data, i, j, k, cube_size);
  170.                     // get a triangle list for the cube
  171.                     var t_list = triangulate(c, isovalue);
  172.                     // if there are triangles, add them to the vertex buffer
  173.                     if(array_length(t_list) > 0){
  174.                         for(var t = 0; t < array_length(t_list); t++){
  175.                             vertex_position_3d(vbuff, t_list[t][0].X, t_list[t][0].Y, t_list[t][0].Z);
  176.                             vertex_color(vbuff, c_yellow, 1);
  177.                             vertex_texcoord(vbuff, 0, 0);
  178.                            
  179.                             vertex_position_3d(vbuff, t_list[t][1].X, t_list[t][1].Y, t_list[t][1].Z);
  180.                             vertex_color(vbuff, c_red, 1);
  181.                             vertex_texcoord(vbuff, 0, 0);
  182.                            
  183.                             vertex_position_3d(vbuff, t_list[t][2].X, t_list[t][2].Y, t_list[t][2].Z);
  184.                             vertex_color(vbuff, c_green, 1);
  185.                             vertex_texcoord(vbuff, 0, 0);
  186.                         }
  187.                     }
  188.                 }
  189.             }
  190.         }
  191.         vertex_end(vbuff);
  192.     }
  193. }
  194.  
  195.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement