/// <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();
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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();
        }
Exemple #5
0
        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);
                }
            }
        }
Exemple #6
0
        /// <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);
            }
        }
Exemple #8
0
        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);
            }
        }
Exemple #10
0
        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();
            }
        }