Is getRayFromScreenCoordinates() dependent on last frame?
-
- Posts: 59
- Joined: Thu May 01, 2008 1:20 am
- Location: New Caledonia (France - Pacific)
- Contact:
Is getRayFromScreenCoordinates() dependent on last frame?
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?
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?
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
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
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
-
- Posts: 59
- Joined: Thu May 01, 2008 1:20 am
- Location: New Caledonia (France - Pacific)
- Contact:
I tried it, but it still won't work.Call camera->updateAbsolutePosition() after moving it.
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();
...
I wonder why is the drawAll() method of the scene manager correcting the problem?
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
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
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
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
-
- Posts: 368
- Joined: Tue Aug 21, 2007 1:43 am
- Location: The Middle of Nowhere
-
- Posts: 59
- Joined: Thu May 01, 2008 1:20 am
- Location: New Caledonia (France - Pacific)
- Contact:
CuteAlien wrote:I think it has to do with the stuff called in OnRegisterSceneNode
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 thisdlangdev wrote:check out the function void CSceneManager::drawAll()
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, I tried this also, but it still won't work...rogerborg wrote:It looks like you want to call node->updateAbsolutePosition() before calling node->getPosition().
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.Dark_Kilauea wrote:if you are using any animators, they will execute on smgr->drawall().
Although ISceneNode::OnRegisterSceneNode solves my problem, I don't understand why... the API doc says
... this is quite blur to me...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:
"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
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
-
- Posts: 368
- Joined: Tue Aug 21, 2007 1:43 am
- Location: The Middle of Nowhere
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.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.
Most animators seem to run during OnRegisterSceneNode()
rogerborg wrote:Every time someone learns to use a debugger, an angel gets their wings.