| 3647 | } |
| 3648 | |
| 3649 | Result PlayNodeParticlefx(HScene scene, HNode node, dmParticle::EmitterStateChangedData* callbackdata) |
| 3650 | { |
| 3651 | InternalNode* n = GetNode(scene, node); |
| 3652 | if (n->m_Node.m_NodeType != NODE_TYPE_PARTICLEFX) { |
| 3653 | return RESULT_WRONG_TYPE; |
| 3654 | } |
| 3655 | |
| 3656 | dmhash_t particlefx_id = n->m_Node.m_ParticlefxHash; |
| 3657 | |
| 3658 | if (particlefx_id == 0) |
| 3659 | { |
| 3660 | dmLogError("Particle FX node does not have a particle fx set"); |
| 3661 | return RESULT_RESOURCE_NOT_FOUND; |
| 3662 | } |
| 3663 | |
| 3664 | if (scene->m_AliveParticlefxs.Full()) |
| 3665 | { |
| 3666 | dmLogError("Particle FX gui component buffer is full (%d), component disregarded. Increase 'gui.max_particlefx_count' as needed", scene->m_AliveParticlefxs.Capacity()); |
| 3667 | return RESULT_OUT_OF_RESOURCES; |
| 3668 | } |
| 3669 | |
| 3670 | dmParticle::HPrototype particlefx_prototype = *(scene->m_Particlefxs.Get(particlefx_id)); |
| 3671 | dmParticle::HInstance inst = dmParticle::CreateInstance(scene->m_ParticlefxContext, particlefx_prototype, callbackdata); |
| 3672 | |
| 3673 | if (n->m_Node.m_AdjustMode == ADJUST_MODE_STRETCH) |
| 3674 | { |
| 3675 | n->m_Node.m_AdjustMode = ADJUST_MODE_FIT; |
| 3676 | dmLogOnceWarning("Adjust mode \"Stretch\" is not supported by particlefx nodes, falling back to \"Fit\" instead (node '%s').", dmHashReverseSafe64(n->m_NameHash)); |
| 3677 | } |
| 3678 | |
| 3679 | // Set initial transform |
| 3680 | Matrix4 trans; |
| 3681 | CalculateNodeTransform(scene, n, (CalculateNodeTransformFlags)(CALCULATE_NODE_INCLUDE_SIZE), trans); |
| 3682 | dmTransform::Transform transform = dmTransform::ToTransform(trans); |
| 3683 | dmParticle::SetPosition(scene->m_ParticlefxContext, inst, Point3(transform.GetTranslation())); |
| 3684 | dmParticle::SetRotation(scene->m_ParticlefxContext, inst, transform.GetRotation()); |
| 3685 | // we can't use transform.GetUniformScale() since the z-component is ignored by the gui |
| 3686 | float scale = dmMath::Min(transform.GetScalePtr()[0], transform.GetScalePtr()[1]); |
| 3687 | dmParticle::SetScale(scene->m_ParticlefxContext, inst, scale); |
| 3688 | |
| 3689 | uint32_t count = scene->m_AliveParticlefxs.Size(); |
| 3690 | scene->m_AliveParticlefxs.SetSize(count + 1); |
| 3691 | ParticlefxComponent* component = &scene->m_AliveParticlefxs[count]; |
| 3692 | component->m_Prototype = particlefx_prototype; |
| 3693 | component->m_Instance = inst; |
| 3694 | component->m_Node = node; |
| 3695 | |
| 3696 | n->m_Node.m_ParticlefxPrototype = particlefx_prototype; |
| 3697 | n->m_Node.m_ParticleInstance = inst; |
| 3698 | |
| 3699 | dmParticle::StartInstance(scene->m_ParticlefxContext, inst); |
| 3700 | |
| 3701 | return RESULT_OK; |
| 3702 | } |
| 3703 | |
| 3704 | Result StopNodeParticlefx(HScene scene, HNode node, bool clear_particles) |
| 3705 | { |