Is getRayFromScreenCoordinates() dependent on last frame?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
piiichan
Posts: 59
Joined: Thu May 01, 2008 1:20 am
Location: New Caledonia (France - Pacific)
Contact:

Is getRayFromScreenCoordinates() dependent on last frame?

Post by piiichan »

I'll try to explain the situation as best as I can, so it may be a bit wordy!

I have a moving player character in a diablo-like game.
The view is isometric, the camera is orthogonal. As soon as the character moves, the camera position and target are updated , so the camera is always looking at the character and is always at the same position relatively to the character. (the camera is NOT a child node of the character node, I do it via camera->setPosition()).
When the left mouse button is down, I use ISceneCollisionManager::getCollisionPoint() and ISceneCollisionManager::getRayFromScreenCoordinates() to find where the player wants to move.

Everything is working correctly when the character is still.

However, when the character is moving, the collision point I get is not correct: I get the collision point of the previous frame.
In other words, I get the collision point just as if the camera was still at the previous location. This is obvious when the character moves fast: the collision point is very far from the mouse location and the offset from the current mouse location is exactly the distance traveled at each frame.
I thought at first I was calling the functions in a wrong order, but everything in my code is correct: I first move the camera, THEN get the collision point from screen coordinates.
After some experiments, calling ISceneManager::drawAll() alone, after repositionning the camera, and before doing the collision test, makes the collision test work fine.

How can I solve this collision problem without calling ISceneManager::drawAll() before doing the collision test?
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Call camera->updateAbsolutePosition() after moving it.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
piiichan
Posts: 59
Joined: Thu May 01, 2008 1:20 am
Location: New Caledonia (France - Pacific)
Contact:

Post by piiichan »

Call camera->updateAbsolutePosition() after moving it.
I tried it, but it still won't work.

Here is where I set the camera position and target:

Code: Select all

camera->setPosition( vector3df(
		node->getPosition().X + offset,
		hypoLength,
		node->getPosition().Z - offset));
camera->setTarget( node->getPosition() );
g_smgr->drawAll();
...
As you see, I have to call drawAll(), even if this code is not between driver-beginScene() and driver->endScene(). Calling camera->updateAbsolutePosition() instead does not solve the problem.

I wonder why is the drawAll() method of the scene manager correcting the problem?
CuteAlien
Admin
Posts: 9716
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

I think it has to do with the stuff called in OnRegisterSceneNode. I am having a similar problem, but couldn't solve it so far. I think the solution is probably to use an own camera. But not sure, maybe someone has a better solution, I also need to check this some more.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Sorry, I misread your problem. It looks like you want to call node->updateAbsolutePosition() before calling node->getPosition().
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

also...

check out the function ...

void CSceneManager::drawAll()

in CSceneManager.cpp

you'll get more information on how positions are calculated.

it could be in the block where it renders default objects, tho.
Image
Dark_Kilauea
Posts: 368
Joined: Tue Aug 21, 2007 1:43 am
Location: The Middle of Nowhere

Post by Dark_Kilauea »

if you are using any animators, they will execute on smgr->drawall().
rogerborg wrote:Every time someone learns to use a debugger, an angel gets their wings.
piiichan
Posts: 59
Joined: Thu May 01, 2008 1:20 am
Location: New Caledonia (France - Pacific)
Contact:

Post by piiichan »

CuteAlien wrote:I think it has to do with the stuff called in OnRegisterSceneNode
dlangdev wrote:check out the function void CSceneManager::drawAll()
Thanks a lot to CuteAlien and dlangdev respectively, the problem is solved. Instead of calling drawAll() from the scene manager, I now call OnRegisterSceneNode() from the camera, like this

Code: Select all

ICameraSceneNode* camera = g_smgr->getActiveCamera();
camera->setPosition( vector3df(
		node->getPosition().X + offset,
		hypoLength,
		node->getPosition().Z - offset));
camera->setTarget( node->getPosition() );

//g_smgr->drawAll();			// called to avoid strange behavior of collision detection, but not needed anymore
camera->OnRegisterSceneNode();	// cleaner solution
rogerborg wrote:It looks like you want to call node->updateAbsolutePosition() before calling node->getPosition().
rogerborg, I tried this also, but it still won't work...
Dark_Kilauea wrote:if you are using any animators, they will execute on smgr->drawall().
Dark_Kilauea, thanks for reminding me this fact. I've read this in the API doc, so I checked if my animators and particle systems were affected by this isolated call to smgr->drawall(), but everything was fine. I think it's because animators rely on time to animate, not on frame rate, so it's pretty safe on this side.

Although ISceneNode::OnRegisterSceneNode solves my problem, I don't understand why... the API doc says
Irrlicht API wrote: This method is called just before the rendering process of the whole scene.

Nodes may register themselves in the render pipeline during this call, precalculate the geometry which should be renderered, and prevent their children from being able to register themselves if they are clipped by simply not calling their OnRegisterSceneNode method. If you are implementing your own scene node, you should overwrite this method with an implementation code looking like this:
... this is quite blur to me...
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

"OnRegisterSceneNode" used to be called "OnPreRender", so it's actually hijacked for alot more stuff than just registering the scene node on the render list.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
piiichan
Posts: 59
Joined: Thu May 01, 2008 1:20 am
Location: New Caledonia (France - Pacific)
Contact:

Post by piiichan »

So is it safe to call it the way I do?
What about efficiency? Is it a CPU intensive method?
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

you may have to call CSceneManager::drawAll() tho.

there's a ton of stuff CSceneManager::drawAll() has to cover. you can't simply drop it like that.

oh my god...

what have i done!
Image
Dark_Kilauea
Posts: 368
Joined: Tue Aug 21, 2007 1:43 am
Location: The Middle of Nowhere

Post by Dark_Kilauea »

Dark_Kilauea, thanks for reminding me this fact. I've read this in the API doc, so I checked if my animators and particle systems were affected by this isolated call to smgr->drawall(), but everything was fine. I think it's because animators rely on time to animate, not on frame rate, so it's pretty safe on this side.
I was reminding you of this fact because animators do change position every frame (due to interpolation) so they could easily be throwing your ray tracing off.

Most animators seem to run during OnRegisterSceneNode()
rogerborg wrote:Every time someone learns to use a debugger, an angel gets their wings.
Post Reply