00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef LILITH_MESHRESOURCE_INCLUDED
00024 #define LILITH_MESHRESOURCE_INCLUDED
00025
00026 #ifdef _MSC_VER
00027 #pragma warning ( disable : 4786 )
00028 #endif
00029
00030 #include "worlddefine.h"
00031 #include "../grinliz/glutil.h"
00032 #include "../grinliz/glgeometry.h"
00033 #include "../grinliz/glcontainer.h"
00034 #include "worlddefine.h"
00035 #include "meshgroup.h"
00036 #include "simplemesh.h"
00037 #include "genericobject.h"
00038
00039
00040 #include <string>
00041 #include <vector>
00042 #include <map>
00043 #include <list>
00044 #include <set>
00045
00046
00047 namespace lilith3d
00048 {
00049
00050 class Texture;
00051 class TreeResource;
00052 class AnimatedResource;
00053 class MD2Resource;
00054 class StaticResource;
00055 class ShadowVolumeCache;
00056
00057 class Tri
00058 {
00059 public:
00060
00061 Tri() : facingLight(0) {
00062 Init();
00063 }
00064 bool NeedShadowSide( const Tri* triArray, int side ) const {
00065 GLASSERT( side >=0 && side < 3 );
00066 GLASSERT( facingLight );
00067 if ( adjacent[side] == NO_ADJACENT || !triArray[ adjacent[side] ].facingLight )
00068 return true;
00069 return false;
00070 }
00071 void Init() {
00072 adjacent[0] = adjacent[1] = adjacent[2] = NO_ADJACENT;
00073 facingLight = 0;
00074 }
00075
00076
00077 mutable U32 facingLight;
00078 int adjacent[3];
00079 enum { NO_ADJACENT = -1 };
00080 };
00081
00082 enum
00083 {
00089 SMOOTH_SHADING = 0x01,
00090 };
00091
00092 struct PathSurface
00093 {
00094 PathSurface()
00095 {
00096 numVertex = 0;
00097 pad.hasPad = 0;
00098 for( int i=0; i<4; ++i ) {
00099 vertex[i].Set( 0.0f, 0.0f, 0.0f );
00100 neighbor[i] = 0;
00101 }
00102 index = 0;
00103 }
00104
00105
00106
00107
00108
00109
00110 unsigned numVertex;
00111 grinliz::Vector3F vertex[4];
00112 PathSurface *neighbor[4];
00113 union {
00114 U32 hasPad;
00115 U8 isPad[4];
00116 } pad;
00117 int index;
00118 };
00119
00120
00121
00122 struct PathSurfaceInstance
00123 {
00124 PathSurfaceInstance() : numVertex( 0 )
00125 {
00126 GLASSERT( !(psiMobRing.psi && psiMobRing.mob ) );
00127 psiMobRing.psi = this;
00128 pad.hasPad = 0;
00129 for( unsigned i=0; i<4; ++i )
00130 {
00131 neighbor[i] = 0;
00132 }
00133 }
00134
00135 unsigned numVertex;
00136 grinliz::Vector3F vertex[4];
00137 PathSurfaceInstance* neighbor[4];
00138
00139 union {
00140 U32 hasPad;
00141 U8 isPad[4];
00142 } pad;
00143 PSIMobRing psiMobRing;
00144
00145 void CalcEdge( unsigned i, grinliz::Vector3F* v0, grinliz::Vector3F* v1 ) const
00146 {
00147 *v0 = vertex[i];
00148 *v1 = vertex[(i+1)%numVertex];
00149 }
00150
00151 void CalcCentroid( grinliz::Vector3F* center ) const {
00152 center->Set( 0.0f, 0.0f, 0.0f );
00153 for( unsigned i=0; i<numVertex; ++i ) {
00154 center->x += vertex[i].x;
00155 center->y += vertex[i].y;
00156 center->z += vertex[i].z;
00157 }
00158 center->x /= (float)numVertex;
00159 center->y /= (float)numVertex;
00160 center->z /= (float)numVertex;
00161 }
00162
00163 private:
00164 PathSurfaceInstance( const PathSurfaceInstance& );
00165 void operator=( const PathSurfaceInstance& );
00166 };
00167
00168 typedef std::vector< PathSurfaceInstance* > PSIVector;
00169 typedef std::vector< PathSurface* > PathSurfaceVector;
00170 typedef std::list< PathSurface* > PadList;
00171 typedef std::list< PathSurface* >::iterator PadListIterator;
00172
00173 class MeshResource
00174 {
00175 public:
00180 MeshResource( const std::string& name );
00181 virtual ~MeshResource();
00182
00183
00184
00185
00186
00187
00188 const grinliz::Rectangle3F& AABB() const { return aabb; }
00189
00190 const std::string& Name() const { return name; }
00191 int TotalTri() const { return totalTri; }
00192
00197 virtual int IntersectRay( const grinliz::Vector3F& , const grinliz::Vector3F& , grinliz::Vector3F* )
00198 {
00199 return grinliz::REJECT;
00200 }
00201
00202
00203 virtual const StaticResource* ToStatic() const { return 0; }
00204 virtual const TreeResource* ToTree() const { return 0; }
00205 virtual const AnimatedResource* ToAnimated() const { return 0; }
00206 virtual const MD2Resource* ToMD2() const { return 0; }
00207
00208 protected:
00209 int totalTri;
00210 grinliz::Rectangle3F aabb;
00211
00212 private:
00213 std::string name;
00214 };
00215
00216 #ifdef _MSC_VER
00217 #pragma warning( disable : 4355 ) // this in initializer list
00218 #endif
00219
00224 class StaticResource : public MeshResource
00225 {
00226 #ifdef DEBUG
00227 friend class MeshResManager;
00228 #endif
00229 public:
00234 StaticResource( const std::string& name, int flags );
00235 virtual ~StaticResource();
00236 virtual const StaticResource* ToStatic() const { return this; }
00237
00238
00239
00240 int NumObject() const { return (int) objects.size(); }
00241
00242 void StreamOut( const Shader* shader, float alpha, ELightPass light ) const;
00243 void StreamOutVertex() const;
00244
00245 #ifdef SHADOW_VOLUME
00246 void StreamOutShadow( ShadowVolumeCache*, const grinliz::Matrix4& mat ) const;
00247 #endif
00248
00249
00253 void SetBaseMatrix( const grinliz::Matrix4& matrix );
00259 void PushObject( const char* name, const grinliz::Matrix4& matrix, const Texture* tex );
00264 void PushSurface( int numVertex, float normalX, float normalY, float normalZ );
00267 void PushVertex( float x, float y, float z, float tx, float ty );
00268
00270 void PopObject();
00272 virtual void ImportDone();
00273
00274 virtual const TreeResource* ToTreeResource() const { return 0; }
00275
00276
00277 void CalcPathingInfo( PSIVector* psi,
00278
00279 const grinliz::Vector3F& location ) const;
00280
00281
00282 void Dump();
00283 int NumVertex() const
00284 { U32 num = 0;
00285 for( unsigned i=0; i<objects.size(); ++i )
00286 num += objects[i]->NVertex();
00287 return (int)num;
00288 }
00289 int NumIndex() const
00290 { U32 num = 0;
00291 for( unsigned i=0; i<objects.size(); ++i )
00292 num += objects[i]->NIndex();
00293 return (int)num;
00294 }
00295
00296 virtual int IntersectRay( const grinliz::Vector3F& point, const grinliz::Vector3F& dir, grinliz::Vector3F* intersection ) const;
00297 int TotalTri() const { return totalTri; }
00298
00299 protected:
00300
00301
00302
00303 void PushVertexTri( float x, float y, float z, float tx, float ty );
00304 void GetCompMatrix( grinliz::Matrix4* out );
00305
00306
00307 std::vector< SimpleMesh* > objects;
00308
00309 int flags;
00310
00311 private:
00312 void StreamOutPather() const;
00313 void PushPatherSurface( grinliz::Vector3F* vertices, unsigned numVertex );
00314 bool ConnectPaths();
00315 void ConnectEdge( PathSurface* ps, int edgeIndex);
00316 void CheckForPad( PathSurface* ps );
00317
00318 void DeletePathData();
00319 void CleanPathData();
00320
00321
00322 PathSurfaceVector pathSurface;
00323
00324
00325 std::vector< grinliz::Matrix4 > matrixStack;
00326 grinliz::Vector3F currentNormal;
00327 int currentObject;
00328 int numVertexInSurface;
00329 int currentVertex;
00330 int totalTri;
00331
00332
00333
00334 grinliz::Vector3F vertexBuffer[4];
00335 grinliz::Vector2F textureXYBuffer[4];
00336
00337 PadList padList;
00338 grinliz::Rectangle2I pathBound;
00339
00340
00341 unsigned displayListId;
00342 void DumpRec( SimpleMesh*, int d );
00343 };
00344
00345
00346 typedef std::map< std::string, MeshResource* > MeshResourceMap;
00347 typedef MeshResourceMap::iterator MeshResourceMapIterator;
00348
00350 class MeshResManager
00351 {
00352 public:
00353 enum
00354 {
00355 NORMAL,
00356 TREE
00357 };
00358
00359 static MeshResManager* Instance() {
00360 return instance;
00361 }
00362 MeshResManager();
00363 ~MeshResManager();
00364
00366 void SetImportPath( const std::string& path ) { importPath = path; }
00367 const std::string& ImportPath() { return importPath; }
00368
00370 bool LoadRequiredModels();
00371
00373 StaticResource* LoadStaticRes( const std::string& filename, const std::string& name, U32 flags );
00375 MD2Resource* LoadMD2Res( const std::string& md2Filename, const std::string& name );
00377 MD2Resource* LoadMD2ResComplete( const std::string& name,
00378 const std::string& md2Tri,
00379 const std::string& skin,
00380 const std::string& md2Weapon,
00381 const std::string& weaponSkin );
00383 TreeResource* LoadTreeRes( const std::string& filename, const std::string& name,
00384 const std::string& shadowName, U32 shadowId );
00385
00386 bool IsResource( const std::string& meshName );
00387 const MeshResource* GetMeshRes( const std::string& meshName );
00388
00389 const StaticResource* GetStaticRes( const std::string& meshName )
00390 {
00391 const MeshResource* res = GetMeshRes( meshName );
00392 if ( res ) return res->ToStatic();
00393 return 0;
00394 }
00395 const AnimatedResource* GetAnimatedRes( const std::string& meshName )
00396 {
00397 const MeshResource* res = GetMeshRes( meshName );
00398 if ( res ) return res->ToAnimated();
00399 return 0;
00400 }
00401 const MD2Resource* GetMD2Res( const std::string& meshName )
00402 {
00403 const MeshResource* res = GetMeshRes( meshName );
00404 if ( res ) return res->ToMD2();
00405 return 0;
00406 }
00407
00408
00409 const TreeResource* treeResourceArray[MAX_TREE_RESOURCE];
00410 int nTreeResource;
00411
00412 protected:
00413
00414 bool Import( const std::string& filename, StaticResource* meshRes );
00415
00416 static MeshResManager* instance;
00417 MeshResourceMap resourceMap;
00418 std::string importPath;
00419 };
00420 };
00421
00422 #endif
00423
00424