/// <summary> /// Renders the space craft at it's correct scale and rotation according to the camera. /// The engines are rendered first and then the space craft body. /// </summary> public override void RenderGdi(Graphics graphics, Camera camera) { if (Terminated) { return; } // Only draws the ship if it's visible if (Visibility(camera.Bounds) > 0) { RectangleD bounds = ComputeBoundingBox(); // In range for render if (camera.Intersects(bounds)) { RectangleF screenBounds = RenderUtils.ComputeBoundingBox(Position, camera.Bounds, Width, Height); // Saftey if (screenBounds.Width > RenderUtils.ScreenWidth * 500) { return; } RenderBelow(graphics, camera); RenderShip(graphics, camera, screenBounds); RenderAbove(graphics, camera); } } // Only draw orbit traces and launch trails for detatched ships if (Parent == null) { camera.ApplyScreenRotation(graphics); if (camera.Bounds.Width > 1000) { if (GravitationalParent != null) { string parentName = GravitationalParent.ToString(); if (_launchTrails.ContainsKey(parentName)) { _launchTrails[parentName].Draw(graphics, camera, GravitationalParent); } } } // Don't draw orbit traces on the ground base.RenderGdi(graphics, camera); graphics.ResetTransform(); } }
/// <summary> /// Updates the spacecraft and it's children. /// </summary> public override void Update(double dt) { ComputeCachedProperties(); double altitude = GetRelativeAltitude(); if (GravitationalParent == null) { IspMultiplier = 1; } else { IspMultiplier = GravitationalParent.GetIspMultiplier(altitude); } if (Parent == null) { UpdateEngines(dt); if (Thrust > 0 && _isReleased) { var thrustVector = new DVector2(Math.Cos(Pitch) * Math.Cos(Yaw), Math.Sin(Pitch) * Math.Cos(Yaw)); var yawVector = new DVector2(Math.Cos(Pitch) * Math.Sin(Yaw), Math.Sin(Pitch) * Math.Sin(Yaw)); AccelerationN += (thrustVector * Thrust) / Mass; AccelerationY += (yawVector * Thrust) / Mass; } if (_requiresStaging) { // Simulate simple staging mechanism double sAngle = StageOffset.Angle(); DVector2 stagingNormal = DVector2.FromAngle(Pitch + sAngle + Constants.PiOverTwo); AccelerationN += stagingNormal * StagingForce; _requiresStaging = false; } if (_isReleased) { // Integrate acceleration Velocity += AccelerationG * dt; Velocity += AccelerationD * dt; Velocity += AccelerationL * dt; Velocity += AccelerationN * dt; LateralVelocity += AccelerationY * dt; LateralPosition += LateralVelocity * dt; } // Re-normalize FTL scenarios if (Velocity.LengthSquared() > Constants.SpeedLightSquared) { Velocity.Normalize(); Velocity *= Constants.SpeedOfLight; } // If the craft is on the ground with high time warpd don't update the position as normal. // Instead just keep putting the ship at the correct spot on it's gravitational body based on rotation. if (OnGround && dt > 5) { DVector2 parentOffset = GravitationalParent.Position - Position; parentOffset.Normalize(); Position = GravitationalParent.Position + parentOffset * GravitationalParent.SurfaceRadius; } else { // Integrate velocity Position += Velocity * dt; } MachNumber = GetRelativeVelocity().Length() * 0.0029411764; foreach (ISpaceCraft child in Children) { child.UpdateChildren(Position, Velocity); } _trailTimer += dt; // Somewhat arbitrary conditions for launch trails if (dt < 0.1666666666 && !InOrbit && !OnGround && _cachedAltitude > 50 && _cachedAltitude < GravitationalParent.AtmosphereHeight * 2 && _trailTimer > 1) { string parentName = GravitationalParent.ToString(); if (!_launchTrails.ContainsKey(parentName)) { _launchTrails.Add(parentName, new LaunchTrail()); } _launchTrails[parentName].AddPoint(Position, GravitationalParent, Throttle > 0); _trailTimer = 0; } } }
/// <summary> /// Updates the spacecraft and it's children. /// </summary> public override void Update(double dt) { ComputeCachedProperties(); double altitude = GetRelativeAltitude(); IspMultiplier = GravitationalParent.GetIspMultiplier(altitude); if (Parent == null) { UpdateEngines(dt); if (Thrust > 0) { var thrustVector = new DVector2(Math.Cos(Pitch), Math.Sin(Pitch)); AccelerationN += (thrustVector * Thrust) / Mass; } if (_requiresStaging) { // Simulate simple staging mechanism double sAngle = StageOffset.Angle(); DVector2 stagingNormal = DVector2.FromAngle(Pitch + sAngle + Math.PI * 0.5); AccelerationN += stagingNormal * StagingForce; _requiresStaging = false; } // Integrate acceleration Velocity += (AccelerationG * dt); Velocity += (AccelerationD * dt); Velocity += (AccelerationN * dt); Velocity += (AccelerationL * dt); // Re-normalize FTL scenarios if (Velocity.LengthSquared() > Constants.SpeedLightSquared) { Velocity.Normalize(); Velocity *= Constants.SpeedOfLight; } // Integrate velocity Position += (Velocity * dt); MachNumber = GetRelativeVelocity().Length() * 0.0029411764; foreach (ISpaceCraft child in Children) { child.UpdateChildren(Position, Velocity); } _trailTimer += dt; // Somewhat arbitrary conditions for launch trails if (dt < 0.1666666666 && !InOrbit && _cachedAltitude > 50 && _cachedAltitude < GravitationalParent.AtmosphereHeight * 2 && _trailTimer > 1) { string parentName = GravitationalParent.ToString(); if (!_launchTrails.ContainsKey(parentName)) { _launchTrails.Add(parentName, new LaunchTrail()); } _launchTrails[parentName].AddPoint(Position, GravitationalParent, Throttle > 0); _trailTimer = 0; } } }