ILINE bool InitializePoseAlignerDeer(PoseAligner::CPose& pose, IEntity& entity, ICharacterInstance& character) { IDefaultSkeleton& rIDefaultSkeleton = character.GetIDefaultSkeleton(); int jointIndexRoot = rIDefaultSkeleton.GetJointIDByName("Def_COG_jnt"); if (jointIndexRoot < 0) return false; int jointIndexBackLeft = rIDefaultSkeleton.GetJointIDByName("Def_L_ToeEnd_jnt"); if (jointIndexBackLeft < 0) return false; int jointIndexBackRight = rIDefaultSkeleton.GetJointIDByName("Def_R_ToeEnd_jnt"); if (jointIndexBackRight < 0) return false; int jointIndexFrontLeft = rIDefaultSkeleton.GetJointIDByName("Def_L_WristEnd_jnt"); if (jointIndexFrontLeft < 0) return false; int jointIndexFrontRight = rIDefaultSkeleton.GetJointIDByName("Def_R_WristEnd_jnt"); if (jointIndexFrontRight < 0) return false; if (!pose.Initialize(entity, jointIndexRoot)) return false; pose.SetRootOffsetMinMax(-0.1f, 0.04f); PoseAligner::SChainDesc chainDesc; chainDesc.name = "Left"; chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb; chainDesc.solver = "LftLeg01"; chainDesc.contactJointIndex = jointIndexBackLeft; chainDesc.bBlendProcedural = true; chainDesc.offsetMin = Vec3(0.0f, 0.0f, -0.05f); chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.4f); if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity)) { pContactRaycast->SetLength(1.0f); chainDesc.pContactReporter = pContactRaycast; } if (!pose.CreateChain(chainDesc)) return false; chainDesc.name = "Left"; chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb; chainDesc.solver = "RgtLeg01"; chainDesc.contactJointIndex = jointIndexBackRight; chainDesc.bBlendProcedural = true; chainDesc.offsetMin = Vec3(0.0f, 0.0f, -0.05f); chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.4f); if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity)) { pContactRaycast->SetLength(1.0f); chainDesc.pContactReporter = pContactRaycast; } if (!pose.CreateChain(chainDesc)) return false; chainDesc.name = "FrontLeft"; chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb; chainDesc.solver = "LftArm01"; chainDesc.contactJointIndex = jointIndexFrontLeft; chainDesc.bBlendProcedural = true; chainDesc.offsetMin = Vec3(0.0f, 0.0f, -0.05f); chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.02f); if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity)) { pContactRaycast->SetLength(1.0f); chainDesc.pContactReporter = pContactRaycast; } if (!pose.CreateChain(chainDesc)) return false; chainDesc.name = "FrontRight"; chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb; chainDesc.solver = "RgtArm01"; chainDesc.contactJointIndex = jointIndexFrontRight; chainDesc.bBlendProcedural = true; chainDesc.offsetMin = Vec3(0.0f, 0.0f, -0.05f); chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.02f); if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity)) { pContactRaycast->SetLength(1.0f); chainDesc.pContactReporter = pContactRaycast; } if (!pose.CreateChain(chainDesc)) return false; return pose.GetChainCount() != 0; }
//------------------------------------------------------------------------ bool CItem::SetGeometry(int slot, const ItemString &name, const Vec3 &poffset, const Ang3 &aoffset, float scale, bool forceReload) { bool changedfp=false; switch(slot) { case eIGS_Arms: { if(!name || forceReload) { GetEntity()->FreeSlot(slot); #ifndef ITEM_USE_SHAREDSTRING m_geometry[slot].resize(0); #else m_geometry[slot].reset(); #endif } ResetCharacterAttachment(eIGS_FirstPerson, ITEM_ARMS_ATTACHMENT_NAME); ICharacterInstance *pCharacter=0; if(name && name[0]) { if(name != m_geometry[slot]) GetEntity()->LoadCharacter(slot, name); DrawSlot(eIGS_Arms, false); pCharacter = GetEntity()->GetCharacter(eIGS_Arms); } else if(m_pForcedArms) { pCharacter = m_pForcedArms; } else { int armsId=m_stats.hand==eIH_Right?0:1; pCharacter = GetOwnerActor()?GetOwnerActor()->GetFPArms(armsId):0; } if(pCharacter) { pCharacter->SetFlags(pCharacter->GetFlags()&(~CS_FLAG_UPDATE)); SetCharacterAttachment(eIGS_FirstPerson, ITEM_ARMS_ATTACHMENT_NAME, pCharacter, 0); } } break; case eIGS_FirstPerson: case eIGS_ThirdPerson: default: { if(!name || forceReload) { GetEntity()->FreeSlot(slot); #ifndef ITEM_USE_SHAREDSTRING m_geometry[slot].resize(0); #else m_geometry[slot].reset(); #endif } DestroyAttachmentHelpers(slot); if(name && name[0]) { if(m_geometry[slot] != name) { const char *ext = PathUtil::GetExt(name.c_str()); if((stricmp(ext, "chr") == 0) || (stricmp(ext, "cdf") == 0) || (stricmp(ext, "cga") == 0)) GetEntity()->LoadCharacter(slot, name, 0); else GetEntity()->LoadGeometry(slot, name, 0, 0); changedfp=slot==eIGS_FirstPerson; } CreateAttachmentHelpers(slot); SetDefaultIdleAnimation(slot, g_pItemStrings->idle); } if(slot == eIGS_FirstPerson) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(eIGS_FirstPerson); if(pCharacter) { pCharacter->SetFlags(pCharacter->GetFlags()&(~CS_FLAG_UPDATE)); } } else if(slot == eIGS_Destroyed) DrawSlot(eIGS_Destroyed, false); } break; } Matrix34 slotTM; slotTM = Matrix34::CreateRotationXYZ(aoffset); slotTM.Scale(Vec3(scale, scale, scale)); slotTM.SetTranslation(poffset); GetEntity()->SetSlotLocalTM(slot, slotTM); if(changedfp && m_stats.mounted) { PlayAction(m_idleAnimation[eIGS_FirstPerson], 0, true); ForceSkinning(true); if(!m_mountparams.pivot.empty()) { Matrix34 tm=GetEntity()->GetSlotLocalTM(eIGS_FirstPerson, false); Vec3 pivot = GetSlotHelperPos(eIGS_FirstPerson, m_mountparams.pivot.c_str(), false); tm.AddTranslation(pivot); GetEntity()->SetSlotLocalTM(eIGS_FirstPerson, tm); } GetEntity()->InvalidateTM(); } m_geometry[slot] = name ? name : ""; ReAttachAccessories(); return true; }
bool CAnimatedGrabHandler::SetGrab(SmartScriptTable &rParams) { // NOTE Aug 16, 2007: <pvl> if there's another grab action under way, this one fails // first the cheaper check (should also cover the case when output is not yet set because of longer transition time) if(m_grabStats.IKActive == true) return false; // then the more expensive check if(IAnimationGraphState *pAGState = m_pActor->GetAnimationGraphState()) { const char *grabActive = pAGState->QueryOutput("GrabActive"); if(grabActive != NULL && grabActive[0] != 0) return false; } if(m_grabStats.grabId > 0) Reset(); m_grabStats.useIKRotation = false; rParams->GetValue("useIKRotation",m_grabStats.useIKRotation); m_grabStats.limbNum = 0; SmartScriptTable limbsTable; if(rParams->GetValue("limbs",limbsTable)) { IScriptTable::Iterator iter = limbsTable->BeginIteration(); while(limbsTable->MoveNext(iter)) { const char *pLimb; iter.value.CopyTo(pLimb); int limbIdx = m_pActor->GetIKLimbIndex(pLimb); if(limbIdx > -1 && m_grabStats.limbNum<GRAB_MAXLIMBS) m_grabStats.limbId[m_grabStats.limbNum++] = limbIdx; } limbsTable->EndIteration(iter); } m_grabStats.usingAnimation = false; const char *pCarryAnimGraphInput = 0; if(rParams->GetValue("carryAnimGraphInput",pCarryAnimGraphInput)) { const int maxNameLen = SGrabStats::s_maxAGInputNameLen; strncpy(m_grabStats.carryAnimGraphInput,pCarryAnimGraphInput,maxNameLen); m_grabStats.carryAnimGraphInput[maxNameLen-1] = 0; } SmartScriptTable animationTable; if(rParams->GetValue("animation",animationTable)) { const char *pAnimGraphSignal = NULL; if(animationTable->GetValue("animGraphSignal",pAnimGraphSignal)) { const int maxNameLen = SGrabStats::s_maxAGInputNameLen; strncpy(m_grabStats.grabAnimGraphSignal,pAnimGraphSignal,maxNameLen); m_grabStats.grabAnimGraphSignal[maxNameLen-1] = 0; } // TODO Dez 15, 2006: <pvl> if there's no graph signal, consider // returning false - won't work without graph signal anyway if(pAnimGraphSignal) { m_grabStats.usingAnimation = true; m_grabStats.usingAnimationForDrop = true; m_grabStats.usingAnimationForGrab = true; } if(animationTable->GetValue("forceThrow",m_grabStats.throwDelay)) { //m_grabStats.grabDelay = 0.0f; m_grabStats.maxDelay = m_grabStats.throwDelay; } m_grabStats.grabbedObjOfs.zero(); animationTable->GetValue("grabbedObjOfs",m_grabStats.grabbedObjOfs); m_grabStats.releaseIKTime = 0.0f; animationTable->GetValue("releaseIKTime",m_grabStats.releaseIKTime); } else { if(rParams->GetValue("grabAnim",animationTable)) { m_grabStats.usingAnimationForGrab = true; m_grabStats.releaseIKTime = 0.0f; animationTable->GetValue("releaseIKTime",m_grabStats.releaseIKTime); m_grabStats.grabbedObjOfs.zero(); animationTable->GetValue("grabbedObjOfs",m_grabStats.grabbedObjOfs); const char *pAnimGraphSignal = NULL; if(animationTable->GetValue("animGraphSignal",pAnimGraphSignal)) { const int maxNameLen = SGrabStats::s_maxAGInputNameLen; strncpy(m_grabStats.grabAnimGraphSignal,pAnimGraphSignal,maxNameLen); m_grabStats.grabAnimGraphSignal[maxNameLen-1] = 0; } } if(rParams->GetValue("dropAnim",animationTable)) { m_grabStats.usingAnimationForDrop = true; // NOTE Feb 10, 2007: <pvl> this is just to get around the // condition in CBaseGrabHandler::SetDrop(). If we don't set // throwDelay to something bigger than zero SetDrop() executes // StartDrop() immediately. // All of this stuff around maxDelay, throwDelay etc. should be // rewritten but in a way that doesn't break existing behaviour. m_grabStats.throwDelay = 1000.0f; const char *pAnimGraphSignal = NULL; if(animationTable->GetValue("animGraphSignal",pAnimGraphSignal)) { const int maxNameLen = SGrabStats::s_maxAGInputNameLen; strncpy(m_grabStats.dropAnimGraphSignal,pAnimGraphSignal,SGrabStats::s_maxAGInputNameLen); m_grabStats.dropAnimGraphSignal[maxNameLen-1] = 0; } } m_grabStats.usingAnimation = m_grabStats.usingAnimationForDrop || m_grabStats.usingAnimationForGrab; } m_grabStats.followBoneID = -1; const char *followBone; if(rParams->GetValue("followBone",followBone)) { ICharacterInstance *pCharacter = m_pActor->GetEntity()->GetCharacter(0); if(pCharacter) m_grabStats.followBoneID = pCharacter->GetISkeletonPose()->GetJointIDByName(followBone); } // TODO Dez 15, 2006: <pvl> consider returning false if bone ID is -1 // at this point - it won't work anyway without bone ID //FIXME:remove this garbage when the grabbing setup is refactored too float savedThrowDelay(m_grabStats.throwDelay); if(! CBaseGrabHandler::SetGrab(rParams)) return false; m_grabStats.additionalRotation.SetIdentity(); m_grabStats.origRotation.SetIdentity(); if(m_grabStats.carryAnimGraphInput[0]) { m_pActor->SetAnimationInput("CarryItem",m_grabStats.carryAnimGraphInput); } if(m_grabStats.grabAnimGraphSignal[0]) { m_pActor->SetAnimationInput("Signal",m_grabStats.grabAnimGraphSignal); } if(! m_grabStats.usingAnimationForGrab) { StartGrab(); } m_grabStats.maxDelay = m_grabStats.throwDelay = savedThrowDelay; return true; }
//------------------------------------------------------------------------ uint32 CItem::AttachEffect(int slot, uint32 id, bool attach, const char *effectName, const char *helper, const Vec3 &offset, const Vec3 &dir, float scale, bool prime) { if (m_stats.mounted) slot=eIGS_FirstPerson; if (attach) { if (!g_pGameCVars->i_particleeffects) return 0; IParticleEffect *pParticleEffect = gEnv->pParticleManager->FindEffect(effectName); if (!pParticleEffect) return 0; // generate id ++m_effectGenId; while (!m_effectGenId || (m_effects.find(m_effectGenId) != m_effects.end())) ++m_effectGenId; SEntitySlotInfo slotInfo; SEffectInfo effectInfo; bool validSlot = GetEntity()->GetSlotInfo(slot, slotInfo) && (slotInfo.pCharacter || slotInfo.pStatObj); if (!validSlot || slotInfo.pStatObj || (!helper || !helper[0])) { // get helper position Vec3 position(0,0,0); if (validSlot && helper && helper[0]) { 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 particle slot to the helper position+offset effectInfo.helper = helper; effectInfo.slot = GetEntity()->LoadParticleEmitter(eIGS_Last+i, pParticleEffect, 0, prime, true); Matrix34 tm = IParticleEffect::ParticleLoc(position, dir, scale); 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 effect '%s' to attachment '%s' which does not exist!", GetEntity()->GetName(), effectName, helper); return 0; } CEffectAttachment *pEffectAttachment = new CEffectAttachment(effectName, Vec3(0,0,0), Vec3(0,1,0), scale); Matrix34 tm = Matrix34(Matrix33::CreateRotationVDir(dir)); tm.SetTranslation(offset); pAttachment->AddBinding(pEffectAttachment); pAttachment->SetAttRelativeDefault(QuatT(tm)); pEffectAttachment->UpdateAttachment(pAttachment); if (pEffectAttachment->GetEmitter()) { if (prime) pEffectAttachment->GetEmitter()->Prime(); } } 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()); if(pAttachment) pAttachment->ClearBinding(); } } m_effects.erase(it); } return 0; }
//------------------------------------------------------------------------ void CItem::SpawnEffect(int slot, const char *effectName, const char *helper, const Vec3 &offset, const Vec3 &dir, float scale) { if (m_stats.mounted) slot=eIGS_FirstPerson; Vec3 position(0,0,0); Vec3 finalOffset = offset; SEntitySlotInfo slotInfo; if (GetEntity()->GetSlotInfo(slot, slotInfo)) { if (slotInfo.pStatObj) // entity slot { // get helper position IStatObj *pStatsObj = slotInfo.pStatObj; position = pStatsObj->GetHelperPos(helper); position = GetEntity()->GetSlotWorldTM(slot).TransformPoint(position); } else if (slotInfo.pCharacter) // bone attachment { ICharacterInstance *pCharacter = slotInfo.pCharacter; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helper); if (pAttachment) { const Matrix34 m = Matrix34(pAttachment->GetAttWorldAbsolute()); position = m.GetTranslation(); } else { int16 id = pCharacter->GetISkeletonPose()->GetJointIDByName(helper); if (id>=0) position = pCharacter->GetISkeletonPose()->GetAbsJointByID(id).t; position = GetEntity()->GetSlotWorldTM(slot).TransformPoint(position); } } } else if(m_stats.mounted && !m_stats.fp) { if(GetIWeapon()) { // if no helper specified, try getting pos from firing locator IWeaponFiringLocator *pLocator = GetIWeapon()->GetFiringLocator(); if (pLocator) { if(!pLocator->GetFiringPos(GetEntityId(), NULL, position)) position.Set(0.0f,0.0f,0.0f); else finalOffset = GetEntity()->GetWorldTM().TransformVector(finalOffset); } } } position += finalOffset; IParticleEffect *pParticleEffect = gEnv->pParticleManager->FindEffect(effectName); if (pParticleEffect) pParticleEffect->Spawn(true, IParticleEffect::ParticleLoc(position, dir, scale)); }
//------------------------------------------------------------------------ IStatObj* CVehiclePartAnimated::GetSubGeometry(CVehiclePartBase* pPart, EVehiclePartState state, Matrix34 &localTM, bool removeFromParent) { ICharacterInstance* pCharInstance = 0; string jointName; pPart->GetGeometryName(state, jointName); int jointId = -1; if (state == eVGS_Destroyed) { pCharInstance = m_pCharInstanceDestroyed; if (pCharInstance) jointId = pCharInstance->GetIDefaultSkeleton().GetJointIDByName(jointName.c_str()); } else { // lookup first on intact, then on destroyed model pCharInstance = m_pCharInstance; if (pCharInstance) jointId = pCharInstance->GetIDefaultSkeleton().GetJointIDByName(jointName.c_str()); if (jointId == -1) { pCharInstance = m_pCharInstanceDestroyed; if (pCharInstance) jointId = pCharInstance->GetIDefaultSkeleton().GetJointIDByName(jointName.c_str()); } } if (jointId != -1) { if (ISkeletonPose* pSkeletonPose = pCharInstance->GetISkeletonPose()) { localTM = Matrix34(pCharInstance->GetISkeletonPose()->GetAbsJointByID(jointId)); if (IStatObj* pStatObj = pSkeletonPose->GetStatObjOnJoint(jointId)) { if (removeFromParent && (pCharInstance != m_pCharInstanceDestroyed)) { if (m_intactStatObjs.find(pPart->GetName()) == m_intactStatObjs.end()) { m_intactStatObjs.insert(TStringStatObjMap::value_type(pPart->GetName(), pStatObj)); } SetCGASlot(jointId, NULL); } if (pPart) { m_jointParts.insert(TStringVehiclePartMap::value_type(pPart->GetName(), pPart)); } return pStatObj; } else if ((state == eVGS_Default) && (pPart->GetState() != eVGS_Default)) { TStringStatObjMap::const_iterator it = m_intactStatObjs.find(pPart->GetName()); if (it != m_intactStatObjs.end()) { return it->second; } } } } return NULL; }
//----------------------------------------------------------------------- void CSpectacularKill::ReadXmlData( const IItemParamsNode* pRootNode) { CRY_ASSERT(pRootNode); ISharedParamsManager* pSharedParamsManager = gEnv->pGame->GetIGameFramework()->GetISharedParamsManager(); CRY_ASSERT(pSharedParamsManager); // If we change the SharedParamsManager to accept CRCs on its interface we could compute this once and store // the name's CRC32 instead of constructing it here each time this method is invoked (it shouldn't be invoked // too often, though) const char* szEntityClassName = m_pOwner->GetEntityClassName(); CryFixedStringT<64> sharedParamsName; sharedParamsName.Format("%s_%s", SSharedSpectacularParams::s_typeInfo.GetName(), szEntityClassName); ISharedParamsConstPtr pSharedParams = pSharedParamsManager->Get(sharedParamsName); if (pSharedParams) { m_pParams = CastSharedParamsPtr<SSharedSpectacularParams>(pSharedParams); return; } m_pParams.reset(); const IItemParamsNode* pParams = pRootNode->GetChild("SpectacularKill"); if (pParams) { SSharedSpectacularParams newParams; const int childCount = pParams->GetChildCount(); newParams.paramsList.reserve(childCount); for (int i = 0; i < childCount; ++i) { const IItemParamsNode* pTargetParams = pParams->GetChild(i); CRY_ASSERT(pTargetParams); IEntityClass* pTargetClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(pTargetParams->GetName()); if (pTargetClass) { SSpectacularKillParams targetParams; const IItemParamsNode* pChildParamsNode = pTargetParams->GetChild("Params"); const IItemParamsNode* pChildAnimsNode = pTargetParams->GetChild("Anims"); targetParams.pEnemyClass = pTargetClass; if(pChildParamsNode) { pChildParamsNode->GetAttribute("impulseScale", targetParams.impulseScale); const char* szImpulseBone = pChildParamsNode->GetAttributeSafe("impulseBone"); ICharacterInstance* pCharacter = m_pOwner->GetEntity()->GetCharacter(0); targetParams.impulseBone = pCharacter ? pCharacter->GetIDefaultSkeleton().GetJointIDByName(szImpulseBone) : -1; } if(pChildAnimsNode) { const int animCount = pChildAnimsNode->GetChildCount(); targetParams.animations.reserve(animCount); for(int j = 0; j < animCount; j++) { const IItemParamsNode* pAnimNode = pChildAnimsNode->GetChild(j); if(pAnimNode) { SSpectacularKillAnimation newAnimation; newAnimation.victimAnimation = pAnimNode->GetAttributeSafe("victimAnimation"); newAnimation.killerAnimation = pAnimNode->GetAttributeSafe("killerAnimation"); pAnimNode->GetAttribute("optimalDist", newAnimation.optimalDist); if (pAnimNode->GetAttribute("targetToKillerAngle", newAnimation.targetToKillerAngle)) newAnimation.targetToKillerAngle = DEG2RAD(newAnimation.targetToKillerAngle); if (pAnimNode->GetAttribute("targetToKillerAngleRange", newAnimation.targetToKillerMinDot)) newAnimation.targetToKillerMinDot = cos_tpl(DEG2RAD(newAnimation.targetToKillerMinDot) / 2.0f); pAnimNode->GetAttribute("obstacleCheckStartOffset", newAnimation.vKillerObstacleCheckOffset); pAnimNode->GetAttribute("obstacleCheckLength", newAnimation.fObstacleCheckLength); targetParams.animations.push_back(newAnimation); } } } CRY_ASSERT_MESSAGE(targetParams.animations.size() > 0, string().Format("No Animations defined for %s spectacular kill", pTargetClass->GetName())); newParams.paramsList.push_back(targetParams); } #ifdef SPECTACULAR_KILL_DEBUG else { GameWarning("spectacular Kill: Couldn't find entity of class '%s', skipping", pTargetParams->GetName()); } #endif } m_pParams = CastSharedParamsPtr<SSharedSpectacularParams>(pSharedParamsManager->Register(sharedParamsName, newParams)); } }
//------------------------------------------------------------------------- void CGameRulesStandardState::Add3DWinningTeamMember() { IActor * localActor = g_pGame->GetIGameFramework()->GetClientActor(); if (localActor != NULL && static_cast<CActor*>(localActor)->GetSpectatorState() != CActor::eASS_SpectatorMode && !g_pGame->GetUI()->IsInMenu()) { IEntity * renderModelFromEntity = NULL; if (m_pGameRules->GetTeamCount() > 1) { // Only way to get in here is for it to be a team game (as opposed to every-man-for-himself Instant Action) const int teamId = m_pGameRules->GetTeam(localActor->GetEntityId()); assert(teamId == 1 || teamId == 2); const int enemyTeamId = 3 - teamId; const int clientTeamScore = m_pGameRules->GetTeamsScore(teamId); const int nonClientTeamScore = m_pGameRules->GetTeamsScore(enemyTeamId); bool winning = (clientTeamScore >= nonClientTeamScore); CryLog ("Want to add 3D model of winning team member... local player '%s' is %s", localActor->GetEntity()->GetName(), winning ? " on the winning team" : "not on the winning team"); if (! winning) { if (m_pGameRules->GetTeamPlayerCount(enemyTeamId, false)) { renderModelFromEntity = gEnv->pEntitySystem->GetEntity(m_pGameRules->GetTeamPlayer(enemyTeamId, 0)); } } } if (renderModelFromEntity == NULL) { // Local entity must exist (checked at top of function) so we'll _definitely_ have a renderModelFromEntity after this renderModelFromEntity = localActor->GetEntity(); } // Additional paranoia :) if (renderModelFromEntity) { CryLog ("Adding 3D model of '%s' to accompany scoreboard", renderModelFromEntity->GetName()); INDENT_LOG_DURING_SCOPE(); ICharacterInstance * characterInst = renderModelFromEntity->GetCharacter(0); if (characterInst != NULL) { CMenuRender3DModelMgr *pModelManager = new CMenuRender3DModelMgr(); CMenuRender3DModelMgr::SSceneSettings sceneSettings; sceneSettings.fovScale = 0.5f; sceneSettings.fadeInSpeed = 0.01f; sceneSettings.flashEdgeFadeScale = 0.2f; sceneSettings.ambientLight = Vec4(0.f, 0.f, 0.f, 0.8f); sceneSettings.lights.resize(3); sceneSettings.lights[0].pos.Set(-25.f, -10.f, 30.f); sceneSettings.lights[0].color.Set(5.f, 6.f, 5.5f); sceneSettings.lights[0].specular = 4.f; sceneSettings.lights[0].radius = 400.f; sceneSettings.lights[1].pos.Set(25.f, -4.f, 30.f); sceneSettings.lights[1].color.Set(0.7f, 0.7f, 0.7f); sceneSettings.lights[1].specular = 10.f; sceneSettings.lights[1].radius = 400.f; sceneSettings.lights[2].pos.Set(60.f, 40.f, 10.f); sceneSettings.lights[2].color.Set(0.5f, 1.0f, 0.7f); sceneSettings.lights[2].specular = 10.f; sceneSettings.lights[2].radius = 400.f; pModelManager->SetSceneSettings(sceneSettings); const char * usePlayerModelName = characterInst->GetFilePath(); CMenuRender3DModelMgr::SModelParams params; params.pFilename = usePlayerModelName; params.posOffset.Set(0.1f, 0.f, -0.2f); params.rot.Set(0.f, 0.f, 3.5f); params.scale = 1.35f; params.pName = "char"; params.screenRect[0] = 0.f; params.screenRect[1] = 0.f; params.screenRect[2] = 0.3f; params.screenRect[3] = 0.8f; const float ANIM_SPEED_MULTIPLIER = 0.5f; if (m_pGameRules->GetGameMode() == eGM_Gladiator) { // In Hunter mode, force the model to be a hunter params.pFilename = "_ObjectsSDK/Characters/Human/sdk_player/sdk_player.cdf"; } const CMenuRender3DModelMgr::TAddedModelIndex characterModelIndex = pModelManager->AddModel(params); pModelManager->UpdateAnim(characterModelIndex, "stand_tac_idle_nw_3p_01", ANIM_SPEED_MULTIPLIER); } } } }
bool CStickyProjectile::StickToEntity( const SStickParams& stickParams, IEntity* pTargetEntity ) { IEntity* pProjectileEntity = stickParams.m_pProjectile->GetEntity(); ICharacterInstance* pCharInstance = pTargetEntity->GetCharacter(0); if( pCharInstance) { IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId()); if (!pActor || (stickParams.m_bStickToFriendlies || !pActor->IsFriendlyEntity(stickParams.m_ownerId)) && (gEnv->bMultiplayer || !pActor->IsDead())) { m_stuckJoint = GetJointIdFromPartId(*pTargetEntity, stickParams.m_targetPartId); m_stuckNormal = stickParams.m_stickNormal; m_stuckPartId = stickParams.m_targetPartId; ICharacterModelSkeleton* pICharacterModelSkeleton = pCharInstance->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeleton = pCharInstance->GetISkeletonPose(); const char* boneName = pICharacterModelSkeleton->GetJointNameByID(m_stuckJoint); const QuatT jointWorld = QuatT(pTargetEntity->GetWorldTM()) * pSkeleton->GetAbsJointByID(m_stuckJoint); QuatT loc; CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc ); pProjectileEntity->SetWorldTM(Matrix34(loc)); // Get the local pos and rot. loc = jointWorld.GetInverted() * loc; m_stuckPos = loc.t; m_stuckRot = loc.q; // Attach. if(AttachToCharacter( stickParams.m_pProjectile, *pTargetEntity, *pCharInstance, boneName)) { m_flags |= eSF_IsStuck; m_flags |= pActor ? pActor->IsPlayer() ? eSF_StuckToPlayer : eSF_StuckToAI : 0; SetParentId(pTargetEntity->GetId()); m_childId = pProjectileEntity->GetId(); return true; } } } else { m_stuckNormal = stickParams.m_stickNormal; m_stuckPartId = stickParams.m_targetPartId; QuatT loc; CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc ); AttachTo(stickParams.m_pProjectile, pTargetEntity); pProjectileEntity->SetWorldTM(Matrix34(loc)); // Set as Stuck. SetParentId(pTargetEntity->GetId()); m_childId = pProjectileEntity->GetId(); m_flags |= eSF_IsStuck; //Store position and rotation relative to parent entity m_stuckPos = pProjectileEntity->GetPos(); m_stuckRot = pProjectileEntity->GetRotation(); return true; } return false; }
//---------------------------------------------------- void CRocketLauncher::UpdateTPLaser(float frameTime) { m_lastUpdate -= frameTime; bool allowUpdate = true; if(m_lastUpdate<=0.0f) m_lastUpdate = m_Timeout; else allowUpdate = false; const CCamera& camera = gEnv->pRenderer->GetCamera(); //If character not visible, laser is not correctly updated if(CActor* pOwner = GetOwnerActor()) { ICharacterInstance* pCharacter = pOwner->GetEntity()->GetCharacter(0); if(pCharacter && !pCharacter->IsCharacterVisible()) return; } Vec3 offset(-0.06f,0.28f,0.115f); //To match scope position in TP LAW model Vec3 pos = GetEntity()->GetWorldTM().TransformPoint(offset); Vec3 dir = GetEntity()->GetWorldRotation().GetColumn1(); Vec3 hitPos(0,0,0); float laserLength = 0.0f; if(allowUpdate) { IPhysicalEntity* pSkipEntity = NULL; if(GetOwner()) pSkipEntity = GetOwner()->GetPhysics(); const float range = m_LaserRangeTP; // Use the same flags as the AI system uses for visibility. const int objects = ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid|ent_independent; //ent_living; const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (10 & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit); ray_hit hit; if (gEnv->pPhysicalWorld->RayWorldIntersection(pos, dir*range, objects, flags, &hit, 1, &pSkipEntity, pSkipEntity ? 1 : 0)) { laserLength = hit.dist; m_lastLaserHitPt = hit.pt; m_lastLaserHitSolid = true; } else { m_lastLaserHitSolid = false; m_lastLaserHitPt = pos + dir * range; laserLength = range + 0.1f; } // Hit near plane if (dir.Dot(camera.GetViewdir()) < 0.0f) { Plane nearPlane; nearPlane.SetPlane(camera.GetViewdir(), camera.GetPosition()); nearPlane.d -= camera.GetNearPlane()+0.15f; Ray ray(pos, dir); Vec3 out; m_lastLaserHitViewPlane = false; if (Intersect::Ray_Plane(ray, nearPlane, out)) { float dist = Distance::Point_Point(pos, out); if (dist < laserLength) { laserLength = dist; m_lastLaserHitPt = out; m_lastLaserHitSolid = true; m_lastLaserHitViewPlane = true; } } } hitPos = m_lastLaserHitPt; } else { laserLength = Distance::Point_Point(m_lastLaserHitPt, pos); hitPos = pos + dir * laserLength; } if (m_smoothLaserLength < 0.0f) m_smoothLaserLength = laserLength; else { if (laserLength < m_smoothLaserLength) m_smoothLaserLength = laserLength; else m_smoothLaserLength += (laserLength - m_smoothLaserLength) * min(1.0f, 10.0f * frameTime); } const float assetLength = 2.0f; m_smoothLaserLength = CLAMP(m_smoothLaserLength,0.01f,m_LaserRangeTP); float scale = m_smoothLaserLength / assetLength; // Scale the laser based on the distance. Matrix34 scl; scl.SetIdentity(); scl.SetScale(Vec3(1,scale,1)); scl.SetTranslation(offset); GetEntity()->SetSlotLocalTM( eIGS_Aux1, scl); if (m_dotEffectSlot >= 0) { if (m_lastLaserHitSolid) { Matrix34 dotMatrix = Matrix34::CreateTranslationMat(Vec3(0,m_smoothLaserLength,0)); dotMatrix.AddTranslation(offset); if(m_lastLaserHitViewPlane) dotMatrix.Scale(Vec3(0.2f,0.2f,0.2f)); GetEntity()->SetSlotLocalTM(m_dotEffectSlot,dotMatrix); } else { Matrix34 scaleMatrix; scaleMatrix.SetIdentity(); scaleMatrix.SetScale(Vec3(0.001f,0.001f,0.001f)); GetEntity()->SetSlotLocalTM(m_dotEffectSlot, scaleMatrix); } } }
//------------------------------------------------------------------------ bool CC4Projectile::StickToCharacter(bool stick,IEntity *pActor) { if(!pActor) return false; //Check for friendly AI if(pActor->GetAI()) { if(CWeapon *pWeapon = GetWeapon()) { if(CActor *pPlayer = pWeapon->GetOwnerActor()) { if(IAIObject *pPlayerAI = pPlayer->GetEntity()->GetAI()) { if(pActor->GetAI()->IsFriendly(pPlayerAI, false)) { return false; } } } } } ICharacterInstance *pCharacter = pActor->GetCharacter(0); if(!pCharacter) return false; //Actors doesn't support constraints, try to stick as character attachment IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = NULL; //Select one of the attachment points Vec3 charOrientation = pActor->GetRotation().GetColumn1(); Vec3 c4ToChar = pActor->GetWorldPos() - GetEntity()->GetWorldPos(); c4ToChar.Normalize(); //if(c4ToChar.Dot(charOrientation)>0.0f) //pAttachment = pAttachmentManager->GetInterfaceByName("c4_back"); //else pAttachment = pAttachmentManager->GetInterfaceByName("c4_front"); if(!pAttachment) { GameWarning("No c4 face attachment found in actor"); if(!pAttachment) return false; } if(stick) { //Check if there's already one if(IAttachmentObject *pAO = pAttachment->GetIAttachmentObject()) return false; CEntityAttachment *pEntityAttachment = new CEntityAttachment(); pEntityAttachment->SetEntityId(GetEntityId()); pAttachment->AddBinding(pEntityAttachment); pAttachment->HideAttachment(0); m_stuck = true; } else { pAttachment->ClearBinding(); m_stuck = false; } return true; }
//------------------------------------------------------------------------ int CScriptBind_Actor::GetCloseColliderParts(IFunctionHandler *pH, int characterSlot, Vec3 hitPos, float radius) { // find nearest physic. parts to explosion center // for now we just return the closest part (using the AABB) CActor *pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); IEntity* pEntity = pActor->GetEntity(); ICharacterInstance* pChar = pEntity->GetCharacter(characterSlot); if (pChar && pChar->GetISkeletonPose()->GetCharacterPhysics()) { IPhysicalEntity* pPhysics = pChar->GetISkeletonPose()->GetCharacterPhysics(); pe_status_nparts nparts; int numParts = pPhysics->GetStatus(&nparts); float minLenSq = radius*radius + 0.1f; int minLenPart = -1; pe_status_pos status; for (int i=0; i<numParts; ++i) { status.ipart = i; if (pPhysics->GetStatus(&status)) { AABB box(status.pos+status.BBox[0], status.pos+status.BBox[1]); // if hitpos inside AABB, return if (box.IsContainPoint(hitPos)) { minLenPart = i; break; } // else find closest distance float lenSq = Distance::Point_AABBSq(hitPos, box); if (lenSq < minLenSq) { minLenSq = lenSq; minLenPart = i; } } } // get material from selected part static ISurfaceTypeManager* pSurfaceMan = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager(); if (minLenPart != -1) { pe_params_part params; params.ipart = minLenPart; if (pPhysics->GetParams(¶ms)) { phys_geometry* pGeom = params.pPhysGeomProxy ? params.pPhysGeomProxy : params.pPhysGeom; if (pGeom->surface_idx > 0 && pGeom->surface_idx < params.nMats) { if (ISurfaceType *pSurfaceType=pSurfaceMan->GetSurfaceType(pGeom->pMatMapping[pGeom->surface_idx])) return pH->EndFunction(params.partid, pSurfaceType->GetName(), pSurfaceType->GetType()); } } return pH->EndFunction(params.partid); } } return pH->EndFunction(); }
void CAICorpse::SetupFromSource( IEntity& sourceEntity, ICharacterInstance& characterInstance, const uint32 priority) { // 1.- Move resources from source entity, into AICorpse GetEntity()->SetFlags(GetEntity()->GetFlags() | (ENTITY_FLAG_CASTSHADOW)); sourceEntity.MoveSlot(GetEntity(), 0); // Moving everything from one slot into another will also clear the render proxies in the source. // Thus, we need to invalidate the model so that it will be properly reloaded when a non-pooled // entity is restored from a save-game. CActor* sourceActor = static_cast<CActor*>(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(sourceEntity.GetId())); if (sourceActor != NULL) { sourceActor->InvalidateCurrentModelName(); } // 2.- After 'MoveSlot()', characterInstance is now stored inside CAICorpse // It needs to be now updated from the entity system characterInstance.SetFlags( characterInstance.GetFlags() | CS_FLAG_UPDATE ); #if AI_CORPSES_ENABLE_SERIALIZE m_modelName = characterInstance.GetFilePath(); #endif // 3.- Search for any attached weapon and clone them IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem(); IAttachmentManager* pAttachmentManager = characterInstance.GetIAttachmentManager(); const uint32 attachmentCount = (uint32)pAttachmentManager->GetAttachmentCount(); for(uint32 i = 0; i < attachmentCount ; ++i) { IAttachment* pAttachment = pAttachmentManager->GetInterfaceByIndex(i); assert(pAttachment != NULL); IAttachmentObject* pAttachmentObject = pAttachment->GetIAttachmentObject(); if((pAttachmentObject == NULL) || (pAttachmentObject->GetAttachmentType() != IAttachmentObject::eAttachment_Entity)) continue; const EntityId attachedEntityId = static_cast<CEntityAttachment*>(pAttachmentObject)->GetEntityId(); IItem* pItem = pItemSystem->GetItem(attachedEntityId); if(pItem != NULL) { if(AllowCloneAttachedItem( pItem->GetEntity()->GetClass() )) { if(m_attachedItemsInfo.size() < m_attachedItemsInfo.max_size()) { AttachedItem attachedItemInfo; attachedItemInfo.pClass = pItem->GetEntity()->GetClass(); attachedItemInfo.attachmentName = pAttachment->GetName(); attachedItemInfo.id = CloneAttachedItem( attachedItemInfo, pAttachment ); m_attachedItemsInfo.push_back(attachedItemInfo); } } } } //Only accept requested priority if it has attached weapons m_priority = (m_attachedItemsInfo.size() > 0) ? priority : 0; //Force physics to sleep immediately (if not already) IPhysicalEntity* pCorpsePhysics = GetEntity()->GetPhysics(); if(pCorpsePhysics != NULL) { pe_action_awake awakeAction; awakeAction.bAwake = 0; pCorpsePhysics->Action( &awakeAction ); } }
const Vec3& CTacticalManager::GetTacticalIconWorldPos(const EntityId tacticalEntityId, IEntity* pTacticalEntity, bool& inOutIsHeadBone) { CRY_ASSERT(tacticalEntityId != 0); CRY_ASSERT(pTacticalEntity != NULL); if (pTacticalEntity == NULL) { return m_tempVec3.Set(0.0f,0.0f,0.0f); } // Try to get pos from headbone if don't have an override pos TTacticalEntityToOverrideEntities::const_iterator iter = m_tacEntityToOverrideEntities.find(tacticalEntityId); if (iter == m_tacEntityToOverrideEntities.end()) { static IEntityClass* s_pTurretEntityClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("Turret"); IEntityClass* pEntityClass = pTacticalEntity->GetClass(); if (pEntityClass != NULL && pEntityClass == s_pTurretEntityClass) { ICharacterInstance* pCharacterInstance = pTacticalEntity->GetCharacter(0); if (pCharacterInstance != NULL) { ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacterInstance->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeletonPose = pCharacterInstance->GetISkeletonPose(); CRY_ASSERT(pSkeletonPose != NULL); const int16 jointId = pICharacterModelSkeleton->GetJointIDByName("arcjoint"); if (0 <= jointId) { QuatT boneLocation = pSkeletonPose->GetAbsJointByID(jointId); m_tempVec3 = pTacticalEntity->GetWorldTM().TransformPoint(boneLocation.t); return m_tempVec3; } } } CUICVars* pCVars = g_pGame->GetUI()->GetCVars(); if (pCVars->hud_InterestPointsAtActorsHeads == 1) { CActor* pActor = static_cast<CActor*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(tacticalEntityId)); // Only want units to go from headbone, since vehicles have headbone as well if(pActor) { if(pActor->HasBoneID(BONE_HEAD)) { QuatT boneLocation = pActor->GetBoneTransform(BONE_HEAD); m_tempVec3 = pTacticalEntity->GetWorldTM().TransformPoint(boneLocation.t) + Vec3(0.0f, 0.0f, 0.25f); inOutIsHeadBone = true; return m_tempVec3; } else if(pActor->HasBoneID(BONE_SPINE)) { QuatT boneLocation = pActor->GetBoneTransform(BONE_SPINE); m_tempVec3 = pTacticalEntity->GetWorldTM().TransformPoint(boneLocation.t); return m_tempVec3; } } } return GetTacticalIconCenterBBoxWorldPos(pTacticalEntity); } else // Override entity exists so it determines position { IEntity* pOverrideEntity = gEnv->pEntitySystem->GetEntity(iter->second); if (pOverrideEntity) { m_tempVec3 = pOverrideEntity->GetWorldPos(); return m_tempVec3; } else { GameWarning("CTacticalManager::GetTacticalIconWorldPos: ID exists in mapping but failed to find entity, defaulting to center bounding box position"); return GetTacticalIconCenterBBoxWorldPos(pTacticalEntity); } } }
virtual void ProcessEvent( EFlowEvent event, SActivationInfo* pActInfo ) { switch ( event ) { case eFE_Initialize: { } break; case eFE_Activate: { ICharacterInstance* pCharacter = NULL; IFacialInstance* pFacialInstance = NULL; IFacialModel* pFacialModel = NULL; IFacialEffectorsLibrary* pLibrary = NULL; IFacialEffector* pEffector = NULL; if ( IsPortActive( pActInfo, EIP_StopLast ) && pActInfo->pEntity ) { if ( m_nChannelId > 0 ) { if ( pActInfo->pEntity ) { pCharacter = pActInfo->pEntity->GetCharacter( 0 ); if ( pCharacter ) { pFacialInstance = pCharacter->GetFacialInstance(); if ( pFacialInstance ) { pFacialInstance->StopEffectorChannel( m_nChannelId, GetPortFloat( pActInfo, EIP_FadeTime ) ); m_nChannelId = -1; } } } } } if ( IsPortActive( pActInfo, EIP_Start ) && pActInfo->pEntity ) { string sEffector = GetPortString( pActInfo, EIP_Name ); if ( !sEffector.empty() ) { if ( sEffector.at( 0 ) == '#' ) { sEffector = sEffector.substr( 1 ); } } if ( pActInfo->pEntity && !sEffector.empty() ) { pCharacter = pActInfo->pEntity->GetCharacter( 0 ); if ( pCharacter ) { pFacialInstance = pCharacter->GetFacialInstance(); if ( pFacialInstance ) { pFacialModel = pFacialInstance->GetFacialModel(); if ( pFacialModel ) { pLibrary = pFacialModel->GetLibrary(); if ( pLibrary ) { pEffector = pLibrary->Find( sEffector ); if ( pEffector ) { m_nChannelId = pFacialInstance->StartEffectorChannel( pEffector, GetPortFloat( pActInfo, EIP_Weight ), GetPortFloat( pActInfo, EIP_FadeTime ), GetPortFloat( pActInfo, EIP_Duration ), GetPortInt( pActInfo, EIP_Repeat ) ); ActivateOutput<float>( pActInfo, EOP_Started, m_nChannelId ); } } } } } } } } break; } }
void CFlashLight::EnableFogVolume(CWeapon* pWeapon, int slot, bool enable) { if (!g_pGameCVars->i_flashlight_has_fog_volume) { return; } if (!m_sharedparams->pFlashLightParams) { return; } IEntity* pFogVolume = 0; if (m_fogVolume == 0) { const Vec3 size = Vec3( m_sharedparams->pFlashLightParams->fogVolumeRadius, m_sharedparams->pFlashLightParams->fogVolumeSize, m_sharedparams->pFlashLightParams->fogVolumeRadius); SEntitySpawnParams fogVolumeParams; fogVolumeParams.pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("FogVolume"); fogVolumeParams.nFlags = ENTITY_FLAG_NO_SAVE; fogVolumeParams.vPosition = Vec3(ZERO); pFogVolume = gEnv->pEntitySystem->SpawnEntity(fogVolumeParams); if (!pFogVolume) { return; } m_fogVolume = pFogVolume->GetId(); SmartScriptTable pProperties; pFogVolume->GetScriptTable()->GetValue("Properties", pProperties); if (pProperties) { pProperties->SetValue("color_Color", m_sharedparams->pFlashLightParams->fogVolumeColor); pProperties->SetValue("GlobalDensity", m_sharedparams->pFlashLightParams->fogVolumeDensity); pProperties->SetValue("Size", size); pProperties->SetValue("FallOffScale", 0.0f); } EntityScripts::CallScriptFunction(pFogVolume, pFogVolume->GetScriptTable(), "OnPropertyChange"); pFogVolume->Activate(true); } else { pFogVolume = gEnv->pEntitySystem->GetEntity(m_fogVolume); } if (!pFogVolume) { return; } const char* attachHelper = "lightFog_term"; const float distance = m_sharedparams->pFlashLightParams->fogVolumeSize * 0.5f; ICharacterInstance* pCharacter = pWeapon->GetEntity()->GetCharacter(slot); if (enable && pCharacter) { IAttachmentManager* pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment* pAttachment = pAttachmentManager->GetInterfaceByName(attachHelper); if (pAttachment) { CEntityAttachment* pEntityAttachment = new CEntityAttachment(); pEntityAttachment->SetEntityId(m_fogVolume); pAttachment->AddBinding(pEntityAttachment); QuatT relative(IDENTITY); relative.t.y = distance; pAttachment->SetAttRelativeDefault(relative); } } pFogVolume->Hide(!enable); }
//------------------------------------------------------------------ void CLam::UpdateTPLaser(float frameTime, CItem* parent) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); const int frameId = gEnv->pRenderer->GetFrameID(); if (s_lastUpdateFrameId != frameId) { // Check how many LAMs to update this frame. float dt = frameTime; // + s_laserUpdateTimeError; const int n = s_lasers.size(); int nActive = 0; for (int i = 0; i < n; ++i) { if (!s_lasers[i]->IsLaserActivated() && !s_lasers[i]->IsLightActivated()) continue; nActive++; } float updatedPerSecond = (nActive / LASER_UPDATE_TIME) + s_laserUpdateTimeError; int updateCount = (int)floorf(updatedPerSecond * dt); if(dt==0.0f) s_laserUpdateTimeError = 0.0f; else s_laserUpdateTimeError = updatedPerSecond - updateCount/dt; s_curLaser %= n; for (int i = 0, j = 0; i < n && j < updateCount ; ++i) { s_curLaser = (s_curLaser + 1) % n; if (!s_lasers[s_curLaser]->IsLaserActivated() && !s_lasers[s_curLaser]->IsLightActivated()) continue; s_lasers[s_curLaser]->SetAllowUpdate(); ++j; } s_lastUpdateFrameId = frameId; } IEntity* pRootEnt = GetEntity(); if (!pRootEnt) return; IEntity *pLaserEntity = m_pEntitySystem->GetEntity(m_pLaserEntityId); // if(!pLaserEntity) // return; const CCamera& camera = gEnv->pRenderer->GetCamera(); Vec3 lamPos = pRootEnt->GetWorldPos(); //pLaserEntity->GetParent()->GetWorldPos(); Vec3 dir = pRootEnt->GetWorldRotation().GetColumn1(); //pLaserEntity->GetParent()->GetWorldRotation().GetColumn1(); bool charNotVisible = false; float dsg1Scale = 1.0f; //If character not visible, laser is not correctly updated if(parent) { if(CActor* pOwner = parent->GetOwnerActor()) { ICharacterInstance* pCharacter = pOwner->GetEntity()->GetCharacter(0); if(pCharacter && !pCharacter->IsCharacterVisible()) charNotVisible = true; } if(parent->GetEntity()->GetClass()==CItem::sDSG1Class) dsg1Scale = 3.0f; } // if (!pLaserEntity->GetParent()) // return; Vec3 hitPos(0,0,0); float laserLength = 0.0f; // HACK??: Use player movement controller locations, or else the laser // pops all over the place when character out of the screen. CActor *pActor = parent->GetOwnerActor(); if (pActor && (!pActor->IsPlayer() || charNotVisible)) { if (IMovementController* pMC = pActor->GetMovementController()) { SMovementState state; pMC->GetMovementState(state); if(!charNotVisible) lamPos = state.weaponPosition; else { float oldZPos = lamPos.z; lamPos = state.weaponPosition; if(m_lastZPos>0.0f) lamPos.z = m_lastZPos; //Stabilize somehow z position (even if not accurate) else lamPos.z = oldZPos; } const float angleMin = DEG2RAD(3.0f); const float angleMax = DEG2RAD(7.0f); const float thr = cosf(angleMax); float dot = dir.Dot(state.aimDirection); if (dot > thr) { float a = acos_tpl(dot); float u = 1.0f - clamp((a - angleMin) / (angleMax - angleMin), 0.0f, 1.0f); dir = dir + u * (state.aimDirection - dir); dir.Normalize(); } } } if(!charNotVisible) m_lastZPos = lamPos.z; lamPos += (dir*0.10f); if (m_allowUpdate) { m_allowUpdate = false; IPhysicalEntity* pSkipEntity = NULL; if(parent->GetOwner()) pSkipEntity = parent->GetOwner()->GetPhysics(); const float range = m_lamparams.laser_range[eIGS_ThirdPerson]*dsg1Scale; // Use the same flags as the AI system uses for visbility. const int objects = ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid|ent_independent; //ent_living; const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (10 & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit); ray_hit hit; if (gEnv->pPhysicalWorld->RayWorldIntersection(lamPos, dir*range, objects, flags, &hit, 1, &pSkipEntity, pSkipEntity ? 1 : 0)) { laserLength = hit.dist; m_lastLaserHitPt = hit.pt; m_lastLaserHitSolid = true; } else { m_lastLaserHitSolid = false; m_lastLaserHitPt = lamPos + dir * range; laserLength = range + 0.1f; } // Hit near plane if (dir.Dot(camera.GetViewdir()) < 0.0f) { Plane nearPlane; nearPlane.SetPlane(camera.GetViewdir(), camera.GetPosition()); nearPlane.d -= camera.GetNearPlane()+0.15f; Ray ray(lamPos, dir); Vec3 out; m_lastLaserHitViewPlane = false; if (Intersect::Ray_Plane(ray, nearPlane, out)) { float dist = Distance::Point_Point(lamPos, out); if (dist < laserLength) { laserLength = dist; m_lastLaserHitPt = out; m_lastLaserHitSolid = true; m_lastLaserHitViewPlane = true; } } } hitPos = m_lastLaserHitPt; } else { laserLength = Distance::Point_Point(m_lastLaserHitPt, lamPos); hitPos = lamPos + dir * laserLength; } if (m_smoothLaserLength < 0.0f) m_smoothLaserLength = laserLength; else { if (laserLength < m_smoothLaserLength) m_smoothLaserLength = laserLength; else m_smoothLaserLength += (laserLength - m_smoothLaserLength) * min(1.0f, 10.0f * frameTime); } float laserAIRange = 0.0f; if (m_laserActivated && pLaserEntity) { // Orient the laser towards the point point. Matrix34 parentTMInv; parentTMInv = pRootEnt->GetWorldTM().GetInverted(); Vec3 localDir = parentTMInv.TransformPoint(hitPos); float finalLaserLen = localDir.NormalizeSafe(); Matrix33 rot; rot.SetIdentity(); rot.SetRotationVDir(localDir); pLaserEntity->SetLocalTM(rot); laserAIRange = finalLaserLen; const float assetLength = 2.0f; finalLaserLen = CLAMP(finalLaserLen,0.01f,m_lamparams.laser_max_len*dsg1Scale); float scale = finalLaserLen / assetLength; // Scale the laser based on the distance. if (m_laserEffectSlot >= 0) { Matrix33 scl; scl.SetIdentity(); scl.SetScale(Vec3(1,scale,1)); pLaserEntity->SetSlotLocalTM(m_laserEffectSlot, scl); } if (m_dotEffectSlot >= 0) { if (m_lastLaserHitSolid) { Matrix34 mt = Matrix34::CreateTranslationMat(Vec3(0,finalLaserLen,0)); if(m_lastLaserHitViewPlane) mt.Scale(Vec3(0.2f,0.2f,0.2f)); pLaserEntity->SetSlotLocalTM(m_dotEffectSlot, mt); } else { Matrix34 scaleMatrix; scaleMatrix.SetIdentity(); scaleMatrix.SetScale(Vec3(0.001f,0.001f,0.001f)); pLaserEntity->SetSlotLocalTM(m_dotEffectSlot, scaleMatrix); } } } float lightAIRange = 0.0f; if (m_lightActivated) { float range = clamp(m_smoothLaserLength, 0.5f, m_lamparams.light_range[eIGS_ThirdPerson]); lightAIRange = range * 1.5f; if (m_lightID[eIGS_ThirdPerson] && m_smoothLaserLength > 0.0f) { CItem* pLightEffect = this; if (IItem *pOwnerItem = m_pItemSystem->GetItem(GetParentId())) pLightEffect = (CItem *)pOwnerItem; pLightEffect->SetLightRadius(range, m_lightID[eIGS_ThirdPerson]); } } if (laserAIRange > 0.0001f || lightAIRange > 0.0001f) UpdateAILightAndLaser(lamPos, dir, lightAIRange, m_lamparams.light_fov[eIGS_ThirdPerson], laserAIRange); }
//------------------------------------------------------------------------ void CItem::UpdateMounted(float frameTime) { IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom(); if (!m_ownerId || !m_stats.mounted) return; CActor *pActor = GetOwnerActor(); if (!pActor) return; CheckViewChange(); if (true) { if (IsClient()) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(eIGS_FirstPerson); if (pCharacter && !m_idleAnimation[eIGS_FirstPerson].empty() && pCharacter->GetISkeletonAnim()->GetNumAnimsInFIFO(0)<1) PlayAction(m_idleAnimation[eIGS_FirstPerson], 0, true); } // need to explicitly update characters at this point // cause the entity system update occered earlier, with the last position for (int i=0; i<eIGS_Last; i++) { if (GetEntity()->GetSlotFlags(i)&ENTITY_SLOT_RENDER) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(i); if (pCharacter) { Matrix34 mloc = GetEntity()->GetSlotLocalTM(i,false); Matrix34 m34 = GetEntity()->GetWorldTM()*mloc; QuatT renderLocation = QuatT(m34); pCharacter->GetISkeletonPose()->SetForceSkeletonUpdate(9); pCharacter->SkeletonPreProcess(renderLocation, renderLocation, GetISystem()->GetViewCamera(),0x55 ); pCharacter->SetPostProcessParameter(renderLocation, renderLocation, 0, 0.0f, 0x55 ); } } } // f32 fColor[4] = {1,1,0,1}; // f32 g_YLine=60.0f; // gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "Mounted Gun Code" ); //adjust the orientation of the gun based on the aim-direction SMovementState info; IMovementController* pMC = pActor->GetMovementController(); pMC->GetMovementState(info); Vec3 dir = info.aimDirection.GetNormalized(); Matrix34 tm = Matrix33::CreateRotationVDir(dir); Vec3 vGunXAxis=tm.GetColumn0(); if (pActor->GetLinkedVehicle()==0) { if (pMC) { if(!pActor->IsPlayer()) { // prevent snapping direction Vec3 currentDir = GetEntity()->GetWorldRotation().GetColumn1(); float dot = currentDir.Dot(dir); dot = CLAMP(dot,-1,1); float reqAngle = cry_acosf(dot); const float maxRotSpeed = 2.0f; float maxAngle = frameTime * maxRotSpeed; if(fabs(reqAngle) > maxAngle) { Vec3 axis = currentDir.Cross(dir); if(axis.GetLengthSquared()>0.001f) // current dir and new dir are enough different dir = currentDir.GetRotated(axis.GetNormalized(),sgn(reqAngle)*maxAngle); } } //adjust the orientation of the gun based on the aim-direction tm = Matrix33::CreateRotationVDir(dir); Vec3 vWPos=GetEntity()->GetWorldPos(); tm.SetTranslation(vWPos); GetEntity()->SetWorldTM(tm); //set the new orientation of the mounted gun vGunXAxis=tm.GetColumn0(); Vec3 vInitialAimDirection = m_stats.mount_dir; Matrix33 vInitialPlayerOrientation = Matrix33::CreateRotationVDir(vInitialAimDirection); assert( vInitialAimDirection.IsUnit() ); Vec3 newp; if (pActor->IsThirdPerson()) { //third person f32 dist = m_mountparams.body_distance*1.3f; Vec3 oldp = pActor->GetEntity()->GetWorldPos(); newp = GetEntity()->GetWorldPos()-vInitialAimDirection*dist; //mounted gun newp.z = oldp.z; } else { //first person f32 fMoveBack = (1.0f+(dir.z*dir.z*dir.z*dir.z*4.0f))*0.75f; f32 dist = m_mountparams.eye_distance*fMoveBack; Vec3 oldp = pActor->GetEntity()->GetWorldPos(); newp = GetEntity()->GetWorldPos()-dir*dist; //mounted gun //newp.z -= 0.75f; newp.z = oldp.z; } Matrix34 actortm(pActor->GetEntity()->GetWorldTM()); //if (pActor->IsThirdPerson()) actortm=vInitialPlayerOrientation; actortm.SetTranslation(newp); pActor->GetEntity()->SetWorldTM(actortm, ENTITY_XFORM_USER); pActor->GetAnimationGraphState()->SetInput("Action","gunnerMounted"); //f32 g_YLine=80.0f; //gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "Mounted Gun Active for FP and AI" ); if (ICharacterInstance *pCharacter = pActor->GetEntity()->GetCharacter(0)) { ISkeletonAnim *pSkeletonAnim = pCharacter->GetISkeletonAnim(); assert(pSkeletonAnim); uint32 numAnimsLayer = pSkeletonAnim->GetNumAnimsInFIFO(0); for(uint32 i=0; i<numAnimsLayer; i++) { CAnimation &animation = pSkeletonAnim->GetAnimFromFIFO(0, i); if (animation.m_AnimParams.m_nFlags & CA_MANUAL_UPDATE) { f32 aimrad = Ang3::CreateRadZ(Vec2(vInitialAimDirection),Vec2(dir)); animation.m_fAnimTime = clamp_tpl(aimrad/gf_PI,-1.0f,+1.0f)*0.5f+0.5f; //if (pActor->IsThirdPerson()==0) //animation.m_fAnimTime=0.6f; //Ivo & Benito: high advanced future code. don't ask what it is //Benito - Not needed any more ;) //f32 g_YLine=100.0f; //gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "AnimTime: %f MyAimAngle: %f deg:% distance:%f", animation.m_fAnimTime, aimrad, RAD2DEG(aimrad),m_mountparams.body_distance ); } } } m_stats.mount_last_aimdir = dir; } } if (ICharacterInstance* pCharInstance = pActor->GetEntity()->GetCharacter(0)) { if (ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim()) { OldBlendSpace ap; if (GetAimBlending(ap)) { pSkeletonAnim->SetBlendSpaceOverride(eMotionParamID_TurnSpeed, 0.5f + 0.5f * ap.m_turn, true); } } } UpdateIKMounted(pActor, vGunXAxis*0.1f); RequireUpdate(eIUS_General); } }
//------------------------------------------------------------------------ bool CItem::SetGeometry(int slot, const ItemString& name, const ItemString& material, bool useParentMaterial, const Vec3& poffset, const Ang3& aoffset, float scale, bool forceReload) { assert(slot >= 0 && slot < eIGS_Last); bool changedfp=false; switch(slot) { case eIGS_Owner: break; case eIGS_FirstPerson: case eIGS_ThirdPerson: default: { if (name.empty() || forceReload) { GetEntity()->FreeSlot(slot); #ifndef ITEM_USE_SHAREDSTRING m_geometry[slot].resize(0); #else m_geometry[slot].reset(); #endif } DestroyAttachmentHelpers(slot); if (!name.empty()) { if (m_geometry[slot] != name) { const char* ext = PathUtil::GetExt(name.c_str()); if ((stricmp(ext, "chr") == 0) || (stricmp(ext, "cdf") == 0) || (stricmp(ext, "cga") == 0) ) GetEntity()->LoadCharacter(slot, name.c_str(), 0); else GetEntity()->LoadGeometry(slot, name.c_str(), 0, 0); changedfp=slot==eIGS_FirstPerson; } CreateAttachmentHelpers(slot); } /* if (slot == eIGS_FirstPerson) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(eIGS_FirstPerson); if (pCharacter) { pCharacter->SetFlags(pCharacter->GetFlags()&(~CS_FLAG_UPDATE)); } } else */if (slot == eIGS_Destroyed) DrawSlot(eIGS_Destroyed, false); } break; } Matrix34 slotTM; slotTM = Matrix34::CreateRotationXYZ(aoffset); slotTM.ScaleColumn(Vec3(scale, scale, scale)); slotTM.SetTranslation(poffset); GetEntity()->SetSlotLocalTM(slot, slotTM); if (changedfp && m_stats.mounted) { if (m_sharedparams->pMountParams && !m_sharedparams->pMountParams->pivot.empty()) { Matrix34 tm=GetEntity()->GetSlotLocalTM(eIGS_FirstPerson, false); Vec3 pivot = GetSlotHelperPos(eIGS_FirstPerson, m_sharedparams->pMountParams->pivot.c_str(), false); tm.AddTranslation(pivot); GetEntity()->SetSlotLocalTM(eIGS_FirstPerson, tm); } GetEntity()->InvalidateTM(); } m_geometry[slot] = name ? name : ItemString(); ReAttachAccessories(); IEntity* pParentEntity = gEnv->pEntitySystem->GetEntity(GetParentId()); IMaterial* pOverrideMaterial = 0; if (!material.empty()) { pOverrideMaterial = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(material.c_str()); } else if (useParentMaterial && pParentEntity) { ICharacterInstance* pParentCharacter = pParentEntity->GetCharacter(slot); IEntityRenderProxy* pParentRenderProxy = static_cast<IEntityRenderProxy*>(pParentEntity->GetProxy(ENTITY_PROXY_RENDER)); if (pParentCharacter) pOverrideMaterial = pParentCharacter->GetIMaterial(); else if (pParentRenderProxy) pOverrideMaterial = pParentRenderProxy->GetSlotMaterial(slot); } if (pOverrideMaterial) { ICharacterInstance* pCharacter = GetEntity()->GetCharacter(slot); IEntityRenderProxy* pRenderProxy = static_cast<IEntityRenderProxy*>(GetEntity()->GetProxy(ENTITY_PROXY_RENDER)); OverrideAttachmentMaterial(pOverrideMaterial, this, slot); if (pCharacter) pCharacter->SetIMaterial_Instance(pOverrideMaterial); else if (pRenderProxy) pRenderProxy->SetSlotMaterial(slot, pOverrideMaterial); } if(slot == eIGS_FirstPerson && IsSelected()) { CActor* pOwnerActor = GetOwnerActor(); IActionController *pActionController = GetActionController(); if(pActionController && pOwnerActor && pOwnerActor->IsClient()) { UpdateScopeContexts(pActionController); } } return true; }
//------------------------------------------------------------------------ EntityEffects::TAttachedEffectId CItem::AttachEffect(int slot, bool attachToAccessory, const char *effectName, const char *helper, const Vec3 &offset, const Vec3 &dir, float scale, bool prime) { if(!g_pGameCVars->i_particleeffects) { return 0; } Vec3 finalOffset(offset); string helperName(helper); if(attachToAccessory) { SEntitySlotInfo slotInfo; QuatT accessoryOffset; accessoryOffset.SetIdentity(); const char* accessoryHelper = ""; const char* accessoryName = NULL; const int numAccessories = m_accessories.size(); for (int curIndex = 0; curIndex < numAccessories; curIndex++) { IEntity* pAccessory = gEnv->pEntitySystem->GetEntity(m_accessories[curIndex].accessoryId); if(pAccessory && pAccessory->GetSlotInfo(slot, slotInfo)) { if(slotInfo.pStatObj) { accessoryOffset.t = slotInfo.pStatObj->GetHelperPos(helper); if(!accessoryOffset.t.IsZero()) { accessoryOffset.q = pAccessory->GetRotation(); accessoryOffset.t += pAccessory->GetPos(); accessoryName = m_accessories[curIndex].pClass->GetName(); break; } } if(slotInfo.pCharacter) { IAttachmentManager *pAttachmentManager = slotInfo.pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helper); if(pAttachment) { accessoryHelper = GetAccessoryParams(m_accessories[curIndex].pClass)->attach_helper.c_str(); accessoryName = m_accessories[curIndex].pClass->GetName(); accessoryOffset = pAttachment->GetAttAbsoluteDefault(); break; } } } } if(accessoryName) { bool validSlot = GetEntity()->GetSlotInfo(slot, slotInfo) && (slotInfo.pCharacter || slotInfo.pStatObj); if (!validSlot || slotInfo.pStatObj) { if (validSlot) { Matrix34 mtx = GetEntity()->GetSlotLocalTM(slot, false) * Matrix34(accessoryOffset); finalOffset += mtx.GetTranslation(); } EntityEffects::SEffectAttachParams attachParams(finalOffset, dir, scale, prime, eIGS_Last); return m_effectsController.AttachParticleEffect(effectName, attachParams); } else if (slotInfo.pCharacter) // bone attachment { ICharacterInstance *pCharacter = slotInfo.pCharacter; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = NULL; helperName = string().Format("%s_%s", helper, accessoryName); pAttachment = pAttachmentManager->GetInterfaceByName(helperName.c_str()); if(!pAttachment) { IAttachment* pAccessoryAttachment = pAttachmentManager->GetInterfaceByName(accessoryHelper); if(pAccessoryAttachment) { const char* bone = pCharacter->GetIDefaultSkeleton().GetJointNameByID(pAccessoryAttachment->GetJointID()); pAttachment = pAttachmentManager->CreateAttachment(helperName.c_str(), CA_BONE, bone); if (pAttachment) { QuatT relative = pAccessoryAttachment->GetAttRelativeDefault(); relative = relative * accessoryOffset; relative.t = relative * finalOffset; finalOffset.zero(); pAttachment->SetAttRelativeDefault(relative); } } } } } } EntityEffects::SEffectAttachParams attachParams(finalOffset, dir, scale, prime, eIGS_Last); return m_effectsController.AttachParticleEffect(effectName, slot, helperName, attachParams); }
void CLaserBeam::FixAttachment(IEntity* pLaserEntity) { m_usingEntityAttachment = false; IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem(); CItem* pOwnerItem = static_cast<CItem*>(pItemSystem->GetItem(m_ownerEntityId)); if (pOwnerItem) { IEntity* pOwnerEntity = pOwnerItem->GetEntity(); IEntity* pAttachedEntity = pOwnerEntity; const char* attach_helper = "laser_term"; Vec3 offset = pOwnerItem->GetSlotHelperPos(m_geometrySlot, attach_helper, false); if(m_geometrySlot == eIGS_FirstPerson) { if(pOwnerItem->IsAccessory()) { EntityId parentId = pOwnerItem->GetParentId(); if(parentId) { if(CItem* pParentItem = static_cast<CItem*>(pItemSystem->GetItem(parentId))) { const SAccessoryParams* pParams = pParentItem->GetAccessoryParams(pAttachedEntity->GetClass()); attach_helper = pParams->attach_helper.c_str(); pAttachedEntity = pParentItem->GetEntity(); } } } if(pAttachedEntity) { ICharacterInstance *pCharacter = pAttachedEntity->GetCharacter(eIGS_FirstPerson); if (pCharacter) { IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pLaserAttachment = pAttachmentManager->GetInterfaceByName(LASER_ATTACH_NAME); if(!pLaserAttachment) { IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(attach_helper); if(pAttachment) { const char* pBone = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton()->GetJointNameByID(pAttachment->GetJointID()); pLaserAttachment = pAttachmentManager->CreateAttachment(LASER_ATTACH_NAME, CA_BONE, pBone); if(pLaserAttachment) { QuatT relative = pAttachment->GetAttRelativeDefault(); if(pOwnerItem->GetEntity() != pAttachedEntity) { Matrix34 mtx(relative); relative.t = relative * offset; } pLaserAttachment->SetAttRelativeDefault(relative); } } } if(pLaserAttachment) { CEntityAttachment* pEntAttach = new CEntityAttachment; pEntAttach->SetEntityId(m_laserEntityId); pLaserAttachment->AddBinding(pEntAttach); pLaserAttachment->HideAttachment(0); m_usingEntityAttachment = true; } } } } if(!m_usingEntityAttachment && pOwnerEntity) { pOwnerEntity->AttachChild(pLaserEntity); pLaserEntity->SetLocalTM(Matrix34::CreateTranslationMat(offset)); } } }
//------------------------------------------------------------------------ void CDebugGun::Update( SEntityUpdateContext& ctx, int update) { if (!IsSelected()) return; static float drawColor[4] = {1,1,1,1}; static const int dx = 5; static const int dy = 15; static const float font = 1.2f; static const float fontLarge = 1.4f; IRenderer* pRenderer = gEnv->pRenderer; IRenderAuxGeom* pAuxGeom = pRenderer->GetIRenderAuxGeom(); pAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags); pRenderer->Draw2dLabel(pRenderer->GetWidth()/5.f, pRenderer->GetHeight()-35, fontLarge, drawColor, false, "Firemode: %s (%.1f)", m_fireModes[m_fireMode].first.c_str(), m_fireModes[m_fireMode].second); ray_hit rayhit; unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any; if (m_fireModes[m_fireMode].first == "pierceability") { flags = (unsigned int)m_fireModes[m_fireMode].second & rwi_pierceability_mask; } // use cam, no need for firing pos/dir CCamera& cam = GetISystem()->GetViewCamera(); if (gEnv->pPhysicalWorld->RayWorldIntersection(cam.GetPosition()+cam.GetViewdir(), cam.GetViewdir()*HIT_RANGE, ent_all, flags, &rayhit, 1)) { IMaterialManager* pMatMan = gEnv->p3DEngine->GetMaterialManager(); IActorSystem* pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem(); IVehicleSystem* pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem(); int x = (int)(pRenderer->GetWidth() *0.5f) + dx; int y = (int)(pRenderer->GetHeight()*0.5f) + dx - dy; // draw normal ColorB colNormal(200,0,0,128); Vec3 end = rayhit.pt + 0.75f*rayhit.n; pAuxGeom->DrawLine(rayhit.pt, colNormal, end, colNormal); pAuxGeom->DrawCone(end, rayhit.n, 0.1f, 0.2f, colNormal); IEntity * pEntity = (IEntity*)rayhit.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY); if(pEntity) { pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)fontLarge, drawColor, false, pEntity->GetName()); } // material const char* matName = pMatMan->GetSurfaceType(rayhit.surface_idx)->GetName(); if (matName[0]) pRenderer->Draw2dLabel((float)x, (y+=dy), (float)font, drawColor, false, "%s (%i)", matName, rayhit.surface_idx); pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.1f m", rayhit.dist); if (pEntity) { IScriptTable* pScriptTable = pEntity->GetScriptTable(); // physics if (IPhysicalEntity* pPhysEnt = pEntity->GetPhysics()) { pe_status_dynamics status; if (pPhysEnt->GetStatus(&status)) { if (status.mass > 0.f) pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.1f kg", status.mass); pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "pe_type: %i", pPhysEnt->GetType()); // PartId - Part name ICharacterInstance* pCharacter = pEntity->GetCharacter(0); if (pCharacter) { CryFixedStringT<64> hit_part("unknown part"); const int FIRST_ATTACHMENT_PARTID = 1000; if (rayhit.partid >= FIRST_ATTACHMENT_PARTID) { IAttachmentManager* pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment* pAttachment = pAttachmentManager->GetInterfaceByIndex(rayhit.partid - FIRST_ATTACHMENT_PARTID); if (pAttachment) { hit_part = pAttachment->GetName(); } } else { ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeletonPose = pCharacter->GetISkeletonPose(); const char* szJointName = pICharacterModelSkeleton->GetJointNameByID(pSkeletonPose->getBonePhysParentOrSelfIndex(rayhit.partid)); if (szJointName && *szJointName) hit_part = szJointName; } pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "partId: %i (%s)", rayhit.partid, hit_part.c_str()); } if (status.submergedFraction > 0.f) pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.2f submerged", status.submergedFraction); if (status.v.len2() > 0.0001f) pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.2f m/s", status.v.len()); } } // class-specific stuff if (IActor* pActor = pActorSystem->GetActor(pEntity->GetId())) { pRenderer->Draw2dLabel((float)x, y+=dy, (float)font, drawColor, false, "%8.2f health", pActor->GetHealth()); } else if (IVehicle* pVehicle = pVehicleSystem->GetVehicle(pEntity->GetId())) { const SVehicleStatus& status = pVehicle->GetStatus(); pRenderer->Draw2dLabel((float)x, y+=dy, (float)font, drawColor, false, "%.0f%% health", 100.f*status.health); pRenderer->Draw2dLabel((float)x, y+=dy, (float)font, drawColor, false, "%i passengers", status.passengerCount); if (pVehicle->GetMovement() && pVehicle->GetMovement()->IsPowered()) { pRenderer->Draw2dLabel((float)x, (float)(y+=dy),(float) font, drawColor, false, "Running"); } } else { if (pScriptTable) { HSCRIPTFUNCTION func = 0; if (pScriptTable->GetValue("GetHealth", func) && func) { float health = 0.f; if (Script::CallReturn(gEnv->pScriptSystem, func, pScriptTable, health)) { pRenderer->Draw2dLabel((float)x, (float)(y+=dy),(float) font, drawColor, false, "%.0f health", health); } } gEnv->pScriptSystem->ReleaseFunc(func); } } } } }
//------------------------------------------------------------------------ //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; }
//------------------------------------------------------------------------ void CReplayActor::ProcessEvent(SEntityEvent &event) { switch (event.event) { case ENTITY_EVENT_PREPHYSICSUPDATE: { const int currentFrameId = gEnv->pRenderer->GetFrameID(); if(currentFrameId==m_lastFrameUpdated) return; m_lastFrameUpdated = currentFrameId; if (m_pActionController) { float frameTime = gEnv->pTimer->GetFrameTime(); m_pActionController->Update(frameTime); } ICharacterInstance* pShadowCharacter = GetShadowCharacter(); if (pShadowCharacter) { QuatTS pose = (QuatTS)GetEntity()->GetWorldTM(); SAnimationProcessParams params; params.locationAnimation = pose; params.bOnRender = 1; params.zoomAdjustedDistanceFromCamera = (GetISystem()->GetViewCamera().GetPosition()-pose.t).GetLength(); pShadowCharacter->StartAnimationProcessing(params); //--- Ensure that we disable the automatic update if we're doing it explicitly pShadowCharacter->SetFlags( pShadowCharacter->GetFlags()&(~CS_FLAG_UPDATE) ); } ICharacterInstance *pCharacter = GetEntity()->GetCharacter(0); ISkeletonPose *pSkelPose = pCharacter ? pCharacter->GetISkeletonPose() : NULL; if(pSkelPose) { ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton(); // GetJointIDByName() returns -1 if it fails; m_headBoneID is initialised to -2 // since -1 is failure and 0+ are valid bone indices. if (m_headBoneID == -2) { // TODO: Should move this to an initialisation function m_headBoneID = pICharacterModelSkeleton->GetJointIDByName("Bip01 Head"); m_cameraBoneID = pICharacterModelSkeleton->GetJointIDByName("Bip01 Camera"); } if (m_headBoneID > -1) { m_headPos = pSkelPose->GetAbsJointByID(m_headBoneID); } if (m_cameraBoneID > -1) { m_cameraPos = pSkelPose->GetAbsJointByID(m_cameraBoneID); } } } break; case ENTITY_EVENT_DONE: case ENTITY_EVENT_RETURNING_TO_POOL: { SAFE_RELEASE(m_pActionController); SAFE_DELETE(m_pAnimContext); m_itemList.OnActionControllerDeleted(); } break; } }
void CHandGrenades::UpdateStowedWeapons() { CActor *pOwnerActor = GetOwnerActor(); if (!pOwnerActor) return; ICharacterInstance *pOwnerCharacter = pOwnerActor->GetEntity()->GetCharacter(0); if (!pOwnerCharacter) return; IStatObj *pTPObj = GetEntity()->GetStatObj(eIGS_ThirdPerson); if (!pTPObj) return; int ammoCount = m_fm ? pOwnerActor->GetInventory()->GetAmmoCount(m_fm->GetAmmoType()) : 0; if (IsSelected() && (ammoCount > 0)) { ammoCount--; } if (!pOwnerActor->IsThirdPerson()) { ammoCount = 0; } int numGrenDiff = ammoCount - m_numStowedCopies; if(numGrenDiff != 0) { if (m_stowSlot < 0) { m_stowSlot = PickStowSlot(pOwnerCharacter->GetIAttachmentManager(), m_sharedparams->params.bone_attachment_01.c_str(), m_sharedparams->params.bone_attachment_02.c_str()); } if (m_stowSlot >= 0) { bool attach = numGrenDiff > 0; int tot = abs(numGrenDiff); IAttachmentManager *pAttachmentManager = pOwnerCharacter->GetIAttachmentManager(); IAttachment *pAttachment = NULL; for (int i=0; i<tot; i++) { //--- Generate the secondary slot from the first by adding one to the attachment name, is all we need at present... const char *attach1 = (m_stowSlot == 0) ? m_sharedparams->params.bone_attachment_01.c_str() : m_sharedparams->params.bone_attachment_02.c_str(); int lenAttachName = strlen(attach1); stack_string attach2(attach1, lenAttachName-1); attach2 += (attach1[lenAttachName-1]+1); if (attach) { pAttachment = pAttachmentManager->GetInterfaceByName(attach1); if(pAttachment && pAttachment->GetIAttachmentObject()) { pAttachment = pAttachmentManager->GetInterfaceByName(attach2); } if (pAttachment && !pAttachment->GetIAttachmentObject()) { CCGFAttachment *pCGFAttachment = new CCGFAttachment(); pCGFAttachment->pObj = pTPObj; pAttachment->AddBinding(pCGFAttachment); pAttachment->HideAttachment(0); pAttachment->HideInShadow(0); m_numStowedCopies++; } } else { pAttachment = pAttachmentManager->GetInterfaceByName(attach2); if(!pAttachment || !pAttachment->GetIAttachmentObject()) { pAttachment = pAttachmentManager->GetInterfaceByName(attach1); } if (pAttachment && pAttachment->GetIAttachmentObject()) { pAttachment->ClearBinding(); m_numStowedCopies--; } } } } } }
void CVehicleWeaponControlled::Update(SEntityUpdateContext& ctx, int update) { IVehicle *pVehicle = m_vehicleId ? gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(m_vehicleId) : NULL; if (!m_vehicleId && GetEntity()->GetParent()) { IEntity *entity = GetEntity(); if (entity) { IEntity *parent = entity->GetParent(); if (parent) { m_vehicleId = parent->GetId(); pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(parent->GetId()); } } } if (pVehicle) { IVehiclePart *pPart = pVehicle->GetWeaponParentPart(GetEntityId()); if(pPart) { if(IVehiclePart *pParentPart = pPart->GetParent()) { CRY_ASSERT(pVehicle->GetEntity()); if(ICharacterInstance *characterInst = pVehicle->GetEntity()->GetCharacter(pParentPart->GetSlot())) { if(ISkeletonPose* pose = characterInst->GetISkeletonPose()) { IDefaultSkeleton& rIDefaultSkeleton = characterInst->GetIDefaultSkeleton(); int16 joint = rIDefaultSkeleton.GetJointIDByName(pPart->GetName()); const QuatT &jQuat = pose->GetAbsJointByID(joint); Matrix34 localT(jQuat); localT.SetTranslation(jQuat.t/* - Vec3(0.0f, 0.75f, 0.0f)*/); Matrix34 vehicleWorldTm = pVehicle->GetEntity()->GetWorldTM(); Matrix34 mat = vehicleWorldTm * localT; Vec3 vehicleSide2 = pPart->GetParent()->GetLocalTM(true, true).GetTranslation(); CPlayer *pl = this->GetOwnerPlayer(); Matrix33 mat2; if (!m_destination.IsEquivalent(ZERO)) { Vec3 diff = GetDestination() - mat.GetTranslation(); //pPart->GetWorldTM().GetTranslation(); diff.Normalize(); Matrix33 loc(mat); loc.Invert(); Vec3 diffLocal = loc.TransformVector(diff); Matrix33 desMat; desMat.SetRotationVDir(diffLocal, 0.0f); Vec3 test = GetEntity()->GetLocalTM().GetColumn0(); Ang3 testTM(desMat); float za = testTM.x - m_Angles.x; za = (za < 0.0f) ? -gf_PI : gf_PI; za *= 0.05f * ctx.fFrameTime; m_Angles.x += za; Limit(m_Angles.x, -gf_PI * 0.33f, gf_PI * 0.33f); if (testTM.z > m_Angles.z + 0.05f) { m_Angles.z += gf_PI * factor1 * ctx.fFrameTime; } else if (testTM.z < m_Angles.z - 0.05f) { m_Angles.z -= gf_PI * factor1 * ctx.fFrameTime; } else { m_Angles.z = testTM.z; } Limit(m_Angles.z, -gf_PI * 0.33f, gf_PI * 0.33f); mat2.SetRotationXYZ(m_Angles); } else { if (!m_FireBlocked) { m_Angles.x = m_Angles.x - ctx.fFrameTime * factor2 * m_Angles.x; m_Angles.z = m_Angles.z - ctx.fFrameTime * factor2 * m_Angles.z; } mat2.SetRotationXYZ(m_Angles); } mat = mat * mat2; GetEntity()->SetWorldTM(mat); if (pl) { Matrix34 worldGunMat = vehicleWorldTm * localT; if (!pl->IsDead()) { Vec3 trans = worldGunMat.GetTranslation() - worldGunMat.GetColumn2() * 0.7f; worldGunMat.SetTranslation(trans); pl->GetEntity()->SetWorldTM(worldGunMat); float dot = mat.GetColumn1().dot(worldGunMat.GetColumn0()); Update3PAnim(pl, 0.5f - dot * 0.5f, ctx.fFrameTime, mat); } else { ICharacterInstance* pCharacter = pl->GetEntity()->GetCharacter(0); int boneId = pCharacter ? pCharacter->GetIDefaultSkeleton().GetJointIDByName("Spine03") : 7; pl->LinkToMountedWeapon(0); if (IVehicleSeat* seat = pVehicle->GetSeatForPassenger(pl->GetEntityId())) { seat->Exit(false, true); } Matrix33 rot(worldGunMat); Vec3 offset(0.0f, 0.0f, 0.70f); Vec3 transformedOff = rot.TransformVector(offset); Vec3 trans = worldGunMat.GetTranslation(); trans -= transformedOff; worldGunMat.SetTranslation(trans); pl->GetEntity()->SetWorldTM(worldGunMat); pl->GetEntity()->SetPos(worldGunMat.GetTranslation()); //worldGunMat.GetTranslation()); pl->RagDollize(true); if (boneId > -1) { IPhysicalEntity *physEnt = pl->GetEntity()->GetPhysics(); if (physEnt) { pe_simulation_params simulationParams; physEnt->GetParams(&simulationParams); pe_params_pos pos; pos.pos = GetEntity()->GetPos(); physEnt->SetParams(&pos); pe_action_impulse impulse; impulse.ipart = boneId; impulse.angImpulse = Vec3(0.0f, 0.0f, 1.0f); impulse.impulse = worldGunMat.GetColumn1() * -1.5f * simulationParams.mass; physEnt->Action(&impulse); } } StopUse(GetOwnerId()); SetOwnerId(0); StopFire(); m_FireBlocked = true; } // IsDead } // pl } // pose } // characterInst } // pParentPart } // pPart } // pVehicle Base::Update(ctx, update); RequireUpdate(eIUS_General); }
//------------------------------------------------------------------------ void CItem::PlayAnimationEx(const char *animationName, int slot, int layer, bool loop, float blend, float speed, uint32 flags) { bool start=true; ICharacterInstance *pCharacter = GetEntity()->GetCharacter(slot); if(!pCharacter && slot==eIGS_FirstPerson && ((m_stats.viewmode&eIVM_FirstPerson)==0)) { start=false; int idx = 0; if(m_stats.hand == eIH_Right) idx = 1; else if(m_stats.hand == eIH_Left) idx = 2; if(m_fpgeometry[idx].name.empty()) idx = 0; pCharacter = m_pItemSystem->GetCachedCharacter(m_fpgeometry[idx].name.c_str()); } if(pCharacter && animationName) { ISkeletonAnim *pSkeletonAnim = pCharacter->GetISkeletonAnim(); if(flags&eIPAF_CleanBlending) { while(pSkeletonAnim->GetNumAnimsInFIFO(layer)>1) { if(!pSkeletonAnim->RemoveAnimFromFIFO(layer, pSkeletonAnim->GetNumAnimsInFIFO(layer)-1)) break; } } if(flags&eIPAF_NoBlend) blend = 0.0f; if(start) { CryCharAnimationParams params; params.m_fTransTime = blend; params.m_nLayerID = layer; params.m_nFlags = (loop?CA_LOOP_ANIMATION:0)|(flags&eIPAF_RestartAnimation?CA_ALLOW_ANIM_RESTART:0)|(flags&eIPAF_RepeatLastFrame?CA_REPEAT_LAST_KEY:0); pSkeletonAnim->StartAnimation(animationName, params); pSkeletonAnim->SetLayerUpdateMultiplier(layer, speed); //pCharacter->GetISkeleton()->SetDebugging( true ); } float duration=0.0f; int animationId = pCharacter->GetIAnimationSet()->GetAnimIDByName(animationName); if(animationId>=0) duration = pCharacter->GetIAnimationSet()->GetDuration_sec(animationId); m_animationTime[slot] = (uint32)(duration*1000.0f/speed); m_animationEnd[slot] = (uint32)(gEnv->pTimer->GetCurrTime()*1000.0f)+m_animationTime[slot]; m_animationSpeed[slot] = speed; } }
void CProceduralContextRagdoll::QueueRagdoll( bool bAlive ) { if( m_targetEntityId == 0 ) { m_targetEntityId = m_entity->GetId(); } IActor* piActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor( m_targetEntityId ); // NOTE: The case where piActor is NULL is when you're - in the CryMann preview! if(piActor) { if( gEnv->bServer && !m_bDispatchedAspectProfile && (piActor->GetGameObject()->GetAspectProfile(eEA_Physics) != eAP_Ragdoll) ) { m_bEntityAlive = bAlive; piActor->GetGameObject()->SetAspectProfile( eEA_Physics, bAlive ? eAP_Sleep : eAP_Ragdoll ); } else if( !m_bInRagdoll || (m_bInRagdoll && !bAlive && m_bEntityAlive) ) { SRagdollizeParams params; params.mass = static_cast<CActor*>(piActor)->GetActorPhysics().mass; params.sleep = m_bEntityAlive = bAlive; params.stiffness = m_stiffness; SGameObjectEvent event( eGFE_QueueRagdollCreation, eGOEF_ToExtensions ); event.ptr = ¶ms; piActor->GetGameObject()->SendEvent( event ); m_bInRagdoll = true; } else { m_bInBlendOut = true; } } #ifndef _RELEASE else { if( IEntity* pEntity = gEnv->pEntitySystem->GetEntity( m_targetEntityId ) ) { ICharacterInstance *pCharacter = pEntity->GetCharacter(0); if (pCharacter) { // dead guys shouldn't blink pCharacter->EnableProceduralFacialAnimation(false); //Anton :: SetDefaultPose on serialization if(gEnv->pSystem->IsSerializingFile() && pCharacter->GetISkeletonPose()) pCharacter->GetISkeletonPose()->SetDefaultPose(); } SEntityPhysicalizeParams pp; pp.fStiffnessScale = m_stiffness; pp.type = PE_ARTICULATED; pp.nSlot = 0; pp.bCopyJointVelocities = true; //never ragdollize without mass [Anton] pp.mass = (float)__fsel(-pp.mass, 80.0f, pp.mass); pe_player_dimensions playerDim; pe_player_dynamics playerDyn; playerDyn.gravity = Vec3( 0.f, 0.f, -15.0f ); playerDyn.kInertia = 5.5f; pp.pPlayerDynamics = &playerDyn; // Joints velocities are copied by default for now pp.bCopyJointVelocities = !gEnv->pSystem->IsSerializingFile(); pp.nFlagsOR = pef_monitor_poststep; pEntity->Physicalize(pp); m_bInRagdoll = true; } } #endif }
//-------------------------------------------------------------------------------------------------- // Name: SpawnParticlesOnSkeleton // Desc: Spawn particles on Skeleton //-------------------------------------------------------------------------------------------------- void CGameEffect::SpawnParticlesOnSkeleton(IEntity* pEntity, IParticleEmitter* pParticleEmitter, uint32 numParticles,float maxHeightScale) const { if((pEntity) && (numParticles>0) && (pParticleEmitter) && (maxHeightScale>0.0f)) { ICharacterInstance* pCharacter = pEntity->GetCharacter(0); if(pCharacter) { IDefaultSkeleton& rIDefaultSkeleton = pCharacter->GetIDefaultSkeleton(); ISkeletonPose* pPose = pCharacter->GetISkeletonPose(); if(pPose) { Vec3 animPos; Quat animRot; IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId()); if(pActor) // First try to get animation data { QuatT animLoc = pActor->GetAnimatedCharacter()->GetAnimLocation(); animPos = animLoc.t; animRot = animLoc.q; } else // If no actor, then use entity data { animPos = pEntity->GetWorldPos(); animRot = pEntity->GetWorldRotation(); } animRot.Invert(); AABB bbox; pEntity->GetLocalBounds(bbox); float bbHeight = bbox.max.z - bbox.min.z; // Avoid division by 0 if(bbHeight == 0) { bbHeight = 0.0001f; } const uint32 numJoints = rIDefaultSkeleton.GetJointCount(); for (uint32 i = 0; i < numParticles; ++i) { int id = cry_random(0U, numJoints - 1); int parentId = rIDefaultSkeleton.GetJointParentIDByID(id); if(parentId>0) { QuatT boneQuat = pPose->GetAbsJointByID(id); QuatT parentBoneQuat= pPose->GetAbsJointByID(parentId); float lerpScale = cry_random(0.0f, 1.0f); QuatTS loc(IDENTITY); loc.t = LERP(boneQuat.t,parentBoneQuat.t,lerpScale); float heightScale = ((loc.t.z - bbox.min.z) / bbHeight); if(heightScale < maxHeightScale) { loc.t = loc.t * animRot; loc.t = loc.t + animPos; pParticleEmitter->EmitParticle(NULL, NULL, &loc); } } } } } } }//-------------------------------------------------------------------------------------------------
ILINE bool InitializePoseAlignerScorcher(PoseAligner::CPose& pose, IEntity& entity, ICharacterInstance& character) { IDefaultSkeleton& rIDefaultSkeleton = character.GetIDefaultSkeleton(); int jointIndexRoot = rIDefaultSkeleton.GetJointIDByName("hips_joint"); if (jointIndexRoot < 0) return false; int jointIndexBackLeft = rIDefaultSkeleton.GetJointIDByName("l_bwd_leg_end_joint"); if (jointIndexBackLeft < 0) return false; int jointIndexBackLeftBlend = rIDefaultSkeleton.GetJointIDByName("planeLockWeightBackLeft"); if (jointIndexBackLeftBlend < 0) return false; int jointIndexBackRight = rIDefaultSkeleton.GetJointIDByName("r_bwd_leg_end_joint"); if (jointIndexBackRight < 0) return false; int jointIndexBackRightBlend = rIDefaultSkeleton.GetJointIDByName("planeLockWeightBackRight"); if (jointIndexBackRightBlend < 0) return false; int jointIndexFrontLeft = rIDefaultSkeleton.GetJointIDByName("l_fwd_leg_end_joint"); if (jointIndexFrontLeft < 0) return false; int jointIndexFrontLeftBlend = rIDefaultSkeleton.GetJointIDByName("planeLockWeightFrontLeft"); if (jointIndexFrontLeftBlend < 0) return false; int jointIndexFrontRight = rIDefaultSkeleton.GetJointIDByName("r_fwd_leg_end_joint"); if (jointIndexFrontRight < 0) return false; int jointIndexFrontRightBlend = rIDefaultSkeleton.GetJointIDByName("planeLockWeightFrontRight"); if (jointIndexFrontRightBlend < 0) return false; if (!pose.Initialize(entity, jointIndexRoot)) return false; pose.SetRootOffsetMinMax(-1.0f, 1.0f); PoseAligner::SChainDesc chainDesc; chainDesc.name = "Left"; chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb; chainDesc.solver = "LftLeg01"; chainDesc.contactJointIndex = jointIndexBackLeft; chainDesc.targetBlendJointIndex = jointIndexBackLeftBlend; chainDesc.offsetMin = Vec3(0.0f, 0.0f, -1.0f); chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.15f); chainDesc.bTargetSmoothing = true; if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity)) { pContactRaycast->SetLength(1.0f); chainDesc.pContactReporter = pContactRaycast; } if (!pose.CreateChain(chainDesc)) return false; chainDesc.name = "Left"; chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb; chainDesc.solver = "RgtLeg01"; chainDesc.contactJointIndex = jointIndexBackRight; chainDesc.targetBlendJointIndex = jointIndexBackRightBlend; chainDesc.offsetMin = Vec3(0.0f, 0.0f, -1.0f); chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.15f); chainDesc.bTargetSmoothing = true; if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity)) { pContactRaycast->SetLength(1.0f); chainDesc.pContactReporter = pContactRaycast; } if (!pose.CreateChain(chainDesc)) return false; chainDesc.name = "FrontLeft"; chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb; chainDesc.solver = "LftArm01"; chainDesc.contactJointIndex = jointIndexFrontLeft; chainDesc.targetBlendJointIndex = jointIndexFrontLeftBlend; chainDesc.offsetMin = Vec3(0.0f, 0.0f, -1.0f); chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.15f); chainDesc.bTargetSmoothing = true; if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity)) { pContactRaycast->SetLength(1.0f); chainDesc.pContactReporter = pContactRaycast; } if (!pose.CreateChain(chainDesc)) return false; chainDesc.name = "FrontRight"; chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb; chainDesc.solver = "RgtArm01"; chainDesc.contactJointIndex = jointIndexFrontRight; chainDesc.targetBlendJointIndex = jointIndexFrontRightBlend; chainDesc.offsetMin = Vec3(0.0f, 0.0f, -1.0f); chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.15f); chainDesc.bTargetSmoothing = true; if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity)) { pContactRaycast->SetLength(1.0f); chainDesc.pContactReporter = pContactRaycast; } if (!pose.CreateChain(chainDesc)) return false; return pose.GetChainCount() != 0; }