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;
}
Пример #3
0
/* 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;
}
Пример #4
0
/* 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();
    }
}
Пример #8
0
/* 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
    }
}