Question

OpenGL gluLookAt: Two camera questions

Asked by: AntonKarlsson

Now I finally understands how gluLookAt works. I just need the camera position(eye) the viewing target(focal point(center)) and roll(for the up vector) in my View class. And calculate the view direction for the up vector.

So my first question is how do I calculate the up vector from the viewing direction vector and camera/view roll?

And two how do I call the gluLookAt and place all scene-objects locations(with the basic gl translation functions)? And when to call glLoadIdentity()?

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2009-08-27 at 11:14:31ID24687569
Tags

opengl glulookat up vector roll angle

Topic

OpenGL Graphics & Game Programming

Participating Experts
1
Points
500
Comments
81

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. How to rotate a camera in opengl using delphi
    Dear all, I have written a starter application using opengl and the following tools Gl, Glu, UrickGL, U3Dpolys. I have walls appearing on the screen and can zoom in and move around the map with my mouse but would like to be able to move the camera not the image. When I try to...
  2. Computer Vision(Eye Camera Analogy In OPen GL)
    Here was a interesting thing which I was doing and i have divided in to two parts, I am trying to rotate a camera around a object in a elliptical shape with radius 30 and obtain different shapes from different perspective center(Looking points). The coordinates of the ...
  3. OpenGL, moving the camera
    I have try to write the code to move the camera around an object,but i only achieved that by using keyborad. How can i do it by using the mouse? like when u click the mouse button and at the same time move the mouse around,u will c different angle of the object. Zooming in an...
  4. Camera Movement in OPENGL
    Hi Auqa, Below is my code for creation of walls and apply texture to it.All the methods below in the class are used to create the walls in a polygon grid (10 X 10) format.And also create a ambient light for Day and Night effect.Now the only thing i need to do i put in a came...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: ikeworkPosted on 2009-08-27 at 23:46:48ID: 25205429

Hi AntonKarlsson,

>> how do I calculate the up vector from the viewing direction vector and camera/view roll?

If you just want a normal camera, then you dont need to calculate it, its just {0.0, 1.0, 0.0}
Only if you want to have a camera-shake effect or something, then you need to calculate it accordingly.

>> how do I call the gluLookAt and place all scene-objects locations(with the basic gl translation functions)? And when to call glLoadIdentity()?

In the beginning of your render function you reset the matrix-stack with glLoadIdentity.
Then you call gluLookAt and after that you render your objects.

If you want to reset the camera and all previous matrix-stack changes, then you can call glLoadIdentity. But usually you jst need to call it in the beginning of your render function, before gluLookAt

ike

 

by: AntonKarlssonPosted on 2009-08-28 at 07:32:59ID: 25208052

You didn't answer my first question fully.  How do I calculate the up vector from the direction vector(from eye - focus point) and the roll angle? I knowyou just can ignore it and just let it be y up. But I want to have it. If the roll is 0 then the up vector shall be (0,1,0) as a reference.
How do I calcuale it if the roll angle is in degrees?

As for the second question, I found its answer elsewhere.

 

by: ikeworkPosted on 2009-08-28 at 07:51:08ID: 25208280

Do you use any math-library? You just need to rotate {0,1,0} around the z-axis by your roll-angle

 

by: ikeworkPosted on 2009-08-28 at 08:00:05ID: 25208373

here is how you calc the up-vector with a given roll-angle (rotation around z-axis)

x' = cos(roll) * x  +  sin(roll) * y
y' = -sin(roll) * x   +  cos(roll) * y
z' = z

 

by: ikeworkPosted on 2009-08-28 at 08:03:17ID: 25208402

since x==0 and y == 1  {0, 1, 0}, its just:

x' = sin(roll)
y' = cos(roll)
z' = z

 

by: ikeworkPosted on 2009-08-28 at 08:08:32ID: 25208457

after that it needs to be rotated with yaw, gimme a sec eh ;)

 

by: ikeworkPosted on 2009-08-28 at 08:26:00ID: 25208635

after you calculated the up-vector rotated by roll, you use this formula to rotate it around the y-axis(yaw)

x' = cos(yaw) * x + -sin(yaw) * z
y' = y
z' = sin(yaw) * x + cos(yaw) * z

thats it .. But I would really recommend to look for a matrix/vector library, since you will need a lot of those calculations, if you want to make 3D graphics

 

by: ikeworkPosted on 2009-08-28 at 08:31:46ID: 25208706

Here are both formulas combined

(note, i made some simplification, assuming that the input-vector x == 0 and z == 0, which is the case for your up-vector, so this is not the general form)

x = cos(yaw) * sin(roll)
y = cos(roll)
z = sin(yaw)

 

by: AntonKarlssonPosted on 2009-09-01 at 08:55:41ID: 25232877

The up vector has to be rotated with roll around its direction vector.

 

by: ikeworkPosted on 2009-09-01 at 10:03:59ID: 25233604

>> The up vector has to be rotated with roll around its direction vector.

Right, but do you have the direction-vector already? Is it rotated by pitch, yaw and roll?
Then its easy: do the same calculations with up-vector to get the rotated up-vector.

 

by: AntonKarlssonPosted on 2009-09-01 at 11:24:07ID: 25234405

The direction vector is easy to calculate, it's just:
{eyeX-centerX, eyeY-centerY, eyeZ-centerZ}  I think.
And nomalize it ofcoarse, if nessesary.

And then rotate it around by roll with 0 at y 1(up). It's this part I need to figure out.

 

by: ikeworkPosted on 2009-09-01 at 11:28:27ID: 25234455

>> The direction vector is easy to calculate, it's just:
>> {eyeX-centerX, eyeY-centerY, eyeZ-centerZ}  I think.
>> And nomalize it ofcoarse, if nessesary.

Yes right, but you said you dont even have the center-vector. I thought you must calculate it from pitch, yaw and roll? Otherwise the Q does not make much sense?

 

by: ikeworkPosted on 2009-09-01 at 11:31:22ID: 25234494

Ah ok, I think I understood what you are asking for now.

So you have:

vector: "center"
vector: "eye"
angle: "roll"

right?

 

by: ikeworkPosted on 2009-09-01 at 11:42:39ID: 25234618

Here it is:

vector direction = normalize( center - eye );
vector rotAxis = crossProduct( axis_y, direction );
float rotAngle = acos( dotProduct( axis_y, direction ) );
// up vector rotated by roll
vector up = { sin(roll), cos(roll), 0.0 };
 
// this quaternion represent the rotation of the direction-vector
quaternion q = { rotAxis.x * sin( rotAngle / 2.0 ), 
                 rotAxis.y * sin( rotAngle / 2.0 ),
                 rotAxis.z * sin( rotAngle / 2.0 ),
                 cos( rotAngle / 2.0 ) };
 
// up vector rotated with the same rotation, the direction vector has
up = up.rotateByQ( q );

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:

Select allOpen in new window

 

by: AntonKarlssonPosted on 2009-09-01 at 11:50:21ID: 25234692

Yes I have the center(focus poistion) and the eye(camera) position and roll; it's in the View class. The only thing I need is the up vector from that direction vector and the roll value with the zero reference at y full(1).

 

by: AntonKarlssonPosted on 2009-09-01 at 11:58:23ID: 25234766

Sorry for the previous post, I didn't red your second last post well enough.
But thanks then ikework?

 

by: ikeworkPosted on 2009-09-01 at 12:01:38ID: 25234799

you're welcome :)

 

by: AntonKarlssonPosted on 2009-09-01 at 12:13:56ID: 25234906

I think I need the code for the quaternion and maybe cross and dotProduct function.
But in what unit is the trigonomy functions with?
And the y_axis is a temporary vector for {0,1,0},  right?

 

by: ikeworkPosted on 2009-09-01 at 12:26:25ID: 25235022

>> And the y_axis is a temporary vector for {0,1,0},  right?

Yes.

>> But in what unit is the trigonomy functions with?

Its the <math.h> function, its always in radians.

>> I think I need the code for the quaternion and maybe cross and dotProduct function.

You really need a vector/matrix math library my friend :)

Explaining the basics of 3D math is really beyond the scope a Q here. You rather need to read books for that and wikis:

http://en.wikipedia.org/wiki/Cross_product
http://en.wikipedia.org/wiki/Dot_product

Another great resource is this http://www.euclideanspace.com

http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/index.htm

rotate vector by quaternion:

http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/index.htm


ike

 

by: ikeworkPosted on 2009-09-01 at 12:31:51ID: 25235077

here are 3d libraries:

google search: "c++ 3d vector matrix library"

http://www.gamasutra.com/features/20000131/barad_pfv.htm

google search: "c++ 3d vector quaternion matrix library"

http://www.xs4all.nl/~hkuiper/cwmtx/cwmtx.html

Or you write your own, if you are going to do more 3D stuff in the future, you should write your own. Its enlightening and fun :)

 

by: ikeworkPosted on 2009-09-01 at 12:53:55ID: 25235261

For starters, here are the funcs that you need:

cross
dot
v3RotByQ

typedef float vector3[3];
typedef float quaternion[4];
 
void cross( vector3 ret, const vector3 a, const vector3 b )
{
    ret[0] = a[1] * b[2] - a[2] * b[1];
    ret[1] = a[2] * b[0] - a[0] * b[2];
    ret[2] = a[0] * b[1] - a[1] * b[0];
}
 
float dot( const vector3 a, const vector3 b )
{
    return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
}
 
void qMulV3( quaternion ret, const quaternion q, const vector3 v )
{
    ret[0] =    q[3]*v[0] + q[1]*v[2] - q[2]*v[1];
    ret[1] =    q[3]*v[1] + q[2]*v[0] - q[0]*v[2];
    ret[2] =    q[3]*v[2] + q[0]*v[1] - q[1]*v[0];
    ret[3] = -( q[0]*v[0] + q[1]*v[1] + q[2]*v[2] );
}
 
void qMulQ( quaternion ret, const quaternion a, const quaternion b )
{
    ret[0] = a[3]*b[0]  +  a[0]*b[3]  +  a[1]*b[2]  -  a[2]*b[1];
    ret[1] = a[3]*b[1]  +  a[1]*b[3]  +  a[2]*b[0]  -  a[0]*b[2];
    ret[2] = a[3]*b[2]  +  a[2]*b[3]  +  a[0]*b[1]  -  a[1]*b[0];
    ret[3] = a[3]*b[3]  -  a[0]*b[0]  -  a[1]*b[1]  -  a[2]*b[2];
}
 
// rotate vector by quaternion
void v3RotByQ( vector3 ret, const vector3 v, const quaternion q )
{
    // v' = q * v * ~q
    quaternion a, b;
    qMulV3( a, q, v);
    const quaternion conj = { -q[0], -q[1], -q[2], q[3] };
    qMulQ( b, a, conj);
    ret[0] = b[0];
    ret[1] = b[1];
    ret[2] = b[2];
}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:

Select allOpen in new window

 

by: ikeworkPosted on 2009-09-01 at 13:19:48ID: 25235560

Hold on, lets go some steps back, because I think here is something wrong. I think there is a much easier and safer way to calculate your up-vector.
It must be calculated with the same input as the "center" - vector is being calculated.

Besider there is a problem, when you only use the "drection"-vector and the roll-angle. You lost information. This becomes a problem, when the direction vector is the same as the y-axis, when it is {0, 1, 0}. There is no way to make the proper up-vector from that input-set. You cant rotate the y-axis around the direction-vector anymore, because they are the same. No matter how big the roll-angle is, it will always be {0, 1, 0} after the retation, because you rotate around {0, 1, 0]

Please show us:

   How you calculate the "center"-vector

I think we are gonna find a much safer and easier way.

 

by: AntonKarlssonPosted on 2009-09-02 at 06:57:48ID: 25241099

Yes I just got aware of that problem myself. It has be rotated around the direction vector. But in that case we really can't have the zero reference at y full. Then have it on one of the other axis.

The center/direction vector calculation:
{eyeX-centerX, eyeY-centerY, eyeZ-centerZ}

 

by: ikeworkPosted on 2009-09-02 at 07:16:29ID: 25241284

>> The center/direction vector calculation:
>> {eyeX-centerX, eyeY-centerY, eyeZ-centerZ}

Yes, but how do you calculate the "center"? There you must have all the information you need to calculate the up-vector. Is it calculated in an external camera-class or something?

 

by: ikeworkPosted on 2009-09-02 at 07:17:28ID: 25241293

>> Then have it on one of the other axis.

Then you will have a *flip* of the camera, its not gonna be smooth, rather a hard flip.

 

by: AntonKarlssonPosted on 2009-09-02 at 08:01:55ID: 25241772

The center is the focus target in my view class. e.i. a pointer to a position of something.
And when the focal direction vector is weilding down, the up vector is drag from its previous direction with it.

 

by: ikeworkPosted on 2009-09-02 at 08:10:40ID: 25241884

>> And when the focal direction vector is weilding down, the up vector is drag from its previous direction with it.

So you already calculate the up-vector there? Now I'm confused. Please show the code, where you do calculate the center-point.

 

by: AntonKarlssonPosted on 2009-09-02 at 12:24:52ID: 25244631

I create a new view principle;
When a View class instance is constructed, the required parameter is the focus target(a 3D position).
Then the constructor set the roll to 0.0f and the up vector to {0,1,0) and setups the eye position(center) from the default look-at(from the eye position to target seen) direction and distance with setEyePos(def_dir_x, def_dir_y, def_dir_z, def_dist); which is dir {0.0f,0.0f,-1.0f} I think.


void View::setEyePos(float dir_x, float dir_y, float dir_z, float dist)
{
    // 1. Set the direction vector from the look-at dir parameters:
    direction.set(dir_x,dir_y,dir_z);
 
    // 2. Set the camera distance from the target to the eye position:
    distance = dist;
 
    // 3. Set the roll angle to zero:
    roll = 0.0f;  // Not really sure if this one is needed.
 
    // 4. Set the eye position from the reversed direction with the distance from the target:
    eyePos.x = /*I'm not really sure here*/;
    eyePos.y = /*      --        --      */;
    eyePos.z = /*      --        --      */;
 
    // 5. Set the up vector(from its previous direction)
}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:

Select allOpen in new window

 

by: AntonKarlssonPosted on 2009-09-02 at 12:51:20ID: 25244882

No, wait. the distance and relation can be changing everytime since the target pointer value position may be changed everytime by the target object and so like.
So it has to be updated continuesly.

Time for me to go to bed now, I think I just got an idea that I will continue tomorrow. I will think it over a bit before I sleep.

void View::setEyePos(float dir_x, float dir_y, float dir_z, float dist)
{
    distance = dist;
 
    // Set the camera eye position from the reverse direction with distance:
    eyePos.x = /* Not really sure here */;
    eyePos.y = /* Not really sure here */;
    eyePos.z = /* Not really sure here */;
}
 
 
void View::update()
{
    // TODO:
}
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:

Select allOpen in new window

 

by: ikeworkPosted on 2009-09-02 at 13:19:09ID: 25245187

Your last post just sets the camera-position. It does not show where you calculate the direction-vector.
The previous post sets the direction from the parameters, but you dont show where you calculate those parameters.

Neither of both posts show where and how you calculate the direction-vector.

We are sort of stuck here.

If you dont have that calculation yet, or you copied it somewhere, but dont fully understand it, just say it, no biggie, so we can move on.
I need your input in order to help you.

 

by: AntonKarlssonPosted on 2009-09-03 at 12:14:22ID: 25253926

I had to go to bed yesterday so I had to stop there.

In the constructor I set the  default look-at direction vector {0.0f,0.0f,-1.0f}  and distance 20.0f as a example with setEyePos(0.0f, 0.0f, -1.0f, 20.f);

I've got the idea to initalize the up vector(pointing up) at construction.
And then when calling setEyePos() it drags the up vector prependicular to the current direction vector from its previous direction(the up vector) and the up vector stays at that state(direction) for the zero roll reference and resets the roll to zero. Then you can rotate/change(increase or decrease by any amount of degrees) the camera's roll angle. Then in update() the up vector that will be passed to gluLookAt() will be rotated by the roll angle from the original/reference(the class member's) up vector. And gluLookAt() is called with it and the focus/target/center position and eye position. But that wont really hold because the target position may change everytime since its a pointer from an objects position(as I stated before) and likewise for the camera eye position which later implementation is going to rotate around its focus target.

 

by: AntonKarlssonPosted on 2009-09-03 at 12:20:51ID: 25253997

I think we need a matrix set from the direction vector.

 

by: ikeworkPosted on 2009-09-03 at 12:26:12ID: 25254043

Ok, I thought you already have the code.

However, if you still need help, feel free to ask.

 

by: ikeworkPosted on 2009-09-03 at 12:35:10ID: 25254144

>> I think we need a matrix set from the direction vector.

The direction-vector IS part of the matrix. Its the 3rd column. the up-vector is the 2rd column.
Here is a camera-class of mine, used to rotate and move in a scene, controlled with the mouse. That might give you an idea, how to calculate the matrix.

Anyway, we should come to a point here, otherwise its gonna be endless posting ;)

#ifndef DEMOCAMERA_INCLUDED
#define DEMOCAMERA_INCLUDED
 
#include "mtx_no_lib/geo.h"
 
class DemoCamera
{
public:
    DemoCamera( bool blnPerspectiveView, const vector &pos, float angle_x, float angle_y );
    ~DemoCamera();
 
    // apply camera to opengl
    void                applyCamera();
 
    // glut - callbacks
    // glut glutMouseFunc - callback
    // button:
    //  GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON
    // state:
    //  GLUT_UP 1, GLUT_DOWN 0
    static void         callback_mouse(int button, int state, int x, int y);
    // glut glutMotionFunc - callback
    static void         callback_mouse_motion(int x, int y);
    // glut glutReshapeFunc - callback
    static void         callback_resize(int width, int height);
 
private:
    void                mouse(int button, int state, int x, int y);
    void                mouse_motion(int x, int y);
    void                resize(int width, int height);
 
    // calculate matrix if needed
    void                update();
 
private:
    bool        m_blnPerspectiveView;
    int         m_screen_width;
    int         m_screen_height;
    vector      m_pos;
    float       m_angle_x;
    float       m_angle_y;
    bool        m_blnMatrixDirty;
    matrix      m_CameraMatrix;
 
    struct MouseMoveCache
    {
        int mouse_button;
        int x_start, y_start;
        float angle_x_start, angle_y_start, distance_start;
    };
 
    MouseMoveCache  m_MouseMoveCache;
 
    static DemoCamera   *ms_pSingleton;
};
 
DemoCamera*   DemoCamera::ms_pSingleton = NULL;
 
inline
DemoCamera::DemoCamera( bool blnPerspectiveView, const vector &pos, float angle_x, float angle_y )
: 
  m_blnPerspectiveView( blnPerspectiveView ),
  m_screen_width( 0 ),
  m_screen_height( 0 ),
  m_pos( pos ),
  m_angle_x( angle_x ),
  m_angle_y( angle_y ),
  m_blnMatrixDirty( true ),
  m_CameraMatrix(),
  m_MouseMoveCache()
{
    assert( !ms_pSingleton );
    ms_pSingleton = this;
}
 
inline
DemoCamera::~DemoCamera()
{
    ms_pSingleton = NULL;
}
 
inline
void               
DemoCamera::applyCamera()
{
    update();
    glLoadIdentity();
    glMultMatrixf( (const GLfloat*)m_CameraMatrix.data_ptr() );
}
 
inline
void        
DemoCamera::update()
{
    if( m_blnMatrixDirty )
    {
        m_CameraMatrix = matrix::translate( -m_pos ) * 
                         matrix::rotate_y( gdeg2rad( m_angle_y ) ) * 
                         matrix::rotate_x( gdeg2rad( m_angle_x ) );
        m_blnMatrixDirty = false;
    }
}
 
inline
void        
DemoCamera::mouse(int button, int state, int x, int y)
{
    if( state == 0 )
    {
        m_MouseMoveCache.mouse_button = button;
        m_MouseMoveCache.x_start = x;
        m_MouseMoveCache.y_start = y;
        m_MouseMoveCache.angle_x_start = m_angle_x;
        m_MouseMoveCache.angle_y_start = m_angle_y;
        m_MouseMoveCache.distance_start = m_pos[2];
    }
}
 
// glut glutMotionFunc - callback
inline
void 
DemoCamera::mouse_motion(int x, int y)
{
    const float DISTANCE_SCALE = m_blnPerspectiveView ? 0.25f : 0.025f;
 
    switch( m_MouseMoveCache.mouse_button )
    {
    case 0:
        m_angle_y = m_MouseMoveCache.angle_y_start + x-m_MouseMoveCache.x_start;
        m_angle_x = m_MouseMoveCache.angle_x_start + y-m_MouseMoveCache.y_start;
        m_blnMatrixDirty = true;
        break;
    case 2:
        m_pos[2] = m_MouseMoveCache.distance_start + (y-m_MouseMoveCache.y_start)*DISTANCE_SCALE;
        if( !m_blnPerspectiveView ) resize( m_screen_width, m_screen_height );
        m_blnMatrixDirty = true;
        break;
    }
    
}
 
inline
void 
DemoCamera::callback_mouse(int button, int state, int x, int y)
{
    if( ms_pSingleton ) ms_pSingleton->mouse( button, state, x, y );
}
 
inline
void 
DemoCamera::callback_mouse_motion(int x, int y)
{
    if( ms_pSingleton ) ms_pSingleton->mouse_motion( x, y );
}
 
inline
void 
DemoCamera::callback_resize(int width, int height)
{
    if( ms_pSingleton ) ms_pSingleton->resize( width, height );
}
 
inline
void 
DemoCamera::resize(int width, int height)
{
    if( height == 0 ) height = 1;
 
    m_screen_width = width;
    m_screen_height = height;
 
    glViewport( 0, 0, m_screen_width, m_screen_height );
 
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
 
    if( m_blnPerspectiveView )
    {
        gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
    }
    else
    {
        float left, right, bottom, top;
        float aspect = (GLfloat)width/(GLfloat)height;
        if( m_screen_width > m_screen_height )
        {
            left =   -m_pos[2] * aspect;
            right =   m_pos[2] * aspect;
            top =     m_pos[2];
            bottom = -m_pos[2];
        }
        else
        {
            left =   -m_pos[2];
            right =   m_pos[2];
            top =     m_pos[2] * aspect;
            bottom = -m_pos[2] * aspect;    
        }
        glOrtho( left, right, bottom, top, -100.0f, +100.0f );
    }
 
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
 
#endif // #ifndef DEMOCAMERA_INCLUDED
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:

Select allOpen in new window

 

by: AntonKarlssonPosted on 2009-09-03 at 12:48:42ID: 25254269

You know:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(roll, dir.x, dir.y, dir.z);

But then how to matrix-vertex multiply the new up vector.

 

by: ikeworkPosted on 2009-09-03 at 13:07:49ID: 25254413

>> You know:

No I dont know what you want to tell me with that code snippet.

>> But then how to matrix-vertex multiply the new up vector.

As I told you in my previous post. If you have the matrix, you already have the up-vector, its the 2nd column of the matrix. There is everything you need, the up-vector is in the matrix. You dont need to multiply anything there.

 

by: ikeworkPosted on 2009-09-03 at 13:21:59ID: 25254552

I think what you really need is a plan. Dont go into the details too early.

We need a new approach here.
You did not answer my question, what kind of application it is.

 

by: AntonKarlssonPosted on 2009-09-06 at 13:17:56ID: 25271324

>> >> You know:

>> No I dont know what you want to tell me with that code snippet.

>> >> But then how to matrix-vertex multiply the new up vector.

>> As I told you in my previous post. If you have the matrix, you already have the up-vector, its the 2nd >> column of the matrix. There is everything you need, the up-vector is in the matrix. You dont need to >> multiply anything there.

I hadn't red your/that post before I posted my/that last one.
No. I meant that I got the idea of setting up a matrix to rotate the up vector(the new one that i passed to gluLookAt()) like you do before the passing the primitives to the pipeline(like glBegin/End()):

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(delta, dir.x, dir.y, dir.z);

By that same priciple each vertex is multiplied with the current matrix. To get that new transformated up vector rotated cw or ccw in the look direction. But how do I multiply matrices by vectors like gl does.

But then, first the up vector has to be moved perpendicular to the director vector from its current direction/state to the closest perpendicular state of the look-at direction vector. How do I do that?

>> You did not answer my question, what kind of application it is.
It's opengl test application. I can't find where you asked that.

 

by: ikeworkPosted on 2009-09-06 at 23:15:16ID: 25272993

>> But how do I multiply matrices by vectors like gl does.

http://www.euclideanspace.com/maths/algebra/matrix/transforms/index.htm

>> But then, first the up vector has to be moved perpendicular to the director vector from its current direction/state to the closest perpendicular state of the look-at direction vector. How do I do that?

As I tried to tell you a couple of times now: When you have the orientation-matrix, then you dont have to calculate the up-vector anymore, because it is the second column of that matrix. Its already there.

 

by: ikeworkPosted on 2009-09-06 at 23:17:00ID: 25272999

>> It's opengl test application.

Please post the code.

 

by: ikeworkPosted on 2009-09-06 at 23:42:22ID: 25273075

 

by: AntonKarlssonPosted on 2009-09-09 at 12:43:49ID: 25294819

Thanks for the useful links.

>> As I tried to tell you a couple of times now: When you have the orientation-matrix, then you dont have to >> calculate the up-vector anymore, because it is the second column of that matrix. Its already there.
You mean this matrix ofcoarse?
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(delta, dir.x, dir.y, dir.z); // Rotate/roll up vector.

>> Please post the code.
It's not written yet. But these tasks has to be done:
1. Everytime the up vector has to be made perpendicular to the look-at direction(Because the relation between the center and eye point may changing all the time)(To do that the up vector has to be moved from its current state straight forward(to the nearest perpendicularity) to the direction plane)
2. When roll rotated around the look-at direction with the roll function task 1 has to be done before. Then perform the rotation(The up vector has to be tilted(CW or CCW) from its perpendiculed state by the look-at direction as the rotate axis).

 

by: AntonKarlssonPosted on 2009-09-09 at 13:04:30ID: 25295028

But then I think that the up vector still has to be "matrix-vertex" multiplied. Because it has to be rotated from its current state/direction by the look-at direction.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(delta, dir.x, dir.y, dir.z); // Rotate/roll up vector.

 

by: ikeworkPosted on 2009-09-09 at 14:10:17ID: 25295585

>> You mean this matrix ofcoarse?
>> glMatrixMode(GL_MODELVIEW);
>> glLoadIdentity();
>> glRotatef(delta, dir.x, dir.y, dir.z); // Rotate/roll up vector.

No, a matrix is a type containing 16 float-values, usually

  float [4][4]
or
  float[16]

and it is uploaded to opengl with glMultMatrix, where the 2nd column is the up-vector.

>> But then I think that the up vector still has to be "matrix-vertex" multiplied. Because it has to be rotated from its current state/direction by the look-at direction.

You keep saying that, and i say, no, because (the last time) the 2nd column of the matrix *is* the up-vector already.
My friend, it really doesnt make any sense continuing here.

I showed you a lot of examples, how to set up a camera class. I'm really not sure how to help you anymore.
You should take the time and look at the examples. If you dont understand a specific part, feel free to ask. But really you have to consider looking at the examples, and try to understand them.


 

by: ikeworkPosted on 2009-09-09 at 23:46:32ID: 25297820

Please read the paragraph "Following Targets" here:

http://nehe.gamedev.net/data/articles/article.asp?article=08

All you have to do, is rotate the y-axis before you use it like shown there to get the new x-axis. Dont use {0, 1, 0} like they did, rotate it first with the roll-angle, like i showed above:

x' = sin(roll)
y' = cos(roll)
z' = z

and then go ahead calculating the new x-axis, like shown in the article.

Give it a try and put that into your code. That should get you started. Post the code here, when you are stuck.

 

by: AntonKarlssonPosted on 2009-09-10 at 13:06:32ID: 25303734

>> >> You mean this matrix ofcoarse?
>> >> glMatrixMode(GL_MODELVIEW);
>> >> glLoadIdentity();
>> >> glRotatef(delta, dir.x, dir.y, dir.z); // Rotate/roll up vector.

>> No, a matrix is a type containing 16 float-values, usually
I meant the matrix formed by those setup calls.

>>   float [4][4]
>> or
>>   float[16]
In OpenGL it is float [16].

>> and it is uploaded to opengl with glMultMatrix, where the 2nd column is the up-vector.
You must mean glLoadMatrix, right?

 

by: ikeworkPosted on 2009-09-10 at 23:33:49ID: 25307072

Yes glLoadMatrix replaces the current matrix, glMultMatrix multiplies it with the current matrix.

Did you read the article? Any progress in implementing the camera?

 

by: AntonKarlssonPosted on 2009-09-15 at 10:37:50ID: 25337282

Yes, I have looked at it. But where's the source of the Vector definition?
But this is setting up the camera matrix manually. I'm using gluLookAt(), just need to calculate the up vector to pass it. But thanks for the source anyway.

 

by: ikeworkPosted on 2009-09-23 at 06:33:55ID: 25402860

>> But where's the source of the Vector definition?

its always a 3 or 4 dimensional vector, either an array or a struct with x, y, z and w.

Besides that, its all there, I told you in this post how to do it:

http://www.experts-exchange.com/Programming/Game/Game_Graphics/OpenGL/Q_24687569.html#25297820


>> just need to calculate the up vector to pass it

then why didnt you use my posts above that showed it, the one with sin/cos?


I showed you some possible solutions in this thread. If you dont come up with some code, where you tried some of it, it doesnt make sense to talk more.
Please read the thread carefully, there was a lot of help. Writing the code is your turn, give it a try.

 

by: AntonKarlssonPosted on 2009-09-23 at 10:32:45ID: 25405699

I have found the perfect solution to my problem now. I took the left vector from the plane of the previous up vector and the new look direction. And took the new up vector(The only thing needed) from the intersection vector from that left vector plane and the direction plane. And nomalize it ofcourse.

I will try it now(write it). And post the code.
I'm sorry for this inconvenience. But thanks anyway.

left = crossProduct(up,dir);
up = crossProduct(left,dir);
up.normalize();
 
gluLookAt(pos->x,pos->y,pos->z,focus->x,focus->y,focus->z,up->x,up->y,up->z);

                                              
1:
2:
3:
4:
5:

Select allOpen in new window

 

by: ikeworkPosted on 2009-09-24 at 23:26:42ID: 25420404

Hey Anton,

So the input "up" is the previous up-vector?

left = crossProduct(up,dir);
up = crossProduct(left,dir);
up.normalize();

Then the new up-vector is not rotated by the roll-factor. It is just in the same plane as the old up-vector and the new direction. That is not the solution that you wanted.

 

by: ikeworkPosted on 2009-09-26 at 01:00:58ID: 25429150

However, good idea to start coding it anyway, then we have a starting point :)

 

by: AntonKarlssonPosted on 2009-09-26 at 05:44:29ID: 25429692

>> Then the new up-vector is not rotated by the roll-factor. It is just in the same plane as the old up-vector and the new direction. That is not the solution that you wanted.

This was the solution to the first problem which seemed very easy; to get the up vector perpendicular to the look direction dragged from its previous direction(the up-vector).

And the second problem was to rotate the up-vector around the look direction; which I will use the gl modelview matrix to setup with glRotatef(rollDelta,lookDir.x,lookDir.y,lookDir.z) (reset with identity first ofcoarse) and then get the matrix values by glGet and rotate the up-vector with it to roll it by the delta. But before that the up-vector has to be made perpendicular with that first task ofcoarse.

I just demonstrate with some sample code. Next I will write the whole code and post it.


void View::makePerpendicular()
{
    lookDir = pos - focus;            // Get the look direction by an overloaded operator implementation in the Vector class.
    left = crossProduct(up,lookDir);  // Calculate the left-vector needed.
    up = crossProduct(left,lookDir);  // Make the up-vector perpendicular.
    up.normalize();               // Normalize the up-vector ofcoarse.
}
 
void View::roll(GLfloat delta)
{
    makePerpendicular();    // Make the up-vector perpendicular first.
 
    // Use gl modelview to setup the matrix we need:
    GLfloat matrix[16];
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glRotatef(delta,lookDir.x,lookDir.y,lookDir.z);
    glGetFloatv(GL_MODELVIEW_MATRIX,matrix);  // Get the entry values.
    // Multiply the up-vector with it to roll it.
    up.multMatrix(matrix);
 // up.normalize(); // Don't know if needed.
}
 
void View::update()
{
    makePerpendicular();    // Make the up-vector perpendicular first.
 
    // The gluLookAt call:
gluLookAt(pos.x,pos.y,pos.z,focus.x,focus.y,focus.z,up.x,up.y,up.z);
 
}
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:

Select allOpen in new window

 

by: ikeworkPosted on 2009-09-26 at 07:49:15ID: 25429964

Now we're getting somewhere :)
I think we need to change a bit, but putting the theory in a programm is much better. Then you can really *see* the results.
If you are stuck anywhere, dont hesitate to ask.

ike

 

by: AntonKarlssonPosted on 2009-09-28 at 12:43:31ID: 25442597

Just one thing; I just give/pass the class the focus target position. I need to set the eye position for the View with setLookAt from a look-at direction and a distance. I don't exactly know how.

I'm just almost done with the code, I just need to know that one.

 

by: ikeworkPosted on 2009-09-28 at 13:26:57ID: 25443006

input:

dir -> normalized direction vector
target -> look at point
distance -> distance eyePos to target

eyePos = target - dir * distance

 

by: AntonKarlssonPosted on 2009-09-29 at 05:25:28ID: 25448059

>> eyePos = target - dir * distance
That easy.

 

by: ikeworkPosted on 2009-09-29 at 05:26:52ID: 25448070

Yepp :)

 

by: AntonKarlssonPosted on 2009-09-29 at 06:03:22ID: 25448487

I was thinking of using sin and cos for each x, y, z component.

But I have to use the * before the focus target position variable for the -operator function because I have it as a pointer(I have to use a pointer if I want to change the focus target in run-time). With the below -operator definition. Is there a way to get around without having 4 different -operator definitions with and without pointers.

Position operator-(Position &p, Vector &d)
{
	return Position(p.x - d.x, p.y - d.y, p.z - d.z);
}
 
 
Vector operator*(Vector &dir, GLfloat dist)
{
	return Vector(dir.x * dist, dir.y * dist, dir.z * dist);
}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:

Select allOpen in new window

 

by: AntonKarlssonPosted on 2009-09-29 at 06:28:27ID: 25448737

The code in makePerpendicular() seem to cause the viewing object to double; As it is flickering between two different perspectives.

void View::makePerpendicular()
{
    lookDir = pos - *focus;            // Get the look direction by an overloaded operator implementation in the Vector class.
    left = crossProduct(up,lookDir);  // Calculate the left-vector needed.
    up = crossProduct(left,lookDir);  // Make the up-vector perpendicular.
    up.normalize();               // Normalize the up-vector ofcoarse.
}

                                              
1:
2:
3:
4:
5:
6:
7:

Select allOpen in new window

 

by: ikeworkPosted on 2009-09-29 at 06:33:13ID: 25448782

>> Is there a way to get around without having 4 different -operator definitions with and without pointers.

Yes, derefernce the pointer using the '*' Example:

// pointer to vector
Vector *v;
Vector b;

// dereference v using '*'
Vector a = (*v) - b;


 

by: ikeworkPosted on 2009-09-29 at 06:36:29ID: 25448816

>> The code in makePerpendicular() seem to cause the viewing object to double; As it is flickering between two different perspectives.

Yes, I told you it wouldnt work like that, but now at least we have working code. Can you post it so I can have a look at it?

 

by: AntonKarlssonPosted on 2009-09-29 at 07:47:23ID: 25449619

>> Yes, derefernce the pointer using the '*' Example:

>> // pointer to vector
>> Vector *v;
>> Vector b;

// dereference v using '*'
Vector a = (*v) - b;

It was exactly what I had to do. But I wondered if there was a operator definition manner that took a pointer or the usual as likewise parameters. So that one doesn't need 4 different operator function definitions. Nevermind, forget about it.

>> Can you post it so I can have a look at it?
Sure, but it's in multiple source files but here's 'view.cpp':

#include "view.h"
#include "context.h"
 
 
View::View(Position *target)
{
	setViewport();
	setFocus(target);
	init();
}
 
 
View::View(Position *target, GLint x, GLint y, GLsizei w, GLsizei h)
{
	setViewport(x,y,w,h);
	setFocus(target);
	init();
}
 
 
void View::init()
{
	up.set(0.0f,1.0f,0.0f);
	setLookAt(0.0f,0.0f,1.0f,20.0f);
}
 
 
void View::setViewport()
{
	xview = 0;
	yview = 0;
	width = GetContextWidth();
	height = GetContextHeight();
 
	flags[FLAG_VIEWPORT_CHANGED] = true;
}
 
 
void View::setViewport(GLint x, GLint y, GLsizei w, GLsizei h)
{
	xview = x;
	yview = y;
	width = w;
	height = h;
 
	flags[FLAG_VIEWPORT_CHANGED] = true;
}
 
 
 
void View::setFocus(Position *target)
{
	focus = target;
}
 
 
void View::setLookAt(GLfloat x, GLfloat y, GLfloat z, GLfloat dist)
{
	lookDir.set(x,y,z);
	distance = dist;
	pos = *focus - lookDir * distance;
}
 
 
 
void View::makePerpendicular()
{
    lookDir = pos - *focus;            // Get the look direction by an overloaded operator implementation in the Vector class.
    left = crossProduct(up,lookDir);  // Calculate the left-vector needed.
    up = crossProduct(left,lookDir);  // Make the up-vector perpendicular.
    up.normalize();               // Normalize the up-vector ofcoarse.
}
 
void View::roll(GLfloat delta)
{
    makePerpendicular();    // Make the up-vector perpendicular first.
 
    // Use gl modelview to setup the matrix we need:
    GLfloat matrix[16];
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glRotatef(delta,lookDir.x,lookDir.y,lookDir.z);
    glGetFloatv(GL_MODELVIEW_MATRIX,matrix);  // Get the entry values.
    // Multiply the up-vector with it to roll it.
    up.matrixMult(matrix);
 // up.normalize(); // Don't know if needed.
}
 
void View::update()
{
    makePerpendicular();    // Make the up-vector perpendicular first.  
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
 
gluLookAt(pos.x,pos.y,pos.z,focus->x,focus->y,focus->z,up.x,up.y,up.z);
 
}
 
 
 
View::~View()
{
 
}
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:

Select allOpen in new window

 

by: AntonKarlssonPosted on 2009-09-29 at 08:52:40ID: 25450375

Why is it behaving like that?

 

by: ikeworkPosted on 2009-09-29 at 09:06:06ID: 25450507

>> Why is it behaving like that?

because this is wrong:

  left = crossProduct(up,dir);
  up = crossProduct(left,dir);
  up.normalize();
 
Can you show how you use the class View, where you call it?

 

by: AntonKarlssonPosted on 2009-09-29 at 10:03:23ID: 25451072

>> because this is wrong:

>>  left = crossProduct(up,dir);
>>  up = crossProduct(left,dir);
>>  up.normalize();

Why? What's wrong in it?

>> Can you show how you use the class View, where you call it?


Object object(0.0f,0.0f,-20.0f);
Position *posTarget;
 
int main(int argc, char *argv[])
{
	SDL_Init(SDL_INIT_VIDEO);
 
	SetupGLContext(640,480,0,SDL_RESIZABLE);
 
	posTarget = &object.pos;
 
	View view(posTarget);
 
//	InitVertices();
 
	SDL_Event event;
	bool running = true;
 
	while (running)
	{
		if (SDL_PollEvent(&event))
		{
			switch (event.type)
			{
			case SDL_QUIT:
				running = false;
				break;
			case SDL_VIDEORESIZE:
				ResizeGLContext(event.resize.w,event.resize.h);
				break;
			case SDL_KEYUP:
				if (event.key.keysym.sym == SDLK_ESCAPE)
					running = false;
				break;
			default:
				break;
			}
 
		}
 
		Uint8 *keys = SDL_GetKeyState(NULL);
		
		///////////////////////////////////
		
		// if move left/right:
		if (keys[SDLK_LEFT])
			posTarget->x -= 0.05f;
		else
		if (keys[SDLK_RIGHT])
			posTarget->x += 0.05f;
	//	else
	//		posTarget->x = 0.0f;
		
		// if move forward/backward:
		if (keys[SDLK_UP])
			posTarget->z -= 0.05f;
		else
		if (keys[SDLK_DOWN])
			posTarget->z += 0.05f;
	//	else
	//		posTarget->z = 0.0f;
		
		// if move up/down:
		if (keys[SDLK_PAGEUP])
			posTarget->y -= 0.05f;
		else
		if (keys[SDLK_PAGEDOWN])
			posTarget->y += 0.05f;
	//	else
	//		posTarget->y = 0.0f;
		
		view.update();
		RenderGLScene();
	}
 
//	FreeVertices();
 
	return 0;
}
 
 
 
 
 
 
 
 
 
void RenderGLScene()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
//	DrawVertices();
 
	object.draw();
 
	SDL_GL_SwapBuffers();
}
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:

Select allOpen in new window

 

by: AntonKarlssonPosted on 2009-09-29 at 11:58:58ID: 25452118

My guess is that the calculation for the up-vector is switching between up and down(the opposit direction). Is that so? Then how do I solve that?

 

by: AntonKarlssonPosted on 2009-09-29 at 12:07:35ID: 25452228

I tried now with swapping the parameters for it in the second crossProduct call. And it worked. Now it seem to be solved then.

My new function definition:

void View::calcUp()
{
    Vector dir = pos - *focus;
    Vector right = crossProduct(up,dir);  // Calculate the rigth(it was, not left)-vector needed.
    up = crossProduct(dir,right);  // <-- Swapped here.
    up.normalize();               
}

                                              
1:
2:
3:
4:
5:
6:
7:

Select allOpen in new window

 

by: AntonKarlssonPosted on 2009-09-29 at 12:38:13ID: 25452563

That got rid of the opposit flickering. The first problem seem to solved now but I forgot to test the roll function. I've done that now and it seem to work too. But I'm not really sure it's rotating correct. I posted the function and Vector's matrixMult function below. So you can see if I'm doing the matrix-vector multiplication right.

void View::roll(GLfloat delta)
{
    calcUp();
 
    // Use gl modelview to setup the matrix we need:
    GLfloat matrix[16];
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glRotatef(delta,lookDir.x,lookDir.y,lookDir.z);
    glGetFloatv(GL_MODELVIEW_MATRIX,matrix);  // Get the entry values.
    // Multiply the up-vector with it to roll it.
    up.matrixMult(matrix);
 // up.normalize(); // Don't know if needed.
}
 
void Vector::matrixMult(GLfloat *m)
{
	x = x*m[0] + y*m[1] + z*m[2]  + m[3];
	y = x*m[4] + y*m[5] + z*m[6]  + m[7];
	z = x*m[8] + y*m[9] + z*m[10] + m[11];
}
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:

Select allOpen in new window

 

by: ikeworkPosted on 2009-09-30 at 00:12:44ID: 25456196

You need to make copies of x and y first, otherwise you already use the transformed x and y.
The row and columns of the matrix are swapped also

void Vector::matrixMult(GLfloat *m)
{
      float xinput = x;
      float yinput = y;
      x = xinput*m[0] + yinput*m[4] + z*m[8]  + m[12];
      y = xinput*m[1] + yinput*m[5] + z*m[9]  + m[13];
      z = xinput*m[2] + yinput*m[6] + z*m[10] + m[14];
}

 

by: ikeworkPosted on 2009-09-30 at 00:18:30ID: 25456217

>>  left = crossProduct(up,dir);
>>  up = crossProduct(left,dir);
>>  up.normalize();

> Why? What's wrong in it?

1) rotate up-vector(0,1,0) by roll angle like shown in posts above
2) calc matrix that rotates the forward-vector(0,-1,0) to the direction vector
3) multiply that matrix(2) by new up-vector(1)

 

by: AntonKarlssonPosted on 2009-09-30 at 03:55:57ID: 25457176

It sometimes seem to roll rotate faster and sometimes slower.

>> 1) rotate up-vector(0,1,0) by roll angle like shown in posts above
>> 2) calc matrix that rotates the forward-vector(0,-1,0) to the direction vector
>> 3) multiply that matrix(2) by new up-vector(1)
Was this the right or wrong way to do it?

>> You need to make copies of x and y first, otherwise you already use the transformed x and y.
Why do I not need to do that with the z component?

I swapped the rows to columns now as below with my definition.

void Vector::matrixMult(GLfloat *m)	// void multMatrix(GLfloat &m[16])
{
	GLfloat _x = x;
	GLfloat _y = y;
	GLfloat _z = z;
	x = _x*m[0] + _y*m[4] + _z*m[8]  + m[12];
	y = _x*m[1] + _y*m[5] + _z*m[9]  + m[13];
	z = _x*m[2] + _y*m[6] + _z*m[10] + m[14];
}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:

Select allOpen in new window

 

by: ikeworkPosted on 2009-09-30 at 04:55:24ID: 25457556

>> Why do I not need to do that with the z component?

Because z is changed in last row.
x is changed in 1st row. so in 2nd row, when y is calulated, you would use the new x, instead of the original.
The same for y. You would use the transformed y, when you calculate z in the last row.

>> >> 1) rotate up-vector(0,1,0) by roll angle like shown in posts above
>> >> 2) calc matrix that rotates the forward-vector(0,-1,0) to the direction vector
>> >> 3) multiply that matrix(2) by new up-vector(1)
>> Was this the right or wrong way to do it?

Its the right way to do it ;)

 

by: AntonKarlssonPosted on 2009-09-30 at 06:15:47ID: 25458453

>> 1) rotate up-vector(0,1,0) by roll angle like shown in posts above
>> 2) calc matrix that rotates the forward-vector(0,-1,0) to the direction vector
>> 3) multiply that matrix(2) by new up-vector(1)
Exactly how in code?

 

by: ikeworkPosted on 2009-09-30 at 07:06:18ID: 25458965

Cant give you a full code resolution, I got a job ;)
Give it a try and when you're stuck, post here and ask a specific question.

 

by: AntonKarlssonPosted on 2009-09-30 at 07:16:51ID: 25459078

No I just meant the code for those 3 steps.

 

by: ikeworkPosted on 2009-09-30 at 07:28:59ID: 25459214

>> No I just meant the code for those 3 steps.

Thats what I meant too. Well step 1) was already in the post above:

1)

x' = sin(roll)
y' = cos(roll)
z' = z

2) a) calc rotation axis = crossProduct of both notmalized vertices
    b) calc rotation angle = acos of the dotProduct if both notmalized vertices
    c) create matrix from a & b

for details look here:
http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/rotation/index.htm

Give it a try

 

by: ikeworkPosted on 2009-09-30 at 07:31:44ID: 25459254

 

by: AntonKarlssonPosted on 2009-11-18 at 12:46:31ID: 25854591

Okey. I want to go with my own solutions(But I can't choose my own, why?) which I  found accurate to the two questions/problems from my OP quoted below:

Problem/Question #1:
>> So my first question is how do I calculate the up vector from the viewing direction vector and camera/view roll?

Problem/Question #2:
>> And two how do I call the gluLookAt and place all scene-objects locations(with the basic gl translation functions)? And when to call glLoadIdentity()?


The solutions:

Problem/Question #1:

I use a void function called 'calcUp' to (re)calculate the up vector to keep it perpendicular/orthogonal to the ever-changing(current) look direction vector(obtained from the delta/diffental vector of the camera/view eye position and the center/target(focal point)). which shall be called before every operation(the update and roll functions) regarding itself.

void View::calcUp()
{
    Vector dir = pos - *focus;                   // Get the actual/current look direction vector.
    Vector right = CrossProduct(up,dir);  // Calculate the rigth vector needed with it and the original up vector's previous state.
    up = CrossProduct(dir,right);            // Get the new requested up vector from the current look direction and the right vector.
    up.normalize();                              // And don't forget to normalize it.
}

The up vector will be initialized to (0.0,1.0,0.0) in the constructor of coarse.


Problem/Question #2:

The roll function:

void View::roll(GLfloat delta)
{
    calcUp();     // Update the up vector.

    Vector dir = pos - *focus;   // Get the actual/current look direction vector.

    // Use gl's modelview to setup the matrix we need:
    GLfloat matrix[16];                         // Declare the fetch matrix array.
    glMatrixMode(GL_MODELVIEW);   // Select the modelview matrix.
    glLoadIdentity();                             // Reset it to identity.
    glRotatef(delta,dir.x,dir.y,dir.z);     // Rotate the matrix by the +/- roll delta around the current/actual look direction.
    glGetFloatv(GL_MODELVIEW_MATRIX,matrix);  // Get the matrix entry values.
    up.matrixMult(matrix);                     // Multiply the up-vector with that matrix.
 // up.normalize();             // Maybe needed. Or
 // calcUp();                      // Could also be needed. And instead.
}

Here I had a bug which was when I first had the look direction specified by the setLookAt() function left.
Which gets void/incorrect when the focal target changes its position which sometimes causes the up vector to rotate slower around or not at all. And rotates around that wrong axis which I now discovered and advised to the current/actual/upcoming look direction as the way I did in the calcUp() function.


The View class code:


 
class View
{
public:
    View(Position &target, SDL_Rect &area, GLfloat dirx, GLfloat diry, GLfloat dirz, GLfloat dist);
    void setLookAt(GLfloat dirx, GLfloat diry, GLfloat dirz, GLfloat dist);
    void calcUp();
    void update();  // The vision update.
    void updateLookAt(); // Updates the camera's eye position.
    void roll(GLfloat delta);
    ~View();
private:
    SDL_Rect *area;   // The viewport area.
 
    // The three variables needed for gluLookAt():
    Position eyePos; // The camera's eye position.
    Position *focus; // The center target focus.
    Vector up;       // The up vector.
 
    // To calculate the eyePos from the focus target:
    Vector lookDir;  // The look direction.
    GLfloat distance;// And the distance from the focus target.
};
 
 
 
 
View::View(Position &target, SDL_Rect &area, GLfloat dirx, GLfloat diry, GLfloat dirz, GLfloat dist)
{
    focus = &target;
    area = &area;
    up.set(0.0,1.0,0.0); // Initially sets the up vector pointing up.
    setLookAt(0.0,0.0,1.0,20.0);
}
 
void View::setLookAt(GLfloat dirx, GLfloat diry, GLfloat dirz, GLfloat dist)
{
    lookDir.set(dirx,diry,dirz);
    distance = dist;
 
    updateLookAt();
}
 
 
 
void View::calcUp()
{
    Vector dir = pos - *focus;                   // Get the actual/current look direction vector.
    Vector right = CrossProduct(up,dir);  // Calculate the rigth vector needed with it and the original up vector's previous state.
    up = CrossProduct(dir,right);		// Get the new requested up vector from the current look direction and the right vector.
    up.normalize();					// And don't forget to normalize it.
}
 
 
// The vision update:
void View::update()
{
    glViewport(area->x,area->y,area->w,area->h);
 
    calcUp();
 
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(eyePos.x,eyePos.y,eyePos.z,focus->x,focus->y,focus->z,up.x,up.y,up.z);
 
    DrawGLScene();  // Draw the GL scene.
}
 
 
// Updates the camera's eye position by
void View::updateLookAt()
{
    eyePos = *focus + lookDir * distance;
}
 
 
void View::roll(GLfloat delta)
{
    calcUp();     // Update the up vector.
 
    Vector dir = pos - *focus;   // Get the actual/current look direction vector.
 
    // Use gl's modelview to setup the matrix we need:
    GLfloat matrix[16];                         // Declare the fetch matrix array.
    glMatrixMode(GL_MODELVIEW);   // Select the modelview matrix.
    glLoadIdentity();                             // Reset it to identity.
    glRotatef(delta,dir.x,dir.y,dir.z);     // Rotate the matrix by the +/- roll delta around the current/actual look direction.
    glGetFloatv(GL_MODELVIEW_MATRIX,matrix);  // Get the matrix entry values.
    up.matrixMult(matrix);                     // Multiply the up-vector with that matrix.
 // up.normalize();             // Maybe needed. Or
 // calcUp();                      // Could also be needed. And instead.
}
 
 
View::~View()
{
}
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:

Select allOpen in new window

 

by: AntonKarlssonPosted on 2009-11-19 at 12:07:53ID: 31621368

Thanks ikework for your help.

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...