ISceneManager :: OnAnimate() question
ISceneManager :: OnAnimate() question
Hello,
I wanna ask a question about the irrlicht source code.
Here is my question :
I am digging codes that handling about animated models.
I try to load "dwarf.x" into the tutorial 1 and trace it.
In ISceneManager :: drawAll(), this function should be the whole scene renderer of irrlicht.
When I traced onto the line
// do animations and other stuff.
OnAnimate(os::Timer::getTime());
This would trigger
CAnimatedMeshSceneNode :: OnAnimate()
void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs)
{
buildFrameNr(timeMs-LastTimeMs);
if (Mesh)
{
scene::IMesh * mesh = getMeshForCurrentFrame();
if (mesh)
Box = mesh->getBoundingBox();
}
LastTimeMs = timeMs;
IAnimatedMeshSceneNode::OnAnimate ( timeMs );
}
And then as I trace to the line
for (i=0; i<SolidNodeList.size(); ++i)
SolidNodeList.Node->render();
This triggers
//! renders the node.
void CAnimatedMeshSceneNode::render()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
if (!Mesh || !driver)
return;
bool isTransparentPass =
SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
++PassCount;
scene::IMesh* m = getMeshForCurrentFrame();
if(m)
{
Box = m->getBoundingBox();
}
else
{
#ifdef _DEBUG
os::Printer::log("Animated Mesh returned no mesh to render.", Mesh->getDebugName(), ELL_WARNING);
#endif
}
.....
My question is that obviously, getMeshForCurrentFrame(); is called twice at each rendering job.
This would cause animated mesh to re-calculate animated vertex data twice, right?
Is there another way to avoid this situation for the performance issue?
Or just this re-calculation is necessary for another purpose?
Any feedback would be appreciated.
I wanna ask a question about the irrlicht source code.
Here is my question :
I am digging codes that handling about animated models.
I try to load "dwarf.x" into the tutorial 1 and trace it.
In ISceneManager :: drawAll(), this function should be the whole scene renderer of irrlicht.
When I traced onto the line
// do animations and other stuff.
OnAnimate(os::Timer::getTime());
This would trigger
CAnimatedMeshSceneNode :: OnAnimate()
void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs)
{
buildFrameNr(timeMs-LastTimeMs);
if (Mesh)
{
scene::IMesh * mesh = getMeshForCurrentFrame();
if (mesh)
Box = mesh->getBoundingBox();
}
LastTimeMs = timeMs;
IAnimatedMeshSceneNode::OnAnimate ( timeMs );
}
And then as I trace to the line
for (i=0; i<SolidNodeList.size(); ++i)
SolidNodeList.Node->render();
This triggers
//! renders the node.
void CAnimatedMeshSceneNode::render()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
if (!Mesh || !driver)
return;
bool isTransparentPass =
SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
++PassCount;
scene::IMesh* m = getMeshForCurrentFrame();
if(m)
{
Box = m->getBoundingBox();
}
else
{
#ifdef _DEBUG
os::Printer::log("Animated Mesh returned no mesh to render.", Mesh->getDebugName(), ELL_WARNING);
#endif
}
.....
My question is that obviously, getMeshForCurrentFrame(); is called twice at each rendering job.
This would cause animated mesh to re-calculate animated vertex data twice, right?
Is there another way to avoid this situation for the performance issue?
Or just this re-calculation is necessary for another purpose?
Any feedback would be appreciated.
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
Re: ISceneManager :: OnAnimate() question
Yeah, try to debug a scene with two nodes with the same .x mesh at different animation cycles and you will see that the two will overwrite their rendering each time. The first time the global visibility and collision etc. are checked. Next time the mesh is created for rendering. We would probably have to rewrite most animated mesh systems to allow caching of this stuff on the expense of significantly increased memory usage. But right now it's not possible to avoid this.
Re: ISceneManager :: OnAnimate() question
The stuff is already cached. What is really required is for a call to get the mesh for the current frame at the start of frame processing and for the collision detection and rendering parts to use this one copy of the mesh.
Re: ISceneManager :: OnAnimate() question
Yeah, I wanna know if this is a small case for adding such class members and modifying relevant parts of irrlicht to achieve that purpose.
Or that's just too complicated for other joint components in irrlicht?
Or that's just too complicated for other joint components in irrlicht?
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
Re: ISceneManager :: OnAnimate() question
The caching happens on a per-mesh base, not per scene node. Hence, using the same mesh twice will make the animation happen twice. For just one mesh, the second call will get the mesh that was calculated in the first place, yes.mongoose7 wrote:The stuff is already cached. What is really required is for a call to get the mesh for the current frame at the start of frame processing and for the collision detection and rendering parts to use this one copy of the mesh.
Re: ISceneManager :: OnAnimate() question
I don't know what you mean. I have one skinned mesh and the mesh is skinned twice per frame. And as in the original post, it is not specific to skinned meshes but follows from the sequence of "top-level" calls.
If two nodes share the same mesh, they must share the same animation, though they can be on different frames, that is true. But the mesh should only be skinned if the frame has changed. Just having a private member m_lastFrame would ensure that the same frame isn't skinned twice.
But I think you don't like talking about the animation system?
If two nodes share the same mesh, they must share the same animation, though they can be on different frames, that is true. But the mesh should only be skinned if the frame has changed. Just having a private member m_lastFrame would ensure that the same frame isn't skinned twice.
But I think you don't like talking about the animation system?
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
Re: ISceneManager :: OnAnimate() question
If the frame does not change, the same skinned result is re-used. At least that's what I recall what happens in the underlying methods. This might have changed between 1.7 and 1.8, but I think it was already changed for the 1.7 series.
Re: ISceneManager :: OnAnimate() question
You've said this before. I posted that a mesh was skinned three times per frame in 1.7.2 and you said it had been fixed on the trunk. I downloaded and checked and found it is skinned twice per frame. I posted a response but the line had gone dead.
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
Re: ISceneManager :: OnAnimate() question
Looking at the code the thing is that *animation* is re-used, but *skinning* is not. Hence, the animation of the inter-frame data is properly cached, but skinning is (for unknown reasons) performed twice. Adding a LastSkinnedFrame could indeed work. Question is where we need to reset this flag. I made an inital attempt (for now completely untested) in trunk. Maybe you can check if it has the intended result and works with all joint modes?!
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
Re: ISceneManager :: OnAnimate() question
Ok, I've quick checked the changes. Speedup is noticeable, rendering with one mesh seems to be correct. Now I just have to check multiple use of the same mesh. We have a test case for this, but right now I need to do some other things. So just tell me if there's something wrong with this patch.
Re: ISceneManager :: OnAnimate() question
Thanks very much, hybrid. (I hope riverandb can do it. I've just rebuilt my system.)
Re: ISceneManager :: OnAnimate() question
Thanks a lot for your responses.
mongoose7 do you mean you want me to help check on rendering of the multiple scene nodes with the same mesh?
I think I can check this point but I have to get the newest daily release version right?
Where can I get it ?
Anyway I appreciate for your helps.
mongoose7 do you mean you want me to help check on rendering of the multiple scene nodes with the same mesh?
I think I can check this point but I have to get the newest daily release version right?
Where can I get it ?
Anyway I appreciate for your helps.
Re: ISceneManager :: OnAnimate() question
No, just check for one node holding the mesh.
Go to http://irrlicht.svn.sourceforge.net/vie ... cht/trunk/ and click on "Download GNU tarball".
Go to http://irrlicht.svn.sourceforge.net/vie ... cht/trunk/ and click on "Download GNU tarball".
Re: ISceneManager :: OnAnimate() question
Err, just a comment. I had a look at the code and I see you used a boolean. But then you had to pepper the code with changes. Hmmm, not good.
Better, I think, would be to set it to the number of the last frame skinned. This only needs to be set to -1 when the object is instantiated. At the start of the skinning code (skinMesh()?) you check if the current frame is the same as the last frame skinned. After skinning, you set the variable to the last frame skinned to the current.
Although, from what I recall, the frame number isn't passed into skinMesh()?
Better, I think, would be to set it to the number of the last frame skinned. This only needs to be set to -1 when the object is instantiated. At the start of the skinning code (skinMesh()?) you check if the current frame is the same as the last frame skinned. After skinning, you set the variable to the last frame skinned to the current.
Although, from what I recall, the frame number isn't passed into skinMesh()?
Re: ISceneManager :: OnAnimate() question
I've quickly checked on one scene node holding only one source skinned mesh, and I think this problem is solved.
However for other types of animated mesh (MD2, HalfLife, MD3 not sure),
they also suffers from the same problem of interpolating animated vertices twice at each rendering job.
And multiple scene nodes for holding the same mesh is also another big problem.
Now I still have no idea about solutions of this problem.
Anyway thanks again, hope that I can help a bit, maybe in the future.
However for other types of animated mesh (MD2, HalfLife, MD3 not sure),
they also suffers from the same problem of interpolating animated vertices twice at each rendering job.
And multiple scene nodes for holding the same mesh is also another big problem.
Now I still have no idea about solutions of this problem.
Anyway thanks again, hope that I can help a bit, maybe in the future.