Guest User

Raycast

a guest
Mar 17th, 2014
458
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.07 KB | None | 0 0
  1. //Location is a struct defined as "double x, y, z;"
  2. Location rayLoc = campos.location, mapLoc, rayDir, glNear, glFar, raySideDist, rayDeltaDist, rayStepDist;
  3.  
  4. //Have we hit a voxel, or is the ray too long?
  5. bool hasCollided = false, tooLong = false;
  6. //How many steps we've taken and how many we should take
  7. int rayIterations = 0, maxIterations = 32;
  8. //What side we hit
  9. int side = 0;
  10. //OpenGL pointers for direction calculation
  11. GLdouble modelview[16], projection[16];
  12. GLint viewport[4];
  13.  
  14. //mapLoc should be all integers, representing a voxel in the world
  15. mapLoc.x = roundf(rayLoc.x);
  16. mapLoc.y = roundf(rayLoc.y);
  17. mapLoc.z = roundf(rayLoc.z);
  18.  
  19. std::cout << "Raypos is [" << rayLoc.x << " " << rayLoc.y << " " << rayLoc.z << "]";
  20. std::cout << ", but rounding to [" << mapLoc.x << " " << mapLoc.y << " " << mapLoc.z << "]\n";
  21.  
  22. //Get pointers for the matrices and unproject to get our direction
  23. glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
  24. glGetDoublev(GL_PROJECTION_MATRIX, projection);
  25. glGetIntegerv(GL_VIEWPORT, viewport);
  26.  
  27. gluUnProject(400, 300, 0, modelview, projection, viewport, &glNear.x, &glNear.y, &glNear.z);
  28. gluUnProject(400, 300, 1, modelview, projection, viewport, &glFar.x, &glFar.y, &glFar.z);
  29.  
  30. rayDir.x = glFar.x - glNear.x;
  31. rayDir.y = glFar.y - glNear.y;
  32. rayDir.z = glFar.z - glNear.z;
  33.  
  34. std::cout << "Orientation: [" << campos.orientation.x << " " << campos.orientation.y << " " << campos.orientation.z << "]\n";
  35. std::cout << "Calculated vectors: [" << rayDir.x << " " << rayDir.y << " " << rayDir.z << "]\n";
  36.  
  37. //Calculations for step distance, distance to next axis side, and distance to next voxel side
  38. if(rayDir.x == 0)
  39. {
  40.     rayStepDist.x = 0;
  41.     rayDeltaDist.x = rayDir.x;
  42.     raySideDist.x = (rayLoc.x - mapLoc.x) * rayDeltaDist.x;
  43. }
  44. else if(rayDir.x < 0)
  45. {
  46.     rayStepDist.x = -1;
  47.     rayDeltaDist.x = rayStepDist.x / rayDir.x;
  48.     raySideDist.x = (rayLoc.x - mapLoc.x) * rayDeltaDist.x;
  49. }
  50. else
  51. {
  52.     rayStepDist.x = 1;
  53.     rayDeltaDist.x = rayStepDist.x / rayDir.x;
  54.     raySideDist.x = ((mapLoc.x + 1) - rayLoc.x) * rayDeltaDist.x;
  55. }    
  56.  
  57. if(rayDir.z == 0)
  58. {
  59.     rayStepDist.z = 0;
  60.     rayDeltaDist.z = rayDir.z;
  61.     raySideDist.z = (rayLoc.z - mapLoc.z) * rayDeltaDist.z;
  62. }
  63. else if(rayDir.z < 0)
  64. {
  65.     rayStepDist.z = -1;
  66.     rayDeltaDist.z = rayStepDist.z / rayDir.z;
  67.     raySideDist.z = (rayLoc.z - mapLoc.z) * rayDeltaDist.z;
  68. }
  69. else
  70. {
  71.     rayStepDist.z = 1;
  72.     rayDeltaDist.z = rayStepDist.z / rayDir.z;
  73.     raySideDist.z = ((mapLoc.z + 1) - rayLoc.z) * rayDeltaDist.z;
  74. }
  75.  
  76. if(rayDir.y == 0)
  77. {
  78.     rayStepDist.y = 0;
  79.     rayDeltaDist.y = rayDir.y;
  80.     raySideDist.y = (rayLoc.y - mapLoc.y) * rayDeltaDist.y;
  81. }
  82. else if(rayDir.y < 0)
  83. {
  84.     rayStepDist.y = -1;
  85.     rayDeltaDist.y = rayStepDist.y / rayDir.y;
  86.     raySideDist.y = (rayLoc.y - mapLoc.y) * rayDeltaDist.y;
  87. }
  88. else
  89. {
  90.     rayStepDist.y = 1;
  91.     rayDeltaDist.y = rayStepDist.y / rayDir.y;
  92.     raySideDist.y = ((mapLoc.y + 1) - rayLoc.y) * rayDeltaDist.y;
  93. }
  94.  
  95. //Raycasing loop
  96. while(hasCollided == false && tooLong == false)
  97. {
  98.     std::cout << "Raycast - [" << mapLoc.x << " " << mapLoc.y << " " << mapLoc.z << "]\n";
  99.    
  100.     //side: x = 0, y = 2, z = 1
  101.     if(raySideDist.x < raySideDist.z)
  102.     {
  103.         if(raySideDist.x < raySideDist.y)
  104.         {
  105.             raySideDist.x += rayDeltaDist.x;
  106.             mapLoc.x += rayStepDist.x;
  107.             side = 0;
  108.         }
  109.         else
  110.         {
  111.             raySideDist.y += rayDeltaDist.y;
  112.             mapLoc.y += rayStepDist.y;
  113.             side = 2;
  114.         }
  115.     }
  116.     else
  117.     {
  118.         if(raySideDist.z < raySideDist.y)
  119.         {
  120.             raySideDist.z += rayDeltaDist.z;
  121.             mapLoc.z += rayStepDist.z;
  122.             side = 1;
  123.         }
  124.         else
  125.         {
  126.             raySideDist.y += rayDeltaDist.y;
  127.             mapLoc.y += rayStepDist.y;
  128.             side = 2;
  129.         }
  130.     }
  131.      
  132.     //If we hit something, exit
  133.     if(world->checkVoxel(mapLoc) == 1)
  134.     {
  135.         hasCollided = true;
  136.        
  137.     }
  138.    
  139.     //If the ray's too long, exit
  140.     if(rayIterations > maxIterations)
  141.     {
  142.         tooLong = true;
  143.     }
  144.    
  145.     //We took a step, so increment the counter
  146.     rayIterations++;
  147. }
  148.  
  149. //If we actually hit a voxel, place or destroy
  150. if(hasCollided == true)
  151. {
  152.     //Left mouse button - destroy the selected voxel, right mouse button - place a new voxel
  153.     if(event.button.button == SDL_BUTTON_LEFT)
  154.     {
  155.         std::cout << "Destroyer!\n";
  156.        
  157.         world->deleteVoxel(mapLoc);
  158.     }
  159.     else if(event.button.button == SDL_BUTTON_RIGHT)
  160.     {
  161.         std::cout << "Placer!\n";
  162.        
  163.         Voxel newvox;
  164.        
  165.         //Subtract a step based on the last hit side
  166.         if(side == 0)
  167.             mapLoc.x -= rayStepDist.x;
  168.         if(side == 1)
  169.             mapLoc.z -= rayStepDist.z;
  170.         if(side == 2)
  171.             mapLoc.y -= rayStepDist.y;
  172.              
  173.         newvox.color.r = 1;
  174.         newvox.color.g = 1;
  175.         newvox.color.b = 0;
  176.        
  177.         //Insert the new voxel
  178.         world->insertVoxel(mapLoc, newvox);
  179.     }
  180. }
Advertisement
Add Comment
Please, Sign In to add comment