void OGLReverseSphericalCamera::animate() { // See http://en.wikipedia.org/wiki/Spherical_coordinate_system#Cartesian_coordinates // Spherical to Cartesian // x = r * sin(theta) * cos(phi) // y = r * cos(theta) // z = r * sin(theta) * sin(phi) float phi = OGLUtil::degToRad(cameraPosSpherical.phi); float theta = OGLUtil::degToRad(cameraPosSpherical.theta + 90.0f); // Remember -90 to 90 float fSinTheta = sinf(theta); float fCosTheta = cosf(theta); float fCosPhi = cosf(phi); float fSinPhi = sinf(phi); glm::vec3 dirToTarget(fSinTheta * fCosPhi, -fCosTheta, fSinTheta * fSinPhi); cameraTarget = (dirToTarget * cameraPosSpherical.rho) + position; lookDir = glm::normalize(position - cameraTarget); }
//------------------------------------------------------------------------ void CMelee::Update(float frameTime, uint32 frameId) { FUNCTION_PROFILER( GetISystem(), PROFILE_GAME ); bool remote = false; bool doMelee = false; bool requireUpdate = false; Vec3 dirToTarget(ZERO); if(m_pMeleeAction && s_meleeSnapTargetId && g_pGameCVars->pl_melee.mp_melee_system_camera_lock_and_turn) { m_attackTime += frameTime; CActor* pOwner = m_pWeapon->GetOwnerActor(); IEntity* pTarget = gEnv->pEntitySystem->GetEntity(s_meleeSnapTargetId); if(pOwner && pTarget) { Vec3 targetPos = pTarget->GetWorldPos(); if(s_bMeleeSnapTargetCrouched) { targetPos.z -= g_pGameCVars->pl_melee.mp_melee_system_camera_lock_crouch_height_offset; } dirToTarget = targetPos - pOwner->GetEntity()->GetWorldPos(); dirToTarget.Normalize(); static const float smooth_time = 0.1f; SmoothCD(m_attackTurnAmount, m_attackTurnAmountSmoothRate, frameTime, 1.f, smooth_time); Quat newViewRotation; newViewRotation.SetSlerp(pOwner->GetViewRotation(), Quat::CreateRotationVDir(dirToTarget), m_attackTurnAmount); Ang3 newAngles(newViewRotation); newAngles.y = 0.f; //No head tilting newViewRotation = Quat(newAngles); pOwner->SetViewRotation( newViewRotation ); } if(m_attackTime >= g_pGameCVars->pl_melee.mp_melee_system_camera_lock_time && pOwner && pOwner->IsClient()) { pOwner->GetActorParams().viewLimits.ClearViewLimit(SViewLimitParams::eVLS_Item); } } if (m_attacking) { MeleeDebugLog ("CMelee<%p> Update while attacking: m_attacked=%d, delay=%f", this, m_attacked, m_delayTimer); requireUpdate = true; if (m_delayTimer>0.0f) { RequestAlignmentToNearestTarget(); m_delayTimer-=frameTime; if (m_delayTimer<=0.0f) { m_delayTimer=0.0f; } } else if (m_netAttacking) { remote = true; doMelee = true; m_attacking = false; m_slideKick = false; m_netAttacking = false; m_pWeapon->SetBusy(false); } else if (!m_attacked) { doMelee = true; m_attacked = true; } if ( !m_collisionHelper.IsBlocked() && doMelee) { if (CActor *pActor = m_pWeapon->GetOwnerActor()) { if (IMovementController * pMC = pActor->GetMovementController()) { SMovementState info; pMC->GetMovementState(info); if(!dirToTarget.IsZeroFast()) { PerformMelee(info.weaponPosition, dirToTarget, remote); //We know where we will be facing at the point of impact - using our current fire direction is not accurate enough } else { PerformMelee(info.weaponPosition, info.fireDirection, remote); } } } } if( (m_useMeleeWeaponDelay <= 0.0f && m_useMeleeWeaponDelay > -1.0f) ) { m_useMeleeWeaponDelay = -1.0f; // Switch to the MELEE WEAPON. SwitchToMeleeWeaponAndAttack(); m_attacking = false; } m_useMeleeWeaponDelay -= frameTime; } if (requireUpdate) m_pWeapon->RequireUpdate(eIUS_FireMode); }