MyGUI: MyGUI_RotatingSkin.cpp Source File

MyGUI 3.4.3

MyGUI_RotatingSkin.cpp
Go to the documentation of this file.
1/*
2 * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3 * Distributed under the MIT License
4 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5 */
6
7#include "MyGUI_Precompiled.h"
8#include "MyGUI_RotatingSkin.h"
9#include "MyGUI_RenderItem.h"
10#include "MyGUI_CommonStateInfo.h"
11#include "MyGUI_RenderManager.h"
12#include "MyGUI_GeometryUtility.h"
13
14namespace MyGUI
15{
16
17 RotatingSkin::RotatingSkin()
18 {
19 mVertexFormat = RenderManager::getInstance().getVertexFormat();
20 }
21
22 void RotatingSkin::setAngle(float _angle)
23 {
24 mAngle = _angle;
25 mGeometryOutdated = true;
26
27 if (nullptr != mNode)
28 mNode->outOfDate(mRenderItem);
29 }
30
31 void RotatingSkin::setCenter(const IntPoint& _center)
32 {
33 mCenterPos = _center;
34 mGeometryOutdated = true;
35
36 if (nullptr != mNode)
37 mNode->outOfDate(mRenderItem);
38 }
39
40 IntPoint RotatingSkin::getCenter(bool _local) const
41 {
42 return mCenterPos + (_local ? IntPoint() : mCroppedParent->getAbsolutePosition());
43 }
44
45 void RotatingSkin::setVisible(bool _visible)
46 {
47 if (mVisible == _visible)
48 return;
49
50 mVisible = _visible;
51 mGeometryOutdated = true;
52
53 if (nullptr != mNode)
54 mNode->outOfDate(mRenderItem);
55 }
56
57 void RotatingSkin::setAlpha(float _alpha)
58 {
59 uint32 alpha = ((uint8)(_alpha * 255) << 24);
60 mCurrentColour = (mCurrentColour & 0x00FFFFFF) | (alpha & 0xFF000000);
61
62 if (nullptr != mNode)
63 mNode->outOfDate(mRenderItem);
64 }
65
66 void RotatingSkin::_correctView()
67 {
68 mGeometryOutdated = true;
69
70 if (nullptr != mNode)
71 mNode->outOfDate(mRenderItem);
72 }
73
74 void RotatingSkin::_setAlign(const IntSize& _oldsize)
75 {
76 // первоначальное выравнивание
77 if (mAlign.isHStretch())
78 {
79 // растягиваем
80 mCoord.width = mCoord.width + (mCroppedParent->getWidth() - _oldsize.width);
81 mIsMargin = true; // при изменении размеров все пересчитывать
82 }
83 else if (mAlign.isRight())
84 {
85 // двигаем по правому краю
86 mCoord.left = mCoord.left + (mCroppedParent->getWidth() - _oldsize.width);
87 }
88 else if (mAlign.isHCenter())
89 {
90 // выравнивание по горизонтали без растяжения
91 mCoord.left = (mCroppedParent->getWidth() - mCoord.width) / 2;
92 }
93
94 if (mAlign.isVStretch())
95 {
96 // растягиваем
97 mCoord.height = mCoord.height + (mCroppedParent->getHeight() - _oldsize.height);
98 mIsMargin = true; // при изменении размеров все пересчитывать
99 }
100 else if (mAlign.isBottom())
101 {
102 // двигаем по нижнему краю
103 mCoord.top = mCoord.top + (mCroppedParent->getHeight() - _oldsize.height);
104 }
105 else if (mAlign.isVCenter())
106 {
107 // выравнивание по вертикали без растяжения
108 mCoord.top = (mCroppedParent->getHeight() - mCoord.height) / 2;
109 }
110
111 mCurrentCoord = mCoord;
112 _updateView();
113 }
114
115 void RotatingSkin::_updateView()
116 {
117 mEmptyView = ((0 >= _getViewWidth()) || (0 >= _getViewHeight()));
118
119 mGeometryOutdated = true;
120
121 if (nullptr != mNode)
122 mNode->outOfDate(mRenderItem);
123 }
124
125 void RotatingSkin::createDrawItem(ITexture* _texture, ILayerNode* _node)
126 {
127 MYGUI_ASSERT(!mRenderItem, "mRenderItem must be nullptr");
128
129 mNode = _node;
130 mRenderItem = mNode->addToRenderItem(_texture, true, false);
131 mRenderItem->addDrawItem(this, (GEOMETRY_VERTICIES_TOTAL_COUNT - 2) * 3);
132 }
133
134 void RotatingSkin::destroyDrawItem()
135 {
136 MYGUI_ASSERT(mRenderItem, "mRenderItem must be not nullptr");
137
138 mNode = nullptr;
139 mRenderItem->removeDrawItem(this);
140 mRenderItem = nullptr;
141 }
142
143 void RotatingSkin::doRender()
144 {
145 if (!mVisible || mEmptyView)
146 return;
147
148 Vertex* verticies = mRenderItem->getCurrentVertexBuffer();
149
150 float vertex_z = mNode->getNodeDepth();
151
152 if (mGeometryOutdated)
153 {
154 _rebuildGeometry();
155 mGeometryOutdated = false;
156 }
157
158 for (int i = 1; i < GEOMETRY_VERTICIES_TOTAL_COUNT - 1; ++i)
159 {
160 verticies[3 * i - 3].set(
161 mResultVerticiesPos[0].left,
162 mResultVerticiesPos[0].top,
163 vertex_z,
164 mResultVerticiesUV[0].left,
165 mResultVerticiesUV[0].top,
166 mCurrentColour);
167 verticies[3 * i - 2].set(
168 mResultVerticiesPos[i].left,
169 mResultVerticiesPos[i].top,
170 vertex_z,
171 mResultVerticiesUV[i].left,
172 mResultVerticiesUV[i].top,
173 mCurrentColour);
174 verticies[3 * i - 1].set(
175 mResultVerticiesPos[i + 1].left,
176 mResultVerticiesPos[i + 1].top,
177 vertex_z,
178 mResultVerticiesUV[i + 1].left,
179 mResultVerticiesUV[i + 1].top,
180 mCurrentColour);
181 }
182
183 mRenderItem->setLastVertexCount((GEOMETRY_VERTICIES_TOTAL_COUNT - 2) * 3);
184 }
185
186 void RotatingSkin::_setColour(const Colour& _value)
187 {
188 uint32 colour = texture_utility::toNativeColour(_value, mVertexFormat);
189 mCurrentColour = (colour & 0x00FFFFFF) | (mCurrentColour & 0xFF000000);
190
191 if (nullptr != mNode)
192 mNode->outOfDate(mRenderItem);
193 }
194
195 void RotatingSkin::setStateData(IStateInfo* _data)
196 {
197 RotatingSkinStateInfo* data = _data->castType<RotatingSkinStateInfo>();
198
199 setAngle(data->getAngle());
200 setCenter(data->getCenter());
201
202 _setUVSet(data->getRect());
203 }
204
205 void RotatingSkin::_setUVSet(const FloatRect& _rect)
206 {
207 mCurrentTexture = _rect;
208
209 mGeometryOutdated = true;
210
211 if (nullptr != mNode)
212 mNode->outOfDate(mRenderItem);
213 }
214
215 inline float len(float x, float y)
216 {
217 return std::sqrt(x * x + y * y);
218 }
219
220 void RotatingSkin::_rebuildGeometry()
221 {
222 /*
223 0 1
224 3 2
225 */
226#ifdef M_PI
227 #undef M_PI
228#endif
229 const float M_PI = 3.141593f;
230
231 float width_base = (float)mCurrentCoord.width;
232 float height_base = (float)mCurrentCoord.height;
233
234 // calculate original unrotated angles of uncropped rectangle verticies: between axis and line from center of rotation to vertex)
235 float baseAngles[RECT_VERTICIES_COUNT];
236 baseAngles[0] = std::atan2((float)mCenterPos.left, (float)mCenterPos.top) + M_PI / 2;
237 baseAngles[1] = std::atan2(-width_base + (float)mCenterPos.left, (float)mCenterPos.top) + M_PI / 2;
238 baseAngles[2] =
239 std::atan2(-width_base + (float)mCenterPos.left, -height_base + (float)mCenterPos.top) + M_PI / 2;
240 baseAngles[3] = std::atan2((float)mCenterPos.left, -height_base + (float)mCenterPos.top) + M_PI / 2;
241
242 // calculate original unrotated distances of uncropped rectangle verticies: between center of rotation and vertex)
243 float baseDistances[RECT_VERTICIES_COUNT];
244 baseDistances[0] = len((float)mCenterPos.left, (float)mCenterPos.top);
245 baseDistances[1] = len(-width_base + (float)mCenterPos.left, (float)mCenterPos.top);
246 baseDistances[2] = len(-width_base + (float)mCenterPos.left, -height_base + (float)mCenterPos.top);
247 baseDistances[3] = len((float)mCenterPos.left, -height_base + (float)mCenterPos.top);
248
249
250 // calculate rotated positions of uncropped rectangle verticies (relative to parent)
251 FloatPoint baseVerticiesPos[RECT_VERTICIES_COUNT];
252
253 int offsetX = /*mCurrentCoord.left +*/ mCenterPos.left;
254 int offsetY = /*mCurrentCoord.top +*/ mCenterPos.top;
255
256 for (int i = 0; i < RECT_VERTICIES_COUNT; ++i)
257 {
258 baseVerticiesPos[i].left = offsetX + std::cos(-mAngle + baseAngles[i]) * baseDistances[i];
259 baseVerticiesPos[i].top = offsetY - std::sin(-mAngle + baseAngles[i]) * baseDistances[i];
260 }
261
262 // base texture coordinates
263 FloatPoint baseVerticiesUV[RECT_VERTICIES_COUNT] = {
264 FloatPoint(mCurrentTexture.left, mCurrentTexture.top),
265 FloatPoint(mCurrentTexture.right, mCurrentTexture.top),
266 FloatPoint(mCurrentTexture.right, mCurrentTexture.bottom),
267 FloatPoint(mCurrentTexture.left, mCurrentTexture.bottom)};
268
269 // now we have rotated uncropped rectangle verticies coordinates
270
271 // --------- here the cropping starts ---------
272
273 // now we are going to calculate verticies of resulting figure
274
275 // no parent - no cropping
276 size_t size = RECT_VERTICIES_COUNT;
277 if (nullptr == mCroppedParent->getCroppedParent())
278 {
279 for (int i = 0; i < RECT_VERTICIES_COUNT; ++i)
280 {
281 mResultVerticiesPos[i] = baseVerticiesPos[i];
282 mResultVerticiesUV[i] = baseVerticiesUV[i];
283 }
284 }
285 else
286 {
287 ICroppedRectangle* parent = mCroppedParent->getCroppedParent();
288
289 VectorFloatPoint resultVerticiesPos = geometry_utility::cropPolygon(
290 baseVerticiesPos,
291 RECT_VERTICIES_COUNT,
292 IntCoord(
293 parent->_getMarginLeft() - mCroppedParent->getLeft(),
294 parent->_getMarginTop() - mCroppedParent->getTop(),
295 parent->_getViewWidth(),
296 parent->_getViewHeight()));
297
298 for (size_t i = 0; i < resultVerticiesPos.size(); ++i)
299 {
300 mResultVerticiesPos[i] = resultVerticiesPos[i];
301 }
302
303 size = resultVerticiesPos.size();
304
305 // calculate texture coordinates
306 FloatPoint v0 = baseVerticiesUV[3] - baseVerticiesUV[0];
307 FloatPoint v1 = baseVerticiesUV[1] - baseVerticiesUV[0];
308 for (size_t i = 0; i < GEOMETRY_VERTICIES_TOTAL_COUNT; ++i)
309 {
310 if (i < size)
311 {
312 FloatPoint point = geometry_utility::getPositionInsideRect(
313 mResultVerticiesPos[i],
314 baseVerticiesPos[0],
315 baseVerticiesPos[1],
316 baseVerticiesPos[3]);
317 mResultVerticiesUV[i] =
318 geometry_utility::getUVFromPositionInsideRect(point, v0, v1, baseVerticiesUV[0]);
319 }
320 else
321 {
322 // all unused verticies is equal to last used
323 mResultVerticiesUV[i] = mResultVerticiesUV[size == 0 ? 0 : (size - 1)];
324 }
325 }
326 }
327
328
329 // now calculate widget base offset and then resulting position in screen coordinates
330 const RenderTargetInfo& info = mRenderItem->getRenderTarget()->getInfo();
331 float vertex_left_base = ((info.pixScaleX * (float)(mCroppedParent->getAbsoluteLeft()) + info.hOffset) * 2) - 1;
332 float vertex_top_base =
333 -(((info.pixScaleY * (float)(mCroppedParent->getAbsoluteTop()) + info.vOffset) * 2) - 1);
334
335 for (size_t i = 0; i < GEOMETRY_VERTICIES_TOTAL_COUNT; ++i)
336 {
337 if (i < size)
338 {
339 mResultVerticiesPos[i].left = vertex_left_base + mResultVerticiesPos[i].left * info.pixScaleX * 2;
340 mResultVerticiesPos[i].top = vertex_top_base + mResultVerticiesPos[i].top * info.pixScaleY * -2;
341 }
342 else
343 {
344 // all unused verticies is equal to last used
345 mResultVerticiesPos[i] = mResultVerticiesPos[size == 0 ? 0 : (size - 1)];
346 }
347 }
348 }
349
350 float RotatingSkin::getAngle() const
351 {
352 return mAngle;
353 }
354
355} // 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