From 64542d92ccbf5c0be90919254eff46c7d3aa88c3 Mon Sep 17 00:00:00 2001 From: badlogic Date: Fri, 12 Apr 2019 17:11:46 +0200 Subject: [PATCH] [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;