Beispiel #1
0
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;
}