 # Diamond Ore Generation attempt

Jan 2nd, 2021
111
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
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;
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
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.
69.
70.     for (int k = 0; k < config_size; ++k)
71.     {
72.         float ring_radius = afloat[k * 4 + 3];
73.
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.             {
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.                     {
106.
108.                         {
109.                             for (int z = z_first; z <= z_last; ++z)
110.                             {
112.
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);
124.                                     }
125.                                 }
126.                             }
127.                         }
128.                     }
129.                 }
130.             }
131.         }
132.     }
133.
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.
167.
169.     int y_bound_start = pos.y - 2            - half_radius;
171.