Inheriting from CAnimatedMeshSceneNode

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
MeisterK
Posts: 66
Joined: Sat Feb 26, 2005 1:20 pm

Inheriting from CAnimatedMeshSceneNode

Post by MeisterK »

I'm wanna create my own AnimatedMeshSceneNode class by inheriting from CAnimatedMeshSceneNode (to add some non Irrlicht releated properties)

But it seems that no "C" class is found in irrlicht.lib?!? Or is it my mistake? I dont want to inherit form ISceneNode with all the implementation nessesary for an CAnimatedMeshSceneNode in my project.

Here is my try

Code: Select all

#include "stdafx.h"

#include "irrlicht.h"

class CTerrainTileFadeInAnimator : public irr::scene::CAnimatedMeshSceneNode
{

};
Returns: Baseclass unknown

Thx

PS: Yes I know I'm asking a lot of questions in the last days (hope they not SO silly :oops: ), but I'm enjoy relearning C++ with such a great think like Irrlicht and sometimes I can give an answer.
jox
Bug Slayer
Posts: 726
Joined: Thu Apr 22, 2004 6:55 pm
Location: Germany

Post by jox »

The only way (currently) to derive from irrlicht classes is to add them to the engine directly. No deriving in your own app. In irrlichtNX you can though.
It is like it is. And because it is like it is, things are like they are.
uakiki

Post by uakiki »

jox wrote:The only way (currently) to derive from irrlicht classes is to add them to the engine directly.
I can successfully derive in this way:

Code: Select all

namespace irr {

namespace scene { // or another sub-namespace...


class MyClass: public IrrlichtClass { ... /* definition here */ }


} // end of namespace scene

} // end of namespace irr
In this way code compiles, even tough I'm having some problems maybe related to this issue... ;)
jox
Bug Slayer
Posts: 726
Joined: Thu Apr 22, 2004 6:55 pm
Location: Germany

Post by jox »

uakiki wrote:I can successfully derive in this way:
You're deriving from a class starting with "I". In irrlicht these are "interfaces" and can be derived from. The problem was regarding the implementing classes that start with "C".

The problems you have is probably pure virtual functions that you didn't implement in your class. See abstract base classes (and the api for the I* classes).
It is like it is. And because it is like it is, things are like they are.
uakiki
Posts: 5
Joined: Tue May 17, 2005 10:43 am

Post by uakiki »

Yes I'm deiving from ISceneNodeAnimator ;)
I can't get my derived animateNode() working, and I can't figure out what is the problem :?
jox
Bug Slayer
Posts: 726
Joined: Thu Apr 22, 2004 6:55 pm
Location: Germany

Post by jox »

If you'd post some code, error messages and more detailed problem description someone might be able to help you. Do you have problems compiling your class or using it?
It is like it is. And because it is like it is, things are like they are.
uakiki
Posts: 5
Joined: Tue May 17, 2005 10:43 am

Post by uakiki »

jox wrote:If you'd post some code, error messages and more detailed problem description someone might be able to help you. Do you have problems compiling your class or using it?
:D ok :)

This is a code fragment:

Code: Select all

ISceneManager* smgr = device->getSceneManager();
ISceneNodeAnimatorEx* anim = (ISceneNodeAnimatorEx*) smgr->
        createFlyStraightAnimator( ... );

if (anim == NULL) {
//...
}
    
h_node->addAnimator(anim);
anim->drop();
ISceneNodeAnimatorEx is a class I derived from ISceneNodeAnimator to ovveride animateNode() virtual function.
When i add this derived animator (addAnimator(anim)), I would expect that the ovverridden animateNode() will be called instead of the original ISceneNodeAnimator::animatedNode().
This thing doesn't happen and the original animateNode() is called, thus animating the node instead of printing something to screen:

Code: Select all

void ISceneNodeAnimatorEx::animateNode (ISceneNode *node, u32 timeMs) {
    cout << "Sto animando! (timeMs = " << timeMs << ")\n";
}
Can't figure out why... :(
jox
Bug Slayer
Posts: 726
Joined: Thu Apr 22, 2004 6:55 pm
Location: Germany

Post by jox »

Thanks, that helps. :)

But it's not gonna work like this.

smgr->createFlyStraightAnimator() will always return an instance of the class CSceneNodeAnimatorFlyStraight. It doesn't help to cast it into a pointer of your class. It's even wrong and can crash your program.

Better do the following:

1) call your class CSceneNodeAnimatorEx not ISceneNodeAnimatorEx (optional but recommended).

2) Create your animator like this:

Code: Select all

ISceneNodeAnimator* anim = new CSceneNodeAnimatorEx(...);
h_node->addAnimator(anim);
anim->drop();
It is like it is. And because it is like it is, things are like they are.
uakiki
Posts: 5
Joined: Tue May 17, 2005 10:43 am

Post by uakiki »

Yes, I supposed it should have been like this :)
The result I was trying to achieve is to add some functionality to my animateNode() (i.e. a condition of termination, to call a sort of callback function) and to still have the original functionality (the "straight forward" animation).
In this way I have to rewrite the code to animate my node on a straight line, right? :)
Thulsa Doom
Posts: 63
Joined: Thu Aug 05, 2004 9:40 am
Location: Germany

Post by Thulsa Doom »

Hello,
there might be some help. I wrote a little demo to extend the engine with some additional functionallity. I created a new SceneManager that manages all the addons I need.

The code can be used like this:

Code: Select all

	/*
	Create an instance of the new SceneManager.	
	*/
	ISceneManagerEx* 
		smgrEx = new CSceneManagerEx(device);
The new scene manager can now used to create further scene nodes and animators. Eg. I implemented an animator that gives a callback as it's finished. The mechanism is very similar to that nikos done it in the current engine release. Just inherit your class from a virtual base that provides a custom callback function 'OnHaltAnimator' that you can overwrite to fit you needs.

Code: Select all

class myClass : 	public ICallbackable
{
myClass()
{	
	scene::IAnimatedMesh* 
			mesh = smgr->getMesh("../media/Torus.3DS");
	ISceneNodeEx* 
		node  = (ISceneNodeEx*) smgrEx->addMeshSceneNode((scene::IMesh*) mesh->getMesh(0), 0, -1, core::vector3df(0, 0, 0), core::vector3df(0, 0, 0), core::vector3df(1.0f, 1.0f, 1.0f) );
		/* 
		Here is an animator with takes the 'this'-pointer as last input argument.
		Set the boolean to true for continously running the animater without using 
		it's callback functionality.
		*/
		core::array< video::ITexture* > 
			BCtexture1;
		BCtexture1.push_back(drvr->getTexture("../media/T1_red.tga"));
		BCtexture1.push_back(drvr->getTexture("../media/T2_green.tga"));
		BCtexture2.push_back(drvr->getTexture("../media/T3_blue.tga"));
		BCtexture2.push_back(drvr->getTexture("../media/T4_yellow.tga"));
		animTexture1 = smgrEx->createTextureAnimator( BCtexture1, 500, true, this );
		animTexture1->drop();
}

void OnHaltAnimator(ISceneNodeAnimatorEx* anim)
{
	// Do something
}
};
The complete download can be found at http://www.ex-ware.de.tc/ in the download section.

T.D.
uakiki
Posts: 5
Joined: Tue May 17, 2005 10:43 am

Post by uakiki »

Thulsa Doom wrote:Hello,
there might be some help. I wrote a little demo to extend the engine with some additional functionallity.
Ok thank you very much for your help :)
I'm trying not to touch the original engine to keep my project separated from the underlying libraries.

Anyway I' think I found a sort of workaround for my problem. To keep using the original feature of animateNode() (i.e. the FlyStraightAnimator) and verify a given condition, I just derive from ISceneNodeAnimator a class (say CConditionAnimator) and define:

Code: Select all

void CConditionAnimator::animateNode()  
{
   // ... my very cool condition here
}
then I create a FlyStraightAnimator, and add BOTH of them to the node I want to be affected by these animators.
IrrlichtDevice calls both animateNode() in sequence, so the first one animate the node, while the second just verifies the condition and acts according to it.
I understand that this is not the best solution, because it relays on the particular implementation of IrrlichtDevice (it works because the calls to animateNode() are done sequentially). Anyway I achieve my goal to have a simple code structure and not to touch Irrlicht code :)
Guest

Post by Guest »

uakiki wrote:I just derive from ISceneNodeAnimator a class (say CConditionAnimator) and define:
Try the following:
Copy the CFlyStraightAnimator.cpp and *.h from the engines source into a separate (irrEx) folder. Let your class inherit from CFlyStraightAnimator after including the corresponding header file.
In your code make a call to the inherited function before your implementation or afterwards, depending on the sequence that you want.

Code: Select all

void CConditionAnimator::animateNode()  
{
   CFlyStraightAnimator::animateNode();
// ... my very cool condition here
}
Thulsa Doom
Posts: 63
Joined: Thu Aug 05, 2004 9:40 am
Location: Germany

// ... my very cool condition here

Post by Thulsa Doom »

:shock: Hi, did forget to logon last time 8)
Does the code work now?
If so I would like to add it to the irrEx demo, and make it available for the community. If it is OK for you, I would appreciate it, if you would post your code. In time we will have some cool addons.
uakiki
Posts: 5
Joined: Tue May 17, 2005 10:43 am

Re: // ... my very cool condition here

Post by uakiki »

Thulsa Doom wrote::shock: Hi, did forget to logon last time 8)
Does the code work now?
If so I would like to add it to the irrEx demo, and make it available for the community. If it is OK for you, I would appreciate it, if you would post your code. In time we will have some cool addons.
Are you talking to me? :shock:
Anyway, the code works, but I decided to do a different thing to make the whole code cleaner and simplier.
I create a new interface ISceneNodeAnimatorEx (same name of the previous class, but now it's an interface :) ) deriving it from ISceneNodeAnimator. I add this function:

Code: Select all

setAnimatorEndCallback(IAnimatorEndCallback* iaecb);
IAnimatorEndCallback is an interface just like IAnimationEndCallback and has this virtual function:

Code: Select all

onAnimatorEnd()
Given these two classes I have the structure to derive my own CMyNodeAnimator from ISceneNodeAnimatorEx and CMyAnimatorEndCallback from IAnimatorEndCallback to implement my own condition and behaviour when the animator ends.

This is the same mechanism of the animation callback :)

When I write the code I will post it here, so you can add it to your examples ;)
Thulsa Doom
Posts: 63
Joined: Thu Aug 05, 2004 9:40 am
Location: Germany

Re: // ... my very cool condition here

Post by Thulsa Doom »

uakiki wrote: Are you talking to me? :shock:
Anyway, the code works, but I decided to do a different thing to make the whole code cleaner and simplier.
Yes,
I'm looking forewared to it, thank u in advance!

T.D.
Post Reply