summaryrefslogtreecommitdiff
path: root/gaunt01/src
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2012-04-05 14:00:51 +0100
committerTim Redfern <tim@eclectronics.org>2012-04-05 14:00:51 +0100
commitf65006daf4979d82d67fd8c8a234d3913088821d (patch)
tree104d30c316ca295cd4bad1110c7f341640112738 /gaunt01/src
parent0c2a97dcc0fb370938dc0d2d3a27053c2c9cb31e (diff)
starting to implement bird
Diffstat (limited to 'gaunt01/src')
-rw-r--r--gaunt01/src/bird.cpp42
-rw-r--r--gaunt01/src/bird.h57
-rw-r--r--gaunt01/src/morphmesh.cpp20
-rw-r--r--gaunt01/src/morphmesh.h13
-rw-r--r--gaunt01/src/testApp.cpp72
-rw-r--r--gaunt01/src/testApp.h17
-rw-r--r--gaunt01/src/trapdoor.cpp16
-rw-r--r--gaunt01/src/trapdoor.h3
8 files changed, 185 insertions, 55 deletions
diff --git a/gaunt01/src/bird.cpp b/gaunt01/src/bird.cpp
new file mode 100644
index 0000000..204bf6e
--- /dev/null
+++ b/gaunt01/src/bird.cpp
@@ -0,0 +1,42 @@
+#include "bird.h"
+
+bird::bird()
+{
+ model.loadMesh("Bird-test.xml");
+ texture.loadImage("TextureBird.jpg");
+
+ //starting pos
+ position=ofVec3f(ofGetWidth()/2,ofGetHeight()/3,ofGetHeight()/2);
+ heading=ofVec3f(-1,0,0);
+ direction=ofVec3f(-1,0,0);
+ velocity=ofGetWidth()/100;
+
+ turnAngle=0;
+ diveAngle=0;
+
+ lastTime=ofGetElapsedTimef();
+}
+
+bird::~bird()
+{
+ //dtor
+}
+
+void bird::update(const vector<ofVec3f>& players){
+ float time=ofGetElapsedTimef();
+ float timeSeg=time-lastTime;
+ lastTime=time;
+ position+=direction*velocity*timeSeg;
+}
+void bird::draw(){
+ ofPushMatrix();
+ ofTranslate(position);
+ //ofRotate(direction);
+ ofRotate(90,0,-1,0);
+ //ofRotate(180,1,0,0);
+ bindTexture(texture);
+ model.draw();
+ unbindTexture(texture);
+ ofPopMatrix();
+}
+
diff --git a/gaunt01/src/bird.h b/gaunt01/src/bird.h
new file mode 100644
index 0000000..4114ad3
--- /dev/null
+++ b/gaunt01/src/bird.h
@@ -0,0 +1,57 @@
+#ifndef BIRD_H
+#define BIRD_H
+
+/*
+ Hostile bird character for 'Run the gauntlet' game
+
+ Tim Redfern April 2012
+
+ ??how to manage visibility
+ Bird should automatically stay within viewing volume of camera
+
+ from the birds POV, The visible area is a frustrum extending down from the camera
+
+ 1) like opensteer, extend the birds heading and decide whether this will hit the edge
+ 2) have an actual model of the volume and work within it
+
+ 3) how do we make the bird aware of players in front of it
+
+ --> this all implies being able to take a sightline from the bird and determine
+ -visibility of objects
+ -distance to obstructions
+
+ -build basic of time/speed/heading update/draw
+ -basic anim cycle
+
+*/
+
+#include "ofMain.h"
+#include "morphmesh.h"
+#include "normBindTexture.h"
+
+
+class bird
+{
+ public:
+ bird();
+ virtual ~bird();
+ void update(const vector<ofVec3f>& players);
+ void draw();
+ protected:
+ private:
+
+ ofVec3f position;
+ ofVec3f heading;
+ ofVec3f direction;
+
+ float velocity; //per second
+ float turnAngle; //per second
+ float diveAngle; //per second
+
+ float lastTime;
+
+ morphmesh model;
+ ofImage texture;
+};
+
+#endif // BIRD_H
diff --git a/gaunt01/src/morphmesh.cpp b/gaunt01/src/morphmesh.cpp
index 64bc24e..475f93b 100644
--- a/gaunt01/src/morphmesh.cpp
+++ b/gaunt01/src/morphmesh.cpp
@@ -4,11 +4,11 @@ morphmesh::morphmesh()
{
loaded=false;
}
-
+
morphmesh::morphmesh(string filename)
{
morphmesh();
- loadfile(filename);
+ loadMesh(filename);
}
morphmesh::~morphmesh()
@@ -47,7 +47,7 @@ void morphmesh::draw(const vector<int>& targets, const vector<float>& weights){
ofMesh::draw();
}
-bool morphmesh::loadfile(string filename){
+bool morphmesh::loadMesh(string filename){
loaded=false;
ofxXmlSettings XML;
if( !XML.loadFile(filename) ){
@@ -60,7 +60,7 @@ bool morphmesh::loadfile(string filename){
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);
@@ -70,10 +70,10 @@ bool morphmesh::loadfile(string filename){
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);
@@ -84,7 +84,7 @@ bool morphmesh::loadfile(string filename){
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);
@@ -95,9 +95,9 @@ bool morphmesh::loadfile(string filename){
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);
@@ -130,4 +130,4 @@ bool morphmesh::loadfile(string filename){
bool morphmesh::isLoaded()
{
return loaded;
-} \ No newline at end of file
+}
diff --git a/gaunt01/src/morphmesh.h b/gaunt01/src/morphmesh.h
index 91a8f17..76a6063 100644
--- a/gaunt01/src/morphmesh.h
+++ b/gaunt01/src/morphmesh.h
@@ -21,13 +21,24 @@ Coords are absolute
*/
+class sequence
+{
+ //stores a morph sequence: an animation cycle or transition
+ public:
+ sequence();
+ virtual ~sequence();
+
+
+};
+
+
class morphmesh : public ofMesh
{
public:
morphmesh();
morphmesh(string filename);
virtual ~morphmesh();
- bool loadfile(string filename);
+ bool loadMesh(string filename);
bool isLoaded();
void draw();
void draw(int target);
diff --git a/gaunt01/src/testApp.cpp b/gaunt01/src/testApp.cpp
index aebbe0b..172190f 100644
--- a/gaunt01/src/testApp.cpp
+++ b/gaunt01/src/testApp.cpp
@@ -30,11 +30,11 @@ void testApp::setup(){
grayImage.allocate(640,480);
grayBg.allocate(640,480);
grayDiff.allocate(640,480);
-
+
blobsManager.normalizePercentage = 0.7;
- blobsManager.giveLowestPossibleIDs = true;
+ blobsManager.giveLowestPossibleIDs = false;
blobsManager.maxUndetectedTime = 500;
- blobsManager.minDetectedTime = 2000;
+ blobsManager.minDetectedTime = 500;
blobsManager.debugDrawCandidates = true;
ofVec3f centre=ofVec3f(ofGetWidth()/2,0,0);
@@ -54,12 +54,12 @@ void testApp::setup(){
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;
-
+
}
@@ -80,7 +80,7 @@ bool testApp::rectsCross(ofRectangle rect1,ofRectangle rect2) {
else if (rect2.x<rect1.x) {
if (rect2.x+rect2.width<rect1.x) overlap = false;
}
- if (overlap) { //still possible
+ if (overlap) { //still possible
if (rect1.y<rect2.y) {
if (rect1.y+rect1.height<rect2.y) overlap = false;
}
@@ -109,22 +109,22 @@ void testApp::updatePlane(){
ofVec2f screenCorners[4];
for (int i=0;i<corners.size();i++) {
-
+
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()));
}
@@ -142,7 +142,7 @@ void testApp::updatePlane(){
float h=max(screenCorners[2].y,screenCorners[3].y)-y;
trapDoor.setBoundingRect(x,y,w,h);
-
+
}
@@ -182,7 +182,7 @@ void testApp::update(){
//hard coded size threshold of 100 pix
contourFinder.findContours(grayDiff, 200, (640*480)/3, 20, false); // don't find holes
-
+
blobsManager.update(contourFinder.blobs);
}
@@ -214,11 +214,11 @@ void testApp::draw(){
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);
@@ -236,14 +236,27 @@ void testApp::draw(){
ofVec3f v=player.getVertex(i);
player.addTexCoord(ofVec2f(v.x,v.y));
}
-
+
+ //figure out if player has stood on trap door
+ //get screen basepoint
+ ofRectangle r=blob.boundingRect;
+ ofVec2f blobBase=ofVec2f(r.x+(r.width/2),r.y+r.height-(r.width/2));
+ if (trapDoor.getInnerRect().inside(blobBase.x,blobBase.y)) trapDoor.trigger();
+
colorImg.getTextureReference().bind();
- player.draw();
+ player.draw(); //trapdoor.getoffset());
colorImg.getTextureReference().unbind();
}
}
-
-
+
+ Bird.update(players);
+
+ ofPushMatrix();
+ ofRotate(cam_angle,1,0,0);
+ Bird.draw();
+ ofPopMatrix();
+
+
break;
case CALIBRATE:
ofFill();
@@ -271,7 +284,7 @@ void testApp::draw(){
ofVec2f pp=screen2plane(pos);
ofSphere(pp.x,pp.y,0,5);
ofPopMatrix();
-
+
ofPushMatrix();
ofRotate(cam_angle,1,0,0);
trapDoor.draw();
@@ -280,17 +293,12 @@ void testApp::draw(){
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;
+ for(int i=0;i<blobsManager.blobs.size();i++){
+ ofxCvBlob blob = blobsManager.blobs.at(i);
+ ofRectangle r=blob.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;
+ blob.draw(0,0);
+ ofPoint p=blob.centroid;
ofSetHexColor(0xffff00);
char numStr[16];
sprintf(numStr, "%i", i);
@@ -304,10 +312,10 @@ void testApp::draw(){
//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
-
+
//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
@@ -319,7 +327,7 @@ void testApp::draw(){
ofBox(0,-10,0,20);
//TODO get this into plane axis
ofPopMatrix();
-
+
//
}
diff --git a/gaunt01/src/testApp.h b/gaunt01/src/testApp.h
index e829630..9ee79db 100644
--- a/gaunt01/src/testApp.h
+++ b/gaunt01/src/testApp.h
@@ -9,6 +9,7 @@
#include "ofxBlobsManager.h"
#include "trapdoor.h"
+#include "bird.h"
//#define _USE_LIVE_VIDEO // uncomment this to use a live camera
// otherwise, we'll use a movie file
@@ -33,15 +34,15 @@ class testApp : public ofBaseApp{
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
-
+
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);
void saveSettings(string filename);
@@ -58,7 +59,7 @@ class testApp : public ofBaseApp{
ofxCvGrayscaleImage grayDiff;
ofxCvContourFinder contourFinder;
-
+
ofxBlobsManager blobsManager;
int threshold;
@@ -73,16 +74,18 @@ class testApp : public ofBaseApp{
ofProjector projector;
ofVec2f pos;
-
+
vector<ofVec3f> players;
trapdoor trapDoor;
ofMesh ground;
-
+
ofVec3f* testpts;
-
+
ofTessellator tesselator;
ofMesh player;
ofPolyline playeroutline;
+ bird Bird;
+
};
diff --git a/gaunt01/src/trapdoor.cpp b/gaunt01/src/trapdoor.cpp
index d1f436e..e1c37ec 100644
--- a/gaunt01/src/trapdoor.cpp
+++ b/gaunt01/src/trapdoor.cpp
@@ -2,7 +2,7 @@
trapdoor::trapdoor(ofVec2f _boundTR,ofVec2f _boundBR,ofVec2f _doorSize)
{
- surround=morphmesh("trapdoor-surround.xml");
+ surround=morphmesh("trapdoor-surround.xml");
lid=morphmesh("trapdoor-lid.xml");
if (!surround.isLoaded()||!lid.isLoaded()) printf("problem loading trap door mesh.\n");
@@ -33,7 +33,7 @@ void trapdoor::start(){
float x=mx+((boundTR.x-mx)*u*(1-v))+((boundBR.x-mx)*u*v);
float y=boundTR.y+((boundBR.y-boundTR.y)*v);
-
+
startPos(ofVec2f(x,y));
}
@@ -44,7 +44,7 @@ void trapdoor::startPos(ofVec2f pos){
doorSpeed=0;
opening=false;
//for (int i=0;i<4;i++) sounds[i].stop();
-
+
}
vector<ofVec2f> trapdoor::getCorners(){
@@ -62,6 +62,12 @@ void trapdoor::setBoundingRect(float x,float y, float width,float height){
ofRectangle trapdoor::getBoundingRect(){
return boundingRect;
}
+ofRectangle trapdoor::getInnerRect() {
+ return ofRectangle(boundingRect.x+(boundingRect.width/4),boundingRect.y+(boundingRect.height/4),boundingRect.width/2,boundingRect.height/2);
+}
+void trapdoor::trigger() {
+ startTime=ofGetElapsedTimef()-10;
+}
ofVec2f trapdoor::bounds2UV(ofVec2f point){
//returns the 0-1 UV coords of a point on the ground plane relative to its bounds.
@@ -73,7 +79,7 @@ ofVec2f trapdoor::bounds2UV(ofVec2f point){
bool trapdoor::checkUpdate(const vector<ofVec3f>& players) {
float segTime=(ofGetElapsedTimef()-startTime);
- if (segTime>3) {
+ if (segTime>10) {
doorSpeed=(doorSpeed+((cos(doorAngle*0.0174532925)/ofGetFrameRate())*50))*0.95;
doorAngle-=doorSpeed;
if (!opening) {
@@ -83,7 +89,7 @@ bool trapdoor::checkUpdate(const vector<ofVec3f>& players) {
opening=true;
}
}
- if (segTime>6) {
+ if (segTime>13) {
start();
return true;
}
diff --git a/gaunt01/src/trapdoor.h b/gaunt01/src/trapdoor.h
index 5975498..389e4ad 100644
--- a/gaunt01/src/trapdoor.h
+++ b/gaunt01/src/trapdoor.h
@@ -30,6 +30,9 @@ class trapdoor
void setBoundingRect(float x,float y, float width,float height);
ofRectangle getBoundingRect();
+ ofRectangle getInnerRect();
+ void trigger();
+ float getoffset();
protected:
private: