/****************************************************************************** * Aligns the slicing plane to the viewing direction. ******************************************************************************/ void SliceModifierEditor::onAlignPlaneToView() { TimeInterval interval; Viewport* vp = dataset()->viewportConfig()->activeViewport(); if(!vp) return; // Get the object to world transformation for the currently selected object. ObjectNode* node = dynamic_object_cast<ObjectNode>(dataset()->selection()->front()); if(!node) return; const AffineTransformation& nodeTM = node->getWorldTransform(dataset()->animationSettings()->time(), interval); // Get the base point of the current slicing plane in local coordinates. SliceModifier* mod = static_object_cast<SliceModifier>(editObject()); if(!mod) return; Plane3 oldPlaneLocal = mod->slicingPlane(dataset()->animationSettings()->time(), interval); Point3 basePoint = Point3::Origin() + oldPlaneLocal.normal * oldPlaneLocal.dist; // Get the orientation of the projection plane of the current viewport. Vector3 dirWorld = -vp->cameraDirection(); Plane3 newPlaneLocal(basePoint, nodeTM.inverse() * dirWorld); if(std::abs(newPlaneLocal.normal.x()) < FLOATTYPE_EPSILON) newPlaneLocal.normal.x() = 0; if(std::abs(newPlaneLocal.normal.y()) < FLOATTYPE_EPSILON) newPlaneLocal.normal.y() = 0; if(std::abs(newPlaneLocal.normal.z()) < FLOATTYPE_EPSILON) newPlaneLocal.normal.z() = 0; undoableTransaction(tr("Align plane to view"), [mod, &newPlaneLocal]() { mod->setNormal(newPlaneLocal.normal.normalized()); mod->setDistance(newPlaneLocal.dist); }); }
/****************************************************************************** * Aligns the current viewing direction to the slicing plane. ******************************************************************************/ void SliceModifierEditor::onAlignViewToPlane() { TimeInterval interval; Viewport* vp = dataset()->viewportConfig()->activeViewport(); if(!vp) return; // Get the object to world transformation for the currently selected object. ObjectNode* node = dynamic_object_cast<ObjectNode>(dataset()->selection()->front()); if(!node) return; const AffineTransformation& nodeTM = node->getWorldTransform(dataset()->animationSettings()->time(), interval); // Transform the current slicing plane to the world coordinate system. SliceModifier* mod = static_object_cast<SliceModifier>(editObject()); if(!mod) return; Plane3 planeLocal = mod->slicingPlane(dataset()->animationSettings()->time(), interval); Plane3 planeWorld = nodeTM * planeLocal; // Calculate the intersection point of the current viewing direction with the current slicing plane. Ray3 viewportRay(vp->cameraPosition(), vp->cameraDirection()); FloatType t = planeWorld.intersectionT(viewportRay); Point3 intersectionPoint; if(t != FLOATTYPE_MAX) intersectionPoint = viewportRay.point(t); else intersectionPoint = Point3::Origin() + nodeTM.translation(); if(vp->isPerspectiveProjection()) { FloatType distance = (vp->cameraPosition() - intersectionPoint).length(); vp->setViewType(Viewport::VIEW_PERSPECTIVE); vp->setCameraDirection(-planeWorld.normal); vp->setCameraPosition(intersectionPoint + planeWorld.normal * distance); } else { vp->setViewType(Viewport::VIEW_ORTHO); vp->setCameraDirection(-planeWorld.normal); } vp->zoomToSelectionExtents(); }