summaryrefslogtreecommitdiff
path: root/gaunt01/src
diff options
context:
space:
mode:
Diffstat (limited to 'gaunt01/src')
-rw-r--r--gaunt01/src/morphmesh.cpp133
-rw-r--r--gaunt01/src/morphmesh.h42
-rw-r--r--gaunt01/src/normBindTexture.cpp52
-rw-r--r--gaunt01/src/normBindTexture.h11
-rw-r--r--gaunt01/src/testApp.cpp150
-rw-r--r--gaunt01/src/testApp.h19
-rw-r--r--gaunt01/src/trapdoor.cpp48
-rw-r--r--gaunt01/src/trapdoor.h46
8 files changed, 454 insertions, 47 deletions
diff --git a/gaunt01/src/morphmesh.cpp b/gaunt01/src/morphmesh.cpp
new file mode 100644
index 0000000..64bc24e
--- /dev/null
+++ b/gaunt01/src/morphmesh.cpp
@@ -0,0 +1,133 @@
+#include "morphmesh.h"
+
+morphmesh::morphmesh()
+{
+ loaded=false;
+}
+
+morphmesh::morphmesh(string filename)
+{
+ morphmesh();
+ loadfile(filename);
+}
+
+morphmesh::~morphmesh()
+{
+ //dtor
+}
+
+int morphmesh::getNumTargets(){
+ return morphs.size();
+}
+void morphmesh::draw() {
+ draw(0);
+}
+void morphmesh::draw(int target){
+ clearVertices();
+ addVertices(morphs[target]);
+ ofMesh::draw();
+}
+void morphmesh::draw(const vector<int>& targets, const vector<float>& weights){
+ clearVertices();
+ //normalise weights
+ int targetsNum=min(targets.size(),morphs.size());
+ float totalWeights=0;
+ for (int i=0;i<targetsNum;i++) totalWeights+=weights[i];
+ float weightFactor=1.0/totalWeights;
+ float bx,by,bz;
+ for (int j=0;j<morphs[0].size();j++) {
+ bx=by=bz=0;
+ for (int i=0;i<targetsNum;i++) {
+ bx+=morphs[targets[i]][j].x*weights[i];
+ by+=morphs[targets[i]][j].y*weights[i];
+ bz+=morphs[targets[i]][j].z*weights[i];
+ }
+ addVertex(ofVec3f(bx*weightFactor,by*weightFactor,bz*weightFactor));
+ }
+ ofMesh::draw();
+}
+
+bool morphmesh::loadfile(string filename){
+ loaded=false;
+ ofxXmlSettings XML;
+ if( !XML.loadFile(filename) ){
+ printf("unable to load %s check data/ folder\n",filename.c_str());
+ }else{
+ if(XML.pushTag("Oak3DModelDocument")) {
+ if(XML.pushTag("MeshList")) {
+ int numMeshes=XML.getNumTags("Mesh");
+ for (int i=0;i<numMeshes;i++) {
+ XML.pushTag("Mesh",i);
+ if (XML.pushTag("AttributeList")) {
+ vector<ofVec3f> verts;
+
+ string vertstring=XML.getAttribute("Attribute","Data","none",0);
+ stringstream ss(vertstring);
+ istream_iterator<string> begin(ss);
+ istream_iterator<string> end;
+ vector<string> vstrings(begin, end);
+ for (int j=0;j<vstrings.size();j+=3) {
+ verts.push_back(ofVec3f(ofToFloat(vstrings[j]),ofToFloat(vstrings[j+1]),ofToFloat(vstrings[j+2])));
+ }
+ morphs.push_back(verts);
+
+ if (i==0) {
+ addVertices(verts);
+
+ vector<ofVec3f> norms;
+ string normstring=XML.getAttribute("Attribute","Data","none",1);
+ stringstream ns(normstring);
+ istream_iterator<string> nbegin(ns);
+ istream_iterator<string> nend;
+ vector<string> nstrings(nbegin, nend);
+ for (int j=0;j<nstrings.size();j+=3) {
+ norms.push_back(ofVec3f(ofToFloat(nstrings[j]),ofToFloat(nstrings[j+1]),ofToFloat(nstrings[j+2])));
+ }
+ addNormals(norms);
+
+ vector<ofVec2f> texcords;
+ string texstring=XML.getAttribute("Attribute","Data","none",2);
+ stringstream ts(texstring);
+ istream_iterator<string> tbegin(ts);
+ istream_iterator<string> tend;
+ vector<string> tstrings(tbegin, tend);
+ for (int j=0;j<tstrings.size();j+=2) {
+ texcords.push_back(ofVec2f(ofToFloat(tstrings[j]),ofToFloat(tstrings[j+1])));
+ }
+ addTexCoords(texcords);
+
+ XML.popTag();
+
+ if (XML.pushTag("IndexList")) {
+ vector<ofIndexType> faces;
+ string facestring=XML.getAttribute("Index","Data","none",0);
+ stringstream fs(facestring);
+ istream_iterator<string> fbegin(fs);
+ istream_iterator<string> fend;
+ vector<string> fstrings(fbegin, fend);
+ for (int j=0;j<fstrings.size();j+=3) {
+ faces.push_back(ofIndexType(ofToInt(fstrings[j])));
+ faces.push_back(ofIndexType(ofToInt(fstrings[j+1])));
+ faces.push_back(ofIndexType(ofToInt(fstrings[j+2])));
+ }
+ addIndices(faces);
+ loaded=true;
+ XML.popTag();
+ }
+ }
+ else XML.popTag();
+ }
+ XML.popTag();
+ }
+ }
+ XML.popTag();
+ }
+ XML.popTag();
+ }
+ return loaded;
+}
+
+bool morphmesh::isLoaded()
+{
+ return loaded;
+} \ No newline at end of file
diff --git a/gaunt01/src/morphmesh.h b/gaunt01/src/morphmesh.h
new file mode 100644
index 0000000..91a8f17
--- /dev/null
+++ b/gaunt01/src/morphmesh.h
@@ -0,0 +1,42 @@
+#ifndef MORPHMESH_H
+#define MORPHMESH_H
+
+#include <iostream>
+#include <iterator>
+
+#include <ofMesh.h>
+#include <ofxXmlSettings.h>
+
+/*
+Tim Redfern, March 2012
+
+Loads meshes in Oak3D XML format
+
+Draws blended morph targets
+
+Multiple meshes are loaded as morph targets
+
+Coords are absolute
+
+*/
+
+
+class morphmesh : public ofMesh
+{
+ public:
+ morphmesh();
+ morphmesh(string filename);
+ virtual ~morphmesh();
+ bool loadfile(string filename);
+ bool isLoaded();
+ void draw();
+ void draw(int target);
+ void draw(const vector<int>& targets, const vector<float>& weights);
+ int getNumTargets();
+ protected:
+ private:
+ vector< vector<ofVec3f> > morphs;
+ bool loaded;
+};
+
+#endif // MORPHMESH_H
diff --git a/gaunt01/src/normBindTexture.cpp b/gaunt01/src/normBindTexture.cpp
new file mode 100644
index 0000000..68c17c9
--- /dev/null
+++ b/gaunt01/src/normBindTexture.cpp
@@ -0,0 +1,52 @@
+#include "normBindTexture.h"
+
+#include "ofMain.h"
+
+//texture binding with normalised coords
+void bindTexture(ofBaseHasTexture &t) {
+ ofTexture &tex = t.getTextureReference();
+ tex.bind();
+
+ glMatrixMode(GL_TEXTURE);
+ glPushMatrix();
+ glLoadIdentity();
+
+ ofTextureData texData = tex.getTextureData();
+ if(texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB) {
+ glScalef(tex.getWidth(), tex.getHeight(), 1.0f);
+ } else {
+ glScalef(tex.getWidth() / texData.tex_w, tex.getHeight() / texData.tex_h, 1.0f);
+ }
+
+ glMatrixMode(GL_MODELVIEW);
+}
+void unbindTexture(ofBaseHasTexture &t) {
+ t.getTextureReference().unbind();
+
+ glMatrixMode(GL_TEXTURE);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+}
+void bindTex(ofTexture &tex) {
+ tex.bind();
+
+ glMatrixMode(GL_TEXTURE);
+ glPushMatrix();
+ glLoadIdentity();
+
+ ofTextureData texData = tex.getTextureData();
+ if(texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB) {
+ glScalef(tex.getWidth(), tex.getHeight(), 1.0f);
+ } else {
+ glScalef(tex.getWidth() / texData.tex_w, tex.getHeight() / texData.tex_h, 1.0f);
+ }
+
+ glMatrixMode(GL_MODELVIEW);
+}
+void unbindTex(ofTexture &tex) {
+ tex.unbind();
+
+ glMatrixMode(GL_TEXTURE);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+}
diff --git a/gaunt01/src/normBindTexture.h b/gaunt01/src/normBindTexture.h
new file mode 100644
index 0000000..f2bcb71
--- /dev/null
+++ b/gaunt01/src/normBindTexture.h
@@ -0,0 +1,11 @@
+#ifndef NORMBINDTEXTURE_H
+#define NORMBINDTEXTURE_H
+
+#include "ofMain.h"
+
+void bindTexture(ofBaseHasTexture &t);
+void unbindTexture(ofBaseHasTexture &t);
+void bindTex(ofTexture &tex);
+void unbindTex(ofTexture &tex);
+
+#endif // NORMBINDTEXTURE_H
diff --git a/gaunt01/src/testApp.cpp b/gaunt01/src/testApp.cpp
index 00658b4..1ab413b 100644
--- a/gaunt01/src/testApp.cpp
+++ b/gaunt01/src/testApp.cpp
@@ -1,23 +1,28 @@
#include "testApp.h"
//--------------------------------------------------------------
+//units ~ 10cm
+//
void testApp::setup(){
+
+ bLearnBakground = true;
+ cam_angle=0;
+ threshold = 80;
+
+ loadSettings("settings.xml");
#ifdef _USE_LIVE_VIDEO
vidGrabber.setVerbose(true);
vidGrabber.initGrabber(320,240);
#else
- vidPlayer.loadMovie("camoutput.mov");
+ vidPlayer.loadMovie("camoutput.wmv"); //footage/ camera needs to be the same res as opencv planes and output
vidPlayer.play();
#endif
- colorImg.allocate(320,240);
- grayImage.allocate(320,240);
- grayBg.allocate(320,240);
- grayDiff.allocate(320,240);
-
- bLearnBakground = true;
- threshold = 80;
+ colorImg.allocate(640,480);
+ grayImage.allocate(640,480);
+ grayBg.allocate(640,480);
+ grayDiff.allocate(640,480);
ofVec3f centre=ofVec3f(ofGetWidth()/2,0,0);
ofVec3f normal=ofVec3f(0,0,-1);
@@ -25,16 +30,17 @@ void testApp::setup(){
plane=ofPlane(centre,normal);
plane.color=ofColor(255,255,255);
- projector=ofProjector(1.535f, ofVec2f(0.0f, 0.5f),ofGetWidth(),ofGetHeight());
- projector.setPosition(ofGetWidth()/2,ofGetHeight()/2,ofGetHeight());
+ projector=ofProjector(2.0f, ofVec2f(0.0f, 0.0f),ofGetWidth(),ofGetHeight()); //1.535f
+ projector.setPosition(ofGetWidth()/2,ofGetHeight()/2,-ofGetWidth());
+ projector.lookAt(ofVec3f(ofGetWidth()/2,ofGetHeight()/2,0),ofVec3f(0, -1, 0));
cam=ofCamera();
- cam.setPosition(ofGetWidth()/2,ofGetHeight()/2,ofGetHeight());
- cam.lookAt(ofVec3f(ofGetWidth()/2,ofGetHeight()/2,0));
- cam.setFov(54.13);
-
- cam_angle=0;
-
+ cam.setPosition(ofGetWidth()/2,ofGetHeight()/2,-ofGetWidth());
+ cam.lookAt(ofVec3f(ofGetWidth()/2,ofGetHeight()/2,0),ofVec3f(0, -1, 0));
+ cam.setFov(42.0); //39.85); //53.13);
+
+ trapDoor=trapdoor(ofRectangle(0,0,ofGetWidth(),ofGetHeight()),ofVec2f(20,20));
+
}
//--------------------------------------------------------------
@@ -56,7 +62,7 @@ void testApp::update(){
#ifdef _USE_LIVE_VIDEO
colorImg.setFromPixels(vidGrabber.getPixels(), 320,240);
#else
- colorImg.setFromPixels(vidPlayer.getPixels(), 320,240);
+ colorImg.setFromPixels(vidPlayer.getPixels(), 640,480);
#endif
grayImage = colorImg;
@@ -71,7 +77,9 @@ 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....
- contourFinder.findContours(grayDiff, 20, (340*240)/3, 10, false); // don't find holes
+
+ //hard coded size threshold of 100 pix
+ contourFinder.findContours(grayDiff, 200, (640*480)/3, 20, false); // don't find holes
}
}
@@ -96,6 +104,8 @@ void testApp::draw(){
// we could draw the whole contour finder
//contourFinder.draw(360,540);
+
+ //keep running background average- how do you use a custom background
colorImg.draw(0,0,ofGetWidth(),ofGetHeight());
@@ -117,27 +127,65 @@ void testApp::draw(){
}
ofPopMatrix();
- cam.end();
-
- ofSphere(pos.x,pos.y,pos.z,5);
-
- for (int i = 0; i < contourFinder.nBlobs; i++){
+
+
+ //ofSphere(pos.x,pos.y,pos.z,5);
+
+ vector<ofVec3f> newPlayers;
+ float movethresh=10;
+
+ for (int i = 0; i < contourFinder.nBlobs; i++){
+ //do some bounds checking, size threshold and overlap removal
+ //in order to translate blobs into players
+ //attempt to track players - maintain ID no
+ //attempt to base blobs
+ //TODO attempt to estimate bounds shape
+ //project all of this into the 3D space
+ ofRectangle r=contourFinder.blobs[i].boundingRect;
+
+ ofVec2f blobBase=ofVec2f(r.x+(r.width/2),r.y+r.height-(r.width/2));
+
contourFinder.blobs[i].draw(0,0);
-
ofPoint p=contourFinder.blobs[i].centroid;
- ofVec3f pp;
- cam.begin();
- ofPushMatrix();
-
- ofRotate(cam_angle,1,0,0);
- ray=projector.castPixel(p.x,(ofGetHeight()/2)-p.y); //(ofGetHeight()-y));
- bool hit = plane.intersect(ray,pp);
- ofBox(pp,50);
- ofPopMatrix();
- cam.end();
+ ofSetHexColor(0xffff00);
+
+ char numStr[16];
+ sprintf(numStr, "%i", i);
+ ofDrawBitmapString(numStr, r.x, r.y);
+
+ ofVec3f pp;
+ ray=projector.castPixel(blobBase.x,blobBase.y); //(ofGetHeight()-y));
+ 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
+ //this is flawed: tracking boxes in a skewed axis
+ //how to get UV coords on the plane
+ //maybe rotate the camera instead of the plane
+
+ }
+ }
+
+ ofPushMatrix();
+ ofTranslate(pp);
+ ofRotate(cam_angle,1,0,0);
+ ofBox(0,-10,0,20);
+ //for now, draw in this axis
+ ofPopMatrix();
- }
+ }
+
+ trapDoor.checkUpdate(players);
+ ofPushMatrix();
+ ofRotate(cam_angle,1,0,0);
+ //for now, draw in this axis
+ trapDoor.draw();
+ ofPopMatrix();
+
+ cam.end();
@@ -146,10 +194,7 @@ void testApp::draw(){
ofSetHexColor(0xffffff);
char reportStr[1024];
sprintf(reportStr, "threshold %i\nnum blobs found %i, fps: %f", threshold, contourFinder.nBlobs, ofGetFrameRate());
- ofDrawBitmapString(reportStr, 10, 215);
-
-
-
+ ofDrawBitmapString(reportStr, 10, ofGetHeight()-40);
}
//--------------------------------------------------------------
@@ -167,12 +212,15 @@ void testApp::keyPressed(int key){
threshold --;
if (threshold < 0) threshold = 0;
break;
- case 'a':
+ case 'a':
cam_angle+=1;
break;
- case 'z':
+ case 'z':
cam_angle-=1;
break;
+ case 's':
+ saveSettings("settings.xml");
+ break;
}
plane.setNormal(ofVec3f(0,sin(cam_angle*0.01745329),-cos(cam_angle*0.01745329)));
}
@@ -199,13 +247,12 @@ void testApp::mousePressed(int x, int y, int button){
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
- ray=projector.castPixel(x,((3*(ofGetHeight()/2))-y)); //(ofGetHeight()-y));
+ ray=projector.castPixel(x,y); //+(ofGetHeight()/2)); //(ofGetHeight()-y));
bool hit = plane.intersect(ray,pos);
//pos=ofVec3f(pos.x*2,pos.y*2,pos.z*2);
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);
-
}
//--------------------------------------------------------------
@@ -222,3 +269,20 @@ void testApp::gotMessage(ofMessage msg){
void testApp::dragEvent(ofDragInfo dragInfo){
}
+
+void testApp::loadSettings(string filename){
+ if( !XML.loadFile(filename) ){
+ printf("unable to load %s check data/ folder\n",filename.c_str());
+ }else{
+ cam_angle=ofToInt(XML.getAttribute("gauntlet","cam_angle","none",0));
+ threshold=ofToInt(XML.getAttribute("gauntlet","threshold","none",0));
+ printf("loaded %s\n",filename.c_str());
+ }
+}
+//--------------------------------------------------------------
+void testApp::saveSettings(string filename){
+ XML.setAttribute("gauntlet","cam_angle",ofToString(cam_angle),0);
+ XML.setAttribute("gauntlet","threshold",ofToString(threshold),0);
+ XML.saveFile(filename);
+ printf("saved %s\n",filename.c_str());
+}
diff --git a/gaunt01/src/testApp.h b/gaunt01/src/testApp.h
index de13eae..b08682c 100644
--- a/gaunt01/src/testApp.h
+++ b/gaunt01/src/testApp.h
@@ -5,6 +5,10 @@
#include "ofxOpenCv.h"
#include "ofxRay.h"
+#include "ofxXmlSettings.h"
+
+#include "trapdoor.h"
+
//#define _USE_LIVE_VIDEO // uncomment this to use a live camera
// otherwise, we'll use a movie file
@@ -24,20 +28,24 @@ class testApp : public ofBaseApp{
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
+
+ ofxXmlSettings XML;
+ void loadSettings(string filename);
+ void saveSettings(string filename);
- #ifdef _USE_LIVE_VIDEO
+ #ifdef _USE_LIVE_VIDEO
ofVideoGrabber vidGrabber;
#else
ofVideoPlayer vidPlayer;
#endif
- ofxCvColorImage colorImg;
+ ofxCvColorImage colorImg;
- ofxCvGrayscaleImage grayImage;
+ ofxCvGrayscaleImage grayImage;
ofxCvGrayscaleImage grayBg;
ofxCvGrayscaleImage grayDiff;
- ofxCvContourFinder contourFinder;
+ ofxCvContourFinder contourFinder;
int threshold;
bool bLearnBakground;
@@ -51,6 +59,9 @@ class testApp : public ofBaseApp{
ofProjector projector;
ofVec3f pos;
+
+ vector<ofVec3f> players;
+ trapdoor trapDoor;
};
diff --git a/gaunt01/src/trapdoor.cpp b/gaunt01/src/trapdoor.cpp
new file mode 100644
index 0000000..b53e30b
--- /dev/null
+++ b/gaunt01/src/trapdoor.cpp
@@ -0,0 +1,48 @@
+#include "trapdoor.h"
+
+trapdoor::trapdoor(ofRectangle _boundingRect,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");
+
+ boundingRect=_boundingRect;
+ doorSize=_doorSize;
+
+ start();
+}
+
+trapdoor::~trapdoor() {}
+
+void trapdoor::start(){
+ position=ofVec2f(boundingRect.x+ofRandom(boundingRect.width),boundingRect.y+ofRandom(boundingRect.height));
+ startTime=ofGetElapsedTimef();
+}
+
+void trapdoor::checkUpdate(const vector<ofVec3f>& players) {
+ if ((ofGetElapsedTimef()-startTime)>5) start();
+}
+
+void trapdoor::draw() {
+ bindTexture(texture);
+ ofPushMatrix();
+ ofTranslate(position.x,0,position.y);
+ //for now size =40x40
+ ofScale(.2,.2,.2);
+ surround.draw();
+ ofPushMatrix();
+ ofTranslate(-90,0,0);
+ ofRotate(doorAngle,1,0,0);
+ lid.draw();
+ ofPopMatrix();
+ ofPushMatrix();
+ ofTranslate(90,0,0);
+ ofRotate(180,0,1,0);
+ ofRotate(doorAngle,1,0,0);
+ lid.draw();
+ ofPopMatrix();
+ ofPopMatrix();
+ unbindTexture(texture);
+}
diff --git a/gaunt01/src/trapdoor.h b/gaunt01/src/trapdoor.h
new file mode 100644
index 0000000..16ad3b1
--- /dev/null
+++ b/gaunt01/src/trapdoor.h
@@ -0,0 +1,46 @@
+#ifndef TRAPDOOR_H
+#define TRAPDOOR_H
+
+#include "ofMain.h"
+#include "morphmesh.h"
+#include "normBindTexture.h"
+
+/*
+const vector<ofxCvBlob>& blobs
+
+receive vector of player positions
+needs to 'debounce' - time threshold for activation
+
+creaking sound player
+*/
+
+class trapdoor
+{
+ public:
+ trapdoor(ofRectangle boundingRect=ofRectangle(0,0,100,100),ofVec2f _doorSize=ofVec2f(10,10));
+ virtual ~trapdoor();
+
+ void checkUpdate(const vector<ofVec3f>& players);
+ void draw();
+ void start();
+
+ protected:
+ private:
+ morphmesh surround;
+ morphmesh lid;
+
+ ofVec2f position;
+
+ float startTime;
+ float triggerTime; //time threshold
+
+ ofRectangle boundingRect;
+ ofVec2f doorSize;
+
+ float doorAngle;
+
+ ofImage texture;
+
+};
+
+#endif // TRAPDOOR_H