Sign in to follow this  
lucky6969b

OpenGL How do I swap Y and Z axis with D3DXMATRIX?

Recommended Posts

I seem to be having problem exporting camera with 3ds max.
The object is sitting horizontally in max, now the exported object is standing upright in dx9
I believe the y-z axis is wrong. How do I flip it around? I mean what matrix can I multiply with this wrong matrix?
[code]
///
float mat[4][4];
Matrix3 invTM;
int persp;
float hither;
float yon;
D3DXMATRIX m_d3dWorldXform; // your app world transform matrix
D3DXMATRIX m_d3dViewXform; // your app view transform matrix
D3DXMATRIX m_d3dProjXform; // your app projection transform matrix
Interface *ip2 = GetCOREInterface();
ViewExp * pView = ip2->GetActiveViewport(); // Get the viewport in question
GraphicsWindow *gw = pView->getGW(); // Get the GraphicsWindow context

gw->getCameraMatrix( mat, &invTM, &persp, &hither, &yon); // getting these values to work with ... see above for their types
float oneOverDepth = 1.0f / (yon - hither);

// Set the Direct3D Camera View Position and Camera Projection Transforms.
//
// The first matrix is the full projection transformation matrix that
// converts World Coordinates into NPC. This means that the matrix is the
// product of the Camera View Position transformation matrix and the Camera
// Projection matrix. The second matrix is the inverse of the Camera View
// Position transformation matrix so if we multiply this second matrix by
// the first, we get the Camera Projection matrix. If we take the inverse
// of the second matrix, we get the Camera View Position matrix.
//
// The Camera View Position transformation converts World coordinates into
// Camera View Position coordinates where the camera is located at the
// origin. We have been given the inverse of the Camera View Position
// matrix so the first step is to take the inverse of this transform to
// obtain the Camera View Position matrix.
// General conversion from 3ds max coords to Direct3D coords:
//
// 3ds max: (Up, Front, Right) == (+Z, +Y, +X)
//
// Direct3D: (Up, Front, Right) == (+Y, +Z, +X)
//
// Conversion from 3ds max to Direct3D coords:
//
// 3ds max * conversion matrix = Direct3D
//
// [ x y z w ] * | +1 0 0 0 | = [ X Y Z W ]
// | 0 0 +1 0 |
// | 0 +1 0 0 |
// | 0 0 0 +1 |
//
// The View transform below accomplishes this. The standard View transform
// received makes the rotation about the X axis because the assumption was
// to transform to RH coords with the XY plane being the vertical plane
// instead of the XZ plane. The negation of the the Z column does the RH
// to LH flip. Thus, the View transform makes the transition from RH 3ds
// max coords to LH Direct3D coords.
Matrix3 camTM = Inverse(invTM);

// We now have an affine matrix (4x3) with no perspective column (it is
// understood to be (0, 0, 0, 1)). We add the fourth column and flip the
// Z-axis because Direct3D uses a left-handed coordinate system and MAX
// uses a right-handed coordinate system.
// Copy the affine view matrix data
int ki, kj;
MRow *pcvm = camTM.GetAddr();
for (ki = 0; ki < 4; ki++) {
for (kj = 0; kj < 3; kj++) {
m_d3dViewXform.m[ki][kj] = pcvm[ki][kj];
}
}
// Assign the fourth column (perspective terms)
m_d3dViewXform.m[0][3] = m_d3dViewXform.m[1][3] = m_d3dViewXform.m[2][3] = 0.0f;
m_d3dViewXform.m[3][3] = 1.0f;

// Scale the Z-axis (third column) by -1 to flip to left-handed Direct3D
// coordinate system
for (ki = 0; ki < 4; ki++) {
m_d3dViewXform.m[ki][2] *= -1.0f;
}

// Calculate the Direct3D Camera Projection transformation matrix.
//
// First, multiply the MAX full projection matrix by the inverse of the MAX
// Camera View Position matrix to obtain the MAX Camera Projection matrix.
//
// This gives us a correct Direct3D Camera Projection matrix except for the
// lower right quadrant.
//
MRow *pa = invTM.GetAddr();
for (ki = 0; ki < 4; ki++) {
float val = (float)(ki==3);
for (kj = 0; kj < 4; kj++) {
m_d3dProjXform.m[ki][kj] = pa[ki][0] * mat[0][kj] +
pa[ki][1] * mat[1][kj] +
pa[ki][2] * mat[2][kj] +
val * mat[3][kj];
}
}

// Now calculate the lower right quadrant of the Camera Projection matrix
// using the facts that MAX uses an NPC Z-axis range of +1 to -1 whereas
// Direct3D uses an NPC Z-axis range of zero to +1.
//
// For ease of reference, the general forms of the Direct3D Projection
// matrix for perspective and orthographic projections are given below.
//
// Please note that the matrices are specified in row-major order. This
// means that the translate terms are located in the fourth row and the
// projection terms in the fourth column. This is consistent with the way
// MAX, Direct3D, and OpenGL all handle matrices. Even though the OpenGL
// documentation is in column-major form, the OpenGL code is designed to
// handle matrix operations in row-major form.

if (persp) {

// Perspective projection. The general form of the Direct3D Camera
// Projection matrix is:
//
// | 2n/(r-l) 0 0 0 |
// | 0 2n/(t-b) 0 0 |
// | (r+l)/(r-l) (t+b)/(t-b) f/(f-n) 1 |
// | 0 0 -fn/(f-n) 0 |
//
// Construct the lower right four terms correctly for Direct3D.
//
m_d3dProjXform.m[2][2] = yon*oneOverDepth;
m_d3dProjXform.m[2][3] = 1.0f;
m_d3dProjXform.m[3][2] = -(yon*hither*oneOverDepth);
m_d3dProjXform.m[3][3] = 0.0f;

} else {

// Orthographic projection. The general form of the Direct3D Camera
// Projection matrix is:
//
// | 2/(r-l) 0 0 0 |
// | 0 2/(t-b) 0 0 |
// | 0 0 1/(f-n) 0 |
// | (r+l)/(r-l) (t+b)/(t-b) -n/(f-n) 1 |
//
// Construct the lower right four terms correctly for Direct3D.
//
m_d3dProjXform.m[2][2] = oneOverDepth;
m_d3dProjXform.m[2][3] = 0.0f;
m_d3dProjXform.m[3][2] = -(hither*oneOverDepth);
m_d3dProjXform.m[3][3] = 1.0f;
}
[/code]

Thanks
Jack Edited by lucky6969b

Share this post


Link to post
Share on other sites
Depending on whether you use a left- or a right-handed coordinate system, you'd need to do something like this:

first pitch the model backwards: D3DXMatrixRotationYawPitchRoll(&matrixPitch, 0.f, PI * .5f, 0.f);
then flip it along the z-axis when needed: D3DXMatrixScaling(&matrixScale, 1.f, 1.f, -1.f);
then concatenate all of them together: matrixPitch * matrixScale * matrixWorld * matrixView * matrixProjection

Of course it would be better to correct a mesh' orientation directly after loading it, not only until you render it.

Share this post


Link to post
Share on other sites
You can always do it while exporting, I think it's easier. When You export .FBX model you can go to Advanced Options -> Axis Conversion, in .OBJ you can chcek (or uncheck)convert yz-axis, most of model exporters got this option.

Share this post


Link to post
Share on other sites
Hi eppo, thanks for your help. I am actually following the typical article found on the net. I think you have read it too.
Basically, it should be correct except I didn't export the world transformation of the object. So would that be the root cause of the problem?
Thanks
Jack

Share this post


Link to post
Share on other sites
max
[url="https://www.asuswebstorage.com/navigate/share/GYYIKLHY5Y"]https://www.asuswebs...hare/GYYIKLHY5Y[/url]
http://img254.imageshack.us/img254/3271/maxz.jpg

dx9
[url="https://www.asuswebstorage.com/navigate/share/GYYUVGHY5Y"]https://www.asuswebs...hare/GYYUVGHY5Y[/url]
http://img687.imageshack.us/img687/6381/56040738.png Edited by lucky6969b

Share this post


Link to post
Share on other sites
How do you feel that it's the view transformation problem or the projection transformation problem?
If the definition of projection matrix is to transforming the view frustum to cuboid shape, it won't do any harm to the camera, will it?
So it must be the view transformation problem.

Share this post


Link to post
Share on other sites
How do I dismantle the up-right-view vectors of the transformation?

[code]
// Scale the Z-axis (third column) by -1 to flip to left-handed Direct3D
// coordinate system
for (ki = 0; ki < 4; ki++) {
m_d3dViewXform.m[ki][2] *= -1.0f;
}
[/code]

Can this simple operation change it from right-handed to left-handed?
Thanks
Jack Edited by lucky6969b

Share this post


Link to post
Share on other sites
I probably should have been clearer on this: the problem isn't really in the object's world-xfrm, it's in the mesh vertices themselves. You either correct this by applying a pre-transformation when rendering or by simply swapping vertex components during loading; D3DXVECTOR3(vec3DS.x, vec3DS.z, (-)vec3DS.y).

Share this post


Link to post
Share on other sites

Hello eppo,

 

                       CameraObject *cam = (CameraObject*) node->EvalWorldState(ip->GetTime()).obj;
            
                        Matrix3 atm = node->GetObjectTM(ip->GetTime(), 0);// 4x3 matrix
             
                        int ki, kj;
                        MRow *pcvm = atm.GetAddr();        
                        for (ki = 0; ki < 4; ki++) {
                            for (kj = 0; kj < 3; kj++) {
                                d3dViewXform.m[ki][kj] = pcvm[ki][kj];
                            }
                        }
                        // Assign the fourth column (perspective terms)

                        d3dViewXform.m[0][3] = d3dViewXform.m[1][3] = d3dViewXform.m[2][3] = 0.0f;
                        d3dViewXform.m[3][3] = 1.0f;


                        D3DXMATRIX matrixPitch, matrixScale;

                        D3DXMatrixIdentity(&matrixPitch);
                        D3DXMatrixIdentity(&matrixScale);

                        D3DXMatrixRotationYawPitchRoll(&matrixPitch, 0.f, PI * .5f, 0.f);
                        D3DXMatrixScaling(&matrixScale, 1.f, 1.f, -1.f);

                        d3dViewXform = matrixPitch * matrixScale * d3dViewXform;

 

The camera still got distorted. I evaluated this thread again because I want +y to go upward and +z go outward.

Thanks

Jack

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Partner Spotlight

  • Forum Statistics

    • Total Topics
      627642
    • Total Posts
      2978354
  • Similar Content

    • By xhcao
      Before using void glBindImageTexture(    GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format), does need to make sure that texture is completeness. 
    • By cebugdev
      hi guys, 
      are there any books, link online or any other resources that discusses on how to build special effects such as magic, lightning, etc. in OpenGL? i mean, yeah most of them are using particles but im looking for resources specifically on how to manipulate the particles to look like an effect that can be use for games,. i did fire particle before, and I want to learn how to do the other 'magic' as well.
      Like are there one book or link(cant find in google) that atleast featured how to make different particle effects in OpenGL (or DirectX)? If there is no one stop shop for it, maybe ill just look for some tips on how to make a particle engine that is flexible enough to enable me to design different effects/magic 
      let me know if you guys have recommendations.
      Thank you in advance!
    • By dud3
      How do we rotate the camera around x axis 360 degrees, without having the strange effect as in my video below? 
      Mine behaves exactly the same way spherical coordinates would, I'm using euler angles.
      Tried googling, but couldn't find a proper answer, guessing I don't know what exactly to google for, googled 'rotate 360 around x axis', got no proper answers.
       
      References:
      Code: https://pastebin.com/Hcshj3FQ
      The video shows the difference between blender and my rotation:
       
    • By Defend
      I've had a Google around for this but haven't yet found some solid advice. There is a lot of "it depends", but I'm not sure on what.
      My question is what's a good rule of thumb to follow when it comes to creating/using VBOs & VAOs? As in, when should I use multiple or when should I not? My understanding so far is that if I need a new VBO, then I need a new VAO. So when it comes to rendering multiple objects I can either:
      * make lots of VAO/VBO pairs and flip through them to render different objects, or
      * make one big VBO and jump around its memory to render different objects. 
      I also understand that if I need to render objects with different vertex attributes, then a new VAO is necessary in this case.
      If that "it depends" really is quite variable, what's best for a beginner with OpenGL, assuming that better approaches can be learnt later with better understanding?
       
    • By test opty
      Hello all,
       
      On my Windows 7 x64 machine I wrote the code below on VS 2017 and ran it.
      #include <glad/glad.h>  #include <GLFW/glfw3.h> #include <std_lib_facilities_4.h> using namespace std; void framebuffer_size_callback(GLFWwindow* window , int width, int height) {     glViewport(0, 0, width, height); } //****************************** void processInput(GLFWwindow* window) {     if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)         glfwSetWindowShouldClose(window, true); } //********************************* int main() {     glfwInit();     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);     //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);     GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);     if (window == nullptr)     {         cout << "Failed to create GLFW window" << endl;         glfwTerminate();         return -1;     }     glfwMakeContextCurrent(window);     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))     {         cout << "Failed to initialize GLAD" << endl;         return -1;     }     glViewport(0, 0, 600, 480);     glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);     glClearColor(0.2f, 0.3f, 0.3f, 1.0f);     glClear(GL_COLOR_BUFFER_BIT);     while (!glfwWindowShouldClose(window))     {         processInput(window);         glfwSwapBuffers(window);         glfwPollEvents();     }     glfwTerminate();     return 0; }  
      The result should be a fixed dark green-blueish color as the end of here. But the color of my window turns from black to green-blueish repeatedly in high speed! I thought it might be a problem with my Graphics card driver but I've updated it and it's: NVIDIA GeForce GTX 750 Ti.
      What is the problem and how to solve it please?
  • Popular Now