Jump to content
  • Advertisement
Sign in to follow this  
Xpyman

Rubik's Cube and Picking

This topic is 4939 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I am developing a simple Rubik's Cube game and I'm trying to implement an easy way for the player to handle the cube. I've already implemented picking in the engine, but I don't really know how could I handle the dragging of the blocks. There is a parent class ( RCCube ) that contains all the blocks and handles the flipping and twisting of the cube, all I've got to do is to call the function void RCCube::Rotate ( int Axis, int Offset, bool Reverse ) with the right attributes and the cube can handle the rest, but I'm having a hard time in getting these parameters from the user's input. I'm able to find wich block the user clicked and witch face he clicked correctly. Can someone help me with an idea for doing that? If you need more information, I may dump some of the code here.

Share this post


Link to post
Share on other sites
Advertisement
you know which block you've clicked. that block defines a layer and a slice of the cube (a 3D row or column), that intersect at that block. You can only rotate these two things in two directions, clockwise and anticlockwise. So, you need to recognize 4 different mouse drag events.

How about up, down, left, and right?

specifically, you'll let the user drag a certain distance, then measure the entire distance moved, calculate the slope of the average line of that distance, and then define ranges of slopes as being certain directions.

For example, slope from -1.0 to 1.0 could indicate horizonal movement, and the sign of the change in X value would give you the specific direction (-x is left, +x is right).

If the slope is NOT between -1.0 and 1.0 (you can't test for it specifically, because the slope goes to infinity in this particular range), then you have vertical movement, with the sign of the y value giving the specific direction (-y is up, +y is down).

Share this post


Link to post
Share on other sites
I tried the following: I defined the 6 block planes for the faces, and for each face I defined 2 more vectors: one for each movement axis, then I got something like this:

Plane3D RCBlock::m_sPlanes[6] =
{
{ D3DXVECTOR3( 0.0f,-1.0f, 0.0f ) , 0.5f },
{ D3DXVECTOR3(-1.0f, 0.0f, 0.0f ) , 0.5f },
{ D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) , 0.5f },
{ D3DXVECTOR3( 1.0f, 0.0f, 0.0f ) , 0.5f },
{ D3DXVECTOR3( 0.0f, 0.0f,-1.0f ) , 0.5f },
{ D3DXVECTOR3( 0.0f, 0.0f, 1.0f ) , 0.5f }
};

D3DXVECTOR3 RCBlock::m_sVecUp[6] =
{
D3DXVECTOR3( 0.0f, 0.0f, 1.0f ),
D3DXVECTOR3( 0.0f, 1.0f, 0.0f ),
D3DXVECTOR3( 0.0f, 0.0f,-1.0f ),
D3DXVECTOR3( 0.0f, 1.0f, 0.0f ),
D3DXVECTOR3( 0.0f, 1.0f, 0.0f ),
D3DXVECTOR3( 0.0f, 1.0f, 0.0f )
};

D3DXVECTOR3 RCBlock::m_sVecRight[6] =
{
D3DXVECTOR3( 1.0f, 0.0f, 0.0f ),
D3DXVECTOR3( 0.0f, 0.0f,-1.0f ),
D3DXVECTOR3( 0.0f, 0.0f,-1.0f ),
D3DXVECTOR3( 0.0f, 0.0f, 1.0f ),
D3DXVECTOR3( 1.0f, 0.0f, 0.0f ),
D3DXVECTOR3(-1.0f, 0.0f, 0.0f )
};

By the way, the order of the faces is: Up, Left, Down, Right, Front, Back and the planes are defined using the normal and distance from the origin.
The RCCube takes care of 2 events: MouseClick and MouseDrag, the mouse click event detects which cube was intercepted by the picking ray, and the point of intersection. On the drag event, I get the new "dragged" picking ray and do an intersection test with the face's plane to find the point P, after that I get the vector that goes from the first intersection to the point P and do a DP3 with the faces's right and up movement vectors, if the result is greater than a threshold I find out around which axis I should flip and the offset of that "flipping ring". But there's a great problem here, since the intersection test is made with using a transformed face and the axis of rotation should be in the world coordinates, I end up "flipping" the axis that I should rotate, therefore the approcach I tried is useless unless I do some kind of math hack.
I believe all the problema that I'm encountering is due a bad data organization ( unfortunately I couldn't find any other way ). If someone is able to look at the code itself, I've uploaded the project here: http://geocities.yahoo.com.br/arquivosxpy/cpp/Projetos/Rubik.zip
I'm sorry about the lack of commenting in some parts, but I usually comment my code when:
a) I need help somewhere
b) I'm sure the code won't be changed
I'm sorry about writing so much, but I hope someone is able to help me.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!