From 58e1df970f0b1c07e9116ba81af844fd36d73193 Mon Sep 17 00:00:00 2001 From: David Back Date: Mon, 17 Dec 2018 14:06:45 -0800 Subject: [PATCH] remove need for Asset/Resources folder, fix rotations on root --- .../Assets/Editor/AvatarExporter.cs | 25 ++++++++---------- .../avatarExporter.unitypackage | Bin 5879 -> 5864 bytes 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/tools/unity-avatar-exporter/Assets/Editor/AvatarExporter.cs b/tools/unity-avatar-exporter/Assets/Editor/AvatarExporter.cs index 3a3cd77496..b62f51f4e8 100644 --- a/tools/unity-avatar-exporter/Assets/Editor/AvatarExporter.cs +++ b/tools/unity-avatar-exporter/Assets/Editor/AvatarExporter.cs @@ -13,7 +13,7 @@ using System.IO; using System.Collections.Generic; public class AvatarExporter : MonoBehaviour { - public static Dictionary HUMANOID_TO_HIFI_JOINT_NAME = new Dictionary { + public static readonly Dictionary HUMANOID_TO_HIFI_JOINT_NAME = new Dictionary { {"Chest", "Spine1"}, {"Head", "Head"}, {"Hips", "Hips"}, @@ -70,7 +70,7 @@ public class AvatarExporter : MonoBehaviour { {"UpperChest", "Spine2"}, }; - public static Dictionary referenceAbsoluteRotations = new Dictionary { + public static readonly Dictionary referenceAbsoluteRotations = new Dictionary { {"Head", new Quaternion(-2.509889e-9f, -3.379446e-12f, 2.306033e-13f, 1f)}, {"Hips", new Quaternion(-3.043941e-10f, -1.573706e-7f, 5.112975e-6f, 1f)}, {"LeftHandIndex3", new Quaternion(-0.5086057f, 0.4908088f, -0.4912299f, -0.5090388f)}, @@ -151,16 +151,10 @@ public class AvatarExporter : MonoBehaviour { } return; } - string assetPath = AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0]); - string assetName = Path.GetFileNameWithoutExtension(assetPath); - string assetDirectory = Path.GetDirectoryName(assetPath); - if (assetDirectory != "Assets/Resources") { - EditorUtility.DisplayDialog("Error", "Please place asset in the Assets/Resources folder", "Ok"); - return; - } + string assetPath = AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0]); ModelImporter importer = ModelImporter.GetAtPath(assetPath) as ModelImporter; if (assetPath.LastIndexOf(".fbx") == -1 || importer == null) { - EditorUtility.DisplayDialog("Error", "Please select an fbx model asset to export", "Ok"); + EditorUtility.DisplayDialog("Error", "Please select an .fbx model asset to export", "Ok"); return; } if (importer.animationType != ModelImporterAnimationType.Human) { @@ -173,7 +167,7 @@ public class AvatarExporter : MonoBehaviour { userAbsoluteRotations.Clear(); // instantiate a game object of the user avatar to save out bone parents then destroy it - UnityEngine.Object avatarResource = Resources.Load(assetName); + UnityEngine.Object avatarResource = AssetDatabase.LoadAssetAtPath(assetPath, typeof(UnityEngine.Object)); if (avatarResource) { GameObject assetGameObject = (GameObject)Instantiate(avatarResource); SetParentNames(assetGameObject.transform, userParentNames); @@ -246,9 +240,10 @@ public class AvatarExporter : MonoBehaviour { userBoneToHumanoidMappings[chestUserBone] = "UpperChest"; } } - + bool copyModelToExport = false; string exportFstPath, exportModelPath; + string assetName = Path.GetFileNameWithoutExtension(assetPath); string documentsFolder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments); if (updateAvatar) { // open file explorer defaulting to user documents folder to select target fst to update @@ -338,10 +333,12 @@ public class AvatarExporter : MonoBehaviour { Quaternion rotation = referenceAbsoluteRotations[outputJointName]; jointOffset = Quaternion.Inverse(userAbsoluteRotations[userBoneName]) * rotation; } else if (userAbsoluteRotations.ContainsKey(userBoneName)) { + outputJointName = userBoneName; string lastRequiredParent = FindLastRequiredParentBone(userBoneName); - if (lastRequiredParent != "root") { + if (lastRequiredParent == "root") { + jointOffset = Quaternion.Inverse(userAbsoluteRotations[userBoneName]); + } else { // take the previous offset and multiply it by the current local when we have an extra joint - outputJointName = userBoneName; string lastRequiredParentHifiName = HUMANOID_TO_HIFI_JOINT_NAME[userBoneToHumanoidMappings[lastRequiredParent]]; Quaternion lastRequiredParentRotation = referenceAbsoluteRotations[lastRequiredParentHifiName]; jointOffset = Quaternion.Inverse(userAbsoluteRotations[userBoneName]) * lastRequiredParentRotation; diff --git a/tools/unity-avatar-exporter/avatarExporter.unitypackage b/tools/unity-avatar-exporter/avatarExporter.unitypackage index 15935b3229ba23614aa7c9f9bf556a304d574369..4134d6f09a52e356fd3e6a543b2bcb134a7daf5b 100644 GIT binary patch literal 5864 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 literal 5879 zcmV#oJJtzP{*zDM=%`kotjHo$uhfTK5}lmEH? zr|ArTk{9!&`VJRmnrDxYvwgKpCy&rN)7YNovk5Mah=DvpD_m|L<7u*-Rj2bsUR1bv zw2csc2@hE^JG=ZDkE`+#`t23eE=yb-CspzY!3(vpkCxeFhMy*L+^+jBDbggXpnB_} z+?@g4o`ll=L)@zl1|L=Q&=SclSEC}$f8@dnv z|4o#?{`hl$AEBcc35en3B@5g}<8pg{f15OXT;Qa_6Lh&k$H|Lyf<8*d&rzNsCqhs2 z7s#>fhymt{Rgqp@SF{Q}hDY>CI>EEFS`E=@HXaF-$7xv=>E)83U1ktLqUsu>qeU`? zk1x_O&PqH)G#n*#M%IXS`vzkQn2g8ye34|UG`m6&zCxeVk58U{bAs{$U02oO(f%Y6>HN044u^V#?+OhLA{DCi=yhARaxPA^KEo` z)~fh8pUoiD1>Vcir#Qn!IzHImUMw$x3pAd=d}>J>Jwi|NEdK~!gMjm8fqp{>Vqhq| z6If^kAIB-hniQ+|L4ZJUh}h=`=<&Btj-H;K9{+TH_S56jPfmaO?CkXE`A<)eo}8dV zl;NAc&c6XIR(>0Ne2vR$FhqlI79b0I@M>6Ve2kL`w9(I2OS&kbg?=_$zQEH8or0EM zQoScL0Hc+UlWaok-L4MsFGy#OCn;E<*3Iec_GOX3Oy>qlwxP=xX;sazfwwQy?D@*= z?9pIO>*sX#liX>2Ox!(5Cle!gtikQ*(!(BWcDgz${`5{J2EQhTud_$0-7avQHPy-K z=p@-{cQ7$^e!ZMu8n~kMZdZp+zG$n{)lG7ybuqAZvLcwpqu%~Wo|D-ppBoSod!3RF z@kM?EoAP3=@DvzcI{?4HR{{_ob)avq^Cj8kGa&V@L!RfD_yF^}Ol&G2q`D|4)YYMzLDFhqujPldE(X># zPsD1KE9&gh%^htvu-EoRdM5*e+#ktj9YS~{_0oV*BpUQ|80nP+oN`M#sPap!0-klS zx@T%u=&-^!i5J~D(H7~QBq%(a!I})}4vNK3GLUMv(f-XyOKSAh0eoy4{(ZGfNOl!! zKR^YZ;sR%5d~{jnGYGD~&Y>TPLRkd3uD^-`MW9D}DUcnAntdydq8RVR(;?b(M{XE< zUV!&(2i~2LYXz3;!mA6f_H?&4Xci*sI01>}xv^(MFN+|xM}Fvr79b7b)gRfm6Nf(D z3v`t2Fj7Zu0mD&X`2>|U@?tBpqKHr-FSY|YPx?ZJWx3GOgWl26Q!K6*I|L;`5;!iE z#2$U|T#LwoK?RZP_o25t&_{t2yBxh8`V1p|aRZ-l&!8O7GjXq$lMeK-`wkd(8`$+F z_Sko=kYkU0Alr-G=@PvgIt~}T4?BBbir$Z+P|)%`*YWz$n`Fbp?K=@i9|8_3?9lZB zf!*=rAkeYb)|3v}M4=r;J{OJy*$IlDzWA0!hQ**G*ye3(NFu%a@i3hisu#g%9dASf*M)yX-!2Et_MH!@%>U-PbE&SY04oibK+)Le8P(YR<8~>oVi^V=ttZz@Htl z4!NNhS-yG++l!Les2TB+WU3okUTE`iyEf=4a+yTHpkuz4fd8WAr%xWW!81~DBM)@N zmkbAdhw$RDABI6Fg<@+iQEdvlSa*nwJ?2wF+je0|W6zcY(>xZc1lw_q^Rh?UcI*(| z__G~I0f&y|sTVsovHk6$N8UjIj@u^8vDYZ@z*{kalM>MR&Lr--vC~v1+sEGbjA`w4 zb@Xg)j$*Mk+jd~9u*mbNLu9d2?8d#=9TRqsXh%LsJSw0_%SC9aa;7UHd`?cF0zJCXm>V zh19}0GR>#Hc!=Aw9dZ^e2UaAt4G5^MQp*BA=Jz4*vKdgNP%D_8)T-^m%EU(m#vk^f z?ywj~4LuG(zcLbnkWmDWAT6Ug_C`W95VFA?vZWc!59SQV4jQ!`PS$l|&o^=28wk-j zC~#~M23d{>f&wLOkarOGVz$kEhoNi95Ge4hScX8bW|9Un25@Dr$q@gE7)T~xI+mdr zBpNxfjDozV76nlPGzjv*wRb8~N6msDCv;^H1U{-31c}X82v!uCRM;H^vABm#8S$*b z9^avK__J$7ZCsOC2n1qv0#}AWu&(>D3V|F)uE=EGJ0>0W1VJB>{bW6 zu#>bxI$7u|OgY#Xy0!QxkO8Ofh;>KLlIcbbY6Kgje$=Ke(2rP32xd|k0xp;<0jCp@ zP}GFkHlv1g2`nfSvjdjwal`>QmC%nB-T>^$lY?5lpH1a>QUK#YjN0w{yr*;P4F-u4Y9C;NE90j9~U#C*uFw)+|Rb}<3I z*E7N3HszoymWqK6l;)n7c|JqS8Zn?n=?H>cr_U}BxeZJdLNHKujOd-9Prp4qE)OJl zIz>Aaa`XkxuBvPF)*-UR06KvV50RySRACn{zO7Osyb&CrEN02-I8A2x)z09gC~}(i z|8j=GlcJI`hLVh38%9-*FdZ|2IeR{!5>n+A!l1YNB8te}j~U*ObmOhS)w0MG#H*I< z8O|>gA}4f2p2?l*OQ1d?!avWCMEj0OH_xmKLS9EnXEUHAJ>iN<^-0QZUVoofu0Nf%?2WoBc>uH3Sg@VWsnUO=NCy?(T(ug zbZ0P{UcMack{PpSqu+n8kpy44oXuWKTxtpd6*MQzZD!G$oEk$BJdTnqom0<#zFJ`P zR!d4p_0|zx*Isip6&u4lC6c%iK~9Dv*3H`vNIdi`!K06XfnrCYY%QTWfO+}T!Q{jK zKG-w3_pBmk!{C3e$Yjpx*DFvyC6-QcqJ+A2GT<_K0T9ayT>{f+LAfajV1_0b=5xM6 zX(b5M@4}7Pw>CH`F>%1g#UuFfJellBr_!3`&3>An{}g&~3KWBS2NFB#ZTD0SxP`N& zJXoWunzVOXXh&6%WaSjT?lNpErj6*B3FdUp58>OWYVfa&N-DuzG5R@AGq6Pwq2<|Z zg@8V(XF5nKm|kf~oz!(YO<@X7&n$G|BOglLDX%z=ZfX%yjX#s|1Oy=@s8wZNTys9 z>u!Bm8+enW$z(_HJmiB{v#iabY$q!MzsX4n>P6FEQ!;wAq!Xa2>n{9M`J16{#YY_r z$y0-i%?TV7**|uAg`Czt#)&i1aN&mZ)WusQ@CZ^<{HGmlYst8-7wU8^7&pp@fFERBz6yOV`+8l3Rf2m+Px!Y zX+crpP#NB8is?K^t=?i(Fn^4rX;{np2&QREjrFaB2{R+Jfniir0=^7YUj7`5MuvymajBLIfk#5(OkiK&hnUmi{@S1 z`wgC@_@tz%lOcblT}g!oKFP<+IoSw*LbE`CmVbZiBzut-c}Chu_J%dHB%2QK%>s|X z?J=Oylhv`n+S&=XGOcYR$rm`I-(@3g&+-EJnXundAgoq76}4npWUin=ByIrh6(l{T z%sLpgI+3Py&|%Aip8tqX2w)aiTY?8#9FCd7%m%WDN>ds z3K(Pf(%j^h?jK59&0UGeCQG~MJv7)Kz`rtc0naSM)+DA4jYw&9LU!!sPK!42IkJQ9 z0%&F}%~*a#OGeTq2E)a78ZIe#`e?!`RL+rR9=PYB&hV*@r^14GrMonZ&5|X^WncVF}NZH&NV@skPi-w8E4~&F5RsoY& z**vB}ZNu3{8>jpJFJ1LvuzZNwr2D1ZO#BAK0?PiTIEZ016eg;90Wb5rr4y` z^5Fo%$bVp8p?I1PcDu3!o!WW-R@!Mhek!9|Yp5lq+vuq#s}0RjzRa$dCL3Ujk<2k(;}a*H|I63fC4VOf{ zRC8I;1Uw82YW2vP1x8e%JTO#eA6k4w_d(6Ti&yD!!yO_YlZBD{0P7AWCUkDXFjvyN z$au*)Hk|F;z<)H~20umsKvxB(88>PuH^gznQPGgdh|*^!qh>)}SQ>vY%-e=j+dbYz zgYOfT@-l>D^A=(4k&aPvWhErnB`y+_!IqN7(WDPl)v=zR9iKfyCB1P*VFX@wT2x?y zr+tz{G{CD0erO2EiYb|MA8z*uSec>{uP#~zxshBbgVeIeB;Pkp@oZ9p6yU!Fa7D&K zL;mdsDH;YG&1UED6LC#~;2JV^YNLhdKW5cx!A=w=tM{(qdx}41Vd4N6*jRt3!V z98Nu}6Jtr{ivwNpM+@+(lP+}#989i~yc8g>uahF_W2Uh|zX5&ooY-70jv`C`+Ho8y znhl4EbwpC6Al^Dkvpgj<6Q_I~Wm=A3T|X00^3=ZGQB2B%dfx^j0~<7%D9#@@&F%@3 z>c~-HF>K9QqdZM0$fe@l&JamuI7vW4fJqe@Iy+T*rHto@7Gs?8PrZV?}VXh}Fr_rtgb_e=@+0=>I-aE-TipmRljJqXOL!_gDV zhfzT!c+I`W9y=kULoLY}!VRQV$S2I{B7q-UYP6?W{h~;Rl{4CBlp;E8Uwhp(o}@RA zz!%F(`U-w#bH@WS&D0eoQ?S5^Z|WxnF5w={@=#hh?D@+5vleL`WlOG#!00q1$s0CW z9dTU-7rS6#($j34_v1!9&GdO4=Wfr*1pIatoDTl7gv8o}xg(m$$tGWD4FsLU+jD2Z zfby*#x1@4k&oOgO1t!0lRkArjgLmZ%Qke8?uRLBB6!$ELSOMLzoH`G2Gd4SzLMXxY zc2pl38`#Dodkkym2G-b+rcH<#N_WdXcR z9+P*T*)T?$r#4h=)YVZ%4Tep227}holpxY|RzpdwJ+0wG(-(L?K-H#aImCgUQiqPU z&Slr>jW}9VWN*>Ae)K~%PKdLOGhnE1qd8N%O>jog*g>+=lDs1D`|q{x9h*LtQ+R^Q zGP&XcGb4QaZ4F_wXxPx9CQiDX-YGN45`)RCfDJlNmLQVW9J1sR%|p)8=eV9Kp$q!_ z!+|M~5u zkM|YA5xvdzFyT2gDXr24^DhhD?lNq2`0%3b#{Ro4ZNp3PqdQMlMnR`tuM zdfIqsHK(e~{+3927=N(oI?F`fx1(SXB%BvjhE)@icFP%rCUr2y!_76he6T}-6rBT zjehS5Ku?dM`r*&W+)G)f