Node rotation/scale now transforms correctly around the pivot point
This commit is contained in:
parent
511a2d8c1f
commit
568cd67994
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,15 @@ CRotateNodeCommand::CRotateNodeCommand()
|
|||
{
|
||||
}
|
||||
|
||||
CRotateNodeCommand::CRotateNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& rkNodes, const CVector3f& /*rkPivot*/, const CQuaternion& rkDelta, ETransformSpace TransformSpace)
|
||||
CRotateNodeCommand::CRotateNodeCommand(
|
||||
INodeEditor *pEditor,
|
||||
const QList<CSceneNode*>& 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 QList<CSceneN
|
|||
Rotate.pNode = pNode;
|
||||
Rotate.InitialPos = pNode->LocalPosition();
|
||||
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);
|
||||
|
|
|
@ -23,7 +23,7 @@ class CRotateNodeCommand : public IUndoCommand
|
|||
|
||||
public:
|
||||
CRotateNodeCommand();
|
||||
CRotateNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& rkNodes, const CVector3f& rkPivot, const CQuaternion& rkDelta, ETransformSpace TransformSpace);
|
||||
CRotateNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& rkNodes, bool UsePivot, const CVector3f& rkPivot, const CQuaternion& rkPivotRotation, const CQuaternion& rkDelta, ETransformSpace TransformSpace);
|
||||
~CRotateNodeCommand();
|
||||
int id() const;
|
||||
bool mergeWith(const QUndoCommand *pkOther);
|
||||
|
|
|
@ -9,7 +9,7 @@ CScaleNodeCommand::CScaleNodeCommand()
|
|||
{
|
||||
}
|
||||
|
||||
CScaleNodeCommand::CScaleNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& rkNodes, const CVector3f& /*rkPivot*/, const CVector3f& rkDelta)
|
||||
CScaleNodeCommand::CScaleNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& rkNodes, bool UsePivot, const CVector3f& rkPivot, const CVector3f& rkDelta)
|
||||
: IUndoCommand("Scale"),
|
||||
mpEditor(pEditor),
|
||||
mCommandEnded(false)
|
||||
|
@ -22,6 +22,12 @@ CScaleNodeCommand::CScaleNodeCommand(INodeEditor *pEditor, const QList<CSceneNod
|
|||
Scale.pNode = pNode;
|
||||
Scale.InitialPos = pNode->LocalPosition();
|
||||
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();
|
||||
|
|
|
@ -23,7 +23,7 @@ class CScaleNodeCommand : public IUndoCommand
|
|||
|
||||
public:
|
||||
CScaleNodeCommand();
|
||||
CScaleNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& rkNodes, const CVector3f& rkPivot, const CVector3f& rkDelta);
|
||||
CScaleNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& rkNodes, bool UsePivot, const CVector3f& rkPivot, const CVector3f& rkDelta);
|
||||
~CScaleNodeCommand();
|
||||
int id() const;
|
||||
bool mergeWith(const QUndoCommand *pkOther);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,5 @@ int main(int argc, char *argv[])
|
|||
|
||||
// Execute application
|
||||
App.InitEditor();
|
||||
App.ProjectDialog()->show();
|
||||
return App.exec();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue