3

So I started creating an app to learn openGL es on adroid. First I went through a chapter that explained how to construct a cube and get it to rotate using the system timer. I then mapped each side to a different segment of one image. For development purposes each side is textured with a number. I then implemented the drag feature to allow the user to rotate the cube up/down or left/right depending how they swiped.

First here is some background on my problem:

I want to keep track of which side is facing the camera because each face is being rotated on the axis it started on. For example given a cube that has the unfolded layout as follows.

  2
  4
3 1 5
  6

Where 1 is the side facing the screen, 2 is the opposite (or back face), 4 is up, 5 is right, 6 is down, and 3 is left.This means 3/5 are on the x-axis, 4/6 on the y-axis, and 1/2 on the z axis.

Here is my issue:

The cube rotates correctly if I only rotate around 1 axis (i.e. I only go left/righ or up/down until I go 360) but if I only go to 90 180 or 270 then the axis I should be rotating around have switched. This happens because of what is stated above about each side of the cube being stuck to the axis it started on.

If you rotate right once so 5 is facing, then the z axis from the users perspective is the x-axis of the cube. This gets even more convoluted when you start going 90 degrees left/right then 90 degrees up/down, etc.

I tried to keep track of the faces with an array of numbers listed clockwise from the top number, but depending which number you came from the new directions for the surrounding numbers have changed.

For Example:

I mapped out the numbers surrounding each number as it faces the screen if it was rotated to from 1 so

  4         2         4         1         4           
3 1 5     3 4 5     1 5 2     3 6 5     2 3 1     
  6         1         6         2         6      

and 2 is a wild card because it can be gotten to from any direction so there is no real initial number layout from 1

  6  
3 2 5
  4  

So my arrays would be

sidesOfFace1[] = {4,5,6,3}
sidesOfFace2[] = {6,5,4,3}
sidesOfFace3[] = {4,1,6,2}
sidesOfFace4[] = {2,5,1,3}
sidesOfFace5[] = {4,2,6,1}
sidesOfFace6[] = {1,5,2,3}

And MOVE can have the values

UP = 1  RIGHT = 2  DOWN = 3  LEFT = 4

Then by keeping track of the previous face, curr face, and last move I tried to figure out a formula to get an offset that would help me select what the next face would be given a direction to move to a new face. Roughly I came out with this interpretation:

prevface MOVE currFace
    1 -> UP(1) -> 4 -> RIGHT(2) -> 5

offset = opposite direction of MOVE - (sidesOfFace.indexOf(prevFace)+1)

So first I get
   1) DOWN - sidesOfFace4.indexOf(1)+1 => 3 - 3 = 0

   2) LEFT - sidesOfFace5.indexOf(4)+1 => 4 - 1 = 3

1) This tells me that the sides around 4 are in the same order as the array sidesOfFace, in clockwise starting at the top. So when the user swipes again I can know which side we are going to. This is imperative in being able to set up the right rotations of the cube since they change for the viewer as the cube gets turned.

2) This shows that there is an offset, if we look at the array the index of 4 should be 0 but the cube has been rotated such that the UP side is now at index 3, RIGHT is 0, DOWN is 1, and LEFT is 2.

Besides needing to know which side is facing the screen for other functionality in my app, I also have to know because depending on which side is facing the screen I have to rotate the cube along the correct axis. I am keeping track of the xRot and yRot but these rotations have to happen according the the camera/users view, not the cubes axis.

For Example I found that:

axis for front face  up/down axis  right/left axis  (as seen by the camera)
    1   +z              +x             +y
    2   -z              -x             -y

    4   +y              +x             +z
    6   -y              -x             -z

    5   +x              +z             +y
    3   -x              -z             -y

This means that depending on which side is facing the screen I have to do the xRotations around the up/down axis and the yRotations around the right/left axis.

A friend said something about possibly checking the 4 vertices that are closest to the camera but since I am using glRotate funcs I wasn't sure where I could get that information from. But I still need to know which numbers are on which side of the front face so I can automate the rotations of the cube.

If you actually sat down and read all this I truely do appreciate it, If you could steer me in the right direction. Maybe a link, or better yet a known solution to this problem would be amazing. I have been struggling with this for a few days now and I was just wondering if this was already a problem that had a solution.

Thanks all,

Alan

4

2 回答 2

1

老实说,我没有完全阅读您帖子的最后 3/4,它看起来比需要的要复杂得多。

但是,如果您只想检测立方体的哪一侧最靠近相机,则只需执行以下操作:

使用未旋转的立方体,为每个方向创建一个向量:

vec3 left(-1, 0, 0)
vec3 right (1, 0, 0)
vec3 up(0, 1, 0)
etc...

然后获取立方体的当前模型视图矩阵。如果您通过立方体的模型视图转换法线,您将在眼睛空间中获得结果向量。

vec3 leftInEyeSpace = modelView * left;
vec3 upInEyeSpace = modelView * up;
...

这将是每个向量相对于您的眼睛的方向。

然后定义一个从立方体中心指向相机的向量:

vec3 cubeToCamera= -normalize((modelView * vec4(0,0,0,1)).xyz);

然后你想用你的 'cubeToCamera' 向量获取每个向量的点积。因为点积随着向量之间的角度增加而减小,所以具有最大量级的点积将是最面向相机的点积。

float leftDot = dot(cubeToCamera, leftInEyeSpace)
float rightDot = dot(cubeToCamera, rightInEyeSpace)
...
于 2012-06-30T03:46:31.877 回答
0

有点令人费解,但这样的事情可以吗?我遗漏了一些方法,但希望你能明白我的大致想法,你应该能够使用布尔变量来确定哪一侧面向用户。

private Boolean right, left, spin;
private Boolean up, down, upsideDown;
private Boolean rightSide, leftSide;
// All false by default.

public void swipe(int swipeDirection)
{
    // Swipe Direction - 0 = Right, 1 = Left, 2 = Up, 3 = Down
    switch (swipeDirection)
    {
    case 0:
        if (upsideDown)
        {
            swipeLeft();
        }
        else if (rightSide)
        {
            swipeDown();
        }
        else if (leftSide)
        {
            swipeUp();
        }
        else
        {
            swipeRight();
        }
        break;
    case 1:
        if (upsideDown)
        {
            swipeRight();
        }
        else if (rightSide)
        {
            swipeUp();
        }
        else if (leftSide)
        {
            swipeDown();
        }
        else
        {
            swipeLeft();
        }
        break;
    case 2:
        if (upsideDown)
        {
            swipeDown();
        }
        else if (rightSide)
        {
            swipeRight();
        }
        else if (leftSide)
        {
            swipeLeft();
        }
        else
        {
            swipeUp();
        }
        break;
    case 3:
        if (upsideDown)
        {
            swipeUp();
        }
        else if (rightSide)
        {
            swipeLeft();
        }
        else if (leftSide)
        {
            swipeRight();
        }
        else
        {
            swipeDown();
        }
        break;
    }
}

private void swipeRight()
{
    if (right)
    {
        right = false;
        spin = true;
    }
    else if (left)
    {
        left = false;
    }
    else if (spin)
    {
        spin = false;
        left = true;
    }
    else if (up)
    {
        up = false;
        if (rightSide)
        {
            rightSide = false;
            upsideDown = true;
        }
        else if (leftSide)
        {
            leftSide = false;
        }
        else
        {
            rightSide = true;
        }
    }
    else if (down)
    {
        down = false;
        if (leftSide)
        {
            leftSide = false;
            upsideDown = true;
        }
        else if (rightSide)
        {
            rightSide = false;
        }
        else
        {
            leftSide = true;
        }
    }
    else
    {
        right = true;
    }
}

private void swipeUp()
{
    if (down)
    {
        down = false;
    }
    else if (up)
    {
        upsideDown = !upsideDown;
    }
    else if (upsideDown)
    {
        upsideDown = false;
        up = true;
    }
}
于 2012-06-30T03:37:59.723 回答