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