⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bezier.h

📁 <B>DirectX9.0 3D游戏编程</B>
💻 H
字号:
/********************************************************************
 *         Advanced 3D Game Programming using DirectX 9.0			*
 ********************************************************************
 * copyright (c) 2003 by Peter A Walsh and Adrian Perez				*
 * See license.txt for modification and distribution information	*
 ********************************************************************/

#ifndef _BEZIER_H
#define _BEZIER_H

#include "stdafx.h"
#include "..\math3d\tri.h"

class cBezierObject;

#define sTri tri<short>

/**
 * Bezier Patch class
 */
class cBezierPatch
{
	// Size (width, height) of the patch.
	int			m_size; 
	
	// Control points for the patch
	point3		m_ctrlPoints[16];

	// holds the tesselated points
	sVertex*	m_vertList; 
	
	// list of all the triangle indices for triangle drawing.		
	sTri*		m_triList;

	// holds the u-dir tangents (for normal generation)
	point3*		m_uTangList; 
	// holds the v-dir tangents (for normal generation)
	point3*		m_vTangList; 

	static matrix4		m_basisMatrix;

	friend class cFwdDiffIterator;
	friend class cTangentIterator;
	friend class cBezierObject;

public:
	cBezierPatch(); // Default constructor
	~cBezierPatch();

	void Init( int size ); // size is the dimension we should init to

	void Tesselate(); // fill the vert list with tesselated values

	void Draw( bool bDrawNet );
	void Load( cFile& file );

};

/**
 * Bezier object (set of patches)
 */
class cBezierObject
{
	int				m_nPatches;
	cBezierPatch	*m_patchList; // our list of patches

public:

	// increment and decrement the level of patch tesselation in the object
	void IncTesselation()
	{

		for( int i=0; i< m_nPatches; i++ )
		{
			if( m_patchList[i].m_size < 10 )
				m_patchList[i].Init( m_patchList[i].m_size+1 );
			else
				m_patchList[i].Init( m_patchList[i].m_size+2 );
		}
	}
	void DecTesselation()
	{
		for( int i=0; i< m_nPatches; i++ )
		{
			if( m_patchList[i].m_size > 10 )
				m_patchList[i].Init( m_patchList[i].m_size-2 );
			else if( m_patchList[i].m_size > 3 )
				m_patchList[i].Init( m_patchList[i].m_size-1 );
		}
	}


	cBezierObject();
	~cBezierObject();

	void Load( char* filename );
	void Draw( const matrix4& mat, bool bDrawNet );
};


class cTangentIterator
{
	int		m_i; // our current step in the iteration
	int		m_nSteps; // the number of steps
	point4	m_p[3]; // for x, y, and z
	point3	m_cPts[4];

	point3	m_Q; // the point at the current iteration location

	void CalcQ()
	{
		float t = (float)m_i / (m_nSteps-1);
		point4 tVec( 3*t*t, 2*t, 1, 0 );
		point4 pVec;

		point4 temp = tVec * cBezierPatch::m_basisMatrix;
		m_Q.x = m_p[0] * temp; 
		m_Q.y = m_p[1] * temp; 
		m_Q.z = m_p[2] * temp; 
	}

public:
	cTangentIterator( int nSteps, point3 p1, point3 p2, point3 p3, point3 p4 )
	{
		m_cPts[0] = p1;
		m_cPts[1] = p2;
		m_cPts[2] = p3;
		m_cPts[3] = p4;

		m_nSteps = nSteps;
		m_p[0].Assign( p1.x, p2.x, p3.x, p4.x );
		m_p[1].Assign( p1.y, p2.y, p3.y, p4.y );
		m_p[2].Assign( p1.z, p2.z, p3.z, p4.z );
	}

	void Start()
	{
		m_i = 0;

		CalcQ();
	}

	bool Done()
	{
		return !(m_i<m_nSteps); 
	}

	point3& GetCurr()
	{
		return m_Q;
	}

	operator point3&()
	{
		return m_Q;
	}

	void CalcNext()
	{
		m_i++;
		CalcQ();
	}
};


class cFwdDiffIterator
{
	int		m_i; // our current step in the iteration
	int		m_nSteps; // the number of steps

	point3	m_p[4]; // The 4 control points

	point3	m_Q; // the point at the current iteration location

	point3	m_dQ; // First derivative (initially at zero)
	point3	m_ddQ; // Second derivative (initially at zero)
	point3	m_dddQ; // Triple derivative (constant)

public:
	cFwdDiffIterator()
	{
		// Do nothing
	}
	cFwdDiffIterator( int nSteps, point3 p1, point3 p2, point3 p3, point3 p4 )
	{
		m_nSteps = nSteps;
		m_p[0] = p1;
		m_p[1] = p2;
		m_p[2] = p3;
		m_p[3] = p4;
	}

	void Start()
	{
		m_i = 0;

		float d = 1.f/(m_nSteps-1);
		float d2 = d*d; // d^2
		float d3 = d*d2;// d^3

		point4 px( m_p[0].x, m_p[1].x, m_p[2].x, m_p[3].x );
		point4 py( m_p[0].y, m_p[1].y, m_p[2].y, m_p[3].y );
		point4 pz( m_p[0].z, m_p[1].z, m_p[2].z, m_p[3].z );

		point4 cVec[3]; // <a, b, c, d> for x, y, and z.
		cVec[0] = px * cBezierPatch::m_basisMatrix;
		cVec[1] = py * cBezierPatch::m_basisMatrix;
		cVec[2] = pz * cBezierPatch::m_basisMatrix;

		m_Q = m_p[0];

		// Do the work for each component
		int i = 3;
		while (i--)
		{
			// remember that t=0 here so many of the terms 
			// in the text drop out.
			float a = cVec[i].v[0];
			float b = cVec[i].v[1];
			float c = cVec[i].v[2];
			// luckily d isn't used, which 
			// would clash with the other d.

			m_dQ.v[i] = a * d3 + b * d2 + c * d;
			m_ddQ.v[i] = 6 * a * d3 + 2 * b * d2;
			m_dddQ.v[i] = 6 * a * d3;
		}
	}

	bool Done()
	{
		return !(m_i<m_nSteps); 
	}

	point3& GetCurr()
	{
		return m_Q;
	}

	operator point3&()
	{
		return m_Q;
	}

	void CalcNext()
	{
		m_Q += m_dQ;
		m_dQ += m_ddQ;
		m_ddQ += m_dddQ;
		
		m_i++;
	}
};

#endif//_BEZIER_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -