Beispiel #1
0
void CAICorpseManager::DebugDraw()
{
	if(g_pGameCVars->g_aiCorpses_DebugDraw == 0)
		return;

	IRenderAuxGeom* pRenderAux = gEnv->pRenderer->GetIRenderAuxGeom();

	gEnv->pRenderer->Draw2dLabel( 50.0f, 50.0f, 1.5f, Col_White, false, "Corpse count %" PRISIZE_T " - Max %d", m_corpsesArray.size(), m_maxCorpses );

	for(size_t i = 0; i < m_corpsesArray.size(); ++i)
	{
		CorpseInfo& corpse = m_corpsesArray[i];

		CAICorpse* pCorpse = corpse.GetCorpse();
		if(pCorpse != NULL)
		{
			AABB corpseBbox;
			pCorpse->GetEntity()->GetWorldBounds(corpseBbox);
			const Vec3 refPosition = corpseBbox.IsEmpty() ? pCorpse->GetEntity()->GetWorldPos() : corpseBbox.GetCenter();

			gEnv->pRenderer->DrawLabel( refPosition, 1.5f, "%s\nPriority %d\n%s\n%s", 
				pCorpse->GetEntity()->GetName(), pCorpse->GetPriority(),
				corpse.flags.AreAnyFlagsActive( CorpseInfo::eFlag_FarAway ) ? "Far away, remove when not visible" : "Not far away",
				corpse.flags.AreAllFlagsActive( CorpseInfo::eFlag_PhysicsDisabled) ? "Physics disabled" : "Physics enabled" );
			pRenderAux->DrawCone( refPosition + Vec3(0.0f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, -1.0f), 0.3f, 0.8f, Col_Red );
		}
	}
}
//------------------------------------------------------------------------
int CScriptBind_Game::RegisterWithAutoAimManager(IFunctionHandler *pH, ScriptHandle entityId, float innerRadiusFactor, float outerRadiusFactor, float snapRadiusFactor)
{
	IEntity* pEntity = gEnv->pEntitySystem->GetEntity((EntityId)entityId.n);
	if (pEntity)
	{
		AABB entityBbox;
		pEntity->GetWorldBounds(entityBbox);

		const float entityRadius = (entityBbox.IsEmpty() == false) ? entityBbox.GetRadius() : 1.0f;
		SAutoaimTargetRegisterParams registerParams;
		registerParams.fallbackOffset = 0.0f;
		registerParams.innerRadius = entityRadius * innerRadiusFactor;
		registerParams.outerRadius = entityRadius * outerRadiusFactor;
		registerParams.snapRadius = entityRadius * snapRadiusFactor;
		registerParams.snapRadiusTagged = entityRadius;
		registerParams.primaryBoneId = -1;
		registerParams.physicsBoneId = -1;
		registerParams.secondaryBoneId = -1;
		
		g_pGame->GetAutoAimManager().RegisterAutoaimTargetObject((EntityId)entityId.n, registerParams);
	}

	return pH->EndFunction();
}
Beispiel #3
0
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;
			}
		}
	}
}
//------------------------------------------------------------------------
bool CTracer::Update(float frameTime, const Vec3 &camera, const float fovScale)
{
	frameTime							= (float)__fsel(-m_age, 0.002f, frameTime);
	const float tracerAge	= (float)__fsel(-m_age, 0.002f, m_age+frameTime);

	m_age = tracerAge;

	if (tracerAge >= m_lifeTime)
		return false;

	Vec3 currentLimitDestination;
	if (gEnv->bMultiplayer)
	{
		if(m_tracerFlags & kTracerFlag_updateDestFromBullet)
		{
			IEntity* pBulletEntity = gEnv->pEntitySystem->GetEntity(m_boundToBulletId);
			if(pBulletEntity)
			{
				m_dest = pBulletEntity->GetPos();
			}
		}
		currentLimitDestination = m_dest;
	}
	else
	{
		IEntity* pBulletEntity = gEnv->pEntitySystem->GetEntity(m_boundToBulletId);
		currentLimitDestination = pBulletEntity ? pBulletEntity->GetPos() : m_dest;
	}

	const Vec3 maxTravelledDistance = m_dest - m_startingPos;
	const float maxTravelledDistanceSqr = maxTravelledDistance.len2();
	
	float dist = sqrt_tpl(maxTravelledDistanceSqr);
	if (dist <= 0.001f)
		return false;
		
	const Vec3 dir = maxTravelledDistance * (float)__fres(dist);
	Vec3 pos = m_pos;
	float lengthScale = 1.f;
	Vec3 newPos = m_pos;
	
	if (!(m_tracerFlags & kTracerFlag_dontTranslate))
  {
    const float sqrRadius = GetGameConstCVar(g_tracers_slowDownAtCameraDistance) * GetGameConstCVar(g_tracers_slowDownAtCameraDistance);
		const float cameraDistance = (m_pos-camera).len2();
    const float speed = m_speed * (float)__fsel(sqrRadius - cameraDistance, 0.35f + (cameraDistance/(sqrRadius*2)), 1.0f); //Slow down tracer when near the player
    newPos += dir * min(speed*frameTime, dist);
	  pos = newPos;

		if(m_slideFrac > 0.f)
		{
			pos += (((2.f * cry_frand()) - 0.5f) * m_slideFrac * speed * frameTime * dir);
		}
  }

	// Now update visuals...
	if (IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_entityId))
	{
		AABB tracerBbox;
		pEntity->GetWorldBounds(tracerBbox);

		float tracerHalfLength = !tracerBbox.IsEmpty() ? tracerBbox.GetRadius() : 0.0f;
		const Vec3 frontOfTracerPos = pos + (dir * tracerHalfLength);

		if((frontOfTracerPos-m_startingPos).len2() > maxTravelledDistanceSqr)
		{
			return false;
		}
	
		if (!(m_tracerFlags & kTracerFlag_dontTranslate) && tracerHalfLength > 0.f)
		{
			//Ensure that never goes in front of the bullet
			const Vec3 dirFromFrontOfTracerToDestination = currentLimitDestination - frontOfTracerPos;
			if (dir.dot(dirFromFrontOfTracerToDestination) < 0)
			{
				pos += dirFromFrontOfTracerToDestination;
			}

			// ... and check if back of tracer is behind starting point, so adjust length.
			const Vec3 backOfTracerPos = pos - (dir * tracerHalfLength);
			const Vec3 dirFromBackOfTracerToStart = m_startingPos - backOfTracerPos;

			if (dir.dot(dirFromBackOfTracerToStart) > 0)
			{
				if(dir.dot((m_startingPos - pos)) > 0)
				{
					pos = m_startingPos + (dir * cry_frand() * tracerHalfLength);
				}

				lengthScale = ((pos - m_startingPos).GetLength() / tracerHalfLength);
			}
		}
		
		m_pos = newPos;
		
		Matrix34 tm(Matrix33::CreateRotationVDir(dir));
		tm.AddTranslation(pos);

		pEntity->SetWorldTM(tm);

		//Do not scale effects
		if((m_tracerFlags & kTracerFlag_useGeometry))
		{
			float finalFovScale = fovScale;
			if((m_tracerFlags & kTracerFlag_scaleToDistance) != 0)
			{
				lengthScale = dist * 0.5f;
			}
			else
			{
				const float cameraDistanceSqr = (m_pos-camera).len2();
				const float minScale = GetGameConstCVar(g_tracers_minScale);
				const float maxScale = GetGameConstCVar(g_tracers_maxScale);
				const float minDistanceRange = GetGameConstCVar(g_tracers_minScaleAtDistance) * GetGameConstCVar(g_tracers_minScaleAtDistance);
				const float maxDistanceRange = max(GetGameConstCVar(g_tracers_maxScaleAtDistance) * GetGameConstCVar(g_tracers_maxScaleAtDistance), minDistanceRange + 1.0f);
				const float currentRefDistance = clamp(cameraDistanceSqr, minDistanceRange, maxDistanceRange);

				const float distanceToCameraFactor = ((currentRefDistance - minDistanceRange) / (maxDistanceRange - minDistanceRange));
				const float distanceToCameraScale = LERP(minScale, maxScale, distanceToCameraFactor);
				
				lengthScale = m_scale * distanceToCameraScale;
				finalFovScale *= distanceToCameraScale;
			}
			
			const float widthScale = fovScale;

			tm.SetIdentity();
			tm.SetScale(Vec3(m_scale * finalFovScale, lengthScale, m_scale * finalFovScale));
			pEntity->SetSlotLocalTM(m_geometrySlot,tm);
		}
	}

	return true;
}
void CPlayerVisTable::DoVisibilityCheck(const Vec3& localPlayerPosn, SVisTableEntry& visInfo, VisEntryIndex visIndex)
{
	Vec3 vecToTarget;

	IEntity * pEntity = gEnv->pEntitySystem->GetEntity(visInfo.entityId);

	if(pEntity)
	{
		IPhysicalEntity* pTargetPhysEnt = pEntity->GetPhysics();

		SDeferredLinetestBuffer& targetBuffer = m_linetestBuffers[GetCurrentLinetestBufferTargetIndex()];

		if(targetBuffer.m_numLinetestsCurrentlyProcessing < kMaxVisTableLinetestsPerFrame)
		{
			visInfo.framesSinceLastCheck = 0;

			SDeferredLinetestReceiver * processingEntry = GetAvailableDeferredLinetestReceiver(targetBuffer);

			assert(processingEntry);

			Vec3 targetPosn = pEntity->GetWorldPos();
			if (visInfo.flags & eVF_CheckAgainstCenter)
			{
				AABB targetBbox;
				pEntity->GetWorldBounds(targetBbox);
				if (!targetBbox.IsEmpty())
				{
					targetPosn = targetBbox.GetCenter();
				}
				float radius = min(min(targetBbox.max.x-targetBbox.min.x, targetBbox.max.y-targetBbox.min.y), targetBbox.max.z-targetBbox.min.z);
				targetPosn += (localPlayerPosn-targetPosn).GetNormalized() * radius * 0.25f;
			}
			targetPosn.z += visInfo.heightOffset;
			vecToTarget = targetPosn - localPlayerPosn;

			processingEntry->visTableIndex = visIndex;			

			ray_hit hit;
			const int rayFlags = rwi_colltype_any(geom_colltype_solid&(~geom_colltype_player)) | rwi_ignore_noncolliding | rwi_pierceability(PIERCE_GLASS);

			m_numLinetestsThisFrame++;
			targetBuffer.m_numLinetestsCurrentlyProcessing++;

			visInfo.flags |= eVF_Pending;
			visInfo.flags &= ~eVF_CheckAgainstCenter;

			processingEntry->visBufferIndex = m_currentBufferTarget;

			const int numEntries = kMaxNumIgnoreEntities + 1; 
			IPhysicalEntity* pSkipEnts[numEntries];
			int numSkipEnts = 0;

			if(pTargetPhysEnt)
			{
				pSkipEnts[numSkipEnts] = pTargetPhysEnt;
				numSkipEnts++;
			}
			if (m_currentNumIgnoreEntities)
			{
				for(int i = 0; i < m_currentNumIgnoreEntities; ++i)
				{
					SIgnoreEntity& ignoreEnt = m_globalIgnoreEntities[i];
					CRY_ASSERT(ignoreEnt.id); 

					IEntity* pIgnoreEntity = gEnv->pEntitySystem->GetEntity(ignoreEnt.id);
					IPhysicalEntity* pIgnorePhysicsEntity = pIgnoreEntity ? pIgnoreEntity->GetPhysics() : NULL;

					if (pIgnorePhysicsEntity)
					{
						pSkipEnts[numSkipEnts] = pIgnorePhysicsEntity;
						numSkipEnts++;
					}
				}
			}
			
			CRY_ASSERT(processingEntry->queuedRayID == 0);

			processingEntry->queuedRayID = g_pGame->GetRayCaster().Queue(
				RayCastRequest::HighPriority,
				RayCastRequest(localPlayerPosn, vecToTarget,
				ent_terrain|ent_static|ent_sleeping_rigid|ent_rigid,
				rayFlags,
				pSkipEnts,
				numSkipEnts, 2),
				functor(*processingEntry, &SDeferredLinetestReceiver::OnDataReceived));

#if ALLOW_VISTABLE_DEBUGGING
			m_debugDraw.UpdateDebugTarget(visInfo.entityId, targetPosn, ((visInfo.flags & eVF_Visible) != 0));
#endif

		}
	}
	else
	{
		visInfo.flags |= eVF_Remove;
	}
}