From 0371727596b33cb0e0a8d0d3757a80e2e7413249 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Tue, 12 Apr 2016 09:40:33 -0400 Subject: [PATCH] Allow sequences to define depth offsets via sprites. --- OpenRA.Game/Graphics/SpriteRenderable.cs | 4 +- .../Graphics/DefaultSpriteSequence.cs | 43 ++++++++++++++++-- mods/ts/bits/isodepth.shp | Bin 0 -> 57676 bytes 3 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 mods/ts/bits/isodepth.shp diff --git a/OpenRA.Game/Graphics/SpriteRenderable.cs b/OpenRA.Game/Graphics/SpriteRenderable.cs index 12a235fba5..b6074cd14f 100644 --- a/OpenRA.Game/Graphics/SpriteRenderable.cs +++ b/OpenRA.Game/Graphics/SpriteRenderable.cs @@ -52,7 +52,9 @@ namespace OpenRA.Graphics float3 ScreenPosition(WorldRenderer wr) { var xy = wr.ScreenPxPosition(pos) + wr.ScreenPxOffset(offset) - (0.5f * scale * sprite.Size.XY).ToInt2(); - return new float3(xy, wr.ScreenZPosition(pos, 0) - 0.5f * scale * sprite.Size.Z); + + // HACK: The z offset needs to be applied somewhere, but this probably is the wrong place. + return new float3(xy, sprite.Offset.Z + wr.ScreenZPosition(pos, 0) - 0.5f * scale * sprite.Size.Z); } public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; } diff --git a/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs b/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs index 021efda8dd..c77b77f6db 100644 --- a/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs +++ b/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs @@ -161,7 +161,7 @@ namespace OpenRA.Mods.Common.Graphics // Allow per-sprite offset, flipping, start, and length var subStart = LoadField(sd, "Start", 0); - var subOffset = LoadField(sd, "Offset", float2.Zero); + var subOffset = LoadField(sd, "Offset", float3.Zero); var subFlipX = LoadField(sd, "FlipX", false); var subFlipY = LoadField(sd, "FlipY", false); @@ -169,7 +169,7 @@ namespace OpenRA.Mods.Common.Graphics var subSprites = cache[subSrc].Select( s => new Sprite(s.Sheet, FlipRectangle(s.Bounds, subFlipX, subFlipY), ZRamp, - new float2(subFlipX ? -s.Offset.X : s.Offset.X, subFlipY ? -s.Offset.Y : s.Offset.Y) + subOffset + offset, + new float3(subFlipX ? -s.Offset.X : s.Offset.X, subFlipY ? -s.Offset.Y : s.Offset.Y, s.Offset.Z) + subOffset + offset, s.Channel, blendMode)); var subLength = 0; @@ -192,10 +192,47 @@ namespace OpenRA.Mods.Common.Graphics sprites = cache[src].Select( s => new Sprite(s.Sheet, FlipRectangle(s.Bounds, flipX, flipY), ZRamp, - new float2(flipX ? -s.Offset.X : s.Offset.X, flipY ? -s.Offset.Y : s.Offset.Y) + offset, + new float3(flipX ? -s.Offset.X : s.Offset.X, flipY ? -s.Offset.Y : s.Offset.Y, s.Offset.Z) + offset, s.Channel, blendMode)).ToArray(); } + var depthSprite = LoadField(d, "DepthSprite", null); + if (!string.IsNullOrEmpty(depthSprite)) + { + var depthSpriteFrame = LoadField(d, "DepthSpriteFrame", 0); + var depthOffset = LoadField(d, "DepthSpriteOffset", float2.Zero); + var depthSprites = cache.AllCached(depthSprite) + .Select(s => s[depthSpriteFrame]); + + sprites = sprites.Select(s => + { + // The depth sprite must live on the same sheet as the main sprite + var ds = depthSprites.FirstOrDefault(dss => dss.Sheet == s.Sheet); + if (ds == null) + { + // The sequence has probably overflowed onto a new sheet. + // Allocating a new depth sprite on this sheet will almost certainly work + ds = cache.Reload(depthSprite)[depthSpriteFrame]; + depthSprites = cache.AllCached(depthSprite) + .Select(ss => ss[depthSpriteFrame]); + + // If that doesn't work then we may be referencing a cached sprite from an earlier sheet + // TODO: We could try and reallocate the main sprite, but that requires more complicated code and a perf hit + // We'll only cross that bridge if this becomes a problem in reality + if (ds.Sheet != s.Sheet) + throw new SheetOverflowException("Cross-sheet depth sprite reference: {0}.{1}: {2}"); + } + + var cw = (ds.Bounds.Left + ds.Bounds.Right) / 2 + (int)(s.Offset.X + depthOffset.X); + var ch = (ds.Bounds.Top + ds.Bounds.Bottom) / 2 + (int)(s.Offset.Y + depthOffset.Y); + var w = s.Bounds.Width / 2; + var h = s.Bounds.Height / 2; + + var r = Rectangle.FromLTRB(cw - w, ch - h, cw + w, ch + h); + return new SpriteWithSecondaryData(s, r, ds.Channel); + }).ToArray(); + } + MiniYaml length; if (d.TryGetValue("Length", out length) && length.Value == "*") Length = sprites.Length - Start; diff --git a/mods/ts/bits/isodepth.shp b/mods/ts/bits/isodepth.shp new file mode 100644 index 0000000000000000000000000000000000000000..d531a5a4224e1fab90ef72ed60f6aef726335258 GIT binary patch literal 57676 zcmeI5$yTCS5QLdka71tbnN(0F0Rd4N6@*PcR6R_;$6fV<^qcf4Tk@PH<@*13+g~lZ zs<&}2nSVw`L2xv~ zk4K~7@b&fO<@tFqczWvhd%bS=@v+lsw_B};hi0?UsMl+?YSrA|-`!OzN}XJ_ejDs_6AOrD$^A0HhZ9v&R*?$z-!vSGin1UnmrdrPB5F&CTs?xm>B--QC|;tF>Ca-e@$N4-c(YyWQzL zK6bmkUcdijo(6;G=a-k)*Wqw98jmNF>2x-GdwYMM&lii2kL7Z;3Ro~QUO=*7WW0c6 z!N_<4$%2vb0+IzI;{_xOMn+ze1tbebMqZKyBnw7HUXleQ3r0p>k_99SM#k5#O=Dzy z{n|7}#@DY+V`O~&+B8PS*RM@KB%@1`2FZev(IrWPWWmVjlB7YhU}SVj(jZwdGHzvC zFfwjsTQD+iWm_;ZZe?3AGHzvC9+I*2HUY_kk+JkP0m*`qvGg_p$%2uw^fm#>f)V|n z{{Q1glI0=M|JPrV7Le%wUtilABl^D@Ni<0G|IM*YFrxo&pKS#s`akpk7LJ7Zf6XL$ z`P$YW+syxd*fw2}=>PP82ijI168)e45C8welEl*5=>PP8@7p&0kl_E-N>YOa|G&Am z6^!8jx9_$EB=~>!|64Q??ElwF5--~}y=-Iu??-K;D-!*m{_h~$l7~e9r~jk>`#~gW zX>Ig>`oDLzt$s-8|CA(IgM|KXQ?@M_q5s>iZ5NQx|Dpfi;*miAzjl&%QQK;Z=>PP82iulBB>F%7AOGJECP_3EXf)q{C}IaZNUit-*#`i zfQ0`K|NoYZ1pNOVLK4JntIf9f|NW$G=!!)Dr~f;|w#Y-G|I`1;{~`a!8j>V#8*L=T z|BwIQd)k(MNcjKo|Kb1pKHE-2lIZ`@|D*r^Hb|2FKl}fUNK%LN~|Kb1P|Kb0=ux;f3Z64de z|BwG4|Nr;5ZG zf7@O}5*8sT`akr4=>L|hRUqI*B*Fi~|HJ>c+nvs%6Ojb}5C31Q*Bgyy)5%C`+{$)y zt=cwTK9a<3lT;tu#%*j%uCKNkUu>Jk$Ox09z3rB>?bCJDCjW>0pKh<$??1UcBqJ|L zR+2g-Nq%km$434S`9I|Uj3<++tR%gZZTYdW|92YOq$1J(UtgI2ng8kkx8-uB;#){U z{*TkxCQ}>pKl4BH|79kVwS**T+m?`R%>PbhTRyhY|2fgN^R;W6`F}Qp|A+rC6pF=? zgOC*cANoJ^f9U_v|79~@kz|%_n_jk||5GbT4HEZ%x&M1zDiw?RkQDkq^ndXG@c;1t z@c*Z&R62cj=1Y-;{}2CPB0>ItG-?S+(zY%1f5A{F9F9axG#ZQTF#j|EGyga0^;)f3 z)gnnfwh2c<{y+Kuy&nF*#X?q+z7)ym|Iq(^ESdkA|C#@p|360(UlWOOlWmFFhW$VL zfA;^(|IGi)|IGj6(P%gnZ<`k*DffT4|HJ(s?*DNA$Jg3cf+UPMNn|AP6(oWFAN_x; zh5jG?|Dn?%DP!@rd8tU`{|pA?|NFLWoork3jfDRn|9>u*&(r_u|6zwi olH~uP|JzR_;_(0Q|M36t|L^lT`F~ySiKPGc`TtKZB+0LT0H~H=`Tzg` literal 0 HcmV?d00001