/* 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;
}
示例#2
0
void RotateManipulator::testSelect (const View& view, const Matrix4& pivot2world)
{
    m_pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport());
    updateCircleTransforms();

    SelectionPool selector;

    {
        {
            Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_local2world_x));

            SelectionIntersection best;
            LineStrip_BestPoint(local2view, m_circle_x.m_vertices.data(), m_circle_x.m_vertices.size(), best);
            selector.addSelectable(best, &m_selectable_x);
        }

        {
            Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_local2world_y));

            SelectionIntersection best;
            LineStrip_BestPoint(local2view, m_circle_y.m_vertices.data(), m_circle_y.m_vertices.size(), best);
            selector.addSelectable(best, &m_selectable_y);
        }

        {
            Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_local2world_z));

            SelectionIntersection best;
            LineStrip_BestPoint(local2view, m_circle_z.m_vertices.data(), m_circle_z.m_vertices.size(), best);
            selector.addSelectable(best, &m_selectable_z);
        }
    }

    {
        Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_viewpointSpace));

        {
            SelectionIntersection best;
            LineLoop_BestPoint(local2view, m_circle_screen.m_vertices.data(), m_circle_screen.m_vertices.size(), best);
            selector.addSelectable(best, &m_selectable_screen);
        }

        {
            SelectionIntersection best;
            Circle_BestPoint(local2view, eClipCullCW, m_circle_sphere.m_vertices.data(),
                             m_circle_sphere.m_vertices.size(), best);
            selector.addSelectable(best, &m_selectable_sphere);
        }
    }

    m_axis_screen = m_pivot.m_axis_screen;

    if (!selector.failed()) {
        (*selector.begin()).second->setSelected(true);
    }
}
示例#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;
}
/* greebo: This "moves" the current selection. It calculates the device manipulation matrix
 * and passes it to the currently active Manipulator.
 */
void RadiantSelectionSystem::MoveSelected(const View& view, const Vector2& devicePoint)
{
    // Check, if the active manipulator is selected in the first place
    if (_manipulator->isSelected()) {
        // Initalise the undo system, if not yet done
        if (!_undoBegun) {
            _undoBegun = true;
            GlobalUndoSystem().start();
        }

        Matrix4 device2manip;
        ConstructDevice2Manip(device2manip, _pivot2worldStart, view.GetModelview(), view.GetProjection(), view.GetViewport());

        Vector2 constrainedDevicePoint(devicePoint);

        // Constrain the movement to the axes, if the modifier is held
        if ((GlobalEventManager().getModifierState() & GDK_SHIFT_MASK) != 0)
        {
            // Get the movement delta relative to the start point
            Vector2 delta = devicePoint - _deviceStart;

            // Set the "minor" value of the movement to zero
            if (fabs(delta[0]) > fabs(delta[1])) {
                // X axis is major, reset the y-value to the start
                delta[1] = 0;
            }
            else {
                // Y axis is major, reset the x-value to the start
                delta[0] = 0;
            }

            // Add the modified delta to the start point, constrained to one axis
            constrainedDevicePoint = _deviceStart + delta;
        }

        // Get the manipulatable from the currently active manipulator (done by selection test)
        // and call the Transform method (can be anything)
        _manipulator->getActiveComponent()->Transform(_manip2pivotStart, device2manip, constrainedDevicePoint[0], constrainedDevicePoint[1]);

        _requestWorkZoneRecalculation = true;
        _requestSceneGraphChange = true;

        requestIdleCallback();
    }
}
示例#5
0
void ScaleManipulator::testSelect (const View& view, const Matrix4& pivot2world)
{
    m_pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport());

    SelectionPool selector;

    {
        Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_worldSpace));

        {
            SelectionIntersection best;
            Line_BestPoint(local2view, m_arrow_x.m_line, best);
            selector.addSelectable(best, &m_selectable_x);
        }

        {
            SelectionIntersection best;
            Line_BestPoint(local2view, m_arrow_y.m_line, best);
            selector.addSelectable(best, &m_selectable_y);
        }

        {
            SelectionIntersection best;
            Line_BestPoint(local2view, m_arrow_z.m_line, best);
            selector.addSelectable(best, &m_selectable_z);
        }
    }

    {
        Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_viewpointSpace));

        {
            SelectionIntersection best;
            Quad_BestPoint(local2view, eClipCullCW, m_quad_screen.m_quad, best);
            selector.addSelectable(best, &m_selectable_screen);
        }
    }

    if (!selector.failed()) {
        (*selector.begin()).second->setSelected(true);
    }
}
示例#6
0
/* greebo: This "moves" the current selection. It calculates the device manipulation matrix
 * and passes it to the currently active Manipulator.
 */
void RadiantSelectionSystem::MoveSelected(const View& view, const float device_point[2]) {
	// Check, if the active manipulator is selected in the first place
	if (_manipulator->isSelected()) {
		// Initalise the undo system
		if (!_undoBegun) {
			_undoBegun = true;
			GlobalUndoSystem().start();
		}

		Matrix4 device2manip;
		ConstructDevice2Manip(device2manip, _pivot2worldStart, view.GetModelview(), view.GetProjection(), view.GetViewport());

		// Get the manipulatable from the currently active manipulator (done by selection test)
		// and call the Transform method (can be anything)
		_manipulator->GetManipulatable()->Transform(_manip2pivotStart, device2manip, device_point[0], device_point[1]);

		_requestWorkZoneRecalculation = true;

		requestIdleCallback();
	}
}
示例#7
0
void TranslateManipulator::testSelect (const View& view, const Matrix4& pivot2world)
{
    m_pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport());

    SelectionPool selector;

    Vector3 x = m_pivot.m_worldSpace.x().getVector3().getNormalised();
    bool show_x = manipulator_show_axis(m_pivot, x);

    Vector3 y = m_pivot.m_worldSpace.y().getVector3().getNormalised();
    bool show_y = manipulator_show_axis(m_pivot, y);

    Vector3 z = m_pivot.m_worldSpace.z().getVector3().getNormalised();
    bool show_z = manipulator_show_axis(m_pivot, z);

    {
        Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_viewpointSpace));

        {
            SelectionIntersection best;
            Quad_BestPoint(local2view, eClipCullCW, m_quad_screen.m_quad, best);
            if (best.valid()) {
                best = SelectionIntersection(0, 0);
                selector.addSelectable(best, &m_selectable_screen);
            }
        }
    }

    {
        Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_worldSpace));

#if defined(DEBUG_SELECTION)
        g_render_clipped.construct(view.GetViewMatrix());
#endif

        if (show_x) {
            SelectionIntersection best;
            Line_BestPoint(local2view, m_arrow_x.m_line, best);
            Triangles_BestPoint(local2view, eClipCullCW, m_arrow_head_x.m_vertices.begin(),
                                m_arrow_head_x.m_vertices.end(), best);
            selector.addSelectable(best, &m_selectable_x);
        }

        if (show_y) {
            SelectionIntersection best;
            Line_BestPoint(local2view, m_arrow_y.m_line, best);
            Triangles_BestPoint(local2view, eClipCullCW, m_arrow_head_y.m_vertices.begin(),
                                m_arrow_head_y.m_vertices.end(), best);
            selector.addSelectable(best, &m_selectable_y);
        }

        if (show_z) {
            SelectionIntersection best;
            Line_BestPoint(local2view, m_arrow_z.m_line, best);
            Triangles_BestPoint(local2view, eClipCullCW, m_arrow_head_z.m_vertices.begin(),
                                m_arrow_head_z.m_vertices.end(), best);
            selector.addSelectable(best, &m_selectable_z);
        }
    }

    if (!selector.failed()) {
        (*selector.begin()).second->setSelected(true);
    }
}
void TranslateManipulator::testSelect(const View& view, const Matrix4& pivot2world) {
    _pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport());

    SelectionPool selector;

    Vector3 x = _pivot._worldSpace.x().getVector3().getNormalised();
    bool show_x = manipulator_show_axis(_pivot, x);

    Vector3 y = _pivot._worldSpace.y().getVector3().getNormalised();
    bool show_y = manipulator_show_axis(_pivot, y);

    Vector3 z = _pivot._worldSpace.z().getVector3().getNormalised();
    bool show_z = manipulator_show_axis(_pivot, z);

    {
		Matrix4 local2view(view.GetViewMatrix().getMultipliedBy(_pivot._viewpointSpace));

      {
        SelectionIntersection best;
        Quad_BestPoint(local2view, eClipCullCW, &_quadScreen.front(), best);
        if(best.valid())
        {
          best = SelectionIntersection(0, 0);
          selector.addSelectable(best, &_selectableScreen);
        }
      }
    }

    {
		Matrix4 local2view(view.GetViewMatrix().getMultipliedBy(_pivot._worldSpace));

      if(show_x)
      {
        SelectionIntersection best;
        Line_BestPoint(local2view, &_arrowX.front(), best);
        Triangles_BestPoint(local2view, eClipCullCW, &_arrowHeadX._vertices.front(), &*(_arrowHeadX._vertices.end()-1)+1, best);
        selector.addSelectable(best, &_selectableX);
      }

      if(show_y)
      {
        SelectionIntersection best;
        Line_BestPoint(local2view, &_arrowY.front(), best);
        Triangles_BestPoint(local2view, eClipCullCW, &_arrowHeadY._vertices.front(), &*(_arrowHeadY._vertices.end()-1)+1, best);
        selector.addSelectable(best, &_selectableY);
      }

      if(show_z)
      {
        SelectionIntersection best;
        Line_BestPoint(local2view, &_arrowZ.front(), best);
        Triangles_BestPoint(local2view, eClipCullCW, &_arrowHeadZ._vertices.front(), &*(_arrowHeadZ._vertices.end()-1)+1, best);
        selector.addSelectable(best, &_selectableZ);
      }
    }

	// greebo: If any of the above arrows could be selected, select the first in the SelectionPool
    if(!selector.failed()) {
      (*selector.begin()).second->setSelected(true);
    } else {
    	Selectable* selectable = NULL;

    	if (registry::getValue<bool>(RKEY_TRANSLATE_CONSTRAINED)) {
	    	// None of the shown arrows (or quad) has been selected, select an axis based on the precedence
	    	Matrix4 local2view(view.GetViewMatrix().getMultipliedBy(_pivot._worldSpace));

	    	// Get the (relative?) distance from the mouse pointer to the manipulator
	    	Vector3 delta = local2view.t().getProjected();

	    	// Get the precedence (which axis has the absolute largest value in it)
	    	bool xGreaterY = (fabs(delta.x()) > fabs(delta.y()));

	    	// The precedence has to be interpreted according to which axes are visible
	    	if (show_z) {
	    		// Either XZ or YZ
	    		if (show_y) {
	    			// YZ
	    			selectable = (xGreaterY) ? &_selectableY : &_selectableZ;
	    		}
	    		else {
	    			// XZ
	    			selectable = (xGreaterY) ? &_selectableX : &_selectableZ;
	    		}
	    	}
	    	else {
	    		// XY
	    		selectable = (xGreaterY) ? &_selectableX : &_selectableY;
	    	}
    	}
    	else {
    		// Don't constrain to axis, choose the freemove translator
    		selectable = &_selectableScreen;
    	}

		// If everything went ok, there is a selectable available, add it
    	if (selectable != NULL) {
    		selector.addSelectable(SelectionIntersection(0,0), selectable);
    		selectable->setSelected(true);
    	}
    }
}