NavigationPtr ViewWrapper3D::getNavigation() { CameraControlPtr camera3D(new CameraControl()); camera3D->setView(mView); return NavigationPtr(new Navigation(mServices, camera3D)); }
void View::drawSkeleton(bool drawTransparent) const { if (doc->mesh.balls.isEmpty()) return; // draw model if (drawTransparent) { // set depth buffer before so we never blend the same pixel twice glClear(GL_DEPTH_BUFFER_BIT); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); doc->mesh.drawKeyBalls(); if (drawInterpolated) doc->mesh.drawInBetweenBalls(); else doc->mesh.drawBones(); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // draw blended key balls and bones glDepthFunc(GL_EQUAL); glEnable(GL_BLEND); glEnable(GL_LIGHTING); doc->mesh.drawKeyBalls(0.25); glColor4f(0.75, 0.75, 0.75, 0.25); if (drawInterpolated) doc->mesh.drawInBetweenBalls(); else doc->mesh.drawBones(); glDisable(GL_LIGHTING); glDisable(GL_BLEND); glDepthFunc(GL_LESS); } else { // draw key balls and in-between balls glEnable(GL_LIGHTING); doc->mesh.drawKeyBalls(); glColor3f(0.75, 0.75, 0.75); if (drawInterpolated) doc->mesh.drawInBetweenBalls(); else doc->mesh.drawBones(); glDisable(GL_LIGHTING); } // draw box around selected ball if (selectedBall != -1) { const Ball &selection = doc->mesh.balls[selectedBall]; float radius = selection.maxRadius(); // enable line drawing glDepthMask(GL_FALSE); glEnable(GL_BLEND); if (mode == MODE_ADD_JOINTS || mode == MODE_ANIMATE_MESH) { glDisable(GL_DEPTH_TEST); glColor4f(0, 0, 0, 0.25); drawWireCube(selection.center - radius, selection.center + radius); glEnable(GL_DEPTH_TEST); glColor3f(0, 0, 0); drawWireCube(selection.center - radius, selection.center + radius); // find the currently selected cube face and display the cursor Raytracer tracer; Vector3 ray = tracer.getRayForPixel(mouseX, mouseY); HitTest result; if (Raytracer::hitTestCube(selection.center - radius, selection.center + radius, currentCamera->eye, ray, result)) { float size = (result.hit - currentCamera->eye).length() * CURSOR_SIZE / height(); Vector2 angles = result.normal.toAngles(); glColor3f(0, 0, 0); glDisable(GL_DEPTH_TEST); glPushMatrix(); glTranslatef(result.hit.x, result.hit.y, result.hit.z); glRotatef(90 - angles.x * 180 / M_PI, 0, 1, 0); glRotatef(-angles.y * 180 / M_PI, 1, 0, 0); glScalef(size, size, size); drawMoveCursor(); glPopMatrix(); glEnable(GL_DEPTH_TEST); } } else if (mode == MODE_SCALE_JOINTS) { // display the cursor Raytracer tracer; Vector3 ray = tracer.getRayForPixel(mouseX, mouseY); HitTest result; if (Raytracer::hitTestSphere(selection.center, radius, currentCamera->eye, ray, result)) { camera2D(); glColor3f(0, 0, 0); glDisable(GL_DEPTH_TEST); glTranslatef(mouseX, mouseY, 0); glScalef(CURSOR_SIZE, CURSOR_SIZE, 0); drawScaleCursor(); glEnable(GL_DEPTH_TEST); camera3D(); } Vector3 delta = currentCamera->eye - selection.center; Vector2 angles = delta.toAngles(); // adjust the radius to the profile of the ball as seen from the camera radius = radius / sinf(acosf(radius / delta.length())); // draw a circle around the selected ball radius *= 1.1; glPushMatrix(); glTranslatef(selection.center.x, selection.center.y, selection.center.z); glRotatef(90 - angles.x * 180 / M_PI, 0, 1, 0); glRotatef(-angles.y * 180 / M_PI, 1, 0, 0); glScalef(radius, radius, radius); glDisable(GL_DEPTH_TEST); glColor4f(0, 0, 0, 0.25); drawWireDisk(); glEnable(GL_DEPTH_TEST); glColor3f(0, 0, 0); drawWireDisk(); glPopMatrix(); } // disable line drawing glDisable(GL_BLEND); glDepthMask(GL_TRUE); } }
void View::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); camera3D(); // Don't paint if we haven't gotten a resize yet #ifdef USE_SHADER_MATERIALS if (normalDepthTexture.getWidth() * normalDepthTexture.getHeight() == 0) return; #endif // position lights float position0[4] = { 0, 1, 0, 0 }; float position1[4] = { 0, -1, 0, 0 }; glLightfv(GL_LIGHT0, GL_POSITION, position0); glLightfv(GL_LIGHT1, GL_POSITION, position1); if (mode == MODE_SCULPT_MESH) { #ifdef USE_SHADER_MATERIALS normalDepthTexture.startDrawingTo(depthTexture); normalDepthShader.use(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); drawMesh(true); normalDepthShader.unuse(); normalDepthTexture.stopDrawingTo(); camera2D(); glDepthFunc(GL_ALWAYS); normalDepthTexture.bind(0); depthTexture.bind(1); finalCompositeShaders[currentMaterial].use(); finalCompositeShaders[currentMaterial].uniform("windowSize", width(), height()); finalCompositeShaders[currentMaterial].texture("depthTexture", 1); drawFullscreenQuad(); finalCompositeShaders[currentMaterial].unuse(); depthTexture.unbind(1); normalDepthTexture.unbind(0); glDepthFunc(GL_LESS); camera3D(); #else drawMesh(true); #endif drawGroundPlane(); } else if (mode == MODE_VIEW_MESH || mode == MODE_ANIMATE_MESH) { drawMesh(false); drawGroundPlane(); drawSkeleton(true); } else { drawSkeleton(false); drawGroundPlane(); } if (drawToolDebug) foreach (Tool *tool, tools) tool->drawDebug(mouseX, mouseY); }