mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-09 21:47:45 +00:00
Mass code cleanup
This commit is contained in:
@@ -10,32 +10,29 @@
|
||||
#include <QDesktopWidget>
|
||||
|
||||
CGizmo::CGizmo()
|
||||
: mSelectedAxes(eNone)
|
||||
, mTransformSpace(eWorldTransform)
|
||||
, mGizmoSize(1.f)
|
||||
, mCameraDist(0.f)
|
||||
, mIsTransforming(false)
|
||||
, mHasTransformed(false)
|
||||
, mWrapOffset(0.f)
|
||||
, mEnableCursorWrap(true)
|
||||
, 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)
|
||||
{
|
||||
LoadModels();
|
||||
|
||||
SetMode(eTranslate);
|
||||
mSelectedAxes = eNone;
|
||||
mTransformSpace = eWorldTransform;
|
||||
mGizmoSize = 1.f;
|
||||
mCameraDist = 0.f;
|
||||
mIsTransforming = false;
|
||||
mHasTransformed = false;
|
||||
mWrapOffset = 0.f;
|
||||
mEnableCursorWrap = true;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
CGizmo::~CGizmo()
|
||||
@@ -55,12 +52,12 @@ void CGizmo::AddToRenderer(CRenderer *pRenderer, const SViewInfo&)
|
||||
CModel *pModel = pPart->pModel;
|
||||
|
||||
// Determine whether to use the mat set for regular (0) or highlight (1)
|
||||
FGizmoAxes partAxes = pPart->modelAxes;
|
||||
bool isHighlighted = (partAxes != eNone) && ((mSelectedAxes & partAxes) == pPart->modelAxes);
|
||||
u32 setID = (isHighlighted ? 1 : 0);
|
||||
FGizmoAxes PartAxes = pPart->ModelAxes;
|
||||
bool IsHighlighted = (PartAxes != eNone) && ((mSelectedAxes & PartAxes) == pPart->ModelAxes);
|
||||
u32 SetID = (IsHighlighted ? 1 : 0);
|
||||
|
||||
// Add to renderer...
|
||||
if (pModel->HasTransparency(setID))
|
||||
if (pModel->HasTransparency(SetID))
|
||||
pRenderer->AddTransparentMesh(this, iPart, pModel->AABox().Transformed(mTransform), eDrawMesh);
|
||||
else
|
||||
pRenderer->AddOpaqueMesh(this, iPart, pModel->AABox().Transformed(mTransform), eDrawMesh);
|
||||
@@ -69,16 +66,16 @@ void CGizmo::AddToRenderer(CRenderer *pRenderer, const SViewInfo&)
|
||||
}
|
||||
}
|
||||
|
||||
void CGizmo::Draw(FRenderOptions /*Options*/, int ComponentIndex, const SViewInfo& /*ViewInfo*/)
|
||||
void CGizmo::Draw(FRenderOptions /*Options*/, int ComponentIndex, const SViewInfo& /*rkViewInfo*/)
|
||||
{
|
||||
// Determine which SModelPart array to use
|
||||
if (ComponentIndex >= (int) mNumCurrentParts) return;
|
||||
SModelPart *pPart = mpCurrentParts;
|
||||
|
||||
// Set model matrix
|
||||
if (pPart[ComponentIndex].isBillboard)
|
||||
if (pPart[ComponentIndex].IsBillboard)
|
||||
CGraphics::sMVPBlock.ModelMatrix = mBillboardTransform.ToMatrix4f();
|
||||
else if ((mMode == eScale) && ((mSelectedAxes & pPart[ComponentIndex].modelAxes) != 0))
|
||||
else if ((mMode == eScale) && ((mSelectedAxes & pPart[ComponentIndex].ModelAxes) != 0))
|
||||
CGraphics::sMVPBlock.ModelMatrix = mScaledTransform.ToMatrix4f();
|
||||
else
|
||||
CGraphics::sMVPBlock.ModelMatrix = mTransform.ToMatrix4f();
|
||||
@@ -90,12 +87,12 @@ void CGizmo::Draw(FRenderOptions /*Options*/, int ComponentIndex, const SViewInf
|
||||
CGraphics::UpdatePixelBlock();
|
||||
|
||||
// Choose material set
|
||||
FGizmoAxes partAxes = pPart[ComponentIndex].modelAxes;
|
||||
bool isHighlighted = (partAxes != eNone) && ((mSelectedAxes & partAxes) == pPart[ComponentIndex].modelAxes);
|
||||
u32 setID = (isHighlighted ? 1 : 0);
|
||||
FGizmoAxes PartAxes = pPart[ComponentIndex].ModelAxes;
|
||||
bool IsHighlighted = (PartAxes != eNone) && ((mSelectedAxes & PartAxes) == pPart[ComponentIndex].ModelAxes);
|
||||
u32 SetID = (IsHighlighted ? 1 : 0);
|
||||
|
||||
// Draw model
|
||||
pPart[ComponentIndex].pModel->Draw((FRenderOptions) 0, setID);
|
||||
pPart[ComponentIndex].pModel->Draw((FRenderOptions) 0, SetID);
|
||||
}
|
||||
|
||||
void CGizmo::IncrementSize()
|
||||
@@ -116,80 +113,80 @@ void CGizmo::DecrementSize()
|
||||
if (mGizmoSize < skMinSize) mGizmoSize = skMinSize;
|
||||
}
|
||||
|
||||
void CGizmo::UpdateForCamera(const CCamera &camera)
|
||||
void CGizmo::UpdateForCamera(const CCamera& rkCamera)
|
||||
{
|
||||
CVector3f camPos = camera.Position();
|
||||
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);
|
||||
CVector3f CamPos = rkCamera.Position();
|
||||
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);
|
||||
mCameraDist = mPosition.Distance(CamPos);
|
||||
|
||||
// todo: make this cleaner...
|
||||
CVector3f billDir = (camPos - mPosition).Normalized();
|
||||
CVector3f axis = CVector3f::skForward.Cross(billDir);
|
||||
float angle = acosf(CVector3f::skForward.Dot(billDir));
|
||||
mBillboardRotation = CQuaternion::FromAxisAngle(angle, axis);
|
||||
CVector3f BillDir = (CamPos - mPosition).Normalized();
|
||||
CVector3f Axis = CVector3f::skForward.Cross(BillDir);
|
||||
float Angle = acosf(CVector3f::skForward.Dot(BillDir));
|
||||
mBillboardRotation = CQuaternion::FromAxisAngle(Angle, Axis);
|
||||
}
|
||||
|
||||
bool CGizmo::CheckSelectedAxes(const CRay &ray)
|
||||
bool CGizmo::CheckSelectedAxes(const CRay& rkRay)
|
||||
{
|
||||
CRay localRay = ray.Transformed(mTransform.Inverse());
|
||||
CRay billRay = ray.Transformed(mBillboardTransform.Inverse());
|
||||
CRay LocalRay = rkRay.Transformed(mTransform.Inverse());
|
||||
CRay BillRay = rkRay.Transformed(mBillboardTransform.Inverse());
|
||||
|
||||
// Do raycast on each model
|
||||
SModelPart *pPart = mpCurrentParts;
|
||||
|
||||
struct SResult {
|
||||
SModelPart *pPart;
|
||||
float dist;
|
||||
float Dist;
|
||||
};
|
||||
std::list<SResult> results;
|
||||
std::list<SResult> Results;
|
||||
|
||||
for (u32 iPart = 0; iPart < mNumCurrentParts; iPart++)
|
||||
{
|
||||
if (!pPart->enableRayCast)
|
||||
if (!pPart->EnableRayCast)
|
||||
{
|
||||
pPart++;
|
||||
continue;
|
||||
}
|
||||
|
||||
CModel *pModel = pPart->pModel;
|
||||
CRay& partRay = (pPart->isBillboard ? billRay : localRay);
|
||||
CRay& rPartRay = (pPart->IsBillboard ? BillRay : LocalRay);
|
||||
|
||||
// Ray/Model AABox test - allow buffer room because lines are small
|
||||
CAABox AABox = pModel->AABox();
|
||||
AABox.ExpandBy(CVector3f::skOne);
|
||||
bool modelBoxCheck = Math::RayBoxIntersection(partRay, AABox).first;
|
||||
bool ModelBoxCheck = Math::RayBoxIntersection(rPartRay, AABox).first;
|
||||
|
||||
if (modelBoxCheck)
|
||||
if (ModelBoxCheck)
|
||||
{
|
||||
bool hit = false;
|
||||
float dist;
|
||||
bool Hit = false;
|
||||
float Dist;
|
||||
|
||||
for (u32 iSurf = 0; iSurf < pModel->GetSurfaceCount(); iSurf++)
|
||||
{
|
||||
// Skip surface/box check - since we use lines the boxes might be too small
|
||||
SSurface *pSurf = pModel->GetSurface(iSurf);
|
||||
std::pair<bool,float> surfCheck = pSurf->IntersectsRay(partRay, false, 0.05f);
|
||||
std::pair<bool,float> SurfCheck = pSurf->IntersectsRay(rPartRay, false, 0.05f);
|
||||
|
||||
if (surfCheck.first)
|
||||
if (SurfCheck.first)
|
||||
{
|
||||
if ((!hit) || (surfCheck.second < dist))
|
||||
dist = surfCheck.second;
|
||||
if ((!Hit) || (SurfCheck.second < Dist))
|
||||
Dist = SurfCheck.second;
|
||||
|
||||
hit = true;
|
||||
Hit = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hit)
|
||||
if (Hit)
|
||||
{
|
||||
SResult result;
|
||||
result.pPart = pPart;
|
||||
result.dist = dist;
|
||||
results.push_back(result);
|
||||
SResult Result;
|
||||
Result.pPart = pPart;
|
||||
Result.Dist = Dist;
|
||||
Results.push_back(Result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,33 +194,33 @@ bool CGizmo::CheckSelectedAxes(const CRay &ray)
|
||||
}
|
||||
|
||||
// Results list empty = no hits
|
||||
if (results.empty())
|
||||
if (Results.empty())
|
||||
{
|
||||
mSelectedAxes = eNone;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, we have at least one hit - sort results and set selected axes
|
||||
results.sort([](const SResult& a, SResult& b) -> bool
|
||||
Results.sort([](const SResult& rkLeft, SResult& rkRight) -> bool
|
||||
{
|
||||
return (a.dist < b.dist);
|
||||
return (rkLeft.Dist < rkRight.Dist);
|
||||
});
|
||||
|
||||
CRay& partRay = (pPart->isBillboard ? billRay : localRay);
|
||||
mSelectedAxes = results.front().pPart->modelAxes;
|
||||
mHitPoint = mTransform * partRay.PointOnRay(results.front().dist);
|
||||
CRay& rPartRay = (pPart->IsBillboard ? BillRay : LocalRay);
|
||||
mSelectedAxes = Results.front().pPart->ModelAxes;
|
||||
mHitPoint = mTransform * rPartRay.PointOnRay(Results.front().Dist);
|
||||
|
||||
return (mSelectedAxes != eNone);
|
||||
}
|
||||
|
||||
u32 CGizmo::NumSelectedAxes()
|
||||
{
|
||||
u32 out = 0;
|
||||
u32 Out = 0;
|
||||
|
||||
for (u32 iAxis = 1; iAxis < 8; iAxis <<= 1)
|
||||
if (mSelectedAxes & FGizmoAxes(iAxis)) out++;
|
||||
if (mSelectedAxes & FGizmoAxes(iAxis)) Out++;
|
||||
|
||||
return out;
|
||||
return Out;
|
||||
}
|
||||
|
||||
void CGizmo::ResetSelectedAxes()
|
||||
@@ -245,13 +242,13 @@ void CGizmo::StartTransform()
|
||||
// Set rotation direction
|
||||
if (mMode == eRotate)
|
||||
{
|
||||
CVector3f axis;
|
||||
if (mSelectedAxes & eX) axis = mRotation.XAxis();
|
||||
else if (mSelectedAxes & eY) axis = mRotation.YAxis();
|
||||
else axis = mRotation.ZAxis();
|
||||
CVector3f Axis;
|
||||
if (mSelectedAxes & eX) Axis = mRotation.XAxis();
|
||||
else if (mSelectedAxes & eY) Axis = mRotation.YAxis();
|
||||
else Axis = mRotation.ZAxis();
|
||||
|
||||
CVector3f gizmoToHit = (mHitPoint - mPosition).Normalized();
|
||||
mMoveDir = axis.Cross(gizmoToHit);
|
||||
CVector3f GizmoToHit = (mHitPoint - mPosition).Normalized();
|
||||
mMoveDir = Axis.Cross(GizmoToHit);
|
||||
}
|
||||
|
||||
// Set scale direction
|
||||
@@ -271,78 +268,78 @@ void CGizmo::StartTransform()
|
||||
// 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;
|
||||
CVector3f AxisA = (mSelectedAxes & eX ? mRotation.XAxis() : mRotation.YAxis());
|
||||
CVector3f AxisB = (mSelectedAxes & eZ ? mRotation.ZAxis() : mRotation.YAxis());
|
||||
mMoveDir = (AxisA + AxisB) / 2.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CGizmo::TransformFromInput(const CRay& ray, CCamera& camera)
|
||||
bool CGizmo::TransformFromInput(const CRay& rkRay, CCamera& rCamera)
|
||||
{
|
||||
// Wrap cursor (this has no effect until the next time this function is called)
|
||||
if (mEnableCursorWrap && (mMode != eTranslate))
|
||||
WrapCursor();
|
||||
|
||||
// Calculate normalized cursor position
|
||||
QPoint cursorPos = QCursor::pos();
|
||||
QRect geom = QApplication::desktop()->screenGeometry();
|
||||
CVector2f mouseCoords(
|
||||
(((2.f * cursorPos.x()) / geom.width()) - 1.f),
|
||||
(1.f - ((2.f * cursorPos.y()) / geom.height()))
|
||||
QPoint CursorPos = QCursor::pos();
|
||||
QRect Geom = QApplication::desktop()->screenGeometry();
|
||||
CVector2f MouseCoords(
|
||||
(((2.f * CursorPos.x()) / Geom.width()) - 1.f),
|
||||
(1.f - ((2.f * CursorPos.y()) / Geom.height()))
|
||||
);
|
||||
|
||||
// Translate
|
||||
if (mMode == eTranslate)
|
||||
{
|
||||
// Create translate plane
|
||||
CVector3f axisA, axisB;
|
||||
u32 numAxes = NumSelectedAxes();
|
||||
CVector3f AxisA, AxisB;
|
||||
u32 NumAxes = NumSelectedAxes();
|
||||
|
||||
if (numAxes == 1)
|
||||
if (NumAxes == 1)
|
||||
{
|
||||
if (mSelectedAxes & eX) axisB = mRotation.XAxis();
|
||||
else if (mSelectedAxes & eY) axisB = mRotation.YAxis();
|
||||
else axisB = mRotation.ZAxis();
|
||||
if (mSelectedAxes & eX) AxisB = mRotation.XAxis();
|
||||
else if (mSelectedAxes & eY) AxisB = mRotation.YAxis();
|
||||
else AxisB = mRotation.ZAxis();
|
||||
|
||||
CVector3f gizmoToCamera = (mPosition - camera.Position()).Normalized();
|
||||
axisA = axisB.Cross(gizmoToCamera);
|
||||
CVector3f GizmoToCamera = (mPosition - rCamera.Position()).Normalized();
|
||||
AxisA = AxisB.Cross(GizmoToCamera);
|
||||
}
|
||||
|
||||
else if (numAxes == 2)
|
||||
else if (NumAxes == 2)
|
||||
{
|
||||
axisA = (mSelectedAxes & eX ? mRotation.XAxis() : mRotation.YAxis());
|
||||
axisB = (mSelectedAxes & eZ ? mRotation.ZAxis() : mRotation.YAxis());
|
||||
AxisA = (mSelectedAxes & eX ? mRotation.XAxis() : mRotation.YAxis());
|
||||
AxisB = (mSelectedAxes & eZ ? mRotation.ZAxis() : mRotation.YAxis());
|
||||
}
|
||||
|
||||
CVector3f planeNormal = axisA.Cross(axisB);
|
||||
mTranslatePlane.Redefine(planeNormal, mPosition);
|
||||
CVector3f PlaneNormal = AxisA.Cross(AxisB);
|
||||
mTranslatePlane.Redefine(PlaneNormal, mPosition);
|
||||
|
||||
// Do translate
|
||||
std::pair<bool,float> result = Math::RayPlaneIntersecton(ray, mTranslatePlane);
|
||||
std::pair<bool,float> Result = Math::RayPlaneIntersecton(rkRay, mTranslatePlane);
|
||||
|
||||
if (result.first)
|
||||
if (Result.first)
|
||||
{
|
||||
CVector3f hit = ray.PointOnRay(result.second);
|
||||
CVector3f localDelta = mRotation.Inverse() * (hit - mPosition);
|
||||
CVector3f Hit = rkRay.PointOnRay(Result.second);
|
||||
CVector3f LocalDelta = mRotation.Inverse() * (Hit - mPosition);
|
||||
|
||||
// Calculate new position
|
||||
CVector3f newPos = mPosition;
|
||||
if (mSelectedAxes & eX) newPos += mRotation.XAxis() * localDelta.x;
|
||||
if (mSelectedAxes & eY) newPos += mRotation.YAxis() * localDelta.y;
|
||||
if (mSelectedAxes & eZ) newPos += mRotation.ZAxis() * localDelta.z;
|
||||
CVector3f NewPos = mPosition;
|
||||
if (mSelectedAxes & eX) NewPos += mRotation.XAxis() * LocalDelta.X;
|
||||
if (mSelectedAxes & eY) NewPos += mRotation.YAxis() * LocalDelta.Y;
|
||||
if (mSelectedAxes & eZ) NewPos += mRotation.ZAxis() * LocalDelta.Z;
|
||||
|
||||
// Check relativity of new pos to camera to reduce issue where the gizmo might
|
||||
// go flying off into the distance if newPosToCamera is parallel to the plane
|
||||
CVector3f newPosToCamera = (newPos - camera.Position()).Normalized();
|
||||
float dot = Math::Abs(planeNormal.Dot(newPosToCamera));
|
||||
if (dot < 0.02f) return false;
|
||||
CVector3f NewPosToCamera = (NewPos - rCamera.Position()).Normalized();
|
||||
float Dot = Math::Abs(PlaneNormal.Dot(NewPosToCamera));
|
||||
if (Dot < 0.02f) return false;
|
||||
|
||||
// Set offset
|
||||
if (!mSetOffset)
|
||||
{
|
||||
mTranslateOffset = mPosition - newPos;
|
||||
mTranslateOffset = mPosition - NewPos;
|
||||
mDeltaTranslation = CVector3f::skZero;
|
||||
mSetOffset = true;
|
||||
return false;
|
||||
@@ -351,10 +348,10 @@ bool CGizmo::TransformFromInput(const CRay& ray, CCamera& camera)
|
||||
// Apply translation
|
||||
else
|
||||
{
|
||||
mDeltaTranslation = mRotation.Inverse() * (newPos - mPosition + mTranslateOffset);
|
||||
if (!(mSelectedAxes & eX)) mDeltaTranslation.x = 0.f;
|
||||
if (!(mSelectedAxes & eY)) mDeltaTranslation.y = 0.f;
|
||||
if (!(mSelectedAxes & eZ)) mDeltaTranslation.z = 0.f;
|
||||
mDeltaTranslation = mRotation.Inverse() * (NewPos - mPosition + mTranslateOffset);
|
||||
if (!(mSelectedAxes & eX)) mDeltaTranslation.X = 0.f;
|
||||
if (!(mSelectedAxes & eY)) mDeltaTranslation.Y = 0.f;
|
||||
if (!(mSelectedAxes & eZ)) mDeltaTranslation.Z = 0.f;
|
||||
|
||||
mTotalTranslation += mDeltaTranslation;
|
||||
mPosition += mRotation * mDeltaTranslation;
|
||||
@@ -377,42 +374,42 @@ bool CGizmo::TransformFromInput(const CRay& ray, CCamera& camera)
|
||||
else if (mMode == eRotate)
|
||||
{
|
||||
// Choose rotation axis
|
||||
CVector3f axis;
|
||||
if (mSelectedAxes & eX) axis = CVector3f::skUnitX;
|
||||
else if (mSelectedAxes & eY) axis = CVector3f::skUnitY;
|
||||
else axis = CVector3f::skUnitZ;
|
||||
CVector3f Axis;
|
||||
if (mSelectedAxes & eX) Axis = CVector3f::skUnitX;
|
||||
else if (mSelectedAxes & eY) Axis = CVector3f::skUnitY;
|
||||
else Axis = CVector3f::skUnitZ;
|
||||
|
||||
// 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 + mMoveDir) * VP).xy() - lineOrigin).Normalized();
|
||||
float rotAmount = lineDir.Dot(mouseCoords + mWrapOffset - lineOrigin) * 180.f;
|
||||
CMatrix4f VP = rCamera.ViewMatrix().Transpose() * rCamera.ProjectionMatrix().Transpose();
|
||||
CVector2f LineOrigin = (mHitPoint * VP).XY();
|
||||
CVector2f LineDir = (((mHitPoint + mMoveDir) * VP).XY() - LineOrigin).Normalized();
|
||||
float RotAmount = LineDir.Dot(MouseCoords + mWrapOffset - LineOrigin) * 180.f;
|
||||
|
||||
// Set offset
|
||||
if (!mSetOffset)
|
||||
{
|
||||
mRotateOffset = -rotAmount;
|
||||
mRotateOffset = -RotAmount;
|
||||
mDeltaRotation = CQuaternion::skIdentity;
|
||||
mSetOffset = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Apply rotation
|
||||
rotAmount += mRotateOffset;
|
||||
CQuaternion oldRot = mCurrentRotation;
|
||||
mCurrentRotation = CQuaternion::FromAxisAngle(Math::DegreesToRadians(rotAmount), axis);
|
||||
mDeltaRotation = mCurrentRotation * oldRot.Inverse();
|
||||
RotAmount += mRotateOffset;
|
||||
CQuaternion OldRot = mCurrentRotation;
|
||||
mCurrentRotation = CQuaternion::FromAxisAngle(Math::DegreesToRadians(RotAmount), Axis);
|
||||
mDeltaRotation = mCurrentRotation * OldRot.Inverse();
|
||||
|
||||
if (mTransformSpace == eLocalTransform)
|
||||
mRotation *= mDeltaRotation;
|
||||
|
||||
// Add to total
|
||||
if (mSelectedAxes & eX) mTotalRotation.x = rotAmount;
|
||||
else if (mSelectedAxes & eY) mTotalRotation.y = rotAmount;
|
||||
else mTotalRotation.z = rotAmount;
|
||||
if (mSelectedAxes & eX) mTotalRotation.X = RotAmount;
|
||||
else if (mSelectedAxes & eY) mTotalRotation.Y = RotAmount;
|
||||
else mTotalRotation.Z = RotAmount;
|
||||
|
||||
if (!mHasTransformed && (rotAmount != 0.f))
|
||||
if (!mHasTransformed && (RotAmount != 0.f))
|
||||
mHasTransformed = true;
|
||||
|
||||
return mHasTransformed;
|
||||
@@ -422,66 +419,66 @@ bool CGizmo::TransformFromInput(const CRay& ray, CCamera& camera)
|
||||
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();
|
||||
CMatrix4f VP = rCamera.ViewMatrix().Transpose() * rCamera.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;
|
||||
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();
|
||||
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();
|
||||
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;
|
||||
else LineDir = CVector2f::skUp;
|
||||
|
||||
float scaleAmount = lineDir.Dot(mouseCoords + mWrapOffset - lineOrigin) * 5.f;
|
||||
float ScaleAmount = LineDir.Dot(MouseCoords + mWrapOffset - LineOrigin) * 5.f;
|
||||
|
||||
// Set offset
|
||||
if (!mSetOffset)
|
||||
{
|
||||
mScaleOffset = -scaleAmount;
|
||||
mScaleOffset = -ScaleAmount;
|
||||
mDeltaScale = CVector3f::skOne;
|
||||
mSetOffset = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Apply scale
|
||||
scaleAmount = scaleAmount + mScaleOffset + 1.f;
|
||||
ScaleAmount = ScaleAmount + mScaleOffset + 1.f;
|
||||
|
||||
// A multiplier is applied to the scale amount of it's less than 1 to prevent it from going negative
|
||||
if (scaleAmount < 1.f)
|
||||
scaleAmount = 1.f / (-(scaleAmount - 1.f) + 1.f);
|
||||
if (ScaleAmount < 1.f)
|
||||
ScaleAmount = 1.f / (-(ScaleAmount - 1.f) + 1.f);
|
||||
|
||||
CVector3f oldScale = mTotalScale;
|
||||
CVector3f OldScale = mTotalScale;
|
||||
|
||||
mTotalScale = CVector3f::skOne;
|
||||
if (mSelectedAxes & eX) mTotalScale.x = scaleAmount;
|
||||
if (mSelectedAxes & eY) mTotalScale.y = scaleAmount;
|
||||
if (mSelectedAxes & eZ) mTotalScale.z = scaleAmount;
|
||||
if (mSelectedAxes & eX) mTotalScale.X = ScaleAmount;
|
||||
if (mSelectedAxes & eY) mTotalScale.Y = ScaleAmount;
|
||||
if (mSelectedAxes & eZ) mTotalScale.Z = ScaleAmount;
|
||||
|
||||
mDeltaScale = mTotalScale / oldScale;
|
||||
mDeltaScale = mTotalScale / OldScale;
|
||||
|
||||
if (!mHasTransformed && (scaleAmount != 1.f))
|
||||
if (!mHasTransformed && (ScaleAmount != 1.f))
|
||||
mHasTransformed = true;
|
||||
|
||||
return mHasTransformed;
|
||||
@@ -496,76 +493,11 @@ void CGizmo::EndTransform()
|
||||
mIsTransforming = false;
|
||||
}
|
||||
|
||||
bool CGizmo::IsTransforming() const
|
||||
void CGizmo::SetMode(EGizmoMode Mode)
|
||||
{
|
||||
return mIsTransforming;
|
||||
}
|
||||
mMode = Mode;
|
||||
|
||||
bool CGizmo::HasTransformed() const
|
||||
{
|
||||
return mHasTransformed;
|
||||
}
|
||||
|
||||
CGizmo::EGizmoMode CGizmo::Mode() const
|
||||
{
|
||||
return mMode;
|
||||
}
|
||||
|
||||
ETransformSpace CGizmo::TransformSpace() const
|
||||
{
|
||||
return mTransformSpace;
|
||||
}
|
||||
|
||||
CVector3f CGizmo::Position() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
CVector3f CGizmo::DeltaTranslation() const
|
||||
{
|
||||
return mDeltaTranslation;
|
||||
}
|
||||
|
||||
CVector3f CGizmo::TotalTranslation() const
|
||||
{
|
||||
return mTotalTranslation;
|
||||
}
|
||||
|
||||
CQuaternion CGizmo::Rotation() const
|
||||
{
|
||||
return mRotation;
|
||||
}
|
||||
|
||||
CQuaternion CGizmo::DeltaRotation() const
|
||||
{
|
||||
return mDeltaRotation;
|
||||
}
|
||||
|
||||
CVector3f CGizmo::TotalRotation() const
|
||||
{
|
||||
return mTotalRotation;
|
||||
}
|
||||
|
||||
CVector3f CGizmo::Scale() const
|
||||
{
|
||||
return mScale;
|
||||
}
|
||||
|
||||
CVector3f CGizmo::DeltaScale() const
|
||||
{
|
||||
return mDeltaScale;
|
||||
}
|
||||
|
||||
CVector3f CGizmo::TotalScale() const
|
||||
{
|
||||
return mTotalScale;
|
||||
}
|
||||
|
||||
void CGizmo::SetMode(EGizmoMode mode)
|
||||
{
|
||||
mMode = mode;
|
||||
|
||||
switch (mode)
|
||||
switch (Mode)
|
||||
{
|
||||
case eTranslate:
|
||||
mpCurrentParts = smTranslateModels;
|
||||
@@ -590,32 +522,22 @@ void CGizmo::SetMode(EGizmoMode mode)
|
||||
}
|
||||
}
|
||||
|
||||
void CGizmo::SetTransformSpace(ETransformSpace space)
|
||||
void CGizmo::SetTransformSpace(ETransformSpace Space)
|
||||
{
|
||||
mTransformSpace = space;
|
||||
mTransformSpace = Space;
|
||||
|
||||
if (space == eWorldTransform)
|
||||
if (Space == eWorldTransform)
|
||||
mRotation = CQuaternion::skIdentity;
|
||||
else
|
||||
mRotation = mLocalRotation;
|
||||
}
|
||||
|
||||
void CGizmo::SetPosition(const CVector3f& position)
|
||||
void CGizmo::SetLocalRotation(const CQuaternion& rkOrientation)
|
||||
{
|
||||
mPosition = position;
|
||||
}
|
||||
|
||||
void CGizmo::SetLocalRotation(const CQuaternion& orientation)
|
||||
{
|
||||
mLocalRotation = orientation;
|
||||
mLocalRotation = rkOrientation;
|
||||
|
||||
if (mTransformSpace == eLocalTransform)
|
||||
mRotation = orientation;
|
||||
}
|
||||
|
||||
void CGizmo::EnableCursorWrap(bool wrap)
|
||||
{
|
||||
mEnableCursorWrap = wrap;
|
||||
mRotation = rkOrientation;
|
||||
}
|
||||
|
||||
// ************ PRIVATE STATIC ************
|
||||
@@ -666,9 +588,9 @@ void CGizmo::UpdateTransform()
|
||||
// Scale also factors in axis flip if mode is Scale.
|
||||
if (mMode == eScale)
|
||||
{
|
||||
if (mFlipScaleX) mScale.x = -mScale.x;
|
||||
if (mFlipScaleY) mScale.y = -mScale.y;
|
||||
if (mFlipScaleZ) mScale.z = -mScale.z;
|
||||
if (mFlipScaleX) mScale.X = -mScale.X;
|
||||
if (mFlipScaleY) mScale.Y = -mScale.Y;
|
||||
if (mFlipScaleZ) mScale.Z = -mScale.Z;
|
||||
}
|
||||
|
||||
// Create transform
|
||||
@@ -698,33 +620,33 @@ void CGizmo::UpdateTransform()
|
||||
|
||||
void CGizmo::WrapCursor()
|
||||
{
|
||||
QRect geom = QApplication::desktop()->screenGeometry();
|
||||
QPoint cursorPos = QCursor::pos();
|
||||
QRect Geom = QApplication::desktop()->screenGeometry();
|
||||
QPoint CursorPos = QCursor::pos();
|
||||
|
||||
// Horizontal
|
||||
if (cursorPos.x() == geom.width() - 1)
|
||||
if (CursorPos.x() == Geom.width() - 1)
|
||||
{
|
||||
QCursor::setPos(1, cursorPos.y());
|
||||
mWrapOffset.x += 2.f;
|
||||
QCursor::setPos(1, CursorPos.y());
|
||||
mWrapOffset.X += 2.f;
|
||||
}
|
||||
else if (cursorPos.x() == 0)
|
||||
else if (CursorPos.x() == 0)
|
||||
{
|
||||
QCursor::setPos(geom.width() - 2, cursorPos.y());
|
||||
mWrapOffset.x -= 2.f;
|
||||
QCursor::setPos(Geom.width() - 2, CursorPos.y());
|
||||
mWrapOffset.X -= 2.f;
|
||||
}
|
||||
|
||||
// Vertical
|
||||
cursorPos = QCursor::pos(); // Grab again to account for changes on horizontal wrap
|
||||
CursorPos = QCursor::pos(); // Grab again to account for changes on horizontal wrap
|
||||
|
||||
if (cursorPos.y() == geom.height() - 1)
|
||||
if (CursorPos.y() == Geom.height() - 1)
|
||||
{
|
||||
QCursor::setPos(cursorPos.x(), 1);
|
||||
mWrapOffset.y -= 2.f;
|
||||
QCursor::setPos(CursorPos.x(), 1);
|
||||
mWrapOffset.Y -= 2.f;
|
||||
}
|
||||
else if (cursorPos.y() == 0)
|
||||
else if (CursorPos.y() == 0)
|
||||
{
|
||||
QCursor::setPos(cursorPos.x(), geom.height() - 2);
|
||||
mWrapOffset.y += 2.f;
|
||||
QCursor::setPos(CursorPos.x(), Geom.height() - 2);
|
||||
mWrapOffset.Y += 2.f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user