Been toying with PG for a few days now, and like it.
Just wanted to suggest / request a feature.
/* Deletes all trees within the rectangle (x.z - X.Z) */
// Delete trees with coords within this rectangle
Man, this library rocks by the way.
Thanks, that's a good suggestion. I'll put it on my list
I already added the code to my PG src, and I'm working on a TreeLoader3d::setTreeMap(material/filename) method to be able to populate a treeloader with an image file by ways of a TreeMap class in PropertyMaps.h/.cpp. Can post a diff when I'm done on that if you want (haven't tested it properly yet).
At the moment the setTreeMap method looks like:
/**\brief Creates trees according to a 2d grayscale image
\param mapFile a file containing a grayscale image
\param trees The number of trees to place per pixel
\param seed The random seed to use when placing trees, pass 0 to not use random placement, or 1 to not generate a new random each time
\param channel The color channel(s) to use from the image
void setTreeMap(const Ogre::String &mapFile, int trees = 4, Ogre::Real seed, MapChannel channel = CHANNEL_COLOR);
/** \brief Overloaded to use a texture object
void setTreeMap(Ogre::Texture *map, int trees = 4, Ogre::Real seed, MapChannel channel = CHANNEL_COLOR);
/** \brief gets a pointer to the treemap being used */
Most of the code is borrowed from the DensityMap relevant code.
Actually there shouldn't really be a TreeMap class - a treemap is just a density map, and there's already a class that serves that purpose very well - DensityMap. You should be able to use a DensityMap to populate density map based trees fairly easily, with useful functions like _getDensityAt_Unfiltered() and _getDensityAt_Bilinear().
If you want to use multiple color channels (red/green/blue/etc.) for different tree layers, that should be easily achievable too because the DensityMap class support color channel extraction also.
Don't worry too much about it though, because I can implement all this myself, though if you're willing to contribute that would be greatly appreciated also.
How about an alternate method :
/* Deletes all trees within the circle (x.z , dist) */
// Delete trees with coords within this circle
Already implemented in the CVS version:
/** \brief Deletes trees within a certain radius of the given coordinates.
\param position The coordinate of the tree(s) to delete
\param radius The radius from the given coordinate where trees will be deleted
\param type The type of tree to delete (optional)
\note If the "type" parameter is set to an entity, only trees created with that entity
will be deleted. */
void deleteTrees(const Ogre::Vector3 &position, float radius, Ogre::Entity *type = NULL);
Well, I just added it to my code since I needed it for my project, so it's no bother. I'm mostly done with the TreeMap, which is pretty much identical to DensityMap, using mostly "borrowed" DensityMap code. Having some strange behaviour with clumping when adding more than one tree per pixel, but will have that sorted out I think. The TreeMap supports different color channels as input, but does not implement different tree entities per channel. I simply didn't think of it
When you mentioned it, I should of course just have used the DensityMap class and created a member instance in TreeLoader3D. I seem to feel I had some reason not to do it. There was beer involved.
Using DensityMap instead of my superfluous class:
Nice. Very colorful too
I guess the advantage of a custom density map over the current DensityMap class would be if you wanted one tree per pixel only, because the DensityMap doesn't do that - it's just a representation of spatially varying densities. I think a density map is superior to a tree-per-pixel approach because it uses less memory for the same amount of trees, and it's probably just easier to paint fairly natural forests in.
Anyway, I'm glad you could make use of the DensityMap class. Originally this functionality was hard-coded directly in the GrassLayer class, but I'm glad now that I separated it - it should be useful for any "density map" related task.
Well, I'm actually using the density map to paint X trees per pixel with different entities per map channel.
The colored balls are different entities with different materials, the white pixels, being of all channels, generate one for each channel.
The header for the setDensityMap method looks like this at the moment:
void TreeLoader3D::addDensityMap(std::map<MapChannel, Ogre::Entity*> *entities, Ogre::String &mapFile, int trees /* = 4 */, Ogre::uint8 seed /* = 1 */)
Where the std::map contains a list of channel->entity pairs. The method then immediately populates the treeloader, so it happens at load time. By setting the random seed you will get the same distribution each time, which is what I was really seeking. This can of course be extended to editing the tree map, but that's really beyond the scope of what I'm doiing, that is M1 Tank Platoon remake hehe
Update: TreeLoader2D and TreeLoader3D now have a deleteTrees() function overload accepting a TBounds variable for the deletion of rectangular regions of trees.