DimensionGenerator.cpp 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "DimensionGenerator.h"
  2. #include "Constants.h"
  3. #include "Noise.h"
  4. #include "NoBlock.h"
  5. DimensionGenerator::DimensionGenerator( BiomInterpolator* interpolator, int dimensionId )
  6. : ReferenceCounter(),
  7. interpolator( interpolator ),
  8. dimensionId( dimensionId )
  9. {
  10. StaticRegistry<DimensionGenerator>::INSTANCE.registerT( this, dimensionId );
  11. }
  12. DimensionGenerator::~DimensionGenerator()
  13. {
  14. interpolator->release();
  15. }
  16. void DimensionGenerator::findBiom( int x, int y, Noise* zNoise, BiomGenerator** firstChoice, BiomGenerator** secondChoice, double& firstChoiceWeight, double& secondChoiceWeight )
  17. {
  18. *firstChoice = biomGenerators.z( 0 );
  19. *secondChoice = biomGenerators.z( 0 );
  20. firstChoiceWeight = 0;
  21. secondChoiceWeight = 0;
  22. int z = BIOM_GENERATION_Z_OFFSET;
  23. for( BiomGenerator* gen : biomGenerators )
  24. {
  25. double noise = zNoise->getNoise( x * gen->getBiomXMultiplier(), y * gen->getBiomYMultiplier(), z ) * gen->getBiomOutputMultiplier();
  26. if( noise > firstChoiceWeight )
  27. {
  28. secondChoiceWeight = firstChoiceWeight;
  29. *secondChoice = *firstChoice;
  30. firstChoiceWeight = noise;
  31. *firstChoice = gen;
  32. }
  33. else if( noise > secondChoiceWeight )
  34. {
  35. secondChoiceWeight = noise;
  36. *secondChoice = gen;
  37. }
  38. z++;
  39. }
  40. }
  41. void DimensionGenerator::registerBiom( BiomGenerator* generator )
  42. {
  43. biomGenerators.add( generator );
  44. }
  45. Chunk* DimensionGenerator::generateChunk( Noise* zNoise, Game* zGame, int centerX, int centerY )
  46. {
  47. Chunk* chunk = new Chunk( Framework::Punkt( centerX, centerY ), zGame, dimensionId );
  48. for( int x = -CHUNK_SIZE / 2; x < CHUNK_SIZE / 2; x++ )
  49. {
  50. for( int y = -CHUNK_SIZE / 2; y < CHUNK_SIZE / 2; y++ )
  51. {
  52. for( int z = 0; z < WORLD_HEIGHT; z++ )
  53. {
  54. auto generated = generateBlock( zNoise, zGame, { x + centerX, y + centerY, z } );
  55. if( generated.isA() )
  56. chunk->putBlockAt( Framework::Vec3<int>( x + CHUNK_SIZE / 2, y + CHUNK_SIZE / 2, z ), generated );
  57. else
  58. chunk->putBlockTypeAt( Framework::Vec3<int>( x + CHUNK_SIZE / 2, y + CHUNK_SIZE / 2, z ), generated );
  59. }
  60. }
  61. }
  62. return chunk;
  63. }
  64. Framework::Either<Block*, int> DimensionGenerator::generateBlock( Noise* zNoise, Game* zGame, Framework::Vec3<int> location )
  65. {
  66. BiomGenerator* actualBiom;
  67. BiomGenerator* neighborBiom;
  68. double actualWeight;
  69. double neighborWeight;
  70. findBiom( location.x, location.y, zNoise, &actualBiom, &neighborBiom, actualWeight, neighborWeight );
  71. double actualHeight = zNoise->getNoise( location.x * actualBiom->getAirLevelXMultiplier(), location.y * actualBiom->getAirLevelYMultiplier(), AIR_LEVEL_Z_OFFSET ) * actualBiom->getAirLevelOutputMultiplier();
  72. double neighborHeight = zNoise->getNoise( location.x * neighborBiom->getAirLevelXMultiplier(), location.y * neighborBiom->getAirLevelYMultiplier(), AIR_LEVEL_Z_OFFSET ) * neighborBiom->getAirLevelOutputMultiplier();
  73. int height = MIN_AIR_LEVEL;
  74. if( actualWeight + neighborWeight > 0 )
  75. height += (int)(((actualHeight * actualHeight + neighborHeight * neighborWeight) / (actualWeight + neighborWeight)) * (MAX_AIR_LEVEL - MIN_AIR_LEVEL));
  76. if( location.z < height )
  77. {
  78. auto actualBlock = actualBiom->getBlock( zNoise, location.x, location.y, location.z, zGame );
  79. auto neighborBlock = neighborBiom->getBlock( zNoise, location.x, location.y, location.z, zGame );
  80. return interpolator->interpolateBlocks( actualBlock, neighborBlock, actualHeight, neighborWeight, zNoise );
  81. }
  82. return AirBlockBlockType::ID;
  83. }
  84. int DimensionGenerator::getDimensionId() const
  85. {
  86. return dimensionId;
  87. }