Laser Sensing Display for UI interfaces in the real world

Dependencies:   mbed

Fork of skinGames_forktest by Alvaro Cassinelli

WrapperFunctions.h

Committer:
mbedalvaro
Date:
2014-04-17
Revision:
47:199042980678
Parent:
43:1dd4cfc30788

File content as of revision 47:199042980678:

/* Name: WrapperFunctions.h
    
   * DESCRIPTION: 
    
    The following file defines a set of "WRAPPER" functions to simplify creating, rendering and displaying objects and scenes. 
    Basically, to display something we have to: 
  
       (1) BUILD A "SCENE" by creating and adding Objects. The rendering stack (lsr) will be used to modify the "modeling transformation RT".
       (2) Set the PERSPECTIVE TRANSFORMATION, and the VIEWING TRANSFORMATION (again, this is just playing with lsr), and then DRAW THE SCENE. 
                
    * NOTE THAT: 
    
       (1) BUILDING the SCENE is done ONLY ONCE (or at least, each time we have a completely new scene to show), and not all the time as 
        in OpenGL (well, the equivalent in OpenGL is the vertex arrays sent to the graphic card). 
       (2) DRAWING THE SCENE is ALSO DONE ONLY WHEN WE GET A NEW VIEWING TRANSFORMATION (i.e., a new "POSE"). This is because 
               
    * HOW DOES IT WORK:
     
       (1) (a) Building a scene start by a call to "beginScene()". This routine first stoping the displaying engine (lsd) if it was working, and then deleting all data in it. 
       The reason is that we will modify the number of points/objects in it, and the "laser sensing display" engine (lsd) would fail trying to access arrays that have been deleted. 
           (b) then, we can add objects (using the objects primitives, or begin/end keywords). In so doing, we can use the modelview matrix stack liberaly, to place things
        where they need to be. Note that the objects are NOT yet rendered. 
           (C) We finish by calling "updateScene()", which has an important function: it tells the (dormant) displaying engine to update the size and structure of the "scene" in its 
        internal variables. BUT WE DON'T REATTACH THE INTERRUPT for the lsd again, because we did NOT yet render anything! 
        
       (2) Time for drawing: the first thing is to set the PROJECTION MATRIX (this in principle can be done once, at the very start of the program and is likely not to change). 
       Then, each time we have a new POSE, we need to set the VIEWING TRANSFORMATION (again, using the modelview stack lsr). 
       When both things are done, a call to "drawScene()" will apply the global viewing transformation to each point in the scene, and RENDER them too (using the projection matrix). 
       By DEFAULT, a call to "drawScene()" will ACTIVATE the DISPLAYING ENGINE if it was not working. 
       
       IMPORTANT: Note that we don't NEED to STOP the displaying interrupt when just changing the pose or even the projection matrix - this is because the STRUCTURE of the scene
                  did not change, and then the displaying engine will not fail. However, there may be some strange graphical "anomalies" (the equivalent of problems with 
                  vertical synch on normal displays). This is because I am not using DOUBLE BUFFERING, but I will address this in future versions. 
       
    * AN EXAMPLE: 
                
    (a) In a setting function:  
    
    //(A) First, set the modelview and projection matrices: 
    // Typically, the projection matrix is set from the PC side, or loaded by default (from file system).
    // The modelview matrix may be, say, the identity:
    lsr.setIdentityPose(); // we could use a wrapper, but I won't for the time being. 

    //(B) Start building the "scene" with objects in it (now I will use wrapper functions - note that "objectPrimitives" are sort of wrapper functions too):    
    
    beginScene(); // stop displaying (in the future we can have double buffering...). then clear the scene.  
    // we can start adding objects: 
    
    // (a) in OpenGL like style:
    begin(1); // start creating object with identifier = 1
    vertex(10,10,0); vertex(10,100,0); vertex(100,100,0); vertex(10,100,0); vertex(10,10,0); // closed square
    end();
    
    // (b) example of adding an object using objectPrimitives: 
    buildLine(10,10,0,100,100,0,10, 1);
    
    endScene(); // this is important: rendering is done here, and the display engine (lsd) is reattached to the interrupt timer. 
    
    
*/

#include "Scene.h"
#include "laserSensingDisplay.h"
#include "LaserRenderer.h"

#include <string> 
//using namespace std; // should not be in a header (we will bring to any other cpp that includes this file!!

// Special classes of derived objects: 
// #include ...

//class laserSensingDisplay; // will produce "incomplete type not allowed" 

// ====================================================================================================================================================

// enum typeObject {GENERIC_OBJECT, LETTER}; // this will be useful for adding derived objects from BaseObject using the being() method, such as letters, and in the future objects
// that can have an "update" method of their own (and move around...)

// =================================   BASIC "OPENGL-like" object/scene builders and query functions ("sense") ==========================================

// Creating a "scene" (a collection of "objects"). 
// NOTE: the advantage of having clustered points into "objects" and then a "scene" is that we may have handles for each of them, to modify their appearance, or query for touch, etc.  
void clearScene();
void updateScene();

// Create objects "a-la" OpenGL (for other ways, see objectPrimitives.h). 
//BaseObject* begin(typeObject _type, unsigned char _id); // This will add a new object with or without identifier _id. In the future, we can have modes - lines, bezier, and points.
BaseObject* begin(unsigned char _id); // This will add a new object with or without identifier _id. In the future, we can have modes - lines, bezier, and points.
void vertex(float x, float y, float z); // add a point, but do not RENDER it yet (no final projection computed)
void vertex(V3& _v3);
void end(); // (this is meaningless if there is no polygon or bezier mode... but even now it is good to have for clarity - and to look like opengl)

// Delete object from current scenembed_reset (in the future, let's use also strings as IDs):
void deleteObject(int _id); 

// Rendering methods: 
void drawObject(int _id) ;
void drawObject(BaseObject* ptr_object) ;
void drawScene();

// Sensing methods (query and process sensed data):
bool senseObject(int _id);
bool senseScene();

// =================================   OTHER auxiliary GLOBAL SCENE/OBJECT TRANSFORMATIONS ==========================================

void trasformObject(int _id) ;
void translateObject(int _id, int xx, int yy, int zz=0);
void rotateObjectX(int _id, float alpha);
void rotateObjectY(int _id, float alpha);
void rotateObjectZ(int _id, float alpha);

void transformObject(BaseObject* ptr_object) ;
void transformScene();
void changeColorScene(unsigned char _color);

// =================================   OBJECT PRIMITIVES (this could be in a different file) ============================================================

// These are some primitive sensing-displaying objects (in the future, kind of UIButtons - would be nice if they could produce "events"...)
// Note that the only way (for now) to query if some object has been "touched" is through the knowledge of its "unique" ID... which acts as a handler. In fact, 
// we can keep track of its pointer in the main program - and this means it will be exactly a handler... 
void line(float x0, float y0, float z0, float x1, float y1, float z1, int npoints);
void line(V3& v0, V3& v1, int npoints);
void square(float sideSize, int npointsSide);
void rectangle(float sideSizeX, float sideSizeY, int interPointDistance);
void circle(float radius, int numpoints);
void cube(float sideSize, int npointsSide);   // not really a cube...
void grid(int nx, int ny, int repeatpoint); // normalized (0-1)x(0-1)
void grid(float sizeX, float sizeY, int nx, int ny, int repeatpoint);
void gridCircles(int nx, int ny, float radius, int nbpointsCircle);
void gridCircles(float sizeX, float sizeY, int nx, int ny, float radius, int nbpointsCircle);
     
// LETTERS and STRINGS:
void letter3d(char _letter, float width, float height);
void string3d(string text, float fontSize, float spaceWidth);

// =================================   WRAPPERS TO LOAD OBJECTS FROM SYSTEM FILE ========================================================================
 // ... to do   
 //void buildRawTrajectory(float * auxbuffer, int arraySize);
    
// =================================   WRAPPERS TO LOAD MATRICES FROM SYSTEM FILE =======================================================================
// ...to do

// ================================= WRAPPERS FOR MORE BASIC IO FUNCTIONS   =================================
void scanSerial(unsigned short pointsPerLine);
void showLimitsMirrors(unsigned short pointsPerLine, unsigned short durationSecs);
void recomputeLookUpTable();
void startDisplay();
void stopDisplay();
void toggleDisplay();
void resumeDisplay();
// =============================== HARDWARE KNOBS: switches, potentiometers... =================================================
void hardwareKnobs();