home *** CD-ROM | disk | FTP | other *** search
/ Quark 3 / Quark3.iso / KATALOG / ARCHIV / TOOL / T001.ZIP / SOURCE.ZIP / drag.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-03  |  8.5 KB  |  316 lines

  1. /*
  2. Copyright (C) Matthew 'pagan' Baranowski & Sander 'FireStorm' van Rossen
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17. */
  18.  
  19. #include "system.h"
  20. #include "ndictionary.h"
  21. #include "md3gl.h"
  22. #include "md3view.h"
  23.  
  24. int m_x, m_y;
  25.  
  26. /*! commands to handle mouse dragging, uses key_flags defines above */
  27. void start_drag( mkey_enum keyFlags, int x, int y )
  28. {
  29.     m_x = x;
  30.     m_y = y;
  31. }
  32.  
  33. void drag(  mkey_enum keyFlags, int x, int y )
  34. {
  35.     if ( keyFlags != 0 )
  36.     {
  37.         if ( keyFlags == KEY_LBUTTON )
  38.         {                
  39.             if ((x != m_x) || (y != m_y))
  40.             {
  41.                 mdview.rotAngleY += (float)(x - m_x) * MOUSE_ROT_SCALE;
  42.                 mdview.rotAngleX += (float)(y - m_y) * MOUSE_ROT_SCALE;
  43.                 if (mdview.rotAngleY> 360.0f) mdview.rotAngleY=mdview.rotAngleY-360.0f;
  44.                 if (mdview.rotAngleY<-360.0f) mdview.rotAngleY=mdview.rotAngleY+360.0f;
  45.                 if (mdview.rotAngleX> 360.0f) mdview.rotAngleX=mdview.rotAngleX-360.0f;
  46.                 if (mdview.rotAngleX<-360.0f) mdview.rotAngleX=mdview.rotAngleX+360.0f;
  47.                 repaint_main();
  48.                 set_cursor( m_x, m_y );  
  49.             }
  50.         } else
  51.         if ( keyFlags == KEY_RBUTTON ) 
  52.         {
  53.             if ( y != m_y )
  54.             {
  55.                 mdview.zPos += ((float)(y - m_y)/10.f) * MOUSE_ZPOS_SCALE;
  56.                 if (mdview.zPos<-1000.f) mdview.zPos=-1000.f;
  57.                 if (mdview.zPos> 1000.f) mdview.zPos= 1000.f;
  58.                 InvalidateRect( mdview.hwnd, NULL, FALSE );
  59.                 set_cursor( m_x , m_y );  
  60.             }
  61.         }
  62.     }
  63. }
  64.  
  65. void end_drag(  mkey_enum keyFlags, int x, int y )
  66. {
  67. }
  68.  
  69.  
  70. /*
  71. =======
  72. rotates an object by placing a trackball sphere around it
  73. =======
  74. */
  75. /*
  76. int ModelControl::TrackballRotate(SNodePrimitive *shape, int sx, int sy, int ex, int ey)
  77. {
  78.   if (!m_shape) return 0;
  79.   
  80.   // simple quick method to avoid NAN results
  81.   if ((abs(sx - ex) < 2) && (abs(sy - ey) < 2)) {
  82.     return 0;
  83.   }
  84.  
  85.   IAVector scale( TRACKBALL_SCALE, TRACKBALL_SCALE, TRACKBALL_SCALE);  
  86.   IAMatrix tbMatrix = scale_mat(scale) * shape->m_inv_CTM;
  87.   IAPoint isecPnt2, isecPnt1, center, origin;
  88.   IAVector vec1, vec2, crossVec;
  89.   Idouble dotA, angle;
  90.  
  91.   if (!m_tracer->ISectRayWithSphere( tbMatrix, &isecPnt1, sx, sy, 
  92.                      m_scene->width(), m_scene->height() )) { 
  93.     return 0;
  94.   }
  95.  
  96.   if (!m_tracer->ISectRayWithSphere( tbMatrix, &isecPnt2, ex, ey, 
  97.                      m_scene->width(), m_scene->height() )) {    
  98.     return 0;
  99.   }
  100.   
  101.   center = shape->m_CTM * center;
  102.   vec1 = isecPnt1 - center;
  103.   vec2 = isecPnt2 - center; 
  104.   vec1.normalize();
  105.   vec2.normalize();
  106.  
  107.   crossVec = cross( vec1, vec2 );
  108.   dotA = dot( vec1, vec2 );
  109.   angle = -atan2( 1, dotA );
  110.   
  111.   shape->m_CTM_rotate = rot_mat(origin, crossVec, angle) * shape->m_CTM_rotate;
  112.   shape->updateCTM();
  113.   
  114.   return 1;
  115. }
  116.  
  117. SNodePrimitive *ISectTracer::ShootRay( int x, int y, int width, int height,
  118.                        Intersection *isec, Ray *ray )
  119. {
  120.   NodePosition pos;
  121.   Ray filmRay, worldRay, objectRay;
  122.   IAMatrix filmToWorld = m_scene->camera()->filmToWorld();    
  123.   Intersection iStack[MAX_INTERSECT_PER_RAY], *iStackP, *iStackP2, *bestISec;
  124.   int numIntersect, isectTotal;
  125.   NodeSequenceInfo *gData = m_scene->m_geometryList;
  126.   Idouble tbest;
  127.   SNodePrimitive *primData;
  128.   Shape *rayShape;
  129.   
  130.  
  131.       filmRay.d[X] = ((double)(2*x)/(double)width) - 1;
  132.       filmRay.d[Y] = 1-((double)(2*y)/(double)height);     
  133.       
  134.       filmRay.d[Z] = -1; filmRay.d[W] = 1;
  135.       filmRay.P = IAPoint();
  136.       
  137.       worldRay.d = filmToWorld * filmRay.d;
  138.       worldRay.P = filmToWorld * filmRay.P;
  139.       normalize( worldRay.d );
  140.  
  141.       iStackP = iStack;   
  142.       isectTotal = 0;
  143.       bestISec = NULL;
  144.       
  145.       // calculate intersections for all shapes
  146.       for (pos = gData->first(); pos != NULL; pos = gData->after(pos) ) {
  147.     primData = (SNodePrimitive *)pos->element();                           // get entry from geometry list
  148.     rayShape = primData->m_shape;
  149.  
  150.     objectRay.d = primData->m_inv_CTM * worldRay.d;                      // transform ray to object space
  151.         objectRay.P = primData->m_inv_CTM * worldRay.P;    
  152.  
  153.     if (!rayShape->IntersectTest( &objectRay )) {
  154.       if (filmRay.d[X] != 0) continue;
  155.     }
  156.  
  157.           numIntersect = rayShape->Intersect( &objectRay, iStackP, primData ); // calculate intersection       
  158.  
  159.     iStackP += numIntersect;
  160.     isectTotal += numIntersect;
  161.       }
  162.  
  163.  
  164.       // find best t for the pixel
  165.       if (iStackP > iStack) {     
  166.     tbest = MAX_FLOAT;
  167.     for (int i = 0; i < isectTotal; i++) {
  168.       if (iStack[i].m_t < tbest) {
  169.         tbest = iStack[i].m_t;
  170.         bestISec = &iStack[i];
  171.       }
  172.     }
  173.       }
  174.        
  175.       if (bestISec) {     
  176.     // copy the relevant data
  177.     if (ray) {
  178.       ray->P = worldRay.P;
  179.       ray->d = worldRay.d;
  180.     }
  181.     if (isec) bestISec->copy( isec );
  182.           return bestISec->m_shape;
  183.       }
  184.       else {        
  185.         return NULL;
  186.       }
  187. }
  188.  
  189. int ISectTracer::ISectRayWithSphere( IAMatrix &object, IAPoint *isec,
  190.                      int x, int y, int width, int height)
  191. {
  192.   Ray filmRay, worldRay, objectRay;
  193.   IAMatrix filmToWorld = m_scene->camera()->filmToWorld();    
  194.   
  195.   filmRay.d[X] = ((double)(2*x)/(double)width) - 1;
  196.   filmRay.d[Y] = 1-((double)(2*y)/(double)height); 
  197.   filmRay.d[Z] = -1; filmRay.d[W] = 1;
  198.   filmRay.P = IAPoint();  
  199.  
  200.   worldRay.d = filmToWorld * filmRay.d;
  201.   worldRay.P = filmToWorld * filmRay.P;
  202.   normalize( worldRay.d );
  203.  
  204.   objectRay.d = object * worldRay.d;
  205.   objectRay.P = object * worldRay.P;
  206.  
  207.   IAVector d = objectRay.d;
  208.   IAPoint P =  objectRay.P;
  209.  
  210.   double a = d[Z]*d[Z] + d[X]*d[X] + d[Y]*d[Y]; 
  211.   double b = 2*(P[X]*d[X] + P[Z]*d[Z] + P[Y]*d[Y]);
  212.   double c = P[X]*P[X] + P[Y]*P[Y] + P[Z]*P[Z] - 0.25;
  213.   double t, det = b*b-4*a*c;
  214.  
  215.   if (det > 0) { 
  216.     t = (-b+det)/a;
  217.     *isec = worldRay.P + worldRay.d * t;
  218.     return 1;
  219.   }
  220.   else return 0;
  221. }
  222.  
  223. int CubeShape::Intersect( Ray *ray, Intersection *iStack, SNodePrimitive *data )
  224. {
  225.   double t, det, u, v;
  226.   IAVector d = ray->d;
  227.   IAPoint P = ray->P;
  228.   Intersection *iStackP = iStack;
  229.  
  230.   // test intersection with z up face
  231.   if (d[Z] != 0) { 
  232.     t = -((P[Z]+0.5) / d[Z]);
  233.     u = P[X] + d[X]*t;
  234.     v = P[Y] + d[Y]*t;
  235.  
  236.     if ((u > -0.5) && (u < 0.5) && (v > -0.5) && (v < 0.5)) {
  237.        iStackP->m_t = t;
  238.        iStackP->m_shape = data;
  239.        iStackP->m_faceID = FACE_ZPOS;
  240.        iStackP++;
  241.     }
  242.   }
  243.  
  244.   // test intersection with z down face
  245.   if (d[Z] != 0) { 
  246.     t = -((-P[Z]+0.5) / -d[Z]);
  247.     u = P[X] + d[X]*t;
  248.     v = P[Y] + d[Y]*t;
  249.  
  250.     if ((u > -0.5) && (u < 0.5) && (v > -0.5) && (v < 0.5)) {
  251.        iStackP->m_t = t;
  252.        iStackP->m_shape = data;
  253.        iStackP->m_faceID = FACE_ZNEG;
  254.        iStackP++;
  255.     }
  256.   }
  257.  
  258.     // test intersection with y up face
  259.   if (d[Y] != 0) { 
  260.     t = -((P[Y]+0.5) / d[Y]);
  261.     u = P[X] + d[X]*t;
  262.     v = P[Z] + d[Z]*t;
  263.  
  264.     if ((u > -0.5) && (u < 0.5) && (v > -0.5) && (v < 0.5)) {
  265.        iStackP->m_t = t;
  266.        iStackP->m_shape = data;
  267.        iStackP->m_faceID = FACE_YPOS;
  268.        iStackP++;
  269.     }
  270.   }
  271.  
  272.   // test intersection with y down face
  273.   if (d[Y] != 0) { 
  274.     t = -((-P[Y]+0.5) / -d[Y]);
  275.     u = P[X] + d[X]*t;
  276.     v = P[Z] + d[Z]*t;
  277.  
  278.     if ((u > -0.5) && (u < 0.5) && (v > -0.5) && (v < 0.5)) {
  279.        iStackP->m_t = t;
  280.        iStackP->m_faceID = FACE_YNEG;
  281.        iStackP->m_shape = data;
  282.        iStackP++;
  283.     }
  284.   }
  285.  
  286.     // test intersection with x up face
  287.   if (d[X] != 0) { 
  288.     t = -((P[X]+0.5) / d[X]);
  289.     u = P[Z] + d[Z]*t;
  290.     v = P[Y] + d[Y]*t;
  291.  
  292.     if ((u > -0.5) && (u < 0.5) && (v > -0.5) && (v < 0.5)) {
  293.        iStackP->m_t = t;
  294.        iStackP->m_faceID = FACE_XPOS;
  295.        iStackP->m_shape = data;
  296.        iStackP++;
  297.     }
  298.   }
  299.  
  300.   // test intersection with x down face
  301.   if (d[X] != 0) { 
  302.     t = -((-P[X]+0.5) / -d[X]);
  303.     u = P[Z] + d[Z]*t;
  304.     v = P[Y] + d[Y]*t;
  305.  
  306.     if ((u > -0.5) && (u < 0.5) && (v > -0.5) && (v < 0.5)) {
  307.        iStackP->m_t = t;
  308.        iStackP->m_shape = data;
  309.        iStackP->m_faceID = FACE_XNEG;
  310.        iStackP++;
  311.     }
  312.   }
  313.     
  314.   return (int)(iStackP-iStack);  
  315. }
  316. */