private void Export(DirectoryInfo dir) { try { List <MeshRenderer> meshList = new List <MeshRenderer>(1); meshList.Add(morphObj); Mesh mesh = Operations.GetMesh(morphObj); colorLists = new bool[mesh.m_Shapes.shapes.Count][]; vertLists = new List <ImportedVertex> [mesh.m_Shapes.shapes.Count]; for (int i = 0; i < mesh.m_Shapes.shapes.Count; i++) { Plugins.UnityConverter conv = new Plugins.UnityConverter(parser, meshList, false, false); ImportedMesh meshObjBase = conv.MeshList[0]; if (faceList == null) { faceList = meshObjBase.SubmeshList[0].FaceList; } List <ImportedVertex> vertList = conv.MeshList[0].SubmeshList[0].VertexList; vertLists[i] = vertList; colorLists[i] = new bool[meshObjBase.SubmeshList[0].VertexList.Count]; int lastVertIndex = (int)(mesh.m_Shapes.shapes[i].firstVertex + mesh.m_Shapes.shapes[i].vertexCount); for (int j = (int)mesh.m_Shapes.shapes[i].firstVertex; j < lastVertIndex; j++) { BlendShapeVertex srcVert = mesh.m_Shapes.vertices[j]; ImportedVertex vert = vertList[(int)srcVert.index]; vert.Position += srcVert.vertex; colorLists[i][(int)srcVert.index] = true; } } string dest = Utility.GetDestFile(dir, morphObj.m_GameObject.instance.m_Name + "-" + mesh.m_Name + "-", ".morph.mqo"); Material mat = morphObj.m_Materials[0].instance; 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; } } Export(dest, mat, matTex); foreach (Texture2D tex in usedTextures) { try { tex.Export(dir.FullName); } catch (Exception ex) { Utility.ReportException(ex); } } Report.ReportLog("Finished exporting morph to " + dest); } catch (Exception ex) { Report.ReportLog("Error exporting morph: " + ex.Message); } }
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 void MergeMaterial(ImportedMaterial material) { Operations.ReplaceMaterial(Parser, material); Changed = true; }
public override void CopyTo(UType dest) { Component asset = null; if (Value.asset != null) { string name = AssetCabinet.ToString(Value.asset); asset = ((UPPtr)dest).file.Bundle.FindComponent(name, Value.asset.classID()); if (asset == null) { switch (Value.asset.classID()) { case UnityClassID.GameObject: if (((UPPtr)dest).Value == null) { GameObject gObj = (GameObject)Value.asset; if (gObj != null) { Transform trans = gObj.FindLinkedComponent(typeof(Transform)); trans = AnimatorRoot != null?Operations.FindFrame(trans.GetTransformPath(), AnimatorRoot) : null; if (trans != null) { asset = trans.m_GameObject.instance; break; } } Report.ReportLog("Warning! Losing PPtr<" + Value.asset.classID() + "> " + Name + " to " + name); break; } return; case UnityClassID.Light: GameObject gameObj = ((Light)Value.asset).m_GameObject.instance; if (gameObj != null) { Transform trans = gameObj.FindLinkedComponent(typeof(Transform)); trans = AnimatorRoot != null?Operations.FindFrame(trans.GetTransformPath(), AnimatorRoot) : null; if (trans != null) { asset = trans.m_GameObject.instance.FindLinkedComponent(UnityClassID.Light); } else { foreach (Component a in ((UPPtr)dest).file.Components) { if (a.classID() == UnityClassID.Light) { string n = a is NotLoaded ? ((NotLoaded)a).Name : AssetCabinet.ToString(a); if (n == name) { asset = a; Report.ReportLog("Warning! Unsharp search for PPtr<" + Value.asset.classID() + "> " + Name + " to " + name + " found PathID=" + a.pathID); break; } } } if (asset == null) { Report.ReportLog("Warning! Losing PPtr<" + Value.asset.classID() + "> " + Name + " to " + name); } } } break; case UnityClassID.MonoBehaviour: gameObj = ((MonoBehaviour)Value.asset).m_GameObject.instance; if (gameObj != null) { Transform trans = gameObj.FindLinkedComponent(typeof(Transform)); trans = AnimatorRoot != null?Operations.FindFrame(trans.GetTransformPath(), AnimatorRoot) : null; if (trans != null) { AssetCabinet.TypeDefinition srcDef = this.file.VersionNumber < AssetCabinet.VERSION_5_5_0 ? this.file.Types.Find ( delegate(AssetCabinet.TypeDefinition def) { return(def.typeId == (int)((MonoBehaviour)Value.asset).classID1); } ) : this.file.Types[(int)((MonoBehaviour)Value.asset).classID1]; bool found = false; var m_Component = trans.m_GameObject.instance.m_Component; for (int i = 0; i < m_Component.Count; i++) { if (m_Component[i].Value.asset != null && m_Component[i].Value.asset.classID() == UnityClassID.MonoBehaviour) { AssetCabinet.TypeDefinition destDef = ((UPPtr)dest).file.VersionNumber < AssetCabinet.VERSION_5_5_0 ? ((UPPtr)dest).file.Types.Find ( delegate(AssetCabinet.TypeDefinition def) { return(def.typeId == (int)((MonoBehaviour)m_Component[i].Value.asset).classID1); } ) : ((UPPtr)dest).file.Types[(int)((MonoBehaviour)m_Component[i].Value.asset).classID1]; if (AssetCabinet.CompareTypes(destDef, srcDef)) { asset = m_Component[i].Value.asset; found = true; break; } } } if (!found) { asset = ((MonoBehaviour)Value.asset).Clone(((UPPtr)dest).file); trans.m_GameObject.instance.AddLinkedComponent((LinkedByGameObject)asset); } } else { Report.ReportLog("Error! Reference to " + Value.asset.classID() + " " + name + " lost. Member " + Name); } } else { asset = ((MonoBehaviour)Value.asset).Clone(((UPPtr)dest).file); } break; case UnityClassID.MonoScript: asset = ((MonoScript)Value.asset).Clone(((UPPtr)dest).file); break; case UnityClassID.Sprite: asset = ((Sprite)Value.asset).Clone(((UPPtr)dest).file); break; case UnityClassID.Transform: asset = AnimatorRoot != null?Operations.FindFrame(((Transform)Value.asset).GetTransformPath(), AnimatorRoot) : null; if (asset == null) { Report.ReportLog("Warning! Reference to " + UnityClassID.Transform + " " + name + " lost. Member " + Name); } break; case UnityClassID.Material: asset = ((Material)Value.asset).Clone(((UPPtr)dest).file); break; case UnityClassID.MeshRenderer: case UnityClassID.SkinnedMeshRenderer: asset = AnimatorRoot != null?Operations.FindMesh(AnimatorRoot, name) : null; if (asset == null) { Report.ReportLog("Warning! Reference to " + Value.asset.classID() + " " + name + " lost. Member " + Name); } break; case UnityClassID.Texture2D: asset = ((Texture2D)Value.asset).Clone(((UPPtr)dest).file); break; case UnityClassID.Cubemap: asset = ((Cubemap)Value.asset).Clone(((UPPtr)dest).file); break; default: if (Value.asset is LoadedByTypeDefinition) { LoadedByTypeDefinition loadedByTypeDef = (LoadedByTypeDefinition)Value.asset; PPtr <GameObject> gameObjPtr = loadedByTypeDef.m_GameObject; if (gameObjPtr == null) { AssetCabinet file = ((UPPtr)dest).file; foreach (Component a in file.Components) { if (a.classID() == loadedByTypeDef.classID() && (a is NotLoaded ? ((NotLoaded)a).Name : AssetCabinet.ToString(a)) == loadedByTypeDef.m_Name) { asset = a; file = null; break; } } if (file != null) { asset = loadedByTypeDef.Clone(file); } } else { Transform srcTrans = gameObjPtr.instance.FindLinkedComponent(typeof(Transform)); Transform destTrans = AnimatorRoot != null?Operations.FindFrame(srcTrans.GetTransformPath(), AnimatorRoot) : null; if (destTrans != null) { asset = destTrans.m_GameObject.instance.FindLinkedComponent(loadedByTypeDef.classID()); } else { foreach (Component a in ((UPPtr)dest).file.Components) { if (a.classID() == Value.asset.classID()) { string n = a is NotLoaded ? ((NotLoaded)a).Name : AssetCabinet.ToString(a); if (n == name) { asset = a; Report.ReportLog("Warning! Unsharp search for PPtr<" + Value.asset.classID() + "> " + Name + " to " + name + " found PathID=" + a.pathID); break; } } } if (asset == null) { Report.ReportLog("Warning! Losing PPtr<" + Value.asset.classID() + "> " + Name + " to " + name); } } } } else { Report.ReportLog("Warning! Reference to " + Value.asset.classID() + " " + name + " unhandled. Member " + Name); } break; } } } ((UPPtr)dest).Value = new PPtr <Object>(asset); }
private void ConvertMeshRenderers(List <MeshRenderer> meshList, bool skins, bool morphs) { MeshList = new List <ImportedMesh>(meshList.Count); MaterialList = new List <ImportedMaterial>(meshList.Count); TextureList = new List <ImportedTexture>(meshList.Count); MorphList = new List <ImportedMorph>(meshList.Count); foreach (MeshRenderer meshR in meshList) { Mesh mesh = Operations.GetMesh(meshR); if (mesh == null) { Report.ReportLog("skipping " + meshR.m_GameObject.instance.m_Name + " - no mesh"); continue; } ImportedMesh iMesh = new ImportedMesh(); Transform meshTransform = meshR.m_GameObject.instance.FindLinkedComponent(UnityClassID.Transform); iMesh.Name = meshTransform.GetTransformPath(); iMesh.SubmeshList = new List <ImportedSubmesh>(mesh.m_SubMeshes.Count); using (BinaryReader vertReader = new BinaryReader(new MemoryStream(mesh.m_VertexData.m_DataSize)), indexReader = new BinaryReader(new MemoryStream(mesh.m_IndexBuffer))) { for (int i = 0; i < mesh.m_SubMeshes.Count; i++) { SubMesh submesh = mesh.m_SubMeshes[i]; ImportedSubmesh iSubmesh = new ImportedSubmesh(); iSubmesh.Index = i; iSubmesh.Visible = true; Material mat = meshR.m_Materials[i].instance; ConvertMaterial(mat); iSubmesh.Material = mat.m_Name; iSubmesh.VertexList = new List <ImportedVertex>((int)submesh.vertexCount); for (int str = 0; str < mesh.m_VertexData.m_Streams.Count; str++) { StreamInfo sInfo = mesh.m_VertexData.m_Streams[str]; if (sInfo.channelMask == 0) { continue; } for (int j = 0; j < mesh.m_SubMeshes[i].vertexCount; j++) { ImportedVertex iVertex; if (iSubmesh.VertexList.Count < mesh.m_SubMeshes[i].vertexCount) { iVertex = new ImportedVertex(); iSubmesh.VertexList.Add(iVertex); } else { iVertex = iSubmesh.VertexList[j]; } for (int chn = 0; chn < mesh.m_VertexData.m_Channels.Count; chn++) { ChannelInfo cInfo = mesh.m_VertexData.m_Channels[chn]; if ((sInfo.channelMask & (1 << chn)) == 0) { continue; } vertReader.BaseStream.Position = sInfo.offset + (submesh.firstVertex + j) * sInfo.stride + cInfo.offset; switch (chn) { case 0: iVertex.Position = new SlimDX.Vector3(-vertReader.ReadSingle(), vertReader.ReadSingle(), vertReader.ReadSingle()); break; case 1: iVertex.Normal = new SlimDX.Vector3(-vertReader.ReadSingle(), vertReader.ReadSingle(), vertReader.ReadSingle()); break; case 3: iVertex.UV = new float[2] { vertReader.ReadSingle(), vertReader.ReadSingle() }; break; case 5: iVertex.Tangent = new SlimDX.Vector4(-vertReader.ReadSingle(), vertReader.ReadSingle(), vertReader.ReadSingle(), -vertReader.ReadSingle()); break; } } if (skins && iVertex.BoneIndices == null && mesh.m_Skin.Count > 0) { BoneInfluence inf = mesh.m_Skin[(int)submesh.firstVertex + j]; iVertex.BoneIndices = new byte[inf.boneIndex.Length]; for (int k = 0; k < iVertex.BoneIndices.Length; k++) { iVertex.BoneIndices[k] = (byte)inf.boneIndex[k]; } iVertex.Weights = (float[])inf.weight.Clone(); } } } int numFaces = (int)(submesh.indexCount / 3); iSubmesh.FaceList = new List <ImportedFace>(numFaces); indexReader.BaseStream.Position = submesh.firstByte; for (int j = 0; j < numFaces; j++) { ImportedFace face = new ImportedFace(); face.VertexIndices = new int[3]; face.VertexIndices[0] = indexReader.ReadUInt16() - (int)submesh.firstVertex; face.VertexIndices[2] = indexReader.ReadUInt16() - (int)submesh.firstVertex; face.VertexIndices[1] = indexReader.ReadUInt16() - (int)submesh.firstVertex; iSubmesh.FaceList.Add(face); } iMesh.SubmeshList.Add(iSubmesh); } } if (skins && meshR is SkinnedMeshRenderer) { SkinnedMeshRenderer sMesh = (SkinnedMeshRenderer)meshR; if (sMesh.m_Bones.Count >= 256) { throw new Exception("Too many bones (" + mesh.m_BindPose.Count + ")"); } if (sMesh.m_Bones.Count != mesh.m_BindPose.Count || sMesh.m_Bones.Count != mesh.m_BoneNameHashes.Count) { throw new Exception("Mismatching number of bones bind pose=" + mesh.m_BindPose.Count + " hashes=" + mesh.m_BoneNameHashes.Count + " numBones=" + sMesh.m_Bones.Count); } iMesh.BoneList = new List <ImportedBone>(sMesh.m_Bones.Count); for (int i = 0; i < sMesh.m_Bones.Count; i++) { ImportedBone bone = new ImportedBone(); uint boneHash = mesh.m_BoneNameHashes[i]; bone.Name = avatar.FindBoneName(boneHash); Matrix m = Matrix.Transpose(mesh.m_BindPose[i]); Vector3 s, t; Quaternion q; m.Decompose(out s, out q, out t); t.X *= -1; Vector3 euler = FbxUtility.QuaternionToEuler(q); euler.Y *= -1; euler.Z *= -1; q = FbxUtility.EulerToQuaternion(euler); bone.Matrix = Matrix.Scaling(s) * Matrix.RotationQuaternion(q) * Matrix.Translation(t); iMesh.BoneList.Add(bone); } } if (morphs && mesh.m_Shapes.shapes.Count > 0) { ImportedMorph morph = new ImportedMorph(); morph.Name = iMesh.Name; morph.ClipName = Operations.BlendShapeName(mesh); morph.KeyframeList = new List <ImportedMorphKeyframe>(mesh.m_Shapes.shapes.Count); for (int i = 0; i < mesh.m_Shapes.shapes.Count; i++) { ImportedMorphKeyframe keyframe = new ImportedMorphKeyframe(); keyframe.Name = Operations.BlendShapeKeyframeName(mesh, i); keyframe.VertexList = new List <ImportedVertex>((int)mesh.m_Shapes.shapes[i].vertexCount); keyframe.MorphedVertexIndices = new List <ushort>((int)mesh.m_Shapes.shapes[i].vertexCount); int lastVertIndex = (int)(mesh.m_Shapes.shapes[i].firstVertex + mesh.m_Shapes.shapes[i].vertexCount); for (int j = (int)mesh.m_Shapes.shapes[i].firstVertex; j < lastVertIndex; j++) { BlendShapeVertex morphVert = mesh.m_Shapes.vertices[j]; ImportedVertex vert = GetSourceVertex(iMesh.SubmeshList, (int)morphVert.index); ImportedVertex destVert = new ImportedVertex(); Vector3 morphPos = morphVert.vertex; morphPos.X *= -1; destVert.Position = vert.Position + morphPos; Vector3 morphNormal = morphVert.normal; morphNormal.X *= -1; destVert.Normal = morphNormal; Vector4 morphTangent = new Vector4(morphVert.tangent, 0); morphTangent.X *= -1; destVert.Tangent = morphTangent; keyframe.VertexList.Add(destVert); keyframe.MorphedVertexIndices.Add((ushort)morphVert.index); } morph.KeyframeList.Add(keyframe); } MorphList.Add(morph); } MeshList.Add(iMesh); } }