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.