Scale gizmo transform functionality implemented

This commit is contained in:
parax0 2015-08-28 18:57:24 -04:00
parent 8d633553c9
commit 281a605586
8 changed files with 254 additions and 75 deletions

View File

@ -115,9 +115,9 @@ CQuaternion CQuaternion::FromEuler(CVector3f euler)
quat.y = ((c1 * s2 * c3) - (s1 * c2 * s3));
quat.z = ((s1 * s2 * c3) + (c1 * c2 * s3));*/
CQuaternion x = CQuaternion::FromAxisAngle(euler.x, CVector3f(1,0,0));
CQuaternion y = CQuaternion::FromAxisAngle(euler.y, CVector3f(0,1,0));
CQuaternion z = CQuaternion::FromAxisAngle(euler.z, CVector3f(0,0,1));
CQuaternion x = CQuaternion::FromAxisAngle(Math::DegreesToRadians(euler.x), CVector3f(1,0,0));
CQuaternion y = CQuaternion::FromAxisAngle(Math::DegreesToRadians(euler.y), CVector3f(0,1,0));
CQuaternion z = CQuaternion::FromAxisAngle(Math::DegreesToRadians(euler.z), CVector3f(0,0,1));
CQuaternion quat = z * y * x;
return quat;
@ -127,7 +127,6 @@ CQuaternion CQuaternion::FromAxisAngle(float angle, CVector3f axis)
{
CQuaternion quat;
axis = axis.Normalized();
angle = Math::DegreesToRadians(angle);
float sa = sinf(angle / 2);
quat.w = cosf(angle / 2);

View File

@ -213,8 +213,9 @@ void CSceneNode::Rotate(const CQuaternion& rotation, ETransformSpace transformSp
MarkTransformChanged();
}
void CSceneNode::Scale(const CVector3f& scale, ETransformSpace transformSpace)
void CSceneNode::Scale(const CVector3f& scale)
{
// No support for stretch/skew world-space scaling; local only
mScale *= scale;
MarkTransformChanged();
}

View File

@ -71,7 +71,7 @@ public:
// Transform
void Translate(const CVector3f& translation, ETransformSpace transformSpace);
void Rotate(const CQuaternion& rotation, ETransformSpace transformSpace);
void Scale(const CVector3f& scale, ETransformSpace transformSpace);
void Scale(const CVector3f& scale);
void UpdateTransform();
void ForceRecalculateTransform();
void MarkTransformChanged();

View File

@ -45,7 +45,7 @@ CScriptNode::CScriptNode(CSceneManager *pScene, CSceneNode *pParent, CScriptObje
{
mpVolumePreviewNode = new CModelNode(pScene, this, pVolumeModel);
mpVolumePreviewNode->SetInheritance(true, (VolumeShape == 1), false);
mpVolumePreviewNode->Scale(mpInstance->GetVolume(), eWorldTransform);
mpVolumePreviewNode->Scale(mpInstance->GetVolume());
mpVolumePreviewNode->ForceAlphaEnabled(true);
}
}

View File

@ -25,15 +25,17 @@ CGizmo::CGizmo()
mPosition = CVector3f::skZero;
mRotation = CQuaternion::skIdentity;
mLocalRotation = CQuaternion::skIdentity;
mScale = CVector3f::skOne;
mFlipScaleX = false;
mFlipScaleY = false;
mFlipScaleZ = false;
mDeltaTranslation = CVector3f::skZero;
mDeltaRotation = CQuaternion::skIdentity;
mDeltaScale = CVector3f::skOne;
mTotalScale = CVector3f::skOne;
mSetOffset = false;
mFlipScaleX = false;
mFlipScaleY = false;
mFlipScaleZ = false;
}
CGizmo::~CGizmo()
@ -74,7 +76,13 @@ void CGizmo::DrawAsset(ERenderOptions options, u32 asset)
SModelPart *pPart = mpCurrentParts;
// Set model matrix
CGraphics::sMVPBlock.ModelMatrix = (pPart[asset].isBillboard ? mBillboardTransform.ToMatrix4f() : mTransform.ToMatrix4f());
if (pPart[asset].isBillboard)
CGraphics::sMVPBlock.ModelMatrix = mBillboardTransform.ToMatrix4f();
else if ((mMode == eScale) && ((mSelectedAxes & pPart[asset].modelAxes) != 0))
CGraphics::sMVPBlock.ModelMatrix = mScaledTransform.ToMatrix4f();
else
CGraphics::sMVPBlock.ModelMatrix = mTransform.ToMatrix4f();
CGraphics::UpdateMVPBlock();
// Choose material set
@ -107,24 +115,23 @@ void CGizmo::DecrementSize()
void CGizmo::UpdateForCamera(const CCamera &camera)
{
CVector3f camPos = camera.Position();
mFlipScaleX = camPos.x < mPosition.x;
mFlipScaleY = camPos.y < mPosition.y;
mFlipScaleZ = camPos.z < mPosition.z;
CVector3f cameraToGizmo = (mPosition - camPos).Normalized();
mFlipScaleX = (mRotation.XAxis().Dot(cameraToGizmo) >= 0.f);
mFlipScaleY = (mRotation.YAxis().Dot(cameraToGizmo) >= 0.f);
mFlipScaleZ = (mRotation.ZAxis().Dot(cameraToGizmo) >= 0.f);
if ((!mIsTransforming) || (mMode != eTranslate))
mCameraDist = mPosition.Distance(camPos);
// todo: make this cleaner...
CVector3f billDir = (mPosition - camPos).Normalized();
CVector3f billDir = (camPos - mPosition).Normalized();
CVector3f axis = CVector3f::skForward.Cross(billDir);
float angle = acosf(CVector3f::skForward.Dot(billDir));
angle = 180 + (angle * 180 / 3.14159265358979323846f);
mBillboardRotation = CQuaternion::FromAxisAngle(angle, axis);
}
bool CGizmo::CheckSelectedAxes(const CRay &ray)
{
// todo: fix raycasting for rotate gizmo; currently it can hit the invisible back side of the model
CRay localRay = ray.Transformed(mTransform.Inverse());
CRay billRay = ray.Transformed(mBillboardTransform.Inverse());
@ -231,7 +238,7 @@ void CGizmo::StartTransform()
mCurrentRotation = CQuaternion::skIdentity;
mTotalScale = CVector3f::skOne;
// Set rotation clockwise direction
// Set rotation direction
if (mMode == eRotate)
{
CVector3f axis;
@ -240,7 +247,31 @@ void CGizmo::StartTransform()
else axis = mRotation.ZAxis();
CVector3f gizmoToHit = (mHitPoint - mPosition).Normalized();
mClockwiseDir = axis.Cross(gizmoToHit);
mMoveDir = axis.Cross(gizmoToHit);
}
// Set scale direction
else if (mMode == eScale)
{
// Only need to set scale direction if < 3 axes selected
if (NumSelectedAxes() != 3)
{
// One axis; direction = selected axis
if (NumSelectedAxes() == 1)
{
if (mSelectedAxes & eX) mMoveDir = mRotation.XAxis();
else if (mSelectedAxes & eY) mMoveDir = mRotation.YAxis();
else mMoveDir = mRotation.ZAxis();
}
// Two axes; interpolate between the two selected axes
else if (NumSelectedAxes() == 2)
{
CVector3f axisA = (mSelectedAxes & eX ? mRotation.XAxis() : mRotation.YAxis());
CVector3f axisB = (mSelectedAxes & eZ ? mRotation.ZAxis() : mRotation.YAxis());
mMoveDir = (axisA + axisB) / 2.f;
}
}
}
}
@ -347,11 +378,11 @@ bool CGizmo::TransformFromInput(const CRay& ray, CCamera& camera)
else if (mSelectedAxes & eY) axis = CVector3f::skUnitY;
else axis = CVector3f::skUnitZ;
// Convert hit point + clockwise direction into a line in screen space
// Convert hit point + move direction into a line in screen space
// Clockwise direction is set in StartTransform(). Is there a cleaner way to calculate the direction?
CMatrix4f VP = camera.ViewMatrix().Transpose() * camera.ProjectionMatrix().Transpose();
CVector2f lineOrigin = (mHitPoint * VP).xy();
CVector2f lineDir = (((mHitPoint + mClockwiseDir) * VP).xy() - lineOrigin).Normalized();
CVector2f lineDir = (((mHitPoint + mMoveDir) * VP).xy() - lineOrigin).Normalized();
float rotAmount = lineDir.Dot(mouseCoords + mWrapOffset - lineOrigin) * 180.f;
// Set offset
@ -366,7 +397,7 @@ bool CGizmo::TransformFromInput(const CRay& ray, CCamera& camera)
// Apply rotation
rotAmount += mRotateOffset;
CQuaternion oldRot = mCurrentRotation;
mCurrentRotation = CQuaternion::FromAxisAngle(rotAmount, axis);
mCurrentRotation = CQuaternion::FromAxisAngle(Math::DegreesToRadians(rotAmount), axis);
mDeltaRotation = mCurrentRotation * oldRot.Inverse();
if (mTransformSpace == eLocalTransform)
@ -383,11 +414,80 @@ bool CGizmo::TransformFromInput(const CRay& ray, CCamera& camera)
return true;
}
// Scale
else if (mMode == eScale)
{
// Create a line in screen space. First step: line origin
CMatrix4f VP = camera.ViewMatrix().Transpose() * camera.ProjectionMatrix().Transpose();
CVector2f lineOrigin = (mPosition * VP).xy();
// Next step: determine the appropriate world space direction using the selected axes and then convert to screen space
// Since the axes can be flipped while the gizmo is transforming, this has to be done every frame rather than
// pre-saving the world space direction like the rotate gizmo does.
CVector3f dirX = (mFlipScaleX ? -mRotation.XAxis() : mRotation.XAxis());
CVector3f dirY = (mFlipScaleY ? -mRotation.YAxis() : mRotation.YAxis());
CVector3f dirZ = (mFlipScaleZ ? -mRotation.ZAxis() : mRotation.ZAxis());
CVector2f lineDir;
// One axis - world space direction is just the selected axis
if (NumSelectedAxes() == 1)
{
CVector3f worldDir;
if (mSelectedAxes & eX) worldDir = dirX;
else if (mSelectedAxes & eY) worldDir = dirY;
else worldDir = dirZ;
lineDir = (((mPosition + worldDir) * VP).xy() - lineOrigin).Normalized();
}
// Two axes - take the two selected axes and convert them to world space, then average them for the line direction
else if (NumSelectedAxes() == 2)
{
CVector3f axisA = (mSelectedAxes & eX ? dirX : dirY);
CVector3f axisB = (mSelectedAxes & eZ ? dirZ : dirY);
CVector2f screenA = (((mPosition + axisA) * VP).xy() - lineOrigin).Normalized();
CVector2f screenB = (((mPosition + axisB) * VP).xy() - lineOrigin).Normalized();
lineDir = ((screenA + screenB) / 2.f).Normalized();
}
// Three axes - use straight up
else lineDir = CVector2f::skUp;
float scaleAmount = lineDir.Dot(mouseCoords + mWrapOffset - lineOrigin) * 5.f;
// Set offset
if (!mSetOffset)
{
mScaleOffset = -scaleAmount;
mDeltaScale = CVector3f::skOne;
mSetOffset = true;
return false;
}
// Apply scale
scaleAmount = scaleAmount + mScaleOffset + 1.f;
if (scaleAmount < 1.f)
scaleAmount = 1.f / (-(scaleAmount - 1.f) + 1.f);
CVector3f oldScale = mTotalScale;
mTotalScale = CVector3f::skOne;
if (mSelectedAxes & eX) mTotalScale.x = scaleAmount;
if (mSelectedAxes & eY) mTotalScale.y = scaleAmount;
if (mSelectedAxes & eZ) mTotalScale.z = scaleAmount;
mDeltaScale = mTotalScale / oldScale;
if (!mHasTransformed && (scaleAmount != 0.f))
mHasTransformed = true;
return true;
}
return false;
}
void CGizmo::EndTransform()
{
mTotalScale = CVector3f::skOne;
mIsTransforming = false;
}
@ -478,6 +578,11 @@ void CGizmo::SetMode(EGizmoMode mode)
void CGizmo::SetTransformSpace(ETransformSpace space)
{
mTransformSpace = space;
if (space == eWorldTransform)
mRotation = CQuaternion::skIdentity;
else
mRotation = mLocalRotation;
}
void CGizmo::SetPosition(const CVector3f& position)
@ -485,9 +590,12 @@ void CGizmo::SetPosition(const CVector3f& position)
mPosition = position;
}
void CGizmo::SetRotation(const CQuaternion& orientation)
void CGizmo::SetLocalRotation(const CQuaternion& orientation)
{
mRotation = orientation;
mLocalRotation = orientation;
if (mTransformSpace == eLocalTransform)
mRotation = orientation;
}
void CGizmo::EnableCursorWrap(bool wrap)
@ -524,9 +632,9 @@ void CGizmo::LoadModels()
smScaleModels[CGIZMO_SCALE_LINES_XY] = SModelPart(eXY, true, false, (CModel*) gResCache.GetResource("../resources/editor/ScaleLinesXY.CMDL"));
smScaleModels[CGIZMO_SCALE_LINES_XZ] = SModelPart(eXZ, true, false, (CModel*) gResCache.GetResource("../resources/editor/ScaleLinesXZ.CMDL"));
smScaleModels[CGIZMO_SCALE_LINES_YZ] = SModelPart(eYZ, true, false, (CModel*) gResCache.GetResource("../resources/editor/ScaleLinesYZ.CMDL"));
smScaleModels[CGIZMO_SCALE_POLY_XY] = SModelPart(eXY, false, false, (CModel*) gResCache.GetResource("../resources/editor/ScalePolyXY.CMDL"));
smScaleModels[CGIZMO_SCALE_POLY_XZ] = SModelPart(eXZ, false, false, (CModel*) gResCache.GetResource("../resources/editor/ScalePolyXZ.CMDL"));
smScaleModels[CGIZMO_SCALE_POLY_YZ] = SModelPart(eYZ, false, false, (CModel*) gResCache.GetResource("../resources/editor/ScalePolyYZ.CMDL"));
smScaleModels[CGIZMO_SCALE_POLY_XY] = SModelPart(eXY, true, false, (CModel*) gResCache.GetResource("../resources/editor/ScalePolyXY.CMDL"));
smScaleModels[CGIZMO_SCALE_POLY_XZ] = SModelPart(eXZ, true, false, (CModel*) gResCache.GetResource("../resources/editor/ScalePolyXZ.CMDL"));
smScaleModels[CGIZMO_SCALE_POLY_YZ] = SModelPart(eYZ, true, false, (CModel*) gResCache.GetResource("../resources/editor/ScalePolyYZ.CMDL"));
smScaleModels[CGIZMO_SCALE_XYZ] = SModelPart(eXYZ, true, false, (CModel*) gResCache.GetResource("../resources/editor/ScaleXYZ.CMDL"));
smModelsLoaded = true;
@ -540,11 +648,9 @@ void CGizmo::UpdateTransform()
// Rotation and position values are just saved directly
mScale = mGizmoSize * (mCameraDist / 10.f);
// Scale also factors in total scale + axis flip if mode is Scale.
// Scale also factors in axis flip if mode is Scale.
if (mMode == eScale)
{
mScale *= mTotalScale;
if (mFlipScaleX) mScale.x = -mScale.x;
if (mFlipScaleY) mScale.y = -mScale.y;
if (mFlipScaleZ) mScale.z = -mScale.z;
@ -564,6 +670,15 @@ void CGizmo::UpdateTransform()
mBillboardTransform.Rotate(mBillboardRotation);
mBillboardTransform.Translate(mPosition);
}
// Create scaled transform for scale gizmo
else if (mMode == eScale)
{
mScaledTransform = CTransform4f::skIdentity;
mScaledTransform.Scale(mScale * mTotalScale);
mScaledTransform.Rotate(mRotation);
mScaledTransform.Translate(mPosition);
}
}
void CGizmo::WrapCursor()

View File

@ -60,8 +60,6 @@ private:
EGizmoMode mMode;
EGizmoAxes mSelectedAxes;
ETransformSpace mTransformSpace;
CVector3f mHitPoint;
CTransform4f mBillboardTransform;
CQuaternion mBillboardRotation;
float mGizmoSize;
float mCameraDist;
@ -71,27 +69,32 @@ private:
bool mEnableCursorWrap;
CTransform4f mTransform;
CTransform4f mBillboardTransform;
CTransform4f mScaledTransform;
CVector3f mPosition;
CVector3f mDeltaTranslation;
CVector3f mTotalTranslation;
CQuaternion mRotation;
CQuaternion mDeltaRotation;
CQuaternion mCurrentRotation;
CVector3f mTotalRotation; // This is a CVector3f because this value displays on the UI and a quat would cause rollover
CQuaternion mLocalRotation;
CVector3f mScale;
CVector3f mDeltaScale;
CVector3f mTotalScale;
bool mFlipScaleX;
bool mFlipScaleY;
bool mFlipScaleZ;
CVector3f mDeltaTranslation;
CVector3f mTotalTranslation;
CQuaternion mDeltaRotation;
CQuaternion mCurrentRotation;
CVector3f mTotalRotation; // This is a CVector3f because this value displays on the UI and a quat would cause rollover
CVector3f mDeltaScale;
CVector3f mTotalScale;
CPlane mTranslatePlane;
CVector3f mTranslateOffset;
float mRotateOffset;
float mScaleOffset;
bool mSetOffset;
CVector3f mRotateHitPoint;
CVector3f mClockwiseDir;
CVector3f mHitPoint;
CVector3f mMoveDir;
struct SModelPart
{
@ -145,7 +148,7 @@ public:
void SetMode(EGizmoMode mode);
void SetTransformSpace(ETransformSpace space);
void SetPosition(const CVector3f& position);
void SetRotation(const CQuaternion& orientation);
void SetLocalRotation(const CQuaternion& orientation);
void EnableCursorWrap(bool wrap);
// Protected

View File

@ -61,13 +61,14 @@ CWorldEditor::CWorldEditor(QWidget *parent) :
ui->CamSpeedSpinBox->SetDefaultValue(1.0);
ResetHover();
mTransformSpace = eWorldTransform;
mTranslateSpace = eWorldTransform;
mRotateSpace = eWorldTransform;
QComboBox *pTransformCombo = new QComboBox(this);
pTransformCombo->setMinimumWidth(75);
pTransformCombo->addItem("World");
pTransformCombo->addItem("Local");
ui->MainToolBar->insertWidget(0, pTransformCombo);
mpTransformSpaceComboBox = new QComboBox(this);
mpTransformSpaceComboBox->setMinimumWidth(75);
mpTransformSpaceComboBox->addItem("World");
mpTransformSpaceComboBox->addItem("Local");
ui->MainToolBar->insertWidget(0, mpTransformSpaceComboBox);
// Initialize offscreen actions
addAction(ui->ActionIncrementGizmo);
@ -76,7 +77,7 @@ CWorldEditor::CWorldEditor(QWidget *parent) :
// Connect signals and slots
connect(ui->TransformSpinBox, SIGNAL(EditingDone(CVector3f)), this, SLOT(OnTransformSpinBoxEdited(CVector3f)));
connect(ui->TransformSpinBox, SIGNAL(ValueChanged(CVector3f)), this, SLOT(OnTransformSpinBoxModified(CVector3f)));
connect(pTransformCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(SetTransformSpace(int)));
connect(mpTransformSpaceComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(SetTransformSpace(int)));
connect(ui->CamSpeedSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnCameraSpeedChange(double)));
connect(ui->MainViewport, SIGNAL(PreRender()), this, SLOT(ViewportPreRender()));
connect(ui->MainViewport, SIGNAL(Render(CCamera&)), this, SLOT(ViewportRender(CCamera&)));
@ -193,27 +194,37 @@ void CWorldEditor::ViewportRayCast()
{
switch (mGizmo.Mode())
{
case CGizmo::eTranslate:
{
CVector3f delta = mGizmo.DeltaTranslation();
for (auto it = mSelectedNodes.begin(); it != mSelectedNodes.end(); it++)
case CGizmo::eTranslate:
{
(*it)->Translate(delta, mTransformSpace);
(*it)->BuildLightList(this->mpArea);
CVector3f delta = mGizmo.DeltaTranslation();
for (auto it = mSelectedNodes.begin(); it != mSelectedNodes.end(); it++)
{
(*it)->Translate(delta, mTranslateSpace);
(*it)->BuildLightList(this->mpArea);
}
break;
}
break;
}
case CGizmo::eRotate:
{
CQuaternion delta = mGizmo.DeltaRotation();
case CGizmo::eRotate:
{
CQuaternion delta = mGizmo.DeltaRotation();
for (auto it = mSelectedNodes.begin(); it != mSelectedNodes.end(); it++)
(*it)->Rotate(delta, mTransformSpace);
for (auto it = mSelectedNodes.begin(); it != mSelectedNodes.end(); it++)
(*it)->Rotate(delta, mRotateSpace);
break;
}
break;
}
case CGizmo::eScale:
{
CVector3f delta = mGizmo.DeltaScale();
for (auto it = mSelectedNodes.begin(); it != mSelectedNodes.end(); it++)
(*it)->Scale(delta);
break;
}
}
RecalculateSelectionBounds();
@ -432,20 +443,23 @@ void CWorldEditor::SetViewportSize(int Width, int Height)
void CWorldEditor::SetTransformSpace(int space)
{
if (mGizmo.Mode() == CGizmo::eScale) return;
ETransformSpace& transformSpace = (mGizmo.Mode() == CGizmo::eTranslate ? mTranslateSpace : mRotateSpace);
switch (space)
{
case 0:
mTransformSpace = eWorldTransform;
mGizmo.SetRotation(CQuaternion::skIdentity);
transformSpace = eWorldTransform;
mGizmo.SetLocalRotation(CQuaternion::skIdentity);
break;
case 1:
mTransformSpace = eLocalTransform;
transformSpace = eLocalTransform;
if (!mSelectedNodes.empty())
mGizmo.SetRotation(mSelectedNodes.front()->AbsoluteRotation());
mGizmo.SetLocalRotation(mSelectedNodes.front()->AbsoluteRotation());
break;
}
mGizmo.SetTransformSpace(mTransformSpace);
mGizmo.SetTransformSpace(transformSpace);
}
// ************ PRIVATE ************
@ -570,10 +584,17 @@ void CWorldEditor::UpdateGizmoUI()
if (!mSelectedNodes.empty())
mGizmo.SetPosition(mSelectedNodes.front()->AbsolutePosition());
if ((mTransformSpace == eLocalTransform) && !mSelectedNodes.empty())
mGizmo.SetRotation(mSelectedNodes.front()->AbsoluteRotation());
else
mGizmo.SetRotation(CQuaternion::skIdentity);
// Determine transform space
ETransformSpace space;
if (mGizmo.Mode() == CGizmo::eTranslate) space = mTranslateSpace;
else if (mGizmo.Mode() == CGizmo::eRotate) space = mRotateSpace;
else space = eLocalTransform;
// Set gizmo transform space
mGizmo.SetTransformSpace(space);
if (!mSelectedNodes.empty())
mGizmo.SetLocalRotation(mSelectedNodes.front()->AbsoluteRotation());
}
mGizmoUIOutdated = false;
@ -764,6 +785,16 @@ void CWorldEditor::on_ActionSelectObjects_triggered()
ui->ActionTranslate->setChecked(false);
ui->ActionRotate->setChecked(false);
ui->ActionScale->setChecked(false);
// Set transform spin box settings
ui->TransformSpinBox->SetSingleStep(0.1);
ui->TransformSpinBox->SetDefaultValue(0.0);
// Set transform space combo box
mpTransformSpaceComboBox->setEnabled(false);
mpTransformSpaceComboBox->blockSignals(true);
mpTransformSpaceComboBox->setCurrentIndex(0);
mpTransformSpaceComboBox->blockSignals(false);
}
void CWorldEditor::on_ActionTranslate_triggered()
@ -771,13 +802,22 @@ void CWorldEditor::on_ActionTranslate_triggered()
mShowGizmo = true;
mGizmoUIOutdated = true;
mGizmo.SetMode(CGizmo::eTranslate);
mGizmo.SetTransformSpace(mTranslateSpace);
ui->ActionSelectObjects->setChecked(false);
ui->ActionTranslate->setChecked(true);
ui->ActionRotate->setChecked(false);
ui->ActionScale->setChecked(false);
// Set transform spin box settings
ui->TransformSpinBox->SetSingleStep(0.1);
ui->TransformSpinBox->SetDefaultValue(0.0);
// Set transform space combo box
int index = (mTranslateSpace == eWorldTransform ? 0 : 1);
mpTransformSpaceComboBox->setEnabled(true);
mpTransformSpaceComboBox->blockSignals(true);
mpTransformSpaceComboBox->setCurrentIndex(index);
mpTransformSpaceComboBox->blockSignals(false);
}
void CWorldEditor::on_ActionRotate_triggered()
@ -785,13 +825,22 @@ void CWorldEditor::on_ActionRotate_triggered()
mShowGizmo = true;
mGizmoUIOutdated = true;
mGizmo.SetMode(CGizmo::eRotate);
mGizmo.SetTransformSpace(mRotateSpace);
ui->ActionSelectObjects->setChecked(false);
ui->ActionTranslate->setChecked(false);
ui->ActionRotate->setChecked(true);
ui->ActionScale->setChecked(false);
// Set transform spin box settings
ui->TransformSpinBox->SetSingleStep(1.0);
ui->TransformSpinBox->SetDefaultValue(0.0);
// Set transform space combo box
int index = (mRotateSpace == eWorldTransform ? 0 : 1);
mpTransformSpaceComboBox->setEnabled(true);
mpTransformSpaceComboBox->blockSignals(true);
mpTransformSpaceComboBox->setCurrentIndex(index);
mpTransformSpaceComboBox->blockSignals(false);
}
void CWorldEditor::on_ActionScale_triggered()
@ -799,13 +848,21 @@ void CWorldEditor::on_ActionScale_triggered()
mShowGizmo = true;
mGizmoUIOutdated = true;
mGizmo.SetMode(CGizmo::eScale);
mGizmo.SetTransformSpace(eLocalTransform);
ui->ActionSelectObjects->setChecked(false);
ui->ActionTranslate->setChecked(false);
ui->ActionRotate->setChecked(false);
ui->ActionScale->setChecked(true);
// Set transform spin box settings
ui->TransformSpinBox->SetSingleStep(0.1);
ui->TransformSpinBox->SetDefaultValue(1.0);
// Set transform space combo box - force to local
mpTransformSpaceComboBox->setEnabled(false);
mpTransformSpaceComboBox->blockSignals(true);
mpTransformSpaceComboBox->setCurrentIndex(1);
mpTransformSpaceComboBox->blockSignals(false);
}
void CWorldEditor::on_ActionIncrementGizmo_triggered()

View File

@ -3,6 +3,7 @@
#include <QMainWindow>
#include <QList>
#include <QComboBox>
#include "CGizmo.h"
#include <Common/CRay.h>
@ -26,7 +27,8 @@ class CWorldEditor : public QMainWindow
CRenderer *mpRenderer;
CSceneManager *mpSceneManager;
CGizmo mGizmo;
ETransformSpace mTransformSpace;
ETransformSpace mTranslateSpace;
ETransformSpace mRotateSpace;
CCamera mCamera;
CGameArea *mpArea;
CWorld *mpWorld;
@ -44,6 +46,8 @@ class CWorldEditor : public QMainWindow
std::list<CSceneNode*> mSelectedNodes;
CAABox mSelectionAABox;
QComboBox *mpTransformSpaceComboBox;
CTimer mFPSTimer;
int mFrameCount;