00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright © 2000-2002 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 #include "OgreQuake3Level.h" 00026 #include "OgreDataChunk.h" 00027 #include "OgreLogManager.h" 00028 #include "OgreTextureManager.h" 00029 00030 namespace Ogre { 00031 00032 00033 Quake3Level::Quake3Level() 00034 { 00035 00036 } 00037 00038 void Quake3Level::loadFromChunk(DataChunk& inChunk) 00039 { 00040 mChunk = inChunk; 00041 initialise(); 00042 00043 #ifdef _DEBUG 00044 dumpContents(); 00045 #endif 00046 00047 00048 } 00049 00050 // byte swapping functions 00051 void SwapFourBytes(unsigned long *dw) 00052 { 00053 unsigned long tmp; 00054 tmp = (*dw & 0x000000FF); 00055 tmp = ((*dw & 0x0000FF00) >> 0x08) | (tmp << 0x08); 00056 tmp = ((*dw & 0x00FF0000) >> 0x10) | (tmp << 0x08); 00057 tmp = ((*dw & 0xFF000000) >> 0x18) | (tmp << 0x08); 00058 memcpy (dw, &tmp, sizeof(unsigned long)); 00059 } 00060 00061 void SwapFourBytesGrup (unsigned long *src, int size) 00062 { 00063 unsigned long *ptr = (unsigned long *)src; 00064 int i; 00065 for (i = 0; i < size/4; ++i) { 00066 SwapFourBytes (&ptr[i]); 00067 } 00068 } 00069 00070 void Quake3Level::initialise(void) 00071 { 00072 int i=0; 00073 00074 mHeader = (bsp_header_t*)mChunk.getPtr(); 00075 mLumpStart = ((unsigned char*)mHeader) + sizeof(mHeader); 00076 00077 mEntities = (unsigned char*)getLump(BSP_ENTITIES_LUMP); 00078 mNumEntities = getLumpSize(BSP_ENTITIES_LUMP); 00079 00080 mElements = (int*)getLump(BSP_ELEMENTS_LUMP); 00081 mNumElements = getLumpSize(BSP_ELEMENTS_LUMP) / sizeof(int); 00082 00083 mFaces = (bsp_face_t*)getLump(BSP_FACES_LUMP); 00084 mNumFaces = getLumpSize(BSP_FACES_LUMP) / sizeof(bsp_face_t); 00085 00086 mLeafFaces = (int*)getLump(BSP_LFACES_LUMP); 00087 mNumLeafFaces = getLumpSize(BSP_LFACES_LUMP) / sizeof(int); 00088 00089 mLeaves = (bsp_leaf_t*)getLump(BSP_LEAVES_LUMP); 00090 mNumLeaves = getLumpSize(BSP_LEAVES_LUMP) / sizeof(bsp_leaf_t); 00091 00092 mLightmaps = (unsigned char*)getLump(BSP_LIGHTMAPS_LUMP); 00093 mNumLightmaps = getLumpSize(BSP_LIGHTMAPS_LUMP)/BSP_LIGHTMAP_BANKSIZE; 00094 00095 mModels = (bsp_model_t*)getLump(BSP_MODELS_LUMP); 00096 mNumModels = getLumpSize(BSP_MODELS_LUMP) / sizeof(bsp_model_t); 00097 00098 mNodes = (bsp_node_t*)getLump(BSP_NODES_LUMP); 00099 mNumNodes = getLumpSize(BSP_NODES_LUMP) / sizeof(bsp_node_t); 00100 00101 mPlanes = (bsp_plane_t*) getLump(BSP_PLANES_LUMP); 00102 mNumPlanes = getLumpSize(BSP_PLANES_LUMP)/sizeof(bsp_plane_t); 00103 00104 mShaders = (bsp_shader_t*) getLump(BSP_SHADERS_LUMP); 00105 mNumShaders = getLumpSize(BSP_SHADERS_LUMP)/sizeof(bsp_shader_t); 00106 00107 mVis = (bsp_vis_t*)getLump(BSP_VISIBILITY_LUMP); 00108 00109 mVertices = (bsp_vertex_t*) getLump(BSP_VERTICES_LUMP); 00110 mNumVertices = getLumpSize(BSP_VERTICES_LUMP)/sizeof(bsp_vertex_t); 00111 00112 mLeafBrushes = (int*)getLump(BSP_LBRUSHES_LUMP); 00113 mNumLeafBrushes = getLumpSize(BSP_LBRUSHES_LUMP)/sizeof(int); 00114 00115 mBrushes = (bsp_brush_t*) getLump(BSP_BRUSH_LUMP); 00116 mNumBrushes = getLumpSize(BSP_BRUSH_LUMP)/sizeof(bsp_brush_t); 00117 00118 mBrushSides = (bsp_brushside_t*) getLump(BSP_BRUSHSIDES_LUMP); 00119 mNumBrushSides = getLumpSize(BSP_BRUSHSIDES_LUMP)/sizeof(bsp_brushside_t); 00120 00121 #if OGRE_PLATFORM == PLATFORM_APPLE 00122 // swap header 00123 SwapFourBytes (&mHeader->version); 00124 SwapFourBytesGrup ((unsigned long*)mElements, mNumElements*sizeof(int)); 00125 SwapFourBytesGrup ((unsigned long*)mFaces, mNumFaces*sizeof(bsp_face_t)); 00126 SwapFourBytesGrup ((unsigned long*)mLeafFaces, mNumLeafFaces*sizeof(int)); 00127 SwapFourBytesGrup ((unsigned long*)mLeaves, mNumLeaves*sizeof(bsp_leaf_t)); 00128 SwapFourBytesGrup ((unsigned long*)mModels, mNumModels*sizeof(bsp_model_t)); 00129 SwapFourBytesGrup ((unsigned long*)mNodes, mNumNodes*sizeof(bsp_node_t)); 00130 SwapFourBytesGrup ((unsigned long*)mPlanes, mNumPlanes*sizeof(bsp_plane_t)); 00131 for (i=0; i < mNumShaders; ++i) { 00132 SwapFourBytes(&mShaders[i].surface_flags); 00133 SwapFourBytes(&mShaders[i].content_flags); 00134 } 00135 SwapFourBytes(&mVis->cluster_count); 00136 SwapFourBytes(&mVis->row_size); 00137 SwapFourBytesGrup ((unsigned long*)mVertices, mNumVertices*sizeof(bsp_vertex_t)); 00138 SwapFourBytesGrup ((unsigned long*)mLeafBrushes, mNumLeafBrushes*sizeof(int)); 00139 SwapFourBytesGrup ((unsigned long*)mBrushes, mNumBrushes*sizeof(bsp_brush_t)); 00140 SwapFourBytesGrup ((unsigned long*)mBrushSides, mNumBrushSides*sizeof(bsp_brushside_t)); 00141 #endif 00142 } 00143 00144 void* Quake3Level::getLump(int lumpType) 00145 { 00146 00147 #if OGRE_PLATFORM == PLATFORM_APPLE 00148 // swap lump offset 00149 SwapFourBytes (&mHeader->lumps[lumpType].offset); 00150 #endif 00151 return (unsigned char*)mHeader + mHeader->lumps[lumpType].offset; 00152 } 00153 00154 int Quake3Level::getLumpSize(int lumpType) 00155 { 00156 00157 #if OGRE_PLATFORM == PLATFORM_APPLE 00158 // swap lump size 00159 SwapFourBytes (&mHeader->lumps[lumpType].size); 00160 #endif 00161 return mHeader->lumps[lumpType].size; 00162 } 00163 00164 void Quake3Level::dumpContents(void) 00165 { 00166 std::ofstream of; 00167 of.open("Quake3Level.log"); 00168 00169 00170 of << "Quake3 level statistics" << std::endl; 00171 of << "-----------------------" << std::endl; 00172 of << "Entities : " << mNumEntities << std::endl; 00173 of << "Faces : " << mNumFaces << std::endl; 00174 of << "Leaf Faces : " << mNumLeafFaces << std::endl; 00175 of << "Leaves : " << mNumLeaves << std::endl; 00176 of << "Lightmaps : " << mNumLightmaps << std::endl; 00177 of << "Elements : " << mNumElements << std::endl; 00178 of << "Models : " << mNumModels << std::endl; 00179 of << "Nodes : " << mNumNodes << std::endl; 00180 of << "Planes : " << mNumPlanes << std::endl; 00181 of << "Shaders : " << mNumShaders << std::endl; 00182 of << "Vertices : " << mNumVertices << std::endl; 00183 of << "Vis Clusters : " << mVis->cluster_count << std::endl; 00184 00185 of << std::endl; 00186 of << "-= Shaders =-"; 00187 of << std::endl; 00188 for (int i = 0; i < mNumShaders; ++i) 00189 { 00190 of << "Shader " << i << ": " << mShaders[i].name << std::endl; 00191 } 00192 00193 of << std::endl; 00194 of << "-= Entities =-"; 00195 of << std::endl; 00196 char* strEnt = strtok((char*)mEntities, "\0"); 00197 while (strEnt != 0) 00198 { 00199 of << strEnt << std::endl; 00200 strEnt = strtok(0, "\0"); 00201 } 00202 00203 00204 00205 00206 of.close(); 00207 } 00208 00209 void Quake3Level::extractLightmaps(void) const 00210 { 00211 // Lightmaps are always 128x128x24 (RGB) 00212 unsigned char* pLightmap = mLightmaps; 00213 for (int i = 0; i < mNumLightmaps; ++i) 00214 { 00215 char name[32]; 00216 sprintf(name, "@lightmap%d", i); 00217 00218 // Load, no mipmaps, brighten by factor 2.5 00219 Image img; img.loadRawData( DataChunk( pLightmap, 128 * 128 * 3 ), 128, 128, PF_R8G8B8 ); 00220 TextureManager::getSingleton().loadImage( name, img, TEX_TYPE_2D, 0, 4.0f ); 00221 pLightmap += BSP_LIGHTMAP_BANKSIZE; 00222 } 00223 00224 00225 } 00226 00227 00228 }
Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:40 2004