Translation gizmo transform functionality implemented
This commit is contained in:
parent
08dbdb337a
commit
63c8351dcf
|
@ -0,0 +1,44 @@
|
|||
#include "CPlane.h"
|
||||
|
||||
CPlane::CPlane()
|
||||
{
|
||||
mNormal = CVector3f::skUp;
|
||||
mDist = 0.f;
|
||||
}
|
||||
|
||||
CPlane::CPlane(const CVector3f& normal, float dist)
|
||||
{
|
||||
mNormal = normal;
|
||||
mDist = dist;
|
||||
}
|
||||
|
||||
CPlane::CPlane(const CVector3f& normal, const CVector3f& origin)
|
||||
{
|
||||
Redefine(normal, origin);
|
||||
}
|
||||
|
||||
void CPlane::Redefine(const CVector3f& normal, const CVector3f& origin)
|
||||
{
|
||||
mNormal = normal;
|
||||
mDist = -normal.Dot(origin);
|
||||
}
|
||||
|
||||
CVector3f CPlane::Normal() const
|
||||
{
|
||||
return mNormal;
|
||||
}
|
||||
|
||||
float CPlane::Dist() const
|
||||
{
|
||||
return mDist;
|
||||
}
|
||||
|
||||
void CPlane::SetNormal(const CVector3f& normal)
|
||||
{
|
||||
mNormal = normal;
|
||||
}
|
||||
|
||||
void CPlane::SetDist(float dist)
|
||||
{
|
||||
mDist = dist;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef CPLANE_H
|
||||
#define CPLANE_H
|
||||
|
||||
#include "CVector3f.h"
|
||||
|
||||
class CPlane
|
||||
{
|
||||
CVector3f mNormal;
|
||||
float mDist;
|
||||
|
||||
public:
|
||||
CPlane();
|
||||
CPlane(const CVector3f& normal, float dist);
|
||||
CPlane(const CVector3f& normal, const CVector3f& origin);
|
||||
|
||||
void Redefine(const CVector3f& normal, const CVector3f& origin);
|
||||
CVector3f Normal() const;
|
||||
float Dist() const;
|
||||
void SetNormal(const CVector3f& normal);
|
||||
void SetDist(float dist);
|
||||
};
|
||||
|
||||
#endif // CPLANE_H
|
|
@ -18,6 +18,47 @@ CQuaternion::CQuaternion(float _x, float _y, float _z, float _w)
|
|||
w = _w;
|
||||
}
|
||||
|
||||
CVector3f CQuaternion::XAxis()
|
||||
{
|
||||
return (*this * CVector3f::skUnitX);
|
||||
}
|
||||
|
||||
CVector3f CQuaternion::YAxis()
|
||||
{
|
||||
return (*this * CVector3f::skUnitY);
|
||||
}
|
||||
|
||||
CVector3f CQuaternion::ZAxis()
|
||||
{
|
||||
return (*this * CVector3f::skUnitZ);
|
||||
}
|
||||
|
||||
CQuaternion CQuaternion::Inverse()
|
||||
{
|
||||
float fNorm = (w * w) + (x * x) + (y * y) + (z * z);
|
||||
|
||||
if (fNorm > 0.f)
|
||||
{
|
||||
float fInvNorm = 1.f / fNorm;
|
||||
return CQuaternion(-x * fInvNorm, -y * fInvNorm, -z * fInvNorm, w * fInvNorm);
|
||||
}
|
||||
else
|
||||
return CQuaternion::skZero;
|
||||
}
|
||||
|
||||
// ************ OPERATORS ************
|
||||
CVector3f CQuaternion::operator*(const CVector3f& vec) const
|
||||
{
|
||||
CVector3f uv, uuv;
|
||||
CVector3f qvec(x, y, z);
|
||||
uv = qvec.Cross(vec);
|
||||
uuv = qvec.Cross(uv);
|
||||
uv *= (2.0f * w);
|
||||
uuv *= 2.0f;
|
||||
|
||||
return vec + uv + uuv;
|
||||
}
|
||||
|
||||
CQuaternion CQuaternion::operator*(const CQuaternion& other) const
|
||||
{
|
||||
CQuaternion out;
|
||||
|
@ -84,3 +125,4 @@ CQuaternion CQuaternion::FromAxisAngle(float angle, CVector3f axis)
|
|||
}
|
||||
|
||||
CQuaternion CQuaternion::skIdentity = CQuaternion(0.f, 0.f, 0.f, 1.f);
|
||||
CQuaternion CQuaternion::skZero = CQuaternion(0.f, 0.f, 0.f, 0.f);
|
||||
|
|
|
@ -11,7 +11,13 @@ public:
|
|||
CQuaternion();
|
||||
CQuaternion(float _x, float _y, float _z, float _w);
|
||||
|
||||
CVector3f XAxis();
|
||||
CVector3f YAxis();
|
||||
CVector3f ZAxis();
|
||||
CQuaternion Inverse();
|
||||
|
||||
// Operators
|
||||
CVector3f operator*(const CVector3f& vec) const;
|
||||
CQuaternion operator*(const CQuaternion& other) const;
|
||||
void operator *= (const CQuaternion& other);
|
||||
|
||||
|
@ -20,6 +26,7 @@ public:
|
|||
static CQuaternion FromAxisAngle(float angle, CVector3f axis);
|
||||
|
||||
static CQuaternion skIdentity;
|
||||
static CQuaternion skZero;
|
||||
};
|
||||
|
||||
#endif // CQUATERNION_H
|
||||
|
|
|
@ -279,12 +279,15 @@ const float& CVector3f::operator[](long index) const
|
|||
const CVector3f CVector3f::skZero = CVector3f(0.f);
|
||||
const CVector3f CVector3f::skOne = CVector3f(1.f);
|
||||
const CVector3f CVector3f::skInfinite = CVector3f(FLT_MAX);
|
||||
const CVector3f CVector3f::skForward = CVector3f(0.f, 1.f, 0.f);
|
||||
const CVector3f CVector3f::skBack = CVector3f(0.f, -1.f, 0.f);
|
||||
const CVector3f CVector3f::skRight = CVector3f( 1.f, 0.f, 0.f);
|
||||
const CVector3f CVector3f::skLeft = CVector3f(-1.f, 0.f, 0.f);
|
||||
const CVector3f CVector3f::skUp = CVector3f(0.f, 0.f, 1.f);
|
||||
const CVector3f CVector3f::skDown = CVector3f(0.f, 0.f, -1.f);
|
||||
const CVector3f CVector3f::skUnitX = CVector3f(1.f, 0.f, 0.f);
|
||||
const CVector3f CVector3f::skUnitY = CVector3f(0.f, 1.f, 0.f);
|
||||
const CVector3f CVector3f::skUnitZ = CVector3f(0.f, 0.f, 1.f);
|
||||
const CVector3f CVector3f::skRight = CVector3f::skUnitX;
|
||||
const CVector3f CVector3f::skLeft = -CVector3f::skUnitX;
|
||||
const CVector3f CVector3f::skForward = CVector3f::skUnitY;
|
||||
const CVector3f CVector3f::skBack = -CVector3f::skUnitY;
|
||||
const CVector3f CVector3f::skUp = CVector3f::skUnitZ;
|
||||
const CVector3f CVector3f::skDown = -CVector3f::skUnitZ;
|
||||
|
||||
// ************ OTHER ************
|
||||
std::ostream& operator<<(std::ostream& o, const CVector3f& Vector)
|
||||
|
|
|
@ -75,10 +75,13 @@ public:
|
|||
static const CVector3f skZero;
|
||||
static const CVector3f skOne;
|
||||
static const CVector3f skInfinite;
|
||||
static const CVector3f skForward;
|
||||
static const CVector3f skBack;
|
||||
static const CVector3f skUnitX;
|
||||
static const CVector3f skUnitY;
|
||||
static const CVector3f skUnitZ;
|
||||
static const CVector3f skRight;
|
||||
static const CVector3f skLeft;
|
||||
static const CVector3f skForward;
|
||||
static const CVector3f skBack;
|
||||
static const CVector3f skUp;
|
||||
static const CVector3f skDown;
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef ETRANSFORMSPACE
|
||||
#define ETRANSFORMSPACE
|
||||
|
||||
enum ETransformSpace
|
||||
{
|
||||
eWorldTransform,
|
||||
eLocalTransform
|
||||
};
|
||||
|
||||
#endif // ETRANSFORMSPACE
|
||||
|
|
@ -3,6 +3,11 @@
|
|||
namespace Math
|
||||
{
|
||||
|
||||
float Abs(float v)
|
||||
{
|
||||
return fabs(v);
|
||||
}
|
||||
|
||||
float Pow(float Base, float Exponent)
|
||||
{
|
||||
return pow(Base, Exponent);
|
||||
|
@ -15,6 +20,23 @@ float Distance(const CVector3f& A, const CVector3f& B)
|
|||
Pow(B.z - A.z, 2.f) );
|
||||
}
|
||||
|
||||
std::pair<bool,float> RayPlaneIntersecton(const CRay& ray, const CPlane& plane)
|
||||
{
|
||||
// Code based on ray/plane intersect code from Ogre
|
||||
// https://bitbucket.org/sinbad/ogre/src/197116fd2ac62c57cdeed1666f9866c3dddd4289/OgreMain/src/OgreMath.cpp?at=default#OgreMath.cpp-350
|
||||
|
||||
// Are ray and plane parallel?
|
||||
float denom = plane.Normal().Dot(ray.Direction());
|
||||
|
||||
if (Abs(denom) < FLT_EPSILON)
|
||||
return std::pair<bool,float>(false, 0.f);
|
||||
|
||||
// Not parallel
|
||||
float nom = plane.Normal().Dot(ray.Origin()) + plane.Dist();
|
||||
float t = -(nom / denom);
|
||||
return std::pair<bool,float>(t >= 0.f, t);
|
||||
}
|
||||
|
||||
std::pair<bool,float> RayBoxIntersection(const CRay& Ray, const CAABox& Box)
|
||||
{
|
||||
// Code slightly modified from Ogre
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "CAABox.h"
|
||||
#include "CRay.h"
|
||||
#include "CPlane.h"
|
||||
#include "CVector3f.h"
|
||||
#include "SRayIntersection.h"
|
||||
#include <utility>
|
||||
|
@ -10,10 +11,14 @@
|
|||
namespace Math
|
||||
{
|
||||
|
||||
float Abs(float v);
|
||||
|
||||
float Pow(float Base, float Exponent);
|
||||
|
||||
float Distance(const CVector3f& A, const CVector3f& B);
|
||||
|
||||
std::pair<bool,float> RayPlaneIntersecton(const CRay& ray, const CPlane& plane);
|
||||
|
||||
std::pair<bool,float> RayBoxIntersection(const CRay& Ray, const CAABox& Box);
|
||||
|
||||
std::pair<bool,float> RayLineIntersection(const CRay& ray, const CVector3f& pointA,
|
||||
|
|
|
@ -140,10 +140,6 @@ void CRenderer::RenderBuckets(CCamera& Camera)
|
|||
mTransparentBucket.Sort(Camera);
|
||||
mTransparentBucket.Draw(mOptions);
|
||||
mTransparentBucket.Clear();
|
||||
|
||||
// Clear depth buffer to enable more rendering passes
|
||||
glDepthMask(GL_TRUE);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void CRenderer::RenderBloom()
|
||||
|
@ -331,6 +327,12 @@ void CRenderer::EndFrame()
|
|||
gDrawCount = 0;
|
||||
}
|
||||
|
||||
void CRenderer::ClearDepthBuffer()
|
||||
{
|
||||
glDepthMask(GL_TRUE);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
// ************ PRIVATE ************
|
||||
void CRenderer::InitFramebuffer()
|
||||
{
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
void AddTransparentMesh(IRenderable *pRenderable, u32 AssetID, CAABox& AABox, ERenderCommand Command);
|
||||
void BeginFrame();
|
||||
void EndFrame();
|
||||
void ClearDepthBuffer();
|
||||
|
||||
// Private
|
||||
private:
|
||||
|
|
|
@ -157,7 +157,6 @@ void CSceneManager::SetActiveArea(CGameArea* _area)
|
|||
{
|
||||
CScriptObject *pObj = pGenLayer->ObjectByIndex(o);
|
||||
CScriptNode *Node = AddScriptObject(pObj);
|
||||
Node->BuildLightList(mpArea);
|
||||
|
||||
// Add to map
|
||||
mScriptNodeMap[pObj->InstanceID()] = Node;
|
||||
|
@ -165,9 +164,12 @@ void CSceneManager::SetActiveArea(CGameArea* _area)
|
|||
}
|
||||
PickEnvironmentObjects();
|
||||
|
||||
// Ensure script nodes have valid positions
|
||||
// Ensure script nodes have valid positions + build light lists
|
||||
for (auto it = mScriptNodeMap.begin(); it != mScriptNodeMap.end(); it++)
|
||||
{
|
||||
it->second->GeneratePosition();
|
||||
it->second->BuildLightList(mpArea);
|
||||
}
|
||||
|
||||
u32 NumLightLayers = mpArea->GetLightLayerCount();
|
||||
CGraphics::sAreaAmbientColor = CColor::skBlack;
|
||||
|
|
|
@ -134,7 +134,8 @@ SOURCES += \
|
|||
UI/WScanPreviewPanel.cpp \
|
||||
UI/WIntegralSpinBox.cpp \
|
||||
UI/CAboutDialog.cpp \
|
||||
UI/CGizmo.cpp
|
||||
UI/CGizmo.cpp \
|
||||
Common/CPlane.cpp
|
||||
|
||||
HEADERS += \
|
||||
Common/AnimUtil.h \
|
||||
|
@ -283,7 +284,9 @@ HEADERS += \
|
|||
UI/CAboutDialog.h \
|
||||
UI/CGizmo.h \
|
||||
Core/IRenderable.h \
|
||||
Core/SRenderablePtr.h
|
||||
Core/SRenderablePtr.h \
|
||||
Common/ETransformSpace.h \
|
||||
Common/CPlane.h
|
||||
|
||||
FORMS += \
|
||||
UI/CWorldEditorWindow.ui \
|
||||
|
|
|
@ -185,15 +185,29 @@ void CSceneNode::DrawBoundingBox()
|
|||
}
|
||||
|
||||
// ************ TRANSFORM ************
|
||||
void CSceneNode::Translate(const CVector3f& Translation)
|
||||
void CSceneNode::Translate(const CVector3f& translation, ETransformSpace transformSpace)
|
||||
{
|
||||
mPosition += Translation;
|
||||
switch (transformSpace)
|
||||
{
|
||||
case eWorldTransform:
|
||||
mPosition += translation;
|
||||
break;
|
||||
case eLocalTransform:
|
||||
mPosition += mRotation * translation;
|
||||
break;
|
||||
}
|
||||
MarkTransformChanged();
|
||||
}
|
||||
|
||||
void CSceneNode::Scale(const CVector3f& Scale)
|
||||
void CSceneNode::Rotate(const CQuaternion& rotation, ETransformSpace transformSpace)
|
||||
{
|
||||
mScale *= Scale;
|
||||
mRotation *= rotation;
|
||||
MarkTransformChanged();
|
||||
}
|
||||
|
||||
void CSceneNode::Scale(const CVector3f& scale, ETransformSpace transformSpace)
|
||||
{
|
||||
mScale *= scale;
|
||||
MarkTransformChanged();
|
||||
}
|
||||
|
||||
|
@ -209,9 +223,9 @@ void CSceneNode::UpdateTransform()
|
|||
void CSceneNode::ForceRecalculateTransform()
|
||||
{
|
||||
_mCachedTransform = CTransform4f::skIdentity;
|
||||
_mCachedTransform.Scale(GetAbsoluteScale());
|
||||
_mCachedTransform.Rotate(GetAbsoluteRotation());
|
||||
_mCachedTransform.Translate(GetAbsolutePosition());
|
||||
_mCachedTransform.Scale(AbsoluteScale());
|
||||
_mCachedTransform.Rotate(AbsoluteRotation());
|
||||
_mCachedTransform.Translate(AbsolutePosition());
|
||||
_mCachedAABox = mLocalAABox.Transformed(_mCachedTransform);
|
||||
|
||||
// Sync with children - only needed if caller hasn't marked transform changed already
|
||||
|
@ -259,47 +273,47 @@ CSceneManager* CSceneNode::Scene()
|
|||
return mpScene;
|
||||
}
|
||||
|
||||
CVector3f CSceneNode::GetPosition() const
|
||||
CVector3f CSceneNode::LocalPosition() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
CVector3f CSceneNode::GetAbsolutePosition() const
|
||||
CVector3f CSceneNode::AbsolutePosition() const
|
||||
{
|
||||
CVector3f ret = mPosition;
|
||||
|
||||
if ((mpParent) && (InheritsPosition()))
|
||||
ret += mpParent->GetAbsolutePosition();
|
||||
ret += mpParent->AbsolutePosition();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
CQuaternion CSceneNode::GetRotation() const
|
||||
CQuaternion CSceneNode::LocalRotation() const
|
||||
{
|
||||
return mRotation;
|
||||
}
|
||||
|
||||
CQuaternion CSceneNode::GetAbsoluteRotation() const
|
||||
CQuaternion CSceneNode::AbsoluteRotation() const
|
||||
{
|
||||
CQuaternion ret = mRotation;
|
||||
|
||||
if ((mpParent) && (InheritsRotation()))
|
||||
ret *= mpParent->GetAbsoluteRotation();
|
||||
ret *= mpParent->AbsoluteRotation();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
CVector3f CSceneNode::GetScale() const
|
||||
CVector3f CSceneNode::LocalScale() const
|
||||
{
|
||||
return mScale;
|
||||
}
|
||||
|
||||
CVector3f CSceneNode::GetAbsoluteScale() const
|
||||
CVector3f CSceneNode::AbsoluteScale() const
|
||||
{
|
||||
CVector3f ret = mScale;
|
||||
|
||||
if ((mpParent) && (InheritsScale()))
|
||||
ret *= mpParent->GetAbsoluteScale();
|
||||
ret *= mpParent->AbsoluteScale();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -3,13 +3,14 @@
|
|||
|
||||
#include <Core/IRenderable.h>
|
||||
#include "ENodeType.h"
|
||||
#include <Common/CVector3f.h>
|
||||
#include <Common/CQuaternion.h>
|
||||
#include <Common/CAABox.h>
|
||||
#include <Common/CQuaternion.h>
|
||||
#include <Common/CRay.h>
|
||||
#include <Common/CRayCollisionTester.h>
|
||||
#include <Common/types.h>
|
||||
#include <Common/CTransform4f.h>
|
||||
#include <Common/CVector3f.h>
|
||||
#include <Common/ETransformSpace.h>
|
||||
#include <Common/types.h>
|
||||
#include <Core/ERenderOptions.h>
|
||||
#include <Resource/CLight.h>
|
||||
#include <Resource/CGameArea.h>
|
||||
|
@ -68,8 +69,9 @@ public:
|
|||
void DrawBoundingBox();
|
||||
|
||||
// Transform
|
||||
void Translate(const CVector3f& Translation);
|
||||
void Scale(const CVector3f& Scale);
|
||||
void Translate(const CVector3f& translation, ETransformSpace transformSpace);
|
||||
void Rotate(const CQuaternion& rotation, ETransformSpace transformSpace);
|
||||
void Scale(const CVector3f& scale, ETransformSpace transformSpace);
|
||||
void UpdateTransform();
|
||||
void ForceRecalculateTransform();
|
||||
void MarkTransformChanged();
|
||||
|
@ -79,12 +81,12 @@ public:
|
|||
std::string Name() const;
|
||||
CSceneNode* Parent() const;
|
||||
CSceneManager* Scene();
|
||||
CVector3f GetPosition() const;
|
||||
CVector3f GetAbsolutePosition() const;
|
||||
CQuaternion GetRotation() const;
|
||||
CQuaternion GetAbsoluteRotation() const;
|
||||
CVector3f GetScale() const;
|
||||
CVector3f GetAbsoluteScale() const;
|
||||
CVector3f LocalPosition() const;
|
||||
CVector3f AbsolutePosition() const;
|
||||
CQuaternion LocalRotation() const;
|
||||
CQuaternion AbsoluteRotation() const;
|
||||
CVector3f LocalScale() const;
|
||||
CVector3f AbsoluteScale() const;
|
||||
CAABox AABox();
|
||||
CVector3f CenterPoint();
|
||||
bool MarkedVisible() const;
|
||||
|
|
|
@ -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());
|
||||
mpVolumePreviewNode->Scale(mpInstance->GetVolume(), eWorldTransform);
|
||||
mpVolumePreviewNode->ForceAlphaEnabled(true);
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ void CScriptNode::GeneratePosition()
|
|||
const SLink& link = (mpInstance->NumInLinks() > 0 ? mpInstance->InLink(0) : mpInstance->OutLink(0));
|
||||
CScriptNode *pNode = mpScene->ScriptNodeByID(link.ObjectID);
|
||||
pNode->GeneratePosition();
|
||||
mPosition = pNode->GetAbsolutePosition();
|
||||
mPosition = pNode->AbsolutePosition();
|
||||
mPosition.z += (pNode->AABox().Size().z / 2.f);
|
||||
mPosition.z += (AABox().Size().z / 2.f);
|
||||
mPosition.z += 2.f;
|
||||
|
|
|
@ -105,24 +105,31 @@ void CEditorGLWidget::mousePressEvent(QMouseEvent *pEvent)
|
|||
|
||||
// Left click only activates if mouse input is inactive to prevent the user from
|
||||
// clicking on things and creating selection rectangles while the cursor is hidden
|
||||
else if (pEvent->button() == Qt::LeftButton)
|
||||
else
|
||||
{
|
||||
if (pEvent->button() == Qt::LeftButton)
|
||||
mButtonsPressed |= eLeftButton;
|
||||
|
||||
emit MouseClick(pEvent);
|
||||
}
|
||||
|
||||
mLastMousePos = pEvent->globalPos();
|
||||
}
|
||||
|
||||
void CEditorGLWidget::mouseReleaseEvent(QMouseEvent *pEvent)
|
||||
{
|
||||
bool fromMouseInput = IsMouseInputActive();
|
||||
if (pEvent->button() == Qt::LeftButton) mButtonsPressed &= ~eLeftButton;
|
||||
if (pEvent->button() == Qt::MidButton) mButtonsPressed &= ~eMiddleButton;
|
||||
if (pEvent->button() == Qt::RightButton) mButtonsPressed &= ~eRightButton;
|
||||
|
||||
// Make cursor visible and emit mouse click event if middle/right mouse buttons are both released
|
||||
// Make cursor visible if needed
|
||||
if (!IsMouseInputActive())
|
||||
{
|
||||
SetCursorVisible(true);
|
||||
emit MouseClick(pEvent);
|
||||
}
|
||||
|
||||
// Emit mouse release event if we didn't just exit mouse input (or regardless on left click)
|
||||
if (!fromMouseInput || (pEvent->button() == Qt::LeftButton))
|
||||
emit MouseRelease(pEvent);
|
||||
}
|
||||
|
||||
void CEditorGLWidget::keyPressEvent(QKeyEvent *pEvent)
|
||||
|
|
|
@ -54,6 +54,7 @@ signals:
|
|||
void Render(CCamera& Camera);
|
||||
void PostRender();
|
||||
void MouseClick(QMouseEvent *pEvent);
|
||||
void MouseRelease(QMouseEvent *pEvent);
|
||||
void MouseDrag(QMouseEvent *pEvent);
|
||||
|
||||
private:
|
||||
|
|
145
UI/CGizmo.cpp
145
UI/CGizmo.cpp
|
@ -2,6 +2,8 @@
|
|||
#include <Common/Math.h>
|
||||
#include <Core/CRenderer.h>
|
||||
#include <Core/CResCache.h>
|
||||
#include <Core/CDrawUtil.h>
|
||||
#include <iostream>
|
||||
|
||||
CGizmo::CGizmo()
|
||||
{
|
||||
|
@ -15,9 +17,10 @@ CGizmo::CGizmo()
|
|||
mPosition = CVector3f::skZero;
|
||||
mRotation = CQuaternion::skIdentity;
|
||||
mScale = CVector3f::skOne;
|
||||
mDeltaPosition = CVector3f::skZero;
|
||||
mDeltaTranslation = CVector3f::skZero;
|
||||
mDeltaRotation = CQuaternion::skIdentity;
|
||||
mDeltaScale = CVector3f::skOne;
|
||||
mSetOffset = false;
|
||||
mFlipScaleX = false;
|
||||
mFlipScaleY = false;
|
||||
mFlipScaleZ = false;
|
||||
|
@ -109,11 +112,10 @@ void CGizmo::UpdateForCamera(const CCamera &camera)
|
|||
mBillboardRotation = CQuaternion::FromAxisAngle(angle, axis);
|
||||
}
|
||||
|
||||
bool CGizmo::IntersectsRay(const CRay &ray)
|
||||
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());
|
||||
float threshold = 0.02f * mGizmoSize * mCameraDist;
|
||||
|
||||
// Do raycast on each model
|
||||
SModelPart *pPart = mpCurrentParts;
|
||||
|
@ -126,7 +128,12 @@ bool CGizmo::IntersectsRay(const CRay &ray)
|
|||
|
||||
for (u32 iPart = 0; iPart < mNumCurrentParts; iPart++)
|
||||
{
|
||||
if (!pPart->enableRayCast) continue;
|
||||
if (!pPart->enableRayCast)
|
||||
{
|
||||
pPart++;
|
||||
continue;
|
||||
}
|
||||
|
||||
CModel *pModel = pPart->pModel;
|
||||
|
||||
// Ray/Model AABox test - allow buffer room because lines are small
|
||||
|
@ -141,7 +148,7 @@ bool CGizmo::IntersectsRay(const CRay &ray)
|
|||
|
||||
for (u32 iSurf = 0; iSurf < pModel->GetSurfaceCount(); iSurf++)
|
||||
{
|
||||
// Skip surface/box check
|
||||
// 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(localRay, 0.05f);
|
||||
|
||||
|
@ -183,11 +190,129 @@ bool CGizmo::IntersectsRay(const CRay &ray)
|
|||
return true;
|
||||
}
|
||||
|
||||
u32 CGizmo::NumSelectedAxes()
|
||||
{
|
||||
u32 out = 0;
|
||||
|
||||
for (u32 iAxis = 1; iAxis < 8; iAxis <<= 1)
|
||||
if (mSelectedAxes & (EGizmoAxes) iAxis) out++;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void CGizmo::ResetSelectedAxes()
|
||||
{
|
||||
mSelectedAxes = eNone;
|
||||
}
|
||||
|
||||
void CGizmo::StartTransform()
|
||||
{
|
||||
mSetOffset = false;
|
||||
mTotalTranslation = CVector3f::skZero;
|
||||
mTotalRotation = CQuaternion::skIdentity;
|
||||
mTotalScale = CVector3f::skOne;
|
||||
}
|
||||
|
||||
bool CGizmo::TransformFromInput(const CRay& ray, const CCamera& camera)
|
||||
{
|
||||
if (mMode == eTranslate)
|
||||
{
|
||||
// Create translate plane
|
||||
CVector3f axisA, axisB;
|
||||
u32 numAxes = NumSelectedAxes();
|
||||
|
||||
if (numAxes == 1)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
else if (numAxes == 2)
|
||||
{
|
||||
axisA = (mSelectedAxes & eX ? mRotation.XAxis() : mRotation.YAxis());
|
||||
axisB = (mSelectedAxes & eZ ? mRotation.ZAxis() : mRotation.YAxis());
|
||||
}
|
||||
|
||||
CVector3f planeNormal = axisA.Cross(axisB);
|
||||
mTranslatePlane.Redefine(planeNormal, mPosition);
|
||||
|
||||
// Do translate
|
||||
std::pair<bool,float> result = Math::RayPlaneIntersecton(ray, mTranslatePlane);
|
||||
|
||||
if (result.first)
|
||||
{
|
||||
CVector3f hit = ray.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;
|
||||
|
||||
// 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;
|
||||
|
||||
// Set offset
|
||||
if (!mSetOffset)
|
||||
{
|
||||
mTranslateOffset = mPosition - newPos;
|
||||
mDeltaTranslation = CVector3f::skZero;
|
||||
mSetOffset = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Apply translation
|
||||
else
|
||||
{
|
||||
mDeltaTranslation = mRotation.Inverse() * (newPos - mPosition + mTranslateOffset);
|
||||
mTotalTranslation += mDeltaTranslation;
|
||||
mPosition = newPos + mTranslateOffset;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
mDeltaTranslation = CVector3f::skZero;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGizmo::EndTransform()
|
||||
{
|
||||
}
|
||||
|
||||
CGizmo::EGizmoMode CGizmo::Mode()
|
||||
{
|
||||
return mMode;
|
||||
}
|
||||
|
||||
CVector3f CGizmo::Position()
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
CVector3f CGizmo::DeltaTranslation()
|
||||
{
|
||||
return mDeltaTranslation;
|
||||
}
|
||||
|
||||
CVector3f CGizmo::TotalTranslation()
|
||||
{
|
||||
return mTotalTranslation;
|
||||
}
|
||||
|
||||
void CGizmo::SetMode(EGizmoMode mode)
|
||||
{
|
||||
mMode = mode;
|
||||
|
@ -197,16 +322,22 @@ void CGizmo::SetMode(EGizmoMode mode)
|
|||
case eTranslate:
|
||||
mpCurrentParts = smTranslateModels;
|
||||
mNumCurrentParts = 9;
|
||||
mDeltaRotation = CQuaternion::skIdentity;
|
||||
mDeltaScale = CVector3f::skOne;
|
||||
break;
|
||||
|
||||
case eRotate:
|
||||
mpCurrentParts = smRotateModels;
|
||||
mNumCurrentParts = 4;
|
||||
mDeltaTranslation = CVector3f::skZero;
|
||||
mDeltaScale = CVector3f::skOne;
|
||||
break;
|
||||
|
||||
case eScale:
|
||||
mpCurrentParts = smScaleModels;
|
||||
mNumCurrentParts = 10;
|
||||
mDeltaTranslation = CVector3f::skZero;
|
||||
mDeltaRotation = CQuaternion::skIdentity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -216,9 +347,9 @@ void CGizmo::SetPosition(const CVector3f& position)
|
|||
mPosition = position;
|
||||
}
|
||||
|
||||
void CGizmo::ResetSelectedAxes()
|
||||
void CGizmo::SetOrientation(const CQuaternion& orientation)
|
||||
{
|
||||
mSelectedAxes = eNone;
|
||||
mRotation = orientation;
|
||||
}
|
||||
|
||||
// ************ PRIVATE STATIC ************
|
||||
|
|
28
UI/CGizmo.h
28
UI/CGizmo.h
|
@ -1,8 +1,9 @@
|
|||
#ifndef CGIZMO_H
|
||||
#define CGIZMO_H
|
||||
|
||||
#include <Common/CVector3f.h>
|
||||
#include <Common/CPlane.h>
|
||||
#include <Common/CQuaternion.h>
|
||||
#include <Common/CVector3f.h>
|
||||
#include <Common/EnumUtil.h>
|
||||
#include <Core/CCamera.h>
|
||||
#include <Core/CToken.h>
|
||||
|
@ -63,15 +64,24 @@ private:
|
|||
|
||||
CTransform4f mTransform;
|
||||
CVector3f mPosition;
|
||||
CVector3f mDeltaTranslation;
|
||||
CVector3f mTotalTranslation;
|
||||
CQuaternion mRotation;
|
||||
CVector3f mScale;
|
||||
CVector3f mDeltaPosition;
|
||||
CQuaternion mDeltaRotation;
|
||||
CQuaternion mTotalRotation;
|
||||
CVector3f mScale;
|
||||
CVector3f mDeltaScale;
|
||||
CVector3f mTotalScale;
|
||||
bool mFlipScaleX;
|
||||
bool mFlipScaleY;
|
||||
bool mFlipScaleZ;
|
||||
|
||||
CPlane mTranslatePlane;
|
||||
CVector3f mLastTranslatePosition;
|
||||
CVector3f mTranslateOffset;
|
||||
bool mSetOffset;
|
||||
|
||||
|
||||
struct SModelPart
|
||||
{
|
||||
EGizmoAxes modelAxes;
|
||||
|
@ -104,12 +114,20 @@ public:
|
|||
void IncrementSize();
|
||||
void DecrementSize();
|
||||
void UpdateForCamera(const CCamera& camera);
|
||||
bool IntersectsRay(const CRay& ray);
|
||||
bool CheckSelectedAxes(const CRay& ray);
|
||||
u32 NumSelectedAxes();
|
||||
void ResetSelectedAxes();
|
||||
void StartTransform();
|
||||
bool TransformFromInput(const CRay& ray, const CCamera& camera);
|
||||
void EndTransform();
|
||||
|
||||
EGizmoMode Mode();
|
||||
CVector3f Position();
|
||||
CVector3f DeltaTranslation();
|
||||
CVector3f TotalTranslation();
|
||||
void SetMode(EGizmoMode mode);
|
||||
void SetPosition(const CVector3f& position);
|
||||
void ResetSelectedAxes();
|
||||
void SetOrientation(const CQuaternion& orientation);
|
||||
|
||||
// Protected
|
||||
protected:
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <iostream>
|
||||
#include <QOpenGLContext>
|
||||
#include <QFontMetrics>
|
||||
#include <QComboBox>
|
||||
#include <Core/Log.h>
|
||||
#include "WDraggableSpinBox.h"
|
||||
|
||||
|
@ -32,6 +33,9 @@ CWorldEditor::CWorldEditor(QWidget *parent) :
|
|||
mpHoverNode = nullptr;
|
||||
mDrawSky = true;
|
||||
mShowGizmo = false;
|
||||
mGizmoHovering = false;
|
||||
mGizmoTransforming = false;
|
||||
mUpdateUILater = false;
|
||||
|
||||
mFrameCount = 0;
|
||||
mFPSTimer.Start();
|
||||
|
@ -47,7 +51,6 @@ CWorldEditor::CWorldEditor(QWidget *parent) :
|
|||
|
||||
delete pOldTitleBar;
|
||||
|
||||
|
||||
// Initialize UI stuff
|
||||
ui->ModifyTabContents->SetEditor(this);
|
||||
ui->InstancesTabContents->SetEditor(this, mpSceneManager);
|
||||
|
@ -55,17 +58,27 @@ CWorldEditor::CWorldEditor(QWidget *parent) :
|
|||
ui->CamSpeedSpinBox->SetDefaultValue(1.0);
|
||||
ResetHover();
|
||||
|
||||
mTransformSpace = eWorldTransform;
|
||||
|
||||
QComboBox *pTransformCombo = new QComboBox(this);
|
||||
pTransformCombo->setMinimumWidth(75);
|
||||
pTransformCombo->addItem("World");
|
||||
pTransformCombo->addItem("Local");
|
||||
ui->MainToolBar->insertWidget(0, pTransformCombo);
|
||||
|
||||
// Initialize offscreen actions
|
||||
addAction(ui->ActionIncrementGizmo);
|
||||
addAction(ui->ActionDecrementGizmo);
|
||||
|
||||
// Connect signals and slots
|
||||
connect(pTransformCombo, 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&)));
|
||||
connect(ui->MainViewport, SIGNAL(ViewportResized(int,int)), this, SLOT(SetViewportSize(int,int)));
|
||||
connect(ui->MainViewport, SIGNAL(frameSwapped()), this, SLOT(ViewportPostRender()));
|
||||
connect(ui->MainViewport, SIGNAL(MouseClick(QMouseEvent*)), this, SLOT(ViewportMouseClick(QMouseEvent*)));
|
||||
connect(ui->MainViewport, SIGNAL(MouseRelease(QMouseEvent*)), this, SLOT(ViewportMouseRelease(QMouseEvent*)));
|
||||
}
|
||||
|
||||
CWorldEditor::~CWorldEditor()
|
||||
|
@ -135,8 +148,16 @@ void CWorldEditor::ViewportRayCast(CRay Ray)
|
|||
{
|
||||
if (!ui->MainViewport->IsMouseInputActive())
|
||||
{
|
||||
// Gizmo ray check
|
||||
mGizmoHovering = mGizmo.IntersectsRay(Ray);
|
||||
if (!mGizmoTransforming)
|
||||
{
|
||||
// Gizmo hover check
|
||||
if (mShowGizmo && !mSelectedNodes.empty())
|
||||
mGizmoHovering = mGizmo.CheckSelectedAxes(Ray);
|
||||
else
|
||||
{
|
||||
mGizmoHovering = false;
|
||||
mGizmo.ResetSelectedAxes();
|
||||
}
|
||||
|
||||
// Scene ray check
|
||||
SRayIntersection Result = mpSceneManager->SceneRayCast(Ray);
|
||||
|
@ -156,7 +177,29 @@ void CWorldEditor::ViewportRayCast(CRay Ray)
|
|||
}
|
||||
else
|
||||
{
|
||||
bool moved = mGizmo.TransformFromInput(Ray, ui->MainViewport->Camera());
|
||||
|
||||
if (moved)
|
||||
{
|
||||
CVector3f delta = mGizmo.DeltaTranslation();
|
||||
|
||||
for (auto it = mSelectedNodes.begin(); it != mSelectedNodes.end(); it++)
|
||||
{
|
||||
(*it)->Translate(delta, mTransformSpace);
|
||||
(*it)->BuildLightList(this->mpArea);
|
||||
}
|
||||
RecalculateSelectionBounds();
|
||||
mUpdateUILater = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mGizmoTransforming)
|
||||
{
|
||||
mGizmoHovering = false;
|
||||
mGizmo.ResetSelectedAxes();
|
||||
}
|
||||
ResetHover();
|
||||
}
|
||||
}
|
||||
|
@ -229,13 +272,32 @@ void CWorldEditor::ClearSelection()
|
|||
// ************ SLOTS ************
|
||||
void CWorldEditor::ViewportMouseDrag(QMouseEvent *pEvent)
|
||||
{
|
||||
// todo: gizmo translate/rotate/scale implementation
|
||||
}
|
||||
|
||||
void CWorldEditor::ViewportMouseClick(QMouseEvent *pEvent)
|
||||
{
|
||||
// Process left click (button press)
|
||||
bool AltPressed = ((pEvent->modifiers() & Qt::AltModifier) != 0);
|
||||
bool CtrlPressed = ((pEvent->modifiers() & Qt::ControlModifier) != 0);
|
||||
|
||||
if (mGizmoHovering && !AltPressed && !CtrlPressed)
|
||||
{
|
||||
mGizmoTransforming = true;
|
||||
mGizmo.StartTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void CWorldEditor::ViewportMouseRelease(QMouseEvent *pEvent)
|
||||
{
|
||||
if (pEvent->button() == Qt::LeftButton)
|
||||
{
|
||||
// Gizmo transform stop
|
||||
if (mGizmoTransforming)
|
||||
{
|
||||
mGizmoTransforming = false;
|
||||
}
|
||||
|
||||
// Object selection/deselection
|
||||
else if (!ui->MainViewport->IsMouseInputActive())
|
||||
{
|
||||
bool ValidNode = ((mpHoverNode) && (mpHoverNode->NodeType() != eStaticNode));
|
||||
bool AltPressed = ((pEvent->modifiers() & Qt::AltModifier) != 0);
|
||||
|
@ -251,22 +313,32 @@ void CWorldEditor::ViewportMouseClick(QMouseEvent *pEvent)
|
|||
DeselectNode(mpHoverNode);
|
||||
}
|
||||
|
||||
// Other - select object
|
||||
else
|
||||
// Ctrl pressed - add object to selection
|
||||
else if (CtrlPressed)
|
||||
{
|
||||
// Control not pressed - clear existing selection
|
||||
if (!CtrlPressed)
|
||||
ClearSelection();
|
||||
|
||||
// Add hover node to selection
|
||||
if (ValidNode)
|
||||
SelectNode(mpHoverNode);
|
||||
}
|
||||
|
||||
UpdateSelectionUI();
|
||||
// Neither pressed
|
||||
else
|
||||
{
|
||||
// If the gizmo isn't under the mouse, clear existing selection + select object (if applicable)
|
||||
if (!mGizmoHovering)
|
||||
{
|
||||
ClearSelection();
|
||||
|
||||
if (ValidNode)
|
||||
SelectNode(mpHoverNode);
|
||||
}
|
||||
}
|
||||
|
||||
// Later, possibly expand to context menu creation for right-click
|
||||
UpdateSelectionUI();
|
||||
}
|
||||
}
|
||||
|
||||
// todo: context menu creation on right-click goes here
|
||||
}
|
||||
|
||||
// ************ SLOTS ************
|
||||
|
@ -298,8 +370,10 @@ void CWorldEditor::ViewportRender(CCamera& Camera)
|
|||
|
||||
if (mShowGizmo && (mSelectedNodes.size() > 0))
|
||||
{
|
||||
mpRenderer->ClearDepthBuffer();
|
||||
|
||||
Camera.LoadMatrices();
|
||||
mGizmo.UpdateForCamera(Camera);
|
||||
if (!mGizmoTransforming) mGizmo.UpdateForCamera(Camera);
|
||||
mGizmo.AddToRenderer(mpRenderer);
|
||||
|
||||
if (mGizmo.Mode() == CGizmo::eRotate)
|
||||
|
@ -318,6 +392,12 @@ void CWorldEditor::ViewportPostRender()
|
|||
// Update UI with raycast results
|
||||
UpdateCursor();
|
||||
UpdateStatusBar();
|
||||
|
||||
if (mUpdateUILater)
|
||||
{
|
||||
UpdateSelectionUI();
|
||||
mUpdateUILater = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CWorldEditor::SetViewportSize(int Width, int Height)
|
||||
|
@ -325,6 +405,22 @@ void CWorldEditor::SetViewportSize(int Width, int Height)
|
|||
mpRenderer->SetViewportSize(Width, Height);
|
||||
}
|
||||
|
||||
void CWorldEditor::SetTransformSpace(int space)
|
||||
{
|
||||
switch (space)
|
||||
{
|
||||
case 0:
|
||||
mTransformSpace = eWorldTransform;
|
||||
mGizmo.SetOrientation(CQuaternion::skIdentity);
|
||||
break;
|
||||
case 1:
|
||||
mTransformSpace = eLocalTransform;
|
||||
if (!mSelectedNodes.empty())
|
||||
mGizmo.SetOrientation(mSelectedNodes.front()->AbsoluteRotation());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ************ PRIVATE ************
|
||||
void CWorldEditor::RecalculateSelectionBounds()
|
||||
{
|
||||
|
@ -396,13 +492,21 @@ void CWorldEditor::UpdateSelectionUI()
|
|||
ui->SelectionInfoLabel->setText(SelectionText);
|
||||
|
||||
// Update transform
|
||||
CVector3f pos = (!mSelectedNodes.empty() ? mSelectedNodes.front()->GetAbsolutePosition() : CVector3f::skZero);
|
||||
CVector3f pos = (!mSelectedNodes.empty() ? mSelectedNodes.front()->AbsolutePosition() : CVector3f::skZero);
|
||||
ui->XSpinBox->setValue(pos.x);
|
||||
ui->YSpinBox->setValue(pos.y);
|
||||
ui->ZSpinBox->setValue(pos.z);
|
||||
|
||||
// Update gizmo
|
||||
if (!mGizmoTransforming)
|
||||
{
|
||||
mGizmo.SetPosition(pos);
|
||||
|
||||
if ((mTransformSpace == eLocalTransform) && !mSelectedNodes.empty())
|
||||
mGizmo.SetOrientation(mSelectedNodes.front()->AbsoluteRotation());
|
||||
else
|
||||
mGizmo.SetOrientation(CQuaternion::skIdentity);
|
||||
}
|
||||
}
|
||||
|
||||
// ************ ACTIONS ************
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <Common/CTimer.h>
|
||||
#include <Common/EKeyInputs.h>
|
||||
#include <Common/SRayIntersection.h>
|
||||
#include <Common/ETransformSpace.h>
|
||||
#include <Core/CRenderer.h>
|
||||
#include <Core/CSceneManager.h>
|
||||
#include <Core/CToken.h>
|
||||
|
@ -25,6 +26,7 @@ class CWorldEditor : public QMainWindow
|
|||
CRenderer *mpRenderer;
|
||||
CSceneManager *mpSceneManager;
|
||||
CGizmo mGizmo;
|
||||
ETransformSpace mTransformSpace;
|
||||
CCamera mCamera;
|
||||
CGameArea *mpArea;
|
||||
CWorld *mpWorld;
|
||||
|
@ -34,6 +36,8 @@ class CWorldEditor : public QMainWindow
|
|||
bool mDrawSky;
|
||||
bool mShowGizmo;
|
||||
bool mGizmoHovering;
|
||||
bool mGizmoTransforming;
|
||||
bool mUpdateUILater;
|
||||
|
||||
CVector3f mHoverPoint;
|
||||
CSceneNode *mpHoverNode;
|
||||
|
@ -64,7 +68,9 @@ public slots:
|
|||
void ViewportPostRender();
|
||||
void ViewportMouseDrag(QMouseEvent *pEvent);
|
||||
void ViewportMouseClick(QMouseEvent *pEvent);
|
||||
void ViewportMouseRelease(QMouseEvent *pEvent);
|
||||
void SetViewportSize(int Width, int Height);
|
||||
void SetTransformSpace(int space);
|
||||
|
||||
private:
|
||||
Ui::CWorldEditor *ui;
|
||||
|
|
|
@ -440,13 +440,16 @@
|
|||
<addaction name="menuWindow"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<widget class="QToolBar" name="Toolbar">
|
||||
<widget class="QToolBar" name="FileToolBar">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>toolBar_2</string>
|
||||
</property>
|
||||
<property name="movable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
|
@ -593,13 +596,19 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<widget class="QToolBar" name="MainToolBar">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
|
|
Loading…
Reference in New Issue