Laser Sensing Display for UI interfaces in the real world
Fork of skinGames_forktest by
Scene.h@40:3ba2b0ea9f33, 2013-10-16 (annotated)
- Committer:
- mbedalvaro
- Date:
- Wed Oct 16 16:14:27 2013 +0000
- Revision:
- 40:3ba2b0ea9f33
- Child:
- 44:2432c218f191
ca compile
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mbedalvaro | 40:3ba2b0ea9f33 | 1 | #ifndef SCENE_H |
mbedalvaro | 40:3ba2b0ea9f33 | 2 | #define SCENE_H |
mbedalvaro | 40:3ba2b0ea9f33 | 3 | |
mbedalvaro | 40:3ba2b0ea9f33 | 4 | #include <vector> |
mbedalvaro | 40:3ba2b0ea9f33 | 5 | #include "matrixClass.h" |
mbedalvaro | 40:3ba2b0ea9f33 | 6 | #include "classLaserSensingTrajectory.h" // BaseObjet use instances of the classes LaserPoint and LaserSensingTrajectory (cannot forward declare only) |
mbedalvaro | 40:3ba2b0ea9f33 | 7 | //#include "LaserRenderer.h" |
mbedalvaro | 40:3ba2b0ea9f33 | 8 | |
mbedalvaro | 40:3ba2b0ea9f33 | 9 | // 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...) |
mbedalvaro | 40:3ba2b0ea9f33 | 10 | class LaserRenderer; |
mbedalvaro | 40:3ba2b0ea9f33 | 11 | class laserSensingDisplay; |
mbedalvaro | 40:3ba2b0ea9f33 | 12 | |
mbedalvaro | 40:3ba2b0ea9f33 | 13 | // A base class for an "object": |
mbedalvaro | 40:3ba2b0ea9f33 | 14 | // 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 |
mbedalvaro | 40:3ba2b0ea9f33 | 15 | // final RT*vi where vi are the points of the objects. |
mbedalvaro | 40:3ba2b0ea9f33 | 16 | // 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 |
mbedalvaro | 40:3ba2b0ea9f33 | 17 | // list (because projected points are also "sensed") and get information about light or dark zones. |
mbedalvaro | 40:3ba2b0ea9f33 | 18 | // Now, to be able to test things (where the object was "touched", etc), we may need to mantain a correspondence between the projected points |
mbedalvaro | 40:3ba2b0ea9f33 | 19 | // and the original 3d point. There are two options: put them into a single structure "laserpoint", or use two separate arrays. |
mbedalvaro | 40:3ba2b0ea9f33 | 20 | class BaseObject { |
mbedalvaro | 40:3ba2b0ea9f33 | 21 | public: |
mbedalvaro | 40:3ba2b0ea9f33 | 22 | |
mbedalvaro | 40:3ba2b0ea9f33 | 23 | friend class Scene; |
mbedalvaro | 40:3ba2b0ea9f33 | 24 | friend class LaserRenderer; |
mbedalvaro | 40:3ba2b0ea9f33 | 25 | friend class laserSensingDisplay; |
mbedalvaro | 40:3ba2b0ea9f33 | 26 | |
mbedalvaro | 40:3ba2b0ea9f33 | 27 | BaseObject(unsigned int _id=0):myID(_id) {} |
mbedalvaro | 40:3ba2b0ea9f33 | 28 | ~BaseObject(); |
mbedalvaro | 40:3ba2b0ea9f33 | 29 | |
mbedalvaro | 40:3ba2b0ea9f33 | 30 | // Setters: |
mbedalvaro | 40:3ba2b0ea9f33 | 31 | void setID(int _id) {myID=_id;} |
mbedalvaro | 40:3ba2b0ea9f33 | 32 | void setColor( unsigned char _color) {myColor=_color;} // color is coded in three bits in fact (for RGB laser), or more or less... |
mbedalvaro | 40:3ba2b0ea9f33 | 33 | // Per-object adjustement of mirror parameters (could be automated if we know the number of points, etc. For the time being, this is manual): |
mbedalvaro | 40:3ba2b0ea9f33 | 34 | |
mbedalvaro | 40:3ba2b0ea9f33 | 35 | // Getters: |
mbedalvaro | 40:3ba2b0ea9f33 | 36 | 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? |
mbedalvaro | 40:3ba2b0ea9f33 | 37 | int color() {return(myColor);} |
mbedalvaro | 40:3ba2b0ea9f33 | 38 | int ID() {return (myID);} |
mbedalvaro | 40:3ba2b0ea9f33 | 39 | Box3d getEnclosingBox(); |
mbedalvaro | 40:3ba2b0ea9f33 | 40 | |
mbedalvaro | 40:3ba2b0ea9f33 | 41 | // Building methods: |
mbedalvaro | 40:3ba2b0ea9f33 | 42 | // NOTE: I will try to have an encapsulated class, so I prefer not to refer to global variables (like the renderer lsr) |
mbedalvaro | 40:3ba2b0ea9f33 | 43 | void addVertex(V3& _v3, Mat44& _RT); // this add a vertex USING THE CURRENT MODELVIEW (in global lsr object). NOTE: it is NOT projected and added to the myDisplaySensingBuffer yet. |
mbedalvaro | 40:3ba2b0ea9f33 | 44 | void clear(); // this deletes all the vertices and their projections from *this BaseObject instance |
mbedalvaro | 40:3ba2b0ea9f33 | 45 | |
mbedalvaro | 40:3ba2b0ea9f33 | 46 | void transform(Mat44& _RT); // this transform all the vertices of the object by _RT |
mbedalvaro | 40:3ba2b0ea9f33 | 47 | |
mbedalvaro | 40:3ba2b0ea9f33 | 48 | // void render(LaserRenderer* ptr_lsr); // this will project ALL the 3d points in the object vertexArray and store into display sensing buffer (myDisplaySensingBuffer), using |
mbedalvaro | 40:3ba2b0ea9f33 | 49 | // 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 |
mbedalvaro | 40:3ba2b0ea9f33 | 50 | // "rendered", we have the same number of projected and 3d points |
mbedalvaro | 40:3ba2b0ea9f33 | 51 | |
mbedalvaro | 40:3ba2b0ea9f33 | 52 | // Sensing methods (note: only way to get data - touched, not touched, etc - through getters that will re-execute the processing on new data... |
mbedalvaro | 40:3ba2b0ea9f33 | 53 | // (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 |
mbedalvaro | 40:3ba2b0ea9f33 | 54 | // the processing anyway...) |
mbedalvaro | 40:3ba2b0ea9f33 | 55 | bool sense(void); |
mbedalvaro | 40:3ba2b0ea9f33 | 56 | unsigned char maxIntensity(void); |
mbedalvaro | 40:3ba2b0ea9f33 | 57 | unsigned char minIntensity(void); |
mbedalvaro | 40:3ba2b0ea9f33 | 58 | |
mbedalvaro | 40:3ba2b0ea9f33 | 59 | // Virtual methods? for more complex testing - like overall direction, or even motion in case of "sprites" |
mbedalvaro | 40:3ba2b0ea9f33 | 60 | // ... |
mbedalvaro | 40:3ba2b0ea9f33 | 61 | // 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 |
mbedalvaro | 40:3ba2b0ea9f33 | 62 | // childrens pointers in the vector (using downcast "dynamic type casting" which won't slice the object). But then, it means the base class declaration |
mbedalvaro | 40:3ba2b0ea9f33 | 63 | // 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 |
mbedalvaro | 40:3ba2b0ea9f33 | 64 | // 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; |
mbedalvaro | 40:3ba2b0ea9f33 | 65 | // if the pointer points to an object that does not have this method implemented, NOTHING should happen (pure virtual function). Otherwise, it should work |
mbedalvaro | 40:3ba2b0ea9f33 | 66 | // as specified by this child. This very much reminds me to weakly typed Objective-C polymorphic arrays... (NSArrays). How to do this in C++? |
mbedalvaro | 40:3ba2b0ea9f33 | 67 | |
mbedalvaro | 40:3ba2b0ea9f33 | 68 | unsigned char myColor; // per object color (public because it will be used intensively by the displaying engine) |
mbedalvaro | 40:3ba2b0ea9f33 | 69 | |
mbedalvaro | 40:3ba2b0ea9f33 | 70 | LaserSensingTrajectory displaySensingBuffer; |
mbedalvaro | 40:3ba2b0ea9f33 | 71 | |
mbedalvaro | 40:3ba2b0ea9f33 | 72 | private: |
mbedalvaro | 40:3ba2b0ea9f33 | 73 | |
mbedalvaro | 40:3ba2b0ea9f33 | 74 | // PRIVATE INSTANCE VARIABLES: |
mbedalvaro | 40:3ba2b0ea9f33 | 75 | int myID; |
mbedalvaro | 40:3ba2b0ea9f33 | 76 | |
mbedalvaro | 40:3ba2b0ea9f33 | 77 | // Array of 3d coordinates and corresponding 2D projections with sense data: |
mbedalvaro | 40:3ba2b0ea9f33 | 78 | // These are private, so we can ensure that their size is the same... |
mbedalvaro | 40:3ba2b0ea9f33 | 79 | vector<V3> vertexArray; |
mbedalvaro | 40:3ba2b0ea9f33 | 80 | //LaserSensingTrajectory displaySensingBuffer; // the object displaySensingBuffer contains the trajectory of v2 projected points, as well |
mbedalvaro | 40:3ba2b0ea9f33 | 81 | // 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 |
mbedalvaro | 40:3ba2b0ea9f33 | 82 | // have a clear separation between sensing parameters "tweaking" (like mirror delays, setting methods and variables) and the more pure graphical BaseObject |
mbedalvaro | 40:3ba2b0ea9f33 | 83 | |
mbedalvaro | 40:3ba2b0ea9f33 | 84 | Box3d enclosingBox; // this will be filled when rendering the object or when explicitly computing the enclosing box |
mbedalvaro | 40:3ba2b0ea9f33 | 85 | }; |
mbedalvaro | 40:3ba2b0ea9f33 | 86 | |
mbedalvaro | 40:3ba2b0ea9f33 | 87 | // ============================================================================================================================================== |
mbedalvaro | 40:3ba2b0ea9f33 | 88 | |
mbedalvaro | 40:3ba2b0ea9f33 | 89 | |
mbedalvaro | 40:3ba2b0ea9f33 | 90 | // The scene, which is just a collection of objets, plus some methods to add objects, etc: |
mbedalvaro | 40:3ba2b0ea9f33 | 91 | class Scene { |
mbedalvaro | 40:3ba2b0ea9f33 | 92 | public: |
mbedalvaro | 40:3ba2b0ea9f33 | 93 | |
mbedalvaro | 40:3ba2b0ea9f33 | 94 | friend class LaserRenderer; |
mbedalvaro | 40:3ba2b0ea9f33 | 95 | friend class laserSensingDisplay; |
mbedalvaro | 40:3ba2b0ea9f33 | 96 | |
mbedalvaro | 40:3ba2b0ea9f33 | 97 | Scene(): numTouchedObjects(0) {clear();} |
mbedalvaro | 40:3ba2b0ea9f33 | 98 | ~Scene(); |
mbedalvaro | 40:3ba2b0ea9f33 | 99 | |
mbedalvaro | 40:3ba2b0ea9f33 | 100 | // TO THINK ABOUT: METHODS TO TRANSFORM THE COORDINATES OF THE POINTS IN THE SCENE (affecting 3d coordinates) and to RERENDER, |
mbedalvaro | 40:3ba2b0ea9f33 | 101 | // or even TO TRANSFORM AND RENDER (but without modifying the original 3d points). |
mbedalvaro | 40:3ba2b0ea9f33 | 102 | |
mbedalvaro | 40:3ba2b0ea9f33 | 103 | // Create/destroy new objects: |
mbedalvaro | 40:3ba2b0ea9f33 | 104 | // TWO WAYS to create objects: |
mbedalvaro | 40:3ba2b0ea9f33 | 105 | // (1) Use a strategy somehow similar to OpenGL, by using a "begin/end" structure |
mbedalvaro | 40:3ba2b0ea9f33 | 106 | // (2) Making a specific object class inheriting from Object struct (or class), and then ADD to the Scene: |
mbedalvaro | 40:3ba2b0ea9f33 | 107 | |
mbedalvaro | 40:3ba2b0ea9f33 | 108 | void addObject(BaseObject* ptr_newObject); |
mbedalvaro | 40:3ba2b0ea9f33 | 109 | void addCurrentObject(); // this adds the "current" object (pointed by ptr_currentObject) |
mbedalvaro | 40:3ba2b0ea9f33 | 110 | |
mbedalvaro | 40:3ba2b0ea9f33 | 111 | void transform(Mat44& _RT); // this transform all the objects of the scene by _RT |
mbedalvaro | 40:3ba2b0ea9f33 | 112 | |
mbedalvaro | 40:3ba2b0ea9f33 | 113 | // Rendering whole scene: |
mbedalvaro | 40:3ba2b0ea9f33 | 114 | // void render(LaserRenderer* ptr_lsr); |
mbedalvaro | 40:3ba2b0ea9f33 | 115 | |
mbedalvaro | 40:3ba2b0ea9f33 | 116 | 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', |
mbedalvaro | 40:3ba2b0ea9f33 | 117 | // so the memory for the object is liberated by calling its destructor, and THEN clear the vector of pointers) |
mbedalvaro | 40:3ba2b0ea9f33 | 118 | void deleteObject(int _id); // selective deletion (if we know the object index ; perhaps using a STL map with names?) |
mbedalvaro | 40:3ba2b0ea9f33 | 119 | |
mbedalvaro | 40:3ba2b0ea9f33 | 120 | int totalObjects(); // number of objects in the scene |
mbedalvaro | 40:3ba2b0ea9f33 | 121 | int totalPoints(); // total number of points in the scene |
mbedalvaro | 40:3ba2b0ea9f33 | 122 | |
mbedalvaro | 40:3ba2b0ea9f33 | 123 | int sense(); |
mbedalvaro | 40:3ba2b0ea9f33 | 124 | |
mbedalvaro | 40:3ba2b0ea9f33 | 125 | // Methods to "rearrange" the objects in the scene for rendering: |
mbedalvaro | 40:3ba2b0ea9f33 | 126 | // TO DO ........................ |
mbedalvaro | 40:3ba2b0ea9f33 | 127 | |
mbedalvaro | 40:3ba2b0ea9f33 | 128 | // Pointer to the current object being built (in case we use begin/end methods for creating and adding new objects to the scene). |
mbedalvaro | 40:3ba2b0ea9f33 | 129 | // In the future, we may have methods to set this pointer to some other object for adding vertices, changing color, etc. Perhaps not necessary... |
mbedalvaro | 40:3ba2b0ea9f33 | 130 | BaseObject* ptr_currentObject; // made it public because accessed by the WRAPPER FUNCTION "vertex" (can be made a friend...) |
mbedalvaro | 40:3ba2b0ea9f33 | 131 | |
mbedalvaro | 40:3ba2b0ea9f33 | 132 | //private: |
mbedalvaro | 40:3ba2b0ea9f33 | 133 | |
mbedalvaro | 40:3ba2b0ea9f33 | 134 | // The array of objects in this scene: |
mbedalvaro | 40:3ba2b0ea9f33 | 135 | vector <BaseObject*> objectArray; // better to use a vector of pointer: the advantage would be, we could have a polymorphic superclass "Objects" with virtual methods... |
mbedalvaro | 40:3ba2b0ea9f33 | 136 | |
mbedalvaro | 40:3ba2b0ea9f33 | 137 | //bool touchedScene; |
mbedalvaro | 40:3ba2b0ea9f33 | 138 | int numTouchedObjects; // only modified and accessed when calling sense() method |
mbedalvaro | 40:3ba2b0ea9f33 | 139 | }; |
mbedalvaro | 40:3ba2b0ea9f33 | 140 | |
mbedalvaro | 40:3ba2b0ea9f33 | 141 | #endif |
mbedalvaro | 40:3ba2b0ea9f33 | 142 | |
mbedalvaro | 40:3ba2b0ea9f33 | 143 | |
mbedalvaro | 40:3ba2b0ea9f33 | 144 |