CLightAttachment *CScriptbind_Entity::BindAttachmentToLight(IAttachment *pAttachment, CDLight &light) { pAttachment->ClearBinding(); CLightAttachment *pLightAttachment = new CLightAttachment(); pLightAttachment->LoadLight(light); pAttachment->AddBinding(pLightAttachment); return pLightAttachment; }
//------------------------------------------------------------------------ void CItem::SetCharacterAttachment(int slot, const char *name, CDLight &light, int flags) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(slot); if (!pCharacter) return; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(name); if (!pAttachment) { GameWarning("Item '%s' trying to attach light on '%s' which does not exist!", GetEntity()->GetName(), name); return; } CLightAttachment *pLightAttachment = new CLightAttachment(); pLightAttachment->LoadLight(light); pAttachment->AddBinding(pLightAttachment); pAttachment->HideAttachment(0); }
//------------------------------------------------------------------------ void CItem::SetLightRadius(float radius, uint32 id) { TEffectInfoMap::const_iterator it = m_effects.find(id); if (it == m_effects.end()) return; const SEffectInfo &info = it->second; SEntitySlotInfo slotInfo; ILightSource* pLightSource = 0; if (info.slot != -1) { if (GetEntity()->GetSlotInfo(info.slot, slotInfo) && slotInfo.pLight) pLightSource = static_cast<ILightSource*>(slotInfo.pLight); } else if (info.characterSlot != -1) { if (GetEntity()->GetSlotInfo(info.characterSlot, slotInfo) && slotInfo.pCharacter) { IAttachmentManager *pAttachmentManager = slotInfo.pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(info.helper.c_str()); if (pAttachment) { CLightAttachment *pLightAttachment = static_cast<CLightAttachment *>(pAttachment->GetIAttachmentObject()); if (pLightAttachment) pLightSource = pLightAttachment->GetLightSource(); } } } if (pLightSource) { CDLight& light = pLightSource->GetLightProperties(); light.m_fRadius = radius; pLightSource->SetLightProperties(light); } }
//------------------------------------------------------------------------ //Above function is almost the same, just some special stuff for flashlight //------------------------------------------------------------------------ uint32 CItem::AttachLightEx(int slot, uint32 id, bool attach, bool fakeLight /*= false */, bool castShadows /*= false*/, IRenderNode* pCasterException, float radius, const Vec3 &color, const float fSpecularMult, const char *projectTexture, float projectFov, const char *helper, const Vec3 &offset, const Vec3 &dir, const char* material, float fHDRDynamic) { if (m_stats.mounted) slot=eIGS_FirstPerson; if (radius<0.1f) return 0; if (attach) { CDLight light; light.SetLightColor(ColorF(color.x, color.y, color.z, 1.0f)); light.SetSpecularMult( fSpecularMult ); light.m_nLightStyle = 0; light.m_fLightFrustumAngle = 45.0f; light.m_fRadius = radius; light.m_fLightFrustumAngle = projectFov*0.5f; light.m_fHDRDynamic = fHDRDynamic; if(fakeLight) light.m_Flags |= DLF_FAKE; //Only on hight/very hight spec if(castShadows && (g_pGameCVars->i_lighteffects!=0)) light.m_Flags |= DLF_CASTSHADOW_MAPS; if (projectTexture && projectTexture[0]) { int flags = 0; light.m_pLightImage = gEnv->pRenderer->EF_LoadTexture(projectTexture, flags); if (!light.m_pLightImage || !light.m_pLightImage->IsTextureLoaded()) { GameWarning("Item '%s' failed to load projecting light texture '%s'!", GetEntity()->GetName(), projectTexture); return 0; } } if (light.m_fLightFrustumAngle && (light.m_pLightImage != NULL) && light.m_pLightImage->IsTextureLoaded()) light.m_Flags |= DLF_PROJECT; else { if (light.m_pLightImage) light.m_pLightImage->Release(); light.m_pLightImage = 0; light.m_Flags |= DLF_POINT; } IMaterial* pMaterial = 0; if (material && material[0]) pMaterial = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(material); // generate id ++m_effectGenId; while (!m_effectGenId || (m_effects.find(m_effectGenId) != m_effects.end())) ++m_effectGenId; SEntitySlotInfo slotInfo; SEffectInfo effectInfo; effectInfo.slot = -1; bool validSlot = GetEntity()->GetSlotInfo(slot, slotInfo) && (slotInfo.pCharacter || slotInfo.pStatObj); if (!validSlot || slotInfo.pStatObj) { // get helper position Vec3 position(0,0,0); if (validSlot) { IStatObj *pStatsObj = slotInfo.pStatObj; position = pStatsObj->GetHelperPos(helper); position = GetEntity()->GetSlotLocalTM(slot, false).TransformPoint(position); } position+=offset; // find a free slot SEntitySlotInfo dummy; int i=0; while (GetEntity()->GetSlotInfo(eIGS_Last+i, dummy)) i++; // move light slot to the helper position+offset effectInfo.helper = helper; effectInfo.slot = GetEntity()->LoadLight(eIGS_Last+i, &light); if (effectInfo.slot != -1 && pMaterial) GetEntity()->SetSlotMaterial(effectInfo.slot, pMaterial); Matrix34 tm = Matrix34(Matrix33::CreateRotationVDir(dir)); tm.SetTranslation(position); GetEntity()->SetSlotLocalTM(effectInfo.slot, tm); } else if (slotInfo.pCharacter) // bone attachment { effectInfo.helper = helper; effectInfo.characterSlot = slot; ICharacterInstance *pCharacter = slotInfo.pCharacter; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helper); if (!pAttachment) { GameWarning("Item '%s' trying to attach light to attachment '%s' which does not exist!", GetEntity()->GetName(), helper); return 0; } CLightAttachment *pLightAttachment = new CLightAttachment(); pLightAttachment->LoadLight(light); if (pMaterial) { if (ILightSource* pLightSource = pLightAttachment->GetLightSource()) pLightSource->SetMaterial(pMaterial); } if(light.m_Flags&DLF_CASTSHADOW_MAPS) { if (ILightSource* pLightSource = pLightAttachment->GetLightSource()) pLightSource->SetCastingException(pCasterException); } Matrix34 tm =Matrix34(Matrix33::CreateRotationVDir(dir)); tm.SetTranslation(offset); pAttachment->AddBinding(pLightAttachment); pAttachment->SetAttRelativeDefault(QuatT(tm)); } m_effects.insert(TEffectInfoMap::value_type(m_effectGenId, effectInfo)); return m_effectGenId; } else if (id) { TEffectInfoMap::iterator it = m_effects.find(id); if (it == m_effects.end()) return 0; SEffectInfo &info = it->second; if (info.slot>-1) { GetEntity()->FreeSlot(info.slot); } else { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(info.characterSlot); if (pCharacter) { IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(info.helper.c_str()); pAttachment->ClearBinding(); } } m_effects.erase(it); } return 0; }
TAttachedEffectId CEffectsController::AttachLight(const int targetSlot, const char *helperName, const SLightAttachParams &attachParams) { CRY_ASSERT(m_pOwnerEntity); CDLight light; light.SetLightColor(ColorF(attachParams.color.x * attachParams.diffuseMultiplier, attachParams.color.y * attachParams.diffuseMultiplier, attachParams.color.z * attachParams.diffuseMultiplier, 1.0f)); light.SetSpecularMult( (float)__fsel( -attachParams.diffuseMultiplier, attachParams.specularMultiplier, (attachParams.specularMultiplier / (attachParams.diffuseMultiplier + FLT_EPSILON)) ) ); light.m_nLightStyle = attachParams.style; light.SetAnimSpeed(attachParams.animSpeed); light.m_fLightFrustumAngle = 45.0f; light.m_fRadius = attachParams.radius; light.m_fLightFrustumAngle = attachParams.projectFov * 0.5f; light.m_fHDRDynamic = attachParams.hdrDynamic; light.m_Flags |= attachParams.deferred ? DLF_DEFERRED_LIGHT : 0; light.m_Flags |= attachParams.castShadows ? DLF_CASTSHADOW_MAPS : 0; light.m_nEntityId = m_pOwnerEntity->GetId(); if (attachParams.projectTexture && attachParams.projectTexture[0]) { light.m_pLightImage = gEnv->pRenderer->EF_LoadTexture(attachParams.projectTexture); if (!light.m_pLightImage || !light.m_pLightImage->IsTextureLoaded()) { GameWarning("[EntityEffects] Entity '%s' failed to load projecting light texture '%s'!", m_pOwnerEntity->GetName(), attachParams.projectTexture); return 0; } } if ((light.m_pLightImage != NULL) && light.m_pLightImage->IsTextureLoaded()) { light.m_Flags |= DLF_PROJECT; } else { if (light.m_pLightImage) { light.m_pLightImage->Release(); } light.m_pLightImage = NULL; light.m_Flags |= DLF_POINT; } IMaterial* pMaterial = NULL; if (attachParams.material && attachParams.material[0]) { pMaterial = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(attachParams.material); } SEntitySlotInfo slotInfo; SEffectInfo effectInfo; const bool validSlot = m_pOwnerEntity->GetSlotInfo(targetSlot, slotInfo); if (!validSlot || slotInfo.pStatObj) { //Get helper position on static object (if any) Vec3 helperPos(ZERO); Vec3 localHelperPosition = attachParams.offset; if (validSlot) { helperPos = slotInfo.pStatObj->GetHelperPos(helperName); if (helperPos.IsZero()) { const int childCount = m_pOwnerEntity->GetChildCount(); for (int i=0;i<childCount;++i) { if (IEntity* pChild = m_pOwnerEntity->GetChild(i)) { if (IStatObj* statObj = pChild->GetStatObj(targetSlot)) { helperPos = statObj->GetHelperPos(helperName); if (!helperPos.IsZero()) { helperPos += pChild->GetPos(); break; } } } } } localHelperPosition = helperPos + attachParams.offset; localHelperPosition = m_pOwnerEntity->GetSlotLocalTM(targetSlot, false).TransformPoint(localHelperPosition); } int attachSlot = FindSafeSlot(attachParams.firstSafeSlot); ++m_effectGeneratorId; effectInfo.id = m_effectGeneratorId; effectInfo.entityEffectSlot = m_pOwnerEntity->LoadLight(attachSlot, &light); if ((effectInfo.entityEffectSlot >= 0) && pMaterial) { m_pOwnerEntity->SetSlotMaterial(effectInfo.entityEffectSlot, pMaterial); } Matrix34 localEffectMtx = Matrix34(Matrix33::CreateRotationVDir(attachParams.direction)); localEffectMtx.SetTranslation(localHelperPosition); m_pOwnerEntity->SetSlotLocalTM(effectInfo.entityEffectSlot, localEffectMtx); m_attachedEffects.push_back(effectInfo); return m_effectGeneratorId; } else if (slotInfo.pCharacter) { IAttachmentManager *pAttachmentManager = slotInfo.pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helperName); if (pAttachment) { CLightAttachment *pLightAttachment = new CLightAttachment(); pLightAttachment->LoadLight(light); ILightSource* pLightSource = pLightAttachment->GetLightSource(); if (pLightSource) { pLightSource->SetMaterial(pMaterial); pLightSource->SetCastingException(attachParams.pCasterException); } pAttachment->AddBinding(pLightAttachment); const bool customOffset = (attachParams.offset != Vec3Constants<float>::fVec3_Zero) || (attachParams.direction != Vec3Constants<float>::fVec3_OneY); if (customOffset) { pAttachment->SetAttRelativeDefault(QuatT(Quat::CreateRotationVDir(attachParams.direction), attachParams.offset)); } } else { GameWarning("[EntityEffects] Entity '%s' trying to attach light to attachment '%s' which does not exist!", m_pOwnerEntity->GetName(), helperName); return 0; } ++m_effectGeneratorId; effectInfo.id = m_effectGeneratorId; effectInfo.helperName = helperName; effectInfo.characterEffectSlot = targetSlot; m_attachedEffects.push_back(effectInfo); return m_effectGeneratorId; } return 0; }