void CAIDebugRenderer::SetDepthWrite(bool bOn) { IRenderAuxGeom* pRenderAuxGeom = m_pRenderer->GetIRenderAuxGeom(); SAuxGeomRenderFlags flags = pRenderAuxGeom->GetRenderFlags(); flags.SetDepthWriteFlag(bOn ? e_DepthWriteOn : e_DepthWriteOff); pRenderAuxGeom->SetRenderFlags(flags); }
void CSmokeManager::DrawSmokeDebugSpheres() { if(g_pGameCVars->g_debugSmokeGrenades) { SAuxGeomRenderFlags oldFlags = gEnv->pRenderer->GetIRenderAuxGeom()->GetRenderFlags(); SAuxGeomRenderFlags newFlags = oldFlags; newFlags.SetAlphaBlendMode(e_AlphaBlended); gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(newFlags); const int kNumActiveSmokeInstances = m_numActiveSmokeInstances; ColorB smokeDebugColor(255, 0, 0, 70); for(int i = 0; i < kNumActiveSmokeInstances; i++) { //DRAW SPHERE SSmokeInstance& smokeInstance = m_smokeInstances[i]; gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(smokeInstance.vPositon, smokeInstance.fCurrentRadius, smokeDebugColor); } gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(oldFlags); // Draw blur amount to screen ColorF textCol(0.0f,1.0f,0.0f,1.0f); gEnv->pRenderer->Draw2dLabel(50.0f,20.0f,1.4f,&textCol.r,false,"Client Blur Amount: %f",m_clientBlurAmount); } }
void CAIDebugRenderer::SetBackFaceCulling(bool bOn) { IRenderAuxGeom* pRenderAuxGeom = m_pRenderer->GetIRenderAuxGeom(); SAuxGeomRenderFlags flags = pRenderAuxGeom->GetRenderFlags(); flags.SetCullMode(bOn ? e_CullModeBack : e_CullModeNone); pRenderAuxGeom->SetRenderFlags(flags); }
void CAIDebugRenderer::SetDrawInFront(bool bOn) { IRenderAuxGeom* pRenderAuxGeom = m_pRenderer->GetIRenderAuxGeom(); SAuxGeomRenderFlags flags = pRenderAuxGeom->GetRenderFlags(); flags.SetDrawInFrontMode(bOn ? e_DrawInFrontOn : e_DrawInFrontOff); pRenderAuxGeom->SetRenderFlags(flags); }
void CAIDebugRenderer::SetAlphaBlended(bool bOn) { IRenderAuxGeom* pRenderAuxGeom = m_pRenderer->GetIRenderAuxGeom(); SAuxGeomRenderFlags flags = pRenderAuxGeom->GetRenderFlags(); flags.SetAlphaBlendMode(bOn ? e_AlphaBlended : e_AlphaNone); pRenderAuxGeom->SetRenderFlags(flags); }
void Draw() { IRenderAuxGeom* pRender = gEnv->pRenderer->GetIRenderAuxGeom(); SAuxGeomRenderFlags flags = pRender->GetRenderFlags(); SAuxGeomRenderFlags oldFlags = pRender->GetRenderFlags(); flags.SetDepthWriteFlag(e_DepthWriteOff); flags.SetDepthTestFlag(e_DepthTestOff); pRender->SetRenderFlags(flags); m_timer += gEnv->pTimer->GetFrameTime(); if (m_timer>30.f) m_timer = 0.f; float time = gEnv->pTimer->GetCurrTime(); float dt = (1.f/50.f); Vec3 offset = Vec3(0.f, 0.f, 0.025f + 0.003f*sinf(8.f*m_timer)); Vec3 offset2 = Vec3(0.f, 0.f, 0.035f + 0.003f*sinf(5.f*m_timer)); ColorB desiredColour = ColorB(255,0,0,255); // Red ColorB desiredVelColour = ColorB(255,(int)(128.f+127.f*sinf(8.f*m_timer)),0,255); // Yellow/Red ColorB actualPosColour = ColorB(0,255,0,255); // Green ColorB actualVelColour = ColorB(0,0,(int)(128.f+127.f*sinf(5.f*m_timer)),255); // blue/black ColorB snapPosColour = ColorB(255,255,255,255); // White ColorB lerpErrorColour = ColorB(255,0,0,255); // Red // Draw the desired positions for (unsigned int i=0; i<m_desired.size(); i++) { Desired &d = m_desired[i]; pRender->DrawSphere(d.pos + offset, 0.025f, desiredColour); pRender->DrawLine(d.pos + offset, desiredVelColour, d.pos + offset + d.vel*dt, desiredVelColour); } if(g_pGameCVars->pl_debugInterpolation == 1) // Show entity position + velocity { for (unsigned int i=0; i<m_actual.size(); i++) { Actual &a = m_actual[i]; pRender->DrawSphere(a.pos + offset2, 0.025f, a.snapped ? snapPosColour : actualPosColour); pRender->DrawLine(a.pos + offset2, actualVelColour, a.pos + offset2 + a.vel*dt, actualVelColour); } } if(g_pGameCVars->pl_debugInterpolation == 2) // Show entity position + lerpError { for (unsigned int i=0; i<m_actual.size(); i++) { Actual &a = m_actual[i]; pRender->DrawSphere(a.pos + offset2, 0.025f, a.snapped ? snapPosColour : actualPosColour); pRender->DrawLine(a.pos + offset2, lerpErrorColour, a.pos + offset2 + a.lerpError, lerpErrorColour); } } pRender->SetRenderFlags(oldFlags); }
void SDebugCannonBallPenetration::Update(float frameTime) { IRenderAuxGeom* pRenderAux = gEnv->pRenderer->GetIRenderAuxGeom(); SAuxGeomRenderFlags oldFlags = pRenderAux->GetRenderFlags(); SAuxGeomRenderFlags newFlags = e_Def3DPublicRenderflags; newFlags.SetAlphaBlendMode(e_AlphaBlended); newFlags.SetDepthTestFlag(e_DepthTestOff); newFlags.SetCullMode(e_CullModeNone); pRenderAux->SetRenderFlags(newFlags); const float baseDebugTimeOut = (g_pGameCVars->g_bulletPenetrationDebugTimeout > 0.0f) ? g_pGameCVars->g_bulletPenetrationDebugTimeout : DEFAULT_DEBUG_CannonBall_HIT_LIFETIME; for (int i = 0; i < MAX_DEBUG_CannonBall_HITS; ++i) { SDebugCannonBallHit& currentHit = m_hitsList[i]; if (currentHit.lifeTime <= 0.0f) { continue; } currentHit.lifeTime -= frameTime; //const float alpha = powf((currentHit.lifeTime / baseDebugTimeOut), 4.0f); // avoid powf whenever possible, for such simple cases, can do with 2 muls float alpha = (currentHit.lifeTime / baseDebugTimeOut); alpha *= alpha; alpha *= alpha; const ColorB red(255, 0, 0, (uint8)(192 * alpha)), green(0, 255, 0, (uint8)(192 * alpha)); const ColorB& hitColor = currentHit.stoppedCannonBall ? red : green; const Vec3 coneBase = currentHit.isBackFaceHit ? (currentHit.hitPosition + (currentHit.CannonBallDirection * 0.3f)) : (currentHit.hitPosition - (currentHit.CannonBallDirection * 0.2f)) ; const Vec3 lineEnd = (coneBase - (currentHit.CannonBallDirection * 0.3f)); pRenderAux->DrawCone(coneBase, currentHit.CannonBallDirection, 0.12f, 0.2f, hitColor); pRenderAux->DrawLine(coneBase, hitColor, lineEnd, hitColor, 3.0f); const Vec3 baseText = (currentHit.isBackFaceHit) ? coneBase + (0.2f * currentHit.CannonBallDirection) : lineEnd - (0.3f * currentHit.CannonBallDirection); const Vec3 textLineOffset(0.0f, 0.0f, 0.14f); const float textColor[4] = {1.0f, 1.0f, 1.0f, alpha}; gEnv->pRenderer->DrawLabelEx(baseText - (textLineOffset * 2.0f), 1.25f, textColor, true, false, "Damage: %.1f", currentHit.damage); gEnv->pRenderer->DrawLabelEx(baseText - (textLineOffset * 3.0f), 1.25f, textColor, true, false, "Pierceability: %d", currentHit.surfacePierceability); gEnv->pRenderer->DrawLabelEx(baseText - (textLineOffset * 4.0f), 1.25f, textColor, true, false, "%s", GetPenetrationLevelByPierceability(currentHit.surfacePierceability)); gEnv->pRenderer->DrawLabelEx(baseText - (textLineOffset * 5.0f), 1.25f, textColor, true, false, currentHit.tooThick ? "Too thick!" : "------"); } pRenderAux->SetRenderFlags(oldFlags); }
void CPlayerVisTableDebugDraw::Update() { const float currentTime = gEnv->pTimer->GetCurrTime(); const float maxDebugLifeTime = 1.0f; IRenderAuxGeom* pRenderAux = gEnv->pRenderer->GetIRenderAuxGeom(); const ColorB visibleColor(0, 255, 0, 128); const ColorB hiddenColor(255, 0, 0, 128); const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; SAuxGeomRenderFlags oldRenderFlags = pRenderAux->GetRenderFlags(); SAuxGeomRenderFlags newRenderFlags = e_Def3DPublicRenderflags; newRenderFlags.SetAlphaBlendMode(e_AlphaBlended); newRenderFlags.SetDepthTestFlag(e_DepthTestOff); newRenderFlags.SetCullMode(e_CullModeNone); pRenderAux->SetRenderFlags(newRenderFlags); TDebugTargets::iterator targetIt = m_debugTargets.begin(); while (targetIt != m_debugTargets.end()) { SDebugInfo& targetInfo = *targetIt; const float lastUpdateAge = (currentTime - targetInfo.m_lastUpdatedTime); const bool remove = (lastUpdateAge > maxDebugLifeTime); if (!remove) { IEntity* pTargetEntity = gEnv->pEntitySystem->GetEntity(targetInfo.m_targetId); if (pTargetEntity) { const ColorB& color = targetInfo.m_visible ? visibleColor : hiddenColor; const Vec3 worldRefPosition = pTargetEntity->GetWorldTM().TransformPoint(targetInfo.m_localTargetPos); const Vec3 offset(0.0f, 0.0f, 0.4f); pRenderAux->DrawCone(worldRefPosition + offset, -Vec3Constants<float>::fVec3_OneZ, 0.125f, offset.z, color); gEnv->pRenderer->DrawLabelEx(worldRefPosition, 1.5f, white, true, false, "%.2f", lastUpdateAge); } ++targetIt; } else { TDebugTargets::iterator nextElement = m_debugTargets.erase(targetIt); targetIt = nextElement; } } pRenderAux->SetRenderFlags(oldRenderFlags); }
int CScriptBind_Game::DebugDrawCone( IFunctionHandler *pH, float x, float y, float z, float radius, float height, int r, int g, int b, int a ) { IRenderAuxGeom* pRenderAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom(); if (pRenderAuxGeom) { SAuxGeomRenderFlags oldFlags = pRenderAuxGeom->GetRenderFlags(); SAuxGeomRenderFlags newFlags = oldFlags; newFlags.SetCullMode(e_CullModeNone); newFlags.SetAlphaBlendMode(e_AlphaBlended); pRenderAuxGeom->SetRenderFlags(newFlags); pRenderAuxGeom->DrawCone(Vec3(x,y,z), Vec3(0.f, 0.f, 1.f), radius, height, ColorB(r,g,b,a)); pRenderAuxGeom->SetRenderFlags(oldFlags); } return pH->EndFunction(); }
int CScriptBind_Game::DebugDrawAABB( IFunctionHandler *pH, float x, float y, float z, float x2, float y2, float z2, int r, int g, int b, int a ) { IRenderAuxGeom* pRenderAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom(); if (pRenderAuxGeom) { SAuxGeomRenderFlags oldFlags = pRenderAuxGeom->GetRenderFlags(); SAuxGeomRenderFlags newFlags = oldFlags; newFlags.SetCullMode(e_CullModeNone); newFlags.SetAlphaBlendMode(e_AlphaBlended); pRenderAuxGeom->SetRenderFlags(newFlags); AABB bbox(Vec3(x, y, z), Vec3(x2, y2, z2)); pRenderAuxGeom->DrawAABB(bbox, true, ColorB(r, g, b, a), eBBD_Faceted); pRenderAuxGeom->SetRenderFlags(oldFlags); } return pH->EndFunction(); }
void CAutoAimManager::DebugDraw() { IRenderAuxGeom* pRenderAux = gEnv->pRenderer->GetIRenderAuxGeom(); const int numAutoaimTargets = m_autoaimTargets.size(); const Vec3 viewPos = gEnv->pSystem->GetViewCamera().GetPosition(); SAuxGeomRenderFlags oldFlags = pRenderAux->GetRenderFlags(); SAuxGeomRenderFlags newFlags = e_Def3DPublicRenderflags; newFlags.SetAlphaBlendMode(e_AlphaBlended); newFlags.SetDepthTestFlag(e_DepthTestOff); newFlags.SetCullMode(e_CullModeNone); pRenderAux->SetRenderFlags(newFlags); const ColorB enemyColor(255,0,0,128); const ColorB friendlyColor(0,255,0,128); const ColorB followColorInner(255,255,0,64); const ColorB followColorOuter(255,255,0,0); const ColorB snapColor(255,255,255,64); for(int i = 0; i < numAutoaimTargets; i++) { const SAutoaimTarget& aaTarget = m_autoaimTargets[i]; Vec3 dirToTarget = aaTarget.primaryAimPosition - viewPos; dirToTarget.NormalizeSafe(); const float snapRadius = aaTarget.HasFlagSet(eAATF_AIRadarTagged) ? aaTarget.snapRadiusTagged * g_pGameCVars->aim_assistSnapRadiusTaggedScale : aaTarget.snapRadius * g_pGameCVars->aim_assistSnapRadiusScale; pRenderAux->DrawSphere(aaTarget.primaryAimPosition, aaTarget.innerRadius, aaTarget.HasFlagSet(eAATF_AIHostile) ? enemyColor : friendlyColor); pRenderAux->DrawSphere(aaTarget.secondaryAimPosition, 0.2f, aaTarget.HasFlagSet(eAATF_AIHostile) ? enemyColor : friendlyColor); DrawDisc(aaTarget.primaryAimPosition, dirToTarget, aaTarget.innerRadius, aaTarget.outerRadius, followColorInner, followColorOuter); DrawDisc(aaTarget.primaryAimPosition, dirToTarget, aaTarget.outerRadius, snapRadius, followColorOuter, snapColor); } pRenderAux->SetRenderFlags(oldFlags); const float white[4] = {1.0f, 1.0f, 1.0f, 0.75f}; gEnv->pRenderer->Draw2dLabel(50.0f, 50.0f, 1.5f, white, false, "Number of targets: %d", numAutoaimTargets); }
//------------------------------------------------------------------------ void CGameRulesHoldObjectiveBase::DebugDrawCylinder(SHoldEntityDetails *pDetails) { // Draw debug cylinder if(g_pGameCVars->g_holdObjectiveDebug == eHOB_Debug_Draw_Sphere) { IEntity *pHoldEntity = gEnv->pEntitySystem->GetEntity(pDetails->m_id); if (pHoldEntity) { IRenderAuxGeom* pAuxRenderer = gEnv->pRenderer->GetIRenderAuxGeom(); SAuxGeomRenderFlags renderFlags = pAuxRenderer->GetRenderFlags(); renderFlags.SetAlphaBlendMode(e_AlphaBlended); pAuxRenderer->SetRenderFlags(renderFlags); pAuxRenderer->DrawCylinder( pHoldEntity->GetPos()+Vec3(0.f,0.f,pDetails->m_controlOffsetZ+(pDetails->m_controlHeight*0.5f)), Vec3(0.0f,0.0f,1.0f), pDetails->m_controlRadius, pDetails->m_controlHeight, ColorB(255,255,0,128)); } } }
Vec3 CPlayerRotation::GetCloseCombatSnapTargetDirection( const Vec3& aimPos, const Vec3& aimDirection, const SAutoaimTarget& aaTarget ) const { Lineseg targetLine; targetLine.start = aaTarget.secondaryAimPosition; targetLine.end = aaTarget.primaryAimPosition; Lineseg aimLine; aimLine.start = aimPos; aimLine.end = aimPos + (aimDirection * g_pGameCVars->aim_assistMaxDistance); float t0 = -1.0f, t1 = -1.0f; Distance::Lineseg_LinesegSq<float>(targetLine, aimLine, &t0, &t1); if (t0 >= 0.0f) { const Vec3 snapTarget = ((targetLine.start) + ((targetLine.end - targetLine.start) * t0)); #if DBG_AUTO_AIM SAuxGeomRenderFlags oldFlags = gEnv->pRenderer->GetIRenderAuxGeom()->GetRenderFlags(); SAuxGeomRenderFlags newFlags = e_Def3DPublicRenderflags; newFlags.SetAlphaBlendMode(e_AlphaBlended); newFlags.SetDepthTestFlag(e_DepthTestOff); newFlags.SetCullMode(e_CullModeNone); gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(newFlags); gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(targetLine.start, ColorB(196, 196, 0), targetLine.end, ColorB(196, 196, 0), 4.0f); gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(snapTarget, 0.125f, ColorB(0, 196, 0)); gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(oldFlags); #endif return (snapTarget - aimPos).GetNormalizedSafe(Vec3Constants<float>::fVec3_OneY); } return ZERO; }
void CVehiclePartSuspensionPart::Update(const float frameTime) { inherited::Update(frameTime); const Matrix34& parentTm = m_pParentPart->GetLocalTM(false); const Matrix34& targetTm = m_targetPart->GetLocalTM(false); Vec3 pos = parentTm * m_pos0; Vec3 targetPos = (m_ikFlags&k_flagIgnoreTargetRotation) ? (targetTm.GetColumn3() + m_targetOffset) : (targetTm * m_targetOffset); Vec3 dir = targetPos - pos; float length = dir.GetLength(); if (length > 1e-2f) { Matrix33 rot = Matrix33::CreateRotationV0V1(m_direction0, dir*(1.f/length)); Matrix33 partRot = rot*Matrix33(m_initialRot); if (m_mode==k_modeRotate || m_mode==k_modeSnapToEF) { if (m_mode==k_modeSnapToEF) { pos = targetPos - rot * m_direction0; } Matrix34 tm(partRot, pos); SetLocalTM(tm); } else if (m_mode==k_modeStretch) { const float scale = length * m_invLength0; const Vec3 z = m_direction0; const Vec3 sz = m_direction0*(scale-1.f); Matrix33 scaleM; scaleM.m00 = 1.f+sz.x*z.x; scaleM.m01 = sz.y*z.x ; scaleM.m02 = sz.z*z.x; scaleM.m10 = sz.x*z.y ; scaleM.m11 = 1.f+sz.y*z.y; scaleM.m12 = sz.z*z.y; scaleM.m20 = sz.x*z.z ; scaleM.m21 = sz.y*z.z ; scaleM.m22 = 1.f+sz.z*z.z; Matrix34 tm(partRot * scaleM, pos); SetLocalTM(tm); } } #if !defined(_RELEASE) if (VehicleCVars().v_debugSuspensionIK) { IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom(); SAuxGeomRenderFlags flags = pAuxGeom->GetRenderFlags(); SAuxGeomRenderFlags oldFlags = pAuxGeom->GetRenderFlags(); flags.SetDepthWriteFlag(e_DepthWriteOff); flags.SetDepthTestFlag(e_DepthTestOff); pAuxGeom->SetRenderFlags(flags); ColorB colRed(255,0,0,255); ColorB colBlue(0,0,255,255); ColorB colWhite(255,255,255,255); ColorB colGreen(0,255,0,255); pos = m_pVehicle->GetEntity()->GetWorldTM() * pos; targetPos = m_pVehicle->GetEntity()->GetWorldTM() * targetPos; pAuxGeom->DrawSphere(pos, 0.02f, colGreen); pAuxGeom->DrawSphere(targetPos, 0.02f, colBlue); pAuxGeom->DrawLine(pos, colWhite, targetPos, colWhite); } #endif }
void CFireModePlugin_AutoAim::AdjustFiringDirection( const Vec3& attackerPos, Vec3& firingDirToAdjust, const bool bCurrentlyZoomed, const EntityId ownerId ) const { CPlayer* pAttackingPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId)); if (pAttackingPlayer && pAttackingPlayer->IsPlayer()) { const ConeParams& aimConeSettings = GetAimConeSettings(bCurrentlyZoomed); // Don't do any projectile adjusting if the player already has a target for themselves, and is on target (e.g. manually scoping to get a headshot) if( m_targetSelectionParams.m_bDisableAutoAimIfPlayerAlreadyHasTarget && pAttackingPlayer->GetCurrentTargetEntityId() || !aimConeSettings.m_enabled) { #if ALLOW_PROJECTILEHELPER_DEBUGGING m_lastShotAutoAimedStatus.append("FALSE - [Reason]: Player already on target"); #endif //#if #endif //#if ALLOW_PROJECTILEHELPER_DEBUGGING return; } float incomingDirLength = firingDirToAdjust.GetLength(); CRY_ASSERT(incomingDirLength>0.f); Vec3 firingDirToAdjustNorm(firingDirToAdjust*__fres(incomingDirLength)); #if ALLOW_PROJECTILEHELPER_DEBUGGING // DEBUG RENDER if (g_pGameCVars->pl_debug_projectileAimHelper) { // Draw Target acquisition cone float length = aimConeSettings.m_maxDistance; float radius = length * tan(aimConeSettings.m_outerConeRads * 0.5f); SAuxGeomRenderFlags originalFlags = gEnv->pRenderer->GetIRenderAuxGeom()->GetRenderFlags(); SAuxGeomRenderFlags newFlags = originalFlags; newFlags.SetCullMode(e_CullModeNone); newFlags.SetFillMode(e_FillModeWireframe); newFlags.SetAlphaBlendMode(e_AlphaBlended); gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(newFlags); gEnv->pRenderer->GetIRenderAuxGeom()->DrawCone(attackerPos + (firingDirToAdjustNorm*aimConeSettings.m_maxDistance),-firingDirToAdjustNorm, radius , length , ColorB(132,190,255,120), true ); // Draw projectile adjust cone radius = length * tan(aimConeSettings.m_innerConeRads * 0.5f); gEnv->pRenderer->GetIRenderAuxGeom()->DrawCone(attackerPos + (firingDirToAdjustNorm*aimConeSettings.m_maxDistance),-firingDirToAdjustNorm, radius , length ,ColorB(0,0,127,120), true ); // Restore render flags gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(originalFlags); } #endif //#if ALLOW_PROJECTILEHELPER_DEBUGGING IEntity* pTargetPlayer = CalculateBestProjectileAutoAimTarget(attackerPos, firingDirToAdjustNorm, bCurrentlyZoomed, ownerId); if(pTargetPlayer) { const SAutoaimTarget* pAutoAimInfo = g_pGame->GetAutoAimManager().GetTargetInfo(pTargetPlayer->GetId()); if(pAutoAimInfo) { Vec3 desiredFiringDir = ( pAutoAimInfo->primaryAimPosition - attackerPos ).GetNormalized(); // Make sure final firing dir still constrained to valid cone float vecDot = firingDirToAdjustNorm.Dot(desiredFiringDir); float maxConeAngle = cos(0.5f * aimConeSettings.m_innerConeRads); if(vecDot >= maxConeAngle) { // within cone firingDirToAdjustNorm = desiredFiringDir; #if ALLOW_PROJECTILEHELPER_DEBUGGING m_lastShotAutoAimedStatus.append("TRUE + desired dir fully WITHIN allowed adjust cone"); #endif //#if ALLOW_PROJECTILEHELPER_DEBUGGING } else { // constrain (generally working with small angles, nLerp should be fine + cheap) const float invConeDot = 1.0f - maxConeAngle; const float invVecDot = 1.0f - vecDot; float zeroToOne = invConeDot / invVecDot; Vec3 finalVec = (zeroToOne * desiredFiringDir) + ((1.0f - zeroToOne) * firingDirToAdjustNorm); finalVec.Normalize(); firingDirToAdjustNorm = finalVec; #if ALLOW_PROJECTILEHELPER_DEBUGGING m_lastShotAutoAimedStatus.Format("TRUE + desired dir CONSTRAINED to allowed cone [desired]: %.3f deg [constrained To]: %.3f deg", RAD2DEG(acos(vecDot)), 0.5f * RAD2DEG(aimConeSettings.m_innerConeRads)); #endif //#if ALLOW_PROJECTILEHELPER_DEBUGGING } } } #if ALLOW_PROJECTILEHELPER_DEBUGGING else { m_lastShotAutoAimedStatus.Format("FALSE - CalculateBestProjectileAutoAimTarget NULL [Last reason]: %s", m_lastTargetRejectionReason.c_str()); } // Draw adjusted vec if (g_pGameCVars->pl_debug_projectileAimHelper) { float length = aimConeSettings.m_maxDistance; gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(attackerPos,ColorB(255,0,255,0),attackerPos + firingDirToAdjustNorm * length,ColorB(255,0,255,0)); } #endif //#if ALLOW_PROJECTILEHELPER_DEBUGGING firingDirToAdjust = firingDirToAdjustNorm*incomingDirLength; } }
void CNetPlayerInput::UpdateInterpolation() { Vec3 desiredPosition = m_curInput.position; Vec3 entPos = m_pPlayer->GetEntity()->GetPos(); Vec3 displacement = desiredPosition - entPos; displacement.z = 0.0f; float dist = displacement.len(); CTimeValue curTime=gEnv->pTimer->GetFrameStartTime(); Vec3 desiredVelocity = m_curInput.deltaMovement * g_pGameCVars->pl_netSerialiseMaxSpeed; m_netDesiredSpeed = desiredVelocity.GetLength2D(); if (m_newInterpolation) { InitialiseInterpolation(dist, displacement, desiredVelocity, curTime); } float dt = curTime.GetDifferenceInSeconds(m_netLastUpdate) + k_lerpTargetTime; dt = min(dt, k_maxPredictTime); m_predictedPosition = desiredPosition + (desiredVelocity * dt); Vec3 predOffset = m_predictedPosition - entPos; float predDist = predOffset.GetLength2D(); float lerpSpeed = (predDist/k_lerpTargetTime); lerpSpeed=clamp(lerpSpeed, k_minInterpolateSpeed, k_maxInterpolateSpeed); m_netLerpSpeed = lerpSpeed; UpdateErrorSnap(entPos, desiredPosition, dist, displacement, curTime); if (!m_passedNetPos && (m_initialDir.Dot(displacement) < 0.0f)) { m_passedNetPos = true; } Vec3 maxPrediction = desiredPosition + (desiredVelocity * k_maxPredictTime); if (m_passedNetPos && !m_passedPredictionPos && (m_initialDir.Dot(maxPrediction - entPos) < 0.0f)) { m_passedPredictionPos = true; } #if !defined(_RELEASE) if (g_pGameCVars->pl_debugInterpolation) { CryWatch("Cur: (%f, %f, %f) Des: (%f, %f, %f) Pred: (%f, %f, %f) ", entPos.x, entPos.y, entPos.z, desiredPosition.x, desiredPosition.y, desiredPosition.z, m_predictedPosition.x, m_predictedPosition.y, m_predictedPosition.z); CryWatch("BlockTime: (%f) PredictTime (%f) LastNetTime (%f) CurTime (%f)", m_blockedTime, dt, m_netLastUpdate.GetSeconds(), curTime.GetSeconds()); CryWatch("Lerp Speed: (%f) Passed pred pos (%d) Passed net pos (%d)", m_netLerpSpeed, m_passedPredictionPos, m_passedNetPos); CryWatch("InputSpeed: (%f, %f, %f) ", desiredVelocity.x, desiredVelocity.y, desiredVelocity.z); IRenderAuxGeom* pRender = gEnv->pRenderer->GetIRenderAuxGeom(); SAuxGeomRenderFlags flags = pRender->GetRenderFlags(); SAuxGeomRenderFlags oldFlags = pRender->GetRenderFlags(); flags.SetDepthWriteFlag(e_DepthWriteOff); flags.SetDepthTestFlag(e_DepthTestOff); pRender->SetRenderFlags(flags); pRender->DrawSphere(desiredPosition + Vec3(0.0f, 0.0f, 0.035f), 0.07f, ColorB(255,0,0,255)); pRender->DrawSphere(m_predictedPosition + Vec3(0.0f, 0.0f, 0.025f), 0.05f, ColorB(255,255,255,255)); pRender->SetRenderFlags(oldFlags); ColorF ballCol = m_passedPredictionPos ? ColorF(1.0f,1.0f,0.0f,0.75f) : (m_passedNetPos ? ColorF(1.0f,1.0f,1.0f,0.75f) : ColorF(0.0f,1.0f,0.0f,0.75f)); g_pGame->GetIGameFramework()->GetIPersistantDebug()->Begin("INTERPOLATION TRAIL", false); g_pGame->GetIGameFramework()->GetIPersistantDebug()->AddSphere(desiredPosition + Vec3(0.0f, 0.0f, 0.1f), 0.04f, ColorF(1.0f,0.0f,0.0f,0.75f), 30.f); g_pGame->GetIGameFramework()->GetIPersistantDebug()->AddSphere(m_predictedPosition + Vec3(0.0f, 0.0f, 0.1f), 0.03f, ColorF(0.0f,0.0f,1.0f,0.8f), 30.f); ballCol.a = 1.0f; g_pGame->GetIGameFramework()->GetIPersistantDebug()->AddSphere(entPos + Vec3(0.0f, 0.0f, 0.1f), 0.02f, ballCol, 30.f); g_pGame->GetIGameFramework()->GetIPersistantDebug()->AddLine(entPos + Vec3(0.0f, 0.0f, 0.1f), m_predictedPosition + Vec3(0.0f, 0.0f, 0.1f), ballCol, 30.f); } #endif //!_RELEASE }
void CPlayerRotation::TargetAimAssistance(CWeapon* pWeapon, float& followH, float& followV, float& scale, float& _fZoomAmount, const Vec3 playerView[4]) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); CRY_ASSERT(m_player.IsClient()); followH = 0.0f; followV = 0.0f; scale = 1.0f; float bestScale = 1.0f; const Vec3 playerFwd = playerView[1]; const Vec3 playerRgt = playerView[0]; const Vec3 playerUp = playerView[2]; const Vec3 playerPos = playerView[3]; Vec3 follow_target_pos(ZERO); float follow_vote_leader = 0.0f; float snap_vote_leader = 0.0f; Vec3 follow_target_dir(ZERO); Vec3 snap_target_dir(ZERO); EntityId follow_target_id = 0; EntityId snap_target_id = 0; CGameRules * pGameRules = g_pGame->GetGameRules(); float distance_follow_threshold_near = max(0.0f, g_pGameCVars->aim_assistMinDistance); float distance_follow_threshold_far = max(20.0f, g_pGameCVars->aim_assistMaxDistance); int playerTeam = pGameRules->GetTeam(m_player.GetEntity()->GetId()); float cloakedPlayerMultiplier = g_pGameCVars->pl_aim_cloaked_multiplier; const bool multipleTeams = pGameRules->GetTeamCount() > 0; const float fFollowFalloffDist = g_pGameCVars->aim_assistFalloffDistance + FLT_EPSILON*g_pGameCVars->aim_assistFalloffDistance; const bool playerIsScoped = m_player.GetActorStats()->isScoped; float minTurnScale, fAimAssistStrength, fMaxDistMult; if(pWeapon) { const float fZoomAmount = pWeapon->GetZoomTransition(); _fZoomAmount = fZoomAmount; const float fStrength = g_pGameCVars->aim_assistStrength; const float fStrengthIronSight = playerIsScoped ? g_pGameCVars->aim_assistStrength_SniperScope : g_pGameCVars->aim_assistStrength_IronSight; const float fDiff = fStrengthIronSight - fStrength; fAimAssistStrength = fStrength + (fZoomAmount * fDiff); const float fMinTurn = g_pGameCVars->aim_assistMinTurnScale; const float fMinTurnIronSight = playerIsScoped ? g_pGameCVars->aim_assistMinTurnScale_SniperScope : g_pGameCVars->aim_assistMinTurnScale_IronSight; const float fMinTurnDiff = fMinTurnIronSight - fMinTurn; minTurnScale = fMinTurn + (fZoomAmount * fMinTurnDiff); const float fMaxAssistDist = g_pGameCVars->aim_assistMaxDistance; const float fMaxAssistDist_Iron = playerIsScoped ? g_pGameCVars->aim_assistMaxDistance_SniperScope : g_pGameCVars->aim_assistMaxDistance_IronSight; const float fMaxAssistDistDiff = (fMaxAssistDist_Iron - fMaxAssistDist) * fZoomAmount; fMaxDistMult = (fMaxAssistDist + fMaxAssistDistDiff) * __fres(fMaxAssistDist); } else { _fZoomAmount = 0.0f; fMaxDistMult = 1.0f; fAimAssistStrength = g_pGameCVars->aim_assistStrength; minTurnScale = g_pGameCVars->aim_assistMinTurnScale; } const float falloffStartDistance = g_pGameCVars->aim_assistSlowFalloffStartDistance; const float falloffPerMeter = 1.0f / (g_pGameCVars->aim_assistSlowDisableDistance - falloffStartDistance); const TAutoaimTargets& aaTargets = g_pGame->GetAutoAimManager().GetAutoAimTargets(); const int targetCount = aaTargets.size(); float fBestTargetDistance = FLT_MAX; #if DBG_AUTO_AIM SAuxGeomRenderFlags oldFlags = gEnv->pRenderer->GetIRenderAuxGeom()->GetRenderFlags(); SAuxGeomRenderFlags newFlags = e_Def3DPublicRenderflags; newFlags.SetAlphaBlendMode(e_AlphaBlended); newFlags.SetDepthTestFlag(e_DepthTestOff); newFlags.SetCullMode(e_CullModeNone); gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(newFlags); #endif for (int i = 0; i < targetCount; ++i) { const SAutoaimTarget& target = aaTargets[i]; CRY_ASSERT(target.entityId != m_player.GetEntityId()); //Skip friendly ai if(gEnv->bMultiplayer) { if(multipleTeams && (pGameRules->GetTeam(target.entityId) == playerTeam)) { continue; } } else { if (target.HasFlagSet(eAATF_AIHostile) == false) continue; distance_follow_threshold_far = fMaxDistMult * (target.HasFlagSet(eAATF_AIRadarTagged) ? g_pGameCVars->aim_assistMaxDistanceTagged : g_pGameCVars->aim_assistMaxDistance); } Vec3 targetPos = target.primaryAimPosition; Vec3 targetDistVec = (targetPos - playerPos); float distance = targetDistVec.GetLength(); if (distance <= 0.1f) continue; Vec3 dirToTarget = targetDistVec / distance; // fast reject everything behind player, too far away or too near from line of view // sort rest by angle to crosshair and distance from player float alignment = playerFwd * dirToTarget; if (alignment <= 0.0f) continue; if ((distance < distance_follow_threshold_near) || (distance > distance_follow_threshold_far)) continue; const int kAutoaimVisibilityLatency = 2; CPlayerVisTable::SVisibilityParams visParams(target.entityId); visParams.queryParams = eVQP_IgnoreGlass; if (!g_pGame->GetPlayerVisTable()->CanLocalPlayerSee(visParams, kAutoaimVisibilityLatency)) { // Since both player and target entities are ignored, and the ray still intersected something, there's something in the way. // Need to profile this and see if it's faster to do the below checks before doing the linetest. It's fairly expensive but // linetests generally are as well... - Richard continue; } #if DBG_AUTO_AIM const ColorB green(0,255,0,255); const ColorB darkgreen(0,155,0,225); gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine( playerPos, darkgreen, targetPos, green); #endif const float angleDot = dirToTarget.dot(-playerRgt); const float angle = (RAD2DEG(acos_tpl(angleDot)) - 90.f); const float absAngle = fabsf(angle); const float angleDotV = playerUp.dot(dirToTarget); const float angleToTargetV = (RAD2DEG(acos_tpl(angleDotV)) - 90.f); const float absAngleV = fabsf(angleToTargetV); const float slowModifiedDistance = distance * g_pGameCVars->aim_assistSlowDistanceModifier; const float radius_slow_threshold_inner = 0.5f; const float radius_slow_threshold_outer = g_pGameCVars->aim_assistSlowThresholdOuter; const float angle_slow_threshold_inner = RAD2DEG(atan_tpl(radius_slow_threshold_inner / slowModifiedDistance)); const float angle_slow_threshold_outer = RAD2DEG(atan_tpl(radius_slow_threshold_outer / slowModifiedDistance)); float angle_slow_fractionH = clamp_tpl((absAngle - angle_slow_threshold_inner) / (angle_slow_threshold_outer - angle_slow_threshold_inner), 0.0f, 1.0f); float angle_slow_fractionV = clamp_tpl((absAngleV - angle_slow_threshold_inner) / (angle_slow_threshold_outer - angle_slow_threshold_inner), 0.0f, 1.0f); float angle_slow_fraction = max(angle_slow_fractionH, angle_slow_fractionV); const float distance_follow_fraction = clamp_tpl((distance - fFollowFalloffDist) / (distance_follow_threshold_far - fFollowFalloffDist), 0.0f, 1.0f); const float radius_follow_threshold_inner = target.innerRadius; const float radius_follow_threshold_outer = target.outerRadius; const float radius_snap = target.HasFlagSet(eAATF_AIRadarTagged) ? target.snapRadiusTagged * g_pGameCVars->aim_assistSnapRadiusTaggedScale : target.snapRadius * g_pGameCVars->aim_assistSnapRadiusScale; const float angle_follow_threshold_inner = RAD2DEG(atan_tpl(radius_follow_threshold_inner / distance)); const float angle_follow_threshold_outer = RAD2DEG(atan_tpl(radius_follow_threshold_outer / distance)); const float angle_follow_fraction = clamp_tpl((absAngle - angle_follow_threshold_inner) / (angle_follow_threshold_outer - angle_follow_threshold_inner), 0.0f, 1.0f); const float angle_follow_fractionV = clamp_tpl((absAngleV - angle_follow_threshold_inner) / (angle_follow_threshold_outer - angle_follow_threshold_inner), 0.0f, 1.0f); const float worst_follow_fraction = (float)__fsel(angle_follow_fraction - angle_follow_fractionV, angle_follow_fraction, angle_follow_fractionV); float follow_fraction = ((1.0f - worst_follow_fraction) * (1.0f - distance_follow_fraction)); float follow_vote = follow_fraction; //clamp the lower bound of the distance_slow_modifier so it can't be lower than the angle slow fraction // which prevents close but off-centre targets slowing us too much const float distance_slow_modifier = clamp_tpl( 1.0f - ((distance - falloffStartDistance) * falloffPerMeter), angle_slow_fraction, 1.0f); const float fCombinedModifier = angle_slow_fraction * distance_slow_modifier; fBestTargetDistance = (float)__fsel(fCombinedModifier - bestScale, fBestTargetDistance, distance); bestScale = min(fCombinedModifier, bestScale); if (follow_vote > follow_vote_leader) { follow_vote_leader = follow_vote; //m_follow_target_id only gets set after the loop -> this won't get hit when a target is selected // as a follow target for the first time. This doesn't need to be in the loop. if ( m_follow_target_id == target.entityId) { const Vec3 follow_target_dir_local = m_follow_target_dir; Vec3 target_rgt = playerRgt; Vec3 target_up = target_rgt.cross(follow_target_dir_local); target_rgt = follow_target_dir_local.cross(target_up); target_rgt.Normalize(); target_up.Normalize(); float alignH = dirToTarget * -target_rgt; float alignV = dirToTarget.z - follow_target_dir_local.z; float angleH = min(fabsf(alignH * fAimAssistStrength), fabsf(angleDot)); float angleV = min(fabsf(alignV * fAimAssistStrength), fabsf(angleDotV)); followH = follow_fraction * (float)__fsel(angleDot, angleH, -angleH); followV = follow_fraction * (float)__fsel(angleDotV, angleV, -angleV); follow_vote_leader += 0.05f; // anti oscillation between different targets follow_target_pos = targetPos; } follow_target_id = target.entityId; snap_target_id = target.entityId; follow_target_dir = dirToTarget; snap_target_dir = PickBestSnapDirection(playerPos, playerFwd, target); } else if (!follow_target_id && (radius_snap > 0.0f)) { Lineseg lineSegment; lineSegment.start = playerPos; lineSegment.end = playerPos + (playerFwd * (distance + radius_snap)); Sphere sphere; sphere.center = targetPos; sphere.radius = radius_snap; Vec3 intersectionPoint; if (Intersect::Lineseg_SphereFirst(lineSegment, sphere, intersectionPoint)) { float t = 0.0f; const float snap_fraction = 1.0f - (Distance::Point_Lineseg(targetPos, lineSegment, t) * (float)__fres(radius_snap)); if (snap_fraction > snap_vote_leader) { snap_vote_leader = snap_fraction; snap_target_id = target.entityId; snap_target_dir = PickBestSnapDirection(playerPos, playerFwd, target); } } } } #if DBG_AUTO_AIM if ((!follow_target_pos.IsZeroFast()) && (g_pGameCVars->pl_targeting_debug != 0)) { float radius_inner = 0.30f; float radius_outer = 0.33f; ColorB colorInner(255,255,0,0x40); ColorB colorOuter(255,255,0,0x40); DrawDisc(follow_target_pos, follow_target_dir, radius_inner, radius_outer, colorInner, colorOuter); } gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(oldFlags); #endif m_follow_target_id = follow_target_id; m_follow_target_dir = follow_target_dir; //IMPORTANT: Apply the minimum-distance scaling of the slowdown _after_ calculating the slowdown for the best target // as we want to help the player aim at the nearest target, and modifying the slowdown multiplier prior to this // could result in a different target being selected const float fSlowDownProximityFadeInBand = (g_pGameCVars->aim_assistSlowStopFadeinDistance - g_pGameCVars->aim_assistSlowStartFadeinDistance) + FLT_EPSILON; float fSlowDownProximityScale = (fBestTargetDistance - g_pGameCVars->aim_assistSlowStartFadeinDistance) / fSlowDownProximityFadeInBand; Limit(fSlowDownProximityScale, 0.0f, 1.0f); float fInvBestScale = (1.0f - bestScale) * fSlowDownProximityScale; bestScale = 1.0f - fInvBestScale; scale = minTurnScale + ((1.0f - minTurnScale) * bestScale); UpdateCurrentSnapTarget(snap_target_id, snap_target_dir); }
bool CContactRaycastPinger::Update(Vec3& position, Vec3& normal) { Vec3 positionPrevious = position; Vec3 positionPreviousGlobal = positionPrevious; Vec3 rayPosition = positionPreviousGlobal; rayPosition.z += m_length; IPhysicalEntity* pSkipEntities[10]; int nSkip = m_pinger.GetSkipEntities(pSkipEntities, 10); static const int totalHits = 6; ray_hit hits[totalHits]; IPhysicalWorld::SRWIParams rp; rp.Init(rayPosition, Vec3(0.0f, 0.0f, -m_length * 2.0f), ent_static | ent_terrain, rwi_pierceability0, SCollisionClass(0, collision_class_living|collision_class_articulated), &hits[0], totalHits, pSkipEntities, nSkip); int hitCount = gEnv->pPhysicalWorld->RayWorldIntersection(rp); // Find best hit. This is the highest contact, that is a viable place to put the foot. // eg. Not on poles, other Pinger's legs, or other unwanted places. ray_hit* pHit = NULL; for(int i=0;i<totalHits;i++) { ray_hit& hit = hits[i]; if(!hit.pCollider) continue; if(!hit.bTerrain) { // Ignore small and fast things. pe_params_flags pgetflags; pe_status_pos sgetpos; if( hit.pCollider->GetStatus(&sgetpos) && hit.pCollider->GetParams(&pgetflags) ) if(sgetpos.iSimClass==2 && (pgetflags.flags&ref_small_and_fast)!=0) continue; pe_params_part pgetpart; pgetpart.ipart = hit.ipart; phys_geometry* geometry = NULL; if(hit.pCollider->GetParams(&pgetpart)) { if(pgetpart.flagsOR&geom_no_coll_response) continue; geometry = pgetpart.pPhysGeomProxy?pgetpart.pPhysGeomProxy:pgetpart.pPhysGeom; } Vec3 sz; if(geometry && geometry->pGeom) { primitives::box tempBox; geometry->pGeom->GetBBox(&tempBox); sz = tempBox.size; } else { pe_params_bbox pgetbox; hit.pCollider->GetParams(&pgetbox); sz = (pgetbox.BBox[1]-pgetbox.BBox[0]); } // Ignore small objects. (Matches similar check in livingentity physics code) const float maxarea = max(max(sz.x*sz.y, sz.x*sz.z), sz.y*sz.z)*sqr(pgetpart.scale)*4; const float maxdim = max(max(sz.x,sz.y),sz.z)*pgetpart.scale*2; if (maxarea<sqr(sz.x)*g_PI*0.25f && maxdim<sz.z*1.4f) continue; } pHit = ((!pHit)||hit.dist<pHit->dist)?&hit:pHit; } // Apply the chosen hit results. if(pHit) { position.z = pHit->pt.z; normal = pHit->n*(float)__fsel(pHit->n.z,1.f,-1.f); normal.NormalizeSafe(Vec3(0.0f, 0.0f, 1.0f)); } #ifndef _RELEASE if (PoseAligner::CVars::GetInstance().m_debugDraw) { SAuxGeomRenderFlags flags = gEnv->pRenderer->GetIRenderAuxGeom()->GetRenderFlags(); flags.SetDepthTestFlag(e_DepthTestOff); gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(flags); if(pHit) { gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(pHit->pt, 0.05f, ColorB(0xff, 0xff, 0x00, 0xff)); } gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(positionPreviousGlobal, 0.05f, ColorB(0xff, 0x00, 0xff, 0xff)); gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine( rayPosition, ColorB(0xff, 0xff, 0xff, 0xff), rayPosition + Vec3(0.0f, 0.0f, -m_length * 2.0f), ColorB(0xff, 0xff, 0xff, 0xff)); } #endif //_RELEASE return pHit!=NULL; }