00001 #ifndef _lib_csm_h_
00002 #define _lib_csm_h_
00003
00004
00005
00006
00007
00008
00009 #pragma warning ( disable : 4786 )
00010
00011
00012
00013
00014 #include <iostream>
00015 #include <ostream>
00016 #include <istream>
00017 #include <fstream>
00018 #include <list>
00019 #include <string>
00020 #include <map>
00021 #include <deque>
00022 #include <vector>
00023 #include <algorithm>
00024 #include <functional>
00025 #include <bitset>
00026
00027
00028
00029
00030 #include <cassert>
00031 #include <sstream>
00032 #include <cmath>
00033 #include <ctime>
00034
00035
00036
00037
00038 #include <exception>
00039
00040
00041
00042
00043
00044 typedef unsigned char ubyte;
00045 typedef short int16;
00046 typedef unsigned short uint16;
00047 typedef uint16 ushort;
00048 typedef long int32;
00049 typedef unsigned int uint32;
00050 typedef uint32 ulong;
00051
00052
00053
00054
00055
00062 #define USE_PKG(x) using namespace x
00063
00069 #define USE_FROM_PKG(x,y) using x::y
00070
00075 #define USE_FROM_STD(x) USE_FROM_PKG(std,x)
00076
00081 #define BEGIN_PKG(x) namespace x{//
00082
00087 #define END_PKG(x) }
00088
00089
00090
00091
00092
00093 USE_FROM_STD(istream);
00094 USE_FROM_STD(ostream);
00095 USE_FROM_STD(ifstream);
00096 USE_FROM_STD(ofstream);
00097 USE_FROM_STD(string);
00098 USE_FROM_STD(list);
00099 USE_FROM_STD(map);
00100 USE_FROM_STD(vector);
00101 USE_FROM_STD(cout);
00102 USE_FROM_STD(cin);
00103 USE_FROM_STD(cerr);
00104 USE_FROM_STD(endl);
00105 USE_FROM_STD(bitset);
00106
00107
00108
00109 BEGIN_PKG(csm);
00110
00111
00117 typedef struct vec3_t
00118 {
00119 float x;
00120 float y;
00121 float z;
00122 }vec3_t;
00128 typedef struct vec4_t
00129 {
00130 float x;
00131 float y;
00132 float z;
00133 float w;
00134 }vec4_t;
00138 typedef vec4_t color_t;
00142 typedef vec4_t quat_t;
00143
00149 typedef struct vec2_t
00150 {
00151 float u;
00152 float v;
00153 }vec2_t;
00154
00160 class CLogger
00161 {
00162 public:
00163 CLogger(string compName): m_Name(compName)
00164 {
00165 }
00166 virtual ~CLogger()
00167 {
00168 }
00169
00170 ostream& debug() { return debug(m_Name);}
00171 ostream& mesg() { return mesg(m_Name);}
00172 ostream& warn() { return warn(m_Name);}
00173 ostream& err() { return err(m_Name);}
00174 protected:
00175 CLogger(const CLogger& logger) : m_Name(logger.m_Name)
00176 {
00177 }
00178 private:
00179 static ostream& debug(string compName);
00180 static ostream& mesg(string compName);
00181 static ostream& warn(string compName);
00182 static ostream& err(string compName);
00183
00184 string m_Name;
00185
00186 };
00187
00193 class Vec3Util
00194 {
00195 public:
00196 static float dot(vec3_t& v1,vec3_t& v2);
00197 static vec3_t& cross(vec3_t& v1,vec3_t& v2,vec3_t& result);
00198 static vec3_t& clear(vec3_t& v1,float val=0.0f);
00199 static vec3_t& scale(vec3_t& v,float factor);
00200 static vec3_t& multiply(vec3_t& v,float factor,vec3_t& result);
00201 static vec3_t& add(vec3_t& v1,vec3_t& v2,vec3_t& result);
00202 static vec3_t& subtract(vec3_t& v1,vec3_t& v2,vec3_t& result);
00203 static vec3_t& assign(vec3_t& target,vec3_t& dest);
00204 static vec3_t& normalize(vec3_t& v,vec3_t& result);
00205 static vec3_t& normalize(vec3_t& v);
00206 static float modulus(vec3_t& v);
00207 static bool equals(vec3_t& v1,vec3_t& v2);
00208 };
00209
00210
00216 template<class T> struct TypeWrapper
00217 {
00218 T val;
00219 };
00220
00221 typedef struct TypeWrapper<ubyte> WrapperByte;
00222 typedef struct TypeWrapper<int16> WrapperShort;
00223 typedef struct TypeWrapper<uint16> WrapperUShort;
00224 typedef struct TypeWrapper<int32> WrapperLong;
00225 typedef struct TypeWrapper<uint32> WrapperULong;
00226 typedef struct TypeWrapper<float> WrapperFloat;
00227 typedef struct TypeWrapper<double> WrapperDouble;
00228
00229
00235 template<class T> class PtrWrapper
00236 {
00237 public:
00238 PtrWrapper(T *t){ m_pVal = t; }
00239 virtual ~PtrWrapper(){ if(m_pVal){ delete m_pVal; m_pVal = 0; } }
00240
00241 T* getPtr(){ return m_pVal; }
00242 T* operator->(){ return getPtr(); }
00243 operator T* (){ return getPtr(); }
00244 private:
00245 PtrWrapper(const PtrWrapper& pOther){ m_pVal = pOther.m_pVal; }
00246 T *m_pVal;
00247
00248 };
00249
00255 template<class T> class ArrayWrapper
00256 {
00257 public:
00258 ArrayWrapper(T *t){ m_pVal = t; }
00259 virtual ~ArrayWrapper(){ if(m_pVal){ delete []m_pVal; m_pVal = 0; } }
00260
00261 T* getArray(){ return m_pVal; }
00262 T* operator->(){ return getArray(); }
00263 operator T* (){ return getArray(); }
00264 private:
00265 ArrayWrapper(const ArrayWrapper& pOther){ m_pVal = pOther.m_pVal; }
00266 T *m_pVal;
00267
00268 };
00269
00270
00271
00272
00273
00274
00275
00276
00277 class Chunk;
00278 class ChunkReader;
00279 class CSMFile;
00280
00281
00287 typedef struct brush_vertex_t
00288 {
00289 vec3_t pos;
00290 vec3_t normal;
00291 vec2_t texCoord;
00292 vec2_t lmapCoord;
00293
00294 }brush_vertex_t;
00298 typedef vector<brush_vertex_t> BrushVertexList;
00304 typedef struct mesh_vertex_t
00305 {
00306 vec3_t pos;
00307 vec3_t normal;
00308 vec2_t texCoord;
00309 vec2_t lmapCoord;
00310 ulong color;
00311 }mesh_vertex_t;
00315 typedef vector<mesh_vertex_t> MeshVertexList;
00321 typedef struct triangle_t
00322 {
00323 ulong vertices[3];
00324 }triangle_t;
00328 typedef vector<triangle_t> TriangleList;
00334 typedef struct chunk_header_t
00335 {
00336 char tag[4];
00337 ulong len;
00338 }chunk_header_t;
00339
00346 class PropertyTable : public map<string,string>
00347 {
00348 public:
00349 PropertyTable(){}
00350 virtual ~PropertyTable(){}
00351
00352 void load(string& str);
00353 };
00359 class BrushFace
00360 {
00361 public:
00362 BrushFace(){ resetFaceData();}
00363 virtual ~BrushFace(){ resetFaceData();}
00364
00365 void loadFaceData(ChunkReader *pChunkReader);
00366 void resetFaceData(){}
00367 private:
00368 vec3_t m_Normal;
00369 float m_PlaneDistance;
00370 string m_TextureName;
00371 ulong m_LightmapIndex;
00372
00373 vec2_t m_TexCoords;
00374 vec2_t m_TexScales;
00375 float m_UVAngle;
00376
00377 BrushVertexList m_Vertices;
00378
00379 };
00383 typedef vector<BrushFace*> FaceList;
00384
00385
00386
00393 class Chunk
00394 {
00395 public:
00396 static const char TAG_BRUSH[4];
00397 static const char TAG_MESH[4];
00398 static const char TAG_GROUP[4];
00399 static const char TAG_LMAP[4];
00400 static const char TAG_ENTITY[4];
00401 static const char TAG_DATA[4];
00402 static const char TAG_UNKNOWN[4];
00403
00404 typedef enum
00405 {
00406 TT_BRUSH=0,
00407 TT_MESH,
00408 TT_GROUP,
00409 TT_LMAP,
00410 TT_ENTITY,
00411 TT_DATA,
00412 TT_UNKNOWN
00413 }TAG_TYPE;
00414 static TAG_TYPE getTagType(char tag[4]);
00415 static string getFullTagName(TAG_TYPE t);
00416 static const char* getTagStr(TAG_TYPE t);
00417
00418
00419 TAG_TYPE getType();
00420 ulong getSize();
00421
00422 virtual void loadChunkData(ChunkReader *pChunkReader);
00423 virtual void resetChunkData();
00424
00425 static Chunk* newChunk(chunk_header_t& hdr);
00426 static void deleteChunk(Chunk* pChunk);
00427
00428
00429
00430 protected:
00431 Chunk(TAG_TYPE t);
00432 Chunk(const Chunk& chunk);
00433 virtual ~Chunk();
00434 void setHeader(chunk_header_t& hdr);
00435 chunk_header_t m_Header;
00436 TAG_TYPE m_Type;
00437
00438 };
00442 typedef vector<Chunk *> ChunkList;
00443
00449 class ChunkReader
00450 {
00451 public:
00452 ChunkReader();
00453 virtual ~ChunkReader();
00454 void loadFile(string fileName,CSMFile& file);
00455 bool ok();
00456 void reset();
00457
00458
00459 void readBuffer(void *buf,ulong len);
00460 ubyte readByte();
00461 ulong readULong();
00462 long readLong();
00463
00464 ushort readUShort();
00465 short readShort();
00466
00467 float readFloat();
00468 double readDouble();
00469
00470 string readString();
00471
00472 void loadVector3(vec3_t& vec);
00473 void loadVector2(vec2_t& vec);
00474
00475 private:
00476 Chunk* nextChunk();
00477
00478 private:
00479 CSMFile *m_pFile;
00480 ifstream *m_pStream;
00481 static CLogger m_Log;
00482 };
00483
00484
00489 class ChunkBrush : public Chunk
00490 {
00491 public:
00492 ChunkBrush();
00493 virtual ~ChunkBrush();
00494
00495 void loadChunkData(ChunkReader *pChunkReader);
00496 void resetChunkData();
00497
00498 ulong& flags(){ return m_Flags; }
00499 ulong& color(){ return m_Color; }
00500 ulong& groupID(){ return m_GroupID; }
00501 PropertyTable& properties(){ return m_Props; }
00502
00503 ulong faceCount(){ return m_Faces.size(); }
00504 BrushFace* faceAt(ulong i){ return m_Faces[i]; }
00505 private:
00506
00507 ulong m_Flags;
00508 ulong m_Color;
00509 ulong m_GroupID;
00510 PropertyTable m_Props;
00511 FaceList m_Faces;
00512 };
00513
00518 class ChunkMesh : public Chunk
00519 {
00520 public:
00521 ChunkMesh();
00522 virtual ~ChunkMesh();
00523 void loadChunkData(ChunkReader *pChunkReader);
00524 void resetChunkData();
00525 ulong& flags(){ return m_Flags; }
00526 ulong& color(){ return m_Color; }
00527 ulong& groupID(){ return m_GroupID; }
00528 PropertyTable& properties(){ return m_Props; }
00529 string& textureName(){ return m_TextureName; }
00530
00531 ulong vertexCount(){ return m_Vertices.size(); }
00532 mesh_vertex_t& vertexAt(ulong i){ return m_Vertices[i]; }
00533
00534 ulong triangleCount(){ return m_Triangles.size(); }
00535 triangle_t& triangleAt(ulong i){ return m_Triangles[i]; }
00536
00537
00538 private:
00539 ulong m_Flags;
00540 ulong m_Color;
00541 ulong m_GroupID;
00542 PropertyTable m_Props;
00543 string m_TextureName;
00544 MeshVertexList m_Vertices;
00545 TriangleList m_Triangles;
00546 };
00547
00552 class ChunkGroup : public Chunk
00553 {
00554 public:
00555 ChunkGroup();
00556 virtual ~ChunkGroup();
00557 void loadChunkData(ChunkReader *pChunkReader);
00558 void resetChunkData();
00559 ulong& groupID(){ return m_GroupID; }
00560 ulong& red(){ return m_Color[0]; }
00561 ulong& green(){ return m_Color[1]; }
00562 ulong& blue(){ return m_Color[2]; }
00563 ulong* color(){ return m_Color; }
00564
00565 private:
00566 ulong m_GroupID;
00567 ulong m_Color[3];
00568 };
00573 class ChunkData: public Chunk
00574 {
00575 public:
00576 ChunkData();
00577 virtual ~ChunkData();
00578 void loadChunkData(ChunkReader *pChunkReader);
00579 void resetChunkData();
00580 vec3_t& cameraPosition(){ return m_CameraPos; }
00581 float& cameraPitch(){ return m_CameraPitch; }
00582 float& cameraYaw(){ return m_CameraYaw; }
00583
00584 ulong& ambientColor(){ return m_AmbientColor; }
00585 private:
00586 vec3_t m_CameraPos;
00587 float m_CameraPitch;
00588 float m_CameraYaw;
00589 ulong m_AmbientColor;
00590 };
00595 class ChunkEntity: public Chunk
00596 {
00597 public:
00598 ChunkEntity();
00599 virtual ~ChunkEntity();
00600 void loadChunkData(ChunkReader *pChunkReader);
00601 void resetChunkData();
00602 ulong& flags(){ return m_Flags; }
00603 vec3_t& position(){ return m_Pos; }
00604 PropertyTable& properties(){ return m_Props; }
00605 ulong& red(){ return m_Color[0]; }
00606 ulong& green(){ return m_Color[1]; }
00607 ulong& blue(){ return m_Color[2]; }
00608 ulong* color(){ return m_Color; }
00609 ulong& width(){ return m_Width; }
00610 ulong& height(){ return m_Height; }
00611
00612 private:
00613 ulong m_Flags;
00614 vec3_t m_Pos;
00615 PropertyTable m_Props;
00616 ulong m_GroupID;
00617 ulong m_Color[3];
00618 ulong m_Width;
00619 ulong m_Height;
00620
00621 };
00626 class ChunkLMap : public Chunk
00627 {
00628 public:
00629 ChunkLMap();
00630 virtual ~ChunkLMap();
00631 void loadChunkData(ChunkReader *pChunkReader);
00632 void resetChunkData();
00633 ulong& width(){ return m_Width; }
00634 ulong& height(){ return m_Height; }
00635
00636 ulong index(ulong x,ulong y){ return ((y * m_Width + x) * 4); }
00637 ubyte* pixelData() { return m_Pixels; }
00638 private:
00639 ulong m_Width;
00640 ulong m_Height;
00641 ubyte *m_Pixels;
00642 };
00643
00644
00645 class CSMFile
00646 {
00647 friend class ChunkReader;
00648 public:
00649
00650 static const ulong MAX_STR_LEN;
00651 CSMFile();
00652 virtual ~CSMFile();
00653
00654 void reset();
00655
00656 ulong getBrushCount();
00657 ChunkBrush* brushAt(ulong index);
00658
00659 ulong getMeshCount();
00660 ChunkMesh* meshAt(ulong index);
00661
00662 ulong getGroupCount();
00663 ChunkGroup* groupAt(ulong index);
00664
00665 ulong getDataCount();
00666 ChunkData* dataAt(ulong index);
00667
00668 ulong getLMapCount();
00669 ChunkLMap* lmapAt(ulong index);
00670
00671 ulong getEntityCount();
00672 ChunkEntity* entityAt(ulong index);
00673
00674
00675
00676
00677
00678
00679 void addChunk(Chunk *pChunk);
00680 private:
00681 void clearChunkList(ChunkList& lis);
00682
00683 ChunkList m_Brushes;
00684 ChunkList m_Meshes;
00685 ChunkList m_Entities;
00686 ChunkList m_Data;
00687 ChunkList m_LMaps;
00688 ChunkList m_Groups;
00689
00690 };
00691
00692
00693
00694 END_PKG(csm);
00695
00696 inline csm::vec3_t& operator +=(csm::vec3_t& v1,csm::vec3_t& v2)
00697 {
00698 return csm::Vec3Util::add(v1,v2,v1);
00699 }
00700 inline csm::vec3_t& operator -=(csm::vec3_t& v1,csm::vec3_t& v2)
00701 {
00702 return csm::Vec3Util::subtract(v1,v2,v1);
00703 }
00704
00705 inline csm::vec3_t& operator *=(csm::vec3_t& v1,csm::vec3_t& v2)
00706 {
00707 return csm::Vec3Util::cross(v1,v2,v1);
00708 }
00709 inline csm::vec3_t& operator *=(csm::vec3_t& v,float x)
00710 {
00711 return csm::Vec3Util::scale(v,x);
00712 }
00713
00714 inline bool operator ==(csm::vec3_t& v1,csm::vec3_t& v2)
00715 {
00716 return csm::Vec3Util::equals(v1,v2);
00717 }
00718 inline bool operator !=(csm::vec3_t& v1,csm::vec3_t& v2)
00719 {
00720 return !(v1 == v2);
00721 }
00722 inline ostream& operator <<(ostream& os,csm::vec3_t& v)
00723 {
00724 os<<"[ "<<v.x<<" "<<v.y<<" "<<v.z<<" ]";
00725 return os;
00726
00727 }
00728
00729
00730
00731
00732
00733 #endif