meshresource.h

00001 /*--License:
00002         Lilith 3D Engine
00003         Copyright Lee Thomason (Grinning Lizard Software) 2002-2007
00004         www.grinninglizard.com/lilith
00005 
00006         This program is free software; you can redistribute it and/or
00007         modify it under the terms of the GNU General Public License
00008         as published by the Free Software Foundation; either version 2
00009         of the License, or (at your option) any later version.
00010 
00011         This program is distributed in the hope that it will be useful,
00012         but WITHOUT ANY WARRANTY; without even the implied warranty of
00013         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014         GNU General Public License for more details.
00015 
00016         You should have received a copy of the GNU General Public License
00017         along with this program; if not, write to the Free Software
00018         Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020         The full text of the license can be found in license.txt
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         // FIXME: get rid of constructor
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         // Indices are inferred. Every 3 index is a tri.
00077         mutable U32 facingLight;        // working flags - set during the lighting pass
00078         int adjacent[3];                        // indices of adjacent tris.
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         //void Init( const grinliz::Vector3F* v, int num ) 
00105         //{
00106         //      numVertex = num;
00107         //      memcpy( vertex, v, sizeof( grinliz::Vector3F) * num );
00108         //}
00109 
00110         unsigned                        numVertex;              // 3 or 4 vertices
00111         grinliz::Vector3F       vertex[4];              // the vertices of the path (will be in global coordinates for meshes)
00112         PathSurface                     *neighbor[4];
00113         union {
00114                 U32 hasPad;
00115                 U8 isPad[4];
00116         } pad;
00117         int                                     index;
00118 };
00119 
00120 
00121 // used by an instance of a building to record its path
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;              // 3 or 4 vertices
00136         grinliz::Vector3F       vertex[4];              // the vertices of the path (global coordinates for meshes)
00137         PathSurfaceInstance* neighbor[4];       // the neighbor is lined up with the vertex array and the
00138                                                                                 // padVertex value.     
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 //  Note this is specifically *not* virtual. Too hard to have one consistent model.
00184 //      virtual void  StreamOut( bool useBlend, 
00185 //                                                       bool useAlphaTest, 
00186 //                                                       float testAlpha ) const = 0;
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& /*point*/, const grinliz::Vector3F& /*dir*/, grinliz::Vector3F* /*intersection*/ )
00198         {
00199                 return grinliz::REJECT;
00200         }
00201 
00202         // Sleazy RTTI
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         //bool Import( const std::string& filename );
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         // Importing
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         // Used by the instace class to get to the pathing information.
00277         void CalcPathingInfo(   PSIVector* psi,
00278                                                         //TerrainConnectorVector* tcv,
00279                                                         const grinliz::Vector3F& location ) const;
00280 
00281         // Debugging / Info
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         // The lower call of push vertex. This expects 3 vertices in a row
00301         // that define a Tri. PushVertex will "buffer" this method in order
00302         // to make quads work.
00303         void PushVertexTri( float x, float y, float z, float tx, float ty );
00304         void GetCompMatrix( grinliz::Matrix4* out );
00305 
00306         // Output
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 );    // take a look at the PS and decide if it is a pad.
00317 
00318         void DeletePathData();
00319         void CleanPathData();
00320 
00321         // Use vectors so the generation of instance paths is reasonable.
00322         PathSurfaceVector                               pathSurface;
00323 
00324         // State
00325         std::vector< grinliz::Matrix4 > matrixStack;
00326         grinliz::Vector3F                               currentNormal;
00327         int                                                             currentObject;
00328         int                                                             numVertexInSurface;
00329         int                                                             currentVertex;
00330         int                                                             totalTri;
00331 
00332         // When vertices are getting pushed, they are accumulated
00333         // before being added in order to accept either quads or tris
00334         grinliz::Vector3F vertexBuffer[4];
00335         grinliz::Vector2F textureXYBuffer[4];
00336         
00337         PadList padList;
00338         grinliz::Rectangle2I pathBound;         // PathSurfaces must be inside the building bounds else
00339                                                                                 // walkers will "jump" onto the upper floors.
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()       {       //if ( !instance ) instance = new MeshResManager();
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         // OPTIMIZATION: do not use.
00409         const TreeResource* treeResourceArray[MAX_TREE_RESOURCE];
00410         int                                     nTreeResource;
00411 
00412   protected:
00413         // Imports to 'static' and 'tree'
00414         bool Import( const std::string& filename, StaticResource* meshRes );
00415 
00416         static MeshResManager*  instance;
00417         MeshResourceMap                 resourceMap;
00418         std::string                             importPath;
00419 };
00420 };      //namespace lilith3d
00421 
00422 #endif
00423 
00424 

Generated on Fri Mar 23 19:36:22 2007 for Lilith3D by  doxygen 1.5.1-p1