DimensionGenerator.cpp 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include "DimensionGenerator.h"
  2. #include "Constants.h"
  3. #include "Noise.h"
  4. #include "NoBlock.h"
  5. #include <iostream>
  6. DimensionGenerator::DimensionGenerator( int dimensionId )
  7. : ReferenceCounter(),
  8. dimensionId( dimensionId )
  9. {
  10. StaticRegistry<DimensionGenerator>::INSTANCE.registerT( this, dimensionId );
  11. }
  12. DimensionGenerator::~DimensionGenerator()
  13. {}
  14. BiomGenerator* DimensionGenerator::zBiomGenerator( int seed, int x, int y )
  15. {
  16. double noise = zBiomNoise( seed )->getNoise( (double)x, (double)y, 0.0 );
  17. double border = 0;
  18. BiomGenerator* gen = 0;
  19. auto genI = biomGenerators.begin();
  20. auto distI = biomDistribution.begin();
  21. do
  22. {
  23. border += (double)distI++;
  24. gen = genI++;
  25. } while( border < noise && (bool)distI && (bool)genI );
  26. return gen;
  27. }
  28. void DimensionGenerator::registerBiom( BiomGenerator* generator, double possibility )
  29. {
  30. biomGenerators.add( generator );
  31. biomDistribution.add( possibility );
  32. }
  33. Chunk* DimensionGenerator::generateChunk( int seed, int centerX, int centerY )
  34. {
  35. std::cout << "generating chunk " << centerX << ", " << centerY << "\n";
  36. Chunk* chunk = new Chunk( Framework::Punkt( centerX, centerY ), dimensionId );
  37. for( int x = -CHUNK_SIZE / 2; x < CHUNK_SIZE / 2; x++ )
  38. {
  39. for( int y = -CHUNK_SIZE / 2; y < CHUNK_SIZE / 2; y++ )
  40. {
  41. BiomGenerator* biom = zBiomGenerator( seed + dimensionId, x + centerX, y + centerY );
  42. // TODO: use Noise interpolator for height map between different bioms
  43. int height = MIN_AIR_LEVEL + (int)(biom->zHeightMapNoise( seed + dimensionId )->getNoise( (double)(x + centerX), (double)(y + centerY), 0.0 ) * (MAX_AIR_LEVEL - MIN_AIR_LEVEL));
  44. for( int z = 0; z < WORLD_HEIGHT; z++ )
  45. {
  46. Framework::Either<Block*, int> generated = AirBlockBlockType::ID;
  47. if( z < height )
  48. generated = biom->getBlock( x + centerX, y + centerY, z );
  49. if( generated.isA() )
  50. chunk->putBlockAt( Framework::Vec3<int>( x + CHUNK_SIZE / 2, y + CHUNK_SIZE / 2, z ), generated );
  51. else
  52. chunk->putBlockTypeAt( Framework::Vec3<int>( x + CHUNK_SIZE / 2, y + CHUNK_SIZE / 2, z ), generated );
  53. }
  54. }
  55. }
  56. return chunk;
  57. }
  58. Framework::Either<Block*, int> DimensionGenerator::generateBlock( int seed, Framework::Vec3<int> location )
  59. {
  60. BiomGenerator* biom = zBiomGenerator( seed + dimensionId, location.x, location.y );
  61. // TODO: use Noise interpolator for height map between different bioms
  62. int height = MIN_AIR_LEVEL + (int)(biom->zHeightMapNoise( seed + dimensionId )->getNoise( (double)(location.x), (double)(location.y), 0.0 ) * (MAX_AIR_LEVEL - MIN_AIR_LEVEL));
  63. if( location.z < height )
  64. return biom->getBlock( location.x, location.y, location.z );
  65. return AirBlockBlockType::ID;
  66. }
  67. int DimensionGenerator::getDimensionId() const
  68. {
  69. return dimensionId;
  70. }