123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- #include "WormCaveGenerator.h"
- #include "Game.h"
- #include "FastNoiseWrapper.h"
- #include "RandNoise.h"
- NoiseWorm3D::NoiseWorm3D(Noise* pitch, Noise* yaw, Noise* size, Framework::Vec3<int> startPos, int distant, int minRad, int maxRad)
- : ReferenceCounter(),
- startChunk(Game::INSTANCE->getChunkCenter(startPos.x, startPos.y))
- {
- Vec3<float> lastPos = (Vec3<float>)startPos;
- keyPoints.add(lastPos);
- this->size.add((float)minRad);
- minAffected.x = (int)lastPos.x - minRad;
- minAffected.y = (int)lastPos.y - minRad;
- maxAffected.x = (int)lastPos.x + minRad;
- maxAffected.y = (int)lastPos.y + minRad;
- while (keyPoints.getEintragAnzahl() < distant * 20)
- {
- Vec3<float> defaultDir(1.f, 0.f, 0.f);
- if (keyPoints.getEintragAnzahl() > 1)
- {
- defaultDir = keyPoints.get(keyPoints.getEintragAnzahl() - 1) - keyPoints.get(keyPoints.getEintragAnzahl() - 2);
- }
- float n = (float)yaw->getNoise(lastPos.x, lastPos.y, lastPos.z);
- defaultDir.rotateZ((n - 0.5f) / 2.f);
- defaultDir.normalize();
- n = (float)pitch->getNoise(lastPos.x, lastPos.y, lastPos.z);
- defaultDir.z = ((float)n - 0.3f) * 2.f;
- lastPos = lastPos + defaultDir;
- if ((Vec2<float>(lastPos.x, lastPos.y) - (Vec2<float>((float)startPos.x, (float)startPos.y))).getLengthSq() >= (float)(distant * distant))
- break;
- keyPoints.add(lastPos);
- float rad = (float)size->getNoise(lastPos.x, lastPos.y, lastPos.z) * (float)(maxRad - minRad) + (float)minRad;
- this->size.add(rad);
- minAffected.x = MIN(minAffected.x, (int)(lastPos.x - rad));
- minAffected.y = MIN(minAffected.y, (int)(lastPos.y - rad));
- maxAffected.x = MAX(maxAffected.x, (int)(lastPos.x + rad));
- maxAffected.y = MAX(maxAffected.y, (int)(lastPos.y + rad));
- }
- }
- Framework::Punkt NoiseWorm3D::getStartChunkCenter()
- {
- return startChunk;
- }
- bool NoiseWorm3D::isChunkAffected(int x, int y)
- {
- if (x - CHUNK_SIZE / 2 <= maxAffected.x && x + CHUNK_SIZE / 2 >= minAffected.x && y - CHUNK_SIZE / 2 <= maxAffected.y && y + CHUNK_SIZE / 2 >= minAffected.y)
- {
- auto pi = keyPoints.begin();
- auto si = size.begin();
- while (pi && si)
- {
- if ((Vec2<float>((float)x, (float)y) - Vec2<float>(pi.val().x, pi.val().y)).getLengthSq() < (si.val() + CHUNK_SIZE / 2) * (si.val() + CHUNK_SIZE / 2))
- return 1;
- ++pi;
- ++si;
- }
- }
- return 0;
- }
- bool NoiseWorm3D::isInside(int x, int y, int z)
- {
- auto pi = keyPoints.begin();
- auto si = size.begin();
- while (pi && si)
- {
- if (Vec3<float>((float)x, (float)y, (float)z).abstand(pi.val()) < si.val())
- return 1;
- ++pi;
- ++si;
- }
- return 0;
- }
- WormCaveChunkGenerator::WormCaveChunkGenerator(Framework::RCArray<NoiseWorm3D> worms)
- : CaveChunkGenerator(),
- worms(worms)
- {}
- bool WormCaveChunkGenerator::isInCave(int x, int y, int z)
- {
- for (NoiseWorm3D* w : worms)
- {
- if (w->isInside(x, y, z))
- return 1;
- }
- return 0;
- }
- WormCaveGenerator::WormCaveGenerator(int minDistant, int maxDistant, int minRadius, int maxRadius, float cavePosibillityPerChunk)
- : CaveGenerator(),
- maxDistant(maxDistant),
- minDistant(minDistant),
- maxRadius(maxRadius),
- minRadius(minRadius),
- cavePosibillity(cavePosibillityPerChunk)
- {}
- WormCaveGenerator::~WormCaveGenerator()
- {
- wormStartNoise->release();
- }
- NoiseWorm3D* WormCaveGenerator::zWormOfChunk(int x, int y)
- {
- for (NoiseWorm3D* worm : cache)
- {
- if (worm->getStartChunkCenter().x == x && worm->getStartChunkCenter().y == y)
- {
- return worm;
- }
- }
- for (Punkt p : noWormChunks)
- {
- if (p.x == x && p.y == y)
- return 0;
- }
- float cNoise = (float)wormStartNoise->getNoise(x, y, 0);
- if (cNoise < cavePosibillity)
- {
- FastNoiseLite* noise = new FastNoiseLite(seed + x * y + y + x);
- noise->SetNoiseType(FastNoiseLite::NoiseType::NoiseType_Perlin);
- noise->SetFrequency(0.05f);
- FastNoiseWrapper* pitch = new FastNoiseWrapper(noise, seed + x * y + y + x);
- noise = new FastNoiseLite(seed + x * y + y + x);
- noise->SetNoiseType(FastNoiseLite::NoiseType::NoiseType_Perlin);
- noise->SetFrequency(0.005f);
- FastNoiseWrapper* yaw = new FastNoiseWrapper(noise, seed - x * y - y - x);
- Vec3<int> start((int)(cNoise / cavePosibillity * CHUNK_SIZE) + x - CHUNK_SIZE / 2, (int)(cNoise / cavePosibillity * CHUNK_SIZE) + y - CHUNK_SIZE / 2, (int)(cNoise / cavePosibillity * 200));
- noise = new FastNoiseLite(seed + start.getLengthSq() + start.x + start.y + start.z);
- noise->SetNoiseType(FastNoiseLite::NoiseType::NoiseType_Perlin);
- noise->SetFrequency(0.005f);
- FastNoiseWrapper* size = new FastNoiseWrapper(noise, seed + start.getLengthSq() + start.x + start.y + start.z);
- NoiseWorm3D* worm = new NoiseWorm3D(pitch, yaw, size, start, (int)(wormStartNoise->getNoise(start.x, start.y, start.z) * (maxDistant - minDistant) + minDistant), minRadius, maxRadius);
- if (cache.getEintragAnzahl() > (maxDistant * 2) / CHUNK_SIZE * (maxDistant * 2) / CHUNK_SIZE * 3)
- cache.remove(0);
- cache.add(worm);
- return worm;
- }
- else
- {
- if (noWormChunks.getEintragAnzahl() > (maxDistant * 2) / CHUNK_SIZE * (maxDistant * 2) / CHUNK_SIZE * 3)
- noWormChunks.remove(0);
- noWormChunks.add(Punkt(x, y));
- }
- return 0;
- }
- void WormCaveGenerator::initialize(int seed)
- {
- wormStartNoise = new RandNoise(seed);
- CaveGenerator::initialize(seed);
- }
- CaveChunkGenerator* WormCaveGenerator::getGeneratorForChunk(int x, int y)
- {
- Framework::RCArray<NoiseWorm3D> affected;
- Punkt center = Game::getChunkCenter(x, y);
- int offset = (int)ceil((float)maxDistant / CHUNK_SIZE);
- for (int cx = -offset; cx <= offset; cx++)
- {
- for (int cy = -offset; cy <= offset; cy++)
- {
- NoiseWorm3D* worm = zWormOfChunk(center.x + cx * CHUNK_SIZE, center.y + cy * CHUNK_SIZE);
- if (worm && worm->isChunkAffected(x, y))
- affected.add(dynamic_cast<NoiseWorm3D*>(worm->getThis()));
- }
- }
- return new WormCaveChunkGenerator(affected);
- }
|