void motionCallback(int x, int y) { if (selectedView == FRONT) { controlPoints[selectedPoint[0]][selectedPoint[1]][0] = ToLocalX(x); controlPoints[selectedPoint[0]][selectedPoint[1]][1] = ToLocalY(y - height/2); } else if (selectedView == UP) { controlPoints[selectedPoint[0]][selectedPoint[1]][0] = ToLocalX(x); controlPoints[selectedPoint[0]][selectedPoint[1]][2] = -ToLocalY(y); } else if (selectedView == LEFT) { controlPoints[selectedPoint[0]][selectedPoint[1]][2] = -ToLocalX(x - width/2); controlPoints[selectedPoint[0]][selectedPoint[1]][1] = ToLocalY(y - height/2); } else if (selectedView == ROTATE) { Vector3d lastP = getMousePoint(lastX, lastY, width / 2.0f, height / 2.0f, radius); Vector3d currentP = getMousePoint(x - width / 2.0f, y, width / 2.0f, height / 2.0f, radius); if (mouseButton == GLUT_LEFT_BUTTON) { Vector3d rotateVector; rotateVector.cross(currentP, lastP); double angle = -currentP.angle(lastP) * 2; rotateVector = unProjectToEye(rotateVector, eye, center, upVector); Vector3d dEye; dEye.sub(center, eye); dEye = rotate(dEye, rotateVector, -angle); upVector = rotate(upVector, rotateVector, -angle); eye.sub(center, dEye); } else if (mouseButton == GLUT_RIGHT_BUTTON) { Vector3d dEye; dEye.sub(center, eye); double offset = 0.025; if ((y - lastY) < 0) { dEye.scale(1 - offset); } else { dEye.scale(1 + offset); } eye.sub(center, dEye); } else if (mouseButton == GLUT_MIDDLE_BUTTON) { double dx = x - width / 2.0f - lastX; double dy = y - lastY; if (dx != 0 || dy != 0) { Vector3d moveVector(dx, dy, 0); moveVector = unProjectToEye(moveVector, eye, center, upVector); moveVector.normalize(); double eyeDistance = Vector3d(eye).distance(Vector3d(center)); moveVector.scale(std::sqrt(dx*dx + dy*dy) / 1000 * eyeDistance); center.add(moveVector); eye.add(moveVector); } } lastX = x - width / 2; lastY = y; } EvaluateSurface(); glutPostRedisplay(); }
void DrawSurface() { for (int i = 0; i <= LOD; i++) for (int j = 0; j <= LOD; j++) { // calculating reflecting vector Vector3d mapped; mapped.sub(center, eye); Vector3d n = Vector3d(surfaceNormals[i][j][0], surfaceNormals[i][j][1], surfaceNormals[i][j][2]); n.scale(-2 * n.dot(mapped)); mapped.add(n); mapped.normalize(); if (mapped.z >= 0) { float parabolic_x = ((mapped.x / (2 * (1 + mapped.z))) + 0.5) / 2; float parabolic_y = (-mapped.y / (2 * (1 + mapped.z))) + 0.5; texCoords[i][j][0] = parabolic_x; texCoords[i][j][1] = parabolic_y; } else { float parabolic_x = ((mapped.x / (2 * (1 - mapped.z))) + 0.5) / 2 + 0.5; float parabolic_y = (-mapped.y / (2 * (1 - mapped.z))) + 0.5; texCoords[i][j][0] = parabolic_x; texCoords[i][j][1] = parabolic_y; } // double sum = sqrt(mapped.x*mapped.x + mapped.y*mapped.y + pow(mapped.z+1,2)); // texCoords[i][j][0] = (mapped.x/sum + 1) / 2; // texCoords[i][j][1] = (-mapped.y/sum + 1) / 2; // float padding_y = 1/3.0; // float padding_x = 1/4.0; // if (mapped.x >= std::abs(mapped.y) && mapped.x >= std::abs(mapped.z)) { // right // texCoords[i][j][0] = (-mapped.z / mapped.x + 1) / 2 / 4 + padding_x * 2; // texCoords[i][j][1] = (-mapped.y / mapped.x + 1) / 2 / 3 + padding_y; // } else if (mapped.y >= std::abs(mapped.x) && mapped.y >= std::abs(mapped.z)) { // top // texCoords[i][j][0] = (mapped.x / mapped.y + 1) / 2 / 4 + padding_x; // texCoords[i][j][1] = (mapped.z / mapped.y + 1) / 2 / 3; // } else if (mapped.z >= std::abs(mapped.x) && mapped.z >= std::abs(mapped.y)) { // front // texCoords[i][j][0] = (mapped.x / mapped.z + 1) / 2 / 4 + padding_x; // texCoords[i][j][1] = (-mapped.y / mapped.z + 1) / 2 / 3 + padding_y; // } else if (mapped.x <= -std::abs(mapped.y) && mapped.x <= -std::abs(mapped.z)) { // left // texCoords[i][j][0] = (-mapped.z / mapped.x + 1) / 2 / 4; // texCoords[i][j][1] = (mapped.y / mapped.x + 1) / 2 / 3 + padding_y; // } else if (mapped.y <= -std::abs(mapped.x) && mapped.y <= -std::abs(mapped.z)) { // bottom // texCoords[i][j][0] = (-mapped.x / mapped.y + 1) / 2 / 4 + padding_x; // texCoords[i][j][1] = (mapped.z / mapped.y + 1) / 2 / 3 + padding_y * 2; // } else if (mapped.z <= -std::abs(mapped.x) && mapped.z <= -std::abs(mapped.y)) { // back // texCoords[i][j][0] = (mapped.x / mapped.z + 1) / 2 / 4 + padding_x * 3; // texCoords[i][j][1] = (mapped.y / mapped.z + 1) / 2 / 3 + padding_y; // } } glEnable(GL_TEXTURE_2D); for (int i = 0; i < LOD; i++) { glBegin(GL_QUAD_STRIP); for (int j = 0; j <= LOD; j++) { glTexCoord2dv(texCoords[i][j]); glVertex3dv(surfacePoints[i][j]); glTexCoord2dv(texCoords[i+1][j]); glVertex3dv(surfacePoints[i+1][j]); } glEnd(); } glDisable(GL_TEXTURE_2D); }