VoxelSkinnedAnimationObjectCore.cs 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186
  1. using UnityEngine;
  2. using UnityEngine.Assertions;
  3. using UnityEditor;
  4. using UnityEditor.Animations;
  5. using UnityEditorInternal;
  6. using System;
  7. using System.Collections;
  8. using System.Collections.Generic;
  9. using System.IO;
  10. using System.Reflection;
  11. #if UNITY_2018_3_OR_NEWER
  12. using UnityEditor.Experimental.SceneManagement;
  13. #endif
  14. namespace VoxelImporter
  15. {
  16. public class VoxelSkinnedAnimationObjectCore : VoxelObjectCore
  17. {
  18. public VoxelSkinnedAnimationObject animationObject { get; protected set; }
  19. public VoxelSkinnedAnimationObjectCore(VoxelBase target) : base(target)
  20. {
  21. voxelObject = null;
  22. animationObject = target as VoxelSkinnedAnimationObject;
  23. }
  24. public override Mesh mesh { get { return animationObject.mesh; } set { animationObject.mesh = value; } }
  25. public override List<Material> materials { get { return animationObject.materials; } set { animationObject.materials = value; } }
  26. public override Texture2D atlasTexture { get { return animationObject.atlasTexture; } set { animationObject.atlasTexture = value; } }
  27. public override void Initialize()
  28. {
  29. base.Initialize();
  30. if (animationObject == null) return;
  31. #region BoneChangeRefresh
  32. if(IsVoxelFileExists())
  33. {
  34. bool boneChange = false;
  35. {
  36. var bones = GetBones();
  37. if (bones != null && animationObject.bones == null)
  38. boneChange = true;
  39. else if (bones == null && animationObject.bones != null)
  40. boneChange = true;
  41. else if (bones.Length != animationObject.bones.Length)
  42. boneChange = true;
  43. else
  44. {
  45. for (int i = 0; i < bones.Length; i++)
  46. {
  47. if (bones[i] != animationObject.bones[i])
  48. {
  49. boneChange = true;
  50. break;
  51. }
  52. }
  53. }
  54. }
  55. if (boneChange)
  56. {
  57. EditorApplication.delayCall += () =>
  58. {
  59. ReCreate();
  60. };
  61. }
  62. }
  63. #endregion
  64. if (animationObject.voxelData == null)
  65. {
  66. animationObject.editMode = VoxelSkinnedAnimationObject.Edit_Mode.None;
  67. }
  68. UpdateBoneWeightTable();
  69. }
  70. #region CreateMesh
  71. protected override bool IsCombineVoxelFace(IntVector3 basePos, IntVector3 combinePos, VoxelBase.Face face)
  72. {
  73. if (!base.IsCombineVoxelFace(basePos, combinePos, face))
  74. return false;
  75. var baseWeights = boneWeightTable.Get(basePos);
  76. if (baseWeights == null)
  77. {
  78. return (boneWeightTable.Get(combinePos) == null) ? true : false;
  79. }
  80. else
  81. {
  82. var combineWeights = boneWeightTable.Get(combinePos);
  83. if (combineWeights == null)
  84. return false;
  85. Assert.IsTrue(baseWeights.Length == (int)VoxelBase.VoxelVertexIndex.Total && combineWeights.Length == (int)VoxelBase.VoxelVertexIndex.Total);
  86. switch (face)
  87. {
  88. case VoxelBase.Face.forward:
  89. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.XYZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex.XYZ] ||
  90. baseWeights[(int)VoxelBase.VoxelVertexIndex.X_YZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex.X_YZ] ||
  91. baseWeights[(int)VoxelBase.VoxelVertexIndex._XYZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex._XYZ] ||
  92. baseWeights[(int)VoxelBase.VoxelVertexIndex._X_YZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex._X_YZ])
  93. return false;
  94. break;
  95. case VoxelBase.Face.up:
  96. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.XYZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex.XYZ] ||
  97. baseWeights[(int)VoxelBase.VoxelVertexIndex.XY_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex.XY_Z] ||
  98. baseWeights[(int)VoxelBase.VoxelVertexIndex._XYZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex._XYZ] ||
  99. baseWeights[(int)VoxelBase.VoxelVertexIndex._XY_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex._XY_Z])
  100. return false;
  101. break;
  102. case VoxelBase.Face.right:
  103. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.XYZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex.XYZ] ||
  104. baseWeights[(int)VoxelBase.VoxelVertexIndex.XY_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex.XY_Z] ||
  105. baseWeights[(int)VoxelBase.VoxelVertexIndex.X_YZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex.X_YZ] ||
  106. baseWeights[(int)VoxelBase.VoxelVertexIndex.X_Y_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex.X_Y_Z])
  107. return false;
  108. break;
  109. case VoxelBase.Face.left:
  110. if (baseWeights[(int)VoxelBase.VoxelVertexIndex._XYZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex._XYZ] ||
  111. baseWeights[(int)VoxelBase.VoxelVertexIndex._XY_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex._XY_Z] ||
  112. baseWeights[(int)VoxelBase.VoxelVertexIndex._X_YZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex._X_YZ] ||
  113. baseWeights[(int)VoxelBase.VoxelVertexIndex._X_Y_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex._X_Y_Z])
  114. return false;
  115. break;
  116. case VoxelBase.Face.down:
  117. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.X_YZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex.X_YZ] ||
  118. baseWeights[(int)VoxelBase.VoxelVertexIndex.X_Y_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex.X_Y_Z] ||
  119. baseWeights[(int)VoxelBase.VoxelVertexIndex._X_YZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex._X_YZ] ||
  120. baseWeights[(int)VoxelBase.VoxelVertexIndex._X_Y_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex._X_Y_Z])
  121. return false;
  122. break;
  123. case VoxelBase.Face.back:
  124. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.XY_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex.XY_Z] ||
  125. baseWeights[(int)VoxelBase.VoxelVertexIndex.X_Y_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex.X_Y_Z] ||
  126. baseWeights[(int)VoxelBase.VoxelVertexIndex._XY_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex._XY_Z] ||
  127. baseWeights[(int)VoxelBase.VoxelVertexIndex._X_Y_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex._X_Y_Z])
  128. return false;
  129. break;
  130. default:
  131. break;
  132. }
  133. return true;
  134. }
  135. }
  136. protected override bool IsHiddenVoxelFace(IntVector3 basePos, VoxelBase.Face faceFlag)
  137. {
  138. Assert.IsTrue(faceFlag == VoxelBase.Face.forward || faceFlag == VoxelBase.Face.up || faceFlag == VoxelBase.Face.right || faceFlag == VoxelBase.Face.left || faceFlag == VoxelBase.Face.down || faceFlag == VoxelBase.Face.back);
  139. IntVector3 combinePos = basePos;
  140. {
  141. if (faceFlag == VoxelBase.Face.forward) combinePos.z++;
  142. if (faceFlag == VoxelBase.Face.up) combinePos.y++;
  143. if (faceFlag == VoxelBase.Face.right) combinePos.x++;
  144. if (faceFlag == VoxelBase.Face.left) combinePos.x--;
  145. if (faceFlag == VoxelBase.Face.down) combinePos.y--;
  146. if (faceFlag == VoxelBase.Face.back) combinePos.z--;
  147. }
  148. if (animationObject.ignoreCavity)
  149. {
  150. if (animationObject.voxelData.VoxelTableContains(combinePos) < 0 &&
  151. !animationObject.voxelData.OutsideTableContains(combinePos))
  152. return true;
  153. }
  154. var baseWeights = boneWeightTable.Get(basePos);
  155. var combineWeights = boneWeightTable.Get(combinePos);
  156. if (baseWeights == null && combineWeights == null)
  157. return true;
  158. if (baseWeights == null)
  159. baseWeights = BoneWeightTableDefault;
  160. if (combineWeights == null)
  161. combineWeights = BoneWeightTableDefault;
  162. switch (faceFlag)
  163. {
  164. case VoxelBase.Face.forward:
  165. {
  166. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.XYZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex.XY_Z]) return false;
  167. if (baseWeights[(int)VoxelBase.VoxelVertexIndex._XYZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex._XY_Z]) return false;
  168. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.X_YZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex.X_Y_Z]) return false;
  169. if (baseWeights[(int)VoxelBase.VoxelVertexIndex._X_YZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex._X_Y_Z]) return false;
  170. }
  171. break;
  172. case VoxelBase.Face.up:
  173. {
  174. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.XYZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex.X_YZ]) return false;
  175. if (baseWeights[(int)VoxelBase.VoxelVertexIndex._XYZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex._X_YZ]) return false;
  176. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.XY_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex.X_Y_Z]) return false;
  177. if (baseWeights[(int)VoxelBase.VoxelVertexIndex._XY_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex._X_Y_Z]) return false;
  178. }
  179. break;
  180. case VoxelBase.Face.right:
  181. {
  182. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.XYZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex._XYZ]) return false;
  183. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.X_YZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex._X_YZ]) return false;
  184. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.XY_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex._XY_Z]) return false;
  185. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.X_Y_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex._X_Y_Z]) return false;
  186. }
  187. break;
  188. case VoxelBase.Face.left:
  189. {
  190. if (baseWeights[(int)VoxelBase.VoxelVertexIndex._XYZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex.XYZ]) return false;
  191. if (baseWeights[(int)VoxelBase.VoxelVertexIndex._X_YZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex.X_YZ]) return false;
  192. if (baseWeights[(int)VoxelBase.VoxelVertexIndex._XY_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex.XY_Z]) return false;
  193. if (baseWeights[(int)VoxelBase.VoxelVertexIndex._X_Y_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex.X_Y_Z]) return false;
  194. }
  195. break;
  196. case VoxelBase.Face.down:
  197. {
  198. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.X_YZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex.XYZ]) return false;
  199. if (baseWeights[(int)VoxelBase.VoxelVertexIndex._X_YZ] != combineWeights[(int)VoxelBase.VoxelVertexIndex._XYZ]) return false;
  200. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.X_Y_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex.XY_Z]) return false;
  201. if (baseWeights[(int)VoxelBase.VoxelVertexIndex._X_Y_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex._XY_Z]) return false;
  202. }
  203. break;
  204. case VoxelBase.Face.back:
  205. {
  206. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.XY_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex.XYZ]) return false;
  207. if (baseWeights[(int)VoxelBase.VoxelVertexIndex._XY_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex._XYZ]) return false;
  208. if (baseWeights[(int)VoxelBase.VoxelVertexIndex.X_Y_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex.X_YZ]) return false;
  209. if (baseWeights[(int)VoxelBase.VoxelVertexIndex._X_Y_Z] != combineWeights[(int)VoxelBase.VoxelVertexIndex._X_YZ]) return false;
  210. }
  211. break;
  212. }
  213. return true;
  214. }
  215. protected override void CreateMeshBefore()
  216. {
  217. base.CreateMeshBefore();
  218. UpdateBoneWeight();
  219. }
  220. protected override void CreateMeshAfter()
  221. {
  222. UpdateSkinnedMeshBounds();
  223. SetRendererCompornent();
  224. base.CreateMeshAfter();
  225. }
  226. public override void SetRendererCompornent()
  227. {
  228. base.SetRendererCompornent();
  229. {
  230. var renderer = animationObject.GetComponent<SkinnedMeshRenderer>();
  231. Undo.RecordObject(renderer, "Inspector");
  232. {//Unity Bug? force update.
  233. renderer.enabled = !renderer.enabled;
  234. renderer.enabled = !renderer.enabled;
  235. }
  236. if (animationObject.mesh != null && animationObject.mesh.vertexCount > 0)
  237. renderer.sharedMesh = animationObject.mesh;
  238. }
  239. if (animationObject.updateAnimatorAvatar)
  240. {
  241. var animator = voxelBase.GetComponent<Animator>();
  242. if (animator != null)
  243. {
  244. Undo.RecordObject(animator, "Inspector");
  245. #region TransformSave
  246. TransformSave[] transformsSave = null;
  247. if (animator.isHuman)
  248. {
  249. if (!animator.isInitialized)
  250. animator.Rebind();
  251. transformsSave = new TransformSave[(int)HumanBodyBones.LastBone];
  252. for (var i = 0; i < (int)HumanBodyBones.LastBone; i++)
  253. {
  254. var t = animator.GetBoneTransform((HumanBodyBones)i);
  255. if (t == null) continue;
  256. transformsSave[i] = new TransformSave(t);
  257. }
  258. }
  259. #endregion
  260. animator.avatar = animationObject.avatar; //Since the Transform will return to its original position, the position is fixed before and after this
  261. #region TransformLoad
  262. if (animator.isHuman && transformsSave != null)
  263. {
  264. if (!animator.isInitialized)
  265. animator.Rebind();
  266. for (var i = 0; i < (int)HumanBodyBones.LastBone; i++)
  267. {
  268. var t = animator.GetBoneTransform((HumanBodyBones)i);
  269. if (t == null || transformsSave[i] == null) continue;
  270. transformsSave[i].LoadLocal(t);
  271. }
  272. }
  273. #endregion
  274. }
  275. }
  276. }
  277. public void UpdateSkinnedMeshBounds()
  278. {
  279. var renderer = animationObject.GetComponent<SkinnedMeshRenderer>();
  280. if (animationObject.skinnedMeshBoundsUpdate)
  281. {
  282. Undo.RecordObject(renderer, "Update Skinned Mesh Bounds");
  283. var bounds = animationObject.mesh.bounds;
  284. if (animationObject.rootBone != null)
  285. bounds.center = Matrix4x4.TRS(animationObject.rootBone.transform.localPosition, animationObject.rootBone.transform.localRotation, animationObject.rootBone.transform.localScale).inverse.MultiplyPoint3x4(bounds.center);
  286. bounds.size = Vector3.Scale(bounds.size, animationObject.skinnedMeshBoundsUpdateScale);
  287. if (float.IsNaN(bounds.center.x) || float.IsNaN(bounds.center.y) || float.IsNaN(bounds.center.z))
  288. bounds.center = Vector3.zero;
  289. renderer.localBounds = bounds;
  290. }
  291. }
  292. #endregion
  293. #region BoneWeight
  294. private static readonly BoneWeight BoneWeightDefault = new BoneWeight() { boneIndex0 = 0, weight0 = 1f };
  295. private static readonly BoneWeight[] BoneWeightTableDefault = new BoneWeight[(int)VoxelBase.VoxelVertexIndex.Total] { BoneWeightDefault, BoneWeightDefault, BoneWeightDefault, BoneWeightDefault, BoneWeightDefault, BoneWeightDefault, BoneWeightDefault, BoneWeightDefault };
  296. private VoxelSkinnedAnimationObjectBoneCore[] bonesCore;
  297. private DataTable3<BoneWeight[]> boneWeightTable;
  298. public override bool isHaveBoneWeight { get { return true; } }
  299. public override Matrix4x4[] GetBindposes() { return animationObject.bindposes; }
  300. public override BoneWeight GetBoneWeight(IntVector3 pos, VoxelBase.VoxelVertexIndex index)
  301. {
  302. var boneWeights = boneWeightTable.Get(pos);
  303. if (boneWeights == null || boneWeights[(int)index].weight0 <= 0f)
  304. {
  305. return BoneWeightDefault;
  306. }
  307. else
  308. {
  309. return boneWeights[(int)index];
  310. }
  311. }
  312. public void UpdateBoneWeight()
  313. {
  314. Undo.RecordObject(animationObject, "Update Bone Weight");
  315. ReadyVoxelData();
  316. UpdateBoneBindposes();
  317. for (int i = 0; i < bonesCore.Length; i++)
  318. {
  319. bonesCore[i].UpdateBoneWeight(i);
  320. }
  321. UpdateBoneWeightTable();
  322. UpdateAvatar();
  323. }
  324. public VoxelSkinnedAnimationObjectBone[] GetBones()
  325. {
  326. List<VoxelSkinnedAnimationObjectBone> list = new List<VoxelSkinnedAnimationObjectBone>();
  327. {
  328. Action<Transform> GetChildrenBones = null;
  329. GetChildrenBones = (trans) =>
  330. {
  331. var comp = trans.GetComponent<VoxelSkinnedAnimationObjectBone>();
  332. if (comp != null)
  333. {
  334. list.Add(comp);
  335. for (int i = 0; i < trans.childCount; i++)
  336. {
  337. GetChildrenBones(trans.GetChild(i));
  338. }
  339. }
  340. };
  341. {
  342. var transformCache = animationObject.transform;
  343. for (int i = 0; i < transformCache.childCount; i++)
  344. {
  345. GetChildrenBones(transformCache.GetChild(i));
  346. }
  347. }
  348. }
  349. return list.ToArray();
  350. }
  351. public void UpdateBoneBindposes()
  352. {
  353. #region Bone
  354. animationObject.bones = GetBones();
  355. {
  356. bonesCore = new VoxelSkinnedAnimationObjectBoneCore[animationObject.bones.Length];
  357. for (int i = 0; i < animationObject.bones.Length; i++)
  358. {
  359. bonesCore[i] = new VoxelSkinnedAnimationObjectBoneCore(animationObject.bones[i], this);
  360. }
  361. }
  362. #endregion
  363. #region MirrorBone
  364. for (int i = 0; i < animationObject.bones.Length; i++)
  365. {
  366. if (animationObject.bones[i].mirrorBone != null) continue;
  367. string mirrorName = null;
  368. if (animationObject.bones[i].name.IndexOf("Left") >= 0)
  369. mirrorName = animationObject.bones[i].name.Replace("Left", "Right");
  370. else if (animationObject.bones[i].name.IndexOf("Right") >= 0)
  371. mirrorName = animationObject.bones[i].name.Replace("Right", "Left");
  372. else
  373. continue;
  374. for (int j = 0; j < animationObject.bones.Length; j++)
  375. {
  376. if (i == j) continue;
  377. if (animationObject.bones[j].name == mirrorName)
  378. {
  379. animationObject.bones[i].mirrorBone = animationObject.bones[j];
  380. break;
  381. }
  382. }
  383. }
  384. #endregion
  385. Transform[] boneTransforms = new Transform[animationObject.bones.Length];
  386. for (int i = 0; i < animationObject.bones.Length; i++)
  387. {
  388. boneTransforms[i] = animationObject.bones[i].transform;
  389. }
  390. #region UpdateBonePosition
  391. if (animationObject.editMode == VoxelSkinnedAnimationObject.Edit_Mode.BonePosition)
  392. {
  393. Undo.RecordObjects(animationObject.bones, "Update Bone Positions");
  394. for (int i = 0; i < animationObject.bones.Length; i++)
  395. {
  396. animationObject.bones[i].bonePosition = animationObject.bones[i].transform.localPosition;
  397. animationObject.bones[i].boneRotation = animationObject.bones[i].transform.localRotation;
  398. animationObject.bones[i].bonePositionSave = true;
  399. }
  400. }
  401. else
  402. {
  403. Undo.RecordObjects(animationObject.bones, "Update Bone Positions");
  404. for (int i = 0; i < animationObject.bones.Length; i++)
  405. {
  406. if (!animationObject.bones[i].bonePositionSave)
  407. {
  408. animationObject.bones[i].bonePosition = animationObject.bones[i].transform.localPosition;
  409. animationObject.bones[i].boneRotation = animationObject.bones[i].transform.localRotation;
  410. animationObject.bones[i].bonePositionSave = true;
  411. }
  412. }
  413. }
  414. #endregion
  415. {
  416. var renderer = animationObject.GetComponent<SkinnedMeshRenderer>();
  417. renderer.bones = boneTransforms;
  418. if (boneTransforms.Length > 0)
  419. renderer.rootBone = boneTransforms[0];
  420. else
  421. renderer.rootBone = null;
  422. animationObject.bindposes = new Matrix4x4[boneTransforms.Length];
  423. {
  424. var world = animationObject.transform.localToWorldMatrix;
  425. List<Vector3> savePosition = new List<Vector3>(boneTransforms.Length);
  426. List<Quaternion> saveRot = new List<Quaternion>(boneTransforms.Length);
  427. List<Vector3> saveScale = new List<Vector3>(boneTransforms.Length);
  428. for (int i = 0; i < boneTransforms.Length; i++)
  429. {
  430. savePosition.Add(boneTransforms[i].localPosition);
  431. boneTransforms[i].localPosition = animationObject.bones[i].bonePosition;
  432. saveRot.Add(boneTransforms[i].localRotation);
  433. boneTransforms[i].localRotation = animationObject.bones[i].boneRotation;
  434. saveScale.Add(boneTransforms[i].localScale);
  435. boneTransforms[i].localScale = Vector3.one;
  436. }
  437. for (int i = 0; i < boneTransforms.Length; i++)
  438. {
  439. animationObject.bindposes[i] = boneTransforms[i].worldToLocalMatrix * world;
  440. }
  441. for (int i = 0; i < boneTransforms.Length; i++)
  442. {
  443. boneTransforms[i].localPosition = savePosition[i];
  444. boneTransforms[i].localRotation = saveRot[i];
  445. boneTransforms[i].localScale = saveScale[i];
  446. }
  447. }
  448. }
  449. }
  450. public void UpdateBoneWeightTable()
  451. {
  452. #region Weight Update
  453. if(animationObject.voxelData != null)
  454. {
  455. boneWeightTable = new DataTable3<BoneWeight[]>(animationObject.voxelData.voxelSize.x, animationObject.voxelData.voxelSize.y, animationObject.voxelData.voxelSize.z);
  456. for (int i = 0; i < animationObject.bones.Length; i++)
  457. {
  458. animationObject.bones[i].weightData.AllAction((pos, weights) =>
  459. {
  460. var boneWeights = boneWeightTable.Get(pos);
  461. if (boneWeights == null)
  462. boneWeights = new BoneWeight[(int)VoxelBase.VoxelVertexIndex.Total];
  463. for (int k = 0; k < (int)VoxelBase.VoxelVertexIndex.Total; k++)
  464. {
  465. var weight = weights.GetWeight((VoxelBase.VoxelVertexIndex)k);
  466. if (weight == 0f) continue;
  467. if (boneWeights[k].weight0 == 0f)
  468. {
  469. boneWeights[k].boneIndex0 = i;
  470. boneWeights[k].weight0 = weight;
  471. }
  472. else if (boneWeights[k].weight1 == 0f)
  473. {
  474. boneWeights[k].boneIndex1 = i;
  475. boneWeights[k].weight1 = weight;
  476. }
  477. else if (boneWeights[k].weight2 == 0f)
  478. {
  479. boneWeights[k].boneIndex2 = i;
  480. boneWeights[k].weight2 = weight;
  481. }
  482. else if (boneWeights[k].weight3 == 0f)
  483. {
  484. boneWeights[k].boneIndex3 = i;
  485. boneWeights[k].weight3 = weight;
  486. }
  487. }
  488. boneWeightTable.Set(pos, boneWeights);
  489. });
  490. }
  491. for (int i = 0; i < animationObject.bones.Length; i++)
  492. {
  493. animationObject.bones[i].weightData.AllAction((pos, weights) =>
  494. {
  495. var boneWeights = boneWeightTable.Get(pos);
  496. for (int k = 0; k < (int)VoxelBase.VoxelVertexIndex.Total; k++)
  497. {
  498. if (boneWeights[k].weight3 > 0f)
  499. {
  500. float power = boneWeights[k].weight0 + boneWeights[k].weight1 + boneWeights[k].weight2 + boneWeights[k].weight3;
  501. boneWeights[k].weight0 = boneWeights[k].weight0 / power;
  502. boneWeights[k].weight1 = boneWeights[k].weight1 / power;
  503. boneWeights[k].weight2 = boneWeights[k].weight2 / power;
  504. boneWeights[k].weight3 = boneWeights[k].weight3 / power;
  505. }
  506. else if (boneWeights[k].weight2 > 0f)
  507. {
  508. float power = boneWeights[k].weight0 + boneWeights[k].weight1 + boneWeights[k].weight2;
  509. if (power >= 1f)
  510. {
  511. boneWeights[k].weight0 = boneWeights[k].weight0 / power;
  512. boneWeights[k].weight1 = boneWeights[k].weight1 / power;
  513. boneWeights[k].weight2 = boneWeights[k].weight2 / power;
  514. }
  515. else
  516. {
  517. boneWeights[k].boneIndex3 = 0;
  518. boneWeights[k].weight3 = 1f - power;
  519. }
  520. }
  521. else if (boneWeights[k].weight1 > 0f)
  522. {
  523. float power = boneWeights[k].weight0 + boneWeights[k].weight1;
  524. if (power >= 1f)
  525. {
  526. boneWeights[k].weight0 = boneWeights[k].weight0 / power;
  527. boneWeights[k].weight1 = boneWeights[k].weight1 / power;
  528. }
  529. else
  530. {
  531. boneWeights[k].boneIndex2 = 0;
  532. boneWeights[k].weight2 = 1f - power;
  533. }
  534. }
  535. else if (boneWeights[k].weight0 > 0f)
  536. {
  537. float power = boneWeights[k].weight0;
  538. if (power >= 1f)
  539. {
  540. boneWeights[k].weight0 = 1f;
  541. }
  542. else
  543. {
  544. boneWeights[k].boneIndex1 = 0;
  545. boneWeights[k].weight1 = 1f - power;
  546. }
  547. }
  548. else
  549. {
  550. boneWeights[k] = BoneWeightDefault;
  551. }
  552. #region Sort
  553. do
  554. {
  555. if (boneWeights[k].weight1 > 0 && boneWeights[k].weight0 < boneWeights[k].weight1)
  556. {
  557. var boneIndex = boneWeights[k].boneIndex0;
  558. var weight = boneWeights[k].weight0;
  559. boneWeights[k].boneIndex0 = boneWeights[k].boneIndex1;
  560. boneWeights[k].weight0 = boneWeights[k].weight1;
  561. boneWeights[k].boneIndex1 = boneIndex;
  562. boneWeights[k].weight1 = weight;
  563. continue;
  564. }
  565. if (boneWeights[k].weight2 > 0 && boneWeights[k].weight1 < boneWeights[k].weight2)
  566. {
  567. var boneIndex = boneWeights[k].boneIndex1;
  568. var weight = boneWeights[k].weight1;
  569. boneWeights[k].boneIndex1 = boneWeights[k].boneIndex2;
  570. boneWeights[k].weight1 = boneWeights[k].weight2;
  571. boneWeights[k].boneIndex2 = boneIndex;
  572. boneWeights[k].weight2 = weight;
  573. continue;
  574. }
  575. if (boneWeights[k].weight3 > 0 && boneWeights[k].weight2 < boneWeights[k].weight3)
  576. {
  577. var boneIndex = boneWeights[k].boneIndex2;
  578. var weight = boneWeights[k].weight2;
  579. boneWeights[k].boneIndex2 = boneWeights[k].boneIndex3;
  580. boneWeights[k].weight2 = boneWeights[k].weight3;
  581. boneWeights[k].boneIndex3 = boneIndex;
  582. boneWeights[k].weight3 = weight;
  583. continue;
  584. }
  585. } while (false);
  586. #endregion
  587. }
  588. boneWeightTable.Set(pos, boneWeights);
  589. });
  590. }
  591. }
  592. else
  593. {
  594. boneWeightTable = new DataTable3<BoneWeight[]>();
  595. }
  596. #endregion
  597. }
  598. #endregion
  599. #region Voxel
  600. public void GetVoxelsFeetArea(out IntVector3 areaMin, out IntVector3 areaMax)
  601. {
  602. areaMin = new IntVector3(int.MaxValue, 0, int.MaxValue);
  603. areaMax = new IntVector3(int.MinValue, voxelData.voxelSize.y - 1, int.MinValue);
  604. #region Step1
  605. {
  606. int minY = voxelData.voxelSize.y - 1;
  607. for (int i = 0; i < voxelData.voxels.Length; i++)
  608. {
  609. minY = Math.Min(minY, voxelData.voxels[i].y);
  610. }
  611. for (int i = 0; i < voxelData.voxels.Length; i++)
  612. {
  613. if (voxelData.voxels[i].y != minY) continue;
  614. areaMin.x = Math.Min(areaMin.x, voxelData.voxels[i].x);
  615. areaMin.z = Math.Min(areaMin.z, voxelData.voxels[i].z);
  616. areaMax.x = Math.Max(areaMax.x, voxelData.voxels[i].x);
  617. areaMax.z = Math.Max(areaMax.z, voxelData.voxels[i].z);
  618. }
  619. areaMin.y = minY;
  620. areaMax.y = minY;
  621. IntVector3 footAreaCenter = areaMin + (areaMax - areaMin) / 2;
  622. footAreaCenter.y = minY;
  623. if (voxelData.VoxelTableContains(footAreaCenter) < 0)
  624. {
  625. int maxY = voxelData.voxelSize.y - 1;
  626. for (int i = 0; i < voxelData.voxelSize.y; i++)
  627. {
  628. if (voxelData.VoxelTableContains(new IntVector3(footAreaCenter.x, i, footAreaCenter.z)) >= 0)
  629. {
  630. maxY = i - 1;
  631. break;
  632. }
  633. }
  634. areaMax.y = maxY;
  635. }
  636. }
  637. #endregion
  638. #region Step2
  639. {
  640. bool enable = false;
  641. var min = new IntVector3(int.MaxValue, areaMin.y, int.MaxValue);
  642. var max = new IntVector3(int.MinValue, areaMax.y, int.MinValue);
  643. for (int x = areaMin.x; x <= areaMax.x; x++)
  644. {
  645. for (int z = areaMin.z; z <= areaMax.z; z++)
  646. {
  647. if (voxelData.VoxelTableContains(x, areaMin.y, z) < 0) continue;
  648. bool e = true;
  649. for (int y = areaMin.y; y <= areaMax.y; y++)
  650. {
  651. if (voxelData.VoxelTableContains(x, y, z) < 0)
  652. {
  653. e = false;
  654. break;
  655. }
  656. }
  657. if(e)
  658. {
  659. enable = true;
  660. min = IntVector3.Min(min, new IntVector3(x, areaMin.y, z));
  661. max = IntVector3.Max(max, new IntVector3(x, areaMax.y, z));
  662. }
  663. }
  664. }
  665. if(enable)
  666. {
  667. areaMin = min;
  668. areaMax = max;
  669. }
  670. }
  671. #endregion
  672. }
  673. public Vector3 GetVoxelsFeet()
  674. {
  675. Vector3 center = Vector3.zero;
  676. IntVector3 feetAreaMin, feetAreaMax;
  677. GetVoxelsFeetArea(out feetAreaMin, out feetAreaMax);
  678. Dictionary<int, List<Vector3>> centers = new Dictionary<int, List<Vector3>>();
  679. for (int i = 0; i < voxelData.voxels.Length; i++)
  680. {
  681. if (voxelData.voxels[i].x < feetAreaMin.x || voxelData.voxels[i].x > feetAreaMax.x ||
  682. voxelData.voxels[i].y < feetAreaMin.y || voxelData.voxels[i].y > feetAreaMax.y ||
  683. voxelData.voxels[i].z < feetAreaMin.z || voxelData.voxels[i].z > feetAreaMax.z)
  684. continue;
  685. Vector3 pos;
  686. {
  687. Vector3 posV3 = new Vector3(voxelData.voxels[i].position.x, voxelData.voxels[i].position.y, voxelData.voxels[i].position.z);
  688. pos = voxelBase.localOffset + new Vector3(0.5f, 0f, 0.5f) + posV3;
  689. }
  690. if (!centers.ContainsKey(voxelData.voxels[i].y))
  691. centers.Add(voxelData.voxels[i].y, new List<Vector3>());
  692. centers[voxelData.voxels[i].y].Add(pos);
  693. }
  694. Dictionary<int, Vector3> centerPositions = new Dictionary<int, Vector3>();
  695. foreach (var pair in centers)
  696. {
  697. Vector3 value = Vector3.zero;
  698. for (int i = 0; i < pair.Value.Count; i++)
  699. value += pair.Value[i];
  700. value /= (float)pair.Value.Count;
  701. centerPositions.Add(pair.Key, value);
  702. }
  703. foreach (var pair in centerPositions)
  704. {
  705. center += pair.Value;
  706. }
  707. center /= (float)centerPositions.Count;
  708. center.x = Mathf.Round(center.x * 2f) / 2f;
  709. {
  710. Vector3 posV3 = new Vector3(feetAreaMin.x, feetAreaMin.y, feetAreaMin.z);
  711. center.y = (voxelBase.localOffset + posV3).y;
  712. }
  713. center.z = Mathf.Round(center.z * 2f) / 2f;
  714. return center;
  715. }
  716. #endregion
  717. #region Avatar
  718. protected void UpdateAvatar()
  719. {
  720. Undo.RecordObject(animationObject, "Update Avatar");
  721. string assetPath = "";
  722. if (IsMainAsset(animationObject.avatar))
  723. {
  724. assetPath = AssetDatabase.GetAssetPath(animationObject.avatar);
  725. }
  726. if (IsSubAsset(animationObject.avatar))
  727. {
  728. animationObject.avatar.name = animationObject.avatar.name + "_Destroyed";
  729. //Destroyed by "DestroyUnusedObjectInPrefabObject" to be called later
  730. }
  731. animationObject.avatar = null;
  732. var parent = animationObject.transform.parent;
  733. var localPosition = animationObject.transform.localPosition;
  734. var localRotation = animationObject.transform.localRotation;
  735. var localScale = animationObject.transform.localScale;
  736. animationObject.transform.SetParent(null);
  737. animationObject.transform.localPosition = Vector3.zero;
  738. animationObject.transform.localRotation = Quaternion.identity;
  739. animationObject.transform.localScale = Vector3.one;
  740. switch (animationObject.rigAnimationType)
  741. {
  742. case VoxelSkinnedAnimationObject.RigAnimationType.Generic:
  743. if (animationObject.rootBone != null)
  744. {
  745. Dictionary<Transform, Transform> saveList = new Dictionary<Transform, Transform>();
  746. List<Transform> findList = new List<Transform>();
  747. for (int j = 0; j < animationObject.transform.childCount; j++)
  748. {
  749. findList.Add(animationObject.transform.GetChild(j));
  750. }
  751. for (int i = 0; i < findList.Count; i++)
  752. {
  753. for (int j = 0; j < findList[i].childCount; j++)
  754. {
  755. findList.Add(findList[i].GetChild(j));
  756. }
  757. if (findList[i].GetComponent<VoxelSkinnedAnimationObjectBone>() == null)
  758. {
  759. saveList.Add(findList[i], findList[i].parent);
  760. findList[i].SetParent(null);
  761. }
  762. }
  763. animationObject.avatar = AvatarBuilder.BuildGenericAvatar(animationObject.gameObject, animationObject.rootBone.gameObject.name);
  764. {
  765. var enu = saveList.GetEnumerator();
  766. while (enu.MoveNext())
  767. {
  768. enu.Current.Key.SetParent(enu.Current.Value);
  769. }
  770. }
  771. }
  772. break;
  773. case VoxelSkinnedAnimationObject.RigAnimationType.Humanoid:
  774. if (animationObject.rootBone != null)
  775. {
  776. HumanDescription humanDescription = new HumanDescription()
  777. {
  778. upperArmTwist = animationObject.humanDescription.upperArmTwist,
  779. lowerArmTwist = animationObject.humanDescription.lowerArmTwist,
  780. upperLegTwist = animationObject.humanDescription.upperLegTwist,
  781. lowerLegTwist = animationObject.humanDescription.lowerLegTwist,
  782. armStretch = animationObject.humanDescription.armStretch,
  783. legStretch = animationObject.humanDescription.legStretch,
  784. feetSpacing = animationObject.humanDescription.feetSpacing,
  785. hasTranslationDoF = animationObject.humanDescription.hasTranslationDoF,
  786. };
  787. #region CreateHumanAndSkeleton
  788. {
  789. List<HumanBone> humanBones = new List<HumanBone>();
  790. List<SkeletonBone> skeletonBones = new List<SkeletonBone>();
  791. if (!animationObject.humanDescription.firstAutomapDone)
  792. {
  793. AutomapHumanDescriptionHuman();
  794. animationObject.humanDescription.firstAutomapDone = true;
  795. }
  796. for (int i = 0; i < animationObject.humanDescription.bones.Length; i++)
  797. {
  798. var index = VoxelSkinnedAnimationObject.HumanTraitBoneNameTable[i];
  799. if (animationObject.humanDescription.bones[(int)index] == null) continue;
  800. humanBones.Add(new HumanBone()
  801. {
  802. boneName = animationObject.humanDescription.bones[(int)index].name,
  803. humanName = HumanTrait.BoneName[i],
  804. limit = new HumanLimit() { useDefaultValues = true },
  805. });
  806. }
  807. #region FindBones
  808. {
  809. for (var bone = animationObject.rootBone; bone != animationObject.transform.parent; bone = bone.parent)
  810. {
  811. skeletonBones.Add(new SkeletonBone()
  812. {
  813. name = bone.name,
  814. position = bone.localPosition,
  815. rotation = bone.localRotation,
  816. scale = bone.localScale,
  817. });
  818. }
  819. skeletonBones.Reverse();
  820. for (int i = 0; i < animationObject.humanDescription.bones.Length; i++)
  821. {
  822. var index = VoxelSkinnedAnimationObject.HumanTraitBoneNameTable[i];
  823. var bone = animationObject.humanDescription.bones[(int)index];
  824. if (bone == null) continue;
  825. if (bone.transform == animationObject.rootBone)
  826. continue;
  827. skeletonBones.Add(new SkeletonBone()
  828. {
  829. name = bone.name,
  830. position = bone.transform.localPosition,
  831. rotation = bone.transform.localRotation,
  832. scale = Vector3.one,
  833. });
  834. }
  835. }
  836. #endregion
  837. humanDescription.human = humanBones.ToArray();
  838. humanDescription.skeleton = skeletonBones.ToArray();
  839. }
  840. #endregion
  841. animationObject.avatar = AvatarBuilder.BuildHumanAvatar(animationObject.gameObject, humanDescription);
  842. }
  843. break;
  844. }
  845. animationObject.transform.SetParent(parent);
  846. animationObject.transform.localPosition = localPosition;
  847. animationObject.transform.localRotation = localRotation;
  848. animationObject.transform.localScale = localScale;
  849. if (animationObject.avatar != null)
  850. {
  851. if (!string.IsNullOrEmpty(assetPath))
  852. {
  853. var tmpPath = AssetDatabase.GenerateUniqueAssetPath(assetPath);
  854. AssetDatabase.CreateAsset(animationObject.avatar, tmpPath);
  855. File.Copy(tmpPath, assetPath, true);
  856. AssetDatabase.DeleteAsset(tmpPath);
  857. animationObject.avatar = AssetDatabase.LoadAssetAtPath<Avatar>(assetPath);
  858. }
  859. if (!AssetDatabase.Contains(animationObject.avatar))
  860. {
  861. AddObjectToPrefabAsset(animationObject.avatar, "avatar");
  862. }
  863. }
  864. }
  865. public void ResetHumanDescriptionHuman()
  866. {
  867. Undo.RecordObject(animationObject, "Reset Human Description");
  868. for (int i = 0; i < animationObject.humanDescription.bones.Length; i++)
  869. {
  870. animationObject.humanDescription.bones[i] = null;
  871. }
  872. }
  873. public void AutomapHumanDescriptionHuman()
  874. {
  875. Undo.RecordObject(animationObject, "Reset Human Description");
  876. ResetHumanDescriptionHuman();
  877. Func<string, VoxelSkinnedAnimationObjectBone> FindBone = (name) =>
  878. {
  879. VoxelSkinnedAnimationObjectBone bone = null;
  880. string nameS = name.Replace(" ", "");
  881. for (int i = 0; i < animationObject.bones.Length; i++)
  882. {
  883. if (animationObject.bones[i] == null) continue;
  884. if (animationObject.bones[i].name.IndexOf(name) >= 0 ||
  885. animationObject.bones[i].name.IndexOf(nameS) >= 0)
  886. {
  887. bone = animationObject.bones[i];
  888. break;
  889. }
  890. }
  891. return bone;
  892. };
  893. #region FindBones
  894. {
  895. var BoneName = HumanTrait.BoneName;
  896. for (int i = 0; i < BoneName.Length; i++)
  897. {
  898. var bone = FindBone(BoneName[i]);
  899. if (bone != null)
  900. {
  901. var index = VoxelSkinnedAnimationObject.HumanTraitBoneNameTable[i];
  902. animationObject.humanDescription.bones[(int)index] = bone;
  903. }
  904. }
  905. }
  906. #endregion
  907. }
  908. public void ResetBoneTransform()
  909. {
  910. if (animationObject.bones == null) return;
  911. for (int i = 0; i < animationObject.bones.Length; i++)
  912. {
  913. if (animationObject.bones[i] == null) continue;
  914. Undo.RecordObject(animationObject.bones[i].transform, "Reset Bone Transform");
  915. if (animationObject.bones[i].bonePositionSave)
  916. {
  917. animationObject.bones[i].transform.localPosition = animationObject.bones[i].bonePosition;
  918. animationObject.bones[i].transform.localRotation = animationObject.bones[i].boneRotation;
  919. }
  920. animationObject.bones[i].transform.localScale = Vector3.one;
  921. }
  922. }
  923. private class TransformSave
  924. {
  925. public TransformSave()
  926. {
  927. }
  928. public TransformSave(Transform t)
  929. {
  930. Save(t);
  931. }
  932. public void Save(Transform t)
  933. {
  934. localPosition = t.localPosition;
  935. localRotation = t.localRotation;
  936. localScale = t.localScale;
  937. }
  938. public void LoadLocal(Transform t)
  939. {
  940. t.localPosition = localPosition;
  941. t.localRotation = localRotation;
  942. t.localScale = localScale;
  943. }
  944. public Vector3 localPosition;
  945. public Quaternion localRotation;
  946. public Vector3 localScale;
  947. }
  948. #endregion
  949. #region Animation
  950. public void FixMissingAnimation()
  951. {
  952. if (animationObject.rigAnimationType == VoxelSkinnedAnimationObject.RigAnimationType.Humanoid) return;
  953. var animator = animationObject.GetComponent<Animator>();
  954. if (animator != null && animator.runtimeAnimatorController != null)
  955. {
  956. Undo.RecordObject(animator, "Fix Missing Animation");
  957. Undo.RecordObject(animator.runtimeAnimatorController, "Fix Missing Animation");
  958. Undo.RecordObjects(animator.runtimeAnimatorController.animationClips, "Fix Missing Animation");
  959. for (int i = 0; i < animationObject.bones.Length; i++)
  960. {
  961. var boneCore = new VoxelSkinnedAnimationObjectBoneCore(animationObject.bones[i], this);
  962. boneCore.FixMissingAnimation();
  963. }
  964. }
  965. }
  966. #endregion
  967. #region Export
  968. public bool ExportDaeFileWithAnimation(string path, bool exportMesh, bool exportAnimation, bool enableFootIK)
  969. {
  970. Dictionary<Transform, SaveTransform> saveTransforms = new Dictionary<Transform, SaveTransform>();
  971. {
  972. saveTransforms.Add(animationObject.transform, new SaveTransform(animationObject.transform));
  973. animationObject.transform.localPosition = Vector3.zero;
  974. animationObject.transform.localRotation = Quaternion.identity;
  975. animationObject.transform.localScale = Vector3.one;
  976. for (int i = 0; i < animationObject.bones.Length; i++)
  977. {
  978. saveTransforms.Add(animationObject.bones[i].transform, new SaveTransform(animationObject.bones[i].transform));
  979. if (animationObject.bones[i].bonePositionSave)
  980. {
  981. animationObject.bones[i].transform.localPosition = animationObject.bones[i].bonePosition;
  982. animationObject.bones[i].transform.localRotation = animationObject.bones[i].boneRotation;
  983. }
  984. animationObject.bones[i].transform.localScale = Vector3.one;
  985. }
  986. }
  987. bool result = false;
  988. try
  989. {
  990. var clips = exportAnimation ? AnimationUtility.GetAnimationClips(voxelBase.gameObject) : null;
  991. List<Transform> transforms = new List<Transform>();
  992. ExportDaeFile_AddTransform(transforms);
  993. DaeExporter exporter = new DaeExporter()
  994. {
  995. settings_exportMesh = exportMesh,
  996. settings_iKOnFeet = enableFootIK,
  997. };
  998. result = exporter.Export(path, transforms, clips);
  999. if (result)
  1000. {
  1001. MethodInfo HasMotionCurves = null;
  1002. {
  1003. var asmUnityEditor = Assembly.LoadFrom(InternalEditorUtility.GetEditorAssemblyPath());
  1004. var animationUtilityType = asmUnityEditor.GetType("UnityEditor.AnimationUtility");
  1005. Assert.IsNotNull(HasMotionCurves = animationUtilityType.GetMethod("HasMotionCurves", BindingFlags.NonPublic | BindingFlags.Static));
  1006. }
  1007. foreach (var p in exporter.exportedFiles)
  1008. {
  1009. if (p.IndexOf(Application.dataPath) < 0) continue;
  1010. var pTmp = p.Replace(Application.dataPath, "Assets");
  1011. AssetDatabase.ImportAsset(pTmp);
  1012. var importer = AssetImporter.GetAtPath(pTmp);
  1013. if (importer is TextureImporter)
  1014. {
  1015. SetTextureImporterSetting(pTmp);
  1016. AssetDatabase.ImportAsset(pTmp);
  1017. importer.SaveAndReimport();
  1018. }
  1019. else if (importer is ModelImporter)
  1020. {
  1021. #region ModelImporter
  1022. var modelImporter = importer as ModelImporter;
  1023. if (clips != null)
  1024. {
  1025. var index = -1;
  1026. {
  1027. var name = pTmp.Substring(pTmp.LastIndexOf("@") + 1);
  1028. name = name.Remove(name.LastIndexOf("."));
  1029. for (int i = 0; i < clips.Length; i++)
  1030. {
  1031. if (clips[i].name.StartsWith(name))
  1032. {
  1033. index = i;
  1034. break;
  1035. }
  1036. }
  1037. }
  1038. if (index >= 0)
  1039. {
  1040. var settings = AnimationUtility.GetAnimationClipSettings(clips[index]);
  1041. bool hasMotionCurves = (bool)HasMotionCurves.Invoke(null, new object[] { clips[index] });
  1042. var setClips = modelImporter.defaultClipAnimations;
  1043. foreach (var setClip in setClips)
  1044. {
  1045. setClip.keepOriginalPositionXZ = true;
  1046. setClip.keepOriginalPositionY = true;
  1047. setClip.keepOriginalOrientation = true;
  1048. if (!hasMotionCurves)
  1049. {
  1050. setClip.lockRootPositionXZ = settings.loopBlendPositionXZ;
  1051. setClip.lockRootHeightY = settings.loopBlendPositionY;
  1052. setClip.lockRootRotation = settings.loopBlendOrientation;
  1053. }
  1054. setClip.name = clips[index].name;
  1055. if (modelImporter.animationType == ModelImporterAnimationType.Legacy)
  1056. {
  1057. setClip.wrapMode = settings.loopTime ? WrapMode.Loop : WrapMode.Default;
  1058. }
  1059. else
  1060. {
  1061. setClip.loop = settings.loopTime;
  1062. setClip.loopTime = settings.loopTime;
  1063. }
  1064. }
  1065. modelImporter.clipAnimations = setClips;
  1066. #region Fix mask
  1067. if (modelImporter.animationType == ModelImporterAnimationType.Legacy)
  1068. {
  1069. var avatarMask = new AvatarMask();
  1070. {
  1071. avatarMask.transformCount = modelImporter.transformPaths.Length;
  1072. for (int i = 0; i < modelImporter.transformPaths.Length; i++)
  1073. {
  1074. avatarMask.SetTransformPath(i, modelImporter.transformPaths[i]);
  1075. avatarMask.SetTransformActive(i, true);
  1076. }
  1077. }
  1078. {
  1079. var updateTransformMask = importer.GetType().GetMethod("UpdateTransformMask", BindingFlags.NonPublic | BindingFlags.Static);
  1080. SerializedObject so = new SerializedObject(modelImporter);
  1081. SerializedProperty spClips = so.FindProperty("m_ClipAnimations");
  1082. for (int i = 0; i < spClips.arraySize; i++)
  1083. {
  1084. var spTransformMask = spClips.GetArrayElementAtIndex(i).FindPropertyRelative("transformMask");
  1085. updateTransformMask.Invoke(modelImporter, new System.Object[] { avatarMask, spTransformMask });
  1086. }
  1087. so.ApplyModifiedProperties();
  1088. }
  1089. }
  1090. #endregion
  1091. }
  1092. }
  1093. importer.SaveAndReimport();
  1094. #endregion
  1095. }
  1096. }
  1097. AssetDatabase.Refresh();
  1098. }
  1099. }
  1100. finally
  1101. {
  1102. foreach (var pair in saveTransforms)
  1103. {
  1104. pair.Value.Load(pair.Key);
  1105. }
  1106. }
  1107. return result;
  1108. }
  1109. protected override void ExportDaeFile_AddTransform(List<Transform> transforms)
  1110. {
  1111. base.ExportDaeFile_AddTransform(transforms);
  1112. for (int i = 0; i < animationObject.bones.Length; i++)
  1113. {
  1114. transforms.Add(animationObject.bones[i].transform);
  1115. }
  1116. }
  1117. #endregion
  1118. #region Undo
  1119. protected override void RefreshCheckerCreate() { animationObject.refreshChecker = new VoxelSkinnedAnimationObject.RefreshCheckerSkinnedAnimation(animationObject); }
  1120. #endregion
  1121. }
  1122. }