1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: gfx_ParticleModel.h 4 5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Revision: 25986 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NW_GFX_PARTICLEMODEL_H_ 17 #define NW_GFX_PARTICLEMODEL_H_ 18 19 #include <nw/gfx/gfx_Model.h> 20 #include <nw/gfx/res/gfx_ResParticleModel.h> 21 #include <nw/gfx/gfx_ParticleShape.h> 22 #include <nw/anim/anim_AnimFrameController.h> 23 #include <nw/ut/ut_MoveArray.h> 24 25 26 namespace nw 27 { 28 namespace gfx 29 { 30 31 class ParticleSet; 32 33 //--------------------------------------------------------------------------- 34 //! @brief ParticleSetが空か調べる関数オブジェクトです。 35 //--------------------------------------------------------------------------- 36 class ParticleSetsAreEmpty 37 { 38 public: 39 //! @brief コンストラクタです 40 //! @param[in] result 結果を返すポインタです。 ParticleSetsAreEmpty(bool * result)41 ParticleSetsAreEmpty(bool* result) 42 { 43 NW_NULL_ASSERT(result); 44 m_Result = result; 45 *m_Result = true; 46 } 47 48 //! @brief ParticleSetが空か調べるオペレータです 49 //! @param[in] particleSet 調べるParticleSetです。 50 void operator()(const ParticleSet* particleSet); 51 52 private: 53 bool* m_Result; 54 }; 55 56 //--------------------------------------------------------------------------- 57 //! @brief ParticleSetを空にする関数オブジェクトです。 58 //--------------------------------------------------------------------------- 59 class ParticleSetsClear 60 { 61 public: 62 //! @brief コンストラクタです ParticleSetsClear()63 ParticleSetsClear() {} 64 65 //! @brief ParticleSetを空にするオペレータです 66 //! @param[in] particleSet 空にするParticleSetです。 67 void operator()(ParticleSet* particleSet); 68 }; 69 70 //--------------------------------------------------------------------------- 71 //! @brief パーティクル用のモデルのクラスです。 72 //--------------------------------------------------------------------------- 73 class ParticleModel : public Model 74 { 75 private: 76 NW_DISALLOW_COPY_AND_ASSIGN(ParticleModel); 77 78 public: 79 NW_UT_RUNTIME_TYPEINFO; 80 81 //! @brief 設定内容です。 82 struct Description : public Model::Description 83 { 84 //! @brief コンストラクタです。 DescriptionDescription85 Description() : 86 particleSetCount(0) 87 {} 88 89 uint particleSetCount; 90 }; 91 92 //---------------------------------------- 93 //! @name 作成/破棄 94 //@{ 95 96 //! @brief モデルを生成します。 97 //! 98 //! @param[in] parent 親のノードです。 99 //! @param[in] resource リソースです。 100 //! @param[in] modelDescription 設定内容です。 101 //! @param[in] mainAllocator メインメモリのアロケータです。 102 //! @param[in] deviceAllocator デバイスメモリのアロケータです。 103 //! 104 //! @return 生成されたモデルです。 105 //! 106 static ParticleModel* Create( 107 SceneNode* parent, 108 ResSceneObject resource, 109 const ParticleModel::Description& modelDescription, 110 os::IAllocator* mainAllocator, 111 os::IAllocator* deviceAllocator); 112 113 //! @brief 生成時に必要なメモリサイズを取得します。 114 //! @param[in] resource リソースです。 115 //! @param[in] description 設定内容です。 116 //! @param[in] alignment アロケータのメモリアライメントです。 117 //! @return 必要なメモリサイズです。 118 static size_t GetMemorySize( 119 ResParticleModel resource, 120 const ParticleModel::Description& modelDescription, 121 size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 122 { 123 os::MemorySizeCalculator size(alignment); 124 125 GetMemorySizeInternal(&size, resource, modelDescription); 126 127 return size.GetSizeWithPadding(alignment); 128 } 129 130 //! @details :private 131 static void GetMemorySizeInternal( 132 os::MemorySizeCalculator* pSize, 133 ResParticleModel resource, 134 const ParticleModel::Description& modelDescription); 135 136 //! @brief 生成時に必要なデバイスメモリサイズを取得します。 137 //! @param[in] resource リソースです。 138 //! @param[in] alignment アロケータのメモリアライメントです。 139 //! @return 必要なデバイスメモリサイズです。 140 static size_t GetDeviceMemorySize( 141 ResParticleModel resource, 142 size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 143 { 144 os::MemorySizeCalculator size(alignment); 145 146 GetDeviceMemorySizeInternal(&size, resource); 147 148 return size.GetSizeWithPadding(alignment); 149 } 150 151 //! @details :private 152 static void GetDeviceMemorySizeInternal( 153 os::MemorySizeCalculator* pSize, 154 ResParticleModel resource); 155 156 //@} 157 158 //---------------------------------------- 159 //! @name 更新 160 //@{ 161 162 //! @brief ビジターを受け付けます。 163 //! 164 //! @param[in] visitor ビジターです。 165 //! 166 virtual void Accept(ISceneVisitor* visitor); 167 168 //! フレームを更新します。 UpdateParticleFrame()169 void UpdateParticleFrame() 170 { 171 m_ParticleAnimFrameController.UpdateFrame(); 172 } 173 174 //! @brief ParticleModel 内の全ての ParticleSet を巡回して TFunction を適用します。 175 //! 176 //! @tparam TFunction ParticleSet へのポインタを引数に取る関数(オブジェクト)の型です。 177 //! @param[in] function 適応する関数(オブジェクト)です。 178 //! 179 template<typename TFunction> ForeachParticleSet(TFunction function)180 void ForeachParticleSet(TFunction function) 181 { 182 for (int i = 0; i < (int)this->GetParticleSetsCount(); ++i) 183 { 184 ParticleSet* particleSet = this->GetParticleSets(i); 185 186 function(particleSet); 187 } 188 } 189 190 //! @brief ParticleModel 内の全ての ParticleSet を巡回して TFunction を適用します。 191 //! 192 //! @tparam TFunction ParticleSet へのポインタを引数に取る関数(オブジェクト)の型です。 193 //! @param[in] function 適応する関数(オブジェクト)です。 194 //! 195 template<typename TFunction> ForeachConstParticleSet(TFunction function)196 void ForeachConstParticleSet(TFunction function) const 197 { 198 for (int i = 0; i < (int)this->GetParticleSetsCount(); ++i) 199 { 200 const ParticleSet* particleSet = this->GetParticleSets(i); 201 202 function(particleSet); 203 } 204 } 205 206 //@} 207 208 //---------------------------------------- 209 //! @name 取得/設定 210 //@{ 211 212 //! @brief リソースを取得します。 213 //! @return パーティクルモデルのリソースを返します。 GetResModel()214 ResParticleModel GetResModel() 215 { 216 return ResDynamicCast<ResParticleModel>(this->GetResSceneObject()); 217 } 218 219 //! @brief リソースを取得します。 220 //! @return パーティクルモデルのリソースを返します。 GetResModel()221 const ResParticleModel GetResModel() const 222 { 223 return ResDynamicCast<ResParticleModel>(this->GetResSceneObject()); 224 } 225 226 //! @brief ParticleSetを追加します。 227 //! 228 //! @param node 追加するパーティクルセットです。 229 //! @return 追加できた場合trueを返します。 AttachParticleSet(ParticleSet * node)230 bool AttachParticleSet(ParticleSet* node) 231 { 232 if (m_ParticleSetCount >= this->m_ParticleSets.size()) return false; 233 234 this->m_ParticleSets[m_ParticleSetCount] = node; 235 ++m_ParticleSetCount; 236 return true; 237 } 238 239 //! @brief パーティクルセットの数を取得します。 240 //! @return パーティクルセットの数を返します。 GetParticleSetsCount()241 u32 GetParticleSetsCount() const 242 { 243 return m_ParticleSetCount; 244 } 245 246 //! @brief パーティクルセットを取得します。 247 //! 248 //! @param[in] index インデックスです。 249 //! @return パーティクルセットを返します。 GetParticleSets(int index)250 ParticleSet* GetParticleSets(int index) 251 { 252 NW_ASSERT(index >= 0 && index < m_ParticleSetCount); 253 return this->m_ParticleSets[index]; 254 } 255 256 //! @brief パーティクルセットを取得します。 257 //! 258 //! @param[in] index インデックスです。 259 //! @return パーティクルセットを返します。 GetParticleSets(int index)260 const ParticleSet* GetParticleSets(int index) const 261 { 262 NW_ASSERT(index >= 0 && index < m_ParticleSetCount); 263 return this->m_ParticleSets[index]; 264 } 265 266 //! @brief ParticleShapeを追加します。 267 //! @param[in] node 追加するParticleShapeです。 268 //! @return 追加できた場合trueを返します。 AttachParticleShape(ParticleShape * node)269 bool AttachParticleShape(ParticleShape* node) 270 { 271 if (m_ParticleShapeCount >= this->m_ParticleShapes.size()) return false; 272 273 this->m_ParticleShapes[m_ParticleSetCount] = node; 274 ++m_ParticleShapeCount; 275 return true; 276 } 277 278 //! @brief パーティクルシェイプの数を取得します。 279 //! @return パーティクルシェイプの数を返します。 GetParticleShapesCount()280 u32 GetParticleShapesCount() const 281 { 282 return m_ParticleShapeCount; 283 } 284 285 //! @brief ParticleShapeを取得します。 286 //! 287 //! @param[in] index インデックスです。 288 //! @return ParticleShapeを返します。 GetParticleShapes(int index)289 ParticleShape* GetParticleShapes(int index) 290 { 291 NW_ASSERT(index >= 0 && index < m_ParticleShapeCount); 292 return this->m_ParticleShapes[index]; 293 } 294 295 //! @brief ParticleShapeを取得します。 296 //! 297 //! @param[in] index インデックスです。 298 //! @return ParticleShapeを返します。 GetParticleShapes(int index)299 const ParticleShape* GetParticleShapes(int index) const 300 { 301 NW_ASSERT(index >= 0 && index < m_ParticleShapeCount); 302 return this->m_ParticleShapes[index]; 303 } 304 305 //! @brief アニメーションフレーム制御情報を取得します。 306 //! @return アニメーションフレームコントローラを返します。 ParticleAnimFrameController()307 anim::AnimFrameController& ParticleAnimFrameController() 308 { 309 return m_ParticleAnimFrameController; 310 } 311 312 //! @brief アニメーションフレーム制御情報を取得します。 313 //! @return アニメーションフレームコントローラを返します。 ParticleAnimFrameController()314 const anim::AnimFrameController& ParticleAnimFrameController() const 315 { 316 return m_ParticleAnimFrameController; 317 } 318 319 //! @brief パーティクルの存在を取得します。 320 //! @return パーティクル粒子が存在すればtrueを返します。 HasParticle()321 bool HasParticle() const 322 { 323 bool result; 324 ParticleSetsAreEmpty function(&result); 325 this->ForeachConstParticleSet(function); 326 return !result; 327 } 328 329 //@} 330 331 protected: 332 virtual Result Initialize(os::IAllocator* allocator); 333 334 //! @details :private 335 static void GetMemorySizeForInitialize( 336 os::MemorySizeCalculator* pSize, 337 ResParticleModel resource, 338 const ParticleModel::Description& modelDescription); 339 340 //---------------------------------------- 341 //! @name コンストラクタ/デストラクタ 342 //@{ 343 344 //! @brief コンストラクタです。 ParticleModel(os::IAllocator * allocator,ResTransformNode resource,const ParticleModel::Description & description)345 ParticleModel( 346 os::IAllocator* allocator, 347 ResTransformNode resource, 348 const ParticleModel::Description& description) 349 : Model( 350 allocator, 351 resource, 352 description), 353 m_MaximumParticleSet(description.particleSetCount), 354 m_ParticleSetCount(0), 355 m_ParticleShapeCount(0), 356 m_ParticleAnimFrameController(0, 16777215, anim::PlayPolicy_Loop) 357 {} 358 359 //! @brief デストラクタです。 ~ParticleModel()360 virtual ~ParticleModel() 361 { 362 for (int i = 0; i < m_ParticleShapes.size(); ++i) // TBD 363 { 364 SafeDestroy(m_ParticleShapes[i]); 365 366 // m_ParticleSetはAttachChild()されているので、 367 // SceneNodeにより自動的に解放されます。 368 } 369 } 370 371 //@} 372 373 private: 374 uint m_MaximumParticleSet; 375 376 int m_ParticleSetCount; 377 ut::MoveArray<ParticleSet*> m_ParticleSets; 378 379 int m_ParticleShapeCount; 380 ut::MoveArray<ParticleShape*> m_ParticleShapes; 381 382 anim::AnimFrameController m_ParticleAnimFrameController; 383 }; 384 385 386 } // namespace gfx 387 } // namespace nw 388 389 #endif // NW_GFX_PARTICLEMODEL_H_ 390