/* 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 } }