void UrhoRenderer::SetMainCamera(Entity *mainCameraEntity)
{
    activeMainCamera = mainCameraEntity;

    Urho3D::Camera *newActiveCamera = 0;
    Camera *cameraComponent = mainCameraEntity ? mainCameraEntity->Component<Camera>().Get() : 0;
    if (cameraComponent)
        newActiveCamera = cameraComponent->UrhoCamera();
    else
    {
        activeMainCamera.Reset();
        if (mainCameraEntity)
            LogWarning("Cannot activate camera '" + mainCameraEntity->Name() + "': It does not have a Camera component!");
    }
    if (mainCameraEntity && !mainCameraEntity->ParentScene()) // If the new to-be camera is not in a scene, don't add it as active.
    {
        LogWarning("Cannot activate camera \"" + mainCameraEntity->Name() + "\": It is not attached to a scene!");
        activeMainCamera.Reset();
        newActiveCamera = 0;
    }

    if (!activeMainCamera.Lock() || !newActiveCamera)
        LogWarning("Setting main window camera to null!");

    Urho3D::Renderer* rend = GetSubsystem<Urho3D::Renderer>();
    if (!rend)
        return; // In headless mode the renderer doesn't exist

    Urho3D::Viewport* vp = rend->GetViewport(0);
    if (vp)
    {
        vp->SetCamera(newActiveCamera);
        vp->SetScene(mainCameraEntity->ParentScene()->Subsystem<GraphicsWorld>()->UrhoScene());
    }
    else
        LogWarning("Could not set active camera, no viewport defined");

    MainCameraChanged.Emit(mainCameraEntity);
}
void GraphicsWorld::HandlePostRenderUpdate(StringHash /*eventType*/, VariantMap& /*eventData*/)
{
    URHO3D_PROFILE(GraphicsWorld_PostRenderUpdate);

    visibleEntities_.Clear();

    Urho3D::Renderer* renderer = GetSubsystem<Urho3D::Renderer>();
    Camera* cameraComp = renderer_->MainCameraComponent();

    if (IsActive() && renderer)
    {
        Urho3D::Camera* cam = cameraComp ? cameraComp->UrhoCamera() : nullptr;
        Urho3D::Viewport* vp = renderer->GetViewport(0);
        Urho3D::View* view = vp ? vp->GetView() : nullptr;
        if (view)
        {
            const Urho3D::PODVector<Urho3D::Drawable*>& geometries = view->GetGeometries();
            for (uint i = 0; i < geometries.Size(); ++i)
            {
                // Verify that the geometry is in main camera view, as also eg. shadow geometries get listed
                Urho3D::Drawable* dr = geometries[i];
                if (!dr || !dr->IsInView(cam))
                    continue;
                EntityWeakPtr ent(static_cast<Entity*>(dr->GetNode()->GetVar(entityLink).GetPtr()));
                if (!ent)
                    continue;
                
                visibleEntities_.Insert(ent);
            }
        }
    }

    // Perform visibility change tracking
    for (HashMap<EntityWeakPtr, bool>::Iterator i = visibilityTrackedEntities_.Begin(); i != visibilityTrackedEntities_.End();)
    {
        // Check whether entity has expired
        if (!i->first_)
            i = visibilityTrackedEntities_.Erase(i);
        else
        {
            bool current = visibleEntities_.Contains(i->first_);
            bool prev = i->second_;
            if (current != prev)
            {
                i->second_ = current;
                if (current)
                {
                    i->first_->EmitEnterView(cameraComp);
                    EntityEnterView.Emit(i->first_.Get());
                }
                else
                {
                    i->first_->EmitLeaveView(cameraComp);
                    EntityLeaveView.Emit(i->first_.Get());
                }
            }

            ++i;
        }
    }
}