Does anyone have a good link for constructing a PVM camera

A PVM as opposed to a MVP model view projection transformation view camera.

I have always built mine the other way mvp and never tyed to do it PVM wise but arrgg.

One that you know works in mono-game is what im looking for.

Ive tryed like a ton of sites suggestions and nothing is working fully to were its like the three stooges getting control over rotation screws up motion and visa versa. Or drawing period in the case of the pvm transforms. I keep reading that the order of operattions is v’= pvm * v but no joy.

Im having a hell of a hard time trying to do it the other way around. All my tests are failing too.
For some reason no matter what i do if i try to go the pvm route instead of mvp way the projection matrix whittles the z element of the translation vector down to the near plane and basically won’t draw.

Here is some of the test code and the output from it below.
Manually doing it as well just wipes out the pvm final transforms z element.

        public void test()
        {
            Console.WriteLine("\n++++++++++++++++++++++++++++++++++++");
            Console.WriteLine("+++++++++++++++++Test+++++++++++++++\n");

            Vector3 pos2 = new Vector3(0, 0, 200);
            Vector3 pos1 = new Vector3(0, 0, 100);

            Matrix model = Matrix.Identity;

            Matrix obj1_Trans = Matrix.CreateTranslation(pos2);
            Matrix obj1_Rot = Matrix.Identity;

            Matrix cam1_Trans = Matrix.CreateTranslation(pos1);
            Matrix cam1_Rot = Matrix.CreateFromAxisAngle(Vector3.Up, TORADIANS * 45f);
            Matrix cam1_Trans_Rev = Matrix.CreateTranslation(-pos1);
            Matrix cam1_Rot_Rev = Matrix.Transpose(cam1_Rot);
            Matrix cam1_con = cam1_Rot; cam1_con.Translation = cam1_Trans.Translation;
            Matrix cam1_con_Transpose = Matrix.Transpose(cam1_con);
            Matrix cam1_TransposeRevTranslate = cam1_Rot_Rev; cam1_TransposeRevTranslate.Translation = Vector3.Transform(cam1_Trans.Translation, cam1_Rot_Rev) ;

            OutputMatrixInfoSimple(GetProjection3D(), "projection");
            OutputMatrixInfoSimple(cam1_Trans, "cam1_Trans = Matrix.CreateTranslation(pos1);");
            OutputMatrixInfoSimple(cam1_Trans_Rev, "cam1_Trans_Rev = Matrix.CreateTranslation(-pos1);");
            OutputMatrixInfoSimple(cam1_Rot, "cam1_Rot = Matrix.CreateFromAxisAngle(Vector3.Up, TORADIANS * 45f);");
            OutputMatrixInfoSimple(cam1_Rot_Rev, "cam1_Rot_Rev = Matrix.Transpose(cam1_Rot);");
            OutputMatrixInfoSimple(cam1_con, "cam1_con = cam1_Rot; cam1_con.Translation = cam1_Trans.Translation;");
            OutputMatrixInfoSimple(cam1_con_Transpose, "cam1_con_Transpose = Matrix.Transpose(cam1_con);");
            OutputMatrixInfoSimple(cam1_TransposeRevTranslate, "cam1_TransposeRevTranslate = cam1_Rot_Rev; cam1_TransposeRevTranslate.Translation = Vector3.Transform(cam1_Trans.Translation, cam1_Rot_Rev) ;");

            Matrix LookAtViewV = Matrix.CreateLookAt(cam1_Trans.Translation, cam1_Trans.Translation + cam1_Rot.Forward, Vector3.Up);
            OutputMatrixInfoSimple(LookAtViewV, "LookAtViewV = Matrix.CreateLookAt(cam1_Trans.Translation, cam1_Trans.Translation + cam1_Rot.Forward, Vector3.Up);");


            Matrix FinalView = cam1_TransposeRevTranslate;
            Console.WriteLine(" FinalView = cam1_TransposeRevTranslate");

            Matrix FinalMVP = model * FinalView * GetProjection3D();
            Matrix FinalPVM = GetProjection3D() * FinalView * model;
            OutputMatrixInfoSimple(FinalMVP, "FinalMVP = model * FinalView * GetProjection3D();");
            OutputMatrixInfoSimple(FinalPVM, "FinalPVM = GetProjection3D() * FinalView * model;");

            Console.WriteLine(" FinalView transforms on a quad");
            Console.WriteLine(OutputTransformTestInfo(FinalView));

            FinalView = LookAtViewV;
            Console.WriteLine("\n \n  FinalView = LookAtViewV;");

            FinalMVP = model * FinalView * GetProjection3D();
            FinalPVM = GetProjection3D() * FinalView * model;
            OutputMatrixInfoSimple(FinalMVP, "FinalMVP = model * FinalView * GetProjection3D();");
            OutputMatrixInfoSimple(FinalPVM, "FinalPVM = GetProjection3D() * FinalView * model;");

            Console.WriteLine(" FinalView transforms on a quad");
            Console.WriteLine(OutputTransformTestInfo(FinalView));

            
            Console.WriteLine("\n++++++++++++++++++++++++++++++++++++");
            Console.WriteLine("++++++++++++++++++++++++++++++++++++\n");
        }

… Console Output

++++++++++++++++++++++++++++++++++++
+++++++++++++++++Test+++++++++++++++


 projection
 Right:       { X:+0.600 Y:       Z:       }   ~integerity:  = 0.36
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:       Y:       Z:+1.001 }   ~integerity:  = 1.001001
 Translation: { X:       Y:       Z:-0.500 }


 cam1_Trans = Matrix.CreateTranslation(pos1);
 Right:       { X:+1.000 Y:       Z:       }   ~integerity:  = 1
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:       Y:       Z:-1.000 }   ~integerity:  = 1
 Translation: { X:       Y:       Z:+100.000 }


 cam1_Trans_Rev = Matrix.CreateTranslation(-pos1);
 Right:       { X:+1.000 Y:       Z:       }   ~integerity:  = 1
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:       Y:       Z:-1.000 }   ~integerity:  = 1
 Translation: { X:       Y:       Z:-100.000 }


 cam1_Rot = Matrix.CreateFromAxisAngle(Vector3.Up, TORADIANS * 45f);
 Right:       { X:+0.707 Y:       Z:-0.707 }   ~integerity:  = 0.9999999
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:-0.707 Y:       Z:-0.707 }   ~integerity:  = 0.9999999
 Translation: { X:       Y:       Z:       }


 cam1_Rot_Rev = Matrix.Transpose(cam1_Rot);
 Right:       { X:+0.707 Y:       Z:+0.707 }   ~integerity:  = 0.9999999
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:+0.707 Y:       Z:-0.707 }   ~integerity:  = 0.9999999
 Translation: { X:       Y:       Z:       }


 cam1_con = cam1_Rot; cam1_con.Translation = cam1_Trans.Translation;
 Right:       { X:+0.707 Y:       Z:-0.707 }   ~integerity:  = 0.9999999
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:-0.707 Y:       Z:-0.707 }   ~integerity:  = 0.9999999
 Translation: { X:       Y:       Z:+100.000 }


 cam1_con_Transpose = Matrix.Transpose(cam1_con);
 Right:       { X:+0.707 Y:       Z:+0.707 }   ~integerity:  = 0.9999999
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:+0.707 Y:       Z:-0.707 }   ~integerity:  = 0.9999999
 Translation: { X:       Y:       Z:       }


 cam1_TransposeRevTranslate = cam1_Rot_Rev; cam1_TransposeRevTranslate.Translation = Vector3.Transform(cam1_Trans.Translation, cam1_Rot_Rev)
 ;
 Right:       { X:+0.707 Y:       Z:+0.707 }   ~integerity:  = 0.9999999
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:+0.707 Y:       Z:-0.707 }   ~integerity:  = 0.9999999
 Translation: { X:-70.711 Y:       Z:+70.711 }


 LookAtViewV = Matrix.CreateLookAt(cam1_Trans.Translation, cam1_Trans.Translation + cam1_Rot.Forward, Vector3.Up);
 Right:       { X:+0.707 Y:       Z:+0.707 }   ~integerity:  = 1
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:+0.707 Y:       Z:-0.707 }   ~integerity:  = 1
 Translation: { X:+70.711 Y:       Z:-70.711 }

 FinalView = cam1_TransposeRevTranslate

 FinalMVP = model * FinalView * GetProjection3D();
 Right:       { X:+0.424 Y:       Z:-0.707 }   ~integerity:  = 0.6805003
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:+0.424 Y:       Z:+0.707 }   ~integerity:  = 0.6805003
 Translation: { X:-42.426 Y:       Z:-71.246 }


 FinalPVM = GetProjection3D() * FinalView * model;
 Right:       { X:+0.424 Y:       Z:+0.424 }   ~integerity:  = 0.36
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:-71.418 Y:       Z:+71.418 }   ~integerity:  = 10201.1
 Translation: { X:+0.354 Y:       Z:-0.354 }

 FinalView transforms on a quad

 Simulated Vertice Transform


 AutoGet is Using MVP
 Positions... > transformed by m to ... >
 [0]: { X:-1.000 Y:-1.000 Z:       }  > [0]: { X:-71.418 Y:-1.000 Z:+70.004 }
 [1]: { X:-1.000 Y:+1.000 Z:       }  > [1]: { X:-71.418 Y:+1.000 Z:+70.004 }
 [2]: { X:+1.000 Y:-1.000 Z:       }  > [2]: { X:-70.004 Y:-1.000 Z:+71.418 }
 [3]: { X:+1.000 Y:+1.000 Z:       }  > [3]: { X:-70.004 Y:+1.000 Z:+71.418 }

 Positions transformed by, PVM
 [0]: { X:-1.000 Y:-1.000 Z:       }  > [0]: { X:-0.600 Y:-1.000 Z:-0.500 }
 [1]: { X:-1.000 Y:+1.000 Z:       }  > [1]: { X:-0.600 Y:+1.000 Z:-0.500 }
 [2]: { X:+1.000 Y:-1.000 Z:       }  > [2]: { X:+0.600 Y:-1.000 Z:-0.500 }
 [3]: { X:+1.000 Y:+1.000 Z:       }  > [3]: { X:+0.600 Y:+1.000 Z:-0.500 }

 Positions transformed by, MVP
 [0]: { X:-1.000 Y:-1.000 Z:       }  > [0]: { X:-0.600 Y:-1.000 Z:-0.500 }
 [1]: { X:-1.000 Y:+1.000 Z:       }  > [1]: { X:-0.600 Y:+1.000 Z:-0.500 }
 [2]: { X:+1.000 Y:-1.000 Z:       }  > [2]: { X:+0.600 Y:-1.000 Z:-0.500 }
 [3]: { X:+1.000 Y:+1.000 Z:       }  > [3]: { X:+0.600 Y:+1.000 Z:-0.500 }


  FinalView = LookAtViewV;

 FinalMVP = model * FinalView * GetProjection3D();
 Right:       { X:+0.424 Y:       Z:-0.707 }   ~integerity:  = 0.6805
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:+0.424 Y:       Z:+0.707 }   ~integerity:  = 0.6805007
 Translation: { X:+42.426 Y:       Z:+70.246 }


 FinalPVM = GetProjection3D() * FinalView * model;
 Right:       { X:+0.424 Y:       Z:+0.424 }   ~integerity:  = 0.36
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:+70.003 Y:       Z:-70.003 }   ~integerity:  = 9800.901
 Translation: { X:+0.354 Y:       Z:-0.354 }

 FinalView transforms on a quad

 Simulated Vertice Transform


 AutoGet is Using MVP
 Positions... > transformed by m to ... >
 [0]: { X:-1.000 Y:-1.000 Z:       }  > [0]: { X:+70.004 Y:-1.000 Z:-71.418 }
 [1]: { X:-1.000 Y:+1.000 Z:       }  > [1]: { X:+70.004 Y:+1.000 Z:-71.418 }
 [2]: { X:+1.000 Y:-1.000 Z:       }  > [2]: { X:+71.418 Y:-1.000 Z:-70.004 }
 [3]: { X:+1.000 Y:+1.000 Z:       }  > [3]: { X:+71.418 Y:+1.000 Z:-70.004 }

 Positions transformed by, PVM
 [0]: { X:-1.000 Y:-1.000 Z:       }  > [0]: { X:-0.600 Y:-1.000 Z:-0.500 }
 [1]: { X:-1.000 Y:+1.000 Z:       }  > [1]: { X:-0.600 Y:+1.000 Z:-0.500 }
 [2]: { X:+1.000 Y:-1.000 Z:       }  > [2]: { X:+0.600 Y:-1.000 Z:-0.500 }
 [3]: { X:+1.000 Y:+1.000 Z:       }  > [3]: { X:+0.600 Y:+1.000 Z:-0.500 }

 Positions transformed by, MVP
 [0]: { X:-1.000 Y:-1.000 Z:       }  > [0]: { X:-0.600 Y:-1.000 Z:-0.500 }
 [1]: { X:-1.000 Y:+1.000 Z:       }  > [1]: { X:-0.600 Y:+1.000 Z:-0.500 }
 [2]: { X:+1.000 Y:-1.000 Z:       }  > [2]: { X:+0.600 Y:-1.000 Z:-0.500 }
 [3]: { X:+1.000 Y:+1.000 Z:       }  > [3]: { X:+0.600 Y:+1.000 Z:-0.500 }

++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++

Vs good z values i get with a mvp. Though to be honest this is a little screwed up as well.

__________________________________

 OutputCameraConsoleInfo  CameraInfo F1

_  TargetForward: { X:       Y:       Z:-1.000 }
_  Position:      { X:       Y:       Z:-2.000 }

 Right:       { X:+1.000 Y:       Z:       }   ~integerity:  = 1
 Up:          { X:       Y:+1.000 Z:       }   ~integerity:  = 1
 Forward:     { X:       Y:       Z:-1.000 }   ~integerity:  = 1
 Translation: { X:       Y:       Z:-2.000 }

 Bering:
 Forward  Nautical bering M31 M33, (degrees): 0
 Forward  Pitch           M32 M33, (degrees): 0
 Up       Roll            M22 M21, (degrees): 0

 Simulated Vertice Transform


 AutoGet is Using MVP
 Positions... > transformed by m to ... >
 [0]: { X:-1.000 Y:-1.000 Z:       }  > [0]: { X:-1.000 Y:-1.000 Z:-2.000 }
 [1]: { X:-1.000 Y:+1.000 Z:       }  > [1]: { X:-1.000 Y:+1.000 Z:-2.000 }
 [2]: { X:+1.000 Y:-1.000 Z:       }  > [2]: { X:+1.000 Y:-1.000 Z:-2.000 }
 [3]: { X:+1.000 Y:+1.000 Z:       }  > [3]: { X:+1.000 Y:+1.000 Z:-2.000 }

 Positions transformed by, PVM
 [0]: { X:-1.000 Y:-1.000 Z:       }  > [0]: { X:-0.600 Y:-1.000 Z:-0.500 }
 [1]: { X:-1.000 Y:+1.000 Z:       }  > [1]: { X:-0.600 Y:+1.000 Z:-0.500 }
 [2]: { X:+1.000 Y:-1.000 Z:       }  > [2]: { X:+0.600 Y:-1.000 Z:-0.500 }
 [3]: { X:+1.000 Y:+1.000 Z:       }  > [3]: { X:+0.600 Y:+1.000 Z:-0.500 }

 Positions transformed by, MVP
 [0]: { X:-1.000 Y:-1.000 Z:       }  > [0]: { X:-0.600 Y:-1.000 Z:+1.501 }
 [1]: { X:-1.000 Y:+1.000 Z:       }  > [1]: { X:-0.600 Y:+1.000 Z:+1.501 }
 [2]: { X:+1.000 Y:-1.000 Z:       }  > [2]: { X:+0.600 Y:-1.000 Z:+1.501 }
 [3]: { X:+1.000 Y:+1.000 Z:       }  > [3]: { X:+0.600 Y:+1.000 Z:+1.501 }