diff --git a/src/Core/Scene/CSceneNode.cpp b/src/Core/Scene/CSceneNode.cpp index f3dd985a..c4a58c6c 100644 --- a/src/Core/Scene/CSceneNode.cpp +++ b/src/Core/Scene/CSceneNode.cpp @@ -291,13 +291,34 @@ void CSceneNode::Rotate(const CQuaternion& rkRotation, ETransformSpace Transform MarkTransformChanged(); } +void CSceneNode::Rotate(const CQuaternion& rkRotation, const CVector3f& rkPivot, const CQuaternion& rkPivotRotation, ETransformSpace TransformSpace) +{ + Rotate(rkRotation, TransformSpace); + + switch (TransformSpace) + { + case eWorldTransform: + mPosition = rkPivot + (rkRotation * (mPosition - rkPivot)); + break; + case eLocalTransform: + mPosition = rkPivot + ((rkPivotRotation * rkRotation * rkPivotRotation.Inverse()) * (mPosition - rkPivot)); + break; + } + MarkTransformChanged(); +} + void CSceneNode::Scale(const CVector3f& rkScale) { - // No support for stretch/skew world-space scaling; local only mScale *= rkScale; MarkTransformChanged(); } +void CSceneNode::Scale(const CVector3f& rkScale, const CVector3f& rkPivot) +{ + mPosition = rkPivot + ((mPosition - rkPivot) * rkScale * rkScale); + Scale(rkScale); +} + void CSceneNode::ForceRecalculateTransform() const { _mCachedTransform = CTransform4f::skIdentity; diff --git a/src/Core/Scene/CSceneNode.h b/src/Core/Scene/CSceneNode.h index 7f96b3c3..04795d1b 100644 --- a/src/Core/Scene/CSceneNode.h +++ b/src/Core/Scene/CSceneNode.h @@ -86,7 +86,9 @@ public: // Transform void Translate(const CVector3f& rkTranslation, ETransformSpace TransformSpace); void Rotate(const CQuaternion& rkRotation, ETransformSpace TransformSpace); + void Rotate(const CQuaternion& rkRotation, const CVector3f& rkPivot, const CQuaternion& rkPivotRotation, ETransformSpace TransformSpace); void Scale(const CVector3f& rkScale); + void Scale(const CVector3f& rkScale, const CVector3f& rkPivot); const CTransform4f& Transform() const; protected: void MarkTransformChanged() const; diff --git a/src/Editor/CEditorApplication.cpp b/src/Editor/CEditorApplication.cpp index 2a3f6f99..cc21e216 100644 --- a/src/Editor/CEditorApplication.cpp +++ b/src/Editor/CEditorApplication.cpp @@ -35,6 +35,8 @@ void CEditorApplication::InitEditor() mpResourceBrowser = new CResourceBrowser(mpWorldEditor); mpProjectDialog = new CProjectOverviewDialog(); connect(mpProjectDialog, SIGNAL(ActiveProjectChanged(CGameProject*)), mpResourceBrowser, SLOT(UpdateStore())); + + mpProjectDialog->show(); } void CEditorApplication::EditResource(CResourceEntry *pEntry) diff --git a/src/Editor/INodeEditor.cpp b/src/Editor/INodeEditor.cpp index 21c933f1..5f7dbca2 100644 --- a/src/Editor/INodeEditor.cpp +++ b/src/Editor/INodeEditor.cpp @@ -330,14 +330,14 @@ void INodeEditor::OnGizmoMoved() case CGizmo::eRotate: { CQuaternion Delta = mGizmo.DeltaRotation(); - mUndoStack.push(new CRotateNodeCommand(this, mpSelection->SelectedNodeList(), CVector3f::skZero, Delta, mRotateSpace)); + mUndoStack.push(new CRotateNodeCommand(this, mpSelection->SelectedNodeList(), true, mGizmo.Position(), mGizmo.Rotation(), Delta, mRotateSpace)); break; } case CGizmo::eScale: { CVector3f Delta = mGizmo.DeltaScale(); - mUndoStack.push(new CScaleNodeCommand(this, mpSelection->SelectedNodeList(), CVector3f::skZero, Delta)); + mUndoStack.push(new CScaleNodeCommand(this, mpSelection->SelectedNodeList(), true, mGizmo.Position(), Delta)); break; } } diff --git a/src/Editor/Undo/CRotateNodeCommand.cpp b/src/Editor/Undo/CRotateNodeCommand.cpp index aea4f136..61609eca 100644 --- a/src/Editor/Undo/CRotateNodeCommand.cpp +++ b/src/Editor/Undo/CRotateNodeCommand.cpp @@ -9,7 +9,15 @@ CRotateNodeCommand::CRotateNodeCommand() { } -CRotateNodeCommand::CRotateNodeCommand(INodeEditor *pEditor, const QList& rkNodes, const CVector3f& /*rkPivot*/, const CQuaternion& rkDelta, ETransformSpace TransformSpace) +CRotateNodeCommand::CRotateNodeCommand( + INodeEditor *pEditor, + const QList& rkNodes, + bool UsePivot, + const CVector3f& rkPivot, + const CQuaternion& rkPivotRotation, + const CQuaternion& rkDelta, + ETransformSpace TransformSpace + ) : IUndoCommand("Rotate"), mpEditor(pEditor), mCommandEnded(false) @@ -22,7 +30,12 @@ CRotateNodeCommand::CRotateNodeCommand(INodeEditor *pEditor, const QListLocalPosition(); Rotate.InitialRot = pNode->LocalRotation(); - pNode->Rotate(rkDelta, TransformSpace); + + if (UsePivot) + pNode->Rotate(rkDelta, rkPivot, rkPivotRotation, TransformSpace); + else + pNode->Rotate(rkDelta, TransformSpace); + Rotate.NewPos = pNode->LocalPosition(); Rotate.NewRot = pNode->LocalRotation(); mNodeList.push_back(Rotate); diff --git a/src/Editor/Undo/CRotateNodeCommand.h b/src/Editor/Undo/CRotateNodeCommand.h index 46aa86fa..b48ed6fb 100644 --- a/src/Editor/Undo/CRotateNodeCommand.h +++ b/src/Editor/Undo/CRotateNodeCommand.h @@ -23,7 +23,7 @@ class CRotateNodeCommand : public IUndoCommand public: CRotateNodeCommand(); - CRotateNodeCommand(INodeEditor *pEditor, const QList& rkNodes, const CVector3f& rkPivot, const CQuaternion& rkDelta, ETransformSpace TransformSpace); + CRotateNodeCommand(INodeEditor *pEditor, const QList& rkNodes, bool UsePivot, const CVector3f& rkPivot, const CQuaternion& rkPivotRotation, const CQuaternion& rkDelta, ETransformSpace TransformSpace); ~CRotateNodeCommand(); int id() const; bool mergeWith(const QUndoCommand *pkOther); diff --git a/src/Editor/Undo/CScaleNodeCommand.cpp b/src/Editor/Undo/CScaleNodeCommand.cpp index 34acd392..05bbff22 100644 --- a/src/Editor/Undo/CScaleNodeCommand.cpp +++ b/src/Editor/Undo/CScaleNodeCommand.cpp @@ -9,7 +9,7 @@ CScaleNodeCommand::CScaleNodeCommand() { } -CScaleNodeCommand::CScaleNodeCommand(INodeEditor *pEditor, const QList& rkNodes, const CVector3f& /*rkPivot*/, const CVector3f& rkDelta) +CScaleNodeCommand::CScaleNodeCommand(INodeEditor *pEditor, const QList& rkNodes, bool UsePivot, const CVector3f& rkPivot, const CVector3f& rkDelta) : IUndoCommand("Scale"), mpEditor(pEditor), mCommandEnded(false) @@ -22,6 +22,12 @@ CScaleNodeCommand::CScaleNodeCommand(INodeEditor *pEditor, const QListLocalPosition(); Scale.InitialScale = pNode->LocalScale(); + + if (UsePivot) + pNode->Scale(rkDelta, rkPivot); + else + pNode->Scale(rkDelta); + pNode->Scale(rkDelta); Scale.NewPos = pNode->LocalPosition(); Scale.NewScale = pNode->LocalScale(); diff --git a/src/Editor/Undo/CScaleNodeCommand.h b/src/Editor/Undo/CScaleNodeCommand.h index 24d821d5..f7c3ba79 100644 --- a/src/Editor/Undo/CScaleNodeCommand.h +++ b/src/Editor/Undo/CScaleNodeCommand.h @@ -23,7 +23,7 @@ class CScaleNodeCommand : public IUndoCommand public: CScaleNodeCommand(); - CScaleNodeCommand(INodeEditor *pEditor, const QList& rkNodes, const CVector3f& rkPivot, const CVector3f& rkDelta); + CScaleNodeCommand(INodeEditor *pEditor, const QList& rkNodes, bool UsePivot, const CVector3f& rkPivot, const CVector3f& rkDelta); ~CScaleNodeCommand(); int id() const; bool mergeWith(const QUndoCommand *pkOther); diff --git a/src/Editor/WorldEditor/CWorldEditor.cpp b/src/Editor/WorldEditor/CWorldEditor.cpp index 45c4439f..7b8625dd 100644 --- a/src/Editor/WorldEditor/CWorldEditor.cpp +++ b/src/Editor/WorldEditor/CWorldEditor.cpp @@ -921,14 +921,14 @@ void CWorldEditor::OnTransformSpinBoxModified(CVector3f Value) case CGizmo::eRotate: { CQuaternion Delta = CQuaternion::FromEuler(Value) * mpSelection->Front()->AbsoluteRotation().Inverse(); - mUndoStack.push(new CRotateNodeCommand(this, mpSelection->SelectedNodeList(), CVector3f::skZero, Delta, mRotateSpace)); + mUndoStack.push(new CRotateNodeCommand(this, mpSelection->SelectedNodeList(), true, mGizmo.Position(), mGizmo.Rotation(), Delta, mRotateSpace)); break; } case CGizmo::eScale: { CVector3f Delta = Value / mpSelection->Front()->AbsoluteScale(); - mUndoStack.push(new CScaleNodeCommand(this, mpSelection->SelectedNodeList(), CVector3f::skZero, Delta)); + mUndoStack.push(new CScaleNodeCommand(this, mpSelection->SelectedNodeList(), true, mGizmo.Position(), Delta)); break; } } diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 55b3ea90..a1bc6220 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -59,6 +59,5 @@ int main(int argc, char *argv[]) // Execute application App.InitEditor(); - App.ProjectDialog()->show(); return App.exec(); }