Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/PlugIns/BSPSceneManager/src/OgreQuake3Level.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 10.3 KB
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-2006 Torus Knot Software Ltd
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
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreQuake3Level.h"
30#include "OgreLogManager.h"
31#include "OgreTextureManager.h"
32
33namespace Ogre {
34
35    //-----------------------------------------------------------------------
36    Quake3Level::Quake3Level()
37    {
38
39    }
40    //-----------------------------------------------------------------------
41    void Quake3Level::loadHeaderFromStream(DataStreamPtr& inStream)
42    {
43        // Load just the header
44        bsp_header_t* pHeader =  new bsp_header_t();
45        inStream->read(pHeader, sizeof(bsp_header_t));
46        mChunk = MemoryDataStreamPtr(
47            new MemoryDataStream(pHeader, sizeof(bsp_header_t), false));
48        // Grab all the counts, header only
49        initialise(true);
50                // Delete manually since delete and delete[] (as used by MemoryDataStream)
51                // are not compatible
52                delete pHeader;
53
54    }
55    //-----------------------------------------------------------------------
56    void Quake3Level::loadFromStream(DataStreamPtr& stream)
57    {
58        mChunk = MemoryDataStreamPtr(new MemoryDataStream(stream));
59        initialise();
60
61#ifdef _DEBUG
62        dumpContents();
63#endif
64
65
66    }
67    //-----------------------------------------------------------------------
68   // byte swapping functions
69   void SwapFourBytes(uint32* dw)
70   {
71      uint32 tmp;
72      tmp =  (*dw & 0x000000FF);
73      tmp = ((*dw & 0x0000FF00) >> 0x08) | (tmp << 0x08);
74      tmp = ((*dw & 0x00FF0000) >> 0x10) | (tmp << 0x08);
75      tmp = ((*dw & 0xFF000000) >> 0x18) | (tmp << 0x08);
76      memcpy (dw, &tmp, sizeof(uint32));
77   }
78   //-----------------------------------------------------------------------
79   void SwapFourBytesGrup (uint32* src, int size)
80   {
81      uint32* ptr = (uint32*)src;
82      int i;
83      for (i = 0; i < size/4; ++i) {
84         SwapFourBytes (&ptr[i]);
85      }
86   }
87   //-----------------------------------------------------------------------
88    void Quake3Level::initialise(bool headerOnly)
89    {
90        mHeader = (bsp_header_t*)mChunk->getPtr();
91
92        // Header counts
93        initialiseCounts();
94        // Data pointers
95        if (headerOnly)
96        {
97            mLumpStart = 0;
98        }
99        else
100        {
101            mLumpStart = ((unsigned char*)mHeader) + sizeof(mHeader);
102                        initialisePointers();
103        }
104
105
106#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
107                // swap header
108        SwapFourBytes ((uint32*)&mHeader->version);
109#endif
110    }
111    //-----------------------------------------------------------------------
112    void Quake3Level::initialiseCounts(void)
113    {
114        mNumEntities = getLumpSize(BSP_ENTITIES_LUMP);
115        mNumElements = getLumpSize(BSP_ELEMENTS_LUMP) / sizeof(int);
116        mNumFaces = getLumpSize(BSP_FACES_LUMP) / sizeof(bsp_face_t);
117        mNumLeafFaces = getLumpSize(BSP_LFACES_LUMP) / sizeof(int);
118        mNumLeaves = getLumpSize(BSP_LEAVES_LUMP) / sizeof(bsp_leaf_t);
119        mNumLightmaps = getLumpSize(BSP_LIGHTMAPS_LUMP)/BSP_LIGHTMAP_BANKSIZE;
120        mNumModels = getLumpSize(BSP_MODELS_LUMP) / sizeof(bsp_model_t);
121        mNumNodes = getLumpSize(BSP_NODES_LUMP) / sizeof(bsp_node_t);
122        mNumPlanes = getLumpSize(BSP_PLANES_LUMP)/sizeof(bsp_plane_t);
123        mNumShaders = getLumpSize(BSP_SHADERS_LUMP)/sizeof(bsp_shader_t);
124        mNumVertices = getLumpSize(BSP_VERTICES_LUMP)/sizeof(bsp_vertex_t);
125        mNumLeafBrushes = getLumpSize(BSP_LBRUSHES_LUMP)/sizeof(int);
126        mNumBrushes = getLumpSize(BSP_BRUSH_LUMP)/sizeof(bsp_brush_t);
127        mNumBrushSides = getLumpSize(BSP_BRUSHSIDES_LUMP)/sizeof(bsp_brushside_t);
128    }
129    //-----------------------------------------------------------------------
130    void Quake3Level::initialisePointers(void)
131    {
132        mEntities = (unsigned char*)getLump(BSP_ENTITIES_LUMP);
133        mElements = (int*)getLump(BSP_ELEMENTS_LUMP);
134        mFaces = (bsp_face_t*)getLump(BSP_FACES_LUMP);
135        mLeafFaces = (int*)getLump(BSP_LFACES_LUMP);
136        mLeaves = (bsp_leaf_t*)getLump(BSP_LEAVES_LUMP);
137        mLightmaps = (unsigned char*)getLump(BSP_LIGHTMAPS_LUMP);
138        mModels = (bsp_model_t*)getLump(BSP_MODELS_LUMP);
139        mNodes = (bsp_node_t*)getLump(BSP_NODES_LUMP);
140        mPlanes = (bsp_plane_t*) getLump(BSP_PLANES_LUMP);
141        mShaders = (bsp_shader_t*) getLump(BSP_SHADERS_LUMP);
142        mVis = (bsp_vis_t*)getLump(BSP_VISIBILITY_LUMP);
143        mVertices = (bsp_vertex_t*) getLump(BSP_VERTICES_LUMP);
144        mLeafBrushes = (int*)getLump(BSP_LBRUSHES_LUMP);
145        mBrushes = (bsp_brush_t*) getLump(BSP_BRUSH_LUMP);
146        mBrushSides = (bsp_brushside_t*) getLump(BSP_BRUSHSIDES_LUMP);
147#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
148        SwapFourBytesGrup ((uint32*)mElements, mNumElements*sizeof(int));
149        SwapFourBytesGrup ((uint32*)mFaces, mNumFaces*sizeof(bsp_face_t));
150        SwapFourBytesGrup ((uint32*)mLeafFaces, mNumLeafFaces*sizeof(int));
151        SwapFourBytesGrup ((uint32*)mLeaves, mNumLeaves*sizeof(bsp_leaf_t));
152        SwapFourBytesGrup ((uint32*)mModels, mNumModels*sizeof(bsp_model_t));
153        SwapFourBytesGrup ((uint32*)mNodes, mNumNodes*sizeof(bsp_node_t));
154        SwapFourBytesGrup ((uint32*)mPlanes, mNumPlanes*sizeof(bsp_plane_t));
155        for (int i=0; i < mNumShaders; ++i) {
156            SwapFourBytes((uint32*)&mShaders[i].surface_flags);
157            SwapFourBytes((uint32*)&mShaders[i].content_flags);
158        }   
159        SwapFourBytes((uint32*)&mVis->cluster_count);
160        SwapFourBytes((uint32*)&mVis->row_size);
161        SwapFourBytesGrup ((uint32*)mVertices, mNumVertices*sizeof(bsp_vertex_t));
162        SwapFourBytesGrup ((uint32*)mLeafBrushes, mNumLeafBrushes*sizeof(int));
163        SwapFourBytesGrup ((uint32*)mBrushes,  mNumBrushes*sizeof(bsp_brush_t));
164        SwapFourBytesGrup ((uint32*)mBrushSides, mNumBrushSides*sizeof(bsp_brushside_t));
165#endif
166    }
167    //-----------------------------------------------------------------------
168    void* Quake3Level::getLump(int lumpType)
169    {
170        if (mLumpStart)
171        {
172       
173#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
174            // swap lump offset
175            SwapFourBytes ((uint32*)&mHeader->lumps[lumpType].offset);
176#endif
177            return (unsigned char*)mHeader + mHeader->lumps[lumpType].offset;
178        }
179        else
180        {
181            return 0;
182        }
183    }
184    //-----------------------------------------------------------------------
185    int Quake3Level::getLumpSize(int lumpType)
186    {
187
188#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
189        // swap lump size
190        SwapFourBytes ((uint32*)&mHeader->lumps[lumpType].size);
191#endif
192        return mHeader->lumps[lumpType].size;
193    }
194    //-----------------------------------------------------------------------
195    void Quake3Level::dumpContents(void)
196    {
197        std::ofstream of;
198        of.open("Quake3Level.log");
199
200
201        of << "Quake3 level statistics" << std::endl;
202        of << "-----------------------" << std::endl;
203        of << "Entities     : " << mNumEntities << std::endl;
204        of << "Faces        : " << mNumFaces << std::endl;
205        of << "Leaf Faces   : " << mNumLeafFaces << std::endl;
206        of << "Leaves       : " << mNumLeaves << std::endl;
207        of << "Lightmaps    : " << mNumLightmaps << std::endl;
208        of << "Elements     : " << mNumElements << std::endl;
209        of << "Models       : " << mNumModels << std::endl;
210        of << "Nodes        : " << mNumNodes << std::endl;
211        of << "Planes       : " << mNumPlanes << std::endl;
212        of << "Shaders      : " << mNumShaders << std::endl;
213        of << "Vertices     : " << mNumVertices << std::endl;
214        of << "Vis Clusters : " << mVis->cluster_count << std::endl;
215
216        of << std::endl;
217        of << "-= Shaders =-";
218        of << std::endl;
219        for (int i = 0; i < mNumShaders; ++i)
220        {
221            of << "Shader " << i << ": " << mShaders[i].name << std::endl;
222        }
223
224        of << std::endl;
225        of << "-= Entities =-";
226        of << std::endl;
227        char* strEnt = strtok((char*)mEntities, "\0");
228        while (strEnt != 0)
229        {
230            of << strEnt << std::endl;
231            strEnt = strtok(0, "\0");
232        }
233
234
235
236
237        of.close();
238    }
239    //-----------------------------------------------------------------------
240    void Quake3Level::extractLightmaps(void) const
241    {
242        // Lightmaps are always 128x128x24 (RGB)
243        unsigned char* pLightmap = mLightmaps;
244        for (int i = 0; i < mNumLightmaps; ++i)
245        {
246                        StringUtil::StrStreamType name;
247            name << "@lightmap" << i;
248
249            // Load, no mipmaps, brighten by factor 2.5
250                        DataStreamPtr stream(new MemoryDataStream(pLightmap, 128 * 128 * 3, false));
251            Image img; 
252                        img.loadRawData( stream, 128, 128, PF_BYTE_RGB );
253            TextureManager::getSingleton().loadImage( name.str(), 
254                                ResourceGroupManager::getSingleton().getWorldResourceGroupName(), img, TEX_TYPE_2D, 0, 4.0f );
255            pLightmap += BSP_LIGHTMAP_BANKSIZE;
256        }
257
258
259    }
260    //-----------------------------------------------------------------------
261
262
263}
Note: See TracBrowser for help on using the repository browser.