1 /*! 2 @file 3 @author Evmenov Georgiy 4 @date 01/2008 5 @module 6 */ 7 8 #pragma once 9 #include <Ogre.h> 10 #include <MyGUI.h> 11 #include "RenderBox.h" 12 #include "Def_Str.h" 13 14 namespace wraps 15 { 16 17 class RenderBoxScene : public RenderBox /*Canvas*/ 18 { 19 public: RenderBoxScene()20 RenderBoxScene() : 21 mScene(nullptr), 22 mNode(nullptr), 23 mCameraNode(nullptr), 24 //mCamera(nullptr), 25 mEntity(nullptr), 26 mAnimationState(nullptr), 27 mRotationSpeed(RENDER_BOX_AUTO_ROTATION_SPEED), 28 mMouseRotation(false), 29 mLastPointerX(0), 30 mMousePressed(false), 31 mAutoRotation(false), 32 mFrameAdvise(false) 33 { 34 } 35 ~RenderBoxScene()36 virtual ~RenderBoxScene() 37 { 38 } 39 40 /** default RenderBox autorotation speed (if enabled) */ 41 enum { RENDER_BOX_AUTO_ROTATION_SPEED = 20 }; 42 43 44 /** Add mesh to scene and remove previous one 45 @param 46 _meshName The name of the Mesh it is to be based on (e.g. 'ogrehead.mesh'). 47 returns mesh size 48 */ 49 Ogre::Vector3 injectObject(const Ogre::String& _meshName, const Ogre::Vector3& _position = Ogre::Vector3::ZERO, const Ogre::Quaternion& _orientation = Ogre::Quaternion::IDENTITY, const Ogre::Vector3& _scale = Ogre::Vector3::UNIT_SCALE) 50 { 51 clearScene(); 52 53 static size_t num = 0; 54 mEntity = mScene->createEntity(MyGUI::utility::toString(this, "_RenderBoxMesh_", _meshName, num++), _meshName); 55 Ogre::SceneNode* node = mNode->createChildSceneNode(_position, _orientation); 56 node->attachObject(mEntity); 57 58 updateViewport(); 59 return mEntity->getBoundingBox().getSize(); /// 60 } 61 62 /** Run mesh animation if animation with such name exist (else print warning in log). 63 To stop animation use empty string. 64 */ setAnimation(const Ogre::String & _value)65 void setAnimation(const Ogre::String& _value) 66 { 67 if (mEntity == nullptr) 68 return; 69 70 try 71 { 72 mAnimationState = mEntity->getAnimationState(_value); 73 mAnimationState->setEnabled(true); 74 mAnimationState->setLoop(true); 75 mAnimationState->setWeight(1); 76 } 77 catch (Ogre::ItemIdentityException& _e) 78 { 79 MYGUI_LOG(Warning, _e.getDescription()); 80 } 81 82 frameAdvise(needFrameUpdate()); 83 } 84 85 /** Clear scene */ clearScene()86 void clearScene() 87 { 88 setRotationAngle(Ogre::Degree(0)); 89 90 if (mScene) 91 { 92 mScene->destroyAllEntities(); 93 mNode->removeAndDestroyAllChildren(); 94 } 95 96 mEntity = nullptr; 97 mAnimationState = nullptr; 98 } 99 100 /** Set speed of entity rotation. 101 @param 102 _speed of rotation in degrees per second. 103 */ 104 void setAutoRotationSpeed(int _value = RENDER_BOX_AUTO_ROTATION_SPEED) 105 { 106 mRotationSpeed = _value; 107 } 108 109 /** Get speed of entity rotation.*/ getAutoRotationSpeed()110 int getAutoRotationSpeed() 111 { 112 return mRotationSpeed; 113 } 114 115 /** Enable or disable auto rotation */ setAutoRotation(bool _value)116 void setAutoRotation(bool _value) 117 { 118 mAutoRotation = _value; 119 frameAdvise(needFrameUpdate()); 120 } 121 122 /** Get auto rotation flag */ getAutoRotation()123 bool getAutoRotation() 124 { 125 return mAutoRotation; 126 } 127 128 /** Set start rotation angle of entity. */ setRotationAngle(const Ogre::Degree & _value)129 void setRotationAngle(const Ogre::Degree& _value) 130 { 131 if (mNode) 132 { 133 mNode->resetOrientation(); 134 mNode->yaw(Ogre::Radian(_value)); 135 } 136 } 137 138 /** Get rotation angle of entity. */ getRotationAngle()139 Ogre::Degree getRotationAngle() 140 { 141 return Ogre::Degree(mNode->getOrientation().getYaw()); 142 } 143 144 /** Set possibility to rotate mesh by mouse drag. */ setMouseRotation(bool _value)145 void setMouseRotation(bool _value) 146 { 147 mMouseRotation = _value; 148 } 149 150 /** Get mouse rotation flag */ getMouseRotation()151 bool getMouseRotation() 152 { 153 return mMouseRotation; 154 } 155 setCanvas(MyGUI::Canvas * _value)156 virtual void setCanvas(MyGUI::Canvas* _value) 157 { 158 RenderBox::setCanvas(_value); 159 160 mCanvas->eventMouseDrag += newDelegate(this, &RenderBoxScene::notifyMouseDrag); 161 mCanvas->eventMouseButtonPressed += newDelegate(this, &RenderBoxScene::notifyMouseButtonPressed); 162 mCanvas->eventMouseButtonReleased += newDelegate(this, &RenderBoxScene::notifyMouseButtonReleased); 163 164 createScene(); 165 } 166 destroy()167 virtual void destroy() 168 { 169 clearScene(); 170 171 if (mCanvas) 172 { 173 frameAdvise(false); 174 175 mCanvas->eventMouseDrag -= newDelegate(this, &RenderBoxScene::notifyMouseDrag); 176 mCanvas->eventMouseButtonPressed -= newDelegate(this, &RenderBoxScene::notifyMouseButtonPressed); 177 mCanvas->eventMouseButtonReleased -= newDelegate(this, &RenderBoxScene::notifyMouseButtonReleased); 178 mCanvas = nullptr; 179 180 Ogre::Root* root = Ogre::Root::getSingletonPtr(); 181 if (root && mScene) 182 root->destroySceneManager(mScene); 183 mScene = nullptr; 184 mNode = nullptr; 185 } 186 187 RenderBox::destroy(); 188 } 189 190 private: notifyMouseDrag(MyGUI::Widget * _sender,int _left,int _top,MyGUI::MouseButton _id)191 void notifyMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) 192 { 193 if (mMouseRotation) 194 { 195 if (mNode) 196 mNode->yaw(Ogre::Radian(Ogre::Degree((float)_left - mLastPointerX))); 197 mLastPointerX = _left; 198 } 199 } 200 notifyMouseButtonPressed(MyGUI::Widget * _sender,int _left,int _top,MyGUI::MouseButton _id)201 void notifyMouseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) 202 { 203 if (mMouseRotation) 204 { 205 if (_id == MyGUI::MouseButton::Left) 206 { 207 const MyGUI::IntPoint& point = MyGUI::InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left); 208 mLastPointerX = point.left; 209 mMousePressed = true; 210 } 211 if (_id == MyGUI::MouseButton::Right) 212 { 213 const MyGUI::IntPoint& point = MyGUI::InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Right); 214 mLastPointerX = point.left; 215 mMousePressed = true; 216 } 217 } 218 } 219 notifyMouseButtonReleased(MyGUI::Widget * _sender,int _left,int _top,MyGUI::MouseButton _id)220 void notifyMouseButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) 221 { 222 mMousePressed = false; 223 } 224 frameAdvise(bool _advise)225 void frameAdvise(bool _advise) 226 { 227 if (_advise && !mFrameAdvise && needFrameUpdate()) 228 { 229 MyGUI::Gui::getInstance().eventFrameStart += MyGUI::newDelegate(this, &RenderBoxScene::frameEntered); 230 mFrameAdvise = true; 231 } 232 else if (!_advise && mFrameAdvise && !needFrameUpdate()) 233 { 234 MyGUI::Gui::getInstance().eventFrameStart -= MyGUI::newDelegate(this, &RenderBoxScene::frameEntered); 235 mFrameAdvise = false; 236 } 237 } 238 frameEntered(float _time)239 void frameEntered(float _time) 240 { 241 if (!mMousePressed) 242 { 243 if (mAutoRotation && mNode) 244 mNode->yaw(Ogre::Radian(Ogre::Degree(_time * mRotationSpeed))); 245 } 246 if (mAnimationState) 247 mAnimationState->addTime(_time); 248 } 249 needFrameUpdate()250 bool needFrameUpdate() 251 { 252 return mAutoRotation || mAnimationState; 253 } 254 255 256 void createScene(); 257 258 void updateViewport(); 259 260 requestUpdateCanvas(MyGUI::Canvas * _canvas,MyGUI::Canvas::Event _event)261 virtual void requestUpdateCanvas(MyGUI::Canvas* _canvas, MyGUI::Canvas::Event _event) 262 { 263 RenderBox::requestUpdateCanvas(_canvas, _event); 264 265 updateViewport(); 266 } 267 268 public: 269 Ogre::SceneManager* mScene; 270 Ogre::SceneNode* mNode; 271 Ogre::SceneNode* mCameraNode; 272 //Ogre::Camera* mCamera; 273 private: 274 Ogre::Entity* mEntity; 275 Ogre::AnimationState* mAnimationState; 276 277 int mRotationSpeed; 278 bool mMouseRotation; 279 int mLastPointerX; 280 bool mMousePressed; 281 bool mAutoRotation; 282 283 bool mFrameAdvise; 284 }; 285 286 } // namespace wraps 287