00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "Common/Assert.h"
00012 #include "Common/Vertex.h"
00013 #include "Common/Matrix.h"
00014
00015 #include "Bsp/BezierPatch.h"
00016
00017
00018 KBezierPatch::KBezierPatch()
00019 {
00020 m_pVertices = NULL;
00021 m_nVertices = 0;
00022 m_pIndices = NULL;
00023 m_nIndices = 0;
00024 }
00025
00026
00027 KBezierPatch::~KBezierPatch()
00028 {
00029 if( m_pVertices )
00030 Deletev( m_pVertices );
00031 if( m_pIndices )
00032 Deletev( m_pIndices );
00033 }
00034
00035
00036 void KBezierPatch::GenerateVertices( KLVertex2* pVertices, KPt& PatchSize )
00037 {
00038 KASSERT( pVertices );
00039 KASSERT( ( PatchSize.x >= 3 ) && ( PatchSize.y >= 3 ) );
00040
00041
00042 if( m_pVertices )
00043 {
00044 Deletev( m_pVertices );
00045 m_nVertices = 0;
00046 }
00047
00048 if( m_pIndices )
00049 {
00050 Deletev( m_pIndices );
00051 m_nIndices = 0;
00052 }
00053
00054 u32 n = 5;
00055 u32 nVertex = 0;
00056 u32 nIndices = 0;
00057 s32 PatchX = 0;
00058 s32 PatchY = 0;
00059
00060 m_nVertices = (u16)(n * n * (( PatchSize.x - 1 ) / 2) * (( PatchSize.y - 1 ) / 2));
00061 m_pVertices = new KLVertex2[m_nVertices];
00062 m_nIndices = (u16)((n - 1) * (n - 1) * 2 * 3 * (( PatchSize.x - 1 ) / 2) * (( PatchSize.y - 1 ) / 2));
00063 m_pIndices = new u16[m_nIndices];
00064
00065 for( PatchY = 0; PatchY < PatchSize.y - 1; PatchY += 2 )
00066 for( PatchX = 0; PatchX < PatchSize.x - 1; PatchX += 2 )
00067 {
00068 KLVertex2 pControlPoint[16];
00069 KLVertex2 pVertexPoint[9];
00070 u32 x, y;
00071
00072
00073 for( y = 0; y < 3; y ++ )
00074 for( x = 0; x < 3; x ++ )
00075 pVertexPoint[y * 3 + x] = pVertices[(y + PatchY) * PatchSize.x + (x + PatchX)];
00076
00077
00078 pControlPoint[0] = pVertexPoint[0];
00079 pControlPoint[1] = (pVertexPoint[0] + pVertexPoint[1]) / 2.0f;
00080 pControlPoint[2] = (pVertexPoint[1] + pVertexPoint[2]) / 2.0f;
00081 pControlPoint[3] = pVertexPoint[2];
00082
00083 pControlPoint[4] = (pVertexPoint[0] + pVertexPoint[3]) / 2.0f;
00084 pControlPoint[5] = (pVertexPoint[0] + pVertexPoint[1] + pVertexPoint[3] + pVertexPoint[4]) / 4.0f;
00085 pControlPoint[6] = (pVertexPoint[1] + pVertexPoint[2] + pVertexPoint[4] + pVertexPoint[5]) / 4.0f;
00086 pControlPoint[7] = (pVertexPoint[2] + pVertexPoint[5]) / 2.0f;
00087
00088 pControlPoint[8] = (pVertexPoint[3] + pVertexPoint[6]) / 2.0f;
00089 pControlPoint[9] = (pVertexPoint[3] + pVertexPoint[4] + pVertexPoint[6] + pVertexPoint[7]) / 4.0f;
00090 pControlPoint[10]= (pVertexPoint[4] + pVertexPoint[5] + pVertexPoint[7] + pVertexPoint[8]) / 4.0f;
00091 pControlPoint[11]= (pVertexPoint[5] + pVertexPoint[8]) / 2.0f;
00092
00093 pControlPoint[12]= pVertexPoint[6];
00094 pControlPoint[13]= (pVertexPoint[6] + pVertexPoint[7]) / 2.0f;
00095 pControlPoint[14]= (pVertexPoint[7] + pVertexPoint[8]) / 2.0f;
00096 pControlPoint[15]= pVertexPoint[8];
00097
00098 double s, t;
00099
00100 KLVertex2* pV = new KLVertex2[n * n];
00101
00102 for( y = 0; y < n; y ++ )
00103 for( x = 0; x < n; x ++ )
00104 {
00105 s = (double)(x / (double)(n - 1));
00106 t = (double)(y / (double)(n - 1));
00107 KASSERT( ( s <= 1.0f ) && ( s >= 0.0f ) );
00108 KASSERT( ( t <= 1.0f ) && ( t >= 0.0f ) );
00109
00110 KMatrix mx( pControlPoint[12].Position.x, pControlPoint[13].Position.x, pControlPoint[14].Position.x, pControlPoint[15].Position.x,
00111 pControlPoint[8].Position.x, pControlPoint[9].Position.x, pControlPoint[10].Position.x, pControlPoint[11].Position.x,
00112 pControlPoint[4].Position.x, pControlPoint[5].Position.x, pControlPoint[6].Position.x, pControlPoint[7].Position.x,
00113 pControlPoint[0].Position.x, pControlPoint[1].Position.x, pControlPoint[2].Position.x, pControlPoint[3].Position.x );
00114
00115 KMatrix my( pControlPoint[12].Position.y, pControlPoint[13].Position.y, pControlPoint[14].Position.y, pControlPoint[15].Position.y,
00116 pControlPoint[8].Position.y, pControlPoint[9].Position.y, pControlPoint[10].Position.y, pControlPoint[11].Position.y,
00117 pControlPoint[4].Position.y, pControlPoint[5].Position.y, pControlPoint[6].Position.y, pControlPoint[7].Position.y,
00118 pControlPoint[0].Position.y, pControlPoint[1].Position.y, pControlPoint[2].Position.y, pControlPoint[3].Position.y );
00119
00120 KMatrix mz( pControlPoint[12].Position.z, pControlPoint[13].Position.z, pControlPoint[14].Position.z, pControlPoint[15].Position.z,
00121 pControlPoint[8].Position.z, pControlPoint[9].Position.z, pControlPoint[10].Position.z, pControlPoint[11].Position.z,
00122 pControlPoint[4].Position.z, pControlPoint[5].Position.z, pControlPoint[6].Position.z, pControlPoint[7].Position.z,
00123 pControlPoint[0].Position.z, pControlPoint[1].Position.z, pControlPoint[2].Position.z, pControlPoint[3].Position.z );
00124
00125 KMatrix mcolora( (float)KGETA(pControlPoint[12].Color), (float)KGETA(pControlPoint[13].Color), (float)KGETA(pControlPoint[14].Color), (float)KGETA(pControlPoint[15].Color),
00126 (float)KGETA(pControlPoint[8].Color), (float)KGETA(pControlPoint[9].Color), (float)KGETA(pControlPoint[10].Color), (float)KGETA(pControlPoint[11].Color),
00127 (float)KGETA(pControlPoint[4].Color), (float)KGETA(pControlPoint[5].Color), (float)KGETA(pControlPoint[6].Color), (float)KGETA(pControlPoint[7].Color),
00128 (float)KGETA(pControlPoint[0].Color), (float)KGETA(pControlPoint[1].Color), (float)KGETA(pControlPoint[2].Color), (float)KGETA(pControlPoint[3].Color) );
00129
00130 KMatrix mcolorr( (float)KGETR(pControlPoint[12].Color), (float)KGETR(pControlPoint[13].Color), (float)KGETR(pControlPoint[14].Color), (float)KGETR(pControlPoint[15].Color),
00131 (float)KGETR(pControlPoint[8].Color), (float)KGETR(pControlPoint[9].Color), (float)KGETR(pControlPoint[10].Color), (float)KGETR(pControlPoint[11].Color),
00132 (float)KGETR(pControlPoint[4].Color), (float)KGETR(pControlPoint[5].Color), (float)KGETR(pControlPoint[6].Color), (float)KGETR(pControlPoint[7].Color),
00133 (float)KGETR(pControlPoint[0].Color), (float)KGETR(pControlPoint[1].Color), (float)KGETR(pControlPoint[2].Color), (float)KGETR(pControlPoint[3].Color) );
00134
00135 KMatrix mcolorg( (float)KGETG(pControlPoint[12].Color), (float)KGETG(pControlPoint[13].Color), (float)KGETG(pControlPoint[14].Color), (float)KGETG(pControlPoint[15].Color),
00136 (float)KGETG(pControlPoint[8].Color), (float)KGETG(pControlPoint[9].Color), (float)KGETG(pControlPoint[10].Color), (float)KGETG(pControlPoint[11].Color),
00137 (float)KGETG(pControlPoint[4].Color), (float)KGETG(pControlPoint[5].Color), (float)KGETG(pControlPoint[6].Color), (float)KGETG(pControlPoint[7].Color),
00138 (float)KGETG(pControlPoint[0].Color), (float)KGETG(pControlPoint[1].Color), (float)KGETG(pControlPoint[2].Color), (float)KGETG(pControlPoint[3].Color) );
00139
00140 KMatrix mcolorb( (float)KGETB(pControlPoint[12].Color), (float)KGETB(pControlPoint[13].Color), (float)KGETB(pControlPoint[14].Color), (float)KGETB(pControlPoint[15].Color),
00141 (float)KGETB(pControlPoint[8].Color), (float)KGETB(pControlPoint[9].Color), (float)KGETB(pControlPoint[10].Color), (float)KGETB(pControlPoint[11].Color),
00142 (float)KGETB(pControlPoint[4].Color), (float)KGETB(pControlPoint[5].Color), (float)KGETB(pControlPoint[6].Color), (float)KGETB(pControlPoint[7].Color),
00143 (float)KGETB(pControlPoint[0].Color), (float)KGETB(pControlPoint[1].Color), (float)KGETB(pControlPoint[2].Color), (float)KGETB(pControlPoint[3].Color) );
00144
00145 KMatrix mspecular( (float)pControlPoint[12].Specular, (float)pControlPoint[13].Specular, (float)pControlPoint[14].Specular, (float)pControlPoint[15].Specular,
00146 (float)pControlPoint[8].Specular, (float)pControlPoint[9].Specular, (float)pControlPoint[10].Specular, (float)pControlPoint[11].Specular,
00147 (float)pControlPoint[4].Specular, (float)pControlPoint[5].Specular, (float)pControlPoint[6].Specular, (float)pControlPoint[7].Specular,
00148 (float)pControlPoint[0].Specular, (float)pControlPoint[1].Specular, (float)pControlPoint[2].Specular, (float)pControlPoint[3].Specular );
00149
00150 KMatrix mu1(pControlPoint[12].tu1, pControlPoint[13].tu1, pControlPoint[14].tu1, pControlPoint[15].tu1,
00151 pControlPoint[8].tu1, pControlPoint[9].tu1, pControlPoint[10].tu1, pControlPoint[11].tu1,
00152 pControlPoint[4].tu1, pControlPoint[5].tu1, pControlPoint[6].tu1, pControlPoint[7].tu1,
00153 pControlPoint[0].tu1, pControlPoint[1].tu1, pControlPoint[2].tu1, pControlPoint[3].tu1 );
00154
00155 KMatrix mv1(pControlPoint[12].tv1, pControlPoint[13].tv1, pControlPoint[14].tv1, pControlPoint[15].tv1,
00156 pControlPoint[8].tv1, pControlPoint[9].tv1, pControlPoint[10].tv1, pControlPoint[11].tv1,
00157 pControlPoint[4].tv1, pControlPoint[5].tv1, pControlPoint[6].tv1, pControlPoint[7].tv1,
00158 pControlPoint[0].tv1, pControlPoint[1].tv1, pControlPoint[2].tv1, pControlPoint[3].tv1 );
00159
00160 KMatrix mu2(pControlPoint[12].tu2, pControlPoint[13].tu2, pControlPoint[14].tu2, pControlPoint[15].tu2,
00161 pControlPoint[8].tu2, pControlPoint[9].tu2, pControlPoint[10].tu2, pControlPoint[11].tu2,
00162 pControlPoint[4].tu2, pControlPoint[5].tu2, pControlPoint[6].tu2, pControlPoint[7].tu2,
00163 pControlPoint[0].tu2, pControlPoint[1].tu2, pControlPoint[2].tu2, pControlPoint[3].tu2 );
00164
00165 KMatrix mv2(pControlPoint[12].tv2, pControlPoint[13].tv2, pControlPoint[14].tv2, pControlPoint[15].tv2,
00166 pControlPoint[8].tv2, pControlPoint[9].tv2, pControlPoint[10].tv2, pControlPoint[11].tv2,
00167 pControlPoint[4].tv2, pControlPoint[5].tv2, pControlPoint[6].tv2, pControlPoint[7].tv2,
00168 pControlPoint[0].tv2, pControlPoint[1].tv2, pControlPoint[2].tv2, pControlPoint[3].tv2 );
00169
00170 pV[y * n + x].Position.x = (float)GetBezierPoint( s, t, mx );
00171 pV[y * n + x].Position.y = (float)GetBezierPoint( s, t, my );
00172 pV[y * n + x].Position.z = (float)GetBezierPoint( s, t, mz );
00173 pV[y * n + x].Color = KRGBA( (u8)GetBezierPoint( s, t, mcolorr ), (u8)GetBezierPoint( s, t, mcolorg ), (u8)GetBezierPoint( s, t, mcolorb ), (u8)GetBezierPoint( s, t, mcolora ) );
00174 pV[y * n + x].Specular = (int)GetBezierPoint( s, t, mspecular );
00175 pV[y * n + x].tu1 = (float)GetBezierPoint( s, t, mu1 );
00176 pV[y * n + x].tv1 = (float)GetBezierPoint( s, t, mv1 );
00177 pV[y * n + x].tu2 = (float)GetBezierPoint( s, t, mu2 );
00178 pV[y * n + x].tv2 = (float)GetBezierPoint( s, t, mv2 );
00179 }
00180
00181
00182
00183 for( u32 v = 0; v < n * n; v ++ )
00184 m_pVertices[nVertex + v] = pV[v];
00185
00186 for( y = 0; y < n - 1; y ++ )
00187 for( x = 0; x < n - 1; x ++ )
00188 {
00189 m_pIndices[nIndices + 0] = (u16)(nVertex + y * n + x);
00190 m_pIndices[nIndices + 1] = (u16)(nVertex + y * n + (x + 1));
00191 m_pIndices[nIndices + 2] = (u16)(nVertex + (y + 1) * n + x);
00192 nIndices += 3;
00193
00194 m_pIndices[nIndices + 0] = (u16)(nVertex + (y + 1) * n + x);
00195 m_pIndices[nIndices + 1] = (u16)(nVertex + y * n + (x + 1));
00196 m_pIndices[nIndices + 2] = (u16)(nVertex + (y + 1) * n + (x + 1));
00197 nIndices += 3;
00198 }
00199
00200 nVertex += n * n;
00201 Deletev( pV );
00202 }
00203 }
00204
00205
00206 double KBezierPatch::GetBezierPoint( double s, double t, KMatrix& m )
00207 {
00208 return pow( 1 - s, 3 ) * ( m._11 * pow( 1 - t, 3 ) + 3 * m._21 * pow( 1 - t, 2 ) * t + 3 * m._31 * ( 1 - t ) * pow( t, 2 ) + m._41 * pow( t, 3 ) )
00209 + 3 * pow( 1 - s, 2 ) * s * ( m._12 * pow( 1 - t, 3 ) + 3 * m._22 * pow( 1 - t, 2 ) * t + 3 * m._32 * ( 1 - t ) * pow( t, 2 ) + m._42 * pow( t, 3 ) )
00210 + 3 * ( 1 - s ) * pow( s, 2 ) * ( m._13 * pow( 1 - t, 3 ) + 3 * m._23 * pow( 1 - t, 2 ) * t + 3 * m._33 * ( 1 - t ) * pow( t, 2 ) + m._43 * pow( t, 3 ) )
00211 + pow( s, 3 ) * ( m._14 * pow( 1 - t, 3 ) + 3 * m._24 * pow( 1 - t, 2 ) * t + 3 * m._34 * ( 1 - t ) * pow( t, 2 ) + m._44 * pow( t, 3 ) );
00212 }