-1

I am stuck right now with my RubiksCube Project.

What I want to achieve: On left-click checking if a single Mini-Cubie was clicked or not. (The Cube might be rotated when clicked)

The Code of the other Rubiks Cube classes works correctly. We need to calculate the functions on our own with math formulas.

Current Problems:

  • Clicking on Edges is not being detected
  • After the rotation clicking at a point sometimes leads to: Wrong layer being marked as clicked or no layer being marked as clicked

My general idea was to safe the coords of every Layer´s 4 Corner Points, updating their position when rotated and checking the Intersection of the Ray with help of these locations

void MergedCube::Render(float aspectRatio)
{

    m_viewProject = glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 100.0f) *
                    glm::lookAt(glm::vec3(0.0f, 0.0f, -9.0f), 
                                glm::vec3(0.0f), 
                                glm::vec3(0.0f, 1.0f, 0.0f)) *
                    glm::mat4_cast(m_orientationQuaternion);

        compound = glm::translate(m_viewProject, (glm::vec3(1, 1, 1) - 1.0f));

        m_cubieRenderer.Render(compound);
            

    // Calling LayerCalculation() for every Layer with direction -1 or 1


}

This method is supposed to calculate my helper vector, the 2 direction vectors and the normalisation vector of every Layer

void MergedCube::LayerCalculation(std::vector<glm::vec3>& points, int normDirection) {

    while (points.size() > 4) {
        points.erase(points.end()-1);
    }

    glm::vec3 middlePoint = (points[0] + points[2]) / 2.0f;
    glm::vec3 firstPoint = (points[0] + points[1]) / 2.0f;
    glm::vec3 secondPoint = (points[0] + points[3]) / 2.0f;

    glm::vec3 vecA = glm::normalize(firstPoint - middlePoint);
    glm::vec3 vecB = glm::normalize(secondPoint - middlePoint);
    
    glm::vec3 normalVector = glm::cross(vecA,vecB) * glm::vec3(direction);

    points.push_back(middlePoint);
    points.push_back(vecA);
    points.push_back(vecB);
    points.push_back(normalVector); 
    
}

Now the RayAndCubeIntersection method.

bool MergedCube::RayAndCubeIntersection(glm::vec3 startingPoint, glm::vec3 direction, 
                                        std::vector<glm::vec3> Pts) {

    glm::vec3 helperVec = pts[4];
    glm::vec3 normVec = pts[7];
    glm::vec3 directionVecA = pts[5];
    glm::vec3 directionVecB = pts[6];

if (glm::dot(rayDirection, normVec) < 0) {

        float res = normVec[0] * helperVec[0] + normVec[1] * helperVec[1] + normVec[2] * helperVec[2];
        float directionMultiplikator = (res - normVec[0] * rayStartingPoint[0] - normVec[1] * rayStartingPoint[1] - normVec[2] * rayStartingPoint[2]) /
                                       (normVec[0] * rayDirection[0] + normVec[1] * rayDirection[1] + normVec[2] * rayDirection[2]);
        glm::vec3 crosspoint = rayStartingPoint + rayDirection * glm::vec3(directionMultiplikator);

        if (glm::dot(crosspoint - helperVec,normVec) == 0) {

            float x = glm::dot(directionVecA,crosspoint - helperVec);
            float y = glm::dot(directionVecB, crosspoint - helperVec);

            if (x > -0.5001 && x < 0.5001) {
                if (y > -0.5001 && y < 0.5001) {
                    return true;
                }
            }   
        }
    }
    return false;
}

Edit: I changed my Code quite a bit, now clicking the cube is being detected in many cases.

Diazodiac
  • 11
  • 3
  • 2
    You'll get more help if you provide an [mcve], with emphasis on "minimum". – Thomas Matthews Mar 30 '23 at 22:39
  • @JaMiT I tried reducing my Code example to only the mandatory part. I updated my Code to only check for the Intersection between the Ray and a single Cubie. Without rotation it works quite well (Besides clicking on edges of the Layer). After the rotation it doesnt, probably because the added corner points are added without rotation. But when using 'compound * edge' my code doesn´t work at all. – Diazodiac Mar 31 '23 at 09:09
  • Have you considered *not* using graphical rotation transforms to move the colors around the cube, but just updating an array representing the color at each location? – Ben Voigt Mar 31 '23 at 16:11
  • @BenVoigt We have to use graphical rotation transforms for the project, we need to program rotation animations later as well. – Diazodiac Mar 31 '23 at 16:19
  • @Diazodiac: The animations are a great time to use graphical transforms, but once you reach a new axis-alignment, you can update the color pattern of the cube and do away with the rotation. That has two advantages: 1. You don't have to stack up multiple rotations as the user continues to solve the puzzle. 2. There's no dynamic rotation in effect when you perform hit testing. – Ben Voigt Mar 31 '23 at 18:16
  • @BenVoigt I am not quite sure if I understood correctly. For example we need to be able to rotate a Rubiks Cube Slice while dynamic rotation is active (so we can see for example 3 Layers while rotating a slice). So that would mean the rotation wouldn´t be performed until hitting a new axis-alignment. – Diazodiac Mar 31 '23 at 19:28
  • 1
    A Rubix cube has 54 visible squares from 27 small cubes. When you rotate, you rotate 9 co-planar small cubes. What I'm proposing is that when the mouse button is up, there is no dynamic graphical transform. When the mouse button is clicked, you do hit-testing using only static transforms. While the mouse is dragged, there's a dynamic rotation in effect for the plane of 9 small cubes and their outward-facing surfaces. When the mouse is released, you snap the plane-in-motion to the nearest axis alignment, update all the moved small cubes, and are back to no dynamic rotation transform. – Ben Voigt Apr 03 '23 at 15:05

1 Answers1

0

Well I guess it is time to answer my own question. The actual problem of my code was checking glm::dot(crosspoint - helperVec,normVec) == 0 . But instead I am supposed to check for glm::abs(glm::dot(crosspoint - helperVec,normVec)) < EPSILON with a really small EPSILON value.

Note to myself: When using floats never check against 0

Diazodiac
  • 11
  • 3
  • 1
    Related links: [Is floating point math broken?](https://stackoverflow.com/q/588004) and [Compare double to zero using epsilon](https://stackoverflow.com/q/13698927) – JaMiT Apr 06 '23 at 00:59