22class DrawStrategyImpl : 
public DrawStrategy {
 
   28    enum ParticleDrawOrder { DRAWORDER_YOUNGERS_FIRST, DRAWORDER_ELDERS_FIRST };
 
   78        bool IsEqual(
const TextureData* _pData, f32 _scaleS, f32 _scaleT,
 
   79                     f32 _transS, f32 _transT, GXTexWrapMode _wrapS,
 
   80                     GXTexWrapMode _wrapT, 
math::VEC2 _scale, f32 _rotate,
 
   83            if (data != _pData || scaleS != _scaleS || scaleT != _scaleT ||
 
   84                transS != _transS || transT != _transT || wrapS != _wrapS ||
 
   85                wrapT != _wrapT || scale.x != _scale.x || scale.y != _scale.y ||
 
   86                rotate != _rotate || translate.x != _translate.x ||
 
   87                translate.y != _translate.y) {
 
   94        void Set(
const TextureData* _pData, f32 _scaleS, f32 _scaleT,
 
   95                 f32 _transS, f32 _transT, GXTexWrapMode _wrapS,
 
   96                 GXTexWrapMode _wrapT, 
math::VEC2 _scale, f32 _rotate,
 
  109            translate.x = _translate.x;
 
  110            translate.y = _translate.y;
 
 
  117    virtual GetFirstDrawParticleFunc
 
  118    GetGetFirstDrawParticleFunc(
int drawOrder); 
 
  120    virtual GetNextDrawParticleFunc
 
  121    GetGetNextDrawParticleFunc(
int drawOrder); 
 
  130                 const DrawInfo& rInfo, 
bool first, 
bool xfDirty);
 
  135        pParticle->GetMoveDir(pAxisY);
 
  137        if (!Normalize(pAxisY)) {
 
  138            *pAxisY = pContext->mCommon.mEmitterAxisY;
 
  142    static void CalcAhead_EmitterCenter(
math::VEC3* pAxisY,
 
  143                                        AheadContext* pContext,
 
  144                                        Particle* pParticle) {
 
  146        math::VEC3Sub(pAxisY, &pParticle->mParameter.mPosition,
 
  147                      &pContext->mCommon.mEmitterCenter);
 
  149        if (!Normalize(pAxisY)) {
 
  150            *pAxisY = pContext->mCommon.mEmitterAxisY;
 
  154    static void CalcAhead_EmitterDesign(math::VEC3* pAxisY,
 
  157        *pAxisY = pContext->mCommon.mEmitterAxisY;
 
  160    static void CalcAhead_Particle(math::VEC3* pAxisY, 
AheadContext* pContext,
 
  161                                   Particle* pParticle) {
 
  164            GetElderDrawParticle(pContext->mCommon.mParticleManager, pParticle);
 
  166        if (pElder != NULL) {
 
  167            math::VEC3Sub(pAxisY, &pElder->mParameter.mPosition,
 
  168                          &pParticle->mParameter.mPosition);
 
  170            math::VEC3Sub(pAxisY, &pParticle->mParameter.mPosition,
 
  171                          &pContext->mCommon.mEmitterCenter);
 
  174        if (!Normalize(pAxisY)) {
 
  175            *pAxisY = pContext->mCommon.mEmitterAxisY;
 
  179    static void CalcAhead_NoDesign(math::VEC3* pAxisY, 
AheadContext* pContext) {
 
  180        *pAxisY = math::VEC3(pContext->mNoDesign.mWorldYAxis);
 
  183    static void CalcAhead_ParticleBoth(math::VEC3* pAxisY,
 
  185                                       Particle* pParticle) {
 
  188            GetElderDrawParticle(pContext->mCommon.mParticleManager, pParticle);
 
  190        Particle* pYounger = GetYoungerDrawParticle(
 
  191            pContext->mCommon.mParticleManager, pParticle);
 
  193        math::VEC3 elderPos(0.0f, 0.0f, 0.0f);
 
  195        if (pElder != NULL) {
 
  196            math::VEC3Sub(&elderPos, &pElder->mParameter.mPosition,
 
  197                          &pParticle->mParameter.mPosition);
 
  199            if (!Normalize(&elderPos)) {
 
  200                elderPos = math::VEC3(0.0f, 0.0f, 0.0f);
 
  204        math::VEC3 youngerPos(0.0f, 0.0f, 0.0f);
 
  206        if (pYounger != NULL) {
 
  207            math::VEC3Sub(&youngerPos, &pYounger->mParameter.mPosition,
 
  208                          &pParticle->mParameter.mPosition);
 
  210            if (!Normalize(&youngerPos)) {
 
  211                youngerPos = math::VEC3(0.0f, 0.0f, 0.0f);
 
  215        math::VEC3Sub(pAxisY, &elderPos, &youngerPos);
 
  217        if (!Normalize(pAxisY)) {
 
  218            *pAxisY = pContext->mCommon.mEmitterAxisY;
 
  222    int GetNumDrawParticle(ParticleManager* pManager) {
 
  223        return pManager->mActivityList.GetNumActive();
 
  226    static Particle* GetElderParticle(ParticleManager* pManager,
 
  227                                      Particle* pParticle) {
 
  229        return static_cast<Particle*
>(
 
  230            NW4R_UT_LIST_GET_LINK(pManager->mActivityList.mActiveList,
 
  234    static Particle* GetYoungerParticle(ParticleManager* pManager,
 
  235                                        Particle* pParticle) {
 
  237        return static_cast<Particle*
>(
 
  238            NW4R_UT_LIST_GET_LINK(pManager->mActivityList.mActiveList,
 
  243    static Particle* GetOldestParticle(ParticleManager* pManager) {
 
  244        return static_cast<Particle*
>(
 
  245            pManager->mActivityList.mActiveList.headObject);
 
  247    static Particle* GetYoungestParticle(ParticleManager* pManager) {
 
  248        return static_cast<Particle*
>(
 
  249            pManager->mActivityList.mActiveList.tailObject);
 
  252    static Particle* GetElderDrawParticle(ParticleManager* pManager,
 
  253                                          Particle* pParticle) {
 
  255        Particle* pIt = GetElderParticle(pManager, pParticle);
 
  257        while (pIt != NULL &&
 
  258               pIt->GetLifeStatus() != ReferencedObject::NW4R_EF_LS_ACTIVE) {
 
  260            pIt = GetElderParticle(pManager, pIt);
 
  265    static Particle* GetYoungerDrawParticle(ParticleManager* pManager,
 
  266                                            Particle* pParticle) {
 
  268        Particle* pIt = GetYoungerParticle(pManager, pParticle);
 
  270        while (pIt != NULL &&
 
  271               pIt->GetLifeStatus() != ReferencedObject::NW4R_EF_LS_ACTIVE) {
 
  273            pIt = GetYoungerParticle(pManager, pIt);
 
  279    static Particle* GetOldestDrawParticle(ParticleManager* pManager) {
 
  280        Particle* pIt = GetOldestParticle(pManager);
 
  282        while (pIt != NULL &&
 
  283               pIt->GetLifeStatus() != ReferencedObject::NW4R_EF_LS_ACTIVE) {
 
  285            pIt = GetYoungerParticle(pManager, pIt);
 
  290    static Particle* GetYoungestDrawParticle(ParticleManager* pManager) {
 
  291        Particle* pIt = GetYoungestParticle(pManager);
 
  293        while (pIt != NULL &&
 
  294               pIt->GetLifeStatus() != ReferencedObject::NW4R_EF_LS_ACTIVE) {
 
  296            pIt = GetElderDrawParticle(pManager, pIt);
 
  302    static bool Normalize(math::VEC3* pVec) {
 
  303        f32 sqMag = math::VEC3Dot(pVec, pVec);
 
  305        if (sqMag < std::numeric_limits<f32>::epsilon()) {
 
  309        *pVec /= math::FSqrt(sqMag);
 
  313    static const math::VEC3& GetXUnitVec() {
 
  316    static const math::VEC3& GetYUnitVec() {
 
  319    static const math::VEC3& GetZUnitVec() {
 
  324    bool _SetupACmp(Particle* pParticle, 
const EmitterDrawSetting& rSetting,
 
  326    bool _SetupTevReg(Particle* pParticle, 
const EmitterDrawSetting& rSetting,
 
  328    bool _SetupTexture(Particle* pParticle, 
const EmitterDrawSetting& rSetting,
 
  329                       const DrawInfo& rInfo, 
bool first);
 
  332    GetFirstDrawParticle_EldersFirst(ParticleManager* pManager);
 
  335    GetFirstDrawParticle_YoungersFirst(ParticleManager* pManager);
 
  337    static Particle* GetNextDrawParticle_EldersFirst(ParticleManager* pManager,
 
  338                                                     Particle* pParticle);
 
  341    GetNextDrawParticle_YoungersFirst(ParticleManager* pManager,
 
  342                                      Particle* pParticle);
 
  346    GXColor mPrevColor[COLOR_LAYER_MAX][COLOR_IDX_MAX]; 
 
  352    int mTexmapMap[TEX_LAYER_MAX];                      
 
  354    static const math::VEC3 mXUnitVec;
 
  355    static const math::VEC3 mYUnitVec;
 
  356    static const math::VEC3 mZUnitVec;
 
  358    static const math::VEC3 mZeroVec;
 
  359    static const math::MTX34 mIdentityMtx;