Fixed holes in vegetation rendering

This commit is contained in:
Michaël Lemaire 2015-11-02 23:00:02 +01:00
parent 68945111d1
commit 2560fe2c53
8 changed files with 56 additions and 6 deletions

View file

@ -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) void VegetationDefinition::applyPreset(VegetationPreset preset)
{ {
VegetationLayerDefinition *layer; VegetationLayerDefinition *layer;

View file

@ -21,6 +21,11 @@ public:
*/ */
inline VegetationLayerDefinition* getVegetationLayer(int position) const {return (VegetationLayerDefinition*)getLayer(position);} inline VegetationLayerDefinition* getVegetationLayer(int position) const {return (VegetationLayerDefinition*)getLayer(position);}
/**
* Get the max height of all layers assembled.
*/
double getMaxHeight() const;
typedef enum typedef enum
{ {
VEGETATION_PRESET_TEMPERATE VEGETATION_PRESET_TEMPERATE

View file

@ -10,6 +10,11 @@ VegetationLayerDefinition::VegetationLayerDefinition(DefinitionNode* parent) :
presence = new VegetationPresenceDefinition(this); presence = new VegetationPresenceDefinition(this);
} }
double VegetationLayerDefinition::getMaxHeight() const
{
return presence->getMaxHeight();
}
void VegetationLayerDefinition::applyPreset(VegetationLayerPreset preset) void VegetationLayerDefinition::applyPreset(VegetationLayerPreset preset)
{ {
model->randomize(); model->randomize();

View file

@ -19,6 +19,8 @@ public:
inline const VegetationPresenceDefinition *getPresence() const {return presence;} inline const VegetationPresenceDefinition *getPresence() const {return presence;}
inline const VegetationModelDefinition *getModel() const {return model;} inline const VegetationModelDefinition *getModel() const {return model;}
double getMaxHeight() const;
typedef enum typedef enum
{ {
VEGETATION_BASIC_TREES VEGETATION_BASIC_TREES

View file

@ -19,6 +19,16 @@ VegetationPresenceDefinition::VegetationPresenceDefinition(VegetationLayerDefini
bool VegetationPresenceDefinition::collectInstances(std::vector<VegetationInstance> *result, const VegetationModelDefinition &model, double xmin, double zmin, double xmax, double zmax, bool outcomers) const bool VegetationPresenceDefinition::collectInstances(std::vector<VegetationInstance> *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; bool added = 0;
const NoiseGenerator *generator = noise->getGenerator(); const NoiseGenerator *generator = noise->getGenerator();
@ -46,3 +56,8 @@ bool VegetationPresenceDefinition::collectInstances(std::vector<VegetationInstan
return added > 0; return added > 0;
} }
double VegetationPresenceDefinition::getMaxHeight() const
{
return 0.3;
}

View file

@ -27,6 +27,8 @@ public:
*/ */
bool collectInstances(std::vector<VegetationInstance> *result, const VegetationModelDefinition &model, double xmin, double zmin, double xmax, double zmax, bool outcomers=true) const; bool collectInstances(std::vector<VegetationInstance> *result, const VegetationModelDefinition &model, double xmin, double zmin, double xmax, double zmax, bool outcomers=true) const;
double getMaxHeight() const;
private: private:
NoiseNode *noise; NoiseNode *noise;
FloatNode *interval; FloatNode *interval;

View file

@ -295,10 +295,14 @@ static void testVegetationModels()
renderer.setSize(width, height); renderer.setSize(width, height);
renderer.setQuality(0.5); renderer.setQuality(0.5);
VegetationModelDefinition model(NULL); for (int i = 0; i < 10; i++)
renderer.setSoloRasterizer(new TestRasterizer(&renderer, model)); {
// 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() void runTestSuite()

View file

@ -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) 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 // Early check if we may cross any vegetation
double ymin, ymax; double ymin, ymax;
double vegetation_max_height = 0.0; // TODO
parent->getTerrainRenderer()->estimateMinMaxHeight(x, z, x + xsize, z + zsize, &ymin, &ymax); 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)); SpaceSegment bbox(Vector3(x, ymin, z), Vector3(x + xsize, ymax, z + zsize));
if (not segment.intersectBoundingBox(bbox)) { if (not segment.intersectBoundingBox(bbox)) {
return RayCastingResult(); return RayCastingResult();
} }
// Iterate all layers and instances // Iterate all layers and instances
VegetationDefinition *vegetation = parent->getScenery()->getVegetation();
int n = vegetation->count(); int n = vegetation->count();
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
{ {