/****************************************************************************** * Computes the bounding box of the the 3D visual elements * shown only in the interactive viewports. ******************************************************************************/ Box3 ViewportSceneRenderer::boundingBoxInteractive(TimePoint time, Viewport* viewport) { OVITO_CHECK_POINTER(viewport); Box3 bb; // Visit all pipeline objects in the scene. renderDataset()->sceneRoot()->visitObjectNodes([this, viewport, time, &bb](ObjectNode* node) -> bool { // Ignore node if it is the view node of the viewport or if it is the target of the view node. if(viewport->viewNode()) { if(viewport->viewNode() == node || viewport->viewNode()->lookatTargetNode() == node) return true; } // Evaluate geometry pipeline of object node. const PipelineFlowState& state = node->evalPipeline(time); for(const auto& dataObj : state.objects()) { for(DisplayObject* displayObj : dataObj->displayObjects()) { if(displayObj && displayObj->isEnabled()) { TimeInterval interval; bb.addBox(displayObj->viewDependentBoundingBox(time, viewport, dataObj, node, state).transformed(node->getWorldTransform(time, interval))); } } } if(PipelineObject* pipelineObj = dynamic_object_cast<PipelineObject>(node->dataProvider())) boundingBoxModifiers(pipelineObj, node, bb); return true; }); // Include visual geometry of input mode overlays in bounding box. MainWindow* mainWindow = viewport->dataset()->mainWindow(); if(mainWindow) { for(const auto& handler : mainWindow->viewportInputManager()->stack()) { if(handler->hasOverlay()) bb.addBox(handler->overlayBoundingBox(viewport, this)); } } // Include construction grid in bounding box. if(viewport->isGridVisible()) { FloatType gridSpacing; Box2I gridRange; std::tie(gridSpacing, gridRange) = determineGridRange(viewport); if(gridSpacing > 0) { bb.addBox(viewport->gridMatrix() * Box3( Point3(gridRange.minc.x() * gridSpacing, gridRange.minc.y() * gridSpacing, 0), Point3(gridRange.maxc.x() * gridSpacing, gridRange.maxc.y() * gridSpacing, 0))); } } return bb; }
/****************************************************************************** * Computes the bounding box of the 3d visual viewport overlay rendered by the input mode. ******************************************************************************/ Box3 ParticleInformationInputMode::overlayBoundingBox(Viewport* vp, ViewportSceneRenderer* renderer) { Box3 bbox = ViewportInputMode::overlayBoundingBox(vp, renderer); for(const auto& pickedParticle : _pickedParticles) bbox.addBox(selectionMarkerBoundingBox(vp, pickedParticle)); return bbox; }
/****************************************************************************** * Renders the modifier's visual representation and computes its bounding box. ******************************************************************************/ Box3 SliceModifier::renderVisual(TimePoint time, ObjectNode* contextNode, SceneRenderer* renderer) { TimeInterval interval; Box3 bb = contextNode->localBoundingBox(time); if(bb.isEmpty()) return Box3(); Plane3 plane = slicingPlane(time, interval); FloatType sliceWidth = 0; if(_widthCtrl) sliceWidth = _widthCtrl->getFloatValue(time, interval); ColorA color(0.8f, 0.3f, 0.3f); if(sliceWidth <= 0) { return renderPlane(renderer, plane, bb, color); } else { plane.dist += sliceWidth / 2; Box3 box = renderPlane(renderer, plane, bb, color); plane.dist -= sliceWidth; box.addBox(renderPlane(renderer, plane, bb, color)); return box; } }
/****************************************************************************** * Returns the bounding box that includes all selected nodes. ******************************************************************************/ Box3 SelectionSet::boundingBox(TimePoint time) const { Box3 bb; for(SceneNode* node : nodes()) { // Get node's world bounding box // and add it to global box. bb.addBox(node->worldBoundingBox(time)); } return bb; }
/****************************************************************************** * Returns the world space point around which the viewport camera orbits. ******************************************************************************/ Point3 ViewportConfiguration::orbitCenter() { // Update orbiting center. if(orbitCenterMode() == ORBIT_SELECTION_CENTER) { Box3 selectionBoundingBox; for(SceneNode* node : dataset()->selection()->nodes()) { selectionBoundingBox.addBox(node->worldBoundingBox(dataset()->animationSettings()->time())); } if(!selectionBoundingBox.isEmpty()) return selectionBoundingBox.center(); else { Box3 sceneBoundingBox = dataset()->sceneRoot()->worldBoundingBox(dataset()->animationSettings()->time()); if(!sceneBoundingBox.isEmpty()) return sceneBoundingBox.center(); } } else if(orbitCenterMode() == ORBIT_USER_DEFINED) { return _userOrbitCenter; } return Point3::Origin(); }