У меня есть сцена, в которой я визуализирую пару кубов с помощью openGL (структура программы не использует GLUT, она находится в структуре программы win32, но я просто рисую кубы с помощью glutSolidCube
), теперь я хочу выбрать эти кубы мышью, выбирая. вот что я делаю: сначала, когда пользователь нажимает кнопку мыши на сцене, я получаю положение мыши и пытаюсь найти его координаты в координатах сцены (templateSkeletons — это скелет, который я создал из кубов, не более того):
if (mouse.buttonPressed(Mouse::BUTTON_LEFT))
{
mouse.update();
templateSkeletons[0].selectionMode = true;
Vector3* points;
points = GetOGLPos();
templateSkeletons[0].setIntersectionPoints(points[0],points[1]);
}else
templateSkeletons[0].selectionMode = false;
это функция GerOGLPos
, с помощью которой я получаю координаты в сцене (обратите внимание, что у меня есть собственная камера и собственная матрица проекции, но я получаю матрицу проекции здесь, в этой функции, просто вызывая glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
, это неправильно, и я должен получить свою собственную проекционная матрица camrea ? ):
Vector3* GetOGLPos()
{Vector3 pointsOnLine[2];
double mvmatrix[16];
double projmatrix[16];
int viewport[4];
double dX, dY, dZ, dClickY,zz;
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
dClickY = double (viewport[3] - mouse.yPos());
// OpenGL renders with (0,0) on bottom, mouse reports with (0,0) on top
//glReadPixels( mouse.xPos(), int(dClickY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &zz );
gluUnProject ((double) mouse.xPos(), dClickY, 0.0, mvmatrix, projmatrix, viewport, &dX, &dY, &dZ);
pointsOnLine[0] = Vector3( (float) dX, (float) dY, (float) dZ );
gluUnProject ((double) mouse.xPos(), dClickY, 1.0, mvmatrix, projmatrix, viewport, &dX, &dY, &dZ);
pointsOnLine[1] = Vector3( (float) dX, (float) dY, (float) dZ );
return pointsOnLine;
}
теперь я полагаю, что у меня есть две точки, указывающие на мой луч выбора в сцене. теперь, когда я визуализирую кубы, я пытаюсь вычислить расстояние линии, созданной лучом и кубом, и если оно меньше значения, я меняю цвет куба, чтобы знать, что я его выбрал (jointsOfSkeleton указывает каждый куб, который создается скелет, ничего больше, здесь я тестирую только куб номер 6 в массиве):
if(selectionMode)
{
distToLine = Vector3::PointToLineDistance3D(rayPoints[0],rayPoints[1],Vector3::Vector3(jointsOfSkeleton[6].x,
jointsOfSkeleton[6].y,jointsOfSkeleton[6].z));
//distToLine = sqrt(distToLine);
if(distToLine < 0.5)
glColor3f(1.0,0.0,0.0);
else
glColor3f(1.0,1.0,1.0);
}
когда я нажимаю на нерелевантные позиции в окне, я вижу, что цвета куба меняются, это не работает правильно, я смотрю расстояния в отладчике, и расстояния выглядят неправильно. и это функция, которую я использовал для определения расстояния от точки линии:
static float PointToLineDistance3D(Vector3 a, Vector3 b, Vector3 point)
{
Vector3 lineDirection = b - a;
float t = (Vector3::dot(point,lineDirection) - Vector3::dot(lineDirection,a))/(Vector3::dot(lineDirection,lineDirection));
Vector3 direction;
direction.x = a.x + (lineDirection.x *t) - point.x;
direction.y = a.y + (lineDirection.y *t) - point.y;
direction.z = a.z + (lineDirection.z *t) - point.z;
float ShortestDistance = sqrtf((direction.x*direction.x)+(direction.y*direction.y)+(direction.z*direction.z));
return ShortestDistance;
}