#include #include #include #include #include #include #include /* glut.h includes gl.h and glu.h*/ #define PI 3.141592 #define NX 32 #define NY 32 #define ST_DEN 4 #define FULL_ST 4 #define MAX_GEN 128 //the number of the object being moved (0 if none) int WHeight = 640; int WWidth = 640; //for detecting doubleclicks time_t clickTime; int clickX = -1; int clickY = -1; //remember mouse position int mouseX; int mouseY; //program modes int addingGen = 0; int currentElement = 0; //display options int option; int displayArrows = 0; int displayBackground = 0; int displayStreams = 0; int displayGen = 0; int displayGrid = 0; int bothWays = 0; //modes int mode1 = 0; // track keyboard actions int keys[256] = {0}; // Define gridsize float VF[NX][NY][2]; float T[NX][NY]; // Field generators float Gen[MAX_GEN][4]; int GenSize = 0; float Wing[9][2]; //function declarations void setProjection(); void display(); void init(); void drawArrow(float a, float d); void shepard(float x, float y, float *v); void shepard2(float T, float x, float y, float *v); void generateField(); void normalizeField(); void drawGenArrow(float a, float d); void calculateTurbulance(); void pick (int x, int y); void drawWing(); void loadMode1(); //calculate norms float dist2(float x, float y) { return x*x+y*y; } float dist(float x, float y) { return sqrt(dist2(x, y)); } float pos(float f) { return (f<0) ? -f : f; } //gets color from velocity void setColor(float v, float alpha) { if (v<0.25) { glColor4f(0.0, v/0.25, 1.0, alpha); } else if (v<0.5) { glColor4f(0.0, 1.0, 2-v/0.25, alpha); } else if (v<0.75) { glColor4f(v/0.25-2, 1.0, 0.0, alpha); } else { glColor4f(1, 4-v/0.25, 0.0, alpha); } } void setColorLoop(float v, float alpha) { float dc = 1./6; if (v0) { int i,j; for (i=n;id) ? max : d; } } if (max!=0) { for (i=0;iT[i][j]) ? max : T[i][j]; } } if (max!=0) { for (i=0;i0) { if (dist2(x-Gen[i][0], y-Gen[i][1])==0) { res[0] = Gen[i][2]-Gen[i][0]; res[1] = Gen[i][3]-Gen[i][1]; C = 1; break; } else { w = 1./dist2(x-Gen[i][0], y-Gen[i][1]); res[0] += w*(Gen[i][2]-Gen[i][0]); res[1] += w*(Gen[i][3]-Gen[i][1]); C += w; } } } v[0] = res[0]/C; v[1] = res[1]/C; printf("%d:[%f %f]\n",i,v[0],v[1]); } void drawStream(float x, float y, float h) { //printf("drawStream - [%f %f %f]\n", x, y, h); if (GenSize!=0) { int i, stop = 0; float v[2] = {0, 0}; float d; float bx=x, by=y; glBegin(GL_LINE_STRIP); for (i=0; stop==0 && i<10000; i++) { glLineWidth(i/5); if (x!=NX && y!=NY) { shepard(x,y,v); } else { stop = 1; } glVertex2f(x, y); d = dist(v[0],v[1]); if (d!=0) { x += v[0]*h/d; y += v[1]*h/d; } if (x<=0 || x>=1 || y<=0 || x>=1 || d<0.001) { stop = 1; } } glEnd(); if (bothWays==1) { glBegin(GL_LINE_STRIP); for (i=0, stop = 0; stop==0 && i<10000; i++) { if (bx!=NX && by!=NY) { shepard(bx,by,v); } else { stop = 1; } glVertex2f(bx, by); d = dist(v[0],v[1]); if (d!=0) { bx -= v[0]*h/d; by -= v[1]*h/d; } if (bx<=0 || bx>=1 || by<=0 || bx>=1 || d<0.001) { stop = 1; } } glEnd(); } } //printf("drawStream - done\n"); } void drawStreams(float h) { //glLineWidth(2); int i; glColor4f(0.01, 0.01, 0.01, 0.8); for (i=0;i0) ? PI/2 : -PI/2; } else { a = atan((Gen[i][3]-Gen[i][1])/(Gen[i][2]-Gen[i][0])); a = ((Gen[i][2]-Gen[i][0])<=0) ? PI+a : a; } glPushMatrix(); glLineWidth(2); glTranslatef(Gen[i][0], Gen[i][1], 0); glColor4f(0.01, 0.01, 0.01, 0.7); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); drawGenArrow(a, d); glColor4f(0.99, 0.99, 0.99, 0.99); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); drawGenArrow(a, d); glLineWidth(1); glPopMatrix(); } //printf("drawGen - done\n"); } void drawRubberGen(float x, float y) { //printf("drawRubberGen - %f %f %f %f\n",Gen[GenSize][0],Gen[GenSize][1],x,y); float a, d = dist(Gen[GenSize][0]-x,Gen[GenSize][1]-y); if ((x-Gen[GenSize][0])==0) { a = ((y-Gen[GenSize][1])>0) ? PI/2 : -PI/2; } else { a = atan((y-Gen[GenSize][1])/(x-Gen[GenSize][0])); a = ((x-Gen[GenSize][0])<=0) ? PI+a : a; } glPushMatrix(); glLineWidth(2); glTranslatef(Gen[GenSize][0], Gen[GenSize][1], 0); glColor4f(0.01, 0.01, 0.01, 0.7); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); drawGenArrow(a, d); glColor4f(0.99, 0.99, 0.99, 0.99); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); drawGenArrow(a, d); glLineWidth(1); glPopMatrix(); } void drawGrid() { int i; glColor4f(0.1, 0.1, 0.1, 0.4); for (i=0;i 0.001) { addGen(Gen[GenSize][0], Gen[GenSize][1],(float)x/WWidth, (float)y/WHeight); //printf("GenSize=%d\n",GenSize); } } addingGen = 0; } else if ((button==GLUT_RIGHT_BUTTON) && (state==GLUT_DOWN)) { addingGen = 0; pick(x, y); if (currentElement!=0) { deleteGen(currentElement-1); } currentElement = 0; } else if ((button==GLUT_RIGHT_BUTTON) && (state==GLUT_UP)) { addingGen = 0; } else if ((button==GLUT_MIDDLE_BUTTON) && (state==GLUT_DOWN)) { } else if ((button==GLUT_MIDDLE_BUTTON) && (state==GLUT_UP)) { } mouseX = x; mouseY = y; display(); } void mouseMove (GLint x, GLint y) { y = WHeight - y; mouseX = x; mouseY = y; display(); } void passiveMouseMove (GLint x, GLint y) { y = WHeight - y; } void keyboardDown (unsigned char key, int x, int y) { //printf("key: %d\n",key); keys[key] = 1; switch (key) { case 114: // r - restart init(); break; case 27 : // escape - quit exit(0); break; case 97 : // a - display arrows displayArrows = (displayArrows+1)%3; break; case 98 : // b - display background displayBackground = (displayBackground+1)%4; break; case 103 : // g - display generators displayGrid = (displayGrid+1)%2; break; case 118 : // v - display generators displayGen = (displayGen+1)%2; break; case 115 : // s - display streams displayStreams = (displayStreams+1)%2; break; case 119 : // s - load wing 1 loadMode1(); } display(); } void keyboardUp (unsigned char key, int x, int y) { printf("key: %d\n",key); keys[key] = 0; } void pick (int x, int y) { GLuint buff[64] = {0}; GLint hits, view[4]; glSelectBuffer(64, buff); glGetIntegerv(GL_VIEWPORT, view); glRenderMode(GL_SELECT); glInitNames(); glPushName(0); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluPickMatrix(x, y, 1.0, 1.0, view); glOrtho(0, 1.0, 0, 1.0, -10., 10.); glMatrixMode(GL_MODELVIEW); glFlush(); printf("addingGen %d\n",addingGen); display(); glPopMatrix(); hits = glRenderMode(GL_RENDER); currentElement = (GLubyte)buff[4*(hits-1)+3]; printf("pick: %d\n",currentElement); glMatrixMode(GL_MODELVIEW); } void reshape(int w, int h){ int m = (w