2

I am writing a rather simple android game and I am implementing Open GL to draw a 3D cube that spins upon the X, Y and Z axis and I need to know where the user has clicked on the texture of the cube.

The texture is a simple square bitmap (100x100) that has a smaller square in the center. I need to know if the user touches the inner square. As well was tell which face of the cube the user touches. Does anyone know how this can be accomplished if not can anyone give some pseudo code on how to tell where the ray correlates to the texture? Or at least point me in the right direction.

The textures of each face are like this:

enter image description here

The whole cube looks like this: https://docs.google.com/file/d/0BzmLnD4ub-ohaU9CM21WWC1GRW8/edit?usp=sharing

The code I am using is from: http://www3.ntu.edu.sg/home/ehchua/programming/android/Android_3D.html2.9 It is a port to android from Lesson 6 NeHe. Example 6a: Photo-Cube

Clayton
  • 21
  • 3
  • Once you know which object was touched, you can iterate through its triangles doing a triangle/ray intersection test to see which face was touched. There's some code for that here. – House Jul 02 '13 at 18:20
  • It is only a rotating cube. But how could I tell if it hits the square in the center? – Clayton Jul 02 '13 at 18:31
  • 1
    To use @Byte56 example, subdivide the cube into smaller triangles. Then keep track of outside versus internal faces in a map to quickly determine from "which triangle face was touched" whether it was inside or outside the area you need. Alternately, add a smaller rectangle at each side of the cube where the red is; if it sticks out just a bit then it will get the intersection before the big cube behind, on each face. – Patrick Hughes Jul 02 '13 at 18:57

1 Answers1

3

If your hit test is really that simple, then instead of doing more complicated triangle intersection as Byte56 suggests you could do simple AABB-ray intersection test. The intersection test will tell you the point that was hit. This point in model space will lie on one of the faces (so one of X, Y, or Z will be +/-h, where h is the half-width of your cube). Assuming that the red square is one third the size of the cube itself, that means that the other two coordinates must both fall within [-h/3,+h/3] in order for the hit to have been the red area.

The triangle approach is also sensible, especially if you want to support more complicated shapes (you could represent any shape on a cube's face with a 2D function, but say you want to support tetrahedrons or something beside just cubes). Tessellate your shape's faces so that (for the cube example) a face is made up of more than a single quad. With one third being the desired hit area width of your cube you'd need 9 quads or 18 triangles for your face. You can then do a triangle-ray collision test. Check if the collided triangles are the ones making up the central quad of any particular face to register hits to the red area.

Sean Middleditch
  • 41,807
  • 4
  • 89
  • 132
  • Yes, the first suggestion is much more simple to do. Good answer Sean. – House Jul 02 '13 at 20:25
  • Can this work if the cube rotating along the x, y, and z axis simultaneously? – Clayton Jul 02 '13 at 21:21
  • To do the test against a rotated cube, you can simply rotate the ray by the inverse of the cubes rotation and test against the unrotated cube and you'll get the same answer as rotating the cube. – Adam Jul 02 '13 at 22:10
  • Indeed. Doing that means for specifically that you'd doing an AABB test instead of a general cube test which is way easier. Axis-aligned slab test in particular. See http://gamedev.stackexchange.com/questions/18436/most-efficient-aabb-vs-ray-collision-algorithms. – Sean Middleditch Jul 02 '13 at 22:29
  • That means Byte56's solution will have to be used or a similar version of Ray Picking. With ray picking I know how to figure out which face of the cube was touched along with the triangle. But what about the inner square? As well as what if the user touches the border between the two triangles? – Clayton Jul 02 '13 at 22:29
  • I explained that. You use ray casting to find out which point on a AABB is picked. Then you can use that point to find out what area on the face is clicked. I'm unsure how to explain it any clearer. – Sean Middleditch Jul 02 '13 at 22:44
  • You are explaining very well, I am quite new to this and I understand what you are explaining to do but just don't know how to get it working. The classes that Byte56 used are in Open GL; While android only supports Open GL ES. I understand that when the user touches my screen I will need to get the x,y coordinates and then from my current angle must create a ray to see what part of the axis is hit to register if the ray runs into my inner cube. – Clayton Jul 03 '13 at 01:08
  • Correct. There is a lot of existing documentation on this, on this very site. Just search for opengl ray casting, then look at the article I linked. Once you get those bits down you can then apply the technique I presented in this answer. – Sean Middleditch Jul 03 '13 at 01:14