CGroupTag::CGroupTag(CTag &tag) { //tag m_eType = TT_GROUP; m_strName = tag.GetName(); m_fMaxTimeLength = tag.GetMaxTimeLength(); m_vOffsetPos = tag.GetOffsetPos(); m_qOffsetRot = tag.GetOffsetRot(); this->AddNewTagInfo(tag.CurrentTagInfo()); }
BOOL CEffectGroup::Process(FLOAT time) { if(!m_bActive) return FALSE; // 1/50의 정확도를 갖는다. //if( time - m_fLastProcessedTime < 0.02f ) return TRUE; FLOAT fProcessedTime = time - m_fStartTime; m_fLastProcessedTime = time; if(!m_bDirectTag) { //tag change 처리 for(INDEX i=0; i<m_vectorTagKey.size(); ++i) { if(m_vectorTagKey[i].m_fSettingTime * m_fSpeedMul > fProcessedTime) continue; //tag를 붙임. 매프레임마다 처리됨. (계속 붙음) EffectKey* effectkey = FindEffectKey(m_vectorTagKey[i].m_iEffectKeyValue); if (effectkey && effectkey->m_pCreatedEffect) { effectkey->m_pCreatedEffect->AttachToTag(m_vectorTagKey[i].m_ptrReserveTag); } } } //effect 처리 CAnyProjection3D &apr = *m_pProjection; BOOL bTestCulling = m_pProjection != NULL && apr.ap_CurrentProjection != NULL; BOOL ret = FALSE; for(INDEX i=0; i<m_vectorEffectKey.size(); ++i) { EffectKey &effectKey = m_vectorEffectKey[ i ]; //시작 시간을 지났으므로 시작한다. 시간은 정해진 시작시간으로 세팅한다. if(effectKey.m_pCreatedEffect->GetState() == ES_NOT_STARTED && time >= effectKey.m_fStartTime * m_fSpeedMul + m_fStartTime) { effectKey.m_pCreatedEffect->Start( m_fStartTime + effectKey.m_fStartTime * m_fSpeedMul ); if(effectKey.m_pCreatedEffect->GetTag().NotNull() && !effectKey.m_pCreatedEffect->GetTag()->Active() && effectKey.m_pCreatedEffect->Playing()) effectKey.m_pCreatedEffect->SetNotRenderAtThisFrame(); } //플레이 상태가 아니면 다음으로 넘어감 if(effectKey.m_pCreatedEffect->Playing() == FALSE) { if(effectKey.m_pCreatedEffect->GetState() == ES_NOT_STARTED) { ret |= TRUE; continue; } else if(effectKey.m_pCreatedEffect->GetState() == ES_PLAY_END && effectKey.m_pCreatedEffect->GetRepeatCount() != 0) { effectKey.m_pCreatedEffect->Start(time); if(effectKey.m_pCreatedEffect->Playing() == FALSE) { if(effectKey.m_pCreatedEffect->GetState() == ES_NOT_STARTED) ret |= TRUE; continue; } } else continue; } if(bTestCulling && effectKey.m_pCreatedEffect->GetType() != ET_SOUND && effectKey.m_pCreatedEffect->GetType() != ET_CAMERA) { BOOL bNoPassTest = FALSE; //거리 테스트, 먼저 한다. CTag *pTagTest = NULL; if(effectKey.m_pCreatedEffect->GetTag()->GetType() != TT_GROUP) { pTagTest = effectKey.m_pCreatedEffect->GetTag().GetNative(); } else { pTagTest = ((CGroupTag*)effectKey.m_pCreatedEffect->GetTag().GetNative())->GetTag(0).GetNative(); } bNoPassTest = (g_fEffectDistance < fabs(apr->GetDistance( pTagTest->CurrentTagInfo().m_vPos ))); if(!bNoPassTest) { //Frustum 테스트 FLOAT fPerspectiveFactor = 1.0f; if( apr.IsPerspective()) fPerspectiveFactor = ((CPerspectiveProjection3D*)&*apr)->ppr_PerspectiveRatios(1); // project point to screen FLOAT3D vProjected; apr->PreClip( pTagTest->CurrentTagInfo().m_vPos, vProjected); // skip if too small const FLOAT fPixSize = effectKey.m_pCreatedEffect->GetBoundingSphereRadius() * fPerspectiveFactor / vProjected(3); if( fPixSize < 0.5f ) bNoPassTest = TRUE; // skip if not in screen const INDEX iTested = apr->TestSphereToFrustum( vProjected, effectKey.m_pCreatedEffect->GetBoundingSphereRadius() ); if( iTested < 0 ) bNoPassTest = TRUE; } if(bNoPassTest) { effectKey.m_pCreatedEffect->SetNotRenderAtThisFrame(); if(effectKey.m_pCreatedEffect->GetType() == ET_SPLINEBILLBOARD || effectKey.m_pCreatedEffect->GetType() == ET_ORBIT) { effectKey.m_pCreatedEffect->Stop(0); } } } if(!effectKey.m_pCreatedEffect->IsNotRenderAtThisFrame()) { //Processing, 내부적으로 상태가 변할 수 있음. BOOL processRet = effectKey.m_pCreatedEffect->Process(time); ret = ret || processRet; } else ret = TRUE; } return ret; }