// eigen-decomposition of a symmetric matrix void Matrix::eig(Matrix& U, Matrix& lambda, unsigned int iter, bool ignoreError) const { ASSERT(isValid() && isSquare()); Matrix basic = *this; Matrix eigenval(m_rows); // 1-dim case if (m_rows == 1) { basic(0, 0) = 1.0; eigenval(0) = m_data[0]; return; } std::vector<double> oD(m_rows); unsigned int i, j, k, l, m; double b, c, f, g, h, hh, p, r, s, scale; // reduction to tridiagonal form for (i=m_rows; i-- > 1;) { h = 0.0; scale = 0.0; if (i > 1) for (k = 0; k < i; k++) scale += fabs(basic(i, k)); if (scale == 0.0) oD[i] = basic(i, i-1); else { for (k = 0; k < i; k++) { basic(i, k) /= scale; h += basic(i, k) * basic(i, k); } f = basic(i, i-1); g = (f > 0.0) ? -::sqrt(h) : ::sqrt(h); oD[i] = scale * g; h -= f * g; basic(i, i-1) = f - g; f = 0.0; for (j = 0; j < i; j++) { basic(j, i) = basic(i, j) / (scale * h); g = 0.0; for (k=0; k <= j; k++) g += basic(j, k) * basic(i, k); for (k=j+1; k < i; k++) g += basic(k, j) * basic(i, k); f += (oD[j] = g / h) * basic(i, j); } hh = f / (2.0 * h); for (j=0; j < i; j++) { f = basic(i, j); g = oD[j] - hh * f; oD[j] = g; for (k=0; k <= j; k++) basic(j, k) -= f * oD[k] + g * basic(i, k); } for (k=i; k--;) basic(i, k) *= scale; } eigenval(i) = h; } eigenval(0) = oD[0] = 0.0; // accumulation of transformation matrices for (i=0; i < m_rows; i++) { if (eigenval(i) != 0.0) { for (j=0; j < i; j++) { g = 0.0; for (k = 0; k < i; k++) g += basic(i, k) * basic(k, j); for (k = 0; k < i; k++) basic(k, j) -= g * basic(k, i); } } eigenval(i) = basic(i, i); basic(i, i) = 1.0; for (j=0; j < i; j++) basic(i, j) = basic(j, i) = 0.0; } // eigenvalues from tridiagonal form for (i=1; i < m_rows; i++) oD[i-1] = oD[i]; oD[m_rows - 1] = 0.0; for (l=0; l < m_rows; l++) { j = 0; do { // look for small sub-diagonal element for (m=l; m < m_rows - 1; m++) { s = fabs(eigenval(m)) + fabs(eigenval(m + 1)); if (fabs(oD[m]) + s == s) break; } p = eigenval(l); if (m != l) { if (j++ == iter) { // Too many iterations --> numerical instability! if (ignoreError) break; else throw("[Matrix::eig] numerical problems"); } // form shift g = (eigenval(l+1) - p) / (2.0 * oD[l]); r = ::sqrt(g * g + 1.0); g = eigenval(m) - p + oD[l] / (g + ((g > 0.0) ? fabs(r) : -fabs(r))); s = 1.0; c = 1.0; p = 0.0; for (i=m; i-- > l;) { f = s * oD[i]; b = c * oD[i]; if (fabs(f) >= fabs(g)) { c = g / f; r = ::sqrt(c * c + 1.0); oD[i+1] = f * r; s = 1.0 / r; c *= s; } else { s = f / g; r = ::sqrt(s * s + 1.0); oD[i+1] = g * r; c = 1.0 / r; s *= c; } g = eigenval(i+1) - p; r = (eigenval(i) - g) * s + 2.0 * c * b; p = s * r; eigenval(i+1) = g + p; g = c * r - b; for (k=0; k < m_rows; k++) { f = basic(k, i+1); basic(k, i+1) = s * basic(k, i) + c * f; basic(k, i) = c * basic(k, i) - s * f; } } eigenval(l) -= p; oD[l] = g; oD[m] = 0.0; } } while (m != l); } // normalize eigenvectors for (j=m_rows; j--;) { s = 0.0; for (i=m_rows; i--;) s += basic(i, j) * basic(i, j); s = ::sqrt(s); for (i=m_rows; i--;) basic(i, j) /= s; } // sort by eigenvalues std::vector<unsigned int> index(m_rows); for (i=0; i<m_rows; i++) index[i] = i; CmpIndex cmpidx(eigenval, index); std::sort(index.begin(), index.end(), cmpidx); U.resize(m_rows, m_rows); lambda.resize(m_rows); for (i=0; i<m_rows; i++) { j = index[i]; lambda(i) = eigenval(j); for (k=0; k<m_rows; k++) U(k, i) = basic(k, j); } }
/*if (0 != Model::nSlidingModel) { // Just the model we're sliding on, if any MyScene.m_Objects.at(Model::nSlidingModel - 1)->Render(2, false); } else* / { MyScene.Render(Scene::StaticSceneGeometry); } double tt = 0; double t0 = glfwGetTime(); uint8 * pPixels = new uint8[4 * nCustomViewportWidth * nCustomViewportHeight]; glReadPixels(0, 0, nCustomViewportWidth, nCustomViewportHeight, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<void *>(pPixels)); float * pDepths = new float[nCustomViewportWidth * nCustomViewportHeight]; glReadPixels(0, 0, nCustomViewportWidth, nCustomViewportHeight, GL_DEPTH_COMPONENT, GL_FLOAT, reinterpret_cast<void *>(pDepths)); tt += glfwGetTime() - t0; // Render the selected model MyScene.Render(Scene::SelectedObjectBackFace); t0 = glfwGetTime(); uint8 * pSPixels = new uint8[4 * nCustomViewportWidth * nCustomViewportHeight]; glReadPixels(0, 0, nCustomViewportWidth, nCustomViewportHeight, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<void *>(pSPixels)); float * pSDepths = new float[nCustomViewportWidth * nCustomViewportHeight]; glReadPixels(0, 0, nCustomViewportWidth, nCustomViewportHeight, GL_DEPTH_COMPONENT, GL_FLOAT, reinterpret_cast<void *>(pSDepths)); tt += glfwGetTime() - t0; //printf("SnapBackPersp() read pixels in %f secs.\n", tt); GLfloat winX, winY; GLdouble posX, posY, posZ; GLdouble modelMatrix[16]; glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); GLdouble projMatrix[16]; glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); GLint viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); float fMinPositiveDistanceSqr = -1; // Positive distance means away from the camera (i.e. to snap back to background); valid range is (0, +oo) Wm5::Vector3d oMoveBackVector(Wm5::Vector3d::ZERO); //Model::nSlidingModel = 0; uint16 SlidingModel = 0; uint16 SlidingTriangle = 0; uint16 SelectedTriangle = 0; uint32 ClosestPixel = 0; t0 = glfwGetTime(); for (uint32 nPixel = 0; nPixel < nCustomViewportWidth * nCustomViewportHeight; ++nPixel) { uint8 r = pPixels[4 * nPixel + 0]; uint8 g = pPixels[4 * nPixel + 1]; uint8 b = pPixels[4 * nPixel + 2]; uint8 a = pPixels[4 * nPixel + 3]; float d = pDepths[nPixel]; uint8 sr = pSPixels[4 * nPixel + 0]; uint8 sg = pSPixels[4 * nPixel + 1]; uint8 sb = pSPixels[4 * nPixel + 2]; uint8 sa = pSPixels[4 * nPixel + 3]; float sd = pSDepths[nPixel]; if ((sr+sg) != 0 && (r+g) != 0) { winX = (GLfloat)(nPixel % nCustomViewportWidth); winY = (GLfloat)(nPixel / nCustomViewportWidth); gluUnProject(winX, winY, d, modelMatrix, projMatrix, viewport, &posX, &posY, &posZ); Wm5::Vector3d oD(posX, posY, posZ); gluUnProject(winX, winY, sd, modelMatrix, projMatrix, viewport, &posX, &posY, &posZ); Wm5::Vector3d oSD(posX, posY, posZ); //printf ("World coords at z= %f (Depth) are (%f, %f, %f)\n", winZ, posX, posY, posZ); double dDepthDiffSqr = Wm5::Mathd::Sign(d - sd) * (oD - oSD).SquaredLength(); if (dDepthDiffSqr >= 0.0 && (dDepthDiffSqr < fMinPositiveDistanceSqr || fMinPositiveDistanceSqr == -1)) { fMinPositiveDistanceSqr = static_cast<float>(dDepthDiffSqr); oMoveBackVector = (oD - oSD); //Model::nSlidingModel = r; //Model::nSlidingTriangle = static_cast<uint32>(g) << 8 | b; SlidingModel = static_cast<uint16>(g) << 8 | r; SlidingTriangle = static_cast<uint16>(a) << 8 | b; SelectedTriangle = static_cast<uint16>(sa) << 8 | sb; ClosestPixel = nPixel; } } } //printf("SnapBackPersp() processed pixels in %f secs.\n", glfwGetTime() - t0); delete[] pPixels; delete[] pDepths; delete[] pSPixels; delete[] pSDepths; //printf("SlidingModel = %d\n SlidingTriangle = %d\n SelectedTriangle = %d\n ClosestPixel = %d\n", SlidingModel, SlidingTriangle, SelectedTriangle, ClosestPixel); // Geometry distance correction if (fMinPositiveDistanceSqr != -1) { winX = (GLfloat)(ClosestPixel % nCustomViewportWidth); winY = (GLfloat)(ClosestPixel / nCustomViewportWidth); gluUnProject(winX, winY, 0, modelMatrix, projMatrix, viewport, &posX, &posY, &posZ); Wm5::Vector3d oNearPoint(posX, posY, posZ); gluUnProject(winX, winY, 1, modelMatrix, projMatrix, viewport, &posX, &posY, &posZ); Wm5::Vector3d oFarPoint(posX, posY, posZ); Wm5::Vector3d Direction = oFarPoint - oNearPoint; Direction.Normalize(); Wm5::Line3d Line(oNearPoint, Direction); float * pSlidingVertexData = &MyScene.m_Objects.at(SlidingModel - 1)->m_pVertexData[3 * 3 * SlidingTriangle]; Wm5::Plane3d SlidingPlane(Wm5::Vector3d(pSlidingVertexData[0], pSlidingVertexData[1], pSlidingVertexData[2]) + MyScene.m_Objects.at(SlidingModel - 1)->GetPosition(), Wm5::Vector3d(pSlidingVertexData[3], pSlidingVertexData[4], pSlidingVertexData[5]) + MyScene.m_Objects.at(SlidingModel - 1)->GetPosition(), Wm5::Vector3d(pSlidingVertexData[6], pSlidingVertexData[7], pSlidingVertexData[8]) + MyScene.m_Objects.at(SlidingModel - 1)->GetPosition()); float * pSelectedVertexData = &MyScene.m_Objects.at(MyScene.GetSelectedObjectId() - 1)->m_pVertexData[3 * 3 * SelectedTriangle]; Wm5::Plane3d SelectedPlane(Wm5::Vector3d(pSelectedVertexData[0], pSelectedVertexData[1], pSelectedVertexData[2]) + MyScene.m_Objects.at(MyScene.GetSelectedObjectId() - 1)->GetPosition(), Wm5::Vector3d(pSelectedVertexData[3], pSelectedVertexData[4], pSelectedVertexData[5]) + MyScene.m_Objects.at(MyScene.GetSelectedObjectId() - 1)->GetPosition(), Wm5::Vector3d(pSelectedVertexData[6], pSelectedVertexData[7], pSelectedVertexData[8]) + MyScene.m_Objects.at(MyScene.GetSelectedObjectId() - 1)->GetPosition()); Wm5::Vector3d SlidingIntersection, SelectedIntersection; { Wm5::IntrLine3Plane3d Intersection(Line, SlidingPlane); if (Intersection.Find()) SlidingIntersection = Intersection.GetLine().Origin + Intersection.GetLine().Direction * Intersection.GetLineParameter(); else printf("Error: No sliding intersection!\n"); } { Wm5::IntrLine3Plane3d Intersection(Line, SelectedPlane); if (Intersection.Find()) SelectedIntersection = Intersection.GetLine().Origin + Intersection.GetLine().Direction * Intersection.GetLineParameter(); else printf("Error: No selected intersection!\n"); } oMoveBackVector = SlidingIntersection - SelectedIntersection; oMoveBackVector += ZoomSelectedModel(-0.001, oMoveBackVector); } if (fMinPositiveDistanceSqr != -1) //MyScene.m_Objects.at(MyScene.GetSelectedObjectId() - 1)->MoveBy(oMoveBackVector + ZoomSelectedModel(-0.01, oMoveBackVector)); MyScene.m_Objects.at(MyScene.GetSelectedObjectId() - 1)->MoveBy(oMoveBackVector); glViewport(0, 0, nViewportWidth, nViewportHeight); glPopMatrix(); }*/ void ClassicMode::SnapPersp(SnapDirection SnapDirection) { glPushMatrix(); // Set a smaller viewport with same aspect ratio uint32 nCustomViewportWidth = std::min<uint32>(400, nViewportWidth); //uint32 nCustomViewportWidth = std::min<uint32>(nViewportWidth, nViewportWidth); uint32 nCustomViewportHeight = nCustomViewportWidth * nViewportHeight / nViewportWidth; glViewport(0, 0, nCustomViewportWidth, nCustomViewportHeight); if (Front == SnapDirection) { // Render only the colliding static scene MyScene.Render(Scene::StaticCollidingSceneGeometry); //MyScene.Render(Scene::StaticSceneGeometry); } else if (Back == SnapDirection) { // Render the static scene /*if (0 != Model::nSlidingModel) { // Just the model we're sliding on, if any MyScene.m_Objects.at(Model::nSlidingModel - 1)->Render(2, false); } else { MyScene.Render(Scene::StaticSceneGeometry); }*/ MyScene.Render(Scene::StaticSceneGeometry); } double tt = 0; double t0 = glfwGetTime(); uint8 * pPixels = new uint8[4 * nCustomViewportWidth * nCustomViewportHeight]; glReadPixels(0, 0, nCustomViewportWidth, nCustomViewportHeight, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<void *>(pPixels)); float * pDepths = new float[nCustomViewportWidth * nCustomViewportHeight]; glReadPixels(0, 0, nCustomViewportWidth, nCustomViewportHeight, GL_DEPTH_COMPONENT, GL_FLOAT, reinterpret_cast<void *>(pDepths)); tt += glfwGetTime() - t0; // Render the selected model MyScene.Render(Scene::SelectedObjectBackFace); t0 = glfwGetTime(); uint8 * pSPixels = new uint8[4 * nCustomViewportWidth * nCustomViewportHeight]; glReadPixels(0, 0, nCustomViewportWidth, nCustomViewportHeight, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<void *>(pSPixels)); float * pSDepths = new float[nCustomViewportWidth * nCustomViewportHeight]; glReadPixels(0, 0, nCustomViewportWidth, nCustomViewportHeight, GL_DEPTH_COMPONENT, GL_FLOAT, reinterpret_cast<void *>(pSDepths)); tt += glfwGetTime() - t0; //printf("SnapPersp() read pixels in %f secs.\n", tt); GLfloat winX, winY; GLdouble posX, posY, posZ; GLdouble modelMatrix[16]; glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); GLdouble projMatrix[16]; glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); GLint viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); double dMinBackDistanceSqr = 0; float fMinPositiveDistanceSqr = -1; // Positive distance means away from the camera (i.e. to snap back to background); valid range is (0, +oo) Wm5::Vector3d oMoveVector(Wm5::Vector3d::ZERO); //Model::nSlidingModel = 0; uint16 SlidingModel = 0; uint16 SlidingTriangle = 0; uint16 SelectedTriangle = 0; uint32 ClosestPixel = 0; bool IsObjectVisible = false; t0 = glfwGetTime(); for (uint32 nPixel = 0; nPixel < nCustomViewportWidth * nCustomViewportHeight; ++nPixel) { uint8 r = pPixels[4 * nPixel + 0]; uint8 g = pPixels[4 * nPixel + 1]; uint8 b = pPixels[4 * nPixel + 2]; uint8 a = pPixels[4 * nPixel + 3]; float d = pDepths[nPixel]; uint8 sr = pSPixels[4 * nPixel + 0]; uint8 sg = pSPixels[4 * nPixel + 1]; uint8 sb = pSPixels[4 * nPixel + 2]; uint8 sa = pSPixels[4 * nPixel + 3]; float sd = pSDepths[nPixel]; if ((sr+sg) != 0 && (r+g) != 0) { winX = (GLfloat)(nPixel % nCustomViewportWidth); winY = (GLfloat)(nPixel / nCustomViewportWidth); gluUnProject(winX, winY, d, modelMatrix, projMatrix, viewport, &posX, &posY, &posZ); Wm5::Vector3d oD(posX, posY, posZ); gluUnProject(winX, winY, sd, modelMatrix, projMatrix, viewport, &posX, &posY, &posZ); Wm5::Vector3d oSD(posX, posY, posZ); //printf ("World coords at z= %f (Depth) are (%f, %f, %f)\n", winZ, posX, posY, posZ); double dDepthDiffSqr = Wm5::Mathd::Sign(d - sd) * (oD - oSD).SquaredLength(); if (Front == SnapDirection) { if (dDepthDiffSqr < dMinBackDistanceSqr) { dMinBackDistanceSqr = dDepthDiffSqr; oMoveVector = (oD - oSD); //Model::nSlidingModel = r; //Model::nSlidingTriangle = static_cast<uint32>(g) << 8 | b; SlidingModel = static_cast<uint16>(g) << 8 | r; SlidingTriangle = static_cast<uint16>(a) << 8 | b; SelectedTriangle = static_cast<uint16>(sa) << 8 | sb; ClosestPixel = nPixel; } } else if (Back == SnapDirection) { if (dDepthDiffSqr >= 0.0 && (dDepthDiffSqr < fMinPositiveDistanceSqr || fMinPositiveDistanceSqr == -1)) { fMinPositiveDistanceSqr = static_cast<float>(dDepthDiffSqr); oMoveVector = (oD - oSD); //Model::nSlidingModel = r; //Model::nSlidingTriangle = static_cast<uint32>(g) << 8 | b; SlidingModel = static_cast<uint16>(g) << 8 | r; SlidingTriangle = static_cast<uint16>(a) << 8 | b; SelectedTriangle = static_cast<uint16>(sa) << 8 | sb; ClosestPixel = nPixel; } } if (!IsObjectVisible && dDepthDiffSqr >= 0) IsObjectVisible = true; } else if (!IsObjectVisible && (sr+sg) != 0 && (r+g) == 0) { IsObjectVisible = true; } } // TODO: Get rid of code duplication and double calculation // If object isn't visible, do a Front snap if (Back == SnapDirection && !IsObjectVisible) { SnapDirection = Front; for (uint32 nPixel = 0; nPixel < nCustomViewportWidth * nCustomViewportHeight; ++nPixel) { uint8 r = pPixels[4 * nPixel + 0]; uint8 g = pPixels[4 * nPixel + 1]; uint8 b = pPixels[4 * nPixel + 2]; uint8 a = pPixels[4 * nPixel + 3]; float d = pDepths[nPixel]; uint8 sr = pSPixels[4 * nPixel + 0]; uint8 sg = pSPixels[4 * nPixel + 1]; uint8 sb = pSPixels[4 * nPixel + 2]; uint8 sa = pSPixels[4 * nPixel + 3]; float sd = pSDepths[nPixel]; if ((sr+sg) != 0 && (r+g) != 0) { winX = (GLfloat)(nPixel % nCustomViewportWidth); winY = (GLfloat)(nPixel / nCustomViewportWidth); gluUnProject(winX, winY, d, modelMatrix, projMatrix, viewport, &posX, &posY, &posZ); Wm5::Vector3d oD(posX, posY, posZ); gluUnProject(winX, winY, sd, modelMatrix, projMatrix, viewport, &posX, &posY, &posZ); Wm5::Vector3d oSD(posX, posY, posZ); //printf ("World coords at z= %f (Depth) are (%f, %f, %f)\n", winZ, posX, posY, posZ); double dDepthDiffSqr = Wm5::Mathd::Sign(d - sd) * (oD - oSD).SquaredLength(); if (dDepthDiffSqr < dMinBackDistanceSqr) { dMinBackDistanceSqr = dDepthDiffSqr; oMoveVector = (oD - oSD); //Model::nSlidingModel = r; //Model::nSlidingTriangle = static_cast<uint32>(g) << 8 | b; SlidingModel = static_cast<uint16>(g) << 8 | r; SlidingTriangle = static_cast<uint16>(a) << 8 | b; SelectedTriangle = static_cast<uint16>(sa) << 8 | sb; ClosestPixel = nPixel; } } } } //printf("SnapPersp() processed pixels in %f secs.\n", glfwGetTime() - t0); delete[] pPixels; delete[] pDepths; delete[] pSPixels; delete[] pSDepths; //printf("SlidingModel = %d\n SlidingTriangle = %d\n SelectedTriangle = %d\n ClosestPixel = %d\n", SlidingModel, SlidingTriangle, SelectedTriangle, ClosestPixel); // Geometry distance correction if (dMinBackDistanceSqr != 0 || fMinPositiveDistanceSqr != -1) { winX = (GLfloat)(ClosestPixel % nCustomViewportWidth); winY = (GLfloat)(ClosestPixel / nCustomViewportWidth); gluUnProject(winX, winY, 0, modelMatrix, projMatrix, viewport, &posX, &posY, &posZ); Wm5::Vector3d oNearPoint(posX, posY, posZ); gluUnProject(winX, winY, 1, modelMatrix, projMatrix, viewport, &posX, &posY, &posZ); Wm5::Vector3d oFarPoint(posX, posY, posZ); Wm5::Vector3d Direction = oFarPoint - oNearPoint; Direction.Normalize(); Wm5::Line3d Line(oNearPoint, Direction); /*float * pSlidingVertexData = &MyScene.m_Objects.at(SlidingModel - 1)->m_pVertexData[3 * 3 * SlidingTriangle]; Wm5::Plane3d SlidingPlane(Wm5::Vector3d(pSlidingVertexData[0], pSlidingVertexData[1], pSlidingVertexData[2]) + MyScene.m_Objects.at(SlidingModel - 1)->GetPosition(), Wm5::Vector3d(pSlidingVertexData[3], pSlidingVertexData[4], pSlidingVertexData[5]) + MyScene.m_Objects.at(SlidingModel - 1)->GetPosition(), Wm5::Vector3d(pSlidingVertexData[6], pSlidingVertexData[7], pSlidingVertexData[8]) + MyScene.m_Objects.at(SlidingModel - 1)->GetPosition()); float * pSelectedVertexData = &MyScene.m_Objects.at(MyScene.GetSelectedObjectId() - 1)->m_pVertexData[3 * 3 * SelectedTriangle]; Wm5::Plane3d SelectedPlane(Wm5::Vector3d(pSelectedVertexData[0], pSelectedVertexData[1], pSelectedVertexData[2]) + MyScene.m_Objects.at(MyScene.GetSelectedObjectId() - 1)->GetPosition(), Wm5::Vector3d(pSelectedVertexData[3], pSelectedVertexData[4], pSelectedVertexData[5]) + MyScene.m_Objects.at(MyScene.GetSelectedObjectId() - 1)->GetPosition(), Wm5::Vector3d(pSelectedVertexData[6], pSelectedVertexData[7], pSelectedVertexData[8]) + MyScene.m_Objects.at(MyScene.GetSelectedObjectId() - 1)->GetPosition());*/ Wm5::Triangle3d SlidingTriangle3 = MyScene.GetObject(SlidingModel).GetTriangle(SlidingTriangle); Wm5::Plane3d SlidingPlane(SlidingTriangle3.V[0], SlidingTriangle3.V[1], SlidingTriangle3.V[2]); Wm5::Triangle3d SelectedTriangle3 = MyScene.GetSelectedObject().GetTriangle(SelectedTriangle); Wm5::Plane3d SelectedPlane(SelectedTriangle3.V[0], SelectedTriangle3.V[1], SelectedTriangle3.V[2]); Wm5::Vector3d SlidingIntersection, SelectedIntersection; { Wm5::IntrLine3Plane3d Intersection(Line, SlidingPlane); if (Intersection.Find()) SlidingIntersection = Intersection.GetLine().Origin + Intersection.GetLine().Direction * Intersection.GetLineParameter(); else printf("Error: No sliding intersection!\n"); } { Wm5::IntrLine3Plane3d Intersection(Line, SelectedPlane); if (Intersection.Find()) SelectedIntersection = Intersection.GetLine().Origin + Intersection.GetLine().Direction * Intersection.GetLineParameter(); else printf("Error: No selected intersection!\n"); } oMoveVector = SlidingIntersection - SelectedIntersection; oMoveVector += ZoomSelectedModel(-0.001, oMoveVector); } MyScene.m_Objects.at(MyScene.GetSelectedObjectId() - 1)->MoveBy(oMoveVector); glViewport(0, 0, nViewportWidth, nViewportHeight); glPopMatrix(); }