GpuParticleEmitterNode.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Scene/GpuParticleEmitterNode.h>
  6. #include <AnKi/Scene/Components/MoveComponent.h>
  7. #include <AnKi/Scene/Components/SpatialComponent.h>
  8. #include <AnKi/Scene/Components/GenericGpuComputeJobComponent.h>
  9. #include <AnKi/Scene/Components/RenderComponent.h>
  10. #include <AnKi/Scene/Components/GpuParticleEmitterComponent.h>
  11. namespace anki {
  12. /// Feedback component
  13. class GpuParticleEmitterNode::MoveFeedbackComponent : public SceneComponent
  14. {
  15. ANKI_SCENE_COMPONENT(GpuParticleEmitterNode::MoveFeedbackComponent)
  16. public:
  17. MoveFeedbackComponent(SceneNode* node)
  18. : SceneComponent(node, getStaticClassId(), true)
  19. {
  20. }
  21. ANKI_USE_RESULT Error update(SceneNode& node, Second prevTime, Second crntTime, Bool& updated) override
  22. {
  23. updated = false;
  24. const MoveComponent& move = node.getFirstComponentOfType<MoveComponent>();
  25. if(move.getTimestamp() == node.getGlobalTimestamp())
  26. {
  27. GpuParticleEmitterNode& mnode = static_cast<GpuParticleEmitterNode&>(node);
  28. mnode.onMoveComponentUpdate(move);
  29. }
  30. return Error::NONE;
  31. }
  32. };
  33. ANKI_SCENE_COMPONENT_STATICS(GpuParticleEmitterNode::MoveFeedbackComponent)
  34. /// Feedback component
  35. class GpuParticleEmitterNode::ShapeFeedbackComponent : public SceneComponent
  36. {
  37. ANKI_SCENE_COMPONENT(GpuParticleEmitterNode::ShapeFeedbackComponent)
  38. public:
  39. ShapeFeedbackComponent(SceneNode* node)
  40. : SceneComponent(node, getStaticClassId(), true)
  41. {
  42. }
  43. ANKI_USE_RESULT Error update(SceneNode& node, Second prevTime, Second crntTime, Bool& updated) override
  44. {
  45. updated = false;
  46. const GpuParticleEmitterComponent& pec = node.getFirstComponentOfType<GpuParticleEmitterComponent>();
  47. if(pec.getTimestamp() == node.getGlobalTimestamp())
  48. {
  49. GpuParticleEmitterNode& mnode = static_cast<GpuParticleEmitterNode&>(node);
  50. mnode.onShapeUpdate(pec);
  51. }
  52. return Error::NONE;
  53. }
  54. };
  55. ANKI_SCENE_COMPONENT_STATICS(GpuParticleEmitterNode::ShapeFeedbackComponent)
  56. GpuParticleEmitterNode::GpuParticleEmitterNode(SceneGraph* scene, CString name)
  57. : SceneNode(scene, name)
  58. {
  59. // Create the components
  60. newComponent<MoveComponent>();
  61. newComponent<MoveFeedbackComponent>();
  62. GpuParticleEmitterComponent* pec = newComponent<GpuParticleEmitterComponent>();
  63. newComponent<ShapeFeedbackComponent>();
  64. newComponent<SpatialComponent>();
  65. GenericGpuComputeJobComponent* gpuComp = newComponent<GenericGpuComputeJobComponent>();
  66. gpuComp->setCallback(GpuParticleEmitterComponent::simulateCallback, pec);
  67. RenderComponent* rcomp = newComponent<RenderComponent>();
  68. const U64 noMerging = 0;
  69. rcomp->initRaster(GpuParticleEmitterComponent::drawCallback, pec, noMerging);
  70. }
  71. GpuParticleEmitterNode::~GpuParticleEmitterNode()
  72. {
  73. }
  74. Error GpuParticleEmitterNode::frameUpdate(Second prevUpdateTime, Second crntTime)
  75. {
  76. const GpuParticleEmitterComponent& pec = getFirstComponentOfType<GpuParticleEmitterComponent>();
  77. if(pec.isEnabled())
  78. {
  79. RenderComponent& rc = getFirstComponentOfType<RenderComponent>();
  80. rc.setFlagsFromMaterial(pec.getParticleEmitterResource()->getMaterial());
  81. }
  82. return Error::NONE;
  83. }
  84. void GpuParticleEmitterNode::onMoveComponentUpdate(const MoveComponent& movec)
  85. {
  86. getFirstComponentOfType<SpatialComponent>().setSpatialOrigin(movec.getWorldTransform().getOrigin().xyz());
  87. getFirstComponentOfType<GpuParticleEmitterComponent>().setWorldTransform(movec.getWorldTransform());
  88. }
  89. void GpuParticleEmitterNode::onShapeUpdate(const GpuParticleEmitterComponent& pec)
  90. {
  91. getFirstComponentOfType<SpatialComponent>().setAabbWorldSpace(pec.getBoundingVolumeWorldSpace());
  92. }
  93. } // end namespace anki