Esempio n. 1
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
	}
}
// 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();
    }
}
/* 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
    }
}