1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- #include "DimensionGenerator.h"
- #include "Constants.h"
- #include "Noise.h"
- #include "NoBlock.h"
- 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 )
- {
- 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++ )
- {
- for( int z = 0; z < WORLD_HEIGHT; z++ )
- {
- auto generated = generateBlock( zNoise, zGame, { x + centerX, y + centerY, z } );
- 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();
- double neighborHeight = zNoise->getNoise( location.x * neighborBiom->getAirLevelXMultiplier(), location.y * neighborBiom->getAirLevelYMultiplier(), AIR_LEVEL_Z_OFFSET ) * neighborBiom->getAirLevelOutputMultiplier();
- int height = MIN_AIR_LEVEL;
- if( actualWeight + neighborWeight > 0 )
- height += (int)(((actualHeight * actualHeight + 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;
- }
|