Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

Object Base Question

Started by simotix Mar 23, 2009 at 1:05 AM 14 replies 1.9k views
Original Post
simotix
simotix
I am creating an object base to use for when I have objects that are renderable and also have physics. The problem is that in PhysicsBase there is a transform and in RenderBase there is a transform. What would be the best way in ObjectBase to help prevent having a transform in all three? ObjectBase : public RenderBase, PhysicsBase
ToohrVyk
ToohrVyk
I would use one of three possible options: either the renderable object's transform is attached to the physics object's transform (therefore taking it into account whenever it's rendered) or the physics object's transform updates the renderable object's transform whenever it changes (and therefore needs a reference to it) or one (or both) of the physics and renderable objects does not own a transform but instead references a transform provided from the outside.

I generally go for the third option.
JustChris
JustChris
I prefer composition over inheritance in this situation. That way you only have one transform to take care of. Use a transform object in your ObjectBase class.
Electronic Meteor - My experiences with XNA and game development
wasd
wasd
This is one of the problems of multiple inheritance; having the functionality of two or more classes conflict with each other. I'd agree with JustChris, it might be easier to have a base class with a transform in it, then have something like a physics modifier which would update the transform, then a render object which uses that to draw itself, and have them stored inside the object, instead of deriving from it. Or alternatively, set up a physics system and a render system which communicate by sending messages, and have two separate objects, one representing the rendering part and one representing the physics part.
Kimmi
Kimmi
I would prefering the option using a reference to an external transform. If you get the transform using inheritance you have a very hard coupling in yor class hierarchy between the transform and the rendering / physics. And maybe the physics and the rendering will need transforms from different sources in the future. Using a reference you can solve this fast because you do not have a hard coded dependency. Inheritance can cause more changes to make this work.

Kimmi
A complicate solution may indicate a not understood problem.


[twitter]KimKulling[/twitter]
simotix
simotix
Quote:
Original post by JustChris
I prefer composition over inheritance in this situation. That way you only have one transform to take care of. Use a transform object in your ObjectBase class.


Then wouldn't that use extra memory by having three transforms?

Quote:
Original post by Kimmi
I would prefering the option using a reference to an external transform.


How would you do this?
Kimmi
Kimmi
I would try to make it as simple as possible like:
class ObjectBase {public:  ...  // Performs a transformation  virtual void transform( const Matrix4x4 &rTransform );};


The instances will get a transform. You can provide a default implementation or just overwrite it with a special implementation for the renderer or the physic engine.

Kimmi
A complicate solution may indicate a not understood problem.


[twitter]KimKulling[/twitter]
simotix
simotix
Well my problem is this:

class RenderBase
{
D3DXMATRIX transform;
};

class PhysicsBase
{
D3DXMATRIX transform;
};

class ObjectBase : public RenderBase, PhysicsBase
{
...
};

What would be the best solution to avoid any time of using the wrong transform?
mazelle
mazelle
Try to avoid multiple inheritance as much as possible. Favor composition over inheritance.

class ObjectBase{  RenderBase renderer;  PhysicsBase physics;};


This might not be the solution you're looking for. But you really have to tell us how those objects interact. It could also be like this.

// Renderer Object interfaceclass IRenderObject{public:  virtual D3DXMATRIX* const getRenderTransform() = 0;};// Physics Object interfaceclass IPhysicsObject{public:  virtual D3DXMATRIX* const getPhysicsTransform() = 0;};// concrete ObjectBaseclass ObjectBase : public virtual IRenderObject, public virtual IPhysicsObject{public:  D3DXMATRIX* const getRenderTransform()  {    return &this->renderMatrix;  }  D3DXMATRIX* const getPhysicsTransform()  {    return &this->physicsMatrix;  }private:  D3DXMATRIX renderMatrix;  D3DXMATRIX physicsMatrix;};
dmatter
dmatter
Quote:
Original post by simotix
What would be the best solution to avoid any time of using the wrong transform?
Do you want the transforms to remain separate or for both the RenderBase and PhysicsBase to be using the same transform object?
simotix
simotix
I would like ObjectBase to use one transform, if it has to be separate from PhysicsBase and RenderBase then that is fine. I am just trying to find a way to save the most memory.
dmatter
dmatter
This would work:

class RenderBase{public:    RenderBase(D3DXMATRIX & transform)      : transform(transform) { }    D3DXMATRIX & transform;};class PhysicsBase{public:    RenderBase(D3DXMATRIX & transform)      : transform(transform) { }    D3DXMATRIX & transform;};class ObjectBase{    D3DXMATRIX transform;    RenderBase rendering;    PhysicsBase physics;public:    ObjectBase()      : rendering(transform)      , physics(transform)    {        D3DXMatrixIdentity(&transform);    }};

All three would be sharing the same D3DXMATRIX object, so any changes are seen by all of them.
Giedrius
Giedrius
I may be wrong because I haven't ever tried this, but wouldn't it work to have a CBaseTransform class which would only contain the transformation variable and some functions to manipulate it, then have your CRenderableObject and CPhysicsObject derive from CBaseTransform and then derive CBaseObject from CRenderableObject and virtually from CPhysicsObject ? This way they should be refering the same transform.

I recently had to implement a physics system to an existing engine and what I did was having a CCollidable class, from which anyone who wanted to use the physics capabilities should derive and pass its position and rotation matrix const pointers to the constructor of CCollidable. Then CCollidable had a virtual UpdatePosition function which should be implemented by the deriving class to update its own transformation with the given one.
mazelle
mazelle
Quote:
Original post by Giedrius
I may be wrong because I haven't ever tried this, but wouldn't it work to have a CBaseTransform class which would only contain the transformation variable and some functions to manipulate it, then have your CRenderableObject and CPhysicsObject derive from CBaseTransform and then derive CBaseObject from CRenderableObject and virtually from CPhysicsObject ? This way they should be refering the same transform.


Don't you think you have the dreaded diamond here? I can't really be sure about language semantics when deriving virtually from a base class that contains data (I'm certain not everyone can really be sure). So I think, this solution is best avoided.
Giedrius
Giedrius
Yes, you are correct. By the way I described it previosuly CRenderableObject and CPhysicsObject would both have had their own unique transform variables. A way to solve it would be to have a pure abstract class for transformation, such as:

class ITransform{// Only x and y for simplicitypublic:	virtual float GetX() const = 0;	virtual float GetY() const = 0;	virtual void SetX(float x) = 0;	virtual void SetY(float y) = 0;};


Have your CRenderableObject and CPhysicsObject derive from it, then derive your CBaseObject from CRenderableObject and CPhysicsObject and finally have all the needed variables in your CBaseObject and implement the ITransform interface. This way the transform would be shared between all the parent classes which derive from ITransform.

Of course this requires extra writting for implementing the same set of functions for every different base object you would have and there probably could be some simplier solutions such as simply passing the pointers to CTransform object to your base classes during construction.
scottrick49
scottrick49
class RenderBase{   D3DXMATRIX *transform;};class PhysicsBase{   D3DXMATRIX *transform;};


Why doesn't this work? Point them at the same thing. Add some sort of ref counting wrapper class if you are worried about when to delete them.

edit: nvm this has already been covered
scottrick49

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.