Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of skinGames_forktest by
Scene.cpp@47:199042980678, 2014-04-17 (annotated)
- 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?
User | Revision | Line number | New 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 |