Refactored vegetation presence
This commit is contained in:
parent
cd7f30ecae
commit
48dc1a8f25
19 changed files with 134 additions and 88 deletions
|
@ -54,7 +54,7 @@ void DefinitionNode::setName(const std::string &name)
|
|||
this->name = name;
|
||||
}
|
||||
|
||||
Scenery* DefinitionNode::getScenery()
|
||||
const Scenery* DefinitionNode::getScenery() const
|
||||
{
|
||||
if (parent)
|
||||
{
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
|
||||
inline const std::string &getTypeName() const {return type_name;}
|
||||
|
||||
virtual Scenery* getScenery();
|
||||
virtual const Scenery* getScenery() const;
|
||||
|
||||
inline const DefinitionNode *getParent() const {return parent;}
|
||||
inline const DefinitionNode *getRoot() const {return root;}
|
||||
|
|
|
@ -102,7 +102,7 @@ Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath)
|
|||
return FILE_OPERATION_OK;
|
||||
}
|
||||
|
||||
Scenery* Scenery::getScenery()
|
||||
const Scenery* Scenery::getScenery() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public:
|
|||
FileOperationResult saveGlobal(const std::string &filepath) const;
|
||||
FileOperationResult loadGlobal(const std::string &filepath);
|
||||
|
||||
virtual Scenery* getScenery() override;
|
||||
virtual const Scenery* getScenery() const override;
|
||||
|
||||
void autoPreset(int seed=0);
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ void TextureLayerDefinition::validate()
|
|||
material->validate();
|
||||
|
||||
/* Update zone height range */
|
||||
Scenery* scenery = getScenery();
|
||||
const Scenery* scenery = getScenery();
|
||||
if (scenery)
|
||||
{
|
||||
TerrainDefinition* terrain = scenery->getTerrain();
|
||||
|
|
|
@ -11,12 +11,6 @@ static DefinitionNode* _layer_constructor(Layers* parent)
|
|||
VegetationDefinition::VegetationDefinition(DefinitionNode* parent) :
|
||||
Layers(parent, "vegetation", _layer_constructor)
|
||||
{
|
||||
debug_model = new VegetationModelDefinition(this);
|
||||
}
|
||||
|
||||
VegetationDefinition::~VegetationDefinition()
|
||||
{
|
||||
delete debug_model;
|
||||
}
|
||||
|
||||
void VegetationDefinition::applyPreset(VegetationPreset preset)
|
||||
|
|
|
@ -15,7 +15,6 @@ class DEFINITIONSHARED_EXPORT VegetationDefinition : public Layers
|
|||
{
|
||||
public:
|
||||
VegetationDefinition(DefinitionNode* parent);
|
||||
virtual ~VegetationDefinition();
|
||||
|
||||
/**
|
||||
* Get a vegetation layer by its position.
|
||||
|
@ -27,9 +26,6 @@ public:
|
|||
VEGETATION_PRESET_TEMPERATE
|
||||
} VegetationPreset;
|
||||
void applyPreset(VegetationPreset preset);
|
||||
|
||||
// TEMP
|
||||
VegetationModelDefinition *debug_model;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,3 +4,8 @@ VegetationInstance::VegetationInstance(const VegetationModelDefinition &model, c
|
|||
model(model), base(base), size(size), angle(angle)
|
||||
{
|
||||
}
|
||||
|
||||
VegetationInstance VegetationInstance::displace(const Vector3 &location, const Vector3 &normal) const
|
||||
{
|
||||
return VegetationInstance(model, location, size, angle);
|
||||
}
|
|
@ -1,19 +1,19 @@
|
|||
#ifndef VEGETATIONINSTANCE_H
|
||||
#define VEGETATIONINSTANCE_H
|
||||
|
||||
#include "software_global.h"
|
||||
#include "definition_global.h"
|
||||
|
||||
#include "Vector3.h"
|
||||
|
||||
namespace paysages {
|
||||
namespace software {
|
||||
namespace definition {
|
||||
|
||||
/**
|
||||
* Single instance of a vegetation layer (e.g. a single tree).
|
||||
*
|
||||
* This is used as potential hit on vegetation lookup.
|
||||
*/
|
||||
class SOFTWARESHARED_EXPORT VegetationInstance
|
||||
class DEFINITIONSHARED_EXPORT VegetationInstance
|
||||
{
|
||||
public:
|
||||
VegetationInstance(const VegetationModelDefinition &model, const Vector3 &base, double size=1.0, double angle=0.0);
|
||||
|
@ -22,6 +22,11 @@ public:
|
|||
inline const Vector3 &getBase() const {return base;}
|
||||
inline double getSize() const {return size;}
|
||||
|
||||
/**
|
||||
* Return a copy of this instance, with terrain displacement applied.
|
||||
*/
|
||||
VegetationInstance displace(const Vector3 &location, const Vector3 &normal) const;
|
||||
|
||||
private:
|
||||
const VegetationModelDefinition &model;
|
||||
Vector3 base;
|
|
@ -1,49 +1,16 @@
|
|||
#include "VegetationLayerDefinition.h"
|
||||
|
||||
#include "TerrainHeightMap.h"
|
||||
#include "VegetationModelDefinition.h"
|
||||
#include "VegetationPresenceDefinition.h"
|
||||
|
||||
VegetationLayerDefinition::VegetationLayerDefinition(DefinitionNode* parent) :
|
||||
DefinitionNode(parent, "layer")
|
||||
{
|
||||
//area = new TerrainHeightMap();
|
||||
model = new VegetationModelDefinition(this);
|
||||
}
|
||||
|
||||
VegetationLayerDefinition::~VegetationLayerDefinition()
|
||||
{
|
||||
//delete area;
|
||||
delete model;
|
||||
}
|
||||
|
||||
void VegetationLayerDefinition::save(PackStream *stream) const
|
||||
{
|
||||
//area->save(stream);
|
||||
model->save(stream);
|
||||
}
|
||||
|
||||
void VegetationLayerDefinition::load(PackStream *stream)
|
||||
{
|
||||
//area->load(stream);
|
||||
model->load(stream);
|
||||
}
|
||||
|
||||
void VegetationLayerDefinition::copy(DefinitionNode *destination_) const
|
||||
{
|
||||
VegetationLayerDefinition *destination = (VegetationLayerDefinition *)destination_;
|
||||
|
||||
//area->copy(destination->area);
|
||||
model->copy(destination->model);
|
||||
}
|
||||
|
||||
void VegetationLayerDefinition::validate()
|
||||
{
|
||||
//area->validate();
|
||||
model->validate();
|
||||
presence = new VegetationPresenceDefinition(this);
|
||||
}
|
||||
|
||||
void VegetationLayerDefinition::applyPreset(VegetationLayerPreset preset)
|
||||
{
|
||||
// TODO
|
||||
model->randomize();
|
||||
}
|
||||
|
|
|
@ -15,12 +15,9 @@ class DEFINITIONSHARED_EXPORT VegetationLayerDefinition : public DefinitionNode
|
|||
{
|
||||
public:
|
||||
VegetationLayerDefinition(DefinitionNode *parent);
|
||||
virtual ~VegetationLayerDefinition();
|
||||
|
||||
virtual void save(PackStream *stream) const override;
|
||||
virtual void load(PackStream *stream) override;
|
||||
virtual void copy(DefinitionNode *destination) const override;
|
||||
virtual void validate() override;
|
||||
inline const VegetationPresenceDefinition *getPresence() const {return presence;}
|
||||
inline const VegetationModelDefinition *getModel() const {return model;}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -32,7 +29,7 @@ private:
|
|||
/**
|
||||
* Geographic area of presence of this layer.
|
||||
*/
|
||||
TerrainHeightMap *area;
|
||||
VegetationPresenceDefinition *presence;
|
||||
|
||||
/**
|
||||
* Base vegetation model to use for this layer.
|
||||
|
|
21
src/definition/VegetationPresenceDefinition.cpp
Normal file
21
src/definition/VegetationPresenceDefinition.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include "VegetationPresenceDefinition.h"
|
||||
|
||||
#include "Scenery.h"
|
||||
#include "TerrainDefinition.h"
|
||||
#include "VegetationLayerDefinition.h"
|
||||
#include "VegetationInstance.h"
|
||||
|
||||
VegetationPresenceDefinition::VegetationPresenceDefinition(VegetationLayerDefinition *parent):
|
||||
DefinitionNode(parent, "presence")
|
||||
{
|
||||
}
|
||||
|
||||
bool VegetationPresenceDefinition::collectInstances(std::vector<VegetationInstance> *result, const VegetationModelDefinition &model, double xmin, double zmin, double xmax, double zmax, bool outcomers) const
|
||||
{
|
||||
// TEMP debug implementation
|
||||
double x = (xmin + xmax) / 2.0;
|
||||
double z = (zmax + zmin) / 2.0;
|
||||
double y = getScenery()->getTerrain()->getInterpolatedHeight(x, z, true, true);
|
||||
result->push_back(VegetationInstance(model, Vector3(x, y, z), 0.2));
|
||||
return true;
|
||||
}
|
34
src/definition/VegetationPresenceDefinition.h
Normal file
34
src/definition/VegetationPresenceDefinition.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef VEGETATIONPRESENCEDEFINITION_H
|
||||
#define VEGETATIONPRESENCEDEFINITION_H
|
||||
|
||||
#include "definition_global.h"
|
||||
|
||||
#include "DefinitionNode.h"
|
||||
|
||||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
/**
|
||||
* Definition of the presence of vegetation at locations.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT VegetationPresenceDefinition: public DefinitionNode
|
||||
{
|
||||
public:
|
||||
VegetationPresenceDefinition(VegetationLayerDefinition *parent);
|
||||
|
||||
/**
|
||||
* Collect instances in a rectangle area.
|
||||
*
|
||||
* If *outcomers* is true, the rectangle area will be expanded to included potential instances that does not originate
|
||||
* in the area, but may have leaves in it.
|
||||
*
|
||||
* The location vector set in collected instances is based on raw terrain height, without displacement.
|
||||
* It's the renderer role to apply the correct displacement.
|
||||
*/
|
||||
bool collectInstances(std::vector<VegetationInstance> *result, const VegetationModelDefinition &model, double xmin, double zmin, double xmax, double zmax, bool outcomers=true) const;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VEGETATIONPRESENCEDEFINITION_H
|
|
@ -30,6 +30,7 @@ SOURCES += \
|
|||
VegetationLayerDefinition.cpp \
|
||||
VegetationDefinition.cpp \
|
||||
VegetationModelDefinition.cpp \
|
||||
VegetationInstance.cpp \
|
||||
PaintedGrid.cpp \
|
||||
PaintedGridBrush.cpp \
|
||||
PaintedGridData.cpp \
|
||||
|
@ -42,7 +43,8 @@ SOURCES += \
|
|||
IntNode.cpp \
|
||||
IntDiff.cpp \
|
||||
GodRaysDefinition.cpp \
|
||||
TimeManager.cpp
|
||||
TimeManager.cpp \
|
||||
VegetationPresenceDefinition.cpp
|
||||
|
||||
HEADERS +=\
|
||||
definition_global.h \
|
||||
|
@ -62,6 +64,7 @@ HEADERS +=\
|
|||
VegetationLayerDefinition.h \
|
||||
VegetationDefinition.h \
|
||||
VegetationModelDefinition.h \
|
||||
VegetationInstance.h \
|
||||
PaintedGrid.h \
|
||||
PaintedGridBrush.h \
|
||||
PaintedGridData.h \
|
||||
|
@ -74,7 +77,8 @@ HEADERS +=\
|
|||
IntNode.h \
|
||||
IntDiff.h \
|
||||
GodRaysDefinition.h \
|
||||
TimeManager.h
|
||||
TimeManager.h \
|
||||
VegetationPresenceDefinition.h
|
||||
|
||||
unix:!symbian {
|
||||
maemo5 {
|
||||
|
|
|
@ -38,6 +38,8 @@ namespace definition {
|
|||
class VegetationDefinition;
|
||||
class VegetationLayerDefinition;
|
||||
class VegetationModelDefinition;
|
||||
class VegetationPresenceDefinition;
|
||||
class VegetationInstance;
|
||||
class PaintedGrid;
|
||||
class PaintedGridData;
|
||||
class PaintedGridBrush;
|
||||
|
|
|
@ -9,17 +9,20 @@
|
|||
#include "Scenery.h"
|
||||
#include "TerrainRenderer.h"
|
||||
#include "VegetationDefinition.h"
|
||||
#include "VegetationLayerDefinition.h"
|
||||
#include "VegetationPresenceDefinition.h"
|
||||
#include "VegetationInstance.h"
|
||||
#include "VegetationResult.h"
|
||||
#include "LightComponent.h"
|
||||
|
||||
const double DEBUG_DENSITY_FACTOR = 0.5;
|
||||
|
||||
// TEMP
|
||||
/**
|
||||
* Grid iterator to collect instances of a layer, in small squares.
|
||||
*/
|
||||
class VegetationGridIterator: public SpaceGridIterator
|
||||
{
|
||||
public:
|
||||
VegetationGridIterator(const SpaceSegment &segment, VegetationRenderer *renderer, VegetationModelDefinition *model, bool only_hit):
|
||||
segment(segment), renderer(renderer), model(model), only_hit(only_hit)
|
||||
VegetationGridIterator(const SpaceSegment &segment, VegetationRenderer *renderer, VegetationLayerDefinition *layer, bool only_hit):
|
||||
segment(segment), renderer(renderer), layer(layer), only_hit(only_hit)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -27,17 +30,24 @@ public:
|
|||
|
||||
virtual bool onCell(int x, int, int z) override
|
||||
{
|
||||
double dx = ((double)x + 0.5) * DEBUG_DENSITY_FACTOR;
|
||||
double dz = ((double)z + 0.5) * DEBUG_DENSITY_FACTOR;
|
||||
Vector3 base = renderer->getParent()->getTerrainRenderer()->getResult(dx, dz, 1, 1).location;
|
||||
VegetationInstance instance(*model, base, 0.2);
|
||||
result = renderer->renderInstance(segment, instance, only_hit);
|
||||
return not result.hit;
|
||||
std::vector<VegetationInstance> instances;
|
||||
|
||||
layer->getPresence()->collectInstances(&instances, *layer->getModel(), x - 0.5, z - 0.5, x + 0.5, z + 0.5);
|
||||
|
||||
for (auto &instance: instances)
|
||||
{
|
||||
result = renderer->renderInstance(segment, instance, only_hit);
|
||||
if (result.hit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
const SpaceSegment &segment;
|
||||
VegetationRenderer *renderer;
|
||||
VegetationModelDefinition *model;
|
||||
VegetationLayerDefinition *layer;
|
||||
RayCastingResult result;
|
||||
bool only_hit;
|
||||
};
|
||||
|
@ -52,10 +62,18 @@ void VegetationRenderer::setEnabled(bool enabled)
|
|||
this->enabled = enabled;
|
||||
}
|
||||
|
||||
RayCastingResult VegetationRenderer::renderInstance(const SpaceSegment &segment, const VegetationInstance &instance, bool only_hit)
|
||||
RayCastingResult VegetationRenderer::renderInstance(const SpaceSegment &segment, const VegetationInstance &instance, bool only_hit, bool displaced)
|
||||
{
|
||||
RayCastingResult final;
|
||||
if (!displaced)
|
||||
{
|
||||
// Recursive call on displaced instance
|
||||
const Vector3 &base = instance.getBase();
|
||||
TerrainRenderer::TerrainResult terrain = parent->getTerrainRenderer()->getResult(base.x, base.z, true, true);
|
||||
VegetationInstance displaced_instance = instance.displace(terrain.location, terrain.normal);
|
||||
return renderInstance(segment, displaced_instance, only_hit, true);
|
||||
}
|
||||
|
||||
RayCastingResult final;
|
||||
VegetationModelRenderer model_renderer(parent, &instance.getModel());
|
||||
SpaceSegment scaled_segment(segment.getStart().sub(instance.getBase()).scale(1.0 / instance.getSize()),
|
||||
segment.getEnd().sub(instance.getBase()).scale(1.0 / instance.getSize()));
|
||||
|
@ -78,17 +96,19 @@ RayCastingResult VegetationRenderer::getResult(const SpaceSegment &segment, bool
|
|||
{
|
||||
if (enabled)
|
||||
{
|
||||
// Find instances potentially crossing the segment
|
||||
// TODO Collect the nearest hit, don't stop at the first one
|
||||
VegetationGridIterator it(segment, this, parent->getScenery()->getVegetation()->debug_model, only_hit);
|
||||
if (not segment.projectedOnYPlane().scaled(1.0 / DEBUG_DENSITY_FACTOR).iterateOnGrid(it))
|
||||
VegetationDefinition *vegetation = parent->getScenery()->getVegetation();
|
||||
int n = vegetation->count();
|
||||
// TODO Don't stop at first layer, find the nearest hit
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
return it.getResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return RayCastingResult();
|
||||
// Find instances potentially crossing the segment
|
||||
VegetationGridIterator it(segment, this, vegetation->getVegetationLayer(i), only_hit);
|
||||
if (not segment.projectedOnYPlane().iterateOnGrid(it))
|
||||
{
|
||||
return it.getResult();
|
||||
}
|
||||
}
|
||||
return RayCastingResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -22,8 +22,12 @@ public:
|
|||
|
||||
/**
|
||||
* Perform ray casting on a single instance.
|
||||
*
|
||||
* If *only_hit* is true, only care about hitting or not, do not compute the color.
|
||||
*
|
||||
* If *displaced* is true, *instance* is considered on already displaced terrain, else, terrain displacement is applied.
|
||||
*/
|
||||
RayCastingResult renderInstance(const SpaceSegment &segment, const VegetationInstance &instance, bool only_hit=false);
|
||||
RayCastingResult renderInstance(const SpaceSegment &segment, const VegetationInstance &instance, bool only_hit=false, bool displaced=false);
|
||||
|
||||
/**
|
||||
* Perform ray casting on a given segment.
|
||||
|
|
|
@ -59,7 +59,6 @@ SOURCES += SoftwareRenderer.cpp \
|
|||
GodRaysResult.cpp \
|
||||
VegetationRasterizer.cpp \
|
||||
VegetationRenderer.cpp \
|
||||
VegetationInstance.cpp \
|
||||
VegetationResult.cpp
|
||||
|
||||
HEADERS += SoftwareRenderer.h\
|
||||
|
@ -109,7 +108,6 @@ HEADERS += SoftwareRenderer.h\
|
|||
GodRaysResult.h \
|
||||
VegetationRasterizer.h \
|
||||
VegetationRenderer.h \
|
||||
VegetationInstance.h \
|
||||
VegetationResult.h
|
||||
|
||||
unix:!symbian {
|
||||
|
|
|
@ -55,7 +55,6 @@ namespace software {
|
|||
class GodRaysSampler;
|
||||
class GodRaysResult;
|
||||
class VegetationResult;
|
||||
class VegetationInstance;
|
||||
class VegetationRenderer;
|
||||
class VegetationModelRenderer;
|
||||
|
||||
|
|
Loading…
Reference in a new issue