Solved Help understanding WorldToScreen

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

dlinkb

Newbie
Jul 31, 2012
2
212
0
After seeing how to find the MVP matrix in Rake's tutorial, I was wondering about a few things.

1) The AC source code has something like this:
C++:
glmatrixf mvmatrix, projmatrix, mvpmatrix, invmvmatrix, invmvpmatrix;
vec worldpos, camdir, camup, camright;

void readmatrices()
{
    glGetFloatv(GL_MODELVIEW_MATRIX, mvmatrix.v);
    glGetFloatv(GL_PROJECTION_MATRIX, projmatrix.v);
    camright = vec(mvmatrix[0], mvmatrix[4], mvmatrix[8]);
    camup = vec(mvmatrix[1], mvmatrix[5], mvmatrix[9]);
    camdir = vec(-mvmatrix[2], -mvmatrix[6], -mvmatrix[10]);

    mvpmatrix.mul(projmatrix, mvmatrix);
    invmvmatrix.invert(mvmatrix);
    invmvpmatrix.invert(mvpmatrix);
}
From what I understand from reading https://www.codinglabs.net/article_world_view_projection_matrix.aspx, the model to world matrix brings a particular model into the coordinate system of the game world, then the world to view matrix brings everything relative to the camera being at the origin, then the view to projection matrix handles flattening everything into a 2D screen.

The model to world matrix would have to be different for every object because the matrix depends on the object's location in the game world. How then, can there be a singular model-view-projection matrix or a model-view matrix (mvmatrix in the code) if every model has a different model to world matrix?

2) Fleep's COD ESP source code has something like this:
C++:
//Grabs our 3d Coordinates and changes them to 2d for us to play with
//---------------------------------------------------------------------------
bool ESP::WorldToScreen(Vect3d &WorldLocation, Vect3d &mypos)
{
    Vect3d vLocal, vTransForm;
	vForward = new Vect3d();
	vRight = new Vect3d();
	vUpward = new Vect3d();

    AngleVectors();
    vLocal = SubVectorDist(WorldLocation, mypos);

    vTransForm.x = vLocal.dotproduct(*vRight);
    vTransForm.y = vLocal.dotproduct(*vUpward);
    vTransForm.z = vLocal.dotproduct(*vForward);

    if (vTransForm.z < 0.01)
        return false;

    ScreenX = screencenter[0] + (screencenter[0] / vTransForm.z * (1 / fov[0])) * vTransForm.x;
    ScreenY = screencenter[1] - (screencenter[1] / vTransForm.z * (1 / fov[1])) * vTransForm.y;

    return true;
}
...
....
....
/// <summary>
/// One of Kn4cker's functions, this beauty does all our complex maths
/// if you want to know more about it get very comfortable with Pythagora
/// </summary>
void ESP::AngleVectors()
{
    float angle;
    float sr, sp, sy, cr, cp, cy, 
        cpi = (3.141f * 2 / 360);

    angle = viewAngles.y * cpi;
    //cpi = same view angles.x isn't

    sy = (float)sin(angle);
    cy = (float)cos(angle);
    angle = viewAngles.x * cpi;
    sp = (float)sin(angle);
    cp = (float)cos(angle);
    angle = viewAngles.z * cpi;
    sr = (float)sin(angle);
    cr = (float)cos(angle);

    vForward->x = cp * cy;
    vForward->y = cp * sy;
    vForward->z = -sp;


    vRight->x = (-1 * sr * sp * cy + -1 * cr * -sy);
    vRight->y = (-1 * sr * sp * sy + -1 * cr * cy);
    vRight->z = -1 * sr * cp;


    vUpward->x = (cr * sp * cy + -sr * -sy);
    vUpward->y = (cr * sp * sy + -sr * cy);
    vUpward->z = cr * cp;
}
He doesn't use the game's MVP matrix, and instead probably calculates everything himself with view angles and fov.

Is there a good resource anywhere to understand what's he doing here? (the math behind it)

And why does it seem like people prefer to do the MVP approach rather than this approach? (do people even prefer the matrix approach for the WorldToScreen function?) It seems it'd be easier to find view angles and fov than it is to find the matrices.

3) I was looking at a ESP tutorial on unkn0wncheats (https://www.unkn0wncheats.me/forum/h1z1/147272-pimp-my-c-esp-episode-3-fix-my-worldtoscreen.html) and was confused about a part of the code OP presented.

C++:
        private bool WorldToScreen(Vector3 vector, out Vector3 screen)
        {
            screen = Vector3.Zero;
            // multiply the matrix by hand like this: float w = M41 * vector.X + M42 * vector.Y + M43 * vector.Z + M44;
            float w = Vector3.Dot(GetMatrixAxis(GameMatrix, 3), vector) + GameMatrix.M44;
            if (w < 0.098f) return false;
            float x = Vector3.Dot(GetMatrixAxis(GameMatrix, 0), vector) + GameMatrix.M14;
            float y = Vector3.Dot(GetMatrixAxis(GameMatrix, 1), vector) + GameMatrix.M24;
            screen.X = ((((this.GameWindowSize.X) / 2) * (1f + (x / w))) + this.GameWindowRect.Left);
            screen.Y = ((((this.GameWindowSize.Y) / 2) * (1f - (y / w))) + this.GameWindowRect.Top);
            return true;
        }
What exactly is w doing?

From looking at https://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/, it looks like the w value is in computer graphics matrices to help make some of the operations possible and to differentiate between direction and position vectors. Clearly, I'm missing something because that usage of w wouldn't make sense in this code snippet. (Plus, the w row in the AC matricies aren't just 1 or 0). So what exactly is w?

Thanks for reading my post. If you don't know the answer, I'd love some resources on where I can find it out on my own.
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,073
78,998
2,371
The model to world matrix would have to be different for every object because the matrix depends on the object's location in the game world. How then, can there be a singular model-view-projection matrix or a model-view matrix (mvmatrix in the code) if every model has a different model to world matrix?
Good question

In my tutorial and in the assault cube source code it's referred to as the "Model View Projection Matrix", but could be simply referred to as the "View Projection Matrix" in openGL.

In 3d programming, there are different "coordinate spaces":

Object Coordinates
World Coordinates
Eye Coordines
Clip Coordinates
Viewport Coordinates
Screen Coordinates

To convert from one space to another, we use "transformational matrices"

In openGL we have only two transformational matrices:

C++:
#define GL_MODELVIEW_MATRIX               0x0BA6
#define GL_PROJECTION_MATRIX              0x0BA7
Notice no GL_MODEL_MATRIX. That is because openGL skips the converion from "Object Coordinates" to "World Coordinates" by combining the Model and View Matrices into the GL_MODELVIEW_MATRIX. Coordinates are multiplied by this matrix to get straight to Eye Coordinates.

Therefore in openGL you could say that the model matrix is implied when saying "view matrix". But to get from eye coordinates to clip coordinates you still need to do do a vector-matrix product calculation using the GL_PROJECTION_MATRIX.
For the most part, we only care about getting from world coordinates to clip coordinates so the combination MVPMatrix makes it easy and apparently most game developers agree and include it in their code.

Here's a visual



2) Fleep's COD ESP source code has something like this:
C++:
//Grabs our 3d Coordinates and changes them to 2d for us to play with
//---------------------------------------------------------------------------
bool ESP::WorldToScreen(Vect3d &WorldLocation, Vect3d &mypos)
{
    Vect3d vLocal, vTransForm;
	vForward = new Vect3d();
	vRight = new Vect3d();
	vUpward = new Vect3d();

    AngleVectors();
    vLocal = SubVectorDist(WorldLocation, mypos);

    vTransForm.x = vLocal.dotproduct(*vRight);
    vTransForm.y = vLocal.dotproduct(*vUpward);
    vTransForm.z = vLocal.dotproduct(*vForward);

    if (vTransForm.z < 0.01)
        return false;

    ScreenX = screencenter[0] + (screencenter[0] / vTransForm.z * (1 / fov[0])) * vTransForm.x;
    ScreenY = screencenter[1] - (screencenter[1] / vTransForm.z * (1 / fov[1])) * vTransForm.y;

    return true;
}
...
....
....
/// <summary>
/// One of Kn4cker's functions, this beauty does all our complex maths
/// if you want to know more about it get very comfortable with Pythagora
/// </summary>
void ESP::AngleVectors()
{
    float angle;
    float sr, sp, sy, cr, cp, cy, 
        cpi = (3.141f * 2 / 360);

    angle = viewAngles.y * cpi;
    //cpi = same view angles.x isn't

    sy = (float)sin(angle);
    cy = (float)cos(angle);
    angle = viewAngles.x * cpi;
    sp = (float)sin(angle);
    cp = (float)cos(angle);
    angle = viewAngles.z * cpi;
    sr = (float)sin(angle);
    cr = (float)cos(angle);

    vForward->x = cp * cy;
    vForward->y = cp * sy;
    vForward->z = -sp;


    vRight->x = (-1 * sr * sp * cy + -1 * cr * -sy);
    vRight->y = (-1 * sr * sp * sy + -1 * cr * cy);
    vRight->z = -1 * sr * cp;


    vUpward->x = (cr * sp * cy + -sr * -sy);
    vUpward->y = (cr * sp * sy + -sr * cy);
    vUpward->z = cr * cp;
}
He doesn't use the game's MVP matrix, and instead probably calculates everything himself with view angles and fov.
Is there a good resource anywhere to understand what's he doing here? (the math behind it)
And why does it seem like people prefer to do the MVP approach rather than this approach? (do people even prefer the matrix approach for the WorldToScreen function?) It seems it'd be easier to find view angles and fov than it is to find the matrices.
3d game math can be programmed using 2 distinc methods that I know of, using traditional float[16] matrices that combine all the necesary data or by keeping them all seperate. Quake Engine games including COD for instance keep them all seperate. Note that the vForward, vRight and vUpward vectors and the FOV are all included in a traditional float[16] matrix:


I share two similar functions and some explanation here:
https://guidedhacking.com/showthread.php?8044-World2Screen-function

What exactly is w doing?
Transforming a 3 dimensional vector into clip coordinates gives you a vec4 including the W component. This is the depth component. If W is less than 0, the object is behind you. You usually do a "if (clipCoords.w < 0.1f)" because between 0 and 0.1 the object is probably clipping through your body and if you compared it with < 0 you would get giant ESP boxes on your screen when other entities are clipping/touching you
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods