Retrieving a point where the camera is facing

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Nyxojaele
Posts: 98
Joined: Mon Sep 18, 2006 4:06 am

Retrieving a point where the camera is facing

Post by Nyxojaele »

So I'm trying to find a vector3df that's placed ANYWHERE on the line projecting from the center of my current camera. This is all during initialization btw, so there have been no calls to createScene() or any such thing.

Basically what I'm trying to achieve is a camera class that calls lookAt() on a target ISceneNode every frame, and I just move that scene node around to have the camera look elsewhere. That all works fine, and what I'm trying to do now is initialize it properly. Right now, I just hard-coded a location for the scene node to start, and as such, the camera will always start facing that point. I want the camera to start facing an arbitrary direction (and thus, point), so I need a way to calculate where to put my scene node the camera will be lookAt()ing at when my camera is first created.

My first few lines of code for this were put immediately after :

Code: Select all

		position2d<s32> screenCenter = position2d<s32>(400, 300);
		line3df line = mDevice->getSceneManager()->getSceneCollisionManager()->getRayFromScreenCoordinates(screenCenter);
But what I noticed at this point was that the line3df returned isn't correct.
line.start is giving me the camera's world position, which is fine, but line.end is always giving me vector3df(0.0f, 0.0f, 1.0f) and I have no idea why. If I put that same code into my createScene(), the first call will give me the same thing, but the later calls will be okay. Why might that be? Is there some updating that needs to be done internally in the engine after I create an ICameraSceneNode with a lookAt position, before it's ACTUALLY looking at that position?
JonLT
Posts: 152
Joined: Thu Mar 15, 2007 5:47 pm
Location: Denmark

Post by JonLT »

i dont fully understand what you want to do. I think you want to make the camera always look at a specific scenenode. To do this you set the target of the camera to the position of the scenenode:

Code: Select all

while(device->run())
{
  driver->beginScene(...);
  camera->setTarget( node->getPosition() );
  smgr->drawAll();
  driver->endScene();
}
Hope this helps :)
Nyxojaele
Posts: 98
Joined: Mon Sep 18, 2006 4:06 am

Post by Nyxojaele »

Sort of.

What I have is a class that looks (simplified) like this:

Code: Select all

class camFree: public camCamera {
public:
  camFree(ICameraSceneNode *camera);
  ~camFree();

  void update();

private:
  ICameraSceneNode *mCamera;
  ISceneNode         *mTarget;
};
roughly. - - Every frame, the update() function is called, and all it really does is the following:

Code: Select all

void camFree::update() {
  mCamera->setTarget(mTarget->getPosition());
}
What this allows me to do is move the camera or the target, and the camera will always be looking at the target.

To elaborate more on what I'm trying to achieve, here's the constructor for the class:

Code: Select all

camFree::camFree(ICameraSceneNode *camera): mCamera(camera) {
  mTarget = ISceneManager::addSceneNode();
  //Figure out where mCamera is looking, and put mTarget there, so when update() is called, it all looks smooth
  //  ---- HOW? ----
}
The line that's creating the class is this:

Code: Select all

ICameraSceneNode *camNode = ISceneManager::addCameraSceneNode(0, vector3df(0, -30, -9), vector3df(9, -30, 9),
camCamera *camera = new camFree(camNode);
So as you can see, I'm specifying the camera's starting position and looking position when I create the ICameraSceneNode, and since my camera is being repositioned every frame to be looking at it's internal target ISceneNode, what I want to do is initially set that target ISceneNode to a position directly in front of the camera, where's it looking when I create the camFree class with that camera.


To put this in simple terms using code that doesn't exist in the Irrlicht Engine, I want to do this:

Code: Select all

mTarget->setPosition(mCamera->getTargetPosition());
But since obviously the camera's target is not a 3d point in space, but rather a ray, this is not possible;; So I've put together a couple of lines of code in the constructor to start figuring that out, but I'm not getting expected results back from ISceneCollisionManager::getRayFromSceneCoordinates()..

When I change the constructor to look like this:

Code: Select all

camFree::camFree(ICameraSceneNode *camera): mCamera(camera) {
  mTarget = ISceneManager::addSceneNode();
  //Figure out where mCamera is looking, and put mTarget there, so when update() is called, it all looks smooth
  position2d<s32> screenCenter = position2d<s32>(400, 300);
  line3df line = ISceneCollisionManager::getRayFromScreenCoordinates(screenCenter);
}
and I examine the line variable after the call to getRayFromScreenCoordinates(), it gives me the correct numbers in line.start, which is the camera's position, but the numbers in line.end are way out to lunch at vector3df(0, 0, 1)... that makes no sense, since the camera's obviously not looking at that point- looking at the code tells us that it's actually looking down the Z axis. If the camera was looking at that point, it would be looking almost straight up! (along the Y axis)
JonLT
Posts: 152
Joined: Thu Mar 15, 2007 5:47 pm
Location: Denmark

Post by JonLT »

there is a getTaget member in the camera class api-link
that might be of use to you?
Nyxojaele
Posts: 98
Joined: Mon Sep 18, 2006 4:06 am

Post by Nyxojaele »

That is exactly what I needed to get this working properly, thank you very much. I wonder how I managed to miss that in the API docs? I guess it helps to have another set of eyes look- thank you muchly^^

So, I'm doing what I want to now, but I'm still curious about my other question: Why is it that the getRayFromScreenCoordinates function was returning such a strange value?
Post Reply