summaryrefslogtreecommitdiff
path: root/gaunt01/src
diff options
context:
space:
mode:
Diffstat (limited to 'gaunt01/src')
-rw-r--r--gaunt01/src/bird.cpp66
-rw-r--r--gaunt01/src/bird.h2
-rw-r--r--gaunt01/src/morphmesh.cpp186
-rw-r--r--gaunt01/src/morphmesh.h29
4 files changed, 226 insertions, 57 deletions
diff --git a/gaunt01/src/bird.cpp b/gaunt01/src/bird.cpp
index 9418b65..0a17563 100644
--- a/gaunt01/src/bird.cpp
+++ b/gaunt01/src/bird.cpp
@@ -11,19 +11,27 @@ finally drawAnimated()
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();
+ if (model.loadMesh("Bird-poses.xml")) printf("mesh loaded with %i vertices, %i face indices, %i targets\n",model.getNumVertices(),model.getNumIndices(),model.getNumTargets());
+ else printf("mesh XML file not parsed\n");
+
+ if (model.loadSeqs("Bird-anim.xml")) printf("animation loaded with %i sequences\n",model.getNumSequences());
+ else printf("animation XML file not parsed\n");
+
+ model.sequences["flap"].start();
+ currentseq="hover";
+
+ texture.loadImage("TextureBird.jpg");
+
+ //starting pos
+ position=ofVec3f(ofGetWidth()/2,ofGetHeight(),-100); //ofGetHeight()/4);
+ heading=ofVec3f(-1,0,0);
+ direction=ofVec3f(-1,0,0);
+ velocity=ofGetWidth()/50;
+
+ turnAngle=-1;
+ diveAngle=0;
+
+ lastTime=ofGetElapsedTimef();
}
bird::~bird()
@@ -32,23 +40,23 @@ bird::~bird()
}
void bird::update(const vector<ofVec3f>& players){
- float time=ofGetElapsedTimef();
- float timeSeg=time-lastTime;
- lastTime=time;
- position+=direction*velocity*timeSeg;
+ float time=ofGetElapsedTimef();
+ float timeSeg=time-lastTime;
+ lastTime=time;
+ position+=direction*velocity*timeSeg;
}
void bird::draw(){
- glEnable(GL_DEPTH_TEST);
- ofPushMatrix();
- ofTranslate(position);
- //ofRotate(direction);
- ofRotate(90,0,0,1);
- ofRotate(90,-1,0,0);
- //ofRotate(180,1,0,0);
- bindTexture(texture);
- model.draw();
- unbindTexture(texture);
- ofPopMatrix();
- glDisable(GL_DEPTH_TEST);
+ glEnable(GL_DEPTH_TEST);
+ ofPushMatrix();
+ ofTranslate(position);
+ //ofRotate(direction);
+ ofRotate(90,0,0,1);
+ ofRotate(90,-1,0,0);
+ ofScale(.15,.15,.15);
+ bindTexture(texture);
+ model.drawAnimated();
+ unbindTexture(texture);
+ ofPopMatrix();
+ glDisable(GL_DEPTH_TEST);
}
diff --git a/gaunt01/src/bird.h b/gaunt01/src/bird.h
index 4114ad3..e4b7f65 100644
--- a/gaunt01/src/bird.h
+++ b/gaunt01/src/bird.h
@@ -52,6 +52,8 @@ class bird
morphmesh model;
ofImage texture;
+
+ string currentseq;
};
#endif // BIRD_H
diff --git a/gaunt01/src/morphmesh.cpp b/gaunt01/src/morphmesh.cpp
index e68e526..a126002 100644
--- a/gaunt01/src/morphmesh.cpp
+++ b/gaunt01/src/morphmesh.cpp
@@ -1,9 +1,5 @@
#include "morphmesh.h"
-sequence::sequence()
-{
-}
-
track::track()
{
}
@@ -19,17 +15,89 @@ float track::evaluate(float time)
{
//interpolate key track
if (time<=keys.begin()->first) return keys.begin()->second;
- if (time>keys.rbegin()->first) return keys.rbegin()->second;
- multimap< float,float >::iterator key2=keys.upper_bound( time );
- multimap< float,float >::iterator key1=key2--;
+ if (time>=keys.rbegin()->first) return keys.rbegin()->second;
+ map< float,float >::iterator key2=keys.upper_bound( time );
+ map< float,float >::iterator key1=key2--;
float interval=key2->first-key1->first;
return (((1.0-((key2->first-time)/interval))*key2->second)+((1.0-((time-key1->first)/interval))*key1->second));
}
+sequence::sequence(string _name,float _length,float _fadeinTime,float _fadeoutTime)
+{
+ name=_name;
+ length=_length;
+ startTime=0;
+ stopTime=0;
+ fadeinTime=_fadeinTime;
+ fadeoutTime=_fadeoutTime;
+ active=false;
+}
+
+//-----------------------------------------------------
+// stopTime & startTime are absolute
+//
+// all other time markers are relative to the sequence
+//
+//
+void sequence::reset(){
+ active=false;
+ fadeinTime=-1;
+ fadeoutTime=-1;
+ startTime=0;
+ stopTime=0;
+}
+void sequence::start(){
+ reset();
+ active=true;
+ startTime=ofGetElapsedTimef();
+}
+void sequence::startAt(float time){
+ reset();
+ active=true;
+ startTime=ofGetElapsedTimef()+time;
+}
+void sequence::stopAt(float time){
+ reset();
+ active=true;
+ stopTime=ofGetElapsedTimef()+time;
+}
+void sequence::fadeout(float time){
+ if(active==true) {
+ reset();
+ active=true;
+ startTime=ofGetElapsedTimef();
+ fadeoutTime=0;
+ stopTime=ofGetElapsedTimef()+time;
+ }
+}
+void sequence::fadein(float time){
+ reset();
+ active=true;
+ fadeinTime=time;
+ startTime=ofGetElapsedTimef();
+}
+void sequence::stop(){
+ reset();
+}
+
+vector<morphWeight> sequence::evaluate(float time){
+ float now=ofGetElapsedTimef();
+ float seqtime=time-startTime;
+ float looptime=fmod(seqtime,length);
+ float fadeWeight=(seqtime<fadeinTime?seqtime/fadeinTime:seqtime>fadeoutTime&&fadeoutTime>-1?1.0-(seqtime/(stopTime-startTime)):1.0);
+ vector<morphWeight> weights;
+ map<string,track>::iterator i;
+ for( i = tracks.begin(); i != tracks.end(); i++ ) {
+ weights.push_back(morphWeight(i->first,(i->second.evaluate(looptime))*fadeWeight));
+ }
+ return weights;
+}
+
morphmesh::morphmesh()
{
loaded=false;
- /*
+
+ /*
//testing track function
track testrack;
testrack.keys.insert( pair<float,float>(0.0,2.0) );
@@ -38,7 +106,7 @@ morphmesh::morphmesh()
for (float f=-0.4;f<1.4;f+=0.1) {
printf("%f : %f\n",f,testrack.evaluate(f));
}
- */
+ */
}
morphmesh::morphmesh(string filename)
@@ -51,6 +119,9 @@ morphmesh::morphmesh(string filename)
int morphmesh::getNumTargets(){
return morphs.size();
}
+int morphmesh::getNumSequences(){
+ return sequences.size();
+}
void morphmesh::draw() {
draw(0);
}
@@ -64,26 +135,106 @@ void morphmesh::draw(string target){
addVertices(morphs[target]);
ofMesh::draw();
}
-void morphmesh::draw(const vector<string>& targets, const vector<float>& weights){
+void morphmesh::draw(const vector<morphWeight>& weights){
clearVertices();
//normalise weights
- int targetsNum=min(targets.size(),morphs.size());
float totalWeights=0;
- for (int i=0;i<targetsNum;i++) totalWeights+=weights[i];
+ for (int i=0;i<weights.size();i++) totalWeights+=weights[i].weight;
float weightFactor=1.0/totalWeights;
float bx,by,bz;
- for (int j=0;j<morphs[targets[0]].size();j++) {
+ for (int j=0;j<morphs.begin()->second.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];
+ for (int i=0;i<weights.size();i++) {
+ bx+=morphs[weights[i].name][j].x*weights[i].weight;
+ by+=morphs[weights[i].name][j].y*weights[i].weight;
+ bz+=morphs[weights[i].name][j].z*weights[i].weight;
}
addVertex(ofVec3f(bx*weightFactor,by*weightFactor,bz*weightFactor));
}
ofMesh::draw();
}
+void morphmesh::drawAnimated(){
+ float time=ofGetElapsedTimef();
+ vector<morphWeight> weights;
+ map<string,sequence>::iterator i;
+ for( i = sequences.begin(); i != sequences.end(); i++ ) {
+ if (i->second.active) {
+ vector<morphWeight> newWeights=i->second.evaluate(time);
+ weights.insert(weights.end(),newWeights.begin(),newWeights.end());
+ if (i->second.stopTime>0&&time>i->second.stopTime) i->second.active=false;
+ }
+ }
+ draw(weights);
+}
+
+
+bool morphmesh::loadSeqs(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("Gauntletanim")) {
+ int numSeqs=XML.getNumTags("Sequence");
+ vector<string> seqnames;
+ for (int i=0;i<numSeqs;i++) seqnames.push_back(XML.getAttribute("Sequence","Name","none",i));
+ for (int i=0;i<numSeqs;i++) {
+ float length=ofToFloat(XML.getAttribute("Sequence","Length","0",i));
+ float fadeinTime=ofToFloat(XML.getAttribute("Sequence","Fadein","0",i));
+ float fadeoutTime=ofToFloat(XML.getAttribute("Sequence","Fadeout","0",i));
+ sequence seq=sequence(seqnames[i],length,fadeinTime,fadeoutTime);
+
+ XML.pushTag("Sequence",i);
+ int numTargs=XML.getNumTags("Target");
+ vector<string> targnames;
+ for (int j=0;j<numTargs;j++) targnames.push_back(XML.getAttribute("Target","Name","none",j));
+ for (int j=0;j<numTargs;j++) {
+ XML.pushTag("Target",j);
+
+ vector<float> times;
+ string keystring=XML.getAttribute("Keys","Times","none",0);
+ stringstream ks(keystring);
+ istream_iterator<string> kbegin(ks);
+ istream_iterator<string> kend;
+ vector<string> kstrings(kbegin, kend);
+
+ vector<float> values;
+ string valstring=XML.getAttribute("Keys","Values","none",0);
+ stringstream vs(valstring);
+ istream_iterator<string> vbegin(vs);
+ istream_iterator<string> vend;
+ vector<string> vstrings(vbegin, vend);
+
+ track tr;
+
+ for (int k=0;k<min(kstrings.size(),vstrings.size());k++) tr.keys[ofToFloat(kstrings[k])]=ofToFloat(vstrings[k]);
+
+ seq.tracks[targnames[j]]=tr;
+
+ XML.popTag();
+ }
+ sequences[seqnames[i]]=seq;
+ /*
+ printf("testing sequence: %s\n",seqnames[i].c_str());
+ for (int k=0;k<targnames.size();k++) {
+ printf("track: %s\n",targnames[k].c_str());
+ for (float l=-.2;l<=2.2;l+=0.1) {
+ printf("%f : %f\n",l,sequences[seqnames[i]].tracks[targnames[k]].evaluate(l));
+ }
+ }
+ */
+ loaded=true;
+ XML.popTag();
+ }
+ XML.popTag();
+ }
+ }
+ return loaded;
+}
+
+
+
bool morphmesh::loadMesh(string filename){
loaded=false;
ofxXmlSettings XML;
@@ -99,7 +250,6 @@ bool morphmesh::loadMesh(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);
diff --git a/gaunt01/src/morphmesh.h b/gaunt01/src/morphmesh.h
index 18463a8..bc22c3d 100644
--- a/gaunt01/src/morphmesh.h
+++ b/gaunt01/src/morphmesh.h
@@ -36,8 +36,9 @@ These could be parameterised on top of the rest?
*/
struct morphWeight
{
- string name;
- float weight;
+ morphWeight(string _name="",float _weight=1.0) {name=_name;weight=_weight;}
+ string name;
+ float weight;
};
struct key
@@ -52,8 +53,7 @@ class track
//a single morph channel. keys a single morph target within a single sequence
public:
track();
- string target;
- multimap<float,float> keys;
+ map<float,float> keys;
float evaluate(float time);
};
@@ -67,15 +67,23 @@ class sequence
//sequencer keeps track of playback time and start/stop of sequences
//tracks is a map of time,value pairs - built in interpolation via multimap
public:
- sequence();
+ sequence(string _name="",float _length=1.0,float _fadeinTime=-2.0,float _fadeoutTime=-2.0);
+ string name;
map<string,track> tracks;
- vector<morphWeight> evaluate();
- private:
+ vector<morphWeight> evaluate(float time);
+ void reset();
+ void start();
+ void stop();
+ void startAt(float time);
+ void stopAt(float time);
+ void fadein(float time);
+ void fadeout(float time);
float length;
float startTime;
+ float stopTime;
float fadeinTime;
float fadeoutTime;
- bool loop,active;
+ bool active;
};
@@ -90,10 +98,11 @@ class morphmesh : public ofMesh
void draw();
void draw(int target);
void draw(string target);
- void draw(const vector<string>& targets, const vector<float>& weights);
+ void draw(const vector<morphWeight>& weights);
void drawAnimated(); //evaluates all active sequences via iterator and builds a collection of targets and weights for above
int getNumTargets();
- map< string,sequence > sequences; //public for direct access
+ int getNumSequences();
+ map<string,sequence> sequences; //public for direct access
protected:
private:
map< string,vector<ofVec3f> > morphs;