void CPlayerRotation::ProcessParachute() { //thats necessary when passing from groundG to normalG //m_baseQuat = m_viewQuat; Ang3 desiredAngVel(m_deltaAngles.x, m_deltaAngles.y * 0.5f - m_deltaAngles.z * 1.0f, m_deltaAngles.z); float rotInertia(7.7f); //align to gravity vector Vec3 vRef(m_viewQuat.GetInverted() * Vec3(0, 0, 1)); float alignAngleY = cry_atan2f(vRef.x, vRef.z); desiredAngVel.y += alignAngleY * 0.05f; Interpolate(m_angularVel, desiredAngVel, rotInertia, m_frameTime); Ang3 finalAngle(m_angularVel + m_angularImpulseDelta); //limit Z angle float viewPitch(GetLocalPitch()); float zLimit(-1.3f); if (viewPitch + finalAngle.x < zLimit) { finalAngle.x = zLimit - viewPitch; } m_viewQuat *= Quat::CreateRotationZ(finalAngle.z) * Quat::CreateRotationX(finalAngle.x) * Quat::CreateRotationY(finalAngle.y); m_viewQuat.Normalize(); Vec3 up(Vec3(0, 0, 1)); Vec3 right(m_viewQuat.GetColumn0()); Vec3 forward((up % right).GetNormalized()); m_baseQuat = Quat(Matrix33::CreateFromVectors(forward % up, forward, up)); //m_viewQuat = m_baseQuat; m_viewRoll = 0; m_upVector = m_baseQuat.GetColumn2(); }
std::vector<Point> EllipticalArc::pointAndDerivatives(Coord t, unsigned int n) const { unsigned int nn = n+1; // nn represents the size of the result vector. std::vector<Point> result; result.reserve(nn); double angle = map_unit_interval_on_circular_arc(t, initialAngle(), finalAngle(), _sweep); std::auto_ptr<EllipticalArc> ea( static_cast<EllipticalArc*>(duplicate()) ); ea->_center = Point(0,0); unsigned int m = std::min(nn, 4u); for ( unsigned int i = 0; i < m; ++i ) { result.push_back( ea->pointAtAngle(angle) ); angle += (_sweep ? M_PI/2 : -M_PI/2); if ( !(angle < 2*M_PI) ) angle -= 2*M_PI; } m = nn / 4; for ( unsigned int i = 1; i < m; ++i ) { for ( unsigned int j = 0; j < 4; ++j ) result.push_back( result[j] ); } m = nn - 4 * m; for ( unsigned int i = 0; i < m; ++i ) { result.push_back( result[i] ); } if ( !result.empty() ) // nn != 0 result[0] = pointAtAngle(angle); return result; }
void CPlayerRotation::ProcessFlyingZeroG() { bool bEnableGyroVerticalFade = (g_pGameCVars->pl_zeroGEnableGyroFade > 0); bool bEnableGyroSpeedFade = (g_pGameCVars->pl_zeroGEnableGyroFade < 2); //thats necessary when passing from groundG to normalG m_baseQuat = m_viewQuat; assert(m_baseQuat.IsValid()); //m_baseQuat = Quat::CreateSlerp(m_viewQuat,m_player.GetEntity()->GetRotation() * Quat::CreateRotationZ(gf_PI),0.5f); Ang3 desiredAngVel(m_deltaAngles.x,m_deltaAngles.y * 0.3f,m_deltaAngles.z); //view recoil in zeroG cause the player to rotate desiredAngVel.x += m_viewAnglesOffset.x * 0.1f; desiredAngVel.z += m_viewAnglesOffset.z * 0.1f; //so once used reset it. m_viewAnglesOffset.Set(0,0,0); //gyroscope: the gyroscope just apply the right roll speed to compensate the rotation, that way effects like //propulsion particles and such can be done easily just by using the angularVel float rotInertia(g_pGameCVars->pl_zeroGAimResponsiveness); if(m_player.GravityBootsOn() && m_stats.gBootsSpotNormal.len2()>0.01f) { Vec3 vRef(m_baseQuat.GetInverted() * m_stats.gBootsSpotNormal); Ang3 alignAngle(0,0,0); alignAngle.y = cry_atan2f(vRef.x, vRef.z); alignAngle.x = cry_atan2f(vRef.y, vRef.z); desiredAngVel.y += alignAngle.y * 0.05f; desiredAngVel.x -= alignAngle.x * 0.05f; } if(m_actions & ACTION_GYROSCOPE && desiredAngVel.y==0) { // we want to fade out the gyroscopic effect Vec3 vRef(m_baseQuat.GetInverted() * m_stats.zeroGUp); Ang3 alignAngle(0,0,0); alignAngle.y = cry_atan2f(vRef.x,vRef.z); float gyroFade = 1.0f; if(bEnableGyroVerticalFade) { float gyroFadeAngleInner = g_pGameCVars->pl_zeroGGyroFadeAngleInner; float gyroFadeAngleOuter = g_pGameCVars->pl_zeroGGyroFadeAngleOuter; float gyroFadeAngleSpan = gyroFadeAngleOuter - gyroFadeAngleInner; float gyroFadeAngleSpanInv = 1.0f / gyroFadeAngleSpan; float viewVerticalAlignment = abs(m_viewQuat.GetFwdZ()); float viewVerticalAngle = RAD2DEG(cry_asinf(viewVerticalAlignment)); gyroFade = 1.0f - CLAMP((viewVerticalAngle - gyroFadeAngleInner) * gyroFadeAngleSpanInv, 0.0f, 1.0f); gyroFade = cry_powf(gyroFade, g_pGameCVars->pl_zeroGGyroFadeExp); } float speedFade = 1.0f; if(bEnableGyroSpeedFade) { float speed = m_player.GetLastRequestedVelocity().GetLength(); speedFade = 1.0f - std::min(1.0f, speed / 5.0f); } desiredAngVel.y += alignAngle.y * speedFade * gyroFade * m_frameTime * g_pGameCVars->pl_zeroGGyroStrength; //rotInertia = 3.0f; } m_absRoll = fabs(desiredAngVel.y); Interpolate(m_angularVel,desiredAngVel,rotInertia,m_frameTime); Ang3 finalAngle(m_angularVel + m_angularImpulseDelta); m_baseQuat *= Quat::CreateRotationZ(finalAngle.z) * Quat::CreateRotationX(finalAngle.x) * Quat::CreateRotationY(finalAngle.y); m_baseQuat.NormalizeSafe(); /*IEntity *pEnt = m_player.GetEntity(); Vec3 offsetToCenter(Vec3(0,0,m_player.GetStanceInfo(m_player.GetStance())->heightCollider)); Vec3 finalPos(pEnt->GetWorldTM() * offsetToCenter); Quat newBaseQuat(m_baseQuat * Quat::CreateRotationZ(finalAngle.z) * Quat::CreateRotationX(finalAngle.x) * Quat::CreateRotationY(finalAngle.y)); Vec3 newPos(pEnt->GetWorldPos() + m_baseQuat * offsetToCenter); pEnt->SetPos(pEnt->GetWorldPos() + (finalPos - newPos),ENTITY_XFORM_USER);*/ //CHECKQNAN_MAT33(m_baseMtx); m_viewQuat = m_baseQuat; m_viewRoll = 0; m_upVector = m_baseQuat.GetColumn2(); }
void Camara_main_movimiento(CGameObject* gameObject) { // lerp static float initial_fixed_rotation_time = 0.f; static bool train_move = false; if(initial_fixed_rotation_time != 0.f) { // Interpolate Y axis to angle "0" vector3f initialAngles = gameObject->Transform()->LRotation(); vector3f finalAngle(0.f, 0.f, 0.f); float current_alpha = (gTime.GetTicks_s() - initial_fixed_rotation_time)/50.f; // 50 -> Arbitrary value gameObject->Transform()->SetAngle(gMath.lerpAngles(initialAngles, finalAngle, current_alpha)); float epsilon = 1.f; if((gMath.abs(finalAngle.x - initialAngles.x) <= epsilon or gMath.abs(finalAngle.x - initialAngles.x) >= 360 - epsilon) and (gMath.abs(finalAngle.y - initialAngles.y) <= epsilon or gMath.abs(finalAngle.y - initialAngles.y) >= 360 - epsilon) and (gMath.abs(finalAngle.z - initialAngles.z) <= epsilon or gMath.abs(finalAngle.z - initialAngles.z) >= 360 - epsilon)) { initial_fixed_rotation_time = 0.f; return; } return; } if(train_move) { vector3f initialPos = gameObject->Transform()->Position(); vector3f finalPos(0.f, 0.f, 0.f); gameObject->Transform()->SetPosition(gMath.lerp(initialPos, finalPos, 0.05f)); if(initialPos == finalPos) train_move = false; return; } if (gUserInput.Keyboard("T")) { initial_fixed_rotation_time = gTime.GetTicks_s(); } if (gUserInput.Keyboard("Y")) { train_move = true; } float boost = 1.f; if (gUserInput.Keyboard("left shift")) boost = 3.f; gameObject->Transform()->LTranslate(gUserInput.axis1.horizontal * boost * -3.f * gTime.deltaTime_s(), 0.f, gUserInput.axis1.vertical * boost * 3.f * gTime.deltaTime_s()); if (gUserInput.Keyboard("E")) { gameObject->Transform()->Translate(0.f, boost * -3.f * gTime.deltaTime_s(), 0.f); } if (gUserInput.Keyboard("Q")) { gameObject->Transform()->Translate(0.f, boost * 3.f * gTime.deltaTime_s(), 0.f); } // Viewport if(gUserInput.axis2.vertical > 0) { gameObject->Camera()->viewport.height += 0.1f * gTime.deltaTime_s(); if(gameObject->Camera()->viewport.height > 1.f) gameObject->Camera()->viewport.height = 1.f; } else if(gUserInput.axis2.vertical < 0) { gameObject->Camera()->viewport.height -= 0.1f * gTime.deltaTime_s(); if(gameObject->Camera()->viewport.height < 0.f) gameObject->Camera()->viewport.height = 0.f; } if(gUserInput.axis2.horizontal < 0) { gameObject->Camera()->viewport.width -= 0.1f * gTime.deltaTime_s(); if(gameObject->Camera()->viewport.width < 0.f) gameObject->Camera()->viewport.width = 0.f; } else if(gUserInput.axis2.horizontal > 0) { gameObject->Camera()->viewport.width += 0.1f * gTime.deltaTime_s(); if(gameObject->Camera()->viewport.width > 1.f) gameObject->Camera()->viewport.width = 1.f; } /*if (gUserInput.Keyboard("T")) { gameObject->Transform()->LookAt(vector3f(0.f, 0.f, 0.f)); }*/ Camara_mouse_movimiento(gameObject); Camara_Joystick_movimiento(gameObject); }
Coord EllipticalArc::map_to_01(Coord angle) const { return map_circular_arc_on_unit_interval(angle, initialAngle(), finalAngle(), _sweep); }