public static void Export(string dirPath, Animator parser, List<MeshRenderer> meshes, bool singleMqo, bool worldCoords) { DirectoryInfo dir = new DirectoryInfo(dirPath); List<Texture2D> usedTextures = null; if (singleMqo) { try { string dest = Utility.GetDestFile(dir, "meshes", ".mqo"); usedTextures = Export(dest, parser, meshes, worldCoords); Report.ReportLog("Finished exporting meshes to " + dest); } catch (Exception ex) { Report.ReportLog("Error exporting meshes: " + ex.Message); } } else { for (int i = 0; i < meshes.Count; i++) { try { string frameName = meshes[i].m_GameObject.instance.m_Name; string dest = dir.FullName + @"\" + frameName + ".mqo"; List<Texture2D> texList = Export(dest, parser, new List<MeshRenderer> { meshes[i] }, worldCoords); foreach (Texture2D tex in texList) { if (!usedTextures.Contains(tex)) { usedTextures.Add(tex); } } Report.ReportLog("Finished exporting mesh to " + dest); } catch (Exception ex) { Report.ReportLog("Error exporting mesh: " + ex.Message); } } } foreach (Texture2D tex in usedTextures) { tex.Export(dirPath); } }
public static Transform CloneTransformTree(Animator parser, Transform frame, Transform parent) { Transform trans = new Transform(parser.file); GameObject gameObj = new GameObject(parser.file); gameObj.m_Name = (string)frame.m_GameObject.instance.m_Name.Clone(); UniqueName(parser, gameObj); gameObj.AddLinkedComponent(trans); parser.m_Avatar.instance.AddBone(parent, trans); trans.m_LocalRotation = frame.m_LocalRotation; trans.m_LocalPosition = frame.m_LocalPosition; trans.m_LocalScale = frame.m_LocalScale; CopyUnknowns(frame, trans); trans.InitChildren(frame.Count); for (int i = 0; i < frame.Count; i++) { trans.AddChild(CloneTransformTree(parser, frame[i], trans)); } return trans; }
public static void UniqueName(Animator parser, Transform frame, List<string> frameNames) { GameObject gameObj = frame.m_GameObject.instance; string frameName = gameObj.m_Name; int attempt = 1; while (FindFrame(gameObj.m_Name, parser.RootTransform) != null) { gameObj.m_Name = frameName + ++attempt; } /*if (rename && attempt > 1) { parser.m_Avatar.instance.RenameBone(frameName, gameObj.m_Name); } Transform parent = frame.Parent; string parentPath = Parser.m_Avatar.instance.BonePath(parent.m_GameObject.instance.m_Name); string framePath = Parser.m_Avatar.instance.BonePath(frame.m_GameObject.instance.m_Name); int childIndex = parent.IndexOf(frame); parent.RemoveChild(frame); Operations.UniqueName(Parser, frame.m_GameObject.instance, true); parent.InsertChild(childIndex, frame); for (int i = 0; i < frame.Count; i++) { UniqueFrame(frame[i]); }*/ }
public static void ReplaceMeshRenderer(Transform frame, Transform rootBone, Animator parser, List<Material> materials, WorkspaceMesh mesh, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod, bool targetFullMesh) { Matrix transform = Transform.WorldTransform(frame); int[] indices; bool[] worldCoords; bool[] replaceSubmeshesOption; SkinnedMeshRenderer sMesh = CreateSkinnedMeshRenderer(parser, materials, mesh, transform, out indices, out worldCoords, out replaceSubmeshesOption); vMesh destMesh = new Operations.vMesh(sMesh, true, false); SkinnedMeshRenderer sFrameMesh = frame.m_GameObject.instance.FindLinkedComponent(UnityClassID.SkinnedMeshRenderer); MeshRenderer frameMeshR = sFrameMesh; if (sFrameMesh == null) { frameMeshR = frame.m_GameObject.instance.FindLinkedComponent(UnityClassID.MeshRenderer); } Mesh frameMesh = frameMeshR != null ? Operations.GetMesh(frameMeshR) : null; vMesh srcMesh = null; List<vVertex> allVertices = null; if (frameMeshR == null || frameMesh == null) { sMesh.m_RootBone = new PPtr<Transform>(rootBone); if (rootBone != null) { sMesh.m_Mesh.instance.m_RootBoneNameHash = parser.m_Avatar.instance.BoneHash(rootBone.m_GameObject.instance.m_Name); } if (frameMeshR != null) { CopyUnknowns(frameMeshR, sMesh); } } else { if (sFrameMesh != null) { sMesh.m_RootBone = new PPtr<Transform>(sFrameMesh.m_RootBone.instance); sMesh.m_Mesh.instance.m_RootBoneNameHash = frameMesh.m_RootBoneNameHash; } else { sMesh.m_RootBone = new PPtr<Transform>((Component)null); } srcMesh = new Operations.vMesh(frameMeshR, true, false); CopyUnknowns(frameMeshR, sMesh); if (targetFullMesh && (normalsMethod == CopyMeshMethod.CopyNear || bonesMethod == CopyMeshMethod.CopyNear)) { allVertices = new List<vVertex>(); HashSet<Vector3> posSet = new HashSet<Vector3>(); foreach (vSubmesh submesh in srcMesh.submeshes) { allVertices.Capacity = allVertices.Count + submesh.vertexList.Count; foreach (vVertex vertex in submesh.vertexList) { if (!posSet.Contains(vertex.position)) { posSet.Add(vertex.position); allVertices.Add(vertex); } } } } } transform.Invert(); vSubmesh[] replaceSubmeshes = (srcMesh == null) ? null : new vSubmesh[srcMesh.submeshes.Count]; List<vSubmesh> addSubmeshes = new List<vSubmesh>(destMesh.submeshes.Count); for (int i = 0; i < destMesh.submeshes.Count; i++) { vSubmesh submesh = destMesh.submeshes[i]; List<vVertex> vVertexList = submesh.vertexList; if (worldCoords[i]) { for (int j = 0; j < vVertexList.Count; j++) { vVertexList[j].position = Vector3.TransformCoordinate(vVertexList[j].position, transform); } } vSubmesh baseSubmesh = null; int idx = indices[i]; if ((srcMesh != null) && (idx >= 0) && (idx < frameMesh.m_SubMeshes.Count)) { baseSubmesh = srcMesh.submeshes[idx]; CopyUnknowns(frameMesh.m_SubMeshes[idx], sMesh.m_Mesh.instance.m_SubMeshes[i]); } if (baseSubmesh != null) { if (normalsMethod == CopyMeshMethod.CopyOrder) { Operations.CopyNormalsOrder(baseSubmesh.vertexList, submesh.vertexList); } else if (normalsMethod == CopyMeshMethod.CopyNear) { Operations.CopyNormalsNear(targetFullMesh ? allVertices : baseSubmesh.vertexList, submesh.vertexList); } if (baseSubmesh.vertexList[0].weights != null) { if (bonesMethod == CopyMeshMethod.CopyOrder) { Operations.CopyBonesOrder(baseSubmesh.vertexList, submesh.vertexList); } else if (bonesMethod == CopyMeshMethod.CopyNear) { Operations.CopyBonesNear(targetFullMesh ? allVertices : baseSubmesh.vertexList, submesh.vertexList); } } } if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i]) { replaceSubmeshes[idx] = submesh; } else { addSubmeshes.Add(submesh); } } if ((srcMesh != null) && merge) { destMesh.submeshes = new List<vSubmesh>(replaceSubmeshes.Length + addSubmeshes.Count); List<vSubmesh> copiedSubmeshes = new List<vSubmesh>(replaceSubmeshes.Length); for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] == null) { vSubmesh srcSubmesh = srcMesh.submeshes[i]; copiedSubmeshes.Add(srcSubmesh); destMesh.submeshes.Add(srcSubmesh); } else { destMesh.submeshes.Add(replaceSubmeshes[i]); } } destMesh.submeshes.AddRange(addSubmeshes); if ((sFrameMesh == null || sFrameMesh.m_Bones.Count == 0) && (sMesh.m_Bones.Count > 0)) { for (int i = 0; i < copiedSubmeshes.Count; i++) { List<vVertex> vertexList = copiedSubmeshes[i].vertexList; for (int j = 0; j < vertexList.Count; j++) { vertexList[j].boneIndices = new int[4] { 0, 0, 0, 0 }; vertexList[j].weights = new float[4] { 0, 0, 0, 0 }; } } } else if (sFrameMesh != null && sFrameMesh.m_Bones.Count > 0) { int[] boneIdxMap; sMesh.m_Bones = MergeBoneList(sFrameMesh.m_Bones, sMesh.m_Bones, out boneIdxMap); uint[] boneHashes = new uint[sMesh.m_Bones.Count]; Matrix[] poseMatrices = new Matrix[sMesh.m_Bones.Count]; for (int i = 0; i < sFrameMesh.m_Bones.Count; i++) { boneHashes[i] = sFrameMesh.m_Mesh.instance.m_BoneNameHashes[i]; poseMatrices[i] = sFrameMesh.m_Mesh.instance.m_BindPose[i]; } for (int i = 0; i < boneIdxMap.Length; i++) { boneHashes[boneIdxMap[i]] = sMesh.m_Mesh.instance.m_BoneNameHashes[i]; poseMatrices[boneIdxMap[i]] = sMesh.m_Mesh.instance.m_BindPose[i]; } sMesh.m_Mesh.instance.m_BoneNameHashes.Clear(); sMesh.m_Mesh.instance.m_BoneNameHashes.AddRange(boneHashes); sMesh.m_Mesh.instance.m_BindPose.Clear(); sMesh.m_Mesh.instance.m_BindPose.AddRange(poseMatrices); if (bonesMethod == CopyMeshMethod.Replace) { for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] != null) { List<vVertex> vertexList = replaceSubmeshes[i].vertexList; if (vertexList[0].boneIndices != null) { for (int j = 0; j < vertexList.Count; j++) { int[] boneIndices = vertexList[j].boneIndices; vertexList[j].boneIndices = new int[4]; for (int k = 0; k < 4; k++) { vertexList[j].boneIndices[k] = boneIdxMap[boneIndices[k]]; } } } } } for (int i = 0; i < addSubmeshes.Count; i++) { List<vVertex> vertexList = addSubmeshes[i].vertexList; if (vertexList[0].boneIndices != null) { for (int j = 0; j < vertexList.Count; j++) { int[] boneIndices = vertexList[j].boneIndices; vertexList[j].boneIndices = new int[4]; for (int k = 0; k < 4; k++) { vertexList[j].boneIndices[k] = boneIdxMap[boneIndices[k]]; } } } } } } } destMesh.Flush(); if (frameMeshR != null) { frame.m_GameObject.instance.RemoveLinkedComponent(frameMeshR); //parser.file.RemoveSubfile(frameMeshR); if (frameMesh != null) { //parser.file.RemoveSubfile(frameMesh); parser.file.ReplaceSubfile(frameMesh, sMesh.m_Mesh.asset); } parser.file.ReplaceSubfile(frameMeshR, sMesh); } frame.m_GameObject.instance.AddLinkedComponent(sMesh); AssetBundle bundle = parser.file.Bundle; if (bundle != null) { if (frameMeshR != null) { if (frameMesh != null) { bundle.ReplaceComponent(frameMesh, sMesh.m_Mesh.asset); } bundle.ReplaceComponent(frameMeshR, sMesh); } else { bundle.RegisterForUpdate(parser.m_GameObject.asset); } } }
public static Transform CreateTransformTree(Animator parser, ImportedFrame frame, Transform parent) { Transform trans = new Transform(parser.file); GameObject gameObj = new GameObject(parser.file); gameObj.m_Name = (string)frame.Name.Clone(); UniqueName(parser, gameObj); gameObj.AddLinkedComponent(trans); parser.m_Avatar.instance.AddBone(parent, trans); Vector3 t, s; Quaternion r; frame.Matrix.Decompose(out s, out r, out t); t.X *= -1; Vector3 euler = FbxUtility.QuaternionToEuler(r); euler.Y *= -1; euler.Z *= -1; trans.m_LocalRotation = FbxUtility.EulerToQuaternion(euler); trans.m_LocalPosition = t; trans.m_LocalScale = s; trans.InitChildren(frame.Count); for (int i = 0; i < frame.Count; i++) { trans.AddChild(CreateTransformTree(parser, frame[i], trans)); } return trans; }
public AnimatorEditor(Animator parser) { Parser = parser; Frames = new List<Transform>(); Meshes = new List<MeshRenderer>(); Materials = new List<Material>(); Textures = new List<Texture2D>(); try { parser.file.BeginLoadingSkippedComponents(); if (Parser.m_Avatar.asset == null) { string animatorName = Parser.m_GameObject.instance.m_Name; if (animatorName.Length > 2 && animatorName[1] == '_') { animatorName = animatorName.Substring(2); } foreach (Component asset in Parser.file.Components) { if (asset.classID1 == UnityClassID.Avatar) { string assetName; if (asset is NotLoaded) { if (((NotLoaded)asset).Name != null) { assetName = ((NotLoaded)asset).Name; } else { Parser.file.SourceStream.Position = ((NotLoaded)asset).offset; assetName = Avatar.LoadName(Parser.file.SourceStream); ((NotLoaded)asset).Name = assetName; } } else { assetName = ((Avatar)asset).m_Name; } if (assetName.Contains(animatorName)) { Parser.m_Avatar = new PPtr<Avatar>(asset); Report.ReportLog("Warning! Using Avatar " + assetName + " for Animator " + Parser.m_GameObject.instance.m_Name); break; } } } } if (Parser.m_Avatar.asset is NotLoaded) { Avatar loadedAvatar = Parser.file.LoadComponent(Parser.file.SourceStream, (NotLoaded)Parser.m_Avatar.asset); Parser.m_Avatar = new PPtr<Avatar>(loadedAvatar); } if (Parser.m_Avatar.instance == null) { Report.ReportLog("Warning! Animator " + Parser.m_GameObject.instance.m_Name + " has no Avatar!"); } InitLists(parser.RootTransform); } finally { parser.file.EndLoadingSkippedComponents(); } }
public void CopyTo(Animator dest) { if (file.Bundle.numContainerEntries(m_GameObject.instance.m_Name, UnityClassID.GameObject) > 1) { Report.ReportLog("Warning! Animator " + m_GameObject.instance.m_Name + " has multiple entries in the AssetBundle's Container."); } dest.file.Bundle.AddComponent(m_GameObject.instance.m_Name, dest.m_GameObject.instance); dest.m_Enabled = m_Enabled; dest.m_Avatar = new PPtr<Avatar>(m_Avatar.instance != null ? m_Avatar.instance.Clone(dest.file) : null); dest.m_Controller = new PPtr<RuntimeAnimatorController>((Component)null); if (m_Controller.asset != null) { Report.ReportLog("Warning! " + m_Controller.asset.classID1 + " " + AssetCabinet.ToString(m_Controller.asset) + " not duplicated!"); } dest.m_CullingMode = m_CullingMode; dest.m_UpdateMode = m_UpdateMode; dest.m_ApplyRootMotion = m_ApplyRootMotion; dest.m_HasTransformHierarchy = m_HasTransformHierarchy; dest.m_AllowConstantClipSamplingOptimization = m_AllowConstantClipSamplingOptimization; }
private void UpdateComponent(Component asset, List<Tuple<List<PPtr<Object>>, List<KeyValuePair<string, AssetInfo>>>> containerGroups) { List<Component> assets = new List<Component>(); List<Component> transforms = new List<Component>(); List<Component> containerRelated = new List<Component>(); GetDependantAssets(asset, assets, transforms, containerRelated); if (asset.classID1 == UnityClassID.GameObject) { GameObject gameObj = (GameObject)asset; Animator animator = gameObj.FindLinkedComponent(UnityClassID.Animator); if (animator == null) { foreach (Component trans in transforms) { GetDependantAssets(trans, assets, null, null); } animator = new Animator(null, 0, UnityClassID.Animator, UnityClassID.Animator); animator.m_Avatar = new PPtr<Avatar>((Component)null); animator.m_Controller = new PPtr<RuntimeAnimatorController>((Component)null); GetDependantAssets(animator, assets, transforms, containerRelated); assets.Remove(animator); } } foreach (var group in containerGroups) { var preloadPart = group.Item1; var containerEntries = group.Item2; for (int i = 0; i < containerEntries.Count; i++) { var assetPair = containerEntries[i]; if (assetPair.Value.asset.asset == asset) { preloadPart.Clear(); for (int j = 0; j < assets.Count; j++) { if (assets[j] is ExternalAsset) { ExternalAsset extAsset = (ExternalAsset)assets[j]; PPtr<Object> preloadEntry = new PPtr<Object>((Component)null); preloadEntry.m_FileID = extAsset.FileID; preloadEntry.m_PathID = extAsset.PathID; preloadPart.Add(preloadEntry); } else { preloadPart.Add(new PPtr<Object>(assets[j])); } } string groupName = containerEntries[0].Key; string assetName = AssetCabinet.ToString(asset); if (String.Compare(groupName, assetName, true) != 0) { groupName = assetName.ToLower(); } if (containerEntries.Count > 1) { for (int j = 0; j < containerEntries.Count; j++) { switch (containerEntries[j].Value.asset.asset.classID1) { case UnityClassID.Mesh: case UnityClassID.AnimationClip: containerEntries.RemoveAt(j); j--; break; } } for (int j = containerRelated.Count - 1; j >= 0; j--) { AnimationClip clip = containerRelated[j] as AnimationClip; if (clip != null) { AssetInfo info = new AssetInfo(file); info.asset = new PPtr<Object>(clip); containerEntries.Insert(1, new KeyValuePair<string, AssetInfo>(groupName, info)); } } for (int j = containerRelated.Count - 1; j >= 0; j--) { MeshRenderer meshR = containerRelated[j] as MeshRenderer; if (meshR != null) { Mesh mesh = Operations.GetMesh(meshR); if (mesh != null) { AssetInfo info = new AssetInfo(file); info.asset = new PPtr<Object>(mesh); containerEntries.Insert(1, new KeyValuePair<string, AssetInfo>(groupName, info)); } } } for (int j = 0; j < containerEntries.Count; j++) { containerEntries[j].Value.preloadSize = assets.Count; } } else { containerEntries[0].Value.preloadSize = assets.Count; } for (int j = 0; j < containerEntries.Count; j++) { if (containerEntries[j].Key != groupName) { containerEntries[j] = new KeyValuePair<string, AssetInfo>(groupName, containerEntries[j].Value); } } return; } } } }
public static void Export(string dirPath, Animator parser, SkinnedMeshRenderer morphObj) { DirectoryInfo dir = new DirectoryInfo(dirPath); ExporterMorph exporter = new ExporterMorph(dir, parser, morphObj); exporter.Export(dir); }
private ExporterMorph(DirectoryInfo dir, Animator parser, SkinnedMeshRenderer morphObj) { this.parser = parser; this.morphObj = morphObj; }
public UnityConverter(Animator animator, List<MeshRenderer> meshList, bool skins, bool morphs) { ConvertFrames(animator.RootTransform, null); if (skins) { avatar = animator.m_Avatar.instance; } ConvertMeshRenderers(meshList, skins, morphs); AnimationList = new List<ImportedAnimation>(); }
public void PasteAllMarked() { int components = Parser.Cabinet.Components.Count; try { Parser.Cabinet.BeginLoadingSkippedComponents(); foreach (object obj in Gui.Scripting.Variables.Values) { if (obj is Unity3dEditor && (Unity3dEditor)obj != this) { Unity3dEditor editor = (Unity3dEditor)obj; HashSet<Component> remove = new HashSet<Component>(); HashSet<Component> replace = new HashSet<Component>(); foreach (Component asset in editor.Marked) { Component loaded; if (asset is NotLoaded) { loaded = editor.Parser.Cabinet.LoadComponent(asset.pathID); remove.Add(asset); replace.Add(loaded); } else { loaded = asset; } switch (asset.classID2) { case UnityClassID.Texture2D: Texture2D tex = (Texture2D)loaded; tex.Clone(Parser.Cabinet); break; case UnityClassID.Cubemap: Cubemap cubemap = (Cubemap)loaded; cubemap.Clone(Parser.Cabinet); break; case UnityClassID.Material: Material mat = (Material)loaded; mat.Clone(Parser.Cabinet); break; case UnityClassID.Mesh: Mesh mesh = (Mesh)loaded; mesh.Clone(Parser.Cabinet); break; case UnityClassID.Shader: Shader shader = (Shader)loaded; shader.Clone(Parser.Cabinet); break; case UnityClassID.Sprite: Sprite sprite = (Sprite)loaded; sprite.Clone(Parser.Cabinet); break; case UnityClassID.Animator: Parser.Cabinet.MergeTypeDefinition(loaded.file, UnityClassID.GameObject); Parser.Cabinet.MergeTypeDefinition(loaded.file, UnityClassID.Transform); Animator anim = (Animator)loaded; anim.m_GameObject.instance.Clone(Parser.Cabinet); break; case UnityClassID.GameObject: Parser.Cabinet.MergeTypeDefinition(loaded.file, UnityClassID.GameObject); Parser.Cabinet.MergeTypeDefinition(loaded.file, UnityClassID.Transform); GameObject gameObj = (GameObject)loaded; Component clone = gameObj.Clone(Parser.Cabinet); Animator vAnim = new Animator(Parser.Cabinet, 0, 0, 0); vAnim.m_Avatar = new PPtr<Avatar>((Component)null); vAnim.m_GameObject = new PPtr<GameObject>(clone); if (loaded.file.Bundle.numContainerEntries(gameObj.m_Name, UnityClassID.GameObject) > 1) { Report.ReportLog("Warning! Animator " + gameObj.m_Name + " has multiple entries in the AssetBundle's Container."); } vAnim.file.Bundle.AddComponent(vAnim.m_GameObject.instance.m_Name, clone); VirtualAnimators.Add(vAnim); if (loaded != asset) { foreach (Animator a in editor.VirtualAnimators) { if (a.m_GameObject.asset == asset) { a.m_GameObject = new PPtr<GameObject>(loaded); break; } } } break; case UnityClassID.Avatar: Avatar avatar = (Avatar)loaded; avatar.Clone(Parser.Cabinet); break; case UnityClassID.MonoBehaviour: MonoBehaviour monoB = (MonoBehaviour)loaded; monoB.Clone(Parser.Cabinet); break; case UnityClassID.TextAsset: TextAsset text = (TextAsset)loaded; text.Clone(Parser.Cabinet); break; case UnityClassID.AnimationClip: AnimationClip clip = (AnimationClip)loaded; clip.Clone(Parser.Cabinet); break; } } do { HashSet<Tuple<Component, Component>> loopSet = new HashSet<Tuple<Component, Component>>(AssetCabinet.IncompleteClones); AssetCabinet.IncompleteClones.Clear(); foreach (var pair in loopSet) { Component src = pair.Item1; Component dest = pair.Item2; Type t = src.GetType(); MethodInfo info = t.GetMethod("CopyTo", new Type[] { t }); info.Invoke(src, new object[] { dest }); } } while (AssetCabinet.IncompleteClones.Count > 0); foreach (Component asset in remove) { editor.Marked.Remove(asset); } foreach (Component asset in replace) { editor.Marked.Add(asset); } } } } finally { Parser.Cabinet.EndLoadingSkippedComponents(); if (components != Parser.Cabinet.Components.Count) { Changed = true; } } }
public bool CreateVirtualAnimator(Component gameObject) { if (gameObject is NotLoaded && ((NotLoaded)gameObject).replacement != null) { gameObject = ((NotLoaded)gameObject).replacement; } if (gameObject is NotLoaded ? IsVirtualAnimator((NotLoaded)gameObject) : GetVirtualAnimator((GameObject)gameObject) != null) { return false; } Animator animator = new Animator(Parser.Cabinet, 0, 0, 0); animator.m_Avatar = new PPtr<Avatar>((Component)null); animator.m_GameObject = new PPtr<GameObject>(gameObject); VirtualAnimators.Add(animator); return true; }
static void UniqueName(Animator parser, GameObject gameObj) { string name = gameObj.m_Name; int attempt = 1; while (FindFrame(gameObj.m_Name, parser.RootTransform) != null) { gameObj.m_Name = name + ++attempt; } }
public static void ExportMorphMqo([DefaultVar]string dirPath, Animator parser, string meshName) { SkinnedMeshRenderer sMesh = (SkinnedMeshRenderer)Operations.FindMesh(parser.RootTransform, meshName); if (sMesh != null) { if (dirPath == null) { dirPath = parser.file.Parser.FilePath; if (dirPath.ToLower().EndsWith(".unity3d")) { dirPath = dirPath.Substring(0, dirPath.Length - 8); } dirPath += @"\" + parser.m_GameObject.instance.m_Name; } Mqo.ExporterMorph.Export(dirPath, parser, sMesh); } }
public static SkinnedMeshRenderer CreateSkinnedMeshRenderer(Animator parser, List<Material> materials, WorkspaceMesh mesh, Matrix meshMatrix, out int[] indices, out bool[] worldCoords, out bool[] replaceSubmeshesOption) { int numUncheckedSubmeshes = 0; foreach (ImportedSubmesh submesh in mesh.SubmeshList) { if (!mesh.isSubmeshEnabled(submesh)) { numUncheckedSubmeshes++; } } int numSubmeshes = mesh.SubmeshList.Count - numUncheckedSubmeshes; indices = new int[numSubmeshes]; worldCoords = new bool[numSubmeshes]; replaceSubmeshesOption = new bool[numSubmeshes]; List<Matrix> poseMatrices = new List<Matrix>(mesh.BoneList.Count); Transform animatorTransform = parser.m_GameObject.instance.FindLinkedComponent(UnityClassID.Transform); List<PPtr<Transform>> bones = CreateBoneList(animatorTransform, meshMatrix, mesh.BoneList, poseMatrices); SkinnedMeshRenderer sMesh = new SkinnedMeshRenderer(parser.file); int totVerts = 0, totFaces = 0; sMesh.m_Materials.Capacity = numSubmeshes; foreach (ImportedSubmesh submesh in mesh.SubmeshList) { if (!mesh.isSubmeshEnabled(submesh)) { continue; } Material matFound = materials.Find ( delegate(Material mat) { return mat.m_Name == submesh.Material; } ); sMesh.m_Materials.Add(new PPtr<Material>(matFound)); totVerts += submesh.VertexList.Count; totFaces += submesh.FaceList.Count; } Mesh uMesh = new Mesh(parser.file); uMesh.m_Name = mesh.Name; sMesh.m_Mesh = new PPtr<Mesh>(uMesh); sMesh.m_Bones = bones; uMesh.m_BindPose = poseMatrices; uMesh.m_BoneNameHashes = new List<uint>(poseMatrices.Count); for (int i = 0; i < mesh.BoneList.Count; i++) { string bone = mesh.BoneList[i].Name; uint hash = parser.m_Avatar.instance.BoneHash(bone); uMesh.m_BoneNameHashes.Add(hash); } uMesh.m_VertexData = new VertexData((uint)totVerts); uMesh.m_Skin = new List<BoneInfluence>(totVerts); uMesh.m_IndexBuffer = new byte[totFaces * 3 * sizeof(ushort)]; using (BinaryWriter vertWriter = new BinaryWriter(new MemoryStream(uMesh.m_VertexData.m_DataSize)), indexWriter = new BinaryWriter(new MemoryStream(uMesh.m_IndexBuffer))) { uMesh.m_LocalAABB.m_Center = new Vector3(Single.MaxValue, Single.MaxValue, Single.MaxValue); uMesh.m_LocalAABB.m_Extend = new Vector3(Single.MinValue, Single.MinValue, Single.MinValue); uMesh.m_SubMeshes = new List<SubMesh>(numSubmeshes); int vertIndex = 0; for (int i = 0, submeshIdx = 0; i < numSubmeshes; i++, submeshIdx++) { while (!mesh.isSubmeshEnabled(mesh.SubmeshList[submeshIdx])) { submeshIdx++; } SubMesh submesh = new SubMesh(); submesh.indexCount = (uint)mesh.SubmeshList[submeshIdx].FaceList.Count * 3; submesh.vertexCount = (uint)mesh.SubmeshList[submeshIdx].VertexList.Count; submesh.firstVertex = (uint)vertIndex; uMesh.m_SubMeshes.Add(submesh); indices[i] = mesh.SubmeshList[submeshIdx].Index; worldCoords[i] = mesh.SubmeshList[submeshIdx].WorldCoords; replaceSubmeshesOption[i] = mesh.isSubmeshReplacingOriginal(mesh.SubmeshList[submeshIdx]); List<ImportedVertex> vertexList = mesh.SubmeshList[submeshIdx].VertexList; Vector3 min = new Vector3(Single.MaxValue, Single.MaxValue, Single.MaxValue); Vector3 max = new Vector3(Single.MinValue, Single.MinValue, Single.MinValue); for (int str = 0; str < uMesh.m_VertexData.m_Streams.Count; str++) { StreamInfo sInfo = uMesh.m_VertexData.m_Streams[str]; if (sInfo.channelMask == 0) { continue; } for (int j = 0; j < vertexList.Count; j++) { ImportedVertex vert = vertexList[j]; for (int chn = 0; chn < uMesh.m_VertexData.m_Channels.Count; chn++) { ChannelInfo cInfo = uMesh.m_VertexData.m_Channels[chn]; if ((sInfo.channelMask & (1 << chn)) == 0) { continue; } vertWriter.BaseStream.Position = sInfo.offset + (j + submesh.firstVertex) * sInfo.stride + cInfo.offset; switch (chn) { case 0: Vector3 pos = vert.Position; pos.X *= -1; vertWriter.Write(pos); min = Vector3.Minimize(min, pos); max = Vector3.Maximize(max, pos); break; case 1: Vector3 normal = vert.Normal; normal.X *= -1; vertWriter.Write(normal); break; case 3: vertWriter.Write(vert.UV); break; case 5: Vector4 tangent = vert.Tangent; tangent.X *= -1; tangent.W *= -1; vertWriter.Write(tangent); break; } } if (sMesh.m_Bones.Count > 0 && sInfo.offset == 0 && uMesh.m_Skin.Count < totVerts) { BoneInfluence item = new BoneInfluence(); for (int k = 0; k < 4; k++) { item.boneIndex[k] = vert.BoneIndices[k] != 0xFF ? vert.BoneIndices[k] : 0; } vert.Weights.CopyTo(item.weight, 0); uMesh.m_Skin.Add(item); } } } vertIndex += (int)submesh.vertexCount; submesh.localAABB.m_Extend = max - min; submesh.localAABB.m_Center = min + submesh.localAABB.m_Extend / 2; uMesh.m_LocalAABB.m_Extend = Vector3.Maximize(uMesh.m_LocalAABB.m_Extend, max); uMesh.m_LocalAABB.m_Center = Vector3.Minimize(uMesh.m_LocalAABB.m_Center, min); List<ImportedFace> faceList = mesh.SubmeshList[submeshIdx].FaceList; submesh.firstByte = (uint)indexWriter.BaseStream.Position; for (int j = 0; j < faceList.Count; j++) { int[] vertexIndices = faceList[j].VertexIndices; indexWriter.Write((ushort)(vertexIndices[0] + submesh.firstVertex)); indexWriter.Write((ushort)(vertexIndices[2] + submesh.firstVertex)); indexWriter.Write((ushort)(vertexIndices[1] + submesh.firstVertex)); } } uMesh.m_LocalAABB.m_Extend -= uMesh.m_LocalAABB.m_Center; uMesh.m_LocalAABB.m_Center += uMesh.m_LocalAABB.m_Extend / 2; } return sMesh; }
private static List<Texture2D> Export(string dest, Animator parser, List<MeshRenderer> meshes, bool worldCoords) { DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(dest)); if (!dir.Exists) { dir.Create(); } Plugins.UnityConverter conv = new Plugins.UnityConverter(parser, meshes, false, false); List<Material> materialList = new List<Material>(meshes.Count); using (StreamWriter writer = new StreamWriter(dest, false)) { for (int i = 0; i < meshes.Count; i++) { MeshRenderer meshRenderer = meshes[i]; ImportedMesh meshListSome = conv.MeshList[i]; for (int j = 0; j < meshListSome.SubmeshList.Count; j++) { Material mat = meshRenderer.m_Materials[j].instance; if (mat != null) { if (!materialList.Contains(mat)) { materialList.Add(mat); } } else { Report.ReportLog("Warning: Mesh " + meshes[i].m_GameObject.instance.m_Name + " Object " + j + " has an invalid material"); } } } writer.WriteLine("Metasequoia Document"); writer.WriteLine("Format Text Ver 1.0"); writer.WriteLine(); writer.WriteLine("Material " + materialList.Count + " {"); for (int matIdx = 0; matIdx < materialList.Count; matIdx++) { Material mat = materialList[matIdx]; string s = "\t\"" + mat.m_Name + "\" col(0.800 0.800 0.800 1.000) dif(0.500) amb(0.100) emi(0.500) spc(0.100) power(30.00)"; try { Texture2D tex = mat.m_SavedProperties.m_TexEnvs[0].Value.m_Texture.instance; for (int i = 1; i < mat.m_SavedProperties.m_TexEnvs.Count; i++) { var texProp = mat.m_SavedProperties.m_TexEnvs[i]; if (texProp.Key.name == "_MainTex") { tex = texProp.Value.m_Texture.instance; break; } } if (tex != null) { string matTexName = tex.m_Name + "-" + tex.m_TextureFormat; string extension = tex.m_TextureFormat == TextureFormat.DXT1 || tex.m_TextureFormat == TextureFormat.DXT5 ? ".dds" : ".tga"; s += " tex(\"" + matTexName + extension + "\")"; } } catch { } writer.WriteLine(s); } writer.WriteLine("}"); Random rand = new Random(); for (int i = 0; i < meshes.Count; i++) { MeshRenderer mesh = meshes[i]; if (worldCoords) { Transform parent = Operations.FindFrame(meshes[i].m_GameObject.instance.m_Name, parser.RootTransform); conv.WorldCoordinates(i, Transform.WorldTransform(parent)); } string meshName = mesh.m_GameObject.instance.m_Name; ImportedMesh meshListSome = conv.MeshList[i]; for (int j = 0; j < meshListSome.SubmeshList.Count; j++) { ImportedSubmesh meshObj = meshListSome.SubmeshList[j]; Material mat = mesh.m_Materials[j].instance; int mqoMatIdx = -1; if (mat != null) { mqoMatIdx = materialList.IndexOf(mat); } float[] color = new float[3]; for (int k = 0; k < color.Length; k++) { color[k] = (float)((rand.NextDouble() / 2) + 0.5); } string mqoName = meshName + "[" + j + "]"; if (worldCoords) { mqoName += "[W]"; } writer.WriteLine("Object \"" + mqoName + "\" {"); writer.WriteLine("\tshading 1"); writer.WriteLine("\tcolor " + color[0].ToFloatString() + " " + color[1].ToFloatString() + " " + color[2].ToFloatString()); writer.WriteLine("\tcolor_type 1"); List<ImportedVertex> vertList = meshObj.VertexList; List<ImportedFace> faceList = meshObj.FaceList; SB3Utility.Mqo.ExporterCommon.WriteMeshObject(writer, vertList, faceList, mqoMatIdx, null); writer.WriteLine("}"); } } writer.WriteLine("Eof"); } List<Texture2D> usedTextures = new List<Texture2D>(meshes.Count); foreach (Material mat in materialList) { try { Texture2D matTex = mat.m_SavedProperties.m_TexEnvs[0].Value.m_Texture.instance; for (int i = 1; i < mat.m_SavedProperties.m_TexEnvs.Count; i++) { var texProp = mat.m_SavedProperties.m_TexEnvs[i]; if (texProp.Key.name == "_MainTex") { matTex = texProp.Value.m_Texture.instance; break; } } if (matTex != null && !usedTextures.Contains(matTex)) { usedTextures.Add(matTex); } } catch { } } return usedTextures; }
public dynamic LoadComponent(Stream stream, int index, NotLoaded comp) { stream.Position = comp.offset; try { switch (comp.classID1) { case UnityClassID.AnimationClip: { AnimationClip animationClip = new AnimationClip(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, animationClip, comp); animationClip.LoadFrom(stream); return animationClip; } case UnityClassID.Animator: { Animator animator = new Animator(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, animator, comp); animator.LoadFrom(stream); return animator; } case UnityClassID.AnimatorController: { AnimatorController animatorController = new AnimatorController(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, animatorController, comp); animatorController.LoadFrom(stream); return animatorController; } case UnityClassID.AssetBundle: { AssetBundle assetBundle = new AssetBundle(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, assetBundle, comp); assetBundle.LoadFrom(stream); return assetBundle; } case UnityClassID.AudioClip: { if (loadingReferencials) { return comp; } AudioClip ac = new AudioClip(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, ac, comp); ac.LoadFrom(stream); return ac; } case UnityClassID.AudioListener: { AudioListener audioListener = new AudioListener(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, audioListener, comp); audioListener.LoadFrom(stream); return audioListener; } case UnityClassID.AudioSource: { AudioSource audioSrc = new AudioSource(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, audioSrc, comp); audioSrc.LoadFrom(stream); return audioSrc; } case UnityClassID.Avatar: { if (loadingReferencials) { return comp; } Avatar avatar = new Avatar(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, avatar, comp); avatar.LoadFrom(stream); return avatar; } case UnityClassID.BoxCollider: { BoxCollider boxCol = new BoxCollider(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, boxCol, comp); boxCol.LoadFrom(stream); return boxCol; } case UnityClassID.Camera: { Camera camera = new Camera(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, camera, comp); camera.LoadFrom(stream); return camera; } case UnityClassID.CapsuleCollider: { CapsuleCollider capsuleCol = new CapsuleCollider(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, capsuleCol, comp); capsuleCol.LoadFrom(stream); return capsuleCol; } case UnityClassID.Cubemap: { Cubemap cubemap = new Cubemap(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, cubemap, comp); cubemap.LoadFrom(stream); Parser.Textures.Add(cubemap); return cubemap; } case UnityClassID.EllipsoidParticleEmitter: { EllipsoidParticleEmitter ellipsoid = new EllipsoidParticleEmitter(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, ellipsoid, comp); ellipsoid.LoadFrom(stream); return ellipsoid; } case UnityClassID.FlareLayer: { FlareLayer flareLayer = new FlareLayer(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, flareLayer, comp); flareLayer.LoadFrom(stream); return flareLayer; } case UnityClassID.Light: { Light light = new Light(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, light, comp); light.LoadFrom(stream); return light; } case UnityClassID.LinkToGameObject: { LinkToGameObject link = new LinkToGameObject(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, link, comp); link.LoadFrom(stream); return link; } case UnityClassID.LinkToGameObject223: { LinkToGameObject223 link = new LinkToGameObject223(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, link, comp); link.LoadFrom(stream); return link; } case UnityClassID.LinkToGameObject225: { LinkToGameObject225 link = new LinkToGameObject225(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, link, comp); link.LoadFrom(stream); return link; } case UnityClassID.GameObject: { GameObject gameObj = new GameObject(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, gameObj, comp); gameObj.LoadFrom(stream); return gameObj; } case UnityClassID.Material: { Material mat = new Material(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, mat, comp); mat.LoadFrom(stream); return mat; } case UnityClassID.Mesh: { if (loadingReferencials) { return comp; } Mesh mesh = new Mesh(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, mesh, comp); mesh.LoadFrom(stream); return mesh; } case UnityClassID.MeshCollider: { MeshCollider meshCol = new MeshCollider(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, meshCol, comp); meshCol.LoadFrom(stream); return meshCol; } case UnityClassID.MeshFilter: { MeshFilter meshFilter = new MeshFilter(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, meshFilter, comp); meshFilter.LoadFrom(stream); return meshFilter; } case UnityClassID.MeshRenderer: { MeshRenderer meshRenderer = new MeshRenderer(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, meshRenderer, comp); meshRenderer.LoadFrom(stream); return meshRenderer; } default: if (comp.classID2 == UnityClassID.MonoBehaviour) { if (Types.Count > 0) { MonoBehaviour monoBehaviour = new MonoBehaviour(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, monoBehaviour, comp); monoBehaviour.LoadFrom(stream); return monoBehaviour; } else { string message = comp.classID2 + " unhandled because of absence of Types in Cabinet (*.assets)"; if (!reported.Contains(message)) { Report.ReportLog(message); reported.Add(message); } return comp; } } else { string message = "Unhandled class: " + comp.classID1 + "/" + comp.classID2; if (!reported.Contains(message)) { Report.ReportLog(message); reported.Add(message); } } break; case UnityClassID.MonoScript: { if (loadingReferencials) { return comp; } MonoScript monoScript = new MonoScript(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, monoScript, comp); monoScript.LoadFrom(stream); return monoScript; } case UnityClassID.MultiLink: { MultiLink multi = new MultiLink(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, multi, comp); multi.LoadFrom(stream); return multi; } case UnityClassID.ParticleAnimator: { ParticleAnimator particleAnimator = new ParticleAnimator(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, particleAnimator, comp); particleAnimator.LoadFrom(stream); return particleAnimator; } case UnityClassID.ParticleRenderer: { ParticleRenderer particleRenderer = new ParticleRenderer(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, particleRenderer, comp); particleRenderer.LoadFrom(stream); return particleRenderer; } case UnityClassID.ParticleSystem: { ParticleSystem particleSystem = new ParticleSystem(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, particleSystem, comp); particleSystem.LoadFrom(stream); return particleSystem; } case UnityClassID.ParticleSystemRenderer: { ParticleSystemRenderer particleSystemRenderer = new ParticleSystemRenderer(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, particleSystemRenderer, comp); particleSystemRenderer.LoadFrom(stream); return particleSystemRenderer; } case UnityClassID.Projector: { Projector projector = new Projector(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, projector, comp); projector.LoadFrom(stream); return projector; } case UnityClassID.Rigidbody: { RigidBody rigidBody = new RigidBody(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, rigidBody, comp); rigidBody.LoadFrom(stream); return rigidBody; } case UnityClassID.Shader: { Shader shader = new Shader(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, shader, comp); shader.LoadFrom(stream); return shader; } case UnityClassID.SkinnedMeshRenderer: { SkinnedMeshRenderer sMesh = new SkinnedMeshRenderer(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, sMesh, comp); sMesh.LoadFrom(stream); return sMesh; } case UnityClassID.SphereCollider: { SphereCollider sphereCol = new SphereCollider(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, sphereCol, comp); sphereCol.LoadFrom(stream); return sphereCol; } case UnityClassID.Sprite: { Sprite sprite = new Sprite(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, sprite, comp); sprite.LoadFrom(stream); return sprite; } case UnityClassID.SpriteRenderer: { SpriteRenderer spriteRenderer = new SpriteRenderer(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, spriteRenderer, comp); spriteRenderer.LoadFrom(stream); return spriteRenderer; } case UnityClassID.TextAsset: { if (loadingReferencials) { return comp; } TextAsset ta = new TextAsset(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, ta, comp); ta.LoadFrom(stream); return ta; } case UnityClassID.Texture2D: { if (loadingReferencials) { return comp; } Texture2D tex = new Texture2D(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, tex, comp); tex.LoadFrom(stream); Parser.Textures.Add(tex); return tex; } case UnityClassID.Transform: { Transform trans = new Transform(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, trans, comp); trans.LoadFrom(stream); return trans; } } } catch { Report.ReportLog("Failed to load " + comp.classID1 + "/" + comp.classID2 + " PathID=" + comp.pathID); foreach (NotLoaded notLoaded in RemovedList) { if (notLoaded == comp) { RemovedList.Remove(notLoaded); Components.RemoveAt(index); notLoaded.replacement = null; Components.Insert(index, notLoaded); break; } } } return null; }
public Animator Clone(AssetCabinet file) { Component gameObj = file.Bundle.FindComponent(m_GameObject.instance.m_Name, UnityClassID.GameObject); if (gameObj == null) { file.MergeTypeDefinition(this.file, UnityClassID.Animator); Animator dest = new Animator(file); AssetCabinet.IncompleteClones.Add(new Tuple<Component, Component>(this, dest)); return dest; } else if (gameObj is NotLoaded) { NotLoaded notLoaded = (NotLoaded)gameObj; if (notLoaded.replacement != null) { gameObj = notLoaded.replacement; } else { gameObj = file.LoadComponent(file.SourceStream, notLoaded); } } return ((GameObject)gameObj).FindLinkedComponent(UnityClassID.Animator); }