With this code (provided here under the GPL):
void ForestTechniqueManager::createTreeList(osg::Node* terrain,const osg::Vec3& origin, const osg::Vec3& size,unsigned int numTreesToCreate,TreeList& trees)
{
float max_TreeHeight = 15*sqrtf(size.length2()/(float)numTreesToCreate);
float max_TreeWidth = max_TreeHeight;
float min_TreeHeight = max_TreeHeight*0.3f;
float min_TreeWidth = min_TreeHeight;
trees.reserve(trees.size()+numTreesToCreate);
float ceil = origin.z()+900.0f;
float floor = origin.z()+300.0f;
for(unsigned int i=0;i {
Tree* tree = new Tree;
tree->_position.set(
random(origin.x(),origin.x()+size.x()),
random(origin.y(),origin.y()+size.y()),
random(floor,ceil)
);
float colorFactor = (tree->_position.z()-floor)/(ceil-floor);
colorFactor = 0.3 + colorFactor*(1.0-0.3);
int color = (int) ((1.0 - (1.0-colorFactor)*(1.0-colorFactor) ) *255.0);
tree->_color.set(
color, color, color,
255
);
tree->_width = random(min_TreeWidth,max_TreeWidth*(1.3f-colorFactor) );
tree->_height = random(min_TreeHeight,max_TreeHeight*(1.3f-colorFactor) );
tree->_type = 0;
//if (terrain)
if (0)
{
osgUtil::IntersectVisitor iv;
osg::ref_ptr segDown = new osg::LineSegment;
segDown->set(tree->_position,tree->_position+osg::Vec3(0.0f,0.0f,size.z()));
iv.addLineSegment(segDown.get());
terrain->accept(iv);
if (iv.hits())
{
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segDown.get());
if (!hitList.empty())
{
osg::Vec3 ip = hitList.front().getWorldIntersectPoint();
osg::Vec3 np = hitList.front().getWorldIntersectNormal();
tree->_position = ip;
}
}
}
trees.push_back(tree);
}
}