// Includes #ifdef G_OS_WIN32 #define WIN32_LEAN_AND_MEAN 1 #include #endif #include #include #include #include "fluids.h" #include "seedpoint.h" #include "renderer_gl.h" struct point seedpoints[MAX_SEEDPOINTS]; int cur_seedpoint; static struct point2f hit_test(struct point2f mouse_coord) { double l_ProjectionMatrix[16], l_ModelViewMatrix[16], l_PointNear[3], l_PointFar[3], l_dFactor; int l_ViewPort[4]; struct point2f new_mouse, return_value; new_mouse.x = mouse_coord.x; new_mouse.y = mouse_coord.y; //first setup the modelview matrix (assume the projection matrix is still valid/correct) glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glTranslatef(x_pos, y_pos, z_pos); glScalef(z_pos, z_pos, z_pos); glRotatef(x_rot, 1.0f, 0.0f, 0.0f); glRotatef(y_rot, 0.0f, 1.0f, 0.0f); glRotatef(z_rot, 0.0f, 0.0f, 1.0f); //get the viewport, modelview and projection matrices' values glGetIntegerv(GL_VIEWPORT, l_ViewPort); glGetDoublev(GL_MODELVIEW_MATRIX, l_ModelViewMatrix); glGetDoublev(GL_PROJECTION_MATRIX, l_ProjectionMatrix); glPopMatrix(); //invert the mouse y coordinate new_mouse.y = (winHeight - new_mouse.y); //unproject the mouse coords to the object coordinates at the near clipping plane gluUnProject((GLdouble) new_mouse.x, new_mouse.y, 0.0, l_ModelViewMatrix, l_ProjectionMatrix, l_ViewPort, &l_PointNear[0], &l_PointNear[1], &l_PointNear[2]); //unproject the mouse coords to the object coordinates at the far clipping plane gluUnProject((GLdouble) new_mouse.x, new_mouse.y, 1.0, l_ModelViewMatrix, l_ProjectionMatrix, l_ViewPort, &l_PointFar[0], &l_PointFar[1], &l_PointFar[2]); //determine where the the vector (l_PointNear -> l_PointFar) intersects the plane z = 0, //because we draw the data visualisation at z = 0, we get the coordinates l_dFactor = -l_PointNear[2] / (l_PointFar[2] - l_PointNear[2]); //return the x,y coordinates at the point where the vector intersects the z = 0 plane return_value.x = l_PointNear[0] + (l_dFactor * (l_PointFar[0] - l_PointNear[0])); return_value.y = l_PointNear[1] + (l_dFactor * (l_PointFar[1] - l_PointNear[1])); return return_value; } void create_seedpoint(float mx, float my) { struct point2f coords; if (cur_seedpoint >= MAX_SEEDPOINTS) return; coords.x = mx; coords.y = my; //coords = hit_test(coords); seedpoints[cur_seedpoint].x = coords.x; seedpoints[cur_seedpoint].y = coords.y; seedpoints[cur_seedpoint].z = 0; cur_seedpoint++; } // create_seedpoint void delete_seedpoint(int seedpoint_nr) { int i = seedpoint_nr; for (i; i < cur_seedpoint; i++) { seedpoints[i].x = seedpoints[i+1].x; seedpoints[i].y = seedpoints[i+1].y; seedpoints[i].z = seedpoints[i+1].z; } for (i; i < MAX_SEEDPOINTS; i++) { seedpoints[i].x = 0.0f; seedpoints[i].y = 0.0f; seedpoints[i].z = 0.0f; } cur_seedpoint--; } // delete_seedpoint void render_seedpoints(void) { int i; GLuint lid = glGenLists(1); GLUquadricObj *qobj = gluNewQuadric(); gluQuadricDrawStyle(qobj, GLU_FILL); gluQuadricNormals(qobj, GLU_SMOOTH); gluQuadricOrientation(qobj, GLU_OUTSIDE); glDisable(GL_BLEND); glNewList(lid, GL_COMPILE); gluSphere(qobj, 10.0f, 16, 16); glEndList(); for (i = 0; i < cur_seedpoint; i++) { float color_scale = (float)i/MAX_SEEDPOINTS; glColor3f(color_scale, 1.0f - color_scale, 0.0f); glPushMatrix(); glTranslatef(seedpoints[i].x, winHeight - seedpoints[i].y, seedpoints[i].z); glCallList(lid); glPopMatrix(); } gluDeleteQuadric(qobj); glDeleteLists(lid, 1); } int get_cur_seedpoint(void) { return cur_seedpoint; } void set_cur_seedpoint(int seed_nr) { cur_seedpoint = seed_nr; } struct point get_seedpoint(int index) { struct point p; p.x = seedpoints[index].x; p.y = seedpoints[index].y; p.z = seedpoints[index].z; return p; }