SO3Engine
SO3Terrain.cpp
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
32#include "SO3Renderer/SO3Root.h"
35
36#include <OgreBitwise.h>
37
38namespace SO3
39{
40
41STerrain::STerrain(SScene* parent, const std::string& resName) : SData(resName)
42{
43 // Init member pointers
44 mScene = parent;
45 mGlobals = OGRE_NEW Ogre::TerrainGlobalOptions();
46 mGlobals->setMaxPixelError(8);
47 //mGlobals->setRenderQueueGroup(Ogre::RENDER_QUEUE_WORLD_GEOMETRY_1);
48 mResourceGroup = SO3_INTERNAL_RESOURCE_GROUP + std::string("/TERRAIN/") + std::string(resName);
49 Ogre::ResourceGroupManager::getSingletonPtr()->createResourceGroup(mResourceGroup);
50
51 mGlobals->setCompositeMapDistance(2000);
52 mGlobals->setCompositeMapAmbient(parent->GetOgreScenePointer()->getAmbientLight());
53 mGlobals->setCompositeMapDiffuse(Ogre::ColourValue(1.0f, 1.0f, 1.0f, 1.0f));
54 mGlobals->setLightMapSize(256);
55 mGlobals->setCastsDynamicShadows(true);
56 Ogre::TerrainMaterialGenerator::Profile* matProfile = mGlobals->getDefaultMaterialGenerator()->getActiveProfile();
57 //matProfile->setLightmapEnabled(false);
58 //matProfile->setReceiveDynamicShadowsEnabled(enabled);
59 //matProfile->setReceiveDynamicShadowsLowLod(true);
60
61 mTerrain = OGRE_NEW Ogre::Terrain(mScene->GetOgreScenePointer());
62 mTerrain->setResourceGroup(mResourceGroup);
63}
64
65STerrain::STerrain() : SData("")
66{
67}
68
70{
71 // Forbiden (private)
72 if (mTerrain)
73 OGRE_DELETE(mTerrain);
74
75 if (mGlobals)
76 OGRE_DELETE(mGlobals);
77
78 Ogre::ResourceGroupManager::getSingletonPtr()->destroyResourceGroup(mResourceGroup);
79}
80
85
86bool STerrain::DefineHeightMap(std::string heightmap, Ogre::Real worldSize, Ogre::Real scale, Ogre::uint16 minBatchsize, Ogre::uint16 maxBatchsize)
87{
88 Ogre::Image img;
89
90 try
91 {
92 img.load(heightmap, mResourceGroup);
93 }
94 catch(Ogre::Exception &)
95 {
96 return false;
97 }
98
99 // informations géométriques
100 Ogre::Terrain::ImportData imp;
101 imp.inputImage = &img;
102 imp.terrainSize = img.getWidth();
103 imp.worldSize = worldSize;
104 imp.inputScale = scale;
105 imp.minBatchSize = minBatchsize;
106 imp.maxBatchSize = maxBatchsize;
107
108 if (mTerrain->isLoaded())
109 mTerrain->unload();
110
111 if (!(Ogre::Bitwise::isPO2(imp.terrainSize - 1) && Ogre::Bitwise::isPO2(imp.minBatchSize - 1) && Ogre::Bitwise::isPO2(imp.maxBatchSize - 1)))
112 return false;
113
114 // textures
115 imp.layerList.resize(3);
116 imp.layerList[0].worldSize = 10;
117 imp.layerList[0].textureNames.push_back("terraindef/grass_green-01_diffusespecular.dds");
118 imp.layerList[0].textureNames.push_back("terraindef/grass_green-01_normalheight.dds");
119 imp.layerList[1].worldSize = 20;
120 imp.layerList[1].textureNames.push_back("terraindef/growth_weirdfungus-03_diffusespecular.dds");
121 imp.layerList[1].textureNames.push_back("terraindef/growth_weirdfungus-03_normalheight.dds");
122 imp.layerList[2].worldSize = 100;
123 imp.layerList[2].textureNames.push_back("terraindef/dirt_grayrocky_diffusespecular.dds");
124 imp.layerList[2].textureNames.push_back("terraindef/dirt_grayrocky_normalheight.dds");
125
126 try
127 {
128 mTerrain->prepare(imp);
129 mTerrain->load();
130 }
131 catch(Ogre::Exception &)
132 {
133 return false;
134 }
135
136 // textures blend
137 Ogre::TerrainLayerBlendMap* blendMap0 = mTerrain->getLayerBlendMap(1);
138 Ogre::TerrainLayerBlendMap* blendMap1 = mTerrain->getLayerBlendMap(2);
139 Ogre::Real minHeight0 = 30;
140 Ogre::Real fadeDist0 = 20;
141 Ogre::Real minHeight1 = 25;
142 Ogre::Real fadeDist1 = 5;
143 float* pBlend0 = blendMap0->getBlendPointer();
144 float* pBlend1 = blendMap1->getBlendPointer();
145 for (Ogre::uint16 y = 0; y < mTerrain->getLayerBlendMapSize(); ++y)
146 {
147 for (Ogre::uint16 x = 0; x < mTerrain->getLayerBlendMapSize(); ++x)
148 {
149 Ogre::Real tx, ty;
150
151 blendMap0->convertImageToTerrainSpace(x, y, &tx, &ty);
152 Ogre::Real height = mTerrain->getHeightAtTerrainPosition(tx, ty);
153 Ogre::Real val = (height - minHeight0) / fadeDist0;
154 val = Ogre::Math::Clamp(val, (Ogre::Real)0, (Ogre::Real)1);
155 *pBlend0++ = val;
156
157 val = (height - minHeight1) / fadeDist1;
158 val = Ogre::Math::Clamp(val, (Ogre::Real)0, (Ogre::Real)1);
159 *pBlend1++ = val;
160 }
161 }
162 blendMap0->dirty();
163 blendMap1->dirty();
164 blendMap0->update();
165 blendMap1->update();
166
167 mTerrain->freeTemporaryResources();
168 return true;
169}
170
171void STerrain::UpdateLight(Ogre::ColourValue ambColor, Ogre::ColourValue sunColor, Ogre::Vector3 sunDir)
172{
173 mGlobals->setCompositeMapAmbient(ambColor);
174 mGlobals->setCompositeMapDiffuse(sunColor);
175 //mGlobals->setLightMapDirection(sunDir);
176 //mTerrain->dirtyLightmap();
177 //mTerrain->update();
178}
179
180}
Ogre::SceneManager * GetOgreScenePointer()
Definition SO3Scene.cpp:449
SScene * mScene
Definition SO3Terrain.h:66
Ogre::Terrain * mTerrain
Definition SO3Terrain.h:67
Ogre::TerrainGlobalOptions * mGlobals
Definition SO3Terrain.h:68
SScene * GetParentScene()
std::string mResourceGroup
Definition SO3Terrain.h:69
bool DefineHeightMap(std::string heightmap, Ogre::Real worldSize=10000.0f, Ogre::Real scale=600.0f, Ogre::uint16 minBatchsize=33, Ogre::uint16 maxBatchsize=65)
void UpdateLight(Ogre::ColourValue ambColor, Ogre::ColourValue sunColor, Ogre::Vector3 sunDir)