Inheriting IAnimatedMeshSceneNode

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
independentCreations
Posts: 24
Joined: Fri Oct 28, 2005 10:05 am
Location: Gold Coast, QLD, Australia

Inheriting IAnimatedMeshSceneNode

Post by independentCreations »

Hey, Setting up a player class, first off.

I created a IAnimatedMeshSceneNode member data.

Now i am trying to inherite from the class IAnimatedMeshSceneNode, so I can add functionality to it. Example stats, name...

declare the player class as:

class Player : public IAnimatedMeshSceneNode

declare the object as:

Player *playerNode;
playerNode = new Player();

Running this creates 2 errors;

'Player' : cannot instantiate abstract class
'Player' : no appropriate default constructor available

Removing the memore allocation allows it to compile and run but on the first access of player i get a memory allocation because no memory has been allocated.

Any ideas, am relatively new to inheritance and none of the books cover inheriting from classes without constructors. Help with this would be great;

Brendan
Guest

Post by Guest »

you dont have to inherit from IAnimatedMeshSceneNode just to add name etc.

just create a IPlayer class without any inheritance and then it should work.
independentCreations
Posts: 24
Joined: Fri Oct 28, 2005 10:05 am
Location: Gold Coast, QLD, Australia

Post by independentCreations »

I have a playerClass, at the moment it has a IAnimatedMeshSceneNode* as a attribute of the class,
That's what you mean isnt it?
But I also have other data that is not in the IAnimatedMeshSceneNode class, such as playerStats and other attributes that make the playerClass that bit different to IAnimatedMeshSceneNode.

Instead of having
PlayerClass->getPlayerNode()->getPosition()...
I want to be able to go right into PlayerClass and have
playerClass->getPosition()...etc

I want to use the same idea for the camera and room class.
"do it, do it now"
Guest

Post by Guest »

take this as an example of a Player class (could be possible that there are typos in it, i did not test it, just wrote to a txt file .. but should work :) )

IPlayer.h

Code: Select all

#ifndef _IPLAYER_H
#define _IPLAYER_H

#include <irrlicht.h>
#include <string.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;

using namespace std;

/*
BASIC PLAYER CLASS
-------------------
This class can easily be used as a template for Players.

Example Usage:
IPlayer* Player = new IPlayer("playermodel.x", "texture.jpg", vector3df(0.0f, 0.0f, 0.0f), smgr, driver);

Player->setScale(vector3df(100.0f, 100.0f, 100.0f));
Player->setID(123);

Player->Name = "Player";
Player->Health = 100;
Player->Armor = 100;


or if you want to get data:

vector3df CurrentPlayerPosition = Player->getPosition();

this is what you wanted, right?

*/

class IPlayer
{
public:
	IPlayer(const c8* filename, const c8* texturename, vector3df position,
	ISceneManager* _SceneManager, IVideoDriver* _VideoDriver);

	void 		setPosition(vector3df position);
	void 		setScale(vector3df scale);
	void 		setRotation(vector3df rotation);
	void		setID(s32 ID);
	void		remove();

	vector3df 	getPosition();
	vector3df 	getScale();
	vector3df 	getRotation();
	s32		getID();

	int 		Health;
	int 		Armor;
	std::string 	Name;

private:
	ISceneManager*		SceneManager;
	IVideoDriver* 		VideoDriver;
	IAnimatedMesh* 		PlayerMesh;
	IAnimatedMeshSceneNode* PlayerNode;
	ITexture*		PlayerTexture;
};

#endif
IPlayer.cpp

Code: Select all

#include "IPlayer.h"

IPlayer::IPlayer(const c8* filename, const c8* texturename, vector3df position,
ISceneManager* _SceneManager, IVideoDriver* _VideoDriver)
{
	SceneManager	= _SceneManager;
	VideoDriver	= _VideoDriver;

	PlayerMesh	= SceneManager->getMesh(filename);
	PlayerTexture	= VideoDriver->getTexture(texturename);
	PlayerNode	= SceneManager->addAnimatedMeshSceneNode(PlayerMesh);

	PlayerNode->setPosition(position);
	PlayerNode->setMaterialFlag(EMF_LIGHTING, false);
}

void IPlayer::setPosition(vector3df position)
{
	PlayerNode->setPosition(position);
}

void IPlayer::setScale(vector3df scale)
{
	PlayerNode->setScale(scale);
}

void IPlayer::setRotation(vector3df rotation)
{
	PlayerNode->setRotation(rotation);
}

void IPlayer::setID(s32 ID)
{
	PlayerNode->setID(ID);
}

void IPlayer::remove()
{
	PlayerTexture->drop();
	PlayerMesh->drop();
	PlayerNode->remove();
}

vector3df IPlayer::getPosition()
{
	return PlayerNode->getPosition();
}

vector3df IPlayer::getScale()
{
	return PlayerNode->getScale();
}

vector3df IPlayer::getRotation()
{
	return PlayerNode->getRotation();
}

s32 IPlayer::getID()
{
	return PlayerNode->getID();
}
independentCreations
Posts: 24
Joined: Fri Oct 28, 2005 10:05 am
Location: Gold Coast, QLD, Australia

Post by independentCreations »

Ok, I see what you have done, have accessor functions to the common functions, thanx ill try that.
should you store the scene manager and video driver in each player lke that? wouldnt that be inefficient?

Thnx for the help :D
"do it, do it now"
Guest

Post by Guest »

no, it actually makes no real difference :) they are just pointers so it should get no fps decrease.
jsprenkle
Posts: 9
Joined: Tue Feb 13, 2007 2:14 am

derived classes used by scenemanager

Post by jsprenkle »

Can you derive a class from something used by scenemanager?
Like:

Code: Select all

class myTerrain : public scene::ITerrainSceneNode
   {
   }
Since scenemanager instantiates all terrain nodes how do you get scenemanager to instantiate objects of your type, not TerrainSceneNode?

Code: Select all

      terrain = smgr->addTerrainSceneNode( "media/terrain-heightmap.bmp" );
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Why would you really want to do that anyway? If you have the definition for your class, why would you want the scene manager to create an instance for you? Just write

Code: Select all

scene::ITerrainSceneNode* myTerrainNode = new myTerrain(...);
Regardless, there is no way to make it so that if you call addTerrainSceneNode() you get some other terrain node type. You will always get the irrlicht terrain scene node.

The only reason I can think of that you'd want the scene manager to create an instance of your class is if you are using loadScene(). If you are doing that, you would use a scene node factory.

Travis
jsprenkle
Posts: 9
Joined: Tue Feb 13, 2007 2:14 am

Post by jsprenkle »

vitek wrote:Why would you really want to do that anyway? If you have the definition for your class, why would you want the scene manager to create an instance for you?
I wanted to add code to create a collision tree for the newton physics engine. It would be nice if it were automatic and transparent. If I
derive a class it can do it automatically for me in the constructor.

It's just the standard inheritance sort of feature object orientation
was supposed to give.

vitek wrote: Just write

Code: Select all

scene::ITerrainSceneNode* myTerrainNode = new myTerrain(...);
That certainly instantiates my class, but doesn't put it into the scene manager's queue/list/array so it will get drawn.

vitek wrote:Regardless, there is no way to make it so that if you call addTerrainSceneNode() you get some other terrain node type. You will always get the irrlicht terrain scene node.
I guess nobody has considered "templating" the scene manager
like the STL container templates?
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

That line will put it in the scene. The parameters to the base class ISceneNode include a scene manager and a parent scene node pointer. When you call addTerrainSceneNode() without specifying the parent, the parent will default to the root of the scene graph. Otherwise the parent will be the node that you provided a pointer to. That will automagically add your scene node to the scene.

You _should_ be able to get access to the triangle data from the terrain with the terrain triangle selector.

Travis
jsprenkle
Posts: 9
Joined: Tue Feb 13, 2007 2:14 am

Post by jsprenkle »

Oh, thanks! I didn't catch that.
jsprenkle
Posts: 9
Joined: Tue Feb 13, 2007 2:14 am

Post by jsprenkle »

Any idea why CSceneManager::addTerrainSceneNode()
instantiates a CTerrainSceneNode but returns an
ITerrainSceneNode ( which is not exposed
by the library)? I can't see how it gains you anything
unless you're trying to prevent inheritance.

Code: Select all

ITerrainSceneNode* CSceneManager::addTerrainSceneNode(...)
{
	CTerrainSceneNode* node = new CTerrainSceneNode(...);

	if (!node->loadHeightMap(heightMapFile, vertexColor))
	{
		node->remove();   
		node->drop();
		return 0;
	}

	node->drop();
	return node;
}
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yes, once again someone's hit by the wonderful object orientation paradigm. It's just like this to make the interface easier extensible by new terrain methods which would make it rather complete to use within an application. If you would use one or the other terrain adding method you would have to change rather large parts of your code, but using the common terrain interface you can choose any such method. And you have a comon interface for all terrains which you can apply to any of those nodes.
Ok, before making this an OOP lesson I'd suggest to believe it or learn about it :D
Post Reply