2
// C++ Implementation: Forest
7
// Author: Erik Hjortsberg <erik.hjortsberg@gmail.com>, (C) 2008
9
// This program is free software; you can redistribute it and/or modify
10
// it under the terms of the GNU General Public License as published by
11
// the Free Software Foundation; either version 2 of the License, or
12
// (at your option) any later version.
14
// This program is distributed in the hope that it will be useful,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
// GNU General Public License for more details.
19
// You should have received a copy of the GNU General Public License
20
// along with this program; if not, write to the Free Software
21
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.//
28
#include "EmberEntityLoader.h"
30
#include "framework/LoggingInstance.h"
31
#include "services/config/ConfigService.h"
32
#include "pagedgeometry/include/PagedGeometry.h"
33
#include "pagedgeometry/include/TreeLoader3D.h"
34
#include "pagedgeometry/include/BatchPage.h"
35
#include "pagedgeometry/include/ImpostorPage.h"
36
#include "pagedgeometry/include/DummyPage.h"
37
#include "pagedgeometry/include/PassiveEntityPage.h"
38
#include "pagedgeometry/include/BatchedGeometry.h"
40
#include "../MathConverter.h"
41
#include "../AvatarCamera.h"
42
#include "../EmberOgre.h"
43
#include "../terrain/TerrainInfo.h"
44
#include "../terrain/TerrainGenerator.h"
45
#include "../terrain/ISceneManagerAdapter.h"
49
namespace Environment {
56
Ogre::Root::getSingleton().addFrameListener(this);
65
Ogre::Root::getSingleton().removeFrameListener(this);
68
void Forest::initialize()
70
S_LOG_INFO("Initializing forest.");
71
const WFMath::AxisBox<2>& worldSize = EmberOgre::getSingleton().getTerrainGenerator()->getTerrainInfo().getWorldSizeInIndices();
72
if (worldSize.upperBound(0) - worldSize.lowerBound(0) > 0 && worldSize.upperBound(1) - worldSize.lowerBound(1) > 0) {
74
Ogre::Camera& camera = EmberOgre::getSingleton().getMainCamera()->getCamera();
76
mTrees = new PagedGeometry::PagedGeometry();
77
mTrees->setCamera(&camera); //Set the camera so PagedGeometry knows how to calculate LODs
78
mTrees->setPageSize(64); //Set the size of each page of geometry
80
::PagedGeometry::TBounds ogreBounds(Atlas2Ogre(worldSize));
81
if (ogreBounds.width() != ogreBounds.height()) {
82
if (ogreBounds.width() > ogreBounds.height()) {
83
float difference = ogreBounds.width() - ogreBounds.height();
84
ogreBounds.bottom += difference;
86
float difference = ogreBounds.height() - ogreBounds.width();
87
ogreBounds.right += difference;
90
mTrees->setBounds(ogreBounds);
91
// mTrees->addDetailLevel<PagedGeometry::BatchPage>(150, 50); //Use batches up to 150 units away, and fade for 30 more units
92
// mTrees->addDetailLevel<PagedGeometry::DummyPage>(100, 0); //Use batches up to 150 units away, and fade for 30 more units
93
mTrees->addDetailLevel<PagedGeometry::PassiveEntityPage>(150, 0); //Use standard entities up to 150 units away, and don't fade since the PassiveEntityPage doesn't support this (yet)
94
mTrees->addDetailLevel<PagedGeometry::ImpostorPage>(500, 50); //Use impostors up to 400 units, and for for 50 more units
96
//Create a new TreeLoader2D object
97
mEntityLoader = new EmberEntityLoader(*mTrees, 64);
98
// mTreeLoader = new PagedGeometry::TreeLoader3D(mTrees, Atlas2Ogre(worldSize));
99
mTrees->setPageLoader(mEntityLoader); //Assign the "treeLoader" to be used to load geometry for the PagedGeometry instance
103
void Forest::addTree(Ogre::Entity *entity, const Ogre::Vector3 &position, Ogre::Degree yaw, Ogre::Real scale)
106
if (mTreeLoader && mTrees)
108
S_LOG_VERBOSE("Adding tree of entity type " << entity->getMesh()->getName() << " to position x: " << position.x << " y: " << position.y << " z: " << position.z << " and scale " << scale);
110
mTreeLoader->addTree(entity, position, yaw, scale);
111
} catch (const std::exception& ex)
113
S_LOG_FAILURE("Error when adding tree: " << ex.what());
116
S_LOG_WARNING("Could not add tree before the forest has been initialized.");
120
bool Forest::frameStarted(const Ogre::FrameEvent & evt)
125
} catch (const Ogre::Exception& ex)
127
S_LOG_FAILURE("Error when updating forest. Will disable forest.\n"<< ex.what());
129
delete mEntityLoader;
139
void Forest::addEmberEntity(EmberPhysicalEntity * entity)
142
mEntityLoader->addEmberEntity(entity);
146
void Forest::removeEmberEntity(EmberPhysicalEntity * entity)
149
mEntityLoader->removeEmberEntity(entity);