} // end of SmoothCamera Update() #endregion #region Internal /// <summary> /// Translates the current eyeOffset to the proper From/At values. /// </summary> private void TranslateOffset(float blend) { if (CameraInfo.FirstPersonActive) { // In first person mode we want to put the camera in the desiredAt // position and set its facing direction based on the rotation. // Use a lerp here to smooth the transition from follow // mode to first person mode. float t = Math.Min(10.0f * Time.GameTimeFrameSeconds, 1.0f); base.From = MyMath.Lerp(base.From, desiredAt, t); float sinRot = (float)Math.Sin(rotation); float cosRot = (float)Math.Cos(rotation); float sinPitch = (float)Math.Sin(firstPersonPitch); float cosPitch = (float)Math.Cos(firstPersonPitch); base.At = base.From + new Vector3(cosRot * cosPitch, sinRot * cosPitch, sinPitch); t *= 0.8f * InGame.CameraSpringStrength; firstPersonPitch = MyMath.Lerp(firstPersonPitch, firstPersonDesiredPitch, t); firstPersonDesiredPitch = MyMath.Lerp(firstPersonDesiredPitch, 0.0f, firstPersonPitchSpring * t); } else { base.At = MyMath.Lerp(base.At, desiredAt, blend); base.From = base.At + eyeOffset; } } // end of TranslateOffset()
} // end of Camera MoveHeightOffset() /// <summary> /// A helper function which smoothly changes the heightOffset of the camera. /// </summary> /// <param name="height">The height we want the camera at point to be.</param> public void ChangeHeightOffset(float height) { float desiredOffset = height - At.Z; // Be sure this doesn't go negative. desiredOffset = Math.Max(0.0f, desiredOffset); targetHeight = height; HeightOffset = MyMath.Lerp(HeightOffset, desiredOffset, Time.WallClockFrameSeconds); } // end of Camera MoveHeightOffset()
public override void Update() { bumped = false; // Calc blend value for lerping. // Use wall clock time so this works even if the game is paused. float secs = Time.WallClockFrameSeconds; float blend = 5.0f * Time.WallClockFrameSeconds; if (GamePadInput.ActiveMode == GamePadInput.InputMode.Touch) { //faster interpolation in touch mode blend = 10.0f * Time.WallClockFrameSeconds; } // Soften up the camera movement if tracking multiple targets. if (CameraInfo.Mode == CameraInfo.Modes.MultiTarget) { blend *= 0.2f; } blend = Math.Min(blend, 1.0f); // Blend the eyeOffset toward the desired value. eyeOffset = MyMath.Lerp(eyeOffset, desiredEyeOffset, blend); TranslateOffset(blend); // Check if the camera needs to be moved to avoid the terrain. InGame.inGame.shared.KeepCameraAboveGround(); // If we hit the terrain, update the From and At values again. if (bumped) { TranslateOffset(blend); } // Update real and desired angles for use this frame. UpdateValues(); base.Update(); pitchChanged = false; } // end of SmoothCamera Update()
public override Matrix Lerp(Matrix a, Matrix b, float t) { return(MyMath.Lerp(ref a, ref b, t)); }
public override Vector4 Lerp(Vector4 a, Vector4 b, float t) { return(MyMath.Lerp(a, b, t)); }
public override float Lerp(float a, float b, float t) { return(MyMath.Lerp(a, b, t)); }
} // end of c'tor // Cut and pasted from BaseSpriteEmitter, just to override // how the position is computed. Might like to refactor the // Update into common particle tasks (spawn, kill, move, etc.) public override void Update(Camera camera) { if (Active) { // Emit new particles if needed. float dt = Time.GameTimeFrameSeconds; dt = MathHelper.Clamp(dt, 0.0f, 1.0f); // Limit to reasonable values. Position += Velocity * dt; if (Emitting) { if (LinearEmission) { Vector3 deltaPosition = Position - PreviousPosition; float dist = deltaPosition.Length(); partial += dist * EmissionRate; } else { partial += dt * EmissionRate; } // Emit as many particles as needed this // frame to keep up with the emission rate. while (partial >= 1.0f) { if (particleList.Count < MaxSprites) { // Pick a random position on the sphere. Vector3 rndVec = new Vector3((float)(rnd.NextDouble() - rnd.NextDouble()), (float)(rnd.NextDouble() - rnd.NextDouble()), (float)(rnd.NextDouble() - rnd.NextDouble())); rndVec.Normalize(); rndVec *= targetRadius; Vector3 pos = Position + rndVec; // Pick a random position somewhere along the path covered this frame. if (PositionJitter > 0.0f) { pos += PositionJitter * new Vector3((float)rnd.NextDouble() - (float)rnd.NextDouble(), (float)rnd.NextDouble() - (float)rnd.NextDouble(), (float)rnd.NextDouble() - (float)rnd.NextDouble()); } float lifetime = MinLifetime + (float)rnd.NextDouble() * (MaxLifetime - MinLifetime); BaseSpriteParticle particle = new BaseSpriteParticle(pos, lifetime, Color, MaxRotationRate, NumTiles); particleList.Add(particle); } partial -= 1.0f; } } // Update the previous position to match the current one for the next frame. ResetPreviousPosition(); // Update any existing particles. For more heavyweight particles we could // have an Update call per particle. These are lightweight enough that we // can just update them directly. for (int i = 0; i < particleList.Count;) { BaseSpriteParticle particle = (BaseSpriteParticle)particleList[i]; particle.age += dt; Debug.Assert(particle.age >= 0.0f); float t = particle.age / particle.lifetime; if (t > 1.0f) { // Dead particle. particleList.RemoveAt(i); } else { particle.radius = MyMath.Lerp(StartRadius, EndRadius, t); particle.alpha = MyMath.Lerp(StartAlpha, EndAlpha, t); particle.rotation += particle.deltaRotation * dt; // Change the linear fade to a curve. particle.alpha *= particle.alpha; // Add in gravity effect. if (NonZeroGravity) { particle.velocity += Gravity * dt; float speed2 = particle.velocity.LengthSquared(); if (speed2 > MaxSpeed * MaxSpeed) { particle.velocity.Normalize(); particle.velocity *= MaxSpeed; } } particle.position += particle.velocity * dt; i++; } } // end loop update particles. // Now that we've updated all the particles, create/update the vertex buffer. UpdateVerts(); // See if we've died. if (Dying && particleList.Count == 0) { Active = false; RemoveFromManager(); } } // end of if active } // end Update
} // end of PixelsToCameraSpaceScreenCoords() /// <summary> /// A helper function which smoothly changes the heightOffset of the camera. /// This takes the desired offset as a paramter, rather than the absolute height. /// </summary> /// <param name="height">The height we want the camera at point to be.</param> public void ChangeHeightOffsetNotHeight(float desiredOffset) { targetHeight = Terrain.GetTerrainHeightFlat(At) + desiredOffset; HeightOffset = MyMath.Lerp(HeightOffset, desiredOffset, Time.WallClockFrameSeconds); } // end of Camera MoveHeightOffset()
} // end of TwitchCurve c'tor /// <summary> /// Applies the curve to the paramter t. Assumes that t is /// in the range [0, 1]. /// </summary> public static float Apply(float t, Shape shape) { const float overshootAmplitutde = 0.1f; float result = t; switch (shape) { case Shape.Linear: result = t; break; case Shape.EaseIn: result = 2.0f * MyMath.SmoothStep(0.0f, 2.0f, t); break; case Shape.EaseOut: result = 2.0f * MyMath.SmoothStep(-1.0f, 1.0f, t) - 1.0f; break; case Shape.EaseInOut: result = MyMath.SmoothStep(0.0f, 1.0f, t); break; case Shape.OvershootIn: { t *= 0.5f; float smooth = MyMath.SmoothStep(0.0f, 1.0f, t); result = smooth - overshootAmplitutde * (float)Math.Cos((t - 0.25f) * MathHelper.TwoPi); // Blend toward smooth at tail. if (t < 0.1f) { result = MyMath.Lerp(smooth, result, t * 10.0f); } result *= 2.0f; } break; case Shape.OvershootOut: { t = 0.5f + t * 0.5f; float smooth = MyMath.SmoothStep(0.0f, 1.0f, t); result = smooth - overshootAmplitutde * (float)Math.Cos((t - 0.25f) * MathHelper.TwoPi); // Blend toward smooth at tail. if (t > 0.9f) { result = MyMath.Lerp(smooth, result, (1.0f - t) * 10.0f); } result = (result - 0.5f) * 2.0f; } break; case Shape.OvershootInOut: { float smooth = MyMath.SmoothStep(0.0f, 1.0f, t); result = smooth - overshootAmplitutde * (float)Math.Cos((t - 0.25f) * MathHelper.TwoPi); // Blend toward smooth at tails. if (t < 0.1f) { result = MyMath.Lerp(smooth, result, t * 10.0f); } else if (t > 0.9f) { result = MyMath.Lerp(smooth, result, (1.0f - t) * 10.0f); } } break; } return(result); } // TwitchCurve Apply()