DimensionGenerator.cpp 3.4 KB

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