mesh.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 #ifndef LILITH_MESH_INCLUDED
00023 #define LILITH_MESH_INCLUDED
00024 
00025 #include <stdio.h>
00026 
00027 #ifdef _MSC_VER
00028 #pragma warning( disable : 4786 )       // Debugger truncating names.
00029 #endif
00030 #include <vector>
00031 #include <list>
00032 #include <string>
00033 #include <map>
00034 
00035 #include "worlddefine.h"
00036 #include "meshgroup.h"
00037 #include "meshnode.h"
00038 #include "../grinliz/glcolor.h"
00039 #include "../grinliz/glutil.h"
00040 #include "../grinliz/glcontainer.h"
00041 #include "genericobject.h"
00042 #include "shader.h"
00043 
00044 namespace lilith3d
00045 {
00046 class MeshResource;
00047 class Texture;
00048 class TerrainMesh;
00049 class StaticResource;
00050 class AnimatedResource;
00051 class BuildingMesh;
00052 class ShadowVolumeCache;
00053 
00059 enum MeshClass
00060 {
00061         DECALMESH               = 0x01,
00062         STATICMESH              = 0x02,
00063         FOLIAGEMESH             = 0x04, // grass, plants, etc. Uses a special shader.
00064         SOLIDMESH               = 0x08,
00065         BUILDINGMESH    = 0x10,
00066         ANIMATEDMESH    = 0x20,
00067         TREEMESH                = 0x40,
00068 
00069         SHADOW_CASTER_MESH = STATICMESH | BUILDINGMESH | ANIMATEDMESH,
00070         SHADOW_RECEIVER_MESH = DECALMESH | STATICMESH | BUILDINGMESH,
00071 };
00072 
00073 
00074 #ifdef _MSC_VER
00075 #pragma warning( disable : 4355 )       // this in initializer list
00076 #endif
00077 
00078 struct PathSurfaceInstance;
00079 class Tri;
00080 
00081 
00082 
00094 class Mesh : public MeshNode
00095 {
00096   public:
00097         // After culling, the singly linked list of things that are drawn
00098         Mesh* nextRender;
00099 
00100   public:
00101         Mesh(   const MeshResource* meshResource, MeshClass type );
00102         virtual ~Mesh();
00103 
00105         const grinliz::Rectangle3F& AABB() const                        { return aabb; }
00107         const grinliz::Rectangle3F& AABBWithShadow() const      { return aabbWithShadow; }
00108 
00109         /*  [Internal]
00110                 Set the position of the mesh. This has to be virtual since the terrain can change
00111                 and change the Z with it. (Although the QuadTree actually calls the UpdateZ() method.)
00112                 This should only be called by the QuadTree()
00113         */
00114         virtual void UpdateZ( float z ) = 0;
00115 
00116         virtual void StreamOutMesh( ELightPass light, EPass pass ) = 0;
00117 
00118         #ifdef SHADOW_VOLUME
00119         virtual void StreamOutShadow( ShadowVolumeCache* ) {}
00120         #endif
00121 
00123         MeshClass                               Type() const                    { return type; }
00125         const MeshResource*             Resource() const                { return meshResource; }
00126         
00133         void AttachToTerrain( bool attach )                     { attachedToTerrain = attach; }
00135         bool AttachedToTerrain() const                          { return attachedToTerrain; }   
00136 
00138         void SetVisible( bool _visible )                        { this->visible = _visible; }
00140         bool Visible() const                                            { return visible; }
00141 
00143         const grinliz::Color3F& Color() const           { return color; }
00145         void SetColor( const grinliz::Color3F& c )      { color = c; }
00146         void SetColor( float r, float g, float b )      { color.r = r; color.g = g; color.b = b; }
00147 
00149         float Alpha() const                                                     { return m_alpha; }
00151         virtual void SetAlpha( float _alpha )           { m_alpha = grinliz::Clamp( _alpha, 0.0f, 1.0f ); }
00152 
00154         const Shader* GetShader()                                       { return m_shader; }
00156         void SetShader( const Shader* _shader )         { m_shader = _shader; }
00157 
00160         void SetStencil( bool _stencil )                        {       GLASSERT( this->Type() == DECALMESH );
00161                                                                                                         stencil = _stencil; 
00162                                                                                                 }
00164         bool Stencil() const                                            { return stencil; }
00165 
00166         // Does this mesh cast shadows? Currently not set-able. Also trees are handle as a special case.
00167         // In the future it would be nice to have this a set-able property.
00168         int IsShadowCaster()                                            { return type & ( SHADOW_CASTER_MESH ); }
00169 
00170         // Does this mesh cast shadows? Currently not set-able. Also terrain is a special case.
00171         // In the future it would be nice to have this a set-able property.
00172         int IsShadowReceiver()                                          { return type & ( SHADOW_RECEIVER_MESH ); }
00173 
00175         const grinliz::Vector3F& Pos() const            { return pos; }
00176 
00178         float ZRot() const;
00180         const grinliz::Matrix4& Rotation() const        { return rotation; }
00181 
00183         void SetPos( const grinliz::Vector3F& pos, float z );
00185         void SetPos( const grinliz::Vector3F& pos, const grinliz::Quaternion& quat );
00187         void SetPos( const grinliz::Vector3F& pos );
00189         void SetPos( float x, float y, float z );
00191         void SetPos( const grinliz::Vector3F& _pos, const grinliz::Matrix4& _rotation ) {
00192                 SetPosV( _pos, _rotation );
00193         }
00194 
00195         // All implementations of SetPos call SetPoSV.
00196         virtual void SetPosV( const grinliz::Vector3F& pos, const grinliz::Matrix4& rotation ) = 0;
00197 
00201         virtual void IntersectRay(      int flags, 
00202                                                                 const grinliz::Vector3F& point, 
00203                                                                 const grinliz::Vector3F& dir, 
00204                                                                 LilithObjectList* vec ) = 0;
00205 
00207         int ID() const  { return id; }
00208         std::string Name() const;
00209 
00210   protected:
00211         // 1. Set up transformation matrices.
00212         // 2. Modify alpha to account for fade.
00213     // 3. Return true if mesh should render.
00214         bool PreStreamOut( float fade, float fadeout, float *alpha );
00215         void PostStreamOut();
00216 
00217         void CalcAABB( const grinliz::Rectangle3F& original );
00218 
00219         // utility function to do basic transformation from world to object space
00220         bool SetupIntersect(    const grinliz::Vector3F& point, 
00221                                                         const grinliz::Vector3F& dir, 
00222                                                         grinliz::Vector3F* point0, 
00223                                                         grinliz::Vector3F* dir0 ) const;
00224 
00225         grinliz::Vector3F       pos;                    // the location of the mesh
00226         grinliz::Matrix4        rotation;               // always a pure rotation matrix
00227 
00228         const MeshResource* meshResource;       // a pointer to its resource
00229 
00230         const grinliz::Matrix4& Transform()     const { return transform; }
00231 
00232         void ComputeTransform() {
00233                 grinliz::Matrix4 translate;
00234                 translate.SetTranslation( pos.x, pos.y, pos.z );
00235                 transform = translate * rotation;
00236         }
00237 
00238         EPass CorrectPass() {
00239                 if ( m_alpha < 1.0f ) 
00240                         return BLEND_PASS;
00241                 return OPAQUE_PASS;
00242         }
00243 
00244   private:
00245         MeshClass                               type;   
00246         int                                             id;
00247         grinliz::Rectangle3F    aabb;
00248         grinliz::Rectangle3F    aabbWithShadow;
00249         bool                                    attachedToTerrain;
00250         bool                                    visible;
00251         bool                                    stencil;
00252         float                                   m_alpha;
00253         const Shader*                   m_shader;
00254         grinliz::Matrix4                transform;
00255         grinliz::Color3F                color;
00256 };
00257 
00258 #ifdef _MSC_VER
00259 #pragma warning( default : 4355 )       // this in initializer list
00260 #endif
00261 
00265 class DecalMesh : public Mesh
00266 {
00267   public:
00271         DecalMesh( const Texture* texture, float size );
00272         virtual ~DecalMesh();
00273 
00274         virtual void SetPosV( const grinliz::Vector3F& _newLoc, const grinliz::Matrix4& _newRot );
00275         virtual void StreamOutMesh( ELightPass light, EPass pass );
00276         static void StreamAllStencilDecals( Mesh* list );
00277 
00278         virtual void UpdateZ( float z );
00279 
00280         // Decal meshes don't report intersections.
00281         virtual void IntersectRay( int /*flags*/, const grinliz::Vector3F& /*point*/, const grinliz::Vector3F& /*dir*/, LilithObjectList* /*vec*/ )
00282         {
00283                 GLASSERT( 0 ); 
00284         }
00285 
00286         const Texture* DecalTexture() { return texture; }
00287 
00288   private:
00289         enum { MAX_DECAL_STENCIL = VERTEXSIZE*VERTEXSIZE/TREE_COVERAGE_DIV };
00290         static DecalMesh* renderVec[ MAX_DECAL_STENCIL ];
00291 
00292         const Texture* texture;
00293         float size;
00294         grinliz::Matrix4 texMat;        // texture transformation matrix
00295 };
00296 
00297 
00298 
00303 class StaticMesh : public Mesh
00304 {
00305  public:
00307         StaticMesh( const StaticResource* meshResource );
00308         virtual ~StaticMesh()   {}
00309 
00310         virtual void StreamOutMesh( ELightPass light, EPass pass );
00311         #ifdef SHADOW_VOLUME
00312         virtual void StreamOutShadow( ShadowVolumeCache* cache );
00313         #endif
00314 
00315         virtual void SetPosV( const grinliz::Vector3F& _newLoc, const grinliz::Matrix4& _newRot );
00316 
00317         virtual void UpdateZ( float z );
00318 
00319         virtual void IntersectRay(      int flags, 
00320                                                                 const grinliz::Vector3F& point, 
00321                                                                 const grinliz::Vector3F& dir, 
00322                                                                 LilithObjectList* vec );
00323 
00324         const StaticResource* GetStaticResource() { return staticResource; }
00325 
00326  protected:
00327         StaticMesh( const StaticResource* meshResource, MeshClass type );
00328         const StaticResource* staticResource;
00329 };
00330 
00331 
00332 class FoliageMesh : public StaticMesh
00333 {
00334 public:
00335         FoliageMesh( const StaticResource* res ) : StaticMesh( res, FOLIAGEMESH )       {}
00336         virtual ~FoliageMesh()  {}
00337 
00338         static void StreamAllFoliage( Mesh* list );
00339 };
00340 
00341 
00348 class SolidMesh : public Mesh
00349 {
00350   public:
00352         SolidMesh();
00353         virtual ~SolidMesh()    {}
00354 
00358         void GenerateSlab( float head, 
00359                                            float tail, 
00360                                            float width,
00361                                            const grinliz::Vector3F& dir,
00362                                            const grinliz::Vector3F& up );
00363 
00367         void GenerateCube( const grinliz::Rectangle3F& bounds );
00368 
00372         void GenerateSphere( float radius, int iterations );
00373 
00374         virtual void SetPosV( const grinliz::Vector3F& _newLoc, const grinliz::Matrix4& _newRot );
00375 
00376         virtual void UpdateZ( float z );
00377 
00378         virtual void StreamOutMesh( ELightPass light, EPass pass );
00379 
00381         void UseIntersection( bool intersection )       { this->useIntersection = intersection; }
00382         bool UsingIntersection()                                        { return useIntersection; }
00383 
00384         virtual void IntersectRay(      int flags, 
00385                                                                 const grinliz::Vector3F& point, 
00386                                                                 const grinliz::Vector3F& dir, 
00387                                                                 LilithObjectList* vec );
00388 
00390         float Length()  { return length; }
00391 
00392   private:
00393         std::vector< grinliz::Vector3F >        vertex;
00394         std::vector< U32 >                                      index;
00395         std::vector< grinliz::Vector3F >        normal;
00396 
00397         bool useIntersection;
00398         float length;
00399         bool lighting;
00400         const Texture* texture;
00401 
00402         grinliz::Rectangle3F resAABB;
00403 };
00404 
00405 
00406 };      // namespace lilith3d
00407 
00408 #endif
00409 

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