#include #include #include #include "xxhash.h" typedef struct { int x; int y; } Vec2I; typedef struct { int x1; int y1; int x2; int y2; } RectI; typedef struct { uint32_t m_data[256]; uint32_t m_carry; uint8_t m_index; } RandState; //RANDOM FUNCTIONS uint32_t randu32(RandState *rand) { uint64_t a = 809430660; uint64_t t = a * rand->m_data[++rand->m_index] + rand->m_carry; rand->m_carry = (t >> 32); rand->m_data[rand->m_index] = t; return t; } int32_t randi32(RandState *rand) { return (int32_t)(randu32(rand)); } void randInit(RandState *rand, uint64_t seed) { /* choose random initial m_carry < 809430660 and */ /* 256 random 32-bit integers for m_data[] */ rand->m_carry = seed % 809430660; rand->m_data[0] = seed; rand->m_data[1] = seed >> 32; for (size_t i = 2; i < 256; ++i) rand->m_data[i] = 69069 * rand->m_data[i - 2] + 362437; rand->m_index = 255; // Hard-coded initial skip of random values, to get the random generator // going. for (unsigned i = 0; i < 32; ++i) randu32(rand); } float randf(RandState *rand) { return (randu32(rand) & 0x7fffffff) / 2147483648.0f; } //END RANDOM FUNCTIONS //pretty sure gcc will just optimize this out int pmod(int a, int m) { int r = a % m; return r < 0 ? r + m : r; } //gets the chunkIndex for a system, based on its x and y coords Vec2I chunkIndexFor(Vec2I systemXY) { systemXY.x = (systemXY.x - pmod(systemXY.x, 50)) / 50; systemXY.y = (systemXY.y - pmod(systemXY.y, 50)) / 50; return systemXY; } //makes a rectangle that encompasses a "chunkRegion" //this is represented as a Vec2I (vector of 2 ints) RectI chunkRegion(Vec2I chunkIndex) { RectI rectangle; rectangle.x1 = chunkIndex.x * 50; rectangle.y1 = chunkIndex.y * 50; rectangle.x2 = (chunkIndex.x+1) * 50; rectangle.y2 = (chunkIndex.y+1) * 50; return rectangle; } int min(int a, int b) { return (a < b) ? a : b; } int max(int a, int b) { return (a > b) ? a : b; } RectI fixRectangle(RectI rectangle) { //rearrange points in a rectangle so the first has the smallest 2 points, and the second has the largest 2 RectI tempRectangle; tempRectangle.x1 = min(rectangle.x1, rectangle.x2); tempRectangle.x2 = max(rectangle.x1, rectangle.x2); tempRectangle.y1 = min(rectangle.y1, rectangle.y2); tempRectangle.y2 = max(rectangle.y1, rectangle.y2); return tempRectangle; } uint64_t staticRandomHash64(int x, int y) { XXH64_state_t* state = XXH64_createState(); XXH64_hash_t seed = 1997293021376312589ULL; XXH64_reset(state, seed); //XXH64_update(state, "test1", 5); XXH64_update(state, (void*)(&x), 4); XXH64_update(state, (void*)(&y), 4); XXH64_update(state, "ChunkIndexMix", 13); seed = XXH64_digest(state); XXH64_freeState(state); return seed; // state v | v void pointer to v memory address //XXH64_update(state, (void*)(&v), 4); // <-- 4 bytes in int // ...sorry /* //loads this as seed XXHash64 hash(1997293021376312589); //updates hash with "v" xxHash64Push(hash, v); //updates hash with rest1 xxHash64Push(hash, rest1); //updates hash with rest2 xxHash64Push(hash, rest2); //finalize hash and spit out return hash.digest(); */ } void produceChunk(uint32_t block[50][50], Vec2I chunkIndex) { //CelestialChunk chunkData; //chunkData.chunkIndex = chunkIndex; XXH64_hash_t seed = staticRandomHash64(chunkIndex.x, chunkIndex.y); RandState rand; randInit(&rand, seed); RectI region = chunkRegion(chunkIndex); region = fixRectangle(region); int32_t z; //List systemLocations; for (int x = region.x1; x < region.x2; ++x) { for (int y = region.y1; y < region.y2; ++y) { if(randf(&rand) < 0.003) { z = randi32(&rand) % 200000000 - 100000000; //systemLocations.append(Vec3I(x, y, z)); //printf("star at x=%d y=%d z=%d\n", x, y, z); block[x - region.x1][y - region.y1] = 1; } } } } /* m_baseInformation.planetOrbitalLevels = 11 m_baseInformation.satelliteOrbitalLevels = 3 m_baseInformation.chunkSize = 50 m_baseInformation.xyCoordRange = [-1000000000, 1000000000]; m_baseInformation.zCoordRange = [-100000000, 100000000]; m_generationInformation.systemProbability = 0.003; m_generationInformation.constellationProbability = 1.5; m_generationInformation.constellationLineCountRange = [3, 8]; m_generationInformation.constellationMaxTries = 500; m_generationInformation.maximumConstellationLineLength = 20.0; m_generationInformation.minimumConstellationLineLength = 1.0; m_generationInformation.minimumConstellationMagnitude = 5; m_generationInformation.minimumConstellationLineCloseness = 1; */ /* "systemTypePerlin" : { "type" : "perlin", "octaves" : 1, "frequency" : 0.01, "amplitude" : 1.0, "bias" : 0.0 }, "systemTypeBins" : [ [-1.00, "White"], [-0.30, "Orange"], [-0.12, "Yellow"], [0.00, "Blue"], [0.12, "Red"], [0.30, ""] // dark mysteries ], */ void perlinInit(uint64_t seed) { } void perlinSetup(Float v, int* b0, int* b1, Float* r0, Float* r1) { int iv = floor(v); float fv = v - iv; *b0 = iv & (PerlinSampleSize - 1); *b1 = (iv + 1) & (PerlinSampleSize - 1); *r0 = fv; *r1 = fv - 1.0; } float s_curve(float t) { return t * t * (3.0 - 2.0 * t); } float at2(Float* q, Float rx, Float ry) { return rx * q[0] + ry * q[1]; } float lerp(float offset, float f0, float f1) { return f0 * (1 - offset) + f1 * (offset); } float noise2(Float vec[2]) { int bx0, bx1, by0, by1, b00, b10, b01, b11; float rx0, rx1, ry0, ry1, sx, sy, a, b, u, v; int i, j; perlinSetup(vec[0], &bx0, &bx1, &rx0, &rx1); perlinSetup(vec[1], &by0, &by1, &ry0, &ry1); i = p[bx0]; j = p[bx1]; b00 = p[i + by0]; b10 = p[j + by0]; b01 = p[i + by1]; b11 = p[j + by1]; sx = s_curve(rx0); sy = s_curve(ry0); u = at2(g2[b00], rx0, ry0); v = at2(g2[b10], rx1, ry0); a = lerp(sx, u, v); u = at2(g2[b01], rx0, ry1); v = at2(g2[b11], rx1, ry1); b = lerp(sx, u, v); return lerp(sy, a, b); } float perlin(float x, Float y) { int i; float val; float sum = 0; float p[2]; float scale = 1; p[0] = x * m_frequency; p[1] = y * m_frequency; for (i = 0; i < m_octaves; i++) { val = noise2(p); sum += val / scale; scale *= m_alpha; p[0] *= m_beta; p[1] *= m_beta; } return sum * m_amplitude + m_bias; } /* Maybe>> produceSystem(RandomSource& random, Vec3I const& location) { float typeSelector = m_generationInformation.systemTypePerlin.get(location[0], location[1]); String systemTypeName = binnedChoiceFromJson(m_generationInformation.systemTypeBins, typeSelector, "").toString(); if (systemTypeName.empty()) return {}; auto systemType = m_generationInformation.systemTypes.get(systemTypeName); CelestialCoordinate systemCoordinate(location); uint64_t systemSeed = random.randu64(); String prefix = m_generationInformation.systemPrefixNames.select(random); String mid = m_generationInformation.systemNames.select(random); String suffix = m_generationInformation.systemSuffixNames.select(random); String systemName = String(strf("%s %s %s", prefix, mid, suffix)).trim(); systemName = systemName.replace("", strf("%01d", random.randu32() % 10)); systemName = systemName.replace("", strf("%02d", random.randu32() % 100)); systemName = systemName.replace("", strf("%03d", random.randu32() % 1000)); systemName = systemName.replace("", strf("%04d", random.randu32() % 10000)); CelestialParameters systemParameters = CelestialParameters(systemCoordinate, systemSeed, systemName, jsonMerge(systemType.baseParameters, random.randValueFrom(systemType.variationParameters))); List planetaryOrbits; for (int i = 1; i <= m_baseInformation.planetOrbitalLevels; ++i) { if (auto systemOrbitRegion = orbitRegion(systemType.orbitRegions, i)) { if (random.randf() <= systemOrbitRegion->bodyProbability) planetaryOrbits.append(i); } } HashMap systemObjects; for (auto planetPair : enumerateIterator(planetaryOrbits)) { auto systemOrbitRegion = orbitRegion(systemType.orbitRegions, planetPair.first); auto planetaryTypeName = systemOrbitRegion->planetaryTypes.select(random); if (m_generationInformation.planetaryTypes.contains(planetaryTypeName)) { auto planetaryType = m_generationInformation.planetaryTypes.get(planetaryTypeName); auto planetaryParameters = jsonMerge(planetaryType.baseParameters, random.randValueFrom(planetaryType.variationParameters)); CelestialCoordinate planetCoordinate(location, planetPair.first); uint64_t planetarySeed = random.randu64(); String planetaryName = strf("%s %s", systemName, m_generationInformation.planetarySuffixes.at(planetPair.second)); CelestialPlanet planet; planet.planetParameters = CelestialParameters(planetCoordinate, planetarySeed, planetaryName, planetaryParameters); List satelliteOrbits; for (int i = 1; i <= m_baseInformation.satelliteOrbitalLevels; ++i) { if (satelliteOrbits.size() < planetaryType.maxSatelliteCount && random.randf() < planetaryType.satelliteProbability) satelliteOrbits.append(i); } for (auto satellitePair : enumerateIterator(satelliteOrbits)) { auto satelliteTypeName = systemOrbitRegion->satelliteTypes.select(random); if (m_generationInformation.satelliteTypes.contains(satelliteTypeName)) { auto satelliteType = m_generationInformation.satelliteTypes.get(satelliteTypeName); auto satelliteParameters = jsonMerge(satelliteType.baseParameters, random.randValueFrom(satelliteType.variationParameters), random.randValueFrom( satelliteType.orbitParameters.value(systemOrbitRegion->regionName, JsonArray()).toArray())); CelestialCoordinate satelliteCoordinate(location, planetPair.first, satellitePair.first); uint64_t satelliteSeed = random.randu64(); String satelliteName = strf("%s %s", planetaryName, m_generationInformation.satelliteSuffixes.at(satellitePair.second)); planet.satelliteParameters[satellitePair.first] = CelestialParameters(satelliteCoordinate, satelliteSeed, satelliteName, satelliteParameters); } } systemObjects[planetPair.first] = move(planet); } } return pair>{move(systemParameters), move(systemObjects)}; } */ int main() { Vec2I position; for(position.x = -1000000; position.x < 1000000; position.x++) { for(position.y = -1000000; position.y < 1000000; position.y++) { if(isGoodPosition(position)) { printf("%d %d\n", 50*position.x, 50*position.y); } } //printf("finished row %d\n", 50*position.x); } }