From a3916b82c89b69c42c0a7816b1c9b1420846c0cd Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Fri, 5 Apr 2019 14:34:08 +0200 Subject: [PATCH 1/8] [unity] Fixed SkeletonMecanim leftover animation rotations when transitioning to an empty "Write Defaults" state. Fixes #1321. --- .../Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs index e68bd4d83..d4c611ea2 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs @@ -379,12 +379,13 @@ namespace Spine.Unity { var layerInfos = layerClipInfos[layer]; int clipInfoCount = animator.GetCurrentAnimatorClipInfoCount(layer); int nextClipInfoCount = animator.GetNextAnimatorClipInfoCount(layer); - + var clipInfos = layerInfos.clipInfos; var nextClipInfos = layerInfos.nextClipInfos; var interruptingClipInfos = layerInfos.interruptingClipInfos; - layerInfos.isInterruptionActive = (clipInfoCount == 0 && nextClipInfoCount == 0); + layerInfos.isInterruptionActive = (clipInfoCount == 0 && clipInfos.Count != 0 && + nextClipInfoCount == 0 && nextClipInfos.Count != 0); // Note: during interruption, GetCurrentAnimatorClipInfoCount and GetNextAnimatorClipInfoCount // are returning 0 in calls above. Therefore we keep previous clipInfos and nextClipInfos From 35edb7922e7222fa76cb87359e0f911ff75a1ce4 Mon Sep 17 00:00:00 2001 From: badlogic Date: Mon, 8 Apr 2019 17:47:42 +0200 Subject: [PATCH 2/8] [ue4] Remove dependency on RHI, RenderCore, and ShaderCore. Still doesn't work with UE 4.22 as symbol names generator in UBT seems broken. Linker can't find editor plugin symbols. --- .../Plugins/SpinePlugin/Source/SpinePlugin/SpinePlugin.Build.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/SpinePlugin.Build.cs b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/SpinePlugin.Build.cs index cb9a760b6..d2037221d 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/SpinePlugin.Build.cs +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/SpinePlugin.Build.cs @@ -15,7 +15,7 @@ namespace UnrealBuildTool.Rules PrivateIncludePaths.Add(Path.Combine(ModuleDirectory, "Private")); PrivateIncludePaths.Add(Path.Combine(ModuleDirectory, "Public/spine-cpp/include")); - PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "RHI", "RenderCore", "ShaderCore", "ProceduralMeshComponent", "UMG", "Slate", "SlateCore" }); + PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "ProceduralMeshComponent", "UMG", "Slate", "SlateCore" }); PublicDefinitions.Add("SPINE_UE4"); } } From 4f0b7bef2c14e73af7818b8488e9629759ad583e Mon Sep 17 00:00:00 2001 From: badlogic Date: Mon, 8 Apr 2019 18:04:08 +0200 Subject: [PATCH 3/8] [ue4] Fixed UE 4.22 linker error. IMPLEMENT_MODULE macro changed. No mention of this in the UE changelog. --- .../Source/SpineEditorPlugin/Private/SpineEditorPlugin.cpp | 2 +- spine-ue4/SpineUE4.uproject | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineEditorPlugin.cpp b/spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineEditorPlugin.cpp index 3b0fbcf5d..640ebb3c3 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineEditorPlugin.cpp +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineEditorPlugin.cpp @@ -37,7 +37,7 @@ class FSpineEditorPlugin: public ISpineEditorPlugin { virtual void ShutdownModule() override; }; -IMPLEMENT_MODULE(FSpineEditorPlugin, ISpineEditorPlugin) +IMPLEMENT_MODULE(FSpineEditorPlugin, SpineEditorPlugin) void FSpineEditorPlugin::StartupModule () { } diff --git a/spine-ue4/SpineUE4.uproject b/spine-ue4/SpineUE4.uproject index 85dca7bbd..8830daf34 100644 --- a/spine-ue4/SpineUE4.uproject +++ b/spine-ue4/SpineUE4.uproject @@ -1,6 +1,6 @@ { "FileVersion": 3, - "EngineAssociation": "4.21", + "EngineAssociation": "4.22", "Category": "", "Description": "", "Modules": [ From a29dbcaf97e3ed4b58606c82b4a60c3c1e779c1f Mon Sep 17 00:00:00 2001 From: badlogic Date: Thu, 11 Apr 2019 16:16:25 +0200 Subject: [PATCH 4/8] [monogame] Upgraded to latest MonoGame version, fixed y-flipping in example. --- spine-csharp/src/SkeletonClipping.cs | 2 +- spine-csharp/src/Triangulator.cs | 2 +- spine-monogame/example/ExampleGame.cs | 13 +++++++------ .../example/spine-monogame-example.csproj | 9 +++++++++ .../data/{goblins-mesh.atlas => goblins.atlas} | 0 5 files changed, 18 insertions(+), 8 deletions(-) rename spine-xna/example/data/{goblins-mesh.atlas => goblins.atlas} (100%) diff --git a/spine-csharp/src/SkeletonClipping.cs b/spine-csharp/src/SkeletonClipping.cs index 7efc7c143..bc2ea4d0b 100644 --- a/spine-csharp/src/SkeletonClipping.cs +++ b/spine-csharp/src/SkeletonClipping.cs @@ -270,7 +270,7 @@ namespace Spine { return clipped; } - static void MakeClockwise (ExposedList polygon) { + public static void MakeClockwise (ExposedList polygon) { float[] vertices = polygon.Items; int verticeslength = polygon.Count; diff --git a/spine-csharp/src/Triangulator.cs b/spine-csharp/src/Triangulator.cs index c4bdb0418..ad9f39ee2 100644 --- a/spine-csharp/src/Triangulator.cs +++ b/spine-csharp/src/Triangulator.cs @@ -31,7 +31,7 @@ using System; namespace Spine { - internal class Triangulator { + public class Triangulator { private readonly ExposedList> convexPolygons = new ExposedList>(); private readonly ExposedList> convexPolygonsIndices = new ExposedList>(); diff --git a/spine-monogame/example/ExampleGame.cs b/spine-monogame/example/ExampleGame.cs index ced2ede1e..f9251046d 100644 --- a/spine-monogame/example/ExampleGame.cs +++ b/spine-monogame/example/ExampleGame.cs @@ -65,9 +65,9 @@ namespace Spine { // String name = "spineboy-ess"; // String name = "goblins-pro"; - // String name = "raptor-pro"; + String name = "raptor-pro"; // String name = "tank-pro"; - String name = "coin-pro"; + // String name = "coin-pro"; String atlasName = name.Replace("-pro", "").Replace("-ess", ""); bool binaryData = false; @@ -109,17 +109,17 @@ namespace Spine { state.Complete += Complete; state.Event += Event; - state.SetAnimation(0, "test", false); + state.SetAnimation(0, "run", false); TrackEntry entry = state.AddAnimation(0, "jump", false, 0); entry.End += End; // Event handling for queued animations. state.AddAnimation(0, "run", true, 0); } else if (name == "raptor-pro") { state.SetAnimation(0, "walk", true); - state.AddAnimation(1, "gungrab", false, 2); + state.AddAnimation(1, "gun-grab", false, 2); } else if (name == "coin-pro") { - state.SetAnimation(0, "rotate", true); + state.SetAnimation(0, "animation", true); } else if (name == "tank-pro") { state.SetAnimation(0, "drive", true); @@ -127,9 +127,10 @@ namespace Spine { else { state.SetAnimation(0, "walk", true); } - + skeleton.X = 400 + (name == "tank-pro" ? 300 : 0); skeleton.Y = GraphicsDevice.Viewport.Height; + skeleton.ScaleY = -1; skeleton.UpdateWorldTransform(); headSlot = skeleton.FindSlot("head"); diff --git a/spine-monogame/example/spine-monogame-example.csproj b/spine-monogame/example/spine-monogame-example.csproj index 5638d957d..bb44f0321 100644 --- a/spine-monogame/example/spine-monogame-example.csproj +++ b/spine-monogame/example/spine-monogame-example.csproj @@ -42,6 +42,15 @@ app.manifest + + spine-xna\ShapeRenderer.cs + + + spine-xna\SkeletonDebugRenderer.cs + + + spine-xna\VertexEffect.cs + spine-xna\MeshBatcher.cs diff --git a/spine-xna/example/data/goblins-mesh.atlas b/spine-xna/example/data/goblins.atlas similarity index 100% rename from spine-xna/example/data/goblins-mesh.atlas rename to spine-xna/example/data/goblins.atlas From 8ca801280410f1c266114981941f36d9b9ec2bc1 Mon Sep 17 00:00:00 2001 From: badlogic Date: Thu, 11 Apr 2019 16:31:44 +0200 Subject: [PATCH 5/8] [ue4] Fixed widget test. Needs to be added to viewport. Designer view does NOT preview blueprint actions... --- spine-ue4/Content/Test/NewWorld.umap | Bin 61534 -> 27034 bytes spine-ue4/Content/Test/raptor-widget.uasset | Bin 0 -> 33646 bytes spine-ue4/Content/Test/widget.uasset | Bin 33280 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 spine-ue4/Content/Test/raptor-widget.uasset delete mode 100644 spine-ue4/Content/Test/widget.uasset diff --git a/spine-ue4/Content/Test/NewWorld.umap b/spine-ue4/Content/Test/NewWorld.umap index ba5b861ae1b39e8a7df7b34017bec68cb50d95c7..051798ef7dea340d5376675e9d8db89d695725c2 100644 GIT binary patch literal 27034 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 literal 0 HcmV?d00001 diff --git a/spine-ue4/Content/Test/widget.uasset b/spine-ue4/Content/Test/widget.uasset deleted file mode 100644 index 14d1131a8fc6a5438f50bde3f0bee8ddaed4d9bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33280 zcmeHw3w%`7wf7!DiV+kQd{yNHQItnQLLdZRMikdTS8;;pV-dtWcR<()%+Td=)! zPgUOW1lwEqn_c6VTs8U8jnC}dUiU0hr^w_h%tr`N7E6{o%Blau6t_teCIEZKRB~z4e+Q3f}_PG zD!<*V5=YV1j2SJJMKhL}A=4i-XBFiY7RUlZTwPz8t^ie&DX;&n5He>OLhQd(f)YQZ zx_-zzogn$u{%$kB+O+LpxUsXZEu*!g9lxEYBC!*(^b-6dXsX+yY*zaUQr{N(JeNG{I-dDqR7AgB6nj=5h~vpic>Z5 z{ECS^<6MokEUp&wR=#bxTOwFxAV_kHovUhIIh0D5hC=5`L1W_aQzmVZpm2Ma6|L~w ze(_<~>~+-B!XFNH`|Y3=ZXktX|jeWGU9UxH%*wL|`xIQYwV ztc7T8M8N8;pl(KW(f^Ob-gLmtW_JX#iJ}SLd36#>ms{Q4X4o!^x3z`L#$Y&X2E^LD zQ|b+cwAM6HYvoorW=G@gXi+iW95qd`?d#7KKsjxd>mvSezzo!cE6iB1Gi*l1txvQr z`66(O{4u4~8X|3imKkXDQ*VjIMIVP`k$SV!-`>|?nt^7kF&^zSo7R}2WoAcAT>srK zodLm}E{+ES;+ZcT-vR?jK%4qvw%NVhjK(1HrS>5+k}5U#MNBd7h?`!Muy3ZCl-<|Izh#p)1>#^qA3TFkn{2!%_oc!h1JdfZAO=@6YJb3bVr>5817)Eip5ydR#21 zZft=*5;!#+Tg%0pNB^K2BQ}9iH4@z;>QB6;63_}0?|-!Q zday_uwEfLNvi-szzV!|0r6L$3)9sVvVg0SImVxccfEx0nt%p{keSO{3-eq?CTk8tN z?#FH$58sC|Xa*{*_Baf%Cfs3(J*^WyQgwh*{-M!tcZsJ<|JNp%f%XlL`YK+v~q`UCB~yHMmBCn z&2YOZzP&$ks;f?*rLv^@_lOqUj*?Z5iXir_Yw3*RPxY1VCyW+ARUq22O)Dg1$wwTy= z$5Sx!DqJN*|LEI)_!zyI7$DKNzkd}>g#nJ7J67zU1o5j)auPH`0?IP49D80fTBtUy zZjq=bY4xkJrs`xdrYOan5cbn=XUf0JP}(^ z#bpJ}qX~wtd*R53CMmqb{*GVGt3`L##FY1vX7}=+j;X~+s4Ik_w(|IuKK1=AcRhs) z8YjC_#I9KJMGOKru+`1R@p&tY5JMyvaMRp4=9k|?UnG@S+?PldF1kEDQ(0c?Ea`{#hs#is3-l=p6W=w=AD*b2l$CWR+7?e&;)Bu1uOZ>qqb*aYHvA^GO0W3=TEi>9|VSLLmRTU)-istQSZiPC@!8nt` zp}(5i2%w78X8C1!@xLeEQ-;0b?Tk%KqUz62gyXJ;Vw!O4XGKnxy#$7VF6<@gQKORLyBEv&OFHA$B_dfCN z2~dQld4Cmj<>l(6eF9*a)ZMJVu{e~t&ip2*rkL7E!CU8JPH?~+ zPL=fk`4z4p=blCy8ZmMF$=m0kX;%m`{>_Vf&<1-x$F2PHnu_rl;L9n>x1xm=qGfjI z5a>>8dtcR#-MH*kYm9wWFISKn&_ zRaINY#%oT$b|3VHG*z9%URo*T>%14PHUq9M18zwg++T%4erk*LtYx(9|?C!2He$Ya4%CmBLfaW8d9o0QSW+%^2B{D18z$i z+#jgTTT^h{FK-iWT?X70X>fm|dZ%Q-b!Wh(w%Mu6x=*YZHx9cgNM1OG@!4Gujtt2Q z2Um^cg~LEc^1{KlA$j585s(#PETr?PxIYoDOyijD#rpac!i7_C8(la{=b0zA zpO>lLG>v1P*bZP5r>E3o`}qywIR6gibuocWt*`0}><>-VdFsxdNd>;g2lr9(nI*`GgPSY0!biP36S2nv#WY2ra^R7!4(7c3>8amv1+dTqwK5)^2 zEzh9?33Lo(DE)2(=wN44wMP9xnKShT=-jRI`$vGzM=m;$XR(XU6rI1TMP~+iq9zl( za}~E;!^XJp-Tm{^5ugLTy{hR$Z|wU(=RD2K8zV&LH5VQB&7iYD(r5kb6sTct|pSWlrPBdW4paH$*=>Q_&q5~X`Ovy_g zFFNoGp!0JmlG079)EU1+rSox$Jc#>Qo;f;@`jYwS&|!IQMTXM#UFwYAk(7tWPmd0! zrmh)2o&70#gAZW6?b7mWwT4gUeHR_H7Sv6G#9>(DQ>u-sGk%AvH+LKY^O~%iM0*^+ zoyWnX#$`Ks*)`S?Tn~Qq5<1|sVb|?+AZ>8b8LB+)c^mRH$d;9USe}<%bTm5S$xEI$ zUGkvv&AJ85Mc>qRFbYEIluaJsz3BYaMF;+x;ie!fE0i?`e|2? zZY$GW4|&gyKvLsvRaUg!Oufx2H^8CPDt{bkqF(_tLO{+yMyiJQB&>{OY6{g z-efNhxF-V93uT94$FC}Cu8q?@r#@*KrE%Mm`bpjll;)MVfrP$D#_P>ONUkS znl#P^>J8ktz}*kE`JTNVw&ok+-OJ2KDAVOoPhk{i7?TMmPS1}sawEYP zNK#cHKWQ5-p`fUwX#Sje^CgaMXwf$Pl5nU`4o_uC80=NSGPwc1msSL$XxQOjl)4b- z74lcX@Owz&`dFQ-78eRjm=tPRqFi)~9?>DzikO7P$+5Q)yiIfwG)6VX=~_$aDnjJ| zjZ@hUVQ0l2r0WishcUXHm3%azsk#oOp-If`plwr1?X>NNF&B!ekH)t{nQ`^B4a9Z4dTe!~ zmwn_hRZC8P=86rXnnt5VdWY_8a-=BLbUE} zdl=EjCCb}WHb$Ez7m{A!4dUVq0WZ)YDkN|8r(Sf`Bir-QB&6u561kpbSYv$liJ|ow z+f;=dJ2qJ=>&ZusQ}N-2%h5RHDIFa-Io7SaC*32`X@9sfFfVK`i%65uw2#6=#m_(t z`{MNcPf18$CCX?6YMv;e-x4vGeix8uDWaaALtcMA9Sf+$9J06)I#9Bl{>`Ct5nVYW zeYkQm&u(w%^j2mp_eOeokJR#3k>(t4>87=swn*ksDYnny%ESI*5!v2)>Bk*^;fAqq zOV9f;nsqyi~W;rQ?geu@f~9>7~fmB~BMj;%w@Td{N-~ zH;Zh~3tH|8E%Sh4Mq^JsTupF&$RC!m2x18*5=@2jOvKU)A6q83G*my$(ZEu&YD>n8 z10g&EFm<*Y=ggQ!@{n;Farn(8Kh`0wwTt4WIOUz0Yq(sq*8zo2YQ2Z(#KpOkQ?as- zRz!-s^d*khC5Fojj~=DL3N34wwCeRlBOCsUnh(~YqgBrFY=hVbqu!6k_ zpo}~l;$QHd4$hG>LH7nd;URTg zM(1ML8~|W-%jHsJ&>`nx z#8ffq_oiiSf!CACHg}q?H&TAly&iN{OO9Vmhd(_l|2(G*lpS#n{&8O?`yO0zWQyG> zp5^1@c^mCwDLTmozR^fK_=(o9hjD0d{S-dB@f!AdAEt1dVmPF@8g0>XY!8|@G@(`i1AfSM>&lrZB65?okgIK?C~HgXlOnENBp-2~jRW?E4hQZX zB_H)~wibAWm}-AsFV2Qz-eLNAk?0hz2`Vm|?IpTto+Uht<3@a91ncyi=pO7_OJ)kq9q< zJ07_2<#+`4IBsmN3tyX67d&UdU&r)444;C0YqVBVFQ2B;f7Iz+%LpBv!gUy6cpU7W*Z|u@}Efv$nyu(n9^* zM!qOS>jkVJFlS=le3@<`y{;L9sIVz3y@PcLMA?{wo3qwnn;0mc+ooG|JIsyS8dRQb zVjaoZE!V@#v(n~qpw^S%8PUtRS?e*a#bh^_=Y8b$2iu#7&f>Ip8Y61CNxP@#XKjPW zpVOOFQqOArd=W)kv*}nse>}dDR(4a!+SC;=g)%>dyxkOuE7I3<_4Pb?eSvV7E!MdC zx@?KQF3@y90W=gXrhwUkVN3;f&oD&^b-8`4V!$b2OrtPC12d1RTd1W-<`Od!v)}?~{G;T$d(UAMQG= z5A5!w_5$|%nO?SDQ1jbdsnrG2S0mzry})lH#zNkvzy6DpcZWX*RLwl91ed-zfmJk9 zv8txR!9Kw^x2Jl;y9W0ZcFMWNJUyp*)xdt9!@t8F=rc~uOt@CM_ijhwoU-uUte4bw z70xNkcxa3BN?P0rKszYQ5T#{rF1&gG_Y>0dqHxZf3_75M_LWSK96bS@uzs=nR1jwl z!y1lZT+?d~D^6IeGZMU_65N$y%N#fouqK97Ztl`WDo#5}n`}{#2v}VQ&4*Ya*k`K`s zhP-6>@9E(hekdxS3%VaXk`GM)&TlBuWoU7ar)7`^Vy;yP+MrP>(IB3bVah<^l>~r+ zGxsA?fF&yFJUI9g_iI>sO(JP3%v11S7zD#gIIKj{I^D}GIo~n6K zwwic4ADoY)V>%sB61c&mP7=s1*>s(e2QT@3J}`iUC*Y8n{eZeuYQvLRcwh}F)%1Kx zf-X~q1Y7pQ`Whp|GnpF76*lPW7SGZIY|@Cc_1QIUe^Un2Lh?XPEMKc|1CgV)zEUoG z*Q;jdgddf&8S(i--4ZJ)!2`5-YC0q|$1R{tJY7NR^8VEt$^F9agh^(6v=R@$A*J>e zJs74CiT>dMSfSwqP7gk}@tr-F*Vb-*=39r)sIRPb3*gTCTs0ZaXP|&j9eoRdpu~M& zr7meZI88cN!&wOly~C?5*T^sFGh1@Pdow$$bb&?soM>e>G1;09`6EKE)JSGHtM(=w zbnMRS_8nREz(xOg!^dZCsACq;4m>Ino?#ue`_9)2HrLmE{WsUWwe^c1?DvA5Axo^eQKyz2O7?M>gcA6 zN-VYe`Fn|Bgf5ryl;}e|6}|1)ldr8iYjybzk8FsXHfq||1QD^C@LH$sq97$#Lt{m@!Dy_nhH_jAT_@Iq+QPmk9kq(Mr{ zby@^f!holjG@4EZO(6|RpoOyNr|vD+X)-KHT5s7%fl^v;xrtgiU~jo=;!m##cK0p0 zbY|!C ze=ptKyX433)*kf(0%aX(;Jo` zwLvGnAfNu!K_$2Cb1ivJiy$nGNZKh;zg%fhz6FKBb5F-5x6En2ujcN5Zr&1qVzuQ3 z!%BoxKf;8>o9hj{e>sQVRf|{GicPvuT87gis3Lr&TrlcJH&&8>y9Q*Az7Vnt1?ibrG zdT=5HNrgqYWjgm`nW$dAY{-uY=z~VA2;lLe&5;6&lgu%uZE75_!iJb0UQu=&Y*JKn2%VDHYduTFXG zIWJfZc+^RTeKj!(`tYd|6~l7a=Nneo=L~-*m!QfS3>6&d(q}Yeuwp@C`$|7#T2(>% z!%vkEtIPB=`W?aXbnjCe>OLO#Uc)VwM^yy#F8MBV23nZtkPv-EzE}R@-#cfOU4P%` zu6X$A|MG$jVLY)yB%LfjgC0*_(V`dZ(;iQ3aF|h2V`|6>JeR?BYWj?f@(N9tyM72p zc>{?tf=0P!NA0^So8Db~-{ha=HC}t=BIXQ?@<2djbldBBKRW9Nzo@+Gru(~o6|7t5 z1sj48aadkQ4@qBV7W|GnQ^%`TZTYE&T2_YuZh_ z@7v}DyTH{ze>q(&?lbtCDmk1n)TbokQ8Oo}xyv-wP7b}rEo9iVhhs$O^H3yZEJ)uXGU!`THi6sM2;aYUQ|AUP1xJtQJEXL` z#>*96d`X|><{k2v(194>L|jlB82)iTrriYDM19k$Y7d+W7ZUP-1IT-Kw>|&j^Hrrk zd_>G$YczhyEPx14c*jsabz{#9#sZ?Qw59>U{_r*$nIDYR)U8s`#Ke-iQ2;pUCF2-| zEI)qz(mC6kcQ3qhSJB;1%$j3mtv4JN7e$5ks+ih5FOrZk_H-zwNLfUQ6uTZ2n z`l*Dy&&GHgy=u_;WMaPa8pFIUv00bAk~qi4D7l2TKBLXDyU6*OMkg)$4f@cZyr3_V z(U(^845Jj^8;luoA{sMn%ZSFqMlc+-gXCQ3TS)PUcAjQ1s=cQy)`pj1MvX|+?4geU z<)D34IvAGi(|4KVmjoq2<(N9_p&fYyb!rHlc~jD@G!hPf_6U$%jI+f1op5>WMkbl{3= zx4+M5kNRV(w{!>P(2kSpF!^CRa2KObFG&!*zD=D%{oBSL(Iinxmy&q9pE{M;){R=;YJHEI+G*OMIbFJeaA(L70AgEz~PM{t5G(iwkp z6Q)6GrWdOQjCOp((u~bC+Tu0^X1)GCHL9h!5&7O#Bgo$vRW_QFvyc$}Zo_cCqGvQ` zjqVb)T%YeV=q6s4XbI*Bmp_XRB)DSN7r$DI@h594;U0&MBmo#&t)BVsPo?-5>Iy_;Wj?fI20% zl;o@I`!sL>67RTQpALy8nFPwX^ImLV9bsdQGUL@roV+( z=_~qtsXim_k_oe&eog!q4H_U5R_1HcA#uOsI*r7_3W?d^mgMpXQ|`$U?fji17F$TX zDIjOtxe6w3(r2tWkvui9RN)eTIr);lzFeOrX)eUTZ)xOgE|hvM&;YK$ENn Date: Fri, 12 Apr 2019 16:17:11 +0200 Subject: [PATCH 6/8] [ue4] Fix crash related to multi-cast delegates. Re-used the event callback for SkeletonAnimationComponent. That cast the rendering object to that class, when the class is really SpineWidget. Lead to various mystery crashes. --- spine-ue4/Config/DefaultEngine.ini | 23 ++++---- spine-ue4/Content/Test/raptor-widget.uasset | Bin 33646 -> 36656 bytes .../SpinePlugin/Private/SpineWidget.cpp | 53 +++++++++++++++--- 3 files changed, 57 insertions(+), 19 deletions(-) diff --git a/spine-ue4/Config/DefaultEngine.ini b/spine-ue4/Config/DefaultEngine.ini index 380efca92..6c63e6306 100644 --- a/spine-ue4/Config/DefaultEngine.ini +++ b/spine-ue4/Config/DefaultEngine.ini @@ -7,9 +7,15 @@ DefaultGraphicsPerformance=Maximum AppliedDefaultGraphicsPerformance=Maximum [/Script/EngineSettings.GameMapsSettings] -GameDefaultMap=/Game/Test/Test.Test +GameDefaultMap=/Game/Test/NewWorld.NewWorld GlobalDefaultGameMode=/Game/Test/Blueprints/TouchClick.TouchClick_C +[/Script/IOSRuntimeSettings.IOSRuntimeSettings] +bSupportsPortraitOrientation=False +bSupportsUpsideDownOrientation=False +bSupportsLandscapeLeftOrientation=True +PreferredLandscapeOrientation=LandscapeLeft + [/Script/Engine.PhysicsSettings] DefaultGravityZ=-980.000000 DefaultTerminalVelocity=4000.000000 @@ -17,12 +23,12 @@ DefaultFluidFriction=0.300000 SimulateScratchMemorySize=262144 RagdollAggregateThreshold=4 TriangleMeshTriangleMinAreaThreshold=5.000000 -bEnableAsyncScene=False bEnableShapeSharing=False bEnablePCM=True bEnableStabilization=False bWarnMissingLocks=True bEnable2DPhysics=False +PhysicErrorCorrection=(PingExtrapolation=0.100000,PingLimit=100.000000,ErrorPerLinearDifference=1.000000,ErrorPerAngularDifference=1.000000,MaxRestoredStateError=1.000000,MaxLinearHardSnapDistance=400.000000,PositionLerp=0.000000,AngleLerp=0.400000,LinearVelocityCoefficient=100.000000,AngularVelocityCoefficient=10.000000,ErrorAccumulationSeconds=0.500000,ErrorAccumulationDistanceSq=15.000000,ErrorAccumulationSimilarity=100.000000) LockedAxis=Invalid DefaultDegreesOfFreedom=Full3D BounceThresholdVelocity=200.000000 @@ -39,6 +45,8 @@ bDefaultHasComplexCollision=True bSuppressFaceRemapTable=False bSupportUVFromHitResults=False bDisableActiveActors=False +bDisableKinematicStaticPairs=False +bDisableKinematicKinematicPairs=False bDisableCCD=False bEnableEnhancedDeterminism=False MaxPhysicsDeltaTime=0.033333 @@ -47,16 +55,7 @@ bSubsteppingAsync=False MaxSubstepDeltaTime=0.016667 MaxSubsteps=6 SyncSceneSmoothingFactor=0.000000 -AsyncSceneSmoothingFactor=0.990000 InitialAverageFrameRate=0.016667 PhysXTreeRebuildRate=10 - - - - -[/Script/IOSRuntimeSettings.IOSRuntimeSettings] -bSupportsPortraitOrientation=False -bSupportsUpsideDownOrientation=False -bSupportsLandscapeLeftOrientation=True -PreferredLandscapeOrientation=LandscapeLeft +DefaultBroadphaseSettings=(bUseMBPOnClient=False,bUseMBPOnServer=False,MBPBounds=(Min=(X=0.000000,Y=0.000000,Z=0.000000),Max=(X=0.000000,Y=0.000000,Z=0.000000),IsValid=0),MBPNumSubdivs=2) diff --git a/spine-ue4/Content/Test/raptor-widget.uasset b/spine-ue4/Content/Test/raptor-widget.uasset index 04c8fd39050907c7529e4a62940c114b36fa2126..bc990b2e0b78d31a96958283afc2ccf8dcfa4d94 100644 GIT binary patch delta 5652 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 diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineWidget.cpp b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineWidget.cpp index a7abb9865..94d1a824f 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineWidget.cpp +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineWidget.cpp @@ -38,7 +38,41 @@ using namespace spine; -void callback(AnimationState* state, spine::EventType type, TrackEntry* entry, Event* event); +void callbackWidget(AnimationState* state, spine::EventType type, TrackEntry* entry, Event* event) { + USpineWidget* component = (USpineWidget*)state->getRendererObject(); + + if (entry->getRendererObject()) { + UTrackEntry* uEntry = (UTrackEntry*)entry->getRendererObject(); + if (type == EventType_Start) { + component->AnimationStart.Broadcast(uEntry); + uEntry->AnimationStart.Broadcast(uEntry); + } + else if (type == EventType_Interrupt) { + component->AnimationInterrupt.Broadcast(uEntry); + uEntry->AnimationInterrupt.Broadcast(uEntry); + } + else if (type == EventType_Event) { + FSpineEvent evt; + evt.SetEvent(event); + component->AnimationEvent.Broadcast(uEntry, evt); + uEntry->AnimationEvent.Broadcast(uEntry, evt); + } + else if (type == EventType_Complete) { + component->AnimationComplete.Broadcast(uEntry); + uEntry->AnimationComplete.Broadcast(uEntry); + } + else if (type == EventType_End) { + component->AnimationEnd.Broadcast(uEntry); + uEntry->AnimationEnd.Broadcast(uEntry); + } + else if (type == EventType_Dispose) { + component->AnimationDispose.Broadcast(uEntry); + uEntry->AnimationDispose.Broadcast(uEntry); + uEntry->SetTrackEntry(nullptr); + component->GCTrackEntry(uEntry); + } + } +} USpineWidget::USpineWidget(const FObjectInitializer& ObjectInitializer): Super(ObjectInitializer) { static ConstructorHelpers::FObjectFinder NormalMaterialRef(TEXT("/SpinePlugin/UI_SpineUnlitNormalMaterial")); @@ -130,7 +164,7 @@ void USpineWidget::CheckState() { AnimationStateData* stateData = SkeletonData->GetAnimationStateData(Atlas->GetAtlas()); state = new (__FILE__, __LINE__) AnimationState(stateData); state->setRendererObject((void*)this); - state->setListener(callback); + state->setListener(callbackWidget); trackEntries.Empty(); } } @@ -355,7 +389,8 @@ UTrackEntry* USpineWidget::SetAnimation(int trackIndex, FString animationName, b trackEntries.Add(uEntry); return uEntry; } - else return NewObject(); + else + return NewObject(); } @@ -370,7 +405,8 @@ UTrackEntry* USpineWidget::AddAnimation(int trackIndex, FString animationName, b trackEntries.Add(uEntry); return uEntry; } - else return NewObject(); + else + return NewObject(); } UTrackEntry* USpineWidget::SetEmptyAnimation(int trackIndex, float mixDuration) { @@ -382,7 +418,8 @@ UTrackEntry* USpineWidget::SetEmptyAnimation(int trackIndex, float mixDuration) trackEntries.Add(uEntry); return uEntry; } - else return NewObject(); + else + return NewObject(); } UTrackEntry* USpineWidget::AddEmptyAnimation(int trackIndex, float mixDuration, float delay) { @@ -394,7 +431,8 @@ UTrackEntry* USpineWidget::AddEmptyAnimation(int trackIndex, float mixDuration, trackEntries.Add(uEntry); return uEntry; } - else return NewObject(); + else + return NewObject(); } UTrackEntry* USpineWidget::GetCurrent(int trackIndex) { @@ -411,7 +449,8 @@ UTrackEntry* USpineWidget::GetCurrent(int trackIndex) { return uEntry; } } - else return NewObject(); + else + return NewObject(); } void USpineWidget::ClearTracks() { From 269e3970ba42ea8d4e53a92f0293778d27b67b7a Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Fri, 12 Apr 2019 16:38:33 +0200 Subject: [PATCH 7/8] [libgdx] Added x and y coordinates for setup pose AABB. --- .../spine/SkeletonBinary.java | 2 ++ .../esotericsoftware/spine/SkeletonData.java | 20 ++++++++++++++++++- .../esotericsoftware/spine/SkeletonJson.java | 2 ++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java index 3100fa51b..6f19ace48 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java @@ -175,6 +175,8 @@ public class SkeletonBinary { if (skeletonData.hash.isEmpty()) skeletonData.hash = null; skeletonData.version = input.readString(); if (skeletonData.version.isEmpty()) skeletonData.version = null; + skeletonData.x = input.readFloat(); + skeletonData.y = input.readFloat(); skeletonData.width = input.readFloat(); skeletonData.height = input.readFloat(); diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonData.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonData.java index bfee2464c..2a800d747 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonData.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonData.java @@ -47,7 +47,7 @@ public class SkeletonData { final Array ikConstraints = new Array(); final Array transformConstraints = new Array(); final Array pathConstraints = new Array(); - float width, height; + float x, y, width, height; String version, hash; // Nonessential. @@ -234,6 +234,24 @@ public class SkeletonData { this.name = name; } + /** The X coordinate of the skeleton's axis aligned bounding box in the setup pose. */ + public float getX () { + return x; + } + + public void setX (float x) { + this.x = x; + } + + /** The Y coordinate of the skeleton's axis aligned bounding box in the setup pose. */ + public float getY () { + return y; + } + + public void setY (float y) { + this.y = y; + } + /** The width of the skeleton's axis aligned bounding box in the setup pose. */ public float getWidth () { return width; diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java index f707cfa19..10fa289b4 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java @@ -122,6 +122,8 @@ public class SkeletonJson { if (skeletonMap != null) { skeletonData.hash = skeletonMap.getString("hash", null); skeletonData.version = skeletonMap.getString("spine", null); + skeletonData.x = skeletonMap.getFloat("x", 0); + skeletonData.y = skeletonMap.getFloat("y", 0); skeletonData.width = skeletonMap.getFloat("width", 0); skeletonData.height = skeletonMap.getFloat("height", 0); skeletonData.fps = skeletonMap.getFloat("fps", 30); From 64542d92ccbf5c0be90919254eff46c7d3aa88c3 Mon Sep 17 00:00:00 2001 From: badlogic Date: Fri, 12 Apr 2019 17:11:46 +0200 Subject: [PATCH 8/8] [ue4] Fixed scaling and rendering of widget. SpineWidget has an additional field Scale that can be used to size a skeleton in a widget in a addition to the default sizing based on the setup pose bounds. --- spine-ue4/Content/Test/raptor-widget.uasset | Bin 36656 -> 33539 bytes .../SpinePlugin/Private/SSpineWidget.cpp | 42 ++++++------------ .../Source/SpinePlugin/Public/SSpineWidget.h | 5 ++- .../Source/SpinePlugin/Public/SpineWidget.h | 2 + 4 files changed, 19 insertions(+), 30 deletions(-) diff --git a/spine-ue4/Content/Test/raptor-widget.uasset b/spine-ue4/Content/Test/raptor-widget.uasset index bc990b2e0b78d31a96958283afc2ccf8dcfa4d94..ff4214a3f60d4ed6b687cbee7dde2b511fec7be2 100644 GIT binary patch delta 1818 zcmZuxdrX^E6uh=2podAuK!!ErYhKu+mX^lmapy6*e|X zfq`di&VhqyH2z0Y{li6LP?OD&sfikmI3{r}(PVRp+aIVKp6~l^DH3mT?>*=I&iS4D zo$uT`|0Z|p3^&o3Tw6higb-5F(%gVsG?|$^nY-_zoRDl(bqR#n(+Qy{f09ASHJsn$ z?3i9&IzM-%06u)b_nWlEHXcvKIYS7<)2)y|pVvq-30WINRNp* z-W^@;dRK#wJQ}{Y7>|zLP1etSa6PUs{t1N2opqiDvRLv~XQ)8-Ac_VcKS2ehi5YZ= zmn1(U_XLb5meUKk>gXH7IxS$!h+SHjE<wbkpHsMg5!MO3%e5PL6LjGC#2bLvBI zQ!ax(Z4BJi#z=Sb9fTtYkF_rD(*{`6R>H@+MDAfDe5E_ijWh`%-FgG3ZiOp)TdZCt zMqKv_NKvYRyWJno{;Y@*^5=$M$zOo*U*JDtfjPza1qMx;f&0QAW`OQAwX&Ug#NqxC z{}XZC<-MPQ`Sxh|F3q3}_ly*;W~Jys-Wv=hq~E4=G4vqAzY|NdP_2g1idYkPsIi6)6FjzP zB=$Szmvp=-DqXV`c3Z1xkHGt`)rlb!jx5+&U60Z&yAAW?qn>^=n;~sStzyOZfy2EY zCKQRV!zqQYZPD;tO${9ZPqQ5++A|P|0ZnZd?SsVjLva6CKRj*Q#kT>p+HUX<6H0dX zVVJe&vsC?uuwSSs?#gdoe|W}>f6_|=fO}z zw{WJt$9ple-(!OmS26q45!XMP62`lim{;KmH}m@Ogy`jhe9wy_%D*_CMuxY%>_>e- zu^sN$WP_Txe`za5J;!@XsNp=_0t@X; zkkVB|$3yn6DGuK5aG)sZv{E__d8faH*^X!^@Z~A^R#7uv{$qXKjs{2^%BNCT=q(nV zX)MfjIE8o_rEwyFyptR}8Zpz8e1Ax;ZO=In&-aF83Gahn=#t@}3=cRJ%%!gi`ki1i z9R>4f*0wR0@+{l=?iU9Cww61+?p7ZWd;02VCY{1&HA}tBMFk}eHI$9%l>ufE9=tN9 n1mN^oPEr_BG3y|#IQ6hHrdvnCFZJtKaW!lk_pn-C9q;@X%smk( delta 2416 zcmb7FdrVtp6u;l4)ls@Z>Fd%KC=1gvJ7t?DEN+tmdth+Qpasfga91wSt*^CrSjM)N zZBAhF+HpDuV;Ywj{bQij7^7y1nNgz&nwVwD78_!W|LAbWsEJcN_x6IjB{B0P-~G-# z=XYM;<9sJh(KA!@Sa-hDMNvwMqIQLX98L;qa{O?`sZ&@ko zeH@?T$eM4ydA3?nd+Fs{cOu_STov?%I3_6yR*}_^OV$_sjyU@$3h$x?Bxlk?cBpI- zHq3`2>z?s-ba6cO*T7YN6$0xsq_@6+&vK3?8`QsMkpU>rH9}jSm7Ih`o|%lo&v|Be zFRy}}6}f5+qfB9d2?3}47P)gv+<9o%n8{J`I|N^8%#hSnkRhndH^XM#3dqg>lJvpN zeDkJ0Dcw1=ua@}xrTMrte~-FwhVBHEYt5KRoz`4-PSOcEtd;l`(mWx}*HJeCV_KtO zT#^WjSSs;O7qI%ZP^nWu+@yv!OmRV5N=GxrcKVE4hIAI{Of)(G;C7l#!xCLMfG zz|hVXS*p1vI~|gXQYMQ|a4p2xAzU7$(UuH%DO0KX`h98TwYCi9wE15T8?(}&%bm+W zcEy};nb4vW420MtinL{qKLZrE*cFO{8A9O<&08$$!^X7LJJAe)v(QdId|Fn#U~{D~ zk6AoTLexuXbE^JyhJA67o&IgP{b*4h6On9kaQ;x(9wgKAl6|Vk#w^~7Z0tadX+3pq zBqM;34c>^Pw|I(>kCJprd?T5FSK|zvcU6!x0+)sR0$;mKu)@6)ulH`ZGkfuR4J6-i z$7qs(=|m}PZ{C3Yq_?>ozi&2IXN^^j06EU!W{y?$h}`6jhic3Mm(_e>18nm&k;7uB zcRgOTnGM^((b9q3-`x)Qp`{RmDfjG_H1R#29AWEK+hUv-6B-XRLQ_BoJD#pH3`*4r z)4~!6#@QH{TW#bB)U>X%twE)WjbLX~HH3XZ&e|llNvm_;e$LBV>$y%Y!Ueq?@U5R1 zH3+WZ{5)%Q`2w73yFbM86txxRyqn=ls01eW1`35euV(#zD+0MLmgl0Xs!+(!u|bL| z5Ro(8DsZ=Ly{n?5Sdk6P?PXF`f%fH9eY{@>kFozz)hqwMqA~bopY6dh%y^L&bjZ0P ztoMMmHrT<%RJB2#>*DZK?M&z1uYiCzXfYtn5%dLE-WLj5cd@t{4Sd8G?4qb=5jd?~ ziGaFLC@e3&60UU|+Pn#M^&EdF60|n5{zIH99dKKakMu5Ec$KPwA2pT)Dka z)>$X5*Hq^nG6;!48%%MfVv}0keM3ZjDk92Y-uI`7=z{tKm1%oCN3Fgpc+~%Z}26xqmNG7+#4@?7#lu#aTFh-nKn03~5Z_Toh?go~~MI2nFY^uptdS#vOj zTTvRBQR)#*!;dirZbzIjAJfC-m;)-KwPYAZd%qDIngSfrBG}sFAj8Q-kB8ti6g^AB z+p#V8f*hww4s40miDu)pQiUPqF4Y7ay-%eh5(P}hD(~GlB#*htD&aONZ{RC>OuUzS z;%cn5J6=KJ_!qIoXzDN5EUKjTN%g~e9RoA{#Y-BYI|}rYsQIJcFKyxQ@t%JG&|SQE diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SSpineWidget.cpp b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SSpineWidget.cpp index 3ddd69342..5ab6b4923 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SSpineWidget.cpp +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SSpineWidget.cpp @@ -51,6 +51,13 @@ void SSpineWidget::Construct(const FArguments& args) { void SSpineWidget::SetData(USpineWidget* Widget) { this->widget = Widget; + if (widget && widget->skeleton && widget->Atlas) { + Skeleton *skeleton = widget->skeleton; + skeleton->setToSetupPose(); + skeleton->updateWorldTransform(); + Vector scratchBuffer; + skeleton->getBounds(this->boundsMin.X, this->boundsMin.Y, this->boundsSize.X, this->boundsSize.Y, scratchBuffer); + } } static void setVertex(FSlateVertex* vertex, float x, float y, float u, float v, const FColor& color, const FVector2D& offset) { @@ -163,6 +170,12 @@ int32 SSpineWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeo void SSpineWidget::Flush(int32 LayerId, FSlateWindowElementList& OutDrawElements, const FGeometry& AllottedGeometry, int &Idx, TArray &Vertices, TArray &Indices, TArray &Uvs, TArray &Colors, TArray& Colors2, UMaterialInstanceDynamic* Material) { if (Vertices.Num() == 0) return; SSpineWidget* self = (SSpineWidget*)this; + + const FVector2D widgetSize = AllottedGeometry.GetDrawSize(); + const float setupScale = (widgetSize / FVector2D(boundsSize.X, boundsSize.Y)).GetMin(); + for (int i = 0; i < Vertices.Num(); i++) { + Vertices[i] = (Vertices[i] - FVector(boundsMin.X, -(boundsMin.Y + boundsSize.Y), 0)) * setupScale * widget->Scale; + } self->renderData.IndexData.SetNumUninitialized(Indices.Num()); uint32* indexData = (uint32*)renderData.IndexData.GetData(); @@ -293,18 +306,6 @@ void SSpineWidget::UpdateMesh(int32 LayerId, FSlateWindowElementList& OutDrawEle } if (lastMaterial != material) { - FBox VerticeBounds = FBox(); - for (int i = 0; i < vertices.Num(); i++) { - VerticeBounds += vertices[i]; - } - const FVector2D DrawSize = AllottedGeometry.GetDrawSize(); - const FVector BoundMin = VerticeBounds.Min; - const FVector BoundSize = VerticeBounds.GetSize(); - const float Scale = (DrawSize / FVector2D(BoundSize.X, BoundSize.Y)).GetMin(); - - for (int i = 0; i < vertices.Num(); i++) { - vertices[i] = (vertices[i] - BoundMin) * Scale; - } Flush(LayerId, OutDrawElements, AllottedGeometry, meshSection, vertices, indices, uvs, colors, darkColors, lastMaterial); lastMaterial = material; idx = 0; @@ -335,22 +336,7 @@ void SSpineWidget::UpdateMesh(int32 LayerId, FSlateWindowElementList& OutDrawEle clipper.clipEnd(*slot); } - - FBox VerticeBounds = FBox(); - for (int i = 0; i < vertices.Num(); i++) - { - VerticeBounds += vertices[i]; - } - const FVector2D DrawSize = AllottedGeometry.GetDrawSize(); - const FVector BoundMin = VerticeBounds.Min; - const FVector BoundSize = VerticeBounds.GetSize(); - const float Scale = (DrawSize / FVector2D(BoundSize.X, BoundSize.Y)).GetMin(); - - for (int i = 0; i < vertices.Num(); i++) - { - vertices[i] = (vertices[i] - BoundMin)*Scale; - } - + Flush(LayerId, OutDrawElements, AllottedGeometry, meshSection, vertices, indices, uvs, colors, darkColors, lastMaterial); clipper.clipEnd(); } \ No newline at end of file diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SSpineWidget.h b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SSpineWidget.h index 5c04c9be1..13c09e7ab 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SSpineWidget.h +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SSpineWidget.h @@ -55,7 +55,8 @@ protected: void Flush(int32 LayerId, FSlateWindowElementList& OutDrawElements, const FGeometry& AllottedGeometry, int &Idx, TArray &Vertices, TArray &Indices, TArray &Uvs, TArray &Colors, TArray &Colors2, UMaterialInstanceDynamic* Material); - USpineWidget* widget; - + USpineWidget* widget; FRenderData renderData; + FVector boundsMin; + FVector boundsSize; }; diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineWidget.h b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineWidget.h index 96f39c8df..12b4c6c85 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineWidget.h +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineWidget.h @@ -52,6 +52,8 @@ public: #if WITH_EDITOR virtual const FText GetPaletteCategory() override; #endif + UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite) + float Scale = 1; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine) USpineAtlasAsset* Atlas;