This is a general design question. I've created a simple interface that connects Bullet and Irrlicht objects/nodes, which I call PhysicalObject. A lot of objects in the game are going to derive from this class. Basically I want to know that are the pros and cons of having PhysicalObject "have-a" scene node, or "be-a" scene node. Currently I have a weird middle ground going on, where there's a method called getSceneNode which just casts "this" into a scene node. Any class that implements PhysicalObject, therefore, must also implement ISceneNode in some form or fashion. This is some funky breaking of OOP principles, so I'd like to know what other's have done.
If I have a wrapper class, I have the benefit of being able to have a PhysicalObject contain different kinds of nodes(like a simple SphereSceneNode for debugging or an AnimatedMeshSceneNode when I want to start using art). Of course, my interface would have to be more extensive for that to work out. If I extend from ISceneNode, I either lose the flexibility of being able to choose the level of complexity of the node's mesh, or I'm forced to reimplement/copy code from existing classes to get things to work. On the other hand, deriving from ISceneNode gains the benefit of being able to use the existing serialization code in irrlicht. The serialization is the biggest thing that I like about that.
My weird middle ground is working for the time being, but it's ugly and I'd like to hear what others have done in this realm.
Pros/cons of "wrapper classes" vs. derived classes.
-
- Posts: 37
- Joined: Fri Nov 04, 2011 12:15 am
Re: Pros/cons of "wrapper classes" vs. derived classes.
I personally would have it "be-a" scene node.
I was sort of just talking about this here http://irrlicht.sourceforge.net/forum/v ... 52#p283700
Weather you want to have your physics engine run "on top" of Irrlicht or be "a part" of Irrlicht. I myself would prefer it to be a part of It just seems more logical to do it that way in my opinion, although you should do whatever suits your needs best :) I know this doesn't much answer your question, I am sorry.
I was sort of just talking about this here http://irrlicht.sourceforge.net/forum/v ... 52#p283700
Weather you want to have your physics engine run "on top" of Irrlicht or be "a part" of Irrlicht. I myself would prefer it to be a part of It just seems more logical to do it that way in my opinion, although you should do whatever suits your needs best :) I know this doesn't much answer your question, I am sorry.
Dream Big Or Go Home.
Help Me Help You.
Help Me Help You.
Re: Pros/cons of "wrapper classes" vs. derived classes.
I tend to prefer own game-objects (or entities), some of which can have a scenenode inside. Then one function in the base-interface which tells if the game-object has a scenenode or not. The scenenodes I work with can still be custom scenenodes which I created myself and don't have to be the ones in Irrlicht by the way. And also important - unlike in Irrlicht the object's never manage themself with addChild or setParent or something like that, but I always have a class managing my gameobject with addObject/removeObject.
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
-
- Posts: 37
- Joined: Fri Nov 04, 2011 12:15 am
Re: Pros/cons of "wrapper classes" vs. derived classes.
My main hangup against having separate game objects is still that I'm throwing away irrlicht's serialization scheme. I'm already planning on writing my own configuration files for loading complicated skeletons, so maybe I could just do a more abstracted serialization scheme.
Re: Pros/cons of "wrapper classes" vs. derived classes.
jwatson1993 wrote:My main hangup against having separate game objects is still that I'm throwing away irrlicht's serialization scheme. I'm already planning on writing my own configuration files for loading complicated skeletons, so maybe I could just do a more abstracted serialization scheme.
i use a combination of the two, using irrlicht's serialization technique inside the object class. Each object serializes identically to the scenenode and then serializes the scenenode itself. It seems to work very nicely and with my OOP preference, it is very easy to implement.
Re: Pros/cons of "wrapper classes" vs. derived classes.
I use similar solution for this posted by CuteAlien in my game engine and it works really nice.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
-
- Posts: 37
- Joined: Fri Nov 04, 2011 12:15 am
Re: Pros/cons of "wrapper classes" vs. derived classes.
Could you go into more detail on this? I've been looking at the serialization technique and it seems that everything is kind of hard coded for scene nodes and animators. Do you have object derive from IAttributeExchangingObject? or ISceneNode?Seven wrote:jwatson1993 wrote:My main hangup against having separate game objects is still that I'm throwing away irrlicht's serialization scheme. I'm already planning on writing my own configuration files for loading complicated skeletons, so maybe I could just do a more abstracted serialization scheme.
i use a combination of the two, using irrlicht's serialization technique inside the object class. Each object serializes identically to the scenenode and then serializes the scenenode itself. It seems to work very nicely and with my OOP preference, it is very easy to implement.
Re: Pros/cons of "wrapper classes" vs. derived classes.
code snippet
Code: Select all
// irrlich exchanging capability
virtual void serializeAttributes(IAttributes* out, SAttributeReadWriteOptions* options=0);
virtual void deserializeAttributes(IAttributes* in, SAttributeReadWriteOptions* options=0);
Code: Select all
void CSObject::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options)
{
out->addString("Name",getName().c_str());
out->addBool("Dead",getDead());
out->addInt("Id",getId());
out->addVector3d("Position",getPosition());
out->addVector3d("PositionOffset",getPositionOffset());
out->addVector3d("BBOffset",getBBOffset());
out->addVector3d("Rotation",getRotation());
out->addVector3d("RotationOffset",getRotationOffset());
out->addVector3d("Scale",getScale());
out->addVector3d("BaseScale",getBaseScale());
out->addBool("DebugObject",getDebugObject());
out->addString("ActorFileName",CLIPTOMEDIAFILENAME(getActorFileName()).c_str());
out->addString("TextureFileName",CLIPTOMEDIAFILENAME(getTextureFileName()).c_str());
out->addFloat("Mass",getMass());
out->addFloat("ReverseLight",getReverseLight());
out->addString("SoundFileName",CLIPTOSOUNDFILENAME(getSoundFileName()).c_str());
}
void CSObject::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
CS_LOG("CSObject::deserialize()");
m_Name = in->getAttributeAsString("Name"); CS_LOG(getName());
m_Dead = in->getAttributeAsBool("Dead");
m_Id = in->getAttributeAsInt("Id");
m_Position = in->getAttributeAsVector3d("Position");
m_PositionOffset = in->getAttributeAsVector3d("PositionOffset");
m_BBOffset = in->getAttributeAsVector3d("BBOffset");
m_Rotation = in->getAttributeAsVector3d("Rotation");
m_RotationOffset = in->getAttributeAsVector3d("RotationOffset");
m_Scale = in->getAttributeAsVector3d("Scale");
m_BaseScale = in->getAttributeAsVector3d("BaseScale");
m_DebugObject = in->getAttributeAsBool("DebugObject");
m_ActorFileName = MEDIAFILENAME(in->getAttributeAsString("ActorFileName"));
m_TextureFileName = MEDIAFILENAME(in->getAttributeAsString("TextureFileName"));
m_Mass = in->getAttributeAsFloat("Mass");
m_ReverseLight = in->getAttributeAsFloat("ReverseLight");
m_SoundFileName = SOUNDFILENAME(in->getAttributeAsString("SoundFileName"));
}
Code: Select all
bool CSLevel::saveToDisk(stringc filename)
{
_chdir(getApplication()->getGameSaveDirectory().c_str());
getDevice()->getFileSystem()->changeWorkingDirectoryTo(getApplication()->getGameSaveDirectory().c_str());
IXMLWriter* writer = getDevice()->getFileSystem()->createXMLWriter(filename);
CS_CHECK_BOOL(writer,"Warning! unable to create save file");
writer->writeXMLHeader();
_chdir(getApplication()->getWorkingDirectory().c_str());
getDevice()->getFileSystem()->changeWorkingDirectoryTo(getApplication()->getWorkingDirectory());
CSObject* obj = getObjectFactory()->getObjectManager()->getNextObject(true);
while(obj)
{
if (!obj->getDebugObject())
{
stringw name("CSOBJECT");
writer->writeElement(name.c_str(), false, L"TYPE",stringw(obj->getInfo()->getName()).c_str());
writer->writeLineBreak();
IAttributes* attr = getDevice()->getFileSystem()->createEmptyAttributes(getDriver());
SAttributeReadWriteOptions options;
obj->serializeAttributes(attr, &options);
if (attr->getAttributeCount() != 0)
{
attr->write(writer);
writer->writeLineBreak();
}
attr->drop();
writer->writeClosingTag(name.c_str());
writer->writeLineBreak();
writer->writeLineBreak();
}
obj = getObjectFactory()->getObjectManager()->getNextObject(false);
}
writer->drop();
return true;
}
-
- Posts: 37
- Joined: Fri Nov 04, 2011 12:15 am
Re: Pros/cons of "wrapper classes" vs. derived classes.
Thanks! I was heading down that path anyway. Good to know that it's a good idea. Irrlicht's serialization scheme takes a bit of digging around, but its great once you figure it out.