/* * * Convert Meshes */ public Dictionary <long, Mesh> ConvertMeshes(AMF amf, Dictionary <string, Material> mats, Dictionary <string, AMFShaderInfo> matHelpers, GameObject root) { //List<Mesh> meshList = new List<Mesh>(); Dictionary <long, Mesh> meshCache = new Dictionary <long, Mesh>(); float meshComplete = 0; float totalMeshCount = 0; List <GameObject> meshNodes = new List <GameObject>(); List <Transform> nodes = null; if (CreateSkinnedMeshes) { nodes = CreateRigging(amf); nodes[0].parent = root.transform; Animator anim = root.AddComponent <Animator>(); //Transform rigRoot=root.GetComponentInChildren<SkinnedMeshRenderer>().rootBone; if (copyAvatar) { //ctx.AddObjectToAsset(m_LastHumanDescriptionAvatarSource.name,m_LastHumanDescriptionAvatarSource); anim.avatar = m_LastHumanDescriptionAvatarSource; } else { //EditorUtility.DisplayProgressBar("Parsing "+ctx.assetPath,"Creating Avatar",(5f/5f)); List <string> reports = new List <string>(); HumanDescription hd = new HumanDescription(); AvatarSetupTool.SkeletonBone[] skeletonBones; bool hasTranslationDOF; reports = AvatarSetupTool.SetupHumanSkeleton(nodes[0].parent.gameObject, ref hd.human, out skeletonBones, out hasTranslationDOF); hd.hasTranslationDoF = hasTranslationDOF; SkeletonBone[] sb = new SkeletonBone[skeletonBones.Length + 1]; Array.Copy(Array.ConvertAll(skeletonBones, (p => (SkeletonBone)p)), sb, sb.Length - 1); sb[sb.Length - 1].name = nodes[0].parent.name; sb[sb.Length - 1].position = nodes[0].parent.localPosition; sb[sb.Length - 1].rotation = nodes[0].parent.localRotation; sb[sb.Length - 1].scale = nodes[0].parent.localScale; hd.skeleton = sb; Avatar a; if (rigType == RigType.Humanoid) { a = AvatarBuilder.BuildHumanAvatar(nodes[0].parent.gameObject, hd); } else { a = AvatarBuilder.BuildGenericAvatar(nodes[0].parent.gameObject, nodes[0].parent.name); } a.name = root.name + "Avatar"; //ctx.AddObjectToAsset(a.name,a); anim.avatar = a; } } foreach (AMF_RegionInfo ri in amf.regionInfo) { totalMeshCount += ri.permutations.Count; } for (int ri = 0; ri < amf.regionInfo.Count; ri++) { GameObject riNode = new GameObject(amf.regionInfo[ri].name); GameObjectUtility.SetParentAndAlign(riNode, root); foreach (AMF_Permutations perm in amf.regionInfo[ri].permutations) { EditorUtility.DisplayProgressBar("Creating Meshes", perm.pName, (meshComplete / totalMeshCount)); Mesh temp; if (createDuplicateInstances || !meshCache.ContainsKey(perm.vAddress)) { temp = ConvertInstanceToMesh(perm); //we have to flip the normals due to the coordinate system translation temp.FlipNormals(); temp.RecalculateNormals(); if (GenerateLightmapUVs) { EditorUtility.DisplayProgressBar("Generating Lightmap UVs", perm.pName, (meshComplete / totalMeshCount)); uvSettings.angleError = angleError; uvSettings.areaError = areaError; uvSettings.hardAngle = hardAngle; uvSettings.packMargin = packMargin; Unwrapping.GenerateSecondaryUVSet(temp, uvSettings); } meshCache.Add(perm.vAddress, temp); } else { temp = meshCache[perm.vAddress]; } GameObject meshNode = new GameObject(perm.pName); Matrix4x4 matr = Matrix4x4.identity; if (!float.IsNaN(perm.mult)) { Matrix4x4 scalerM = new Matrix4x4(); scalerM.SetRow(0, new Vector4(100f * m_FileScaleFactor, 0)); scalerM.SetRow(1, new Vector4(0, 100f * m_FileScaleFactor)); scalerM.SetRow(2, new Vector4(0, 0, 100f * m_FileScaleFactor)); scalerM.SetRow(3, new Vector4(0, 0, 0, 1)); matr.SetRow(0, new Vector4(perm.mult, 0)); matr.SetRow(1, new Vector4(0, perm.mult)); matr.SetRow(2, new Vector4(0, 0, perm.mult)); matr.SetRow(3, new Vector4(0, 0, 0, 1)); matr *= perm.matrix4x4; matr *= scalerM; Matrix4x4 unityMatr = matr.Convert3DSMatrixToUnity(); meshNode.transform.localScale = unityMatr.ExtractScale(); meshNode.transform.localRotation = unityMatr.GetRotation(); meshNode.transform.localPosition = unityMatr.ExtractPosition(); } else { meshNode.transform.localScale = new Vector3(m_FileScaleFactor, m_FileScaleFactor, m_FileScaleFactor); } //GameObjectUtility.SetParentAndAlign(meshNode,riNode); //meshNode.transform.localToWorldMatrix=matr; Renderer mr; if (temp.boneWeights.Length > 0 && CreateSkinnedMeshes) { mr = meshNode.AddComponent <SkinnedMeshRenderer>(); meshNode.transform.localRotation = Quaternion.Euler(0, 90, 0); Matrix4x4[] bindPoses = new Matrix4x4[nodes.Count]; for (int m = 0; m < bindPoses.Length; m++) { bindPoses[m] = nodes[m].worldToLocalMatrix * meshNode.transform.localToWorldMatrix; } temp.bindposes = bindPoses; ((SkinnedMeshRenderer)mr).sharedMesh = temp; ((SkinnedMeshRenderer)mr).bones = nodes.ToArray(); ((SkinnedMeshRenderer)mr).rootBone = nodes[0]; } else { MeshFilter mf = meshNode.AddComponent <MeshFilter>(); mf.sharedMesh = temp; mr = meshNode.AddComponent <MeshRenderer>(); if (RecenterPivots && !splitSubmeshes) { //for safety, lets guard this against splitting submeshes. mf.RecenterPivot(); } } meshNode.transform.parent = riNode.transform; if (GenerateMeshCollidersOnClusters && amf.regionInfo[ri].name.Equals("Clusters")) { MeshCollider mc = meshNode.AddComponent <MeshCollider>(); mc.sharedMesh = temp; } Material[] materials = new Material[temp.subMeshCount]; List <AMFShaderInfo> si = new List <AMFShaderInfo>(); for (int i = 0; i < materials.Length; i++) { materials[i] = mats[amf.shaderInfos[perm.meshes[i].shaderIndex].sName]; si.Add(matHelpers[amf.shaderInfos[perm.meshes[i].shaderIndex].sName]); //si[i].SaveData(amf.shaderInfos[perm.meshes[i].shaderIndex]); } mr.sharedMaterials = materials; AMFMaterialHelper mh = meshNode.AddComponent <AMFMaterialHelper>(); mh.shaderSettings = si; //mh.SaveData(amf.shaderInfos[perm.meshes[0].shaderIndex]); //Debug.LogFormat("Transform: Pos:{0} Rot:{1} Scale:{2}",perm.matrix4x4.ExtractPosition(),perm.matrix4x4.ExtractRotation(),perm.matrix4x4.ExtractScale()); meshComplete++; meshNodes.Add(meshNode); } } //This is annoying to do this here, but we have to wait until after the mesh cache is fully populated before we start splitting submeshes out. if (splitSubmeshes) { meshCache.Clear(); long fakeKey = 0; foreach (GameObject go in meshNodes) { MeshFilter mf = go.GetComponent <MeshFilter>(); if (mf != null && mf.sharedMesh.subMeshCount > 1) { Renderer r = go.GetComponent <MeshRenderer>(); for (int i = 0; i < mf.sharedMesh.subMeshCount; i++) { int matIndex = Mathf.Min(i, r.sharedMaterials.Length); GameObject tempGo = new GameObject(go.name + "_" + r.sharedMaterials[matIndex].name); MeshFilter tempMF = tempGo.AddComponent <MeshFilter>(); tempMF.sharedMesh = mf.sharedMesh.ExtractSubmesh(i); tempGo.AddComponent <MeshRenderer>().sharedMaterial = r.sharedMaterials[matIndex]; GameObjectUtility.SetParentAndAlign(tempGo, go); if (RecenterPivots) { tempMF.RecenterPivot(); } meshCache.Add(fakeKey, tempGo.GetComponent <MeshFilter>().sharedMesh); fakeKey++; } DestroyImmediate(mf); DestroyImmediate(r); } else { if (RecenterPivots) { go.GetComponent <MeshFilter>().RecenterPivot(); } meshCache.Add(fakeKey, go.GetComponent <MeshFilter>().sharedMesh); fakeKey++; } } } return(meshCache); }