diff --git a/src/definition/VegetationDefinition.cpp b/src/definition/VegetationDefinition.cpp index 9437560..845a8fa 100644 --- a/src/definition/VegetationDefinition.cpp +++ b/src/definition/VegetationDefinition.cpp @@ -13,6 +13,23 @@ VegetationDefinition::VegetationDefinition(DefinitionNode* parent) : { } +double VegetationDefinition::getMaxHeight() const +{ + double max_height = 0.0; + int n = count(); + + for (int i = 0; i < n; i++) + { + double layer_height = getVegetationLayer(i)->getMaxHeight(); + if (layer_height > max_height) + { + max_height = layer_height; + } + } + + return max_height; +} + void VegetationDefinition::applyPreset(VegetationPreset preset) { VegetationLayerDefinition *layer; diff --git a/src/definition/VegetationDefinition.h b/src/definition/VegetationDefinition.h index aea9e11..9480a0a 100644 --- a/src/definition/VegetationDefinition.h +++ b/src/definition/VegetationDefinition.h @@ -21,6 +21,11 @@ public: */ inline VegetationLayerDefinition* getVegetationLayer(int position) const {return (VegetationLayerDefinition*)getLayer(position);} + /** + * Get the max height of all layers assembled. + */ + double getMaxHeight() const; + typedef enum { VEGETATION_PRESET_TEMPERATE diff --git a/src/definition/VegetationLayerDefinition.cpp b/src/definition/VegetationLayerDefinition.cpp index 79e53fa..f906f44 100644 --- a/src/definition/VegetationLayerDefinition.cpp +++ b/src/definition/VegetationLayerDefinition.cpp @@ -10,6 +10,11 @@ VegetationLayerDefinition::VegetationLayerDefinition(DefinitionNode* parent) : presence = new VegetationPresenceDefinition(this); } +double VegetationLayerDefinition::getMaxHeight() const +{ + return presence->getMaxHeight(); +} + void VegetationLayerDefinition::applyPreset(VegetationLayerPreset preset) { model->randomize(); diff --git a/src/definition/VegetationLayerDefinition.h b/src/definition/VegetationLayerDefinition.h index 8fe775b..6a9e41d 100644 --- a/src/definition/VegetationLayerDefinition.h +++ b/src/definition/VegetationLayerDefinition.h @@ -19,6 +19,8 @@ public: inline const VegetationPresenceDefinition *getPresence() const {return presence;} inline const VegetationModelDefinition *getModel() const {return model;} + double getMaxHeight() const; + typedef enum { VEGETATION_BASIC_TREES diff --git a/src/definition/VegetationPresenceDefinition.cpp b/src/definition/VegetationPresenceDefinition.cpp index f45b301..c77e7d0 100644 --- a/src/definition/VegetationPresenceDefinition.cpp +++ b/src/definition/VegetationPresenceDefinition.cpp @@ -19,6 +19,16 @@ VegetationPresenceDefinition::VegetationPresenceDefinition(VegetationLayerDefini bool VegetationPresenceDefinition::collectInstances(std::vector *result, const VegetationModelDefinition &model, double xmin, double zmin, double xmax, double zmax, bool outcomers) const { + if (outcomers) + { + // Expand the area to include outcoming instances + double max_radius = getMaxHeight(); + xmin -= max_radius; + zmin -= max_radius; + xmax += max_radius; + zmax += max_radius; + } + bool added = 0; const NoiseGenerator *generator = noise->getGenerator(); @@ -46,3 +56,8 @@ bool VegetationPresenceDefinition::collectInstances(std::vector 0; } + +double VegetationPresenceDefinition::getMaxHeight() const +{ + return 0.3; +} diff --git a/src/definition/VegetationPresenceDefinition.h b/src/definition/VegetationPresenceDefinition.h index 776c21f..8983c3f 100644 --- a/src/definition/VegetationPresenceDefinition.h +++ b/src/definition/VegetationPresenceDefinition.h @@ -27,6 +27,8 @@ public: */ bool collectInstances(std::vector *result, const VegetationModelDefinition &model, double xmin, double zmin, double xmax, double zmax, bool outcomers=true) const; + double getMaxHeight() const; + private: NoiseNode *noise; FloatNode *interval; diff --git a/src/interface/commandline/tests.cpp b/src/interface/commandline/tests.cpp index 10d04cd..b6ad79b 100644 --- a/src/interface/commandline/tests.cpp +++ b/src/interface/commandline/tests.cpp @@ -295,10 +295,14 @@ static void testVegetationModels() renderer.setSize(width, height); renderer.setQuality(0.5); - VegetationModelDefinition model(NULL); - renderer.setSoloRasterizer(new TestRasterizer(&renderer, model)); + for (int i = 0; i < 10; i++) + { + // TODO Make random sequence repeatable + VegetationModelDefinition model(NULL); + renderer.setSoloRasterizer(new TestRasterizer(&renderer, model)); - startTestRender(&renderer, "vegetation_model_basic"); + startTestRender(&renderer, "vegetation_model_basic", i); + } } void runTestSuite() diff --git a/src/render/software/VegetationRenderer.cpp b/src/render/software/VegetationRenderer.cpp index 89ff530..a04dff2 100644 --- a/src/render/software/VegetationRenderer.cpp +++ b/src/render/software/VegetationRenderer.cpp @@ -101,18 +101,18 @@ RayCastingResult VegetationRenderer::getResult(const SpaceSegment &segment, bool RayCastingResult VegetationRenderer::getBoundResult(const SpaceSegment &segment, double x, double z, bool only_hit, double xsize, double zsize) { + VegetationDefinition *vegetation = parent->getScenery()->getVegetation(); + // Early check if we may cross any vegetation double ymin, ymax; - double vegetation_max_height = 0.0; // TODO parent->getTerrainRenderer()->estimateMinMaxHeight(x, z, x + xsize, z + zsize, &ymin, &ymax); - ymax += vegetation_max_height; + ymax += vegetation->getMaxHeight(); SpaceSegment bbox(Vector3(x, ymin, z), Vector3(x + xsize, ymax, z + zsize)); if (not segment.intersectBoundingBox(bbox)) { return RayCastingResult(); } // Iterate all layers and instances - VegetationDefinition *vegetation = parent->getScenery()->getVegetation(); int n = vegetation->count(); for (int i = 0; i < n; i++) {