void RadiantSelectionSystem::keyChanged() { if (!nothingSelected()) { pivotChanged(); ConstructPivot(); } }
/* greebo: This is called by the ManipulateObserver class on the mouseDown event. It checks, if a manipulator * can be selected where the mouse is pointing to. */ bool RadiantSelectionSystem::SelectManipulator(const View& view, const Vector2& device_point, const Vector2& device_epsilon) { if (!nothingSelected() || (ManipulatorMode() == eDrag && Mode() == eComponent)) { // Unselect any currently selected manipulators to be sure _manipulator->setSelected(false); // Test, if the current manipulator can be selected if (!nothingSelected() || (ManipulatorMode() == eDrag && Mode() == eComponent)) { View scissored(view); ConstructSelectionTest(scissored, Rectangle::ConstructFromPoint(device_point, device_epsilon)); // The manipulator class checks on its own, if any of its components can be selected _manipulator->testSelect(scissored, GetPivot2World()); } // Save the pivot2world matrix startMove(); // This is true, if a manipulator could be selected _pivotMoving = _manipulator->isSelected(); // is a manipulator selected / the pivot moving? if (_pivotMoving) { Pivot2World pivot; pivot.update(GetPivot2World(), view.GetModelview(), view.GetProjection(), view.GetViewport()); _manip2pivotStart = _pivot2worldStart.getFullInverse().getMultipliedBy(pivot._worldSpace); Matrix4 device2manip; ConstructDevice2Manip(device2manip, _pivot2worldStart, view.GetModelview(), view.GetProjection(), view.GetViewport()); _manipulator->getActiveComponent()->Construct(device2manip, device_point[0], device_point[1]); _deviceStart = Vector2(device_point[0], device_point[1]); _undoBegun = false; } SceneChangeNotify(); } return _pivotMoving; }
/* greebo: This is called by the ManipulateObserver class on the mouseDown event. It checks, if a manipulator * can be selected where the mouse is pointing to. */ bool RadiantSelectionSystem::SelectManipulator(const View& view, const float device_point[2], const float device_epsilon[2]) { if (!nothingSelected() || (ManipulatorMode() == eDrag && Mode() == eComponent)) { #if defined (DEBUG_SELECTION) g_render_clipped.destroy(); #endif // Unselect any currently selected manipulators to be sure _manipulator->setSelected(false); // Test, if the current manipulator can be selected if (!nothingSelected() || (ManipulatorMode() == eDrag && Mode() == eComponent)) { View scissored(view); ConstructSelectionTest(scissored, SelectionBoxForPoint(device_point, device_epsilon)); // The manipulator class checks on its own, if any of its components can be selected _manipulator->testSelect(scissored, GetPivot2World()); } // Save the pivot2world matrix startMove(); // This is true, if a manipulator could be selected _pivotMoving = _manipulator->isSelected(); // is a manipulator selected / the pivot moving? if (_pivotMoving) { Pivot2World pivot; pivot.update(GetPivot2World(), view.GetModelview(), view.GetProjection(), view.GetViewport()); _manip2pivotStart = matrix4_multiplied_by_matrix4(matrix4_full_inverse(_pivot2worldStart), pivot.m_worldSpace); Matrix4 device2manip; ConstructDevice2Manip(device2manip, _pivot2worldStart, view.GetModelview(), view.GetProjection(), view.GetViewport()); _manipulator->GetManipulatable()->Construct(device2manip, device_point[0], device_point[1]); _undoBegun = false; } SceneChangeNotify(); } return _pivotMoving; }
/* greebo: This calculates and constructs the pivot point of the selection. * It cycles through all selected objects and creates its AABB. The origin point of the AABB * is basically the pivot point. Pivot2World is therefore a translation from (0,0,0) to the calculated origin. * * The pivot point is also snapped to the grid. */ void RadiantSelectionSystem::ConstructPivot() const { if (!_pivotChanged || _pivotMoving) return; _pivotChanged = false; Vector3 objectPivot; if (!nothingSelected()) { { // Create a local variable where the aabb information is stored AABB bounds; // Traverse through the selection and update the <bounds> variable if (Mode() == eComponent) { GlobalSceneGraph().traverse(BoundsSelectedComponent(bounds)); } else { GlobalSceneGraph().traverse(BoundsSelected(bounds)); } // the <bounds> variable now contains the AABB of the selection, retrieve the origin objectPivot = bounds.origin; } // Snap the pivot point to the grid vector3_snap(objectPivot, GlobalGrid().getGridSize()); // The pivot2world matrix is just a translation from the world origin (0,0,0) to the object pivot _pivot2world = Matrix4::getTranslation(objectPivot); // Only rotation and scaling need further calculations switch (_manipulatorMode) { case eTranslate: break; case eRotate: if (Mode() == eComponent) { matrix4_assign_rotation_for_pivot(_pivot2world, _componentSelection.back()); } else { matrix4_assign_rotation_for_pivot(_pivot2world, _selection.back()); } break; case eScale: if (Mode() == eComponent) { matrix4_assign_rotation_for_pivot(_pivot2world, _componentSelection.back()); } else { matrix4_assign_rotation_for_pivot(_pivot2world, _selection.back()); } break; default: break; } // switch } }
/* greebo: Renders the currently active manipulator by setting the render state and * calling the manipulator's render method */ void RadiantSelectionSystem::renderSolid(RenderableCollector& collector, const VolumeTest& volume) const { if (!nothingSelected()) { collector.highlightFaces(false); collector.highlightPrimitives(false); collector.SetState(_state, RenderableCollector::eWireframeOnly); collector.SetState(_state, RenderableCollector::eFullMaterials); _manipulator->render(collector, volume, GetPivot2World()); } }
void ROITreeView::mousePressEvent(QMouseEvent *event) { QModelIndex item = indexAt( event->pos() ); bool selected = selectionModel()->isSelected( indexAt( event->pos() ) ); QTreeView::mousePressEvent( event ); if ( ( item.row() == -1 && item.column() == -1 ) || selected ) { clearSelection(); const QModelIndex index; selectionModel()->setCurrentIndex( index, QItemSelectionModel::Select ); emit nothingSelected(); } repaint(); }
// Applies the scaling vector <scaling> to the current selection, this is called by the according ManipulatorComponents void RadiantSelectionSystem::scale(const Vector3& scaling) { // Check if anything is selected if (!nothingSelected()) { // Store the scaling vector internally _scale = scaling; // Pass the scale to the according traversor if (Mode() == eComponent) { Scene_Scale_Component_Selected(GlobalSceneGraph(), _scale, _pivot2world.t().getVector3()); } else { Scene_Scale_Selected(GlobalSceneGraph(), _scale, _pivot2world.t().getVector3()); } // Update the scene views SceneChangeNotify(); } }
/* greebo: Renders the currently active manipulator by setting the render state and * calling the manipulator's render method */ void RadiantSelectionSystem::renderSolid(Renderer& renderer, const VolumeTest& volume) const { if (!nothingSelected()) { // TODO: Don't render transparent faces textures invisible renderer.Highlight(Renderer::ePrimitive, false); renderer.Highlight(Renderer::eFace, false); renderer.SetState(_state, Renderer::eWireframeOnly); renderer.SetState(_state, Renderer::eFullMaterials); _manipulator->render(renderer, volume, GetPivot2World()); } #if defined(DEBUG_SELECTION) renderer.SetState(g_state_clipped, Renderer::eWireframeOnly); renderer.SetState(g_state_clipped, Renderer::eFullMaterials); renderer.addRenderable(g_render_clipped, g_render_clipped.m_world); #endif }
// Applies the rotation vector <rotation> to the current selection void RadiantSelectionSystem::rotate(const Quaternion& rotation) { // Check if there is anything to do if (!nothingSelected()) { // Store the quaternion internally _rotation = rotation; // Perform the rotation according to the current mode if (Mode() == eComponent) { Scene_Rotate_Component_Selected(GlobalSceneGraph(), _rotation, _pivot2world.t().getVector3()); matrix4_assign_rotation_for_pivot(_pivot2world, _componentSelection.ultimate()); } else { Scene_Rotate_Selected(GlobalSceneGraph(), _rotation, _pivot2world.t().getVector3()); matrix4_assign_rotation_for_pivot(_pivot2world, _selection.ultimate()); } // Update the views SceneChangeNotify(); } }
// Applies the translation vector <translation> to the current selection void RadiantSelectionSystem::translate(const Vector3& translation) { // Check if we have anything to do at all if (!nothingSelected()) { // Store the translation vector, so that the outputTranslation member method can access it _translation = translation; // Get the current pivot matrix and multiply it by the translation matrix defined by <translation>. _pivot2world = _pivot2worldStart; _pivot2world.translateBy(translation); // Call the according scene graph traversors and pass the translation vector if (Mode() == eComponent) { Scene_Translate_Component_Selected(GlobalSceneGraph(), _translation); } else { Scene_Translate_Selected(GlobalSceneGraph(), _translation); } // Update the scene so that the changes are made visible SceneChangeNotify(); } }
/* greebo: This calculates and constructs the pivot point of the selection. * It cycles through all selected objects and creates its AABB. The origin point of the AABB * is basically the pivot point. Pivot2World is therefore a translation from (0,0,0) to the calculated origin. * * The pivot point is also snapped to the grid. */ void RadiantSelectionSystem::ConstructPivot() { if (!_pivotChanged || _pivotMoving) return; _pivotChanged = false; Vector3 objectPivot; if (!nothingSelected()) { if (_selectionInfo.entityCount == 1 && _selectionInfo.totalCount == 1 && registry::getValue<bool>(RKEY_ROTATION_PIVOT)) { // Test, if a single entity is selected scene::INodePtr node = ultimateSelected(); Entity* entity = Node_getEntity(node); if (entity != NULL) { objectPivot = string::convert<Vector3>( entity->getKeyValue("origin") ); } } else { // Create a local variable where the aabb information is stored AABB bounds; // Traverse through the selection and update the <bounds> variable if (Mode() == eComponent) { ComponentBoundsAccumulator walker; foreachSelected(walker); bounds = walker.getBounds(); } else { // greebo: Traverse the current selection to accumulate the AABB BoundsAccumulator walker; foreachSelected(walker); bounds = walker.getBounds(); } // the <bounds> variable now contains the AABB of the selection, retrieve the origin objectPivot = bounds.origin; } // Snap the pivot point to the grid (greebo: disabled this (issue #231)) //vector3_snap(objectPivot, GlobalGrid().getGridSize()); // The pivot2world matrix is just a translation from the world origin (0,0,0) to the object pivot _pivot2world = Matrix4::getTranslation(objectPivot); // Only rotation and scaling need further calculations switch (_manipulatorMode) { case eTranslate: break; case eRotate: if (Mode() == eComponent) { matrix4_assign_rotation_for_pivot(_pivot2world, _componentSelection.ultimate()); } else { matrix4_assign_rotation_for_pivot(_pivot2world, _selection.ultimate()); } break; case eScale: if (Mode() == eComponent) { matrix4_assign_rotation_for_pivot(_pivot2world, _componentSelection.ultimate()); } else { matrix4_assign_rotation_for_pivot(_pivot2world, _selection.ultimate()); } break; default: break; } // switch } }