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); } }
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); } }
public void setMorphKeyframeNewName(ImportedMorphKeyframe keyframe, string newName) { AdditionalMorphKeyframeOptions options; if (this.MorphKeyframeOptions.TryGetValue(keyframe, out options)) { options.NewName = newName; return; } throw new Exception("Morph keyframe not found"); }
public void setMorphKeyframeEnabled(ImportedMorphKeyframe keyframe, bool enabled) { AdditionalMorphKeyframeOptions options; if (this.MorphKeyframeOptions.TryGetValue(keyframe, out options)) { options.Enabled = enabled; return; } throw new Exception("Morph keyframe not found"); }
public bool isMorphKeyframeEnabled(ImportedMorphKeyframe keyframe) { AdditionalMorphKeyframeOptions options; if (this.MorphKeyframeOptions.TryGetValue(keyframe, out options)) { return options.Enabled; } throw new Exception("Morph keyframe not found"); }
public string getMorphKeyframeNewName(ImportedMorphKeyframe keyframe) { AdditionalMorphKeyframeOptions options; if (this.MorphKeyframeOptions.TryGetValue(keyframe, out options)) { return options.NewName != null ? options.NewName : String.Empty; } throw new Exception("Morph keyframe not found"); }