public override void OnInspectorGUI() { DrawDefaultInspector(); if (GUILayout.Button("Setup Materials")) { (target as AMFMaterialHelper).SetupMaterial(); } AMFMaterialHelper amf = target as AMFMaterialHelper; showHax = EditorGUILayout.Foldout(showHax, "Helper Hacks"); if (showHax) { index = EditorGUILayout.IntField("Index:", index); AMFShaderInfo si = amf.shaderSettings[index]; EditorGUILayout.LabelField(si.sName + ":" + si.shaderType.ToString()); if (GUILayout.Button("Toggle Shader Type")) { if (si.shaderType == AMFShaderInfo.ShaderInfoType.Regular) { si.shaderType = AMFShaderInfo.ShaderInfoType.Terrain; } else { si.shaderType = AMFShaderInfo.ShaderInfoType.Regular; } si.SetupMaterial(amf.GetComponent <MeshRenderer>().sharedMaterials[index]); } if (si.shaderType == AMFShaderInfo.ShaderInfoType.Terrain) { if (GUILayout.Button("Compress Blendmap")) { si.CompressBlendMapChannels(); } } } }
/* * * 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); }
/* * * 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; 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 = new Mesh(); temp.name = perm.pName; List <Vector3> verts = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); List <int> badIndex = new List <int>(); int[] identity = new int[perm.vertices.Count]; //matr=matr.ConvertHandedness(); Matrix4x4 texMatrix = Matrix4x4.identity; for (int i = 0; i < perm.vertices.Count; i++) { Vector3 pos = perm.vertices[i].pos; identity[i] = i; //pos=perm.matrix4x4*pos; if (pos.IsBad()) { Debug.LogErrorFormat("Invalid vertex found: [{0}]" + perm.vertices[i].pos.ToString(), i); badIndex.Add(i); verts.Add(Vector3.zero); uvs.Add(Vector2.zero); } else { if (!float.IsNaN(perm.mult)) { Matrix4x4 flip = Matrix4x4.identity; flip.SetRow(0, new Vector4(-1, 0)); verts.Add(flip.MultiplyPoint3x4(pos)); } else { //verts.Add(Matrix4x4.identity.Convert3DSMatrixToUnity().MultiplyPoint3x4(pos)); Matrix4x4 flip = Matrix4x4.identity; flip.SetRow(0, new Vector4(-1, 0)); flip.SetRow(1, new Vector4(0, 0, 1)); flip.SetRow(2, new Vector4(0, -1)); verts.Add(flip.MultiplyPoint3x4(pos)); } uvs.Add(perm.vertices[i].tex); texMatrix = perm.vertices[i].tmat; } } temp.SetVertices(verts); temp.SetUVs(0, uvs); List <int> tris; int faceTotal = 0; temp.subMeshCount = perm.meshes.Count; /* temp.SetIndices(identity,MeshTopology.Points,0); */ // Debug.LogFormat("{0} adding submeshes",perm.pName); for (int s = 0; s < perm.meshes.Count; s++) { AMF_Mesh sinfo = perm.meshes[s]; faceTotal += sinfo.faceCount; tris = new List <int>(); // Debug.LogFormat("{0}:{1}-{2}",s,sinfo.startingFace,sinfo.faceCount); for (int f = 0; f < sinfo.faceCount; f++) { Vector3Int face = perm.faces[f + sinfo.startingFace]; if (badIndex.Contains(face.x) || badIndex.Contains(face.y) || badIndex.Contains(face.z)) { // Debug.LogWarning("Dumping face due to invalid vertex"); } else { tris.Add(face.x); tris.Add(face.y); tris.Add(face.z); } } //Debug.LogFormat("{0} Setting {1} triangles",s,tris.Count); temp.SetTriangles(tris, s); } if (perm.faces.Count != faceTotal) { Debug.LogErrorFormat("Faces mistmatch: {0}vs{1} {2}", perm.faces.Count, faceTotal, perm.pName); } //if(!float.IsNaN(perm.mult)){ temp.FlipNormals(); //} temp.RecalculateNormals(); if (GenerateLightmapUVs) { Unwrapping.GenerateSecondaryUVSet(temp); } 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 * importScale, 0)); scalerM.SetRow(1, new Vector4(0, 100f * importScale)); scalerM.SetRow(2, new Vector4(0, 0, 100f * importScale)); 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(importScale, importScale, importScale); } //GameObjectUtility.SetParentAndAlign(meshNode,riNode); //meshNode.transform.localToWorldMatrix=matr; MeshFilter mf = meshNode.AddComponent <MeshFilter>(); mf.sharedMesh = temp; MeshRenderer mr = meshNode.AddComponent <MeshRenderer>(); meshNode.transform.parent = riNode.transform; if (GenerateMeshCollidersOnClusters && amf.regionInfo[ri].name.Equals("Clusters")) { MeshCollider mc = meshNode.AddComponent <MeshCollider>(); mc.sharedMesh = mf.sharedMesh; } 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++; } } return(meshCache); }