void VAnimationEventEffectTrigger::OnAnimationEvent() { // Get the active event trigger info VEventEffectTriggerInfo_t* info = (VEventEffectTriggerInfo_t*) m_pActiveTriggerInfo; // Check if effect file is specified if (info == NULL || info->m_spEffectFile == NULL) return; // Get bone translation and orientation (if bone ID is 0 no bone has been specified) VisBaseEntity_cl* pEntity = (VisBaseEntity_cl *)m_pOwner; hkvVec3 vPos = pEntity->GetPosition() + info->m_vPositionOffset; hkvVec3 vOri = pEntity->GetOrientation() + info->m_vOrientationOffset; if (info->m_iAttachToBone != -1) { hkvQuat vRot; pEntity->GetBoneCurrentWorldSpaceTransformation(info->m_iAttachToBone, vPos, vRot); // Add position and orientation offset vPos = PositionOffset + vPos; hkvQuat vOffsetRot; vOffsetRot.setFromEulerAngles (vOri.data[2], vOri.data[1], vOri.data[0]); vRot = vRot.multiplyReverse (vOffsetRot); vRot.getAsEulerAngles (vOri.z, vOri.y, vOri.x); } // Trigger effect VisParticleEffect_cl* pEffectInstance = info->m_spEffectFile->CreateParticleEffectInstance(vPos, vOri); pEffectInstance->SetRemoveWhenFinished(true); }
VisParticleEffect_cl* RPG_VisionEffectHelper::CreateParticleEffect(VString const& particleFilename, hkvVec3 const& position /*= hkvVec3(0.f, 0.f, 0.f)*/, hkvVec3 const& orientation /*= hkvVec3(0.f, 0.f, 0.f)*/) { VASSERT(!particleFilename.IsEmpty()); VisParticleEffectFile_cl *effectResource = static_cast<VisParticleEffectFile_cl *> (GetEffectResource("Particles", particleFilename.AsChar())); if (effectResource) { VisParticleEffect_cl* effect = effectResource->CreateParticleEffectInstance(position, orientation); if(effect) { for (int index = 0; index < effect->GetParticleGroupCount(); ++index) { effect->GetParticleGroup(index)->SetUpdateLifetimeIfInvisible(true); } } return effect; } return NULL; }
bool RPG_Effect::CreateVisualEffect(RPG_EffectDefinition const& effectDefinition, hkvVec3 const& position /*= hkvVec3(0.f, 0.f, 0.f)*/, hkvVec3 const& orientation /*= hkvVec3(0.f, 0.f, 0.f)*/) { VString vfxFilename = effectDefinition.m_vfxFilename; if (m_debugDisplay) { VString msg; if (m_parentEntity) { msg += m_parentEntity->GetTypeId()->m_lpszClassName; msg += " --> "; } msg += "Creating Particle FX: "; msg += vfxFilename.AsChar(); hkvLog::Info(msg.AsChar()); Vision::Message.Add(1, msg.AsChar()); } VisParticleEffect_cl* particleEffect = RPG_VisionEffectHelper::CreateParticleEffect(vfxFilename, position, orientation); if (!particleEffect) { hkvLog::Warning("Create Particle Effect failed: %s", vfxFilename.AsChar()); return false; } particleEffect->AttachToParent(this); // apply position offset, relative to the RPG_Effect object's transform if (!effectDefinition.m_vfxPositionOffset.isZero()) { particleEffect->SetLocalPosition(effectDefinition.m_vfxPositionOffset); } // apply orientation offset if (!effectDefinition.m_vfxOrientationOffset.isZero()) { particleEffect->SetLocalOrientation(effectDefinition.m_vfxOrientationOffset); } // by default, emitters update their position over time. We need to call TeleportSpawnPosition() to force them to update immediately. particleEffect->TeleportSpawnPosition(); // if this is a persistent effect, add it to the character's effect list. if (particleEffect && RPG_VisionEffectHelper::IsPersistentEffect(particleEffect)) { if (GetParent()) { particleEffect->SetRemoveWhenFinished(false); // if we're storing an effect here, we want to be responsible for its removal. m_persistentParticleEffect = particleEffect; } else { // a persistent effect was created, but not attached to a parent entity. Make some noise about this and shut it down. VString msg; msg.Format("Effect: %s is a looping effect, which must be attached to an entity capable of cleaning it up.", vfxFilename.AsChar()); hkvLog::Warning(msg.AsChar()); //VASSERT_MSG(false, "Effects containing looping particle systems MUST be parented to an entity which can manage their shutdown and cleanup."); particleEffect->SetFinished(); } } DebugDisplayParticleInformation(particleEffect); return true; }