Tslat

Diamond Ore Generation attempt

Jan 2nd, 2021
60
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×