Model nodepath wrapper

as we know, when we need a model object we got to instantate it calling the loader.loadmodel() method that returns our model as a Nodepath. But what when we need a custom model object to stick in it our methods extending its functionality? This snippet shows how to, making use of autodelegation:

class xmodel:
  '''
  object that appear as a NodePath model so that we could extend it 
  with our methods packing 'em in one only object.
  '''
  def __init__(self, modelpath):
    # this first
    self.__dict__['mdlNP']=loader.loadModel(modelpath)
    self.custom_attribute=''
  #-----------------------------------------------------------------
  # nodepath autodelegation
  def __getattr__(self, attr):
    if hasattr(self.__dict__['mdlNP'], attr):
      return getattr(self.__dict__['mdlNP'], attr)
    else: return self.__dict__[attr]
  def __setattr__(self, attr, value):
    if hasattr(self.__dict__['mdlNP'], attr):
      setattr(self.__dict__['mdlNP'], attr, value)
    else: self.__dict__[attr]=value
  #-----------------------------------------------------------------
  #custom methods
  def shout(self):
    print "SHOUT!"

I would not recommend this. Also many people use this approach and panda3d itself with Actors and some cases in DirectGUI. I feel its broken.

First when you get the model its not really the “object” just representation of it in 3d. The class that is created in python represent more of how it behaves and intersects with the rest of the system - not a very large list of its display properties.

What i do in my code is create:

class SomeGameObject:
     def __init__(self):
         self.model = loader.loadModel("blabla")

It also prevents as much interaction form the outside because not model is more of an internal mechanism so that i would not set SomeGameObject from the outside world but only from the SomeGameObject scope. But i also mark it not private because i some times need access to its position form the outside of the class which ._model would look bad.

I also do it because the 3d representation is not the only part of my game object. My object also have SQL representations and network state representation so it kind of comes in handy wen the object is not tide to the 3d representation being a nodepath.

Also this can cause confusion because if you add your augmented nodepath to the scene graph you can’t get it back again - its lost. Its also can cause confusion when you add a method with the same name as the nodepath.

And finally at its internal c++ representation NodePath is nothing more but a pointer to PandaNode. A pointer that adds some functionality manly to manipulate attributes NodePath in c++ really does not carry any state so you are wrapper the wrapper??? Usually when you extend a wrapper it still is a wrapper but in this case you are extending pre wrapped PandaNode called NodePath? Drawing a proper UML diagram of this is impossible.

On the other hand this is a correct way to accomplish what you want to accomplish the difference here is of style, and object oriented methodology, you have been warned.

aye treeform thankyou for your clarification.

let me explain that I’m almost a pythoner and not very much skilled so I’d made it from that point of view, knowing not much what there is under the hood of p3d engine. Said this my needs were to manage something closer to what did chombee with his ZUI interface where he got a complex object composed by a model, a bunch of directgui objects like directframes, buttons etc… that have to be zoomed with a click of the mouse. Instances of this object have to be collected under and managed by a container as child nodes. This is why I did this.