void VRendererNodeCommon::UpdateTimeOfDay()
{
  // Update the active sky.
  IVSky* pSky = m_spSky;
  if (pSky == NULL)
  {
    pSky = Vision::World.GetActiveSky();
  }
  if (pSky != NULL)
  {
    pSky->Tick(0);
  }

  // Update Time Of Day handler.
  IVTimeOfDay* pTimeOfDayInterface = Vision::Renderer.GetTimeOfDayHandler();
  if (pTimeOfDayInterface != NULL)
  {
    VASSERT_MSG(pTimeOfDayInterface->IsOfType(V_RUNTIME_CLASS(VTimeOfDay)),
      "Incompatible time of day handler installed - has to be VTimeOfDay or a subclass of it!");
    VTimeOfDay* pTimeOfDay = vstatic_cast<VTimeOfDay*>(pTimeOfDayInterface);
    pTimeOfDay->UpdateFogParameters();

    VColorRef vAmbientColor = pTimeOfDay->GetAmbientColor();
    Vision::Renderer.SetGlobalAmbientColor(vAmbientColor.ToFloat().getAsVec4(1.0f));
  }
  else
  {
    // Set the default global ambient color.
    Vision::Renderer.SetGlobalAmbientColor(Vision::Renderer.GetDefaultGlobalAmbientColor());
  }
}
 // Set color for subtractive shadows
 inline void SetShadowColor(const VColorRef &shadowColor)
 {
   hkvVec3 vShadowColor = shadowColor.ToFloat();
   float pParams[4] = { vShadowColor.x, vShadowColor.y, vShadowColor.z, 1.0f };
   m_RegShadowColor.SetRegisterValueSafeF(this, pParams);
 }
void VTimeOfDayComponent::UpdateParent()
{
  IVTimeOfDay *pTimeOfDayInterface = Vision::Renderer.GetTimeOfDayHandler();
  if (pTimeOfDayInterface == NULL)
    return;

  VisObject3D_cl *pOwnerObject = (VisObject3D_cl *)m_pOwner;
  VASSERT(pOwnerObject);

  hkvVec3 vDirection(hkvNoInitialization);
  pTimeOfDayInterface->GetSunDirection(vDirection);
  vDirection.normalizeIfNotZero();

  if (AttachmentType == TIMEOFDAY_ATTACHMENT_MOONLIGHTSOURCE)
  {
    vDirection = -vDirection; 
  }
  else if(AttachmentType == TIMEOFDAY_ATTACHMENT_SUNBACKLIGHTSOURCE)
  {
    vDirection.x = -vDirection.x;
    vDirection.y = -vDirection.y;
  }
  
  if (AttachmentType != TIMEOFDAY_ATTACHMENT_ENABLEDATNIGHTLIGHTSOURCE)
  {
    pOwnerObject->SetDirection(vDirection);
  }

  if (AttachmentType == TIMEOFDAY_ATTACHMENT_CORONALIGHTSOURCE)
  {
    // TODO (multiple renderer nodes)
    IVRendererNode *pRenderer = Vision::Renderer.GetRendererNode(0);
    float fNear, fFar;
    pRenderer->GetReferenceContext()->GetClipPlanes(fNear, fFar);
    hkvVec3 vCamPos = pRenderer->GetReferenceContext()->GetCamera()->GetPosition();

    hkvVec3 vCoronaPos = -vDirection;
    vCoronaPos *= 0.95f * fFar;
    vCoronaPos += vCamPos;
    pOwnerObject->SetPosition(vCoronaPos);
  }

  if (m_bIsLightClass)
  {
    VisLightSource_cl *pLight = (VisLightSource_cl*)m_pOwner;
    VColorRef sunColor = pTimeOfDayInterface->GetSunColor();

    bool bSwitchable = (AttachmentType == TIMEOFDAY_ATTACHMENT_ENABLEDATNIGHTLIGHTSOURCE);
    float fBelowHorizonMultiplier = hkvMath::pow (hkvMath::Max(-vDirection.z+0.1f, 0.0f), bSwitchable ? 1.0f : 0.1f);
    fBelowHorizonMultiplier = hkvMath::Min(1.0f, fBelowHorizonMultiplier);

    if (bSwitchable && fBelowHorizonMultiplier < 1.0f && fBelowHorizonMultiplier > 0.f)
    {
      pLight->SetColor(m_iColor);
      pLight->SetMultiplier(Intensity * (1.0f - fBelowHorizonMultiplier));
    }
    else if (AttachmentType == TIMEOFDAY_ATTACHMENT_SUNLIGHTSOURCE)
    {
      pLight->SetColor(sunColor);
      pLight->SetMultiplier(Intensity * fBelowHorizonMultiplier);
    }
    else if ((AttachmentType == TIMEOFDAY_ATTACHMENT_MOONLIGHTSOURCE) ||
             (AttachmentType == TIMEOFDAY_ATTACHMENT_SUNBACKLIGHTSOURCE))
    {
      // TODO
      VColorRef negativeColor = V_RGBA_WHITE - sunColor;
      pLight->SetColor(negativeColor);
      pLight->SetMultiplier(Intensity * fBelowHorizonMultiplier * 0.333f);
    }  
    else if (AttachmentType == TIMEOFDAY_ATTACHMENT_CORONALIGHTSOURCE)
    {
      hkvVec3 vSunColorFloat = sunColor.ToFloat();
      float fLargestComponent = hkvMath::Max(hkvMath::Max(vSunColorFloat.x, vSunColorFloat.y), vSunColorFloat.z);
      if (fLargestComponent <= 0.0f)
        fLargestComponent = 1.0f;
      sunColor.FromFloat(vSunColorFloat * (1.0f / fLargestComponent));

      pLight->SetColor(sunColor * fBelowHorizonMultiplier);
      pLight->SetMultiplier(0.0f);
    }
  }
}
void VTimeOfDayComponent::UpdateParent()
{
  VTimeOfDay *pTimeOfDayInterface = (VTimeOfDay*)Vision::Renderer.GetTimeOfDayHandler();
  if (pTimeOfDayInterface == NULL)
    return;

  VisObject3D_cl *pOwnerObject = (VisObject3D_cl *)m_pOwner;
  VASSERT(pOwnerObject);

  hkvVec3 vDirection(hkvNoInitialization);
  pTimeOfDayInterface->GetSunDirection(vDirection);

  // The Moon and back light direction is calculated from the Sun direction
  if (AttachmentType == TIMEOFDAY_ATTACHMENT_MOONLIGHTSOURCE)
  {
    vDirection = -vDirection; 
  }
  else if(AttachmentType == TIMEOFDAY_ATTACHMENT_SUNBACKLIGHTSOURCE)
  {
    vDirection.x = -vDirection.x;
    vDirection.y = -vDirection.y;
  }
  
  if (AttachmentType != TIMEOFDAY_ATTACHMENT_ENABLEDATNIGHTLIGHTSOURCE)
  {
    pOwnerObject->SetDirection(vDirection);
  }

  if (AttachmentType == TIMEOFDAY_ATTACHMENT_CORONALIGHTSOURCE)
  {
    // TODO (multiple renderer nodes)
    IVRendererNode *pRenderer = Vision::Renderer.GetRendererNode(0);
    float fNear, fFar;
    pRenderer->GetReferenceContext()->GetClipPlanes(fNear, fFar);
    hkvVec3 vCamPos = pRenderer->GetReferenceContext()->GetCamera()->GetPosition();

    hkvVec3 vCoronaPos = -vDirection;
    vCoronaPos *= 0.95f * fFar;
    vCoronaPos += vCamPos;
    pOwnerObject->SetPosition(vCoronaPos);
  }

  // Set the color and intensity of the light
  if (m_bIsLightClass)
  {
    VisLightSource_cl *pLight = (VisLightSource_cl*)m_pOwner;
    VColorRef color;
    float intensity = 0.0f;

    switch (AttachmentType)
    {
    case TIMEOFDAY_ATTACHMENT_ENABLEDATNIGHTLIGHTSOURCE:
      {
        color = m_iColor;
        const float fMarginNearHorizon = 0.1f; //10% - Margin above the horizon to switch lights ON/OFF
        const float fBelowHorizonMultiplier = hkvMath::Max(-vDirection.z + fMarginNearHorizon, 0.0f);
        intensity = 1.0f - hkvMath::Min(1.0f, fBelowHorizonMultiplier);
        break;
      }
    case TIMEOFDAY_ATTACHMENT_CORONALIGHTSOURCE:
      {
        color = pTimeOfDayInterface->GetSunColor();
        hkvVec3 vSunColorFloat = color.ToFloat();
        float fLargestComponent = hkvMath::Max(hkvMath::Max(vSunColorFloat.x, vSunColorFloat.y), vSunColorFloat.z);
        if (fLargestComponent > 0.0f)
        {
          color.FromFloat(vSunColorFloat / fLargestComponent);
        }      
        intensity = 0.0f;
        break;
      }
    case TIMEOFDAY_ATTACHMENT_SUNLIGHTSOURCE:
      {
        color = pTimeOfDayInterface->GetSunColor();
        intensity = pTimeOfDayInterface->GetSunIntensity();
        break;
      }
    case TIMEOFDAY_ATTACHMENT_SUNBACKLIGHTSOURCE:
      {
        color = pTimeOfDayInterface->GetBackLightColor();
        intensity = pTimeOfDayInterface->GetBackLightIntensity();
        break;
      }
    case TIMEOFDAY_ATTACHMENT_MOONLIGHTSOURCE:
      {
        color = pTimeOfDayInterface->GetMoonColor();
        intensity = pTimeOfDayInterface->GetMoonIntensity();
        break;
      }
    default:
      VASSERT_MSG(0,"Unknown time of day attachment type");
    }

    pLight->SetColor(color);
    pLight->SetMultiplier(intensity * Intensity);    
  }
}