123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- #include "DimensionGenerator.h"
- #include "Constants.h"
- #include "Noise.h"
- #include "NoBlock.h"
- #include <iostream>
- DimensionGenerator::DimensionGenerator( BiomInterpolator* interpolator, int dimensionId )
- : ReferenceCounter(),
- interpolator( interpolator ),
- dimensionId( dimensionId )
- {
- StaticRegistry<DimensionGenerator>::INSTANCE.registerT( this, dimensionId );
- }
- DimensionGenerator::~DimensionGenerator()
- {
- interpolator->release();
- }
- void DimensionGenerator::findBiom( int x, int y, Noise* zNoise, BiomGenerator** firstChoice, BiomGenerator** secondChoice, double& firstChoiceWeight, double& secondChoiceWeight )
- {
- *firstChoice = biomGenerators.z( 0 );
- *secondChoice = biomGenerators.z( 0 );
- firstChoiceWeight = 0;
- secondChoiceWeight = 0;
- int z = BIOM_GENERATION_Z_OFFSET;
- for( BiomGenerator* gen : biomGenerators )
- {
- double noise = zNoise->getNoise( x * gen->getBiomXMultiplier(), y * gen->getBiomYMultiplier(), z ) * gen->getBiomOutputMultiplier();
- if( noise > firstChoiceWeight )
- {
- secondChoiceWeight = firstChoiceWeight;
- *secondChoice = *firstChoice;
- firstChoiceWeight = noise;
- *firstChoice = gen;
- }
- else if( noise > secondChoiceWeight )
- {
- secondChoiceWeight = noise;
- *secondChoice = gen;
- }
- z++;
- }
- }
- void DimensionGenerator::registerBiom( BiomGenerator* generator )
- {
- biomGenerators.add( generator );
- }
- Chunk* DimensionGenerator::generateChunk( Noise* zNoise, Game* zGame, int centerX, int centerY )
- {
- std::cout << "generating chunk " << centerX << ", " << centerY << "\n";
- Chunk* chunk = new Chunk( Framework::Punkt( centerX, centerY ), zGame, dimensionId );
- for( int x = -CHUNK_SIZE / 2; x < CHUNK_SIZE / 2; x++ )
- {
- for( int y = -CHUNK_SIZE / 2; y < CHUNK_SIZE / 2; y++ )
- {
- BiomGenerator* actualBiom;
- BiomGenerator* neighborBiom;
- double actualWeight;
- double neighborWeight;
- findBiom( x + centerX, y + centerY, zNoise, &actualBiom, &neighborBiom, actualWeight, neighborWeight );
- double actualHeight = zNoise->getNoise( (x + centerX) * actualBiom->getAirLevelXMultiplier(), (y + centerY) * actualBiom->getAirLevelYMultiplier(), AIR_LEVEL_Z_OFFSET ) * actualBiom->getAirLevelOutputMultiplier() + actualBiom->getAirLevelOutputAddition();
- double neighborHeight = zNoise->getNoise( (x + centerX) * neighborBiom->getAirLevelXMultiplier(), (y + centerY) * neighborBiom->getAirLevelYMultiplier(), AIR_LEVEL_Z_OFFSET ) * neighborBiom->getAirLevelOutputMultiplier() + neighborBiom->getAirLevelOutputAddition();
- int height = MIN_AIR_LEVEL;
- if( actualWeight + neighborWeight > 0 )
- height += (int)(((actualHeight * actualWeight + neighborHeight * neighborWeight) / (actualWeight + neighborWeight)) * (MAX_AIR_LEVEL - MIN_AIR_LEVEL));
- for( int z = 0; z < WORLD_HEIGHT; z++ )
- {
- Framework::Either<Block*, int> generated = AirBlockBlockType::ID;
- if( z < height )
- {
- auto actualBlock = actualBiom->getBlock( zNoise, x + centerX, y + centerY, z, zGame );
- auto neighborBlock = neighborBiom->getBlock( zNoise, x + centerX, y + centerY, z, zGame );
- generated = interpolator->interpolateBlocks( actualBlock, neighborBlock, actualHeight, neighborWeight, zNoise );
- }
- if( generated.isA() )
- chunk->putBlockAt( Framework::Vec3<int>( x + CHUNK_SIZE / 2, y + CHUNK_SIZE / 2, z ), generated );
- else
- chunk->putBlockTypeAt( Framework::Vec3<int>( x + CHUNK_SIZE / 2, y + CHUNK_SIZE / 2, z ), generated );
- }
- }
- }
- return chunk;
- }
- Framework::Either<Block*, int> DimensionGenerator::generateBlock( Noise* zNoise, Game* zGame, Framework::Vec3<int> location )
- {
- BiomGenerator* actualBiom;
- BiomGenerator* neighborBiom;
- double actualWeight;
- double neighborWeight;
- findBiom( location.x, location.y, zNoise, &actualBiom, &neighborBiom, actualWeight, neighborWeight );
- double actualHeight = zNoise->getNoise( location.x * actualBiom->getAirLevelXMultiplier(), location.y * actualBiom->getAirLevelYMultiplier(), AIR_LEVEL_Z_OFFSET ) * actualBiom->getAirLevelOutputMultiplier() + actualBiom->getAirLevelOutputAddition();
- double neighborHeight = zNoise->getNoise( location.x * neighborBiom->getAirLevelXMultiplier(), location.y * neighborBiom->getAirLevelYMultiplier(), AIR_LEVEL_Z_OFFSET ) * neighborBiom->getAirLevelOutputMultiplier() + neighborBiom->getAirLevelOutputAddition();
- int height = MIN_AIR_LEVEL;
- if( actualWeight + neighborWeight > 0 )
- height += (int)(((actualHeight * actualWeight + neighborHeight * neighborWeight) / (actualWeight + neighborWeight)) * (MAX_AIR_LEVEL - MIN_AIR_LEVEL));
- if( location.z < height )
- {
- auto actualBlock = actualBiom->getBlock( zNoise, location.x, location.y, location.z, zGame );
- auto neighborBlock = neighborBiom->getBlock( zNoise, location.x, location.y, location.z, zGame );
- return interpolator->interpolateBlocks( actualBlock, neighborBlock, actualHeight, neighborWeight, zNoise );
- }
- return AirBlockBlockType::ID;
- }
- int DimensionGenerator::getDimensionId() const
- {
- return dimensionId;
- }
|