lilith3d.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 LILITH3D_INCLUDED
00024 #define LILITH3D_INCLUDED
00025 
00100 #ifdef _MSC_VER
00101 #pragma warning( disable : 4786 )       // Debugger truncating names.
00102 #pragma warning( disable : 4530 )       // Exception handler isn't used
00103 #endif
00104 
00105 #include "terrainmesh.h"
00106 #include "worlddefine.h"
00107 #include "lilith3dgl.h"
00108 #include "terraindecor.h"
00109 #include "quadtree.h"
00110 #include "mob.h"
00111 #include "weather.h"
00112 #include "camera.h"
00113 #include "texture.h"
00114 #include "meshresource.h"
00115 #include "timeclock.h"
00116 #include "particle.h"
00117 #include "light.h"
00118 #include "terrainmorph.h"
00119 #include "shadowvolumecache.h"
00120 #include "building.h"
00121 
00122 #include <list>
00123 #include <vector>
00124 
00125 namespace lilith3d
00126 {
00127 
00128 class TerrainMorph;
00129 class ParticleSystem;
00130 class PointLight;
00131 class TerrainDecor;
00132 class QuadTree;
00133 class GravParticles;
00134 class RainDropParticles;
00135 class RainSplashParticles;
00136 class ISequence;
00137 class Camera;
00138 class Mesh;
00139 
00140 typedef std::list< ISequence* >                 SequenceList;
00141 typedef SequenceList::iterator                  SequenceListIterator;
00142 typedef std::vector< ParticleSystem* >  ParticleSystemVector;
00143 typedef std::vector< MeshGroup* >               MeshGroupVector;
00144 
00145 
00146 const int LilithVersionMajor = 2;
00147 const int LilithVersionMinor = 0;
00148 const int LilithVersionPatch = 0;
00149 
00150 enum
00151 {
00152         // Ordering depends on the Lilith Engine culling code. Don't change!
00153         L3_LEFT_PLANE,
00154         L3_RIGHT_PLANE,
00155         L3_BOTTOM_PLANE,
00156         L3_TOP_PLANE,
00157         L3_NEAR_PLANE,
00158         L3_FAR_PLANE,
00159 };
00160 
00161 
00165 class IMapDraw
00166 {
00167 public:
00168         virtual void DrawToMap() = 0;
00169 };
00170 
00171 
00180 class Lilith3D
00181 {
00182   public:
00189         Lilith3D( U32 msecPerDay = DEFAULT_MSEC_PER_DAY, U32 msecStart = DEFUALT_MSEC_DAY_START );
00190         virtual ~Lilith3D();
00191 
00213         virtual void BeginDraw();
00214         virtual void Draw();
00215         virtual void EndDraw();
00216 
00218         static Lilith3D* Instance()             { return instance; }
00231         static SDL_Surface* SetSDLVideoMode( int width, int height, int multisample, bool fullscreen );
00232 
00233         static TerrainMesh*  GetTerrainMesh()   { return Instance() ? Instance()->terrainMesh : 0; }    
00234         static TerrainDecor* GetTerrainDecor()  { return Instance() ? Instance()->terrainDecor : 0; }   
00235         static TimeClock*        GetTimeClock()         { return Instance() ? &Instance()->timeClock : 0; }     
00236 
00243         void AddSequence( ISequence* orphanSequence );
00244         
00245         // [internal] Add a mobile object to lilith - managed by the Mob Object.
00246         void AddMob( Mob* mob )                                                 { mobGroup.Add( mob ); }
00247         // [internal] Remove a mobile object - managed by the Mob Object.
00248         void RemoveMob( Mob* mob )                                              { mobGroup.Remove( mob ); }
00249 
00251         QuadTree*                       GetQuadTree()                                   { return quadTree; }
00252 
00253         // --- Weather --- //
00255         Weather*                GetTargetWeather()      { return &targetWeather; }
00257         const Weather&  CurrentWeather()        { return weather; }
00258 
00259 
00260         // ------ Rendering options ------- //
00261         enum {
00262                 // Rendering modes.
00263                 RENDER_FLAT = 0,
00264                 RENDER_LOD,
00265                 RENDER_PATH,
00266                 RENDER_COUNT,
00267         };      
00274         void SetRenderMode( int r );
00275         int  RenderMode()                                               { return renderMode; }                  
00276         void SetRenderFoliage( bool foliage )   { renderFoliage = foliage; }    
00277         bool RenderFoliage()                                    { return renderFoliage; }               
00278         void SetRenderShadows( bool shadows )   { renderShadows = shadows; }    
00279         bool RenderShadows()                                    { return renderShadows; }               
00280         void SetPerfDataDisplay( bool perfData) { displayPerfData = perfData; } 
00281         bool PerfDataDisplay()                                  { return displayPerfData; }             
00282 
00285         void SetMapSize( float size )   { targetMapSize = grinliz::Clamp( size, 0.0f, 1.0f ); }
00286         float MapSize()                                 { return targetMapSize; }
00287         void AddMapDrawer( IMapDraw* draw )             { mapDrawerSet.insert( draw ); }
00288         void RemoveMapDrawer( IMapDraw* draw )  { mapDrawerSet.erase( draw ); }
00289 
00290         enum {
00291                 INFO_VERSION = 0x01,    
00292                 INFO_TIME = 0x02,               
00293                 INFO_INTERSECT = 0x04,  
00294                 INFO_MINIMAP = 0x08,    
00295 
00296                 INFO_DEFAULT = INFO_VERSION | INFO_TIME | INFO_INTERSECT | INFO_MINIMAP
00297         };
00302         void SetInfoDisplay( int flags )        { infoDisplay = flags; }
00303 
00308         void ScreenCapture( const char* baseFilename );
00309         
00310         // --- Selection and picking --- //
00315         void IntersectRayFromScreen( int x, int y, int flags, LilithObjectList* vec );
00316 
00320         int IntersectMapFromScreen( int x, int y, grinliz::Vector3F* vertex );
00321 
00325         void IntersectRay( const grinliz::Ray& ray, int flags, LilithObjectList* vec );
00326 
00331         void RegisterParticleSystem( ParticleSystem* system );
00333         ParticleSystem* FindParticleSystem( const char* name );
00335         GravParticles* GetGravParticles()       { return gravityParticles; }
00336 
00338         Camera* GetCamera()     { return &camera; }
00339 
00340         // --- Internal --- //
00341         // Mesh's react to lights in different ways. So they have to walk the
00342         // light list itself and decide what to do with it. Nothing should
00343         // change this list...and it should be const. But that's a pain.
00344         grinliz::InnerCircle<PointLight>* PointLights() { return &pointLightSentinel; }
00345 
00346         // Only valid *after* DoCulling has been called, through the rendering pass.
00347         const grinliz::Plane& CullingPlane( int i )     {       GLASSERT( i >= L3_LEFT_PLANE && i <= L3_FAR_PLANE );
00348                                                                                                         return cullingPlane[i];
00349                                                                                                 }
00350                                 
00355         bool InFrustum( const grinliz::Rectangle3F& aabb );
00356 
00363         int IntersectFrustum( const grinliz::Rectangle3F& aabb );
00364 
00366         static void CreateOpenGLToLilith( grinliz::Matrix4* matrix );
00367 
00368         #ifdef SHADOW_VOLUME
00369         float ShadowFade() { return shadowFade; }
00370         #endif
00371 
00372         // Bounds check for shadows.
00373         static inline bool CheckShadowInBounds( const grinliz::Vector3F& eye,
00374                                                                                         const grinliz::Vector3F& dir,
00375                                                                                         const grinliz::Rectangle2F& shadow,
00376                                                                                         const grinliz::Rectangle3F& aabb )
00377 
00378         {
00379                 // Presumably we can see the shadow, so look for the corner opposite the
00380                 // direction of the eye. If we are in the shadow, hopefully any corner
00381                 // is close enough
00382                 grinliz::Rectangle3F bounds = aabb;
00383                 bounds.min.x += shadow.min.x;           // take advantage that all lilith shadows are from the sun.
00384                 bounds.max.x += shadow.max.x;
00385 
00386                 grinliz::Vector3F close;
00387                 close.x = ( dir.x > 0.0f ) ? bounds.min.x : bounds.max.x;
00388                 close.y = ( dir.y > 0.0f ) ? bounds.min.y : bounds.max.y;
00389                 close.z = ( dir.z > 0.0f ) ? bounds.min.z : bounds.max.z;
00390 
00391                 float dsquared =   (eye.x-close.x) * (eye.x-close.x)
00392                                                  + (eye.y-close.y) * (eye.y-close.y)
00393                                                  + (eye.z-close.z) * (eye.z-close.z);
00394 
00395                 if ( dsquared < SHADOW_END_FADE_SQUARED )
00396                         return true;
00397                 return false;
00398         }
00399                                                                                         
00401         Mesh* GetMesh( int id ) {       GLASSERT( id >= 0 );
00402                                                                 return meshPool.Get( (U32)id ); }
00403         // [internal]
00404         grinliz::MapId< Mesh* > meshPool;
00405 
00406   private:
00407         static Lilith3D* instance;
00408         TimeClock timeClock;
00409 
00410         void InitShadows();
00411 
00412         #ifdef SHADOW_VOLUME
00413         void DrawShadowVolumes();
00414         void StreamShadowList( Mesh* root, const grinliz::Rectangle2F& shadow );
00415 
00416         ShadowVolumeCache shadowVolumeCache;
00417         float shadowFade;
00418         #endif
00419 
00420         enum { LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR };
00421         void CalcCullingPlanes();       // normally called by "DoCulling" but also called by the shadow code.
00422         void DoCulling();
00423         void AdjustWeather();
00424         void GetMapInfo( grinliz::Vector2F* translation, grinliz::Vector2F* scale );
00425 
00426         Camera                                  camera;
00427 
00428         int                                             surfaceWidth, surfaceHeight;    // actual screen size
00429         GLuint                                  shadowId;
00430         GLuint                                  frameBufferObject;
00431         grinliz::Matrix4                worldToLight;
00432 
00433         int                                             renderMode;
00434         bool                                    renderFoliage;
00435         //bool                                  renderFromLight;
00436         bool                                    renderShadows;          // Set true if we want to render shadows
00437         float                                   sunCircle;                      // The radius that that the sun takes through the sky.
00438                                                                                                 // The view distance is double this.
00439 
00440         TerrainMesh*                    terrainMesh;
00441         TerrainDecor*                   terrainDecor;
00442         QuadTree*                               quadTree;
00443 
00444         SequenceList                    sequenceList;           // owned: clean up memory
00445         ParticleSystemVector    particleSystems;        // owned: clean up particle memory
00446         grinliz::InnerCircle<PointLight>        pointLightSentinel;
00447 
00448         // Not owned: just a reference! Collection
00449         // of all the above items.
00450         MeshGroupVector         meshSystems;            // includes terrain, particle, objects. Pointer to, not owned.
00451         MobGroup                        mobGroup;
00452 
00453         U32             sequenceStart;
00454         int             sequenceLength;
00455 
00456         enum
00457         {
00458                 // left, right, bottom, top, near, far
00459                 NUM_CULLING = 6,
00460         };
00461         grinliz::Plane          cullingPlane[ NUM_CULLING ];
00462 
00463         Weather weather, targetWeather;
00464 
00465         GravParticles*          gravityParticles;
00466         RainDropParticles*      rainDropParticles;
00467         RainSplashParticles*    rainSplashParticles;
00468 
00469         bool displayPerfData;
00470         int infoDisplay;
00471         float targetMapSize;
00472         float mapSize;
00473 
00474         std::set< IMapDraw* > mapDrawerSet;
00475 };
00476 };      // namespace lilith3d
00477 
00478 #endif

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