Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <vlGraphics/BezierSurface.hpp>
00033
00034 using namespace vl;
00035
00036
00070 void BezierPatch::resize(int x, int y)
00071 {
00072 if ( ((x-1)/3)*3+1 != x || ((y-1)/3)*3+1 != y )
00073 {
00074 vl::Log::error("BezierPatch::resize(): illegal patch dimensions.\n");
00075 mControlPoints.clear();
00076
00077 VL_CHECK( ((x-1)/3)*3+1 == x )
00078 VL_CHECK( ((y-1)/3)*3+1 == y )
00079 return;
00080 }
00081
00082 mX = x;
00083 mY = y;
00084 mControlPoints.resize(mX*mY);
00085 }
00086
00087 void BezierSurface::updateBezierSurface(bool gen_tex_coords)
00088 {
00089 int patch_count = 0;
00090 for(unsigned ipatch=0; ipatch<patches().size(); ++ipatch)
00091 patch_count += ((patches()[ipatch]->x()-1)/3)*((patches()[ipatch]->y()-1)/3);
00092
00093 ref<ArrayFloat3> vert_array = dynamic_cast<ArrayFloat3*>(vertexArray());
00094 if (!vert_array)
00095 {
00096 vert_array = new ArrayFloat3;
00097 setVertexArray(vert_array.get());
00098 }
00099 vert_array->resize(detail()*detail()*patch_count);
00100
00101 ref<ArrayFloat2> texc_array = dynamic_cast<ArrayFloat2*>(texCoordArray(0));
00102 if ( gen_tex_coords )
00103 {
00104 if (!texc_array)
00105 {
00106 texc_array = new ArrayFloat2;
00107 setTexCoordArray(0,texc_array.get());
00108 }
00109 texc_array->resize(detail()*detail()*patch_count);
00110 }
00111
00112 ref<DrawElementsUInt> de = drawCalls()->size() == 1 ? dynamic_cast<DrawElementsUInt*>(drawCalls()->at(0)) : NULL;
00113 if (!de)
00114 {
00115 drawCalls()->clear();
00116 de = new DrawElementsUInt(PT_QUADS);
00117 drawCalls()->push_back(de.get());
00118 }
00119 de->indices()->resize((detail()-1)*(detail()-1)*4*patch_count);
00120
00121 int ivert = 0;
00122 int iquad = 0;
00123 for(unsigned ipatch=0, patch_num=0; ipatch<patches().size(); ++ipatch)
00124 {
00125 const BezierPatch* p = patches()[ipatch].get();
00126 for(int ix=0; ix<p->x()-3; ix+=3)
00127 for(int iy=0; iy<p->y()-3; iy+=3)
00128 {
00129 for(unsigned y=0; y<detail(); ++y)
00130 {
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 Real v = (Real)y/(detail()-1);
00141 Real ty = 1.0f - v;
00142 Real ty1 = 1.0f - ty;
00143 Real k0 = ty*ty*ty;
00144 Real k1 = 3*ty*ty*ty1;
00145 Real k2 = 3*ty*ty1*ty1;
00146 Real k3 = ty1*ty1*ty1;
00147 vec3 A = p->at(ix+0,iy+0)*k0 + p->at(ix+0,iy+1)*k1 + p->at(ix+0,iy+2)*k2 + p->at(ix+0,iy+3)*k3;
00148 vec3 B = p->at(ix+1,iy+0)*k0 + p->at(ix+1,iy+1)*k1 + p->at(ix+1,iy+2)*k2 + p->at(ix+1,iy+3)*k3;
00149 vec3 C = p->at(ix+2,iy+0)*k0 + p->at(ix+2,iy+1)*k1 + p->at(ix+2,iy+2)*k2 + p->at(ix+2,iy+3)*k3;
00150 vec3 D = p->at(ix+3,iy+0)*k0 + p->at(ix+3,iy+1)*k1 + p->at(ix+3,iy+2)*k2 + p->at(ix+3,iy+3)*k3;
00151 for(unsigned x=0; x<detail(); ++x, ++ivert)
00152 {
00153 Real u = (Real)x/(detail()-1);
00154 Real tx = 1.0f - u;
00155 Real tx1 = 1.0f - tx;
00156 vert_array->at(ivert) = (fvec3)(A*tx*tx*tx + B*3*tx*tx*tx1 + C*3*tx*tx1*tx1 + D*tx1*tx1*tx1);
00157 if(gen_tex_coords)
00158 {
00159 texc_array->at(ivert).x() = (float)u;
00160 texc_array->at(ivert).y() = (float)v;
00161 }
00162 }
00163 }
00164
00165 int istart = detail()*detail()*patch_num;
00166 for(unsigned y=0; y<detail()-1; ++y)
00167 {
00168 for(unsigned x=0; x<detail()-1; ++x)
00169 {
00170 de->indices()->at(iquad++) = istart + y *detail() + x;
00171 de->indices()->at(iquad++) = istart + y *detail() + x+1;
00172 de->indices()->at(iquad++) = istart + (y+1)*detail() + x+1;
00173 de->indices()->at(iquad++) = istart + (y+1)*detail() + x;
00174 }
00175 }
00176 ++patch_num;
00177 }
00178 }
00179 }
00180