Commit Graph

279 Commits

Author SHA1 Message Date
Nel-S
f19aafa88c
Refactor findFittest as nested for loop
The functions perform the same instructions either way, but this makes it far clearer (to me, at least) how rad and ang relate to each other, and what the runtime complexity of findFittest is (O(n^2) instead of the O(n) it might appear to be at first glance).
2023-02-15 18:59:14 -08:00
Cubitect
ddd19a14f6 Performance improvements to beta 1.7 biome gen. 2023-02-07 22:02:46 +01:00
Cubitect
b03c559c86 Fixed error in substitution of biomes ids 2023-02-05 19:49:49 +01:00
Cubitect
a666727069
Merge pull request #90 from KaiSandstrom/master
Beta 1.7 fixes and tweaks
2023-02-05 19:02:09 +01:00
Kai Sandstrom
e59c0d09e2 Beta 1.7 fixes and tweaks
(generator.c)
- getMinCacheSize():
    - Replaced integer mults/divs by powers of 2 with bit shifts.
    - Fixed a bug that made the cache buffer 2 SeaLevelColumnNoises too short.
          I'm kind of surprised this didn't cause segfaults.
- genBiomes():
    - Now copies cache values from y=0 to higher y values when sy > 1, to match
          behavior of b1.8 - 1.17.

(noise.c)
- removed sampleOctave2D().

(layers.c)
- genColumnNoise(): Now uses sampleOctaveAmp() for 2D Perlin samples.
- processColumnNoise(), sampleBlocks(), sampleBetaBiomeOneBlock(),
    genBetaBiomeNoiseScaled():
    - Replaced integer mults/divs and modulos by powers of 2 with left/right
        bit shifts and bitwise and, respectively.
2023-02-05 12:38:24 -05:00
Cubitect
c504c9aced Disable strogholds for beta 1.7 2023-02-05 17:47:16 +01:00
Cubitect
df2b40f3ac Make biomes finders work with beta 1.7 + fix getSpawn for <=1.0 2023-02-05 17:26:52 +01:00
Cubitect
01653265ff Remap biome IDs for beta 1.7 + color tweak 2023-02-05 01:27:43 +01:00
Cubitect
7496e316a0 Octave specific biome noise initialization + use new IDs for beta + removed VLA 2023-02-04 18:09:05 +01:00
Cubitect
19f13a9a22
Merge pull request #87 from KaiSandstrom/master
Add support for Alpha 1.2 - Beta 1.7 biome system
2023-02-04 14:14:50 +01:00
Kai Sandstrom
a42d97197c Added ocean detection for Beta 1.7
(generator.c)
- getMinCacheSize(): Allocate extra cache for Beta ocean column noise buffer

(noise.c)
- samplePerlin(): Reverted previous change, as the attempted optimization had
      unintended side-effects for 1.18+ generation and had no measurable
      performance improvement.

(layers.h)
- Renamed two OctaveNoise members of struct SurfaceNoiseBeta
- Added new struct SeaLevelColumnNoiseBeta
- Added headers for four new functions defined in layers.c

(layers.c)
- initSurfaceNoiseBeta(): Reflect changes to names in layers.h
- sampleBiomeNoiseBeta(): When nptype == 1, returned humidity value is now
      multiplied by temperature to reflect the behavior seen in biome gen
- Added new function genColumnNoise():
      Generates values used to calculate terrain noise columns and places
      them in a SeaLevelColumnNoiseBeta struct pointed to by the provided
      pointer.
- Added new function processColumnNoise():
      Generates a partial noise column for finding the block at sea level
      using data pointed to by the provided SeaLevelColumnNoiseBeta pointer
- Added new function sampleBlocks():
      Using adjacent noise columns, determine whether the blocks at y=64 are
      solid and place results in array pointed to by provided pointer
- Added new function sampleBetaBiomeOneBlock():
      Generates new noise columns for each sampled block and skips the
      diagonal traversal with cache buffer, as no noise columns data can be
      re-used when scale >= 8.
- genBetaBiomeNoiseScaled():
          Previous "no ocean" code is now locked behind (noOcean || scale >= 8)
      condition. Calls sampleBiomeNoiseBeta() when noOcean is true, and calls
      sampleBetaBiomeOneBlock() otherwise.
          Else, the generated region is traversed in 4x4 block sections
      corresponding to terrain noise columns. Columns are saved for re-use in
      future passes in order to minimize unnecessary Perlin generation, and
      region traversal is done in diagonal stripes in order to minimize extra
      cache size needed (on average) for the saved noise sample buffer.

My original plan for the diagonal traversal was to store SeaLevelColumnNoise
*pointers* in the extra cache space, which would be dynamically allocated
when generated, but since extra cache space will only exceed the original
cache space when the generated area is so small that memory concerns are
trivial, this plan was abandoned in favor of storing the structs directly in
the cache. This approach also eliminates the risk of memory leaks.

Currently, with oceans, this code takes about 20 seconds to generate the
biomes for a 4096 x 4096 block region. Since this approach to ocean-finding
deals in 4x4 noise columns, scales 2-4 are still quite slow for the same
scaled region -- about 13 seconds at 1:4 scale. At higher scales, the
diagonal approach is abandoned and four new noise columns are generated for
every midpoint block that is sampled.

I made a quick test build of Cubiomes Viewer, and while the ocean-finding
code works, the regions are very slow to show up in the view window, and
changing the zoom level can cause regions to reset when zooming in both
directions. Perhaps some optimizations can be made in Cubiomes Viewer in
terms of handling cache and displaying generated biomes at different scales,
but I'm not familiar enough with that project to suggest anything specific.
I tried to cut out as much unnecessary processing as possible in my
implementation of the inherently cpu-intensive ocean-finding algorithm, but
it's certainly possible optimizations can be made in the generation code
itself.
2023-02-01 19:00:03 -05:00
Cubitect
2e9cfee110
Merge pull request #89 from Nel-S/patch-2
Remove premature spawn return
2023-01-29 13:02:29 +01:00
Nel-S
773f647f43
Remove premature spawn return
After estimating the approximate spawn position, Cubiomes currently centers the position in the middle of the corresponding chunk and then (I'm guessing erroneously) returns the position immediately, completely skipping all of the code fine-tuning the position to the most likely block afterwards. As a result, every single spawnpoint calculated by Cubiomes (and consequently Cubiomes Viewer) is in the middle of a chunk, leading to problems such as origin spawns always returning as (8, 8) instead of (0, 0), and so on.
2023-01-28 22:10:37 -08:00
Kai Sandstrom
b9ab274afa Added noise generation functions for Beta 1.7 terrain
(biome_tree.c)
- Moved a curly brace to maintain style consistent with repo

(generator.h)
- Removed SurfaceNoiseBeta struct from Generator

(generator.c)
- applySeed(): Removed initSurfaceNoiseBeta() call
- genBiomes():
      Now declares and initializes SurfaceNoiseBeta when mc <= MC_B1_7
      Returns err when g->dim == DIM_END and mc < MC_1_0

(layers.c)
- biomeExists(): Added new checks for mc <= B1_7
- initSurfaceNoiseBeta(): Implemented
- New comment added to sampleBiomeNoiseBeta()

(noise.h)
- Added headers for four new functions defined in noise.c

(noise.c)
- samplePerlin(): Placed all lerps used for 3D noise but not used for 2D noise
      behind a (d2 != 0) condition. I'm anticipating needing every bit of
      optimization I can find to make ocean-finding practically efficient.
- added new samplePerlinOldBetaTerrain3D() function:
      used to generate the octmin, octmax, and octmain noise near sea level
      for the given noise column x and z. The necessity for this function will
      be explained more in-depth below.
- added new initOctaveOldBetaTerrain() function:
      Used to initialize the five Perlin OctaveNoise structs in
      SurfaceNoiseBeta. Unlike climate noise, these are Perlin noise maps
      instead of Simplex, but the existing octaveInit() cannot be used because
      the starting lacunarity values are not integer powers of 2.
- added new sampleOctave2D() function:
      Nearly identical to sampleOctave(), except that ay is set to -(p->b),
      forcing samplePerlin()'s d2 variable to be 0, resulting in a 2D noise
      sample.
- added new sampleOctaveOldBetaTerrain3D() function:
      Used to sample the three 3D noisemaps in SurfaceNoiseBeta. The function
      is passed a 2-element array of doubles, which is passed to
      samplePerlinOldBetaTerrain3D() where the different octaves' values are
      added. The only samples made are the ones necessary to determine the
      blocks at sea level.

samplePerlinOldBetaTerrain3D() is necessary because when generating these
versions' overworld octmin, octmax, and octmain noise, lower levels affect
higher levels based on whether the lower 8 bits of i2 are equal to the lower
8 bits of i2 from the previous iteration. Each level is only affected by the
immediately previous level where (i2 & 255 !- previ2), so I was able to make an
optimization -- the first several y-level iterations are split into a separate
for loop that only looks at i2, and finds the highest y-level that affects the
final output at sea level. In my Java test program using Minecraft's code, this
optimization brough the time needed to produce an image of a 4096 x 4096 region
down to 1/3 of what it was before the optimization.

The yLacFlag argument determines whether or not lacunarity is cut in half for
the y dimension -- octmain uses lacunarity values for y that are half of the
x/z lacunarity value.

In a future commit, I may extend samplePerlinOldBetaTerrain3D() and
sampleOctaveOldBetaTerrain3D() to generate partial noise columns between ymin
and ymax bounds, in order to eventually implement 4x4 surface height finding.
2023-01-27 20:17:38 -05:00
Kai Sandstrom
08b55ff7b1 Added Beta climate biome generation (no ocean gen yet)
(biome_tree.c)
- getOldBetaBiome: removed isWater argument.

(finders.c)
- getStructureConfig: now returns 0 for mineshafts and villages before B1.8.

(layers.h)
- Added SurfaceNoiseBeta struct:
      Very similar to SurfaceNoise.
      Since SurfaceNoiseBeta will only ever be used for the Overworld, the
          double values saved in SurfaceNoise will be hardcoded into the
          SurfaceNoiseBeta sampling function.
      octSurf and octDepth in surfaceNoise are replaced with new octA and octB
          OctaveNoises, used for precise terrain generation. These names are
          subject to change if I come up with more meaningful names in the
          future.
      The oct array contains six additional PerlinNoise structs compared to
          SurfaceNoise, as the 4-octave octSurf is replaced with the 10-octave
          octA.
- Added BiomeNoiseBeta struct:
      Mostly a cut-down version of BiomeNoise.
      The climate array contains three OctaveNoise structs, corresponding to
          the 4-octave temperature and humidity noise generators, as well as
          an additional 2-octave generator that I'm calling "fuzz". The fuzz
          noise is high-frequency and low-amplitude, and is used as a factor
          applied to the raw output of both the temperature and humidity
          generators before these values are used.
      The PerlinNoise array oct contains 10 octaves -- 4 for temperature, 4 for
          humidity, and 2 for fuzz.
      nptype and mc are carried over from BiomeNoise. mc currently has no
          purpose, but I've heard of a bug in some early beta versions causing
          chunk biomes to generate rotated, so storing the version may
          eventually prove useful.
- Added headers for 5 new functions in layers.c.
- Changed header for getOldBetaBiome (defined in biome_tree.c) to reflect new
      signature.

(layers.c)
- Added initSurfaceNoiseBeta function: No-op placeholder for now.
- Added setBetaBiomeSeed function: Initializes the three climate simplex noise
      generators and sets bnb->nptype to -1 by default.
- Added sampleBiomeNoiseBeta function:
      sampleBiomeNoiseBeta samples climate noise at the given x and z
          coordinates (1:1 scale) and returns a biome ID corresponding to the
          biome at the generated temperature and humidity noise values.
      The behavior of zeroing out the array np when it is passed is copied
          from sampleBiomeNoise. I'm not sure about its function, so if it's
          not applicable, this argument and associated behavior can be removed.
      If bnb->nptype is set to NP_TEMPERATURE or NP_HUMIDITY, only that noise
          value is generated and the other is ignored. The noise value is
          multiplied by 10000 and returned as a signed long to match the
          behavior of sampleBiomeNoise. Note that Beta climate values range from
          0 to 1, not -1 to 1, so the resulting ints will all be nonnegative.
      The argument nv (noise values) is a pointer to a 2-element array of
          doubles. If it is present, the noise values are placed in the array
          before the biome is determined.
- Added genBetaBiomeNoiseScaled function:
      At 1:1 scale, every block in Range r is sampled and the return value of
          sampleBiomeNoiseBeta is placed in the cache.
      At higher scales, midpoints are sampled.
      When ocean support is added, this function will likely behave
          differently when NO_BETA_OCEAN is clear in order to maximize time
          and memory efficiency.

(generator.h)
- Flags enum: Bit 1 (0x2) is now the NO_BETA_OCEAN flag.
- Generator struct: New union member for pre-B1.8: Includes BiomeNoiseBeta
      and SurfaceNoiseBeta structs now defined in layers.h

(generator.c)
- setupGenearator:
      New version so pre-B1.8 versions behave correctly.
      For mc <= MC_B1_7, setupGenerator simply sets g->bnb.mc, as all other
          setup for pre-B1.8 biome generation requires the seed to be known.
- applySeed:
      When mc <= MC_B1_7, the new setBetaBiomeSeed function defined in layers.c
          is called. If the NO_BETA_OCEAN flag is not set, initSurfaceNoiseBeta
          is also called. initSurfaceNoiseBeta is currently just a no-op
          placeholder.
- getMinCacheSize:
      New version check.
      Returns default size when mc <= MC_B1_7. Will likely be modified when
      ocean-finding functionality is added.
- genBiomes: Calls genBetaBiomeNoiseScaled when mc <= MC_B1_7

Note: Compiling libcubiomes.a will will currently cause several warnings due to
unused parameters related to not-yet-implemented ocean finding.
2023-01-23 16:51:54 -05:00
KaiSandstrom
0152f212e8
Merge branch 'Cubitect:master' into master 2023-01-22 20:26:08 -05:00
Cubitect
1b5b73f9ad another version string issue 2023-01-22 14:16:10 +01:00
Cubitect
eecaa764e9 add missing version string 2023-01-22 14:11:39 +01:00
Cubitect
bdec4f5ce8 1.19.2 vs 1.19.3
1) add support for 1.19.2 along side 1.19.3
2) get approx stronghold positions in 1.19.3 without biome check
2023-01-22 14:01:56 +01:00
Kai Sandstrom
6f790f4fa5 Add biome table, new funcs for beta climate maps
(biome_tree.c)
- Add lookup table for pre-B1.8 biomes
- Add getOldBetaBiome function to look up biome from climate noise values

(layers.h)
- Add header for getOldBetaBiome function defined in biome_tree.c
- Fix small error from previous commit (semicolons instead of commas)

(noise.c)
- Add new octaveInitOldBetaBiome function
- Add new sampleOctaveOldBetaBiome function

(noise.h)
- Add headers for two new functions defined in noise.c

This commit adds new functions required to generate Alpha 1.2 - Beta 1.7
climate maps, as well as a lookup table for biomes.

The pre- Beta 1.8 biome system uses three 2D simplex noise maps to determine
biomes -- two 4-octave maps for temperature and humidity, and an additional
2-octave map as a source of high-frequency noise that is applied to the raw
output of both climate maps as they are mapped to the range [-1, 1] before
being used to determine the biome at each coordinate sample.

Beta 1.7.3's NoiseGeneratorOctaves2 class defines the lacunarity and
amplitude of each octave of a map in a way that seems incompatible with the
existing octaveInit function. The lacunarity of each octave is the provided
starting value multiplied by a power of a provided modifier value, starting
at modifier^0 and ending at modifier^(octcnt-1). Amplitude works similarly, but
the starting value and modifier are hardcoded. As far as I can tell, there's no
way to get the correct results using octaveInit, so a new
octaveInitOldBetaBiome is used here to initialize the octaves correctly.

Given that Cubiomes has no pre-existing function for sampling simplex
OctaveNoise, I added sampleOctaveOldBetaBiome. It works the same as
sampleOctave, except that it calls sampleSimplex2D instead of samplePerlin,
and it adds the noisemap's random values 'a' and 'b' onto ax and az
respectively in order to match Minecraft b1.7's simplex sampling algorithm.
2023-01-19 20:02:29 -05:00
Kai Sandstrom
3bfdd1d056 Add Beta 1.7 and its unique biomes to enums, util
(layers.h)
- Add MC_B1_7 to MCVersion enum
- Add name mappings for B1.7 biomes to BiomeID enum

(util.c)
- Add Beta 1.7 to mc2str and str2mc functions
- Add name mappings for B1.7 biomes to biome2str function
2023-01-19 15:13:58 -05:00
Cubitect
03895e6c22 Refactored some of the MC version checks paving the way for distinct minor versions. 2023-01-16 20:47:12 +01:00
Cubitect
42924426d0
Merge pull request #86 from KaiSandstrom/master
Support Beta 1.8 (Closes #67)
2023-01-16 20:27:56 +01:00
Cubitect
15434e622d Treat approximate surface height as float and include shift for slightly better accuracy 2023-01-15 19:44:14 +01:00
KaiSandstrom
c9fc194cde
Merge branch 'Cubitect:master' into master 2023-01-15 11:30:53 -05:00
Cubitect
231ee62abe Performance improvements and separate climate min/max finders 2023-01-15 14:01:57 +01:00
Kai Sandstrom
720fa2d3fb getStructureConfig now returns 0 for Fortress when MC is Beta 1.8 2023-01-09 12:00:35 -05:00
Kai Sandstrom
fffa4d78a5 update mc2str and str2mc functions 2023-01-09 11:59:29 -05:00
Kai Sandstrom
93d7d02d58 Changed layer stack for Beta 1.8 2023-01-08 18:42:42 -05:00
Kai Sandstrom
88503edc2c Added new mapLandB18 function that uses Beta 1.8's different method of handling returned RNG values, and introduces the plains/ocean bug at 1:32 2023-01-08 18:41:58 -05:00
Kai Sandstrom
833e13516d Added new entries in MCVersion and LayerID enumerations 2023-01-08 17:32:59 -05:00
Cubitect
c2442e0c94 Fix lookup table for large biome noise 2023-01-08 16:14:08 +01:00
Cubitect
859c039392 Update stronghold positions for 1.19.3 2023-01-05 16:07:23 +01:00
Cubitect
49658d7100 Better height estimation for 1.18+ 2023-01-05 14:24:46 +01:00
Cubitect
47b45a33f2 Updated 1.19 biome generation to 1.19.3 2023-01-05 11:02:02 +01:00
Cubitect
a7df5c6916 Approxmate surface height + improved accuracy of getSpawn 2022-12-30 13:20:29 +01:00
Cubitect
da965eed28 Fixing 1.14 and 1.15 outposts 2022-11-14 20:29:37 +01:00
Cubitect
10e297d17d Fixed some biome checks and added 1:256 biome locator
* fixed biomeExists() for 1.19 end dimension
* fixed biome check position for village and bastion in 1.18+
* added support for 1:256 scale of biome locator in 1.17-
2022-11-13 15:43:24 +01:00
Cubitect
0bf8cb0cce Fixed uninitialized state for biome center finder 2022-10-03 13:32:09 +02:00
Cubitect
90bfe9a904 avoid overflow on small area limit 2022-10-01 20:37:15 +02:00
Cubitect
d3112ca416 avoid recursion floodfill exceeding stack limit (crashes on windows) 2022-10-01 19:39:40 +02:00
Cubitect
6989510924 header update 2022-10-01 15:36:26 +02:00
Cubitect
2dbece7363 Added biome center finder 2022-10-01 15:14:37 +02:00
Cubitect
6f2ef55b73 Fixes, performance improvements and changes
1) fixed inaccuracy in village bounding boxes (1.18+)
2) fixed 2 block voronoi offset for end dimension
3) made monument biome check significantly faster (1.18+)
4) removed structure configurations from global scope
5) renamed biome filter flags
2022-09-25 22:35:40 +02:00
Cubitect
99a2e1718e fixed variable name 2022-09-12 21:34:12 +02:00
Cubitect
d4afdbf19e Fixed nether portal variants for 1.17- + support arbitrary end biome scales 2022-09-12 21:12:49 +02:00
Cubitect
8b87d9379a Added fortress piece generator + fixed inverted terrain viability check 2022-09-11 12:30:05 +02:00
Cubitect
ff13e171c8 Fixed end city pieces generation 2022-09-05 20:46:24 +02:00
Cubitect
b9d374445b Structure variants and fixes
expanded support for structure variants
added end city pieces generation (WIP)
added outer end voids (MC-159283)
fixed several issues with the availablity of biomes for layered generation
fixed that about half of 1.18/1.19 end gateways have wrong positions
2022-09-04 22:40:19 +02:00
Cubitect
469f4d144b Do special sampling for layered biome exclusions 2022-08-21 10:59:24 +02:00