00001 #include "lugre_prefix.h"
00002 #include <math.h>
00003
00004 #include "GhoulPrimitives.h"
00005
00006 using namespace GhoulPrimitive;
00007 using namespace Lugre;
00008
00009
00010
00011
00012
00013 Loft::Loft () { PROFILE
00014 mBase_bAutoNormal = true;
00015 mUseScale = true;
00016 mUseRot = true;
00017 mAutoBackSide = false;
00018 mSphericalAutoNormals = false;
00019 mSphericalAutoNormals_Center = Vector3::ZERO;
00020 }
00021
00022 Loft::~Loft () {
00023
00024 }
00025
00026 void Loft::Update (Drawer& drawer,bool bHasNormals,bool bHasTexCoords) { PROFILE
00027 size_t basePointCount = mlBasePoint.size();
00028 size_t pathPointCount = mlPathPoint.size();
00029 size_t vertexCount = basePointCount * pathPointCount;
00030 size_t indexCount = (basePointCount-1) * 6 * (pathPointCount - 1);
00031 size_t i,j,k,startoff,autobackoffset;
00032
00033 if (mAutoBackSide) {
00034 autobackoffset = vertexCount;
00035 indexCount *= 2;
00036 vertexCount *= 2;
00037 }
00038
00039
00040 drawer.Prepare(kOpType_TRIANGLE_LIST,kGeometryChange_Seldom,vertexCount,indexCount,bHasNormals,bHasTexCoords);
00041
00042
00043 BasePoint* base;
00044 PathPoint* path;
00045 Vector3 p,n;
00046 for (k=0;k<(mAutoBackSide?2:1);++k)
00047 for (i=0;i<pathPointCount;++i) { path = &mlPathPoint[i];
00048 for (j=0;j<basePointCount;++j) { base = &mlBasePoint[j];
00049
00050 if (mUseRot) {
00051 if (mUseScale)
00052 p = path->p + path->rot * base->p * path->scale;
00053 else p = path->p + path->rot * base->p;
00054 } else {
00055 if (mUseScale)
00056 p = path->p + base->p * path->scale;
00057 else p = path->p + base->p;
00058 }
00059
00060 if (mSphericalAutoNormals)
00061 n = (p - mSphericalAutoNormals_Center).normalisedCopy();
00062 else n = (mUseRot)?(path->rot * base->n):(base->n);
00063
00064 if (k==0) drawer.AddVertex( p , n , base->u + path->uBias, path->v );
00065 if (mAutoBackSide && k==1) drawer.AddVertex( p , -n , base->u + path->uBias, path->v );
00066
00067
00068 }
00069 }
00070
00071
00072 for (i=1,startoff=0;i<pathPointCount;++i,startoff+=basePointCount) {
00073 for (j=0;j<basePointCount-1;++j) {
00074 drawer.AddIndex(startoff + j+0);
00075 drawer.AddIndex(startoff + j+0 + basePointCount);
00076 drawer.AddIndex(startoff + j+1 + basePointCount);
00077 drawer.AddIndex(startoff + j+0);
00078 drawer.AddIndex(startoff + j+1 + basePointCount);
00079 drawer.AddIndex(startoff + j+1);
00080
00081 if (mAutoBackSide) {
00082 drawer.AddIndex(startoff+autobackoffset + j+0);
00083 drawer.AddIndex(startoff+autobackoffset + j+1 + basePointCount);
00084 drawer.AddIndex(startoff+autobackoffset + j+0 + basePointCount);
00085 drawer.AddIndex(startoff+autobackoffset + j+0);
00086 drawer.AddIndex(startoff+autobackoffset + j+1);
00087 drawer.AddIndex(startoff+autobackoffset + j+1 + basePointCount);
00088 }
00089 }
00090 }
00091
00092 drawer.Finish();
00093 }
00094
00095 void Loft::ClearBasePoints () { PROFILE
00096 mlBasePoint.clear();
00097 }
00098
00099 void Loft::AddBasePoint (kVector3 p,kVector3 n,kReal u) { PROFILE
00100 SetBasePoint(mlBasePoint.size(),p,n,u);
00101 }
00102
00103 void Loft::SetBasePoint (size_t i,kVector3 p,kVector3 n,kReal u) { PROFILE
00104 if (mlBasePoint.size() < i+1)
00105 mlBasePoint.resize(i+1);
00106 if (mBase_bAutoNormal && n.x == 0.0 && n.y == 0.0 && n.z == 0.0)
00107 mlBasePoint[i] = BasePoint(p,p.normalisedCopy(),u);
00108 else mlBasePoint[i] = BasePoint(p,n,u);
00109 }
00110
00111 void Loft::ClearPathPoints () { PROFILE
00112 mlPathPoint.clear();
00113 }
00114
00115 void Loft::AddPathPoint (kVector3 p,kReal v,kReal uBias,kVector3 scale,kQuaternion rot) { PROFILE
00116 SetPathPoint(mlPathPoint.size(),p,v,uBias,scale,rot);
00117 }
00118
00119 void Loft::SetPathPoint (size_t i,kVector3 p,kReal v,kReal uBias,kVector3 scale,kQuaternion rot) { PROFILE
00120 if (mlPathPoint.size() < i+1)
00121 mlPathPoint.resize(i+1);
00122 mlPathPoint[i] = PathPoint(p,v,uBias,scale,rot);
00123 }