Al's Programming Resource Homepage  Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

selection.cpp

Go to the documentation of this file.
00001 // Polygon selection functions by Alan Baylis 2003
00002 
00003 // SelectPolygon() creates a ray from the current camera coordinates to a point half a unit into the screen that is coincident
00004 // with the mouse coordinates passed in and checks for an intersection along the line of this ray with the array of 
00005 // polygons passed in.
00006 // If there is an intersection then the function returns the zero based index of the closest polygon intersected or -1
00007 // if there was no intersection.
00008 // The polygons passed in must have between 3 to 29 edges, be convex, non-degenerate and have their normals set. 
00009 // MouseX and MouseY are relative to the top-left corner of the window.
00010 
00011 #include "selection.h"
00012 #include "camera.h"
00013 #include "general.h"
00014 #include "collision.h"
00015 
00016 extern CAMERA* camera;
00017 extern int currentCamera;
00018 
00019 int SelectPolygon(HWND hWnd, POLYGON* Polygons, int numPolys, int MouseX, int MouseY)
00020 {
00021     POLYGON tempPolygon;
00022     VECTOR CollisionPoint, p0, pN, a, b, c;
00023     int tempPolygonNumber;  // Returned index
00024     VECTOR tempVect;
00025     float Distance;
00026     VERTEX tempVertex;
00027     VECTOR WorldPos;
00028     float ShortestDistance = 10000000;  // Set to an initial distance further than all polygons
00029     bool flag = false;  // Flag indicating intersection status
00030 
00031     // Temporary variables for polygon tessellation
00032     int numNewPolygons = 0;
00033     POLYGON newPolygon[30];
00034 
00035     // Get the modelview and projection matrices 
00036     double WorldPosX, WorldPosY, WorldPosZ, MousePosX, MousePosY, MousePosZ;
00037     double ModelMatrix[16]; 
00038     glGetDoublev(GL_MODELVIEW_MATRIX, ModelMatrix);
00039     double ProjMatrix[16];
00040     glGetDoublev(GL_PROJECTION_MATRIX, ProjMatrix);
00041 
00042     // Get the current viewport
00043     int Viewport[4];
00044     glGetIntegerv(GL_VIEWPORT, Viewport);
00045 
00046     if (MouseX >= Viewport[0] && MouseX <= Viewport[2] && MouseY >= Viewport[1] && MouseY <= Viewport[3])
00047     {
00048         // Set the end point of ray in windows coordinates
00049         MousePosX = MouseX;
00050         MousePosY = Viewport[3] - MouseY; // invert mouse Y coordinate
00051         MousePosZ = 0.5; // near clip plane depth
00052 
00053         // Get unprojected end point
00054         gluUnProject
00055         (
00056             MousePosX, 
00057             MousePosY, 
00058             MousePosZ, 
00059             ModelMatrix, 
00060             ProjMatrix,
00061             Viewport,
00062             &WorldPosX,
00063             &WorldPosY,
00064             &WorldPosZ
00065         );
00066         WorldPos.x = WorldPosX;
00067         WorldPos.y = WorldPosY;
00068         WorldPos.z = WorldPosZ;
00069 
00070         // Check for line polygon collision with all polygons
00071         for (int outerloop = 0; outerloop < numPolys; outerloop++)
00072         {
00073             // Make a copy of the polygon to work with
00074             tempPolygon.Vertex[0] = Polygons[outerloop].Vertex[0];
00075             tempPolygon.Vertex[1] = Polygons[outerloop].Vertex[1];
00076             tempPolygon.Vertex[2] = Polygons[outerloop].Vertex[2];
00077             tempPolygon.numVertices = Polygons[outerloop].numVertices;
00078             // Get a point on the polygon
00079             p0 = tempPolygon.Vertex[0].coords;
00080             // Get the polygons normal
00081             pN = tempPolygon.Vertex[0].normal;
00082             // Find collision point on the plane
00083             CollisionPoint = line_plane_collision(&camera[currentCamera].Position, &WorldPos, &tempPolygon);
00084             // If the collision point is outside the frustum (indicating a collision behind the camera) then continue
00085             if (!CheckClipPlanes(camera[currentCamera], CollisionPoint)) // Function is in the general.cpp source file
00086                    continue;
00087 
00088             // Subdivide polygon into new polygons
00089             numNewPolygons = 0;
00090             for (int innerloop = 2; innerloop < tempPolygon.numVertices; innerloop++)
00091             {
00092                 numNewPolygons++;
00093                 newPolygon[innerloop - 2].Vertex[0] = tempPolygon.Vertex[0];
00094                 newPolygon[innerloop - 2].Vertex[1] = tempPolygon.Vertex[innerloop - 1];
00095                 newPolygon[innerloop - 2].Vertex[2] = tempPolygon.Vertex[innerloop];
00096             }
00097 
00098             // If collision point is within the polygon
00099             for (int innerloop = 0; innerloop < numNewPolygons; innerloop++)
00100             {                
00101                 a = newPolygon[innerloop].Vertex[0].coords;
00102                 b = newPolygon[innerloop].Vertex[1].coords;
00103                 c = newPolygon[innerloop].Vertex[2].coords;
00104                 if (CheckPointInTriangle(CollisionPoint, a, b, c)) // Function is in the collision.cpp source file
00105                 {
00106                     // Find distance to the collision point
00107                     tempVect = CollisionPoint - camera[currentCamera].Position;
00108                     Distance = tempVect.GetMagnitude();
00109                     // If this intersection is closest
00110                     if (Distance < ShortestDistance)
00111                     {
00112                         tempPolygonNumber = outerloop;
00113                         ShortestDistance = Distance;
00114                         flag = true;    
00115                     }
00116                 }
00117             }                    
00118         }
00119         if (flag)
00120             return tempPolygonNumber;
00121         else
00122             return -1;
00123     }
00124 }
00125 

Generated on Fri Dec 23 05:20:59 2005 for Polygon Selection by doxygen1.2.15