PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: SceneContainer.h * 00003 * 00004 * Copyright (C) 2002-2011 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", "") 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 SceneNode).", "") 00121 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.", "") 00122 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'.", "") 00123 #endif 00124 // Signals 00125 pl_signal_1(SignalLoadProgress, float, "Scene load progress signal. Current load progress as parameter - if not within 0-1 loading is done.", "") 00126 pl_class_end 00127 00128 00129 //[-------------------------------------------------------] 00130 //[ Public RTTI get/set functions ] 00131 //[-------------------------------------------------------] 00132 public: 00133 PLS_API PLCore::String GetHierarchy() const; 00134 PLS_API void SetHierarchy(const PLCore::String &sValue); 00135 PLS_API void SetFilename(const PLCore::String &sValue); 00136 00137 00138 //[-------------------------------------------------------] 00139 //[ Public functions ] 00140 //[-------------------------------------------------------] 00141 public: 00142 /** 00143 * @brief 00144 * Default constructor 00145 */ 00146 PLS_API SceneContainer(); 00147 00148 /** 00149 * @brief 00150 * Destructor 00151 */ 00152 PLS_API virtual ~SceneContainer(); 00153 00154 /** 00155 * @brief 00156 * Creates a new scene node 00157 * 00158 * @param[in] sClass 00159 * Name of the scene node class to create an instance from 00160 * @param[in] sName 00161 * Scene node name 00162 * @param[in] sParameters 00163 * Optional parameter string 00164 * 00165 * @return 00166 * Pointer to the new scene node or a null pointer if something went wrong 00167 * (maybe unknown class or the class is not derived from SceneNode) 00168 * 00169 * @note 00170 * - If the desired name is already in use, the name is chosen automatically 00171 */ 00172 PLS_API SceneNode *Create(const PLCore::String &sClass, const PLCore::String &sName = "", const PLCore::String &sParameters = ""); 00173 00174 /** 00175 * @brief 00176 * Calculates and sets the axis align bounding box in 'scene node space' 00177 * 00178 * @remarks 00179 * Because the 'scene node space' axis aligned bounding box should always cover all scene nodes of 00180 * this container, you can use this function to calculate and set this a bounding box automatically. 00181 */ 00182 PLS_API void CalculateAABoundingBox(); 00183 00184 /** 00185 * @brief 00186 * Calculates a transform matrix to bring a transformation from 'this scene container' into 'another scene container' 00187 * 00188 * @param[in] cContainer 00189 * 'Target' scene container 00190 * @param[out] mTransform 00191 * Receives the transform matrix, may contain an invalid matrix on error 00192 * 00193 * @return 00194 * 'true' if all went fine, else 'false' 00195 */ 00196 PLS_API bool GetTransformMatrixTo(SceneContainer &cContainer, PLMath::Matrix3x4 &mTransform); 00197 00198 //[-------------------------------------------------------] 00199 //[ Hierarchy functions ] 00200 //[-------------------------------------------------------] 00201 /** 00202 * @brief 00203 * Creates the scene hierarchy of this scene container 00204 * 00205 * @param[in] sClass 00206 * Class name of the scene hierarchy to create, if empty this function will do nothing 00207 * 00208 * @return 00209 * Pointer to the created scene hierarchy of this scene container. This is NEVER 00210 * a null pointer - if no special hierarchy is used the default hierarchy 'PLScene::SHList' 00211 * is used instead which is in fact only a simple list which is using the container directly. 00212 * 00213 * @note 00214 * - This hierarchy is destroyed by this scene container automatically 00215 * - All current container scene nodes are added to the hierarchy automatically 00216 * and the hierarchy is created 00217 */ 00218 PLS_API SceneHierarchy *CreateHierarchy(const PLCore::String &sClass = "PLScene::SHList"); 00219 00220 /** 00221 * @brief 00222 * Returns the scene hierarchy of this scene container 00223 * 00224 * @return 00225 * Pointer to the scene hierarchy of this scene container, 00226 * can NEVER be a null pointer! 00227 * 00228 * @remarks 00229 * Before the hierarchy is returned, scene nodes are refreshed if required. So, do NOT 00230 * backup the returned pointer, call this function if you need a pointer to the hierarchy! 00231 */ 00232 PLS_API SceneHierarchy *GetHierarchyInstance(); 00233 00234 //[-------------------------------------------------------] 00235 //[ Query functions ] 00236 //[-------------------------------------------------------] 00237 /** 00238 * @brief 00239 * Creates a scene query 00240 * 00241 * @param[in] sClass 00242 * Class name of the scene query to create 00243 * 00244 * @remarks 00245 * Have a look at SceneQuery for scene query remarks. If your created 00246 * query is no longer required you can destroy it using the DestroyQuery() 00247 * functions. But note that if you need a query frequently it's not a good 00248 * idea to create & destroy it every time you perform this query. For instance 00249 * queries for rendering the scene will store different current rendering information, 00250 * in this case it would be terrible to create & destroy the query every frame! 00251 * Maybe the rendering algorithm doesn't work correctly if this is done because 00252 * sometimes they will need information from the previous frame! 00253 * Such queries should be created once and then be used all the time. Use 00254 * SceneQueryHandler to hold your pointer to the query. If the container is destroyed 00255 * your pointer is set to a null pointer automatically. 00256 * If for instance the scene hierarchy was changed some queries like render queries have 00257 * to update some internal data. The internal scene query manager of the scene container 00258 * will inform it's queries in such a case. 00259 * The created scene query can ONLY operate on this scene container and it's child scene nodes/ 00260 * containers. Therefore you can limit your queries to for instance to a single room instead 00261 * using the hold scene. Use the scene root (GetRootContainer()) to access the complete scene. 00262 * 00263 * @return 00264 * Pointer to the created scene query operating on this scene container, 00265 * a null pointer on error (maybe unknown class or the class is not derived from 00266 * 'SceneQuery') 00267 */ 00268 PLS_API SceneQuery *CreateQuery(const PLCore::String &sClass); 00269 00270 /** 00271 * @brief 00272 * Destroys a scene query 00273 * 00274 * @param[in] cQuery 00275 * Scene query to destroy 00276 * 00277 * @return 00278 * 'true' if all went fine, else 'false' (invalid query :) 00279 */ 00280 PLS_API bool DestroyQuery(SceneQuery &cQuery); 00281 00282 00283 //[-------------------------------------------------------] 00284 //[ Private functions ] 00285 //[-------------------------------------------------------] 00286 private: 00287 /** 00288 * @brief 00289 * Adds a node 00290 * 00291 * @param[in] cNode 00292 * Reference to the node that should be added 00293 * @param[in] sName 00294 * Node name 00295 * @param[in] bInitNode 00296 * Should the node be initialized? 00297 * 00298 * @return 00299 * 'true' if all went fine, else 'false' 00300 * 00301 * @note 00302 * - If the node name is already used another unused node name will be used instead! 00303 * - Use this function only in special cases! 00304 */ 00305 bool Add(SceneNode &cNode, const PLCore::String &sName = "", bool bInitNode = true); 00306 00307 /** 00308 * @brief 00309 * Removes a node 00310 * 00311 * @param[in] cNode 00312 * Reference to the node that should be removed 00313 * @param[in] bDeInitNode 00314 * Should the node be de-initialized? 00315 * 00316 * @return 00317 * 'true' if all went fine, else 'false' 00318 * 00319 * @note 00320 * - The node object itself is still there after it is de-initialized 00321 * and removed from the manager! 00322 * - Use this function only in special cases! 00323 */ 00324 bool Remove(SceneNode &cNode, bool bDeInitNode = true); 00325 00326 00327 //[-------------------------------------------------------] 00328 //[ Private data ] 00329 //[-------------------------------------------------------] 00330 private: 00331 // Private data 00332 PLCore::String m_sHierarchy; /**< Class name of the scene container hierarchy */ 00333 SceneContext *m_pSceneContext; /**< The scene context this scene container is in (should be always valid!) */ 00334 SceneHierarchy *m_pHierarchy; /**< Scene hierarchy, can be a null pointer */ 00335 SceneQueryManager *m_pQueryManager; /**< Scene query manager, can be a null pointer */ 00336 00337 /** List of scene nodes which need a scene hierarchy refresh */ 00338 PLCore::Pool<SceneNode*> m_lstHierarchyRefresh; 00339 00340 00341 //[-------------------------------------------------------] 00342 //[ Protected virtual SceneNode functions ] 00343 //[-------------------------------------------------------] 00344 protected: 00345 PLS_API virtual void InitFunction() override; 00346 PLS_API virtual void DeInitFunction() override; 00347 PLS_API virtual void OnActivate(bool bActivate) override; 00348 00349 00350 //[-------------------------------------------------------] 00351 //[ Public virtual PLCore::ElementManager functions ] 00352 //[-------------------------------------------------------] 00353 public: 00354 PLS_API virtual bool DeInit() override; 00355 PLS_API virtual SceneNode *GetByIndex(PLCore::uint32 nIndex = 0) const override; 00356 PLS_API virtual SceneNode *GetByName(const PLCore::String &sName) const override; 00357 00358 00359 //[-------------------------------------------------------] 00360 //[ Public virtual PLCore::Loadable functions ] 00361 //[-------------------------------------------------------] 00362 public: 00363 PLS_API virtual bool LoadByFilename(const PLCore::String &sFilename, const PLCore::String &sParams = "", const PLCore::String &sMethod = "") override; 00364 PLS_API virtual bool LoadByFile(PLCore::File &cFile, const PLCore::String &sParams = "", const PLCore::String &sMethod = "") override; 00365 PLS_API virtual bool Unload() override; 00366 PLS_API virtual PLCore::String GetLoadableTypeName() const override; 00367 00368 00369 //[-------------------------------------------------------] 00370 //[ Protected virtual PLCore::Loadable functions ] 00371 //[-------------------------------------------------------] 00372 protected: 00373 PLS_API virtual bool CallLoadable(PLCore::File &cFile, PLCore::Loader &cLoader, const PLCore::String &sMethod, const PLCore::String &sParams) override; 00374 00375 00376 //[-------------------------------------------------------] 00377 //[ Private virtual PLCore::ElementManager functions ] 00378 //[-------------------------------------------------------] 00379 private: 00380 PLS_API virtual SceneNode *CreateElement(const PLCore::String &sName) override; 00381 00382 00383 }; 00384 00385 00386 //[-------------------------------------------------------] 00387 //[ Namespace ] 00388 //[-------------------------------------------------------] 00389 } // PLScene 00390 00391 00392 #endif // __PLSCENE_SCENECONTAINER_H__
|