source: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreBiHeightmapTerrainPageSource.cpp @ 2348

Revision 2348, 10.4 KB checked in by vizrt_christian_seidl, 18 years ago (diff)

Added: BIHierarchy SceneManager?

BITerrain SceneManager?

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25
26#include <OgreException.h>
27#include <OgreStringConverter.h>
28#include <OgreResourceManager.h>
29#include <OgreLogManager.h>
30
31#include "OgreBiHeightmapTerrainPageSource.h"
32#include "OgreBiTerrainSceneManager.h"
33#include "OgreBiTerrainPage.h"
34
35namespace Ogre {
36
37    //-------------------------------------------------------------------------
38    BiHeightmapTerrainPageSource::BiHeightmapTerrainPageSource()
39        : mIsRaw(false), mFlipTerrain(false), mPage(0)
40    {
41    }
42    //-------------------------------------------------------------------------
43    BiHeightmapTerrainPageSource::~BiHeightmapTerrainPageSource()
44    {
45        shutdown();
46    }
47    //-------------------------------------------------------------------------
48    void BiHeightmapTerrainPageSource::shutdown(void)
49    {
50        // Image will destroy itself
51        delete mPage;
52        mPage = 0;
53    }
54    //-------------------------------------------------------------------------
55    void BiHeightmapTerrainPageSource::loadHeightmap(void)
56    {
57        size_t imgSize;
58        // Special-case RAW format
59        if (mIsRaw)
60        {
61            // Image size comes from setting (since RAW is not self-describing)
62            imgSize = mRawSize;
63           
64            // Load data
65            mRawData.setNull();
66            DataStreamPtr stream =
67                ResourceGroupManager::getSingleton().openResource(
68                    mSource, ResourceGroupManager::getSingleton().getWorldResourceGroupName());
69            mRawData = MemoryDataStreamPtr(new MemoryDataStream(mSource, stream));
70
71            // Validate size
72            size_t numBytes = imgSize * imgSize * mRawBpp;
73            if (mRawData->size() != numBytes)
74            {
75                shutdown();
76                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
77                    "RAW size (" + StringConverter::toString(mRawData->size()) +
78                    ") does not agree with configuration settings.",
79                    "HeightmapTerrainPageSource::loadHeightmap");
80            }
81        }
82        else
83        {
84            mImage.load(mSource, ResourceGroupManager::getSingleton().getWorldResourceGroupName());
85            // Must be square (dimensions checked later)
86            if ( mImage.getWidth() != mImage.getHeight())
87            {
88                shutdown();
89                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
90                    "Heightmap must be square",
91                    "HeightmapTerrainPageSource::loadHeightmap");
92            }
93            imgSize = mImage.getWidth();
94        }
95        //check to make sure it's the expected size
96        if ( imgSize != mPageSize)
97        {
98            shutdown();
99            String err = "Error: Invalid heightmap size : " +
100                StringConverter::toString( imgSize ) +
101                ". Should be " + StringConverter::toString(mPageSize);
102            OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, err,
103                "HeightmapTerrainPageSource::loadHeightmap" );
104        }
105
106    }
107    //-------------------------------------------------------------------------
108    void BiHeightmapTerrainPageSource::initialise(BiTerrainSceneManager* tsm,
109                uint tileSize, uint pageSize, bool asyncLoading,
110        BiTerrainPageSourceOptionList& optionList)
111    {
112        // Shutdown to clear any previous data
113        shutdown();
114
115        BiTerrainPageSource::initialise(tsm, tileSize, pageSize, asyncLoading, optionList);
116
117        // Get source image
118        BiTerrainPageSourceOptionList::iterator ti, tiend;
119        tiend = optionList.end();
120        bool imageFound = false;
121        mIsRaw = false;
122        bool rawSizeFound = false;
123        bool rawBppFound = false;
124        for (ti = optionList.begin(); ti != tiend; ++ti)
125        {
126            String val = ti->first;
127            StringUtil::trim(val);
128            if (StringUtil::startsWith(val, "Heightmap.image", false))
129            {
130                mSource = ti->second;
131                imageFound = true;
132                // is it a raw?
133                if (StringUtil::endsWith(mSource, "raw"))
134                {
135                    mIsRaw = true;
136                }
137            }
138            else if (StringUtil::startsWith(val, "Heightmap.raw.size", false))
139            {
140                mRawSize = atoi(ti->second.c_str());
141                rawSizeFound = true;
142            }
143            else if (StringUtil::startsWith(val, "Heightmap.raw.bpp", false))
144            {
145                mRawBpp = atoi(ti->second.c_str());
146                if (mRawBpp < 1 || mRawBpp > 2)
147                {
148                    OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
149                        "Invalid value for 'Heightmap.raw.bpp', must be 1 or 2",
150                        "HeightmapTerrainPageSource::initialise");
151                }
152                rawBppFound = true;
153            }
154            else if (StringUtil::startsWith(val, "Heightmap.flip", false))
155            {
156                mFlipTerrain = StringConverter::parseBool(ti->second);
157            }
158            else
159            {
160                LogManager::getSingleton().logMessage("Warning: ignoring unknown Heightmap option '"
161                    + val + "'");
162            }
163        }
164        if (!imageFound)
165        {
166            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
167                "Missing option 'Heightmap.image'",
168                "HeightmapTerrainPageSource::initialise");
169        }
170        if (mIsRaw &&
171            (!rawSizeFound || !rawBppFound))
172        {
173            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
174                "Options 'Heightmap.raw.size' and 'Heightmap.raw.bpp' must "
175                "be specified for RAW heightmap sources",
176                "HeightmapTerrainPageSource::initialise");
177        }
178        // Load it!
179        loadHeightmap();
180    }
181    //-------------------------------------------------------------------------
182    void BiHeightmapTerrainPageSource::requestPage(ushort x, ushort y)
183    {
184        // Only 1 page provided
185        if (x == 0 && y == 0 && !mPage)
186        {
187            // Convert the image data to unscaled floats
188            ulong totalPageSize = mPageSize * mPageSize;
189            Real *heightData = new Real[totalPageSize];
190            const uchar* pOrigSrc, *pSrc;
191            Real* pDest = heightData;
192            Real invScale;
193            bool is16bit = false;
194           
195            if (mIsRaw)
196            {
197                pOrigSrc = mRawData->getPtr();
198                is16bit = (mRawBpp == 2);
199            }
200            else
201            {
202                PixelFormat pf = mImage.getFormat();
203                if (pf != PF_L8 && pf != PF_L16)
204                {
205                    OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
206                        "Error: Image is not a grayscale image.",
207                        "HeightmapTerrainPageSource::requestPage" );
208                }
209
210                pOrigSrc = mImage.getData();
211                is16bit = (pf == PF_L16);
212            }
213            // Determine mapping from fixed to floating
214            ulong rowSize;
215            if ( is16bit )
216            {
217                invScale = 1.0f / 65535.0f;
218                rowSize =  mPageSize * 2;
219            }
220            else
221            {
222                invScale = 1.0f / 255.0f;
223                rowSize =  mPageSize;
224            }
225            // Read the data
226            pSrc = pOrigSrc;
227            for (ulong j = 0; j < mPageSize; ++j)
228            {
229                if (mFlipTerrain)
230                {
231                    // Work backwards
232                    pSrc = pOrigSrc + (rowSize * (mPageSize - j - 1));
233                }
234                for (ulong i = 0; i < mPageSize; ++i)
235                {
236                    if (is16bit)
237                    {
238                        #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
239                            ushort val = *pSrc++ << 8;
240                            val += *pSrc++;
241                        #else
242                            ushort val = *pSrc++;
243                            val += *pSrc++ << 8;
244                        #endif
245                        *pDest++ = Real(val) * invScale;
246                    }
247                    else
248                    {
249                        *pDest++ = Real(*pSrc++) * invScale;
250                    }
251                }
252            }
253
254            // Call listeners
255            firePageConstructed(0, 0, heightData);
256            // Now turn into TerrainPage
257            // Note that we're using a single material for now
258            if (mSceneManager)
259            {
260                mPage = buildPage(heightData,
261                    mSceneManager->getOptions().terrainMaterial);
262                mSceneManager->attachPage(0, 0, mPage);
263            }
264
265            // Free temp store
266            delete [] heightData;
267        }
268    }
269    //-------------------------------------------------------------------------
270    void BiHeightmapTerrainPageSource::expirePage(ushort x, ushort y)
271    {
272        // Single page
273        if (x == 0 && y == 0 && mPage)
274        {
275            delete mPage;
276            mPage = 0;
277        }
278
279    }
280    //-------------------------------------------------------------------------
281
282
283}
Note: See TracBrowser for help on using the repository browser.