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();
                }
            }
        }
    }
Example #2
0
    /*
     *
     * 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);
    }
Example #3
0
    /*
     *
     * 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);
    }