Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: Free camera placement and coordinate transformatio

  1. #1
    Junior Member Newbie
    Join Date
    Oct 2009
    Posts
    7

    Free camera placement and coordinate transformatio

    Hey everybody,
    thanks in advance to anyone who is willing to help me, I’m really struggling “a bit” with some (I guess) basic stuff….I have a problem concerning the camera placement (aka „scene transformation“) and the transformation of coordinate systems and it seems that I make some wrong transformations or do them in the wrong order... The situation is as follows:
    I have modeled a scene in 3DSMax, let’s say this scene contains a teapot at (500 / 200 / 100) (no rotations) and a free camera at (700 / 1800 / 850 ) with the rotations ( 110 / 45 / 0).
    Now, I want to recreate the exact same scene with the same camera-view in OpenGL ( via Jogl in java to be precise, but I guess this doesn’t matter here). The input parameters should be the coordinates from 3DSMax, and the render-view should render the same picture (same perspective etc) as the 3DSMax version.
    Until now, I have had an implementation via the “glLookAt” – method (with the coordinate origin as target) and a transformation method to change the coordinate system from 3dsmax to opengl:
    Code :
    protected void transformTo3DSMax(GL gl){
           double [] transformmatrix =  { 1, 0, 0, 0,    0, 0, -1, 0,    0, 1, 0, 0,    0, 0, 0, 1};
            gl.glMultMatrixd(transformmatrix,0);
        }

    Then I also have separate functions for the individual objects I want to render, in each of those I call the “transformTo3DSMax”, for example
    Code :
    public void drawMarker(GL gl, double x, double y, double z) {
            gl.glPushMatrix();        
            //do translations and rotations  here
            //paint object with glu.FooBar() here        
            transformTo3DSMax(gl;
            gl.glPopMatrix(); 
         }
    Also the method to set the camera perspective usesthe transform method:
    Code :
        protected void setEye(GL gl){
            gl.glLoadIdentity();
            glu.gluLookAt(cam_pos.getX(), cam_pos.getY(), cam_pos.getZ(),            //position eye
                          LOOKAT.getX(), LOOKAT.getY(), LOOKAT.getZ(),               //look at
                          up_vector.getX(), up_vector.getY(), up_vector.getZ());     //up vector
            transformTo3DSMax(gl);
        }

    Using these methods, the rendering is correct, the coordinates are transformed correctly ( so the transform matrix must be correct) .
    The point is, I want to set the camera “freely”, that means I want to be able to enter the transformation but also the single x y and z angles from 3dsmax. Which basically means I have to get rid of the gluLookAt method and replace it by a method in which I rotate and translate the whole scene ( if I got it right).
    So my plan was as follows: Replace the the setEye method by:
    Code :
    protected void setEye(GL gl, tx, ty, tz, r_x,r_y,r_z){
            gl.glLoadIdentity();
            gl.glTranslated(-t_x, -t_y, -t_z);
            gl.glRotated(r_x, 1, 0, 0);
            gl.glRotated(r_y, 0, 1, 0);
            gl.glRotated(r_z, 0, 0, 1);
            transformTo3DSMax(gl);
    }
    This method should have been the very first that is called in the display method from OpenGL, and I thought it would prepare the whole matrix stack in a way, that every matrix operation afterwards ( for example painting markers, circles, teapots) gets the camera perspective I also have in 3dsmax. But for whatever reason, this doesn’t seem to work. I tried many different combinations of rotations and transformations in the setEye method, but every single one of them produced a wrong perspective / render output -_-
    If anyone got my problem – can you tell me where my fault is, or is there any good tutorial how I can place a camera freely in combination with a coordinate transformation?

    Thanks a lot!

    Binom

  2. #2
    Senior Member Regular Contributor
    Join Date
    Mar 2007
    Location
    CA
    Posts
    408

    Re: Free camera placement and coordinate transformatio

    Quote Originally Posted by DrittesBinom
    I have modeled a scene in 3DSMax, let’s say this scene contains a teapot at (500 / 200 / 100) (no rotations) and a free camera at (700 / 1800 / 850 ) with the rotations ( 110 / 45 / 0).
    Not being familiar with 3dsmax, can you clarify further what you mean by the rotations ( 110 / 45 / 0)? Are these the Euler angles (yaw,pitch,roll) of the camera's orientation? Or the teapot? You may want to take a look at 9.162 How can I transform an object with a given yaw, pitch, and roll?.

    Is [t_x,t_y,t_z] the location of the teapot that you want to look at or is it the vector difference of the position of the teapot - position of camera? or something else?

    I suspect your order of operations is incorrect and it might be fixed with
    Code :
    protected void setEye(GL gl, tx, ty, tz, r_x,r_y,r_z){
            gl.glLoadIdentity();
            gl.glRotated(r_z, 0, 0, 1);
            gl.glRotated(r_y, 0, 1, 0);
            gl.glRotated(r_x, 1, 0, 0);
            gl.glTranslated(-t_x, -t_y, -t_z);
            transformTo3DSMax(gl);
    }

  3. #3
    Junior Member Newbie
    Join Date
    Oct 2009
    Posts
    7

    Re: Free camera placement and coordinate transformatio

    Hello marshats,

    yes - the camera rotation angles are euler angles ( so x=110 , y=45 and z= 0) and 3dsmax also rotates in the order x, then y then z...( so its ZYXEuler I guess). The teapot itself could have a rotation also, but that doesnt matter in this case.

    the parameters of the setEye method should be the translation and rotation parameters of the camera-positioning. Meaning that if i get the 3dsmax coordinates t(700 / 1800 / 850 ) and r( 110 / 45 / 0) of the camera, i would want to place it with exact these parameters in OpenGL. The problem is the coordinate transformation i guess...

    I also dont know if I have to transform coordinates for every single object I draw after the camera placement or if one single transformTo3DSMax() call does suffice as a modelview matrix preparation?

  4. #4
    Senior Member Regular Contributor
    Join Date
    Mar 2007
    Location
    CA
    Posts
    408

    Re: Free camera placement and coordinate transformatio

    I need a little more info ...

    Are you placing your objects thinking in terms of the global 3ds coordinate system or the openGL coordinate system?

    In terms of local 3ds coordinates, is the up direction in the y_3ds direction? is the forward direction of the camera pointing along the z_3ds axis?

  5. #5
    Junior Member Newbie
    Join Date
    Oct 2009
    Posts
    7

    Re: Free camera placement and coordinate transformatio

    Hello marshats,

    thanks for your reply! What you mentioned is exactly what I also thought how the order of the transformations should be (despite of the camera rotations/translations, which should perhaps be negative angles/translations as of the fact that you actually rotate the scene).

    I am placing my objects by taking the coordinates from the 3ds coordinate system, so if i have my teapot at (x=100 / y=200 / z=300), I want to feed my Jogl App with the exact same parameters (which I have the the transformTo3DSMax() method for - or at least I hope so :P)

    The default camera viewing direction in 3DS is along the negative z axis, but I changed the local camera coordinate system so that the camera is looking into positive z - should be resulting in the OpenGL coordinate system ( z into screen, x to the left, y upwards).
    Unfortunately, I seem to always get a weird/wrong render output in my Jogl application, no matter in which order i call the rotate/translate/transformto3dsmax methods within the setEye method -_- When I tried your suggestion from above, I even get a blank screen...
    If you are willing to look into a (short) Java code snippet, I'd be happy to upload it somehow.
    All I can think of now is that maybe the camera coordinate change I proceeded in 3ds might falsify something...

  6. #6
    Senior Member Regular Contributor
    Join Date
    Mar 2007
    Location
    CA
    Posts
    408

    Re: Free camera placement and coordinate transformatio

    I need a little more info ...

    Are you placing your objects thinking in terms of the global 3ds coordinate system or the openGL coordinate system? If the answer is "3ds coordinates" then put the transformTo3DSMax call at the begining not the end as;
    Code :
    protected void setEye(GL gl, tx, ty, tz, r_x,r_y,r_z){
            gl.glLoadIdentity();
            transformTo3DSMax(gl);
            gl.glRotated(r_z, 0, 0, 1);
            gl.glRotated(r_y, 0, 1, 0);
            gl.glRotated(r_x, 1, 0, 0);
            gl.glTranslated(-t_x, -t_y, -t_z);     
    }
    and you should remove transformTo3DSMax() from all your
    Code :
    public void drawMarker(GL gl, double x, double y, double z) {
            gl.glPushMatrix();        
            //do translations and rotations  here
            //paint object with glu.FooBar() here        
            /// -- remove this -- not needed transformTo3DSMax(gl;
            gl.glPopMatrix(); 
         }
    so any time you place an object it will get processed as
    Code :
    MV = I*T_3ds*Rz*Ry*Rx*T_eye
    V_gl = MV*M_object*V_3ds
         = I*T_3ds*Rz*Ry*Rx*T_eye*M_object*V_3ds
    where M_object is the rotations/translation/etc of your object in 3ds coordinates
    This way everything is processed in 3ds coordinates and at the very end/last matrix operation it is converted back to opengl Coordinates (x=right, y=up, z=out of screen)

    In terms of local 3ds coordinates, is the up direction in the y_3ds direction? is the forward direction of the camera pointing along the z_3ds axis? [you answered the camera is pointing along the -z_3ds axis] That means there may need to be an extra step in setEye to flip the z-axis (not 100% certain on this though -- I need to think more about it). But here is the code on first thought
    Code :
    protected void setEye(GL gl, tx, ty, tz, r_x,r_y,r_z){
            gl.glLoadIdentity();
            gl.glRotated(180, 0, 1, 0); // take care of looking down -z_3ds axis
            transformTo3DSMax(gl);
            gl.glRotated(r_z, 0, 0, 1);
            gl.glRotated(r_y, 0, 1, 0);
            gl.glRotated(r_x, 1, 0, 0);
            gl.glTranslated(-t_x, -t_y, -t_z);     
    }
    so
    Code :
    MV = I*R_180*T_3ds*F_z*Rz*Ry*Rx*T_eye
    V_gl = MV*M_object*V_3ds
         = I*R_180*T_3ds*Rz*Ry*Rx*T_eye*M_object*V_3ds
    where M_object is the rotations/translation/etc of your object in 3ds coordinates

    Sure if you have some simple jogl code I could look at that.

  7. #7
    Junior Member Newbie
    Join Date
    Oct 2009
    Posts
    7

    Re: Free camera placement and coordinate transformatio

    My 3ds camera looks into the positive z axis, with x pointing left and y up.
    I place my objects using the 3ds coordinates.

    Currently, my application looks like this (your latest suggestion included): (open spoiler to view source code)
    <div class="ubbcode-block"><div class="ubbcode-header">Click to reveal.. <input type="button" class="form-button" value="Show me!" onclick="toggle_spoiler(this, 'Yikes, my eyes!', 'Show me!')" />]<div style="display: none;">
    Code :
    package testerproject;
     
    import com.sun.opengl.util.GLUT;
    import javax.media.opengl.GL;
    import javax.media.opengl.GLAutoDrawable;
    import javax.media.opengl.GLEventListener;
    import javax.media.opengl.glu.GLU;
    import javax.vecmath.Point3d;
     
    public class GLRenderer implements GLEventListener{
        private GLU glu;
        protected final double FIELDOFVIEW;
        protected final double ASPECT;
        protected final double NEAR_RANGE;
        protected final double FAR_RANGE;
     
        private Point3d cam_pos, cam_rot;
     
        public GLRenderer(){
            FIELDOFVIEW = 54.432;
            ASPECT = 4/3;
            NEAR_RANGE= 0.0;
            FAR_RANGE = 15000;
        }
     
     
        public void init(GLAutoDrawable arg0)
        {
            GL gl = arg0.getGL();
            glu = new GLU();
            gl.glClearColor(0.7f, 0.7f, 0.7f, 0.0f);
            //Festlegung der Maße von GL-Primitiven
            gl.glPointSize(2.0f); //Größe eines Punktes
            gl.glLineWidth(2.0f); // Dicke von Linien
            gl.glLineStipple(2, (short) 0x00FF); //Mustervorgabe für gestrichelte Linien
     
            this.setCameraMatrix(gl);
            gl.glEnable(GL.GL_TEXTURE_RECTANGLE_NV);
            gl.glMatrixMode(GL.GL_MODELVIEW);
        }
     
     
        public void display(GLAutoDrawable arg0)
        {
          GL gl = arg0.getGL();
          GLUT glut = new GLUT();
          gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
          cam_pos = new Point3d(700,1800,850);
          cam_rot = new Point3d(110,45,0);
          setCamera(gl);
          drawRootCoordinateSystem(gl, 100000.0f);
     
          drawTeaPot(gl, glut);
          drawSphere(gl, glut);
     
        }
     
     
        protected void setCamera(GL gl){
            gl.glLoadIdentity();
     
            transformTo3DSMax(gl);
            gl.glRotated(cam_rot.getZ(), 0, 0, 1);
            gl.glRotated(cam_rot.getY(), 0, 1, 0);
            gl.glRotated(cam_rot.getX(), 1, 0, 0);
            gl.glTranslated(-cam_pos.getX(), -cam_pos.getY(), -cam_pos.getZ());
        }
     
     
        protected void drawSphere(GL gl, GLUT glut){
            gl.glPushMatrix();
               gl.glColor3f(0.3f, 0.5f, 0.3f);
               gl.glTranslated(160, 110, -1000);
               glut.glutSolidSphere(25,10,5);
            gl.glPopMatrix();
        }
     
     
        protected void drawTeaPot(GL gl, GLUT glut){
           gl.glPushMatrix();
               gl.glColor3f(0.3f, 0.5f, 0.3f);
               gl.glTranslated(500, 200, 150);
               glut.glutWireTeapot(150.0f);
           gl.glPopMatrix();
        }
     
     
        protected void drawRootCoordinateSystem(GL gl, float length_axis){
            gl.glPushMatrix();
               //x axis red
               gl.glColor3f( 1.0f, 0.0f, 0.0f );
               drawLine(gl, 0.0f, 0.0f, 0.0f, length_axis, 0.0f,0.0f);
               drawDottedLine(gl, -length_axis, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
     
               //y axis green
               gl.glColor3f( 0.0f, 1.0f, 0.0f );
               drawLine(gl, 0.0f, 0.0f, 0.0f, 0.0f, length_axis, 0.0f);
               drawDottedLine(gl, 0.0f, -length_axis, 0.0f, 0.0f, 0.0f, 0.0f);
     
               //z axis blue
               gl.glColor3f( 0.0f, 0.0f, 1.0f );
               drawLine(gl, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, length_axis);
               drawDottedLine(gl, 0.0f, 0.0f, -length_axis, 0.0f, 0.0f, 0.0f);
           gl.glPopMatrix();
        }
     
     
        protected void drawLine(GL gl, double x1, double y1, double z1,
                                     double x2, double y2, double z2)
        {
           gl.glBegin(GL.GL_LINES);
                gl.glVertex3d(x1, y1, z1);
                gl.glVertex3d(x2, y2, z2);
           gl.glEnd();
        }
     
     
        protected void drawDottedLine(GL gl,double x1, double y1, double z1,
                                          double x2, double y2, double z2)
        {
           gl.glEnable(GL.GL_LINE_STIPPLE);
           gl.glBegin(GL.GL_LINES);
                gl.glVertex3d(x1, y1, z1);
                gl.glVertex3d(x2, y2, z2);
           gl.glEnd();
           gl.glDisable(GL.GL_LINE_STIPPLE);
        }
     
     
        protected void transformTo3DSMax(GL gl){
            double [] transformmatrix =  { 1, 0, 0, 0,    0, 0, -1, 0,    0, 1, 0, 0,    0, 0, 0, 1};
            gl.glMultMatrixd(transformmatrix,0);
        }
     
     
        protected void setCameraMatrix(GL gl) {
            int w =500, h = 500;
     
            gl.glViewport(0, 0, w, h);
     
            gl.glMatrixMode(GL.GL_PROJECTION);
            gl.glLoadIdentity(); //load identity matrix
     
            glu.gluPerspective(this.FIELDOFVIEW, this.ASPECT, this.NEAR_RANGE ,this.FAR_RANGE);
        }
     
     
     
     
        public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4)
        {
        }
     
     
        public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2)
        {
        }
     
     
    }
    [/QUOTE]</div>


    If I render this, it produces this picture: ( the dotted blue line is a part of the negative z axis).



    I used the camera and object coordinates from 3ds, which produces this picture, rendred from the cameras point of view:



    What came into my mind while posting this: Could it be possible that theres something wrong with the up vector of the camera or do I not have to care about this when not using gluLookat ?

  8. #8
    Senior Member Regular Contributor
    Join Date
    Mar 2007
    Location
    CA
    Posts
    408

    Re: Free camera placement and coordinate transformatio

    Quote Originally Posted by DrittesBinom
    What came into my mind while posting this: Could it be possible that theres something wrong with the up vector of the camera or do I not have to care about this when not using gluLookat ?
    The up vector along with the forward view of camera and and the direction of the camera side is defined by your euler angles. So you are still taking into account the up vector just as gluLookAt did. Rather than having to explicitly specify up, your 3-angles are implicitly giving you up,side, and fowrard camera directions.

    Thanks for the code and pictures ... that gives me something to work with.

  9. #9
    Senior Member Regular Contributor
    Join Date
    Mar 2007
    Location
    CA
    Posts
    408

    Re: Free camera placement and coordinate transformatio

    For debugging purposes you will find it easier to work with glOrtho instead of persepctive so I suggest commenting out the line

    glu.gluPerspective(this.FIELDOFVIEW, this.ASPECT, this.NEAR_RANGE ,this.FAR_RANGE)
    until things work as expected

    Code :
        protected void setCameraMatrix(GL gl) {
            int w =500, h = 500;
     
            gl.glViewport(0, 0, w, h);
     
            gl.glMatrixMode(GL.GL_PROJECTION);
            gl.glLoadIdentity(); //load identity matrix
     
            glOrtho(-2000,2000,-2000,2000,-2000,2000);
            //glu.gluPerspective(this.FIELDOFVIEW, this.ASPECT, this.NEAR_RANGE ,this.FAR_RANGE);
        }
    I really suspect the three rotations related to the euler angles are not pointing in the directions that I expect.

    If the 3dsmax camera is located a the origin and the euler angles are all zero then what are the 3dsmax axes corresponding to up? right? and into the screen?

    Repeat the question but with camera euler angles = (90,0,0)

    Repeat the question but with camera euler angles = (0,90,0)

    Repeat the question but with camera euler angles = (0,0,90)

    Repeat the question but with camera euler angles = (45,45,45)

    Pictures there would be very helpful showing the global coordinates as seen thru the 3ds camera.

  10. #10
    Senior Member Regular Contributor
    Join Date
    Mar 2007
    Location
    CA
    Posts
    408

    Euler angles and +? -? signs in setCamera def.

    Does this apply to your 3dsmax model -- using viewport coordinates?

    Note, because Blender does not have this ambiguity, I decided to check your code against Blender rather than 3dsmax because that is what I have available to view a scene with euler angles. This helped me to understand one thing (still doesn't completely fix your problem) -- whether or not there should be a negative sign in setCamera angles.

    To understand this suppose you wanted to place an object in your scene at the same position and orientation as the camera. You would rotate first according to the Euler angles and then translate to the position ie
    Code :
        void drawCameraTriad(){
            glPushMatrix();
              glTranslated(cam_pos.getX(), cam_pos.getY(), cam_pos.getZ());
              glRotated(cam_rot.getZ(), 0, 0, 1);
              glRotated(cam_rot.getY(), 0, 1, 0);
              glRotated(cam_rot.getX(), 1, 0, 0);
              drawRootCoordinateSystem(1500.);
            glPopMatrix();
         }
    Now if you applied the setCamera correctly then this would always display to the screen the object representing the camera axis perfectly aligned to the horizontal, vertical, and normal monitor axis. Well the only way to get that is to do the inverse matrix operation when setting the camera "lookAt" and for glTranslate that means putting a negative sign on all coordinates and for glRotate that means rotate by a negative angle. And the inverse also changes the order of operations. Hence by inspection of drawCameraTriad() the inverse matrix is constructed by setCamera and has to be made by flipping signs and reversing order of operations as
    Code :
        void setCamera(){
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
     
            //transformTo3DSMax();
            glRotated(-cam_rot.getX(), 1, 0, 0);
            glRotated(-cam_rot.getY(), 0, 1, 0);
            glRotated(-cam_rot.getZ(), 0, 0, 1);
            glTranslated(-cam_pos.getX(), -cam_pos.getY(), -cam_pos.getZ());
        }
    This code works perfectly when I compare it against Blender (ie with no need for transformTo3DSMax call). It does not solve your problem of the zy axis flip from 3dsmax to openGL. But this result must be true in either case. So the problem has to either be in one of two places transformTo3DSMax() or the order euler angle rotations defined by 3dsmax. For blender it was easy to figure this out by simply rotating one Euler angle at a time, then two in succession, and determining that blender applies X rotation first! then Y rotation second, and finally z rotation.

    Not a complete solution ... still looking into 3dsmax euler angle definition as the most likely candidate needing improvement. Hence the motivation for the questions I posed in the previous post where you try different euler sttings and note their effects.

Page 1 of 2 12 LastLast

Similar Threads

  1. Dynamic camera placement
    By SamMillner in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 03-05-2012, 03:43 PM
  2. Camera placement
    By Irena in forum OpenGL: General
    Replies: 4
    Last Post: 03-15-2010, 09:23 AM
  3. HELP! - Free Look Camera
    By PSI in forum OpenGL: Advanced Coding
    Replies: 1
    Last Post: 02-19-2004, 05:12 AM
  4. Camera placement and movement
    By ltrain_riders in forum OpenGL: Basic Coding
    Replies: 3
    Last Post: 12-06-2002, 11:53 AM
  5. Pixel placement and Bitmap placement with OpenGL
    By D_Lux in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 06-11-2001, 07:58 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean