// Rotating sponge
void Anim()
{
    static DWORD s_PrevTick = GetTickCount();
    DWORD tick = GetTickCount(); // msec
    float dt = float(tick - s_PrevTick) / 1000.0f; // sec
    if (g_Animate && dt > 0 && dt < 0.2f)
    {
        Vector3 axis = Vector3::ZERO;
        float angle = 0;
        AxisAngleFromRotation(axis, angle, g_SpongeRotation);
        if (Length(axis) < 1.0e-6f) 
            axis.v[1] = 1;
        angle += g_AnimationSpeed * dt;
        if (angle >= 2.0f*FLOAT_PI)
            angle -= 2.0f*FLOAT_PI;
        else if (angle <= 0)
            angle += 2.0f*FLOAT_PI;
        g_SpongeRotation = RotationFromAxisAngle(axis, angle);
    }
    s_PrevTick = tick;
}
void AtmosphereSample::Update(double CurrTime, double ElapsedTime)
{
    SampleBase::Update(CurrTime, ElapsedTime);

    m_fElapsedTime = static_cast<float>(ElapsedTime);

    const auto& SCDesc = m_pSwapChain->GetDesc();
    // Set world/view/proj matrices and global shader constants
    float aspectRatio = (float)SCDesc.Width / SCDesc.Height;

    float3 CamZ = normalize( m_f3CameraDir );
    float3 CamX = normalize( cross( float3( 0, 1, 0 ), CamZ ) );
    float3 CamY = normalize( cross( CamZ, CamX ) );

    m_mCameraView =
        translationMatrix( -m_f3CameraPos ) *
        ViewMatrixFromBasis( CamX, CamY, CamZ );


    // This projection matrix is only used to set up directions in view frustum
    // Actual near and far planes are ignored
    float FOV = (float)M_PI/4.f;
    float4x4 mTmpProj = Projection(FOV, aspectRatio, 50.f, 500000.f, m_bIsDXDevice);

    float fEarthRadius = AirScatteringAttribs().fEarthRadius;
    float3 EarthCenter(0, -fEarthRadius, 0);
    float fNearPlaneZ, fFarPlaneZ;
    ComputeApproximateNearFarPlaneDist(m_f3CameraPos,
                                       m_mCameraView,
                                       mTmpProj,
                                       EarthCenter,
                                       fEarthRadius,
                                       fEarthRadius + m_fMinElevation,
                                       fEarthRadius + m_fMaxElevation,
                                       fNearPlaneZ,
                                       fFarPlaneZ);
    fNearPlaneZ = std::max(fNearPlaneZ, 50.f);
    fFarPlaneZ  = std::max(fFarPlaneZ, fNearPlaneZ+100.f);
    fFarPlaneZ  = std::max(fFarPlaneZ, 1000.f);

    m_mCameraProj = Projection(FOV, aspectRatio, fNearPlaneZ, fFarPlaneZ, m_bIsDXDevice);

#if 0
    if( m_bAnimateSun )
    {
        auto &LightOrientationMatrix = *m_pDirLightOrienationCamera->GetParentMatrix();
        float3 RotationAxis( 0.5f, 0.3f, 0.0f );
        float3 LightDir = m_pDirLightOrienationCamera->GetLook() * -1;
        float fRotationScaler = ( LightDir.y > +0.2f ) ? 50.f : 1.f;
        float4x4 RotationMatrix = float4x4RotationAxis(RotationAxis, 0.02f * (float)deltaSeconds * fRotationScaler);
        LightOrientationMatrix = LightOrientationMatrix * RotationMatrix;
        m_pDirLightOrienationCamera->SetParentMatrix(LightOrientationMatrix);
    }

    float dt = (float)ElapsedTime;
    if (m_Animate && dt > 0 && dt < 0.2f)
    {
        float3 axis;
        float angle = 0;
        AxisAngleFromRotation(axis, angle, m_SpongeRotation);
        if (length(axis) < 1.0e-6f) 
            axis[1] = 1;
        angle += m_AnimationSpeed * dt;
        if (angle >= 2.0f*FLOAT_PI)
            angle -= 2.0f*FLOAT_PI;
        else if (angle <= 0)
            angle += 2.0f*FLOAT_PI;
        m_SpongeRotation = RotationFromAxisAngle(axis, angle);
    }
#endif
    UpdateGUI();
}