Advertisement
Tslat

Diamond Ore Generation attempt

Jan 2nd, 2021
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.95 KB | None | 0 0
  1. int spheres_made = 0;
  2.  
  3. bool func_207803_a(int config_size, float x_start, float x_end, float y_start, float y_end, float z_start, float z_end, int xstart, int ystart, int zstart, int width, int length) {
  4.  
  5.     uint32_t state = config_size + x_start + x_end + y_start + y_end + z_start + z_end + xstart+ystart+zstart+width+length;
  6.  
  7.     // BitSets are probably terrible for such small data
  8.     std::vector<bool> bitset(width * width * length);
  9.     std::vector<float> afloat(config_size * 4);
  10.  
  11.     for (int k = 0; k < config_size; ++k)
  12.     {
  13.         float t = (float) k / (float) config_size;
  14.  
  15.         float half_radius = config_size / 16.F;
  16.         float random_times_half_radius = rnd(&state) * half_radius;
  17.  
  18.         // Point XYZ along vein axis start to end
  19.         // Veins are only on the XZ plane so why we bother with Y calculations at all...
  20.         // I have no idea, it's always going to result in 0 change.
  21.         afloat[k * 4 + 0] = lerp(t, x_start, x_end);
  22.         afloat[k * 4 + 1] = lerp(t, y_start, y_end);
  23.         afloat[k * 4 + 2] = lerp(t, z_start, z_end);
  24.  
  25.         float taper = sinf(3.14159F * t); // Smaller at ends, larger in middle
  26.         float taper_min = taper + 1.0F;  // Add one so we taper between 1x to 2x
  27.         float taper_times_radius = taper_min * random_times_half_radius; // Combined taper and random effect
  28.         float radius_min = taper_times_radius + 1.F; // Don't want a 0 radius, minimum radius = 1?
  29.         float radius = radius_min / 2.F; // Not sure why the division again (comensate for +1's maybe) but it keeps the size in check
  30.  
  31.         // Diameter of vein is maximum of config.size / 4 at this point.
  32.  
  33.         afloat[k * 4 + 3] = radius;
  34.     }
  35.     // Some kind of smoothing? Can't visually tell the difference at all
  36.     for (int k = 0; k < config_size - 1; ++k)
  37.     { // ^v^v For each non-elimated ring
  38.         if (afloat[k * 4 + 3] > 0)
  39.         {
  40.             for (int k3 = k + 1; k3 < config_size; ++k3)
  41.             {  // ^v^v For each non-elimated ring after, moving towards end
  42.                 if (afloat[k3 * 4 + 3] > 0)
  43.                 {
  44.                     float xdiff = afloat[k * 4 + 0] - afloat[k3 * 4 + 0];
  45.                     float ydiff = afloat[k * 4 + 1] - afloat[k3 * 4 + 1];
  46.                     float zdiff = afloat[k * 4 + 2] - afloat[k3 * 4 + 2];
  47.  
  48.                     float rdiff = afloat[k * 4 + 3] - afloat[k3 * 4 + 3];
  49.  
  50.                     /// If difference in ring size is greater than separation distance,
  51.                     // No idea what the significance of this is... best guess is that
  52.                     // it tries to make ends more flat but I'm not noticing that
  53.                     // Or maybe a slight optimisation to remove small rings covered by
  54.                     // previous rings?
  55.                     if (rdiff * rdiff > xdiff * xdiff + ydiff * ydiff + zdiff * zdiff)
  56.                     {
  57.                         // Eliminate smaller ring
  58.                         if (rdiff > 0)
  59.                             afloat[k3 * 4 + 3] = -1.0;
  60.                         else
  61.                             afloat[k * 4 + 3] = -1.0;
  62.                     }
  63.                 }
  64.             }
  65.         }
  66.     }
  67.  
  68.     spheres_made = 0;
  69.  
  70.     for (int k = 0; k < config_size; ++k)
  71.     {
  72.         float ring_radius = afloat[k * 4 + 3];
  73.  
  74.         if (ring_radius >= 0)
  75.         {
  76.             // XYZ Position at point k
  77.             float pos_x = afloat[k * 4 + 0];
  78.             float pos_y = afloat[k * 4 + 1];
  79.             float pos_z = afloat[k * 4 + 2];
  80.  
  81.             // Sub radius from current position as a starting point.
  82.             // The max check is useless, ring_radius should have never been
  83.             // set greater than the width/2 of our bounding volume
  84.             int x_first = max(floor(pos_x - ring_radius), xstart);
  85.             int y_first = max(floor(pos_y - ring_radius), ystart);
  86.             int z_first = max(floor(pos_z - ring_radius), zstart);
  87.  
  88.             // Get final position to iterate to...
  89.  
  90.             // However, ring_radius can't be negative here, so this position is always greater than xyz_first
  91.             // Therefore this max call is useless? even if the xyz_first was meant to be xyz_start + width it
  92.             // would still be wrong... I don't get this...
  93.  
  94.             int x_last = max(floor(pos_x + ring_radius), x_first);
  95.             int y_last = max(floor(pos_y + ring_radius), y_first);
  96.             int z_last = max(floor(pos_z + ring_radius), z_first);
  97.             for (int x = x_first; x <= x_last; ++x)
  98.             {
  99.                 float x_perc_ring_radius = (x + 0.5f - pos_x) / ring_radius;
  100.  
  101.                 if (x_perc_ring_radius < 1) // Don't do anything if outside of ring
  102.                 {
  103.                     for (int y = y_first; y <= y_last; ++y)
  104.                     {
  105.                         float y_perc_ring_radius = (y + 0.5f - pos_y) / ring_radius;
  106.  
  107.                         if (mag(x_perc_ring_radius, y_perc_ring_radius) < 1)
  108.                         {
  109.                             for (int z = z_first; z <= z_last; ++z)
  110.                             {
  111.                                 float z_perc_ring_radius = (z + 0.5f - pos_z) / ring_radius;
  112.  
  113.                                 if (mag(x_perc_ring_radius, y_perc_ring_radius, z_perc_ring_radius) < 1)
  114.                                 {
  115.                                     // 3D array indexing formula (bitset is a 3d array flattened)
  116.                                     int l2 = x - (xstart) + (y - ystart) * width + (z - zstart) * width * length;
  117.                                    
  118.                                     if (!bitset[l2])
  119.                                     {
  120.                                         bitset[l2] = true;
  121.                                         sphere s{ V3F(x, y, z), .5F, 2 };
  122.                                         g_mc_world.spheres.push_back(s);
  123.                                         ++spheres_made;
  124.                                     }
  125.                                 }
  126.                             }
  127.                         }
  128.                     }
  129.                 }
  130.             }
  131.         }
  132.     }
  133.  
  134.     return spheres_made > 0;
  135. }
  136.  
  137. bool generate(V3F pos, int config_size, int test=6)
  138. {
  139.     // How it works summary:
  140.     // Vein made from a position P, size K, and angle A. The radius will be K/8.
  141.     // The vein spans a line segment contain K points beginning at P-(angle * radius)
  142.     // to P+(angle*radius). For each of these points randomly generate a 'ring radius'.
  143.     // Do some filtering (or not) on it. Lastly for each point, iterate the blocks in the
  144.     // bounding box around it (dimensions of ring radius), checking if the distance
  145.     // to that block is within ring radius units. Basically you iterate over a sphere for
  146.     // each of the K points.
  147.  
  148.     uint32_t state = config_size + pos.x + pos.y + pos.z + test*test;
  149.  
  150.     float angle = rnd(&state) * 3.14159F;
  151.     //angle = 0;
  152.     float radius = config_size / 8.f;
  153.  
  154.     // No need to caclulate these twice...
  155.     float sinAngle = sin(angle) * radius;
  156.     float cosAngle = cos(angle) * radius;
  157.  
  158.     float x_start = pos.x + sinAngle;
  159.     float x_end   = pos.x - sinAngle;
  160.     float z_start = pos.z + cosAngle;
  161.     float z_end   = pos.z - cosAngle;
  162.  
  163.     float y_start = pos.y - (rand() % 3);
  164.     float y_end   = y_start;
  165.  
  166.     int half_radius = ceil(radius / 2 + 0.5);
  167.  
  168.     int x_bound_start = pos.x - ceil(radius) - half_radius;
  169.     int y_bound_start = pos.y - 2            - half_radius;
  170.     int z_bound_start = pos.z - ceil(radius) - half_radius;
  171.  
  172.     int bound_width = 2 * (ceil(radius) + half_radius);
  173.     int bound_length = 4 + 2 * half_radius;
  174.  
  175.     for (int x = x_bound_start; x <= x_bound_start + bound_width; ++x)
  176.         for (int z = z_bound_start; z <= z_bound_start + bound_width; ++z)
  177.             return func_207803_a(config_size, x_start, x_end, y_start, y_end, z_start, z_end, x_bound_start, y_bound_start, z_bound_start, bound_width, bound_length);
  178.  
  179.     return false;
  180. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement