mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-18 18:40:06 +00:00
Scale from center of selection.
This commit is contained in:
parent
388917df89
commit
571969cd65
@ -59,6 +59,36 @@ osg::Quat CSVRender::InstanceMode::eulerToQuat(const osg::Vec3f& euler) const
|
|||||||
return zr * yr * xr;
|
return zr * yr * xr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osg::Vec3f CSVRender::InstanceMode::getSelectionCenter(const std::vector<osg::ref_ptr<TagBase> >& selection) const
|
||||||
|
{
|
||||||
|
osg::Vec3f center = osg::Vec3f(0, 0, 0);
|
||||||
|
int objectCount = 0;
|
||||||
|
|
||||||
|
for (std::vector<osg::ref_ptr<TagBase> >::const_iterator iter (selection.begin()); iter!=selection.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (iter->get()))
|
||||||
|
{
|
||||||
|
const ESM::Position& position = objectTag->mObject->getPosition();
|
||||||
|
center += osg::Vec3f(position.pos[0], position.pos[1], position.pos[2]);
|
||||||
|
|
||||||
|
++objectCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
center /= objectCount;
|
||||||
|
|
||||||
|
return center;
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Vec3f CSVRender::InstanceMode::getScreenCoords(const osg::Vec3f& pos)
|
||||||
|
{
|
||||||
|
osg::Matrix viewMatrix = getWorldspaceWidget().getCamera()->getViewMatrix();
|
||||||
|
osg::Matrix projMatrix = getWorldspaceWidget().getCamera()->getProjectionMatrix();
|
||||||
|
osg::Matrix windowMatrix = getWorldspaceWidget().getCamera()->getViewport()->computeWindowMatrix();
|
||||||
|
osg::Matrix combined = viewMatrix * projMatrix * windowMatrix;
|
||||||
|
|
||||||
|
return pos * combined;
|
||||||
|
}
|
||||||
|
|
||||||
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent)
|
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent)
|
||||||
: EditMode (worldspaceWidget, QIcon (":placeholder"), Mask_Reference, "Instance editing",
|
: EditMode (worldspaceWidget, QIcon (":placeholder"), Mask_Reference, "Instance editing",
|
||||||
parent), mSubMode (0), mSubModeId ("move"), mSelectionMode (0), mDragMode (DragMode_None),
|
parent), mSubMode (0), mSubModeId ("move"), mSelectionMode (0), mDragMode (DragMode_None),
|
||||||
@ -223,14 +253,16 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos)
|
|||||||
objectTag->mObject->setEdited (Object::Override_Scale);
|
objectTag->mObject->setEdited (Object::Override_Scale);
|
||||||
mDragMode = DragMode_Scale;
|
mDragMode = DragMode_Scale;
|
||||||
|
|
||||||
// Calculate scale
|
// Calculate scale factor
|
||||||
int widgetWidth = getWorldspaceWidget().width();
|
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getEdited (Mask_Reference);
|
||||||
|
osg::Vec3f center = getScreenCoords(getSelectionCenter(selection));
|
||||||
|
|
||||||
int widgetHeight = getWorldspaceWidget().height();
|
int widgetHeight = getWorldspaceWidget().height();
|
||||||
|
|
||||||
int x = pos.x() - widgetWidth / 2;
|
float dx = pos.x() - center.x();
|
||||||
int y = pos.y() - widgetHeight / 2;
|
float dy = (widgetHeight - pos.y()) - center.y();
|
||||||
|
|
||||||
mUnitScaleDist = std::sqrt(x * x + y * y);
|
mUnitScaleDist = std::sqrt(dx * dx + dy * dy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -258,6 +290,8 @@ void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, dou
|
|||||||
osg::Vec3f offset;
|
osg::Vec3f offset;
|
||||||
osg::Quat rotation;
|
osg::Quat rotation;
|
||||||
|
|
||||||
|
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getEdited (Mask_Reference);
|
||||||
|
|
||||||
if (mDragMode == DragMode_Move)
|
if (mDragMode == DragMode_Move)
|
||||||
{
|
{
|
||||||
osg::Vec3f eye, centre, up;
|
osg::Vec3f eye, centre, up;
|
||||||
@ -330,20 +364,22 @@ void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, dou
|
|||||||
}
|
}
|
||||||
else if (mDragMode == DragMode_Scale)
|
else if (mDragMode == DragMode_Scale)
|
||||||
{
|
{
|
||||||
int widgetWidth = getWorldspaceWidget().width();
|
osg::Vec3f center = getScreenCoords(getSelectionCenter(selection));
|
||||||
|
|
||||||
|
// Calculate scaling distance/rate
|
||||||
int widgetHeight = getWorldspaceWidget().height();
|
int widgetHeight = getWorldspaceWidget().height();
|
||||||
|
|
||||||
int x = pos.x() - widgetWidth / 2;
|
float dx = pos.x() - center.x();
|
||||||
int y = pos.y() - widgetHeight / 2;
|
float dy = (widgetHeight - pos.y()) - center.y();
|
||||||
|
|
||||||
float dist = std::sqrt(x * x + y * y);
|
float dist = std::sqrt(dx * dx + dy * dy);
|
||||||
float scale = dist / mUnitScaleDist;
|
float scale = dist / mUnitScaleDist;
|
||||||
|
|
||||||
// Only uniform scaling is currently supported
|
// Only uniform scaling is currently supported
|
||||||
offset = osg::Vec3f(scale, scale, scale);
|
offset = osg::Vec3f(scale, scale, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getEdited (Mask_Reference);
|
// Apply
|
||||||
for (std::vector<osg::ref_ptr<TagBase> >::iterator iter (selection.begin()); iter!=selection.end(); ++iter)
|
for (std::vector<osg::ref_ptr<TagBase> >::iterator iter (selection.begin()); iter!=selection.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (iter->get()))
|
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (iter->get()))
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef CSV_RENDER_INSTANCEMODE_H
|
#ifndef CSV_RENDER_INSTANCEMODE_H
|
||||||
#define CSV_RENDER_INSTANCEMODE_H
|
#define CSV_RENDER_INSTANCEMODE_H
|
||||||
|
|
||||||
|
#include <osg/ref_ptr>
|
||||||
#include <osg/Quat>
|
#include <osg/Quat>
|
||||||
#include <osg/Vec3f>
|
#include <osg/Vec3f>
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ namespace CSVWidget
|
|||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
{
|
{
|
||||||
|
class TagBase;
|
||||||
class InstanceSelectionMode;
|
class InstanceSelectionMode;
|
||||||
|
|
||||||
class InstanceMode : public EditMode
|
class InstanceMode : public EditMode
|
||||||
@ -40,6 +42,9 @@ namespace CSVRender
|
|||||||
osg::Vec3f quatToEuler(const osg::Quat& quat) const;
|
osg::Vec3f quatToEuler(const osg::Quat& quat) const;
|
||||||
osg::Quat eulerToQuat(const osg::Vec3f& euler) const;
|
osg::Quat eulerToQuat(const osg::Vec3f& euler) const;
|
||||||
|
|
||||||
|
osg::Vec3f getSelectionCenter(const std::vector<osg::ref_ptr<TagBase> >& selection) const;
|
||||||
|
osg::Vec3f getScreenCoords(const osg::Vec3f& pos);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0);
|
InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user