Repository: FlaxEngine/FlaxEngine
File: Source/Engine/Level/Actors/Camera.cpp (C++)

Code before:
    if (Math::NotNearEqual(_orthoScale, value))
    {
        _orthoScale = value;
        UpdateCache();
    }
}

void Camera::ProjectPoint(const Vector3& worldSpaceLocation, Float2& gameWindowSpaceLocation) const
{
    ProjectPoint(worldSpaceLocation, gameWindowSpaceLocation, GetViewport());
}

void Camera::ProjectPoint(const Vector3& worldSpaceLocation, Float2& cameraViewportSpaceLocation, const Viewport& viewport) const
{
    Matrix v, p, vp;
    GetMatrices(v, p, viewport);
    Matrix::Multiply(v, p, vp);
    Vector3 clipSpaceLocation;
    Vector3::Transform(worldSpaceLocation, vp, clipSpaceLocation);
    viewport.Project(worldSpaceLocation, vp, clipSpaceLocation);
    cameraViewportSpaceLocation = Float2(clipSpaceLocation);
}

bool Camera::IsPointOnView(const Vector3& worldSpaceLocation) const
{
    Camera* mainCamera = Camera::GetMainCamera();

    if (!mainCamera)
    {
        return false;
    }

    Vector3 cameraUp = mainCamera->GetTransform().GetUp();
    Vector3 cameraForward = mainCamera->GetTransform().GetForward();
    Vector3 directionToPosition = (worldSpaceLocation- mainCamera->GetPosition()).GetNormalized();

    if (Vector3::Dot(cameraForward, directionToPosition) < 0)
    {
        return false;
    }

    Quaternion lookAt = Quaternion::LookRotation(directionToPosition, cameraUp);
    Vector3 lookAtDirection = lookAt * Vector3::Forward;
    Vector3 newWorldLocation = mainCamera->GetPosition() + lookAtDirection;

    Float2 windowSpace = Float2();
    Float2 screenSize = Screen::GetSize();

    mainCamera->ProjectPoint(newWorldLocation, windowSpace);

    return (windowSpace.X >= 0 && windowSpace.X <= screenSize.X) &&

Review comment (suggestion):
Instead of using `mainCamera` this code can use `this` camera object. Then scripts can use multiple cameras if needed or just query from main camera.

Code after:
    {
        _orthoScale = value;
        UpdateCache();
    }
}

void Camera::ProjectPoint(const Vector3& worldSpaceLocation, Float2& gameWindowSpaceLocation) const
{
    ProjectPoint(worldSpaceLocation, gameWindowSpaceLocation, GetViewport());
}

void Camera::ProjectPoint(const Vector3& worldSpaceLocation, Float2& cameraViewportSpaceLocation, const Viewport& viewport) const
{
    Matrix v, p, vp;
    GetMatrices(v, p, viewport);
    Matrix::Multiply(v, p, vp);
    Vector3 clipSpaceLocation;
    Vector3::Transform(worldSpaceLocation, vp, clipSpaceLocation);
    viewport.Project(worldSpaceLocation, vp, clipSpaceLocation);
    cameraViewportSpaceLocation = Float2(clipSpaceLocation);
}

bool Camera::IsPointOnView(const Vector3& worldSpaceLocation) const
{
    Vector3 cameraUp = GetTransform().GetUp();
    Vector3 cameraForward = GetTransform().GetForward();
    Vector3 directionToPosition = (worldSpaceLocation - GetPosition()).GetNormalized();

    if (Vector3::Dot(cameraForward, directionToPosition) < 0)
    {
        return false;
    }

    Quaternion lookAt = Quaternion::LookRotation(directionToPosition, cameraUp);
    Vector3 lookAtDirection = lookAt * Vector3::Forward;
    Vector3 newWorldLocation = GetPosition() + lookAtDirection;

    Float2 windowSpace = Float2();
    Float2 screenSize = GetViewport().Size;

    ProjectPoint(newWorldLocation, windowSpace);

    return (windowSpace.X >= 0 && windowSpace.X <= screenSize.X) &&
           (windowSpace.Y >= 0 && windowSpace.Y <= screenSize.Y);
}

Ray Camera::ConvertMouseToRay(const Float2& mousePosition) const
{
    return ConvertMouseToRay(mousePosition, GetViewport());
}