//------------------------------------------------------------------------ Matrix34 CVehiclePartAnimated::GetDestroyedGeometryTM(const char* pJointName, unsigned int index) { if (pJointName[0] && m_pCharInstanceDestroyed) { IDefaultSkeleton &rICharacterModelSkeletonDestroyed = m_pCharInstanceDestroyed->GetIDefaultSkeleton(); ISkeletonPose* pSkeletonDestroyed = m_pCharInstanceDestroyed->GetISkeletonPose(); CRY_ASSERT(pSkeletonDestroyed); char buffer[256]; const char* pSuffix = !m_pSharedParameters->m_destroyedSuffix.empty() ? m_pSharedParameters->m_destroyedSuffix.c_str() : GetDestroyedGeometrySuffix(eVGS_Destroyed); if (index == 0) { cry_sprintf(buffer, "%s%s", pJointName, pSuffix); } else { cry_sprintf(buffer, "%s_debris_%u", pJointName, index); } buffer[sizeof(buffer) - 1] = '\0'; int16 jointIdForDestroyed = rICharacterModelSkeletonDestroyed.GetJointIDByName(buffer); if (jointIdForDestroyed > -1) return Matrix34(pSkeletonDestroyed->GetAbsJointByID(jointIdForDestroyed)); } Matrix34 identTM; identTM.SetIdentity(); return identTM; }
Vec3 CVehicleSeatActionOrientateBoneToView::GetCurrentLookPosition() const { ISkeletonPose* pSkeleton = GetSkeleton(); CRY_ASSERT_MESSAGE(pSkeleton, "CVehicleSeatActionOrientateBoneToView::GetCurrentLookPosition - Couldn't get ISkeletonPose from vehicle entity"); QuatT lookQuat = pSkeleton->GetAbsJointByID(m_LookBoneId); return m_pVehicle->GetEntity()->GetWorldPos() + lookQuat.t; }
//------------------------------------------------------------------------ const Matrix33 &CItem::GetSlotHelperRotation(int slot, const char *helper, bool worldSpace, bool relative) { static Matrix33 rotation; rotation.SetIdentity(); IEntity* pEntity = GetEntity(); if(!pEntity) return rotation; SEntitySlotInfo info; if (pEntity->GetSlotInfo(slot, info)) { if (info.pStatObj) { IStatObj *pStatObj = info.pStatObj; rotation = Matrix33(pStatObj->GetHelperTM(helper)); rotation.OrthonormalizeFast(); rotation = Matrix33(GetEntity()->GetSlotLocalTM(slot, false))*rotation; } else if (info.pCharacter) { ICharacterInstance *pCharacter = info.pCharacter; if(!pCharacter) return rotation; IAttachment* pAttachment = pCharacter->GetIAttachmentManager()->GetInterfaceByName(helper); if(pAttachment) { rotation = Matrix33(worldSpace ? pAttachment->GetAttWorldAbsolute().q : pAttachment->GetAttModelRelative().q); return rotation; } else { ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeletonPose = pCharacter->GetISkeletonPose(); int16 id = pICharacterModelSkeleton->GetJointIDByName(helper); if (id > -1) { rotation = relative ? Matrix33(pSkeletonPose->GetRelJointByID(id).q) : Matrix33(pSkeletonPose->GetAbsJointByID(id).q); } } if (!relative) { rotation = Matrix33(pEntity->GetSlotLocalTM(slot, false)) * rotation; } } } if (worldSpace) { rotation = Matrix33(pEntity->GetWorldTM()) * rotation; } return rotation; }
bool CMFXParticleEffect::AttachToCharacter( IEntity& targetEntity, const SMFXParticleEntry& particleParams, const SMFXRunTimeEffectParams& params, const Vec3& dir, float scale ) { if (params.partID >= 0) { //Assume character is loaded in first slot //We could iterate through all available slots, but first one should be good enough ICharacterInstance* pCharacterInstace = targetEntity.GetCharacter(0); ISkeletonPose* pSkeletonPose = pCharacterInstace ? pCharacterInstace->GetISkeletonPose() : NULL; if (pSkeletonPose) { IDefaultSkeleton& rIDefaultSkeleton = pCharacterInstace->GetIDefaultSkeleton(); //It hit the character, but probably in a physicalized attached part, like armor plates, etc if (params.partID >= rIDefaultSkeleton.GetJointCount()) { return false; } //It hit some valid joint, create an attachment const char* boneName = rIDefaultSkeleton.GetJointNameByID(params.partID); TAttachmentName attachmentName; GetNextCharacterAttachmentName(attachmentName); IAttachmentManager* pAttachmentManager = pCharacterInstace->GetIAttachmentManager(); CRY_ASSERT(pAttachmentManager); //Remove the attachment first (in case was created before) pAttachmentManager->RemoveAttachmentByName(attachmentName.c_str()); //Create attachment on nearest hit bone IAttachment* pAttachment = pAttachmentManager->CreateAttachment(attachmentName.c_str(), CA_BONE, boneName, false); if (pAttachment) { //Apply relative offsets const QuatT boneLocation = pSkeletonPose->GetAbsJointByID(params.partID); Matrix34 inverseJointTM = targetEntity.GetWorldTM() * Matrix34(boneLocation); inverseJointTM.Invert(); Vec3 attachmentOffsetPosition = inverseJointTM * params.pos; Quat attachmentOffsetRotation = Quat(inverseJointTM) * targetEntity.GetRotation(); CRY_ASSERT(attachmentOffsetPosition.IsValid()); //CRY_ASSERT(attachmentOffsetRotation.IsUnit()); pAttachment->SetAttRelativeDefault(QuatT(attachmentOffsetRotation, attachmentOffsetPosition)); //Finally attach the effect CEffectAttachment* pEffectAttachment = new CEffectAttachment(particleParams.name.c_str(), Vec3(0,0,0), dir, scale); pAttachment->AddBinding(pEffectAttachment); return true; } } } return false; }
//------------------------------------------------------------------------ Vec3 CItem::GetSlotHelperPos(int slot, const char *helper, bool worldSpace, bool relative) const { Vec3 position(0,0,0); SEntitySlotInfo info; if (GetEntity()->GetSlotInfo(slot, info)) { if (info.pStatObj) { IStatObj *pStatsObj = info.pStatObj; position = pStatsObj->GetHelperPos(helper); position = GetEntity()->GetSlotLocalTM(slot, false).TransformPoint(position); } else if (info.pCharacter) { ICharacterInstance *pCharacter = info.pCharacter; IAttachment* pAttachment = pCharacter->GetIAttachmentManager()->GetInterfaceByName(helper); if (pAttachment) { position = worldSpace ? pAttachment->GetAttWorldAbsolute().t : pAttachment->GetAttModelRelative().t; return position; } else { ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeletonPose = pCharacter->GetISkeletonPose(); int16 id = pICharacterModelSkeleton->GetJointIDByName(helper); if (id > -1) { position = relative ? pSkeletonPose->GetRelJointByID(id).t : pSkeletonPose->GetAbsJointByID(id).t; } } if (!relative) { position = GetEntity()->GetSlotLocalTM(slot, false).TransformPoint(position); } } } if (worldSpace) { position = GetWorldTM().TransformPoint(position); } return position; }
QuatT CScriptbind_Entity::GetJointAbsolute(IEntity *pEntity, mono::string jointName, int characterSlot) { if(ICharacterInstance *pCharacter = pEntity->GetCharacter(characterSlot)) { const IDefaultSkeleton *pDefaultSkeleton = &pCharacter->GetIDefaultSkeleton(); ISkeletonPose *pSkeletonPose = pCharacter->GetISkeletonPose(); if (pSkeletonPose != nullptr) { int16 id = pDefaultSkeleton->GetJointIDByName(ToCryString(jointName)); if(id > -1) return pSkeletonPose->GetAbsJointByID(id); } } return QuatT(); }
void EntityEffects::SpawnParticleWithEntity( const IEntity* pTargetEntity, const int targetSlot, IParticleEffect* pParticleEffect, const char* helperName, const EntityEffects::SEffectSpawnParams& spawnParams ) { SEffectSpawnParams newSpawnParams = spawnParams; if (pTargetEntity) { SEntitySlotInfo slotInfo; if (pTargetEntity->GetSlotInfo(targetSlot, slotInfo)) { if (slotInfo.pStatObj) { //Get helper position from static object const Vec3 localHelperPosition = slotInfo.pStatObj->GetHelperPos(helperName); newSpawnParams.position = pTargetEntity->GetSlotWorldTM(targetSlot).TransformPoint(localHelperPosition); } else if (slotInfo.pCharacter) { //Get helper position from character IAttachmentManager *pAttachmentManager = slotInfo.pCharacter->GetIAttachmentManager(); if (IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helperName)) { newSpawnParams.position = pAttachment->GetAttWorldAbsolute().t; } else { ICharacterModelSkeleton* pICharacterModelSkeleton = slotInfo.pCharacter->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeletonPose = slotInfo.pCharacter->GetISkeletonPose(); Vec3 localJointPosition = ZERO; const int16 jointId = pICharacterModelSkeleton->GetJointIDByName(helperName); if (jointId >= 0) { localJointPosition = pSkeletonPose->GetAbsJointByID(jointId).t; } newSpawnParams.position = pTargetEntity->GetSlotWorldTM(targetSlot).TransformPoint(localJointPosition); } } } } SpawnParticleFX(pParticleEffect, newSpawnParams); }
//-------------------------------------------------------------------------------------------------- // 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); } } } } } } }//-------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------ void CVehiclePartTread::Update(const float frameTime) { FUNCTION_PROFILER( GetISystem(), PROFILE_ACTION ); if (!m_pCharInstance) return; if (m_bForceSetU) { m_bForceSetU = false; m_currentU = m_wantedU + 1.0f; UpdateU(); } ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose(); pSkeletonPose->SetForceSkeletonUpdate(0); if (VehicleCVars().v_staticTreadDeform == 0 && m_pVehicle->GetStatus().speed < 0.001f) { return; } if (frameTime > 0.f && (m_damageRatio >= 1.f || !m_pVehicle->GetGameObject()->IsProbablyVisible() || m_pVehicle->IsProbablyDistant())) { return; } // we need a tread update in next frame pSkeletonPose->SetForceSkeletonUpdate(1); m_pVehicle->NeedsUpdate(); // animate the UV texture according to the wheels speed if (m_uvSpeedMultiplier != 0.0f && frameTime > 0.0f) { IPhysicalEntity* pPhysics = GetEntity()->GetPhysics(); pe_status_wheel wheelStatus; wheelStatus.iWheel = m_lastWheelIndex; if (pPhysics && pPhysics->GetStatus(&wheelStatus) != 0) { m_wantedU += m_uvSpeedMultiplier * (wheelStatus.w * wheelStatus.r * frameTime); m_wantedU -= std::floor(m_wantedU); UpdateU(); } } // deform the tread to follow the wheels QuatT absRoot = pSkeletonPose->GetAbsJointByID(0); for (TWheelInfoVector::const_iterator ite=m_wheels.begin(), end=m_wheels.end(); ite != end; ++ite) { const SWheelInfo& wheelInfo = *ite; const Matrix34& slotTM = GetEntity()->GetSlotLocalTM(wheelInfo.slot, true); VALIDATE_MAT(slotTM); if (m_operatorQueue) { m_operatorQueue->PushPosition(wheelInfo.jointId, IAnimationOperatorQueue::eOp_Override, slotTM.GetTranslation()); } #if ENABLE_VEHICLE_DEBUG if (VehicleCVars().v_debugdraw == 4) { Vec3 local = GetEntity()->GetWorldTM().GetInverted() * slotTM.GetTranslation(); gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(GetEntity()->GetWorldTM() * (local+Vec3((float)sgn(local.x)*0.5f,0.f,0.f)),0.1f,ColorB(0,0,255,255)); } #endif } ISkeletonAnim* pSkeletonAnim = m_pCharInstance->GetISkeletonAnim(); pSkeletonAnim->PushPoseModifier(VEH_ANIM_POSE_MODIFIER_LAYER, m_operatorQueue, "VehiclePartAnimatedJoint"); }
void CAutoAimManager::UpdateTargetInfo(SAutoaimTarget& aaTarget, float fFrameTime) { IEntity * pTargetEntity = gEnv->pEntitySystem->GetEntity(aaTarget.entityId); if(pTargetEntity) { CActorPtr pTargetActor = aaTarget.pActorWeak.lock(); if (pTargetActor) { Vec3 characterPos; Quat characterRot; //Need this because of decouple catch-up movement if (IAnimatedCharacter* pAnimatedCharacter = pTargetActor->GetAnimatedCharacter()) { const QuatT& animationLocation = pAnimatedCharacter->GetAnimLocation(); characterPos = animationLocation.t; characterRot = animationLocation.q; } else { const Matrix34& targetWorldTM = pTargetEntity->GetWorldTM(); //Fallback to entity position characterPos = targetWorldTM.GetTranslation(); characterRot = Quat(targetWorldTM); } Vec3 primaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset); Vec3 secondaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset); if (aaTarget.primaryBoneId >= 0) { if (pTargetActor->HasBoneID(aaTarget.primaryBoneId)) { primaryOffset = pTargetActor->GetBoneTransform(aaTarget.primaryBoneId).t; } else { GameWarning("CAutoAimManager: Character %s missing primary boneID: %s", pTargetEntity->GetName(), s_BONE_ID_NAME[aaTarget.primaryBoneId]); aaTarget.primaryBoneId = -1; } } if (aaTarget.secondaryBoneId >= 0) { if (pTargetActor->HasBoneID(aaTarget.secondaryBoneId)) { secondaryOffset = pTargetActor->GetBoneTransform(aaTarget.secondaryBoneId).t; } else { GameWarning("CAutoAimManager: Character %s missing secondary boneID: %s", pTargetEntity->GetName(), s_BONE_ID_NAME[aaTarget.secondaryBoneId]); aaTarget.secondaryBoneId = -1; } } aaTarget.primaryAimPosition = characterPos + (characterRot * primaryOffset); aaTarget.secondaryAimPosition = characterPos + (characterRot * secondaryOffset); //Update hostility (changes during gameplay) if (!gEnv->bMultiplayer) { uint8 targetFaction = (aaTarget.aiFaction != IFactionMap::InvalidFactionID) ? aaTarget.aiFaction : GetTargetFaction(*pTargetEntity); if (gEnv->pAISystem->GetFactionMap().GetReaction(GetLocalPlayerFaction(), aaTarget.aiFaction) == IFactionMap::Hostile) { aaTarget.SetFlag(eAATF_AIHostile); } else { aaTarget.RemoveFlag(eAATF_AIHostile); } aaTarget.aiFaction = targetFaction; } } else if(aaTarget.hasSkeleton) { //Not an actor but has a skeleton (and so can use bone offsets) ISkeletonPose* pSkeletonPose = pTargetEntity->GetCharacter(0)->GetISkeletonPose(); const Matrix34& characterMat = pTargetEntity->GetWorldTM(); const Vec3 characterPos = characterMat.GetTranslation(); const Quat characterRot(characterMat); Vec3 primaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset); Vec3 secondaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset); if (aaTarget.primaryBoneId >= 0) { primaryOffset = pSkeletonPose->GetAbsJointByID(aaTarget.primaryBoneId).t; } if (aaTarget.secondaryBoneId >= 0) { secondaryOffset = pSkeletonPose->GetAbsJointByID(aaTarget.secondaryBoneId).t; } aaTarget.primaryAimPosition = characterPos + (characterRot * primaryOffset); aaTarget.secondaryAimPosition = characterPos + (characterRot * secondaryOffset); } else { //Must be an object const Matrix34& entityWorldTM = pTargetEntity->GetWorldTM(); Vec3 primaryPosition = entityWorldTM.GetTranslation(); Vec3 secondaryPosition = entityWorldTM.TransformPoint(Vec3(0.0f, 0.0f, 0.5f)); AABB entityLocalBBox; pTargetEntity->GetLocalBounds(entityLocalBBox); if (!entityLocalBBox.IsEmpty()) { const Vec3 offset (0.0f, 0.0f, entityLocalBBox.GetRadius() * 0.2f); const Vec3 objectCenter = entityLocalBBox.GetCenter(); primaryPosition = entityWorldTM.TransformPoint((objectCenter - offset)); secondaryPosition = entityWorldTM.TransformPoint((objectCenter + offset)); } aaTarget.primaryAimPosition = primaryPosition; aaTarget.secondaryAimPosition = secondaryPosition; } //The physics drags the render proxy and entity behind it. If we auto aim at the render position, // we will handicap the console players by failing to let them aim ahead of the target. if(IPhysicalEntity * pPhysicalEntity = pTargetEntity->GetPhysics()) { pe_status_dynamics dyn; if(pPhysicalEntity->GetStatus(&dyn)) { Vec3 lookAhead = (dyn.v * fFrameTime); aaTarget.primaryAimPosition = aaTarget.primaryAimPosition + lookAhead; aaTarget.secondaryAimPosition = aaTarget.secondaryAimPosition + lookAhead; } } } }
//------------------------------------------------------------------------ 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; } }
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; }
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); } } }
void CHUDTagNames::DrawTagName(IActor *pActor,bool bLocalVehicle) { CRY_ASSERT(pActor); if(!pActor) return; IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); CGameRules *pGameRules = g_pGame->GetGameRules(); int iClientTeam = pGameRules->GetTeam(pClientActor->GetEntityId()); if(!bLocalVehicle && pActor->GetLinkedVehicle()) return; const char *szRank = GetPlayerRank(pActor->GetEntityId()); IEntity *pEntity = pActor->GetEntity(); if(!pEntity) return; char szText[HUD_MAX_STRING_SIZE]; if(szRank) { sprintf(szText,"%s %s",szRank,pEntity->GetName()); } else { sprintf(szText,"%s",pEntity->GetName()); } ICharacterInstance *pCharacterInstance = pEntity->GetCharacter(0); if(!pCharacterInstance) return; ISkeletonPose *pSkeletonPose = pCharacterInstance->GetISkeletonPose(); if(!pSkeletonPose) return; int16 sHeadID = pSkeletonPose->GetJointIDByName("Bip01 Head"); if(-1 == sHeadID) return; Matrix34 matWorld = pEntity->GetWorldTM() * Matrix34(pSkeletonPose->GetAbsJointByID(sHeadID)); Vec3 vWorldPos = matWorld.GetTranslation(); // Who has a bigger head? :) vWorldPos.z += 0.4f; AABB box; pEntity->GetWorldBounds(box); bool bDrawOnTop = bLocalVehicle; if(ProjectOnSphere(vWorldPos,box)) { bDrawOnTop = true; } ColorF rgbTagName = COLOR_ENEMY; if(0 == iClientTeam) { if(IsFriendlyToClient(pActor->GetEntityId())) { rgbTagName = COLOR_FRIEND; } } else if(pGameRules->GetTeam(pActor->GetEntityId()) == iClientTeam) { rgbTagName = COLOR_FRIEND; } if(pActor->GetHealth() <= 0) { rgbTagName = COLOR_DEAD; } m_tagNamesVector.resize(1); for(std::vector<EntityId>::iterator iter=SAFE_HUD_FUNC_RET(GetRadar()->GetSelectedTeamMates())->begin(); iter!=SAFE_HUD_FUNC_RET(GetRadar()->GetSelectedTeamMates())->end(); ++iter) { if(pActor->GetEntityId() == *iter) { // Teammate is selected in radar, force the visibility of that name bDrawOnTop = true; break; } } STagName *pTagName = &m_tagNamesVector[0]; pTagName->strName = szText; pTagName->vWorld = vWorldPos; pTagName->bDrawOnTop = bDrawOnTop; pTagName->rgb = rgbTagName; DrawTagNames(); }