#pragma warning(disable:4244)
#pragma warning(disable:4800)
#pragma warning(disable:4305)
// Comment this line if you have algebra.h
//#define NO_ALGEBRA_H
#include <d3d.h>
#include <assert.h>
#ifndef NO_ALGEBRA_H
#include "algebra.h"
#endif
#include "bezier.h"
// Globals
D3DVERTEX D3DVerts[6] = { { 0 } };
bool DrawCtrl, DrawLines, DrawPolys;
int PointCount;
// Bezier basis functions
void bez(float u, float* bez)
{
float invu = 1 - u;
bez[0] = invu * invu * invu;
bez[1] = 3 * u * invu * invu;
bez[2] = 3 * u * u * invu;
bez[3] = u * u * u;
}
// TCtrlPoints - bezier basis function inputs. A TCtrlPoints is created from the inner sections
// of 4 TPatchVertex objects by DrawPatch.
typedef vector3d TCtrlPoints[4][4];
void GetPatchPoint( float u, float v, TCtrlPoints* Ctrl, vector3d* Out )
{
vector3d Point( 0, 0, 0 ); // Output
// Keep track of how many Points evaluated per frame.
PointCount++;
float bezx[4], bezy[4];
bez( u, bezx );
bez( v, bezy );
int i, j;
for ( i = 0; i < 4; i++ )
for ( j = 0; j < 4; j++ )
{
vector3d* cp = &( *Ctrl )[j][i];
float cpscale = bezx[j] * bezy[i];
Point.x += cp->x * cpscale;
Point.y += cp->y * cpscale;
Point.z += cp->z * cpscale;
}
*Out = Point;
}
void DrawPatch( LPDIRECT3DDEVICE7 pd3dDevice, SPatch* Patch, TPatchVertex* VertexPool, float Subdiv )
{
TCtrlPoints Ctrl; // 16 control Points that ultimately define SPatch
TPatchVertex* pv;
// Get control Points from TL SPatch vertex.
pv = &VertexPool[Patch->Verts[0]];
Ctrl[0][0] = (*pv)[1][1];
Ctrl[1][0] = (*pv)[2][1];
Ctrl[0][1] = (*pv)[1][2];
Ctrl[1][1] = (*pv)[2][2];
// Get control Points from TR SPatch vertex.
pv = &VertexPool[Patch->Verts[1]];
Ctrl[2][0] = (*pv)[0][1];
Ctrl[3][0] = (*pv)[1][1];
Ctrl[2][1] = (*pv)[0][2];
Ctrl[3][1] = (*pv)[1][2];
// Get control Points from BR SPatch vertex.
pv = &VertexPool[Patch->Verts[2]];
Ctrl[2][2] = (*pv)[0][0];
Ctrl[3][2] = (*pv)[1][0];
Ctrl[2][3] = (*pv)[0][1];
Ctrl[3][3] = (*pv)[1][1];
// Get control Points from BL SPatch vertex.
pv = &VertexPool[Patch->Verts[3]];
Ctrl[0][2] = (*pv)[1][0];
Ctrl[1][2] = (*pv)[2][0];
Ctrl[0][3] = (*pv)[1][1];
Ctrl[1][3] = (*pv)[2][1];
if ( DrawCtrl )
{
// draw the control poxnts.
for ( int x = 0; x < 3; x++ )
for ( int y = 0; y < 3; y++ )
{
D3DVerts[0].x = Ctrl[x][y].x;
D3DVerts[0].y = Ctrl[x][y].y;
D3DVerts[0].z = Ctrl[x][y].z;
D3DVerts[1].x = Ctrl[x + 1][y].x;
D3DVerts[1].y = Ctrl[x + 1][y].y;
D3DVerts[1].z = Ctrl[x + 1][y].z;
D3DVerts[2].x = Ctrl[x + 1][y + 1].x;
D3DVerts[2].y = Ctrl[x + 1][y + 1].y;
D3DVerts[2].z = Ctrl[x + 1][y + 1].z;
D3DVerts[3].x = Ctrl[x][y + 1].x;
D3DVerts[3].y = Ctrl[x][y + 1].y;
D3DVerts[3].z = Ctrl[x][y + 1].z;
D3DVerts[4].x = Ctrl[x][y].x;
D3DVerts[4].y = Ctrl[x][y].y;
D3DVerts[4].z = Ctrl[x][y].z;
pd3dDevice->DrawPrimitive( D3DPT_LINESTRIP, D3DFVF_VERTEX, D3DVerts, 5, NULL );
}
}
if ( DrawLines || DrawPolys )
{
assert( Subdiv >= 1.0 );
float Step = 1.0 / Subdiv;
// ok, now draw the curve Points
for ( float i = 0.0; i < 1.0; i += Step )
for ( float j = 0.0; j < 1.0; j += Step )
{
vector3d v;
float di = Step, dj = Step;
if ( i + di > 1.0 )
di = 1.0 - i;
if ( j + dj > 1.0 )
dj = 1.0 - j;
// triangle 1
GetPatchPoint( i, j, &Ctrl, &v );
D3DVerts[0].x = v.x;
D3DVerts[0].y = v.y;
D3DVerts[0].z = v.z;
D3DVerts[0].tu = i;
D3DVerts[0].tv = j;
GetPatchPoint( i + di, j, &Ctrl, &v );
D3DVerts[1].x = v.x;
D3DVerts[1].y = v.y;
D3DVerts[1].z = v.z;
D3DVerts[1].tu = i + di;
D3DVerts[1].tv = j;
GetPatchPoint( i, j + dj, &Ctrl, &v );
D3DVerts[2].x = v.x;
D3DVerts[2].y = v.y;
D3DVerts[2].z = v.z;
D3DVerts[2].tu = i;
D3DVerts[2].tv = j + dj;
GetPatchPoint( i + di, j + dj, &Ctrl, &v );
D3DVerts[3].x = v.x;
D3DVerts[3].y = v.y;
D3DVerts[3].z = v.z;
D3DVerts[3].tu = i + di;
D3DVerts[3].tv = j + dj;
if ( DrawPolys )
pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX, D3DVerts, 4, NULL );
if ( DrawLines )
{
// Flip stuff around to get the extra lines.
D3DVERTEX TempVert = D3DVerts[2];
D3DVerts[2] = D3DVerts[3];
D3DVerts[3] = TempVert;
D3DVerts[4] = D3DVerts[0];
D3DVerts[5] = D3DVerts[2];
pd3dDevice->DrawPrimitive( D3DPT_LINESTRIP, D3DFVF_VERTEX, D3DVerts, 6, NULL );
}
}
}
}
|