How to get the position in 3d space in OpenGL ES?
Login to reply to this topic.
Fri, 2010-01-08 09:48
Joined: 2008-02-12
Forum posts: 77

I need to get the cameras position in x,y and z coordinates. How can I get this information? I don't find
any method for this.

I am programming a 3d space game. It is possible to move around in the 3d space with the arrow keys. glTranslatef and glRotatef calls moves the camera when the user wants to move. So the camera 's x,y and z coordinates is changed when the user presses the arrow keys. I need to find the cameras position after this movement. How can I do that?


Mon, 2010-01-11 14:20
Joined: 2005-01-11
Forum posts: 56
Mon, 2010-01-11 15:44
Joined: 2008-02-12
Forum posts: 77

Thanks for the link, but I need a way to get the current position. Is there a way to get this position from the modelview matrix?

The user moves around by pressing the arrow keys. The up and down key changes the X rotation (cRotX) and the left and right key changes the Z rotation (cRotZ). zplaceReal are increased for every time,which creates the movement. Then these calls are made:

glTranslatef(xplace, yplace, zplaceReal);
glRotatef(cRotX, 1, 0, 1);
glRotatef(cRotZ, 0, 1, 1);

Based on this, I could calculate the movement in x,y,z and from this update parameters which would track the current position. This would however be complicated,since both z and x rotations are made for each movement. So it would be much better if I could just get the current position after the movement from the modelview matrix. Is this possible?

Tue, 2010-01-12 10:58
Joined: 2004-11-29
Forum posts: 1419

By definition in OpenGL, the camera is always in (0,0,0).
You then change the modelview matrix to "move the world" around the camera.

So you have to keep track yourself of where in your virtual world your camera is.

What you need is a better way to handle your movement so it isn't so complicated to keep track of where you are.

In most 3D programming, you make sure to build the modelview matrix from scratch each frame (starting with a call to glLoadIdententiy() ), using the stored position and heading of the camera. A common way is to have 3 vectors, position, up, and direction defining your camera position, and calculate your matrix from that. (basically doing a change of basis in linear algebra)

It gets a slightly trickier to move it around, you have to work with vectors instead of just adds.
But its easier in the long run. It quickly gets confusing if you try to save a matrix between frames, and for not much gain.

Another tip is the gluLookAt function from the gl-utilities.
You can find those here: http://www.khronos.org/developers/resources/opengles/#tutilities

Can also recommend the PoverVR SDKs matrix classes for all your 3d linear algebra needs.
Find those under the "implementation" tab on the above link.

Note: I say "from scratch" but usually you have parts of it cached of course, but the point is to not let it accumulate over frames, but rebuild it from identity every frame.

Tue, 2010-01-12 15:30
Joined: 2008-02-12
Forum posts: 77

I see, I will have to implement a better movement then. I found the TCamera utility class from Nokia (attached below). It has 3 vectors, position, up, and direction. It also has a GetViewMatrix()method,which calculates the matrix from that.

Do you mean that the movement should change this matrix, and then that the position, up, and direction vectors get affected by this change? Then I could just get the position from the available GetPosition() method.

------

// =============================================================================
// =============================================================================
/**
* Helper class that implements a camera in 3D space using single precision floating point math.
* The camera is represented by an eye point vector, "look-at" direction vector and an up vector.
* This class is very useful since it provides an implementation of the gluLookAt() method
* which is not part of the OpenGL ES specification.
*/
class TCamera
{
public: // Constructors

/**
* Constructs and initializes TCamera to Position (0,0,0), LookAt (0,0,-1), Up(0,1,0).
* This equals the default model view matrix setting of OpenGL (camera located at origo, looking towards
* negative Z-axis and up direction towards positive Y-axis).
*/
TCamera();

/**
* Constructs and initializes TCamera using the given position, look at direction and up orientation vector.
* @param aPosition Position of the camera.
* @param aLookAt "Look-at" direction of the camera.
* @param aUp "Up" vector of the camera.
*/
TCamera(TVector aPosition, TVector aLookAt, TVector aUp);

public: // New functions

/**
* Returns the position of this camera.
* @return Position of this camera.
*/
TVector GetPosition();

/**
* Returns the "look-at" direction of this camera.
* @return "Look-at" direction of this camera.
*/
TVector GetLookAt();

/**
* Returns the "up" direction of this camera.
* @return "Up" direction of this camera.
*/
TVector GetUp();

/**
* Returns the 4x4 model-view matrix representation of this camera.
* @return Pointer to 4x4 model-view matrix representation of this camera.
*/
GLfloat * GetViewMatrix();

/**
* Resets the given 4x4 matrix to identity matrix.
* @param aMatrix Target matrix to be reset to indentity matrix.
*/
static void MakeIdentity(GLfloat * aMatrix);

/**
* Sets the camera to use the given position, look-at direction and up direction vectors.
* This is NOT an implementation of the gluLookAt() function. This method DOES NOT place
* the translation of the camera position into the view matrix. The position must be applied
* separately after applying the view matrix.
* E.g. glTranslatef( -iCamera->getPosition().iX, -iCamera->getPosition().iY, -iCamera->getPosition().iZ )
*
* @param aPosition Position of the camera.
* @param aLookAt "Look-at" direction of the camera.
* @param aUp "Up" vector of the camera.
*/
void LookAt(TVector aPosition, TVector aLookAt, TVector aUp);

protected: // Data
/** Position of the camera's eye point. */
TVector iPosition;
/** Position of the "look-at" direction point. */
TVector iLookAt;
/** Direction of the up vector. */
TVector iUp;
/** View matrix. */
GLfloat iViewMatrix[4][4];

public: // Friend classes
friend class T3DModel;
};

Thu, 2010-01-14 10:02
Joined: 2004-11-29
Forum posts: 1419

You could use that class to calculate the matrix.

You should have some kind of model of how your spacecraft is behaving in the world.
could be anything from an advanced physical model to something simple like a speed-vector you add to your position, and rotate and re-normalize (to avoid calculation errors) the speed-vector when your craft manouvers.
Also an up-vector to know what is up, and make it possible to roll and such.

Then, when you draw the scene, you use the values from your spacecraft model, calculate the vectors you need if there isn't an exact match in your model, put them into this class (or gluLookat, or some other way to calcualate the modelview matrix), calculate the matrix, and load it into the modelview matrix.

This is really a lot bigger topic then you might excpect at the first glance, I have a hard time trying to keep it brief Smiling
There is lots of stuff to find through google, and lots of nice books out there to read though.

www.gamedev.net comes to mind.

Thu, 2010-01-14 13:14
Joined: 2008-02-12
Forum posts: 77

The movement that I had implemented before did a x-rotation upwards with the up arrow and a x-rotation downwards with the down arrow. It did a y-rotation to the left with the left arrow key and a a y-rotation to the right with the right arrow key. Fire button increased speed and * decreased it. # changed the movement direction.

I use the

iCamera.LookAt( posVector,
lookAtVector,upVector)

method. Do you mean that I should change the posVector and the upVector to implement x-rotation and y-rotation?

Then I could use glTranslatef( -iCamera->getPosition().iX, -iCamera->getPosition().iY, -iCamera->getPosition().iZ )

to load the positions into the model view matrix?

And then glRotatef(angle, upVector.iX, upVector.iY, upVector.iZ); to load the rotation into the model view matrix?

Fri, 2010-01-15 16:36
Joined: 2008-02-12
Forum posts: 77

I realized that the code that I posted last time was probably wrong. You say "you have to work with vectors instead of just adds". I assume that you mean that I should use glLoadMatrixf instead of glrotate and gltranslate? I use this code now:

void CParticles::HandleMovement()
{
TVector posVector = TVector(xplace, yplace, zplaceReal);
TVector upVector = TVector(cRotX, cRotY, cRotZ);

iCamera.LookAt(posVector, lookAtVector, upVector);

GLfloat* matrix = iCamera.GetViewMatrix();
glLoadMatrixf(matrix);
}

Was it somthing like this that you meant? Do I need gl-utilities or PoverVR SDKs matrix classes or can I solve this with the classed that I have?

The lookAtVector is never changed,it is just initialized to lookAtVector=TVector(0.f, 0.f, -1000f)
My model of how the spacecraft is behaving is that the left and right keys should do a y rotation,by changing the
posVector and the values of the upVector. The up and down keys should do a x rotation,by changing the values of the posVector and the upVector.

The Fire button should increased the speed and * decrease it.
The speed should be how much the values of the upVector and the posVector are changing. Do you think this could work?

Mon, 2010-01-25 14:47
Joined: 2008-02-12
Forum posts: 77

It seems like there is no gluLookAtf function in the GLU ES library on your link:
http://www.khronos.org/developers/resources/opengles/#tutilities
Where can I find this function?

Mon, 2010-01-25 15:17
Joined: 2005-01-11
Forum posts: 56

I dont think you need to use the matrix directly, using glPush and glPop will help too


Tue, 2010-02-02 13:52
Joined: 2004-11-29
Forum posts: 1419

Sorry, its just a bit too much work to go through this in detail with you.
There are many ways it "could" be done, and what way is the best depends too much on what you want to do, your skill with 3d math, and the rest of your code, for it to be possible for me to tell you "the right way".

If I were you I'd try to post questions like this on an OpenGL or game programming forum instead.

This has nothing to do with cell phones or Symbian really (or even C/C++ if taking it to the extreme)

Thu, 2010-02-18 09:46
Joined: 2008-02-12
Forum posts: 77

I have hired a consultant company to fix this problem. I need the position in 3d space for implementing collision detection between the player and objects in 3d space.

The consultant company recommend placing a bound around an invicible object which is placed at the view point. They say that no detection is done using viewpoint coordinates. Instead it's always advisable to check the invicible objects bounds to the other objects bounds. Then you don't need to keep track of the camera's position, but just a check if the collision object ID's did collide.

The GLulookat method implementation is meant to to easy the use of Camera and its tracking, but you don't need any tracking for this if you use an invicible object which is placed at the view point. They say that this can be solved with the same movement that is implemented now, so the movement does not need to be changed.

Is the consultant company right about this? Should I really not use the GLulookat method? Should I place a bound around an invicible object which is placed at the view point and then compare the bounds? Can I keep the same movement that I have now?

Thu, 2010-02-18 13:08
Joined: 2005-01-11
Forum posts: 56

Collision detection is a tough subject ...

quoting you:

> but just a check if the collision object ID's did collide.

well you'll also need to position of the object, so if it is around the camera, you'll stell need the camera position too Smiling

Volumes collision is a great technique, but u'll have to compute this for each displayed objects ...

An other solution is to implement a raycasting method to see how far you're from the colliding object ...

This can be optimized with rendering object number into a non displayed buffer (ie stencil, but might not be avaliable on embedded chips)

Unlesss you find some lib doing this :
http://code.google.com/p/bullet/

Regards


Thu, 2010-02-18 14:34
Joined: 2008-02-12
Forum posts: 77

I see, but is the consultant company right about this? Should I really not use the GLulookat method? Should I place a bound around an invicible object which is placed at the view point and then compare the bounds? Is it true that no detection is done using viewpoint coordinates? You can see my collision method below. x1,y1 and z1 are the positions of the viewpoint. Do you think this method would work?

TBool CParticles::detectcollision(GLfloat x1, GLfloat y1, GLfloat z1)
{
TReal xd, yd, zd, minDistance;
minDistance = 100;
TReal Distance;

xd = posX - x1;
yd = posY - y1;
zd = posZ - z1;
TReal magnitude = (TReal) (xd * xd + yd * yd + zd * zd);

const TReal &aSrc = magnitude;
Math::Sqrt(Distance, magnitude);

if (minDistance >= Distance)
return true; //collision
else
return false; //no collision
}

Thu, 2010-02-18 14:52
Joined: 2008-02-12
Forum posts: 77

By the way,the objects in the game are very simple. They are only textured rectangles. That is why I figured that my simple collistion detection method would work. Is it really necessary to have bounds for so simple objects as textured rectangles?

Thu, 2010-02-18 17:11
Joined: 2004-11-29
Forum posts: 1419

Its very hard to answer these question accurately without intimate knowledge of your code and requirements.

3D can be tricky, and often you can find solutions you didn't think of first, just by looking at the problem from a different angle (possibly quite literally... Eye-wink )

Its possible your simple 2 point distance check is enough for you.

And if you analyse it a bit, you will see that it is infact also a volume check, namely a Sphere<->Point check.
(for Sphere<->Sphere you just have to add together the two radiuses and do the same check)

AABB (axis aligned bounding box) volume checks are not very complex either though, so nothing to be afraid of.

Also the mentioned rays are pretty easy just a line equation in 3d. p = v * t (v being the direction vector)

If your texture rectangles are axis aligned, a distance check in only the perpendicular axis could be enough.

If not, you might want to consider a Point<->Plane check.

Or again, maybe the simple 2 point distance check is enough.

Then there is a whole bunch of other volume checks possible, more or less complex. Its a whole academic field in itself almost...

if you have a very simple scene, without need for advanced camera movements, you might indeed not need gluLookAt.
That would mean you would keep your virtual camera at 0,0,0 always, and just move all objects around you.
If all objects move independently, this might be the best approach, but if a lot of objects are interdependent, it might be more optimal to move the virtual camera instead. (or not, there are other ways to handle it too...)

I understand these answers might be frustrating, but in 3D games programming the answer is often "it depends..."

What is right for you, you can only find through experience.

Because its also a lot up to how you want to look at the problem for you to understand it the easiest.

(quick tip; you could optimize away the sqrt if you are just comparing distances, just compare with the distance^2 instead of distance. sqrt is very slow compared to a multiplication, and if the distance is constant, you can square it in compile time)


copyright 2003-2009 NewLC SARL