PagedGeometry版本:1.1
ONE.静态树a).创建PagedGeometry对象,用于管理草体的细节
PagedGeometry *trees = new PagedGeometry();
1 trees->setCamera(camera); //Set the camera so PagedGeometry knows how to calculate LODs
2 trees->setPageSize(80); //Set the size of each page of geometry
3 trees->setInfinite(); //Use infinite paging mode
4 trees->addDetailLevel<BatchPage>(150, 50); //Use batches up to 150 units away, and fade for 30 more units
5 trees->addDetailLevel<ImpostorPage>(500, 50); //Use impostors up to 400 units, and for for 50 more units b).创建草体加载器,用于加载加载草体,铺草
TreeLoader3D *treeLoader = new TreeLoader3D(trees, TBounds(0, 0, 1500,1500));
1 trees->setPageLoader(treeLoader); //Assign the "treeLoader" to be used to load geometry for the PagedGeometry instance
2
3 //Load a tree entity
4 Entity *myEntity = sceneMgr->createEntity("Tree", "tree2.mesh");
5
6 //Setup the height function (so the Y values of trees can be calculated when they are placed on the terrain)
7 HeightFunction::initialize(sceneMgr);
8
9 //Randomly place 20,000 copies of the tree on the terrain
10 Vector3 position;
11 Radian yaw;
12 Real scale;
13 for (int i = 0; i < 20000; i++){
14 yaw = Degree(Math::RangeRandom(0, 360));
15
16 position.x = Math::RangeRandom(0, 1500);
17 position.z = Math::RangeRandom(0, 1500);
18 position.y = HeightFunction::getTerrainHeight(position.x, position.z);
19
20 scale = Math::RangeRandom(0.5f, 0.6f);
21
22 treeLoader->addTree(myEntity, position, yaw, scale);
23 }c).帧循环中进行更新
trees->update();
其内部有3个动作:
1.更新loader
2.更新内部对象:GeometryPageManager
3. Update misc. subsystems
StaticBillboardSet::updateAll(_convertToLocal(getCamera()->getDerivedDirection()));
d).退出时清理内存
1 //[NOTE] Always remember to delete any PageLoader(s) and PagedGeometry instances in order to avoid memory leaks.
2
3 //Delete the TreeLoader3D instance
4 delete trees->getPageLoader();
5
6 //Delete the PagedGeometry instance
7 delete trees;
8
9 //Also delete the tree entity
10 sceneMgr->destroyEntity("Tree");
TWO.动态草体动态草和静态树的创建如出一辙,只是将植物加载器换从“TreeLoader3D”换成了“GrassLoader”而已,顺利成章的,如果要家长其他不同类的植物,只需使用一个该植物的“XXXLoader”即可。其实整个PagedGeometry中的加载器只有三个,
PageLoader派生了3个加载器:
- Forests::GrassLoader
- Forests::TreeLoader2D
- Forests::TreeLoader3D
GrassLoader创建如下:
1 grassLoader = new GrassLoader(grass);
2 grass->setPageLoader(grassLoader); //Assign the "treeLoader" to be used to load geometry for the PagedGeometry instance
3
4 //Supply a height function to GrassLoader so it can calculate grass Y values
5 HeightFunction::initialize(sceneMgr);
6 grassLoader->setHeightFunction(&HeightFunction::getTerrainHeight);GrassLoader借助一个GrassLayer对象来“植树”:
1 //Add some grass to the scene with GrassLoader::addLayer()
2 GrassLayer *l = grassLoader->addLayer("grass");
3
4 //Configure the grass layer properties (size, density, animation properties, fade settings, etc.)
5 l->setMinimumSize(2.0f, 2.0f);
6 l->setMaximumSize(2.5f, 2.5f);
7 l->setAnimationEnabled(true); //Enable animations
8 l->setSwayDistribution(10.0f); //Sway fairly unsynchronized
9 l->setSwayLength(0.5f); //Sway back and forth 0.5 units in length
10 l->setSwaySpeed(0.5f); //Sway 1/2 a cycle every second
11 l->setDensity(1.5f); //Relatively dense grass
12 l->setFadeTechnique(FADETECH_GROW); //Distant grass should slowly raise out of the ground when coming in range
13 l->setRenderTechnique(GRASSTECH_QUAD); //Draw grass as scattered quads
14
15 //This sets a color map to be used when determining the color of each grass quad. setMapBounds()
16 //is used to set the area which is affected by the color map. Here, "terrain_texture.jpg" is used
17 //to color the grass to match the terrain under it.
18 l->setColorMap("terrain_texture.jpg");
19 l->setMapBounds(TBounds(0, 0, 1500, 1500)); //(0,0)-(1500,1500) is the full boundaries of the terraina).源码中队GrassLayer的说明
A data structure giving you full control over grass properties.Grass is added to the scene through GrassLoader::addLayer(). Through this class you can configure your grass layer any way you like - size, density, render technique,animation, etc. Simply call the appropriate "set" member function to set the desired property.Remember that you cannot create or delete layers directly. Layers can only be created with GrassLoader::addLayer(), and may not be deleted manually (they will be deleted when the associated GrassLoader is deleted).
- GrassLayer只能通过GrassLoader::addLayer()来创建
- GrassLoader不能直接创建或删除
- GrassLoader不能进行手动删除
addlayer传给GrassLayer的参数是一个字符串,这个字符串是一个material的名字,以便渲染手动创建的草体mesh时使用。
1GrassLayer *GrassLoader::addLayer(const String &material)
2{
3 GrassLayer *layer = new GrassLayer(geom, this);
4 layer->setMaterialName(material);
5 layerList.push_back(layer);
6
7 return layer;
8}
b).草实体的创建
草体是在GrassLoader::loadPage中创建的
mesh = generateGrass_QUAD(page, layer, position, grassCount);
而loadPage是在帧循环调用“GeometryPageManager::update”时调用的,通过GeometryPageManager::update的“cacheInterval”技术实现渲染前调用一次,好比在帧循环中设置一个标志位,如果发现草实体没有创建,则创建之。这里的generateGrass_QUAD实现了一个手动创建mesh的方法。
THREE.静态树和动态草一起创建2个PagedGeometry对象,分别互不干涉的各管各即可。当然需要在帧循环中分别更新了。
FOUR.2D树和3D树的区别
If the inability to supply a vertical coordinate to addTree() is too limiting, or you are unable to implement
a fast enough height function, please refer to TreeLoader3D. TreeLoader3D allows you to provide full 3D x/y/z
coordinates, although 40% more memory is required per tree.
更多说明见<pagedGeometry-1.1.0\include\TreeLoader2D.h>
- 2D树非常省内存
- 2D树对放置的3D坐标有限制
- 3D树可以设置完全的3D坐标
- 3D树的每一颗树都比2D树多占用40%的内存