Advertisement
Aslai

Untitled

Sep 19th, 2011
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.42 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define _USE_MATH_DEFINES
  4. #include <math.h>
  5. #define pi M_PI
  6. #define FREEGLUT_STATIC
  7. #include <GL/freeglut.h>
  8. #include <GL/gl.h>
  9. #include <gl/glu.h>
  10. #include <windows.h>
  11.  
  12.  
  13. struct __verlet_node__{
  14.     double __x, __y, __z, __xp, __yp, __zp, __mass, __damp, __grav;
  15.     __verlet_node__()
  16.     {
  17.         __x = 0; __y = 0; __z = 0; __xp = __x; __yp = __y; __zp = __z;
  18.         __mass = 1; __damp = 1; __grav = .1;
  19.     }
  20.     __verlet_node__( double x, double y, double z, double mass = 1, double damp = 1 )
  21.     {
  22.         __x = x; __y = y; __z = z; __xp = __x; __yp = __y; __zp = __z;
  23.         __mass = mass; __damp = damp; __grav = .1;
  24.     }
  25.     __verlet_node__( double mass, double damp = 1 )
  26.     {
  27.         __x = 0; __y = 0; __z = 0; __xp = __x; __yp = __y; __zp = __z;
  28.         __mass = mass; __damp = damp; __grav = .1;
  29.     }
  30.     void move()
  31.     {
  32.         double xp2 = __x, yp2 = __y, zp2 = __z;
  33.         __x += ( __x - __xp ) * __damp * (1 - 1 / (__mass+50));
  34.         __y += ( __y - __yp ) * __damp * (1 - 1 / (__mass+50));
  35.         __z += ( __z - __zp ) * __damp * (1 - 1 / (__mass+50)) + __grav;
  36.         __xp = xp2; __yp = yp2; __zp = zp2;
  37.     }
  38.     void moveTo( double x, double y, double z )
  39.     {
  40.         __x = x;
  41.         __y = y;
  42.         __z = z;
  43.     }
  44.     void moveRel( double x, double y, double z )
  45.     {
  46.         __x += x;
  47.         __y += y;
  48.         __z += z;
  49.     }
  50.     void moveDir( double latDir, double vertDir, double distance )
  51.     {
  52.         __x += cos( latDir ) * cos( vertDir );
  53.         __y += sin( latDir ) * cos( vertDir );
  54.         __z += sin( vertDir );
  55.     }
  56. };
  57. struct __verlet_constraint__{
  58.     struct __verlet_node__ *n1;
  59.     struct __verlet_node__ *n2;
  60.     double __len;
  61.     int __ret_time;
  62.     __verlet_constraint__( struct __verlet_node__ *_n1, struct __verlet_node__ *_n2 )
  63.     {
  64.         n1 = _n1;
  65.         n2 = _n2;
  66.         __ret_time = 1;
  67.         double dx = n2->__x - n1->__x;
  68.         double dy = n2->__y - n1->__y;
  69.         double dz = n2->__z - n1->__z;
  70.         __len = sqrt( dx*dx+dy*dy+dz*dz );
  71.     }
  72.     __verlet_constraint__( struct __verlet_node__ *_n1, struct __verlet_node__ *_n2, double len )
  73.     {
  74.         n1 = _n1;
  75.         n2 = _n2;
  76.         __ret_time = 1;
  77.         __len = len;
  78.     }
  79.  
  80.     void satisfy()
  81.     {
  82.         double dx = n2->__x - n1->__x;
  83.         double dy = n2->__y - n1->__y;
  84.         double dz = n2->__z - n1->__z;
  85.         double h = sqrt( dx*dx+dy*dy+dz*dz);
  86.         double scale = (__len - h) / h;
  87.         double massRatio1 = n2->__mass / (n1->__mass+n2->__mass);
  88.         double massRatio2 = n1->__mass / (n1->__mass+n2->__mass);
  89.  
  90.         n1->moveRel( -( dx * scale ) / __ret_time * massRatio1, -( dy * scale ) / __ret_time * massRatio1, -( dz * scale ) / __ret_time * massRatio1 );
  91.         n2->moveRel(  ( dx * scale ) / __ret_time * massRatio2,  ( dy * scale ) / __ret_time * massRatio2,  ( dz * scale ) / __ret_time * massRatio2 );
  92.     }
  93. };
  94.  
  95. typedef struct __verlet_constraint__ CONSTRAINT;
  96. typedef struct __verlet_node__ NODE;
  97.  
  98.  
  99. // These variables set the dimensions of the rectanglar region we wish to view.
  100. const double Xmin = 0.0, Xmax = 3.0;
  101. const double Ymin = 0.0, Ymax = 3.0;
  102.  
  103. // glutKeyboardFunc is called below to set this function to handle
  104. //      all "normal" ascii key presses.
  105. // Only space bar and escape key have an effect.
  106.  
  107.  
  108. int mouse_x = 320, mouse_y= 100, mvd = 0;
  109. void setM( int x, int y){
  110.     mouse_x = x;
  111.     mouse_y = y;
  112. }
  113. void getM( int x, int y){
  114.     mvd = 0;
  115.     if( x != mouse_x || y != mouse_y )
  116.         mvd = 1;
  117. }
  118.  
  119.  
  120. NODE* n1;
  121.  
  122.  
  123.  
  124.  
  125. void myKeyboardFunc( unsigned char key, int x, int y )
  126. {
  127.     switch ( key ) {
  128.     case ' ':
  129.         printf( "X: %f; Y: %f; MX = %i; MY = %i;\n", n1->__x, n1->__y, mouse_x, mouse_y );
  130.         break;
  131.     case 27:                                    // "27" is theEscape key
  132.         exit(1);
  133.  
  134.     }
  135. }
  136.  
  137. #include<vector>
  138. std::vector<NODE*> Nodes;
  139. std::vector<CONSTRAINT*> Cons;
  140.  
  141. NODE* new_node( double x, double y, double z, double mass = 1, double damp = 1 )
  142. {
  143.     NODE* a = new NODE( x, y, z, mass, damp );
  144.     Nodes.push_back( a );
  145.     return a;
  146. }
  147. CONSTRAINT* constrain( NODE* n1, NODE* n2 )
  148. {
  149.     CONSTRAINT* a = new CONSTRAINT( n1, n2 );
  150.     Cons.push_back( a );
  151.     return a;
  152. }
  153. CONSTRAINT* constrain( NODE* n1, NODE* n2, double len )
  154. {
  155.     CONSTRAINT* a = new CONSTRAINT( n1, n2, len );
  156.     Cons.push_back( a );
  157.     return a;
  158. }
  159.  
  160.  
  161.  
  162.  
  163.  
  164. void init(){
  165.  
  166.     #define R 9
  167.     #define RAD 5
  168.     NODE* nodes[160][320];
  169.  
  170.     int j = 0;
  171.     int i = 0;
  172.     for( double rv = pi/2; rv > -pi/2; rv -= pi/R, i ++ ){
  173.         if( rv == pi/2) continue;
  174.         j = 0;
  175.         for( double rl = 0; rl < 2*pi; rl += pi/R, j ++ ){
  176.             nodes[i][j] = new_node( RAD * cos( rl ) * cos( rv ), RAD * sin( rl ) * cos(rv), RAD * sin( rv ), 1, .999 );
  177.         }
  178.     }
  179.     printf( "Made Nodes\n" );
  180.     nodes[0][0] = new_node( 0, 0, RAD, 1000, .999 );
  181.     for( int i = 1; i < 2*R; i ++ ) nodes[0][i] = nodes[0][0];
  182.     nodes[R][0] = new_node( 0, 0, -RAD, 1, .999 );
  183.     printf( "Constraining\n" );
  184.     for( int i = 1; i < R; i ++ ){
  185.         printf(" %i\t", i );
  186.         for( int j = 0; j < 2*R; j ++ ){
  187.             printf(" %i\t", j );
  188.             constrain( nodes[i][j], nodes[i-1][j] );
  189.             constrain( nodes[i][j], nodes[i][(j+R)%(2*R)] );
  190.  
  191.             if( i != R-i) constrain( nodes[i][j], nodes[R-i][j] );
  192.  
  193.             constrain( nodes[i][j], nodes[i-1][(j+1)%(2*R)] );
  194.  
  195.             //constrain( nodes[i][j], nodes[i-1][(j+2*R-1)%(2*R)] );
  196.  
  197.             constrain( nodes[i][j], nodes[i][(j+1)%(2*R)] );
  198.         }
  199.     }
  200.     printf( "Constraining Bottom\n" );
  201.     for( int j = 0; j < 2*R; j ++ ){
  202.             constrain( nodes[R][0], nodes[R-1][j] );
  203.     }
  204.     constrain( nodes[R][0], nodes[0][0] );
  205.     printf( "Constrained\n" );
  206.     n1 = nodes[0][0];
  207.  
  208.  
  209.  
  210.  
  211. }
  212.  
  213. #include <deque>
  214.  
  215. void myIdleFunction()
  216. {
  217.     double mx = -(640 - mouse_x), my = -(480 - mouse_y);
  218.     double x2 = 640/2-mouse_x;
  219.     double y2 = -(480/2-mouse_y);
  220.     if( !mvd ){
  221.         n1->moveTo( x2/25, 0, y2/25 );
  222.         n1->__xp = n1->__x;
  223.         n1->__yp = n1->__y;
  224.         n1->__zp = n1->__z;}
  225.  
  226.         for( int i = 0; i < Nodes.size(); i ++ ){
  227.             Nodes[i]->move();
  228.         }
  229.  
  230.         /*std::deque<int> d;
  231.         for( int j = 0; j < 10; j ++ ){
  232.         for( int i = 0; i < Cons.size(); i ++ )
  233.             d.push_front( i );
  234.         while( d.size() > 0 )
  235.         {
  236.             int k = rand() % (d.size()*2);
  237.             while( k > 0 ){
  238.                 k--;
  239.                 d.push_back( d.front());
  240.                 d.pop_front();
  241.             }
  242.             Cons[d.front()]->satisfy();
  243.             d.pop_front();
  244.         }}*/
  245.  
  246.         for( int k = 0; k < 90; k ++ ){
  247.         for( int i = 0; i < Cons.size(); i ++ ){
  248.             Cons[i]->satisfy();
  249.         }
  250.         /*for( int i = Cons.size()-1; i >= 0; i -- ){
  251.             Cons[i]->satisfy();
  252.         }*/
  253.         }
  254.  
  255. }
  256.  
  257.  
  258.  
  259. void drawScene(void)
  260. {
  261.     myIdleFunction();
  262.     // Clear the rendering window
  263. glEnable(GL_LIGHT1);
  264.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  265.  
  266.     // Set drawing color to white
  267.     glColor3f( 1.0, 1.0, 1.0 );
  268.         glBegin( GL_LINES );
  269.         for( int i = 0; i < Cons.size(); i ++ ){
  270.             glVertex3d( Cons[i]->n1->__x, Cons[i]->n1->__y, Cons[i]->n1->__z );
  271.             glVertex3d( Cons[i]->n2->__x, Cons[i]->n2->__y, Cons[i]->n2->__z );
  272.         }
  273.  
  274.         glEnd();
  275.  
  276.     glFlush();
  277.     glutSwapBuffers();
  278.     Sleep( 20 );
  279.     glutPostRedisplay();
  280. }
  281.  
  282. void initRendering()
  283. {
  284.  
  285.     //glEnable ( GL_DEPTH_TEST );
  286.   /* Setup the view of the cube. */
  287.  
  288.     // Uncomment out the first block of code below, and then the second block,
  289.     //      to see how they affect line and point drawing.
  290.  
  291.     // The following commands should cause points and line to be drawn larger
  292.     //  than a single pixel width.
  293.     glPointSize(8);
  294.     glLineWidth(2);
  295.  
  296.  
  297.  
  298.     // The following commands should induce OpenGL to create round points and
  299.     //  antialias points and lines.  (This is implementation dependent unfortunately).
  300.     /*glEnable(GL_POINT_SMOOTH);
  301.     glEnable(GL_LINE_SMOOTH);
  302.     glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);    // Make round points, not square points
  303.     glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);     // Antialias the lines
  304.     glEnable(GL_BLEND);
  305.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);*/
  306.  
  307.  
  308. }
  309.  
  310.  
  311. void resizeWindow(int w, int h)
  312. {
  313.     double scale, center;
  314.     double windowXmin, windowXmax, windowYmin, windowYmax;
  315.  
  316.     // Define the portion of the window used for OpenGL rendering.
  317.     glViewport( 0, 0, w, h );   // View port uses whole window
  318.  
  319.     // Set up the projection view matrix: orthographic projection
  320.     // Determine the min and max values for x and y that should appear in the window.
  321.     // The complication is that the aspect ratio of the window may not match the
  322.     //      aspect ratio of the scene we want to view.
  323.     w = (w==0) ? 1 : w;
  324.     h = (h==0) ? 1 : h;
  325.     if ( (Xmax-Xmin)/w < (Ymax-Ymin)/h ) {
  326.         scale = ((Ymax-Ymin)/h)/((Xmax-Xmin)/w);
  327.         center = (Xmax+Xmin)/2;
  328.         windowXmin = center - (center-Xmin)*scale;
  329.         windowXmax = center + (Xmax-center)*scale;
  330.         windowYmin = Ymin;
  331.         windowYmax = Ymax;
  332.     }
  333.     else {
  334.         scale = ((Xmax-Xmin)/w)/((Ymax-Ymin)/h);
  335.         center = (Ymax+Ymin)/2;
  336.         windowYmin = center - (center-Ymin)*scale;
  337.         windowYmax = center + (Ymax-center)*scale;
  338.         windowXmin = Xmin;
  339.         windowXmax = Xmax;
  340.     }
  341.  
  342.     // Now that we know the max & min values for x & y that should be visible in the window,
  343.     //      we set up the orthographic projection.
  344.     glMatrixMode( GL_PROJECTION );
  345.     glLoadIdentity();
  346.     gluPerspective( 90, scale, 0, 1000 );
  347.     gluLookAt( 0, -10, 0, 0, 0, 0, 0, 0, -1 );
  348.  
  349.  
  350.     //glOrtho( windowXmin, windowXmax, windowYmin, windowYmax, -1, 1 );
  351.  
  352. }
  353.  
  354. GLfloat light1_diffuse[] =
  355. {300, 300, 300, 300};
  356. GLfloat light1_position[] =
  357. {1.0, 1.0, 1.0, 0.0};
  358.  
  359. int main( int argc, char** argv )
  360. {
  361.     init();
  362.     glutInit(&argc,argv);
  363.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
  364.  
  365.     // Window position (from top corner), and size (width and hieght)
  366.     glutInitWindowPosition( 20, 60 );
  367.     glutInitWindowSize( 640, 480 );
  368.     glutCreateWindow( "Verlet Draw" );
  369.  
  370.     // Initialize OpenGL as we like it..
  371.     initRendering();
  372.  
  373.       glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
  374.   glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
  375.  
  376.     // Set up callback functions for key presses
  377.     glutKeyboardFunc( myKeyboardFunc );         // Handles "normal" ascii symbols
  378.     // glutSpecialFunc( mySpecialKeyFunc );     // Handles "special" keyboard keys
  379.  
  380.     // Set up the callback function for resizing windows
  381.     glutReshapeFunc( resizeWindow );
  382.  
  383.     // Call this for background processing
  384.      //glutIdleFunc( myIdleFunction );
  385.  
  386.     // call this whenever window needs redrawing
  387.     glutDisplayFunc( drawScene );
  388.     //glutPassiveMotionFunc(getM);
  389.     glutMotionFunc( setM );
  390.  
  391.  
  392.     GLfloat fogcolour[4]={0.0,0.0,0.0,1.0};         /* BLACK fog */
  393.  
  394.   glFogfv(GL_FOG_COLOR,fogcolour);              /* Define the fog colour */
  395.   glFogf(GL_FOG_DENSITY,0.1);                   /* How dense */
  396.   glFogi(GL_FOG_MODE,GL_LINEAR);                   /* exponential decay */
  397.   glFogf(GL_FOG_START,0);                   /* Where wwe start fogging */
  398.   glFogf(GL_FOG_END,10.0);                       /* end */
  399.   //glHint(GL_FOG_HINT, GL_FASTEST);              /* compute per vertex */
  400.   glEnable(GL_FOG);                             /* ENABLE */
  401.  
  402.  
  403.     // Start the main loop.  glutMainLoop never returns.
  404.     glutMainLoop(  );
  405.  
  406.     return(0);  // This line is never reached.
  407. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement