/// <summary>Renders a single planet.</summary> /// <param name="component">The component.</param> /// <param name="translation">The translation.</param> private void RenderPlanet(PlanetRenderer component, ref FarPosition translation) { // Get factory, skip if none known. var factory = component.Factory; if (factory == null) { return; } // Load the texture if we don't have it yet. LoadPlanetTextures(factory, component, ((ContentSystem)Manager.GetSystem(ContentSystem.TypeId)).Content); // The position and orientation we're rendering at and in. var transform = ((ITransform)Manager.GetComponent(component.Entity, TransformTypeId)); var position = transform.Position; var rotation = transform.Angle; // Get position relative to our sun, to rotate atmosphere and shadow. var toSun = Vector2.Zero; var sun = GetSun(component.Entity); if (sun > 0) { var sunTransform = ((ITransform)Manager.GetComponent(sun, TransformTypeId)); if (sunTransform != null) { toSun = (Vector2)(sunTransform.Position - position); var matrix = Matrix.CreateRotationZ(-rotation); Vector2.Transform(ref toSun, ref matrix, out toSun); toSun.Normalize(); } } // Apply transformation. _planet.Center = (Vector2)FarUnitConversion.ToScreenUnits(position + translation); // Set remaining parameters for draw. _planet.Rotation = rotation; _planet.SetSize(component.Radius * 2); _planet.SurfaceTexture = component.Albedo; _planet.SurfaceNormals = component.Normals; _planet.SurfaceSpecular = component.Specular; _planet.SurfaceLights = component.Lights; _planet.Clouds = component.Clouds; _planet.SurfaceTint = factory.SurfaceTint; _planet.SpecularAlpha = factory.SpecularAlpha; _planet.SpecularExponent = factory.SpecularExponent; _planet.SpecularOffset = factory.SpecularOffset; _planet.AtmosphereTint = factory.AtmosphereTint; _planet.AtmosphereInner = factory.AtmosphereInner; _planet.AtmosphereOuter = factory.AtmosphereOuter; _planet.AtmosphereInnerAlpha = factory.AtmosphereInnerAlpha; _planet.AtmosphereOuterAlpha = factory.AtmosphereOuterAlpha; _planet.SurfaceRotation = component.SurfaceRotation; _planet.LightDirection = toSun; // And draw it. _planet.Draw(); }
public void OnDraw(Draw message) { if (!Enabled) { return; } var camera = (CameraSystem)Manager.GetSystem(CameraSystem.TypeId); // Get camera transform. var cameraTransform = camera.Transform; var cameraTranslation = camera.Translation; var interpolation = (InterpolationSystem)Manager.GetSystem(InterpolationSystem.TypeId); // Iterate over all visible entities. _spriteBatch.Begin( SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, cameraTransform); foreach (var entity in camera.VisibleEntities) { var ai = (ArtificialIntelligence)Manager.GetComponent(entity, ArtificialIntelligence.TypeId); if (ai != null) { FarPosition position; float angle; interpolation.GetInterpolatedTransform(entity, out position, out angle); position = position + cameraTranslation; // Render vegetative influences. DrawArrow((Vector2)position, ai.GetLastEscape(), Color.Red); DrawArrow((Vector2)position, ai.GetLastSeparation(), Color.Yellow); DrawArrow((Vector2)position, ai.GetLastCohesion(), Color.Blue); DrawArrow((Vector2)position, ai.GetLastFormation(), Color.Teal); // Render target. DrawArrow((Vector2)position, ai.GetBehaviorTargetDirection(), Color.Green); // Render current state. position = FarUnitConversion.ToScreenUnits(position); position.Y += 20; // don't intersect with entity id if visible _spriteBatch.DrawString( _font, "AI: " + ai.CurrentBehavior, (Vector2)position, Color.White, 0, Vector2.Zero, 1f / camera.CameraZoom, SpriteEffects.None, 0); } } _spriteBatch.End(); }
protected override FarTransform GetTransform() { var camera = (CameraSystem)Manager.GetSystem(CameraSystem.TypeId); FarTransform transform; transform.Matrix = camera.Transform; transform.Matrix *= Matrix.CreateTranslation( -transform.Matrix.Translation.X, -transform.Matrix.Translation.Y, 0) * Matrix.CreateScale(1, -1, 1); transform.Translation = FarUnitConversion.ToScreenUnits(camera.Translation); return(transform); }
public void OnDraw(Draw message) { if (!Enabled) { return; } var camera = (CameraSystem)Manager.GetSystem(CameraSystem.TypeId); // Get camera transform. var cameraTransform = camera.Transform; var cameraTranslation = camera.Translation; var interpolation = (InterpolationSystem)Manager.GetSystem(InterpolationSystem.TypeId); // Iterate over all visible entities. _spriteBatch.Begin( SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, cameraTransform); foreach (var entity in camera.VisibleEntities) { var transform = (ITransform)Manager.GetComponent(entity, TransformTypeId); if (transform != null) { int x, y, subX, subY; BitwiseMagic.Unpack(CellSystem.GetCellIdFromCoordinates(transform.Position), out x, out y); BitwiseMagic.Unpack(CellSystem.GetSubCellIdFromCoordinates(transform.Position), out subX, out subY); var text = string.Format( "ID: {0} @ {1} / {2}\nCell: {3}:{4}, SubCell: {5}:{6}", transform.Entity, transform.Position, transform.Angle, x, y, subX, subY); FarPosition position; float angle; interpolation.GetInterpolatedTransform(transform.Entity, out position, out angle); position = FarUnitConversion.ToScreenUnits(position + cameraTranslation); _spriteBatch.DrawString( _font, text, (Vector2)position, Color.White, 0, Vector2.Zero, 1f / camera.CameraZoom, SpriteEffects.None, 1); } } _spriteBatch.End(); }
public void OnDraw(Draw message) { if (!Enabled) { return; } var camera = ((CameraSystem)Manager.GetSystem(CameraSystem.TypeId)); var cameraTransform = camera.Transform; var cameraTranslation = camera.Translation; // Update all floating texts. _spriteBatch.Begin( SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, cameraTransform); for (var i = _texts.Count - 1; i >= 0; i--) { var text = _texts[i]; text.Position.Y -= UnitConversion.ToSimulationUnits(FloatDistance / text.TotalTimeToLive); _spriteBatch.Draw( text.Value, (Vector2)FarUnitConversion.ToScreenUnits(text.Position + cameraTranslation), null, text.Color, 0f, Vector2.Zero, 1f / camera.CameraZoom, SpriteEffects.None, 0f); if (text.TimeToLive > 0) { --text.TimeToLive; } } _spriteBatch.End(); for (var i = _texts.Count - 1; i >= 0; i--) { var text = _texts[i]; if (text.TimeToLive == 0) { // This text has expired, don't show it next time. text.Value.Dispose(); _texts.RemoveAt(i); } } }
/// <summary>Renders the specified sun.</summary> /// <param name="component">The component.</param> /// <param name="transform">The transform.</param> /// <param name="translation">The translation.</param> private void RenderSun(SunRenderer component, Matrix transform, FarPosition translation) { // Get absolute position of sun. var position = ((ITransform)Manager.GetComponent(component.Entity, TransformTypeId)).Position; // Apply transformation. _sun.Center = (Vector2)FarUnitConversion.ToScreenUnits(position + translation); _sun.SetTransform(transform); _sun.Color = component.Tint; // Set remaining parameters for draw. _sun.SetSize(component.Radius * 2); _sun.SurfaceRotation = component.SurfaceRotation; _sun.PrimaryTurbulenceRotation = component.PrimaryTurbulenceRotation; _sun.SecondaryTurbulenceRotation = component.SecondaryTurbulenceRotation; // And draw it. _sun.Draw(); }
public void Play(string effect, FarPosition position, Vector2 impulse, float rotation = 0.0f, float scale = 1.0f) { if (!Enabled) { return; } // Check if it's in bounds, i.e. whether we have to render it at all. var camera = (CameraSystem)Manager.GetSystem(CameraSystem.TypeId); if (!camera.ComputeVisibleBounds().Contains(position)) { return; } // Let there be graphics! position = FarUnitConversion.ToScreenUnits(position); lock (this) { GetEffect(effect).Trigger(ref position, ref impulse, rotation, scale); } }
protected override void Draw() { // Only do the actual rendering if we have our environment. if (_target == null) { // Otherwise just clear the screen. GraphicsDeviceManager.GraphicsDevice.Clear(Color.FromNonPremultiplied(64, 64, 64, 255)); return; } // OK, set our custom render target and clear it. GraphicsDeviceManager.GraphicsDevice.SetRenderTarget(_target); GraphicsDeviceManager.GraphicsDevice.Clear(Color.FromNonPremultiplied(64, 64, 64, 255)); try { // Toggle systems depending on the check state in the context menu. foreach (var component in _manager.Components) { if (component is ParticleEffects) { ((ParticleEffects)component).SetGroupEnabled(ParticleEffects.EffectGroup.Thruster, ((ToolStripMenuItem)_contextMenu.Items["thrusterfx"]).Checked); } } if (_slots != null) { _slots.Enabled = ((ToolStripMenuItem)_contextMenu.Items["slots"]).Checked; } if (_maxBounds != null) { _maxBounds.Enabled = ((ToolStripMenuItem)_contextMenu.Items["maxbounds"]).Checked; } if (_shields != null) { _shields.Enabled = ((ToolStripMenuItem)_contextMenu.Items["shieldfx"]).Checked; } // Render the grid in the background. if (_grid != null && ((ToolStripMenuItem)_contextMenu.Items["grid"]).Checked) { _grid.SetSize(GraphicsDeviceManager.GraphicsDevice.Viewport.Width, GraphicsDeviceManager.GraphicsDevice.Viewport.Height); _grid.SetCenter(GraphicsDeviceManager.GraphicsDevice.Viewport.Width / 2f, GraphicsDeviceManager.GraphicsDevice.Viewport.Height / 2f); _grid.Draw(); } // Render our light source, if it's set. This is for lighting of objects that // support it (only planets for now). if (_sunId > 0) { var mousePos = PointToClient(MousePosition); FarPosition sunPos; sunPos.X = mousePos.X - Width / 2f; sunPos.Y = mousePos.Y - Height / 2f; var t = (ITransform)Manager.GetComponent(_sunId, TransformTypeId); t.Position = FarUnitConversion.ToSimulationUnits(sunPos); } // Draw our mini simulation. _manager.Draw(_frame, _drawTimer.Interval); } catch (Exception ex) { // Something went wrong, so we'll just clear the manager, hoping that'll at least // keep the error from happening over and over again. Clear(); Console.WriteLine(ex); } // Switch back to main backbuffer and copy over our render target. GraphicsDeviceManager.GraphicsDevice.SetRenderTarget(null); _batch.Begin(SpriteSortMode.Immediate, BlendState.Opaque); _batch.Draw(_target, GraphicsDeviceManager.GraphicsDevice.PresentationParameters.Bounds, Color.White); _batch.End(); }
public void OnDraw(Draw message) { if (!Enabled) { return; } // Get global transform. var transform = GetTransform(); var translation = GetTranslation(); // Get delta to keep update speed constant regardless of framerate. var delta = (message.ElapsedMilliseconds / 1000f) * _simulationSpeed(); // Get the interpolation system to get an interpolated position for the effect generator. var interpolation = (InterpolationSystem)Manager.GetSystem(InterpolationSystem.TypeId); // Handle particle effects attached to entities. foreach (var component in Components) { // Skip disabled components. if (!component.Enabled) { continue; } // Handle each effect per component. foreach (var effect in component.Effects) { // Get info for triggering and rendering. FarPosition position; float angle; interpolation.GetInterpolatedTransform(component.Entity, out position, out angle); // Load / initialize particle effects if they aren't yet. if (effect.Effect == null) { var content = ((ContentSystem)Manager.GetSystem(ContentSystem.TypeId)).Content; effect.Effect = content.Load <ParticleEffect>(effect.AssetName).DeepCopy(); effect.Effect.LoadContent(content); effect.Effect.Initialise(); } // Only do the triggering work if the effect is actually enabled. // ALWAYS RENDER, to allow already triggered effects to play out (and not // instantly disappear). if (effect.Enabled && effect.Scale * effect.Intensity > 0.1f) { // Check if it's in bounds, i.e. whether we have to trigger it at all. var localTranslation = Vector2.Transform((Vector2)(position + translation), transform); var bounds = _renderer.GraphicsDeviceService.GraphicsDevice.Viewport.Bounds; bounds.Inflate(256, 256); if (bounds.Contains((int)localTranslation.X, (int)localTranslation.Y)) { // Move the offset according to rotation. var cosRadians = (float)Math.Cos(angle); var sinRadians = (float)Math.Sin(angle); FarPosition offset; offset.X = effect.Offset.X * cosRadians - effect.Offset.Y * sinRadians; offset.Y = effect.Offset.X * sinRadians + effect.Offset.Y * cosRadians; // Adjust emitting rotation. angle += effect.Direction; // Trigger. effect.Effect.Trigger(offset, angle, effect.Scale * effect.Intensity); } } // Render at owning entity's position. FarTransform localTransform; localTransform.Matrix = transform; localTransform.Translation = FarUnitConversion.ToScreenUnits(translation + position); _renderer.RenderEffect(effect.Effect, ref localTransform); // Update after rendering. effect.Effect.Update(delta); } } // Render and update all known unbound effects (not attached to an entity). FarTransform globalTransform; globalTransform.Matrix = transform; globalTransform.Translation = FarUnitConversion.ToScreenUnits(translation); foreach (var effect in _effects.Values) { _renderer.RenderEffect(effect, ref globalTransform); effect.Update(delta); } }
public void OnDraw(Draw message) { if (!Enabled) { return; } var camera = (CameraSystem)Manager.GetSystem(CameraSystem.TypeId); var interpolation = (CameraCenteredInterpolationSystem)Manager.GetSystem(InterpolationSystem.TypeId); foreach (var effect in Components) { // Render shields, using accumulative coverage and structure of // dominant shield (largest coverage). // Get energy, start fading out when below half energy. var power = 0f; var energy = (Energy)Manager.GetComponent(effect.Entity, Energy.TypeId); if (energy != null) { // Compute relative energy in lower half. power = Math.Min(1, 2 * energy.Value / energy.MaxValue); // Based on how low we are, occasionally flicker the shield (by skipping the render). if (power < 0.01f || Random.NextDouble() * 0.5 > power) { continue; } } // Got some energy left, figure out coverage. var equipment = (SpaceItemSlot)Manager.GetComponent(effect.Entity, ItemSlot.TypeId); var attributes = (Attributes <AttributeType>)Manager.GetComponent(effect.Entity, Attributes <AttributeType> .TypeId); var coverage = 0f; var radius = 0f; if (attributes != null) { coverage = MathHelper.Clamp(attributes.GetValue(AttributeType.ShieldCoverage), 0f, 1f) * MathHelper.TwoPi; radius = attributes.GetValue(AttributeType.ShieldRadius); } // Skip render if we have no coverage or a tiny radius. if (coverage <= 0f || radius <= 5f) { continue; } // Figure out best shield (for texture). var maxQuality = ItemQuality.None; foreach (SpaceItemSlot slot in equipment.AllSlots) { // Skip empty slots. if (slot.Item < 1) { continue; } // Skip all non-shields. var shield = (Shield)Manager.GetComponent(slot.Item, ComponentSystem.Components.Shield.TypeId); if (shield == null) { continue; } // Check level. if (shield.Quality > maxQuality) { maxQuality = shield.Quality; // Load texture if necessary. if (shield.Structure == null && !string.IsNullOrWhiteSpace(shield.Factory.Structure)) { shield.Structure = ((ContentSystem)Manager.GetSystem(ContentSystem.TypeId)).Content.Load <Texture2D>(shield.Factory.Structure); } // Set structure overlay and custom color. _shader.Structure = shield.Structure; _shader.Color = shield.Factory.Tint; } } // Apply relative opacity with minimum visibility. _shader.Color *= 0.3f + 0.7f * power; // Position the shader. Only rotation differs for equipped shields. FarPosition position; float angle; interpolation.GetInterpolatedTransform(effect.Entity, out position, out angle); _shader.Center = (Vector2)FarUnitConversion.ToScreenUnits(position + camera.Translation); // Set size. _shader.SetSize(radius * 2); // Set coverage of the shield. _shader.Coverage = coverage; // Rotate the structure. _shader.StructureRotation = MathHelper.ToRadians(message.Frame / Settings.TicksPerSecond * 5); // Set transform, including rotation of owner and slot. _shader.Transform = Matrix.CreateRotationZ(-angle) * camera.Transform; // Draw it. _shader.Draw(); } }