This site requires JavaScript, please enable it in your browser!
Greenfoot back
wabuilderman
wabuilderman wrote ...

2014/12/5

raycasting headache

wabuilderman wabuilderman

2014/12/5

#
Ok, so I have still been fiddling with a project for several months... I am just trying to have a cube. Despite my valiant (but still noobish) efforts, I have gotten no closer to my goal. I am familiar with the notion that ray casting involves calculating the distance in 3-dimensional shape to a point upon a 3-dimensional surface, but how would I do that? Since I don't neccissarily want to paste in a novel, here is what I am doing in short: I have a camera, that has location, and rotation (rotation changed in-game) I have an "Object3d" class for my 3-dimensional Actors, that gives all objects their faces, vertices, and other important data I have a ArrayListTools class that is being used to take an array of faces and attempts to sort them by their closeness to the camera. So far, the best thing I have that works (though it still doesn't really work) is this:
public boolean RaycastCompare(Face face1, Face face2, Vertice Orign)
   {
       float distanceToFace1 = Math.abs(face1.getAverageX()) + Math.abs(face1.getAverageY()) + Math.abs(face1.getAverageZ());
       float distanceToFace2 = Math.abs(face2.getAverageX()) + Math.abs(face2.getAverageY()) + Math.abs(face2.getAverageZ());
       float totalCam = Math.abs(Orign.getX()) + Math.abs(Orign.getY()) + Math.abs(Orign.getZ());
       distanceToFace1 -= totalCam;
       distanceToFace2 -= totalCam;
       if(distanceToFace1 <= distanceToFace2)
       {
           return true;
       }
       return false;
   }
using this, it would determine if one face in a list is closer than another. It would then go about rearranging them using this method.
public ArrayList SortByRaycast(ArrayList<Face> array,world3d world)
   {
      //RaycastCompare(face1, face2, Cam.position) //if face1 is closer than face2, return true
      Camera Cam = world.getCam();
      int i = 0;
      while(i < array.size())
      {
          boolean shouldRepeat = true;
          while(shouldRepeat)
          {
              if(i<array.size()-1)
              {
                  if(!(RaycastCompare(array.get(i),array.get(i+1), Cam.getPosition())))
                  {
                      Face tempFace1 = array.get(i);
                      Face tempFace2 = array.get(i + 1);
                      array.set(i,tempFace2);
                      array.set(i+1,tempFace1);
                  }
                  
                  else
                  {
                      shouldRepeat = false;
                  }
              }
              else
              {
                  shouldRepeat = false;
              }
          }
          i++;
      }
      return array;
   }
In general, I just need to know what I am doing wrong, and if there is a better way entirely to go about rendering the scene. Currently, the order of these simply determines the order in which they are painted. Is there a way I could do the good kind of raycast, that doesn't render what isn't seen?
davmac davmac

2014/12/5

#
So far, the best thing I have that works (though it still doesn't really work) is this: (...) using this, it would determine if one face in a list is closer than another. It would then go about rearranging them using this method.
I think you have one or two conceptual misunderstandings. First, it is not possible to sort a set of faces by "distance to a point" in a way that is useful for rendering (whether it be by raycasting or not); for one thing, you render many points (whatever the dimensions of your screen or viewport are), not just the one, and faces that are closer to one point might be further from another. You would have to sort the faces again for every pixel that you render. Furthermore you cannot use the average X, Y, Z of a face for anything meaningful. One face might on average be closer to the camera that another face, but still be behind that face. Then, your distance calculation in method 'RaycastCompare' is completely wrong. You need to look up the Pythagorean theorem (it is often used for 2 dimenionsal problems but can easily be extended into the 3rd dimension). Finally, your Java style is bad. Method names should begin with lower-case letters - 'SortByRaycast' should be 'sortByRaycast' and 'RaycastCompare' should be 'raycastCompare'. Now, in general, the kind of thing you are trying to do would be accomplished by first building a binary space partition tree aka BSP tree. To render a pixel in your viewport you project a line away from the camera (remember the camera position is in front of the screen, ideally where your head is!) which intersects the pixel that you want to render. You navigate the BSP tree while following this line until you find a face. If your BSP scheme means that you need to distinguish which is the closest of multiple faces, you need to calculate the point of intersection between the projection line and the two faces and then compare the distance between those two points and the camera (remembering that you calculate the distance using Pythagoras).
You need to login to post a reply.