source: OGRE/trunk/ogrenew/PlugIns/OctreeSceneManager/src/OgreHeightmapTerrainPageSource.cpp @ 692

Revision 692, 10.3 KB checked in by mattausch, 19 years ago (diff)

adding ogre 1.2 and dependencies

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 "OgreHeightmapTerrainPageSource.h"
27#include "OgreTerrainPage.h"
28#include "OgreException.h"
29#include "OgreStringConverter.h"
30#include "OgreTerrainSceneManager.h"
31#include "OgreResourceManager.h"
32#include "OgreLogManager.h"
33
34namespace Ogre {
35
36    //-------------------------------------------------------------------------
37    HeightmapTerrainPageSource::HeightmapTerrainPageSource()
38        : mIsRaw(false), mFlipTerrain(false), mPage(0)
39    {
40    }
41    //-------------------------------------------------------------------------
42    HeightmapTerrainPageSource::~HeightmapTerrainPageSource()
43    {
44        shutdown();
45    }
46    //-------------------------------------------------------------------------
47    void HeightmapTerrainPageSource::shutdown(void)
48    {
49        // Image will destroy itself
50        delete mPage;
51        mPage = 0;
52    }
53    //-------------------------------------------------------------------------
54    void HeightmapTerrainPageSource::loadHeightmap(void)
55    {
56        size_t imgSize;
57        // Special-case RAW format
58        if (mIsRaw)
59        {
60            // Image size comes from setting (since RAW is not self-describing)
61            imgSize = mRawSize;
62           
63            // Load data
64            mRawData.setNull();
65            DataStreamPtr stream =
66                ResourceGroupManager::getSingleton().openResource(
67                    mSource, ResourceGroupManager::getSingleton().getWorldResourceGroupName());
68            mRawData = MemoryDataStreamPtr(new MemoryDataStream(mSource, stream));
69
70            // Validate size
71            size_t numBytes = imgSize * imgSize * mRawBpp;
72            if (mRawData->size() != numBytes)
73            {
74                shutdown();
75                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
76                    "RAW size (" + StringConverter::toString(mRawData->size()) +
77                    ") does not agree with configuration settings.",
78                    "HeightmapTerrainPageSource::loadHeightmap");
79            }
80        }
81        else
82        {
83            mImage.load(mSource, ResourceGroupManager::getSingleton().getWorldResourceGroupName());
84            // Must be square (dimensions checked later)
85            if ( mImage.getWidth() != mImage.getHeight())
86            {
87                shutdown();
88                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
89                    "Heightmap must be square",
90                    "HeightmapTerrainPageSource::loadHeightmap");
91            }
92            imgSize = mImage.getWidth();
93        }
94        //check to make sure it's the expected size
95        if ( imgSize != mPageSize)
96        {
97            shutdown();
98            String err = "Error: Invalid heightmap size : " +
99                StringConverter::toString( imgSize ) +
100                ". Should be " + StringConverter::toString(mPageSize);
101            OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, err,
102                "HeightmapTerrainPageSource::loadHeightmap" );
103        }
104
105    }
106    //-------------------------------------------------------------------------
107    void HeightmapTerrainPageSource::initialise(TerrainSceneManager* tsm,
108        ushort tileSize, ushort pageSize, bool asyncLoading,
109        TerrainPageSourceOptionList& optionList)
110    {
111        // Shutdown to clear any previous data
112        shutdown();
113
114        TerrainPageSource::initialise(tsm, tileSize, pageSize, asyncLoading, optionList);
115
116        // Get source image
117        TerrainPageSourceOptionList::iterator ti, tiend;
118        tiend = optionList.end();
119        bool imageFound = false;
120        mIsRaw = false;
121        bool rawSizeFound = false;
122        bool rawBppFound = false;
123        for (ti = optionList.begin(); ti != tiend; ++ti)
124        {
125            String val = ti->first;
126            StringUtil::trim(val);
127            if (StringUtil::startsWith(val, "Heightmap.image", false))
128            {
129                mSource = ti->second;
130                imageFound = true;
131                // is it a raw?
132                if (StringUtil::endsWith(mSource, "raw"))
133                {
134                    mIsRaw = true;
135                }
136            }
137            else if (StringUtil::startsWith(val, "Heightmap.raw.size", false))
138            {
139                mRawSize = atoi(ti->second.c_str());
140                rawSizeFound = true;
141            }
142            else if (StringUtil::startsWith(val, "Heightmap.raw.bpp", false))
143            {
144                mRawBpp = atoi(ti->second.c_str());
145                if (mRawBpp < 1 || mRawBpp > 2)
146                {
147                    OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
148                        "Invalid value for 'Heightmap.raw.bpp', must be 1 or 2",
149                        "HeightmapTerrainPageSource::initialise");
150                }
151                rawBppFound = true;
152            }
153            else if (StringUtil::startsWith(val, "Heightmap.flip", false))
154            {
155                mFlipTerrain = StringConverter::parseBool(ti->second);
156            }
157            else
158            {
159                LogManager::getSingleton().logMessage("Warning: ignoring unknown Heightmap option '"
160                    + val + "'");
161            }
162        }
163        if (!imageFound)
164        {
165            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
166                "Missing option 'Heightmap.image'",
167                "HeightmapTerrainPageSource::initialise");
168        }
169        if (mIsRaw &&
170            (!rawSizeFound || !rawBppFound))
171        {
172            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
173                "Options 'Heightmap.raw.size' and 'Heightmap.raw.bpp' must "
174                "be specified for RAW heightmap sources",
175                "HeightmapTerrainPageSource::initialise");
176        }
177        // Load it!
178        loadHeightmap();
179    }
180    //-------------------------------------------------------------------------
181    void HeightmapTerrainPageSource::requestPage(ushort x, ushort y)
182    {
183        // Only 1 page provided
184        if (x == 0 && y == 0 && !mPage)
185        {
186            // Convert the image data to unscaled floats
187            ulong totalPageSize = mPageSize * mPageSize;
188            Real *heightData = new Real[totalPageSize];
189            const uchar* pOrigSrc, *pSrc;
190            Real* pDest = heightData;
191            Real invScale;
192            bool is16bit = false;
193           
194            if (mIsRaw)
195            {
196                pOrigSrc = mRawData->getPtr();
197                is16bit = (mRawBpp == 2);
198            }
199            else
200            {
201                PixelFormat pf = mImage.getFormat();
202                if (pf != PF_L8 && pf != PF_L16)
203                {
204                    OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
205                        "Error: Image is not a grayscale image.",
206                        "HeightmapTerrainPageSource::requestPage" );
207                }
208
209                pOrigSrc = mImage.getData();
210                is16bit = (pf == PF_L16);
211            }
212            // Determine mapping from fixed to floating
213            ulong rowSize;
214            if ( is16bit )
215            {
216                invScale = 1.0f / 65535.0f;
217                rowSize =  mPageSize * 2;
218            }
219            else
220            {
221                invScale = 1.0f / 255.0f;
222                rowSize =  mPageSize;
223            }
224            // Read the data
225            pSrc = pOrigSrc;
226            for (ulong j = 0; j < mPageSize; ++j)
227            {
228                if (mFlipTerrain)
229                {
230                    // Work backwards
231                    pSrc = pOrigSrc + (rowSize * (mPageSize - j - 1));
232                }
233                for (ulong i = 0; i < mPageSize; ++i)
234                {
235                    if (is16bit)
236                    {
237                        #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
238                            ushort val = *pSrc++ << 8;
239                            val += *pSrc++;
240                        #else
241                            ushort val = *pSrc++;
242                            val += *pSrc++ << 8;
243                        #endif
244                        *pDest++ = Real(val) * invScale;
245                    }
246                    else
247                    {
248                        *pDest++ = Real(*pSrc++) * invScale;
249                    }
250                }
251            }
252
253            // Call listeners
254            firePageConstructed(0, 0, heightData);
255            // Now turn into TerrainPage
256            // Note that we're using a single material for now
257            if (mSceneManager)
258            {
259                mPage = buildPage(heightData,
260                    mSceneManager->getOptions().terrainMaterial);
261                mSceneManager->attachPage(0, 0, mPage);
262            }
263
264            // Free temp store
265            delete [] heightData;
266        }
267    }
268    //-------------------------------------------------------------------------
269    void HeightmapTerrainPageSource::expirePage(ushort x, ushort y)
270    {
271        // Single page
272        if (x == 0 && y == 0 && mPage)
273        {
274            delete mPage;
275            mPage = 0;
276        }
277
278    }
279    //-------------------------------------------------------------------------
280
281
282}
Note: See TracBrowser for help on using the repository browser.