泛型粒子系統的設計2 (轉)

themoney發表於2007-09-15
泛型粒子系統的設計2 (轉)[@more@]

現在我們已經可以很方便的組裝我們所需要的粒子結構了,但任存在一個問題。每當我們需要加入一個新的粒子部分時必須自定義一個類似SParticlePos的結構,如果我們設計的是一個粒子的拆分部分非常多的這無疑是一件非常枯燥的差事。有沒有什麼方法可以解決呢?我們不妨定義一個泛型的粒子部分::namespace prefix = o ns = "urn:schemas--com::office" />

// 粒子部分

template<

  typename _Type

> struct TParticlePart {

  _Type m_Value;

};

我們透過_Type模板引數來指定粒子部分的型別,比如原先的SParticlePos我們在使用D3D的平臺上可以寫成TParticlePart< D3DXVECTOR3 >。這樣的設計看似很好,其實隱藏著一個問題。如我們在D3D平臺上定義一個如下的粒子:

typedef TParticlePolicy<

  boost::mpl::vector<

  TParticlePart< D3DXVECTOR3 >,  // 位置

  TParticlePart< D3DXVECTOR3 >,  // 速度

  TParticlePart< D3DXCOLOR >,  // 顏色

  TParticlePart< FLOAT >,   // 壽命

  >

> tMyParticle;

tMyParticle p;

此時我們要訪問粒子的位置部分應該寫成p.m_Value,但如果你這樣寫就會抱怨產生了歧義。原因是不論你需要訪問的是位置、速度、顏色還是壽命都應該寫成p.m_Value,如何告訴編譯器你真正想要訪問的部分呢?這就需要引入一個用於區分不同部分的TPartDiff模板類,同時對TParticlePartHolder和TParticlePolicy做一些修改:

// 區分粒子的不同部分

template<

  class _Part,

  class _Diff

> class TPartDiff : public _Part

{};

// 粒子組裝器

template<

  class _PartIter,

  class _PartsVector

> class TParticlePartHolder

  : public TPartDiff<

  boost::mpl::deref< _PartIter >::type,

  boost::mpl::int_< _PartIter::pos::value >

  >

  , public TParticlePartHolder< _PartIter::next, _PartsVector >

{};

template<

  class _PartsVector

> class TParticlePartHolder< boost::mpl::end< _PartsVector >::type, _PartsVector >

  : public boost::blank

{};

// 粒子

template<

  class _PartsVector

> struct TParticlePolicy

  : public TParticlePartHolder< boost::mpl::begin< _PartsVector >::type, _PartsVector >

{

  typedef _PartsVector tPartsVector;

  // 部分數

  static const int s_ciNumOfParts = boost::mpl::size< _PartsVector >::type::value;

  // 獲取一個粒子部分

  template< size_t nIndex >

  TPartDiff< boost::mpl::at_c< _PartsVector, nIndex >::type, boost::mpl::int_< nIndex > >& Part( void ) {

  return *this;

  }

  // 獲取一個粒子部分

  template< size_t nIndex >

  const TPartDiff< boost::mpl::at_c< _PartsVector, nIndex >::type, boost::mpl::int_< nIndex > >& Part( void ) const {

  return *this;

  }

TPartDiff接受兩個模板引數第一個是形如TParticlePart< D3DXVECTOR3 >的粒子部分,第二個是用此粒子部分在粒子定義中的位置轉換的型別(透過boost::mpl::int_<>可以將常量轉換為型別)用於區分。TParticlePartHolder不再直接繼承粒子部分,而是透過TPartDiff繼承帶有區分的粒子部分。TParticlePolicy引入了一個公共模板成員Part()用於訪問不同的粒子部分,其有一個模板引數用於指定所需要訪問的粒子部分的索引,這個函式還有一個Const版本。如果我們要訪問以上定義的tMyParticle型別的粒子p的不同部分我們可以寫成:

p.Part< 0 >().m_Value; // 訪問粒子的位置

p.Part< 1 >().m_Value; // 訪問粒子的速度

p.Part< 2 >().m_Value; // 訪問粒子的顏色

p.Part< 3 >().m_Value; // 訪問粒子的壽命


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10794571/viewspace-969585/,如需轉載,請註明出處,否則將追究法律責任。

相關文章