Design (2016, v 0.1)
PObject is the base class of any object directly related to ogre:
- meshes, obviously,
This is an abstract object, only containing empty definition of methods and no attributes. Its purpose is to enable communication between any kind of object, especially retrieval of transformation and parenting.
PObject < OType >
PObject < OType > is a template that implements the majority of PObjectAbstract methods and declare commons attributes. The only methods to implement in daughter classes are the one related to the template type. SceneNode for instance does not have the same behaviour as Light, reading their position or orientation can not be done in the same way.
- PNode is a PObject < Ogre::SceneNode* >
- PCamera is a PObject < Ogre::Camera* >
- PLight is a PObject < Ogre::Light* >
Thanks to this template, each PObject has a pointer to the correct class. In its params, you find:
- OType _object ( Ogre::SceneNode for PNode, Ogre::Camera for PCamera, etc. )
The parent is stored as a PObjectAbstract*, meaning any PObject can be linked to any other in a hierarchy.
This design was working well until now but has a serious lack of flexibility for custom classes based on ManualObject for instance, and requires duplication of method declarations in PObjectAbstract and PObject, making the evolution of the code tedious and dangerous.
New design (2017, v 0.2)
To fix these issues, a new class hierarchy has to be implemented.
This new design is avoiding the problem of template encountered with the PObject < OType > one.
- pink: classes not usable on their own; they have implemented methods but does not allocate pointers (~interfaces);
- yellow: in polymorph namespace, stand-alone classes;
- blue: singletons.
Any object present in the scene or patch loaded by puredata inherits form PObject, a highly abstract object containing only the name of the object, its unique id and several method regarding serialisation to XML and that's about it. PObject is just making sure any daughter can be saved and loaded. It might include methods previously placed in PUtil, such as bullet to ogre and ogre to bullet converters, and standard structures string convertors (vector3, quaternions, colors, etc.).
4 other interfaces are in charge of specific work. None of them allocate pointers on their own at instanciation, but contains methods to do so, via explicit calls or data loading.
The main difference of these object with standard interfaces is that they declared the pointers and structures to store objects. A class using them is able to use these
PRenderable concerns any object defined in the 3D world, meaning having at least a position and therefore a relation to the SceneManager.
It contains all transformation methods, translate, move, orientation and scale plus complete matrices and utilities to pass from local to global coordinates and reverse.
The serialisable structure representing this class is a PRenderableData.
PDrawable concerns any object displayed on screen: entity and manualobject. It is a bridge to all ogre classes related to mesh management and creation. It is also gives access to materials of any of the meshes loaded in this object through PMaterial (already implemented).
The serialisable structure representing this class is a PDrawableData, refering to PMaterialData.
PPuppet is dedicated to rig management. It simplify the manipulation to any bones (already implemented) and their animation (not yet implemented).
The serialisable structure representing this class is a PPuppetData.
PPhysical contains all required methods to add, remove and modify btRigiBody.
The serialisable structure representing this class is a PPhysicalData.
Even if it inherits from an active class, PSceneNode, PManual is a not allocating any pointers on its own. It contains all required methods to manipulate ogre's ManualObject stored in PDrawable interface.
Stand alone (yellow)
The specialisation of interfaces makes it easier to describe the active objects. They just have to extends the correct interfaces and call the allocaiton methos of each one to perform specific tasks.
Even if not an absolute necessity to have this class, it is very practical to visualise axis of the an object, or the mesh controlling the physics. PSceneDebug is attachable to any kind of PRenderable objects, and manage its own pointers (via PDrawable). Therfore, it can be enabled or disabled separatly from the object it debugs.
Several primitives has to be added to the ogre basic ones through static methods: cylinder, pyramid, cone & torus.
PSceneDebug can not declared on its own, even if it does not really make sense.
This class becomes the main super-class for any object active in the scene. it makes any object inheriting form it a drawable and potentially physical object. Even if some of the object, such as ogre's Camera and Light, can not have materials, making these daughters of PSceneNode enables their parenting to any other ones.
If instanciated, the equivalent of PSceneNode is an empty in blender, a displayable transformation matrix.
A PSceneNode contains one PSceneDebug by default.
note: PSceneDebug declaration should be cancelled when compiling a release version of the application.
The classic object to load a mesh form the disk and manipulate it. It is the only class that inherits from PPuppet by default.
Allows creation of primitive meshes:
- ogre primitives
- polymorph primitives
- pyramid (a four vertices based cone)
- torus (to vaidate).
The additional primitives will allow debugging of bullet's primitives.
A line is rendered in wireframe by default.
Management of an ogre's camera.
A camera mounted on 2 axis, making it easier to move and rotate.
Management of an ogre's light.
Management of an ogre's material.
Not yet perfectly defined, a PSource is basically a sound speaker localised in the 3d world, by opposition to a PTrack. It's behaviour is closed to a PLight (sun, directional, point).
PPatch, PTrack and PMixer
This design is still unvalidated. The PPatch is an in/out interface with a puredata patch, a PTrack is a basic sample player and a PMixer is a mix table managing the sound output. In the current design, it is still impossible to efficiently pass information from a physical object to a patch, or inverse.
PBullet and PPuredata are managing engines and the communication between PObjects.
note: They should both inherits from PObject, both requiring configuration!