Inheritance: IDisposable
Beispiel #1
0
        public void RenderAfterWorld(WorldRenderer wr, Actor self)
        {
            foreach (var i in impacts)
            {
                var alpha = 255.0f * i.Time / info.DisplayDuration;
                var rangeStep = alpha / i.Range.Length;

                RangeCircleRenderable.DrawRangeCircle(wr, i.CenterPosition, i.OuterRange,
                    1, Color.FromArgb((int)alpha, i.Color), 0, i.Color);

                foreach (var r in i.Range)
                {
                    var tl = wr.ScreenPosition(i.CenterPosition - new WVec(r.Length, r.Length, 0));
                    var br = wr.ScreenPosition(i.CenterPosition + new WVec(r.Length, r.Length, 0));
                    var rect = RectangleF.FromLTRB(tl.X, tl.Y, br.X, br.Y);

                    Game.Renderer.WorldRgbaColorRenderer.FillEllipse(rect, Color.FromArgb((int)alpha, i.Color));

                    alpha -= rangeStep;
                }

                if (!wr.World.Paused)
                    i.Time--;
            }

            impacts.RemoveAll(i => i.Time == 0);
        }
Beispiel #2
0
        public IEnumerable<IRenderable> Render(WorldRenderer wr)
        {
            if (wr.world.FogObscures(pos.ToCPos()))
                yield break;

            yield return new TextRenderable(font, pos, 0, color, text);
        }
 public void InitPalette( WorldRenderer wr )
 {
     var paletteName = "{0}{1}".F( info.BaseName, owner.InternalName );
     var newpal = new Palette(wr.GetPalette(info.BasePalette),
                      new PlayerColorRemap(info.PaletteFormat, owner.ColorRamp));
     wr.AddPalette(paletteName, newpal);
 }
Beispiel #4
0
        public IEnumerable<IRenderable> Render(WorldRenderer wr)
        {
            if (wr.World.FogObscures(wr.World.Map.CellContaining(pos)))
                yield break;

            yield return new TextRenderable(font, pos, 0, color, text);
        }
Beispiel #5
0
        public override void DrawInner( WorldRenderer wr )
        {
            if (video == null)
                return;

            if (!(stopped || paused))
            {
                var nextFrame = (int)float2.Lerp(0, video.Frames, Sound.VideoSeekPosition*invLength);
                if (nextFrame > video.Frames)
                {
                    Stop();
                    return;
                }

                while (nextFrame > video.CurrentFrame)
                {
                    video.AdvanceFrame();
                    if (nextFrame == video.CurrentFrame)
                        videoSprite.sheet.Texture.SetData(video.FrameData);
                }
            }

            Game.Renderer.RgbaSpriteRenderer.DrawSprite(videoSprite, videoOrigin, videoSize);

            if (DrawOverlay)
                Game.Renderer.RgbaSpriteRenderer.DrawSprite(overlaySprite, videoOrigin, videoSize);
        }
Beispiel #6
0
        public IEnumerable<IRenderable> Render(WorldRenderer wr)
        {
            var rc = cargo.Render(wr);

            // Don't render anything if the cargo is invisible (e.g. under fog)
            if (!rc.Any())
                yield break;

            var parachuteShadowPalette = wr.Palette(parachutableInfo.ParachuteShadowPalette);
            foreach (var c in rc)
            {
                if (!c.IsDecoration && shadow == null)
                    yield return c.WithPalette(parachuteShadowPalette).WithZOffset(c.ZOffset - 1).AsDecoration();

                yield return c.OffsetBy(pos - c.Pos);
            }

            var shadowPalette = !string.IsNullOrEmpty(parachutableInfo.ShadowPalette) ? wr.Palette(parachutableInfo.ShadowPalette) : rc.First().Palette;
            if (shadow != null)
                foreach (var r in shadow.Render(pos - new WVec(0, 0, pos.Z), WVec.Zero, 1, shadowPalette, 1f))
                    yield return r;

            var parachutePalette = !string.IsNullOrEmpty(parachutableInfo.ParachutePalette) ? wr.Palette(parachutableInfo.ParachutePalette) : rc.First().Palette;
            if (parachute != null)
                foreach (var r in parachute.Render(pos, parachuteOffset, 1, parachutePalette, 1f))
                    yield return r;
        }
Beispiel #7
0
        public void RenderAfterWorld(WorldRenderer wr, Actor self)
        {
            Color trailStart = TrailColor;
            Color trailEnd = Color.FromArgb(trailStart.A - 255 / TrailLength, trailStart.R,
                                            trailStart.G, trailStart.B);

            // LocalPlayer is null on shellmap
            ShroudRenderer shroud = null;
            if (self.World.LocalPlayer != null)
                shroud = self.World.LocalPlayer.Shroud;

            for (int i = positions.Count - 1; i >= 1; --i)
            {
                var conPos = positions[i];
                var nextPos = positions[i - 1];

                if (shroud == null ||
                    shroud.IsVisible(OpenRA.Traits.Util.CellContaining(conPos)) ||
                    shroud.IsVisible(OpenRA.Traits.Util.CellContaining(nextPos)))
                {
                    Game.Renderer.LineRenderer.DrawLine(conPos, nextPos, trailStart, trailEnd);

                    trailStart = trailEnd;
                    trailEnd = Color.FromArgb(trailStart.A - 255 / positions.Count, trailStart.R,
                                                trailStart.G, trailStart.B);
                }
            }
        }
 public ViewportControllerWidget(World world, WorldRenderer worldRenderer)
 {
     this.world = world;
     this.worldRenderer = worldRenderer;
     tooltipContainer = Exts.Lazy(() =>
         Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));
 }
Beispiel #9
0
        public IEnumerable<IRenderable> Render(WorldRenderer wr)
        {
            if (!a.IsInWorld || a.World.FogObscures(a.Location))
                return SpriteRenderable.None;

            return anim.Render(a.CenterPosition, wr.Palette(palette));
        }
Beispiel #10
0
        public TerrainRenderer(World world, WorldRenderer wr)
        {
            this.world = world;
            this.map = world.Map;

            var tileSize = new Size( Game.CellSize, Game.CellSize );
            var tileMapping = new Cache<TileReference<ushort,byte>, Sprite>(
                x => Game.modData.SheetBuilder.Add(world.TileSet.GetBytes(x), tileSize));

            var vertices = new Vertex[4 * map.Bounds.Height * map.Bounds.Width];

            terrainSheet = tileMapping[map.MapTiles.Value[map.Bounds.Left, map.Bounds.Top]].sheet;

            int nv = 0;

            var terrainPalette = wr.Palette("terrain").Index;

            for( int j = map.Bounds.Top; j < map.Bounds.Bottom; j++ )
                for( int i = map.Bounds.Left; i < map.Bounds.Right; i++ )
                {
                    var tile = tileMapping[map.MapTiles.Value[i, j]];
                    // TODO: move GetPaletteIndex out of the inner loop.
                    Util.FastCreateQuad(vertices, Game.CellSize * new float2(i, j), tile, terrainPalette, nv, tile.size);
                    nv += 4;

                    if (tileMapping[map.MapTiles.Value[i, j]].sheet != terrainSheet)
                        throw new InvalidOperationException("Terrain sprites span multiple sheets");
                }

            vertexBuffer = Game.Renderer.Device.CreateVertexBuffer( vertices.Length );
            vertexBuffer.SetData( vertices, nv );
        }
Beispiel #11
0
 public override void DrawInner( WorldRenderer wr )
 {
     if (!IsVisible()) return;
     // todo: fix
     paletteHeight = DrawPalette(wr, world, CurrentQueue);
     DrawBuildTabs(world, paletteHeight);
 }
Beispiel #12
0
        public IEnumerable<IRenderable> Render(WorldRenderer wr)
        {
            if (world.FogObscures(pos))
                return SpriteRenderable.None;

            return anim.Render(pos, wr.Palette(palette));
        }
Beispiel #13
0
        internal void Draw(WorldRenderer wr)
        {
            if (initializePalettes)
            {
                fogPalette = wr.Palette("fog");
                shroudPalette = wr.Palette("shroud");
                initializePalettes = false;
            }

            if (shroud != null && shroud.dirty)
            {
                shroud.dirty = false;
                for (int i = map.Bounds.Left; i < map.Bounds.Right; i++)
                    for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++)
                        sprites[i, j] = ChooseShroud(i, j);

                for (int i = map.Bounds.Left; i < map.Bounds.Right; i++)
                    for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++)
                        fogSprites[i, j] = ChooseFog(i, j);
            }

            var clipRect = Game.viewport.WorldBounds(wr.world);
            DrawShroud(wr, clipRect, sprites, shroudPalette);
            if (wr.world.WorldActor.HasTrait<Fog>())
                DrawShroud(wr, clipRect, fogSprites, fogPalette);
        }
Beispiel #14
0
		public void Render(WorldRenderer wr)
		{
			if (!cache.Any() || length != cachedLength || pos != cachedPos)
				cache = GenerateRenderables(wr);

			cache.Do(c => c.Render(wr));
		}
		public ObserverSupportPowerIconsWidget(World world, WorldRenderer worldRenderer)
		{
			this.world = world;
			this.worldRenderer = worldRenderer;
			clocks = new Dictionary<string, Animation>();
			icon = new Animation(world, "icon");
		}
 public void InitPalette( WorldRenderer wr )
 {
     var info = Rules.Info["player"].Traits.WithInterface<PlayerColorPaletteInfo>()
         .First(p => p.BaseName == Info.PlayerPalette);
     format = info.PaletteFormat;
     wr.AddPalette("colorpicker", wr.GetPalette(info.BasePalette));
 }
Beispiel #17
0
        public IEnumerable<IRenderable> Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition)
        {
            var jamsMissiles = ai.TraitInfoOrDefault<JamsMissilesInfo>();
            if (jamsMissiles != null)
            {
                yield return new RangeCircleRenderable(
                    centerPosition,
                    jamsMissiles.Range,
                    0,
                    Color.FromArgb(128, Color.Red),
                    Color.FromArgb(96, Color.Black));
            }

            var jamsRadar = ai.TraitInfoOrDefault<JamsRadarInfo>();
            if (jamsRadar != null)
            {
                yield return new RangeCircleRenderable(
                    centerPosition,
                    jamsRadar.Range,
                    0,
                    Color.FromArgb(128, Color.Blue),
                    Color.FromArgb(96, Color.Black));
            }

            foreach (var a in w.ActorsWithTrait<RenderJammerCircle>())
                if (a.Actor.Owner.IsAlliedWith(w.RenderPlayer))
                    foreach (var r in a.Trait.RenderAfterWorld(wr))
                        yield return r;
        }
 public ObserverProductionIconsWidget(World world, WorldRenderer worldRenderer)
 {
     this.world = world;
     this.worldRenderer = worldRenderer;
     clocks = new Dictionary<ProductionQueue, Animation>();
     timestep = world.IsReplay ? world.WorldActor.Trait<MapOptions>().GameSpeed.Timestep : world.Timestep;
 }
Beispiel #19
0
        public void DoControlGroup(World world, WorldRenderer worldRenderer, int group, Modifiers mods, int MultiTapCount)
        {
            var addModifier = Platform.CurrentPlatform == PlatformType.OSX ? Modifiers.Meta : Modifiers.Ctrl;
            if (mods.HasModifier(addModifier))
            {
                if (actors.Count == 0)
                    return;

                if (!mods.HasModifier(Modifiers.Shift))
                    controlGroups[group].Clear();

                for (var i = 0; i < 10; i++)	/* all control groups */
                    controlGroups[i].RemoveAll(a => actors.Contains(a));

                controlGroups[group].AddRange(actors.Where(a => a.Owner == world.LocalPlayer));
                return;
            }

            var groupActors = controlGroups[group].Where(a => !a.IsDead() && !world.FogObscures(a));

            if (mods.HasModifier(Modifiers.Alt) || MultiTapCount >= 2)
            {
                worldRenderer.Viewport.Center(groupActors);
                return;
            }

            Combine(world, groupActors, mods.HasModifier(Modifiers.Shift), false);
        }
Beispiel #20
0
        public IEnumerable<IRenderable> RenderAfterWorld(WorldRenderer wr)
        {
            if (!self.Owner.IsAlliedWith(self.World.RenderPlayer))
                yield break;

            var jamsMissiles = self.Info.TraitInfoOrDefault<JamsMissilesInfo>();
            if (jamsMissiles != null)
            {
                yield return new RangeCircleRenderable(
                    self.CenterPosition,
                    jamsMissiles.Range,
                    0,
                    Color.FromArgb(128, Color.Red),
                    Color.FromArgb(96, Color.Black));
            }

            var jamsRadar = self.Info.TraitInfoOrDefault<JamsRadarInfo>();
            if (jamsRadar != null)
            {
                yield return new RangeCircleRenderable(
                    self.CenterPosition,
                    jamsRadar.Range,
                    0,
                    Color.FromArgb(128, Color.Blue),
                    Color.FromArgb(96, Color.Black));
            }
        }
Beispiel #21
0
		public TileSelectorLogic(Widget widget, WorldRenderer worldRenderer, Ruleset modRules)
		{
			var tileset = modRules.TileSets[worldRenderer.World.Map.Tileset];

			editor = widget.Parent.Get<EditorViewportControllerWidget>("MAP_EDITOR");
			panel = widget.Get<ScrollPanelWidget>("TILETEMPLATE_LIST");
			itemTemplate = panel.Get<ScrollItemWidget>("TILEPREVIEW_TEMPLATE");
			panel.Layout = new GridLayout(panel);

			var tileCategorySelector = widget.Get<DropDownButtonWidget>("TILE_CATEGORY");
			var categories = tileset.EditorTemplateOrder;
			Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
			{
				var item = ScrollItemWidget.Setup(template,
					() => tileCategorySelector.Text == option,
					() => { tileCategorySelector.Text = option; IntializeTilePreview(widget, worldRenderer, tileset, option); });

				item.Get<LabelWidget>("LABEL").GetText = () => option;
				return item;
			};

			tileCategorySelector.OnClick = () =>
				tileCategorySelector.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, categories, setupItem);

			tileCategorySelector.Text = categories.First();
			IntializeTilePreview(widget, worldRenderer, tileset, categories.First());
		}
Beispiel #22
0
        public MapEditorTabsLogic(Widget widget, WorldRenderer worldRenderer)
        {
            var tabContainer = widget.Get("MAP_EDITOR_TAB_CONTAINER");

            var tilesTab = tabContainer.Get<ButtonWidget>("TILES_TAB");
            tilesTab.IsHighlighted = () => menuType == MenuType.Tiles;
            tilesTab.OnClick = () => { menuType = MenuType.Tiles; };

            var overlaysTab = tabContainer.Get<ButtonWidget>("OVERLAYS_TAB");
            overlaysTab.IsHighlighted = () => menuType == MenuType.Layers;
            overlaysTab.OnClick = () => { menuType = MenuType.Layers; };

            var actorsTab = tabContainer.Get<ButtonWidget>("ACTORS_TAB");
            actorsTab.IsHighlighted = () => menuType == MenuType.Actors;
            actorsTab.OnClick = () => { menuType = MenuType.Actors; };

            var tileContainer = widget.Parent.Get<ContainerWidget>("TILE_WIDGETS");
            tileContainer.IsVisible = () => menuType == MenuType.Tiles;

            var layerContainer = widget.Parent.Get<ContainerWidget>("LAYER_WIDGETS");
            layerContainer.IsVisible = () => menuType == MenuType.Layers;

            var actorContainer = widget.Parent.Get<ContainerWidget>("ACTOR_WIDGETS");
            actorContainer.IsVisible = () => menuType == MenuType.Actors;
        }
 public ObserverProductionIconsWidget(World world, WorldRenderer worldRenderer)
     : base()
 {
     this.world = world;
     this.worldRenderer = worldRenderer;
     clocks = new Dictionary<ProductionQueue, Animation>();
 }
Beispiel #24
0
        public IEnumerable<IRenderable> Render(WorldRenderer wr)
        {
            if (a.Destroyed || wr.world.FogObscures(a))
                return SpriteRenderable.None;

            return anim.Render(a.CenterPosition, wr.Palette("chrome"));
        }
Beispiel #25
0
		public void Render(WorldRenderer wr)
		{
			// Need at least 4 points to smooth the contrail over
			if (length - skip < 4)
				return;

			var wlr = Game.Renderer.WorldLineRenderer;
			var oldWidth = wlr.LineWidth;
			wlr.LineWidth = wr.Viewport.Zoom;

			// Start of the first line segment is the tail of the list - don't smooth it.
			var curPos = trail[Index(next - skip - 1)];
			var curColor = color;
			for (var i = 0; i < length - skip - 4; i++)
			{
				var j = next - skip - i - 2;
				var nextPos = Average(trail[Index(j)], trail[Index(j - 1)], trail[Index(j - 2)], trail[Index(j - 3)]);
				var nextColor = Exts.ColorLerp(i * 1f / (length - 4), color, Color.Transparent);

				if (!world.FogObscures(curPos) && !world.FogObscures(nextPos))
					wlr.DrawLine(wr.ScreenPosition(curPos), wr.ScreenPosition(nextPos), curColor, nextColor);

				curPos = nextPos;
				curColor = nextColor;
			}

			wlr.LineWidth = oldWidth;
		}
Beispiel #26
0
        void IRenderAboveWorld.RenderAboveWorld(Actor self, WorldRenderer wr)
        {
            if (!world.Paused)
                UpdateWeatherOverlay(wr);

            DrawWeatherOverlay(wr);
        }
Beispiel #27
0
        public IngameMenuLogic(Widget widget, World world, Action onExit, WorldRenderer worldRenderer)
        {
            widget.Get<ButtonWidget>("DISCONNECT").OnClick = () =>
            {
                onExit();
                LeaveGame(world);
            };

            widget.Get<ButtonWidget>("SETTINGS").OnClick = () =>
            {
                widget.Visible = false;
                Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs()
                {
                    { "onExit", () => widget.Visible = true },
                    { "worldRenderer", worldRenderer },
                });
            };

            widget.Get<ButtonWidget>("MUSIC").OnClick = () =>
            {
                widget.Visible = false;
                Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs { { "onExit", () => { widget.Visible = true; } } });
            };
            widget.Get<ButtonWidget>("RESUME").OnClick = () => onExit();

            widget.Get<ButtonWidget>("SURRENDER").OnClick = () =>
            {
                world.IssueOrder(new Order("Surrender", world.LocalPlayer.PlayerActor, false));
                onExit();
            };
            widget.Get("SURRENDER").IsVisible = () => world.LocalPlayer != null && world.LocalPlayer.WinState == WinState.Undefined;
        }
        public IEnumerable<IRenderable> RenderAfterWorld(WorldRenderer wr)
        {
            if (!self.Owner.IsAlliedWith(self.World.RenderPlayer) || self.World.FogObscures(self))
                yield break;

            if (Info.RenderSelectionBox)
                yield return new SelectionBoxRenderable(self, Info.SelectionBoxColor);

            if (Info.RenderSelectionBars)
                yield return new SelectionBarsRenderable(self);

            if (self.World.LocalPlayer != null && self.World.LocalPlayer.PlayerActor.Trait<DeveloperMode>().PathDebug)
                yield return new TargetLineRenderable(ActivityTargetPath(), Color.Green);

            var b = self.VisualBounds;
            var pos = wr.ScreenPxPosition(self.CenterPosition);
            var tl = wr.Viewport.WorldToViewPx(pos + new int2(b.Left, b.Top));
            var bl = wr.Viewport.WorldToViewPx(pos + new int2(b.Left, b.Bottom));
            var tm = wr.Viewport.WorldToViewPx(pos + new int2((b.Left + b.Right) / 2, b.Top));

            foreach (var r in DrawControlGroup(wr, self, tl))
                yield return r;

            foreach (var r in DrawPips(wr, self, bl))
                yield return r;

            foreach (var r in DrawTags(wr, self, tm))
                yield return r;
        }
Beispiel #29
0
        public void Draw( WorldRenderer wr, Viewport viewport )
        {
            int verticesPerRow = map.Bounds.Width * 4;

            int visibleRows = (int)(viewport.Height * 1f / Game.CellSize / viewport.Zoom + 2);

            int firstRow = (int)(viewport.Location.Y * 1f / Game.CellSize - map.Bounds.Top);
            int lastRow = firstRow + visibleRows;

            if (lastRow < 0 || firstRow > map.Bounds.Height)
                return;

            if (firstRow < 0) firstRow = 0;
            if (lastRow > map.Bounds.Height) lastRow = map.Bounds.Height;

            if (world.RenderedPlayer != null && !world.RenderedShroud.Disabled && world.RenderedShroud.Bounds.HasValue)
            {
                var r = world.RenderedShroud.Bounds.Value;
                if (firstRow < r.Top - map.Bounds.Top)
                    firstRow = r.Top - map.Bounds.Top;

                if (firstRow > r.Bottom - map.Bounds.Top)
                    firstRow = r.Bottom - map.Bounds.Top;
            }

            if( lastRow < firstRow ) lastRow = firstRow;

            Game.Renderer.WorldSpriteRenderer.DrawVertexBuffer(
                vertexBuffer, verticesPerRow * firstRow, verticesPerRow * (lastRow - firstRow),
                PrimitiveType.QuadList, terrainSheet);

            foreach (var r in world.WorldActor.TraitsImplementing<IRenderOverlay>())
                r.Render( wr );
        }
        public ProductionPaletteWidget([ObjectCreator.Param] World world,
		                               [ObjectCreator.Param] WorldRenderer worldRenderer)
        {
            this.world = world;
            this.worldRenderer = worldRenderer;
            tooltipContainer = new Lazy<TooltipContainerWidget>(() =>
                Widget.RootWidget.GetWidget<TooltipContainerWidget>(TooltipContainer));

            cantBuild = new Animation("clock");
            cantBuild.PlayFetchIndex("idle", () => 0);
            clock = new Animation("clock");

            iconSprites = Rules.Info.Values
                .Where(u => u.Traits.Contains<BuildableInfo>() && u.Name[0] != '^')
                .ToDictionary(
                    u => u.Name,
                    u => Game.modData.SpriteLoader.LoadAllSprites(
                        u.Traits.Get<TooltipInfo>().Icon ?? (u.Name + "icon"))[0]);

            overlayFont = Game.Renderer.Fonts["TinyBold"];
            holdOffset = new float2(32,24) - overlayFont.Measure("On Hold") / 2;
            readyOffset = new float2(32,24) - overlayFont.Measure("Ready") / 2;
            timeOffset = new float2(32,24) - overlayFont.Measure(WidgetUtils.FormatTime(0)) / 2;
            queuedOffset = new float2(4,2);
        }
Beispiel #31
0
        public void RenderDebugGeometry(WorldRenderer wr)
        {
            var offset = ScreenPosition(wr) + sprite.offset;

            Game.Renderer.WorldLineRenderer.DrawRect(offset, offset + sprite.size, Color.Red);
        }
Beispiel #32
0
 public void BeforeRender(WorldRenderer wr)
 {
 }
Beispiel #33
0
 public RenderableComparer(WorldRenderer wr)
 {
     this.wr = wr;
 }
Beispiel #34
0
        public VoxelRenderProxy RenderAsync(
            WorldRenderer wr, IEnumerable <VoxelAnimation> voxels, WRot camera, float scale,
            float[] groundNormal, WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor,
            PaletteReference color, PaletteReference normals, PaletteReference shadowPalette)
        {
            // Correct for inverted y-axis
            var scaleTransform = Util.ScaleMatrix(scale, scale, scale);

            // Correct for bogus light source definition
            var lightYaw        = Util.MakeFloatMatrix(new WRot(WAngle.Zero, WAngle.Zero, -lightSource.Yaw).AsMatrix());
            var lightPitch      = Util.MakeFloatMatrix(new WRot(WAngle.Zero, -lightSource.Pitch, WAngle.Zero).AsMatrix());
            var shadowTransform = Util.MatrixMultiply(lightPitch, lightYaw);

            var invShadowTransform = Util.MatrixInverse(shadowTransform);
            var cameraTransform    = Util.MakeFloatMatrix(camera.AsMatrix());
            var invCameraTransform = Util.MatrixInverse(cameraTransform);

            // Sprite rectangle
            var tl = new float2(float.MaxValue, float.MaxValue);
            var br = new float2(float.MinValue, float.MinValue);

            // Shadow sprite rectangle
            var stl = new float2(float.MaxValue, float.MaxValue);
            var sbr = new float2(float.MinValue, float.MinValue);

            foreach (var v in voxels)
            {
                // Convert screen offset back to world coords
                var offsetVec       = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(v.OffsetFunc()));
                var offsetTransform = Util.TranslationMatrix(offsetVec[0], offsetVec[1], offsetVec[2]);

                var worldTransform = v.RotationFunc().Aggregate(Util.IdentityMatrix(),
                                                                (x, y) => Util.MatrixMultiply(Util.MakeFloatMatrix(y.AsMatrix()), x));
                worldTransform = Util.MatrixMultiply(scaleTransform, worldTransform);
                worldTransform = Util.MatrixMultiply(offsetTransform, worldTransform);

                var bounds       = v.Voxel.Bounds(v.FrameFunc());
                var worldBounds  = Util.MatrixAABBMultiply(worldTransform, bounds);
                var screenBounds = Util.MatrixAABBMultiply(cameraTransform, worldBounds);
                var shadowBounds = Util.MatrixAABBMultiply(shadowTransform, worldBounds);

                // Aggregate bounds rects
                tl  = float2.Min(tl, new float2(screenBounds[0], screenBounds[1]));
                br  = float2.Max(br, new float2(screenBounds[3], screenBounds[4]));
                stl = float2.Min(stl, new float2(shadowBounds[0], shadowBounds[1]));
                sbr = float2.Max(sbr, new float2(shadowBounds[3], shadowBounds[4]));
            }

            // Inflate rects to ensure rendering is within bounds
            tl  -= SpritePadding;
            br  += SpritePadding;
            stl -= SpritePadding;
            sbr += SpritePadding;

            // Corners of the shadow quad, in shadow-space
            var corners = new float[][]
            {
                new[] { stl.X, stl.Y, 0, 1 },
                new[] { sbr.X, sbr.Y, 0, 1 },
                new[] { sbr.X, stl.Y, 0, 1 },
                new[] { stl.X, sbr.Y, 0, 1 }
            };

            var shadowScreenTransform = Util.MatrixMultiply(cameraTransform, invShadowTransform);
            var shadowGroundNormal    = Util.MatrixVectorMultiply(shadowTransform, groundNormal);
            var screenCorners         = new float2[4];

            for (var j = 0; j < 4; j++)
            {
                // Project to ground plane
                corners[j][2] = -(corners[j][1] * shadowGroundNormal[1] / shadowGroundNormal[2] +
                                  corners[j][0] * shadowGroundNormal[0] / shadowGroundNormal[2]);

                // Rotate to camera-space
                corners[j]       = Util.MatrixVectorMultiply(shadowScreenTransform, corners[j]);
                screenCorners[j] = new float2(corners[j][0], corners[j][1]);
            }

            // Shadows are rendered at twice the resolution to reduce artifacts
            Size spriteSize, shadowSpriteSize;
            int2 spriteOffset, shadowSpriteOffset;

            CalculateSpriteGeometry(tl, br, 1, out spriteSize, out spriteOffset);
            CalculateSpriteGeometry(stl, sbr, 2, out shadowSpriteSize, out shadowSpriteOffset);

            var sprite       = sheetBuilder.Allocate(spriteSize, spriteOffset);
            var shadowSprite = sheetBuilder.Allocate(shadowSpriteSize, shadowSpriteOffset);
            var sb           = sprite.Bounds;
            var ssb          = shadowSprite.Bounds;
            var spriteCenter = new float2(sb.Left + sb.Width / 2, sb.Top + sb.Height / 2);
            var shadowCenter = new float2(ssb.Left + ssb.Width / 2, ssb.Top + ssb.Height / 2);

            var translateMtx              = Util.TranslationMatrix(spriteCenter.X - spriteOffset.X, renderer.SheetSize - (spriteCenter.Y - spriteOffset.Y), 0);
            var shadowTranslateMtx        = Util.TranslationMatrix(shadowCenter.X - shadowSpriteOffset.X, renderer.SheetSize - (shadowCenter.Y - shadowSpriteOffset.Y), 0);
            var correctionTransform       = Util.MatrixMultiply(translateMtx, FlipMtx);
            var shadowCorrectionTransform = Util.MatrixMultiply(shadowTranslateMtx, ShadowScaleFlipMtx);

            doRender.Add(Pair.New <Sheet, Action>(sprite.Sheet, () =>
            {
                foreach (var v in voxels)
                {
                    // Convert screen offset to world offset
                    var offsetVec       = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(v.OffsetFunc()));
                    var offsetTransform = Util.TranslationMatrix(offsetVec[0], offsetVec[1], offsetVec[2]);

                    var rotations = v.RotationFunc().Aggregate(Util.IdentityMatrix(),
                                                               (x, y) => Util.MatrixMultiply(Util.MakeFloatMatrix(y.AsMatrix()), x));
                    var worldTransform = Util.MatrixMultiply(scaleTransform, rotations);
                    worldTransform     = Util.MatrixMultiply(offsetTransform, worldTransform);

                    var transform = Util.MatrixMultiply(cameraTransform, worldTransform);
                    transform     = Util.MatrixMultiply(correctionTransform, transform);

                    var shadow = Util.MatrixMultiply(shadowTransform, worldTransform);
                    shadow     = Util.MatrixMultiply(shadowCorrectionTransform, shadow);

                    var lightTransform = Util.MatrixMultiply(Util.MatrixInverse(rotations), invShadowTransform);

                    var frame = v.FrameFunc();
                    for (uint i = 0; i < v.Voxel.Limbs; i++)
                    {
                        var rd = v.Voxel.RenderData(i);
                        var t  = v.Voxel.TransformationMatrix(i, frame);

                        // Transform light vector from shadow -> world -> limb coords
                        var lightDirection = ExtractRotationVector(Util.MatrixMultiply(Util.MatrixInverse(t), lightTransform));

                        Render(rd, Util.MatrixMultiply(transform, t), lightDirection,
                               lightAmbientColor, lightDiffuseColor, color.TextureMidIndex, normals.TextureMidIndex);

                        // Disable shadow normals by forcing zero diffuse and identity ambient light
                        Render(rd, Util.MatrixMultiply(shadow, t), lightDirection,
                               ShadowAmbient, ShadowDiffuse, shadowPalette.TextureMidIndex, normals.TextureMidIndex);
                    }
                }
            }));

            var screenLightVector = Util.MatrixVectorMultiply(invShadowTransform, ZVector);

            screenLightVector = Util.MatrixVectorMultiply(cameraTransform, screenLightVector);
            return(new VoxelRenderProxy(sprite, shadowSprite, screenCorners, -screenLightVector[2] / screenLightVector[1]));
        }
Beispiel #35
0
 public void Render(WorldRenderer wr)
 {
     Game.Renderer.WorldSpriteRenderer.DrawSprite(sprite, ScreenPosition(wr), palette, sprite.size * scale);
 }
 public IFinalizedRenderable PrepareRender(WorldRenderer wr)
 {
     return(this);
 }
Beispiel #37
0
 float2 ScreenPosition(WorldRenderer wr)
 {
     return(wr.ScreenPxPosition(pos) + wr.ScreenPxOffset(offset) - (0.5f * scale * sprite.size).ToInt2());
 }
 public Rectangle ScreenBounds(WorldRenderer wr)
 {
     return(Rectangle.Empty);
 }
        public void RenderDebugGeometry(WorldRenderer wr)
        {
            var screenOffset = ScreenPosition(wr) + sprite.Offset;

            Game.Renderer.WorldRgbaColorRenderer.DrawRect(screenOffset, screenOffset + sprite.Size, 1 / wr.Viewport.Zoom, Color.Red);
        }
 public void RenderDebugGeometry(WorldRenderer wr)
 {
 }
        public Rectangle ScreenBounds(WorldRenderer wr)
        {
            var screenOffset = ScreenPosition(wr) + sprite.Offset;

            return(new Rectangle((int)screenOffset.X, (int)screenOffset.Y, (int)sprite.Size.X, (int)sprite.Size.Y));
        }