--- /dev/null
+all:
+ scons
+
+clean:
+ scons -c;\
+ figlet CLEAN ;
+
+
+run:
+ make run_`uname`
+
+
+debug:
+ make debug_`uname`
+
+
+run_Darwin:
+ ./mouseamations
+
+run_CYGWIN_NT-5.1:
+ ./mouseamations.exe
+
+debug_CYGWIN_NT-5.1:
+ gdb ./mouseamations.exe
+
--- /dev/null
+import os,string,sys
+
+def framework(a):
+ return '/System/Library/Frameworks/'+a+'.framework/'+a
+
+
+#load the list of used classes
+sourcelist = []
+sl=os.listdir('./intern')
+for i in sl:
+ s = string.split(i,'.')
+ if(s[1]=='cpp' or s[1]=='c'):
+ sourcelist = sourcelist + [i]
+
+for i in range(0,len(sourcelist)):
+ sourcelist[i]="intern/"+sourcelist[i]
+
+# look here for headers
+cpppath=[
+ '.',
+ '/usr/local/include',
+ '/opt/local/include',
+ '/opt/local/include/GraphicsMagick',
+ '/opt/local/include/libpng12',
+ '/opt/local/include/freetype2/',
+ '/opt/local/include/freetype2/',
+ '/usr/include/GraphicsMagick',
+ '/System/Library/Frameworks/ApplicationServices.framework/Headers',
+ '/cygdrive/c/Program Files/fmodapi375win/api/inc',
+ 'extern/myron/source',
+ 'extern/myron/ezcam',
+ ]
+
+# look here for libs
+libpath = [
+ '/usr/local/lib',
+ '/opt/local/lib',
+ '/usr/lib',
+# '/sw/lib/freetype2/lib',
+# '/sw/lib',
+ '/cygdrive/c/Program Files/fmodapi375win/api/lib',
+ 'extern/myron/ezcam',
+ ]
+
+# DLLs
+if(sys.platform=='darwin'):
+ sourcelist += [
+ framework('OpenGL'),
+ framework('GLUT'),
+ framework('Foundation'),
+ framework('ApplicationServices'),
+ framework('Carbon'),
+ framework('CoreServices'),
+ framework('QuickTime'),
+ '/opt/local/lib/libGraphicsMagick++.dylib',
+ '/opt/local/lib/libfreetype.6.dylib',
+ '/usr/lib/libz.1.1.3.dylib',
+ ]
+else:
+ sourcelist += [
+ '/usr/lib/libGraphicsMagick++.dll.a',
+ 'extern/myron/ezcam/myron_ezcam.dll',
+ 'extern/myron/myron.o',
+]
+
+# static link libs (preferrable, add to conf check)
+libs = []
+
+# compiler args
+ccflags=[
+ "-Wno-deprecated", #don't warn about deprecated
+ "-w", #no warnings
+ ]
+
+if(sys.platform=='darwin'):
+ #OS-specific define until i find one already provided
+ ccflags.append( "-D__DARWIN__ -arch i386")
+
+#make new scons instance
+env = Environment(CCFLAGS=ccflags,CPPPATH=cpppath,LIBS=libs,LIBPATH=libpath)
+
+#configure checks
+conf = Configure(env)
+
+if(sys.platform=='darwin'):
+ pass
+# if not conf.CheckLibWithHeader('freetype','freetype/freetype.h','c','',1):
+# print 'freetype2 must be installed!'
+# Exit(1)
+else: #windows, so far
+ if not conf.CheckLibWithHeader('freetype','ft2build.h','c','',1):
+ print 'freetype2 must be installed!'
+ Exit(1)
+ if not conf.CheckLibWithHeader('opengl32','GL/gl.h','c','',1):
+ print 'OpenGL must be installed!'
+ Exit(1)
+ if not conf.CheckLibWithHeader('glut32','GL/glut.h','c','',1):
+ print 'OpenGL must be installed!'
+ Exit(1)
+ if not conf.CheckLibWithHeader('glu32','GL/glu.h','c','',1):
+ print 'OpenGL must be installed!'
+ Exit(1)
+
+if not conf.CheckCXXHeader('Magick++.h'):
+ print 'GraphicsMagick must be installed!'
+ Exit(1)
+
+if not conf.CheckLibWithHeader('png12','png.h','c++','',1):
+ print 'libpng12 must be installed!'
+ Exit(1)
+
+
+
+if not conf.CheckCXXHeader('openal/al.h'):
+ print 'try this: sudo port install openal'
+ Exit(1)
+
+#if not conf.CheckLibWithHeader('fmod','fmod.h','c','',1):
+# print 'fmod must be installed!'
+# Exit(1)
+
+
+if not conf.CheckLibWithHeader('curl','curl/curl.h','c++','',1):
+ print 'libcurl must be installed!'
+ Exit(1)
+
+
+env = conf.Finish()
+
+#the app
+env.Program(target='mouseamations',source=sourcelist)
+
+#mac bundle post step
+if(sys.platform=='darwin'):
+ env.AddPostAction('mouseamations', Action('script/appIt $TARGET'))
+# env.AddPostAction('mouseamations', Action('script/bundle_depends.py $TARGET\.app/Contents/MacOS/$TARGET'))
+# env.AddPostAction('mouseamations', Action('script/findReplace.py $TARGET\.app/Contents/MacOS/libGraphicsMagick.1.dylib /opt/local/share/GraphicsMagick-1.1.7/config/ ./././././././././././././././././././config/'))
+# env.AddPostAction('mouseamations', Action('cp -r /opt/local/share/GraphicsMagick-1.1.7/config $TARGET\.app/Contents/Resources/config'))
+ env.Clean('mouseamations','mouseamations.app')
+
+
--- /dev/null
+#include "Global.h"
+#include "gl_et_al.h";
+#include "jttoolkit.h";
+#include "JPath.h";
+
+Global *Global::instance;
+
+Global::Global(){
+
+ srand(982);
+
+ instance=this;
+
+ hideMouse();
+
+ // toggleFullScreen();
+
+ // random number array
+ for(int i=0;i<20000;i++){
+ rnd.push_back(randomFloat());
+ }
+
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_POINT_SMOOTH);
+ glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
+
+ for(int i=0;i<10000;i++){
+ thingies.push_back(new Thingy());
+ thingies.back()->z = ((rnd[i+7]-.5)*1000000);
+ }
+}
+
+
+
+Global::~Global(){
+}
+
+
+void Global::loop(){
+ vector<Thingy*>::iterator it;
+
+
+ int cnt=0;
+ /*
+ for(it=thingies.begin();it!=thingies.end();it++){
+
+ (*it)->step();
+ (*it)->draw();
+ (*it)->x = rnd[cnt] * width();
+ (*it)->y = rnd[cnt] * height();
+ (*it)->z = 0; //(rnd[cnt]-.5)*1000; // ( ((rnd[cnt]-.5)*10) + ( (mouseX()-(width()/2)) * .085 ) );
+ //(*it)->dest.z = (rnd[cnt]-.5)*1000; //( ((rnd[cnt]-.5)*10) + ( (mouseX()-(width()/2) ) * .085 ) );
+ cnt++;
+}
+*/
+
+ for(int i=0; i<thingies.size(); i++){
+
+ thingies[i]->x = rnd[i]*width();
+ thingies[i]->y = rnd[i+3]*height();
+
+
+ thingies[i]->z += ((mouseX()-(width()/2))*.04);
+
+ thingies[i]->step();
+ thingies[i]->draw();
+ }
+
+
+
+ glColor4f(1,1,1, 0.1);
+ glBegin(GL_LINE_STRIP);
+ for(it=thingies.begin();it!=thingies.end();it++){
+ (*it)->glVertex();
+ }
+ glEnd();
+
+
+
+ glColor4f(1,1,1, 1);
+ glBegin(GL_POINTS);
+ for(it=thingies.begin();it!=thingies.end();it++){
+ (*it)->glVertex();
+ }
+ glEnd();
+
+
+
+
+}
+
+
+void Global::keyDown(int k,int special){
+ char s[256];
+ sprintf(s, "god.%04i.png", ticks());
+ cout << s << endl;
+ saveScreen(s);
+
+}
+
+
+void Global::mouseDown(){
+ rnd.clear();
+ for(int i=0;i<1000;i++){
+ rnd.push_back(randomFloat());
+ }
+ vector<Thingy*>::iterator it;
+
+ int cnt = 0;
+ for(it=thingies.begin();it!=thingies.end();it++){
+ (*it)->resetRandoms();
+ (*it)->z = ((rnd[cnt+7]-.5)*9000000);
+ cnt++;
+ }
+
+}
+void Global::mouseUp(){
+}
+
--- /dev/null
+#ifndef _Global_H_
+#define _Global_H_
+
+#include <vector>
+#include <deque>
+#include <Magick++.h>
+#include "JImage.h"
+#include "JMass.h"
+#include "JPath.h"
+#include "JChain.h"
+#include "Thingy.h"
+
+using namespace std;
+using namespace Magick;
+
+class Global{
+ public:
+
+ /**
+ the one and only static global instance of the Global object.
+ refer to me as `Global::instance`
+ */
+
+
+ static Global*instance;
+ vector<Thingy*>thingies;
+ vector<float> rnd;
+ void loop();
+ void keyDown(int k,int special);
+ void mouseDown();
+ void mouseUp();
+ Global();
+ ~Global();
+};
+
+#endif
+
--- /dev/null
+#include "JChain.h"
+#include "JPath.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+JChain::JChain(deque<JMass*> m,float v){
+ strength=v;
+ src=new JPoint();
+ dst= new JPoint();
+ deque<JMass*>::iterator it;
+ for(it=m.begin();it!=m.end();it++){
+ masses.push_back(*it);
+ }
+}
+
+JChain::JChain(float v){
+ strength=v;
+ src=new JPoint();
+ dst= new JPoint();
+}
+
+
+
+
+JChain::~JChain(){
+ delete src;
+ delete dst;
+}
+
+void JChain::step(){
+
+ for(int i=0;i<masses.size();i++){
+ if(i==0)masses[i]->springTo(*src,strength);
+ else masses[i]->springTo(*masses[i-1],strength);
+ }
+ for(int i=masses.size()-1;i>=0;i--){
+ if(i==masses.size()-1)masses[i]->springTo(*dst,strength);
+ else masses[i]->springTo(*masses[i+1],strength);
+ }
+
+}
+
+void JChain::draw(int type){
+ glBegin(type);
+ src->glVertex();
+ for(int i=0;i<masses.size();i++){
+ masses[i]->glVertex();
+ }
+ dst->glVertex();
+ glEnd();
+}
+
+
+// smooth with JPath
+// added by g-done
+void JChain::drawSmooth(int type, int v){
+
+ JPath smoothed(masses);
+
+ smoothed.smooth(v);
+
+ glBegin(type);
+ src->glVertex();
+ smoothed.glVertex();
+ dst->glVertex();
+ glEnd();
+}
+
+void JChain::drawScrewey(int type, int v, float rnd){
+
+ JPath smoothed(masses);
+
+ smoothed.smooth(1);
+
+ glBegin(type);
+ src->glVertex();
+
+ deque<JPoint*>::iterator it;
+ int i=0;
+ for(it=smoothed.points.begin(); it!=smoothed.points.end();it++){
+
+ float xx = (*it)->x + (Global::instance->rnd[i]-.5) * v * rnd;
+ float yy = (*it)->y + (Global::instance->rnd[i]-.5) * v * rnd;
+ float zz = (*it)->z + (Global::instance->rnd[i]-.5) * v * rnd;
+ glVertex3f(xx,yy,zz);
+ i++;
+ }
+
+ dst->glVertex();
+ glEnd();
+}
+
+
+
+
+
+void JChain::jitterFluff(float s, float r){
+
+ deque<JMass*>::iterator it;
+
+ int i=0;
+
+ for(it=masses.begin(); it!=masses.end(); it++){
+
+ float ox = (*it)->x;
+ float oy = (*it)->y;
+
+ (*it)->x += sin(ticks()*s*Global::instance->rnd[i]) * r;
+ (*it)->y += cos(ticks()*s*Global::instance->rnd[i]) * r;
+
+ i++;
+
+ }
+}
+
+
+
+
+
--- /dev/null
+#ifndef _JChain_H_
+#define _JChain_H_
+
+
+#include "JMass.h"
+#include <vector>
+#include <deque>
+
+using namespace std;
+
+class JChain{
+ public:
+ float strength;
+ JPoint *src;
+ JPoint *dst;
+ deque<JMass*> masses;
+ JChain(deque<JMass*>,float);
+ JChain(float);
+ ~JChain();
+
+ JChain* makeSmooth(int);
+
+ void step();
+ void draw(int);
+ void drawSmooth(int,int);
+ void drawScrewey(int,int,float); // draw type, variance, individual random
+ void jitterFluff(float,float);
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "JImage.h"
+#include "gl_et_al.h"
+#include "jttoolkit.h"
+
+
+void JImage::initMem(){
+ listID=0;
+}
+
+
+void JImage::load(char *fname){
+ read(fname);
+ modifyImage();
+ type(TrueColorType);
+ pixels = getPixels(0,0,columns(),rows());
+ update();
+}
+
+JImage::JImage(){
+ initMem();
+}
+
+JImage::JImage(char *file){
+ initMem();
+ load(file);
+}
+
+void JImage::update(){
+ update(false);
+}
+
+void JImage::update(int alphaOnly){
+ syncPixels();
+ //kill it first if needed
+ deleteGLResources();
+
+ //RE-ORDER THE PIXELS FOR OPENGL
+ GLfloat *f = new GLfloat[columns()*rows()*4];
+
+ if(!alphaOnly){
+
+ for(int y=0;y<rows();y++){
+ for(int x=0;x<columns();x++){
+ ColorRGB c(pixels[y*columns()+x]);
+ f[y*columns()*4+x*4+0] = c.red();
+ f[y*columns()*4+x*4+1] = c.green();
+ f[y*columns()*4+x*4+2] = c.blue();
+ f[y*columns()*4+x*4+3] = 1-c.alpha();
+ }
+ }
+
+ }else{
+ for(int y=0;y<rows();y++){
+ for(int x=0;x<columns();x++){
+ ColorRGB c(pixels[y*columns()+x]);
+ f[y*columns()*4+x*4+0] = 1;
+ f[y*columns()*4+x*4+1] = 1;
+ f[y*columns()*4+x*4+2] = 1;
+ f[y*columns()*4+x*4+3] = 1-c.alpha();
+ }
+ }
+ }
+
+ //CREATE TEXTURE
+ glGenTextures(1,&textureID);
+ glBindTexture(GL_TEXTURE_2D, textureID);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ gluBuild2DMipmaps( GL_TEXTURE_2D, 4, columns(),rows(),GL_RGBA, GL_FLOAT, f );
+ glTexImage2D(GL_TEXTURE_2D, 0,4, columns(),rows(), 0, GL_RGBA, GL_FLOAT, f);
+
+ //CLEAN
+ delete [] f;
+
+ //USE TEXTURE TO MAKE A DISPLAY LIST
+ listID = glGenLists(1);
+ glNewList(listID, GL_COMPILE);
+ glBindTexture(GL_TEXTURE_2D, textureID);
+
+
+ //ratio may not be square.
+
+ float w;
+ float h;
+
+ if(rows()<columns()){
+ w = 1;
+ h = (float)rows()/(float)columns();
+ }else{
+ w = (float)columns()/(float)rows();
+ h = 1;
+ }
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0,0);glVertex2f(0,0);
+ glTexCoord2f(1,0);glVertex2f(w,0);
+ glTexCoord2f(1,1);glVertex2f(w,h);
+ glTexCoord2f(0,1);glVertex2f(0,h);
+ glEnd();
+
+ glBindTexture(GL_TEXTURE_2D,0);
+ glEndList();
+ glBindTexture(GL_TEXTURE_2D,0);
+}
+
+
+JImage::~JImage(){
+ deleteGLResources();
+}
+
+/**
+ wrapper for glCallList
+*/
+void JImage::drawList(){
+ glCallList( listID );
+}
+
+void JImage::deleteGLResources(){
+ if(listID!=0){
+ glDeleteLists(listID,1);
+ glDeleteTextures(1,&textureID);
+ listID=0;
+ textureID=0;
+ }
+}
--- /dev/null
+#ifndef _JImage_H_
+#define _JImage_H_
+
+#include <Magick++.h>
+#include "jttoolkit.h"
+
+using namespace Magick;
+using namespace std;
+
+class JImage : public Image{
+ private:
+ void deleteGLResources();
+ public:
+ PixelPacket *pixels;
+ GLuint textureID;
+ GLuint listID;
+ void update();
+ void initMem();
+ void load(char *);
+ void update(int alphaOnlyBool);
+ void drawList();
+ JImage();
+ JImage(char *filename);
+ ~JImage();
+};
+#endif
--- /dev/null
+#include "JMass.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+JPoint JMass::friction(0.99,0.99,0.99);
+JPoint JMass::gravity(0,1,0);
+
+JMass::JMass(float xx,float yy,float zz):JPoint(xx,yy,zz){
+}
+
+JMass::JMass(JPoint p):JPoint(p){
+}
+
+JMass::JMass():JPoint(0){
+}
+
+JMass::~JMass(){
+
+}
+
+void JMass::step(){
+ (*this)+=force;
+ force+=gravity;
+ force*=friction;
+}
+
+void JMass::draw(){
+}
+
+
+void JMass::applyForce(JPoint that){
+ force += that;
+}
+
+
+void JMass::springTo(JPoint that,float strength){
+ applyForce((that-(*this))*strength);
+
+}
--- /dev/null
+#ifndef _JMass_H_
+#define _JMass_H_
+
+
+#include "JPoint.h"
+#include <vector>
+
+using namespace std;
+
+class JMass : public JPoint{
+ public:
+ static JPoint friction;
+ static JPoint gravity;
+
+ JPoint force;
+ JMass(float,float,float);
+ JMass(JPoint);
+ JMass();
+ ~JMass();
+
+ void step();
+ void draw();
+ void applyForce(JPoint p);
+ void springTo(JPoint p,float strength);
+};
+
+
+
+#endif
+
--- /dev/null
+/**
+ JPath
+ by Josh Nimoy
+ for Gabe Dunne
+ 23 jan 2007
+*/
+
+#include "JPath.h"
+#include "JMass.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+JPath::JPath(deque<JPoint*>p){
+ //make a deep copy of that vector
+ deque<JPoint*>::iterator it;
+ for(it=p.begin();it!=p.end();it++){
+ points.push_back(new JPoint(**it));
+ }
+}
+JPath::JPath(vector<JPoint*>p){
+ //make a deep copy of that vector
+ vector<JPoint*>::iterator it;
+ for(it=p.begin();it!=p.end();it++){
+ points.push_back(new JPoint(**it));
+ }
+}
+JPath::JPath(deque<JMass*>p){
+ //make a deep copy of that vector
+ deque<JMass*>::iterator it;
+ for(it=p.begin();it!=p.end();it++){
+ points.push_back(new JPoint(**it));
+ }
+}
+
+
+
+
+JPath::~JPath(){
+ deque<JPoint*>::iterator it;
+ for(it=points.begin();it!=points.end();it++){
+ delete *it;
+ }
+}
+
+/**
+ divide all edges in 2.
+*/
+void JPath::subdiv(){
+ deque<JPoint*>dest;
+ deque<JPoint*>::iterator it;
+ int i=0;
+ for(it=points.begin();it!=points.end();it++){
+ dest.push_back(*it);
+ if(i<points.size()-1){//don't add one for the last
+ dest.push_back(new JPoint( (*it)->lerpTo(**(it+1),0.5) ));
+ }
+ i++;
+ }
+
+
+
+
+
+ //ok, now copy dest back into points
+ points.clear();
+ for(it=dest.begin();it!=dest.end();it++){
+ points.push_back(*it);
+ }
+
+}
+
+
+/**
+ loop through all the verts and call glVertex3f(x,y,z);
+*/
+void JPath::glVertex(){
+ deque<JPoint*>::iterator it;
+ /**
+ JPath
+ by Josh Nimoy
+ for Gabe Dunne
+ 23 jan 2007
+*/
+
+
+#ifndef _JPath_H_
+#define _JPath_H_
+
+#include "JPoint.h"
+#include "JMass.h"
+#include <vector>
+#include <deque>
+
+using namespace std;
+
+class JPath{
+ public:
+ deque<JPoint*>points;
+
+
+ JPath(vector<JPoint*>);
+ JPath(deque<JMass*>);
+ JPath(deque<JPoint*>);
+
+ ~JPath();
+
+ void melt(float heat);
+ void subdiv();
+ void glVertex();
+ void smooth(int val);
+};
+
+
+
+#endif
+
+ for(it=points.begin();it!=points.end();it++){
+ (*it)->glVertex();
+ }
+
+}
+
+
+/*
+ lerping towards the previous and next points, we are effectively
+ melting the geometry toward the center.
+*/
+void JPath::melt(float heat){
+ //draw handles
+
+ deque<JPoint*>::iterator it;
+ int i=0;
+
+ for(it=points.begin();it!=points.end();it++){
+
+ JPoint *curr = *it;
+ JPoint *prev;
+ JPoint *next;
+
+ if(i>0)prev=*(it-1);
+ else prev=curr;
+
+ if(i<points.size()-1)next=*(it+1);
+ else next=curr;
+
+ curr->lerpSelfTo(*prev,heat);
+ curr->lerpSelfTo(*next,heat);
+
+ i++; //keep this close to the end curly bracket.
+ }
+
+
+
+}
+
+void JPath::smooth(int val){
+ for(int i=0;i<val;i++){
+ subdiv();
+ melt(0.5);
+ }
+}
--- /dev/null
+/**
+ JPath
+ by Josh Nimoy
+ for Gabe Dunne
+ 23 jan 2007
+*/
+
+
+#ifndef _JPath_H_
+#define _JPath_H_
+
+#include "JPoint.h"
+#include "JMass.h"
+#include <vector>
+#include <deque>
+
+using namespace std;
+
+class JPath{
+ public:
+ deque<JPoint*>points;
+
+
+ JPath(vector<JPoint*>);
+ JPath(deque<JMass*>);
+ JPath(deque<JPoint*>);
+
+ ~JPath();
+
+ void melt(float heat);
+ void subdiv();
+ void glVertex();
+ void smooth(int val);
+};
+
+
+
+#endif
+
--- /dev/null
+#include "JPoint.h"
+#include "gl_et_al.h"
+#include "math.h"
+
+#include <iostream>
+using namespace std;
+
+JPoint JPoint::rotateZ(float deg,JPoint pivot){
+ float r = distanceFrom(pivot);
+ float theta = pivot.thetaFrom(*this) + deg;
+ return JPoint(
+ r*cos(theta),
+ r*sin(theta),
+ 0
+ );
+}
+
+JPoint JPoint::lerpTo(JPoint p,float lerpVal){
+ cout << p.x << ' ' << p.y << ' ' << p.z <<endl;
+ float xx=p.x-x;
+ float yy=p.y-y;
+ float zz=p.z-z;
+ return JPoint(
+ x+xx*lerpVal,
+ y+yy*lerpVal,
+ z+zz*lerpVal
+ );
+}
+
+
+void JPoint::lerpSelfTo(JPoint p,float lerpVal){
+ JPoint pp = (*this)+(p-(*this))*lerpVal;
+ copyFrom(pp);
+}
+
+
+JPoint::JPoint(){
+ x=0;
+ y=0;
+ z=0;
+}
+
+JPoint::JPoint(float xx,float yy,float zz){
+ x=xx;
+ y=yy;
+ z=zz;
+}
+
+JPoint::JPoint(float v){
+ x=v;
+ y=v;
+ z=v;
+}
+
+JPoint::~JPoint(){
+
+}
+
+void JPoint::glVertex(){
+ glVertex3f(x,y,z);
+}
+
+void JPoint::glTranslate(){
+ glTranslatef(x,y,z);
+}
+
+
+void JPoint::copyFrom(JPoint p){
+ x=p.x;
+ y=p.y;
+ z=p.z;
+}
+
+
+
+
+float JPoint::thetaFrom(JPoint p){
+ float xd = p.x-x;
+ float yd = p.y-y;
+ return atan2(yd,xd);
+}
+
+
+JPoint JPoint::operator+(JPoint p){
+ return JPoint(p.x+x,p.y+y,p.z+z);
+}
+
+
+JPoint JPoint::operator-(JPoint p){
+ return JPoint(x-p.x,y-p.y,z-p.z);
+}
+
+
+void JPoint::operator+=(JPoint p){
+ x+=p.x;
+ y+=p.y;
+ z+=p.z;
+}
+
+void JPoint::operator*=(JPoint p){
+ x*=p.x;
+ y*=p.y;
+ z*=p.z;
+}
+
+void JPoint::operator*=(float f){
+ x*=f;
+ y*=f;
+ z*=f;
+}
+
+void JPoint::operator-=(JPoint p){
+ x-=p.x;
+ y-=p.y;
+ z-=p.z;
+}
+
+JPoint JPoint::operator*(JPoint p){
+ return JPoint(p.x*x,p.y*y,p.z*z);
+}
+
+JPoint JPoint::operator*(float v){
+ return JPoint(x*v,y*v,z*v);
+}
+
+
+
+void JPoint::swap(JPoint p){
+ float tx = x;
+ float ty = y;
+ float tz = z;
+ x=p.x;
+ y=p.y;
+ z=p.z;
+ p.x = tx;
+ p.y = ty;
+ p.z = tz;
+}
+
+
+float JPoint::distanceFrom(JPoint p){
+ float xd = p.x-x;
+ float yd = p.y-y;
+ float zd = p.z-z;
+ return sqrt(xd*xd+yd*yd+zd*zd);
+}
--- /dev/null
+#ifndef _JPoint_H_
+#define _JPoint_H_
+
+class JPoint{
+ public:
+ float x;
+ float y;
+ float z;
+ float ox,oy,oz;
+ JPoint();
+ JPoint(float,float,float);
+ JPoint(float);
+ ~JPoint();
+ JPoint rotateZ(float deg,JPoint pivot);
+ float distanceFrom(JPoint p);
+ JPoint lerpTo(JPoint p,float lerpVal);
+ void lerpSelfTo(JPoint p,float lerpVal);
+ void glVertex();
+ void glTranslate();
+ void copyFrom(JPoint);
+ float thetaFrom(JPoint p);
+ JPoint operator+(JPoint);
+ void operator+=(JPoint);
+ void operator*=(JPoint);
+ void operator*=(float);
+ void operator-=(JPoint);
+ JPoint operator*(JPoint);
+ JPoint operator*(float);
+ JPoint operator-(JPoint);
+ void swap(JPoint p);
+};
+
+
+
+#endif
+
--- /dev/null
+#include "joshfont.h"\r#include "jttoolkit.h"\r\r//static Vector *persisPts;\r\rJoshFont::JoshFont(char file[], int lettersize, int renderStyle, int antialiased,int mipmap){\r rendermode = GL_POLYGON;\r open(file,lettersize, renderStyle, antialiased,mipmap);\r}\r\rJoshFont::~JoshFont(){\r //dispose of the memory\r FT_Done_Face ( ft_face );\r FT_Done_FreeType( ft_library );\r}\r\rint JoshFont::open(char file[], int lettersize,int renderstyle, int antialiased,int mipmap){\r initsize = lettersize;\r int ii;\r int texturesize;\r if(lettersize<= 4 &&lettersize> 2 ){\r texturesize = 4;\r } else if(lettersize<= 8 &&lettersize> 4 ){\r texturesize = 8;\r } else if(lettersize<= 16 &&lettersize> 8 ){\r texturesize = 16;\r } else if(lettersize<= 32 &&lettersize> 16 ){\r texturesize = 32;\r } else if(lettersize<= 64 &&lettersize> 32 ){\r texturesize = 64;\r } else if(lettersize<= 128 &&lettersize> 64 ){\r texturesize = 128;\r } else if(lettersize<= 256 &&lettersize> 128 ){\r texturesize = 256;\r } else if(lettersize<= 512 &&lettersize> 256 ){\r texturesize = 512;\r } else {\r texturesize = 1024;\r }\r\r\r base = glGenLists(256);\r //load the images into textures and make them into gllists.\r \r int err = FT_Init_FreeType(&ft_library);\r \r if(err){\r printf("error initializing freetype2: %i\n",err);\r exit(0); \r }\r\r err = FT_New_Face(ft_library,file,0,&ft_face);\r if(err==FT_Err_Unknown_File_Format){\r printf("error: the font file could be\\r opened and read, but it appears that its font format is unsupported\n");\r return err;\r } else if(err){\r printf("error opening font: %i\n",err);\r return err;\r }\r\r\r //report\r // printf("font info:\n",0);\r // printf(" num_faces: %i\n",ft_face->num_faces);\r // printf(" num_glyphs: %i\n",ft_face->num_glyphs);\r // printf(" units_per_EM: %i\n",ft_face->units_per_EM);\r // printf(" size: %i\n",ft_face->size);\r \r //generate a sample bitmap\r err = FT_Set_Pixel_Sizes(ft_face,0,lettersize);\r if(err)printf("there was an error\n: %i\n",err);\r \r units_per_EM = ft_face->units_per_EM;\r ascender = ft_face->ascender;\r descender = ft_face->descender;\r\r //now render all 256 characters\r for(int i=0;i<256;i++){\r //err = FT_Load_Char(ft_face,'4',FT_LOAD_RENDER);\r int glyph_index = FT_Get_Char_Index(ft_face, i);\r err = FT_Load_Glyph(ft_face,glyph_index,FT_LOAD_DEFAULT );\r if(err)printf("there was an error\n: %i\n",err);\r \r#if defined(__DARWIN__)\r#define RENDER_NORMAL FT_RENDER_MODE_NORMAL\r#else\r#define RENDER_NORMAL ft_render_mode_normal\r#endif\r FT_Glyph g;\r FT_Get_Glyph (ft_face->glyph, &g);\r err = FT_Render_Glyph(ft_face->glyph,RENDER_NORMAL);\r if(err)printf("there was an error\n: %i\n",err);\r FT_GlyphSlot slot = ft_face->glyph;\r \r //printf("rows: %i\n",slot->bitmap.rows);\r //printf("width: %i\n",slot->bitmap.width);\r //printf("pitch: %i\n",slot->bitmap.pitch);\r \r if( ft_glyph_format_outline != g->format){\r //printf("not outline format\n");\r } else {\r //printf("yes outline format\n");\r }\r //do something with the vectors.\r \r FT_OutlineGlyph outline = (FT_OutlineGlyph)g;\r FT_Outline ftOutline = outline->outline;\r\r //make tex from loading the bitmap buffer into openGL.\r if(!antialiased){\r //do a posterize filter on the bitmap.\r for(ii=0;ii<slot->bitmap.rows*slot->bitmap.width;ii++){\r if(slot->bitmap.buffer[ii]>128){\r slot->bitmap.buffer[ii] = 255;\r } else {\r slot->bitmap.buffer[ii] = 0;\r }\r }\r }\r \r //record kerning info.\r charWidths[i] = ((float)(slot->metrics.width)/(float)((texturesize*64)));\r charHeights[i] = ((float)(slot->metrics.height)/(float)((texturesize*64)));\r charHoriBearingYs[i] = ((float)(slot->metrics.horiBearingY)/(float)((texturesize*64)));\r charHoriBearingXs[i] = ((float)(slot->metrics.horiBearingX)/(float)((texturesize*64)));\r charHoriAdvances[i] = ((float)(slot->metrics.horiAdvance)/(float)((texturesize*64)));\r if(i=='\t')charHoriAdvances[i] = 4;\r charVertBearingYs[i] = ((float)(slot->metrics.vertBearingY)/(float)((texturesize*64)));\r charVertBearingXs[i] = ((float)(slot->metrics.vertBearingX)/(float)((texturesize*64)));\r charVertAdvances[i] = ((float)(slot->metrics.vertAdvance)/(float)((texturesize*64)));\r //printf("%c %f\n",i,charHoriBearingYs[i]);\r \r int tex;\r \r if(renderstyle==JF_BITMAP){\r tex = loadBitmapCharRAWFromMemory(slot->bitmap.buffer,\r texturesize,texturesize,slot->bitmap.width,\r slot->bitmap.rows,mipmap);\r }else if(renderstyle==JF_VECTOR){\r tex = 0;\r }\r //int tex = 0;\r \r \r //persisPts = new Vector();\r \r\r glNewList(base+i,GL_COMPILE);\r \r float trans = -1.0;\r \r if(renderstyle==JF_BITMAP){\r \r //textures[i] = tex;\r if(tex!=0){\r\r glTranslatef(0,trans,0);\r glBindTexture(GL_TEXTURE_2D,tex);\r \r glBegin(GL_QUADS);\r glTexCoord2f(0,0);\r glVertex2f(0,0);\r \r glTexCoord2f(1,0);\r glVertex2f(1,0);\r \r glTexCoord2f(1,1);\r glVertex2f(1,1);\r \r glTexCoord2f(0,1);\r glVertex2f(0,1);\r glEnd();\r\r glBindTexture(GL_TEXTURE_2D,0); \r glTranslatef(0,-trans,0);\r }\r\r }\r \r //debugging tool\r // if(0){\r // if(ftOutline.n_points>0){\r // glBindTexture(GL_TEXTURE_2D,0);\r // //glColor3f(0,0,0);\r // glDisable(GL_BLEND);\r // JTTessBegin();\r // if(ftOutline.n_contours>0){\r // int curContourIndex=0;\r // int curCloser = ftOutline.contours[0];\r // for(int cii=0;cii<ftOutline.n_points;cii++){\r // JTTessVertex(ftOutline.points[cii].x/(64.0*lettersize),\r // ftOutline.points[cii].y/(64.0*lettersize),0);\r \r // if(curCloser==cii){\r // JTTessNewContour();\r // if(curContourIndex+2<ftOutline.n_contours) {\r // curContourIndex++;\r // curCloser = ftOutline.contours[curContourIndex];\r // }\r // }\r // }\r // }\r \r // JTTessEnd();\r // }\r // }\r\r if(renderstyle==JF_VECTOR)tessChar(i,lettersize); \r\r if(0){//render each of the vertex points too.\r glBegin(GL_POINTS);\r float w = ascender/(64.0*lettersize)-charHoriBearingYs[i];\r \r for(int vci=0;vci<ftOutline.n_points;vci++){\r if(ftOutline.tags[vci]==0)glColor3f(1,0,0);\r else glColor3f(0,1,0);\r \r float x = ftOutline.points[vci].x/(64.0*lettersize);\r float y = -ftOutline.points[vci].y/(64.0*lettersize)-w;\r glVertex3f(x,y,0);\r //glRectf(x-0.01,y-0.01,x+0.01,y+0.01);\r }\r glEnd();\r }\r\r glEndList();\r \r if(renderstyle==JF_VECTOR)feedbackChar(i,lettersize);//record some triangles.\r \r }\r glBindTexture(GL_TEXTURE_2D,0);\r}\r\rvoid JoshFont::drawChar(char c){\r glCallList(base+c);\r}\r\r\rvoid JoshFont::feedbackChar(char i,float lettersize){\r //call tessChar and catch the feedback.\r feedbackScale = 640;//width();\r feedbackBuffers[i] = new float[1024*256];//this should be enough, or the size will return -1.\r glFeedbackBuffer(1024*256, GL_2D ,feedbackBuffers[i]);\r glRenderMode(GL_FEEDBACK);\r glPushMatrix();\r glTranslatef(0,feedbackScale/2.0,0);\r glScalef(feedbackScale/2.0,feedbackScale/2.0,0);\r tessChar(i,lettersize);\r glPopMatrix();\r feedbackSizes[i] = glRenderMode(GL_RENDER);\r if(feedbackSizes[i]==-1){\r printf("error: glFeedback not enough buffer space for this list.\n",0);\r }\r}\r\rvoid JoshFont::drawTriangleChar(char c,float size){\r \r float *buffer = feedbackBuffers[c];\r float bsize = feedbackSizes[c];\r glPushMatrix();\r glScalef(1,-1,1);\r glScalef(size/(initsize*5),size/(initsize*5),1);\r glTranslatef(0,-160.16,0);\r\r int i=-1;\r while(i+1<bsize){\r //get a block\r i++;\r float block = buffer[i];\r if(block==GL_POLYGON_TOKEN){\r //printf("GL_POLYGON_TOKEN ",block);\r \r i++;\r int vcount = round(buffer[i]);\r //printf("n=%i ",vcount);\r glBegin(rendermode);\r for(int ii=0;ii<vcount;ii++){\r i++;\r GLfloat x = (GLfloat)buffer[i];\r //printf("x=%f ",x);\r i++;\r GLfloat y = ((GLfloat)buffer[i]);\r //printf("y=%f ",y);\r glVertex3f(x,y,0);\r }\r glEnd();\r //printf("\n",0);\r } else if(block==GL_POINT_TOKEN){\r printf("GL_POINT_TOKEN \n",block);\r } else if(block==GL_LINE_TOKEN){\r printf("GL_LINE_TOKEN \n",block);\r } else if(block==GL_LINE_RESET_TOKEN){\r printf("GL_LINE_RESET_TOKEN \n",block);\r } else if(block==GL_PASS_THROUGH_TOKEN){\r printf("GL_PASS_THROUGH_TOKEN \n",block);\r \r } else {\r printf("%f <-- unrecognized\n",block);\r i++;//see if we can pull ourselves out of that.\r }\r }\r glPopMatrix();\r}\r\rvoid JoshFont::initFeedback(){\r \r}\r\rvoid JoshFont::tessChar(char i,float lettersize){\r if(1){\r int glyph_index = FT_Get_Char_Index(ft_face, i);\r int err = FT_Load_Glyph(ft_face,glyph_index,FT_LOAD_DEFAULT );\r if(err)printf("there was an error\n: %i\n",err);\r \r //int err;\r FT_Glyph g;\r FT_Get_Glyph (ft_face->glyph, &g);\r //err = FT_Render_Glyph(ft_face->glyph,RENDER_NORMAL);\r //if(err)printf("there was an error\n: %i\n",err);\r FT_GlyphSlot slot = ft_face->glyph;\r // printf("rows: %i\n",slot->bitmap.rows);\r // printf("width: %i\n",slot->bitmap.width);\r // printf("pitch: %i\n",slot->bitmap.pitch);\r \r if( ft_glyph_format_outline != g->format){\r //printf("not outline format\n");\r } else {\r //printf("yes outline format\n");\r }\r //do something with the vectors.\r \r FT_OutlineGlyph outline = (FT_OutlineGlyph)g;\r FT_Outline ftOutline = outline->outline;\r\r //debugging incompat btwn tess and font paths.\r //now this is the VECTOR VERSION of the preceding rendering routine!\r glBindTexture(GL_TEXTURE_2D,0);\r //glColor3f(0,0,0);\r //glDisable(GL_BLEND);\r JTTessBegin();\r //printf("contours:%i\n", ftOutline.n_points);\r if(ftOutline.n_contours>0){\r //first copy all the points into their own gluTess compatible persistent points.\r float w = ascender/(64.0*lettersize)-charHoriBearingYs[i];\r \r //glPushMatrix();\r \r //glTranslatef(0,w,0);\r //GLUtesselator*tess = getTessObj();\r \r ///gluTessBeginPolygon(tess,NULL);\r //gluTessBeginContour(tess);\r \r //for(int j=0;j<5;j++){\r \r //}\r \r int curContourIndex=0;\r int curContour=ftOutline.contours[0];\r int bezcount = 0;\r int bezaccum[64];\r for(int ii=0;ii<ftOutline.n_points;ii++){\r FT_Vector v = ftOutline.points[ii];\r //printf("%c %i %i %i\n",i,ftOutline.tags[ii],v.x/64,v.y/64);\r if(ftOutline.tags[ii]==1){\r \r if(bezcount!=0){\r //new mutli bez event.\r \r for(int thisB=0;thisB<bezcount;thisB++){\r \r //aligning the points with the function\r int thisp = bezaccum[thisB];//this bez point.\r \r //here is the function.\r#define BEZIER_STEP_SIZE 0.22\r float bezierValues[2][2];\r float controlPoints[3][2];\r \r controlPoints[1][0] = ftOutline.points[thisp ].x;\r controlPoints[1][1] = ftOutline.points[thisp ].y;\r int virtualfirst = ((curContourIndex>0)?(ftOutline.contours[curContourIndex-1]+1):0);\r if (thisp==virtualfirst) {//the one after the last contour's end, or the very first one in the whole array.\r controlPoints[0][0] = ftOutline.points[curContour].x;\r controlPoints[0][1] = ftOutline.points[curContour].y;\r controlPoints[2][0] = ftOutline.points[thisp+1].x;\r controlPoints[2][1] = ftOutline.points[thisp+1].y;\r } else if (thisp==curContour) {\r controlPoints[0][0] = ftOutline.points[thisp-1].x;\r controlPoints[0][1] = ftOutline.points[thisp-1].y;\r controlPoints[2][0] = ftOutline.points[virtualfirst].x;\r controlPoints[2][1] = ftOutline.points[virtualfirst].y;\r } else {\r controlPoints[0][0] = ftOutline.points[thisp-1].x;\r controlPoints[0][1] = ftOutline.points[thisp-1].y;\r controlPoints[2][0] = ftOutline.points[thisp+1].x;\r controlPoints[2][1] = ftOutline.points[thisp+1].y;\r }\r for( unsigned int bi = 0; bi <= ( 1.0f / BEZIER_STEP_SIZE); bi++){\r float t = static_cast<float>(bi) * BEZIER_STEP_SIZE;\r \r \r bezierValues[0][0] = (1.0f - t) * controlPoints[0][0] + t * controlPoints[1][0];\r bezierValues[0][1] = (1.0f - t) * controlPoints[0][1] + t * controlPoints[1][1];\r \r bezierValues[1][0] = (1.0f - t) * controlPoints[1][0] + t * controlPoints[2][0];\r bezierValues[1][1] = (1.0f - t) * controlPoints[1][1] + t * controlPoints[2][1];\r \r bezierValues[0][0] = (1.0f - t) * bezierValues[0][0] + t * bezierValues[1][0];\r bezierValues[0][1] = (1.0f - t) * bezierValues[0][1] + t * bezierValues[1][1];\r \r //AddPoint( bezierValues[0][0], bezierValues[0][1]);\r \r GLdouble d[12];\r d[0] = (bezierValues[0][0]/(64.0*lettersize)+0.000001);\r d[1] = -(bezierValues[0][1]/(64.0*lettersize))-w;\r d[2] = 0;\r d[3] = 0;\r //persisPts->push((long)d);\r JTTessVertex(d[0],d[1],0);\r }//end of beszier function \r \r \r \r /*\r GLdouble d[12];\r d[0] = (ftOutline.points[thisp].x/(64.0*lettersize)+ii*0.0001);\r d[1] = -(ftOutline.points[thisp].y/(64.0*lettersize)+ii*0.0001)-w;\r d[2] = 0;\r d[3] = 0;\r JTTessVertex(d[0],d[1],0);\r */\r \r //add a moveTo\r if(curContour==thisp){\r //persisPts->push(0);\r JTTessNewContour();\r curContourIndex++;\r curContour=ftOutline.contours[curContourIndex];\r }\r //\r \r }//end of looping through all the involved conic pts in this path chunk.\r \r }\r bezcount = 0;\r \r \r //then finally take care of this on-point.\r GLdouble d[12];\r d[0] = (ftOutline.points[ii].x/(64.0*lettersize)+ii*0.0001);\r d[1] = -(ftOutline.points[ii].y/(64.0*lettersize)+ii*0.0001)-w;\r d[2] = 0;\r d[3] = 0;\r //persisPts->push((long)d);\r JTTessVertex(d[0],d[1],0);\r \r if(curContour==ii){\r //persisPts->push(0);\r JTTessNewContour();\r curContourIndex++;\r curContour=ftOutline.contours[curContourIndex];\r }\r \r \r \r } else {\r if(ftOutline.tags[ii]!=FT_Curve_Tag_Conic){\r printf("encountered a non-FT_Curve_Tag_Conic\n",0);\r }\r bezaccum[bezcount]=ii;\r bezcount++;\r }\r }\r //one last checl for the chunks\r \r if(bezcount!=0){\r //new mutli bez event.\r \r for(int thisB=0;thisB<bezcount;thisB++){\r \r //aligning the points with the function\r int thisp = bezaccum[thisB];//this bez point.\r \r //here is the function.\r#define BEZIER_STEP_SIZE 0.22\r float bezierValues[2][2];\r float controlPoints[3][2];\r \r controlPoints[1][0] = ftOutline.points[thisp ].x;\r controlPoints[1][1] = ftOutline.points[thisp ].y;\r int virtualfirst = ((curContourIndex>0)?(ftOutline.contours[curContourIndex-1]+1):0);\r if (thisp==virtualfirst) {//the one after the last contour's end, or the very first one in the whole array.\r controlPoints[0][0] = ftOutline.points[curContour].x;\r controlPoints[0][1] = ftOutline.points[curContour].y;\r controlPoints[2][0] = ftOutline.points[thisp+1].x;\r controlPoints[2][1] = ftOutline.points[thisp+1].y;\r } else if (thisp==curContour) {\r controlPoints[0][0] = ftOutline.points[thisp-1].x;\r controlPoints[0][1] = ftOutline.points[thisp-1].y;\r controlPoints[2][0] = ftOutline.points[virtualfirst].x;\r controlPoints[2][1] = ftOutline.points[virtualfirst].y;\r } else {\r controlPoints[0][0] = ftOutline.points[thisp-1].x;\r controlPoints[0][1] = ftOutline.points[thisp-1].y;\r controlPoints[2][0] = ftOutline.points[thisp+1].x;\r controlPoints[2][1] = ftOutline.points[thisp+1].y;\r }\r for( unsigned int bi = 0; bi <= ( 1.0f / BEZIER_STEP_SIZE); bi++){\r float t = static_cast<float>(bi) * BEZIER_STEP_SIZE;\r \r \r bezierValues[0][0] = (1.0f - t) * controlPoints[0][0] + t * controlPoints[1][0];\r bezierValues[0][1] = (1.0f - t) * controlPoints[0][1] + t * controlPoints[1][1];\r \r bezierValues[1][0] = (1.0f - t) * controlPoints[1][0] + t * controlPoints[2][0];\r bezierValues[1][1] = (1.0f - t) * controlPoints[1][1] + t * controlPoints[2][1];\r \r bezierValues[0][0] = (1.0f - t) * bezierValues[0][0] + t * bezierValues[1][0];\r bezierValues[0][1] = (1.0f - t) * bezierValues[0][1] + t * bezierValues[1][1];\r \r //AddPoint( bezierValues[0][0], bezierValues[0][1]);\r \r GLdouble d[12];\r d[0] = (bezierValues[0][0]/(64.0*lettersize)+thisp*0.000001);\r d[1] = -(bezierValues[0][1]/(64.0*lettersize))-w;\r d[2] = 0;\r d[3] = 0;\r //persisPts->push((long)d);\r JTTessVertex(d[0],d[1],0);\r }//end of beszier function \r \r \r /*\r GLdouble d[12];\r d[0] = (ftOutline.points[thisp].x/(64.0*lettersize)+ii*0.0001);\r d[1] = -(ftOutline.points[thisp].y/(64.0*lettersize)+ii*0.0001)-w;\r d[2] = 0;\r d[3] = 0;\r JTTessVertex(d[0],d[1],0);\r */\r \r //add a moveTo\r if(curContour==thisp){\r //persisPts->push(0);\r JTTessNewContour();\r curContourIndex++;\r curContour=ftOutline.contours[curContourIndex];\r }\r //\r \r }//end of looping through all the involved conic pts in this path chunk.\r \r }\r bezcount = 0;\r //end lasst chunk check\r \r }\r \r //glPopMatrix();\r \r \r \r //---------------------now actually draw the processed vertexes.\r \r /*\r GLUtesselator*tess = getTessObj();\r gluTessBeginPolygon(tess,NULL);\r gluTessBeginContour(tess);\r \r for(int ii=0;ii<persisPts->count;ii++){\r GLdouble *pi = (GLdouble*)persisPts->get(ii);\r if(pi==0){\r gluTessEndContour(tess);\r //gluTessEndPolygon(tess);\r //empty space\r //gluTessBeginPolygon(tess,NULL);\r gluTessBeginContour(tess);\r } else {\r gluTessVertex(tess,pi,pi);\r }\r }\r gluTessEndContour(tess);\r gluTessEndPolygon(tess);\r */\r \r \r /*\r for(int ii=0;ii<persisPts->count;ii++){\r GLdouble *pi = (GLdouble*)persisPts->get(ii);\r if(pi==0){\r JTTessNewContour();\r } else {\r JTTessVertex(pi[0], pi[0],0);\r }\r }\r */\r JTTessEnd();\r }\r \r \r}\r\rvoid JoshFont::drawStringFittedBox(char *inputstr,float right,float bottom){\r glPushMatrix();\r \r\r glScalef((right/getStringWidth(inputstr,1)),(bottom/charHeights['H']),0);\r glTranslatef(0,charHeights['H']*2.38,0);\r drawString(inputstr,1,0);\r glPopMatrix();\r}\r\rvoid JoshFont::drawString(char *inputstr,float size,float tracking){\r glPushMatrix();\r \r glPushMatrix();\r glScalef(size,size,0);\r //glTranslatef( -(1.0-offx/255.0) , -(1.0-offy/255.0) , 0 );\r int lineno = 1;\r for(int i=0;i<strlen(inputstr);i++){\r if(inputstr[i]==13||inputstr[i]==10){\r glPopMatrix();\r lineno++;\r glTranslatef(0,round(tracking*size),0);\r glPushMatrix();\r glScalef(size,size,0);\r } else {\r glPushMatrix();\r glTranslatef(charHoriBearingXs[inputstr[i]],\r -(float)charHoriBearingYs[inputstr[i]],0);\r this->drawChar(inputstr[i]);\r glPopMatrix();\r \r glTranslatef( (float)(charHoriAdvances[inputstr[i]]) ,0,0);\r }\r }\r \r glPopMatrix();\r glPopMatrix();\r \r}\r\r\r\r\rvoid JoshFont::drawStringBoxWrap(char *inputstr,float size,float tracking, \r float right,float bottom,int quickrender){\r glPushMatrix();\r glTranslatef(0,round(tracking*size)*2,0);\r glPushMatrix();\r glScalef(size,size,0);\r \r //glTranslatef( -(1.0-offx/255.0) , -(1.0-offy/255.0) , 0 );\r int lineno = 1;\r float lineadvance = 0;\r int line_wordcount=0;\r int strln = strlen(inputstr);\r for(int i=0;i<strln;i++){\r char thisChar = inputstr[i];\r \r // //calculate the current line size for force-justify spacing per line.\r // float thisFJ = 0;\r // int curPlace = i;\r // int theoretical_line=0;\r // int theoretical_word=0;\r // int wordcount=0;\r // while(1){\r \r // while(1){\r // curPlace++;\r // //break if we got too far.\r // if(!(curPlace<strln)){\r // break;\r // }\r // if(inputstr[curPlace]==' '||inputstr[curPlace]=='-'){\r // break;\r // } else {\r // theoretical_word += (float)charHoriAdvances[inputstr[curPlace]];\r // }\r // }\r // wordcount++;\r // if((theoretical_line+theoretical_word)*size>right||curPlace>=strln){\r // break;\r // } else {\r // theoretical_line += theoretical_word;\r // }\r // }\r // //now we have the current line. How much longer is the full width of the box?\r // thisFJ = (right-theoretical_line*size)/(float)wordcount;\r \r if(thisChar==13||thisChar==10){\r glPopMatrix();\r lineno++;\r glTranslatef(0,round(tracking*size),0);\r glPushMatrix();\r glScalef(size,size,0);\r lineadvance=0;\r line_wordcount=0;\r } else {\r //calculate the would-be resultant adanvace of the current word.\r float theoretical_advance = lineadvance;\r int curPlace = i-1;\r while(1){\r curPlace++;\r //break if we got too far.\r if(!(curPlace<strln)){\r break;\r }\r if(inputstr[curPlace]==' '||inputstr[curPlace]=='-'||charHoriAdvances[i] == '\t'){\r break;\r } else {\r theoretical_advance += (float)charHoriAdvances[inputstr[curPlace]];\r }\r }\r \r if( theoretical_advance*size>right && line_wordcount>0 ){//shall we soft-wrap?\r glPopMatrix();\r lineno++;\r glTranslatef(0,round(tracking*size),0);\r glPushMatrix();\r glScalef(size,size,0);\r lineadvance=0;\r line_wordcount=0;\r }\r \r glPushMatrix();\r \r if(quickrender){\r if(thisChar!=' '&&thisChar!='\t'){\r glTranslatef(charHoriBearingXs[thisChar],\r -(float)tracking,0);\r glBegin(GL_LINES);\r glVertex3f(0,0,0);\r glVertex3f(1,1,0);\r glVertex3f(1,0,0); \r glVertex3f(0,1,0);\r glEnd();\r } \r } else{\r glTranslatef(charHoriBearingXs[thisChar],\r -(float)charHoriBearingYs[thisChar],0);\r //glScalef(i*0.05,i*0.05,1);\r this->drawChar(inputstr[i]);\r\r if(thisChar==' '||thisChar=='-'||thisChar=='\t'){\r line_wordcount++;\r }\r }\r \r glPopMatrix();\r // if(thisChar==' '){\r // glTranslatef( (float)charHoriAdvances[thisChar]+round(thisFJ) ,0,0);\r // lineadvance+= (float)charHoriAdvances[thisChar]+round(thisFJ);\r // } else {\r glTranslatef( (float)charHoriAdvances[thisChar] ,0,0);\r lineadvance+= (float)charHoriAdvances[thisChar];\r // }\r \r }\r }\r \r glPopMatrix();\r glPopMatrix();\r \r}\r\r\r\rfloat JoshFont::getStringWidth(char *inputstr,int size){\r float strw=0; \r int strln = strlen(inputstr);\r for(int i=0;i<strln;i++){\r //this->drawChar(inputstr[i]);\r if(i==strln-1){\r strw+=size*(charWidths[inputstr[i]]+charHoriBearingXs[inputstr[i]]);\r } else {\r strw+=size*(float)charHoriAdvances[inputstr[i]] ;\r }\r }\r return strw;\r}\r\r\rint JoshFont::loadBitmapCharRAWFromMemory(void*buffer,\r int imageWidth, int imageHeight,\r int srcWidth, int srcHeight,int mipmap){\r unsigned char *f = (unsigned char*)buffer;\r if(buffer==0){\r return 0;\r }\r unsigned char *f_alphad = new unsigned char[imageWidth*imageHeight*4];\r int gutter=3;\r for(int y=0;y<imageHeight;y++){\r for(int x=0;x<imageWidth;x++){\r if((x-gutter)<srcWidth&&(y-gutter)<srcHeight && y>=gutter && x>=gutter){\r f_alphad[(y)*imageWidth*4+4*(x )] = 255;\r f_alphad[(y)*imageWidth*4+4*(x)+1] = 255;\r f_alphad[(y)*imageWidth*4+4*(x)+2] = 255;\r f_alphad[(y)*imageWidth*4+4*(x)+3] = f[(y-gutter)*srcWidth+(x-gutter)];//this will differ depending on the ink being used.\r } else {\r f_alphad[(y)*imageWidth*4+4*(x )] = 0;\r f_alphad[(y)*imageWidth*4+4*(x)+1] = 0;\r f_alphad[(y)*imageWidth*4+4*(x)+2] = 0;\r f_alphad[(y)*imageWidth*4+4*(x)+3] = 0;\r }\r }\r }\r GLuint t;\r glGenTextures(1,&t);\r glBindTexture(GL_TEXTURE_2D, t);\r glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r \r\r if(mipmap){\r glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);\r gluBuild2DMipmaps( GL_TEXTURE_2D, 4, imageWidth,imageHeight,GL_RGBA, GL_UNSIGNED_BYTE, f_alphad );\r }else{\r glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r }\r \r \r glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);\r glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);\r //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP);\r glTexImage2D(GL_TEXTURE_2D,\r 0,4, imageWidth, imageHeight, 0,\r GL_RGBA,\r GL_UNSIGNED_BYTE,\r f_alphad);\r //#if defined(__DARWIN__)\r delete f_alphad;\r //delete f;\r //#endif\r return t;\r}\r\rfloat JoshFont::randomFloat(){\r return ((float)rand())/((float)RAND_MAX);\r}\r
\ No newline at end of file
--- /dev/null
+#ifndef _JOSHFONT_H_\r
+#define _JOSHFONT_H_\r
+\r
+#include <fstream.h>\r
+#include <iostream.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+//#include "joshfix.h"\r
+\r
+\r
+#if defined(__DARWIN__)\r
+#include <GLUT/glut.h>\r
+#include <ft2build.h>\r
+#include <freetype/freetype.h>\r
+#include <freetype/ttnameid.h>\r
+#include <freetype/ftglyph.h>\r
+#elif defined(linux)\r
+#include <GL/glut.h>\r
+#else\r
+#include <windows.h>\r
+#include <GL/glut.h>\r
+#include <ft2build.h>\r
+#include FT_FREETYPE_H\r
+#include <freetype/ttnameid.h>\r
+#include <freetype/ftglyph.h>\r
+#endif\r
+\r
+\r
+#include <string.h>\r
+\r
+#define JF_VECTOR 0\r
+#define JF_BITMAP 1\r
+\r
+\r
+class JoshFont{\r
+public:\r
+ \r
+ JoshFont(char file[], int lettersize,int renderstyle, int antialiased,int mipmap);\r
+ ~JoshFont();\r
+ \r
+ //int offx;\r
+ //int offy;\r
+\r
+ int base;\r
+ int textures[256];\r
+ float charWidths[256];\r
+ float charHeights[256];\r
+ float charHoriBearingYs[256];\r
+ float charHoriBearingXs[256];\r
+ float charHoriAdvances[256];\r
+ float charVertBearingYs[256];\r
+ float charVertBearingXs[256];\r
+ float charVertAdvances[256];\r
+ float*feedbackBuffers[256];\r
+ int feedbackSizes[256];\r
+ float units_per_EM;\r
+ float ascender;\r
+ float descender;\r
+ float text_height;\r
+ float initsize;\r
+ int rendermode;\r
+ FT_Library ft_library;\r
+ FT_Face ft_face;\r
+ float feedbackScale;//used to store initial window values.\r
+ void drawTriangleChar(char c,float size);\r
+ void initFeedback();\r
+ int open(char file[], int lettersize,int renderStyle, int antialiased,int mipmap);\r
+ \r
+ void drawChar(char c);\r
+ void tessChar(char c,float lettersize);\r
+ void feedbackChar(char c,float lettersize);\r
+ void drawString(char *inputstr,float size,float tracking);\r
+ void drawStringBoxWrap(char *inputstr,float size,float tracking,float right,float bottom,int quickrender);\r
+ void drawStringFittedBox(char *inputstr,float right,float bottom);\r
+ float getStringWidth(char *inputstr, int size);\r
+ int loadBitmapCharRAWFromMemory(void*buffer,\r
+ int imageWidth, int imageHeight,\r
+ int srcWidth, int srcHeight,int mipmap);\r
+ float randomFloat();\r
+};\r
+\r
+#endif\r
+\r
--- /dev/null
+#include "Thingy.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+#define RAND_COUNT 10
+
+Thingy::Thingy(){
+
+ for(int i=0;i<RAND_COUNT;i++)rnd.push_back(randomFloat());
+
+ size = 0;
+
+ reset();
+
+
+
+ dest.x = width()/2;
+ dest.y = height()/2;
+ dest.z = 0;
+
+ this->copyFrom(dest);
+}
+
+void Thingy::resetRandoms(){
+ rnd.clear();
+ for(int i=0;i<RAND_COUNT;i++)rnd.push_back(randomFloat());
+ reset();
+}
+
+void Thingy::reset(){
+
+ float xxx = (width()/2);
+ float yyy = (height()/2);
+
+ x = xxx; //xxx * cos(randomFloat() * (2*PI)) * 2;
+ y = yyy; //yyy * sin(randomFloat() * (2*PI)) * 2;
+ z = (randomFloat() - 0.5) * 100;
+
+ dest.copyFrom(*this);
+
+ destSize = randomFloat()*10;
+}
+
+Thingy::~Thingy(){
+
+}
+
+void Thingy::step(){
+
+
+ // (*this)+=JPoint( randomFloat()-0.5, randomFloat()-0.5, randomFloat()-0.5);
+
+ size += (destSize-size)*0.1;
+
+ float xx = (dest.x-x) * .02;
+ float yy = (dest.y-y) * .02;
+ float zz = (dest.z-z) * .02;
+
+ x += xx;
+ y += yy;
+ z += zz;
+
+
+}
+
+
+// HEAVEN FROM THE FUTURE
+void Thingy::draw(){
+
+ glColor4f(rnd[3],rnd[4],rnd[5],1);
+
+ float steps = 3;
+
+ float inc = (PI*2) / steps;
+
+
+ float rot = sin(ticks() * .01 * rnd[5]) * 3.2;
+
+
+ glBegin(GL_LINE_LOOP);
+
+ for(int i=0; i<steps; i++) {
+
+ float xx = x + size * cos(inc*i) * rot;
+ float yy = y + size * sin(inc*i) * rot;
+
+
+ glVertex3f(xx,yy,z);
+
+
+ }
+ glEnd();
+
+
+
+
+
+
+}
+
+
+
+
+
+
+
+
+
--- /dev/null
+#ifndef _Thingy_H_
+#define _Thingy_H_
+
+
+#include <vector>
+#include "JMass.h"
+
+using namespace std;
+
+class Thingy : public JMass{
+ public:
+ JPoint dest;
+ float size;
+ float destSize;
+ vector<float> rnd;
+ Thingy();
+ ~Thingy();
+
+ void reset();
+ void step();
+ void draw();
+ void resetRandoms();
+};
+
+
+
+#endif
+
--- /dev/null
+/**
+ wrapper include for openGL interested includers.
+ so i don't have to multiply update all opengl includings each time i switch plats.
+*/
+
+#if defined(__DARWIN__)
+ #include <GLUT/glut.h>
+ #include <OpenGL/gl.h>
+#else
+ #include <GL/glut.h>
+ #include <GL/gl.h>
+#endif
+
--- /dev/null
+#include "jttoolkit.h"\r#include <stdio.h>\r#include <stdlib.h>\r#include <string.h>\r#include <iostream.h> \r#include <fstream.h>\r\r\r#define INIT_WINDOW_X 100\r#define INIT_WINDOW_Y 100\r#define INIT_WINDOW_WIDTH 810\r#define INIT_WINDOW_HEIGHT 510\r\r\r//#include "gl2ps.h"\r#if defined (__DARWIN__)\r#include <ApplicationServices/ApplicationServices.h>\r#endif\r\r#define use_perspective\r#define VERBOSE 0\r//turn this on and off for speed\r\r\r//---- user-global access functions\r\rint ticks(){return _ticks;}\rint width(){return _width;}\rint height(){return _height;}\r\rint mouseX(){return _mouseX;}\rint mouseY(){return _mouseY;}\r\r\rvoid setMouseX(long xx){_mouseX = xx;}\rvoid setMouseY(long yy){_mouseY = yy;}\r\rvoid ignoreMouse(int state){_ignoreMouse = state;}\r\r//--------------\r\rvoid *threadFunc(void*stuff){\r}\r\r//------------------------------------------------------------------------\rvoid initfmod(){\r /* \r if (FSOUND_GetVersion() < FMOD_VERSION){\r printf("Error : You are using the wrong DLL version! You should be using FMOD %.02f\n", FMOD_VERSION);\r exit(1);\r }\r \r if(!FSOUND_Init(48000, 1024, FSOUND_INIT_GLOBALFOCUS)){\r printf("%s\n",FMOD_ErrorString(FSOUND_GetError()));\r }\r */\r}\r//------------------------------------------------------------------------\r\r\r\rfloat friction(){return _friction;}\rvoid setFriction(float f){_friction = f;}\r\rfloat frequencyRange(){return _frequencyRange;}\rvoid setFrequencyRange(float f){_frequencyRange = f;}\r\rvoid drawUnitSquare(){\r glBegin(GL_QUADS);\r glTexCoord2f(0,0);glVertex2f(0,0); \r glTexCoord2f(1,0);glVertex2f(1,0);\r glTexCoord2f(1,1);glVertex2f(1,1);\r glTexCoord2f(0,1);glVertex2f(0,1);\r glEnd();\r}\r\r\rvoid drawUnitSquareSlightlySmaller(){\r glBegin(GL_QUADS);\r glTexCoord2f(0.01,0.01);glVertex2f(0,0); \r glTexCoord2f(0.99,0.01);glVertex2f(1,0);\r glTexCoord2f(0.99,0.99);glVertex2f(1,1);\r glTexCoord2f(0.01,0.99);glVertex2f(0,1);\r glEnd();\r}\r\r\r\r\rvoid toggleFullScreen(){\r fullscreenmode=!fullscreenmode;\r if(fullscreenmode){\r glutFullScreen();\r } else {\r glutReshapeWindow(INIT_WINDOW_WIDTH,INIT_WINDOW_HEIGHT);\r glutPositionWindow(0,10);\r }\r}\r\rchar* trimLeft(char*buff){\r //count how many to offset backward\r int whiteCount = 0;\r for(int i=0;i<strlen(buff);i++){\r if(buff[i]==' '||buff[i]=='\r'||buff[i]=='\n'||buff[i]=='\t'){\r whiteCount++;\r }else{\r break;\r }\r }\r if(whiteCount>0){\r for(int b=0;b<strlen(buff)-whiteCount;b++){\r buff[b] = buff[b+whiteCount];\r }\r }\r return buff;\r}\r\rvoid fileFromString(unsigned char *fname, char *data, long datasize){\r long i=0;\r FILE *fp = fopen((const char*)fname,"wb");\r for(i=0;i<datasize;i++){\r fputc(data[i],fp);\r }\r fclose(fp);\r}\r\r\r//--------------------------------------------------------------------\r\r\runsigned char* stringFromFile(char *fname){\r long fsize;\r unsigned char *a;\r\r if(fname==NULL){\r if(VERBOSE)printf("err: stringFromFile: filename was null\n",NULL);\r return 0;\r }\r fsize = getFileSize(fname);\r\r if(fsize==0){\r if(VERBOSE)printf("err: stringFromFile: file size was zero\n",NULL);\r return 0;\r }\r a = new unsigned char[fsize+1];\r \r if(a==NULL){\r if(VERBOSE)printf("err: stringFromFile: memory allocation failed\n",NULL);\r return 0;\r }\r \r getFile((char*)fname,a,fsize);\r a[fsize]=0;\r return a;\r}\r\r\r//--------------------------------------------------------------------\r\rlong getFileSize( char *fname){\r FILE *fp;\r long fsize;\r if (fname == NULL){\r if(VERBOSE)printf("err: getFileSize: filename was null\n",NULL);\r return 0;\r }\r fp = fopen((const char*)fname, "rb");\r if (fp == NULL){\r if(VERBOSE)printf("err: getFileSize: file stream failed\n",NULL);\r return 0;\r }\r if(fseek(fp, 0, SEEK_END)!=0){\r if(VERBOSE)printf("err: getFileSize: fseek failed\n",NULL);\r }\r fsize = ftell(fp);\r fclose(fp);\r return fsize;\r}\r\r\r//--------------------------------------------------------------------\r\rvoid getFile( char *filename, unsigned char *buff, int length){\r unsigned char c=0;\r long buffcnt=0;\r long i=0;\r ifstream f;\r //#if defined(__DARWIN__)\r // f.open(filename);\r //#else\r f.open((const char*)filename, ios::binary);\r //#endif\r f.read((char*)buff, length);\r //for(i=0;i<length;i++){\r // printf("{%c}",buff[i]);\r //}\r f.close();\r}\r\r\r//--------------------------------------------------------------------\r\rvoid hideMouse(){\r\r#if defined(__DARWIN__)\r //MAC\r HideCursor();\r#elif defined(linux)\r //LINUX\r //ignore\r#else\r //WINDOWS\r ShowCursor(FALSE);\r#endif\r\r\r}\r\r//--------------------------------------------------------------------\r\rvoid showMouse(){\r#if defined(__DARWIN__)\r //MAC\r ShowCursor();\r#elif defined(linux)\r //ignore\r#else\r //WINDOWS\r ShowCursor(TRUE);\r#endif\r}\r\rvoid display(){}\rvoid display2(){}\r\rvoid _execute_frame(){\r glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);\r glPushMatrix();\r#if defined(use_perspective)\r glTranslatef(-width()/2.0f,height()/2.0,-height()/2.0);\r glScalef(1,-1,1);\r#endif \r if(penta_firstloop){//first time!\r penta_firstloop = false;\r font = new JoshFont("media/usethis.ttf",40,JF_BITMAP,true,true);\r glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\r setup();\r }else{\r loop();\r //glFlush();\r //glutPostRedisplay();\r _ticks++;\r }\r glPopMatrix();\r glutSwapBuffers();\r \r}\r\rvoid idle(){\r /*\r if(glutGet(GLUT_ELAPSED_TIME) - lastGlutFrameTime > frameRate){\r _execute_frame();\r lastGlutFrameTime = glutGet(GLUT_ELAPSED_TIME);\r }\r */\r}\r\r\rvoid timerFunc(int v) {\r //if(glutGet(GLUT_ELAPSED_TIME) - lastGlutFrameTime > frameRate){\r _execute_frame();\r //}\r glutTimerFunc(frameRate,timerFunc,0);\r}\r\rvoid preKeyDown(unsigned char k, int special){\r if(special){\r if(k==11){\r toggleFullScreen();\r }\r } else {\r //non special\r if(k==27){\r //exit(0);\r }else if (k==KEY_DELETE || k==KEY_BACKSPACE){\r\r\r } else if (k==6){//ctrl+f on a mac\r toggleFullScreen();\r } else {\r\r }\r }\r\r}\r\rvoid keyboardDown(unsigned char k,int x,int y){\r if(!_ignoreMouse){\r _mouseX=x;\r _mouseY=y;\r }\r preKeyDown(k,0);\r jttoolkit_keyDown(k,0);\r}\r\rvoid keyboardUp(unsigned char k,int x,int y){\r if(!_ignoreMouse){\r _mouseX=x;\r _mouseY=y;\r }\r //printf("keyboardUp: %c %i\n",k);\r jttoolkit_keyUp(k,0);\r}\r\r\rvoid specialFunc(int k,int x,int y){\r if(!_ignoreMouse){\r _mouseX=x;\r _mouseY=y;\r }\r preKeyDown(k,1);\r jttoolkit_keyDown(k,1);\r}\r\rvoid mouseMotionFunc(int x, int y){\r if(!_ignoreMouse){\r _mouseX=x;\r _mouseY=y;\r }else{\r ignored_mouseMove(x,y);\r }\r\r}\r\rvoid mousePassiveMotionFunc(int x, int y){\r if(!_ignoreMouse){\r _mouseX=x;\r _mouseY=y;\r }else{\r ignored_mouseMove(x,y);\r }\r // printf("%i %i\n",_mouseX,_mouseY);\r}\r\rvoid mouseFunc(int button, int state, int x, int y){\r if(!_ignoreMouse){\r _mouseX=x;\r _mouseY=y;\r \r if(state==GLUT_DOWN){\r jttoolkit_mouseDown();\r } else {\r jttoolkit_mouseUp();\r }\r \r }else{\r \r if(state==GLUT_DOWN){\r ignored_mouseDown(x,y);\r } else {\r ignored_mouseUp(x,y);\r }\r \r }\r}\r\rvoid viewPerspective(float angle){\r glMatrixMode(GL_PROJECTION);\r glLoadIdentity();\r gluPerspective(angle,(float)width()/(float)height(),0.0001,10000);\r //glFrustum(-2, 2, -2, 2, 1.0f, 100.0f);\r glMatrixMode(GL_MODELVIEW);\r}\r\r\rvoid viewOrtho(){\r glMatrixMode(GL_PROJECTION);\r glLoadIdentity();\r glOrtho(0,width(),-height(),0,-10000,10000);\r glMatrixMode(GL_MODELVIEW);\r}\r\rvoid reshape(int w,int h){\r // if(glutGetWindow()==MainWindowID){\r if(1){\r \r _width = w;\r _height = h;\r // to keep it propertional & let the window stretch\r // glMatrixMode(GL_PROJECTION);\r // glLoadIdentity();\r glViewport(0,0,w,h);\r // if(w<h){\r // float r = ((float)h/(float)w);\r // glOrtho(-1,1,-r,r,-2,2);\r // }else{\r float r = ((float)w/(float)h);\r // glOrtho(-r,r,-1,1,-2,2);\r // }\r // this->draw();\r \r viewPerspective(90);\r glLoadIdentity();\r \r } else { //then i can assume for now that it was the output console window.\r \r glViewport(0,0,w,h);\r float r = ((float)w/(float)h);\r \r glMatrixMode(GL_PROJECTION);\r glLoadIdentity();\r \r //#if defined(use_perspective)\r //gluPerspective(90,(float)w/(float)h,0.0001,10000);\r //#else\r glOrtho(0,w,h,0,-10000,10000);\r //#endif\r //glFrustum(-2, 2, -2, 2, 1.0f, 100.0f);\r \r glMatrixMode(GL_MODELVIEW);\r glLoadIdentity();\r }\r // jt_resizeDrawBuffer();\r}\r\rvoid jt_resizeDrawBuffer(){\r // delete [] drawbuffer;\r // drawbuffer = new unsigned char[width()*height()*4];\r}\r\rint main(int argc,char** argv){\r\r\r glutInit(&argc,argv);\r glutInitDisplayMode (GLUT_DOUBLE|GLUT_RGBA);\r glutInitWindowSize (INIT_WINDOW_WIDTH,INIT_WINDOW_HEIGHT);\r glutInitWindowPosition (INIT_WINDOW_X,INIT_WINDOW_Y);\r\r int gameMode = 0;\r if(argc>1){\r for(int i=0;i<strlen(argv[1]);i++){\r switch(argv[1][i]){\r case 'g':\r gameMode = true;\r }\r }\r }\r\r if(gameMode){\r glutGameModeString("1440x900:16@60");\r glutEnterGameMode();\r }else{\r glutCreateWindow (" ");\r }\r \r jttoolkit_init();\r glutMainLoop();\r\r //do we ever even get here?\r //FSOUND_Close();\r stop();\r exit(0);\r return 0;\r}\r\rint jttoolkit_init(){\r glutIdleFunc(idle);\r glutDisplayFunc(display);\r glutReshapeFunc(reshape);\r glutMouseFunc(mouseFunc);\r glutMotionFunc(mouseMotionFunc);\r glutPassiveMotionFunc(mousePassiveMotionFunc);\r glutKeyboardFunc (keyboardDown);\r glutKeyboardUpFunc (keyboardUp);\r glutSpecialFunc (specialFunc);\r glutTimerFunc(frameRate,timerFunc,0);\r \r // a whole bunch of switches for the openGL engine\r glEnable(GL_TEXTURE_2D);\r glEnable(GL_BLEND);\r glEnable(GL_DEPTH_TEST);\r //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);\r //glEnable(GL_LINE_SMOOTH);\r //glEnable(GL_POLYGON_SMOOTH);\r glLineWidth(1);\r // glDepthFunc(GL_LESS);//was GL_LEQUAL\r glDepthFunc(GL_LEQUAL);//was GL_LEQUAL\r glClearDepth(1.0f);\r glDisable(GL_DITHER);\r //glShadeModel(GL_SMOOTH);\r glMatrixMode(GL_PROJECTION); // The Projection Matrix\r glLoadIdentity(); // The Projection Matrix\r // Calculate The Aspect Ratio Of The Window\r //gluPerspective(45.0f,(float)wW/(float)wH,0.1f,100.0f);\r //gluLookAt(0,0,1,0,0,0,0,1,0);\r glMatrixMode(GL_MODELVIEW); // The Modelview Matrix\r glLoadIdentity(); // The Modelview Matrix\r //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Perspective Calculations\r //glEnable(GL_FOG);\r //glFogf(GL_FOG_START,-100);\r //glFogf(GL_FOG_END,-200);\r //glFogf(GL_FOG_DENSITY,0.1);\r //float r[] = {0.5,0.5,0.5,0.5};\r //glFogfv(GL_FOG_COLOR,r);\r //--------------------------------------------------------------------------------\r glClearColor(0,0,0,0);\r //also, if that doesn't work, check if the users screen is 640x48, then fullscreen the game.\r //#if defined(__DARWIN__)\r //problem with fullscreen - it disables the glut passive motion func.\r //#else\r //if(fullscreenmode)glutFullScreen();\r //#endif\r\r}\r\rint buildScreenFont(char *fontName, int size){\r return 0;\r}\r\r\rvoid _draw_single_screenFont(int fontID, char*text){\r \r glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);\r \r}\r\rvoid drawScreenFont(int fontID, char*text,int tracking){\r int i;\r int drawScreenFont_buffpt=0;\r int lineCounter=0;\r if (text == NULL)return;\r glPushAttrib(GL_LIST_BIT);\r glRasterPos3f(0,lineCounter,0);\r glListBase(fontID);\r for(i=0;i<strlen(text);i++){\r if(text[i]=='\n'){\r drawScreenFont_buff[drawScreenFont_buffpt]=0;\r _draw_single_screenFont(fontID,drawScreenFont_buff);\r lineCounter+=tracking;\r glRasterPos3f(0,lineCounter,0);\r drawScreenFont_buffpt=0;\r }else{\r drawScreenFont_buff[drawScreenFont_buffpt] = text[i];\r drawScreenFont_buffpt++;\r }\r }\r drawScreenFont_buff[drawScreenFont_buffpt]=0;\r _draw_single_screenFont(fontID,drawScreenFont_buff);\r glPopAttrib();\r}\r\r\rvoid killScreenFont(int fontID){\r glDeleteLists(fontID,256);\r}\r\r\rvoid lights(){\r glEnable(GL_LIGHT0);\r glEnable(GL_LIGHTING);\r glEnable(GL_COLOR_MATERIAL);\r glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\r}\r\r\r\rvoid nolights(){\r glDisable(GL_LIGHT0);\r glDisable(GL_LIGHTING);\r glDisable(GL_COLOR_MATERIAL);\r}\r\r\rfloat randomFloat(){\r return ((float)rand())/((float)RAND_MAX);\r}\r\rvoid line(JPoint p1,JPoint p2){\r glBegin(GL_LINES);\r p1.glVertex();\r p2.glVertex();\r glEnd();\r}\r\rvoid bezier(JPoint p1,JPoint p2,JPoint p3,JPoint p4,int steps){\r float *Xs = new float[steps];\r float *Ys = new float[steps];\r float *Zs = new float[steps];\r\r\r interpolateBezier(\r p1.x,p1.y,p1.z,\r p2.x,p2.y,p2.z,\r p3.x,p3.y,p3.z,\r p4.x,p4.y,p4.z,\r steps,Xs,Ys,Zs) ;\r \r glBegin(GL_LINE_STRIP);\r p1.glVertex();\r for(int i=1;i<steps-1;i++){\r glVertex3f(Xs[i],Ys[i],Zs[i]);\r }\r p4.glVertex();\r glEnd();\r \r delete Xs;\r delete Ys;\r delete Zs;\r\r}\r\r\rvoid interpolateBezier(\r float P0X,float P0Y,float P0Z,\r float P1X,float P1Y,float P1Z,\r float P2X,float P2Y,float P2Z,\r float P3X,float P3Y,float P3Z,\r int segs,\r float Xs[] , float Ys[] , float Zs[]) {\r \r float t=0.0f,dt=1.0f/(float)segs; // calculating increment\r float Q0X,Q0Y,Q0Z;\r float Q1X,Q1Y,Q1Z;\r float Q2X,Q2Y,Q2Z;\r float R0X,R0Y,R0Z;\r float R1X,R1Y,R1Z;\r float x;float y;float z;\r float xx=P0X;float yy=P0Y;float zz=P0Z;\r for (int i=1;i<segs;i++) {\r Q0X = P0X + t*(P1X-P0X); Q0Y = P0Y + t*(P1Y-P0Y); Q0Z = P0Z + t*(P1Z-P0Z);\r Q1X = P1X + t*(P2X-P1X); Q1Y = P1Y + t*(P2Y-P1Y); Q1Z = P1Z + t*(P2Z-P1Z);\r Q2X = P2X + t*(P3X-P2X); Q2Y = P2Y + t*(P3Y-P2Y); Q2Z = P2Z + t*(P3Z-P2Z);\r R0X = Q0X + t*(Q1X-Q0X); R0Y = Q0Y + t*(Q1Y-Q0Y); R0Z = Q0Z + t*(Q1Z-Q0Z);\r R1X = Q1X + t*(Q2X-Q1X); R1Y = Q1Y + t*(Q2Y-Q1Y); R1Z = Q1Z + t*(Q2Z-Q1Z);\r x = R0X + t*(R1X-R0X);\r y = R0Y + t*(R1Y-R0Y);\r z = R0Z + t*(R1Z-R0Z);\r //drawLine(xx,yy,zz,x,y,z);\r Xs[i-1]=x;\r Ys[i-1]=y;\r Zs[i-1]=z;\r xx=x;\r yy=y;\r zz=z;\r t+=dt;\r }\r}\r\r\rfloat absf(float a){\r if(a<0)return -a;\r return a;\r}\r\r\rfloat getDist(float x1,float y1,float x2,float y2){\r double x = absf(x1-x2);\r double y = absf(y1-y2);\r x=x*x;\r y=y*y;\r return (float)sqrt(x+y);\r}\r\r\rvoid rect2polar(double x,double y,double returnPair[2]){\r returnPair[0] = getDist(0.0,0.0,x,y);\r returnPair[1] = atan2(y,x);\r}\r\rvoid polar2rect(double r,double theta,double returnPair[2]){\r returnPair[0] = r*cos(theta);\r returnPair[1] = r*sin(theta);\r}\r\r\r\r//tess\r\rvoid JTTessVertex(float x,float y, float z){\r //first look for available memory before allocating more.\r //printf("%f %f %f\n",x,y,z);\r doTessErrorCheck();\r //printf("1 %i\n",tessPtr);\r GLdouble *p = tesscache[tessBase+tessPtr];\r //printf("2\n",0);\r tessPtr++;\r \r p[0] = x;\r p[1] = y;\r p[2] = z;\r p[3] = 0;\r //printf("3\n",0);\r //if(tesscache!=0)tesscache->push((long)p);\r}\r\r\rvoid JTTessEnd(){\r //FLUSH IT!\r \r tobj = gluNewTess();\r _tessBind();\r \r if(tesscache!=0){\r gluTessBeginPolygon(tobj,NULL);\r gluTessBeginContour(tobj);\r \r for(int i=tessBase;i<tessBase+tessPtr;i++){\r GLdouble*t = tesscache[i];\r if((long)t==TESSCACHE_NEWCONTOUR){\r gluTessEndContour(tobj);\r gluTessBeginContour(tobj);\r } else {\r GLdouble *g = (GLdouble*)t;\r gluTessVertex(tobj,g,g);\r }\r }\r \r gluTessEndContour(tobj);\r gluTessEndPolygon(tobj);\r }\r gluDeleteTess(tobj);\r glFlush();\r //JTTessBegin();//reset to new.\r \r}\r\r\r/*\rvoid JTTessInit(int memsize){\r tessfreemem = new Vector();\r tesscache = new GLdouble*[memsize];\r tessmax = memsize;\r for(int i=0;i<memsize;i++){\r tesscache[i] = new GLdouble[12];\r }\r}\r*/\r\r\r\rvoid JTTessNewContour(){\r doTessErrorCheck();\r tesscache[tessBase+tessPtr] = (GLdouble*)TESSCACHE_NEWCONTOUR;\r tessPtr++;\r\r}\r\r\rvoid JTTessBegin(){\r /*\r if(tesscache!=0){\r // for(int i=0;i<tesscache->count ;i++){\r // long t = tesscache->get(i);\r // switch(t){\r // case TESSCACHE_NEWCONTOUR:break;\r // default:\r //printf("%i\n",t);\r //printf("%i\n",((GLdouble*)(t))[0]);\r //delete [] (GLdouble*)t;//i'm leaving this all in memory, but it's dangerous!\r //tessfreemem->push(t);\r //break;\r // }\r //}\r //delete tesscache;\r //tesscache = new Vector();\r \r } else { //it WAS zero.\r //tesscache = new Vector();\r }\r tessBase += tessPtr;//advance forward.\r tessPtr = 0;\r*/\r}\r\r\rvoid doTessErrorCheck(){\r if(tessPtr+tessBase>tessmax){\r printf("error:not enough memory allocated to JTTess",0);\r exit(0);\r }\r}\r\r\r\rvoid _tessBind(){ \r\r //#if defined (__DARWIN__)\r //#define TESSTYPE (GLvoid (*)(...))\r //#else\r //typedef GLvoid ( *GluTessCallbackType)(...);\r //#define TESSTYPE reinterpret_cast<GluTessCallbackType>\r //#endif\r /*\r \r gluTessCallback(tobj, GLU_TESS_VERTEX,\r TESSTYPE(glVertex3dv));\r gluTessCallback(tobj, GLU_TESS_BEGIN,\r TESSTYPE(JTTess_beginCallback));\r gluTessCallback(tobj, GLU_TESS_END,\r TESSTYPE(&JTTess_endCallback));\r gluTessCallback(tobj, GLU_TESS_ERROR,\r TESSTYPE(JTTess_errorCallback));\r gluTessCallback(tobj, GLU_TESS_COMBINE,\r TESSTYPE(JTTess_combineCallback)); \r gluTessProperty(tobj, GLU_TESS_WINDING_RULE,\r GLU_TESS_WINDING_POSITIVE);\r */\r}\r\r\r/* the callback routines registered by gluTessCallback() */\r\r\rvoid JTTESSCALLBACK JTTess_combineCallback(GLdouble coords[3], \r GLdouble *vertex_data[4],\r GLfloat weight[4], GLdouble **dataOut ){\r GLdouble *vertex;\r int i;\r doTessErrorCheck();\r vertex = tesscache[tessBase+tessPtr];//(GLdouble *) malloc(6 * sizeof(GLdouble));\r tessPtr++;\r vertex[0] = coords[0];\r vertex[1] = coords[1];\r vertex[2] = coords[2];\r for (i = 3; i < 7; i++)\r vertex[i] = weight[0] * vertex_data[0][i] \r + weight[1] * vertex_data[1][i]\r + weight[2] * vertex_data[2][i] \r + weight[3] * vertex_data[3][i];\r *dataOut = vertex;\r}\r\r\rvoid JTTESSCALLBACK JTTess_beginCallback(GLenum which){\r glBegin(which);\r}\r\rvoid JTTESSCALLBACK JTTess_endCallback(void)\r{\r glEnd();\r}\r\rvoid JTTESSCALLBACK JTTess_errorCallback(GLenum errorCode)\r{\r const GLubyte *estring;\r\r estring = gluErrorString(errorCode);\r fprintf (stderr, "Tessellation Error: %s\n", estring);\r exit (0);\r}\r\r\r/* new callback routines registered by these calls */\rvoid JTTESSCALLBACK JTTess_vertexCallback(GLvoid *vertex){\r const GLdouble *pointer;\r \r pointer = (GLdouble *) vertex;\r glColor3dv(pointer+3);\r glVertex3dv((const GLdouble*)vertex);\r}\r\r\r\rJoshFont *getFont(){\r return font;\r}\r\rJPoint mouse(){\r return JPoint(mouseX(),mouseY(),0);\r}\r\r/**\r saves the screen to a file. format support provided by image magick.\r supported formats: http://www.imagemagick.org/script/formats.php\r*/\rvoid saveScreen(char *filename){\r using namespace Magick; \r if(rawpixels==NULL){\r rawpixels = new unsigned char[width()*height()*3];\r }\r glReadPixels(0,0,width(),height(), GL_RGB , GL_UNSIGNED_BYTE ,rawpixels);\r \r /*\r //reverse the alpha vals.\r for(int i=0;i<width()*height();i++){\r rawpixels[i*4+3] = 255 - rawpixels[i*4+3];\r }\r */\r \r Image image(width(),height(),"RGB" , CharPixel , rawpixels);\r //image.modifyImage();\r image.flip();\r \r \r image.write(filename);//save\r //delete [] rawpixels;\r}\r\r\r\r/**\r saves the screen to a file. format support provided by image magick.\r supported formats: http://www.imagemagick.org/script/formats.php\r*/\rImage* getPixels(){\r using namespace Magick; \r if(rawpixels==NULL){\r rawpixels = new unsigned char[width()*height()*3];\r }\r glReadPixels(0,0,width(),height(), GL_RGB , GL_UNSIGNED_BYTE ,rawpixels);\r \r /*\r //reverse the alpha vals.\r for(int i=0;i<width()*height();i++){\r rawpixels[i*4+3] = 255 - rawpixels[i*4+3];\r }\r */\r \r Image*image = new Image(width(),height(),"RGB" , CharPixel , rawpixels);\r //image.modifyImage();\r image->flip();\r return image;\r}\r\r\r\r\r\r\r\r/* allocates new storage for an 8-bit image of the specified dimensions\r */\rpng_bytep* make_pixels(int width, int height) {\r int pixel_size = 3;\r //printf("debug debug debug 1\n",0);\r png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);\r if (png_ptr == NULL) {\r \r return NULL;\r }\r //printf("debug debug debug 2\n",0);\r png_bytep *row_pointers = (unsigned char **)png_malloc(png_ptr, height*sizeof(png_bytep));\r for (int i = 0; i < height; i++)\r row_pointers[i] = (unsigned char *)png_malloc(png_ptr, width*pixel_size);\r //printf("debug debug debug 3\n",0);\r \r return row_pointers;\r}\r//--------------------------------------------------------------------------------------------\r\rvoid jt_frameRate(unsigned long f){\r frameRate = f;\r}\r\r\rvoid roundedRect(int gl_style,float x1,float y1,float x2,float y2,float radius,int steps){\r float inc = (PI*0.5)/steps;\r glBegin(gl_style);\r //draw a quarter circle here.\r \r for(int i=0;i<steps;i++){\r float x = radius*cos(inc*i-PI*0.5) + x2 - radius;\r float y = radius*sin(inc*i-PI*0.5) + y1 + radius;\r glVertex2f(x,y);\r }\r\r \r for(int i=0;i<steps;i++){\r float x = radius*cos(inc*i) + x2 - radius;\r float y = radius*sin(inc*i) + y2 - radius;\r glVertex2f(x,y);\r }\r\r \r for(int i=0;i<steps;i++){\r float x = radius*cos(inc*i+PI*0.5) + x1 + radius;\r float y = radius*sin(inc*i+PI*0.5) + y2 - radius;\r glVertex2f(x,y);\r }\r\r \r for(int i=0;i<steps;i++){\r float x = radius*cos(inc*i+PI) + x1 + radius;\r float y = radius*sin(inc*i+PI) + y1 + radius;\r glVertex2f(x,y);\r }\r\r \r\r glEnd();\r}\r
\ No newline at end of file
--- /dev/null
+#ifndef __JTTOOLKIT__
+#define __JTTOOLKIT__
+
+#define DEFAULT_MOUSEX 695
+#define DEFAULT_MOUSEY 457
+
+#include <math.h>
+#include <time.h>
+#include <stdlib.h>
+#include <Magick++.h>
+
+#if defined(__DARWIN__)
+#include "png.h"
+#elif defined(linux)
+#include <png.h>
+#else
+#define NOMINMAX
+#include <windows.h>
+#include <png.h>
+//
+#endif
+
+#define PI 3.141592653
+#include "gl_et_al.h"
+
+#include <iostream.h>
+
+#include <fstream.h>
+#include "Vector.h"
+//#include <fmod.h>
+//#include <fmod_errors.h>
+
+#include "project.h"
+#include <string.h>
+#include "quadstretch.h"
+#include "JoshFont.h"
+#include "JPoint.h"
+
+
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <sched.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+
+
+
+
+#if defined(__DARWIN__)
+#define KEY_BACKSPACE 65
+#else
+#define KEY_BACKSPACE 8
+#endif
+#define KEY_DELETE 127
+
+
+using namespace Magick;
+
+//------------ user event prototypes ------------------------------
+
+void setup();
+void stop();
+void loop();
+void jttoolkit_keyDown(int key,int special);
+void jttoolkit_keyUp(int key,int special);
+void jttoolkit_mouseDown();
+void jttoolkit_mouseUp();
+
+// ----------------- user tool function prototypes ------------------------
+
+extern "C"{
+
+ void generateNumberSwarmString(int treatmentID , float rnd, char *strBuff, float num);
+
+ int main(int ,char**);
+ char* trimLeft(char*buff);
+ void drawUnitSquare();
+ void drawUnitSquareSlightlySmaller();
+
+ void viewPerspective(float angle);
+ void viewOrtho();
+
+ void roundedRect(int gl_style,float x1,float y1,float x2,float y2,float radius,int steps);
+
+ //void postQuit(JTScene *newScene);
+ //tells the system to quit out of the scene while the scene is not executing any events!
+ int jttoolkit_init();
+ void toggleFullScreen();
+
+ void exportPostscript(char *filename);
+ //exports the current frame to EPS vector-based file format.
+
+ void fileFromString( char *fname, char *data, long datasize);
+ //writes the bytes in null-terminated data string to file fname.
+
+ unsigned char* stringFromFile(char *fname);
+ //returns a file pointer to the contents of the file.
+ //when you are done using this string, free it using free(ptr);
+
+ long getFileSize( char *fname);
+ //returns the size of a file in bytes.
+
+ void getFile( char *filename, unsigned char *buff, int length);
+ //gets the contents of a file and stores it into a string.
+
+ void hideMouse();
+ //hides the mouse
+
+ void showMouse();
+ //shows the mouse
+
+ int buildScreenFont(char *fontName,int size);
+ //loads a font and returns the ID
+
+ void drawScreenFont(int fontID,char*text,int tracking);
+ //draws the font to the screen as text
+
+ void killScreenFont(int fontID);
+ //unloads the fontID (i've never needed to call this)
+
+ float randomFloat();
+ // gives you a random float between 0.0 and 1.0
+
+ void lights();
+ // enables GL lighting (defaultly off)
+
+ void nolights();
+ //disables GL lighting
+
+ float getDist(float x1,float y1,float x2,float y2);
+ void polar2rect(double r,double theta,double returnPair[2]);
+ void rect2polar(double x,double y,double returnPair[2]);
+
+
+ void line(JPoint p1,JPoint p2);
+ void bezier(JPoint p1,JPoint p2,JPoint p3,JPoint p4,int steps);
+ void interpolateBezier(float P0X,float P0Y,float P0Z,
+ float P1X,float P1Y,float P1Z,
+ float P2X,float P2Y,float P2Z,
+ float P3X,float P3Y,float P3Z,
+ int segs,float Xs[],float Ys[],float Zs[]);
+ float absf(float a);
+
+ png_bytep* make_pixels(int width, int height) ;
+
+ //removed when i went to imagemagick
+ //void saveScreenToTGAFile(char *filename);
+ //void init_saveScreen();
+
+
+ static unsigned char*rawpixels = NULL;
+ void saveScreen(char *filename);
+
+
+
+ //------------------------ internal prototypes-------------------------------
+
+
+ void display();
+ void idle();
+ void timerFunc(int v);
+ void keyboardDown(unsigned char k,int x,int y);
+ void keyboardUp (unsigned char k,int x, int y);
+ void specialFunc(int k, int x,int y);
+ void mouseMotionFunc(int x, int y);
+ void mousePassiveMotionFunc(int x, int y);
+ void mouseFunc(int state, int button, int x, int y);
+ void reshape(int w,int h);
+ void _draw_single_screenFont(int fontID, char*text);
+ void writeps(int format, int sort, int options, int nbcol, char *file);
+ void _execute_frame();//the actual frame call.
+};
+
+//----------------- useful globals for high level programmers -----------------
+
+static unsigned long _ticks = 0;
+int ticks();
+
+static unsigned long _width = 0;
+int width();
+
+static unsigned long _height = 0;
+int height();
+
+
+void ignoreMouse(int state);
+static int _ignoreMouse = 0;
+
+static unsigned long _mouseX = DEFAULT_MOUSEX;
+int mouseX();
+void setMouseX(long);
+
+static unsigned long _mouseY = DEFAULT_MOUSEY;
+int mouseY();
+void setMouseY(long);
+
+static float _friction = 0.99997f;
+float friction();
+void setFriction(float f);
+
+static float _frequencyRange = 50000;
+float frequencyRange();
+void setFrequencyRange(float f);
+
+
+//tess
+
+/// adding tesselation functionality
+#if defined(__DARWIN__)
+#define JTTESSCALLBACK
+#else
+#define JTTESSCALLBACK __stdcall
+#endif
+
+#define TESSCACHE_NEWCONTOUR 1
+
+//-some tesselation globals
+static GLdouble **tesscache;
+//static Vector*tessfreemem=0;
+static int tessPtr = 0;
+static int tessmax = 0;
+static int tessBase = 0;
+static GLUtesselator* tobj=0;
+
+
+
+void JTTessVertex(float x,float y, float z);
+void JTTessEnd();
+void JTTessInit(int memsize);
+void JTTessNewContour();
+void JTTessBegin();
+void doTessErrorCheck();
+
+void _tessBind();
+
+void JTTESSCALLBACK JTTess_combineCallback(GLdouble coords[3],
+ GLdouble *vertex_data[4],
+ GLfloat weight[4], GLdouble **dataOut );
+
+
+
+
+void JTTESSCALLBACK JTTess_vertexCallback(GLvoid *vertex);
+void JTTESSCALLBACK JTTess_errorCallback(GLenum errorCode);
+void JTTESSCALLBACK JTTess_endCallback(void);
+void JTTESSCALLBACK JTTess_beginCallback(GLenum which);
+
+//-----------------internal globals--------------------------------------------
+
+static int penta_firstloop=1;
+static unsigned long frameRate = 24;
+void jt_frameRate(unsigned long f);
+//this is misleading. it's actually the pause time in milliseconds.
+static char drawScreenFont_buff[1024*256];//text max
+static int lastGlutFrameTime=0;
+static unsigned char *drawbuffer;
+
+static int fullscreenmode = 0;
+
+void jt_resizeDrawBuffer();
+
+#if defined(__DARWIN__)
+//MAC CLASSIC
+#elif defined(linux)
+#else
+//WINDOWS
+static HWND theHwnd=0;
+#endif
+
+static JoshFont *font;
+JoshFont *getFont();
+JPoint mouse();
+Image* getPixels();
+
+
+void stopDemo();
+void loadByNumber(int num);
+
+void ignored_mouseMove(int x,int y);
+void ignored_mouseDown(int x,int y);
+void ignored_mouseUp(int x,int y);
+void keep_the_party_going();
+//-----------------------------------------------------------------------------
+#endif
+
--- /dev/null
+#define VERSION 215\r#include "jttoolkit.h"\r#include "Global.h"\r#include "JImage.h"\r\rusing namespace std;\r\rGlobal *instance;\r\rvoid setup(){\r glutSwapBuffers();//a little trick to make the window go black while it waits.\r instance = new Global();\r\r}\r\rvoid loop(){\r instance->loop();\r}\r\rvoid jttoolkit_keyDown(int k,int special){\r if(k==27){\r exit(0);\r }\r instance->keyDown(k,special);\r}\r\rvoid jttoolkit_keyUp(int k,int special){}\r\rvoid jttoolkit_mouseDown(){\r instance->mouseDown();\r \r}\r\rvoid jttoolkit_mouseUp(){\r instance->mouseUp();\r}\r\rvoid stop(){\r}\r\rvoid ignored_mouseMove(int x,int y){\r}\r\r\rvoid ignored_mouseDown(int x,int y){\r \r}\r\rvoid ignored_mouseUp(int x,int y){\r}\r
\ No newline at end of file
--- /dev/null
+#ifndef _QUADSTRETCH_H_
+#define QUADSTRETCH_H_
+
+
+void intersect_lines2(float x0,float y0,float x1,float y1,float x2,float y2,float x3,float y3,float &xi,float &yi);
+
+void interpolatePoints2(float x1,float y1,float x2,float y2,float i,float &x,float &y);
+
+void quadstretch(float x,float y,float l,float t,
+ float w,float h,float *qx,float *qy,float *ret);
+
+
+void quadStretch2(float x,float y,float l,float t,float w,float h,float *q,float &newx,float &newy);
+
+void interpolatePoints(float x1,float y1,
+ float x2,float y2,float i,float *ret);
+
+void intersect_lines(float x0,float y0,float x1,
+ float y1,float x2,float y2,
+ float x3,float y3,float *ret);
+
+int intersectLineSegs(float x1,float y1,
+ float x2,float y2,
+ float x3,float y3,
+ float x4,float y4);
+
+#endif
--- /dev/null
+#include "ArrowVector.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+ArrowVector::ArrowVector(float xx,float yy,float zz){
+ this->x = xx;
+ this->y = yy;
+ this->z = zz;
+ theta=0;
+ destTheta=0;
+ radius=40;
+ destRadius = 40;
+ glLineWidth(3);
+ for(int i=0;i<10;i++){
+ rnd.push_back(randomFloat());
+ }
+ lowerHalf = ((900-x) < y*1.2);
+}
+
+
+void ArrowVector::reset(){
+ theta=0;
+ destTheta=0;
+ radius=30;
+ destRadius=30;
+}
+
+ArrowVector::~ArrowVector(){
+
+}
+
+void ArrowVector::draw(){
+
+ //am i in the upper triangle or the lower?
+
+
+ //i was going to record a nice mouse track for this
+ //cout << mouseX() << ' ' << mouseY() << endl;
+
+ glColor4f(1,1,1,0.3);
+ //step
+
+ //get thetas for everyone.
+
+ float accum = 0;
+ for(int i=0;i<Global::instance->edies.size();i++){
+ float d = this->distanceFrom(*Global::instance->edies[i]);
+ //d = 1-d*0.001;
+ accum += this->thetaFrom(*Global::instance->edies[i]);
+ }
+ destTheta = accum/Global::instance->edies.size();
+ //flip around fixits
+
+ if(destTheta-theta>(PI))theta+=PI*2.0;
+ else if(theta-destTheta>(PI))theta-=PI*2.0;
+
+
+ float faultStrength;
+
+ faultStrength = fmax(0.01,(1-fabs(y-(1280-x-400))*0.0005));
+
+
+ //overshooting to make conical effect
+ float spreadAmount = 0.1;
+ if(lowerHalf){
+ destTheta -= pow(faultStrength,4)*spreadAmount;
+ }else{
+ destTheta += pow(faultStrength,4)*spreadAmount;
+ }
+
+
+
+
+ theta += (destTheta-theta)*pow(faultStrength,4)*0.5;
+
+
+ radius += (destRadius-radius)*faultStrength*0.05;
+ // * (theta+PI/2)/(PI*2) * 200 * rnd[0];
+
+ JPoint tip;
+
+ tip.x = x + cos(theta)*radius;
+ tip.y = y + sin(theta)*radius;
+ tip.z = z;
+
+ float headSize = 0.45;
+
+
+ float r = 40;//radius softening
+
+ JPoint arrowEdge1;
+ arrowEdge1.x = tip.x + cos(PI+theta-0.5)*r*headSize;
+ arrowEdge1.y = tip.y + sin(PI+theta-0.5)*r*headSize;
+ arrowEdge1.z = tip.z;
+
+
+ JPoint arrowEdge2;
+ arrowEdge2.x = tip.x + cos(PI+theta+0.5)*r*headSize;
+ arrowEdge2.y = tip.y + sin(PI+theta+0.5)*r*headSize;
+ arrowEdge2.z = tip.z;
+
+ JPoint arrowPoint;
+ arrowPoint.x = tip.x + cos(PI+theta)*(r*headSize - 22);
+ arrowPoint.y = tip.y + sin(PI+theta)*(r*headSize - 22);
+ arrowPoint.z = tip.z;
+
+ Edie *e = Global::instance->edies[0];
+ active = ((e->x)+e->y)*10.5-8000 < (x+(1000-y));
+
+
+ //affected by the wind screen yet?
+ destRadius += ( (60+faultStrength) - destRadius)*0.2;//snapping back
+ if(active && e->x > 0){
+ destRadius += rnd[0]*400*pow(faultStrength,4);//random radius variance per arrow fingerprint - scaled by a time-based backward pull
+ }
+
+ float gradient_alpha;
+
+ if(active){
+ gradient_alpha = pow(faultStrength,3);
+ }else{
+ gradient_alpha = 1;
+ }
+ glColor4f(1,1, (theta+PI/2)/(PI*2) ,gradient_alpha);
+ old_active=active;
+
+ //draw
+
+ glPushMatrix();
+
+
+ glBegin(GL_LINES);
+ glVertex();
+ tip.glVertex();
+ glEnd();
+
+
+ glBegin(GL_POLYGON);
+ arrowPoint.glVertex();
+ arrowEdge1.glVertex();
+ arrowEdge2.glVertex();
+ glEnd();
+
+
+ glPushMatrix();
+ (tip+JPoint(80,200,0)).glTranslate();
+ JoshFont*f=getFont();
+ char s[64];
+ sprintf(s,"%2.2f",theta);
+ if(x>900 || y > 831)f->drawString(s,75,1);
+
+ glPopMatrix();
+
+
+
+ glPopMatrix();
+}
--- /dev/null
+#ifndef _ArrowVector_H_
+#define _ArrowVector_H_
+#include "JPoint.h"
+#include <vector>
+
+using namespace std;
+
+class ArrowVector:public JPoint{
+ public:
+ bool active;
+ bool old_active;
+ bool lowerHalf;
+ vector<float> rnd;
+ float destTheta;
+ float theta;
+ float radius;
+ float destRadius;
+ ArrowVector(float ,float ,float);
+ ~ArrowVector();
+ void draw();
+ void reset();
+};
+
+
+
+#endif
+
--- /dev/null
+#include "Athletes.h"
+#include "Global.h"
+#include "gl_et_al.h"
+#include "Guy.h"
+#include "obj.h"
+#include "JPoint.h"
+
+using namespace obj4gl;
+
+
+Athletes::Athletes(){
+ //load the OBJ
+ OBJ *obj = new OBJ("media/footBall_objs/footballman4.obj");
+ int list = glGenLists(1);
+ glNewList(list,GL_COMPILE);
+ obj->outlineFaces();
+ glEndList();
+
+ //make new guys
+ JPoint p;
+ for(int i=0;i<22;i++){
+ Global::instance->field.randomPoint(&p);
+ guys.push_back(Guy(list,p.x,p.y,i>11,i));
+ }
+}
+
+Athletes::~Athletes(){
+
+}
+
+void Athletes::step(){
+ deque<Guy>::iterator iter;
+ for(iter=guys.begin();iter!=guys.end();iter++){
+ (*iter).step();
+ }
+}
+
+
+void Athletes::draw(){
+
+ deque<Guy>::iterator iter;
+ for(iter=guys.begin();iter!=guys.end();iter++){
+ glPushMatrix();
+ (*iter).draw();
+ glPopMatrix();
+ }
+}
+
--- /dev/null
+#ifndef _Athletes_H_
+#define _Athletes_H_
+#include "Satellite.h"
+#include "Guy.h"
+#include <deque>
+
+using namespace std;
+
+class Athletes : public Satellite {
+ public:
+ deque<Guy> guys;
+ Athletes();
+ ~Athletes();
+ void step();
+ void draw();
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "BallPathTracer.h"
+#include "jttoolkit.h"
+
+BallPathTracer::BallPathTracer(){
+
+}
+
+BallPathTracer::~BallPathTracer(){
+
+}
+
+void BallPathTracer::step(){
+ path.push_back(JPoint(Global::instance->ball->x,Global::instance->ball->y,Global::instance->ball->z));
+ if(path.size()>100){
+ JPoint p = path.front();
+ path.pop_front();
+ if(p.z==0)killThese.push_back(p);
+ }
+
+
+ //grow the upcoming signs
+ vector<JPoint> dropflags;
+ if(path.size()>0){
+ for(int i=0;i<path.size();i++){
+ JPoint p = path[i];
+ if(p.z==0)dropflags.push_back(p);
+ }
+ }
+
+ for(int i=0;i<dropflags.size();i++){
+ JPoint p = (dropflags[i]);
+ flagMap[p]+= (30-flagMap[p])*0.1;
+ }
+
+
+ for(int i=0;i<killThese.size();i++){
+ JPoint p = killThese[i];
+ flagMap[p]+= (0-flagMap[p])*0.5;
+ }
+
+
+ // just a spot of memory management
+ if(killThese.size()>0){
+ if(flagMap[killThese.front()]<1){
+ flagMap[killThese.front()]=0;
+ killThese.pop_front();
+ }
+ }
+}
+
+void BallPathTracer::draw(){
+
+ vector<JPoint> dropflags;
+
+ glColor4f(1,1,1,0.5);
+ glEnable(GL_LINE_STIPPLE);
+ glLineStipple(Global::instance->worldScale*3,0x5555);
+ glBegin(GL_LINE_STRIP);
+
+ if(path.size()>0){
+ for(int i=0;i<path.size();i++){
+ JPoint p = path[i];
+ if(p.z==0){
+ glEnd();
+ glBegin(GL_LINE_STRIP);
+ dropflags.push_back(p);
+ }
+ p.glVertex();
+ }
+ }
+
+ glEnd();
+ glDisable(GL_LINE_STIPPLE);
+
+
+ //ok, now draw the dropflags.
+ for(int i=0;i<dropflags.size();i++)drawFlag(dropflags[i]);
+ for(int i=0;i<killThese.size();i++)drawFlag(killThese[i]);
+
+}
+
+void BallPathTracer::drawFlag(JPoint p){
+ //increment the sign distance
+
+ glColor4f(1,1,1,0.8);
+ glBegin(GL_LINES);
+ glVertex3f(p.x,p.y,p.z+10);
+ glVertex3f(p.x,p.y,p.z+10+flagMap[p]);
+ glEnd();
+
+ glPushMatrix();
+ glTranslatef(p.x,p.y,p.z+10+flagMap[p]);
+ glRotatef(90,1,0,0);
+ glRotatef(Global::instance->tumbleY,0,1,0);//auto-orient , billboard, lookAtCamera
+ //glRectf(-2,-2,2,2);
+
+ JoshFont *f = getFont();
+ glTranslatef(-1,-1,0);
+ glRotatef(180,0,0,1);
+ glRotatef(180,0,1,0);
+
+ char txt[64];
+ sprintf(txt,"%i",(int)p.y);
+
+ f->drawString(txt,2,5);
+ glPopMatrix();
+
+ //draw arrow
+ glPushMatrix();
+ glTranslatef(p.x,p.y,p.z+10);
+ glRotatef(Global::instance->tumbleY+90,0,0,1);//auto-orient , billboard, lookAtCamera
+ glBegin(GL_POLYGON);
+ glVertex3f(0,0,0);
+ glVertex3f(0,-1,2);
+ glVertex3f(0,0,1);
+ glVertex3f(0,1,2);
+ glEnd();
+ glPopMatrix();
+
+}
--- /dev/null
+#ifndef _BallPathTracer_H_
+#define _BallPathTracer_H_
+
+#include "JPoint.h"
+#include "Global.h"
+#include "Satellite.h"
+#include <map>
+
+//some rules for the map
+struct ltjpoint{
+ bool operator()(const JPoint s1,const JPoint s2)const{
+ return (s1.x*100 + s1.y*50 + s1.z) > (s2.x*100 + s2.y*50 + s2.z);
+ }
+};
+
+
+class BallPathTracer : public Satellite {
+ public:
+ map<JPoint, float, ltjpoint> flagMap;
+ deque<JPoint>killThese;
+ deque<JPoint> path;
+ BallPathTracer();
+ ~BallPathTracer();
+ void step();
+ void draw();
+ void drawFlag(JPoint p);
+};
+
+
+
+#endif
+
--- /dev/null
+#include "BallPointer.h"
+
+#include "Global.h"
+#include "gl_et_al.h"
+#include "jttoolkit.h"
+
+BallPointer::BallPointer(){
+ x = Global::instance->ball->x;
+ y = Global::instance->ball->y;
+ z = Global::instance->ball->z;
+
+}
+
+BallPointer::~BallPointer(){
+
+}
+
+
+void BallPointer::step(){
+
+ x += (Global::instance->ball->x - x)*0.05;
+ y += (Global::instance->ball->y - y)*0.05;
+ z += (Global::instance->ball->z - z)*0.05;
+
+}
+
+void BallPointer::draw(){
+
+ glEnable(GL_LINE_SMOOTH);
+ glLineWidth(10);
+ //draw the line - one part lags behind.
+ glColor4f(1,1,1,0.05);
+ glBegin(GL_LINE_STRIP);
+ glVertex3f(
+ Global::instance->ball->x,
+ Global::instance->ball->y,
+ Global::instance->ball->z + 5);
+ glVertex3f(
+ Global::instance->ball->x,
+ Global::instance->ball->y,
+ Global::instance->ball->z + 50);
+ glVertex3f(x,y,z + 90);
+ glEnd();
+
+
+
+
+ //draw circle around ball
+ glPushMatrix();
+ glTranslatef(Global::instance->ball->x,
+ Global::instance->ball->y,
+ Global::instance->ball->z);
+
+ glRotatef(90,1,0,0);
+ glRotatef(Global::instance->tumbleY,0,1,0);//auto-orient , billboard, lookAtCamera
+ glBegin(GL_LINE_LOOP);
+ float rad = 5;
+ float steps = 45;
+ float inc = (PI*2)/steps;
+ for(int i=0;i<steps;i++){
+ float x = cos(inc*i)*rad;
+ float y = sin(inc*i)*rad;
+ glVertex2f(x,y);
+ }
+ glEnd();
+ glPopMatrix();
+
+
+
+ //draw some text
+ glPushMatrix();
+ glTranslatef(x,y,z+21);
+ JoshFont *f = getFont();
+ glTranslatef(0,0,90);
+ glRotatef(90,1,0,0);
+ glRotatef(180,0,0,1);
+ glRotatef(Global::instance->tumbleY+180,0,-1,0);//auto-orient , billboard, lookAtCamera
+ glTranslatef(-3,13,0);
+ char s[256];
+ sprintf(s,"Ball\nX=%1.1f\nY=%1.1f\nZ=%1.1f",
+ Global::instance->ball->x,
+ Global::instance->ball->y,
+ Global::instance->ball->z);
+ glColor4f(1,1,1,0.4);
+ f->drawString(s,2,0.7);
+ glPopMatrix();
+
+
+
+
+ glLineWidth(1);
+ // //draw a rect around the info box.
+ // glPushMatrix();
+ // glTranslatef(x,y,z + 90);
+ // glRotatef(90,1,0,0);
+ // glRotatef(Global::instance->tumbleY,0,1,0);//auto-orient , billboard, lookAtCamera
+ // glTranslatef(-20,0,0);
+ // glBegin(GL_LINE_LOOP);
+ // glVertex2f(0,0);
+ // glVertex2f(50,0);
+ // glVertex2f(50,50);
+ // glVertex2f(0,50);
+ // glEnd();
+ // glPopMatrix();
+}
+
--- /dev/null
+#ifndef _BallPointer_H_
+#define _BallPointer_H_
+
+#include "Satellite.h"
+
+class BallPointer:public Satellite {
+ public:
+
+ float x;
+ float y;
+ float z;
+
+ BallPointer();
+ ~BallPointer();
+
+ void step();
+ void draw();
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "Client.h"
+
+Client::Client(){
+ state=0;
+ shape =randomFloat();
+ size = randomFloat();
+ rotation = randomFloat();
+ interp=0;
+ spinX=randomFloat();
+ spinY=randomFloat();
+ spinZ=randomFloat();
+ drawMode=randomFloat();
+
+ spokeCount = randomFloat();
+ radius = randomFloat();
+
+}
+
+Client::~Client(){
+
+}
+
+void Client::draw(){
+ if(state==2){
+ interp += ( 0 - interp) * 0.1;
+ }else{
+ interp += ( 1 - interp) * 0.1;
+ }
+
+ glScalef(interp*size*max_size,interp*size*max_size,0);
+ glRotatef(spinX*ticks()*spin_scalar,1,0,0);
+ glRotatef(spinY*ticks()*spin_scalar,0,1,0);
+ glRotatef(spinZ*ticks()*spin_scalar,0,0,1);
+
+ if(drawMode>0.0 && drawMode<=0.3){
+ glBegin(GL_LINE_LOOP);
+ }else if(drawMode>0.3 && drawMode<=0.7){
+ glBegin(GL_TRIANGLE_FAN);
+ }else if(drawMode>0.7 && drawMode>=1){
+ glBegin(GL_POINTS);
+ }
+
+
+ int steps = round(shape*10);
+ float inc = (PI*2)/steps;
+ float r = interp*size;
+ for(int i=0;i<steps;i++){
+ float x = r * cos(i*inc + rotation*PI);
+ float y = r * sin(i*inc + rotation*PI);
+ glVertex2f(x,y);
+ }
+ glEnd();
+
+
+ glBegin(GL_LINES);
+ steps = round(spokeCount*10);
+ inc = (PI*2)/steps;
+ for(int i=0;i<steps;i++){
+ float x = radius*3 * cos(i*inc + rotation*PI);
+ float y = radius*3 * sin(i*inc + rotation*PI);
+ glVertex2f(x,y);
+ glVertex2f(0,0);
+ }
+ glEnd();
+
+
+
+
+}
+
+void Client::changeState(int s){
+ state = s;
+}
--- /dev/null
+#ifndef _Client_H_
+#define _Client_H_
+#include "jttoolkit.h"
+
+class Client{
+ private:
+ static const float max_size=20.0;
+ static const float spin_scalar=5.0;
+ int state;
+ float shape;
+ float size;
+ float rotation;
+ float interp;
+ float drawMode;
+
+ float spinX;
+ float spinY;
+ float spinZ;
+
+ float radius;
+ float spokeCount;
+
+ public:
+ Client();
+ ~Client();
+ void changeState(int state);
+ void draw();
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "Clover.h"
+#include "jttoolkit.h"
+#include "Global.h"
+#include "GameGrid.h"
+
+vector<char*> Clover::phrases;
+
+Clover::Clover(GameGrid *_parent){
+ parent = _parent;
+ size=0;
+ lag_rotateX=0;
+ lag_rotateY=0;
+ rotateX=0;
+ rotateY=0;
+ counter=0;
+ for(int i=0;i<10;i++){
+ rnd.push_back(randomFloat());
+ }
+ label[0]=0;
+}
+
+void Clover::syncDest(){
+ dest.x=x;
+ dest.y=y;
+ dest.z=z;
+}
+
+Clover::~Clover(){
+
+}
+
+void Clover::softReset(){
+ dest.y = 0;
+ rotateX = 0;
+ rotateY = 0;
+}
+
+void Clover::step(){
+ lag_rotateX+=(rotateX-lag_rotateX)*0.3;
+ lag_rotateY+=(rotateY-lag_rotateY)*0.3;
+
+ (*this)+=(dest-(*this))*0.4;//move towards destx
+
+ if(counter% (int)( rnd[0]*500+1 )==0){
+ rotateX = round(randomFloat()*8-4)*90;
+ rotateY = round(randomFloat()*8-4)*90;
+ if(randomFloat()>0.5){
+ dest.y += (randomFloat()-0.5)*10;
+ }else{
+ dest.y = parent->slide;
+ }
+ }
+
+
+ counter++;
+}
+
+
+float Clover::getActivity(){
+ JPoint p = (*this)-dest;
+ float drx = fabs(rotateX-lag_rotateX);
+ float dry = fabs(rotateY-lag_rotateY);
+ return p.x+p.y+p.z+drx+dry ;
+}
+
+void Clover::draw(int listID){
+ glPushMatrix();
+ glTranslate();
+
+ float act = getActivity();
+ act*=0.01;
+ if(act<1)act=1;
+
+ glScalef(size,size,size);
+ glRotatef(90,1,0,0);
+ glRotatef(lag_rotateX,0,1,0);
+ glRotatef(lag_rotateY,1,0,0);
+
+ //draw the clover.
+ glPushMatrix();
+ glScalef(act,act,act);
+ glCallList(listID);
+ glPopMatrix();
+
+
+ //draw the cros hair thing
+ glColor4f(1,1,1,0.2);
+ float s = 3;
+ glBegin(GL_LINES);
+ glVertex3f(-s,0,0);
+ glVertex3f(s,0,0);
+ glVertex3f(0,-s,0);
+ glVertex3f(0,s,0);
+ glEnd();
+
+
+
+ //draw the glass pain
+ s= 5;
+ glColor4f(1,1,1,0.03);
+ glBegin(GL_POLYGON);
+ glVertex3f(-s,-s,0);
+ glVertex3f( s,-s,0);
+ glVertex3f( s, s,0);
+ glVertex3f(-s, s,0);
+ glEnd();
+
+
+ //draw some text
+ glColor4f(1,1,1,0.5);
+ JoshFont *f = getFont();
+ glRotatef(180,0,0,1);
+ glTranslatef(-5,2,0);
+
+ char *thisPhrase = phrases[rnd[1]*phrases.size()];
+ sprintf(label,"%s",thisPhrase);
+ label[counter%strlen(thisPhrase)] = 0;
+ f->drawString(label,1,0);
+
+
+ glPopMatrix();
+
+
+ //connect the clover to lense
+ Global::instance->lenseLine((*this),1,1,1,0.05);
+
+}
--- /dev/null
+#ifndef _Clover_H_
+#define _Clover_H_
+
+#include "JPoint.h"
+#include "jttoolkit.h"
+
+class GameGrid;
+
+class Clover : public JPoint{
+ public:
+ static vector<char*> phrases;
+ float size;
+ float rotateX;
+ float rotateY;
+ float lag_rotateX;
+ float lag_rotateY;
+ char label[256];
+ vector<float> rnd;
+ JPoint dest;
+ GameGrid *parent;
+ int counter;
+ Clover(GameGrid *_parent);
+ ~Clover();
+ void step();
+ void syncDest();
+ void draw(int listID);
+ void softReset();
+ float getActivity();
+};
+
+
+
+#endif
+
--- /dev/null
+#include "DieingParent.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+DieingParent::DieingParent(JPoint t){
+ for(int i=0;i<5;i++)rnd.push_back(randomFloat());
+ copyFrom(t);
+}
+
+DieingParent::~DieingParent(){
+
+}
+
+void DieingParent::step(){
+ lerpSelfTo(JPoint(0,0,0),0.4);
+}
+
+void DieingParent::draw(int counter,JPoint end){
+
+}
+
--- /dev/null
+#ifndef _DieingParent_H_
+#define _DieingParent_H_
+
+
+#include "JPoint.h"
+#include "TreeNode.h"
+#include <vector>
+
+using namespace std;
+
+class TreeNode;
+
+class DieingParent : public JPoint{
+ public:
+
+
+
+ vector<float> rnd;
+ DieingParent(JPoint t);
+ ~DieingParent();
+
+ void step();
+ void draw(int counter,JPoint end);
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "Edie.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+Edie::Edie(float xx,float yy,float zz):JPoint(xx,yy,zz){
+
+}
+
+Edie::Edie(){
+ for(int i=0;i<5;i++)rnd.push_back(randomFloat());
+
+}
+
+Edie::~Edie(){
+
+}
+
+void Edie::step(){
+
+}
+
+void Edie::draw(){
+ glPushMatrix();
+ glTranslate();
+ glRectf(-3,-3,3,3);
+ glPopMatrix();
+}
+
--- /dev/null
+#ifndef _Edie_H_
+#define _Edie_H_
+
+
+#include "JPoint.h"
+#include <vector>
+
+using namespace std;
+
+class Edie : public JPoint{
+ public:
+ vector<float> rnd;
+ Edie();
+ ~Edie();
+
+ void step();
+ void draw();
+ Edie(float xx,float yy,float zz);
+};
+
+
+
+#endif
+
--- /dev/null
+#include "FXImg.h"
+#include "gl_et_al.h"
+
+FXImg::FXImg(char*filename):JImage(filename){
+ leftEatAwayPosition = 0;
+
+ int rndcount = rows()*9;
+
+ rnd = new float[rndcount];
+ eaters = new float[rows()];
+
+ for(int i=0;i<rows();i++){
+ eaters[i] = 0;
+ }
+
+ for(int i=0;i<rndcount;i++){
+ rnd[i] = randomFloat();
+
+ }
+}
+
+FXImg::~FXImg(){
+ delete [] rnd;
+ delete [] eaters;
+}
+
+void FXImg::brushedSteelFade(){
+ brushedSteelFade(20,10);
+}
+
+void FXImg::brushedSteelFade(float mag,int insurance){
+ for(int y=0;y<rows();y++){
+ for(int x=0;x<columns();x++){
+ Color c1(pixels[ y *columns()+x]);
+ float a = c1.alphaQuantum();
+ float r = rnd[y*3]*mag;
+ if(y<22 || y>rows()-22)r=20;//force top and bottoms to go fast. border thing.
+ a += r + insurance;
+ if(a>MaxRGB)a = MaxRGB;
+ c1.alphaQuantum(a);
+ pixels[ y *columns()+x] = c1;
+ }
+ }
+}
+
+
+void FXImg::stepLeftEatAway(){
+ stepLeftEatAway(4);
+}
+
+void FXImg::stepLeftEatAway(int chase){
+
+ for(int steps=0;steps<5;steps++){
+ for(int y=0;y<rows();y++){
+ if(eaters[y]<=columns()){
+ int x = columns() - eaters[y] - 1;
+ Color c1(pixels[ y *columns()+x]);
+
+ float a = c1.alphaQuantum();
+ a += 300;
+ if(a>MaxRGB)a = MaxRGB;
+
+ c1.alphaQuantum(a);
+ pixels[ y *columns()+x] = c1;
+ eaters[y] += rnd[y*2]*0.9+0.1;
+ }
+ }
+ }
+
+
+ //gradient chaser
+ for(int steps=0;steps<3;steps++){
+ for(int y=0;y<rows();y++){
+ for(int x=0;x<columns();x++){
+ if((columns()-x)<leftEatAwayPosition){
+ Color c1(pixels[ y *columns()+x]);
+ float a = c1.alphaQuantum();
+ a += chase;//just make it more transparent, evenly.
+ if(a>MaxRGB)a = MaxRGB;
+ c1.alphaQuantum(a);
+ pixels[ y *columns()+x] = c1;
+ }
+ }
+ }
+ leftEatAwayPosition++;
+ }
+
+
+
+
+}
+
+void FXImg::killRandomPixel(){
+ int x = (int)(columns()*randomFloat());
+ int y = (int)(rows()*randomFloat());
+ Color c(pixels[y*columns()+x]);
+ c.alphaQuantum(MaxRGB);
+ pixels[y*columns()+x] = c;
+}
+
+void FXImg::drawAsQuadStrip(deque<Point*> pts){
+ glBindTexture(GL_TEXTURE_2D,textureID);
+ glBegin(GL_TRIANGLE_STRIP);
+ for(int i=0;i<pts.size();i++){
+ glTexCoord2f(pts[i]->texX,pts[i]->texY);
+ glVertex2f(pts[i]->x,pts[i]->y);
+ }
+ glEnd();
+}
+
+void FXImg::drawQuadStripAsWireframe(deque<Point*> pts){
+ glBindTexture(GL_TEXTURE_2D,0);
+ glEnable(GL_LINE_SMOOTH);
+ glBegin(GL_LINES);
+
+ //draw track spokes.
+ for(int i=0;i<pts.size();i++){
+ glVertex2f(pts[i]->x,pts[i]->y);
+ }
+
+ float steps = 128;
+ float inc = 1/steps;
+
+ if(pts.size()>1){
+ for(int i=1;i<pts.size()/2;i++){
+
+ for(int j=0;j<=steps;j++){
+ float px1 = pts[i*2]->x + (pts[i*2+1]->x - pts[i*2]->x)*inc*j;
+ float py1 = pts[i*2]->y + (pts[i*2+1]->y - pts[i*2]->y)*inc*j;
+ float px2 = pts[i*2-2]->x + (pts[i*2-1]->x - pts[i*2-2]->x)*inc*j;
+ float py2 = pts[i*2-2]->y + (pts[i*2-1]->y - pts[i*2-2]->y)*inc*j;
+ glVertex2f(px1,py1);
+ glVertex2f(px2,py2);
+ }
+ }
+ }
+
+ glEnd();
+}
+
+
+
+void FXImg::drawQuadStripAsHairs(deque<Point*> pts,float start,float end){
+ glBindTexture(GL_TEXTURE_2D,textureID);
+ //glEnable(GL_LINE_SMOOTH);
+ //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
+
+ float taper_to_fluff_ratio = 0.5;
+ // float crossoverScaler = 0.000008;
+ float crossoverScaler = 0.025;
+ float steps = rows()*2;
+ float inc = 1/steps;
+
+ float ptss2 = pts.size()/2;
+ if(pts.size()>1){
+ for(int j=0;j<=steps;j++){
+ glBegin(GL_LINE_STRIP);
+ for(int i=0;i<ptss2;i++){
+ if(i>=start*ptss2 && i<end*ptss2){
+ float mx1 = pts[i*2]->x + (pts[i*2+1]->x - pts[i*2]->x)*inc*steps*0.5;
+ float my1 = pts[i*2]->y + (pts[i*2+1]->y - pts[i*2]->y)*inc*steps*0.5;
+
+ float px1 = pts[i*2]->x + (pts[i*2+1]->x - pts[i*2]->x)*inc*j;
+ float py1 = pts[i*2]->y + (pts[i*2+1]->y - pts[i*2]->y)*inc*j;
+
+ float destScalar1 = crossoverScaler*pow(i,2);//*rnd[j*2+1];
+ if(rnd[j*2+1]>taper_to_fluff_ratio)destScalar1 = -destScalar1;
+ else destScalar1 = fmin(0.5,destScalar1);
+
+ px1 += (mx1 - px1)*destScalar1;
+ py1 += (my1 - py1)*destScalar1;
+
+ float tx1 = pts[i*2]->texX + (pts[i*2+1]->texX - pts[i*2]->texX)*inc*j;
+ float ty1 = pts[i*2]->texY + (pts[i*2+1]->texY - pts[i*2]->texY)*inc*j;
+
+ glTexCoord2f(tx1,ty1); glVertex2f(px1,py1);
+ }
+ }
+ glEnd();
+ }
+ }
+}
--- /dev/null
+#ifndef _FXImg_H_
+#define _FXImg_H_
+
+#include "JImage.h"
+#include "Point.h"
+#include <Magick++.h>
+#include <vector>
+#include <deque>
+
+using namespace Magick;
+using namespace std;
+
+class FXImg : public JImage{
+ float *rnd;
+ float *eaters;
+ public:
+ int leftEatAwayPosition;
+ FXImg(char *filename);
+ ~FXImg();
+ void killRandomPixel();
+ void stepLeftEatAway();
+ void stepLeftEatAway(int chase);
+ void drawAsQuadStrip(deque<Point*>);
+ void drawQuadStripAsWireframe(deque<Point*>);
+ void drawQuadStripAsHairs(deque<Point*>,float start,float end);
+ void brushedSteelFade();
+ void brushedSteelFade(float mag,int insurance);
+};
+
+#endif
--- /dev/null
+#include "FluxDiagram.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+FluxDiagram::FluxDiagram(float position){
+ pos = position;
+ nodes.push_back(new TreeNode(NULL,0));
+}
+
+FluxDiagram::~FluxDiagram(){
+
+}
+
+void FluxDiagram::step(){
+ //step all the treenodes
+ deque<TreeNode*>::iterator i;
+ for(i=nodes.begin();i!=nodes.end();i++){
+ (*i)->step();
+ }
+}
+
+
+void FluxDiagram::draw(){
+
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+ glPushMatrix();
+ glTranslatef(0,pos,-10);
+ //step all the treenodes
+ deque<TreeNode*>::iterator i;
+ for(i=nodes.begin();i!=nodes.end();i++){
+ (*i)->draw();
+ }
+ glPopMatrix();
+}
+
--- /dev/null
+#ifndef _FluxDiagram_H_
+#define _FluxDiagram_H_
+
+
+#include "Satellite.h"
+#include "TreeNode.h"
+
+class FluxDiagram : public Satellite{
+ public:
+ float pos;
+ deque<TreeNode*> nodes;
+ FluxDiagram(float position);
+ ~FluxDiagram();
+
+ void step();
+ void draw();
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "GameGrid.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+
+GameGrid::GameGrid(float sld):Satellite(){
+ steps = 7;
+ slide=sld;
+ boardHeight = 100;
+ for(int i=0;i<100;i++){
+ rnd.push_back(randomFloat());
+ }
+ clover.load("media/christianisms/clover.png");
+
+ Clover::phrases.push_back("If Joe throws the ball to Bill, Evan needs to run and block the second offensive man.");
+ Clover::phrases.push_back("Assuming Mr. Kim caught the pass on play #353, run 20 yards past the quarterback.");
+ Clover::phrases.push_back("Quarterback jumps over other quarterback then catch the ball.");
+ Clover::phrases.push_back("Throw the ball to the other player and run away.");
+ Clover::phrases.push_back("Block the receiving 45. Sneak past the offensive line and touch down gracefully.");
+ Clover::phrases.push_back("In play 238, the eagle crows when the lizard finds the sacred egg. No bluffing!");
+
+ createCloverList();
+ populateSpots();
+}
+
+
+
+void GameGrid::createCloverList(){
+ //make clover shape.
+ cloverList = glGenLists(1);
+ glNewList(cloverList,GL_COMPILE);
+ glColor4f(1,1,1,0.3);
+#define DRAWBALL glutSolidSphere(0.13,6,6)
+ DRAWBALL;
+
+ glPushMatrix();
+ glTranslatef(0.35,0,0);
+ DRAWBALL;
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(-0.35,0,0);
+ DRAWBALL;
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(0,0.35,0);
+ DRAWBALL;
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(0,-0.35,0);
+ DRAWBALL;
+ glPopMatrix();
+#undef DRAWBALL
+
+ glEndList();
+}
+
+void GameGrid::populateSpots(){
+ //populate spots.
+ JRect f = Global::instance->field;
+ float incX = f.width() /steps;
+ float incY = boardHeight/steps;
+
+ for(int yi=1;yi<steps;yi++){
+ for(int xi=1;xi<steps;xi++){
+ float x = f.x1 + incX*xi;
+ float y = boardHeight - incY*yi;
+ Clover c(this);
+ c.x = x;
+ c.y = slide;
+ c.z = y;
+ c.size = 2;
+ c.syncDest();//so the dest is there too
+ spots.push_back(c);
+ }
+ }
+}
+
+GameGrid::~GameGrid(){
+
+}
+
+
+
+void GameGrid::step(){
+ //step the clovers
+ for(deque<Clover>::iterator i=spots.begin() ; i!=spots.end() ; i++){
+ (*i).step();
+ }
+
+
+ //swap positions?
+ Clover c1 = spots[(int)(randomFloat()*spots.size())];
+ Clover c2 = spots[(int)(randomFloat()*spots.size())];
+ c1.dest.swap(c2.dest);
+
+
+ //reset everyone?
+ if(randomFloat()>0.999){
+ for(deque<Clover>::iterator i=spots.begin() ; i!=spots.end() ; i++){
+ (*i).softReset();
+ }
+ }
+
+
+}
+
+
+
+void GameGrid::draw(){
+
+ /*
+ //make canvas
+ glColor4f(1,1,1,0.05);
+ glBegin(GL_POLYGON);
+ glVertex3f( Global::field.x2 , 0 , 0 );
+ glVertex3f( Global::field.x1 , 0 , 0 );
+ glVertex3f( Global::field.x1 , 0 , boardHeight );
+ glVertex3f( Global::field.x2 , 0 , boardHeight );
+ glEnd();
+ */
+
+ //draw rects.
+
+
+ //draw the clovers
+ for(deque<Clover>::iterator i=spots.begin() ; i!=spots.end() ; i++){
+ (*i).draw(cloverList);
+ }
+
+ //connect the clovers based on random vals.
+
+ glColor4f(1,0.5,0,0.2);
+ glBegin(GL_LINES);
+ for(int i=3;i<20;i++){
+ Clover c1 = spots[rnd[i]*spots.size()];
+ Clover c2 = spots[rnd[i-1]*spots.size()];
+ Clover c3 = spots[rnd[i-2]*spots.size()];
+ Clover c4 = spots[rnd[i-3]*spots.size()];
+ bezier(c1,c2,c3,c4,100);
+ }
+ glEnd();
+}
--- /dev/null
+#ifndef _GameGrid_H_
+#define _GameGrid_H_
+
+#include "Satellite.h"
+#include "JImage.h"
+#include "Clover.h"
+#include <deque>
+
+class GameGrid : public Satellite{
+ public:
+ vector<float> rnd;
+ int steps;
+ float slide;
+ float boardHeight;
+ deque<Clover> spots;
+ JImage clover;
+ int cloverList;
+ GameGrid(float sld);
+ ~GameGrid();
+ void step();
+ void draw();
+ void populateSpots();
+ void createCloverList();
+};
+
+
+
+#endif
+
--- /dev/null
+#include "Guy.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+Guy::Guy(int glDisplayList,float x,float y,int teamID,int id_){
+ model = glDisplayList;
+ pos.x = x;
+ pos.y = y;
+ team = teamID;
+ id=id_;
+ counter=0;
+
+ for(int i=0;i<10;i++){
+ rnd.push_back(randomFloat());
+ }
+
+ randomizeDirection();
+ lag_theta = theta;//catch up now, cause it's the beginning.
+}
+
+Guy::~Guy(){
+}
+
+void Guy::step(){
+ lag_theta+=(theta-lag_theta)*0.2;
+ pos+=(dest-pos)*(0.02*rnd[1]);
+ if(!Global::instance->field.pointInside(pos)){
+ //choose another direction.
+ randomizeDirection();
+ }
+
+ counter++;
+
+ int modable = round(this->rnd[0]*100+1);
+
+ if(counter % modable ==0){
+ randomizeDirection();
+ }
+
+
+}
+
+void Guy::draw(){
+
+ float b = 1;
+ if(!team)b=0.3;
+
+ glPushMatrix();
+ pos.glTranslate();
+ glScalef(6,6,6);
+ glRotatef(90+lag_theta*(180/PI),0,0,1);
+ glTranslatef(0,1,0);
+
+ glColor4f(1,1,b,0.05);
+
+ glCallList(model);
+ glPopMatrix();
+
+ //lense connectors.
+ Global::instance->lensePlane(pos,pos+JPoint(0,0,11),1,1,b,0.01);
+
+}
+
+
+void Guy::randomizeDirection(){
+ Global::instance->field.randomPoint(&dest);
+ theta = pos.thetaFrom(dest);
+}
--- /dev/null
+#ifndef _Guy_H_
+#define _Guy_H_
+
+#include "JPoint.h"
+#include "vector"
+
+using namespace std;
+
+class Guy{
+ public:
+ int team;
+ int counter;
+ vector<float> rnd;
+ float theta;
+ float lag_theta;
+ JPoint pos;
+ JPoint dest;
+ int model;
+ int id;
+ Guy(int,float,float,int,int);
+ ~Guy();
+ void draw();
+ void step();
+ void randomizeDirection();
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "GuyConnectors.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+GuyConnectors::GuyConnectors(){
+ for(int i=0;i<Global::instance->athletes->guys.size()*2;i++){
+ rnd.push_back(randomFloat());
+ }
+}
+
+GuyConnectors::~GuyConnectors(){
+
+}
+
+void GuyConnectors::step(){
+
+}
+
+void GuyConnectors::draw(){
+
+ glEnable(GL_LINE_SMOOTH);
+ glTranslatef(0,0,5);
+ JoshFont *f = getFont();
+ for( int i=0;i<Global::instance->athletes->guys.size()-1;i++){
+ Guy g1 = Global::instance->athletes->guys[i];
+ Guy g2 = Global::instance->athletes->guys[i+1];
+ JPoint elevate(0,0,g1.pos.distanceFrom(g2.pos));
+
+ int modulee = (int)round(rnd[i]*200+10);
+ int modResult = ticks() % modulee;
+ float a = fabs((modResult/(float)modulee) - 0.5) - 0.1;
+ glColor4f(1,1,0.5,a);
+
+ bezier(g1.pos,
+ g1.pos+elevate,
+ g2.pos+elevate,
+ g2.pos,
+ 30);
+
+
+ glColor4f(1,1,0.5,a*0.03);
+ Global::instance->lenseBezier(g1.pos,
+ g1.pos+elevate,
+ g2.pos+elevate,
+ g2.pos,
+ 30
+ );
+
+
+ glColor4f(1,1,0.5,a);
+ bezier(g1.pos,
+ g1.pos,
+ g2.pos,
+ g2.pos,
+ 30);
+
+ //draw label for parabola
+ glPushMatrix();
+ JPoint labelPos = (elevate+g1.pos.lerpTo(g2.pos,0.5));
+ labelPos.glTranslate();
+ glRotatef(90,0,1,0);
+ glRotatef(180,0,0,1);
+ //glRotatef( 180 ,0,0,1);
+ glRotatef( g1.pos.thetaFrom(g2.pos)*(180/PI) , 1,0,0);
+
+ char labelStr[64];
+ sprintf(labelStr,"E=%f",labelPos.z);
+ glTranslatef(-10,0,-5);
+ f->drawString(labelStr,2,0);
+ glRotatef(90,0,0,1);
+ glRotatef(90,0,1,0);
+ sprintf(labelStr,"D=%f",labelPos.z*2);
+ f->drawString(labelStr,2,0);
+ glPopMatrix();
+ }
+
+
+
+
+}
+
--- /dev/null
+#ifndef _GuyConnectors_H_
+#define _GuyConnectors_H_
+
+
+#include "Satellite.h"
+#include "Global.h"
+#include <vector>
+
+class GuyConnectors : public Satellite{
+ public:
+ vector<float> rnd;
+ GuyConnectors();
+ ~GuyConnectors();
+
+ void step();
+ void draw();
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "GuyPointer.h"
+#include "Global.h"
+#include "Athletes.h"
+#include "Guy.h"
+#include "jttoolkit.h"
+
+
+GuyPointer::GuyPointer(){
+ //this assumes all the guys exist before i do. cause i'm counting them.
+ int s = Global::instance->athletes->guys.size();
+ for(int i=0;i<s;i++){
+ signs.push_back(new StatSign(&Global::instance->athletes->guys[i]));
+ }
+}
+
+GuyPointer::~GuyPointer(){
+
+}
+
+void GuyPointer::step(){
+ for( vector<StatSign*>::iterator i=signs.begin();i!=signs.end();i++ ){
+ (*i)->step();
+ }
+
+}
+
+void GuyPointer::draw(){
+ for( vector<StatSign*>::iterator i=signs.begin();i!=signs.end();i++ ){
+ (*i)->draw();
+ }
+}
--- /dev/null
+#ifndef _GuyPointer_H_
+#define _GuyPointer_H_
+
+#include "Satellite.h"
+#include <vector>
+#include "StatSign.h"
+#include "JImage.h"
+
+class GuyPointer : public Satellite{
+ public:
+ vector<StatSign*> signs;
+ GuyPointer();
+ ~GuyPointer();
+ void step();
+ void draw();
+};
+
+
+
+#endif
+
--- /dev/null
+#include "JImageSequence.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+void JImageSequence::load(char *filestr_, int begin_, int end){
+ filestr = new char[512];
+ sprintf(filestr,"%s",filestr_);
+ begin=begin_;
+ //load frame 1.
+ char filename[512];
+ sprintf(filename,filestr,begin);
+ frames.push_back(new JImage(filename));
+
+
+ max = end-begin;
+ counter = 0;
+ frameNum = begin;
+}
+
+JImageSequence::JImageSequence(char *filestr_, int begin, int end){
+ load(filestr_,begin,end);
+}
+
+JImageSequence::~JImageSequence(){
+ delete filestr;
+ for(int i=0;i<frames.size();i++){
+ delete frames[i];
+ }
+}
+
+void JImageSequence::step(){
+ counter++;
+ if(counter==max)counter=0;
+ frameNum = begin+counter;
+}
+
+void JImageSequence::stepBack(){
+ counter--;
+ if(counter<0)counter = max-1;
+ frameNum = begin+counter;
+}
+
+
+
+void JImageSequence::draw(){
+
+ while(frames.size()-1<counter){
+ //load frame
+ char filename[512];
+ sprintf(filename,filestr,begin+frames.size());
+ frames.push_back(new JImage(filename));
+ }
+
+ frames[counter]->drawList();
+}
+
--- /dev/null
+#ifndef _JImageSequence_H_
+#define _JImageSequence_H_
+
+
+#include "JImage.h"
+#include <vector>
+
+using namespace std;
+
+class JImageSequence {
+ public:
+ int frameNum;
+ int counter;
+ int max;
+ int begin;
+ char *filestr;
+ vector<JImage*> frames;
+ JImageSequence(char *filestr, int begin,int end);
+ JImageSequence();
+ ~JImageSequence();
+ void step();
+ void stepBack();
+ void draw();
+ void load(char *filestr, int begin,int end);
+};
+
+
+
+#endif
+
--- /dev/null
+#include "JRect.h"
+#include "jttoolkit.h"
+
+
+
+void JRect::randomPoint(JPoint *out){
+ out->x = randomFloat()*(x2-x1) + x1;
+ out->y = randomFloat()*(y2-y1) + y1;
+}
+
+JRect::JRect(){
+
+}
+
+JRect::~JRect(){
+
+}
+
+
+void JRect::initCorners(float x1_,float y1_,float x2_,float y2_){
+ x1 = x1_;
+ y1 = y1_;
+ x2 = x2_;
+ y2 = y2_;
+
+}
+
+
+void JRect::glRect(){
+ glRectf(x1,y1,x2,y2);
+}
+
+int JRect::pointInside(JPoint p){
+ if(p.x<x2 && p.x>x1 && p.y<y2 && p.y>y1){
+ return true;
+ }else return false;
+}
+
+
+float JRect::width(){
+ return x2-x1;
+}
+
+float JRect::height(){
+ return y2-y1;
+}
--- /dev/null
+#ifndef _JRect_H_
+#define _JRect_H_
+
+#include "JPoint.h"
+
+class JRect{
+ public:
+ float x1;
+ float y1;
+ float x2;
+ float y2;
+ JRect();
+ ~JRect();
+ void initCorners(float x1,float y1,float x2,float y2);
+ void glRect();
+ void randomPoint(JPoint *out);
+ int pointInside(JPoint p);
+ float width();
+ float height();
+};
+
+
+
+#endif
+
--- /dev/null
+#include "NetTicket.h"
+
+NetTicket::NetTicket(char*theURL){
+ if(!jtHTTPClient_started)jtHTTPClient_init();//start the shared engine if not started.
+ stringWriter = new Vector();
+ data = new char[1];data[0]=0;
+ url = theURL;
+ status = -1;
+ progressMax = -1;
+ progress = -1;
+ jtHTTPClient_curlQueue->push((long)this);
+}
+
+NetTicket::~NetTicket(){
+ //jtHTTPClient_deleteMatch((long)this);//remove myself from the global queue in case I am in there.
+ //ok this is terrible, but if you delete it mid-download, it will cause the system to crash.
+ delete stringWriter;
+ delete [] data;
+}
+
+
+void jtHTTPClient_init(){
+ jtHTTPClient_started = 1;
+ jtHTTPClient_curlQueue = new Vector();
+ jtHTTPClient__curl = curl_easy_init();
+ curl_easy_setopt(jtHTTPClient__curl,CURLOPT_NOPROGRESS,0);
+ curl_easy_setopt(jtHTTPClient__curl,CURLOPT_PROGRESSFUNCTION,jtHTTPClient_progress_callback);
+ curl_easy_setopt(jtHTTPClient__curl,CURLOPT_WRITEFUNCTION,jtHTTPClient_write_data);
+ pthread_create(&jtHTTPClient_myThread,NULL,jtHTTPClient_threadFunc,NULL);
+
+ // scheduling parameters of target thread
+
+}
+
+
+void jtHTTPClient_reset(){
+ curl_easy_cleanup(jtHTTPClient__curl);
+ delete jtHTTPClient_curlQueue;
+ jtHTTPClient_init();
+}
+
+
+size_t jtHTTPClient_write_data(void*buffer,size_t size,size_t nmemb,void *userp){
+ char*b = (char*)buffer;
+ NetTicket *thisTicket = (NetTicket*)jtHTTPClient_curlQueue->get(0);
+ for(int i=0;i<nmemb;i++){
+ thisTicket->stringWriter->push((long)b[i]);
+ if(i%20==0)sched_yield();
+ }
+ return nmemb;
+}
+
+char*jtHTTPClient_getData(NetTicket *ticket){
+ return ticket->stringWriter->createString();
+}
+
+void *jtHTTPClient_threadFunc(void*stuff){
+ while(true){
+ //always sorting through for unattended tickets.
+ while(jtHTTPClient_curlQueue->count>0){
+ NetTicket *thisTicket = (NetTicket*)jtHTTPClient_curlQueue->get(0);
+
+ curl_easy_setopt(jtHTTPClient__curl,CURLOPT_URL,thisTicket->url);
+ int result = curl_easy_perform(jtHTTPClient__curl);
+ if(result==0){//fill data
+ delete thisTicket->data;
+ thisTicket->data = thisTicket->stringWriter->createStringSleepy();
+ }
+ thisTicket->status = result;
+ jtHTTPClient_curlQueue->unshift();
+ //curl_easy_cleanup(jtHTTPClient__curl);
+ //printf("threadfunc working\n",0);
+ sched_yield();
+ }
+ sched_yield();
+ }
+}
+
+int jtHTTPClient_progress_callback(void *clientp,
+ double dltotal,
+ double dlnow,
+ double ultotal,
+ double ulnow) {
+
+ //printf("%f %f %f %f\n",dltotal,dlnow,ultotal,ulnow);
+ NetTicket *thisTicket = (NetTicket*)jtHTTPClient_curlQueue->get(0);
+ thisTicket->progress = dlnow;
+ thisTicket->progressMax = dltotal;
+ return 0;
+}
--- /dev/null
+#ifndef _NETTICKET_H_
+#define _NETTICKET_H_
+#include "Vector.h"
+
+#ifdef WIN32
+#define SOCKET long
+#endif
+
+
+#include "curl/curl.h"
+#include <pthread.h>
+
+class NetTicket{
+ public:
+ NetTicket(char*url);
+ ~NetTicket();
+ char *url;
+ char *data;
+ int status;
+ float progressMax;
+ float progress;
+ Vector *stringWriter;
+};
+
+//global queuing system using curl
+static Vector *jtHTTPClient_curlQueue;
+static CURL*jtHTTPClient__curl;
+static int jtHTTPClient_started = 0;
+static pthread_t jtHTTPClient_myThread;
+void jtHTTPClient_init();
+void jtHTTPClient_reset();
+int jtHTTPClient_progress_callback(void *clientp,double dltotal,double dlnow,double ultotal,double ulnow);
+size_t jtHTTPClient_write_data(void*buffer,size_t size,size_t nmemb,void *userp);
+void *jtHTTPClient_threadFunc(void*stuff);
+#endif
--- /dev/null
+#include "NeuralHanger.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+NeuralHanger::NeuralHanger():JPoint(0,0,0){
+ for(int i=0;i<5;i++)rnd.push_back(randomFloat());
+ counter=0;
+ radius = 0;
+ theta = 0;
+ destRadius = 0;
+ destTheta = 0;
+ lineWidth = 2;
+}
+
+NeuralHanger::~NeuralHanger(){
+
+}
+
+void NeuralHanger::step(){
+
+ counter++;
+
+ radius += (destRadius-radius)*0.3;
+ theta += (destTheta-theta)*0.3;
+
+ //sampling the color in the space.
+ JPoint p = offset + tip;
+
+ ColorRGB backplatePixel;
+ ColorRGB screenPixel;
+ //backplate pixel color
+ backplatePixel = Global::instance->backplate.pixelColor(p.x,p.y);
+
+ //current screen buffer pixel color
+ if(Global::instance->pixels!=NULL)screenPixel = Global::instance->pixels->pixelColor(p.x,p.y);
+
+ if(p.x>0 && p.y>0 && p.x < width() && p.y < height()){
+ if( screenPixel.red() < backplatePixel.red()/6+0 ){
+ children.push_back(new NeuralHanger());
+ children.back()->depth = depth+1;
+ children.back()->destRadius = destRadius + (randomFloat()-0.5)*depth*0.3;
+ children.back()->destTheta = destTheta + (randomFloat()-0.5)*1;
+ children.back()->theta = children.back()->destTheta;//start theta off on the right track.
+ children.back()->lineWidth = fabs(lineWidth+(randomFloat()-0.5)*3);
+ }
+ }
+
+
+ for(int i=0;i<children.size();i++)children[i]->step();
+}
+
+void NeuralHanger::draw(JPoint external_offset){
+ tip.copyFrom(JPoint(radius*cos(theta),
+ radius*sin(theta),0));
+
+ offset.copyFrom(external_offset);
+ glLineWidth((int)lineWidth);
+ glBegin(GL_LINES);
+ (offset).glVertex();
+ (tip+offset).glVertex();
+ glEnd();
+ for(int i=0;i<children.size();i++)children[i]->draw(offset+tip);
+}
+
--- /dev/null
+#ifndef _NeuralHanger_H_
+#define _NeuralHanger_H_
+
+
+#include "JPoint.h"
+#include <vector>
+
+using namespace std;
+
+class NeuralHanger : public JPoint{
+ public:
+
+ JPoint offset;
+ JPoint tip;
+
+ float lineWidth;
+
+ int counter;
+ int matureTime;
+
+ float radius;
+ float destRadius;
+
+ float theta;
+ float destTheta;
+
+ int depth;
+
+ vector<float> rnd;
+ vector<NeuralHanger*> children;
+ NeuralHanger();
+ ~NeuralHanger();
+
+ void step();
+ void draw(JPoint offset);
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "OrniArrow1.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+OrniArrow1::OrniArrow1(){
+ for(int i=0;i<5;i++)rnd.push_back(randomFloat());
+}
+
+OrniArrow1::~OrniArrow1(){
+
+}
+
+void OrniArrow1::step(){
+
+}
+
+void OrniArrow1::draw(int counter,JPoint end){
+ glPushMatrix();
+ glColor4f(1,1,1,0.3);
+ end.glTranslate();
+ float sc = counter*0.4;
+ glRotatef(rnd[4]*360,0,0,1);
+ glBegin(GL_TRIANGLES);
+ glVertex3f(-0.8*sc,0,0);
+ glVertex3f(0,0,0.5*sc);
+ glVertex3f(0,0,1*sc);
+ glVertex3f(0.8*sc,0,0);
+ glVertex3f(0,0,0.5*sc);
+ glVertex3f(0,0,1*sc);
+ glEnd();
+ glPopMatrix();
+}
+
--- /dev/null
+#ifndef _OrniArrow1_H_
+#define _OrniArrow1_H_
+
+#include "TreeOrniment.h"
+#include <vector>
+#include "JPoint.h"
+
+using namespace std;
+
+class OrniArrow1 : public TreeOrniment{
+ public:
+ vector<float> rnd;
+ OrniArrow1();
+ ~OrniArrow1();
+
+ void step();
+ void draw(int counter,JPoint end);
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "OrniBubbleRing1.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+OrniBubbleRing1::OrniBubbleRing1(){
+ for(int i=0;i<6;i++)rnd.push_back(randomFloat());
+}
+
+OrniBubbleRing1::~OrniBubbleRing1(){
+
+}
+
+void OrniBubbleRing1::step(){
+
+}
+
+void OrniBubbleRing1::draw(int counter,JPoint end){
+ //draw circular bubble blowing thing
+ glPushMatrix();
+ glLineWidth(10);
+ glColor4f(1,1,1,0.3);
+ end.glTranslate();
+ float sc = counter*1;
+ glRotatef(rnd[4]*360 + (ticks()*( rnd[5]-0.5 )*20),0,0,1);
+ float steps = 60;
+ float inc = (PI*2)/steps;
+ glBegin(GL_LINES);
+ for(int i=0;i<steps;i++){
+ glVertex3f( 0,sc*cos(i*inc),sc*sin(i*inc) );
+ }
+ glEnd();
+ glLineWidth(1);
+ glPopMatrix();
+
+}
+
--- /dev/null
+#ifndef _OrniBubbleRing1_H_
+#define _OrniBubbleRing1_H_
+
+
+#include "TreeOrniment.h"
+#include <vector>
+
+using namespace std;
+
+class OrniBubbleRing1 : public TreeOrniment{
+ public:
+ vector<float> rnd;
+ OrniBubbleRing1();
+ ~OrniBubbleRing1();
+
+ void step();
+ void draw(int counter,JPoint end);
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "OrniBubbleRing2.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+OrniBubbleRing2::OrniBubbleRing2(){
+ for(int i=0;i<6;i++)rnd.push_back(randomFloat());
+
+}
+
+OrniBubbleRing2::~OrniBubbleRing2(){
+
+}
+
+void OrniBubbleRing2::step(){
+
+}
+
+void OrniBubbleRing2::draw(int counter,JPoint end){
+
+ glPushMatrix();
+ glColor4f(1,1,1,0.1);
+ glLineWidth(2);
+ end.glTranslate();
+ float sc = counter*0.3;
+ glRotatef(rnd[4]*360 + (ticks()*( rnd[5]-0.5 )*20),0,0,1);
+
+ glScalef(sc,sc,sc);
+ glRotatef(90,1,0,0);
+ glRotatef(90,0,1,0);
+ Global::instance->bubblering_model->outlineFaces();
+ glLineWidth(1);
+ glPopMatrix();
+
+}
+
--- /dev/null
+#ifndef _OrniBubbleRing2_H_
+#define _OrniBubbleRing2_H_
+
+
+#include "TreeOrniment.h"
+#include <vector>
+
+using namespace std;
+
+class OrniBubbleRing2 : public TreeOrniment{
+ public:
+ vector<float> rnd;
+ OrniBubbleRing2();
+ ~OrniBubbleRing2();
+
+ void step();
+ void draw(int counter,JPoint end);
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "OrniTriangle1.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+OrniTriangle1::OrniTriangle1(){
+ for(int i=0;i<6;i++)rnd.push_back(randomFloat());
+
+}
+
+OrniTriangle1::~OrniTriangle1(){
+
+}
+
+void OrniTriangle1::step(){
+
+}
+
+void OrniTriangle1::draw(int counter,JPoint end){
+ //draw upside down triangle thing
+ glPushMatrix();
+ glColor4f(1,1,0.1,0.1);
+ glLineWidth(1);
+ end.glTranslate();
+ float sc = counter*0.8;
+ glRotatef(rnd[4]*360 + (ticks()*( rnd[5]-0.5 )*20),0,0,1);
+
+ //glBegin(GL_LINE_LOOP);
+ //glVertex3f(0, 0, 0);
+ //glVertex3f(0, 5*sc,10*sc);
+ //glVertex3f(0,-5*sc,10*sc);
+ //glEnd();
+
+ glScalef(sc,sc,sc);
+ glRotatef(90,1,0,0);
+ glRotatef(90,0,1,0);
+ Global::instance->triangle_gem_model->outlineFaces();
+ glLineWidth(1);
+ glPopMatrix();
+
+}
+
--- /dev/null
+#ifndef _OrniTriangle1_H_
+#define _OrniTriangle1_H_
+
+
+#include "TreeOrniment.h"
+#include <vector>
+
+using namespace std;
+
+class OrniTriangle1 : public TreeOrniment{
+ public:
+ vector<float> rnd;
+ OrniTriangle1();
+ ~OrniTriangle1();
+
+ void step();
+ void draw(int counter,JPoint end);
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "Raster2Vector.h"\r
+\r
+\r
+/*\r
+ Rastor to Vector convertion object by Josh Nimoy, April 2002, jtnimoy@ucla.edu\r
+ */\r
+\r
+Raster2Vector::~Raster2Vector(){\r
+ delete [] vectors;\r
+ delete [] paths;\r
+ delete [] bits;\r
+ delete [] reg;\r
+}\r
+\r
+Raster2Vector::Raster2Vector(int width, int height){\r
+ this->picW = width;\r
+ this->picH = height;\r
+ this->vectors = new VECTOR[picW*picH * 4];\r
+ this->paths = new unsigned int[picW*picH*256];\r
+ this->bits = new unsigned char[picW*picH];\r
+ this->reg = new PointReg[(picW+1)*(picH+1)];\r
+}\r
+\r
+//################################################################################################\r
+\r
+void Raster2Vector::generateVectors(){\r
+ this->vCount = 0;\r
+ //printf("converting to edges to vectors\n",NULL);\r
+ //create vectors from the bitmap data, creating square-sides only if a border\r
+\r
+ \r
+ //clear the registry\r
+ for(int i=0;i<(picW+1)*(picH+1);i++)reg[i].state=0;\r
+\r
+ //generate\r
+ for(int y=0;y<picH;y++){\r
+ for(int x=0;x<picW;x++){\r
+ if(bits[y*picW+x]==0){\r
+ //add a new vector to form the square\r
+ //1X\r
+ //2X\r
+ if(x>0){\r
+ if(bits[y*picW+(x-1)]==255)newVector(x,y,x,y+1);\r
+ }else newVector(x,y,x,y+1);\r
+ //XX\r
+ //34\r
+ if(y<picH-1){\r
+ if(bits[(y+1)*picW+x]==255)newVector(x,y+1,x+1,y+1);\r
+ }else newVector(x,y+1,x+1,y+1);\r
+ //X6\r
+ //X5\r
+ if(x<picW -1){\r
+ if(bits[y*picW+(x+1)]==255)newVector(x+1,y+1,x+1,y);\r
+ }else newVector(x+1,y+1,x+1,y);\r
+ //87\r
+ //XX\r
+ if(y>0){\r
+ if(bits[picW*(y-1)+x]==255)newVector(x+1,y,x,y);\r
+ }else newVector(x+1,y,x,y);\r
+ }\r
+ }\r
+ }\r
+ \r
+ //printf("chaining...\n",NULL);\r
+ //chain them together \r
+ pathCount=0;\r
+ for(int i=0;i<vCount;i++){\r
+ //states - 1=ready 2=connected\r
+ //I can assume now that there are exactly 2 of every point - no more and no less.\r
+ if(vectors[i].state==1){\r
+ //remember the last point for later\r
+ int curVec = i;\r
+ int oldCurVec = -100;\r
+ paths[pathCount]=curVec;\r
+ pathCount++;\r
+ while(!(EQUALPOINTS(vectors[curVec].p2,vectors[i].p1))){//as long as we do not reach the other side...\r
+\r
+ //printf("%i %i %f %f %f %f\n",curVec,i,vectors[curVec].p2.x,vectors[curVec].p2.y,\r
+ //vectors[i].p1.x,vectors[i].p1.y);\r
+\r
+ for(int ii=i+1;ii<vCount;ii++){\r
+ //looking for the connector for [curVec].p2\r
+ if(vectors[ii].state==1&&EQUALPOINTS(vectors[curVec].p2,vectors[ii].p1)){\r
+ curVec = ii;\r
+ //add it to paths\r
+ paths[pathCount]=ii;\r
+ pathCount++;\r
+ //mark it as used\r
+ vectors[ii].state = 2;\r
+ break;\r
+ }\r
+\r
+ if(vectors[ii].state==1&&EQUALPOINTS(vectors[curVec].p2,vectors[ii].p2)){\r
+ curVec = ii;\r
+ //also swap this guy's p1 and p2 so we can always count on comparing the current p2\r
+ FLOATPOINT tmp;\r
+ tmp.x = vectors[ii].p2.x;\r
+ tmp.y = vectors[ii].p2.y;\r
+ vectors[ii].p2.x=vectors[ii].p1.x;\r
+ vectors[ii].p2.y=vectors[ii].p1.y;\r
+ vectors[ii].p1.x=tmp.x;\r
+ vectors[ii].p1.y=tmp.y;\r
+ //end swap\r
+\r
+ //add it to paths\r
+ paths[pathCount]=curVec;\r
+ pathCount++; \r
+ //mark it as used\r
+ vectors[ii].state = 2;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(curVec==oldCurVec)break;\r
+ oldCurVec = curVec;\r
+ }\r
+ paths[pathCount]=-1;//signifies the end of a group.\r
+ pathCount++;\r
+ vectors[i].state = 2;\r
+ }\r
+ }\r
+ //printf("done chaining...\n",NULL);\r
+\r
+}\r
+\r
+\r
+void Raster2Vector::newVector(int x,int y,int xx,int yy){\r
+ newVector(float(x),float(y),float(xx),float(yy));\r
+}\r
+\r
+void Raster2Vector::newVector(float x,float y,float xx,float yy){\r
+ vectors[vCount].state = 1;\r
+ vectors[vCount].p1.x = x;\r
+ vectors[vCount].p1.y = y;\r
+ vectors[vCount].p1.state = 0;\r
+ vectors[vCount].p2.x = xx;\r
+ vectors[vCount].p2.y = yy;\r
+ vectors[vCount].p2.state = 0;\r
+ \r
+ bendDuplicates();\r
+ \r
+ vCount++;\r
+ //printf("%i ",vCount);\r
+}\r
+\r
+//################################################################################################\r
+bool Raster2Vector::equalVectors(int v1,int v2){\r
+ return(( EQUALPOINTS(vectors[v1].p1,vectors[v2].p1) && EQUALPOINTS(vectors[v1].p2,vectors[v2].p2) )||\r
+ ( EQUALPOINTS(vectors[v1].p2,vectors[v2].p1) && EQUALPOINTS(vectors[v1].p1,vectors[v2].p2) ));\r
+}\r
+\r
+#define bendFactor 0.001f\r
+\r
+void Raster2Vector::bendDuplicates(){\r
+//the purpose of this function is to make sure that vectors[vCount] does not overlap with any pre-existing point.\r
+\r
+\r
+//bend the duplicates slightly off their destination to keep shapes seperated \r
+\r
+ unsigned char foundCount1 = 0;\r
+ unsigned char foundCount2 = 0;\r
+ \r
+ for(int i=0;i<vCount;i++){\r
+ //checking p1 against p1\r
+ if(EQUALPOINTS(vectors[vCount].p1,vectors[i].p1)){\r
+ //a happy couple\r
+ if( vectors[i].p1.state==0){\r
+ vectors[vCount].p1.state=1;\r
+ vectors[i].p1.state=1;\r
+ }else{\r
+ //find one of your own\r
+ vectors[vCount].p1.x+=bendFactor;\r
+ vectors[vCount].p1.y+=bendFactor;\r
+ }\r
+ foundCount1++;\r
+ if(foundCount1==2)break;\r
+ }\r
+\r
+ //checking p1 against p2\r
+ if(EQUALPOINTS(vectors[vCount].p1,vectors[i].p2)){\r
+ //a happy couple\r
+ if( vectors[i].p2.state==0){\r
+ vectors[vCount].p1.state=1;\r
+ vectors[i].p2.state=1;\r
+ }else{\r
+ //find one of your own\r
+ vectors[vCount].p1.x+=bendFactor;\r
+ vectors[vCount].p1.y+=bendFactor;\r
+ }\r
+ foundCount1++;\r
+ if(foundCount1==2)break;\r
+ }\r
+\r
+ //checking p2 against p1\r
+ if(EQUALPOINTS(vectors[vCount].p2,vectors[i].p1)){\r
+ //a happy couple\r
+ if( vectors[i].p1.state==0){\r
+ vectors[vCount].p2.state=1;\r
+ vectors[i].p1.state=1;\r
+ }else{\r
+ //find one of your own\r
+ vectors[vCount].p2.x+=bendFactor;\r
+ vectors[vCount].p2.y+=bendFactor;\r
+ }\r
+ foundCount2++;\r
+ if(foundCount2==2)break;\r
+ }\r
+ \r
+ //checking p2 against p2\r
+ if(EQUALPOINTS(vectors[vCount].p2, vectors[i].p2)){\r
+ //a happy couple\r
+ if( vectors[i].p2.state==0){\r
+ vectors[vCount].p2.state=1;\r
+ vectors[i].p2.state=1;\r
+ }else{\r
+ //find one of your own\r
+ vectors[vCount].p2.x+=bendFactor;\r
+ vectors[vCount].p2.y+=bendFactor;\r
+ }\r
+ foundCount2++;\r
+ if(foundCount2==2)break;\r
+ }\r
+ } \r
+\r
+\r
+}\r
+\r
+\r
+\r
+void Raster2Vector::bendDuplicates2(){\r
+ //here, points wait for each other in 2D spots on a grid.\r
+ PointReg *thisReg = ®[int(vectors[vCount].p1.y)*(picW)+int(vectors[vCount].p1.x+1)];\r
+\r
+ //printf("%i p1 %f\t%f\t%f\t%i\n",vCount,vectors[vCount].p1.x,vectors[vCount].p1.y,vectors[vCount].p1.y*picW+vectors[vCount].p1.x,int(vectors[vCount].p1.y)*picW+int(vectors[vCount].p1.x));\r
+\r
+ switch(thisReg->state){\r
+ case 0:\r
+ // ah, a pioneer.\r
+ thisReg->waitingPt = &vectors[vCount].p1;\r
+ break;\r
+ case 1:\r
+ //there was a lover waiting!\r
+ vectors[vCount].p1.state = 1;\r
+ thisReg->waitingPt->state = 1;\r
+ break;\r
+ case 2:\r
+ //no threesomes allowed - get your own partner!\r
+ thisReg->waitingPt = &vectors[vCount].p1;\r
+ thisReg->waitingPt->state = 1;\r
+ vectors[vCount].p1.x+=bendFactor;\r
+ vectors[vCount].p1.y+=bendFactor;\r
+ break;\r
+ case 3:\r
+ //there was a mutant lover waiting!\r
+ vectors[vCount].p1.x+=bendFactor;\r
+ vectors[vCount].p1.y+=bendFactor;\r
+ vectors[vCount].p1.state = 1;\r
+ break;\r
+ default:\r
+ printf("%i exception!\n",thisReg->state);\r
+ }\r
+ thisReg->state++;\r
+\r
+\r
+ //switch gears for p2\r
+\r
+ thisReg = ®[int(vectors[vCount].p2.y)*(picW)+int(vectors[vCount].p2.x)];\r
+\r
+\r
+ //printf("%i p2 %f\t%f\t%f\t%i\n",vCount,vectors[vCount].p2.x,vectors[vCount].p2.y,vectors[vCount].p2.y*picW+vectors[vCount].p2.x,int(vectors[vCount].p2.y)*picW+int(vectors[vCount].p2.x));\r
+\r
+ switch(thisReg->state){\r
+ case 0:\r
+ // ah, a pioneer.\r
+ thisReg->waitingPt = &vectors[vCount].p2;\r
+ break;\r
+ case 1:\r
+ //there was a lover waiting!\r
+ vectors[vCount].p2.state = 1;\r
+ thisReg->waitingPt->state = 1;\r
+ break;\r
+ case 2:\r
+ //no threesomes allowed - get your own partner!\r
+ thisReg->waitingPt = &vectors[vCount].p2;\r
+ thisReg->waitingPt->state = 1;\r
+ vectors[vCount].p2.x+=bendFactor;\r
+ vectors[vCount].p2.y+=bendFactor;\r
+ break;\r
+ case 3:\r
+ //there was a mutant lover waiting!\r
+ vectors[vCount].p2.x+=bendFactor;\r
+ vectors[vCount].p2.y+=bendFactor;\r
+ vectors[vCount].p2.state = 1;\r
+ break;\r
+ default:\r
+ printf("%i exception!\n",thisReg->state);\r
+ }\r
+ thisReg->state++;\r
+\r
+}\r
--- /dev/null
+#ifndef RASTER2VECTOR\r
+#define RASTER2VECTOR\r
+\r
+\r
+#include <stdio.h>\r
+\r
+/*\r
+ Rastor to Vector convertion object by Josh Nimoy, April 2002, jtnimoy@ucla.edu\r
+ */\r
+\r
+\r
+struct FLOATPOINT{\r
+ float x;\r
+ float y;\r
+ int state;\r
+};\r
+//////////////////////////////////\r
+\r
+\r
+#define EQUALPOINTS(p1,p2) ((p1.x==p2.x)&&(p1.y==p2.y))\r
+\r
+struct VECTOR{\r
+ FLOATPOINT p1;\r
+ FLOATPOINT p2;\r
+ int state;\r
+};\r
+//////////////////////////////////\r
+\r
+\r
+struct PointReg{\r
+ unsigned char state;\r
+ FLOATPOINT *waitingPt;\r
+};\r
+\r
+/////////////////////////////////\r
+class Raster2Vector{\r
+public:\r
+\r
+ int vCount;\r
+ int picW;\r
+ int picH;\r
+ \r
+ unsigned char *bits;\r
+ \r
+ VECTOR *vectors;\r
+ unsigned int *paths;\r
+ int pathCount;\r
+\r
+ void generateVectors(); ////this will do the actual convertion.\r
+\r
+ PointReg *reg;\r
+\r
+ Raster2Vector(int width, int height);\r
+ ~Raster2Vector();\r
+ ///////////////////////////////\r
+ bool equalVectors(int v1,int v2);\r
+ void newVector(float x,float y,float xx,float yy);\r
+ void newVector(int x,int y,int xx,int yy);\r
+ void bendDuplicates();\r
+ void bendDuplicates2();\r
+};\r
+\r
+\r
+//////////////////////////////////\r
+#endif\r
+\r
--- /dev/null
+#include "Satellite.h"
+
+Satellite::Satellite(){
+
+}
+
+Satellite::~Satellite(){
+
+}
+
+void Satellite::step(){
+
+}
+
+void Satellite::draw(){
+
+}
+
--- /dev/null
+#ifndef _Satellite_H_
+#define _Satellite_H_
+
+
+
+class Satellite{
+ public:
+ Satellite();
+ ~Satellite();
+ virtual void step();//step time, with no drawing routines.
+ virtual void draw();//render yoself, without incrementing any of the animation stuff.
+};
+
+
+
+#endif
+
--- /dev/null
+#include "ShotProfile.h"
+#include "jttoolkit.h"
+#include "Global.h"
+#include "gl_et_al.h"
+
+void ShotProfile::nudge(float x,float y,float z){
+ offsetX+=x;
+ offsetY+=y;
+ offsetZ+=z;
+
+
+}
+
+void ShotProfile::glTranslate(){
+ glTranslatef( offsetX+translateX+forceX*counter ,
+ offsetY+translateY+forceY*counter ,
+ offsetZ+translateZ+forceZ*counter );
+}
+
+void ShotProfile::reset(){
+ counter=0;
+ offsetX=0;
+ offsetY=0;
+ offsetZ=0;
+}
+
+void ShotProfile::step(){
+ counter++;
+}
+
+ShotProfile::ShotProfile(int vis,
+ float tx,float ty,float tz,
+ float fx,float fy,float fz,
+ float ws,float tmy,float tmx,float langle
+ ){
+ translateX = tx;
+ translateY = ty;
+ translateZ = tz;
+
+ forceX = fx;
+ forceY = fy;
+ forceZ = fz;
+
+ gameVisible=vis;
+
+ tumbleX = tmx;
+ tumbleY = tmy;
+
+ lenseAngle = langle;
+
+ worldScale = ws;
+ reset();
+}
+
+ShotProfile::~ShotProfile(){
+
+}
+
+
+void ShotProfile::perspective(){
+ viewPerspective(lenseAngle);
+}
--- /dev/null
+#ifndef _ShotProfile_H_
+#define _ShotProfile_H_
+
+class ShotProfile {
+ private:
+ float translateX;
+ float translateY;
+ float translateZ;
+ float offsetX;
+ float offsetY;
+ float offsetZ;
+ float forceX;
+ float forceY;
+ float forceZ;
+ float lenseAngle;
+ public:
+ float tumbleY;
+ float tumbleX;
+ int gameVisible;
+ float worldScale;
+ int counter;
+ void reset();
+ void step();
+ void glTranslate();
+ void perspective();
+ void nudge(float x,float y,float z);
+
+ ShotProfile(int vis,
+ float tx,float ty,float tz,
+ float fx,float fy,float fz,
+ float ws,float tmy,float tmx,
+ float lenseAngle_);
+ ~ShotProfile();
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "StatSign.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+StatSign::StatSign(Guy *g){
+ guy=g;
+ counter=0;
+ for(int i=0;i<2;i++){
+ rnd.push_back(randomFloat());
+ }
+ state=0;
+ char fname[256];
+ sprintf(fname,"media/cardfaces/%02i.png",g->id);
+ face = new JImage(fname);
+}
+
+StatSign::~StatSign(){
+ delete face;
+}
+
+void StatSign::step(){
+
+ if(state==1)counter++;
+ if(state==2)counter--;
+
+ if(counter>10)counter=10;
+ if(counter<0)counter=0;
+
+ float ratio = 0.995;
+ if(state==1)ratio = 0.9;
+ if(randomFloat()>ratio && (counter==10 || counter==0)){
+ float r= randomFloat();
+ if(r>0.5){
+ state = 2;
+ }else{
+ state = 1;
+ }
+
+ }
+}
+
+void StatSign::draw(){
+
+
+ float globalscale = fmin(1,counter*0.1);
+
+ Guy g =(*guy);
+ glColor4f(1,1,1,0.3);
+ glPushMatrix();
+
+ glRotatef((1-globalscale)*90,0,0,1);
+
+ //draw arrow
+ glPushMatrix();
+ (g.pos+JPoint(0,0,12*globalscale)).glTranslate();
+
+ glRotatef(Global::instance->tumbleY+90,1,0,0);//auto-orient , billboard, lookAtCamera
+ glScalef(globalscale,globalscale,globalscale);
+ glBegin(GL_POLYGON);
+ glVertex3f(0,0,0);
+ glVertex3f(0,-1,2);
+ glVertex3f(0,0,1);
+ glVertex3f(0,1,2);
+ glEnd();
+
+ glPopMatrix();
+
+ glBegin(GL_LINE_STRIP);
+ (g.pos+JPoint(0,0,12*globalscale)).glVertex();
+ (g.pos+JPoint(0,0,25*globalscale)).glVertex();
+ JPoint jutOut = g.pos+JPoint(0,0,25*globalscale);
+ jutOut -= (JPoint(0,0,0)-jutOut)*(0.5 * globalscale);
+ jutOut.glVertex();
+ glEnd();
+
+ (jutOut-JPoint(12*globalscale,0,-2)).glTranslate();
+ glScalef(globalscale,globalscale,globalscale);
+ glRotatef(90,1,0,0);
+
+ //light milky background filler
+ glColor4f(1,1,0.5,0.1);
+ roundedRect(GL_POLYGON,-12,-10, 12,10, 1,5);
+
+
+ //draw the photo
+ glPushMatrix();
+ glTranslatef(-1.25,8,0);
+ glScalef(16,16,0);
+ glRotatef(180,0,0,1);
+ glColor4f(1,1,1,0.5);
+ face->drawList();
+ glPopMatrix();
+
+ //layout outlines
+ glColor4f(1,1,1,0.3);
+ roundedRect(GL_LINE_LOOP,-12,-10, 12,10, 1,5);
+ roundedRect(GL_LINE_LOOP,-10,-8, -1 , 8, 0.5,5);
+
+ //some little white filled doodaads to populate the layout.
+ float textscaler = fmin(1,counter*0.1);
+ glRectf(-1, 3 , 5*textscaler , 4 );
+ glRectf(-1, 2 , 4*textscaler , 2.5);
+ glRectf(-1, 4 , -4*textscaler , 5.5);
+ glRectf(-1, -1 , -5*textscaler , -2 );
+
+ glPopMatrix();
+}
+
--- /dev/null
+#ifndef _StatSign_H_
+#define _StatSign_H_
+
+
+#include "Satellite.h"
+#include "Guy.h"
+#include "JImage.h"
+#include <vector>
+
+using namespace std;
+
+class StatSign : public Satellite{
+ public:
+ JImage *face;
+ Guy *guy;
+ StatSign(Guy *g);
+ ~StatSign();
+ void step();
+ void draw();
+ int counter;
+ vector<float> rnd;
+ int state;
+};
+
+
+
+#endif
+
--- /dev/null
+#include "TheBall.h"
+#include "gl_et_al.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+float TheBall::FRICTION = 1;
+float TheBall::GRAVITY = -0.4;
+
+TheBall::TheBall(){
+
+ x = 0;
+ y = 0;
+ z = 0;
+ forceX=4;
+ forceY=3;
+ forceZ=4;
+
+ radius = 1;
+}
+
+TheBall::~TheBall(){
+
+}
+
+
+void TheBall::step(){
+ float leap = 5;
+
+ //apply forces
+ x += forceX;
+ y += forceY;
+ z += forceZ;
+
+ //apply friction
+ forceX *= FRICTION;
+ forceY *= FRICTION;
+ forceZ *= FRICTION;
+
+ forceZ += GRAVITY;
+
+ //collide with the field boundaries and ground.
+ if(z<0){
+ z=0;
+ forceZ=-forceZ*0.5;//grass friction
+ }
+
+ if(x<Global::instance->field.x1){
+ x=Global::instance->field.x1;
+ forceX = -forceX;
+ forceZ = 3;//kick it.
+ }
+
+ if(x>Global::instance->field.x2){
+ x=Global::instance->field.x2;
+ forceX = -forceX;
+ forceZ = 3;//kick it.
+ }
+
+ if(y<Global::instance->field.y1){
+ y=Global::instance->field.y1;
+ forceY = -forceY;
+ forceZ = 3;//kick it.
+ }
+
+ if(y>Global::instance->field.y2){
+ y=Global::instance->field.y2;
+ forceY = -forceY;
+ forceZ = 3;//kick it.
+ }
+
+
+
+
+}
+
+void TheBall::draw(){
+
+ //draw the ball
+ glPushMatrix();
+ glColor4f(0.3,0.1,0.05,0.9);
+ glTranslatef(x,y,z);
+ glutSolidSphere(radius,30,30);
+ glPopMatrix();
+
+
+ //connect to lense
+ JPoint p1(x,y,z-radius);
+ JPoint p2(x,y,z+radius);
+
+ glBindTexture(GL_TEXTURE_2D,0);
+ Global::instance->lensePlane(p1,p2,
+ 0.3,0.1,0.05,0.1);
+}
--- /dev/null
+#ifndef _TheBall_H_
+#define _TheBall_H_
+
+#include "Satellite.h"
+
+class TheBall : public Satellite{
+ public:
+ static float FRICTION;
+ static float GRAVITY;
+ float x;
+ float y;
+ float z;
+
+ float forceX;
+ float forceY;
+ float forceZ;
+
+ float radius;
+
+ TheBall();
+ ~TheBall();
+
+ void step();
+ void draw();
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "TreeNode.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+TreeNode::TreeNode(int d,float xx,float yy,float zz,float rad,float th,float lw):JPoint(xx,yy,zz){
+ lineWidth=lw;
+ depth = d;
+ theta = th;
+ radius = rad;
+ for(int i=0;i<5;i++)rnd.push_back(randomFloat());
+
+
+ destOrigin.copyFrom(*this);
+
+
+ dest.x = radius*cos(theta);
+ dest.y = radius*sin(theta);
+ dest.z = 0;
+
+ dieingParent = 0;
+
+}
+
+TreeNode::~TreeNode(){
+
+}
+
+void TreeNode::step(){
+ tip.lerpSelfTo(dest,0.2);
+ lerpSelfTo(destOrigin,0.2);
+ //have a baby?
+
+ ColorRGB c = Global::instance->backplate.pixelColor((*this+dest).x,(*this+dest).y);
+ ColorRGB c2;
+ if(Global::instance->pixels!=NULL){
+ c2 = Global::instance->pixels->pixelColor((*this+dest).x,(*this+dest).y);
+ }
+ float bright = (c.red() + c.green() + c.blue())/3;
+ float bright2 = (c2.red() + c2.green() + c2.blue())/3;
+
+ if( ( randomFloat()>0.9 && children.size() < 4 && (( (bright > 0.5 || ticks() > 200) && bright2 < 0.1) || depth < 3) ) ){
+
+ float newTheta;
+ if(depth>4){
+ newTheta = theta +(randomFloat()-0.5)*1;
+ }else{
+ newTheta = theta +(randomFloat()-0.6)*1.1;
+ }
+
+ children.push_back(new TreeNode(depth+1, //depth, necessary to pass this + 1
+ tip.x,tip.y,tip.z, //position (will be constantly updated anyway
+ radius+(randomFloat()-0.5)*10, //radius
+ newTheta, //theta
+ lineWidth+(randomFloat()-0.5)*2 //line width
+ )
+ );
+ }
+
+ for(int i=0;i<children.size();i++){
+ children[i]->copyFrom(*this+tip);
+ children[i]->destOrigin.copyFrom(*this+tip);
+ children[i]->step();
+ }
+
+
+ if(dieingParent!=0){
+ dieingParent->step();
+ }
+
+
+}
+
+void TreeNode::draw(){
+ glColor4f(1,1,1,1);
+ glLineWidth((int)round(lineWidth));
+ glBegin(GL_LINES);
+ glVertex();
+ if(children.size()==0){
+ glColor4f(1,1,1,0.0);
+ }
+ (*this+tip).glVertex();
+ glEnd();
+
+ for(int i=0;i<children.size();i++){
+ children[i]->draw();
+ }
+
+
+ if(dieingParent!=0){
+ glBegin(GL_LINES);
+ glColor4f(1,1,1,1);
+ this->glVertex();
+ glColor4f(1,1,1,0);
+ (*this+*dieingParent).glVertex();
+ glEnd();
+ }
+
+}
+
--- /dev/null
+#ifndef _TreeNode_H_
+#define _TreeNode_H_
+
+
+#include "JPoint.h"
+#include "DieingParent.h"
+#include <vector>
+
+using namespace std;
+
+class DieingParent;
+
+class TreeNode:public JPoint{
+ public:
+
+ float lineWidth;
+ int depth;
+ DieingParent *dieingParent;
+ JPoint tip;
+ JPoint dest;
+ JPoint destOrigin;
+ float theta;
+ float radius;
+ vector<float> rnd;
+ vector<TreeNode*> children;
+ TreeNode(int,float,float,float,float,float,float);
+ ~TreeNode();
+
+ void step();
+ void draw();
+
+};
+
+
+
+#endif
+
--- /dev/null
+#include "TreeOrniment.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+TreeOrniment::TreeOrniment(){
+
+}
+
+TreeOrniment::~TreeOrniment(){
+
+}
+
+void TreeOrniment::step(){
+
+}
+
+void TreeOrniment::draw(int counter,JPoint end){
+
+}
+
+
+/*
+ if(rnd[6]>0 && rnd[6] < 0.25){
+ //draw pointing arrow
+
+
+ }else if(rnd[6]>0.25 && rnd[6] < 0.50 ){
+
+
+ }else if(rnd[6]>0.50 && rnd[6] < 0.75 ){
+
+
+ }else{
+
+
+ //draw upside down triangle thing
+
+ }
+*/
--- /dev/null
+#ifndef _TreeOrniment_H_
+#define _TreeOrniment_H_
+
+#include "gl_et_al.h"
+#include "JPoint.h"
+
+class TreeOrniment {
+ public:
+
+ TreeOrniment();
+ ~TreeOrniment();
+ virtual void step();
+ virtual void draw(int counter,JPoint end);
+
+};
+
+
+
+#endif
+
--- /dev/null
+int data1_count = 8;
+float data1[] = {
+ 124.000000,136.000000,77,115,SwappingEquation::LETTER,
+ 129.000000,130.000000,106,135,SwappingEquation::LETTER,
+ 127.000000,130.000000,154,113,SwappingEquation::LETTER,
+ 128.000000,130.000000,154,127,SwappingEquation::LETTER,
+ 124.000000,130.000000,254,85,SwappingEquation::LETTER,
+ 126.000000,130.000000,259,118,SwappingEquation::DIV,
+ 123.000000,130.000000,255,158,SwappingEquation::IGNOREME,
+ 128.000000,130.000000,290,156,SwappingEquation::LETTER
+};
+int data2_count = 7;
+float data2[] = {
+ 126.000000,135.000000,79,114,SwappingEquation::LETTER,
+ 130.000000,131.000000,106,136,SwappingEquation::LETTER,
+ 127.000000,128.000000,154,108,SwappingEquation::LETTER,
+ 129.000000,128.000000,156,124,SwappingEquation::LETTER,
+ 125.000000,127.000000,209,82,SwappingEquation::LETTER,
+ 126.000000,128.000000,212,116,SwappingEquation::LETTER,
+ 128.000000,128.000000,213,155,SwappingEquation::LETTER
+};
+int data3_count = 9;
+float data3[] = {
+ 119.000000,123.000000,70,135,SwappingEquation::LBRACKET,
+ 125.000000,132.000000,113,142,SwappingEquation::LETTER,
+ 130.000000,130.000000,176,142,SwappingEquation::LETTER,
+ 130.000000,128.000000,174,154,SwappingEquation::LETTER,
+ 115.000000,122.000000,254,131,SwappingEquation::IGNOREME,
+ 137.000000,123.000000,300,101,SwappingEquation::LETTER,
+ 131.000000,128.000000,297,147,SwappingEquation::LETTER,
+ 137.000000,131.000000,297,189,SwappingEquation::LETTER,
+ 141.000000,131.000000,369,143,SwappingEquation::RBRACKET
+};
+int data4_count = 9;
+float data4[] = {
+ 119.000000,129.000000,70,141,SwappingEquation::LBRACKET,
+ 125.000000,134.000000,114,145,SwappingEquation::LETTER,
+ 129.000000,131.000000,176,142,SwappingEquation::LETTER,
+ 129.000000,132.000000,174,158,SwappingEquation::LETTER,
+ 117.000000,121.000000,257,129,SwappingEquation::IGNOREME,
+ 128.000000,129.000000,303,106,SwappingEquation::LETTER,
+ 129.000000,130.000000,296,149,SwappingEquation::LETTER,
+ 134.000000,132.000000,292,193,SwappingEquation::LETTER,
+ 142.000000,130.000000,369,142,SwappingEquation::RBRACKET
+};
+int data5_count = 11;
+float data5[] = {
+ 117.000000,125.000000,67,138,SwappingEquation::LBRACKET,
+ 136.000000,128.000000,134,144,SwappingEquation::LETTER,
+ 127.000000,129.000000,152,180,SwappingEquation::LETTER,
+ 127.000000,129.000000,203,139,SwappingEquation::LETTER,
+ 130.000000,129.000000,205,156,SwappingEquation::LETTER,
+ 128.000000,129.000000,272,138,SwappingEquation::LETTER,
+ 127.000000,129.000000,293,179,SwappingEquation::LETTER,
+ 128.000000,128.000000,364,146,SwappingEquation::LETTER,
+ 128.000000,129.000000,444,137,SwappingEquation::LETTER,
+ 129.000000,131.000000,464,184,SwappingEquation::LETTER,
+ 139.000000,128.000000,504,140,SwappingEquation::RBRACKET
+};
+int data6_count = 9;
+float data6[] = {
+ 126.000000,133.000000,78,143,SwappingEquation::LETTER,
+ 127.000000,130.000000,109,165,SwappingEquation::LETTER,
+ 118.000000,131.000000,145,143,SwappingEquation::LBRACKET,
+ 128.000000,128.000000,194,148,SwappingEquation::LETTER,
+ 128.000000,130.000000,221,164,SwappingEquation::LETTER,
+ 128.000000,130.000000,267,149,SwappingEquation::LETTER,
+ 128.000000,130.000000,325,150,SwappingEquation::LETTER,
+ 128.000000,130.000000,354,165,SwappingEquation::LETTER,
+ 137.000000,131.000000,396,144,SwappingEquation::RBRACKET
+};
+int data7_count = 8;
+float data7[] = {
+ 130.000000,127.000000,69,146,SwappingEquation::LBRACKET,
+ 127.000000,127.000000,98,147,SwappingEquation::LETTER,
+ 129.000000,133.000000,127,168,SwappingEquation::LETTER,
+ 128.000000,130.000000,169,151,SwappingEquation::LETTER,
+ 128.000000,130.000000,229,150,SwappingEquation::LETTER,
+ 128.000000,130.000000,256,165,SwappingEquation::LETTER,
+ 128.000000,129.000000,273,148,SwappingEquation::RBRACKET,
+ 128.000000,134.000000,297,103,SwappingEquation::LETTER
+};
+int data8_count = 10;
+float data8[] = {
+ 128.000000,131.000000,93,150,SwappingEquation::DIV,
+ 120.000000,131.000000,93,142,SwappingEquation::LBRACKET,
+ 112.000000,130.000000,136,139,SwappingEquation::LETTER,
+ 126.000000,131.000000,208,139,SwappingEquation::LETTER,
+ 127.000000,130.000000,258,157,SwappingEquation::LETTER,
+ 128.000000,129.000000,302,147,SwappingEquation::DIV,
+ 128.000000,130.000000,366,139,SwappingEquation::LETTER,
+ 127.000000,130.000000,423,138,SwappingEquation::LETTER,
+ 136.000000,131.000000,486,141,SwappingEquation::LETTER,
+ 133.000000,131.000000,488,149,SwappingEquation::RBRACKET
+};
+
+
+
+
+
+
+
+/*
+ int data0_count = 26;
+ float data0[] = {
+ 47.000000, 63.000000, 178, 170, SwappingEquation::LETTER,
+ 46.000000, 70.000000, 174, 214, SwappingEquation::DIV,
+ 26.000000, 72.000000, 155, 260, SwappingEquation::LETTER,
+ 60.000000, 78.000000, 190, 266, SwappingEquation::LETTER,
+ 53.000000, 65.000000, 241, 214, SwappingEquation::LBRACKET,
+ 62.000000, 49.000000, 287, 202, SwappingEquation::LETTER,
+ 57.000000, 60.000000, 325, 212, SwappingEquation::LBRACKET,
+ 60.000000, 63.000000, 362, 215, SwappingEquation::LETTER,
+ 73.000000, 62.000000, 399, 213, SwappingEquation::RBRACKET,
+ 69.000000, 65.000000, 428, 214, SwappingEquation::RBRACKET,
+ 62.000000, 65.000000, 478, 216, SwappingEquation::IGNOREME,
+ 57.000000, 59.000000, 578, 165, SwappingEquation::LETTER,
+ 63.000000, 67.000000, 575, 213, SwappingEquation::DIV,
+ 66.000000, 69.000000, 554, 262, SwappingEquation::LETTER,
+ 58.000000, 70.000000, 593, 263, SwappingEquation::LETTER,
+ 56.000000, 69.000000, 640, 216, SwappingEquation::LBRACKET,
+ 64.000000, 54.000000, 681, 205, SwappingEquation::LETTER,
+ 55.000000, 64.000000, 719, 212, SwappingEquation::LBRACKET,
+ 66.000000, 63.000000, 755, 214, SwappingEquation::LETTER,
+ 77.000000, 62.000000, 798, 213, SwappingEquation::RBRACKET,
+ 72.000000, 63.000000, 821, 211, SwappingEquation::RBRACKET,
+ 59.000000, 57.000000, 865, 162, SwappingEquation::LETTER,
+ 76.000000, 59.000000, 904, 165, SwappingEquation::LETTER,
+ 76.000000, 66.000000, 889, 212, SwappingEquation::DIV,
+ 59.000000, 75.000000, 866, 262, SwappingEquation::LETTER,
+ 82.000000, 73.000000, 901, 265, SwappingEquation::LETTER
+ };
+
+
+ int data1_count = 7;
+ float data1[] = {
+ 128.000000, 126.000000, 184, 239, SwappingEquation::LETTER,
+ 136.000000, 127.000000, 270, 112, SwappingEquation::LETTER,
+ 128.000000, 130.000000, 223, 117, SwappingEquation::LETTER,
+ 127.000000, 130.000000, 181, 168, SwappingEquation::LETTER,
+ 117.000000, 128.000000, 94, 112, SwappingEquation::LETTER,
+ 130.000000, 131.000000, 149, 114, SwappingEquation::LETTER,
+ 128.000000, 129.000000, 184, 114, SwappingEquation::LETTER
+ };
+
+ int data2_count = 7;
+ float data2[] = {
+ 130.000000,134.000000,114,93,SwappingEquation::LETTER,
+ 127.000000,132.000000,202,87,SwappingEquation::LETTER,
+ 126.000000,128.000000,108,195,SwappingEquation::LETTER,
+ 128.000000,128.000000,156,133,SwappingEquation::LETTER,
+ 128.000000,129.000000,154,195,SwappingEquation::LETTER,
+ 128.000000,130.000000,153,84,SwappingEquation::LETTER,
+ 128.000000,133.000000,204,203,SwappingEquation::LETTER
+ };
+
+*/
--- /dev/null
+/*
+ * GL2PS, an OpenGL to PostScript Printing Library
+ * Copyright (C) 1999-2003 Christophe Geuzaine
+ *
+ * $Id: gl2ps.c,v 1.1.1.1 2004/01/09 21:54:34 administrator Exp $
+ *
+ * E-mail: geuz@geuz.org
+ * URL: http://www.geuz.org/gl2ps/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Contributor(s):
+ * Michael Sweet <mike@easysw.com>
+ * Marc Ume <marc.ume@digitalgraphics.be>
+ * Jean-Francois Remacle <remacle@scorec.rpi.edu>
+ * Bart Kaptein <B.L.Kaptein@lumc.nl>
+ * Quy Nguyen-Dai<quy@vnilux.com>
+ * Sam Buss <sbuss@ucsd.edu>
+ * Shane Hill <Shane.Hill@dsto.defence.gov.au>
+ * Romain Boman <r_boman@yahoo.fr>
+ * Rouben Rostamian <rostamian@umbc.edu>
+ * Diego Santa Cruz <Diego.SantaCruz@epfl.ch>
+ * Shahzad Muzaffar <Shahzad.Muzaffar@cern.ch>
+ * Lassi Tuura <lassi.tuura@cern.ch>
+ * Guy Barrand <barrand@lal.in2p3.fr>
+ */
+
+
+#if defined(__DARWIN__)
+ #include <Types.h>
+#else
+ #include <sys/types.h>
+#endif
+
+
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+#include "gl2ps.h"
+
+/* The gl2ps context. gl2ps is not thread safe (we should create a
+ local GL2PScontext during gl2psBeginPage) */
+
+GL2PScontext *gl2ps = NULL;
+
+/* Some 'system' utility routines */
+
+void gl2psMsg(GLint level, char *fmt, ...){
+ va_list args;
+
+ if(!(gl2ps->options & GL2PS_SILENT)){
+ switch(level){
+ case GL2PS_INFO : fprintf(stderr, "GL2PS info: "); break;
+ case GL2PS_WARNING : fprintf(stderr, "GL2PS warning: "); break;
+ case GL2PS_ERROR : fprintf(stderr, "GL2PS error: "); break;
+ }
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ }
+ /* if(level == GL2PS_ERROR) exit(1); */
+}
+
+void *gl2psMalloc(size_t size){
+ void *ptr;
+
+ if(!size) return(NULL);
+ ptr = malloc(size);
+ if(!ptr){
+ gl2psMsg(GL2PS_ERROR, "Couldn't allocate requested memory");
+ exit(1);
+ }
+ return(ptr);
+}
+
+void *gl2psRealloc(void *ptr, size_t size){
+ if(!size) return(NULL);
+ ptr = realloc(ptr, size);
+ if(!ptr){
+ gl2psMsg(GL2PS_ERROR, "Couldn't reallocate requested memory");
+ exit(1);
+ }
+ return(ptr);
+}
+
+void gl2psFree(void *ptr){
+ if(!ptr) return;
+ free(ptr);
+}
+
+/* The list handling routines */
+
+void gl2psListRealloc(GL2PSlist *list, GLint n){
+ if(n <= 0) return;
+ if(!list->array){
+ list->nmax = ((n - 1) / list->incr + 1) * list->incr;
+ list->array = (char *)gl2psMalloc(list->nmax * list->size);
+ }
+ else{
+ if(n > list->nmax){
+ list->nmax = ((n - 1) / list->incr + 1) * list->incr;
+ list->array = (char *)gl2psRealloc(list->array,
+ list->nmax * list->size);
+ }
+ }
+}
+
+GL2PSlist *gl2psListCreate(GLint n, GLint incr, GLint size){
+ GL2PSlist *list;
+
+ if(n < 0) n = 0;
+ if(incr <= 0) incr = 1;
+ list = (GL2PSlist *)gl2psMalloc(sizeof(GL2PSlist));
+ list->nmax = 0;
+ list->incr = incr;
+ list->size = size;
+ list->n = 0;
+ list->array = NULL;
+ gl2psListRealloc(list, n);
+ return(list);
+}
+
+void gl2psListReset(GL2PSlist *list){
+ list->n = 0;
+}
+
+void gl2psListDelete(GL2PSlist *list){
+ gl2psFree(list->array);
+ gl2psFree(list);
+}
+
+void gl2psListAdd(GL2PSlist *list, void *data){
+ list->n++;
+ gl2psListRealloc(list, list->n);
+ memcpy(&list->array[(list->n - 1) * list->size], data, list->size);
+}
+
+GLint gl2psListNbr(GL2PSlist *list){
+ return(list->n);
+}
+
+void *gl2psListPointer(GL2PSlist *list, GLint index){
+ if((index < 0) || (index >= list->n)){
+ gl2psMsg(GL2PS_ERROR, "Wrong list index in gl2psListPointer");
+ return(&list->array[0]);
+ }
+ return(&list->array[index * list->size]);
+}
+
+void gl2psListSort(GL2PSlist *list,
+ int (*fcmp)(const void *a, const void *b)){
+ qsort(list->array, list->n, list->size, fcmp);
+}
+
+void gl2psListAction(GL2PSlist *list,
+ void (*action)(void *data, void *dummy)){
+ GLint i, dummy;
+
+ for(i = 0; i < gl2psListNbr(list); i++){
+ (*action)(gl2psListPointer(list, i), &dummy);
+ }
+}
+
+void gl2psListActionInverse(GL2PSlist *list,
+ void (*action)(void *data, void *dummy)){
+ GLint i, dummy;
+
+ for(i = gl2psListNbr(list); i > 0; i--){
+ (*action)(gl2psListPointer(list, i-1), &dummy);
+ }
+}
+
+/* The 3D sorting routines */
+
+GLfloat gl2psComparePointPlane(GL2PSxyz point, GL2PSplane plane){
+ return(plane[0] * point[0] +
+ plane[1] * point[1] +
+ plane[2] * point[2] +
+ plane[3]);
+}
+
+GLfloat gl2psPsca(GLfloat *a, GLfloat *b){
+ return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
+}
+
+void gl2psPvec(GLfloat *a, GLfloat *b, GLfloat *c){
+ c[0] = a[1]*b[2] - a[2]*b[1];
+ c[1] = a[2]*b[0] - a[0]*b[2];
+ c[2] = a[0]*b[1] - a[1]*b[0];
+}
+
+GLfloat gl2psNorm(GLfloat *a){
+ return sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
+}
+
+void gl2psGetNormal(GLfloat *a, GLfloat *b, GLfloat *c){
+ GLfloat norm;
+
+ gl2psPvec(a, b, c);
+ if(!GL2PS_ZERO(norm = gl2psNorm(c))){
+ c[0] = c[0] / norm;
+ c[1] = c[1] / norm;
+ c[2] = c[2] / norm;
+ }
+ else{
+ /* FIXME: the plane is still wrong, despite our tests in
+ gl2psGetPlane... Let's return a dummy value for now (this is a
+ hack: we should do more tests in GetPlane) */
+ c[0] = c[1] = 0.;
+ c[2] = 1.;
+ }
+}
+
+void gl2psGetPlane(GL2PSprimitive *prim, GL2PSplane plane){
+ GL2PSxyz v = {0., 0., 0.}, w = {0., 0., 0.};
+
+ switch(prim->type){
+ case GL2PS_TRIANGLE :
+ case GL2PS_QUADRANGLE :
+ v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0];
+ v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1];
+ v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2];
+ w[0] = prim->verts[2].xyz[0] - prim->verts[0].xyz[0];
+ w[1] = prim->verts[2].xyz[1] - prim->verts[0].xyz[1];
+ w[2] = prim->verts[2].xyz[2] - prim->verts[0].xyz[2];
+ if((GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])) ||
+ (GL2PS_ZERO(w[0]) && GL2PS_ZERO(w[1]) && GL2PS_ZERO(w[2]))){
+ plane[0] = plane[1] = 0.;
+ plane[2] = 1.;
+ plane[3] = -prim->verts[0].xyz[2];
+ }
+ else{
+ gl2psGetNormal(v, w, plane);
+ plane[3] =
+ - plane[0] * prim->verts[0].xyz[0]
+ - plane[1] * prim->verts[0].xyz[1]
+ - plane[2] * prim->verts[0].xyz[2];
+ }
+ break;
+ case GL2PS_LINE :
+ v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0];
+ v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1];
+ v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2];
+ if(GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])){
+ plane[0] = plane[1] = 0.;
+ plane[2] = 1.;
+ plane[3] = -prim->verts[0].xyz[2];
+ }
+ else{
+ if(GL2PS_ZERO(v[0])) w[0] = 1.;
+ else if(GL2PS_ZERO(v[1])) w[1] = 1.;
+ else w[2] = 1.;
+ gl2psGetNormal(v, w, plane);
+ plane[3] =
+ - plane[0] * prim->verts[0].xyz[0]
+ - plane[1] * prim->verts[0].xyz[1]
+ - plane[2] * prim->verts[0].xyz[2];
+ }
+ break;
+ case GL2PS_POINT :
+ case GL2PS_PIXMAP :
+ case GL2PS_TEXT :
+ plane[0] = plane[1] = 0.;
+ plane[2] = 1.;
+ plane[3] = -prim->verts[0].xyz[2];
+ break;
+ default :
+ gl2psMsg(GL2PS_ERROR, "Unknown primitive type in BSP tree");
+ plane[0] = plane[1] = plane[3] = 0.;
+ plane[2] = 1.;
+ break;
+ }
+}
+
+void gl2psCutEdge(GL2PSvertex *a, GL2PSvertex *b, GL2PSplane plane,
+ GL2PSvertex *c){
+ GL2PSxyz v;
+ GLfloat sect;
+
+ v[0] = b->xyz[0] - a->xyz[0];
+ v[1] = b->xyz[1] - a->xyz[1];
+ v[2] = b->xyz[2] - a->xyz[2];
+ sect = - gl2psComparePointPlane(a->xyz, plane) / gl2psPsca(plane, v);
+
+ c->xyz[0] = a->xyz[0] + v[0] * sect;
+ c->xyz[1] = a->xyz[1] + v[1] * sect;
+ c->xyz[2] = a->xyz[2] + v[2] * sect;
+
+ c->rgba[0] = (1.-sect) * a->rgba[0] + sect * b->rgba[0];
+ c->rgba[1] = (1.-sect) * a->rgba[1] + sect * b->rgba[1];
+ c->rgba[2] = (1.-sect) * a->rgba[2] + sect * b->rgba[2];
+ c->rgba[3] = (1.-sect) * a->rgba[3] + sect * b->rgba[3];
+}
+
+void gl2psCreateSplitPrimitive(GL2PSprimitive *parent, GL2PSplane plane,
+ GL2PSprimitive *child, GLshort numverts,
+ GLshort *index0, GLshort *index1){
+ GLshort i;
+
+ if(numverts > 4){
+ gl2psMsg(GL2PS_WARNING, "%d vertices in polygon", numverts);
+ numverts = 4;
+ }
+
+ switch(numverts){
+ case 1 : child->type = GL2PS_POINT; break;
+ case 2 : child->type = GL2PS_LINE; break;
+ case 3 : child->type = GL2PS_TRIANGLE; break;
+ case 4 : child->type = GL2PS_QUADRANGLE; break;
+ }
+ child->boundary = 0; /* not done! */
+ child->depth = parent->depth; /* should not be used in this case */
+ child->culled = parent->culled;
+ child->dash = parent->dash;
+ child->width = parent->width;
+ child->numverts = numverts;
+ child->verts = (GL2PSvertex *)gl2psMalloc(numverts * sizeof(GL2PSvertex));
+
+ for(i = 0; i < numverts; i++){
+ if(index1[i] < 0){
+ child->verts[i] = parent->verts[index0[i]];
+ }
+ else{
+ gl2psCutEdge(&parent->verts[index0[i]], &parent->verts[index1[i]],
+ plane, &child->verts[i]);
+ }
+ }
+}
+
+void gl2psAddIndex(GLshort *index0, GLshort *index1, GLshort *nb,
+ GLshort i, GLshort j){
+ GLint k;
+
+ for(k = 0; k < *nb; k++){
+ if((index0[k] == i && index1[k] == j) ||
+ (index1[k] == i && index0[k] == j)) return;
+ }
+ index0[*nb] = i;
+ index1[*nb] = j;
+ (*nb)++;
+}
+
+GLshort gl2psGetIndex(GLshort i, GLshort num){
+ return(i < num-1) ? i+1 : 0;
+}
+
+GLint gl2psTestSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane){
+ GLint type = GL2PS_COINCIDENT;
+ GLshort i, j;
+ GLfloat d[5];
+
+ for(i = 0; i < prim->numverts; i++){
+ d[i] = gl2psComparePointPlane(prim->verts[i].xyz, plane);
+ }
+
+ if(prim->numverts < 2){
+ return 0;
+ }
+ else{
+ for(i = 0; i < prim->numverts; i++){
+ j = gl2psGetIndex(i, prim->numverts);
+ if(d[j] > GL2PS_EPSILON){
+ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF;
+ else if(type != GL2PS_IN_BACK_OF) return 1;
+ if(d[i] < -GL2PS_EPSILON) return 1;
+ }
+ else if(d[j] < -GL2PS_EPSILON){
+ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF;
+ else if(type != GL2PS_IN_FRONT_OF) return 1;
+ if(d[i] > GL2PS_EPSILON) return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+GLint gl2psSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane,
+ GL2PSprimitive **front, GL2PSprimitive **back){
+ GLshort i, j, in=0, out=0, in0[5], in1[5], out0[5], out1[5];
+ GLint type;
+ GLfloat d[5];
+
+ type = GL2PS_COINCIDENT;
+
+ for(i = 0; i < prim->numverts; i++){
+ d[i] = gl2psComparePointPlane(prim->verts[i].xyz, plane);
+ }
+
+ switch(prim->type){
+ case GL2PS_POINT :
+ if(d[0] > GL2PS_EPSILON) type = GL2PS_IN_BACK_OF;
+ else if(d[0] < -GL2PS_EPSILON) type = GL2PS_IN_FRONT_OF;
+ else type = GL2PS_COINCIDENT;
+ break;
+ default :
+ for(i = 0; i < prim->numverts; i++){
+ j = gl2psGetIndex(i, prim->numverts);
+ if(d[j] > GL2PS_EPSILON){
+ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF;
+ else if(type != GL2PS_IN_BACK_OF) type = GL2PS_SPANNING;
+ if(d[i] < -GL2PS_EPSILON){
+ gl2psAddIndex(in0, in1, &in, i, j);
+ gl2psAddIndex(out0, out1, &out, i, j);
+ type = GL2PS_SPANNING;
+ }
+ gl2psAddIndex(out0, out1, &out, j, -1);
+ }
+ else if(d[j] < -GL2PS_EPSILON){
+ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF;
+ else if(type != GL2PS_IN_FRONT_OF) type = GL2PS_SPANNING;
+ if(d[i] > GL2PS_EPSILON){
+ gl2psAddIndex(in0, in1, &in, i, j);
+ gl2psAddIndex(out0, out1, &out, i, j);
+ type = GL2PS_SPANNING;
+ }
+ gl2psAddIndex(in0, in1, &in, j, -1);
+ }
+ else{
+ gl2psAddIndex(in0, in1, &in, j, -1);
+ gl2psAddIndex(out0, out1, &out, j, -1);
+ }
+ }
+ break;
+ }
+
+ if(type == GL2PS_SPANNING){
+ *back = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+ *front = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+ gl2psCreateSplitPrimitive(prim, plane, *back, out, out0, out1);
+ gl2psCreateSplitPrimitive(prim, plane, *front, in, in0, in1);
+ }
+
+ return type;
+}
+
+void gl2psDivideQuad(GL2PSprimitive *quad,
+ GL2PSprimitive **t1, GL2PSprimitive **t2){
+ *t1 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+ *t2 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+ (*t1)->type = (*t2)->type = GL2PS_TRIANGLE;
+ (*t1)->numverts = (*t2)->numverts = 3;
+ (*t1)->depth = (*t2)->depth = quad->depth;
+ (*t1)->culled = (*t2)->culled = quad->culled;
+ (*t1)->dash = (*t2)->dash = quad->dash;
+ (*t1)->width = (*t2)->width = quad->width;
+ (*t1)->verts = (GL2PSvertex *)gl2psMalloc(3 * sizeof(GL2PSvertex));
+ (*t2)->verts = (GL2PSvertex *)gl2psMalloc(3 * sizeof(GL2PSvertex));
+ (*t1)->verts[0] = quad->verts[0];
+ (*t1)->verts[1] = quad->verts[1];
+ (*t1)->verts[2] = quad->verts[2];
+ (*t1)->boundary = ((quad->boundary & 1) ? 1 : 0) | ((quad->boundary & 2) ? 2 : 0);
+ (*t2)->verts[0] = quad->verts[0];
+ (*t2)->verts[1] = quad->verts[2];
+ (*t2)->verts[2] = quad->verts[3];
+ (*t1)->boundary = ((quad->boundary & 4) ? 2 : 0) | ((quad->boundary & 4) ? 2 : 0);
+}
+
+int gl2psCompareDepth(const void *a, const void *b){
+ GL2PSprimitive *q, *w;
+ GLfloat diff;
+
+ q = *(GL2PSprimitive**)a;
+ w = *(GL2PSprimitive**)b;
+ diff = q->depth - w->depth;
+ if(diff > 0.){
+ return 1;
+ }
+ else if(diff < 0.){
+ return -1;
+ }
+ else{
+ return 0;
+ }
+}
+
+int gl2psTrianglesFirst(const void *a, const void *b){
+ GL2PSprimitive *q, *w;
+
+ q = *(GL2PSprimitive**)a;
+ w = *(GL2PSprimitive**)b;
+ return(q->type < w->type ? 1 : -1);
+}
+
+GLint gl2psFindRoot(GL2PSlist *primitives, GL2PSprimitive **root){
+ GLint i, j, count, best = 1000000, index = 0;
+ GL2PSprimitive *prim1, *prim2;
+ GL2PSplane plane;
+ GLint maxp;
+
+ if(gl2ps->options & GL2PS_BEST_ROOT){
+ *root = *(GL2PSprimitive**)gl2psListPointer(primitives, 0);
+ maxp = gl2psListNbr(primitives);
+ if(maxp > gl2ps->maxbestroot){
+ maxp = gl2ps->maxbestroot;
+ }
+ for(i = 0; i < maxp; i++){
+ prim1 = *(GL2PSprimitive**)gl2psListPointer(primitives, i);
+ gl2psGetPlane(prim1, plane);
+ count = 0;
+ for(j = 0; j < gl2psListNbr(primitives); j++){
+ if(j != i){
+ prim2 = *(GL2PSprimitive**)gl2psListPointer(primitives, j);
+ count += gl2psTestSplitPrimitive(prim2, plane);
+ }
+ if(count > best) break;
+ }
+ if(count < best){
+ best = count;
+ index = i;
+ *root = prim1;
+ if(!count) return index;
+ }
+ }
+ /* if(index) gl2psMsg(GL2PS_INFO, "GL2PS_BEST_ROOT was worth it: %d", index); */
+ return index;
+ }
+ else{
+ *root = *(GL2PSprimitive**)gl2psListPointer(primitives, 0);
+ return 0;
+ }
+}
+
+void gl2psFreePrimitive(void *a, void *b){
+ GL2PSprimitive *q;
+
+ q = *(GL2PSprimitive**)a;
+ gl2psFree(q->verts);
+ if(q->type == GL2PS_TEXT){
+ gl2psFree(q->text->str);
+ gl2psFree(q->text->fontname);
+ gl2psFree(q->text);
+ }
+ if(q->type == GL2PS_PIXMAP){
+ gl2psFree(q->image->pixels);
+ gl2psFree(q->image);
+ }
+ gl2psFree(q);
+}
+
+void gl2psAddPrimitiveInList(GL2PSprimitive *prim, GL2PSlist *list){
+ GL2PSprimitive *t1, *t2;
+
+ if(prim->type != GL2PS_QUADRANGLE){
+ gl2psListAdd(list, &prim);
+ }
+ else{
+ gl2psDivideQuad(prim, &t1, &t2);
+ gl2psListAdd(list, &t1);
+ gl2psListAdd(list, &t2);
+ gl2psFreePrimitive(&prim, NULL);
+ }
+
+}
+
+void gl2psFreeBspTree(GL2PSbsptree **tree){
+ if(*tree){
+ if((*tree)->back) gl2psFreeBspTree(&(*tree)->back);
+ if((*tree)->primitives){
+ gl2psListAction((*tree)->primitives, gl2psFreePrimitive);
+ gl2psListDelete((*tree)->primitives);
+ }
+ if((*tree)->front) gl2psFreeBspTree(&(*tree)->front);
+ gl2psFree(*tree);
+ *tree = NULL;
+ }
+}
+
+GLboolean gl2psGreater(GLfloat f1, GLfloat f2){
+ if(f1 > f2) return 1;
+ else return 0;
+}
+
+GLboolean gl2psLess(GLfloat f1, GLfloat f2){
+ if(f1 < f2) return 1;
+ else return 0;
+}
+
+void gl2psBuildBspTree(GL2PSbsptree *tree, GL2PSlist *primitives){
+ GL2PSprimitive *prim, *frontprim, *backprim;
+ GL2PSlist *frontlist, *backlist;
+ GLint i, index;
+
+ tree->front = NULL;
+ tree->back = NULL;
+ tree->primitives = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*));
+ index = gl2psFindRoot(primitives, &prim);
+ gl2psGetPlane(prim, tree->plane);
+ gl2psAddPrimitiveInList(prim, tree->primitives);
+
+ frontlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*));
+ backlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*));
+
+ for(i = 0; i < gl2psListNbr(primitives); i++){
+ if(i != index){
+ prim = *(GL2PSprimitive**)gl2psListPointer(primitives,i);
+ switch(gl2psSplitPrimitive(prim, tree->plane, &frontprim, &backprim)){
+ case GL2PS_COINCIDENT:
+ gl2psAddPrimitiveInList(prim, tree->primitives);
+ break;
+ case GL2PS_IN_BACK_OF:
+ gl2psAddPrimitiveInList(prim, backlist);
+ break;
+ case GL2PS_IN_FRONT_OF:
+ gl2psAddPrimitiveInList(prim, frontlist);
+ break;
+ case GL2PS_SPANNING:
+ gl2psAddPrimitiveInList(backprim, backlist);
+ gl2psAddPrimitiveInList(frontprim, frontlist);
+ gl2psFreePrimitive(&prim, NULL);
+ break;
+ }
+ }
+ }
+
+ if(gl2psListNbr(tree->primitives)){
+ gl2psListSort(tree->primitives, gl2psTrianglesFirst);
+ }
+
+ if(gl2psListNbr(frontlist)){
+ gl2psListSort(frontlist, gl2psTrianglesFirst);
+ tree->front = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree));
+ gl2psBuildBspTree(tree->front, frontlist);
+ }
+ else{
+ gl2psListDelete(frontlist);
+ }
+
+ if(gl2psListNbr(backlist)){
+ gl2psListSort(backlist, gl2psTrianglesFirst);
+ tree->back = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree));
+ gl2psBuildBspTree(tree->back, backlist);
+ }
+ else{
+ gl2psListDelete(backlist);
+ }
+
+ gl2psListDelete(primitives);
+}
+
+void gl2psTraverseBspTree(GL2PSbsptree *tree, GL2PSxyz eye, GLfloat epsilon,
+ GLboolean (*compare)(GLfloat f1, GLfloat f2),
+ void (*action)(void *data, void *dummy)){
+ GLfloat result;
+
+ if(!tree) return;
+
+ result = gl2psComparePointPlane(eye, tree->plane);
+
+ if(compare(result, epsilon)){
+ gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action);
+ gl2psListAction(tree->primitives, action);
+ gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action);
+ }
+ else if(compare(-epsilon, result)){
+ gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action);
+ gl2psListAction(tree->primitives, action);
+ gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action);
+ }
+ else{
+ gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action);
+ gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action);
+ }
+}
+
+/* The 2D sorting routines (for occlusion culling) */
+
+GLint gl2psGetPlaneFromPoints(GL2PSxyz a, GL2PSxyz b, GL2PSplane plane){
+ GLfloat n;
+
+ plane[0] = b[1] - a[1];
+ plane[1] = a[0] - b[0];
+ n = sqrt(plane[0]*plane[0] + plane[1]*plane[1]);
+ plane[2]=0.;
+ if(n != 0.){
+ plane[0] /= n;
+ plane[1] /= n;
+ plane[3] = -plane[0]*a[0]-plane[1]*a[1];
+ return 1;
+ }
+ else{
+ plane[0] = -1.0;
+ plane[1] = 0.;
+ plane[3] = a[0];
+ return 0;
+ }
+}
+
+void gl2psFreeBspImageTree(GL2PSbsptree2d **tree){
+ if(*tree){
+ if((*tree)->back) gl2psFreeBspImageTree(&(*tree)->back);
+ if((*tree)->front) gl2psFreeBspImageTree(&(*tree)->front);
+ gl2psFree(*tree);
+ *tree = NULL;
+ }
+}
+
+GLint gl2psCheckPoint(GL2PSxyz point, GL2PSplane plane){
+ GLfloat pt_dis;
+
+ pt_dis = gl2psComparePointPlane(point, plane);
+ if(pt_dis > GL2PS_EPSILON) return GL2PS_POINT_INFRONT;
+ else if(pt_dis < -GL2PS_EPSILON) return GL2PS_POINT_BACK;
+ else return GL2PS_POINT_COINCIDENT;
+}
+
+void gl2psAddPlanesInBspTreeImage(GL2PSprimitive *prim,
+ GL2PSbsptree2d **tree){
+ GLint ret = 0;
+ GLint i;
+ GLint offset = 0;
+ GL2PSbsptree2d *head = NULL, *cur = NULL;
+
+ if((*tree == NULL) && (prim->numverts > 2)){
+ head = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
+ for(i = 0; i < prim->numverts-1; i++){
+ if(!gl2psGetPlaneFromPoints(prim->verts[i].xyz,
+ prim->verts[i+1].xyz,
+ head->plane)){
+ if(prim->numverts-i > 3){
+ offset++;
+ }
+ else{
+ gl2psFree(head);
+ return;
+ }
+ }
+ else{
+ break;
+ }
+ }
+ head->back = NULL;
+ head->front = NULL;
+ for(i = 2+offset; i < prim->numverts; i++){
+ ret = gl2psCheckPoint(prim->verts[i].xyz, head->plane);
+ if(ret != GL2PS_POINT_COINCIDENT) break;
+ }
+ switch(ret){
+ case GL2PS_POINT_INFRONT :
+ cur = head;
+ for(i = 1+offset; i < prim->numverts-1; i++){
+ if(cur->front == NULL){
+ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
+ }
+ if(gl2psGetPlaneFromPoints(prim->verts[i].xyz,
+ prim->verts[i+1].xyz,
+ cur->front->plane)){
+ cur = cur->front;
+ cur->front = NULL;
+ cur->back = NULL;
+ }
+ }
+ if(cur->front == NULL){
+ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
+ }
+ if(gl2psGetPlaneFromPoints(prim->verts[i].xyz,
+ prim->verts[offset].xyz,
+ cur->front->plane)){
+ cur->front->front = NULL;
+ cur->front->back = NULL;
+ }
+ else{
+ gl2psFree(cur->front);
+ cur->front = NULL;
+ }
+ break;
+ case GL2PS_POINT_BACK :
+ for(i = 0; i < 4; i++){
+ head->plane[i] = -head->plane[i];
+ }
+ cur = head;
+ for(i = 1+offset; i < prim->numverts-1; i++){
+ if(cur->front == NULL){
+ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
+ }
+ if(gl2psGetPlaneFromPoints(prim->verts[i+1].xyz,
+ prim->verts[i].xyz,
+ cur->front->plane)){
+ cur = cur->front;
+ cur->front = NULL;
+ cur->back = NULL;
+ }
+ }
+ if(cur->front == NULL){
+ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
+ }
+ if(gl2psGetPlaneFromPoints(prim->verts[offset].xyz,
+ prim->verts[i].xyz,
+ cur->front->plane)){
+ cur->front->front = NULL;
+ cur->front->back = NULL;
+ }
+ else{
+ gl2psFree(cur->front);
+ cur->front = NULL;
+ }
+ break;
+ default:
+ gl2psFree(head);
+ return;
+ }
+ (*tree) = head;
+ }
+}
+
+GLint gl2psCheckPrimitive(GL2PSprimitive *prim, GL2PSplane plane){
+ GLint i;
+ GLint pos;
+
+ pos = gl2psCheckPoint(prim->verts[0].xyz, plane);
+ for(i = 1; i < prim->numverts; i++){
+ pos |= gl2psCheckPoint(prim->verts[i].xyz, plane);
+ if(pos == (GL2PS_POINT_INFRONT | GL2PS_POINT_BACK)) return GL2PS_SPANNING;
+ }
+ if(pos & GL2PS_POINT_INFRONT) return GL2PS_IN_FRONT_OF;
+ else if(pos & GL2PS_POINT_BACK) return GL2PS_IN_BACK_OF;
+ else return GL2PS_COINCIDENT;
+}
+
+GL2PSprimitive* gl2psCreateSplitPrimitive2D(GL2PSprimitive *parent,
+ GLshort numverts,
+ GL2PSvertex *vertx){
+ GLint i;
+ GL2PSprimitive *child = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+
+ switch(numverts){
+ case 1 : child->type = GL2PS_POINT; break;
+ case 2 : child->type = GL2PS_LINE; break;
+ case 3 : child->type = GL2PS_TRIANGLE; break;
+ case 4 : child->type = GL2PS_QUADRANGLE; break;
+ }
+ child->boundary = 0; /* not done! */
+ child->depth = parent->depth;
+ child->culled = parent->culled;
+ child->dash = parent->dash;
+ child->width = parent->width;
+ child->numverts = numverts;
+ child->verts = (GL2PSvertex *)gl2psMalloc(numverts * sizeof(GL2PSvertex));
+ for(i = 0; i < numverts; i++){
+ child->verts[i] = vertx[i];
+ }
+ return child;
+}
+
+void gl2psSplitPrimitive2D(GL2PSprimitive *prim,
+ GL2PSplane plane,
+ GL2PSprimitive **front,
+ GL2PSprimitive **back){
+
+ /* cur will hold the position of the current vertex
+ prev will hold the position of the previous vertex
+ prev0 will hold the position of the vertex number 0
+ v1 and v2 represent the current and previous vertices, respectively
+ flag is set if the current vertex should be checked against the plane */
+ GLint cur = -1, prev = -1, i, v1 = 0, v2 = 0, flag = 1, prev0 = -1;
+
+ /* list of vertices that will go in front and back primitive */
+ GL2PSvertex *front_list = NULL, *back_list = NULL;
+
+ /* number of vertices in front and back list */
+ GLint front_count = 0, back_count = 0;
+
+ for(i = 0; i <= prim->numverts; i++){
+ v1 = i;
+ if(v1 == prim->numverts){
+ if(prim->numverts < 3) break;
+ v1 = 0;
+ v2 = prim->numverts-1;
+ cur = prev0;
+ }
+ else if(flag){
+ cur = gl2psCheckPoint(prim->verts[v1].xyz, plane);
+ if(i == 0){
+ prev0 = cur;
+ }
+ }
+ if(((prev == -1) || (prev == cur) || (prev == 0) || (cur == 0)) &&
+ (i < prim->numverts)){
+ if(cur == GL2PS_POINT_INFRONT){
+ front_count++;
+ front_list = (GL2PSvertex*)gl2psRealloc(front_list,
+ sizeof(GL2PSvertex)*front_count);
+ front_list[front_count-1] = prim->verts[v1];
+ }
+ else if(cur == GL2PS_POINT_BACK){
+ back_count++;
+ back_list = (GL2PSvertex*)gl2psRealloc(back_list,
+ sizeof(GL2PSvertex)*back_count);
+ back_list[back_count-1] = prim->verts[v1];
+ }
+ else{
+ front_count++;
+ front_list = (GL2PSvertex*)gl2psRealloc(front_list,
+ sizeof(GL2PSvertex)*front_count);
+ front_list[front_count-1] = prim->verts[v1];
+ back_count++;
+ back_list = (GL2PSvertex*)gl2psRealloc(back_list,
+ sizeof(GL2PSvertex)*back_count);
+ back_list[back_count-1] = prim->verts[v1];
+ }
+ flag = 1;
+ }
+ else if((prev != cur) && (cur != 0) && (prev != 0)){
+ if(v1 != 0){
+ v2 = v1-1;
+ i--;
+ }
+ front_count++;
+ front_list = (GL2PSvertex*)gl2psRealloc(front_list,
+ sizeof(GL2PSvertex)*front_count);
+ gl2psCutEdge(&prim->verts[v2],
+ &prim->verts[v1],
+ plane,
+ &front_list[front_count-1]);
+ back_count++;
+ back_list = (GL2PSvertex*)gl2psRealloc(back_list,
+ sizeof(GL2PSvertex)*back_count);
+ back_list[back_count-1] = front_list[front_count-1];
+ flag = 0;
+ }
+ prev = cur;
+ }
+ *front = gl2psCreateSplitPrimitive2D(prim, front_count, front_list);
+ *back = gl2psCreateSplitPrimitive2D(prim, back_count, back_list);
+ gl2psFree(front_list);
+ gl2psFree(back_list);
+}
+
+GLint gl2psAddInBspImageTree(GL2PSprimitive *prim, GL2PSbsptree2d **tree){
+ GLint ret = 0;
+ GL2PSprimitive *frontprim = NULL, *backprim = NULL;
+
+ /* FIXME: until we consider the actual extent of text strings and
+ pixmaps, never cull them. Otherwise the whole string/pixmap gets
+ culled as soon as the reference point is hidden */
+ if(prim->type == GL2PS_PIXMAP || prim->type == GL2PS_TEXT){
+ return 1;
+ }
+
+ if(*tree == NULL){
+ gl2psAddPlanesInBspTreeImage(prim, tree);
+ return 1;
+ }
+ else{
+ switch(gl2psCheckPrimitive(prim, (*tree)->plane)){
+ case GL2PS_IN_BACK_OF: return gl2psAddInBspImageTree(prim, &(*tree)->back);
+ case GL2PS_IN_FRONT_OF:
+ if((*tree)->front != NULL) return gl2psAddInBspImageTree(prim, &(*tree)->front);
+ else return 0;
+ case GL2PS_SPANNING:
+ gl2psSplitPrimitive2D(prim, (*tree)->plane, &frontprim, &backprim);
+ ret = gl2psAddInBspImageTree(backprim, &(*tree)->back);
+ if((*tree)->front != NULL){
+ if(gl2psAddInBspImageTree(frontprim, &(*tree)->front)){
+ ret = 1;
+ }
+ }
+ gl2psFree(frontprim->verts);
+ gl2psFree(frontprim);
+ gl2psFree(backprim->verts);
+ gl2psFree(backprim);
+ return ret;
+ case GL2PS_COINCIDENT:
+ if(prim->numverts < 3) return 1;
+ else return 0;
+ }
+ }
+ return 0;
+}
+
+void gl2psAddInImageTree(void *a, void *b){
+ GL2PSprimitive *prim = *(GL2PSprimitive **)a;
+
+ if(!gl2psAddInBspImageTree(prim, &gl2ps->imagetree)){
+ prim->culled = 1;
+ }
+}
+
+/* Boundary contruction */
+
+void gl2psAddBoundaryInList(GL2PSprimitive *prim, GL2PSlist *list){
+ GL2PSprimitive *b;
+ GLshort i;
+ GL2PSxyz c;
+
+ c[0] = c[1] = c[2] = 0.;
+ for(i = 0; i < prim->numverts; i++){
+ c[0] += prim->verts[i].xyz[0];
+ c[1] += prim->verts[i].xyz[1];
+ }
+ c[0] /= prim->numverts;
+ c[1] /= prim->numverts;
+
+ for(i = 0; i < prim->numverts; i++){
+ if(prim->boundary & (GLint)pow(2., i)){
+ b = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+ b->type = GL2PS_LINE;
+ b->dash = prim->dash;
+ b->depth = prim->depth; /* FIXME: this is wrong */
+ b->culled = prim->culled;
+ b->width = prim->width;
+ b->boundary = 0;
+ b->numverts = 2;
+ b->verts = (GL2PSvertex *)gl2psMalloc(2 * sizeof(GL2PSvertex));
+
+#if 0 /* FIXME: need to work on boundary offset... */
+ v[0] = c[0] - prim->verts[i].xyz[0];
+ v[1] = c[1] - prim->verts[i].xyz[1];
+ v[2] = 0.;
+ norm = gl2psNorm(v);
+ v[0] /= norm;
+ v[1] /= norm;
+ b->verts[0].xyz[0] = prim->verts[i].xyz[0] +0.1*v[0];
+ b->verts[0].xyz[1] = prim->verts[i].xyz[1] +0.1*v[1];
+ b->verts[0].xyz[2] = prim->verts[i].xyz[2];
+ v[0] = c[0] - prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0];
+ v[1] = c[1] - prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1];
+ norm = gl2psNorm(v);
+ v[0] /= norm;
+ v[1] /= norm;
+ b->verts[1].xyz[0] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0] +0.1*v[0];
+ b->verts[1].xyz[1] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1] +0.1*v[1];
+ b->verts[1].xyz[2] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[2];
+#else
+ b->verts[0].xyz[0] = prim->verts[i].xyz[0];
+ b->verts[0].xyz[1] = prim->verts[i].xyz[1];
+ b->verts[0].xyz[2] = prim->verts[i].xyz[2];
+ b->verts[1].xyz[0] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0];
+ b->verts[1].xyz[1] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1];
+ b->verts[1].xyz[2] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[2];
+#endif
+
+ b->verts[0].rgba[0] = 0.;
+ b->verts[0].rgba[1] = 0.;
+ b->verts[0].rgba[2] = 0.;
+ b->verts[0].rgba[3] = 0.;
+ b->verts[1].rgba[0] = 0.;
+ b->verts[1].rgba[1] = 0.;
+ b->verts[1].rgba[2] = 0.;
+ b->verts[1].rgba[3] = 0.;
+ gl2psListAdd(list, &b);
+ }
+ }
+
+}
+
+void gl2psBuildPolygonBoundary(GL2PSbsptree *tree){
+ GLint i, n;
+ GL2PSprimitive *prim;
+
+ if(!tree) return;
+ gl2psBuildPolygonBoundary(tree->back);
+ n = gl2psListNbr(tree->primitives);
+ for(i = 0; i < n; i++){
+ prim = *(GL2PSprimitive**)gl2psListPointer(tree->primitives, i);
+ if(prim->boundary) gl2psAddBoundaryInList(prim, tree->primitives);
+ }
+ gl2psBuildPolygonBoundary(tree->front);
+}
+
+/* The feedback buffer parser */
+
+void gl2psAddPolyPrimitive(GLshort type, GLshort numverts,
+ GL2PSvertex *verts, GLint offset,
+ char dash, GLfloat width,
+ char boundary){
+ GLshort i;
+ GLfloat factor, units, area, dZ, dZdX, dZdY, maxdZ;
+ GL2PSprimitive *prim;
+
+ prim = (GL2PSprimitive *)gl2psMalloc(sizeof(GL2PSprimitive));
+ prim->type = type;
+ prim->numverts = numverts;
+ prim->verts = (GL2PSvertex *)gl2psMalloc(numverts * sizeof(GL2PSvertex));
+ memcpy(prim->verts, verts, numverts * sizeof(GL2PSvertex));
+ prim->boundary = boundary;
+ prim->dash = dash;
+ prim->width = width;
+ prim->culled = 0;
+
+ if(gl2ps->options & GL2PS_SIMPLE_LINE_OFFSET){
+
+ if(type == GL2PS_LINE){
+ if(gl2ps->sort == GL2PS_SIMPLE_SORT){
+ prim->verts[0].xyz[2] -= GL2PS_SIMPLE_OFFSET_LARGE;
+ prim->verts[1].xyz[2] -= GL2PS_SIMPLE_OFFSET_LARGE;
+ }
+ else{
+ prim->verts[0].xyz[2] -= GL2PS_SIMPLE_OFFSET;
+ prim->verts[1].xyz[2] -= GL2PS_SIMPLE_OFFSET;
+ }
+ }
+
+ }
+ else if(offset && type == GL2PS_TRIANGLE){
+
+ /* FIXME: this needs some more work... */
+
+ if(gl2ps->sort == GL2PS_SIMPLE_SORT){
+ factor = gl2ps->offset[0];
+ units = gl2ps->offset[1];
+ }
+ else{
+ factor = gl2ps->offset[0] / 800.;
+ units = gl2ps->offset[1] / 800.;
+ }
+
+ area =
+ (prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) *
+ (prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) -
+ (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) *
+ (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]);
+ dZdX =
+ (prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) *
+ (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) -
+ (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]) *
+ (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) / area;
+ dZdY =
+ (prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) *
+ (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) -
+ (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) *
+ (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) / area;
+
+ maxdZ = sqrt(dZdX*dZdX + dZdY*dZdY);
+
+ dZ = factor * maxdZ + units;
+
+ prim->verts[0].xyz[2] += dZ;
+ prim->verts[1].xyz[2] += dZ;
+ prim->verts[2].xyz[2] += dZ;
+ }
+
+ prim->depth = 0.;
+ if(gl2ps->sort == GL2PS_SIMPLE_SORT){
+ for(i = 0; i < numverts; i++){
+ prim->depth += prim->verts[i].xyz[2];
+ }
+ prim->depth /= (GLfloat)numverts;
+ }
+
+ gl2psListAdd(gl2ps->primitives, &prim);
+}
+
+GLint gl2psGetVertex(GL2PSvertex *v, GLfloat *p){
+ GLint i;
+
+ v->xyz[0] = p[0];
+ v->xyz[1] = p[1];
+ v->xyz[2] = GL2PS_DEPTH_FACT * p[2];
+
+ if(gl2ps->colormode == GL_COLOR_INDEX && gl2ps->colorsize > 0){
+ i = (GLint)(p[3] + 0.5);
+ v->rgba[0] = gl2ps->colormap[i][0];
+ v->rgba[1] = gl2ps->colormap[i][1];
+ v->rgba[2] = gl2ps->colormap[i][2];
+ v->rgba[3] = gl2ps->colormap[i][3];
+ return 4;
+ }
+ else{
+ v->rgba[0] = p[3];
+ v->rgba[1] = p[4];
+ v->rgba[2] = p[5];
+ v->rgba[3] = p[6];
+ return 7;
+ }
+}
+
+GLint gl2psParseFeedbackBuffer(void){
+ char flag, dash = 0;
+ GLshort boundary;
+ GLint i, used, count, v, vtot, offset = 0;
+ GLfloat lwidth = 1., psize = 1.;
+ GLfloat *current;
+ GL2PSvertex vertices[3];
+
+ used = glRenderMode(GL_RENDER);
+
+ if(used < 0){
+ gl2psMsg(GL2PS_INFO, "OpenGL feedback buffer overflow");
+ return GL2PS_OVERFLOW;
+ }
+
+ if(used == 0){
+ /* gl2psMsg(GL2PS_INFO, "Empty feedback buffer"); */
+ return GL2PS_NO_FEEDBACK;
+ }
+
+ current = gl2ps->feedback;
+ boundary = gl2ps->boundary = 0;
+
+ while(used > 0){
+
+ if(boundary) gl2ps->boundary = 1;
+
+ switch((GLint)*current){
+ case GL_POINT_TOKEN :
+ current ++;
+ used --;
+ i = gl2psGetVertex(&vertices[0], current);
+ current += i;
+ used -= i;
+ gl2psAddPolyPrimitive(GL2PS_POINT, 1, vertices, 0, dash, psize, 0);
+ break;
+ case GL_LINE_TOKEN :
+ case GL_LINE_RESET_TOKEN :
+ current ++;
+ used --;
+ i = gl2psGetVertex(&vertices[0], current);
+ current += i;
+ used -= i;
+ i = gl2psGetVertex(&vertices[1], current);
+ current += i;
+ used -= i;
+ gl2psAddPolyPrimitive(GL2PS_LINE, 2, vertices, 0, dash, lwidth, 0);
+ break;
+ case GL_POLYGON_TOKEN :
+ count = (GLint)current[1];
+ current += 2;
+ used -= 2;
+ v = vtot = 0;
+ while(count > 0 && used > 0){
+ i = gl2psGetVertex(&vertices[v], current);
+ current += i;
+ used -= i;
+ count --;
+ vtot++;
+ if(v == 2){
+ if(boundary){
+ if(!count && vtot == 2) flag = 1|2|4;
+ else if(!count) flag = 2|4;
+ else if(vtot == 2) flag = 1|2;
+ else flag = 2;
+ }
+ else
+ flag = 0;
+ gl2psAddPolyPrimitive(GL2PS_TRIANGLE, 3, vertices,
+ offset, dash, 1, flag);
+ vertices[1] = vertices[2];
+ }
+ else
+ v ++;
+ }
+ break;
+ case GL_BITMAP_TOKEN :
+ case GL_DRAW_PIXEL_TOKEN :
+ case GL_COPY_PIXEL_TOKEN :
+ current ++;
+ used --;
+ i = gl2psGetVertex(&vertices[0], current);
+ current += i;
+ used -= i;
+ break;
+ case GL_PASS_THROUGH_TOKEN :
+ switch((GLint)current[1]){
+ case GL2PS_BEGIN_POLYGON_OFFSET_FILL : offset = 1; break;
+ case GL2PS_END_POLYGON_OFFSET_FILL : offset = 0; break;
+ case GL2PS_BEGIN_POLYGON_BOUNDARY : boundary = 1; break;
+ case GL2PS_END_POLYGON_BOUNDARY : boundary = 0; break;
+ case GL2PS_BEGIN_LINE_STIPPLE : dash = 4; break;
+ case GL2PS_END_LINE_STIPPLE : dash = 0; break;
+ case GL2PS_SET_POINT_SIZE :
+ current += 2;
+ used -= 2;
+ psize = current[1];
+ break;
+ case GL2PS_SET_LINE_WIDTH :
+ current += 2;
+ used -= 2;
+ lwidth = current[1];
+ break;
+ }
+ current += 2;
+ used -= 2;
+ break;
+ default :
+ gl2psMsg(GL2PS_WARNING, "Unknown token in buffer");
+ current ++;
+ used --;
+ break;
+ }
+ }
+
+ return GL2PS_SUCCESS;
+}
+
+GLboolean gl2psSameColor(GL2PSrgba rgba1, GL2PSrgba rgba2){
+ return !(rgba1[0] != rgba2[0] ||
+ rgba1[1] != rgba2[1] ||
+ rgba1[2] != rgba2[2]);
+}
+
+GLboolean gl2psVertsSameColor(const GL2PSprimitive *prim){
+ int i;
+
+ for(i = 1; i < prim->numverts; i++){
+ if(!gl2psSameColor(prim->verts[0].rgba, prim->verts[i].rgba)){
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* The PostScript routines. Other (vector) image formats should be
+ easy to generate by creating the three corresponding routines
+ (gl2psPrintXXXHeader, gl2psPrintXXXPrimitive, gl2psPrintXXXFooter,
+ gl2psPrintXXXBeginViewport and gl2psPrintXXXEndViewport) for the
+ new format. */
+
+void gl2psWriteByte(FILE *stream, unsigned char byte){
+ unsigned char h = byte / 16;
+ unsigned char l = byte % 16;
+ fprintf(stream, "%x%x", h, l);
+}
+
+int gl2psGetRGB(GLfloat *pixels, GLsizei width, GLsizei height, GLuint x, GLuint y,
+ GLfloat *red, GLfloat *green, GLfloat *blue){
+ /* OpenGL image is from down to up, PS image is up to down */
+ GLfloat *pimag;
+ pimag = pixels + 3 * (width * (height - 1 - y) + x);
+ *red = *pimag; pimag++;
+ *green = *pimag; pimag++;
+ *blue = *pimag; pimag++;
+ return 1;
+}
+
+void gl2psPrintPostScriptPixmap(GLfloat x, GLfloat y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLfloat *pixels,
+ FILE *stream){
+ typedef unsigned char Uchar;
+ int status = 1, nbhex, nbyte2, nbyte4, nbyte8;
+ GLsizei row, col, col_max;
+ float dr, dg, db, fgrey;
+ Uchar red, green, blue, b, grey;
+ /* FIXME: this has to be generalized... */
+ int shade = 0;
+ int nbit = 4;
+
+ if((width <= 0) || (height <= 0)) return;
+
+ /* Msg(INFO, "gl2psPrintPostScriptPixmap: x %g y %g w %d h %d", x, y, width, height); */
+
+ fprintf(stream, "gsave\n");
+ fprintf(stream, "%.2f %.2f translate\n", x, y);
+ fprintf(stream, "%d %d scale\n", width, height);
+
+ if(shade != 0){ /* grey */
+ fprintf(stream, "/picstr %d string def\n", width);
+ fprintf(stream, "%d %d %d\n", width, height, 8);
+ fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", width, height, height);
+ fprintf(stream, "{ currentfile picstr readhexstring pop }\n");
+ fprintf(stream, "image\n");
+ for(row = 0; row < height; row++){
+ for(col = 0; col < width; col++){
+ status = gl2psGetRGB(pixels, width, height,
+ col, row, &dr, &dg, &db) == 0 ? 0 : status;
+ fgrey = (0.30 * dr + 0.59 * dg + 0.11 * db);
+ grey = (Uchar)(255. * fgrey);
+ gl2psWriteByte(stream, grey);
+ }
+ fprintf(stream, "\n");
+ }
+ nbhex = width * height * 2;
+ fprintf(stream, "%%%% nbhex digit :%d\n", nbhex);
+ }
+ else if(nbit == 2){
+ nbyte2 = (width * 3)/4;
+ nbyte2 /=3;
+ nbyte2 *=3;
+ col_max = (nbyte2 * 4)/3;
+ /* 2 bit for r and g and b */
+ /* rgbs following each other */
+ fprintf(stream, "/rgbstr %d string def\n", nbyte2);
+ fprintf(stream, "%d %d %d\n", col_max, height, 2);
+ fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", col_max, height, height);
+ fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n" );
+ fprintf(stream, "false 3\n" );
+ fprintf(stream, "colorimage\n" );
+ for(row = 0; row < height; row++){
+ for(col = 0; col < col_max; col+=4){
+ status = gl2psGetRGB(pixels, width, height,
+ col, row, &dr, &dg, &db) == 0 ? 0 : status;
+ red = (Uchar)(3. * dr);
+ green = (Uchar)(3. * dg);
+ blue = (Uchar)(3. * db);
+ b = red;
+ b = (b<<2)+green;
+ b = (b<<2)+blue;
+ status = gl2psGetRGB(pixels, width, height,
+ col+1, row, &dr, &dg, &db) == 0 ? 0 : status;
+ red = (Uchar)(3. * dr);
+ green = (Uchar)(3. * dg);
+ blue = (Uchar)(3. * db);
+ b = (b<<2)+red;
+ gl2psWriteByte(stream, b);
+
+ b = green;
+ b = (b<<2)+blue;
+ status = gl2psGetRGB(pixels, width, height,
+ col+2, row, &dr, &dg, &db) == 0 ? 0 : status;
+ red = (Uchar)(3. * dr);
+ green = (Uchar)(3. * dg);
+ blue = (Uchar)(3. * db);
+ b = (b<<2)+red;
+ b = (b<<2)+green;
+ gl2psWriteByte(stream, b);
+
+ b = blue;
+ status = gl2psGetRGB(pixels,width,height,
+ col+3, row, &dr, &dg, &db) == 0 ? 0 : status;
+ red = (Uchar)(3. * dr);
+ green = (Uchar)(3. * dg);
+ blue = (Uchar)(3. * db);
+ b = (b<<2)+red;
+ b = (b<<2)+green;
+ b = (b<<2)+blue;
+ gl2psWriteByte(stream, b);
+ }
+ fprintf(stream, "\n");
+ }
+ }
+ else if(nbit == 4){
+ nbyte4 = (width * 3)/2;
+ nbyte4 /=3;
+ nbyte4 *=3;
+ col_max = (nbyte4 * 2)/3;
+ /* 4 bit for r and g and b */
+ /* rgbs following each other */
+ fprintf(stream, "/rgbstr %d string def\n", nbyte4);
+ fprintf(stream, "%d %d %d\n", col_max, height,4);
+ fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", col_max, height, height);
+ fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n");
+ fprintf(stream, "false 3\n");
+ fprintf(stream, "colorimage\n");
+ for(row = 0; row < height; row++){
+ for(col = 0; col < col_max; col+=2){
+ status = gl2psGetRGB(pixels, width, height,
+ col, row, &dr, &dg, &db) == 0 ? 0 : status;
+ red = (Uchar)(15. * dr);
+ green = (Uchar)(15. * dg);
+ fprintf(stream, "%x%x", red, green);
+ blue = (Uchar)(15. * db);
+
+ status = gl2psGetRGB(pixels, width, height,
+ col+1, row, &dr, &dg, &db) == 0 ? 0 : status;
+ red = (Uchar)(15. * dr);
+ fprintf(stream,"%x%x",blue,red);
+ green = (Uchar)(15. * dg);
+ blue = (Uchar)(15. * db);
+ fprintf(stream, "%x%x", green, blue);
+ }
+ fprintf(stream, "\n");
+ }
+ }
+ else{
+ nbyte8 = width * 3;
+ /* 8 bit for r and g and b */
+ fprintf(stream, "/rgbstr %d string def\n", nbyte8);
+ fprintf(stream, "%d %d %d\n", width, height, 8);
+ fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", width, height, height);
+ fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n");
+ fprintf(stream, "false 3\n");
+ fprintf(stream, "colorimage\n");
+ for(row = 0; row < height; row++){
+ for(col = 0; col < width; col++){
+ status = gl2psGetRGB(pixels, width, height,
+ col, row, &dr, &dg, &db) == 0 ? 0 : status;
+ red = (Uchar)(255. * dr);
+ gl2psWriteByte(stream, red);
+ green = (Uchar)(255. * dg);
+ gl2psWriteByte(stream, green);
+ blue = (Uchar)(255. * db);
+ gl2psWriteByte(stream, blue);
+ }
+ fprintf(stream, "\n");
+ }
+ }
+
+ if(status == 0){
+ gl2psMsg(GL2PS_ERROR, "Problem to retrieve some pixel rgb");
+ }
+ fprintf(stream, "grestore\n");
+}
+
+void gl2psPrintPostScriptHeader(void){
+ GLint index;
+ GLfloat rgba[4];
+ time_t now;
+
+ time(&now);
+
+ if(gl2ps->format == GL2PS_PS){
+ fprintf(gl2ps->stream, "%%!PS-Adobe-3.0\n");
+ }
+ else{
+ fprintf(gl2ps->stream, "%%!PS-Adobe-3.0 EPSF-3.0\n");
+ }
+
+ fprintf(gl2ps->stream,
+ "%%%%Title: %s\n"
+ "%%%%Creator: GL2PS %d.%d.%d, an OpenGL to PostScript Printing Library\n"
+ "%%%%For: %s\n"
+ "%%%%CreationDate: %s"
+ "%%%%LanguageLevel: 3\n"
+ "%%%%DocumentData: Clean7Bit\n"
+ "%%%%Pages: 1\n",
+ gl2ps->title, GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION,
+ gl2ps->producer, ctime(&now));
+
+ if(gl2ps->format == GL2PS_PS){
+ fprintf(gl2ps->stream,
+ "%%%%Orientation: %s\n"
+ "%%%%DocumentMedia: Default %d %d 0 () ()\n",
+ (gl2ps->options & GL2PS_LANDSCAPE) ? "Landscape" : "Portrait",
+ (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[3] : gl2ps->viewport[2],
+ (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[2] : gl2ps->viewport[3]);
+ }
+
+ fprintf(gl2ps->stream,
+ "%%%%BoundingBox: %d %d %d %d\n"
+ "%%%%Copyright: GNU LGPL (C) 1999-2003 Christophe Geuzaine <geuz@geuz.org>\n"
+ "%%%%EndComments\n",
+ (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[1] : gl2ps->viewport[0],
+ (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[0] : gl2ps->viewport[1],
+ (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[3] : gl2ps->viewport[2],
+ (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[2] : gl2ps->viewport[3]);
+
+ /* RGB color: r g b C (replace C by G in output to change from rgb to gray)
+ Grayscale: r g b G
+ Font choose: size fontname FC
+ String primitive: (string) x y size fontname S
+ Point primitive: x y size P
+ Line width: width W
+ Flat-shaded line: x2 y2 x1 y1 L
+ Smooth-shaded line: x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 SL
+ Flat-shaded triangle: x3 y3 x2 y2 x1 y1 T
+ Smooth-shaded triangle: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 ST */
+
+ fprintf(gl2ps->stream,
+ "%%%%BeginProlog\n"
+ "/gl2psdict 64 dict def gl2psdict begin\n"
+ "1 setlinecap 1 setlinejoin\n"
+ "/tryPS3shading %s def %% set to false to force subdivision\n"
+ "/rThreshold %g def %% red component subdivision threshold\n"
+ "/gThreshold %g def %% green component subdivision threshold\n"
+ "/bThreshold %g def %% blue component subdivision threshold\n"
+ "/BD { bind def } bind def\n"
+ "/C { setrgbcolor } BD\n"
+ "/G { 0.082 mul exch 0.6094 mul add exch 0.3086 mul add neg 1.0 add setgray } BD\n"
+ "/W { setlinewidth } BD\n"
+ "/FC { findfont exch scalefont setfont } BD\n"
+ "/S { FC moveto show } BD\n"
+ "/P { newpath 0.0 360.0 arc closepath fill } BD\n"
+ "/L { newpath moveto lineto stroke } BD\n"
+ "/SL { C moveto C lineto stroke } BD\n"
+ "/T { newpath moveto lineto lineto closepath fill } BD\n",
+ (gl2ps->options & GL2PS_NO_PS3_SHADING) ? "false" : "true",
+ gl2ps->threshold[0], gl2ps->threshold[1], gl2ps->threshold[2]);
+
+ /* Smooth-shaded triangle with PostScript level 3 shfill operator:
+ x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STshfill */
+
+ fprintf(gl2ps->stream,
+ "/STshfill {\n"
+ " /b1 exch def /g1 exch def /r1 exch def /y1 exch def /x1 exch def\n"
+ " /b2 exch def /g2 exch def /r2 exch def /y2 exch def /x2 exch def\n"
+ " /b3 exch def /g3 exch def /r3 exch def /y3 exch def /x3 exch def\n"
+ " gsave << /ShadingType 4 /ColorSpace [/DeviceRGB]\n"
+ " /DataSource [ 0 x1 y1 r1 g1 b1 0 x2 y2 r2 g2 b2 0 x3 y3 r3 g3 b3 ] >>\n"
+ " shfill grestore } BD\n");
+
+ /* Flat-shaded triangle with middle color:
+ x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 Tm */
+
+ fprintf(gl2ps->stream,
+ /* stack : x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 */
+ "/Tm { 3 -1 roll 8 -1 roll 13 -1 roll add add 3 div\n" /* r = (r1+r2+r3)/3 */
+ /* stack : x3 y3 g3 b3 x2 y2 g2 b2 x1 y1 g1 b1 r */
+ " 3 -1 roll 7 -1 roll 11 -1 roll add add 3 div\n" /* g = (g1+g2+g3)/3 */
+ /* stack : x3 y3 b3 x2 y2 b2 x1 y1 b1 r g b */
+ " 3 -1 roll 6 -1 roll 9 -1 roll add add 3 div" /* b = (b1+b2+b3)/3 */
+ /* stack : x3 y3 x2 y2 x1 y1 r g b */
+ " C T } BD\n");
+
+ /* Split triangle in four sub-triangles (at sides middle points) and call the
+ STnoshfill procedure on each, interpolating the colors in RGB space:
+ x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STsplit
+ (in procedure comments key: (Vi) = xi yi ri gi bi) */
+
+ fprintf(gl2ps->stream,
+ "/STsplit {\n"
+ " 4 index 15 index add 0.5 mul\n" /* x13 = (x1+x3)/2 */
+ " 4 index 15 index add 0.5 mul\n" /* y13 = (y1+y3)/2 */
+ " 4 index 15 index add 0.5 mul\n" /* r13 = (r1+r3)/2 */
+ " 4 index 15 index add 0.5 mul\n" /* g13 = (g1+g3)/2 */
+ " 4 index 15 index add 0.5 mul\n" /* b13 = (b1+b3)/2 */
+ " 5 copy 5 copy 25 15 roll\n"
+ /* stack : (V3) (V13) (V13) (V13) (V2) (V1) */
+ " 9 index 30 index add 0.5 mul\n" /* x23 = (x2+x3)/2 */
+ " 9 index 30 index add 0.5 mul\n" /* y23 = (y2+y3)/2 */
+ " 9 index 30 index add 0.5 mul\n" /* r23 = (r2+r3)/2 */
+ " 9 index 30 index add 0.5 mul\n" /* g23 = (g2+g3)/2 */
+ " 9 index 30 index add 0.5 mul\n" /* b23 = (b2+b3)/2 */
+ " 5 copy 5 copy 35 5 roll 25 5 roll 15 5 roll\n"
+ /* stack : (V3) (V13) (V23) (V13) (V23) (V13) (V23) (V2) (V1) */
+ " 4 index 10 index add 0.5 mul\n" /* x12 = (x1+x2)/2 */
+ " 4 index 10 index add 0.5 mul\n" /* y12 = (y1+y2)/2 */
+ " 4 index 10 index add 0.5 mul\n" /* r12 = (r1+r2)/2 */
+ " 4 index 10 index add 0.5 mul\n" /* g12 = (g1+g2)/2 */
+ " 4 index 10 index add 0.5 mul\n" /* b12 = (b1+b2)/2 */
+ " 5 copy 5 copy 40 5 roll 25 5 roll 15 5 roll 25 5 roll\n"
+ /* stack : (V3) (V13) (V23) (V13) (V12) (V23) (V13) (V1) (V12) (V23) (V12) (V2) */
+ " STnoshfill STnoshfill STnoshfill STnoshfill } BD\n");
+
+ /* Gouraud shaded triangle using recursive subdivision until the difference
+ between corner colors does not exceed the thresholds:
+ x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STnoshfill */
+
+ fprintf(gl2ps->stream,
+ "/STnoshfill {\n"
+ " 2 index 8 index sub abs rThreshold gt\n" /* |r1-r2|>rth */
+ " { STsplit }\n"
+ " { 1 index 7 index sub abs gThreshold gt\n" /* |g1-g2|>gth */
+ " { STsplit }\n"
+ " { dup 6 index sub abs bThreshold gt\n" /* |b1-b2|>bth */
+ " { STsplit }\n"
+ " { 2 index 13 index sub abs rThreshold gt\n" /* |r1-r3|>rht */
+ " { STsplit }\n"
+ " { 1 index 12 index sub abs gThreshold gt\n" /* |g1-g3|>gth */
+ " { STsplit }\n"
+ " { dup 11 index sub abs bThreshold gt\n" /* |b1-b3|>bth */
+ " { STsplit }\n"
+ " { 7 index 13 index sub abs rThreshold gt\n" /* |r2-r3|>rht */
+ " { STsplit }\n"
+ " { 6 index 12 index sub abs gThreshold gt\n" /* |g2-g3|>gth */
+ " { STsplit }\n"
+ " { 5 index 11 index sub abs bThreshold gt\n" /* |b2-b3|>bth */
+ " { STsplit }\n"
+ " { Tm }\n" /* all colors sufficiently similar */
+ " ifelse }\n"
+ " ifelse }\n"
+ " ifelse }\n"
+ " ifelse }\n"
+ " ifelse }\n"
+ " ifelse }\n"
+ " ifelse }\n"
+ " ifelse }\n"
+ " ifelse } BD\n");
+
+ fprintf(gl2ps->stream,
+ "tryPS3shading\n"
+ "{ /shfill where\n"
+ " { /ST { STshfill } BD }\n"
+ " { /ST { STnoshfill } BD }\n"
+ " ifelse }\n"
+ "{ /ST { STnoshfill } BD }\n"
+ "ifelse\n");
+
+ fprintf(gl2ps->stream,
+ "end\n"
+ "%%%%EndProlog\n"
+ "%%%%BeginSetup\n"
+ "/DeviceRGB setcolorspace\n"
+ "gl2psdict begin\n"
+ "%%%%EndSetup\n"
+ "%%%%Page: 1 1\n"
+ "%%%%BeginPageSetup\n");
+
+ if(gl2ps->options & GL2PS_LANDSCAPE){
+ fprintf(gl2ps->stream,
+ "%d 0 translate 90 rotate\n",
+ gl2ps->viewport[3]);
+ }
+
+ fprintf(gl2ps->stream,
+ "%%%%EndPageSetup\n"
+ "mark\n"
+ "gsave\n"
+ "1.0 1.0 scale\n");
+
+ if(gl2ps->options & GL2PS_DRAW_BACKGROUND){
+ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){
+ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
+ }
+ else{
+ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
+ rgba[0] = gl2ps->colormap[index][0];
+ rgba[1] = gl2ps->colormap[index][1];
+ rgba[2] = gl2ps->colormap[index][2];
+ rgba[3] = 0.;
+ }
+ fprintf(gl2ps->stream,
+ "%g %g %g C\n"
+ "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
+ "closepath fill\n",
+ rgba[0], rgba[1], rgba[2],
+ gl2ps->viewport[0], gl2ps->viewport[1], gl2ps->viewport[2],
+ gl2ps->viewport[1], gl2ps->viewport[2], gl2ps->viewport[3],
+ gl2ps->viewport[0], gl2ps->viewport[3]);
+ }
+}
+
+void gl2psPrintPostScriptColor(GL2PSrgba rgba){
+ if(!gl2psSameColor(gl2ps->lastrgba, rgba)){
+ gl2ps->lastrgba[0] = rgba[0];
+ gl2ps->lastrgba[1] = rgba[1];
+ gl2ps->lastrgba[2] = rgba[2];
+ fprintf(gl2ps->stream, "%g %g %g C\n", rgba[0], rgba[1], rgba[2]);
+ }
+}
+
+void gl2psResetPostScriptColor(void){
+ gl2ps->lastrgba[0] = gl2ps->lastrgba[1] = gl2ps->lastrgba[2] = -1.;
+}
+
+void gl2psPrintPostScriptPrimitive(void *a, void *b){
+ GL2PSprimitive *prim;
+
+ prim = *(GL2PSprimitive**)a;
+
+ if((gl2ps->options & GL2PS_OCCLUSION_CULL) && prim->culled) return;
+
+ switch(prim->type){
+ case GL2PS_PIXMAP :
+ gl2psPrintPostScriptPixmap(prim->verts[0].xyz[0], prim->verts[0].xyz[1],
+ prim->image->width, prim->image->height,
+ prim->image->format, prim->image->type,
+ prim->image->pixels, gl2ps->stream);
+ break;
+ case GL2PS_TEXT :
+ gl2psPrintPostScriptColor(prim->verts[0].rgba);
+ fprintf(gl2ps->stream, "(%s) %g %g %d /%s S\n",
+ prim->text->str, prim->verts[0].xyz[0], prim->verts[0].xyz[1],
+ prim->text->fontsize, prim->text->fontname);
+ break;
+ case GL2PS_POINT :
+ gl2psPrintPostScriptColor(prim->verts[0].rgba);
+ fprintf(gl2ps->stream, "%f %f %f P\n",
+ prim->verts[0].xyz[0], prim->verts[0].xyz[1], 0.5*prim->width);
+ break;
+ case GL2PS_LINE :
+ if(gl2ps->lastlinewidth != prim->width){
+ gl2ps->lastlinewidth = prim->width;
+ fprintf(gl2ps->stream, "%f W\n", gl2ps->lastlinewidth);
+ }
+ if(prim->dash){
+ fprintf(gl2ps->stream, "[%d] 0 setdash\n", prim->dash);
+ }
+ if(!gl2psVertsSameColor(prim)){
+ gl2psResetPostScriptColor();
+ fprintf(gl2ps->stream, "%f %f %f %f %f %f %f %f %f %f SL\n",
+ prim->verts[1].xyz[0], prim->verts[1].xyz[1],
+ prim->verts[1].rgba[0], prim->verts[1].rgba[1],
+ prim->verts[1].rgba[2], prim->verts[0].xyz[0],
+ prim->verts[0].xyz[1], prim->verts[0].rgba[0],
+ prim->verts[0].rgba[1], prim->verts[0].rgba[2]);
+ }
+ else{
+ gl2psPrintPostScriptColor(prim->verts[0].rgba);
+ fprintf(gl2ps->stream, "%f %f %f %f L\n",
+ prim->verts[1].xyz[0], prim->verts[1].xyz[1],
+ prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
+ }
+ if(prim->dash){
+ fprintf(gl2ps->stream, "[] 0 setdash\n");
+ }
+ break;
+ case GL2PS_TRIANGLE :
+ if(!gl2psVertsSameColor(prim)){
+ gl2psResetPostScriptColor();
+ fprintf(gl2ps->stream, "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f ST\n",
+ prim->verts[2].xyz[0], prim->verts[2].xyz[1],
+ prim->verts[2].rgba[0], prim->verts[2].rgba[1],
+ prim->verts[2].rgba[2], prim->verts[1].xyz[0],
+ prim->verts[1].xyz[1], prim->verts[1].rgba[0],
+ prim->verts[1].rgba[1], prim->verts[1].rgba[2],
+ prim->verts[0].xyz[0], prim->verts[0].xyz[1],
+ prim->verts[0].rgba[0], prim->verts[0].rgba[1],
+ prim->verts[0].rgba[2]);
+ }
+ else{
+ gl2psPrintPostScriptColor(prim->verts[0].rgba);
+ fprintf(gl2ps->stream, "%f %f %f %f %f %f T\n",
+ prim->verts[2].xyz[0], prim->verts[2].xyz[1],
+ prim->verts[1].xyz[0], prim->verts[1].xyz[1],
+ prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
+ }
+ break;
+ case GL2PS_QUADRANGLE :
+ gl2psMsg(GL2PS_WARNING, "There should not be any quad left to print");
+ break;
+ default :
+ gl2psMsg(GL2PS_ERROR, "Unknown type of primitive to print");
+ break;
+ }
+}
+
+void gl2psPrintPostScriptFooter(void){
+ fprintf(gl2ps->stream,
+ "grestore\n"
+ "showpage\n"
+ "cleartomark\n"
+ "%%%%PageTrailer\n"
+ "%%%%Trailer\n"
+ "end\n"
+ "%%%%EOF\n");
+}
+
+void gl2psPrintPostScriptBeginViewport(GLint viewport[4]){
+ GLint index;
+ GLfloat rgba[4];
+ int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3];
+
+ glRenderMode(GL_FEEDBACK);
+
+ fprintf(gl2ps->stream,
+ "gsave\n"
+ "1.0 1.0 scale\n");
+
+ if(gl2ps->options & GL2PS_DRAW_BACKGROUND){
+ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){
+ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
+ }
+ else{
+ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
+ rgba[0] = gl2ps->colormap[index][0];
+ rgba[1] = gl2ps->colormap[index][1];
+ rgba[2] = gl2ps->colormap[index][2];
+ rgba[3] = 0.;
+ }
+ fprintf(gl2ps->stream,
+ "%g %g %g C\n"
+ "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
+ "closepath fill\n",
+ rgba[0], rgba[1], rgba[2],
+ x, y, x+w, y, x+w, y+h, x, y+h);
+ fprintf(gl2ps->stream,
+ "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
+ "closepath clip\n",
+ x, y, x+w, y, x+w, y+h, x, y+h);
+ }
+
+}
+
+GLint gl2psPrintPostScriptEndViewport(void){
+ GLint res;
+ GLint gl2psPrintPrimitives(void);
+
+ res = gl2psPrintPrimitives();
+ fprintf(gl2ps->stream, "grestore\n");
+ return res;
+}
+
+/* The LaTeX routines */
+
+void gl2psPrintTeXHeader(void){
+ char name[256];
+ int i;
+
+ if(gl2ps->filename && strlen(gl2ps->filename) < 256){
+ for(i = strlen(gl2ps->filename)-1; i >= 0; i--){
+ if(gl2ps->filename[i] == '.'){
+ strncpy(name, gl2ps->filename, i);
+ name[i] = '\0';
+ break;
+ }
+ }
+ if(i <= 0) strcpy(name, gl2ps->filename);
+ }
+ else{
+ strcpy(name, "untitled");
+ }
+
+ fprintf(gl2ps->stream,
+ "\\setlength{\\unitlength}{1pt}\n"
+ "\\begin{picture}(0,0)\n"
+ "\\includegraphics{%s}\n"
+ "\\end{picture}%%\n"
+ "%s\\begin{picture}(%d,%d)(0,0)\n",
+ name, (gl2ps->options & GL2PS_LANDSCAPE) ? "\\rotatebox{90}{" : "",
+ gl2ps->viewport[2], gl2ps->viewport[3]);
+}
+
+void gl2psPrintTeXPrimitive(void *a, void *b){
+ GL2PSprimitive *prim;
+
+ prim = *(GL2PSprimitive**)a;
+
+ switch(prim->type){
+ case GL2PS_TEXT :
+ fprintf(gl2ps->stream, "\\put(%g,%g){\\makebox(0,0)[lb]{%s}}\n",
+ prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->text->str);
+ break;
+ default :
+ break;
+ }
+}
+
+void gl2psPrintTeXFooter(void){
+ fprintf(gl2ps->stream, "\\end{picture}%s\n",
+ (gl2ps->options & GL2PS_LANDSCAPE) ? "}" : "");
+}
+
+void gl2psPrintTeXBeginViewport(GLint viewport[4]){
+}
+
+GLint gl2psPrintTeXEndViewport(void){
+ return GL2PS_SUCCESS;
+}
+
+/* The general primitive printing routine */
+
+GLint gl2psPrintPrimitives(void){
+ GL2PSbsptree *root;
+ GL2PSxyz eye = {0., 0., 100000.};
+ GLint res = GL2PS_SUCCESS;
+ void (*pprim)(void *a, void *b) = 0;
+
+ if(gl2ps->format == GL2PS_PS || gl2ps->format == GL2PS_EPS){
+ res = gl2psParseFeedbackBuffer();
+ }
+
+ if(res != GL2PS_SUCCESS){
+ return res;
+ }
+
+ switch(gl2ps->format){
+ case GL2PS_TEX :
+ pprim = gl2psPrintTeXPrimitive;
+ break;
+ case GL2PS_PS :
+ case GL2PS_EPS :
+ pprim = gl2psPrintPostScriptPrimitive;
+ break;
+ }
+
+ switch(gl2ps->sort){
+ case GL2PS_NO_SORT :
+ gl2psListAction(gl2ps->primitives, pprim);
+ gl2psListAction(gl2ps->primitives, gl2psFreePrimitive);
+ /* reset the primitive list, waiting for the next viewport */
+ gl2psListReset(gl2ps->primitives);
+ break;
+ case GL2PS_SIMPLE_SORT :
+ gl2psListSort(gl2ps->primitives, gl2psCompareDepth);
+ if(gl2ps->options & GL2PS_OCCLUSION_CULL){
+ gl2psListAction(gl2ps->primitives, gl2psAddInImageTree);
+ gl2psFreeBspImageTree(&gl2ps->imagetree);
+ }
+ gl2psListActionInverse(gl2ps->primitives, pprim);
+ gl2psListAction(gl2ps->primitives, gl2psFreePrimitive);
+ /* reset the primitive list, waiting for the next viewport */
+ gl2psListReset(gl2ps->primitives);
+ break;
+ case GL2PS_BSP_SORT :
+ root = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree));
+ gl2psBuildBspTree(root, gl2ps->primitives);
+ if(gl2ps->boundary) gl2psBuildPolygonBoundary(root);
+ if(gl2ps->options & GL2PS_OCCLUSION_CULL){
+ gl2psTraverseBspTree(root, eye, -(float)GL2PS_EPSILON, gl2psLess,
+ gl2psAddInImageTree);
+ gl2psFreeBspImageTree(&gl2ps->imagetree);
+ }
+ gl2psTraverseBspTree(root, eye, (float)GL2PS_EPSILON, gl2psGreater,
+ pprim);
+ gl2psFreeBspTree(&root);
+ /* reallocate the primitive list (it's been deleted by
+ gl2psBuildBspTree) in case there is another viewport */
+ gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*));
+ break;
+ default :
+ gl2psMsg(GL2PS_ERROR, "Unknown sorting algorithm: %d", gl2ps->sort);
+ res = GL2PS_ERROR;
+ break;
+ }
+
+ fflush(gl2ps->stream);
+
+ return res;
+}
+
+/* The public routines */
+
+GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer,
+ GLint viewport[4], GLint format, GLint sort,
+ GLint options, GLint colormode,
+ GLint colorsize, GL2PSrgba *colormap,
+ GLint nr, GLint ng, GLint nb, GLint buffersize,
+ FILE *stream, const char *filename){
+ int i;
+
+ gl2ps = (GL2PScontext*)gl2psMalloc(sizeof(GL2PScontext));
+ gl2ps->maxbestroot = 10;
+ gl2ps->format = format;
+ gl2ps->title = title;
+ gl2ps->producer = producer;
+ gl2ps->filename = filename;
+ gl2ps->sort = sort;
+ gl2ps->options = options;
+ for(i = 0; i < 4; i++){
+ gl2ps->viewport[i] = viewport[i];
+ }
+ gl2ps->threshold[0] = nr ? 1./(GLfloat)nr : 0.032;
+ gl2ps->threshold[1] = ng ? 1./(GLfloat)ng : 0.017;
+ gl2ps->threshold[2] = nb ? 1./(GLfloat)nb : 0.05;
+ gl2ps->colormode = colormode;
+ gl2ps->buffersize = buffersize > 0 ? buffersize : 2048 * 2048;
+ for(i = 0; i < 4; i++){
+ gl2ps->lastrgba[i] = -1.;
+ }
+ gl2ps->lastlinewidth = -1.;
+ gl2ps->imagetree = NULL;
+
+ if(gl2ps->colormode == GL_RGBA){
+ gl2ps->colorsize = 0;
+ gl2ps->colormap = NULL;
+ }
+ else if(gl2ps->colormode == GL_COLOR_INDEX){
+ if(!colorsize || !colormap){
+ gl2psMsg(GL2PS_ERROR, "Missing colormap for GL_COLOR_INDEX rendering");
+ gl2psFree(gl2ps);
+ gl2ps = NULL;
+ return GL2PS_ERROR;
+ }
+ gl2ps->colorsize = colorsize;
+ gl2ps->colormap = (GL2PSrgba*)gl2psMalloc(gl2ps->colorsize * sizeof(GL2PSrgba));
+ memcpy(gl2ps->colormap, colormap, gl2ps->colorsize * sizeof(GL2PSrgba));
+ }
+ else{
+ gl2psMsg(GL2PS_ERROR, "Unknown color mode in gl2psBeginPage");
+ gl2psFree(gl2ps);
+ gl2ps = NULL;
+ return GL2PS_ERROR;
+ }
+
+ if(!stream){
+ gl2psMsg(GL2PS_ERROR, "Bad file pointer");
+ gl2psFree(gl2ps);
+ gl2ps = NULL;
+ return GL2PS_ERROR;
+ }
+ else{
+ gl2ps->stream = stream;
+ /* In case gl2psEndPage failed (e.g. due to a GL2PS_OVERFLOW) and
+ we didn't reopen the stream before calling gl2psBeginPage
+ again, we need to rewind the stream */
+ rewind(gl2ps->stream);
+ }
+
+ switch(gl2ps->format){
+ case GL2PS_TEX :
+ gl2psPrintTeXHeader();
+ break;
+ case GL2PS_PS :
+ case GL2PS_EPS :
+ gl2psPrintPostScriptHeader();
+ break;
+ default :
+ gl2psMsg(GL2PS_ERROR, "Unknown output format: %d", gl2ps->format);
+ gl2psFree(gl2ps);
+ gl2ps = NULL;
+ return GL2PS_ERROR;
+ }
+
+ gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*));
+ gl2ps->feedback = (GLfloat*)gl2psMalloc(gl2ps->buffersize * sizeof(GLfloat));
+ glFeedbackBuffer(gl2ps->buffersize, GL_3D_COLOR, gl2ps->feedback);
+ glRenderMode(GL_FEEDBACK);
+
+ return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psEndPage(void){
+ GLint res;
+
+ if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+ res = gl2psPrintPrimitives();
+
+ /* print the footer even if gl2psPrintPrimitives didn't succeed, so
+ that we end up with a valid file */
+ switch(gl2ps->format){
+ case GL2PS_TEX :
+ gl2psPrintTeXFooter();
+ break;
+ case GL2PS_PS :
+ case GL2PS_EPS :
+ gl2psPrintPostScriptFooter();
+ break;
+ }
+
+ fflush(gl2ps->stream);
+
+ gl2psListDelete(gl2ps->primitives);
+ gl2psFree(gl2ps->colormap);
+ gl2psFree(gl2ps->feedback);
+ gl2psFree(gl2ps);
+ gl2ps = NULL;
+
+ return res;
+}
+
+GL2PSDLL_API GLint gl2psBeginViewport(GLint viewport[4]){
+ if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+ switch(gl2ps->format){
+ case GL2PS_EPS :
+ gl2psPrintPostScriptBeginViewport(viewport);
+ break;
+ default :
+ /* FIXME: handle other formats */
+ break;
+ }
+
+ return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psEndViewport(void){
+ GLint res;
+
+ if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+ switch(gl2ps->format){
+ case GL2PS_EPS :
+ res = gl2psPrintPostScriptEndViewport();
+ break;
+ default :
+ /* FIXME: handle other formats */
+ res = GL2PS_SUCCESS;
+ break;
+ }
+
+ return res;
+}
+
+GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize){
+ GLfloat pos[4];
+ GL2PSprimitive *prim;
+ GLboolean valid;
+
+ if(!gl2ps || !str) return GL2PS_UNINITIALIZED;
+
+ if(gl2ps->options & GL2PS_NO_TEXT) return GL2PS_SUCCESS;
+
+ glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
+ if(!valid) return GL2PS_SUCCESS; /* the primitive is culled */
+
+ glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
+
+ prim = (GL2PSprimitive *)gl2psMalloc(sizeof(GL2PSprimitive));
+ prim->type = GL2PS_TEXT;
+ prim->boundary = 0;
+ prim->numverts = 1;
+ prim->verts = (GL2PSvertex *)gl2psMalloc(sizeof(GL2PSvertex));
+ prim->verts[0].xyz[0] = pos[0];
+ prim->verts[0].xyz[1] = pos[1];
+ prim->verts[0].xyz[2] = GL2PS_DEPTH_FACT * pos[2];
+ prim->depth = pos[2];
+ prim->culled = 0;
+ prim->dash = 0;
+ prim->width = 1;
+ glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba);
+ prim->text = (GL2PSstring*)gl2psMalloc(sizeof(GL2PSstring));
+ prim->text->str = (char*)gl2psMalloc((strlen(str)+1)*sizeof(char));
+ strcpy(prim->text->str, str);
+ prim->text->fontname = (char*)gl2psMalloc((strlen(fontname)+1)*sizeof(char));
+ strcpy(prim->text->fontname, fontname);
+ prim->text->fontsize = fontsize;
+
+ gl2psListAdd(gl2ps->primitives, &prim);
+
+ return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,
+ GLint xorig, GLint yorig,
+ GLenum format, GLenum type,
+ const void *pixels){
+ int size;
+ GLfloat pos[4];
+ GL2PSprimitive *prim;
+ GLboolean valid;
+
+ if(!gl2ps || !pixels) return GL2PS_UNINITIALIZED;
+
+ if((width <= 0) || (height <= 0)) return GL2PS_ERROR;
+
+ if(gl2ps->options & GL2PS_NO_PIXMAP) return GL2PS_SUCCESS;
+
+ if(format != GL_RGB || type != GL_FLOAT){
+ gl2psMsg(GL2PS_ERROR, "gl2psDrawPixels only implemented for GL_RGB, GL_FLOAT pixels");
+ return GL2PS_ERROR;
+ }
+
+ glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
+ if(!valid) return GL2PS_SUCCESS; /* the primitive is culled */
+
+ glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
+
+ prim = (GL2PSprimitive *)gl2psMalloc(sizeof(GL2PSprimitive));
+ prim->type = GL2PS_PIXMAP;
+ prim->boundary = 0;
+ prim->numverts = 1;
+ prim->verts = (GL2PSvertex *)gl2psMalloc(sizeof(GL2PSvertex));
+ prim->verts[0].xyz[0] = pos[0] + xorig;
+ prim->verts[0].xyz[1] = pos[1] + yorig;
+ prim->verts[0].xyz[2] = GL2PS_DEPTH_FACT * pos[2];
+ prim->depth = pos[2];
+ prim->culled = 0;
+ prim->dash = 0;
+ prim->width = 1;
+ glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba);
+ prim->image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage));
+ prim->image->width = width;
+ prim->image->height = height;
+ prim->image->format = format;
+ prim->image->type = type;
+ size = height*width*3*sizeof(GLfloat); /* FIXME: handle other types/formats */
+ prim->image->pixels = (GLfloat*)gl2psMalloc(size);
+ memcpy(prim->image->pixels, pixels, size);
+
+ gl2psListAdd(gl2ps->primitives, &prim);
+
+ return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psEnable(GLint mode){
+ if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+ switch(mode){
+ case GL2PS_POLYGON_OFFSET_FILL :
+ glPassThrough(GL2PS_BEGIN_POLYGON_OFFSET_FILL);
+ glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &gl2ps->offset[0]);
+ glGetFloatv(GL_POLYGON_OFFSET_UNITS, &gl2ps->offset[1]);
+ break;
+ case GL2PS_POLYGON_BOUNDARY :
+ glPassThrough(GL2PS_BEGIN_POLYGON_BOUNDARY);
+ break;
+ case GL2PS_LINE_STIPPLE :
+ glPassThrough(GL2PS_BEGIN_LINE_STIPPLE);
+ break;
+ default :
+ gl2psMsg(GL2PS_WARNING, "Unknown mode in gl2psEnable: %d", mode);
+ return GL2PS_WARNING;
+ }
+
+ return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psDisable(GLint mode){
+ if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+ switch(mode){
+ case GL2PS_POLYGON_OFFSET_FILL :
+ glPassThrough(GL2PS_END_POLYGON_OFFSET_FILL);
+ break;
+ case GL2PS_POLYGON_BOUNDARY :
+ glPassThrough(GL2PS_END_POLYGON_BOUNDARY);
+ break;
+ case GL2PS_LINE_STIPPLE :
+ glPassThrough(GL2PS_END_LINE_STIPPLE);
+ break;
+ default :
+ gl2psMsg(GL2PS_WARNING, "Unknown mode in gl2psDisable: %d", mode);
+ return GL2PS_WARNING;
+ }
+
+ return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psPointSize(GLfloat value){
+ if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+ glPassThrough(GL2PS_SET_POINT_SIZE);
+ glPassThrough(value);
+
+ return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psLineWidth(GLfloat value){
+ if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+ glPassThrough(GL2PS_SET_LINE_WIDTH);
+ glPassThrough(value);
+
+ return GL2PS_SUCCESS;
+}
--- /dev/null
+/*\r * GL2PS, an OpenGL to PostScript Printing Library\r * Copyright (C) 1999-2003 Christophe Geuzaine\r *\r * $Id: gl2ps.h,v 1.1.1.1 2004/01/09 21:54:34 administrator Exp $ \r *\r * E-mail: geuz@geuz.org\r * URL: http://www.geuz.org/gl2ps/\r *\r * This library is free software; you can redistribute it and/or\r * modify it under the terms of the GNU Library General Public\r * License as published by the Free Software Foundation; either\r * version 2 of the License, or (at your option) any later version.\r *\r * This library is distributed in the hope that it will be useful,\r * but WITHOUT ANY WARRANTY; without even the implied warranty of\r * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r * Library General Public License for more details.\r *\r * You should have received a copy of the GNU Library General Public\r * License along with this library; if not, write to the Free\r * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r *\r */\r\r#ifndef __GL2PS_H__\r#define __GL2PS_H__\r\r#include <stdio.h>\r#include <stdlib.h>\r#include <math.h>\r\r/* To generate a Windows dll, define GL2PSDLL at compile time */\r\r#ifdef WIN32\r# include <windows.h>\r# ifdef GL2PSDLL\r# ifdef GL2PSDLL_EXPORTS\r# define GL2PSDLL_API __declspec(dllexport)\r# else\r# define GL2PSDLL_API __declspec(dllimport)\r# endif\r# else\r# define GL2PSDLL_API\r# endif\r#else\r# define GL2PSDLL_API\r#endif\r\r#ifdef __APPLE__\r# include <OpenGL/gl.h>\r#else\r# include <GL/gl.h>\r#endif\r\r/* Version number */\r\r#define GL2PS_MAJOR_VERSION 0\r#define GL2PS_MINOR_VERSION 9\r#define GL2PS_PATCH_VERSION 0\r\r#define GL2PS_VERSION (GL2PS_MAJOR_VERSION + \\r 0.01 * GL2PS_MINOR_VERSION + \\r 0.0001 * GL2PS_PATCH_VERSION)\r\r/* Output file format */\r\r#define GL2PS_PS 1\r#define GL2PS_EPS 2\r#define GL2PS_TEX 3\r\r/* Sorting algorithms */\r\r#define GL2PS_NO_SORT 1\r#define GL2PS_SIMPLE_SORT 2\r#define GL2PS_BSP_SORT 3\r\r/* Options for gl2psBeginPage */\r\r#define GL2PS_NONE 0\r#define GL2PS_DRAW_BACKGROUND (1<<0)\r#define GL2PS_SIMPLE_LINE_OFFSET (1<<1)\r#define GL2PS_SILENT (1<<2)\r#define GL2PS_BEST_ROOT (1<<3)\r#define GL2PS_OCCLUSION_CULL (1<<4)\r#define GL2PS_NO_TEXT (1<<5)\r#define GL2PS_LANDSCAPE (1<<6)\r#define GL2PS_NO_PS3_SHADING (1<<7)\r#define GL2PS_NO_PIXMAP (1<<8)\r\r/* Arguments for gl2psEnable/gl2psDisable */\r\r#define GL2PS_POLYGON_OFFSET_FILL 1\r#define GL2PS_POLYGON_BOUNDARY 2\r#define GL2PS_LINE_STIPPLE 3\r\r/* Magic numbers */\r\r#define GL2PS_EPSILON 5.e-3\r#define GL2PS_DEPTH_FACT 1000.0\r#define GL2PS_SIMPLE_OFFSET 0.05\r#define GL2PS_SIMPLE_OFFSET_LARGE 1.0\r#define GL2PS_ZERO(arg) (fabs(arg)<1.e-20)\r\r/* Message levels and error codes */\r\r#define GL2PS_SUCCESS 0\r#define GL2PS_INFO 1\r#define GL2PS_WARNING 2\r#define GL2PS_ERROR 3\r#define GL2PS_NO_FEEDBACK 4\r#define GL2PS_OVERFLOW 5\r#define GL2PS_UNINITIALIZED 6\r\r/* Primitive types */\r\r#define GL2PS_TEXT 1\r#define GL2PS_POINT 2\r#define GL2PS_LINE 3\r#define GL2PS_QUADRANGLE 4\r#define GL2PS_TRIANGLE 5\r#define GL2PS_PIXMAP 6\r\r/* BSP tree primitive comparison */\r\r#define GL2PS_COINCIDENT 1\r#define GL2PS_IN_FRONT_OF 2\r#define GL2PS_IN_BACK_OF 3\r#define GL2PS_SPANNING 4\r\r/* 2D BSP tree primitive comparison */\r\r#define GL2PS_POINT_COINCIDENT 0\r#define GL2PS_POINT_INFRONT 1\r#define GL2PS_POINT_BACK 2\r\r/* Pass through options */\r\r#define GL2PS_BEGIN_POLYGON_OFFSET_FILL 1\r#define GL2PS_END_POLYGON_OFFSET_FILL 2\r#define GL2PS_BEGIN_POLYGON_BOUNDARY 3\r#define GL2PS_END_POLYGON_BOUNDARY 4\r#define GL2PS_BEGIN_LINE_STIPPLE 5\r#define GL2PS_END_LINE_STIPPLE 6\r#define GL2PS_SET_POINT_SIZE 7\r#define GL2PS_SET_LINE_WIDTH 8\r\rtypedef GLfloat GL2PSrgba[4];\rtypedef GLfloat GL2PSxyz[3];\rtypedef GLfloat GL2PSplane[4];\r\rtypedef struct _GL2PSbsptree2d GL2PSbsptree2d;\r\rstruct _GL2PSbsptree2d {\r GL2PSplane plane;\r GL2PSbsptree2d *front, *back;\r};\r\rtypedef struct {\r GLint nmax, size, incr, n;\r char *array;\r} GL2PSlist;\r\rtypedef struct _GL2PSbsptree GL2PSbsptree;\r\rstruct _GL2PSbsptree {\r GL2PSplane plane;\r GL2PSlist *primitives;\r GL2PSbsptree *front, *back;\r};\r\rtypedef struct {\r GL2PSxyz xyz;\r GL2PSrgba rgba;\r} GL2PSvertex;\r\rtypedef struct {\r GLshort fontsize;\r char *str, *fontname;\r} GL2PSstring;\r\rtypedef struct {\r GLsizei width, height;\r GLenum format, type;\r GLfloat *pixels;\r} GL2PSimage;\r\rtypedef struct {\r GLshort type, numverts;\r char boundary, dash, culled;\r GLfloat width, depth;\r GL2PSvertex *verts;\r GL2PSstring *text;\r GL2PSimage *image;\r} GL2PSprimitive;\r\rtypedef struct {\r GLint format, sort, options, colorsize, colormode, buffersize, maxbestroot;\r const char *title, *producer, *filename;\r GLboolean boundary;\r GLfloat *feedback, offset[2];\r GLint viewport[4];\r GL2PSrgba *colormap, lastrgba, threshold;\r float lastlinewidth;\r GL2PSlist *primitives;\r GL2PSbsptree2d *imagetree;\r FILE *stream;\r} GL2PScontext;\r\r/* public functions */\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\rGL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, \r GLint viewport[4], GLint format, GLint sort,\r GLint options, GLint colormode,\r GLint colorsize, GL2PSrgba *colormap, \r GLint nr, GLint ng, GLint nb, GLint buffersize,\r FILE *stream, const char *filename);\rGL2PSDLL_API GLint gl2psEndPage(void);\rGL2PSDLL_API GLint gl2psBeginViewport(GLint viewport[4]);\rGL2PSDLL_API GLint gl2psEndViewport(void);\rGL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize);\rGL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,\r GLint xorig, GLint yorig,\r GLenum format, GLenum type, const void *pixels);\rGL2PSDLL_API GLint gl2psEnable(GLint mode);\rGL2PSDLL_API GLint gl2psDisable(GLint mode);\rGL2PSDLL_API GLint gl2psPointSize(GLfloat value);\rGL2PSDLL_API GLint gl2psLineWidth(GLfloat value);\r\r#ifdef __cplusplus\r};\r#endif\r\r#endif /* __GL2PS_H__ */\r
\ No newline at end of file
--- /dev/null
+/**\r
+\r
+OBJ import by jtnimoy\r
+\r
+*/\r
+\r
+\r
+#include "obj.h"\r
+using namespace obj4gl;\r
+\r
+#include <OpenGL/gl.h>\r
+\r
+\r
+\r
+Vertex OBJ::getVertex(int i){\r
+ if(i<vertexCount){\r
+ return vertices[i];\r
+ }else{\r
+ return vertices[0];\r
+ }\r
+}\r
+\r
+OBJ::OBJ(){\r
+}\r
+\r
+\r
+OBJ::OBJ(char file[]){\r
+ open(file);\r
+}\r
+\r
+void OBJ::open(char file[]){\r
+ //count\r
+ \r
+ if(strlen(file)==0){\r
+ fprintf(stderr,"obj4gl::OBJ::open() Filename string was empty\n",0);\r
+ return;\r
+ }\r
+ \r
+ \r
+\r
+ \r
+ printf("opening %s\n",file);\r
+ \r
+ char temp[100];\r
+ vertexCount = 0;\r
+ faceCount = 0;\r
+ normalCount = 0;\r
+ \r
+ ifstream ff(file);\r
+ while(!ff.eof()){\r
+ ff.getline(temp,100,' ');\r
+ if(!strcmp(temp,"g")){\r
+ ff.getline(temp,100);\r
+ }else if(!strcmp(temp,"v")){\r
+ vertexCount++;\r
+ ff.getline(temp,100,' ');\r
+ ff.getline(temp,100,' ');\r
+ ff.getline(temp,100);\r
+ ignoreRestOfLine(&ff);\r
+ }\r
+ } \r
+ ff.close();\r
+ //allocate\r
+ //faces = new Face[vertexCount];\r
+ //vertices = new Vertex[vertexCount];\r
+ //parse\r
+ ifstream f(file);\r
+ \r
+ int vcx = 0;\r
+ int fcx = 0;\r
+ \r
+ while(!f.eof()){\r
+ char tok[256];\r
+ f.getline(tok,256,' ');\r
+ if(!strcmp(tok,"l")){\r
+ //f.getline(tok,256);\r
+ ignoreRestOfLine(&f);\r
+ //printf("\(\"%s\")\n",tok);\r
+ }else if(!strcmp(tok,"g")){\r
+ //f.getline(tok,256);\r
+ ignoreRestOfLine(&f);\r
+ //printf("\nShadingGroup(\"%s\")\n",tok);\r
+ }else if(!strcmp(tok,"v")){\r
+ this->vertices.resize(this->vertices.size()+1);//allocate 1 new in the vector.\r
+ \r
+ f >> this->vertices[vcx].x;\r
+ f >> this->vertices[vcx].y;\r
+ f >> this->vertices[vcx].z;\r
+ \r
+ char t[256];\r
+ //f.getline(t,256);\r
+ ignoreRestOfLine(&f);\r
+ vcx++;\r
+ }else if(!strcmp(tok,"#")){\r
+ //comment\r
+ char t[32];\r
+ //f.getline(t,32,'\n');\r
+ ignoreRestOfLine(&f);\r
+ \r
+ }else if(!strcmp(tok,"usemap")){\r
+ //comment\r
+ char t[32];\r
+ //f.getline(t,32,'\n');\r
+ ignoreRestOfLine(&f);\r
+ \r
+ }else if(!strcmp(tok,"o")){\r
+ //name -- don't care (for now)\r
+ char t[256];\r
+ //f.getline(t,256);\r
+ ignoreRestOfLine(&f);\r
+ }else if(!strcmp(tok,"vt")){\r
+ char t[32];\r
+ f.getline(t,32,' ');\r
+ float x = strtod(t,NULL);\r
+ //f.getline(t,32);\r
+ ignoreRestOfLine(&f);\r
+ float y = strtod(t,NULL);\r
+ //printf("textureVertex(%s,%s)\n",x,y);\r
+\r
+ }else if(!strcmp(tok,"vn")){\r
+ this->normals.resize(this->normals.size()+1);//allocate the new one.\r
+ f >> this->normals[normalCount].x;\r
+ f >> this->normals[normalCount].y;\r
+ f >> this->normals[normalCount].z;\r
+ normalCount++;\r
+ ignoreRestOfLine(&f);\r
+ }else if(!strcmp(tok,"g")){\r
+ char x[32];\r
+ //f.getline(x,32);\r
+ ignoreRestOfLine(&f);\r
+ //printf("group name(%s)\n",x);\r
+ }else if(!strcmp(tok,"s")){\r
+ char x[32];\r
+ //f.getline(x,32);\r
+ ignoreRestOfLine(&f);\r
+ //printf("shadingGroup(%s)\n",x);\r
+ }else if(!strcmp(tok,"usemtl")){\r
+ char x[256];\r
+ //f.getline(x,256);\r
+ ignoreRestOfLine(&f);\r
+ //printf("useMaterial(%s)\n",x);\r
+\r
+ }else if(!strcmp(tok,"mtllib")){\r
+ char x[256];\r
+ //f.getline(x,256);\r
+ ignoreRestOfLine(&f);\r
+ //printf("useMaterial(%s)\n",x);\r
+\r
+\r
+ }else if(!strcmp(tok,"f") || !strcmp(tok,"fo")){\r
+ char x[256];\r
+ \r
+ int strlen_x;\r
+ this->faces.resize(this->faces.size()+1);\r
+ \r
+ /**\r
+ get the number of vertices in this face and store it in the face struct.\r
+ */\r
+ int oldpos = f.tellg(); //push file ptr\r
+ f.getline(x,256,'\n');\r
+ strlen_x=strlen(x);\r
+ this->faces[fcx].count = 1;\r
+ for(int i=0;i<strlen_x;i++){\r
+ if(x[i]==' '||x[i]=='\t')this->faces[fcx].count++;\r
+ }\r
+ f.seekg(oldpos);//pop file ptr\r
+ \r
+ \r
+ \r
+ /**\r
+ get the number of forward slashes per line in order to categorise.\r
+ \r
+ */\r
+ oldpos = f.tellg(); //push file ptr\r
+ f.getline(x,256,'\n');\r
+ strlen_x=strlen(x);\r
+ this->faces[fcx].type = 1;\r
+ for(int i=0;i<strlen_x;i++){\r
+ if(x[i]=='/')this->faces[fcx].type++;\r
+ else if(x[i]==' '||x[i]=='\t')break;//only count the first one.\r
+ }\r
+ f.seekg(oldpos);//pop file ptr\r
+ \r
+ /**\r
+ validate vertex size to make sure this is a type of face-spec we know how to parse\r
+ which is only 2, 3, and 4\r
+ */\r
+ if(this->faces[fcx].count>4 ){\r
+ printf("OBJ Unrecognized face vertex.count: %i. skipping rest of line.\n",this->faces[fcx].count);\r
+ ignoreRestOfLine(&f);\r
+ continue;\r
+ }\r
+ \r
+ \r
+ \r
+ /**\r
+ validate vertex.type - the data-depth. ie. how many numbers per chunk.\r
+ */\r
+ if(this->faces[fcx].type!=3 && this->faces[fcx].type!=2 && this->faces[fcx].type!=1 ){\r
+ printf("OBJ Unrecognized face vertex.type: %i. skipping rest of line.\n",this->faces[fcx].type);\r
+ ignoreRestOfLine(&f);\r
+ continue;\r
+ }\r
+ \r
+ \r
+ \r
+ /**\r
+ loop through and collect the appropriate data into the arrays.\r
+ */\r
+ for(int thisVertexID=0;thisVertexID<this->faces[fcx].count;thisVertexID++){\r
+ if(this->faces[fcx].count>=thisVertexID+1){\r
+ \r
+ //depending on the syntax of the face vertex chunk, parse accordingly\r
+ if(this->faces[fcx].type==3){\r
+ // %i/%i/%i\r
+ f.getline(x,256,'/');\r
+ this->faces[fcx].v[thisVertexID] = strtol(x,NULL,10);\r
+ f.getline(x,256,'/');\r
+ this->faces[fcx].t[thisVertexID] = strtol(x,NULL,10);//collect the texture coord\r
+ if(this->faces[fcx].count==thisVertexID+1)f.getline(x,256);//this works because if the count is zero,\r
+ else f.getline(x,256,' ');\r
+ this->faces[fcx].n[thisVertexID] = strtol(x,NULL,10);//collect the normal\r
+ }else if(this->faces[fcx].type==2){\r
+ // %i/%i\r
+ f.getline(x,256,'/');\r
+ this->faces[fcx].v[thisVertexID] = strtol(x,NULL,10);//collect the texture coord\r
+ if(this->faces[fcx].count==thisVertexID+1)f.getline(x,256);//this works because if the count is zero,\r
+ else f.getline(x,256,' ');\r
+ this->faces[fcx].t[thisVertexID] = strtol(x,NULL,10);//collect the normal\r
+ }else if(this->faces[fcx].type==1){\r
+ // %i\r
+ if(this->faces[fcx].count==thisVertexID+1)f.getline(x,256);//this works because if the count is zero,\r
+ else f.getline(x,256,' ');\r
+ this->faces[fcx].v[thisVertexID] = strtol(x,NULL,10);//collect the normal\r
+ }\r
+ \r
+ }\r
+\r
+ }\r
+ faceCount++;\r
+ fcx++;\r
+ \r
+ }else if(strlen(tok)==0){\r
+ }else{\r
+ if(tok[0]!='#'){\r
+ printf("OBJ Unrecognized Command: \"%s\"\n",tok);\r
+ }\r
+ ignoreRestOfLine(&f);\r
+ \r
+ }\r
+ }\r
+ f.close();\r
+\r
+ vertexCount = vcx;\r
+\r
+}\r
+\r
+OBJ::~OBJ(){\r
+ //delete [] vertices;\r
+ //delete [] faces;\r
+}\r
+\r
+\r
+void OBJ::renderFace(int i){\r
+ \r
+ /**\r
+ draw the verts\r
+ */\r
+ // printf("%i\n",-1);\r
+ for(int ii=0;ii<faces[i].count;ii++){\r
+ //printf("%i\n",0);\r
+ if(faces[i].count>=ii+1){\r
+ // printf("%i\n",1);\r
+ //todo: glTexCoord2f(...,...);\r
+ \r
+ if(faces[i].type>2){\r
+ glNormal3f(normals[faces[i].n[ii]-1].x,\r
+ normals[faces[i].n[ii]-1].y,\r
+ normals[faces[i].n[ii]-1].z);\r
+ }\r
+ //printf("%i\n",2);\r
+ glVertex3f(vertices[faces[i].v[ii]-1].x,\r
+ vertices[faces[i].v[ii]-1].y,\r
+ vertices[faces[i].v[ii]-1].z);\r
+ //printf("%i\n",3);\r
+ }\r
+ //printf("%i\n",4);\r
+ }\r
+ //printf("%i\n",5);\r
+}\r
+\r
+\r
+void OBJ::fillFaces(){\r
+ glEnable(GL_RESCALE_NORMAL);\r
+ for(int i=0;i<faceCount;i++){\r
+ glBegin(GL_TRIANGLE_FAN);\r
+ renderFace(i);\r
+ glEnd();\r
+ }\r
+}\r
+\r
+\r
+\r
+void OBJ::outlineFaces(){\r
+ for(int i=0;i<faceCount;i++){\r
+ glBegin(GL_LINE_STRIP);\r
+ renderFace(i);\r
+ glEnd();\r
+ }\r
+}\r
+\r
+\r
+void OBJ::pointVertices(){\r
+ for(int i=0;i<faceCount;i++){\r
+ glBegin(GL_POINTS);\r
+ renderFace(i);\r
+ glEnd();\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+void OBJ::ignoreRestOfLine(ifstream *f){\r
+ char buff[256];\r
+ f->getline(buff,256);\r
+ //ok, now skip empty lines as well.\r
+ if(f->peek()=='\n')ignoreRestOfLine(f);\r
+}\r
--- /dev/null
+/**\r
+\r
+OBJ import by jtnimoy\r
+\r
+last updated 1-aug-06\r
+\r
+still needs to be implemented:\r
+ - texture coordinates\r
+ - faces with vertex counts greater than 255.\r
+ - dynamically allocate arrays instead of hard coding a max value. but use standard STL vectors.\r
+ - some of the objs folder demos come out crooked. is this a vertex ordering thing, or a 1 vs. 0 thing?\r
+\r
+references:\r
+ http://orion.math.iastate.edu/burkardt/data/obj/obj_format.txt\r
+\r
+\r
+*/\r
+\r
+#ifndef _OBJ4GL_H_\r
+#define _OBJ4GL_H_\r
+\r
+#include <fstream>\r
+#include <vector>\r
+using namespace std;\r
+\r
+namespace obj4gl{\r
+\r
+ /**\r
+ holds the information for a single face.\r
+ */\r
+ struct Face{\r
+ /**\r
+ number of v,n,t token-phrases seperated by space.\r
+ */\r
+ int count;\r
+ \r
+ /**\r
+ could be "%i/%i/%i" or "%i/%i" or number, and possibly "%i"\r
+ */\r
+ int type;\r
+ \r
+ /**\r
+ vertices contained in the face\r
+ */\r
+ long v[4];\r
+ \r
+ /**\r
+ normals of that vertex (optional - see ::type)\r
+ */\r
+ long n[4];\r
+ \r
+ /**\r
+ texture coord of that vertex (optional - see ::type)\r
+ */\r
+ long t[4];\r
+ \r
+ };\r
+ \r
+ struct Vertex{\r
+ float x;\r
+ float y;\r
+ float z;\r
+ };\r
+ \r
+ class OBJ{\r
+ public:\r
+ \r
+ OBJ(char file[]);\r
+ OBJ();\r
+ \r
+ ~OBJ();\r
+ \r
+ int vertexCount;\r
+ int faceCount;\r
+ int normalCount;\r
+ \r
+ vector<Face> faces;\r
+ vector<Vertex> vertices;\r
+ vector<Vertex> normals;\r
+ \r
+ void open(char[]);\r
+ \r
+ void outlineFaces();\r
+ void fillFaces();\r
+ void pointVertices();\r
+ Vertex getVertex(int i);\r
+ \r
+ private:\r
+ void renderFace(int i);\r
+ void ignoreRestOfLine(ifstream *f);\r
+ };\r
+ \r
+};\r
+\r
+#endif\r
--- /dev/null
+#include "quadstretch.h"
+
+void intersect_lines2(float x0,float y0,float x1,float y1,float x2,float y2,float x3,float y3,float &xi,float &yi){
+ //THANK YOU PETE CONOLLY
+ float infinity_approx = 999999999999999999999.0f;
+ float a1=0.0;
+ float b1=0.0;
+ float c1=0.0; // constants of linear equations
+ float a2=0.0;
+ float b2=0.0;
+ float c2=0.0;
+ float det_inv=0.0; // the inverse of the determinant of the coefficient
+ float m1=0.0;
+ float m2=0.0; // the slopes of each line
+
+ if(x1!=x0)m1=(y1-y0)/(x1-x0);
+ else m1 = infinity_approx;
+
+ if(x3!=x2)m2=(y3-y2)/(x3-x2);
+ else m2 = infinity_approx;
+ a1=m1;
+ a2=m2;
+ b1=-1;
+ b2=-1;
+ c1=(y0-m1*x0);
+ c2=(y2-m2*x2);
+ // compute the inverse of the determinate
+ det_inv = 1/(a1*b2 - a2*b1);
+ // use Kramers rule to compute xi and yi
+ xi=((b1*c2 - b2*c1)*det_inv);
+ yi=((a2*c1 - a1*c2)*det_inv);
+}
+
+
+void quadStretch2(float x,float y,float l,float t,float w,float h,float *q,float &newx,float &newy){
+ /*
+ --x & y are the original point
+ -- l & t are left and top of original rect
+ -- w & h are width and height of original rect
+ --q is an array of 4 points describing the new quad.
+
+ --1. strip it down to floats between 0 and 1
+ -- so we know where it is, relative to the boundaries.
+ */
+ float xF = (x-l)/w;
+ float yF = (y-t)/h;
+ //2. generate "vertical"
+
+ float interpTop[2];
+ float interpBottom[2];
+ float interpLeft[2];
+ float interpRight[2];
+
+ interpolatePoints2( q[0*2+0],q[0*2+1],
+ q[1*2+0],q[1*2+1],xF,
+ interpTop[0],interpTop[1]);
+
+ interpolatePoints2( q[3*2+0],q[3*2+1],
+ q[2*2+0],q[2*2+1],xF,
+ interpBottom[0],interpBottom[1]);
+
+ //3. generate "horizontal"
+ interpolatePoints2( q[0*2+0],q[0*2+1],
+ q[3*2+0],q[3*2+1],yF,
+ interpLeft[0],interpLeft[1]);
+
+ interpolatePoints2(q[1*2+0],q[1*2+1],
+ q[2*2+0],q[2*2+1],yF,
+ interpRight[0],interpRight[1]);
+
+ intersect_lines2( interpTop[0], interpTop[1],
+ interpBottom[0], interpBottom[1],
+ interpLeft[0], interpLeft[1],
+ interpRight[0], interpRight[1],
+ newx,newy);
+}
+
+
+void interpolatePoints2(float x1,float y1,float x2,float y2,float i,float &x,float &y){
+ //i is a float between 0 and 1
+ x=x1+(x2-x1)*i;
+ y=y1+(y2-y1)*i;
+}
+
+
+void interpolatePoints(float x1,float y1,
+ float x2,float y2,float i,float *ret){
+ // --i is a float between 0 and 1
+ ret[0] = x1 + (x2-x1)*i;
+ ret[1] = y1 + (y2-y1)*i;
+}
+
+//-----------------------------------------------------------------------------
+void intersect_lines(float x0,float y0,float x1,
+ float y1,float x2,float y2,
+ float x3,float y3,float *ret){
+ // --THANK YOU PETE CONOLLY
+#define infinity_approx 999999999999999999999.0
+ float a1=0.0;
+ float b1=0.0;
+ float c1=0.0; // constants of linear equations
+ float a2=0.0;
+ float b2=0.0;
+ float c2=0.0;
+ float det_inv=0.0; // the inverse of the determinant of the coefficient
+ float m1=0.0;
+ float m2=0.0; // the slopes of each line
+ if (x1 != x0) {
+ m1 = (y1-y0)/(x1-x0);
+ } else {
+ m1 = infinity_approx;
+ }
+ if (x3 != x2) {
+ m2 = (y3-y2)/(x3-x2);
+ } else {
+ m2 = infinity_approx;
+ }
+ a1 = m1;
+ a2 = m2;
+ b1 = -1;
+ b2 = -1;
+ c1 = (y0-m1*x0);
+ c2 = (y2-m2*x2);
+ // compute the inverse of the determinate
+ det_inv = 1/(a1*b2 - a2*b1);
+ // use Kramers rule to compute xi and yi
+ float xi=((b1*c2 - b2*c1)*det_inv);
+ float yi=((a2*c1 - a1*c2)*det_inv);
+ ret[0] = xi;
+ ret[1] = yi;
+}
+
+//-----------------------------------------------------------------------------
+
+void quadstretch(float x,float y,float l,float t,
+ float w,float h,float *qx,float *qy,float *ret){
+
+ /*
+ --x & y are the original point
+ -- l & t are left and top of original rect
+ -- w & h are width and height of original rect
+ --qx and qy are arrays of 4 points describing the new quad.
+
+ --1. strip it down to floats between 0 and 1
+ -- so we know where it is, relative to the boundaries.
+ */
+
+ float xF = (x-l)/float(w);
+ float yF = (y-t)/float(h);
+ // 2. generate "vertical"
+ float interpTop[2];
+ interpolatePoints(qx[0],qy[0],qx[1],qy[1],xF,interpTop);
+
+ float interpBottom[2];
+ interpolatePoints(qx[3],qy[3],qx[2],qy[2],xF,interpBottom);
+ //3. generate "horizontal"
+ float interpLeft[2];
+ interpolatePoints(qx[0],qy[0],qx[3],qy[3],yF,interpLeft);
+
+ float interpRight[2];
+ interpolatePoints(qx[1],qy[1],qx[2],qy[2],yF,interpRight);
+
+ intersect_lines(interpTop [0], interpTop[1],
+ interpBottom[0],interpBottom[1],
+ interpLeft [0], interpLeft[1],
+ interpRight [0], interpRight[1],ret);
+}
+
+//-----------------------------------------------------------------------------
+
+#define CMPPNTS(a,b,c,d) ((a==c)&&(b==d))
+
+int intersectLineSegs(float x1,float y1,
+ float x2,float y2,
+ float x3,float y3,
+ float x4,float y4){
+ float ix=0;
+ float iy=0;
+ float m1=0;
+ float m2=0;
+ float b1=0;
+ float b2=0;
+ // this code was taken from virtual origami icm final from itp
+ // dumbed down only to return true or false, instead of a
+ // full geometric relationships report.
+
+ // warning: Z not implemented
+
+ if(CMPPNTS(x1,y1,x3,y3)||CMPPNTS(x1,y1,x4,y4)||
+ CMPPNTS(x2,y2,x3,y3)||CMPPNTS(x2,y2,x4,y4)){
+ //any vertexes have a straight match?
+ return true;
+ }
+
+ //vertical check
+ if(x1==x2){//vertical solutions
+ m2 = (y3 - y4)/(x3 - x4);
+ b2 = y3 - m2 * x3;
+ ix = x1;
+ iy = m2*x1 + b2;
+
+ }else if(x3==x4){//vertical solutions
+ m1 = (y1 - y2)/(x1 - x2);
+ b1 = y1 - m1 * x1;
+ ix = x3;
+ iy = m1*x3 + b1;
+
+ }else{//otherwise, do it like you would
+ // slopes
+ m1 = (y1 - y2)/(x1 - x2);
+ m2 = (y3 - y4)/(x3 - x4);
+
+ if(m1==m2){
+ //ir.parallel = true;
+ //return ir;
+ return false;
+ }
+ // y-intercepts
+ b1 = y1 - m1 * x1;
+ b2 = y3 - m2 * x3;
+
+ ix = (b1-b2)/(m2-m1);
+ iy = m1*ix + b1;
+ }
+
+ //and finally, check to see if it is within both segments.
+ //first, the Xs
+
+ if(x1>x2){
+ if(ix > x1 || ix < x2)return false;//ir.outside = true;
+ }else{
+ if(ix < x1 || ix > x2)return false;//ir.outside = true;
+ }
+
+ if(x3>x4){
+ if(ix > x3 || ix < x4)return false;//ir.outside = true;
+ }else{
+ if(ix < x3 || ix > x4)return false;//ir.outside = true;
+ }
+
+ //then the Y's
+
+ if(y1>y2){
+ if(iy > y1 || iy < y2)return false;//ir.outside = true;
+ }else{
+ if(iy < y1 || iy > y2)return false;//ir.outside = true;
+ }
+
+ if(y3>y4){
+ if(iy > y3 || iy < y4)return false;//ir.outside = true;
+ }else{
+ if(iy < y3 || iy > y4)return false;//ir.outside = true;
+ }
+
+ // if(ir.outside){
+ // return false;
+ //return ir;
+ // }else{
+ //ir.ok = true;
+ return true;
+ //return ir;
+ //}
+}
--- /dev/null
+/*
+ * server_internals.c
+ * meant to be compiled on g++ on win32 and os x
+ * this is the backend for server.cpp
+ */
+
+#include "server_internals.h"
+
+//------------------------------------------------------------------------------
+void _tcpserver_messageCallbackFunc(void(*message_callbackfuncname)(int,int,int)){
+ _tcpserver_message_callbackfunc = message_callbackfuncname;
+}
+
+//------------------------------------------------------------------------------
+void _tcpserver_close(){
+ close(_tcpserver_socket);//this will also send EOFs to all the threads.
+ _tcpserver_socket = -1;
+}
+//------------------------------------------------------------------------------
+void *_tcpserver_serverListening(void *args){
+ int ret;
+ //listen out the port.
+
+ while(1){
+ //printf("debug %i\r\n",_tcpserver_socket);
+ sched_yield();
+ listen(_tcpserver_socket,0);
+ if(_tcpserver_socket!=-1){
+ pthread_t tid;
+ if ((_tcpserver_pendingSocket = get_client_socket(_tcpserver_socket)) == -1){
+ printf("error getting network client. %i\n",_tcpserver_pendingSocket);
+ return 0;
+ } else { //success
+ ret = pthread_create(&tid, NULL,_tcpserver_clienthandler, NULL); //create a new thread
+ }
+
+ } else {
+ printf("there was an error\n",0);
+ break;
+ }
+ }
+}
+//------------------------------------------------------------------------------
+int _tcpserver_listen(int port){
+
+ if((_tcpserver_socket = make_listen_socket(port)) == -1){
+ printf("error making socket\n",0);
+ return -1;
+ }
+ pthread_t tid;
+ pthread_create(&tid, NULL,_tcpserver_serverListening, NULL); //create a new thread
+ return _tcpserver_socket;
+}
+//------------------------------------------------------------------------------
+void *_tcpserver_clienthandler(void *args){
+ int mySock = _tcpserver_pendingSocket;//take a snapshot.
+ int ret;
+ FILE *fp = fdopen(mySock, "r");
+ _tcpserver_message_callbackfunc( _TCPSERVER_MESSAGE_CLIENT_CONNECTED,_tcpserver_pendingSocket,0 );
+ //get some input
+ int c;
+ while ((c = fgetc(fp)) != EOF ) {
+ sched_yield();
+ _tcpserver_message_callbackfunc( _TCPSERVER_MESSAGE_CLIENT_RECEIVED_BYTE,mySock,c );
+ }
+
+ fclose(fp);
+ close(mySock);
+
+ _tcpserver_message_callbackfunc( _TCPSERVER_MESSAGE_CLIENT_DISCONNECTED,mySock,0 );
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+
+int get_client_socket( int listen_socket) {
+ struct sockaddr_in sin;
+ int sock;
+ socklen_t sin_len;
+ memset(&sin, 0, sizeof( sin));
+ sin_len = sizeof( sin);
+ sock = accept( listen_socket, (struct sockaddr *) &sin, &sin_len);
+ return sock;
+}
+
+//------------------------------------------------------------------------------
+
+int make_listen_socket( int port) {
+ struct sockaddr_in sin;
+ int sock;
+ sock = socket( AF_INET, SOCK_STREAM, 0);
+ if (sock < 0){
+ printf("network error:socket could not be created. (port:%i)\n",port);
+ return -1;
+ }
+ memset(& sin, 0, sizeof( sin));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = htonl( INADDR_ANY);
+ sin.sin_port = htons( port);
+ if (bind( sock, (struct sockaddr*) &sin, sizeof( sin)) < 0){
+ printf("network error:socket could not be bound. (port:%i) Do you have permissions?\n",port);
+ return -1;
+ }
+ return sock;
+
+}
+//------------------------------------------------------------------------------
+int _tcpserver_getSocket(){
+ return _tcpserver_socket;
+}
+
--- /dev/null
+#ifndef _SERVER_INTERNALS_H_
+#define _SERVER_INTERNALS_H_
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <sched.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+
+static int _tcpserver_socket=-1;//main socket
+static int _tcpserver_pendingSocket=-1;
+
+static void(*_tcpserver_message_callbackfunc)(int,int,int);
+
+#define _TCPSERVER_MESSAGE_CLIENT_CONNECTED 0
+#define _TCPSERVER_MESSAGE_CLIENT_DISCONNECTED 1
+#define _TCPSERVER_MESSAGE_CLIENT_RECEIVED_BYTE 2
+
+void _server_callback(int arg1,int arg2,int arg3);
+void server_close();
+void server_init(int port);
+void server_sendAll(char *data,int length);
+int server_valid();//returns true only if the server is ready and listening.
+int server_clientcount();
+
+//------------------------------------------------------------------------------
+
+void _tcpserver_messageCallbackFunc(void(*message_callbackfuncname)(int,int,int));
+int make_listen_socket( int port) ;
+int get_client_socket( int listen_socket) ;
+void *_tcpserver_clienthandler(void *args);
+void *_tcpserver_serverListening(void *args);
+int _tcpserver_listen(int port);
+void _tcpserver_close();
+int _tcpserver_getSocket();
+#endif
--- /dev/null
+#include "server_internals.h"
+#include "Vector.h"
+
+static Vector *_server_clients=0;
+
+//------------------------------------------------------------------------------
+
+int server_valid(){
+ //printf("%i\r\n",_tcpserver_getSocket());
+ return (_tcpserver_getSocket()!=-1);//zero if not valid.
+}
+
+int server_clientcount(){
+ if(_server_clients!=0){
+ return _server_clients->count;
+ } else {
+ return 0;
+ }
+}
+
+void _server_callback(int arg1,int arg2,int arg3){
+
+ switch(arg1){
+ case _TCPSERVER_MESSAGE_CLIENT_CONNECTED:
+ //printf("new client %i\n",arg2);
+ _server_clients->push(arg2);
+ break;
+ case _TCPSERVER_MESSAGE_CLIENT_DISCONNECTED:
+ //printf("bye client %i\n",arg2);
+ _server_clients->deleteMatch(arg2);
+ break;
+ case _TCPSERVER_MESSAGE_CLIENT_RECEIVED_BYTE:
+ if(arg3=='\n'){
+ //printf("received %i %i '\\n'\n",arg2,arg3,arg3);
+ } else if(arg3=='\r'){
+ //printf("received %i %i '\\r'\n",arg2,arg3,arg3);
+ } else {
+ //printf("received %i %i '%c'\n",arg2,arg3,arg3);
+ }
+
+ // here is a demonstration of a simple broadcast server. it echos all messages to everyone.
+ //char thebyte;
+ //thebyte = (char)arg3;
+ //server_sendAll(&thebyte,1);// here is where i relay any messages to the other clients.
+ //
+
+ break;
+ default:
+ printf("error: invalid _tcpserver internal callback message: %i\n",arg1);//wtfh?!
+ }
+}
+
+void server_close(){
+ if(_server_clients!=0){
+ delete _server_clients;
+ }
+ if(_tcpserver_socket!=-1){
+ _tcpserver_close();
+ }
+}
+
+void server_init(int port){
+ _server_clients = new Vector();
+ _tcpserver_messageCallbackFunc(_server_callback);
+ _tcpserver_listen(port);
+}
+
+
+void server_sendAll(char *data,int length){
+ for(int i=0;i<_server_clients->count;i++){
+ int thisClient = _server_clients->get(i);
+ send(thisClient,data,length,0);
+ }
+}
+
+/* this is an example program that uses this API
+
+int main(){
+ server_init(667);
+ while(1){
+ //server_sendAll("hi there\n",strlen("hi there\n"));
+ sched_yield();//don't care what i do here.
+ }
+ server_close();
+ return 0;
+}
+
+*/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>%%PROJNAME%%</string>
+ <key>CFBundleGetInfoString</key>
+ <string>no description (yet)</string>
+ <key>CFBundleIconFile</key>
+ <string>appIcon</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>%%PROJNAME%%</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+</dict>
+</plist>
--- /dev/null
+#!/usr/bin/python
+
+import sys
+
+chmod = 0755
+
+if(len(sys.argv)==1):
+ print "help goes here"
+else: #make it
+ import os
+ projname = sys.argv[1]
+ try:
+ os.mkdir(projname+".app",chmod)
+ os.mkdir(projname+".app/Contents",chmod)
+ os.mkdir(projname+".app/Contents/MacOS",chmod)
+ os.mkdir(projname+".app/Contents/Resources",chmod)
+ os.mkdir(projname+".app/Contents/Resources/renders",chmod)
+ except(OSError):#who cares if it already exists
+ pass
+
+ os.system("cp -r ./media ./" + projname + ".app/Contents/Resources")
+ os.system("cp ./"+projname+" ./" + projname + ".app/Contents/MacOS/" + projname)
+ os.system("cp ./media/appIcon.icns ./" + projname + ".app/Contents/Resources/appIcon.icns")
+ #Info.plist
+ plist = open("script/Info.plist.template.xml","r")
+ plist = plist.read()
+ import string
+ plist = string.split(plist,"%%PROJNAME%%")
+ plist = string.join(plist,projname)
+
+ a = open("./" + projname + ".app/Contents/Info.plist","w")
+ a.write(plist)
+ a.close()
--- /dev/null
+#!/usr/bin/python
+#
+# this will analyse a given binary and bundle all depends from /opt/local/lib
+#
+import sys,os,string
+
+queue = []
+
+class OtoolResult(object):
+ """docstring"""
+
+ fullPath = ""
+ moduleName = ""
+ path = ""
+ updatable = ""
+
+ def __init__(self,s,u):
+ """docstring"""
+ self.extract(s)
+ self.updatable = u
+ def extract(self,s):
+ """docstring"""
+ self.fullPath = string.split(s[1:],' ')[0]
+ self.moduleName = string.split(self.fullPath,'/')[-1]
+ self.path = string.join(string.split(self.fullPath,'/')[:-1],'/')
+
+ def __str__(self):
+ return "OtoolResult{\n\tfullpath=" + self.fullPath + "\n\tmoduleName=" + self.moduleName + "\n\tpath=" + self.path + "\n}\n"
+
+ def getDestDir(self):
+ return (string.join(string.split(sys.argv[1],"/")[:-1],"/"))
+
+
+ def previousExists(self):
+ """determines whether or not we should copy the file into that dir"""
+ lss = os.listdir(self.getDestDir())
+ retval = 0
+ for i in lss:
+ if(i==self.moduleName):
+ retval = 1
+ break
+ return retval
+
+ def bundlePathMatch(self,p):
+ if(self.path == p):
+ if(not self.previousExists()):
+ global queue
+ os.system("cp " + self.path + "/" + self.moduleName + " " + self.getDestDir())
+ #todo - call install_name_tool with -id flag to update the lib's ID.
+ os.system("install_name_tool -id @executable_path/" + self.moduleName + " " + self.getDestDir() + "/" + self.moduleName)
+ print "\tbundled " + self.moduleName
+ queue += [self.getDestDir() + "/" + self.moduleName] #add this to the end of the list
+ os.system("install_name_tool -change " + self.fullPath + " " + "@executable_path/" + self.moduleName + " " + self.updatable)
+
+# argument validation
+if(len(sys.argv) < 2):
+ print "\n\nexample: bundle_depends.py ../programme.app/Contents/MacOS/programme\n\n"
+
+
+def bundle_depends(filename):
+ p = os.popen("otool -L "+filename,'r')
+ p = string.split(p.read(),'\n')
+
+ p = p[1:-1] #format otool output by trimming 1 from left and right
+
+ for i in p:
+ otr = OtoolResult(i,filename)
+ otr.bundlePathMatch(thisPath)
+
+
+thisPath = "/opt/local/lib"
+queue += [sys.argv[1]]
+
+while(len(queue)>0):
+ print("Updating " + queue[0])
+ bundle_depends(queue[0]) #deal with the first one
+ queue = queue[1:] #chop off the first one
--- /dev/null
+#include "<MODULENAME>.h"
+#include "jttoolkit.h"
+#include "Global.h"
+
+<MODULENAME>::<MODULENAME>(){
+ for(int i=0;i<5;i++)rnd.push_back(randomFloat());
+
+}
+
+<MODULENAME>::~<MODULENAME>(){
+
+}
+
+void <MODULENAME>::step(){
+
+}
+
+void <MODULENAME>::draw(int counter,JPoint end){
+
+}
+
--- /dev/null
+#!/usr/bin/python
+
+#
+# this script will generate a new C++ class in its own file, inside
+# the intern directory.
+#
+
+import string
+import sys
+import os
+
+f = open(sys.path[0] + "/cpptemplate.cpp","r")
+cpptemplate = f.read()
+f.close()
+
+f = open(sys.path[0] + "/headertemplate.h","r")
+headertemplate = f.read()
+f.close()
+
+def replace(str,newname):
+ s = string.split(str,"<MODULENAME>")
+ return string.join(s,newname)
+
+if(len(sys.argv)<2):
+ print "creates a new object in jttoolkit intern and adds it to the makefile.\nexample: ./create.py JTClassName"
+else:
+ full=sys.argv[1]
+ print "making object \""+full+".cpp\""
+ name = full
+ #execfile("./generate")
+ out=open(sys.path[0] + "/../intern/"+full+".cpp","a")
+ out.write(replace(cpptemplate,name))
+ out.close()
+ out=open(sys.path[0] + "/../intern/"+name+".h","a")
+ out.write(replace(headertemplate,name))
+ out.close()
+
--- /dev/null
+#!/usr/bin/python
+import string,sys
+
+a = open(sys.argv[1],"rb")
+a=a.read()
+a=string.split(a,sys.argv[2])
+a=string.join(a,sys.argv[3])
+b=open(sys.argv[1],"wb")
+b.write(a)
+b.close()
--- /dev/null
+#!/usr/bin/python
+import string
+infile = open("../script/list.txt","r")
+objs = string.split(infile.read())
+out = open("objectsbuild_generated.mk","w")
+for i in objs:
+ if(i!=''):
+ n = string.split(i,'.')[0] #chop off the .cpp or .c
+ out.write("build/"+n+".o: intern/"+i+"\n\tcd build; g++ $(OFLAGS) ../intern/"+i+"\n\n")
+out.close()
+
+out = open("objectslist_generated.mk","w")
+out.write("OBJECTS=");
+for i in objs:
+ if(i!=''):
+ n = string.split(i,'.')[0] #chop off the .cpp or .c
+ out.write(n+".o ")
+out.write("\n\n")
+out.close()
+
+
+out = open("objectslistbuild_generated.mk","w")
+out.write("OBJECTSBUILD=");
+for i in objs:
+ if(i!=''):
+ n = string.split(i,'.')[0] #chop off the .cpp or .c
+ out.write("build/"+n+".o ")
+out.write("\n\n")
+out.close()
--- /dev/null
+#ifndef _<MODULENAME>_H_
+#define _<MODULENAME>_H_
+
+
+#include "TreeOrniment.h"
+#include <vector>
+
+using namespace std;
+
+class <MODULENAME> : public TreeOrniment{
+ public:
+ vector<float> rnd;
+ <MODULENAME>();
+ ~<MODULENAME>();
+
+ void step();
+ void draw(int counter,JPoint end);
+
+};
+
+
+
+#endif
+
--- /dev/null
+build/jttoolkit.o: intern/jttoolkit.cpp
+ cd build; g++ $(OFLAGS) ../intern/jttoolkit.cpp
+
+build/project.o: intern/project.cpp
+ cd build; g++ $(OFLAGS) ../intern/project.cpp
+
+build/JoshFont.o: intern/JoshFont.cpp
+ cd build; g++ $(OFLAGS) ../intern/JoshFont.cpp
+
+build/quadstretch.o: intern/quadstretch.cpp
+ cd build; g++ $(OFLAGS) ../intern/quadstretch.cpp
+
+build/obj.o: intern/obj.cpp
+ cd build; g++ $(OFLAGS) ../intern/obj.cpp
+
+build/Global.o: intern/Global.cpp
+ cd build; g++ $(OFLAGS) ../intern/Global.cpp
+
+build/JRect.o: intern/JRect.cpp
+ cd build; g++ $(OFLAGS) ../intern/JRect.cpp
+
+build/Satellite.o: intern/Satellite.cpp
+ cd build; g++ $(OFLAGS) ../intern/Satellite.cpp
+
+build/TheBall.o: intern/TheBall.cpp
+ cd build; g++ $(OFLAGS) ../intern/TheBall.cpp
+
+build/BallPointer.o: intern/BallPointer.cpp
+ cd build; g++ $(OFLAGS) ../intern/BallPointer.cpp
+
+build/BallPathTracer.o: intern/BallPathTracer.cpp
+ cd build; g++ $(OFLAGS) ../intern/BallPathTracer.cpp
+
+build/JPoint.o: intern/JPoint.cpp
+ cd build; g++ $(OFLAGS) ../intern/JPoint.cpp
+
+build/Athletes.o: intern/Athletes.cpp
+ cd build; g++ $(OFLAGS) ../intern/Athletes.cpp
+
+build/Guy.o: intern/Guy.cpp
+ cd build; g++ $(OFLAGS) ../intern/Guy.cpp
+
+build/GameGrid.o: intern/GameGrid.cpp
+ cd build; g++ $(OFLAGS) ../intern/GameGrid.cpp
+
+build/JImage.o: intern/JImage.cpp
+ cd build; g++ $(OFLAGS) ../intern/JImage.cpp
+
+build/Clover.o: intern/Clover.cpp
+ cd build; g++ $(OFLAGS) ../intern/Clover.cpp
+
+build/GuyPointer.o: intern/GuyPointer.cpp
+ cd build; g++ $(OFLAGS) ../intern/GuyPointer.cpp
+
+build/StatSign.o: intern/StatSign.cpp
+ cd build; g++ $(OFLAGS) ../intern/StatSign.cpp
+
+build/GuyConnectors.o: intern/GuyConnectors.cpp
+ cd build; g++ $(OFLAGS) ../intern/GuyConnectors.cpp
+
+build/JImageSequence.o: intern/JImageSequence.cpp
+ cd build; g++ $(OFLAGS) ../intern/JImageSequence.cpp
+
+build/ShotProfile.o: intern/ShotProfile.cpp
+ cd build; g++ $(OFLAGS) ../intern/ShotProfile.cpp
+
+build/FluxDiagram.o: intern/FluxDiagram.cpp
+ cd build; g++ $(OFLAGS) ../intern/FluxDiagram.cpp
+
+build/TreeNode.o: intern/TreeNode.cpp
+ cd build; g++ $(OFLAGS) ../intern/TreeNode.cpp
+
--- /dev/null
+OBJECTS=jttoolkit.o project.o JoshFont.o quadstretch.o obj.o Global.o JRect.o Satellite.o TheBall.o BallPointer.o BallPathTracer.o JPoint.o Athletes.o Guy.o GameGrid.o JImage.o Clover.o GuyPointer.o StatSign.o GuyConnectors.o JImageSequence.o ShotProfile.o FluxDiagram.o TreeNode.o
+
--- /dev/null
+OBJECTSBUILD=build/jttoolkit.o build/project.o build/JoshFont.o build/quadstretch.o build/obj.o build/Global.o build/JRect.o build/Satellite.o build/TheBall.o build/BallPointer.o build/BallPathTracer.o build/JPoint.o build/Athletes.o build/Guy.o build/GameGrid.o build/JImage.o build/Clover.o build/GuyPointer.o build/StatSign.o build/GuyConnectors.o build/JImageSequence.o build/ShotProfile.o build/FluxDiagram.o build/TreeNode.o
+