Alvaro Cassinelli
/
skinGames_II
save loops
Diff: blobConfig.cpp
- Revision:
- 0:df6fdd9b99f0
- Child:
- 1:3be7b7d050f4
diff -r 000000000000 -r df6fdd9b99f0 blobConfig.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/blobConfig.cpp Tue Dec 02 04:39:15 2014 +0000 @@ -0,0 +1,537 @@ + +#include "blobConfig.h" + +blobConfig::blobConfig(): numBlobs(0) { + //blobArray.clear();// there is no need to do this, the vector does not contains anything here. +} + +blobConfig::~blobConfig() { + clearConfig(); +} + +// =========================================== STANDARD CONFIGURATIONS ============================================================================= + + + +void blobConfig::clearConfig() { + for (int i=0; i<blobArray.size(); i++) delete blobArray[i]; // we must delete the pointer created with new, so the memory for the object is liberated (calls its destructor) + blobArray.clear(); + numBlobs=0;// this is just equal to blobArray.size() +} + +void blobConfig::initConfig(configType cfType, int numblobs) { + myConfigType=cfType; + int i; + switch(myConfigType) { + case ONE_ELASTIC_FOLLOWING: + // computeBoundingBox(); + clearConfig(); + addOneElasticContourFollowing(); + break; + case ONE_ELASTIC_MOUTH: + // computeBoundingBox(); + clearConfig(); + addOneElasticLoopContractCentral(); + break; + case ONE_ELASTIC_MOUTH_SMALL: + // computeBoundingBox(); + clearConfig(); + addOneElasticLoopContractCentralFast(); + break; + case BOUNCING_SPOTS: + // computeBoundingBox(); + clearConfig(); + for (i=0; i<numblobs ; i++) addOneRigidLoopBouncing(); + randomizeAllColors(); + break; + case LORENTZ_SPOTS: + // computeBoundingBox(); + clearConfig(); + for (i=0; i<numblobs ; i++) addOneRigidLoopLorentz(); + randomizeAllColors(); + break; + case FOLLOWING_SPOTS: + // computeBoundingBox(); + clearConfig(); + for (i=0; i<numblobs ; i++) { + addOneRigidLoopFollowing(vector2Df(CENTER_AD_MIRROR_X+i*200, CENTER_AD_MIRROR_Y+i*200), vector2Df(11,0)); + } + // randomize colors: + randomizeAllColors(); + break; + case ONE_TRACKING_SPOT: + clearConfig(); + addOneRigidTrackingSpot(); + break; + case ONE_TRACKING_SPOT_DOT: + clearConfig(); + addOneRigidTrackingSpotDot(); + break; + case AIR_HOCKEY_GAME: + // computeBoundingBox(); + clearConfig(); + for (i=0; i<numblobs ; i++) addOneRigidLoopAirHockey(); + break; + case CIRCULAR_PONG_GAME: + // computeBoundingBox(); + clearConfig(); + // (1) One SPOT_TRACK to track the background. It will be the number 0 in the config. + addOneRigidTrackingSpotDot(); + // (2) Add bouncing spots: + for (i=0; i<numblobs ; i++) { + float anglaux=1.0*i/numblobs*2*PI; + addOneRigidLoopBouncing(vector2Df(CENTER_AD_MIRROR_X+200*cos(anglaux), CENTER_AD_MIRROR_Y+200*sin(anglaux)), + vector2Df(5*cos(anglaux),sin(anglaux))*10); + } + break; + case VERTICAL_PINBALL_GAME: + clearConfig(); + // (1) one (or two) SPOT_TRACK or SPOT_TRACK_DOT to track the background - It will be the number 0 (and 1) in the config. + addOneRigidTrackingSpotDot(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y+600), + vector2Df(0,0)); + // addOneRigidTrackingSpot(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y+600), + // vector2Df(0,0)); + // (2) one or more bouncing spots with gravity: + for (i=0; i<numblobs ; i++) { + addOneRigidLoopBouncingGravity(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y-600), + vector2Df(i*10-5,0)); + } + + break; + case RAIN_MODE: + clearConfig(); + // Add bouncing spot with gravity: + for (i=0; i<numblobs ; i++) { + addOneRigidLoopBouncingGravity(vector2Df(CENTER_AD_MIRROR_X, 10), vector2Df(0,0)); + } + randomizeAllColors(); + break; + case FISH_NET_GAME: + clearConfig(); + // (1) one SPOT_TRACK_DOT to track the background - It will be the number 0 + addOneRigidTrackingSpotDot(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y), // CENTERED + vector2Df(0,0)); + // (2) Add bouncing spots without gravity: + for (i=0; i<numblobs ; i++) { + float anglaux=1.0*i/numblobs*2*PI; + addOneRigidLoopBouncing(vector2Df(CENTER_AD_MIRROR_X+400*cos(anglaux), CENTER_AD_MIRROR_Y+400*sin(anglaux)), + vector2Df(cos(anglaux),sin(anglaux))*10); + } + break; + case PAC_MAN_GAME: + clearConfig(); + //(1) add one very slowly slidind-bouncing spot, the PACMAN (number 0 in the config): + // addOneRigidLoopPacman(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y), vector2Df(20,0)); + + // note: the pacman behaviour is not so good... for the time being, let's just use a following spot: + addOneRigidLoopFollowing(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y), vector2Df(10,0)); + // set the color to red+green: + blobArray.back()->setColor(0x06); + + + // (2) Add some initial SPOT_FOLLOWING or SPOT_GHOST spots (the ghosts): + addOneRigidLoopGhost(vector2Df(CENTER_AD_MIRROR_X+500, CENTER_AD_MIRROR_Y-500), vector2Df(-5,0)); + addOneRigidLoopGhost(vector2Df(CENTER_AD_MIRROR_X-500, CENTER_AD_MIRROR_Y-500), vector2Df(5,0)); + + break; + default: + break; + } + + // make sure lockin red is ON (could be off if using blue for checking mirror delay...): + IO.setLaserLockinPower(1); +} + +void blobConfig::printParameters() { + for (int i=0; i<blobArray.size(); i++) { + pc.printf("Blob n.%d\n", i); + blobArray[i]->printParameters(); // a blob that is in stand-by mode may send data (good for testing with a fixed loop) + } + } + + // ==================== Template spots from which to create multi-spot configurations: ===================== + +void blobConfig::addOneElasticLoopRelax(vector2Df initpos, vector2Df initspeed) { + elasticLoop* pBlob= new elasticLoop(); + pBlob->createBlob(blobArray.size(), RELAX, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); + +} + + +void blobConfig::addOneElasticLoopContract(vector2Df initpos, vector2Df initspeed) { + elasticLoop* pBlob= new elasticLoop(); + pBlob->createBlob(blobArray.size(), CONTRACT, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} + +void blobConfig::addOneElasticLoopContractCentral(vector2Df initpos, vector2Df initspeed) { + elasticLoop* pBlob= new elasticLoop(); + pBlob->createBlob(blobArray.size(), CONTRACT_CENTRAL, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} + +void blobConfig::addOneElasticLoopContractCentralFast(vector2Df initpos, vector2Df initspeed) { + elasticLoop* pBlob= new elasticLoop(); + pBlob->createBlob(blobArray.size(), CONTRACT_CENTRAL_FAST, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} + +void blobConfig::addOneElasticContourFollowing(vector2Df initpos, vector2Df initspeed) { + + elasticLoop* pBlob= new elasticLoop(); + pBlob->createBlob(blobArray.size(), CONTOUR_FOLLOWING, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} + + +void blobConfig:: addOneElasticContourFollowingFAST(vector2Df initpos, vector2Df initspeed) { + elasticLoop* pBlob= new elasticLoop(); + pBlob->createBlob(blobArray.size(), CONTOUR_FOLLOWING_FAST, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} + +void blobConfig::addOneElasticBouncing(vector2Df initpos, vector2Df initspeed) { + elasticLoop* pBlob= new elasticLoop(); + pBlob->createBlob(blobArray.size(), BOUNCING, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} +void blobConfig::addOneRigidLoopBouncingGravity(vector2Df initpos, vector2Df initspeed) { + rigidLoop* pBlob= new rigidLoop(); + pBlob->createBlob(blobArray.size(), SPOT_BOUNCING_FACTOR, initpos, initspeed); + // (We can use here methods of the child class, even if these are not declared virtual on the base class, because we are doing this BEFORE + // adding this to the blobArray as a pointer). This is good to set parameters... + pBlob->gravity.set(0,3.5); + pBlob->centerMass.dampMotion = 0.002; + pBlob->factorBouncingForce=0;//0.003; // this is because we will use a force on the central mass (not used in SPOT_BOUNCING_FACTOR) + pBlob->factorAbsorptionShock=0.9; // coef elastic bouncing + + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} +void blobConfig::addOneRigidLoopBouncing(vector2Df initpos, vector2Df initspeed) { + rigidLoop* pBlob= new rigidLoop(); + pBlob->createBlob(blobArray.size(), SPOT_BOUNCING_FACTOR, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} + +void blobConfig::addOneRigidLoopPacman(vector2Df initpos, vector2Df initspeed) { + rigidLoop* pBlob= new rigidLoop(); + pBlob->createBlob(blobArray.size(), SPOT_PACMAN, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} +void blobConfig::addOneRigidLoopGhost(vector2Df initpos, vector2Df initspeed) { + rigidLoop* pBlob= new rigidLoop(); + pBlob->createBlob(blobArray.size(), SPOT_GHOST, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} + + +void blobConfig::addOneRigidLoopLorentz(vector2Df initpos, vector2Df initspeed) { + rigidLoop* pBlob= new rigidLoop(); + pBlob->createBlob(blobArray.size(), SPOT_LORENTZ_FORCE, initpos, initspeed); + // add this loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} + +void blobConfig::addOneRigidLoopAirHockey(vector2Df initpos, vector2Df initspeed) { + rigidLoop* pBlob= new rigidLoop(); + pBlob->createBlob(blobArray.size(), SPOT_AIR_HOCKEY, initpos, initspeed); + // add this loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} + +void blobConfig::addOneRigidLoopFollowing(vector2Df initpos, vector2Df initspeed) { + rigidLoop* pBlob= new rigidLoop(); + pBlob->createBlob(blobArray.size(), SPOT_FOLLOWING, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // random color for Tokyo Designer Week: + //randomizeAllColors(); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} + +void blobConfig::addOneRigidLoopTest(vector2Df initpos, vector2Df initspeed) { + rigidLoop* pBlob= new rigidLoop(); + pBlob->createBlob(blobArray.size(), SPOT_TEST, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} + +void blobConfig::addOneRigidTrackingSpot(vector2Df initpos, vector2Df initspeed) { + rigidLoop* pBlob= new rigidLoop(); + pBlob->createBlob(blobArray.size(), SPOT_TRACK, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} + +void blobConfig::addOneRigidTrackingSpotDot(vector2Df initpos, vector2Df initspeed) { + rigidLoop* pBlob= new rigidLoop(); + pBlob->createBlob(blobArray.size(), SPOT_TRACK_DOT, initpos, initspeed); + // add this relaxing loop to the present config: + blobArray.push_back(pBlob); + + // update auxiliary variable numBlobs (just for easy reference): + numBlobs=blobArray.size(); +} +// ================================================================================================================================================== +void blobConfig::processSensedData() { + for (int i=0; i<blobArray.size(); i++) blobArray[i]->displaySensingBuffer.processSensedData(); // note: region with light is -1, and without is 2 (TO CHANGE!!! then we don't need to do "if" in the moment computation, but just a product) +} + +void blobConfig::allKill() { // this put all the blobs in "dead" mode, meaning that neither rendering nor update is done (but they are not deleted). + for (int i=0; i<blobArray.size(); i++) { + blobArray[i]->render = false; + blobArray[i]->standByMode = false; + } +} +void blobConfig::allAlive() { + for (int i=0; i<blobArray.size(); i++) { + blobArray[i]->render = true; + blobArray[i]->standByMode = true; + } +} + +void blobConfig::allStandBy() { + for (int i=0; i<blobArray.size(); i++) blobArray[i]->standByMode = true; +} + +void blobConfig::allResume() { + for (int i=0; i<blobArray.size(); i++) blobArray[i]->standByMode = false; +} + +void blobConfig::allVisible() { + for (int i=0; i<blobArray.size(); i++) blobArray[i]->render = true; +} + +void blobConfig::allInvisible() { // note that they may continue to evolve + for (int i=0; i<blobArray.size(); i++) blobArray[i]->render = false; +} + +void blobConfig::allSetColor(unsigned char c) { + for (int i=0; i<blobArray.size(); i++) blobArray[i]->setColor(c); + } + + void blobConfig::allSetGreen(unsigned char c) { + for (int i=0; i<blobArray.size(); i++) blobArray[i]->setGreenColor(c); + } + + void blobConfig::allSetBlue(unsigned char c) { + for (int i=0; i<blobArray.size(); i++) blobArray[i]->setBlueColor(c); + } + + void blobConfig::randomizeAllColors() { + int c; + for (int i=0; i<blobArray.size(); i++) { + c= rand() % 2; + blobArray[i]->setBlueColor(c); + c= rand() % 2; + blobArray[i]->setGreenColor(c); + } + } + +void blobConfig::update() { // update dynamics of the blob configuration: +int i; +float minDist=5000, dist; +bool win; + // Depending on the config type, perform some special test and updates: + switch(myConfigType) { + // simple behaviours: + case ONE_ELASTIC_FOLLOWING: + case ONE_ELASTIC_MOUTH: + case ONE_ELASTIC_MOUTH_SMALL: + case BOUNCING_SPOTS: + case LORENTZ_SPOTS: + case FOLLOWING_SPOTS: + case ONE_TRACKING_SPOT: + case AIR_HOCKEY_GAME: + // In all these simple cases, update dynamics of each blob independently: + for (i=0; i<blobArray.size(); i++) { + if (blobArray[i]->standByMode==false) blobArray[i]->update(); + } + break; + // more game-like: + case CIRCULAR_PONG_GAME: + // spot index 0 is a tracking spot, the background "anchor": + if (blobArray[0]->standByMode==false) blobArray[0]->update(); + // all the other spots are bouncing spots: + for (i=1; i<blobArray.size(); i++) { + if (blobArray[i]->standByMode==false) blobArray[i]->update(); + } + // GAME CHECK: is some bouncing spot too far from the anchor? if so, make it "explode" (and then dissapear, but leave this for now): + for (i=1; i<blobArray.size(); i++) { + dist=(blobArray[0]->getCenter()).distance(blobArray[i]->getCenter()); + if (dist>1000) { + blobArray[i]->explosion(); + float anglaux=1.0*(i-1)/(blobArray.size()-1)*2*PI; + blobArray[i]->setPositionSpeed(vector2Df(CENTER_AD_MIRROR_X+200*cos(anglaux), CENTER_AD_MIRROR_Y+200*sin(anglaux)), + vector2Df(cos(anglaux),sin(anglaux))*10); + } + } + break; + case RAIN_MODE: // this is just spots with gravity that reapears in the top position when reaching the bottom: + // others are bouncing with gravity: + for (i=0; i<blobArray.size(); i++) { + if (blobArray[i]->standByMode==false) blobArray[i]->update(); + } + // GAME CHECKS: + for (i=0; i<blobArray.size(); i++) { + if (blobArray[i]->getCenter().y>MAX_AD_MIRRORS-20) { + // Replace position of spot to the initial position: + blobArray[i]->explosion(); + blobArray[i]->resetPositionSpeed(); + } + } + break; + case VERTICAL_PINBALL_GAME: + // spot index 0 is a tracking spot, the background "anchor": + if (blobArray[0]->standByMode==false) blobArray[0]->update(); + // others are bouncing with gravity: + for (i=1; i<blobArray.size(); i++) { + if (blobArray[i]->standByMode==false) blobArray[i]->update(); + } + // GAME CHECKS: + for (i=1; i<blobArray.size(); i++) { + dist=(blobArray[0]->getCenter()).distance(blobArray[i]->getCenter()); + //(1) win (meaning bouncing spot very close to anchor): + if (dist<60) { + blobArray[i]->explosion(); + blobArray[i]->setPositionSpeed(vector2Df(blobArray[0]->getCenter().x-400+rand()%800, blobArray[0]->getCenter().y-1200), + vector2Df(0, 0)); + } + //(2) loose (meaning spot went outside range): + if (blobArray[i]->getCenter().y>blobArray[0]->getCenter().y) { + blobArray[i]->setPositionSpeed(vector2Df(blobArray[0]->getCenter().x-400+rand()%800, blobArray[0]->getCenter().y-1200), + vector2Df(i*10-5, 0)); + } + } + break; + case FISH_NET_GAME: + // spot index 0 is a tracking spot, the background "anchor": + if (blobArray[0]->standByMode==false) blobArray[0]->update(); + // all the other spots are bouncing spots: + for (i=1; i<blobArray.size(); i++) { + if (blobArray[i]->standByMode==false) blobArray[i]->update(); + } + // GAME CHECKS: a win only, when all the spots are very close to the mother spot: + win=true; + for (i=1; i<blobArray.size(); i++) { + dist=(blobArray[0]->getCenter()).distance(blobArray[i]->getCenter()); + win&=(dist<80); + } + if (win) { + for (i=1; i<blobArray.size(); i++) { + blobArray[i]->explosion(); + float anglaux=1.0*(i-1)/(blobArray.size()-1)*2*PI; + blobArray[i]->setPositionSpeed(vector2Df(CENTER_AD_MIRROR_X+400*cos(anglaux), CENTER_AD_MIRROR_Y+400*sin(anglaux)), + vector2Df(cos(anglaux),sin(anglaux))*10); + } + } + break; + case PAC_MAN_GAME: + // spot index 0 is the pacman: + if (blobArray[0]->standByMode==false) blobArray[0]->update(); + // spot 1 and 2 are ghosts: + if (blobArray[1]->standByMode==false) blobArray[1]->update(blobArray[0]->getCenter()); + if (blobArray[2]->standByMode==false) blobArray[2]->update(blobArray[0]->getCenter()); // pass the position of the PACMAN! + + // GAME CHECK: are any ghost too close to the pacman? + for (i=1; i<blobArray.size(); i++) { + dist=(blobArray[0]->getCenter()).distance(blobArray[i]->getCenter()); + if (minDist>dist) minDist=dist; + } + if (minDist<50) { + blobArray[0]->explosion(); + // then restart the game: + // initConfig(PAC_MAN_GAME); + } + + break; + default: + break; + } + + +} + +void blobConfig::computeBoundingBox() { + for (int i=0; i<blobArray.size(); i++) { + blobArray[i]->computeBoundingBox(); + } +} + +void blobConfig::draw() { // draw uses the opengl like renderer (if any), and save projected trajectory in the LaserSensingTrajectory object of each blob + for (int i=0; i<blobArray.size(); i++) { + if (blobArray[i]->render==true) blobArray[i]->draw(); + } +} + +void blobConfig::sendConfData() { +// For the time being, only "per blob" data sending: +// (b) Per-spot sending of data (note: both are NOT exclusive; so if we want just packaged data, we need to make all the spot STOP sending data. + for (int i=0; i<blobArray.size(); i++) { + if (blobArray[i]->render==true) blobArray[i]->sendData(); // a blob that is in stand-by mode may send data (good for testing with a fixed loop) + } +} + + + +