summaryrefslogtreecommitdiff
path: root/gaunt01
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2012-04-03 23:06:21 +0100
committerTim Redfern <tim@eclectronics.org>2012-04-03 23:06:21 +0100
commit0c2a97dcc0fb370938dc0d2d3a27053c2c9cb31e (patch)
tree1678420c09caa3ef73b4c45195b7da35cf31a363 /gaunt01
parent0363ee4f188c735a43c6624a2b10a191f74c3029 (diff)
blobs tesselated into textured polys
Diffstat (limited to 'gaunt01')
-rw-r--r--gaunt01/addons.make1
-rw-r--r--gaunt01/src/testApp.cpp189
-rw-r--r--gaunt01/src/testApp.h11
-rw-r--r--gaunt01/src/trapdoor.cpp71
-rw-r--r--gaunt01/src/trapdoor.h28
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