コード例 #1
0
ファイル: GlobalRendering.cpp プロジェクト: mistletoe/spring
void CGlobalRendering::UpdateSunParams(float4 newSunDir, float startAngle, float orbitTime, bool iscompat) {
	newSunDir.ANormalize();
	sunStartAngle = startAngle;
	sunOrbitTime = orbitTime;

	initialSunAngle = fastmath::coords2angle(newSunDir.x, newSunDir.z);

	if(iscompat) { // backwards compatible: sunDir is position where sun reaches highest altitude
		float sunLen = newSunDir.Length2D();
		float sunAzimuth = (sunLen <= 0.001f) ? PI / 2.0f : atan(newSunDir.y / sunLen);
		float sunHeight = tan(sunAzimuth - 0.001f);

		float orbitMinSunHeight = 0.1f; // the lowest sun altitude for an auto generated orbit
		float3 v1(cos(initialSunAngle), sunHeight, sin(initialSunAngle));
		v1.ANormalize();

		if(v1.y <= orbitMinSunHeight) {
			newSunDir = float3(0.0f, 1.0f, 0.0f);
			sunOrbitHeight = v1.y;
			sunOrbitRad = sqrt(1.0f - sunOrbitHeight * sunOrbitHeight);
		}
		else {
			float3 v2(cos(initialSunAngle + PI), orbitMinSunHeight, sin(initialSunAngle + PI));
			v2.ANormalize();
			float3 v3 = v2 - v1;
			sunOrbitRad = v3.Length() / 2.0f;
			v3.ANormalize();
			float3 v4 = v3.cross(float3(0.0f, 1.0f, 0.0f));
			v4.ANormalize();
			float3 v5 = v3.cross(v4);
			v5.ANormalize();
			if(v5.y < 0)
				v5 = -v5;
			newSunDir = v5;
			sunOrbitHeight = v5.dot(v1);
		}
	}
	else { // new: sunDir is center position of orbit, and sunDir.w is orbit height
		sunOrbitHeight = std::max(-1.0f, std::min(newSunDir.w, 1.0f));
		sunOrbitRad = sqrt(1.0f - sunOrbitHeight * sunOrbitHeight);
	}

	sunRotation.LoadIdentity();
	sunRotation.SetUpVector(newSunDir);

	float4 peakSunDir = CalculateSunDir(0.0f);
	shadowDensityFactor = 1.0f / std::max(0.01f, peakSunDir.y);
	UpdateSun(true);
}
	void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo )
	{
		switch (event)
		{
			case eFE_Initialize:
			{
				m_blending = false;
				m_paused = false;
				break;
			}

			case eFE_Activate:
			{
				ITimeOfDay* pTOD = gEnv->p3DEngine->GetTimeOfDay();
				if (!pTOD)
					break;

				if (IsPortActive(pActInfo,IN_START))
				{
					pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, true );
					m_durationLeft = GetPortFloat( pActInfo, IN_DURATION );
					m_sunTimeToUpdate = GetPortFloat( pActInfo, IN_SUN_POSITION_UPDATE_INTERVAL );
					m_TODTimeToUpdate = GetPortFloat( pActInfo, IN_TOD_FORCE_UPDATE_INTERVAL );
					m_startSunLongitude = pTOD->GetSunLongitude();
					m_startSunLatitude = pTOD->GetSunLatitude();
					m_startTOD = pTOD->GetTime();
					m_blending = true;
					m_paused = false;
					m_activeID = m_ID;
				}
				if (IsPortActive(pActInfo,IN_PAUSE))
				{
					if (m_blending)
					{
						m_paused = !m_paused;
						pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, !m_paused );
					}
				}
				break;
			}

			case eFE_Update:
			{
				if (m_activeID!=m_ID)
				{
					pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
					m_blending = false;
					break;
				}

				ITimeOfDay* pTOD = gEnv->p3DEngine->GetTimeOfDay();
				if (!pTOD)
					break;

				m_durationLeft -= gEnv->pTimer->GetFrameTime();
				bool forceUpdate = false;
				if (m_durationLeft<=0)
				{
					m_durationLeft = 0;
					m_blending = false;
					pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
					ActivateOutput( pActInfo, OUT_DONE, true );
					forceUpdate = true;
					m_activeID = 0xffffffff;
				}
				float totalDuration = GetPortFloat(pActInfo, IN_DURATION);
				float blendPos = totalDuration==0 ? 1.f : 1.f - (m_durationLeft / totalDuration);

				bool needUpdate = UpdateTOD( blendPos, pActInfo, pTOD, forceUpdate );
				needUpdate |= UpdateSun( blendPos, pActInfo, pTOD, forceUpdate );

				if (needUpdate)
					pTOD->Update( true, true );
				break;
			}
		}
	}