/// <summary> /// Handles the FrameMove. /// </summary> /// <param name="device"></param> /// <param name="totalTime"></param> /// <param name="elapsedTime"></param> public void OnFrameMove(Device device, double totalTime, float elapsedTime) { if ((crashTime > 0) && (crashTime + 3.0 < totalTime)) { Reset(); } elapsedCumul += elapsedTime; if (elapsedCumul > 0.1f) { elapsedCumul = 0f; if (variometer != null) { variometer.Frequency = (int)(22100 - Math.Sign(iFlightModel.Velocity.Z) * Math.Sqrt(Math.Abs(iFlightModel.Velocity.Z)) * 1000); variometer.Volume = Math.Min(100, (int)(Math.Abs(iFlightModel.Velocity.Z - 0.3f) * 100)); } } int throttle = 0; int rudder = 0; int elevator = 0; int aileron = 0; if (owner.InputManager.IsJoyStickAvailable) { throttle = owner.InputManager.GetAxisValue("throttle"); rudder = owner.InputManager.GetAxisValue("rudder"); elevator = owner.InputManager.GetAxisValue("elevator"); aileron = owner.InputManager.GetAxisValue("aileron"); } else { if (owner.InputManager.KeyBoardState != null) { if (owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.NumPad9] || owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.PageUp]) { kbThrottle = Math.Min(100, kbThrottle + 75 * elapsedTime); } else if (owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.NumPad7] || owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.PageDown]) { kbThrottle = Math.Max(-100, kbThrottle - 75 * elapsedTime); } //else throttle = (int)(200 * (iFlightModel.Throttle - 0.5)); if (owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.NumPad3] || owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.End]) { kbRudder = Math.Min(100, kbRudder + 200 * elapsedTime); } else if (owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.NumPad1] || owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.Home]) { kbRudder = Math.Max(-100, kbRudder - 200 * elapsedTime); } else if (Math.Abs(kbRudder) < 5) { kbRudder = 0; } else { kbRudder = Math.Max(-100, Math.Min(100, kbRudder + (kbRudder > 0 ? -350 * elapsedTime : 350 * elapsedTime))); } if (owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.NumPad2] || owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.DownArrow]) { kbElevator = Math.Min(100, kbElevator + 300 * elapsedTime); } else if (owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.NumPad8] || owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.UpArrow]) { kbElevator = Math.Max(-100, kbElevator - 300 * elapsedTime); } else if (Math.Abs(kbElevator) < 5) { kbElevator = 0; } else { kbElevator = Math.Max(-100, Math.Min(100, kbElevator + (kbElevator > 0 ? -350 * elapsedTime : 350 * elapsedTime))); } if (owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.NumPad4] || owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.LeftArrow]) { kbAileron = Math.Max(-100, kbAileron - 75 * elapsedCumul); } else if (owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.NumPad6] || owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.RightArrow]) { kbAileron = Math.Min(100, kbAileron + 75 * elapsedCumul); } else if (Math.Abs(kbAileron) < 5) { kbAileron = 0; } else { kbAileron = Math.Max(-100, Math.Min(100, kbAileron + (kbAileron > 0 ? -450 * elapsedTime : 450 * elapsedTime))); } throttle = (int)kbThrottle; rudder = (int)kbRudder; elevator = (int)kbElevator; aileron = (int)kbAileron; } } // Flaps & Gear if (owner.InputManager.KeyBoardState != null) { if (AircraftParameters.HasFlaps) { if (owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.F]) { if (!flapsKeyDown) { flapsKeyDown = true; iFlightModel.FlapsExtended = !iFlightModel.FlapsExtended; } } else if (flapsKeyDown) { flapsKeyDown = false; } } if (AircraftParameters.HasRetracts) { if (owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.G]) { if (!gearKeyDown) { gearKeyDown = true; iFlightModel.GearExtended = !iFlightModel.GearExtended; } } else if (gearKeyDown) { gearKeyDown = false; } } } if (AircraftParameters.HasFlaps) { int flapsChannel = owner.InputManager.GetAxisValue("flaps"); if (Math.Abs(flapsChannel - prevFlapsChannel) > 50) { prevFlapsChannel = flapsChannel; iFlightModel.FlapsExtended = !iFlightModel.FlapsExtended; } } if (AircraftParameters.HasRetracts) { int gearChannel = owner.InputManager.GetAxisValue("gear"); if (Math.Abs(gearChannel - prevGearChannel) > 50) { prevGearChannel = gearChannel; iFlightModel.GearExtended = !iFlightModel.GearExtended; } } // Towing if (AircraftParameters.AllowsTowing && owner.InputManager.KeyBoardState[Microsoft.DirectX.DirectInput.Key.T]) { if (!towKeyDown) { if (!iFlightModel.CableEnabled) { if (towing == null) { towing = new Towing(); } owner.CenterHud.ShowGameText("", 1f); iFlightModel.Reset(); crashTime = 0; towing.Start(); iFlightModel.CableEnabled = true; iFlightModel.CableLength = 10f; } else { iFlightModel.CableEnabled = false; } } towKeyDown = true; } else { towKeyDown = false; } if (iFlightModel.CableEnabled) { if (towing.Time > 70f) { iFlightModel.CableEnabled = false; } } if ((iFlightModel.AircraftParameters.Channels < 4) && (useAileronForRudder)) { rudder = aileron; } iFlightModel.Throttle = throttle / 100.0; iFlightModel.Rudder = rudder / 100.0; iFlightModel.Elevator = elevator / 100.0; iFlightModel.Ailerons = aileron / 100.0; if (expoRoll) { iFlightModel.Ailerons *= iFlightModel.Ailerons * Math.Sign(aileron); } if (expoPitch) { iFlightModel.Elevator *= iFlightModel.Elevator * Math.Sign(elevator); } if (expoYaw) { iFlightModel.Rudder *= iFlightModel.Rudder * Math.Sign(rudder); } float height = heightmap.GetHeightAt(-iFlightModel.Y, -iFlightModel.X); iFlightModel.UpdateControls(elapsedTime); airplane.Position = new Vector3(-iFlightModel.Y, -iFlightModel.Z, -iFlightModel.X); Vector3 angles = iFlightModel.Angles; airplane.YawPitchRoll = new Vector3(angles.Z, angles.Y, angles.X); airplane.OnFrameMove(device, totalTime, elapsedTime); iFlightModel.Wind = wind.GetWindAt(airplane.Position); //windVector.Vertex1 = airplane.Position; //windVector.Vertex2 = airplane.Position + iFlightModel.Wind; //windVector.OnFrameMove(device, totalTime, elapsedTime); //debugObject.Position = model.DebugPosition; //debugObject.OnFrameMove(device, totalTime, elapsedTime); if (towing != null) { if (iFlightModel.CableEnabled) { towLine.Vertex1 = airplane.Position; towLine.Vertex2 = towing.Position; towLine.OnFrameMove(device, totalTime, elapsedTime); } iFlightModel.CableOrigin = FlightModelWind.ToModel(towing.Position); iFlightModel.CableVelocity = FlightModelWind.ToModel(towing.Velocity); towing.OnFrameMove(device, totalTime, elapsedTime); } smoke.Position = this.Position - (float)iFlightModel.Throttle * this.Airplane.Front; smoke.OnFrameMove(device, totalTime, elapsedTime); if (iFlightModel.OnWater) { ripples.AddRipple((float)iFlightModel.Speed, Position, totalTime); } ripples.OnFrameMove(device, totalTime, elapsedTime); //Program.Instance.CenterHud.ShowGameText(model.RelativeRotorForce.ToString(), totalTime, 1.0); if ((iFlightModel.Crashed) && (crashTime == 0)) { owner.HandleCrash(); this.HandleCrash(); crashTime = totalTime; Framework.Instance.CurrentCamera.Shake(totalTime, 1.0, 0.05f, 50); } //normalObject.Position = new Vector3(airplane.Position.X, height, airplane.Position.Z); //terrainNormal.Vertex2 = heightmap.GetNormalAt(airplane.Position.X, airplane.Position.Z); // Collisions if (!iFlightModel.Crashed) { // Collisions List <Vector3> newColPoints = iFlightModel.CollisionPoints; for (int i = 0; i < Math.Min(newColPoints.Count, prevColPoints.Count); i++) { Vector3 rayPos = prevColPoints[i]; Vector3 rayDir = newColPoints[i] - prevColPoints[i]; foreach (CollisionMesh collisionMesh in CollisionManager.MeshList) { if (collisionMesh.Intersects(rayPos, rayDir)) { iFlightModel.Crashed = true; iFlightModel.Velocity = new Vector3(0, 0, 0); newColPoints = new List <Vector3>(); break; } } } prevColPoints = newColPoints; } prevPos = this.Position; }
public void OnFrameMove(Device device, double totalTime, float elapsedTime) { if (playing) { if (startTime == -1) { startTime = totalTime; } relativeTime = totalTime - startTime; if (relativeTime >= nextTime) { previousTime = nextTime; previousState.Position = nextState.Position; previousState.Orientation = nextState.Orientation; previousState.Rudder = nextState.Rudder; previousState.Throttle = nextState.Throttle; previousState.Elevator = nextState.Elevator; previousState.Ailerons = nextState.Ailerons; previousState.Smoke = nextState.Smoke; previousState.Gear = nextState.Gear; previousState.Flaps = nextState.Flaps; previousState.OnWater = nextState.OnWater; try { nextTime = binaryReader.ReadDouble(); nextState.Read(binaryReader); } catch (Exception) { StopPlaying(); return; } } double factor = (relativeTime - previousTime) / (nextTime - previousTime); float newYaw; float newPitch; float newRoll; if (Math.Abs(previousState.Orientation.X - nextState.Orientation.X) > Math.PI) { newYaw = (float)(1 - factor) * ((previousState.Orientation.X + 2 * (float)Math.PI) % (2 * (float)Math.PI)) + (float)factor * ((nextState.Orientation.X + 2 * (float)Math.PI) % (2 * (float)Math.PI)); } else { newYaw = (float)(1 - factor) * previousState.Orientation.X + (float)factor * nextState.Orientation.X; } if (Math.Abs(previousState.Orientation.Y - nextState.Orientation.Y) > Math.PI) { newPitch = (float)(1 - factor) * ((previousState.Orientation.Y + 2 * (float)Math.PI) % (2 * (float)Math.PI)) + (float)factor * ((nextState.Orientation.Y + 2 * (float)Math.PI) % (2 * (float)Math.PI)); } else { newPitch = (float)(1 - factor) * previousState.Orientation.Y + (float)factor * nextState.Orientation.Y; } if (Math.Abs(previousState.Orientation.Z - nextState.Orientation.Z) > Math.PI) { newRoll = (float)(1 - factor) * ((previousState.Orientation.Z + 2 * (float)Math.PI) % (2 * (float)Math.PI)) + (float)factor * ((nextState.Orientation.Z + 2 * (float)Math.PI) % (2 * (float)Math.PI)); } else { newRoll = (float)(1 - factor) * previousState.Orientation.Z + (float)factor * nextState.Orientation.Z; } if ((currentState.Flaps) && (Flaps < 0.9999)) { Flaps = Math.Min(1.0, Flaps + elapsedTime / AircraftParameters.FlapsDelay); } else if ((Flaps > 0.0001) && (!currentState.Flaps)) { Flaps = Math.Max(0, Flaps - elapsedTime / AircraftParameters.FlapsDelay); } if ((currentState.Gear) && (Gear < 0.9999)) { Gear = Math.Min(1.0, Gear + elapsedTime / AircraftParameters.GearDelay); } else if ((Gear > 0.0001) && (!currentState.Gear)) { Gear = Math.Max(0, Gear - elapsedTime / AircraftParameters.GearDelay); } currentState.Position = (float)(1 - factor) * previousState.Position + (float)factor * nextState.Position; currentState.Orientation = new Microsoft.DirectX.Vector3(newYaw, newPitch, newRoll); currentState.Rudder = (1 - factor) * previousState.Rudder + factor * nextState.Rudder; currentState.Throttle = (1 - factor) * previousState.Throttle + factor * nextState.Throttle; currentState.Elevator = (1 - factor) * previousState.Elevator + factor * nextState.Elevator; currentState.Ailerons = (1 - factor) * previousState.Ailerons + factor * nextState.Ailerons; currentState.Smoke = previousState.Smoke; currentState.Gear = previousState.Gear; currentState.Flaps = previousState.Flaps; currentState.OnWater = previousState.OnWater; float speed = (float)((currentState.Position - nextState.Position).Length() / (nextTime - previousTime)); airplaneModel.Position = currentState.Position; airplaneModel.YawPitchRoll = currentState.Orientation; airplaneModel.OnFrameMove(device, totalTime, elapsedTime); smoke.Position = airplaneModel.Position - (float)Throttle * this.airplaneModel.Front; smoke.Emitting = currentState.Smoke; smoke.OnFrameMove(device, totalTime, elapsedTime); if (currentState.OnWater) { ripples.AddRipple(speed, airplaneModel.Position, totalTime); } ripples.OnFrameMove(device, totalTime, elapsedTime); } }