MyGUI_RotatingSkin.cpp
Go to the documentation of this file.
/*
* This source file is part of MyGUI. For the latest info, see http://mygui.info/
* Distributed under the MIT License
* (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_RotatingSkin.h"
#include "MyGUI_RenderItem.h"
#include "MyGUI_CommonStateInfo.h"
#include "MyGUI_RenderManager.h"
#include "MyGUI_GeometryUtility.h"
namespace MyGUI
{
RotatingSkin::RotatingSkin()
{
mVertexFormat = RenderManager::getInstance().getVertexFormat();
}
void RotatingSkin::setAngle(float _angle)
{
mAngle = _angle;
mGeometryOutdated = true;
if (nullptr != mNode)
mNode->outOfDate(mRenderItem);
}
void RotatingSkin::setCenter(const IntPoint& _center)
{
mCenterPos = _center;
mGeometryOutdated = true;
if (nullptr != mNode)
mNode->outOfDate(mRenderItem);
}
IntPoint RotatingSkin::getCenter(bool _local) const
{
return mCenterPos + (_local ? IntPoint() : mCroppedParent->getAbsolutePosition());
}
void RotatingSkin::setVisible(bool _visible)
{
if (mVisible == _visible)
return;
mVisible = _visible;
mGeometryOutdated = true;
if (nullptr != mNode)
mNode->outOfDate(mRenderItem);
}
void RotatingSkin::setAlpha(float _alpha)
{
uint32 alpha = ((uint8)(_alpha * 255) << 24);
mCurrentColour = (mCurrentColour & 0x00FFFFFF) | (alpha & 0xFF000000);
if (nullptr != mNode)
mNode->outOfDate(mRenderItem);
}
void RotatingSkin::_correctView()
{
mGeometryOutdated = true;
if (nullptr != mNode)
mNode->outOfDate(mRenderItem);
}
void RotatingSkin::_setAlign(const IntSize& _oldsize)
{
// первоначальное выравнивание
if (mAlign.isHStretch())
{
// растягиваем
mCoord.width = mCoord.width + (mCroppedParent->getWidth() - _oldsize.width);
mIsMargin = true; // при изменении размеров все пересчитывать
}
else if (mAlign.isRight())
{
// двигаем по правому краю
mCoord.left = mCoord.left + (mCroppedParent->getWidth() - _oldsize.width);
}
else if (mAlign.isHCenter())
{
// выравнивание по горизонтали без растяжения
mCoord.left = (mCroppedParent->getWidth() - mCoord.width) / 2;
}
if (mAlign.isVStretch())
{
// растягиваем
mCoord.height = mCoord.height + (mCroppedParent->getHeight() - _oldsize.height);
mIsMargin = true; // при изменении размеров все пересчитывать
}
else if (mAlign.isBottom())
{
// двигаем по нижнему краю
mCoord.top = mCoord.top + (mCroppedParent->getHeight() - _oldsize.height);
}
else if (mAlign.isVCenter())
{
// выравнивание по вертикали без растяжения
mCoord.top = (mCroppedParent->getHeight() - mCoord.height) / 2;
}
mCurrentCoord = mCoord;
_updateView();
}
void RotatingSkin::_updateView()
{
mEmptyView = ((0 >= _getViewWidth()) || (0 >= _getViewHeight()));
mGeometryOutdated = true;
if (nullptr != mNode)
mNode->outOfDate(mRenderItem);
}
void RotatingSkin::createDrawItem(ITexture* _texture, ILayerNode* _node)
{
MYGUI_ASSERT(!mRenderItem, "mRenderItem must be nullptr");
mNode = _node;
mRenderItem = mNode->addToRenderItem(_texture, true, false);
mRenderItem->addDrawItem(this, (GEOMETRY_VERTICIES_TOTAL_COUNT - 2) * 3);
}
void RotatingSkin::destroyDrawItem()
{
MYGUI_ASSERT(mRenderItem, "mRenderItem must be not nullptr");
mNode = nullptr;
mRenderItem->removeDrawItem(this);
mRenderItem = nullptr;
}
void RotatingSkin::doRender()
{
if (!mVisible || mEmptyView)
return;
Vertex* verticies = mRenderItem->getCurrentVertexBuffer();
float vertex_z = mNode->getNodeDepth();
if (mGeometryOutdated)
{
_rebuildGeometry();
mGeometryOutdated = false;
}
for (int i = 1; i < GEOMETRY_VERTICIES_TOTAL_COUNT - 1; ++i)
{
verticies[3 * i - 3].set(
mResultVerticiesPos[0].left,
mResultVerticiesPos[0].top,
vertex_z,
mResultVerticiesUV[0].left,
mResultVerticiesUV[0].top,
mCurrentColour);
verticies[3 * i - 2].set(
mResultVerticiesPos[i].left,
mResultVerticiesPos[i].top,
vertex_z,
mResultVerticiesUV[i].left,
mResultVerticiesUV[i].top,
mCurrentColour);
verticies[3 * i - 1].set(
mResultVerticiesPos[i + 1].left,
mResultVerticiesPos[i + 1].top,
vertex_z,
mResultVerticiesUV[i + 1].left,
mResultVerticiesUV[i + 1].top,
mCurrentColour);
}
mRenderItem->setLastVertexCount((GEOMETRY_VERTICIES_TOTAL_COUNT - 2) * 3);
}
void RotatingSkin::_setColour(const Colour& _value)
{
uint32 colour = texture_utility::toNativeColour(_value, mVertexFormat);
mCurrentColour = (colour & 0x00FFFFFF) | (mCurrentColour & 0xFF000000);
if (nullptr != mNode)
mNode->outOfDate(mRenderItem);
}
void RotatingSkin::setStateData(IStateInfo* _data)
{
RotatingSkinStateInfo* data = _data->castType<RotatingSkinStateInfo>();
setAngle(data->getAngle());
setCenter(data->getCenter());
_setUVSet(data->getRect());
}
void RotatingSkin::_setUVSet(const FloatRect& _rect)
{
mCurrentTexture = _rect;
mGeometryOutdated = true;
if (nullptr != mNode)
mNode->outOfDate(mRenderItem);
}
inline float len(float x, float y)
{
return std::sqrt(x * x + y * y);
}
void RotatingSkin::_rebuildGeometry()
{
/*
0 1
3 2
*/
#ifdef M_PI
#undef M_PI
#endif
const float M_PI = 3.141593f;
float width_base = (float)mCurrentCoord.width;
float height_base = (float)mCurrentCoord.height;
// calculate original unrotated angles of uncropped rectangle verticies: between axis and line from center of rotation to vertex)
float baseAngles[RECT_VERTICIES_COUNT];
baseAngles[0] = std::atan2((float)mCenterPos.left, (float)mCenterPos.top) + M_PI / 2;
baseAngles[1] = std::atan2(-width_base + (float)mCenterPos.left, (float)mCenterPos.top) + M_PI / 2;
baseAngles[2] =
std::atan2(-width_base + (float)mCenterPos.left, -height_base + (float)mCenterPos.top) + M_PI / 2;
baseAngles[3] = std::atan2((float)mCenterPos.left, -height_base + (float)mCenterPos.top) + M_PI / 2;
// calculate original unrotated distances of uncropped rectangle verticies: between center of rotation and vertex)
float baseDistances[RECT_VERTICIES_COUNT];
baseDistances[0] = len((float)mCenterPos.left, (float)mCenterPos.top);
baseDistances[1] = len(-width_base + (float)mCenterPos.left, (float)mCenterPos.top);
baseDistances[2] = len(-width_base + (float)mCenterPos.left, -height_base + (float)mCenterPos.top);
baseDistances[3] = len((float)mCenterPos.left, -height_base + (float)mCenterPos.top);
// calculate rotated positions of uncropped rectangle verticies (relative to parent)
FloatPoint baseVerticiesPos[RECT_VERTICIES_COUNT];
int offsetX = /*mCurrentCoord.left +*/ mCenterPos.left;
int offsetY = /*mCurrentCoord.top +*/ mCenterPos.top;
for (int i = 0; i < RECT_VERTICIES_COUNT; ++i)
{
baseVerticiesPos[i].left = offsetX + std::cos(-mAngle + baseAngles[i]) * baseDistances[i];
baseVerticiesPos[i].top = offsetY - std::sin(-mAngle + baseAngles[i]) * baseDistances[i];
}
// base texture coordinates
FloatPoint baseVerticiesUV[RECT_VERTICIES_COUNT] = {
FloatPoint(mCurrentTexture.left, mCurrentTexture.top),
FloatPoint(mCurrentTexture.right, mCurrentTexture.top),
FloatPoint(mCurrentTexture.right, mCurrentTexture.bottom),
FloatPoint(mCurrentTexture.left, mCurrentTexture.bottom)};
// now we have rotated uncropped rectangle verticies coordinates
// --------- here the cropping starts ---------
// now we are going to calculate verticies of resulting figure
// no parent - no cropping
size_t size = RECT_VERTICIES_COUNT;
if (nullptr == mCroppedParent->getCroppedParent())
{
for (int i = 0; i < RECT_VERTICIES_COUNT; ++i)
{
mResultVerticiesPos[i] = baseVerticiesPos[i];
mResultVerticiesUV[i] = baseVerticiesUV[i];
}
}
else
{
ICroppedRectangle* parent = mCroppedParent->getCroppedParent();
VectorFloatPoint resultVerticiesPos = geometry_utility::cropPolygon(
baseVerticiesPos,
RECT_VERTICIES_COUNT,
IntCoord(
parent->_getMarginLeft() - mCroppedParent->getLeft(),
parent->_getMarginTop() - mCroppedParent->getTop(),
parent->_getViewWidth(),
parent->_getViewHeight()));
for (size_t i = 0; i < resultVerticiesPos.size(); ++i)
{
mResultVerticiesPos[i] = resultVerticiesPos[i];
}
size = resultVerticiesPos.size();
// calculate texture coordinates
FloatPoint v0 = baseVerticiesUV[3] - baseVerticiesUV[0];
FloatPoint v1 = baseVerticiesUV[1] - baseVerticiesUV[0];
for (size_t i = 0; i < GEOMETRY_VERTICIES_TOTAL_COUNT; ++i)
{
if (i < size)
{
FloatPoint point = geometry_utility::getPositionInsideRect(
mResultVerticiesPos[i],
baseVerticiesPos[0],
baseVerticiesPos[1],
baseVerticiesPos[3]);
mResultVerticiesUV[i] =
geometry_utility::getUVFromPositionInsideRect(point, v0, v1, baseVerticiesUV[0]);
}
else
{
// all unused verticies is equal to last used
mResultVerticiesUV[i] = mResultVerticiesUV[size == 0 ? 0 : (size - 1)];
}
}
}
// now calculate widget base offset and then resulting position in screen coordinates
const RenderTargetInfo& info = mRenderItem->getRenderTarget()->getInfo();
float vertex_left_base = ((info.pixScaleX * (float)(mCroppedParent->getAbsoluteLeft()) + info.hOffset) * 2) - 1;
float vertex_top_base =
-(((info.pixScaleY * (float)(mCroppedParent->getAbsoluteTop()) + info.vOffset) * 2) - 1);
for (size_t i = 0; i < GEOMETRY_VERTICIES_TOTAL_COUNT; ++i)
{
if (i < size)
{
mResultVerticiesPos[i].left = vertex_left_base + mResultVerticiesPos[i].left * info.pixScaleX * 2;
mResultVerticiesPos[i].top = vertex_top_base + mResultVerticiesPos[i].top * info.pixScaleY * -2;
}
else
{
// all unused verticies is equal to last used
mResultVerticiesPos[i] = mResultVerticiesPos[size == 0 ? 0 : (size - 1)];
}
}
}
float RotatingSkin::getAngle() const
{
return mAngle;
}
} // namespace MyGUI
MyGUI_CommonStateInfo.h
MYGUI_ASSERT
#define MYGUI_ASSERT(exp, dest)
Definition MyGUI_Diagnostic.h:31
MyGUI_GeometryUtility.h
MyGUI_Precompiled.h
MyGUI_RenderItem.h
MyGUI_RenderManager.h
MyGUI_RotatingSkin.h
MyGUI::ICroppedRectangle
Definition MyGUI_ICroppedRectangle.h:17
MyGUI::ICroppedRectangle::mIsMargin
bool mIsMargin
Definition MyGUI_ICroppedRectangle.h:248
MyGUI::ICroppedRectangle::mCoord
IntCoord mCoord
Definition MyGUI_ICroppedRectangle.h:245
MyGUI::ICroppedRectangle::mCroppedParent
ICroppedRectangle * mCroppedParent
Definition MyGUI_ICroppedRectangle.h:249
MyGUI::ICroppedRectangle::_getMarginLeft
int _getMarginLeft() const
Definition MyGUI_ICroppedRectangle.h:166
MyGUI::ICroppedRectangle::_getMarginTop
int _getMarginTop() const
Definition MyGUI_ICroppedRectangle.h:174
MyGUI::ICroppedRectangle::_getViewWidth
int _getViewWidth() const
Definition MyGUI_ICroppedRectangle.h:148
MyGUI::ICroppedRectangle::_getViewHeight
int _getViewHeight() const
Definition MyGUI_ICroppedRectangle.h:152
MyGUI::ILayerNode
Definition MyGUI_ILayerNode.h:29
MyGUI::ILayerNode::addToRenderItem
virtual RenderItem * addToRenderItem(ITexture *_texture, bool _firstQueue, bool _separate)=0
MyGUI::IObject::castType
Type * castType(bool _throw=true)
Definition MyGUI_IObject.h:18
MyGUI::IStateInfo
Definition MyGUI_IStateInfo.h:17
MyGUI::ISubWidget::mAlign
Align mAlign
Definition MyGUI_ISubWidget.h:67
MyGUI::ISubWidget::mVisible
bool mVisible
Definition MyGUI_ISubWidget.h:68
MyGUI::ITexture
Definition MyGUI_ITexture.h:28
MyGUI::RenderItem::addDrawItem
void addDrawItem(ISubWidget *_item, size_t _count)
Definition MyGUI_RenderItem.cpp:112
MyGUI::RenderManager::getVertexFormat
virtual VertexColourType getVertexFormat() const =0
MyGUI::RenderManager::getInstance
static RenderManager & getInstance()
MyGUI::RotatingSkin::setAlpha
void setAlpha(float _alpha) override
Definition MyGUI_RotatingSkin.cpp:57
MyGUI::RotatingSkin::doRender
void doRender() override
Definition MyGUI_RotatingSkin.cpp:143
MyGUI::RotatingSkin::setAngle
void setAngle(float _angle)
Definition MyGUI_RotatingSkin.cpp:22
MyGUI::RotatingSkin::getAngle
float getAngle() const
Definition MyGUI_RotatingSkin.cpp:350
MyGUI::RotatingSkin::_setColour
void _setColour(const Colour &_value) override
Definition MyGUI_RotatingSkin.cpp:186
MyGUI::RotatingSkin::_setUVSet
void _setUVSet(const FloatRect &_rect) override
Definition MyGUI_RotatingSkin.cpp:205
MyGUI::RotatingSkin::getCenter
IntPoint getCenter(bool _local=true) const
Definition MyGUI_RotatingSkin.cpp:40
MyGUI::RotatingSkin::RotatingSkin
RotatingSkin()
Definition MyGUI_RotatingSkin.cpp:17
MyGUI::RotatingSkin::setStateData
void setStateData(IStateInfo *_data) override
Definition MyGUI_RotatingSkin.cpp:195
MyGUI::RotatingSkin::_rebuildGeometry
void _rebuildGeometry()
Definition MyGUI_RotatingSkin.cpp:220
MyGUI::RotatingSkin::_correctView
void _correctView() override
Definition MyGUI_RotatingSkin.cpp:66
MyGUI::RotatingSkin::destroyDrawItem
void destroyDrawItem() override
Definition MyGUI_RotatingSkin.cpp:134
MyGUI::RotatingSkin::setVisible
void setVisible(bool _visible) override
Definition MyGUI_RotatingSkin.cpp:45
MyGUI::RotatingSkin::_updateView
void _updateView() override
Definition MyGUI_RotatingSkin.cpp:115
MyGUI::RotatingSkin::createDrawItem
void createDrawItem(ITexture *_texture, ILayerNode *_node) override
Definition MyGUI_RotatingSkin.cpp:125
MyGUI::RotatingSkin::setCenter
void setCenter(const IntPoint &_center)
Definition MyGUI_RotatingSkin.cpp:31
MyGUI::RotatingSkin::_setAlign
void _setAlign(const IntSize &_oldsize) override
Definition MyGUI_RotatingSkin.cpp:74
MyGUI::RotatingSkinStateInfo
Definition MyGUI_CommonStateInfo.h:111
MyGUI::RotatingSkinStateInfo::getCenter
const IntPoint & getCenter() const
Definition MyGUI_CommonStateInfo.h:120
MyGUI::RotatingSkinStateInfo::getRect
const FloatRect & getRect() const
Definition MyGUI_CommonStateInfo.h:125
MyGUI::RotatingSkinStateInfo::getAngle
float getAngle() const
Definition MyGUI_CommonStateInfo.h:115
MyGUI::geometry_utility::getUVFromPositionInsideRect
FloatPoint getUVFromPositionInsideRect(const FloatPoint &_point, const FloatPoint &_v0, const FloatPoint &_v1, const FloatPoint &_baseUV)
Definition MyGUI_GeometryUtility.cpp:104
MyGUI::geometry_utility::getPositionInsideRect
FloatPoint getPositionInsideRect(const FloatPoint &_point, const FloatPoint &_corner0, const FloatPoint &_corner1, const FloatPoint &_corner2)
Definition MyGUI_GeometryUtility.cpp:86
MyGUI::geometry_utility::cropPolygon
VectorFloatPoint cropPolygon(FloatPoint *_baseVerticiesPos, size_t _size, const IntCoord &_cropRectangle)
Definition MyGUI_GeometryUtility.cpp:13
MyGUI::texture_utility::toNativeColour
uint32 toNativeColour(const Colour &_colour, VertexColourType _format)
Convert Colour to 32-bit representation.
Definition MyGUI_TextureUtility.cpp:63
MyGUI
Definition MyGUI_ActionController.h:15
MyGUI::uint32
uint32_t uint32
Definition MyGUI_Types.h:48
MyGUI::uint8
uint8_t uint8
Definition MyGUI_Types.h:46
MyGUI::IntPoint
types::TPoint< int > IntPoint
Definition MyGUI_Types.h:27
MyGUI::FloatRect
types::TRect< float > FloatRect
Definition MyGUI_Types.h:34
MyGUI::FloatPoint
types::TPoint< float > FloatPoint
Definition MyGUI_Types.h:28
MyGUI::VectorFloatPoint
std::vector< FloatPoint > VectorFloatPoint
Definition MyGUI_GeometryUtility.h:16
MyGUI::M_PI
const float M_PI
Definition MyGUI_ControllerEdgeHide.cpp:20
MyGUI::IntCoord
types::TCoord< int > IntCoord
Definition MyGUI_Types.h:36
MyGUI::IntSize
types::TSize< int > IntSize
Definition MyGUI_Types.h:30
MyGUI::len
float len(float x, float y)
Definition MyGUI_PolygonalSkin.cpp:22
MyGUI::Colour
Definition MyGUI_Colour.h:17
MyGUI::RenderTargetInfo
Definition MyGUI_RenderTargetInfo.h:16
MyGUI::RenderTargetInfo::vOffset
float vOffset
Definition MyGUI_RenderTargetInfo.h:29
MyGUI::RenderTargetInfo::hOffset
float hOffset
Definition MyGUI_RenderTargetInfo.h:28
MyGUI::RenderTargetInfo::pixScaleX
float pixScaleX
Definition MyGUI_RenderTargetInfo.h:26
MyGUI::RenderTargetInfo::pixScaleY
float pixScaleY
Definition MyGUI_RenderTargetInfo.h:27
MyGUI::Vertex
Definition MyGUI_VertexData.h:17
MyGUI::Vertex::set
void set(float _x, float _y, float _z, float _u, float _v, uint32 _colour)
Definition MyGUI_VertexData.h:18
MyGUI::types::TPoint::left
T left
Definition MyGUI_TPoint.h:19
MyGUI::types::TPoint::top
T top
Definition MyGUI_TPoint.h:20
MyGUI::types::TSize::width
T width
Definition MyGUI_TSize.h:19
MyGUI::types::TSize::height
T height
Definition MyGUI_TSize.h:20