Page 1 of 1

Replacing PlaneProjection

Posted: 17 Jun 2020, 20:37
by acardoso
Hi, I'm upgrading a project that uses an old version of Noesis to the latest one.

I noticed that PlaneProjection class was dropped, how can I replace its functionality preserving all properties: CenterOfRotation, GlobalOffset, LocalOffset and Rotation.

Basically, if you guys could disclose the implementation of this dropped function, it will solve my problem:
//(Include/NsGui/PlaneProjection.h:)
    static Math::Matrix4f ConstructProjectionMatrix(
        const Drawing::Size& surface, const Drawing::Size& size,
        NsFloat32 centerX, NsFloat32 centerY, NsFloat32 centerZ,
        NsFloat32 globalOffX, NsFloat32 globalOffY, NsFloat32 globalOffZ,
        NsFloat32 localOffX, NsFloat32 localOffY, NsFloat32 localOffZ,
        NsFloat32 rotX, NsFloat32 rotY, NsFloat32 rotZ);

Re: Replacing PlaneProjection

Posted: 18 Jun 2020, 12:46
by jsantos
In 3.0, you need to use Transform3D to achieve something similar.

This is the implementation of ConstructProjectionMatrix in 2.2.6:
Matrix4f PlaneProjection::ConstructProjectionMatrix(
    const Size& surface, const Size& size,
    float centerOfRotationX, float centerOfRotationY, float centerOfRotationZ,
    float globalOffsetX, float globalOffsetY, float globalOffsetZ,
    float localOffsetX, float localOffsetY, float localOffsetZ,
    float rotationX, float rotationY, float rotationZ)
{
    if (IsZero(surface.width) || IsZero(surface.height) ||
        IsIdentityProjection(globalOffsetX, globalOffsetY, globalOffsetZ,
            localOffsetX, localOffsetY, localOffsetZ,
            rotationX, rotationY, rotationZ))
    {
        return Matrix4f::Identity();
    }

    // Values between 0 and 1 set the pivot line at some location within the object
    float centerX = centerOfRotationX * size.width;
    float centerY = centerOfRotationY * size.height;
    // Values greater than 0 correspond to coordinates out from the plane of the object, and
    // negative values correspond to coordinates behind the plane of the object
    float centerZ = -centerOfRotationZ;

    Matrix4f moveToRotationCenter = Transform3f::Trans(-centerX, -centerY, -centerZ);
    Matrix4f moveFromRotationCenter = Transform3f::Trans(centerX, centerY, centerZ);

    Matrix4f globalOffset = Transform3f::Trans(globalOffsetX, -globalOffsetY, -globalOffsetZ);
    Matrix4f localOffset = Transform3f::Trans(localOffsetX, -localOffsetY, -localOffsetZ);
    Matrix4f rotation =
        Transform3f::RotX(rotationX * DegToRad) *
        Transform3f::RotY(-rotationY * DegToRad) *
        Transform3f::RotZ(-rotationZ * DegToRad) * Matrix4f::Identity();

    float fov = 17.0f * DegToRad;
    float away = (surface.height / 2.0f) / tanf(fov / 2.0f);
    float aspect = surface.width / surface.height;

    Matrix4f awayFromCamera = Transform3f::Trans(-size.width * 0.5f, -size.height * 0.5f, away);
    Matrix4f perspective = Matrix4f::PerspectiveFov(fov, aspect, 1.0f);
    Matrix4f viewport = Matrix4f::Viewport(surface.width, surface.height);
    Matrix4f moveToZero = Transform3f::Trans(
        -surface.width * 0.5f + size.width * 0.5f,
        -surface.height * 0.5f + size.height * 0.5f,
        0.0f);

    return moveToRotationCenter * localOffset * rotation * moveFromRotationCenter * globalOffset *
        awayFromCamera * perspective * viewport * moveToZero;
}

Re: Replacing PlaneProjection

Posted: 18 Jun 2020, 17:13
by acardoso
Perfect!
The reason I asked was that I could not figure out if the projection was left handed or right handed, the precedence order of the look-at transform and the fov of the PlaneProjection transform, which was not provided to the user (I see it's 17 degrees).

That solves my problem, Thank you!

Re: Replacing PlaneProjection

Posted: 19 Jun 2020, 12:16
by jsantos
Great! Remember that in v3.0 this is a bit different, the projection matrix is global for all the elements, in v2.X the projection is happening in each element.