Rotating camera around an object

Started by
16 comments, last by BroderickCalpe 11 years, 1 month ago

I've been searching the web and can't find any good tutorial or example of how to rotate the camera around an object.

Imagine having an object in the center and the camera should rotate around it so it looks like the object itself is rotating.

How is this done ?

Please explain in detail because I'm really new at this. Code would really help out.

Thanks :-)

Advertisement

Well... I am certainly not an oracle, so... Are you talking about 2D or 3D? Which programming language are you using and which graphics library/engine?

look up gluLookAt(assuming 3D)

you'll need to update the eye position as you move around a circle, like so:


float Theta = 0.0f;
float Distance = 20.0f;
while(!Done){
  gluLookAt(cosf(Theta)*Distance, 0.0f, sinf(Theta)*Distance, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
 Theta+=M_PI*0.01f; //move at a slow pace.
 
}

of course, you'll have to figure out where to integrate this into your code base=-)

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

I'm using C++, using Gameplay3D engine.

I found these operations to be used in Gameplay3D but don't know how to apply them to get the correct effect.

Any help would be appreciated.

float dt = elapsedTime / 1000.0f;


Node* carNode = _scene->findNode("Board");


Node *cameraNode = _scene->getActiveCamera()->getNode();


Vector3 carPosition(carNode->getTranslation());


Vector3 commandedPosition(carPosition + Vector3::unitY()*4.0f - carNode->getBackVector()*10.0f);


cameraNode->translateSmooth(commandedPosition, dt, 0.2f);


Matrix m;


Matrix::createLookAt(cameraNode->getTranslation(), carPosition, Vector3::unitY(), &m);


m.transpose();


Quaternion q;


m.getRotation(&q);


cameraNode->setRotation(q);

I know that the code above doesn't solve my problem but I guess it helps to maybe get the solution.

What is M_PI ?

Is this maybe just PI = 3.14......


static float Theta = 0.0f;
    float Distance = 20.0f;
    Node *boardNode = _scene->findNode("Board");
    Node *cameraNode = _scene->getActiveCamera()->getNode();
    Vector3 upY(0.0f, 1.0f, 0.0f);
    Matrix m;
    Matrix::createLookAt(cosf(Theta)*cameraNode->getTranslation(), sinf(Theta)*boardNode->getTranslation(), upY, &m);
    Theta += 3.14*0.01f;
    Quaternion q;
    m.getRotation(&q);
    cameraNode->setRotation(q); 

I gave it a try using Gameplay3D. Having a look at the code GluLookAt. But I can't get it to work properly.

first of all, do you have a mental-model for what you are trying to do? Without at least understanding that, no amount of code will help you.

What you are essentially trying to do is rotate an object around a point. in this case, the object is the camera, and the point is some item's location.

each object, including your camera, should have some way of specifying both location and direction (usually in the form of vectors).

Armed with these, some basic math:

you can make a vector from the point you want to rotate around to the camera (camera's coordinates - point you want to rotate around).

Once you have this, you can do some matrix math (or quaternions or whatever) to rotate that vector some X degrees. This will give you a resultant vector which points in the direction you want your object to be in. be scaling this to the length of the original vector, you get the exact coordinates you want to move the camera to. So...translate the camera to that point!

Ok, that's half the problem. You now know how to move the camera to the spot you want, but it is still facing the ORIGINAL direction. so how do we rotate the camera?

well, if you take the vector you made above for translation (the end-result vector) and reverse it, you now have a vector pointing in the direction you want to be looking. using the components from this vector, you can get the amount you need to rotate the Camera's x, y, z DIRECTION vectors by to rotate it. Again, do your matrix math (or quaternion or whatever) to rotate these vectors (and thus the camera) around its local origin (or, translate first to the origin and then rotate, and translate back).

on a fundamental level, the above is one way to think about it. I make no claim that it is fastest / best (in fact, i'm a bit rusty so might even be wrong?)

once you have these fundamentals in hand I think it will be a lot easier for you since the rest is mostly lining up the right function calls...

also here's a nice note on the subject

http://stackoverflow.com/questions/786293/opengl-rotate-around-a-spot

maybe that is easier for you to understand?

Thanks all for the help.

The theory sounds really good and interesting but the actual programming part is what is missing.

Too bad that it seems to be so hard to find practical examples or tutorial regarding this problem.

Someone told me also that there is the old way of doing things using older versions of OpenGL and then there's the more recent method, meaning that you have to do the actual Matrix math. I assume the later part is what I need practical examples of.

The theory sounds really good and interesting but the actual programming part is what is missing.

Too bad that it seems to be so hard to find practical examples or tutorial regarding this problem.

That's the part that you do yourself as a programmer. Thinly veiled "just give me the code" request, anyone?

The latest code you posted is confused at best. createLookAt creates a view matrix. It does not, in any way, represent the rotation/orbit you're seeking.

The object you're rotating around has its own translation, a point in worldspace. That will always be the target of your lookAt function.

All you need to do is calculate a matrix for rotating the camera's translation around the car's translation. Calling lookAt with an origin of the camera's (updated) location and a target of the car's location will orient your camera's view matrix correctly.

To rotate an object around a point in space, you have to do two things:

  • treat that point as the origin
  • determine what axis you're rotating around

The first bullet is what the translate calls are for in the stackoverflow link Ikarus posted. Gameplay3D has Matrix::translate, so you're good there. Let's assume you just want to rotate around a universal "vertical" axis, so a Y axis running through the car. Matrix multiplication for the camera's position would then use

Matrix::translate(the opposite/negative version of the car's position)

Matrix::createRotationY(to rotate a set number of degrees around the Y axis...assuming the Y axis is "up" in your game)

Matrix::translate again (this time pushing the rotated camera back to it's relative location near the car)

The result of these three operations can be multiplied together (in the correct order, I'm always bad about remembering matrix multiplication order, whether it's backwards or forwards) and applied to the camera's position to rotate around the target.

Arguments to your Matrix::createLookAt function shouldn't change. The camera will always want to "look at" the same target from its own position.

Hazard Pay :: FPS/RTS in SharpDX (gathering dust, retained for... historical purposes)
DeviantArt :: Because right-brain needs love too (also pretty neglected these days)

This topic is closed to new replies.

Advertisement