public static MeshInfo[] MeshesInfoFromGameObject(GameObject gameObject)
        {
            // Associate all renderers and materials to an asset
            // An asset is composed of at least one Mesh
            // It will fail if one asset is rendered multiple times in the game object hierarchy
            Dictionary <string, MeshInfo> meshesInfo = new Dictionary <string, MeshInfo>();

            foreach (Renderer rendererCandidate in gameObject.GetComponentsInChildren <Renderer>())
            {
                Mesh foundMesh = null;
                if (rendererCandidate is MeshRenderer)
                {
                    // A MeshRenderer defines materials to apply on a Mesh
                    // It implies there is a MeshFilter on the same GameObject referencing the Mesh
                    MeshFilter meshFilter = rendererCandidate.GetComponent <MeshFilter>();
                    if (meshFilter != null)
                    {
                        foundMesh = meshFilter.sharedMesh;
                    }
                }
                if (rendererCandidate is SkinnedMeshRenderer)
                {
                    // A SkinnedMeshRenderer defines materials to apply on a Mesh and references it
                    foundMesh = ((SkinnedMeshRenderer)rendererCandidate).sharedMesh;
                }
                if (foundMesh == null)
                {
                    continue;
                }

                string     assetPath = AssetDatabase.GetAssetPath(foundMesh);
                Material[] materials = rendererCandidate.sharedMaterials.ToList()
                                       .Where(m => m != null && ShadersInfos.ContainsShader(m.shader))
                                       .ToArray();
                if (materials.Length == 0)
                {
                    continue;
                }

                if (!meshesInfo.ContainsKey(assetPath))
                {
                    meshesInfo.Add(assetPath, new MeshInfo {
                        AssetPath = assetPath
                    });
                }
                meshesInfo[assetPath].AddMaterials(materials);
                meshesInfo[assetPath].Identifier = gameObject.GetInstanceID();
            }
            return(meshesInfo.Values.ToArray());
        }
Пример #2
0
        private static JSONNode GetSpDataLinkToSend(MeshInfo meshInfo, string substancePainterProjectPath)
        {
            // Prepare data to send to SP
            string workspacePath = Path.GetDirectoryName(Application.dataPath);
            string meshPath      = Path.GetFullPath(Path.Combine(workspacePath, meshInfo.AssetPath).ToString());
            string exportPath    = Path.Combine(Path.Combine("Assets", "SP_Textures"), Path.GetFileNameWithoutExtension(meshInfo.AssetPath)).ToString();
            string meshUri       = new System.Uri(meshPath).AbsoluteUri;

            JSONClass materialsLink = new JSONClass();

            foreach (Material material in meshInfo.Materials)
            {
                ShaderInfos shaderInfos           = ShadersInfos.GetShaderInfos(material.shader);
                JSONClass   propertiesAssociation = new JSONClass();
                foreach (string propertyName in shaderInfos.PropertiesAssociation.Keys)
                {
                    propertiesAssociation.Add(propertyName, new JSONData(shaderInfos.PropertiesAssociation[propertyName]));
                }

                JSONClass materialLink = new JSONClass();
                materialLink.Add("assetPath", AssetDatabase.GetAssetPath(material));
                materialLink.Add("exportPreset", shaderInfos.ExportPreset);
                materialLink.Add("resourceShader", shaderInfos.ResourceShader);
                materialLink.Add("spToLiveLinkProperties", propertiesAssociation);

                // HACK: Sanitize the name the same way SP internally do it
                string sanitizedName = MaterialsManipulation.SanitizeMaterialName(material.name);
                materialsLink.Add(sanitizedName, materialLink);
            }

            JSONClass project = new JSONClass();

            project.Add("meshUrl", new JSONData(meshUri));
            project.Add("normal", new JSONData("OpenGL"));
            project.Add("template", new JSONData(""));
            project.Add("url", new JSONData(new System.Uri(substancePainterProjectPath).AbsoluteUri));

            JSONClass jsonData = new JSONClass();

            jsonData.Add("applicationName", new JSONData("Unity"));
            jsonData.Add("exportPath", new JSONData(exportPath));
            jsonData.Add("workspacePath", new JSONData(workspacePath));
            jsonData.Add("materials", materialsLink);
            jsonData.Add("project", project);
            jsonData.Add("linkIdentifier", new JSONData(meshInfo.Identifier));

            return(jsonData);
        }
Пример #3
0
        private static void SendMeshToSP(MeshInfo meshInfo)
        {
            if (!webSocket.IsAlive)
            {
                ConnectSocket();
            }
            if (!webSocket.IsAlive || !webSocket.Ping())
            {
                EditorUtility.DisplayDialog(
                    "Send to Substance Painter",
                    "Substance Painter is not detected.\n" +
                    "Please check if Substance Painter is correctly started and if the \"unity-link\" plugin is enabled.", "OK");
                return;
            }

            // Ensure compatibility
            foreach (Material material in meshInfo.Materials)
            {
                if (ShadersInfos.ContainsShader(material.shader))
                {
                    ShadersInfos.GetShaderInfos(material.shader).EnsureMaterialCompatibility(material);
                }
            }

            // Check if a project already exist
            string substancePainterProjectPath = GetSpProjectPath(meshInfo);

            if (File.Exists(substancePainterProjectPath))
            {
                // If the project exists, open it then reimport the mesh
                Debug.Log(string.Format("Reopening Substance Painter project located at {0}", substancePainterProjectPath));
                OpenSpProject(meshInfo, substancePainterProjectPath);
            }
            else
            {
                // If the project doesn't exist, create a new one and save it here
                Debug.Log(string.Format("Creating a new Substance Painter project located at {0}", substancePainterProjectPath));
                CreateSpProject(meshInfo, substancePainterProjectPath);
            }
        }
        public static bool SetMaterialParam(Material material, string property, JSONNode valueNode)
        {
            int propertyIndex;

            if (!CheckMaterialProperty(material, property, out propertyIndex))
            {
                return(false);
            }

            // Set the property value
            bool succeed = false;

            ShaderUtil.ShaderPropertyType type = ShaderUtil.GetPropertyType(material.shader, propertyIndex);
            switch (type)
            {
            case ShaderUtil.ShaderPropertyType.TexEnv: succeed = SetMaterialTexture(material, property, valueNode); break;

            default:
                Debug.LogWarning(string.Format("{0} property exchange not implemented", type.ToString()));
                break;
            }

            if (!succeed)
            {
                Debug.LogWarning(string.Format("Failed to load property '{0}' value of type {1} on material {2}: {3}", property, type.ToString(), AssetDatabase.GetAssetPath(material), valueNode.Value));
            }
            else
            {
                // Apply property changed post process
                ShaderInfos shaderInfos = ShadersInfos.GetShaderInfos(material.shader);
                if (shaderInfos.PostProcesses.ContainsKey(property))
                {
                    shaderInfos.PostProcesses[property](material, valueNode);
                }
            }
            return(succeed);
        }
        private static bool CheckMaterialProperty(Material material, string property, out int propertyIndex)
        {
            propertyIndex = -1;
            // Check parameter validity
            ShaderInfos shaderInfos = ShadersInfos.GetShaderInfos(material.shader);

            if (shaderInfos == null || !shaderInfos.PropertiesAssociation.ContainsValue(property))
            {
                Debug.LogWarning(string.Format("Unknown '{0}' parameter in shader {1}", property, material.shader.name));
                return(false);
            }
            int propertyCount = ShaderUtil.GetPropertyCount(material.shader);

            for (int i = 0; i < propertyCount; ++i)
            {
                if (ShaderUtil.GetPropertyName(material.shader, i).Equals(property))
                {
                    propertyIndex = i;
                    return(true);
                }
            }
            Debug.LogWarning(string.Format("Material '{0}' doesn't contain '{1}' property", AssetDatabase.GetAssetPath(material), property));
            return(false);
        }