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 mZOrder = zorder; 00069 00070 // Notify attached 2D elements 00071 GuiContainerList::iterator i, iend; 00072 iend = m2DElements.end(); 00073 for (i = m2DElements.begin(); i != iend; ++i) 00074 { 00075 (*i)->_notifyZOrder(zorder); 00076 } 00077 00078 } 00079 //--------------------------------------------------------------------- 00080 ushort Overlay::getZOrder(void) const 00081 { 00082 return mZOrder; 00083 } 00084 //--------------------------------------------------------------------- 00085 bool Overlay::isVisible(void) const 00086 { 00087 return mVisible; 00088 } 00089 //--------------------------------------------------------------------- 00090 void Overlay::show(void) 00091 { 00092 mVisible = true; 00093 } 00094 //--------------------------------------------------------------------- 00095 void Overlay::hide(void) 00096 { 00097 mVisible = false; 00098 } 00099 //--------------------------------------------------------------------- 00100 void Overlay::add2D(GuiContainer* cont) 00101 { 00102 m2DElements.push_back(cont); 00103 // Notify parent 00104 cont->_notifyParent(0, this); 00105 // Set Z order, scaled to separate overlays 00106 // NB max 100 container levels per overlay, should be plenty 00107 cont->_notifyZOrder(mZOrder * 100); 00108 00109 Matrix4 xform; 00110 _getWorldTransforms(&xform); 00111 cont->_notifyWorldTransforms(xform); 00112 cont->_notifyViewport(); 00113 } 00114 //--------------------------------------------------------------------- 00115 void Overlay::remove2D(GuiContainer* cont) 00116 { 00117 m2DElements.remove(cont); 00118 } 00119 //--------------------------------------------------------------------- 00120 void Overlay::add3D(SceneNode* node) 00121 { 00122 mRootNode->addChild(node); 00123 } 00124 //--------------------------------------------------------------------- 00125 void Overlay::remove3D(SceneNode* node) 00126 { 00127 mRootNode->removeChild(node->getName()); 00128 } 00129 //--------------------------------------------------------------------- 00130 void Overlay::clear(void) 00131 { 00132 mRootNode->removeAllChildren(); 00133 m2DElements.clear(); 00134 // Note no deallocation, memory handled by GuiManager & SceneManager 00135 } 00136 //--------------------------------------------------------------------- 00137 void Overlay::setScroll(Real x, Real y) 00138 { 00139 mScrollX = x; 00140 mScrollY = y; 00141 mTransformOutOfDate = true; 00142 mTransformUpdated = true; 00143 } 00144 //--------------------------------------------------------------------- 00145 Real Overlay::getScrollX(void) const 00146 { 00147 return mScrollX; 00148 } 00149 //--------------------------------------------------------------------- 00150 Real Overlay::getScrollY(void) const 00151 { 00152 return mScrollY; 00153 } 00154 //--------------------------------------------------------------------- 00155 GuiContainer* Overlay::getChild(const String& name) 00156 { 00157 00158 GuiContainerList::iterator i, iend; 00159 iend = m2DElements.end(); 00160 for (i = m2DElements.begin(); i != iend; ++i) 00161 { 00162 if ((*i)->getName() == name) 00163 { 00164 return *i; 00165 00166 } 00167 } 00168 return NULL; 00169 } 00170 //--------------------------------------------------------------------- 00171 void Overlay::scroll(Real xoff, Real yoff) 00172 { 00173 mScrollX += xoff; 00174 mScrollY += yoff; 00175 mTransformOutOfDate = true; 00176 mTransformUpdated = true; 00177 } 00178 //--------------------------------------------------------------------- 00179 void Overlay::setRotate(Real angleunits) 00180 { 00181 mRotate = angleunits; 00182 mTransformOutOfDate = true; 00183 mTransformUpdated = true; 00184 } 00185 //--------------------------------------------------------------------- 00186 Real Overlay::getRotate(void) const 00187 { 00188 return mRotate; 00189 } 00190 //--------------------------------------------------------------------- 00191 void Overlay::rotate(Real angleunits) 00192 { 00193 setRotate(mRotate += angleunits); 00194 } 00195 //--------------------------------------------------------------------- 00196 void Overlay::setScale(Real x, Real y) 00197 { 00198 mScaleX = x; 00199 mScaleY = y; 00200 mTransformOutOfDate = true; 00201 mTransformUpdated = true; 00202 } 00203 //--------------------------------------------------------------------- 00204 Real Overlay::getScaleX(void) const 00205 { 00206 return mScaleX; 00207 } 00208 //--------------------------------------------------------------------- 00209 Real Overlay::getScaleY(void) const 00210 { 00211 return mScaleY; 00212 } 00213 //--------------------------------------------------------------------- 00214 void Overlay::_getWorldTransforms(Matrix4* xform) const 00215 { 00216 if (mTransformOutOfDate) 00217 { 00218 updateTransform(); 00219 } 00220 *xform = mTransform; 00221 00222 } 00223 //----------------------------------------------------------------------- 00224 const Quaternion& Overlay::getWorldOrientation(void) const 00225 { 00226 // n/a 00227 return Quaternion::IDENTITY; 00228 } 00229 //----------------------------------------------------------------------- 00230 const Vector3& Overlay::getWorldPosition(void) const 00231 { 00232 // n/a 00233 return Vector3::ZERO; 00234 } 00235 //--------------------------------------------------------------------- 00236 void Overlay::_findVisibleObjects(Camera* cam, RenderQueue* queue) 00237 { 00238 GuiContainerList::iterator i, iend; 00239 00240 if (OverlayManager::getSingleton().hasViewportChanged()) 00241 { 00242 iend = m2DElements.end(); 00243 for (i = m2DElements.begin(); i != iend; ++i) 00244 { 00245 (*i)->_notifyViewport(); 00246 } 00247 } 00248 00249 if (!mVisible) 00250 return; 00251 00252 // Add 3D elements 00253 mRootNode->setPosition(cam->getDerivedPosition()); 00254 mRootNode->setOrientation(cam->getDerivedOrientation()); 00255 mRootNode->_update(true, false); 00256 // Set up the default queue group for the objects about to be added 00257 RenderQueueGroupID oldgrp = queue->getDefaultQueueGroup(); 00258 queue->setDefaultQueueGroup(RENDER_QUEUE_OVERLAY); 00259 mRootNode->_findVisibleObjects(cam, queue, true, false); 00260 // Reset the group 00261 queue->setDefaultQueueGroup(oldgrp); 00262 00263 00264 // update elements 00265 if (mTransformUpdated) 00266 { 00267 GuiContainerList::iterator i, iend; 00268 Matrix4 xform; 00269 00270 _getWorldTransforms(&xform); 00271 iend = m2DElements.end(); 00272 for (i = m2DElements.begin(); i != iend; ++i) 00273 { 00274 (*i)->_notifyWorldTransforms(xform); 00275 } 00276 00277 mTransformUpdated = false; 00278 } 00279 00280 // Add 2D elements 00281 iend = m2DElements.end(); 00282 for (i = m2DElements.begin(); i != iend; ++i) 00283 { 00284 (*i)->_update(); 00285 00286 (*i)->_updateRenderQueue(queue); 00287 } 00288 00289 } 00290 //--------------------------------------------------------------------- 00291 void Overlay::updateTransform(void) const 00292 { 00293 // Ordering: 00294 // 1. Scale 00295 // 2. Rotate 00296 // 3. Translate 00297 00298 00299 Matrix3 rot3x3, scale3x3; 00300 rot3x3.FromEulerAnglesXYZ(0,0,Math::AngleUnitsToRadians(mRotate)); 00301 scale3x3 = Matrix3::ZERO; 00302 scale3x3[0][0] = mScaleX; 00303 scale3x3[1][1] = mScaleY; 00304 scale3x3[2][2] = 1.0f; 00305 00306 mTransform = Matrix4::IDENTITY; 00307 mTransform = rot3x3 * scale3x3; 00308 mTransform.setTrans(Vector3(mScrollX, mScrollY, 0)); 00309 00310 mTransformOutOfDate = false; 00311 } 00312 //--------------------------------------------------------------------- 00313 void Overlay::load(void) 00314 { 00315 // Do nothing 00316 } 00317 //--------------------------------------------------------------------- 00318 void Overlay::unload(void) 00319 { 00320 // Do nothing 00321 } 00322 00323 GuiElement* Overlay::findElementAt(Real x, Real y) 00324 { 00325 GuiElement* ret = NULL; 00326 int currZ = -1; 00327 GuiContainerList::iterator i, iend; 00328 iend = m2DElements.end(); 00329 for (i = m2DElements.begin(); i != iend; ++i) 00330 { 00331 int z = (*i)->getZOrder(); 00332 if (z > currZ) 00333 { 00334 GuiElement* elementFound = (*i)->findElementAt(x,y); 00335 if(elementFound) 00336 { 00337 currZ = elementFound->getZOrder(); 00338 ret = elementFound; 00339 } 00340 } 00341 } 00342 return ret; 00343 } 00344 00345 } 00346
Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:22:29 2004