diff options
Diffstat (limited to 'gaunt01')
| -rw-r--r-- | gaunt01/addons.make | 1 | ||||
| -rw-r--r-- | gaunt01/src/testApp.cpp | 189 | ||||
| -rw-r--r-- | gaunt01/src/testApp.h | 11 | ||||
| -rw-r--r-- | gaunt01/src/trapdoor.cpp | 71 | ||||
| -rw-r--r-- | gaunt01/src/trapdoor.h | 28 |
5 files changed, 224 insertions, 76 deletions
diff --git a/gaunt01/addons.make b/gaunt01/addons.make index 22fba83..d5faedd 100644 --- a/gaunt01/addons.make +++ b/gaunt01/addons.make @@ -1,3 +1,4 @@ ofxOpenCv +ofxBlobsManager ofxRay ofxXmlSettings diff --git a/gaunt01/src/testApp.cpp b/gaunt01/src/testApp.cpp index 87a51c4..aebbe0b 100644 --- a/gaunt01/src/testApp.cpp +++ b/gaunt01/src/testApp.cpp @@ -4,11 +4,11 @@ //units ~ 10cm // void testApp::setup(){ - + bLearnBakground = true; cam_angle=0; threshold = 80; - + loadSettings("settings.xml"); vidPlayer.loadMovie("camoutput.mov"); //footage/ camera needs to be the same res as opencv planes and output @@ -18,19 +18,24 @@ void testApp::setup(){ hasCamera=true; useCamera=true; } - else + else { hasCamera=false; useCamera=false; vidPlayer.play(); } - colorImg.allocate(640,480); colorImg.setUseTexture(true); grayImage.allocate(640,480); grayBg.allocate(640,480); grayDiff.allocate(640,480); + + blobsManager.normalizePercentage = 0.7; + blobsManager.giveLowestPossibleIDs = true; + blobsManager.maxUndetectedTime = 500; + blobsManager.minDetectedTime = 2000; + blobsManager.debugDrawCandidates = true; ofVec3f centre=ofVec3f(ofGetWidth()/2,0,0); ofVec3f normal=ofVec3f(0,0,-1); @@ -45,59 +50,104 @@ void testApp::setup(){ cam=ofCamera(); cam.setPosition(ofGetWidth()/2,ofGetHeight()/2,-ofGetWidth()); cam.lookAt(ofVec3f(ofGetWidth()/2,ofGetHeight()/2,0),ofVec3f(0, -1, 0)); - cam.setFov(41.0); //39.85); //53.13); + cam.setFov(41.1); //39.85); //53.13); + cam.cacheMatrices(); //stop error messages + + testpts=new ofVec3f[4]; + trapDoor=trapdoor(screen2plane(ofVec2f(ofGetWidth(),0)),screen2plane(ofVec2f(ofGetWidth(),ofGetHeight())),ofVec2f(30,30)); updatePlane(); - + mode=PLAY; + } ofVec2f testApp::screen2plane(ofVec2f screenpos){ ofVec3f p; - ray=projector.castPixel(screenpos.x,screenpos.y); + ray=projector.castPixel(screenpos.x,screenpos.y); bool hit = plane.intersect(ray,p); return ofVec2f(p.x,pow(pow(p.y,2)+pow(p.z,2),0.5f)); } ofVec3f testApp::plane2world(ofVec2f planepos){ return ofVec3f(planepos.x,planepos.y,0); } +bool testApp::rectsCross(ofRectangle rect1,ofRectangle rect2) { + bool overlap=true; //must overlap in x and y + if (rect1.x<rect2.x) { + if (rect1.x+rect1.width<rect2.x) overlap = false; + } + else if (rect2.x<rect1.x) { + if (rect2.x+rect2.width<rect1.x) overlap = false; + } + if (overlap) { //still possible + if (rect1.y<rect2.y) { + if (rect1.y+rect1.height<rect2.y) overlap = false; + } + else if (rect2.y<rect1.y) { + if (rect2.y+rect2.height<rect1.y) overlap = false; + } + } + return overlap; +} + void testApp::updatePlane(){ - plane.setNormal(ofVec3f(0,sin(cam_angle*0.01745329),-cos(cam_angle*0.01745329))); - trapDoor=trapdoor(screen2plane(ofVec2f(ofGetWidth(),0)),screen2plane(ofVec2f(ofGetWidth(),ofGetHeight())),ofVec2f(20,20)); + plane.setNormal(ofVec3f(0,sin(cam_angle*DEG_TO_RAD),-cos(cam_angle*DEG_TO_RAD))); //create ground mesh with hole for trapdoor ground=ofMesh(); - ground.addVertex(plane2world(screen2plane(ofVec2f(0,0)))); + ground.addVertex(ofVec3f(0,0,0)); ground.addTexCoord(ofVec2f(0,0)); - ground.addVertex(plane2world(screen2plane(ofVec2f(ofGetWidth(),0)))); + ground.addVertex(ofVec3f(ofGetWidth(),0,0)); ground.addTexCoord(ofVec2f(1,0)); - ground.addVertex(plane2world(screen2plane(ofVec2f(ofGetWidth(),ofGetHeight())))); + ground.addVertex(ofVec3f(ofGetWidth(),ofGetHeight(),0)); ground.addTexCoord(ofVec2f(1,1)); - ground.addVertex(plane2world(screen2plane(ofVec2f(0,ofGetHeight())))); + ground.addVertex(ofVec3f(0,ofGetHeight(),0)); ground.addTexCoord(ofVec2f(0,1)); - - ground.addTriangle(0,2,1); - ground.addTriangle(0,3,2); - - /* + vector<ofVec2f> corners=trapDoor.getCorners(); + ofVec2f screenCorners[4]; + for (int i=0;i<corners.size();i++) { - ground.addVertex(plane2world(corners[0])); - ground.addTexCoord(trapDoor.bounds2UV(corners[0])); + + ofNode axis; + ofNode c; + c.setParent(axis); + + c.setPosition(corners[i].x,corners[i].y,0); + + axis.rotate(cam_angle,1,0,0); + + ofVec3f p=c.getGlobalPosition(); + + testpts[i]=p; + ofVec3f s=cam.worldToScreen(p); + //printf("corner %i: %f,%f,%f\n",i,s.x,s.y,s.z); + screenCorners[i]=ofVec2f(s.x,s.y); + + ground.addVertex(s); + ground.addTexCoord(ofVec2f(s.x/ofGetWidth(),s.y/ofGetHeight())); } //join a quad for each side - for (int i=0;i<corners.size();i++) { - ground.addTriangle(i,i+4,i+1); - ground.addTriangle(i+4,(i+5)%ground.getNumVertices(),i+1); + // the 2 rear sides should always point towards the rear + for (int i=0;i<3;i++) { + ground.addTriangle(i,i+4,i+5); + ground.addTriangle(i+5,i+1,i); } - */ + ground.addTriangle(3,7,0); + ground.addTriangle(7,4,0); + float x=min(screenCorners[0].x,screenCorners[3].x); + float y=min(screenCorners[0].y,screenCorners[1].y); + float w=max(screenCorners[1].x,screenCorners[2].x)-x; + float h=max(screenCorners[2].y,screenCorners[3].y)-y; + trapDoor.setBoundingRect(x,y,w,h); + + } //-------------------------------------------------------------- void testApp::update(){ - ofBackground(100,100,100); bool bNewFrame = false; @@ -129,34 +179,71 @@ void testApp::update(){ // find contours which are between the size of 20 pixels and 1/3 the w*h pixels. // also, find holes is set to true so we will get interior contours as well.... - + //hard coded size threshold of 100 pix contourFinder.findContours(grayDiff, 200, (640*480)/3, 20, false); // don't find holes + + blobsManager.update(contourFinder.blobs); } } //-------------------------------------------------------------- void testApp::draw(){ + ofBackground(0,0,0); cam.begin(); - + + if (trapDoor.checkUpdate(players)) updatePlane(); + switch(mode) { case PLAY: glDisable(GL_DEPTH_TEST); - //must be a better way than this colorImg.draw(0,0,ofGetWidth(),ofGetHeight()); - ofFill(); ofSetHexColor(0x000000); ofRect(0,0,ofGetWidth(),ofGetHeight()); + //PITA ofSetHexColor(0xffffff); ofPushMatrix(); ofRotate(cam_angle,1,0,0); - bindTexture(colorImg); - ground.draw(); - unbindTexture(colorImg); - trapDoor.checkUpdate(players); trapDoor.draw(); ofPopMatrix(); + ofSetHexColor(0xffffff); + /* + glEnable(GL_BLEND); + glBlendFunc(GL_CONSTANT_ALPHA,GL_ONE); + glBlendColor(1.0f,1.0f,1.0f, 0.5f); + glDisable(GL_BLEND); + */ + + bindTexture(colorImg); + ground.draw(); + unbindTexture(colorImg); + + /* + glEnable(GL_BLEND); + glBlendFunc(GL_CONSTANT_ALPHA,GL_ONE); + glBlendColor(1.0f,0.5f,0.1f, 0.5f); + ofRect(trapDoor.getBoundingRect()); + glDisable(GL_BLEND); + */ + for (int i = 0; i < contourFinder.nBlobs; i++){ + ofxCvBlob blob=contourFinder.blobs[i]; + if (rectsCross(blob.boundingRect,trapDoor.getBoundingRect())){ + //create outline mesh + playeroutline=ofPolyline(blob.pts); + tesselator.tessellateToMesh(playeroutline,OF_POLY_WINDING_NONZERO,player,true); + for (int i=0;i<player.getNumVertices();i++) { + ofVec3f v=player.getVertex(i); + player.addTexCoord(ofVec2f(v.x,v.y)); + } + + colorImg.getTextureReference().bind(); + player.draw(); + colorImg.getTextureReference().unbind(); + } + } + + break; case CALIBRATE: ofFill(); @@ -167,7 +254,7 @@ void testApp::draw(){ //keep running background average- how do you use a custom background ofSetHexColor(0xffffff); colorImg.draw(0,0,ofGetWidth(),ofGetHeight()); - + ofPushMatrix(); ofRotate(cam_angle,1,0,0); for (float i=0;i<=ofGetWidth();i+=ofGetWidth()/10) { @@ -180,8 +267,17 @@ void testApp::draw(){ glVertex3f(ofGetWidth(),i,0); glEnd(); } + + ofVec2f pp=screen2plane(pos); + ofSphere(pp.x,pp.y,0,5); + ofPopMatrix(); + + ofPushMatrix(); + ofRotate(cam_angle,1,0,0); + trapDoor.draw(); ofPopMatrix(); + vector<ofVec3f> newPlayers; float movethresh=10; for (int i = 0; i < contourFinder.nBlobs; i++){ @@ -201,7 +297,7 @@ void testApp::draw(){ ofDrawBitmapString(numStr, r.x, r.y); ofVec3f pp; ray=projector.castPixel(blobBase.x,blobBase.y); //(ofGetHeight()-y)); - bool hit = plane.intersect(ray,pp); + bool hit = plane.intersect(ray,pp); for (int i=0;i<players.size();i++) { if (abs(players[i].x-pp.x)<10&&abs(players[i].z-pp.z)) { //identified a player @@ -209,23 +305,25 @@ void testApp::draw(){ //how to get UV coords on the plane //maybe rotate the camera instead of the plane + //for the bird interaction, need to get player coords in the ground axis. + //for the door interaction, need to build player outline in the screen axis + + //for the door, first determine if the boundings cross - create overlay + //if the base centre is in the hole- trigger falling behaviour + } } ofPushMatrix(); ofTranslate(pp); ofRotate(cam_angle,1,0,0); ofBox(0,-10,0,20); - //for now, draw in this axis + //TODO get this into plane axis ofPopMatrix(); + + // } - - trapDoor.checkUpdate(players); - ofPushMatrix(); - ofRotate(cam_angle,1,0,0); - trapDoor.draw(); - ofPopMatrix(); - - + + // finally, a report: ofSetHexColor(0xffffff); @@ -297,7 +395,8 @@ void testApp::mouseReleased(int x, int y, int button){ pos=ofVec2f(x,y); //if (hit) printf("ray:%i,%i hit plane:%f,%f,%f\n",x,y,pos.x,pos.y,pos.z); //else printf("ray:%i,%i missed plane\n",x,y); - + trapDoor.startPos(screen2plane(pos)); + updatePlane(); } //-------------------------------------------------------------- diff --git a/gaunt01/src/testApp.h b/gaunt01/src/testApp.h index 2870008..e829630 100644 --- a/gaunt01/src/testApp.h +++ b/gaunt01/src/testApp.h @@ -6,6 +6,7 @@ #include "ofxRay.h" #include "ofxXmlSettings.h" +#include "ofxBlobsManager.h" #include "trapdoor.h" @@ -35,9 +36,11 @@ class testApp : public ofBaseApp{ int mode; + //utility functions ofVec2f screen2plane(ofVec2f screenpos); ofVec3f plane2world(ofVec2f planepos); void updatePlane(); + bool rectsCross(ofRectangle rect1,ofRectangle rect2); ofxXmlSettings XML; void loadSettings(string filename); @@ -55,6 +58,8 @@ class testApp : public ofBaseApp{ ofxCvGrayscaleImage grayDiff; ofxCvContourFinder contourFinder; + + ofxBlobsManager blobsManager; int threshold; bool bLearnBakground; @@ -72,6 +77,12 @@ class testApp : public ofBaseApp{ vector<ofVec3f> players; trapdoor trapDoor; ofMesh ground; + + ofVec3f* testpts; + + ofTessellator tesselator; + ofMesh player; + ofPolyline playeroutline; }; diff --git a/gaunt01/src/trapdoor.cpp b/gaunt01/src/trapdoor.cpp index ce06b4a..d1f436e 100644 --- a/gaunt01/src/trapdoor.cpp +++ b/gaunt01/src/trapdoor.cpp @@ -5,46 +5,64 @@ trapdoor::trapdoor(ofVec2f _boundTR,ofVec2f _boundBR,ofVec2f _doorSize) surround=morphmesh("trapdoor-surround.xml"); lid=morphmesh("trapdoor-lid.xml"); if (!surround.isLoaded()||!lid.isLoaded()) printf("problem loading trap door mesh.\n"); - + texture.loadImage("TextureTrapdoor.jpg"); - + + sounds=new ofSoundPlayer[4]; + sounds[0].loadSound("creeky door short1.wav"); + sounds[1].loadSound("creeky door short2.wav"); + sounds[2].loadSound("creeky door short3.wav"); + sounds[3].loadSound("voice falling down hole.wav"); + boundTR=_boundTR; boundBR=_boundBR; - - printf("trapdoor bounds: %f,%f - %f,%f\n",boundTR.x,boundTR.y,boundBR.x,boundBR.y); - + size=_doorSize; start(); } -trapdoor::~trapdoor() {} - +trapdoor::~trapdoor() { + } + void trapdoor::start(){ //place trapdoor within bounds float u=ofRandom(-0.9,0.9); //(-1 to 1) float v=ofRandom(0.05,0.95); float mx=ofGetWidth()/2; - + float x=mx+((boundTR.x-mx)*u*(1-v))+((boundBR.x-mx)*u*v); float y=boundTR.y+((boundBR.y-boundTR.y)*v); - printf("new trapdoor: %f,%f\n",x,y); - position=ofVec2f(x,y); + startPos(ofVec2f(x,y)); +} + +void trapdoor::startPos(ofVec2f pos){ + position=pos; startTime=ofGetElapsedTimef(); doorAngle=0; doorSpeed=0; + opening=false; + //for (int i=0;i<4;i++) sounds[i].stop(); + } vector<ofVec2f> trapdoor::getCorners(){ vector<ofVec2f> corners; - corners.push_back(ofVec2f(-size.x/2,-size.y/2)); - corners.push_back(ofVec2f(size.x/2,-size.y/2)); - corners.push_back(ofVec2f(size.x/2,size.y/2)); - corners.push_back(ofVec2f(-size.x/2,size.y/2)); + corners.push_back(ofVec2f(position.x-(size.x/2),position.y-(size.y/2))); + corners.push_back(ofVec2f(position.x+(size.x/2),position.y-(size.y/2))); + corners.push_back(ofVec2f(position.x+(size.x/2),position.y+(size.y/2))); + corners.push_back(ofVec2f(position.x-(size.x/2),position.y+(size.y/2))); return corners; } +void trapdoor::setBoundingRect(float x,float y, float width,float height){ + boundingRect=ofRectangle(x,y,width,height); +} +ofRectangle trapdoor::getBoundingRect(){ + return boundingRect; +} + ofVec2f trapdoor::bounds2UV(ofVec2f point){ //returns the 0-1 UV coords of a point on the ground plane relative to its bounds. float v=(point.y-boundTR.y)/(boundBR.y-boundTR.y); @@ -52,26 +70,37 @@ ofVec2f trapdoor::bounds2UV(ofVec2f point){ float u=((point.x-mx)/(((boundTR.x-mx)*(1-v))+((boundBR.x-mx)*v)))+0.5; return ofVec2f(u,v); } - -void trapdoor::checkUpdate(const vector<ofVec3f>& players) { + +bool trapdoor::checkUpdate(const vector<ofVec3f>& players) { float segTime=(ofGetElapsedTimef()-startTime); - if (segTime>5) start(); if (segTime>3) { doorSpeed=(doorSpeed+((cos(doorAngle*0.0174532925)/ofGetFrameRate())*50))*0.95; doorAngle-=doorSpeed; + if (!opening) { + int whichsound=(int)ofRandom(2.9999999); + sounds[whichsound].play(); + //sound.play(); + opening=true; + } + } + if (segTime>6) { + start(); + return true; } + else return false; } - + void trapdoor::draw() { glEnable(GL_DEPTH_TEST); ofSetHexColor(0xffffff); bindTexture(texture); ofPushMatrix(); - ofRotate(90,-1,0,0); - ofTranslate(ofVec3f(position.x,0,position.y)); + //ofRotate(90,-1,0,0); + ofTranslate(ofVec3f(position.x,position.y,0)); //ofRotate(180,-1,0,0); //for now size =40x40 - ofScale(.1,.1,.1); + ofRotate(90,-1,0,0); + ofScale(.15,.15,.15); surround.draw(); ofPushMatrix(); ofTranslate(90,0,0); diff --git a/gaunt01/src/trapdoor.h b/gaunt01/src/trapdoor.h index b1318b3..5975498 100644 --- a/gaunt01/src/trapdoor.h +++ b/gaunt01/src/trapdoor.h @@ -19,35 +19,43 @@ class trapdoor public: trapdoor(ofVec2f _boundTR=ofVec2f(0,0),ofVec2f _boundBR=ofVec2f(0,0),ofVec2f _doorSize=ofVec2f(10,10)); virtual ~trapdoor(); - - void checkUpdate(const vector<ofVec3f>& players); + + bool checkUpdate(const vector<ofVec3f>& players); void draw(); void start(); - + void startPos(ofVec2f pos); + vector<ofVec2f> getCorners(); ofVec2f bounds2UV(ofVec2f pt); - + + void setBoundingRect(float x,float y, float width,float height); + ofRectangle getBoundingRect(); + protected: private: morphmesh surround; morphmesh lid; - + ofVec2f position; ofVec2f boundTR; ofVec2f boundBR; ofVec2f size; - + float startTime; float triggerTime; //time threshold - + ofRectangle boundingRect; ofVec2f doorSize; - + float doorAngle; float doorSpeed; - + ofImage texture; - + + ofSoundPlayer* sounds; + + bool opening; + }; #endif // TRAPDOOR_H |
