Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Location is a struct defined as "double x, y, z;"
- Location rayLoc = campos.location, mapLoc, rayDir, glNear, glFar, raySideDist, rayDeltaDist, rayStepDist;
- //Have we hit a voxel, or is the ray too long?
- bool hasCollided = false, tooLong = false;
- //How many steps we've taken and how many we should take
- int rayIterations = 0, maxIterations = 32;
- //What side we hit
- int side = 0;
- //OpenGL pointers for direction calculation
- GLdouble modelview[16], projection[16];
- GLint viewport[4];
- //mapLoc should be all integers, representing a voxel in the world
- mapLoc.x = roundf(rayLoc.x);
- mapLoc.y = roundf(rayLoc.y);
- mapLoc.z = roundf(rayLoc.z);
- std::cout << "Raypos is [" << rayLoc.x << " " << rayLoc.y << " " << rayLoc.z << "]";
- std::cout << ", but rounding to [" << mapLoc.x << " " << mapLoc.y << " " << mapLoc.z << "]\n";
- //Get pointers for the matrices and unproject to get our direction
- glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
- glGetDoublev(GL_PROJECTION_MATRIX, projection);
- glGetIntegerv(GL_VIEWPORT, viewport);
- gluUnProject(400, 300, 0, modelview, projection, viewport, &glNear.x, &glNear.y, &glNear.z);
- gluUnProject(400, 300, 1, modelview, projection, viewport, &glFar.x, &glFar.y, &glFar.z);
- rayDir.x = glFar.x - glNear.x;
- rayDir.y = glFar.y - glNear.y;
- rayDir.z = glFar.z - glNear.z;
- std::cout << "Orientation: [" << campos.orientation.x << " " << campos.orientation.y << " " << campos.orientation.z << "]\n";
- std::cout << "Calculated vectors: [" << rayDir.x << " " << rayDir.y << " " << rayDir.z << "]\n";
- //Calculations for step distance, distance to next axis side, and distance to next voxel side
- if(rayDir.x == 0)
- {
- rayStepDist.x = 0;
- rayDeltaDist.x = rayDir.x;
- raySideDist.x = (rayLoc.x - mapLoc.x) * rayDeltaDist.x;
- }
- else if(rayDir.x < 0)
- {
- rayStepDist.x = -1;
- rayDeltaDist.x = rayStepDist.x / rayDir.x;
- raySideDist.x = (rayLoc.x - mapLoc.x) * rayDeltaDist.x;
- }
- else
- {
- rayStepDist.x = 1;
- rayDeltaDist.x = rayStepDist.x / rayDir.x;
- raySideDist.x = ((mapLoc.x + 1) - rayLoc.x) * rayDeltaDist.x;
- }
- if(rayDir.z == 0)
- {
- rayStepDist.z = 0;
- rayDeltaDist.z = rayDir.z;
- raySideDist.z = (rayLoc.z - mapLoc.z) * rayDeltaDist.z;
- }
- else if(rayDir.z < 0)
- {
- rayStepDist.z = -1;
- rayDeltaDist.z = rayStepDist.z / rayDir.z;
- raySideDist.z = (rayLoc.z - mapLoc.z) * rayDeltaDist.z;
- }
- else
- {
- rayStepDist.z = 1;
- rayDeltaDist.z = rayStepDist.z / rayDir.z;
- raySideDist.z = ((mapLoc.z + 1) - rayLoc.z) * rayDeltaDist.z;
- }
- if(rayDir.y == 0)
- {
- rayStepDist.y = 0;
- rayDeltaDist.y = rayDir.y;
- raySideDist.y = (rayLoc.y - mapLoc.y) * rayDeltaDist.y;
- }
- else if(rayDir.y < 0)
- {
- rayStepDist.y = -1;
- rayDeltaDist.y = rayStepDist.y / rayDir.y;
- raySideDist.y = (rayLoc.y - mapLoc.y) * rayDeltaDist.y;
- }
- else
- {
- rayStepDist.y = 1;
- rayDeltaDist.y = rayStepDist.y / rayDir.y;
- raySideDist.y = ((mapLoc.y + 1) - rayLoc.y) * rayDeltaDist.y;
- }
- //Raycasing loop
- while(hasCollided == false && tooLong == false)
- {
- std::cout << "Raycast - [" << mapLoc.x << " " << mapLoc.y << " " << mapLoc.z << "]\n";
- //side: x = 0, y = 2, z = 1
- if(raySideDist.x < raySideDist.z)
- {
- if(raySideDist.x < raySideDist.y)
- {
- raySideDist.x += rayDeltaDist.x;
- mapLoc.x += rayStepDist.x;
- side = 0;
- }
- else
- {
- raySideDist.y += rayDeltaDist.y;
- mapLoc.y += rayStepDist.y;
- side = 2;
- }
- }
- else
- {
- if(raySideDist.z < raySideDist.y)
- {
- raySideDist.z += rayDeltaDist.z;
- mapLoc.z += rayStepDist.z;
- side = 1;
- }
- else
- {
- raySideDist.y += rayDeltaDist.y;
- mapLoc.y += rayStepDist.y;
- side = 2;
- }
- }
- //If we hit something, exit
- if(world->checkVoxel(mapLoc) == 1)
- {
- hasCollided = true;
- }
- //If the ray's too long, exit
- if(rayIterations > maxIterations)
- {
- tooLong = true;
- }
- //We took a step, so increment the counter
- rayIterations++;
- }
- //If we actually hit a voxel, place or destroy
- if(hasCollided == true)
- {
- //Left mouse button - destroy the selected voxel, right mouse button - place a new voxel
- if(event.button.button == SDL_BUTTON_LEFT)
- {
- std::cout << "Destroyer!\n";
- world->deleteVoxel(mapLoc);
- }
- else if(event.button.button == SDL_BUTTON_RIGHT)
- {
- std::cout << "Placer!\n";
- Voxel newvox;
- //Subtract a step based on the last hit side
- if(side == 0)
- mapLoc.x -= rayStepDist.x;
- if(side == 1)
- mapLoc.z -= rayStepDist.z;
- if(side == 2)
- mapLoc.y -= rayStepDist.y;
- newvox.color.r = 1;
- newvox.color.g = 1;
- newvox.color.b = 0;
- //Insert the new voxel
- world->insertVoxel(mapLoc, newvox);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment