MyGUI  3.0.1
MyGUI_RotatingSkin.cpp
Go to the documentation of this file.
00001 
00007 /*
00008     This file is part of MyGUI.
00009 
00010     MyGUI is free software: you can redistribute it and/or modify
00011     it under the terms of the GNU Lesser General Public License as published by
00012     the Free Software Foundation, either version 3 of the License, or
00013     (at your option) any later version.
00014 
00015     MyGUI is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018     GNU Lesser General Public License for more details.
00019 
00020     You should have received a copy of the GNU Lesser General Public License
00021     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
00022 */
00023 #include "MyGUI_Precompiled.h"
00024 #include "MyGUI_RotatingSkin.h"
00025 #include "MyGUI_RenderItem.h"
00026 #include "MyGUI_CommonStateInfo.h"
00027 
00028 namespace MyGUI
00029 {
00030 
00031     RotatingSkin::RotatingSkin() :
00032         SubSkin(),
00033         mAngle(0.0f),
00034         mLocalCenter(false)
00035     {
00036         for (int i = 0; i<4; ++i)
00037         {
00038             mBaseAngles[i] = 0.0f;
00039             mBaseDistances[i] = 0.0f;
00040         }
00041     }
00042 
00043     RotatingSkin::~RotatingSkin()
00044     {
00045     }
00046 
00047     void RotatingSkin::setAngle(float _angle)
00048     {
00049         mAngle = _angle;
00050         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00051     }
00052 
00053     void RotatingSkin::setCenter(const IntPoint &_center, bool _local)
00054     {
00055         mCenterPos = _center;
00056         mLocalCenter = _local;
00057         recalculateAngles();
00058         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00059     }
00060 
00061     IntPoint RotatingSkin::getCenter(bool _local) const
00062     {
00063         return mCenterPos + (_local ? IntPoint() : mCroppedParent->getAbsolutePosition());
00064     }
00065 
00066     void RotatingSkin::doRender()
00067     {
00068         if ((!mVisible) || mEmptyView) return;
00069 
00070         VertexQuad* quad = (VertexQuad*)mRenderItem->getCurrentVertextBuffer();
00071 
00072         const RenderTargetInfo& info = mRenderItem->getRenderTarget()->getInfo();
00073 
00074         float vertex_z = info.maximumDepth;
00075 
00076         float vertex_left_base = ((info.pixScaleX * (float)(mCurrentCoord.left + mCroppedParent->getAbsoluteLeft() + mCenterPos.left) + info.hOffset) * 2) - 1;
00077         float vertex_top_base = -(((info.pixScaleY * (float)(mCurrentCoord.top + mCroppedParent->getAbsoluteTop() + mCenterPos.top) + info.vOffset) * 2) - 1);
00078 
00079         // FIXME: do it only when size changes
00080         recalculateAngles();
00081 
00082         quad->set(
00083             vertex_left_base + cos(-mAngle + mBaseAngles[0]) * mBaseDistances[0] * info.pixScaleX * -2,
00084             vertex_top_base + sin(-mAngle + mBaseAngles[0]) * mBaseDistances[0] * info.pixScaleY * -2,
00085             vertex_left_base + cos(-mAngle + mBaseAngles[3]) * mBaseDistances[3] * info.pixScaleX * -2,
00086             vertex_top_base + sin(-mAngle + mBaseAngles[3]) * mBaseDistances[3] * info.pixScaleY * -2,
00087             vertex_left_base + cos(-mAngle + mBaseAngles[2]) * mBaseDistances[2] * info.pixScaleX * -2,
00088             vertex_top_base + sin(-mAngle + mBaseAngles[2]) * mBaseDistances[2] * info.pixScaleY * -2,
00089             vertex_left_base + cos(-mAngle + mBaseAngles[1]) * mBaseDistances[1] * info.pixScaleX * -2,
00090             vertex_top_base + sin(-mAngle + mBaseAngles[1]) * mBaseDistances[1] * info.pixScaleY * -2,
00091             vertex_z,
00092             mCurrentTexture.left,
00093             mCurrentTexture.top,
00094             mCurrentTexture.right,
00095             mCurrentTexture.bottom,
00096             mCurrentColour
00097             );
00098 
00099         mRenderItem->setLastVertexCount(VertexQuad::VertexCount);
00100     }
00101 
00102     inline float len(float x, float y) { return sqrt(x*x + y*y); }
00103 
00104     void RotatingSkin::recalculateAngles()
00105     {
00106 #ifndef M_PI
00107         const float M_PI = 3.141593f;
00108 #endif
00109         // FIXME mLocalCenter ignored
00110         float left_base = 0;
00111         float top_base = 0;
00112 
00113         if (!mLocalCenter)
00114         {
00115             left_base = (float)mCurrentCoord.width;
00116             top_base = (float)mCurrentCoord.height;
00117         }
00118 
00119         float width_base = (float)mCurrentCoord.width;
00120         float height_base = (float)mCurrentCoord.height;
00121 
00122         mBaseAngles[0] = atan2((float)           - mCenterPos.left,             - mCenterPos.top) + M_PI/2;
00123         mBaseAngles[1] = atan2((float)           - mCenterPos.left, height_base - mCenterPos.top) + M_PI/2;
00124         mBaseAngles[2] = atan2((float)width_base - mCenterPos.left, height_base - mCenterPos.top) + M_PI/2;
00125         mBaseAngles[3] = atan2((float)width_base - mCenterPos.left,             - mCenterPos.top) + M_PI/2;
00126 
00127         mBaseDistances[0] = len((float)           - mCenterPos.left,             - mCenterPos.top);
00128         mBaseDistances[1] = len((float)           - mCenterPos.left, height_base - mCenterPos.top);
00129         mBaseDistances[2] = len((float)width_base - mCenterPos.left, height_base - mCenterPos.top);
00130         mBaseDistances[3] = len((float)width_base - mCenterPos.left,             - mCenterPos.top);
00131 
00132     }
00133 
00134 } // namespace MyGUI