DimensionGenerator.cpp 3.8 KB

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