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: 28677 $ 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 計算に用いるアライメントです。2 のべき乗である必要があります。 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 計算に用いるアライメントです。2 のべき乗である必要があります。 139 //! @return 必要なデバイスメモリサイズです。 140 static size_t GetDeviceMemorySize( 141 ResParticleModel resource, 142 const ParticleModel::Description& modelDescription, 143 size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 144 { 145 os::MemorySizeCalculator size(alignment); 146 147 GetDeviceMemorySizeInternal(&size, resource, modelDescription); 148 149 return size.GetSizeWithPadding(alignment); 150 } 151 152 //! @details :private 153 static void GetDeviceMemorySizeInternal( 154 os::MemorySizeCalculator* pSize, 155 ResParticleModel resource, 156 const ParticleModel::Description& modelDescription); 157 158 //@} 159 160 //---------------------------------------- 161 //! @name 更新 162 //@{ 163 164 //! @brief ビジターを受け付けます。 165 //! 166 //! @param[in] visitor ビジターです。 167 //! 168 virtual void Accept(ISceneVisitor* visitor); 169 170 //! フレームを更新します。 UpdateParticleFrame()171 void UpdateParticleFrame() 172 { 173 m_ParticleAnimFrameController.UpdateFrame(); 174 } 175 176 //! @brief ParticleModel 内の全ての ParticleSet を巡回して TFunction を適用します。 177 //! 178 //! @tparam TFunction ParticleSet へのポインタを引数に取る関数(オブジェクト)の型です。 179 //! @param[in] function 適応する関数(オブジェクト)です。 180 //! 181 template<typename TFunction> ForeachParticleSet(TFunction function)182 void ForeachParticleSet(TFunction function) 183 { 184 for (int i = 0; i < (int)this->GetParticleSetsCount(); ++i) 185 { 186 ParticleSet* particleSet = this->GetParticleSets(i); 187 188 function(particleSet); 189 } 190 } 191 192 //! @brief ParticleModel 内の全ての ParticleSet を巡回して TFunction を適用します。 193 //! 194 //! @tparam TFunction ParticleSet へのポインタを引数に取る関数(オブジェクト)の型です。 195 //! @param[in] function 適応する関数(オブジェクト)です。 196 //! 197 template<typename TFunction> ForeachConstParticleSet(TFunction function)198 void ForeachConstParticleSet(TFunction function) const 199 { 200 for (int i = 0; i < (int)this->GetParticleSetsCount(); ++i) 201 { 202 const ParticleSet* particleSet = this->GetParticleSets(i); 203 204 function(particleSet); 205 } 206 } 207 208 //@} 209 210 //---------------------------------------- 211 //! @name 取得/設定 212 //@{ 213 214 //! @brief リソースを取得します。 215 //! @return パーティクルモデルのリソースを返します。 GetResModel()216 ResParticleModel GetResModel() 217 { 218 return ResDynamicCast<ResParticleModel>(this->GetResSceneObject()); 219 } 220 221 //! @brief リソースを取得します。 222 //! @return パーティクルモデルのリソースを返します。 GetResModel()223 const ResParticleModel GetResModel() const 224 { 225 return ResDynamicCast<ResParticleModel>(this->GetResSceneObject()); 226 } 227 228 //! @brief ParticleSetを追加します。 229 //! 230 //! @param node 追加するパーティクルセットです。 231 //! @return 追加できた場合trueを返します。 AttachParticleSet(ParticleSet * node)232 bool AttachParticleSet(ParticleSet* node) 233 { 234 if (m_ParticleSetCount >= this->m_ParticleSets.size()) return false; 235 236 this->m_ParticleSets[m_ParticleSetCount] = node; 237 ++m_ParticleSetCount; 238 return true; 239 } 240 241 //! @brief パーティクルセットの数を取得します。 242 //! @return パーティクルセットの数を返します。 GetParticleSetsCount()243 u32 GetParticleSetsCount() const 244 { 245 return m_ParticleSetCount; 246 } 247 248 //! @brief パーティクルセットを取得します。 249 //! 250 //! @param[in] index インデックスです。 251 //! @return パーティクルセットを返します。 GetParticleSets(int index)252 ParticleSet* GetParticleSets(int index) 253 { 254 NW_ASSERT(index >= 0 && index < m_ParticleSetCount); 255 return this->m_ParticleSets[index]; 256 } 257 258 //! @brief パーティクルセットを取得します。 259 //! 260 //! @param[in] index インデックスです。 261 //! @return パーティクルセットを返します。 GetParticleSets(int index)262 const ParticleSet* GetParticleSets(int index) const 263 { 264 NW_ASSERT(index >= 0 && index < m_ParticleSetCount); 265 return this->m_ParticleSets[index]; 266 } 267 268 //! @brief ParticleShapeを追加します。 269 //! @param[in] node 追加するParticleShapeです。 270 //! @return 追加できた場合trueを返します。 AttachParticleShape(ParticleShape * node)271 bool AttachParticleShape(ParticleShape* node) 272 { 273 if (m_ParticleShapeCount >= this->m_ParticleShapes.size()) return false; 274 275 this->m_ParticleShapes[m_ParticleSetCount] = node; 276 ++m_ParticleShapeCount; 277 return true; 278 } 279 280 //! @brief パーティクルシェイプの数を取得します。 281 //! @return パーティクルシェイプの数を返します。 GetParticleShapesCount()282 u32 GetParticleShapesCount() const 283 { 284 return m_ParticleShapeCount; 285 } 286 287 //! @brief ParticleShapeを取得します。 288 //! 289 //! @param[in] index インデックスです。 290 //! @return ParticleShapeを返します。 GetParticleShapes(int index)291 ParticleShape* GetParticleShapes(int index) 292 { 293 NW_ASSERT(index >= 0 && index < m_ParticleShapeCount); 294 return this->m_ParticleShapes[index]; 295 } 296 297 //! @brief ParticleShapeを取得します。 298 //! 299 //! @param[in] index インデックスです。 300 //! @return ParticleShapeを返します。 GetParticleShapes(int index)301 const ParticleShape* GetParticleShapes(int index) const 302 { 303 NW_ASSERT(index >= 0 && index < m_ParticleShapeCount); 304 return this->m_ParticleShapes[index]; 305 } 306 307 //! @brief アニメーションフレーム制御情報を取得します。 308 //! @return アニメーションフレームコントローラを返します。 ParticleAnimFrameController()309 anim::AnimFrameController& ParticleAnimFrameController() 310 { 311 return m_ParticleAnimFrameController; 312 } 313 314 //! @brief アニメーションフレーム制御情報を取得します。 315 //! @return アニメーションフレームコントローラを返します。 ParticleAnimFrameController()316 const anim::AnimFrameController& ParticleAnimFrameController() const 317 { 318 return m_ParticleAnimFrameController; 319 } 320 321 //! @brief パーティクルの存在を取得します。 322 //! @return パーティクル粒子が存在すればtrueを返します。 HasParticle()323 bool HasParticle() const 324 { 325 bool result; 326 ParticleSetsAreEmpty function(&result); 327 this->ForeachConstParticleSet(function); 328 return !result; 329 } 330 331 //@} 332 333 protected: 334 virtual Result Initialize(os::IAllocator* allocator); 335 336 //! @details :private 337 static void GetMemorySizeForInitialize( 338 os::MemorySizeCalculator* pSize, 339 ResParticleModel resource, 340 const ParticleModel::Description& modelDescription); 341 342 //---------------------------------------- 343 //! @name コンストラクタ/デストラクタ 344 //@{ 345 346 //! @brief コンストラクタです。 ParticleModel(os::IAllocator * allocator,ResTransformNode resource,const ParticleModel::Description & description)347 ParticleModel( 348 os::IAllocator* allocator, 349 ResTransformNode resource, 350 const ParticleModel::Description& description) 351 : Model( 352 allocator, 353 resource, 354 description), 355 m_MaximumParticleSet(description.particleSetCount), 356 m_ParticleSetCount(0), 357 m_ParticleShapeCount(0), 358 m_ParticleAnimFrameController(0, 16777215, anim::PlayPolicy_Loop) 359 {} 360 361 //! @brief デストラクタです。 ~ParticleModel()362 virtual ~ParticleModel() 363 { 364 for (int i = 0; i < m_ParticleShapes.size(); ++i) // TBD 365 { 366 SafeDestroy(m_ParticleShapes[i]); 367 368 // m_ParticleSetはAttachChild()されているので、 369 // SceneNodeにより自動的に解放されます。 370 } 371 } 372 373 //@} 374 375 private: 376 uint m_MaximumParticleSet; 377 378 int m_ParticleSetCount; 379 ut::MoveArray<ParticleSet*> m_ParticleSets; 380 381 int m_ParticleShapeCount; 382 ut::MoveArray<ParticleShape*> m_ParticleShapes; 383 384 anim::AnimFrameController m_ParticleAnimFrameController; 385 }; 386 387 388 } // namespace gfx 389 } // namespace nw 390 391 #endif // NW_GFX_PARTICLEMODEL_H_ 392