Alvaro Cassinelli / Mbed 2 deprecated laserUI

Dependencies:   mbed

Fork of skinGames_forktest by Alvaro Cassinelli

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Scene.h Source File

Scene.h

00001 #ifndef SCENE_H
00002 #define SCENE_H
00003 
00004 #include <vector> 
00005 #include "matrixClass.h"
00006 #include "classLaserSensingTrajectory.h" // BaseObjet use instances of the classes LaserPoint and LaserSensingTrajectory (cannot forward declare only)
00007 //#include "LaserRenderer.h"
00008 
00009 // Forward declared classes (attention: a pointer to an "incomplete class" - eg, only forward declared - is not allowed. It is just like unsing an actual object...)
00010 class LaserRenderer;
00011 class laserSensingDisplay;
00012 
00013 // A base class for an "object":
00014 // Note: all the 3d coordinates of the object are in PROJECTOR coordinates in fact... we don't store a POSE for each object, but instead the
00015 // final RT*vi where vi are the points of the objects in local coordinates. 
00016 // Also, we store IN THE OBJECT the list of projected points (that is, the 3d points projected by using K). The object has methods to study this 
00017 // list (because projected points are also "sensed") and get information about light or dark zones.
00018 // Now, to be able to test things (where the object was "touched", etc), we may need to mantain a correspondence between the projected points 
00019 // and the original 3d point. There are two options: put them into a single structure "laserpoint", or use two separate arrays. 
00020 class BaseObject {
00021  public: 
00022  
00023     friend class Scene;
00024     friend class LaserRenderer;
00025     friend class laserSensingDisplay;
00026  
00027     BaseObject(unsigned int _id=0):myID(_id) {}
00028     ~BaseObject();
00029     
00030     // Setters:
00031     void setID(int _id) {myID=_id;}
00032     void setColor( unsigned char _color) {myColor=_color;} // color is coded in three bits in fact (for RGB laser), or more or less...
00033     // Per-object adjustement of mirror parameters (could be automated if we know the number of points, etc. For the time being, this is manual):
00034     
00035     // Getters: 
00036     int size() {return(vertexArray.size());} // ATTN: in principle, the vertexArray size and the myDisplaySensingBuffer number of points should be equal!! we could check this here?
00037     int color() {return(myColor);}
00038     int ID() {return (myID);}
00039     Box3d getEnclosingBox();
00040     
00041      // Building methods:
00042      // NOTE: I will try to have an encapsulated class, so I prefer not to refer to global variables (like the renderer lsr)
00043     void addVertex(V3& _v3);// add a vertex in LOCAL COORDINATES
00044     void addVertex(V3& _v3, Mat44& _RT); // this will be usefull to add a vertex USING THE CURRENT MODELVIEW (in global lsr object) when 
00045     // creating objects using the "open-gl" like "begin/end" wrappers. NOTE: it is NOT projected and added to the myDisplaySensingBuffer yet.
00046     void clear(); // this deletes all the vertices and their projections from *this BaseObject instance
00047     
00048     // Transformation of vertices:
00049     void transform(Mat44& _RT); // this transform all the vertices of the object by _RT
00050     
00051     // void render(LaserRenderer* ptr_lsr); // this will project ALL the 3d points in the object vertexArray and store into display sensing buffer (myDisplaySensingBuffer), using 
00052     // the current projection matrix and the current projecting mode in the global lsr object. NOTE: THE PREVIOUS DISPLAY BUFFER for this object is CLEARED. This ensures that when 
00053     // "rendered", we have the same number of projected and 3d points 
00054     
00055      // Sensing methods (note: only way to get data - touched, not touched, etc - through getters that will re-execute the processing on new data... 
00056      // (we could have a boolean to check if new data is available, but since the displaying is done very fast, it is likely that we may need to re-compute
00057      // the processing anyway...)
00058     bool sense(void); 
00059     unsigned char maxIntensity(void);
00060     unsigned char minIntensity(void);
00061     
00062     // Virtual methods? for more complex testing - like overall direction, or even motion in case of "sprites"
00063     // ...
00064     // NOTE: as always, I run into this annoying problem: if I have a vector of pointers to the base class, AND virtual methods, then I can store all the
00065     // childrens pointers in the vector (using downcast "dynamic type casting" which won't slice the object). But then, it means the base class declaration 
00066     // needs to know somehting about the children methods! (at least their types and names). THIS IS REALLY ANNOYING, because I would like to add new kind
00067     // of children objects without needing to modify the base class declaration! How to do that? The thing is, sometimes I may need to call to a child method; 
00068     // if the pointer points to an object that does not have this method implemented, NOTHING should happen (pure virtual function). Otherwise, it should work
00069     // as specified by this child. This very much reminds me to weakly typed Objective-C polymorphic arrays... (NSArrays). How to do this in C++?
00070   
00071   unsigned char myColor; // per object color (public because it will be used intensively by the displaying engine)
00072   
00073    LaserSensingTrajectory displaySensingBuffer;
00074    
00075  private:
00076  
00077  // PRIVATE INSTANCE VARIABLES:
00078    int myID;
00079     
00080     // Array of 3d coordinates and corresponding 2D projections with sense data:
00081     // These are private, so we can ensure that their size is the same... 
00082     vector<V3> vertexArray;
00083     //LaserSensingTrajectory displaySensingBuffer; // the object displaySensingBuffer contains the trajectory of v2 projected points, as well
00084     // as some methods to perform the analysis of the saccade. NOTE: I could have made BaseObject a CHILD of the clas LaserSensingTrajectory. But I prefer to 
00085     // have a clear separation between sensing parameters "tweaking" (like mirror delays, setting methods and variables) and the more pure graphical BaseObject  
00086 
00087     Box3d enclosingBox; // this will be filled when rendering the object or when explicitly computing the enclosing box
00088     
00089     // FUTURE WORK: 
00090     // - OBJECTS should have their own transformation matrix, and methods (inherited from a base class?) to modify it or recreate it. This way we will 
00091     // avoid transforming the object 3d points independently, which will create problems because approximations. Eventually, these objects will have 
00092     // behaviours that will affect this transformation matrix (as a function of time). When rendering an object, the object original 3d points will be first modified by 
00093     // the object's own RT, THEN by the global modelview. This is exactly like in an openGL program...
00094 };
00095 
00096 // ==============================================================================================================================================
00097 
00098 
00099 // The scene, which is just a collection of objets, plus some methods to add objects, etc:
00100 class Scene {
00101 public:
00102 
00103     friend class LaserRenderer;
00104     friend class laserSensingDisplay;
00105     
00106     Scene(): numTouchedObjects(0) {clear();}
00107     ~Scene();
00108 
00109     // TO THINK ABOUT: METHODS TO TRANSFORM THE COORDINATES OF THE POINTS IN THE SCENE (affecting 3d coordinates) and to RERENDER, 
00110     // or even TO TRANSFORM AND RENDER (but without modifying the original 3d points). 
00111 
00112  // Create/destroy new objects:
00113     // TWO WAYS to create objects: 
00114     // (1) Use a strategy somehow similar to OpenGL, by using a "begin/end" structure 
00115     // (2) Making a specific object class inheriting from Object struct (or class), and then ADD to the Scene:
00116      
00117     void addObject(BaseObject* ptr_newObject);
00118     void addCurrentObject(); // this adds the "current" object (pointed by ptr_currentObject)
00119      
00120     void transform(Mat44& _RT); // this transform all the objects of the scene by _RT
00121     
00122     // Rendering whole scene:
00123     // void render(LaserRenderer* ptr_lsr);
00124     
00125     void clear(); // "delete" all the objects in the scene (attn! if we store the objects in the scene as POINTERS, we must 'delete' the pointer created with 'new', 
00126     // so the memory for the object is liberated by calling its destructor, and THEN clear the vector of pointers)
00127     void deleteObject(int _id); // selective deletion (if we know the object index ; perhaps using a STL map with names?)
00128     
00129      int totalObjects(); // number of objects in the scene 
00130      int totalPoints(); // total number of points in the scene
00131      
00132      int sense();
00133     
00134 //   Methods to "rearrange" the objects in the scene for rendering: 
00135     // TO DO ........................   
00136 
00137     // Pointer to the current object being built (in case we use begin/end methods for creating and adding new objects to the scene).
00138     // In the future, we may have methods to set this pointer to some other object for adding vertices, changing color, etc. Perhaps not necessary...
00139     BaseObject* ptr_currentObject; // made it public because accessed by the WRAPPER FUNCTION "vertex" (can be made a friend...)
00140 
00141 //private:
00142     
00143     // The array of objects in this scene: 
00144     vector <BaseObject*> objectArray; // better to use a vector of pointer: the advantage would be, we could have a polymorphic superclass "Objects" with virtual methods...
00145     
00146      //bool touchedScene;
00147      int numTouchedObjects; // only modified and accessed when calling sense() method
00148 };
00149 
00150 #endif
00151 
00152 
00153