00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
00246 void AddMob( Mob* mob ) { mobGroup.Add( mob ); }
00247
00248 void RemoveMob( Mob* mob ) { mobGroup.Remove( mob ); }
00249
00251 QuadTree* GetQuadTree() { return quadTree; }
00252
00253
00255 Weather* GetTargetWeather() { return &targetWeather; }
00257 const Weather& CurrentWeather() { return weather; }
00258
00259
00260
00261 enum {
00262
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
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
00341
00342
00343
00344 grinliz::InnerCircle<PointLight>* PointLights() { return &pointLightSentinel; }
00345
00346
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
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
00380
00381
00382 grinliz::Rectangle3F bounds = aabb;
00383 bounds.min.x += shadow.min.x;
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
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();
00422 void DoCulling();
00423 void AdjustWeather();
00424 void GetMapInfo( grinliz::Vector2F* translation, grinliz::Vector2F* scale );
00425
00426 Camera camera;
00427
00428 int surfaceWidth, surfaceHeight;
00429 GLuint shadowId;
00430 GLuint frameBufferObject;
00431 grinliz::Matrix4 worldToLight;
00432
00433 int renderMode;
00434 bool renderFoliage;
00435
00436 bool renderShadows;
00437 float sunCircle;
00438
00439
00440 TerrainMesh* terrainMesh;
00441 TerrainDecor* terrainDecor;
00442 QuadTree* quadTree;
00443
00444 SequenceList sequenceList;
00445 ParticleSystemVector particleSystems;
00446 grinliz::InnerCircle<PointLight> pointLightSentinel;
00447
00448
00449
00450 MeshGroupVector meshSystems;
00451 MobGroup mobGroup;
00452
00453 U32 sequenceStart;
00454 int sequenceLength;
00455
00456 enum
00457 {
00458
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 };
00477
00478 #endif