00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright © 2000-2002 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 #include "OgreStableHeaders.h" 00026 00027 #include "OgreOverlay.h" 00028 #include "OgreRoot.h" 00029 #include "OgreSceneManager.h" 00030 #include "OgreGuiContainer.h" 00031 #include "OgreCamera.h" 00032 #include "OgreOverlayManager.h" 00033 #include "OgreQuaternion.h" 00034 #include "OgreVector3.h" 00035 00036 00037 namespace Ogre { 00038 00039 //--------------------------------------------------------------------- 00040 Overlay::Overlay(const String& name) 00041 { 00042 mName = name; 00043 mRotate = 0.0f; 00044 mScaleX = 1.0f; 00045 mScaleY = 1.0f; 00046 mScrollX = 0.0f; 00047 mScrollY = 0.0f; 00048 mVisible = false; 00049 mTransformOutOfDate = true; 00050 mTransformUpdated = true; 00051 mZOrder = 100; // Default 00052 mRootNode = new SceneNode(NULL); 00053 00054 } 00055 //--------------------------------------------------------------------- 00056 Overlay::~Overlay() 00057 { 00058 delete mRootNode; 00059 } 00060 //--------------------------------------------------------------------- 00061 const String& Overlay::getName(void) const 00062 { 00063 return mName; 00064 } 00065 //--------------------------------------------------------------------- 00066 void Overlay::setZOrder(ushort zorder) 00067 { 00068 // Limit to 650 since this is multiplied by 100 to pad out for containers 00069 assert (zorder <= 650 && "Overlay ZOrder cannot be greater than 650!"); 00070 00071 mZOrder = zorder; 00072 00073 // Notify attached 2D elements 00074 GuiContainerList::iterator i, iend; 00075 iend = m2DElements.end(); 00076 for (i = m2DElements.begin(); i != iend; ++i) 00077 { 00078 (*i)->_notifyZOrder(zorder); 00079 } 00080 00081 } 00082 //--------------------------------------------------------------------- 00083 ushort Overlay::getZOrder(void) const 00084 { 00085 return mZOrder; 00086 } 00087 //--------------------------------------------------------------------- 00088 bool Overlay::isVisible(void) const 00089 { 00090 return mVisible; 00091 } 00092 //--------------------------------------------------------------------- 00093 void Overlay::show(void) 00094 { 00095 mVisible = true; 00096 } 00097 //--------------------------------------------------------------------- 00098 void Overlay::hide(void) 00099 { 00100 mVisible = false; 00101 } 00102 //--------------------------------------------------------------------- 00103 void Overlay::add2D(GuiContainer* cont) 00104 { 00105 m2DElements.push_back(cont); 00106 // Notify parent 00107 cont->_notifyParent(0, this); 00108 // Set Z order, scaled to separate overlays 00109 // NB max 100 container levels per overlay, should be plenty 00110 cont->_notifyZOrder(mZOrder * 100); 00111 00112 Matrix4 xform; 00113 _getWorldTransforms(&xform); 00114 cont->_notifyWorldTransforms(xform); 00115 cont->_notifyViewport(); 00116 } 00117 //--------------------------------------------------------------------- 00118 void Overlay::remove2D(GuiContainer* cont) 00119 { 00120 m2DElements.remove(cont); 00121 } 00122 //--------------------------------------------------------------------- 00123 void Overlay::add3D(SceneNode* node) 00124 { 00125 mRootNode->addChild(node); 00126 } 00127 //--------------------------------------------------------------------- 00128 void Overlay::remove3D(SceneNode* node) 00129 { 00130 mRootNode->removeChild(node->getName()); 00131 } 00132 //--------------------------------------------------------------------- 00133 void Overlay::clear(void) 00134 { 00135 mRootNode->removeAllChildren(); 00136 m2DElements.clear(); 00137 // Note no deallocation, memory handled by GuiManager & SceneManager 00138 } 00139 //--------------------------------------------------------------------- 00140 void Overlay::setScroll(Real x, Real y) 00141 { 00142 mScrollX = x; 00143 mScrollY = y; 00144 mTransformOutOfDate = true; 00145 mTransformUpdated = true; 00146 } 00147 //--------------------------------------------------------------------- 00148 Real Overlay::getScrollX(void) const 00149 { 00150 return mScrollX; 00151 } 00152 //--------------------------------------------------------------------- 00153 Real Overlay::getScrollY(void) const 00154 { 00155 return mScrollY; 00156 } 00157 //--------------------------------------------------------------------- 00158 GuiContainer* Overlay::getChild(const String& name) 00159 { 00160 00161 GuiContainerList::iterator i, iend; 00162 iend = m2DElements.end(); 00163 for (i = m2DElements.begin(); i != iend; ++i) 00164 { 00165 if ((*i)->getName() == name) 00166 { 00167 return *i; 00168 00169 } 00170 } 00171 return NULL; 00172 } 00173 //--------------------------------------------------------------------- 00174 void Overlay::scroll(Real xoff, Real yoff) 00175 { 00176 mScrollX += xoff; 00177 mScrollY += yoff; 00178 mTransformOutOfDate = true; 00179 mTransformUpdated = true; 00180 } 00181 //--------------------------------------------------------------------- 00182 void Overlay::setRotate(const Radian& angle) 00183 { 00184 mRotate = angle; 00185 mTransformOutOfDate = true; 00186 mTransformUpdated = true; 00187 } 00188 //--------------------------------------------------------------------- 00189 void Overlay::rotate(const Radian& angle) 00190 { 00191 setRotate(mRotate + angle); 00192 } 00193 //--------------------------------------------------------------------- 00194 void Overlay::setScale(Real x, Real y) 00195 { 00196 mScaleX = x; 00197 mScaleY = y; 00198 mTransformOutOfDate = true; 00199 mTransformUpdated = true; 00200 } 00201 //--------------------------------------------------------------------- 00202 Real Overlay::getScaleX(void) const 00203 { 00204 return mScaleX; 00205 } 00206 //--------------------------------------------------------------------- 00207 Real Overlay::getScaleY(void) const 00208 { 00209 return mScaleY; 00210 } 00211 //--------------------------------------------------------------------- 00212 void Overlay::_getWorldTransforms(Matrix4* xform) const 00213 { 00214 if (mTransformOutOfDate) 00215 { 00216 updateTransform(); 00217 } 00218 *xform = mTransform; 00219 00220 } 00221 //----------------------------------------------------------------------- 00222 const Quaternion& Overlay::getWorldOrientation(void) const 00223 { 00224 // n/a 00225 return Quaternion::IDENTITY; 00226 } 00227 //----------------------------------------------------------------------- 00228 const Vector3& Overlay::getWorldPosition(void) const 00229 { 00230 // n/a 00231 return Vector3::ZERO; 00232 } 00233 //--------------------------------------------------------------------- 00234 void Overlay::_findVisibleObjects(Camera* cam, RenderQueue* queue) 00235 { 00236 GuiContainerList::iterator i, iend; 00237 00238 if (OverlayManager::getSingleton().hasViewportChanged()) 00239 { 00240 iend = m2DElements.end(); 00241 for (i = m2DElements.begin(); i != iend; ++i) 00242 { 00243 (*i)->_notifyViewport(); 00244 } 00245 } 00246 00247 // update elements 00248 if (mTransformUpdated) 00249 { 00250 GuiContainerList::iterator i, iend; 00251 Matrix4 xform; 00252 00253 _getWorldTransforms(&xform); 00254 iend = m2DElements.end(); 00255 for (i = m2DElements.begin(); i != iend; ++i) 00256 { 00257 (*i)->_notifyWorldTransforms(xform); 00258 } 00259 00260 mTransformUpdated = false; 00261 } 00262 00263 if (mVisible) 00264 { 00265 // Add 3D elements 00266 mRootNode->setPosition(cam->getDerivedPosition()); 00267 mRootNode->setOrientation(cam->getDerivedOrientation()); 00268 mRootNode->_update(true, false); 00269 // Set up the default queue group for the objects about to be added 00270 RenderQueueGroupID oldgrp = queue->getDefaultQueueGroup(); 00271 ushort oldPriority = queue-> getDefaultRenderablePriority(); 00272 queue->setDefaultQueueGroup(RENDER_QUEUE_OVERLAY); 00273 queue->setDefaultRenderablePriority((mZOrder*100)-1); 00274 mRootNode->_findVisibleObjects(cam, queue, true, false); 00275 // Reset the group 00276 queue->setDefaultQueueGroup(oldgrp); 00277 queue->setDefaultRenderablePriority(oldPriority); 00278 // Add 2D elements 00279 iend = m2DElements.end(); 00280 for (i = m2DElements.begin(); i != iend; ++i) 00281 { 00282 (*i)->_update(); 00283 00284 (*i)->_updateRenderQueue(queue); 00285 } 00286 } 00287 00288 00289 00290 00291 } 00292 //--------------------------------------------------------------------- 00293 void Overlay::updateTransform(void) const 00294 { 00295 // Ordering: 00296 // 1. Scale 00297 // 2. Rotate 00298 // 3. Translate 00299 00300 Matrix3 rot3x3, scale3x3; 00301 rot3x3.FromEulerAnglesXYZ(Radian(0),Radian(0),mRotate); 00302 scale3x3 = Matrix3::ZERO; 00303 scale3x3[0][0] = mScaleX; 00304 scale3x3[1][1] = mScaleY; 00305 scale3x3[2][2] = 1.0f; 00306 00307 mTransform = Matrix4::IDENTITY; 00308 mTransform = rot3x3 * scale3x3; 00309 mTransform.setTrans(Vector3(mScrollX, mScrollY, 0)); 00310 00311 mTransformOutOfDate = false; 00312 } 00313 //--------------------------------------------------------------------- 00314 void Overlay::load(void) 00315 { 00316 // Do nothing 00317 } 00318 //--------------------------------------------------------------------- 00319 void Overlay::unload(void) 00320 { 00321 // Do nothing 00322 } 00323 00324 GuiElement* Overlay::findElementAt(Real x, Real y) 00325 { 00326 GuiElement* ret = NULL; 00327 int currZ = -1; 00328 GuiContainerList::iterator i, iend; 00329 iend = m2DElements.end(); 00330 for (i = m2DElements.begin(); i != iend; ++i) 00331 { 00332 int z = (*i)->getZOrder(); 00333 if (z > currZ) 00334 { 00335 GuiElement* elementFound = (*i)->findElementAt(x,y); 00336 if(elementFound) 00337 { 00338 currZ = elementFound->getZOrder(); 00339 ret = elementFound; 00340 } 00341 } 00342 } 00343 return ret; 00344 } 00345 00346 } 00347
Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:37 2004