1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: demo_Particle.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: 28494 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NW_DEMO_PARTICLE_H_ 17 #define NW_DEMO_PARTICLE_H_ 18 19 #include <nw/gfx.h> 20 #include <nw/ut.h> 21 #include <nw/demo/demo_GraphicsSystem.h> 22 23 namespace nw 24 { 25 26 namespace demo 27 { 28 29 //! @brief パーティクル管理用のクラスです。 30 //! Transformノードに管理用の情報を付加しています。 31 class ParticleHandle : public gfx::TransformNode 32 { 33 private: 34 NW_DISALLOW_COPY_AND_ASSIGN(ParticleHandle); 35 36 public: 37 NW_UT_RUNTIME_TYPEINFO; 38 39 //---------------------------------------- 40 //! @name 作成/破棄 41 //@{ 42 43 //! @brief シーンノードを動的に構築するためのクラスです。 44 //! 45 //! IsFixedSizeMemory の初期値は true です。false に変更すると、各種最大数の設定は無視されます。 46 class DynamicBuilder 47 { 48 public: 49 //! コンストラクタです。 DynamicBuilder()50 DynamicBuilder() {} 51 //! デストラクタです。 ~DynamicBuilder()52 ~DynamicBuilder() {} 53 54 //! @brief 生成時以外にもメモリを確保するかどうかのフラグを設定します。 55 //! 56 //! true を指定すると、生成時のみ固定サイズのメモリ確保を行います。 57 //! 58 //! false を指定すると、生成時以外にも必要に応じて動的にメモリ確保が行われます。 IsFixedSizeMemory(bool isFixedSizeMemory)59 DynamicBuilder& IsFixedSizeMemory(bool isFixedSizeMemory) 60 { 61 m_Description.isFixedSizeMemory = isFixedSizeMemory; 62 return *this; 63 } 64 65 //! 子の最大数を設定します。 MaxChildren(int maxChildren)66 DynamicBuilder& MaxChildren(int maxChildren) 67 { 68 m_Description.maxChildren = maxChildren; 69 return *this; 70 } 71 72 //! 管理できるコールバックの最大数を設定します。 MaxCallbacks(int maxCallbacks)73 DynamicBuilder& MaxCallbacks(int maxCallbacks) 74 { 75 m_Description.maxCallbacks = maxCallbacks; 76 return *this; 77 } 78 79 //! @brief シーンノードを生成します。 80 //! 81 //! @param[in] allocator アロケータです。 82 //! 83 //! @return 生成したシーンノードを返します。 84 //! 85 ParticleHandle* Create(os::IAllocator* allocator); 86 87 private: 88 gfx::TransformNode::Description m_Description; 89 }; 90 91 //@} 92 93 //---------------------------------------- 94 //! @name パーティクル操作 95 //@{ 96 97 //! @brief IDを取得します。 98 //! 99 //! @return IDです。 GetID()100 int GetID() const 101 { 102 return m_Id; 103 } 104 105 //! @brief IDを設定します。 106 //! 107 //! @param[in] id 設定するIDです。 SetID(int id)108 void SetID(int id) 109 { 110 m_Id = id; 111 } 112 113 //! @brief 位置を設定します。 114 //! 115 //! @param[in] x 設定する位置Xです。 116 //! @param[in] y 設定する位置Yです。 117 //! @param[in] z 設定する位置Zです。 SetTranslate(f32 x,f32 y,f32 z)118 void SetTranslate(f32 x, f32 y, f32 z) 119 { 120 this->Transform().SetTranslate(x, y, z); 121 } 122 123 //! @brief 位置を設定します。 124 //! 125 //! @param[in] translate 設定する位置です。 SetTranslate(const nw::math::VEC3 & translate)126 void SetTranslate(const nw::math::VEC3& translate) 127 { 128 this->Transform().SetTranslate(translate); 129 } 130 131 //! @brief 位置を取得します。 GetTranslate(nw::math::VEC3 * translate)132 void GetTranslate(nw::math::VEC3* translate) const 133 { 134 this->Transform().GetTranslate(translate); 135 } 136 137 //! @brief 回転を設定します。 138 //! 139 //! @param[in] x 設定する回転値X(ラジアン)です。 140 //! @param[in] y 設定する回転値Y(ラジアン)です。 141 //! @param[in] z 設定する回転値Z(ラジアン)です。 SetRotate(f32 radX,f32 radY,f32 radZ)142 void SetRotate(f32 radX, f32 radY, f32 radZ) 143 { 144 this->Transform().SetRotateXYZ(radX, radY, radZ ); 145 } 146 147 //! @brief 拡縮を設定します。 148 //! 149 //! @param[in] x 設定する拡縮値Xです。 150 //! @param[in] y 設定する拡縮値Yです。 151 //! @param[in] z 設定する拡縮値Zです。 SetScale(f32 x,f32 y,f32 z)152 void SetScale(f32 x, f32 y, f32 z) 153 { 154 this->Transform().SetScale(x, y, z); 155 } 156 157 //! @brief ステップフレームを設定します。 158 //! 159 //! @param[in] 設定するステップフレームです。 SetStepFrame(f32 stepFrame)160 void SetStepFrame(f32 stepFrame) 161 { 162 u32 emitterNum = this->GetParticleEmitterSize(); 163 for (u32 i = 0; i < emitterNum; ++i) 164 { 165 nw::gfx::ParticleEmitter* emitter = this->GetParticleEmitter(i); 166 emitter->ParticleAnimFrameController().SetStepFrame(stepFrame); 167 } 168 169 u32 modelNum = this->GetParticleModelSize(); 170 171 for (u32 i = 0; i < modelNum; ++i) 172 { 173 nw::gfx::ParticleModel* model = this->GetParticleModel(i); 174 model->ParticleAnimFrameController().SetStepFrame(stepFrame); 175 } 176 } 177 178 //! @brief フレームを設定します。 179 //! 180 //! @param[in] 設定するフレームです。 SetFrame(f32 frame)181 void SetFrame(f32 frame) 182 { 183 u32 emitterNum = this->GetParticleEmitterSize(); 184 for (u32 i = 0; i < emitterNum; ++i) 185 { 186 nw::gfx::ParticleEmitter* emitter = this->GetParticleEmitter(i); 187 emitter->ParticleAnimFrameController().SetFrame(frame); 188 } 189 190 u32 modelNum = this->GetParticleModelSize(); 191 192 for (u32 i = 0; i < modelNum; ++i) 193 { 194 nw::gfx::ParticleModel* model = this->GetParticleModel(i); 195 model->ParticleAnimFrameController().SetFrame(frame); 196 } 197 } 198 199 //! @brief 指定数だけフレームを回します。 200 //! 201 //! @param[in] times フレームを回す回数です。 202 //! @param[in] addFrame 進めるフレーム数です。 203 //! @param[in] particleContext パーティクルコンテキストです。 AddTimes(uint times,gfx::ParticleContext * particleContext)204 void AddTimes(uint times, gfx::ParticleContext* particleContext) 205 { 206 for (u32 k = 0; k < times; ++k) 207 { 208 for (u32 i = 0; i < this->GetParticleModelSize(); ++i) 209 { 210 this->GetParticleModel(i)->UpdateParticleFrame(); 211 } 212 213 for (u32 i = 0; i < this->GetParticleEmitterSize(); ++i) 214 { 215 this->GetParticleEmitter(i)->UpdateParticleFrame(); 216 this->GetParticleEmitter(i)->Emission(particleContext); 217 } 218 219 for (u32 i = 0; i < this->GetParticleModelSize(); ++i) 220 { 221 for (u32 j = 0; j < this->GetParticleModel(i)->GetParticleSetsCount(); ++j) 222 { 223 this->GetParticleModel(i)->GetParticleSets(j)->UpdateParticles(particleContext); 224 } 225 } 226 } 227 } 228 229 //! @brief リセットします。 230 //! GPU処理中はコールできません。 231 //! 232 //! @param[in] リセットを行い、初期状態に戻します。 Reset()233 void Reset() 234 { 235 u32 emitterNum = this->GetParticleEmitterSize(); 236 for (u32 i = 0; i < emitterNum; ++i) 237 { 238 nw::gfx::ParticleEmitter* emitter = this->GetParticleEmitter(i); 239 emitter->Reset(); 240 } 241 242 u32 modelNum = this->GetParticleModelSize(); 243 244 for (u32 i = 0; i < modelNum; ++i) 245 { 246 nw::gfx::ParticleModel* model = this->GetParticleModel(i); 247 model->ForeachParticleSet(nw::gfx::ParticleSetsClear()); 248 model->ParticleAnimFrameController().SetFrame(0.f); 249 } 250 } 251 252 //! @brief 放出量をセットします。 253 //! 254 //! @param[in] ratio 設定する放出量です。 SetEmissionRatio(f32 ratio)255 void SetEmissionRatio(f32 ratio) 256 { 257 u32 emitterNum = this->GetParticleEmitterSize(); 258 for (u32 i = 0; i < emitterNum; ++i) 259 { 260 nw::gfx::ParticleEmitter* emitter = this->GetParticleEmitter(i); 261 nw::gfx::ResParticleEmitterParameter resParameter = emitter->GetResParticleEmitterParameterCopy(); 262 NW_ASSERT(resParameter.IsValid()); 263 264 resParameter.SetEmissionRatio(ratio); 265 } 266 } 267 268 //! @brief 現在のパーティクルの個数を取得します。 269 //! 270 //! @return 現在のパーティクルの個数です。 GetParticleSize()271 u32 GetParticleSize() 272 { 273 u32 particleNum = 0; 274 275 u32 modelNum = this->GetParticleModelSize(); 276 277 for (u32 i = 0; i < modelNum; ++i) 278 { 279 nw::gfx::ParticleModel* model = this->GetParticleModel(i); 280 for (u32 j = 0; j < model->GetParticleSetsCount(); ++j ) 281 { 282 nw::gfx::ParticleSet* particleSet = model->GetParticleSets(j); 283 particleNum += particleSet->GetParticleCollection()->GetCount(); 284 } 285 } 286 287 return particleNum; 288 } 289 290 //! @brief 終了状態かどうかを取得します。 291 //! 292 //! @return 終了状態であれば、trueが返ります。 IsDone()293 bool IsDone() 294 { 295 u32 modelNum = this->GetParticleModelSize(); 296 for (u32 i = 0; i < modelNum; ++i) 297 { 298 nw::gfx::ParticleModel* model = this->GetParticleModel(i); 299 if (model->HasParticle()) 300 { 301 return false; 302 } 303 } 304 305 u32 emitterNum = this->GetParticleEmitterSize(); 306 for (u32 i = 0; i < emitterNum; ++i) 307 { 308 nw::gfx::ParticleEmitter* emitter = this->GetParticleEmitter(i); 309 if (emitter->IsAlive()) 310 { 311 return false; 312 } 313 } 314 315 return true; 316 } 317 318 //! @brief 再生中のエフェクトがループエフェクト(無限ループ)かどうかを取得します。 319 //! 320 //! @return ループエフェクト(無限ループ)であれば、trueが返ります。 IsInfinity()321 bool IsInfinity() 322 { 323 bool isInfinity = false; 324 325 u32 emitterNum = this->GetParticleEmitterSize(); 326 for (u32 i = 0; i < emitterNum; ++i) 327 { 328 nw::gfx::ParticleEmitter* emitter = this->GetParticleEmitter(i); 329 const nw::gfx::ResParticleEmitterParameter resource = emitter->GetResParticleEmitterParameterCopy(false); 330 NW_ASSERT(resource.IsValid()); 331 332 if (resource.GetEmissionSpanInfinity()) 333 { 334 isInfinity = true; 335 } 336 } 337 338 return isInfinity; 339 } 340 341 //! @brief 粒子のスケールのオフセット値設定します。 342 //! 343 //! @param[in] particleOffset 設定する粒子のスケールのオフセットです。 SetParticleScaleOffset(f32 particleOffset)344 void SetParticleScaleOffset( f32 particleOffset ) 345 { 346 u32 modelNum = this->GetParticleModelSize(); 347 348 for (u32 i = 0; i < modelNum; ++i) 349 { 350 nw::gfx::ParticleModel* model = this->GetParticleModel(i); 351 352 for (int j = 0; j < (int)model->GetParticleSetsCount(); ++j) 353 { 354 nw::gfx::ParticleSet* particleSet = model->GetParticleSets(j); 355 particleSet->SetScaleOffset(nw::math::VEC3(particleOffset, particleOffset, particleOffset)); 356 } 357 } 358 } 359 360 //! @brief 粒子のスケールのオフセット値設定します。 361 //! 362 //! @param[in] particleOffsetX 設定する粒子のスケールのオフセットXです。 363 //! @param[in] particleOffsetY 設定する粒子のスケールのオフセットYです。 364 //! @param[in] particleOffsetZ 設定する粒子のスケールのオフセットZです。 365 void SetParticleScaleOffset( f32 particleOffsetX, f32 particleOffsetY, f32 particleOffsetZ = 1.f ) 366 { 367 u32 modelNum = this->GetParticleModelSize(); 368 369 for (u32 i = 0; i < modelNum; ++i) 370 { 371 nw::gfx::ParticleModel* model = this->GetParticleModel(i); 372 373 for (int j = 0; j < (int)model->GetParticleSetsCount(); ++j) 374 { 375 nw::gfx::ParticleSet* particleSet = model->GetParticleSets(j); 376 particleSet->SetScaleOffset(nw::math::VEC3(particleOffsetX, particleOffsetY, particleOffsetZ)); 377 } 378 } 379 } 380 381 //! @brief 放出処理を行います。 382 //! 383 //! @param[in] particleContext パーティクルコンテキストです。 Emission(gfx::ParticleContext * particleContext)384 void Emission(gfx::ParticleContext* particleContext) 385 { 386 for (u32 i = 0; i < this->GetParticleEmitterSize(); ++i) 387 { 388 nw::gfx::ParticleEmitter* emitter = this->GetParticleEmitter(i); 389 emitter->UpdateParticleFrame(); 390 emitter->Emission(particleContext); 391 emitter->Reset(); 392 } 393 } 394 395 //@} 396 397 //---------------------------------------- 398 //! @name インスタンス管理 399 //@{ 400 401 //! @brief パーティクルモデルのインスタンスを登録します。 402 //! 403 //! @param[in] 登録するパーティクルモデルのインスタンスです。 RegisterParticleModel(nw::gfx::ParticleModel * model)404 void RegisterParticleModel( nw::gfx::ParticleModel* model ) 405 { 406 m_ModelInstances.PushBack(model); 407 } 408 409 //! @brief パーティクルエミッタのインスタンスを登録します。 410 //! 411 //! @param[in] 登録するパーティクルエミッタのインスタンスです。 RegisterParticleEmitter(nw::gfx::ParticleEmitter * emitter)412 void RegisterParticleEmitter( nw::gfx::ParticleEmitter* emitter ) 413 { 414 m_EmitterInstances.PushBack(emitter); 415 } 416 417 //! @brief 保持しているパーティクルモデル数を取得します。 418 //! 419 //! @return 保持しているパーティクルモデル数です。 GetParticleModelSize()420 u32 GetParticleModelSize() const 421 { 422 return m_ModelInstances.size(); 423 } 424 425 //! @brief 保持しているパーティクルエミッタ数を取得します。 426 //! 427 //! @return 保持しているパーティクルエミッタ数です。 GetParticleEmitterSize()428 u32 GetParticleEmitterSize() const 429 { 430 return m_EmitterInstances.size(); 431 } 432 433 //! @brief 保持しているパーティクルモデルインスタンスを取得します。 434 //! 435 //! @return パーティクルモデルのインスタンスです。 GetParticleModel(u32 index)436 nw::gfx::ParticleModel* GetParticleModel(u32 index) 437 { 438 if (this->GetParticleModelSize() > index) 439 { 440 return m_ModelInstances[index]; 441 } 442 return NULL; 443 } 444 445 //! @brief 保持しているパーティクルエミッタインスタンスを取得します。 446 //! 447 //! @return パーティクルエミッタのインスタンスです。 GetParticleEmitter(u32 index)448 nw::gfx::ParticleEmitter* GetParticleEmitter(u32 index) 449 { 450 if (this->GetParticleEmitterSize() > index) 451 { 452 return m_EmitterInstances[index]; 453 } 454 return NULL; 455 } 456 457 //! @brief パーティクルセットを取得します。 458 //! 459 //! @param[in] name パーティクルセットの名前です。 460 //! @return パーティクルセットを返します。 GetParticleSet(const char * name)461 nw::gfx::ParticleSet* GetParticleSet(const char* name) 462 { 463 u32 modelNum = this->GetParticleModelSize(); 464 465 for (u32 i = 0; i < modelNum; ++i) 466 { 467 nw::gfx::ParticleModel* model = this->GetParticleModel(i); 468 469 for (int j = 0; j < (int)model->GetParticleSetsCount(); ++j) 470 { 471 nw::gfx::ParticleSet* particleSet = model->GetParticleSets(j); 472 const char* particleSetName = particleSet->GetResParticleSet().GetName(); 473 474 if (std::strcmp(particleSetName, name) == 0) 475 { 476 return particleSet; 477 } 478 } 479 } 480 481 return NULL; 482 } 483 484 //@} 485 486 protected: 487 //---------------------------------------- 488 //! @name コンストラクタ/デストラクタ 489 //@{ 490 491 //! コンストラクタです。 492 ParticleHandle( 493 os::IAllocator* allocator, 494 gfx::ResTransformNode resObj, 495 const gfx::TransformNode::Description& description); 496 497 //! デストラクタです。 ~ParticleHandle()498 virtual ~ParticleHandle() 499 { 500 501 } 502 503 //@} 504 505 private: 506 int m_Id; 507 ut::MoveArray<nw::gfx::ParticleModel*> m_ModelInstances; 508 ut::MoveArray<nw::gfx::ParticleEmitter*> m_EmitterInstances; 509 }; 510 511 512 // NW4C1.2.0との互換性維持の為。 513 typedef ParticleHandle ParticleNode; 514 515 516 517 //! @brief 一表現のためのパーティクル一式です 518 // パーティクルを管理する機能はアプリケーション毎の実装になります。 519 // このクラスは参考のための実装例です。 520 // パフォーマンスよりも簡便性を重視した実装です。 521 class ParticleEffect 522 { 523 public: 524 //---------------------------------------- 525 //! @name 初期化・終了処理 526 //@{ 527 528 //! @brief ParticleEffectクラスを生成します。 529 //! 530 //! @return 生成したParticleEffectクラスを返します。 531 //! 532 static ParticleEffect* Create(os::IAllocator* mainAllocator, 533 os::IAllocator* deviceAllocator, 534 bool autoAlocate, 535 gfx::ParticleContext* particleContext); 536 537 //! @brief ParticleEffectクラスを破棄します。 538 //! 539 void Destroy(); 540 541 private: 542 //! @brief コンストラクタです。 543 //! 544 //! @param[in] mainAllocator メインメモリのアロケータです。 545 //! @param[in] deviceAllocator デバイスメモリのアロケータです。 546 //! @param[in] autoAlocate 足りない時に自動でアロケートすることを許可するフラグです。 547 //! @param[in] particleContext パーティクルコンテキストです。 548 //! ParticleEffect(os::IAllocator * mainAllocator,os::IAllocator * deviceAllocator,bool autoAlocate,gfx::ParticleContext * particleContext)549 ParticleEffect( 550 os::IAllocator* mainAllocator, 551 os::IAllocator* deviceAllocator, 552 bool autoAlocate, 553 gfx::ParticleContext* particleContext 554 ) 555 : m_NextId(0), 556 m_MainAllocator(mainAllocator), 557 m_DeviceAllocator(deviceAllocator), 558 m_AutoAlocate(autoAlocate), 559 m_ResModels(mainAllocator), 560 m_ResEmitters(mainAllocator), 561 m_FreeInstances(mainAllocator), 562 m_ActiveInstances(mainAllocator), 563 m_ParticleContext(particleContext) 564 { 565 } 566 567 //! デストラクタです。 ~ParticleEffect()568 ~ParticleEffect() 569 { 570 NW_ASSERT(this->GetActiveSize() == 0); 571 this->FreePool(); 572 } 573 public: 574 //! @brief リソースのセットアップを行います。 575 //! 576 //! @param[in] useParticleMaterial パーティクルマテリアルを使用する場合はtrueを指定します。 577 void Setup(gfx::ResGraphicsFile resource, bool useParticleMaterial = false); 578 579 //! @brief リソースから指定された名前のノードを管理対象として登録します。 580 //! 581 //! @param[in] resource グラフィックスリソースです。 582 //! @param[in] nodeNames 登録するノード一覧です。 583 void Register(gfx::ResGraphicsFile resource, const char** nodeNames); 584 585 //! @brief 全てのリソースを管理対象として登録します。 586 //! 587 //! @param[in] resource グラフィックスリソースです。 588 void Register(gfx::ResGraphicsFile resource); 589 590 //@} 591 592 //---------------------------------------- 593 //! @name 生成・破棄 594 //@{ 595 596 //! @brief ParticleHandleを生成します。 597 //! @return 生成されたParticleHandleインスタンスを返します。 598 ParticleHandle* CreateMultiEmitterParticleHandle(u32 particleEmitterNum); 599 600 //! @brief 生成済みのParticleHandleをリース(レンタル)します。 601 //! @return 生成済みのParticleHandleインスタンスを返します。 LeaseInstance()602 ParticleHandle* LeaseInstance() 603 { 604 if (this->GetFreeSize() == 0) 605 { 606 if (this->m_AutoAlocate) 607 { 608 this->AddPool(1); 609 } 610 else 611 { 612 return NULL; 613 } 614 } 615 616 ParticleHandle* node = this->m_FreeInstances.Back(); 617 this->m_FreeInstances.PopBack(); 618 this->m_ActiveInstances.PushBack(node); 619 620 this->ResetParticle(node); 621 622 return node; 623 } 624 625 //! @brief リース済みのParticleHandleを返却します。 626 //! @param[in] node 開放するトップノードです。 ReleaseInstance(gfx::SceneNode * node)627 void ReleaseInstance(gfx::SceneNode* node) 628 { 629 ParticleHandle* topNode = ut::DynamicCast<ParticleHandle*>(node); 630 631 if (topNode != NULL) 632 { 633 int activeCount = this->GetActiveSize(); 634 this->m_ActiveInstances.EraseFind(topNode); 635 NW_ASSERT(this->GetActiveSize() == activeCount - 1); 636 637 this->m_FreeInstances.PushBack(topNode); 638 } 639 } 640 641 //! @details :private 642 void DestroyParticleHandle(ParticleHandle* node); DestroyParticleNode(ParticleHandle * node)643 void DestroyParticleNode(ParticleHandle* node) 644 { 645 return DestroyParticleHandle(node); 646 } 647 648 //@} 649 650 //---------------------------------------- 651 //! @name 取得 652 //@{ 653 654 //! @brief インデックスでリース中のエフェクトを取得します。 655 //! @param[in] index インデックスです。 656 //! @return 該当するトップノードです。 GetActiveEffect(int index)657 ParticleHandle* GetActiveEffect(int index) 658 { 659 if (index < 0 || index >= this->GetActiveSize()) 660 { 661 return NULL; 662 } 663 664 return this->m_ActiveInstances[index]; 665 } 666 667 //! @brief ノードを初期化します。 668 //! @param[in] topNode 初期化するエフェクトをトップノードで指定します。 ResetParticle(nw::gfx::SceneNode * topNode)669 void ResetParticle(nw::gfx::SceneNode* topNode) 670 { 671 if (nw::ut::IsTypeOf<nw::gfx::ParticleModel>(topNode)) 672 { 673 nw::gfx::ParticleModel* particleModel = 674 nw::ut::DynamicCast<nw::gfx::ParticleModel*>(topNode); 675 676 particleModel->ForeachParticleSet(nw::gfx::ParticleSetsClear()); 677 particleModel->ParticleAnimFrameController().SetFrame(0); 678 } 679 else if (nw::ut::IsTypeOf<nw::gfx::ParticleEmitter>(topNode)) 680 { 681 nw::gfx::ParticleEmitter* emitter = 682 nw::ut::DynamicCast<nw::gfx::ParticleEmitter*>(topNode); 683 684 emitter->Reset(); 685 } 686 687 nw::gfx::SceneNodeChildren::iterator end = topNode->GetChildEnd(); 688 for (nw::gfx::SceneNodeChildren::iterator child = topNode->GetChildBegin(); 689 child != end; 690 ++child) 691 { 692 ResetParticle(*child); 693 } 694 } 695 696 //@} 697 698 //---------------------------------------- 699 //! @name インスタンスプール 700 //@{ 701 702 //! @brief リース中を含む確保済みのインスタンスの総数を取得します。 GetPoolSize()703 int GetPoolSize() const 704 { 705 return this->GetFreeSize() + this->GetActiveSize(); 706 } 707 708 //! @brief リース中のでないフリーのインスタンスの数を取得します。 GetFreeSize()709 int GetFreeSize() const 710 { 711 return this->m_FreeInstances.Size(); 712 } 713 714 //! @brief リース中のインスタンスの数を取得します。 GetActiveSize()715 int GetActiveSize() const 716 { 717 return this->m_ActiveInstances.Size(); 718 } 719 720 //! @brief 指定数のインスタンスを新しくプールします。 AddPool(int num)721 void AddPool(int num) 722 { 723 for (int i = 0 ; i < num ; ++i) 724 { 725 ParticleHandle* node = this->Allocate(); 726 this->m_FreeInstances.push_back(node); 727 } 728 } 729 730 //! @brief リース中以外の全てのインスタンスを破棄します。 FreePool()731 void FreePool() 732 { 733 while (this->m_FreeInstances.Size() > 0) 734 { 735 ParticleHandle* node = this->m_FreeInstances.Back(); 736 this->m_FreeInstances.PopBack(); 737 DestroyParticleHandle(node); 738 } 739 } 740 741 //@} 742 743 744 //---------------------------------------- 745 //! @name シェーダバイナリ管理 746 //@{ 747 748 //! @brief 外部シェーダファイルをロードします。 749 static void InitializeShaderBinary(const wchar_t* shaderFilePath, os::IAllocator* deviceAllocator); 750 751 //! @brief ロードした外部シェーダファイルを破棄します。 752 static void FinalizeShaderBinary(); 753 754 //@} 755 756 private: 757 //! @details :private 758 ParticleHandle* Allocate(); 759 760 int m_NextId; 761 762 os::IAllocator* m_MainAllocator; 763 os::IAllocator* m_DeviceAllocator; 764 765 766 bool m_AutoAlocate; 767 768 ut::MoveArray<gfx::ResParticleModel> m_ResModels; 769 ut::MoveArray<gfx::ResParticleEmitter> m_ResEmitters; 770 771 ut::MoveArray<ParticleHandle*> m_FreeInstances; 772 ut::MoveArray<ParticleHandle*> m_ActiveInstances; 773 774 gfx::ParticleContext* m_ParticleContext; 775 776 static nw::demo::ResourceSet* m_ShaderResource; 777 static os::IAllocator* m_ShaderAllocator; 778 }; 779 780 781 } // namespace demo 782 783 } // namespace nw 784 785 #endif // NW_DEMO_PARTICLE_H_ 786