void db_FrameToReferenceRegistration::Set_H_dref_to_ins(double H[9])
{
    double H_ins_to_ref[9];

    db_Identity3x3(H_ins_to_ref);   // Ensure it has proper values
    db_InvertAffineTransform(H_ins_to_ref,m_H_ref_to_ins);  // Invert to get ins to ref
    db_Multiply3x3_3x3(m_H_dref_to_ref,H,H_ins_to_ref); // Update dref to ref using the input H from dref to ins
}
// This function computes fills the 4x4 matrices g_dAffinetrans,
// and g_dAffinetransPan using the specified 3x3 affine
// transformation between the first captured frame and the current frame.
// The computed g_dAffinetrans is such that it warps the preview mosaic in
// the last frame's coordinate system into the coordinate system of the
// current frame. Thus, applying this transformation will create the current
// frame mosaic but with the current frame missing. This frame will then be
// pasted in by gWarper2 after translating it by g_dTranslationToFBOCenter.
// The computed g_dAffinetransPan is such that it offsets the computed preview
// mosaic horizontally to make the viewfinder pan within the UI layout.
void UpdateWarpTransformation(float *trs)
{
    double H[9], Hp[9], Htemp1[9], Htemp2[9], T[9];

    for(int i = 0; i < 9; i++)
    {
        gThisH1t[i] = trs[i];
    }

    // Alignment is done based on low-res data.
    // To render the preview mosaic, the translation of the high-res mosaic is estimated to
    // H2L_FACTOR x low-res-based tranlation.
    gThisH1t[2] *= H2L_FACTOR;
    gThisH1t[5] *= H2L_FACTOR;

    db_Identity3x3(T);
    T[2] = -gCenterOffsetX;
    T[5] = -gCenterOffsetY;

    // H = ( inv(gThisH1t) * gLastH1t ) * T
    db_Identity3x3(Htemp1);
    db_Identity3x3(Htemp2);
    db_Identity3x3(H);
    db_InvertAffineTransform(Htemp1, gThisH1t);
    db_Multiply3x3_3x3(Htemp2, Htemp1, gLastH1t);
    db_Multiply3x3_3x3(H, Htemp2, T);

    for(int i = 0; i < 9; i++)
    {
        gLastH1t[i] = gThisH1t[i];
    }

    // Move the origin such that the frame is centered in the previewFBO
    // i.e. H = inv(T) * H
    H[2] += gCenterOffsetX;
    H[5] += gCenterOffsetY;

    // Hp = inv(Km) * H * Km
    // Km moves the coordinate system from openGL to image pixels so
    // that the alignment transform H can be applied to them.
    // inv(Km) moves the coordinate system back to openGL normalized
    // coordinates so that the shader can correctly render it.
    db_Identity3x3(Htemp1);
    db_Multiply3x3_3x3(Htemp1, H, gKm);
    db_Multiply3x3_3x3(Hp, gKminv, Htemp1);

    ConvertAffine3x3toGL4x4(g_dAffinetrans, Hp);

    ////////////////////////////////////////////////
    ////// Compute g_dAffinetransPan now...   //////
    ////////////////////////////////////////////////

    gThisTx = trs[2];

    if(gPanViewfinder)
    {
        gPanOffset += (gThisTx - gLastTx) * VIEWFINDER_PAN_FACTOR_HORZ;
    }

    gLastTx = gThisTx;
    gPanViewfinder = continuePanningFBO(gPanOffset);

    db_Identity3x3(H);
    H[2] = gPanOffset;

    // Hp = inv(Km) * H * Km
    db_Identity3x3(Htemp1);
    db_Multiply3x3_3x3(Htemp1, H, gKm);
    db_Multiply3x3_3x3(Hp, gKminv, Htemp1);

    //if (gIsLandscapeOrientation) {
        ConvertAffine3x3toGL4x4(g_dAffinetransPan, Hp);
    //} else {
    //    // rotate Hp by 90 degress.
    //    db_Multiply3x3_3x3(Htemp1, gRotation90, Hp);
    //    ConvertAffine3x3toGL4x4(g_dAffinetransPan, Htemp1);
   // }
}