GhoulPrimitives.cpp

Go to the documentation of this file.
00001 #include "lugre_prefix.h"
00002 #include <math.h>
00003 //#include <cmath> ??
00004 #include "GhoulPrimitives.h"
00005 #include "Ogre.h"
00006 
00007 using namespace GhoulPrimitive;
00008 using namespace Lugre;
00009 
00010 
00011 inline int max (const int a, const int b) { return (a>b)?a:b; }
00012 
00013 
00014 // default implementation empty
00015 Drawer::Drawer      () {}
00016 Drawer::~Drawer     () {}
00017 void    Drawer::Prepare     (eOpType opType,eGeometryChange gcHint,size_t vertexCount,size_t indexCount,bool hasNormals,bool hasTexCoords) {}
00018 void    Drawer::AddVertex   (kVector3 p,kVector3 n,kReal u,kReal v) { AddVertex(p.x,p.y,p.z,n.x,n.y,n.z,u,v); }
00019 void    Drawer::AddVertex   (kReal x,kReal y,kReal z,kReal nx,kReal ny,kReal nz,kReal u,kReal v) {}
00020 void    Drawer::AddIndex    (IndexInt i) {}
00021 void    Drawer::Finish      () {}
00022 
00023 Primitive::Primitive        () {}
00024 Primitive::~Primitive       () {}
00025 void    Primitive::Update   (Drawer& drawer,bool bHasNormals,bool bHasTexCoords) {}
00026 
00027 
00037 void    Primitive::Ellipse  (Real* a,size_t blocks,size_t components,kReal radiusx,kReal radiusy,kReal startang,kReal endang,bool setOtherComponentsToZero) { PROFILE
00038     assert(blocks > 1 && "min one block");
00039     int i,j;
00040     if (components <= 0) return;
00041     Real ang,angstep=(endang-startang)/((Real)(blocks-1));
00042     for (i=0,ang=startang;i<blocks;++i,ang+=angstep) {
00043         if (i==blocks-1) ang = endang; // more exact end
00044         a[i*components+0] = radiusx * sin(ang);
00045         if (components > 1) {
00046             a[i*components+1] = radiusy * cos(ang);
00047             if (setOtherComponentsToZero) for (j=2;j<components;++j) a[i*components+j] = 0.0;
00048         }
00049     }
00050 }
00051 
00052 void    Primitive::Circle   (Real* a,size_t blocks,size_t components,kReal radius,kReal startang,kReal endang,bool setOtherComponentsToZero) { PROFILE
00053     Primitive::Ellipse(a,blocks,components,radius,radius,startang,endang,setOtherComponentsToZero);
00054 }
00055 
00056 
00068 void    Primitive::InterpolatateFloatV  (kReal* source,Real* dest,kReal t,size_t num,size_t startoff,size_t bufsize,eInterpolationMode mode,size_t stride) { PROFILE
00069     // use enum, choose from buffer, extend dynamically, stride : this function interpolates floats, stride enables using it for buffers containing vectors...
00070     ASSERT(startoff >= 0 && "negative startoff");
00071     ASSERT(stride >= 0 && "negative stride");
00072     ASSERT(source && "source buffer null");
00073     ASSERT(dest && "dest buffer null");
00074     ASSERT(bufsize >= (num+stride) + startoff && "source buffer too small");  // source must at least have one complete block !
00075     int i,j;
00076     switch (mode) {
00077         case kInterpolate_Constant:
00078             for (i=0;i<num;++i) {
00079                 dest[i] = source[startoff+i];
00080             }
00081         break;
00082         case kInterpolate_SmoothQuadric:
00083         {
00084             //assert(bufsize >= (num+stride)*3 + startoff && "source buffer too small");
00085             //assert(0 <= startoff - (num+stride) && "source buffer too small");
00086             Real t2 = t * t;
00087             Real t3 = t2 * t;
00088             Real t3m2 = t3 - t2;
00089             Real p1,p2,q1,q2,r1,r2;
00090 
00091             //Q(t) = P1*(2t^3-3t^2+1) + R1*(t^3-2t^2+t) + P2*(-2t^3+3t^2) + R2*(t^3-t^2)
00092             //Q(0) = P1*(1) + R1*(0) + P2*(0) + R2*(0)
00093             //Q(1) = P1*(0) + R1*(0) + P2*(1) + R2*(0)
00094             // hermit spline or something like that
00095             // R1,R2 are tangent-vectors at P1,P2
00096 
00097             for (i=0;i<num;++i) {
00098                 // the order is  q1  p1  p2  q2   , interpolation between p1 and p2
00099                 p1 = source[startoff+i];
00100                 j = startoff+i + (num+stride);
00101                 p2 = (j<bufsize)?source[j]:p1;
00102                 j += (num+stride);
00103                 q2 = (j<bufsize)?source[j]:p2;
00104                 j = startoff+i - (num+stride);
00105                 q1 = (j>=0)?source[j]:p1;
00106 
00107                 r1 = (p2 - q1) * 0.5;
00108                 r2 = (q2 - p1) * 0.5;
00109                 dest[i] = (t<0.0)?p1:((t>1.0)?p2:( p1*(t3m2+t3m2-t2+1.0) + r1*(t3m2-t2+t) + p2*(-t3m2-t3m2+t2) + r2*(t3m2) ));
00110             }
00111         }
00112         break;
00113         case kInterpolate_Linear:
00114         default :
00115         {
00116             Real p1,p2;
00117             for (i=0;i<num;++i) {
00118                 //assert(bufsize >= (num+stride)*2 + startoff && "source buffer too small");
00119                 p1 = source[startoff+i];
00120                 j = startoff+i + (num+stride);
00121                 p2 = (j<bufsize)?source[j]:p1;
00122                 dest[i] = (t<0.0)?p1:((t>1.0)?p2:(p1+(p2-p1)*t));
00123             }
00124         }
00125     }
00126 }
00127 
00128 Real    Primitive::InterpolatateFloat   (kReal* source,kReal t,size_t startoff,size_t bufsize,eInterpolationMode mode,size_t stride) { PROFILE
00129     Real res;
00130     Primitive::InterpolatateFloatV(source,&res,t,1,startoff,bufsize,mode,stride);
00131     return res;
00132 }
00133 
00134 
00135 Real        InterpolatateFloat_Linear   (kReal p1,kReal p2,kReal t) { PROFILE
00136     Real source[] = { p1, p2 };
00137     return Primitive::InterpolatateFloat(source,t,0,2,kInterpolate_Linear,0);
00138 }
00139 Real        InterpolatateFloat_Smooth   (kReal q1,kReal p1,kReal p2,kReal q2,kReal t) { PROFILE
00140     Real source[] = { q1, p1, p2, q2 };
00141     return Primitive::InterpolatateFloat(source,t,1,4,kInterpolate_SmoothQuadric,0);
00142 }
00143 
00144 
00146 Ellipsoid::~Ellipsoid() {}
00147 Ellipsoid::Ellipsoid                (kVector3 pos,kVector3 rad,size_t rings,size_t segments) : Loft() { PROFILE
00148     SetParams(pos,rad,rings,segments);
00149 }
00150 Ellipsoid&  Ellipsoid::SetParams    (kVector3 pos,kVector3 rad,size_t rings,size_t segments) { PROFILE
00151     size_t i;
00152     Real t;
00153     Real *circle;
00154     circle = new Real[segments*2];
00155     Primitive::Ellipse(circle,segments,2,rad.x,rad.y);
00156     for (i=0;i<segments;++i)
00157         AddBasePoint(Vector3(circle[i*2+0],circle[i*2+1],0.0),Vector3::ZERO,(Real)i/(Real)(max(2,segments)-1));
00158 
00159     for (i=0;i<rings;++i) {
00160         t = (Real)i/(Real)(max(2,rings)-1);
00161         AddPathPoint(Vector3(pos.x,pos.y,pos.z-rad.z*cos(t*pi)),t,0,Vector3::UNIT_SCALE*sin(t*pi));
00162     }
00163     mSphericalAutoNormals = true;
00164     mSphericalAutoNormals_Center = pos;
00165     delete(circle);
00166     return *this;
00167 }
00168 
00169 OgreEllipsoid::~OgreEllipsoid() {}
00170 OgreEllipsoid::OgreEllipsoid        (kVector3 pos,kVector3 rad,size_t rings,size_t segments)
00171     : Ellipsoid(pos,rad,rings,segments), OgreRenderableDrawer() { PROFILE
00172     Update(*this);
00173 }
00174 
00175 
00176 
00178 Cone::~Cone() {}
00179 Cone::Cone                  (kVector3 pos1,kVector3 pos2,kReal rad1X,kReal rad1Y,kReal endscale,size_t segments,size_t height_segments) : Loft() { PROFILE
00180     SetParams(pos1,pos2,rad1X,rad1Y,endscale,segments,height_segments);
00181 }
00182 Cone&   Cone::SetParams     (kVector3 pos1,kVector3 pos2,kReal rad1X,kReal rad1Y,kReal endscale,size_t segments,size_t height_segments) { PROFILE
00183     size_t i;
00184     Vector3 v = pos2 - pos1;
00185     Vector3 vn = v.normalisedCopy();
00186     Vector3 x,y;
00187     if (fabs(vn.x) > fabs(vn.y))
00188             x = vn.crossProduct(Vector3::UNIT_Y); // x or z was max
00189     else    x = vn.crossProduct(Vector3::UNIT_X); // y or z was max
00190     y = vn.crossProduct(x);
00191 
00192     Real t;
00193     Real *circle;
00194     circle = new Real[segments*2];
00195     Primitive::Ellipse(circle,segments,2,rad1X,rad1Y);
00196     for (i=0;i<segments;++i) {
00197         AddBasePoint(x*circle[i*2+0] + y*circle[i*2+1],Vector3::ZERO,(Real)i/(Real)(max(2,segments)-1));
00198     }
00199 
00200     height_segments = max(2,height_segments);
00201     for (i=0;i<height_segments;++i) {
00202         t = (Real)i/(Real)(max(2,height_segments)-1);
00203         AddPathPoint(pos1+t*v,t,0,Vector3::UNIT_SCALE*(1.0 - t*(1.0-endscale)));
00204     }
00205     delete(circle);
00206     return *this;
00207 }
00208 
00209 OgreCone::~OgreCone() {}
00210 OgreCone::OgreCone          (kVector3 pos1,kVector3 pos2,kReal rad1X,kReal rad1Y,kReal endscale,size_t segments,size_t height_segments)
00211     : Cone(pos1,pos2,rad1X,rad1Y,endscale,segments,height_segments), OgreRenderableDrawer() { PROFILE
00212     Update(*this);
00213 }

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