Laser Sensing Display for UI interfaces in the real world

Dependencies:   mbed

Fork of skinGames_forktest by Alvaro Cassinelli

Committer:
mbedalvaro
Date:
Thu Apr 17 08:04:14 2014 +0000
Revision:
47:199042980678
Parent:
43:1dd4cfc30788
publishing for sharing with Ken Iwasaki

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedalvaro 40:3ba2b0ea9f33 1 #include "Scene.h"
mbedalvaro 40:3ba2b0ea9f33 2 //#include "hardwareIO.h" //(for tests using serial port only)
mbedalvaro 40:3ba2b0ea9f33 3
mbedalvaro 40:3ba2b0ea9f33 4 Scene scene; // pre-instantiated GLOBAL (cross file object, declared extern in the Scene.h header)
mbedalvaro 40:3ba2b0ea9f33 5
mbedalvaro 40:3ba2b0ea9f33 6 //extern LaserRenderer lsr; // Use of the global object lsr (LaserRenderer type). Object is pre-instantiated in LaserRenderer.cpp
mbedalvaro 40:3ba2b0ea9f33 7
mbedalvaro 40:3ba2b0ea9f33 8 using namespace std;
mbedalvaro 40:3ba2b0ea9f33 9
mbedalvaro 40:3ba2b0ea9f33 10 //======================================= BASE OBJECT CLASS =======================================
mbedalvaro 40:3ba2b0ea9f33 11 //BaseObject::BaseObject() {}
mbedalvaro 40:3ba2b0ea9f33 12
mbedalvaro 40:3ba2b0ea9f33 13 BaseObject::~BaseObject() {
mbedalvaro 40:3ba2b0ea9f33 14 // in principle, we don't need to do anything:
mbedalvaro 40:3ba2b0ea9f33 15 // the vertexArray is a vector that does NOT contain pointers; also myDisplaySensingBuffer is destroyed by calling its destructor.
mbedalvaro 40:3ba2b0ea9f33 16 }
mbedalvaro 40:3ba2b0ea9f33 17
mbedalvaro 40:3ba2b0ea9f33 18
mbedalvaro 40:3ba2b0ea9f33 19 void BaseObject::addVertex(V3& _v3, Mat44& _RT) { // passing the current modelview (lsr.RT) as a parameter seems cleaner (more encapsulated class) than using the global lsr object...
mbedalvaro 40:3ba2b0ea9f33 20 vertexArray.push_back(_RT*_v3);
mbedalvaro 40:3ba2b0ea9f33 21 }
mbedalvaro 40:3ba2b0ea9f33 22
mbedalvaro 40:3ba2b0ea9f33 23 void BaseObject::transform(Mat44& _RT) { // this transform all the vertices of the object by _RT
mbedalvaro 40:3ba2b0ea9f33 24 for (unsigned short i=0; i<vertexArray.size(); i++) vertexArray[i]=_RT*vertexArray[i];
mbedalvaro 40:3ba2b0ea9f33 25 }
mbedalvaro 40:3ba2b0ea9f33 26
mbedalvaro 40:3ba2b0ea9f33 27 void BaseObject::clear() { // this deletes all the vertices (and their projections) in the object:
mbedalvaro 40:3ba2b0ea9f33 28 vertexArray.clear();
mbedalvaro 40:3ba2b0ea9f33 29 displaySensingBuffer.lsdTrajectory.clear();
mbedalvaro 40:3ba2b0ea9f33 30 }
mbedalvaro 40:3ba2b0ea9f33 31
mbedalvaro 40:3ba2b0ea9f33 32 /* THIS PRODUCE A CIRCULAR REFERENCE!
mbedalvaro 40:3ba2b0ea9f33 33 void BaseObject::render(LaserRenderer* ptr_lsr) {
mbedalvaro 40:3ba2b0ea9f33 34 // Use the lsr methods: again, this would be kind of convoluted if these objects belongs to a scene that belongs to lsr...
mbedalvaro 40:3ba2b0ea9f33 35 ptr_lsr->renderObject(this);
mbedalvaro 40:3ba2b0ea9f33 36 */
mbedalvaro 40:3ba2b0ea9f33 37
mbedalvaro 40:3ba2b0ea9f33 38 //Or do it "directly" (but again, we need to use data from the lsr state machine):
mbedalvaro 40:3ba2b0ea9f33 39 /*
mbedalvaro 40:3ba2b0ea9f33 40 // First, clear the current lsdTrajectory:
mbedalvaro 40:3ba2b0ea9f33 41 Object.myDisplaySensingBuffer.lsdTrajectory.clear();
mbedalvaro 40:3ba2b0ea9f33 42 if (lsr.renderingMode==PROJECTION)
mbedalvaro 40:3ba2b0ea9f33 43 for (int i=0; i<vertexArray.size(); i++) {
mbedalvaro 40:3ba2b0ea9f33 44 LaserPoint newLp=lsr.renderPointProj(Object.vertexArray[i]); // or use a render method for a LaserPoint or an extended V3 class (or directly)
mbedalvaro 40:3ba2b0ea9f33 45 // Set per-vertex color too? No, for the time being one color per object...
mbedalvaro 40:3ba2b0ea9f33 46 // newLp.myColor=color;
mbedalvaro 40:3ba2b0ea9f33 47 Object.myDisplaySensingBuffer.lsdTrajectory.push_back(newLp);
mbedalvaro 40:3ba2b0ea9f33 48 }
mbedalvaro 40:3ba2b0ea9f33 49 else
mbedalvaro 40:3ba2b0ea9f33 50 for (int i=0; i<Object.vertexArray.size(); i++) {
mbedalvaro 40:3ba2b0ea9f33 51 LaserPoint newLp=lsr.renderPointRaw(Object.vertexArray[i]);
mbedalvaro 40:3ba2b0ea9f33 52 // Set per-vertex color too? No, for the time being one color per object...
mbedalvaro 40:3ba2b0ea9f33 53 // newLp.myColor=color;
mbedalvaro 40:3ba2b0ea9f33 54 Object.myDisplaySensingBuffer.lsdTrajectory.push_back(newLp);
mbedalvaro 40:3ba2b0ea9f33 55 }
mbedalvaro 40:3ba2b0ea9f33 56 }
mbedalvaro 40:3ba2b0ea9f33 57 }
mbedalvaro 40:3ba2b0ea9f33 58 */
mbedalvaro 40:3ba2b0ea9f33 59
mbedalvaro 40:3ba2b0ea9f33 60 Box3d BaseObject::getEnclosingBox() {
mbedalvaro 40:3ba2b0ea9f33 61 // This will give the 3d enclosing box for the object, in LOCAL coordinates.
mbedalvaro 40:3ba2b0ea9f33 62 // (for the time being, let's compute every time we query about it. In the future we can optimize by computing only when the object changed)
mbedalvaro 40:3ba2b0ea9f33 63 if (vertexArray.size()==0) {
mbedalvaro 40:3ba2b0ea9f33 64 enclosingBox.minX=enclosingBox.maxX=enclosingBox.minY=enclosingBox.maxY=enclosingBox.minZ=enclosingBox.maxZ=0;
mbedalvaro 40:3ba2b0ea9f33 65 }
mbedalvaro 40:3ba2b0ea9f33 66 else
mbedalvaro 40:3ba2b0ea9f33 67 {
mbedalvaro 40:3ba2b0ea9f33 68 enclosingBox.minX=enclosingBox.maxX=vertexArray[0].x;
mbedalvaro 40:3ba2b0ea9f33 69 enclosingBox.minY=enclosingBox.maxY=vertexArray[0].y;
mbedalvaro 40:3ba2b0ea9f33 70 enclosingBox.minZ=enclosingBox.maxZ=vertexArray[0].z;
mbedalvaro 40:3ba2b0ea9f33 71 for (unsigned short i=1; i<vertexArray.size(); i++) {
mbedalvaro 40:3ba2b0ea9f33 72 if (vertexArray[i].x>enclosingBox.maxX) enclosingBox.maxX=vertexArray[i].x;
mbedalvaro 40:3ba2b0ea9f33 73 else if (vertexArray[i].x<enclosingBox.minX) enclosingBox.minX=vertexArray[i].x;
mbedalvaro 40:3ba2b0ea9f33 74 if (vertexArray[i].y>enclosingBox.maxY) enclosingBox.maxY=vertexArray[i].y;
mbedalvaro 40:3ba2b0ea9f33 75 else if (vertexArray[i].y<enclosingBox.minY) enclosingBox.minY=vertexArray[i].y;
mbedalvaro 40:3ba2b0ea9f33 76 }
mbedalvaro 40:3ba2b0ea9f33 77 }
mbedalvaro 40:3ba2b0ea9f33 78 return (enclosingBox);
mbedalvaro 40:3ba2b0ea9f33 79 }
mbedalvaro 40:3ba2b0ea9f33 80
mbedalvaro 40:3ba2b0ea9f33 81 // Sensing methods (query and process sensed data):
mbedalvaro 40:3ba2b0ea9f33 82 // That this is separated from displaying routine make sense: we can query at ANY time for new data,
mbedalvaro 40:3ba2b0ea9f33 83 // and this is uncorrelated with the display buffer continuous to work, displaying and sensing things.
mbedalvaro 40:3ba2b0ea9f33 84 // ALSO, it is separated from the LaserRenderer: this routine does not uses any "state machine" data.
mbedalvaro 40:3ba2b0ea9f33 85 bool BaseObject::sense() {return(this->displaySensingBuffer.processSensedData());}
mbedalvaro 40:3ba2b0ea9f33 86
mbedalvaro 40:3ba2b0ea9f33 87 // Max and Min intensity RATIOS (normalized between 0 and 255):
mbedalvaro 40:3ba2b0ea9f33 88 unsigned char BaseObject::maxIntensity(void) {displaySensingBuffer.processSensedData(); return displaySensingBuffer.maxI;}
mbedalvaro 40:3ba2b0ea9f33 89 unsigned char BaseObject::minIntensity(void) {displaySensingBuffer.processSensedData(); return displaySensingBuffer.minI;}
mbedalvaro 40:3ba2b0ea9f33 90
mbedalvaro 40:3ba2b0ea9f33 91
mbedalvaro 40:3ba2b0ea9f33 92 //======================================= THE SCENE CLASS =======================================
mbedalvaro 40:3ba2b0ea9f33 93
mbedalvaro 40:3ba2b0ea9f33 94 //Scene::Scene() : numTouchedObjects(0) {}
mbedalvaro 40:3ba2b0ea9f33 95
mbedalvaro 40:3ba2b0ea9f33 96 Scene::~Scene() {
mbedalvaro 40:3ba2b0ea9f33 97 this->clear(); // necessary because Scene object variable objectArray is an vector of POINTERS and we need to free memory for the pointed objects.
mbedalvaro 40:3ba2b0ea9f33 98 }
mbedalvaro 40:3ba2b0ea9f33 99
mbedalvaro 40:3ba2b0ea9f33 100 void Scene::clear() {
mbedalvaro 40:3ba2b0ea9f33 101 //NOTE: objectArray stores POINTERS to objects; we need therefore to delete first the object itself:
mbedalvaro 40:3ba2b0ea9f33 102 for (int i=0; i<this->totalObjects(); i++) {
mbedalvaro 40:3ba2b0ea9f33 103 // pc.printf("deleting object: %d\n", i);
mbedalvaro 40:3ba2b0ea9f33 104 delete objectArray[i]; // this call the destructor for BaseObject
mbedalvaro 40:3ba2b0ea9f33 105 }
mbedalvaro 40:3ba2b0ea9f33 106 objectArray.clear(); // clear the vector of pointers
mbedalvaro 40:3ba2b0ea9f33 107 ptr_currentObject=NULL;
mbedalvaro 40:3ba2b0ea9f33 108 }
mbedalvaro 40:3ba2b0ea9f33 109
mbedalvaro 40:3ba2b0ea9f33 110 void Scene::addObject(BaseObject* ptr_newObject) {
mbedalvaro 40:3ba2b0ea9f33 111 objectArray.push_back(ptr_newObject); // note: the object pointed by ptr_newObject has been instantiated OUTSIDE this method.
mbedalvaro 40:3ba2b0ea9f33 112 //ptr_currentObject=ptr_newObject;
mbedalvaro 40:3ba2b0ea9f33 113 }
mbedalvaro 40:3ba2b0ea9f33 114
mbedalvaro 40:3ba2b0ea9f33 115 void Scene::addCurrentObject() { // this adds the "current" object (pointed by ptr_currentObject)
mbedalvaro 40:3ba2b0ea9f33 116 objectArray.push_back(ptr_currentObject);
mbedalvaro 40:3ba2b0ea9f33 117 // Note: the current object pointerd by ptr_currentObject can be BaseObject... or any child class. This is not a problem as long as the methods applied to the
mbedalvaro 40:3ba2b0ea9f33 118 // scene vector array don't use child methods (then we can do a dynamic cast before including in the array: pb = dynamic_cast<CBase*>(&d); ). IF we want
mbedalvaro 40:3ba2b0ea9f33 119 // the scene class to be able to use child methods, then we need to make BaseObject polymorphic, by declaring all usable methods VIRTUAL.
mbedalvaro 40:3ba2b0ea9f33 120
mbedalvaro 40:3ba2b0ea9f33 121 }
mbedalvaro 40:3ba2b0ea9f33 122
mbedalvaro 40:3ba2b0ea9f33 123 void Scene::transform(Mat44& _RT) { // this transform all the objects of the scene by _RT
mbedalvaro 40:3ba2b0ea9f33 124 for (int i=0; i<totalObjects(); i++) objectArray[i]->transform(_RT);
mbedalvaro 40:3ba2b0ea9f33 125 }
mbedalvaro 40:3ba2b0ea9f33 126
mbedalvaro 43:1dd4cfc30788 127 // ATTENTION: deleting objects imply stoping the displaying engine, and updating. This is mandatory, not in the case of ADDING objects...
mbedalvaro 40:3ba2b0ea9f33 128 void Scene::deleteObject(int _id) {
mbedalvaro 40:3ba2b0ea9f33 129 // We could use an STL map, but here I will do the matching manually:
mbedalvaro 40:3ba2b0ea9f33 130 for (int i=0; i<totalObjects(); i++)
mbedalvaro 40:3ba2b0ea9f33 131 if ( (objectArray[i]->ID()) == _id) objectArray.erase(objectArray.begin()+i); // note: I don't stop the for-loop. I delete ALL objects with this ID
mbedalvaro 40:3ba2b0ea9f33 132 // Not sure I will use the "current pointer", but if I do, then we need to decide what it becomes here... let's point to the last element in the vector:
mbedalvaro 40:3ba2b0ea9f33 133 if (!objectArray.empty()) ptr_currentObject=objectArray.back(); else ptr_currentObject=NULL;
mbedalvaro 40:3ba2b0ea9f33 134 }
mbedalvaro 40:3ba2b0ea9f33 135
mbedalvaro 40:3ba2b0ea9f33 136 // number of objects in the scene:
mbedalvaro 40:3ba2b0ea9f33 137 int Scene::totalObjects() {return(objectArray.size());}
mbedalvaro 40:3ba2b0ea9f33 138
mbedalvaro 40:3ba2b0ea9f33 139 // total number of points in the scene:
mbedalvaro 40:3ba2b0ea9f33 140 int Scene::totalPoints() {
mbedalvaro 40:3ba2b0ea9f33 141 int ttlpoints=0;
mbedalvaro 40:3ba2b0ea9f33 142 for (unsigned short i=0; i<objectArray.size(); i++) ttlpoints+=objectArray[i]->size();
mbedalvaro 40:3ba2b0ea9f33 143 return(ttlpoints);
mbedalvaro 40:3ba2b0ea9f33 144 }
mbedalvaro 40:3ba2b0ea9f33 145
mbedalvaro 40:3ba2b0ea9f33 146 /*
mbedalvaro 40:3ba2b0ea9f33 147 void Scene::render(LaserRenderer* ptr_lsr) {
mbedalvaro 40:3ba2b0ea9f33 148 ptr_lsr->renderScene(this);
mbedalvaro 40:3ba2b0ea9f33 149 // Or, if one want to use the object render method (that also calls lsr methods anyway, so it is heavier):
mbedalvaro 40:3ba2b0ea9f33 150 // for (int i=0; i<Scene.size(); i++) renderObject(ptr_scene->objectArray[i]);
mbedalvaro 40:3ba2b0ea9f33 151 }
mbedalvaro 40:3ba2b0ea9f33 152 */
mbedalvaro 40:3ba2b0ea9f33 153
mbedalvaro 40:3ba2b0ea9f33 154 int Scene::sense() {
mbedalvaro 40:3ba2b0ea9f33 155 numTouchedObjects=0;
mbedalvaro 40:3ba2b0ea9f33 156 for (int i=0; i<totalObjects(); i++)
mbedalvaro 40:3ba2b0ea9f33 157 if (objectArray[i]->displaySensingBuffer.processSensedData()) numTouchedObjects++;
mbedalvaro 40:3ba2b0ea9f33 158 //touchedScene=(numTouchedObjects>0);
mbedalvaro 40:3ba2b0ea9f33 159 return(numTouchedObjects);
mbedalvaro 40:3ba2b0ea9f33 160 }
mbedalvaro 40:3ba2b0ea9f33 161
mbedalvaro 40:3ba2b0ea9f33 162