[ACCEPTED] loader->deleteTrees()

klumhru

29-03-2008 21:46:50

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) */
TreeLoader3D::deleteTrees(TRect *rectArea)
{
// Delete trees with coords within this rectangle
}


Man, this library rocks by the way.

JohnJ

02-04-2008 15:24:52

Thanks, that's a good suggestion. I'll put it on my list :)

klumhru

02-04-2008 16:28:23

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 */
TreeMap *getTreeMap()
{
return treeMap;
}


Most of the code is borrowed from the DensityMap relevant code.

JohnJ

04-04-2008 04:42:50

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.

Shadow007

04-04-2008 09:52:29

How about an alternate method : /* Deletes all trees within the circle (x.z , dist) */
TreeLoader3D::deleteTrees(center, distance)
{
// Delete trees with coords within this circle
}

klumhru

04-04-2008 10:47:38

@Shadow007

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);


@JohnJ
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.

Treemap:


Result:


EDIT:
Using DensityMap instead of my superfluous class:

Treemap.png


Result:

JohnJ

04-04-2008 16:16:10

Nice. Very colorful too :D.

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.

klumhru

05-04-2008 00:38:35

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 :)

JohnJ

19-04-2008 22:42:26

Update: TreeLoader2D and TreeLoader3D now have a deleteTrees() function overload accepting a TBounds variable for the deletion of rectangular regions of trees.