Esempio n. 1
0
void CMoon::ReflectSun( SVector& vSunDirLocal_ )
{
	// 처음에 해는 보름달을 비추는 방향으로 있습니다 (지역좌표계에서)
	vSunDirLocal_.X = 0.0f;
	vSunDirLocal_.Y = 0.0f;
	vSunDirLocal_.Z = 1.0f;

	// 이제 달이 찬 정도를 이용해서 Pitch 값을 만들고 빛의 방향을 정합니다.
	SMatrix matSunDirRot;
	matSunDirRot.SetRotation( SRotator( Rad2Angle(fPi*(1.0f-m_fFillRate)), 0, 0 ) );
	vSunDirLocal_ = matSunDirRot.TransformNormal( vSunDirLocal_ );

	SMatrix matMoonPitch;
	matMoonPitch.SetRotation( SRotator( Rad2Angle(m_fPitch), 0, 0 ) );
	SMatrix matMoonRot;
	matMoonRot.SetRotation( SRotator( 0, 0, Rad2Angle(m_fRisingRate*fPi*2.0f)) );
	matMoonRot =  matMoonRot*matMoonPitch;
	vSunDirLocal_ = matMoonRot.TransformNormal( vSunDirLocal_ );
}
Esempio n. 2
0
void GDynamicActor::Tick( float DeltaSeconds )
{
	Super::Tick( DeltaSeconds );
	GrpSuper::TickGrp( DeltaSeconds );

	m_ftDelta = DeltaSeconds;

	float f = max(s_fTotalCullLength, GetCullLength());

	// Grid Item
	if( m_pGridItem )
	{
		m_pGridItem->Sphere().vecCenter = m_Locus.Location;
		m_pGridItem->Sphere().fRadius = Max( m_vExtent.Y, m_vExtent.X );
	}
	// Grid Field
	if( m_nGridCell!=INVALIDINDEX && s_pGridField!=NULL )
	{
		// Real Shape Shadow
		if( m_pShadow )
		{// 그림자를 가지고 있다면 자신이 속한 셀에서 가장 가까운 광원정보를 뽑고 전혀 뽑히지 않으면 태양광으로 한다.
			m_vNearestLightDir = s_vGlobalLightDir;
			
			vector<CSceneItem*> aItem;
			s_pGridField->FindItemOnPosition( m_Locus.Location, aItem );

			if( !aItem.empty() )
			{
				float fDistNearSq = 900000.0f;
				float fDistSq;
				for( dword nItem=0; nItem<aItem.size(); ++nItem )
				{
					CSceneItem *pItem = aItem[nItem];
					if( pItem->GetType()==SIT_LIGHTSOURCE )
					{
						DLightActor *pLightActor = DLightActor::GrpGetActor( pItem->GetSrcID() );
						if( pLightActor->GetLightClass().IsValid() )
						{
							fDistSq = (m_Locus.Location-pLightActor->m_Locus.Location).SizeSquared();
							if( fDistSq<fDistNearSq )
							{
								fDistNearSq = fDistSq;
								m_vNearestLightDir = pLightActor->m_Locus.Location-m_Locus.Location;
							}
						}
					}
				}
				
				m_vNearestLightDir.Normalize();
				static SVector vUp( 0.0f, 1.0f, 0.0f );
				float fDotNearLight = vUp|m_vNearestLightDir;
				if( fDotNearLight<0.34f ) // 0.34은 약 cos(70도)
				{// 너무 각도가 작은 광원은 적절한 수준으로 올리기
					float fYawNear = atan2f( m_vNearestLightDir.X, m_vNearestLightDir.Z );
					SMatrix matRot;
					matRot.SetRotation( SRotator(Rad2Angle(-0.349f), Rad2Angle(fYawNear), 0) );
					m_vNearestLightDir.X = 0.0f;
					m_vNearestLightDir.Y = 0.0f;
					m_vNearestLightDir.Z = 1.0f;
					m_vNearestLightDir = matRot.TransformNormal( m_vNearestLightDir );
				}

				// 그림자 멀어지면 흐릿하게 하기
				if( fDistNearSq>400.0f )
				{
					m_pShadow->SetColor( 0xFF777777 );
				}
				else if( fDistNearSq>4.0f )
				{
					float fR = (fDistNearSq-4.0f)/396.0f;
					if( fR>1.0f ) fR = 1.0f;
					byte byColor = (byte)(fR*255.0f);
					if( byColor<0x77 ) byColor = 0x77;
				
					m_pShadow->SetColor( byColor|(byColor<<8)|(byColor<<16)|0xFF000000 );
				}
				else
				{
					m_pShadow->SetColor( 0xFF777777 );
				}
			}
			else
			{
				m_vNearestLightDir.Normalize();
				static SVector vUp( 0.0f, 1.0f, 0.0f );
				float fDotNearLight = vUp|m_vNearestLightDir;
				if( fDotNearLight<0.34f ) // 0.34은 약 cos(70도)
				{// 너무 각도가 작은 광원은 적절한 수준으로 올리기
					float fYawNear = atan2f( m_vNearestLightDir.X, m_vNearestLightDir.Z );
					SMatrix matRot;
					matRot.SetRotation( SRotator(Rad2Angle(-0.349f), Rad2Angle(fYawNear), 0) );
					m_vNearestLightDir.X = 0.0f;
					m_vNearestLightDir.Y = 0.0f;
					m_vNearestLightDir.Z = 1.0f;
					m_vNearestLightDir = matRot.TransformNormal( m_vNearestLightDir );
				}
				m_pShadow->SetColor( 0xFF777777 );
			}
		}
		// Approx. Shape Shadow
		else if( m_pApproxShadow )
		{
			m_vNearestLightDir = SVector( 0.01f, 15.0f, -0.01f );
			m_pApproxShadow->SetColor( 0xFF454545 );
		}

		if( s_pGridField->TestValidity( m_Locus.Location, m_nGridCell ) ) { return; }
		// Cell 위치가 변해야 한다.
		s_pGridField->UpdateItemPosition( m_nGridCell, m_pGridItem, m_Locus.Location );
		m_pGridItem->Sphere().vecCenter = m_Locus.Location;
	}
}