Page 1 of 1

Inheriting from CAnimatedMeshSceneNode

Posted: Sun May 08, 2005 6:00 pm
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.

Posted: Sun May 08, 2005 6:25 pm
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.

Posted: Tue May 17, 2005 10:43 am
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... ;)

Posted: Tue May 17, 2005 11:01 am
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).

Posted: Tue May 17, 2005 12:19 pm
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 :?

Posted: Wed May 18, 2005 10:22 am
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?

Posted: Wed May 18, 2005 12:13 pm
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... :(

Posted: Wed May 18, 2005 1:54 pm
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();

Posted: Thu May 19, 2005 9:40 am
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? :)

Posted: Thu May 19, 2005 5:22 pm
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.

Posted: Fri May 20, 2005 7:10 am
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 :)

Posted: Fri May 20, 2005 11:34 am
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
}

// ... my very cool condition here

Posted: Tue May 24, 2005 10:30 am
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.

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

Posted: Wed May 25, 2005 8:44 am
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 ;)

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

Posted: Wed May 25, 2005 1:49 pm
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.