PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: SceneContainer.h * 00003 * 00004 * Copyright (C) 2002-2012 The PixelLight Team (http://www.pixellight.org/) 00005 * 00006 * This file is part of PixelLight. 00007 * 00008 * PixelLight is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published by 00010 * the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * PixelLight is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with PixelLight. If not, see <http://www.gnu.org/licenses/>. 00020 \*********************************************************/ 00021 00022 00023 #ifndef __PLSCENE_SCENECONTAINER_H__ 00024 #define __PLSCENE_SCENECONTAINER_H__ 00025 #pragma once 00026 00027 00028 //[-------------------------------------------------------] 00029 //[ Includes ] 00030 //[-------------------------------------------------------] 00031 #include <PLCore/Container/Pool.h> 00032 #include <PLCore/Tools/Loadable.h> 00033 #include "PLScene/Scene/SceneNode.h" 00034 00035 00036 //[-------------------------------------------------------] 00037 //[ Namespace ] 00038 //[-------------------------------------------------------] 00039 namespace PLScene { 00040 00041 00042 //[-------------------------------------------------------] 00043 //[ Forward declarations ] 00044 //[-------------------------------------------------------] 00045 class SceneQuery; 00046 class SceneHierarchy; 00047 class SceneQueryManager; 00048 00049 00050 //[-------------------------------------------------------] 00051 //[ Classes ] 00052 //[-------------------------------------------------------] 00053 /** 00054 * @brief 00055 * Scene container node (group node) class which is using scene nodes 00056 * 00057 * @remarks 00058 * This is a root or inner node of the scene graph. 00059 * 00060 * @note 00061 * - The 'scene node space' axis aligned bounding box should always cover all scene nodes of this container 00062 * - Within GetByName(<Name>) you can also use 'absolute names' instead of 'relative' names. 'Root.MyScene.MyNode' 00063 * for instance will return the scene node 'MyNode' within the scene container 'MyScene' which is a 00064 * subnode of 'Root'. 'MyScene.MyNode' will return the node 'MyNode' of the container 'MyScene' which is 00065 * an element of the current container. 'Parent.MyNode' will return the scene node 'MyNode' within the parent 00066 * scene container. 'Parent' returns the parent scene container, 'This' returns THIS container, 'Root' will return 00067 * the root scene container itself. 00068 * - Use "GetSceneContext()->GetRoot()" to get the 'root' node in which you can insert your scenes 00069 * - Derived classes should use a 'SC'-prefix (example: SCCell) 00070 * - By default, all draw function flags are set 00071 */ 00072 class SceneContainer : public SceneNode, public PLCore::ElementManager<SceneNode>, public PLCore::Loadable { 00073 00074 00075 //[-------------------------------------------------------] 00076 //[ Friends ] 00077 //[-------------------------------------------------------] 00078 friend class SceneNode; 00079 friend class SceneLoader; 00080 friend class SceneContext; 00081 00082 00083 //[-------------------------------------------------------] 00084 //[ Public definitions ] 00085 //[-------------------------------------------------------] 00086 public: 00087 /** 00088 * @brief 00089 * Scene node flags (SceneNode flags extension) 00090 */ 00091 enum EFlags { 00092 NoRecursion = 1<<10 /**< Do NOT take the scene nodes of this container into account when for instance 00093 rendering the scene. 'SCRenderToTexture' for example sets this flag. */ 00094 }; 00095 pl_enum(EFlags) 00096 pl_enum_base(SceneNode::EFlags) 00097 pl_enum_value(NoRecursion, "Do NOT take the scene nodes of this container into account when for instance rendering the scene. 'SCRenderToTexture' for example sets this flag.") 00098 pl_enum_end 00099 00100 00101 //[-------------------------------------------------------] 00102 //[ RTTI interface ] 00103 //[-------------------------------------------------------] 00104 pl_class(PLS_RTTI_EXPORT, SceneContainer, "PLScene", PLScene::SceneNode, "Scene container node (group node) class which is using scene nodes") 00105 // Attributes 00106 pl_attribute(Hierarchy, PLCore::String, "", ReadWrite, GetSet, "Class name of the scene container hierarchy", "") 00107 // Overwritten SceneNode attributes 00108 pl_attribute(Flags, pl_flag_type(EFlags), 0, ReadWrite, GetSet, "Flags", "") 00109 pl_attribute(AABBMin, PLMath::Vector3, PLMath::Vector3(-10000.0f, -10000.0f, -10000.0f), ReadWrite, GetSet, "Minimum position of the 'scene node space' axis aligned bounding box", "") 00110 pl_attribute(AABBMax, PLMath::Vector3, PLMath::Vector3( 10000.0f, 10000.0f, 10000.0f), ReadWrite, GetSet, "Maximum position of the 'scene node space' axis aligned bounding box", "") 00111 // Overwritten Loadable attributes 00112 pl_attribute(Filename, PLCore::String, "", ReadWrite, GetSet, "Filename of the file to load the container from", "Type='Scene'") 00113 #ifdef PLSCENE_EXPORTS // The following is only required when compiling PLScene 00114 // Constructors 00115 pl_constructor_0(DefaultConstructor, "Default constructor", "") 00116 // Methods 00117 pl_method_1(Clear, pl_ret_type(bool), bool, "Destroys all scene nodes within this scene container. If the first parameter is 'true' protected scene nodes are destroyed as well. Returns 'true' if all went fine, else 'false'.", "") 00118 pl_method_1(GetByIndex, pl_ret_type(SceneNode*), PLCore::uint32, "Returns a scene node by using the given index, result can be a null pointer.", "") 00119 pl_method_1(GetByName, pl_ret_type(SceneNode*), const PLCore::String&, "Returns a scene node by using the given name, result can be a null pointer.", "") 00120 pl_method_3(Create, pl_ret_type(SceneNode*), const PLCore::String&, const PLCore::String&, const PLCore::String&, "Creates a new scene node. Name of the scene node class to create an instance from as first parameter, scene node name as second parameter and optional parameter string as third parameter. Returns a pointer to the new scene node or a null pointer if something went wrong (maybe unknown class or the class is not derived from \"PLScene::SceneNode\").", "") 00121 pl_method_4(CreateAtIndex, pl_ret_type(SceneNode*), const PLCore::String&, const PLCore::String&, const PLCore::String&, int, "Creates a new scene node at a certain index inside the scene node list. Name of the scene node class to create an instance from as first parameter, scene node name as second parameter and optional parameter string as third parameter, optional index position specifying the location within the scene node list where the scene node should be added as fourth parameter (<0 for at the end). Returns a pointer to the new scene node or a null pointer if something went wrong (maybe unknown class or the class is not derived from \"PLScene::SceneNode\").", "") 00122 pl_method_0(CalculateAABoundingBox, pl_ret_type(void), "Calculates and sets the axis align bounding box in 'scene node space'. Because the 'scene node space' axis aligned bounding box should always cover all scene nodes of this container, you can use this function to calculate and set this a bounding box automatically.", "") 00123 pl_method_3(LoadByFilename, pl_ret_type(bool), const PLCore::String&, const PLCore::String&, const PLCore::String&, "Load a scene from a file given by filename. Scene filename as first parameter, optional load method parameters as second parameter, optional name of the load method to use as third parameter. Returns 'true' if all went fine, else 'false'.", "") 00124 #endif 00125 // Signals 00126 pl_signal_1(SignalLoadProgress, float, "Scene load progress signal. Current load progress as parameter - if not within 0-1 loading is done.", "") 00127 pl_class_end 00128 00129 00130 //[-------------------------------------------------------] 00131 //[ Public RTTI get/set functions ] 00132 //[-------------------------------------------------------] 00133 public: 00134 PLS_API PLCore::String GetHierarchy() const; 00135 PLS_API void SetHierarchy(const PLCore::String &sValue); 00136 PLS_API void SetFilename(const PLCore::String &sValue); 00137 00138 00139 //[-------------------------------------------------------] 00140 //[ Public functions ] 00141 //[-------------------------------------------------------] 00142 public: 00143 /** 00144 * @brief 00145 * Default constructor 00146 */ 00147 PLS_API SceneContainer(); 00148 00149 /** 00150 * @brief 00151 * Destructor 00152 */ 00153 PLS_API virtual ~SceneContainer(); 00154 00155 /** 00156 * @brief 00157 * Creates a new scene node 00158 * 00159 * @param[in] sClass 00160 * Name of the scene node class to create an instance from 00161 * @param[in] sName 00162 * Scene node name 00163 * @param[in] sParameters 00164 * Optional parameter string 00165 * 00166 * @return 00167 * Pointer to the new scene node or a null pointer if something went wrong 00168 * (maybe unknown class or the class is not derived from SceneNode) 00169 * 00170 * @note 00171 * - If the desired name is already in use, the name is chosen automatically 00172 */ 00173 inline SceneNode *Create(const PLCore::String &sClass, const PLCore::String &sName = "", const PLCore::String &sParameters = ""); 00174 00175 /** 00176 * @brief 00177 * Creates a new scene node at a certain index inside the scene node list 00178 * 00179 * @param[in] sClass 00180 * Name of the scene node class to create an instance from 00181 * @param[in] sName 00182 * Scene node name 00183 * @param[in] sParameters 00184 * Optional parameter string 00185 * @param[in] nPosition 00186 * Optional index position specifying the location within the scene node list where the scene node should be added, <0 for at the end 00187 * 00188 * @return 00189 * Pointer to the new scene node or a null pointer if something went wrong 00190 * (maybe unknown class or the class is not derived from SceneNode) 00191 * 00192 * @note 00193 * - If the desired name is already in use, the name is chosen automatically 00194 */ 00195 PLS_API SceneNode *CreateAtIndex(const PLCore::String &sClass, const PLCore::String &sName = "", const PLCore::String &sParameters = "", int nPosition = -1); 00196 00197 /** 00198 * @brief 00199 * Calculates and sets the axis align bounding box in 'scene node space' 00200 * 00201 * @remarks 00202 * Because the 'scene node space' axis aligned bounding box should always cover all scene nodes of 00203 * this container, you can use this function to calculate and set this a bounding box automatically. 00204 */ 00205 PLS_API void CalculateAABoundingBox(); 00206 00207 /** 00208 * @brief 00209 * Calculates a transform matrix to bring a transformation from 'this scene container' into 'another scene container' 00210 * 00211 * @param[in] cContainer 00212 * 'Target' scene container 00213 * @param[out] mTransform 00214 * Receives the transform matrix, may contain an invalid matrix on error 00215 * 00216 * @return 00217 * 'true' if all went fine, else 'false' 00218 */ 00219 PLS_API bool GetTransformMatrixTo(SceneContainer &cContainer, PLMath::Matrix3x4 &mTransform); 00220 00221 //[-------------------------------------------------------] 00222 //[ Hierarchy functions ] 00223 //[-------------------------------------------------------] 00224 /** 00225 * @brief 00226 * Creates the scene hierarchy of this scene container 00227 * 00228 * @param[in] sClass 00229 * Class name of the scene hierarchy to create, if empty this function will do nothing 00230 * 00231 * @return 00232 * Pointer to the created scene hierarchy of this scene container. This is NEVER 00233 * a null pointer - if no special hierarchy is used the default hierarchy 'PLScene::SHList' 00234 * is used instead which is in fact only a simple list which is using the container directly. 00235 * 00236 * @note 00237 * - This hierarchy is destroyed by this scene container automatically 00238 * - All current container scene nodes are added to the hierarchy automatically 00239 * and the hierarchy is created 00240 */ 00241 PLS_API SceneHierarchy *CreateHierarchy(const PLCore::String &sClass = "PLScene::SHList"); 00242 00243 /** 00244 * @brief 00245 * Returns the scene hierarchy of this scene container 00246 * 00247 * @return 00248 * Pointer to the scene hierarchy of this scene container, 00249 * can NEVER be a null pointer! 00250 * 00251 * @remarks 00252 * Before the hierarchy is returned, scene nodes are refreshed if required. So, do NOT 00253 * backup the returned pointer, call this function if you need a pointer to the hierarchy! 00254 */ 00255 PLS_API SceneHierarchy *GetHierarchyInstance(); 00256 00257 //[-------------------------------------------------------] 00258 //[ Query functions ] 00259 //[-------------------------------------------------------] 00260 /** 00261 * @brief 00262 * Creates a scene query 00263 * 00264 * @param[in] sClass 00265 * Class name of the scene query to create 00266 * 00267 * @remarks 00268 * Have a look at SceneQuery for scene query remarks. If your created 00269 * query is no longer required you can destroy it using the DestroyQuery() 00270 * functions. But note that if you need a query frequently it's not a good 00271 * idea to create & destroy it every time you perform this query. For instance 00272 * queries for rendering the scene will store different current rendering information, 00273 * in this case it would be terrible to create & destroy the query every frame! 00274 * Maybe the rendering algorithm doesn't work correctly if this is done because 00275 * sometimes they will need information from the previous frame! 00276 * Such queries should be created once and then be used all the time. Use 00277 * SceneQueryHandler to hold your pointer to the query. If the container is destroyed 00278 * your pointer is set to a null pointer automatically. 00279 * If for instance the scene hierarchy was changed some queries like render queries have 00280 * to update some internal data. The internal scene query manager of the scene container 00281 * will inform it's queries in such a case. 00282 * The created scene query can ONLY operate on this scene container and it's child scene nodes/ 00283 * containers. Therefore you can limit your queries to for instance to a single room instead 00284 * using the hold scene. Use the scene root (GetRootContainer()) to access the complete scene. 00285 * 00286 * @return 00287 * Pointer to the created scene query operating on this scene container, 00288 * a null pointer on error (maybe unknown class or the class is not derived from 00289 * 'SceneQuery') 00290 */ 00291 PLS_API SceneQuery *CreateQuery(const PLCore::String &sClass); 00292 00293 /** 00294 * @brief 00295 * Destroys a scene query 00296 * 00297 * @param[in] cQuery 00298 * Scene query to destroy 00299 * 00300 * @return 00301 * 'true' if all went fine, else 'false' (invalid query :) 00302 */ 00303 PLS_API bool DestroyQuery(SceneQuery &cQuery); 00304 00305 00306 //[-------------------------------------------------------] 00307 //[ Private functions ] 00308 //[-------------------------------------------------------] 00309 private: 00310 /** 00311 * @brief 00312 * Adds a node 00313 * 00314 * @param[in] cNode 00315 * Reference to the node that should be added 00316 * @param[in] sName 00317 * Node name 00318 * @param[in] bInitNode 00319 * Should the node be initialized? 00320 * @param[in] nPosition 00321 * Optional index position specifying the location within the child list where the scene node should be added, <0 for at the end 00322 * 00323 * @return 00324 * 'true' if all went fine, else 'false' 00325 * 00326 * @note 00327 * - If the node name is already used another unused node name will be used instead! 00328 * - Use this function only in special cases! 00329 */ 00330 bool Add(SceneNode &cNode, const PLCore::String &sName = "", bool bInitNode = true, int nPosition = -1); 00331 00332 /** 00333 * @brief 00334 * Removes a node 00335 * 00336 * @param[in] cNode 00337 * Reference to the node that should be removed 00338 * @param[in] bDeInitNode 00339 * Should the node be de-initialized? 00340 * 00341 * @return 00342 * 'true' if all went fine, else 'false' 00343 * 00344 * @note 00345 * - The node object itself is still there after it is de-initialized 00346 * and removed from the manager! 00347 * - Use this function only in special cases! 00348 */ 00349 bool Remove(SceneNode &cNode, bool bDeInitNode = true); 00350 00351 00352 //[-------------------------------------------------------] 00353 //[ Private data ] 00354 //[-------------------------------------------------------] 00355 private: 00356 // Private data 00357 PLCore::String m_sHierarchy; /**< Class name of the scene container hierarchy */ 00358 SceneContext *m_pSceneContext; /**< The scene context this scene container is in (should be always valid!) */ 00359 SceneHierarchy *m_pHierarchy; /**< Scene hierarchy, can be a null pointer */ 00360 SceneQueryManager *m_pQueryManager; /**< Scene query manager, can be a null pointer */ 00361 00362 /** List of scene nodes which need a scene hierarchy refresh */ 00363 PLCore::Pool<SceneNode*> m_lstHierarchyRefresh; 00364 00365 00366 //[-------------------------------------------------------] 00367 //[ Protected virtual SceneNode functions ] 00368 //[-------------------------------------------------------] 00369 protected: 00370 PLS_API virtual void InitFunction() override; 00371 PLS_API virtual void DeInitFunction() override; 00372 PLS_API virtual void OnActivate(bool bActivate) override; 00373 00374 00375 //[-------------------------------------------------------] 00376 //[ Public virtual PLCore::ElementManager functions ] 00377 //[-------------------------------------------------------] 00378 public: 00379 PLS_API virtual bool DeInit() override; 00380 PLS_API virtual SceneNode *GetByIndex(PLCore::uint32 nIndex = 0) const override; 00381 PLS_API virtual SceneNode *GetByName(const PLCore::String &sName) const override; 00382 00383 00384 //[-------------------------------------------------------] 00385 //[ Public virtual PLCore::Loadable functions ] 00386 //[-------------------------------------------------------] 00387 public: 00388 PLS_API virtual bool LoadByFilename(const PLCore::String &sFilename, const PLCore::String &sParams = "", const PLCore::String &sMethod = "") override; 00389 PLS_API virtual bool LoadByFile(PLCore::File &cFile, const PLCore::String &sParams = "", const PLCore::String &sMethod = "") override; 00390 PLS_API virtual bool Unload() override; 00391 PLS_API virtual PLCore::String GetLoadableTypeName() const override; 00392 00393 00394 //[-------------------------------------------------------] 00395 //[ Protected virtual PLCore::Loadable functions ] 00396 //[-------------------------------------------------------] 00397 protected: 00398 PLS_API virtual bool CallLoadable(PLCore::File &cFile, PLCore::Loader &cLoader, const PLCore::String &sMethod, const PLCore::String &sParams) override; 00399 00400 00401 //[-------------------------------------------------------] 00402 //[ Private virtual PLCore::ElementManager functions ] 00403 //[-------------------------------------------------------] 00404 private: 00405 PLS_API virtual SceneNode *CreateElement(const PLCore::String &sName) override; 00406 00407 00408 }; 00409 00410 00411 //[-------------------------------------------------------] 00412 //[ Namespace ] 00413 //[-------------------------------------------------------] 00414 } // PLScene 00415 00416 00417 //[-------------------------------------------------------] 00418 //[ Implementation ] 00419 //[-------------------------------------------------------] 00420 #include "PLScene/Scene/SceneContainer.inl" 00421 00422 00423 #endif // __PLSCENE_SCENECONTAINER_H__
|