GhoulPrimitives.h

Go to the documentation of this file.
00001 #ifndef ROB_PRIMITIVES_H
00002 #define ROB_PRIMITIVES_H
00003 
00004 #include <OgreSimpleRenderable.h>
00005 #include <OgreCamera.h>
00006 #include <vector>
00007 
00033 // who needs meshes, all is loft !
00034 // multiple inheritance rocks !
00035 
00036 // TODO : lua bindings
00037 // TODO : vertex colors
00038 // TODO : OgreMeshDrawer (to generate a mesh instead of filling vertex buffers, that can be exported, 
00039 
00040 namespace GhoulPrimitive {
00041 
00042 class Primitive;
00043 class Drawer;
00044     
00045 // types  (edit me for binding to something different than ogre)
00046 typedef Ogre::Real          Real;
00047 typedef Ogre::Vector3       Vector3;
00048 typedef Ogre::Quaternion    Quaternion;
00049 typedef Ogre::Camera        Camera;
00050 typedef unsigned short      IndexInt; // for hardware-index-buffer (vertex index)
00051 
00052 typedef const Real          kReal;
00053 typedef const Vector3       kVector3;
00054 typedef const Quaternion    kQuaternion;
00055     
00056 // constants
00057 const Real pi =         3.14159265358979323846; // math.h : M_PI
00058 const Real pi2 = 2.0*   3.14159265358979323846; // (pi*2.0)
00059 
00060 typedef enum {
00061     kInterpolate_Constant,
00062     kInterpolate_Linear,
00063     kInterpolate_SmoothQuadric, // quadric with automatic tangents
00064     // kInterpolate_Quadric, // TODO? : maybe handle tangent points extra...
00065 } eInterpolationMode;
00066     
00067 typedef enum {
00068     kOpType_POINT_LIST,     // Ogre::RenderOperation::OT_POINT_LIST
00069     kOpType_LINE_LIST,
00070     kOpType_LINE_STRIP,
00071     kOpType_TRIANGLE_LIST,
00072     kOpType_TRIANGLE_STRIP,
00073     kOpType_TRIANGLE_FAN,
00074 } eOpType;
00075 
00076 typedef enum {
00077     // gives a hint at the frequency of geometry changes 
00078     kGeometryChange_Seldom,             // Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY
00079     kGeometryChange_Often,              // Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY
00080     kGeometryChange_AlmostEveryFrame,   // Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE
00081 } eGeometryChange;
00082 
00085 class Drawer {
00086     public:
00087     Drawer();
00088     virtual ~Drawer();
00089     
00090     virtual void    Prepare     (eOpType opType,eGeometryChange gcHint,size_t vertexCount,size_t indexCount=0,bool hasNormals=true,bool hasTexCoords=true); // renderop(trilist,linelist...)
00091             void    AddVertex   (kVector3 p,kVector3 n=Vector3::ZERO,kReal u=0.0,kReal v=0.0);
00092     virtual void    AddVertex   (kReal x,kReal y,kReal z=0.0,kReal nx=0.0,kReal ny=0.0,kReal nz=0.0,kReal u=0.0,kReal v=0.0);
00093     virtual void    AddIndex    (IndexInt i);
00094     virtual void    Finish      ();  
00095 };
00096 
00097 
00098 class OgreRenderableDrawer : public Drawer,public Ogre::SimpleRenderable {
00099     public:
00101     OgreRenderableDrawer            ();
00102     virtual ~OgreRenderableDrawer   ();
00103     
00104     // TODO : lua binding ??
00105     
00107     virtual void    Prepare     (eOpType opType,eGeometryChange gcHint,size_t vertexCount,size_t indexCount=0,bool hasNormals=true,bool hasTexCoords=true); // renderop(trilist,linelist...)
00108     virtual void    AddVertex   (kReal x,kReal y,kReal z=0.0,kReal nx=0.0,kReal ny=0.0,kReal nz=0.0,kReal u=0.0,kReal v=0.0);
00109     virtual void    AddIndex    (IndexInt i);
00110     virtual void    Finish      ();
00111     
00112     static Ogre::RenderOperation::OperationType     GetOgreOpType   (const eOpType opType);
00113     static Ogre::HardwareBuffer::Usage              GetOgreHWBUsage (const eGeometryChange geometryChangeHint);
00114     
00115     
00117     virtual Ogre::Real getBoundingRadius(void) const;
00119     virtual Ogre::Real getSquaredViewDepth(const Ogre::Camera* cam) const;
00120     
00121     protected:
00122     bool        mReady;
00123     bool        mVertexDecInitialized;
00124     bool        mIndexBufferInitialized;
00125     bool        mHasNormals;
00126     bool        mHasTexCoords;
00127     bool        mBoundingBoxEmpty;
00128     Vector3     mvAABMin;
00129     Vector3     mvAABMax;
00130     Real*       mWritePtr;
00131     IndexInt*   mIndexWritePtr;
00132     Ogre::HardwareVertexBufferSharedPtr mHWVBuf;
00133     Ogre::HardwareIndexBufferSharedPtr  mHWIBuf;
00134     size_t      miVerticesLeft;
00135     size_t      miIndicesLeft;
00136     size_t      mVertexBufferCapacity;
00137     size_t      mIndexBufferCapacity;
00138 };
00139 
00140 
00141 class Primitive {
00143     public:
00144     
00146     virtual void    Update          (Drawer& drawer,bool bHasNormals=true,bool bHasTexCoords=true);
00147     // TODO : (getboundingbox,boundingsphere..)
00148     
00149     // construction
00150     Primitive();
00151     virtual ~Primitive();
00152     
00154     static void     Circle                  (Real* a,size_t blocks,size_t components=2,kReal radius=1.0,kReal startang=0.0,kReal endang=pi2,bool setOtherComponentsToZero=true);
00155     static void     Ellipse                 (Real* a,size_t blocks,size_t components=2,kReal radiusx=1.0,kReal radiusy=1.0,kReal startang=0.0,kReal endang=pi2,bool setOtherComponentsToZero=true);
00156     
00157     // utils : interpolation
00158     static void     InterpolatateFloatV     (kReal* source,Real* dest,kReal t,size_t num=1,size_t startoff=0,size_t bufsize=2,eInterpolationMode mode=kInterpolate_Linear,size_t stride=0); 
00159     static Real     InterpolatateFloat      (kReal* source,kReal t,size_t startoff=0,size_t bufsize=2,eInterpolationMode mode=kInterpolate_Linear,size_t stride=0); 
00161     static Real     InterpolatateFloat_Linear   (kReal p1,kReal p2,kReal t); 
00163     static Real     InterpolatateFloat_Smooth   (kReal q1,kReal p1,kReal p2,kReal q2,kReal t);
00164     
00165     // static void Interpolatate_quaternion4_x  slerp,squad
00166 };
00167 
00168 
00172 class Loft : public Primitive {
00173     public:
00174     // interface
00175     
00177     Loft();
00178     virtual ~Loft();
00179     
00180     // interface
00181     virtual void    Update          (Drawer& drawer,bool bHasNormals=true,bool bHasTexCoords=true);
00182     
00183     // the "base" polygon defined by BasePoints is extruded along the "path" defined by PathPoints
00184     // the "base" defines the first texcoord "u"
00185     // the "path" defines the second texcoord "v"
00186     
00187     void    ClearBasePoints ();
00188     void    SetBasePoint    (size_t i,  kVector3 p,kVector3 n=Vector3::ZERO,kReal u=0);
00189     void    AddBasePoint    (           kVector3 p,kVector3 n=Vector3::ZERO,kReal u=0);
00190     
00191     void    ClearPathPoints ();
00192     void    SetPathPoint    (size_t i,  kVector3 p,kReal uBias=0,kReal v=0,kVector3 scale=Vector3::UNIT_SCALE,kQuaternion rot=Quaternion::IDENTITY);
00193     void    AddPathPoint    (           kVector3 p,kReal uBias=0,kReal v=0,kVector3 scale=Vector3::UNIT_SCALE,kQuaternion rot=Quaternion::IDENTITY);
00194     
00195     bool                    mBase_bAutoNormal;              
00196     bool                    mUseScale;                      
00197     bool                    mUseRot;                        
00198     bool                    mAutoBackSide;                  
00199     bool                    mSphericalAutoNormals;          
00200     Vector3                 mSphericalAutoNormals_Center;   
00201     
00202     private:
00203         
00204     class BasePoint {
00205         public:
00206         Vector3     p;
00207         Vector3     n;
00208         Real        u;
00209         inline BasePoint () { }
00210         inline BasePoint (kVector3 p,kVector3 n,kReal u) : p(p), n(n), u(u) {}
00211         inline BasePoint (const BasePoint& a) : p(a.p), n(a.n), u(a.u) {}
00212     };
00213     class PathPoint {
00214         public:
00215         Vector3     p;
00216         Real        v;
00217         Real        uBias;
00218         Vector3     scale;
00219         Quaternion  rot;
00220         inline PathPoint () { }
00221         inline PathPoint (kVector3 p,kReal v,kReal uBias,kVector3 scale,kQuaternion rot) : p(p), v(v), uBias(uBias), scale(scale), rot(rot) {}
00222         inline PathPoint (const PathPoint& a) : p(a.p), v(a.v), uBias(a.uBias), scale(a.scale), rot(a.rot) {}
00223     };
00224     std::vector<BasePoint>      mlBasePoint;
00225     std::vector<PathPoint>      mlPathPoint;
00226 };
00227 
00228 
00230 class Ellipsoid : public Loft { public:
00231     virtual ~Ellipsoid();
00232     Ellipsoid               (kVector3 pos=Vector3::ZERO,kVector3 rad=Vector3::UNIT_SCALE,size_t rings=11,size_t segments=23);
00233     Ellipsoid&  SetParams   (kVector3 pos=Vector3::ZERO,kVector3 rad=Vector3::UNIT_SCALE,size_t rings=11,size_t segments=23);
00234 };
00235 class OgreEllipsoid : public Ellipsoid,public OgreRenderableDrawer { public:
00236     virtual ~OgreEllipsoid();
00237     OgreEllipsoid           (kVector3 pos=Vector3::ZERO,kVector3 rad=Vector3::UNIT_SCALE,size_t rings=11,size_t segments=23);
00238 };
00239 
00241 class Cone : public Loft { public:
00242     virtual ~Cone();
00243     Cone                    (kVector3 pos1=Vector3::ZERO,kVector3 pos2=Vector3::UNIT_Y,kReal rad1X=1.0,kReal rad1Y=1.0,kReal endscale=1.0,size_t segments=23,size_t height_segments=1);
00244     Cone&   SetParams       (kVector3 pos1=Vector3::ZERO,kVector3 pos2=Vector3::UNIT_Y,kReal rad1X=1.0,kReal rad1Y=1.0,kReal endscale=1.0,size_t segments=23,size_t height_segments=1);
00245 };
00246 class OgreCone : public Cone, public OgreRenderableDrawer { public:
00247     virtual ~OgreCone();
00248     OgreCone                (kVector3 pos1=Vector3::ZERO,kVector3 pos2=Vector3::UNIT_Y,kReal rad1X=1.0,kReal rad1Y=1.0,kReal endscale=1.0,size_t segments=23,size_t height_segments=1);
00249 };
00250 
00251 }; // end namespace
00252 
00253 
00254 #if 0 // NOTES 
00255 
00256     /*
00257     // todo : hyperloft : mutliple different base-polygons, all with the same vertexcount, and every pathpoint gets a FLOAT to interpolate (quadric) between them
00258     // LOFT-LOD : just change indices ?
00259     // loft-wireframe... obvious... different modi : only u, only v
00260 
00262     eInterpolationMode      mInterpolate_Path_Pos;
00263     eInterpolationMode      mInterpolate_Path_V;
00264     eInterpolationMode      mInterpolate_Path_UBias;
00265     eInterpolationMode      mInterpolate_Path_Scale;        
00266     eInterpolationMode      mInterpolate_Path_Rotation; 
00267 
00268     mInterpolate_Path_Pos       = kInterpolate_Linear;
00269     mInterpolate_Path_V         = kInterpolate_Linear;
00270     mInterpolate_Path_UBias     = kInterpolate_Linear;
00271     mInterpolate_Path_Scale     = kInterpolate_Linear;
00272     mInterpolate_Path_Rotation  = kInterpolate_Linear;
00273     */
00274 
00275     // class OgreRenderableDrawer : public OgreSimpleRenderable,private Drawer { }; // TODO : runtime drawing using hardware buffers
00276     // class OgreMeshDrawer : public OgreSimpleRenderable,private Drawer { };       // TODO : generate ogre-mesh
00277     // primitivegroups (not renderable in one flow): capped cylinders, grids, automatic LOD decorator
00278         // use one common hardwarebuffer -> still faster than simply combining primitives directly
00279 
00280     // drawer decorators:
00281     //  texturecoordinate transformer/animator
00282     //  texturecoordinate assignment (cylindrical/plane/sphere wrapping)
00283     //  vertex deformer (spacewarp) , jitter,twist&bend&scale,mirror,... animation
00284     //  colormapper (based on TexCoords,VertexCoords or normals)
00285 
00286 
00287     /*
00288         class Prism : Loft {};
00289         class Cylinder : Prism {
00290             Cylinder(Real rad,Real height,size_t height_segments=1,size_t round_segments=16,bool hasNormals=true,bool hasTexCoords=true);   
00291         };
00292         // maybe even csg ? (constructive solid geomety : intersect,difference,merge) ... probably not
00293         look at 
00294         #include <OgreSimpleSpline.h>
00295         #include <OgreRotationalSpline.h>
00296     */
00297     
00298     
00299     // Triangles
00300     // TriangleStrip
00301     // TriangleFan
00302     // Quads                Triangles       see Ogre::RenderOperation,Renderable
00303     // QuadStrip            TriangleStrip   see Ogre::RenderOperation,Renderable
00304     // Polygon              TriangleFan if convex ? .. filling currently not possible if not convex... (i dunno how)
00305     // Polygon_Wire         LineStrip
00306 
00307     // Lines
00308     // LineStrip
00309     // Spline               LineStrip
00310         // (segments, interpolation(coord,uv)(constant,linear,quadric:smooth,quadric:controlpoints), can be "rendered" to buffer, with stride)
00311         // add "refine" command ("time" as param?) to input vertex in the middle and maybe set controlpoints automatically
00312         // use as input to various forms (polygon,loft,prism...)
00313         // add some nice calc functions such as "GetClosestTime(Point,index1,index2)", approximate using segments at first
00314         // can splines have some kind of normals or quaternions ? -> loft-path, quaternion for pointing z axis along the path
00315 
00316     // Circle               TriangleFan, around the first point (one poly and one vertex less than centerfan)
00317     // Circle_CenterFan     TriangleFan, around the center point, has nicer lighting ?
00318     // Circle_Wire          LineStrip, (or Spline with 4(or even 2, normal-bug) points ???)
00319 
00320     // Rect                 QuadStrip
00321     // Rect_Wire            LineStrip
00322     // Rect_FastWire        Lines, no vertex at line crossing => fewer lines
00323 
00324     // Ellipsoid            Loft (cool for partial sphere, pacman) , Sphere
00325     // Ellipsoid_Wire       Loft
00326     // Box                  Loft (collapsed on lower left edge) , needs not be orthogonal
00327     // Box_Wire             Lines ? LineStrip ? Loft-in-wire-mode ? Box_FastWire alone should be enough
00328     // Box_FastWire         Lines, no vertex at line crossing => fewer lines    
00329     // Torus                Loft, "donut"
00330 
00331     // Spline               also as possible input for loft, also add "refine" command
00332     // Nurbs                
00333     // RoundedCube          Loft
00334     // Capsule              Loft, (=oil-tank?) : a cylinder with half-spheres at the end
00335     // Arrow                Loft, 3d and 2d(just less segments)
00336     // Wall                 Loft, extruded line, lofted upwards, spline-based ?
00337     // Lathe                Loft, (no move, only rotate)
00338     // Frame                Group<Prism> : generated from mesh (or spline-patch-mesh-thing), also used for spaceships
00339 
00340     // teapot               this one is a must
00341     // TorusKnot            orge-company-logo : Loft (with control-points if quadric)
00342     // superellipsoid ??? dunno what that is
00343     // geosphere : triangle-strip, created by subdividing faces 1 to 4, start with 2 mirrored triangles
00344 
00345     // Loft
00346         // Prism        (Cone,Cylinder)         // Arrow,Crystals ?
00347         // Lathe                                // Asteroid ?
00348             // Ellipsoid    (Sphere)
00349             // Torus 1 (spinning circle)
00350 
00351     // morping loft : more than one base-shape -> spike-ball, teapot (not quite) 
00352         
00353         
00354 #endif
00355 
00356 #endif // ROB_PRIMITIVES_H

Generated on Tue May 22 06:00:13 2012 for cpp by  doxygen 1.5.6