Esempio n. 1
0
        void PrintAttributes(MFnDependencyNode dependencyNode, int logRank)
        {
            // prints
            RaiseVerbose("Attributes", logRank);
            for (uint i = 0; i < dependencyNode.attributeCount; i++)
            {
                MObject attribute = dependencyNode.attribute(i);

                if (attribute.hasFn(MFn.Type.kAttribute))
                {
                    MFnAttribute mFnAttribute = new MFnAttribute(attribute);
                    RaiseVerbose("name=" + mFnAttribute.name + "    apiType=" + attribute.apiType, logRank + 1);
                }
            }
        }
Esempio n. 2
0
        private void dumpInfo(MObject fileNode, MFnDependencyNode nodeFn, MObjectArray nodePath)
        {
            MObject           fileAttr   = nodeFn.attribute("fileTextureName");
            MPlug             plugToFile = new MPlug(fileNode, fileAttr);
            MFnDependencyNode dgFn       = new MFnDependencyNode();

            MGlobal.displayInfo("Name:    " + nodeFn.name);

            MObject fnameValue = new MObject();

            try
            {
                plugToFile.getValue(fnameValue);
            }
            catch (Exception)
            {
                MGlobal.displayInfo("error getting value from plug");
                return;
            }

            MFnStringData stringFn = new MFnStringData(fnameValue);

            MGlobal.displayInfo("Texture: " + stringFn.stringProperty);

            string path = "Path:    ";

            for (int i = (int)nodePath.length - 1; i >= 0; i--)
            {
                MObject currentNode = nodePath[i];
                dgFn.setObject(currentNode);

                path += dgFn.name + "(" + dgFn.typeName + ")";
                if (i > 0)
                {
                    path += " -> ";
                }
            }
            MGlobal.displayInfo(path);
        }
Esempio n. 3
0
        void Print(MFnDependencyNode dependencyNode, int logRank, string title)
        {
            // prints
            RaiseVerbose(title, logRank);
            RaiseVerbose("Attributes", logRank + 1);
            for (uint i = 0; i < dependencyNode.attributeCount; i++)
            {
                MObject attribute = dependencyNode.attribute(i);

                if (attribute.hasFn(MFn.Type.kAttribute))
                {
                    MFnAttribute mFnAttribute = new MFnAttribute(attribute);
                    RaiseVerbose("name=" + mFnAttribute.name, logRank + 2);
                }
            }
            RaiseVerbose("Connections", logRank + 1);
            MPlugArray connections = new MPlugArray();

            try {
                dependencyNode.getConnections(connections);
                RaiseVerbose("connections.Count=" + connections.Count, logRank + 2);
                foreach (MPlug connection in connections)
                {
                    MObject source = connection.source.node;
                    if (source != null && source.hasFn(MFn.Type.kDependencyNode))
                    {
                        MFnDependencyNode node = new MFnDependencyNode(source);
                        RaiseVerbose("name=" + connection.name + "    source=" + node.name, logRank + 2);
                    }
                    else
                    {
                        RaiseVerbose("name=" + connection.name, logRank + 2);
                    }
                }
            }
            catch (Exception e)
            {
            }
        }
Esempio n. 4
0
        private void ExportMaterial(MFnDependencyNode materialDependencyNode, BabylonScene babylonScene, bool fullPBR)
        {
            MObject materialObject = materialDependencyNode.objectProperty;
            var     name           = materialDependencyNode.name;
            var     id             = materialDependencyNode.uuid().asString();

            RaiseMessage(name, 1);
            RaiseMessage(materialObject.apiType.ToString(), 1);

            RaiseVerbose("materialObject.hasFn(MFn.Type.kBlinn)=" + materialObject.hasFn(MFn.Type.kBlinn), 2);
            RaiseVerbose("materialObject.hasFn(MFn.Type.kPhong)=" + materialObject.hasFn(MFn.Type.kPhong), 2);
            RaiseVerbose("materialObject.hasFn(MFn.Type.kPhongExplorer)=" + materialObject.hasFn(MFn.Type.kPhongExplorer), 2);

            Print(materialDependencyNode, 2, "Print ExportMaterial materialDependencyNode");

            // Retreive Babylon Material dependency node
            MFnDependencyNode babylonAttributesDependencyNode = getBabylonMaterialNode(materialDependencyNode);

            // Standard material
            if (materialObject.hasFn(MFn.Type.kLambert))
            {
                if (materialObject.hasFn(MFn.Type.kBlinn))
                {
                    RaiseMessage("Blinn shader", 2);
                }
                else if (materialObject.hasFn(MFn.Type.kPhong))
                {
                    RaiseMessage("Phong shader", 2);
                }
                else if (materialObject.hasFn(MFn.Type.kPhongExplorer))
                {
                    RaiseMessage("Phong E shader", 2);
                }
                else
                {
                    RaiseMessage("Lambert shader", 2);
                }

                var lambertShader = new MFnLambertShader(materialObject);

                RaiseVerbose("typeId=" + lambertShader.typeId, 2);
                RaiseVerbose("typeName=" + lambertShader.typeName, 2);
                RaiseVerbose("color=" + lambertShader.color.toString(), 2);
                RaiseVerbose("transparency=" + lambertShader.transparency.toString(), 2);
                RaiseVerbose("ambientColor=" + lambertShader.ambientColor.toString(), 2);
                RaiseVerbose("incandescence=" + lambertShader.incandescence.toString(), 2);
                RaiseVerbose("diffuseCoeff=" + lambertShader.diffuseCoeff, 2);
                RaiseVerbose("translucenceCoeff=" + lambertShader.translucenceCoeff, 2);

                BabylonStandardMaterial babylonMaterial = new BabylonStandardMaterial(id)
                {
                    name    = name,
                    diffuse = lambertShader.color.toArrayRGB()
                };

                // User custom attributes
                babylonMaterial.metadata = ExportCustomAttributeFromMaterial(babylonMaterial);

                bool isTransparencyModeFromBabylonMaterialNode = false;
                if (babylonAttributesDependencyNode != null)
                {
                    // Transparency mode
                    if (babylonAttributesDependencyNode.hasAttribute("babylonTransparencyMode"))
                    {
                        int transparencyMode = babylonAttributesDependencyNode.findPlug("babylonTransparencyMode").asInt();
                        babylonMaterial.transparencyMode = transparencyMode;

                        isTransparencyModeFromBabylonMaterialNode = true;
                    }
                }

                // Maya ambient <=> babylon emissive
                babylonMaterial.emissive = lambertShader.ambientColor.toArrayRGB();
                babylonMaterial.linkEmissiveWithDiffuse = true; // Incandescence (or Illumination) is not exported

                if (isTransparencyModeFromBabylonMaterialNode == false || babylonMaterial.transparencyMode != 0)
                {
                    // If transparency is not a shade of grey (shade of grey <=> R=G=B)
                    if (lambertShader.transparency[0] != lambertShader.transparency[1] ||
                        lambertShader.transparency[0] != lambertShader.transparency[2])
                    {
                        RaiseWarning("Transparency color is not a shade of grey. Only it's R channel is used.", 2);
                    }
                    // Convert transparency to opacity
                    babylonMaterial.alpha = 1.0f - lambertShader.transparency[0];
                }

                // Specular power
                if (materialObject.hasFn(MFn.Type.kReflect))
                {
                    var reflectShader = new MFnReflectShader(materialObject);

                    RaiseVerbose("specularColor=" + reflectShader.specularColor.toString(), 2);
                    RaiseVerbose("reflectivity=" + reflectShader.reflectivity, 2);
                    RaiseVerbose("reflectedColor=" + reflectShader.reflectedColor.toString(), 2);

                    babylonMaterial.specular = reflectShader.specularColor.toArrayRGB();

                    if (materialObject.hasFn(MFn.Type.kBlinn))
                    {
                        MFnBlinnShader blinnShader = new MFnBlinnShader(materialObject);
                        babylonMaterial.specularPower = (1.0f - blinnShader.eccentricity) * 256;
                    }
                    else if (materialObject.hasFn(MFn.Type.kPhong))
                    {
                        MFnPhongShader phongShader = new MFnPhongShader(materialObject);

                        float glossiness = (float)Math.Log(phongShader.cosPower, 2) * 10;
                        babylonMaterial.specularPower = glossiness / 100 * 256;
                    }
                    else if (materialObject.hasFn(MFn.Type.kPhongExplorer))
                    {
                        MFnPhongEShader phongEShader = new MFnPhongEShader(materialObject);
                        // No use of phongE.whiteness and phongE.highlightSize
                        babylonMaterial.specularPower = (1.0f - phongEShader.roughness) * 256;
                    }
                    else
                    {
                        RaiseWarning("Unknown reflect shader type: " + reflectShader.typeName + ". Specular power is default 64. Consider using a Blinn or Phong shader instead.", 2);
                    }
                }

                // TODO
                //babylonMaterial.wireframe = stdMat.Wire;

                // --- Textures ---

                babylonMaterial.diffuseTexture  = ExportTexture(materialDependencyNode, "color", babylonScene);
                babylonMaterial.emissiveTexture = ExportTexture(materialDependencyNode, "ambientColor", babylonScene); // Maya ambient <=> babylon emissive
                babylonMaterial.bumpTexture     = ExportTexture(materialDependencyNode, "normalCamera", babylonScene);
                if (isTransparencyModeFromBabylonMaterialNode == false || babylonMaterial.transparencyMode != 0)
                {
                    babylonMaterial.opacityTexture = ExportTexture(materialDependencyNode, "transparency", babylonScene, false, true);
                }
                if (materialObject.hasFn(MFn.Type.kReflect))
                {
                    babylonMaterial.specularTexture   = ExportTexture(materialDependencyNode, "specularColor", babylonScene);
                    babylonMaterial.reflectionTexture = ExportTexture(materialDependencyNode, "reflectedColor", babylonScene, true, false, true);
                }

                if (isTransparencyModeFromBabylonMaterialNode == false && (babylonMaterial.alpha != 1.0f || (babylonMaterial.diffuseTexture != null && babylonMaterial.diffuseTexture.hasAlpha) || babylonMaterial.opacityTexture != null))
                {
                    babylonMaterial.transparencyMode = (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHABLEND;
                }

                // Constraints
                if (babylonMaterial.diffuseTexture != null)
                {
                    babylonMaterial.diffuse = new[] { 1.0f, 1.0f, 1.0f };
                }

                if (babylonMaterial.emissiveTexture != null)
                {
                    babylonMaterial.emissive = new float[] { 0, 0, 0 };
                }

                if (babylonMaterial.transparencyMode == (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHATEST)
                {
                    // Set the alphaCutOff value explicitely to avoid different interpretations on different engines
                    // Use the glTF default value rather than the babylon one
                    babylonMaterial.alphaCutOff = 0.5f;
                }

                if (babylonAttributesDependencyNode == null)
                {
                    // Create Babylon Material dependency node
                    babylonStandardMaterialNode.Create(materialDependencyNode);

                    // Retreive Babylon Material dependency node
                    babylonAttributesDependencyNode = getBabylonMaterialNode(materialDependencyNode);
                }

                if (babylonAttributesDependencyNode != null)
                {
                    // Ensure all attributes are setup
                    babylonStandardMaterialNode.Init(babylonAttributesDependencyNode, babylonMaterial);

                    RaiseVerbose("Babylon Attributes of " + babylonAttributesDependencyNode.name, 2);

                    // Common attributes
                    ExportCommonBabylonAttributes(babylonAttributesDependencyNode, babylonMaterial);

                    // Special treatment for Unlit
                    if (babylonMaterial.isUnlit)
                    {
                        if ((babylonMaterial.emissive != null && (babylonMaterial.emissive[0] != 0 || babylonMaterial.emissive[1] != 0 || babylonMaterial.emissive[2] != 0)) ||
                            (babylonMaterial.emissiveTexture != null) ||
                            (babylonMaterial.emissiveFresnelParameters != null))
                        {
                            RaiseWarning("Material is unlit. Emission is discarded and replaced by diffuse.", 2);
                        }
                        // Copy diffuse to emissive
                        babylonMaterial.emissive                  = babylonMaterial.diffuse;
                        babylonMaterial.emissiveTexture           = babylonMaterial.diffuseTexture;
                        babylonMaterial.emissiveFresnelParameters = babylonMaterial.diffuseFresnelParameters;

                        babylonMaterial.disableLighting         = true;
                        babylonMaterial.linkEmissiveWithDiffuse = false;
                    }
                    // Special treatment for "Alpha test" transparency mode
                    if (babylonMaterial.transparencyMode == (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHATEST &&
                        ((babylonMaterial.diffuseTexture != null && babylonMaterial.opacityTexture != null && babylonMaterial.diffuseTexture.originalPath != babylonMaterial.opacityTexture.originalPath) ||
                         (babylonMaterial.diffuseTexture == null && babylonMaterial.opacityTexture != null)))
                    {
                        // Base color and alpha files need to be merged into a single file
                        Color             defaultColor = Color.FromArgb((int)(babylonMaterial.diffuse[0] * 255), (int)(babylonMaterial.diffuse[1] * 255), (int)(babylonMaterial.diffuse[2] * 255));
                        MFnDependencyNode baseColorTextureDependencyNode = getTextureDependencyNode(materialDependencyNode, "color");
                        MFnDependencyNode opacityTextureDependencyNode   = getTextureDependencyNode(materialDependencyNode, "transparency");
                        babylonMaterial.diffuseTexture = ExportBaseColorAlphaTexture(baseColorTextureDependencyNode, opacityTextureDependencyNode, babylonScene, name, defaultColor, babylonMaterial.alpha);
                        babylonMaterial.opacityTexture = null;
                        babylonMaterial.alpha          = 1.0f;
                    }
                }

                babylonScene.MaterialsList.Add(babylonMaterial);
            }
            // Stingray PBS material
            else if (isStingrayPBSMaterial(materialDependencyNode))
            {
                RaiseMessage("Stingray shader", 2);

                var babylonMaterial = new BabylonPBRMetallicRoughnessMaterial(id)
                {
                    name = name
                };

                // --- Global ---

                // Color3
                babylonMaterial.baseColor = materialDependencyNode.findPlug("base_color").asFloatArray();

                // Alpha
                string opacityAttributeName = "opacity";
                if (materialDependencyNode.hasAttribute(opacityAttributeName))
                {
                    float opacityAttributeValue = materialDependencyNode.findPlug(opacityAttributeName).asFloat();
                    babylonMaterial.alpha = 1.0f - opacityAttributeValue;
                }

                // Metallic & roughness
                babylonMaterial.metallic  = materialDependencyNode.findPlug("metallic").asFloat();
                babylonMaterial.roughness = materialDependencyNode.findPlug("roughness").asFloat();

                // Emissive
                float emissiveIntensity = materialDependencyNode.findPlug("emissive_intensity").asFloat();
                // Factor emissive color with emissive intensity
                emissiveIntensity        = Tools.Clamp(emissiveIntensity, 0f, 1f);
                babylonMaterial.emissive = materialDependencyNode.findPlug("emissive").asFloatArray().Multiply(emissiveIntensity);

                // --- Textures ---

                // Base color & alpha
                bool   useColorMap   = materialDependencyNode.findPlug("use_color_map").asBool();
                bool   useOpacityMap = false;
                string useOpacityMapAttributeName = "use_opacity_map";
                if (materialDependencyNode.hasAttribute(useOpacityMapAttributeName))
                {
                    useOpacityMap = materialDependencyNode.findPlug(useOpacityMapAttributeName).asBool();
                }
                if (materialDependencyNode.hasAttribute("mask_threshold")) // Preset "Masked"
                {
                    if (useColorMap && useOpacityMap)
                    {
                        // Texture is assumed to be already merged
                        babylonMaterial.baseTexture = ExportTexture(materialDependencyNode, "TEX_color_map", babylonScene, false, true);
                    }
                    else if (useColorMap || useOpacityMap)
                    {
                        // Merge Diffuse and Mask
                        Color defaultColor = Color.FromArgb((int)(babylonMaterial.baseColor[0] * 255), (int)(babylonMaterial.baseColor[1] * 255), (int)(babylonMaterial.baseColor[2] * 255));
                        // In Maya, a Masked StingrayPBS material without opacity or mask textures is counted as being fully transparent
                        // Such material is visible only when the mask threshold is set to 0
                        float defaultOpacity = 0;

                        // Either use the color map
                        MFnDependencyNode baseColorTextureDependencyNode = null;
                        if (useColorMap)
                        {
                            baseColorTextureDependencyNode = getTextureDependencyNode(materialDependencyNode, "TEX_color_map");
                        }
                        // Or the opacity map
                        MFnDependencyNode opacityTextureDependencyNode = null;
                        if (useOpacityMap)
                        {
                            opacityTextureDependencyNode = getTextureDependencyNode(materialDependencyNode, "TEX_color_map");
                        }

                        // Merge default value and texture
                        babylonMaterial.baseTexture = ExportBaseColorAlphaTexture(baseColorTextureDependencyNode, opacityTextureDependencyNode, babylonScene, babylonMaterial.name, defaultColor, defaultOpacity);
                    }
                    else
                    {
                        // In Maya, a Masked StingrayPBS material without opacity or mask textures is counted as being fully transparent
                        // Such material is visible only when the mask threshold is set to 0
                        babylonMaterial.alpha = 0;
                    }
                }
                else
                {
                    if (useColorMap || useOpacityMap)
                    {
                        // Force non use map to default value
                        // Ex: if useOpacityMap == false, force alpha = 255 for all pixels.
                        babylonMaterial.baseTexture = ExportTexture(materialDependencyNode, "TEX_color_map", babylonScene, false, useOpacityMap);
                    }
                }

                if (babylonMaterial.transparencyMode == (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHATEST)
                {
                    // Set the alphaCutOff value explicitely to avoid different interpretations on different engines
                    // Use the glTF default value rather than the babylon one
                    babylonMaterial.alphaCutOff = 0.5f;
                }

                // Alpha cuttoff
                if (materialDependencyNode.hasAttribute("mask_threshold")) // Preset "Masked"
                {
                    babylonMaterial.alphaCutOff = materialDependencyNode.findPlug("mask_threshold").asFloat();
                }

                // Metallic, roughness, ambient occlusion
                bool   useMetallicMap        = materialDependencyNode.findPlug("use_metallic_map").asBool();
                bool   useRoughnessMap       = materialDependencyNode.findPlug("use_roughness_map").asBool();
                string useAOMapAttributeName = "use_ao_map";
                bool   useAOMap = materialDependencyNode.hasAttribute(useAOMapAttributeName) && materialDependencyNode.findPlug(useAOMapAttributeName).asBool();

                MFnDependencyNode metallicTextureDependencyNode         = useMetallicMap ? getTextureDependencyNode(materialDependencyNode, "TEX_metallic_map") : null;
                MFnDependencyNode roughnessTextureDependencyNode        = useRoughnessMap ? getTextureDependencyNode(materialDependencyNode, "TEX_roughness_map") : null;
                MFnDependencyNode ambientOcclusionTextureDependencyNode = useAOMap ? getTextureDependencyNode(materialDependencyNode, "TEX_ao_map") : null;

                // Check if MR or ORM textures are already merged
                bool areTexturesAlreadyMerged = false;
                if (metallicTextureDependencyNode != null && roughnessTextureDependencyNode != null)
                {
                    string sourcePathMetallic  = getSourcePathFromFileTexture(metallicTextureDependencyNode);
                    string sourcePathRoughness = getSourcePathFromFileTexture(roughnessTextureDependencyNode);

                    if (sourcePathMetallic == sourcePathRoughness)
                    {
                        if (ambientOcclusionTextureDependencyNode != null)
                        {
                            string sourcePathAmbientOcclusion = getSourcePathFromFileTexture(ambientOcclusionTextureDependencyNode);
                            if (sourcePathMetallic == sourcePathAmbientOcclusion)
                            {
                                // Metallic, roughness and ambient occlusion are already merged
                                RaiseVerbose("Metallic, roughness and ambient occlusion are already merged", 2);
                                BabylonTexture ormTexture = ExportTexture(metallicTextureDependencyNode, babylonScene);
                                babylonMaterial.metallicRoughnessTexture = ormTexture;
                                babylonMaterial.occlusionTexture         = ormTexture;
                                areTexturesAlreadyMerged = true;
                            }
                        }
                        else
                        {
                            // Metallic and roughness are already merged
                            RaiseVerbose("Metallic and roughness are already merged", 2);
                            BabylonTexture ormTexture = ExportTexture(metallicTextureDependencyNode, babylonScene);
                            babylonMaterial.metallicRoughnessTexture = ormTexture;
                            areTexturesAlreadyMerged = true;
                        }
                    }
                }
                if (areTexturesAlreadyMerged == false)
                {
                    if (metallicTextureDependencyNode != null || roughnessTextureDependencyNode != null)
                    {
                        // Merge metallic, roughness and ambient occlusion
                        RaiseVerbose("Merge metallic, roughness and ambient occlusion", 2);
                        BabylonTexture ormTexture = ExportORMTexture(babylonScene, metallicTextureDependencyNode, roughnessTextureDependencyNode, ambientOcclusionTextureDependencyNode, babylonMaterial.metallic, babylonMaterial.roughness);
                        babylonMaterial.metallicRoughnessTexture = ormTexture;

                        if (ambientOcclusionTextureDependencyNode != null)
                        {
                            babylonMaterial.occlusionTexture = ormTexture;
                        }
                    }
                    else if (ambientOcclusionTextureDependencyNode != null)
                    {
                        // Simply export occlusion texture
                        RaiseVerbose("Simply export occlusion texture", 2);
                        babylonMaterial.occlusionTexture = ExportTexture(ambientOcclusionTextureDependencyNode, babylonScene);
                    }
                }

                // Normal
                if (materialDependencyNode.findPlug("use_normal_map").asBool())
                {
                    babylonMaterial.normalTexture = ExportTexture(materialDependencyNode, "TEX_normal_map", babylonScene);
                }

                // Emissive
                bool useEmissiveMap = materialDependencyNode.findPlug("use_emissive_map").asBool();
                if (useEmissiveMap)
                {
                    babylonMaterial.emissiveTexture = ExportTexture(materialDependencyNode, "TEX_emissive_map", babylonScene, false, false, false, emissiveIntensity);
                }

                // Constraints
                if (useColorMap)
                {
                    babylonMaterial.baseColor = new[] { 1.0f, 1.0f, 1.0f };
                }
                if (useOpacityMap)
                {
                    babylonMaterial.alpha = 1.0f;
                }
                if (babylonMaterial.alpha != 1.0f || (babylonMaterial.baseTexture != null && babylonMaterial.baseTexture.hasAlpha))
                {
                    if (materialDependencyNode.hasAttribute("mask_threshold"))
                    {
                        babylonMaterial.transparencyMode = (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHATEST;
                    }
                    else
                    {
                        babylonMaterial.transparencyMode = (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHABLEND;
                    }
                }
                if (useMetallicMap)
                {
                    babylonMaterial.metallic = 1.0f;
                }
                if (useRoughnessMap)
                {
                    babylonMaterial.roughness = 1.0f;
                }
                if (useEmissiveMap)
                {
                    babylonMaterial.emissive = new[] { 1.0f, 1.0f, 1.0f };
                }

                // User custom attributes
                babylonMaterial.metadata = ExportCustomAttributeFromMaterial(babylonMaterial);

                if (babylonAttributesDependencyNode == null)
                {
                    // Create Babylon Material dependency node
                    babylonStingrayPBSMaterialNode.Create(materialDependencyNode);

                    // Retreive Babylon Material dependency node
                    babylonAttributesDependencyNode = getBabylonMaterialNode(materialDependencyNode);
                }

                if (babylonAttributesDependencyNode != null)
                {
                    // Ensure all attributes are setup
                    babylonStingrayPBSMaterialNode.Init(babylonAttributesDependencyNode, babylonMaterial);

                    RaiseVerbose("Babylon Attributes of " + babylonAttributesDependencyNode.name, 2);

                    // Common attributes
                    ExportCommonBabylonAttributes(babylonAttributesDependencyNode, babylonMaterial);
                    babylonMaterial.doubleSided = !babylonMaterial.backFaceCulling;
                    babylonMaterial._unlit      = babylonMaterial.isUnlit;

                    // Update displayed Transparency mode value based on StingrayPBS preset material
                    MGlobal.executeCommand($"setAttr - l false {{ \"{babylonAttributesDependencyNode.name}.babylonTransparencyMode\" }}"); // Unlock attribute
                    int babylonTransparencyMode = 0;
                    if (materialDependencyNode.hasAttribute("mask_threshold"))
                    {
                        babylonTransparencyMode = 1;
                    }
                    else if (materialDependencyNode.hasAttribute("use_opacity_map"))
                    {
                        babylonTransparencyMode = 2;
                    }
                    MGlobal.executeCommand($"setAttr \"{babylonAttributesDependencyNode.name}.babylonTransparencyMode\" {babylonTransparencyMode};");
                    MGlobal.executeCommand($"setAttr - l true {{ \"{babylonAttributesDependencyNode.name}.babylonTransparencyMode\" }}"); // Lock it afterwards
                }

                babylonScene.MaterialsList.Add(babylonMaterial);
            }
            // Arnold Ai Standard Surface
            else if (isAiStandardSurface(materialDependencyNode))
            {
                RaiseMessage("Ai Standard Surface shader", 2);

                var babylonMaterial = new BabylonPBRMetallicRoughnessMaterial(id)
                {
                    name = name
                };

                // User custom attributes
                babylonMaterial.metadata = ExportCustomAttributeFromMaterial(babylonMaterial);

                // --- Global ---

                bool isTransparencyModeFromBabylonMaterialNode = false;
                if (babylonAttributesDependencyNode != null)
                {
                    // Transparency mode
                    if (babylonAttributesDependencyNode.hasAttribute("babylonTransparencyMode"))
                    {
                        babylonMaterial.transparencyMode          = babylonAttributesDependencyNode.findPlug("babylonTransparencyMode").asInt();
                        isTransparencyModeFromBabylonMaterialNode = true;
                    }
                }

                // Color3
                float   baseWeight = materialDependencyNode.findPlug("base").asFloat();
                float[] baseColor  = materialDependencyNode.findPlug("baseColor").asFloatArray();
                babylonMaterial.baseColor = baseColor.Multiply(baseWeight);

                // Alpha
                MaterialDuplicationData materialDuplicationData = materialDuplicationDatas[id];
                // If at least one mesh is Transparent and is using this material either directly or as a sub material
                if ((isTransparencyModeFromBabylonMaterialNode == false || babylonMaterial.transparencyMode != 0) && materialDuplicationData.isArnoldTransparent())
                {
                    float[] opacityAttributeValue = materialDependencyNode.findPlug("opacity").asFloatArray();
                    babylonMaterial.alpha = opacityAttributeValue[0];
                }
                else
                {
                    // Do not bother about alpha
                    babylonMaterial.alpha = 1.0f;
                }

                // Metallic & roughness
                babylonMaterial.metallic  = materialDependencyNode.findPlug("metalness").asFloat();
                babylonMaterial.roughness = materialDependencyNode.findPlug("specularRoughness").asFloat();

                // Emissive
                float emissionWeight = materialDependencyNode.findPlug("emission").asFloat();
                babylonMaterial.emissive = materialDependencyNode.findPlug("emissionColor").asFloatArray().Multiply(emissionWeight);


                var list = new List <string>();

                for (int i = 0; i < materialDependencyNode.attributeCount; i++)
                {
                    var attr = materialDependencyNode.attribute((uint)i);
                    var plug = materialDependencyNode.findPlug(attr);
                    //string aliasName;
                    //materialDependencyNode.getPlugsAlias(plug, out aliasName);
                    System.Diagnostics.Debug.WriteLine(plug.name + i.ToString());
                }

                // --- Clear Coat ---
                float             coatWeight = materialDependencyNode.findPlug("coat").asFloat();
                MFnDependencyNode intensityCoatTextureDependencyNode = getTextureDependencyNode(materialDependencyNode, "coat");
                if (coatWeight > 0.0f || intensityCoatTextureDependencyNode != null)
                {
                    babylonMaterial.clearCoat.isEnabled         = true;
                    babylonMaterial.clearCoat.indexOfRefraction = materialDependencyNode.findPlug("coatIOR").asFloat();

                    var coatRoughness = materialDependencyNode.findPlug("coatRoughness").asFloat();
                    MFnDependencyNode roughnessCoatTextureDependencyNode = getTextureDependencyNode(materialDependencyNode, "coatRoughness");
                    var coatTexture = ExportCoatTexture(intensityCoatTextureDependencyNode, roughnessCoatTextureDependencyNode, babylonScene, name, coatWeight, coatRoughness);
                    if (coatTexture != null)
                    {
                        babylonMaterial.clearCoat.texture   = coatTexture;
                        babylonMaterial.clearCoat.roughness = 1.0f;
                        babylonMaterial.clearCoat.intensity = 1.0f;
                    }
                    else
                    {
                        babylonMaterial.clearCoat.intensity = coatWeight;
                        babylonMaterial.clearCoat.roughness = coatRoughness;
                    }

                    float[] coatColor = materialDependencyNode.findPlug("coatColor").asFloatArray();
                    if (coatColor[0] != 1.0f || coatColor[1] != 1.0f || coatColor[2] != 1.0f)
                    {
                        babylonMaterial.clearCoat.isTintEnabled = true;
                        babylonMaterial.clearCoat.tintColor     = coatColor;
                    }

                    babylonMaterial.clearCoat.tintTexture = ExportTexture(materialDependencyNode, "coatColor", babylonScene);
                    if (babylonMaterial.clearCoat.tintTexture != null)
                    {
                        babylonMaterial.clearCoat.tintColor     = new[] { 1.0f, 1.0f, 1.0f };
                        babylonMaterial.clearCoat.isTintEnabled = true;
                    }

                    // EyeBall deduction...
                    babylonMaterial.clearCoat.tintThickness = 0.65f;

                    babylonMaterial.clearCoat.bumpTexture = ExportTexture(materialDependencyNode, "coatNormal", babylonScene);
                }

                // --- Textures ---

                // Base color & alpha
                if ((isTransparencyModeFromBabylonMaterialNode == false || babylonMaterial.transparencyMode != 0) && materialDuplicationData.isArnoldTransparent())
                {
                    MFnDependencyNode baseColorTextureDependencyNode = getTextureDependencyNode(materialDependencyNode, "baseColor");
                    MFnDependencyNode opacityTextureDependencyNode   = getTextureDependencyNode(materialDependencyNode, "opacity");
                    if (baseColorTextureDependencyNode != null && opacityTextureDependencyNode != null &&
                        getSourcePathFromFileTexture(baseColorTextureDependencyNode) == getSourcePathFromFileTexture(opacityTextureDependencyNode))
                    {
                        // If the same file is used for base color and opacity
                        // Base color and alpha are already merged into a single file
                        babylonMaterial.baseTexture = ExportTexture(baseColorTextureDependencyNode, babylonScene, false, true);
                    }
                    else
                    {
                        // Base color and alpha files need to be merged into a single file
                        Color _baseColor = Color.FromArgb((int)(baseColor[0] * 255), (int)(baseColor[1] * 255), (int)(baseColor[2] * 255));
                        babylonMaterial.baseTexture = ExportBaseColorAlphaTexture(baseColorTextureDependencyNode, opacityTextureDependencyNode, babylonScene, name, _baseColor, babylonMaterial.alpha);
                    }
                }
                else
                {
                    // Base color only
                    // Do not bother about alpha
                    babylonMaterial.baseTexture = ExportTexture(materialDependencyNode, "baseColor", babylonScene);
                }

                // Metallic & roughness
                MFnDependencyNode metallicTextureDependencyNode  = getTextureDependencyNode(materialDependencyNode, "metalness");
                MFnDependencyNode roughnessTextureDependencyNode = getTextureDependencyNode(materialDependencyNode, "specularRoughness");
                if (metallicTextureDependencyNode != null && roughnessTextureDependencyNode != null &&
                    getSourcePathFromFileTexture(metallicTextureDependencyNode) == getSourcePathFromFileTexture(roughnessTextureDependencyNode))
                {
                    // If the same file is used for metallic and roughness
                    // Then we assume it's an ORM file (Red=Occlusion, Green=Roughness, Blue=Metallic)

                    // Metallic and roughness are already merged into a single file
                    babylonMaterial.metallicRoughnessTexture = ExportTexture(metallicTextureDependencyNode, babylonScene);

                    // Use same file for Ambient occlusion
                    babylonMaterial.occlusionTexture = babylonMaterial.metallicRoughnessTexture;
                }
                else
                {
                    // Metallic and roughness files need to be merged into a single file
                    // Occlusion texture is not exported since aiStandardSurface material doesn't provide input for it
                    babylonMaterial.metallicRoughnessTexture = ExportORMTexture(babylonScene, metallicTextureDependencyNode, roughnessTextureDependencyNode, null, babylonMaterial.metallic, babylonMaterial.roughness);
                }

                // Normal
                babylonMaterial.normalTexture = ExportTexture(materialDependencyNode, "normalCamera", babylonScene);

                // Emissive
                babylonMaterial.emissiveTexture = ExportTexture(materialDependencyNode, "emissionColor", babylonScene);

                // Constraints
                if (babylonMaterial.baseTexture != null)
                {
                    babylonMaterial.baseColor = new[] { baseWeight, baseWeight, baseWeight };
                    babylonMaterial.alpha     = 1.0f;
                }
                if (babylonMaterial.metallicRoughnessTexture != null)
                {
                    babylonMaterial.metallic  = 1.0f;
                    babylonMaterial.roughness = 1.0f;
                }
                if (babylonMaterial.emissiveTexture != null)
                {
                    babylonMaterial.emissive = new[] { emissionWeight, emissionWeight, emissionWeight };
                }

                // If this material is containing alpha data
                if (babylonMaterial.alpha != 1.0f || (babylonMaterial.baseTexture != null && babylonMaterial.baseTexture.hasAlpha))
                {
                    if (isTransparencyModeFromBabylonMaterialNode == false)
                    {
                        babylonMaterial.transparencyMode = (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHABLEND;
                    }

                    // If this material is assigned to both Transparent and Opaque meshes (either directly or as a sub material)
                    if (materialDuplicationData.isDuplicationRequired())
                    {
                        // Duplicate material
                        BabylonPBRMetallicRoughnessMaterial babylonMaterialCloned = DuplicateMaterial(babylonMaterial, materialDuplicationData);

                        // Store duplicated material too
                        babylonScene.MaterialsList.Add(babylonMaterialCloned);
                    }
                }

                if (babylonMaterial.transparencyMode == (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHATEST)
                {
                    // Set the alphaCutOff value explicitely to avoid different interpretations on different engines
                    // Use the glTF default value rather than the babylon one
                    babylonMaterial.alphaCutOff = 0.5f;
                }

                if (babylonAttributesDependencyNode == null)
                {
                    // Create Babylon Material dependency node
                    babylonAiStandardSurfaceMaterialNode.Create(materialDependencyNode);

                    // Retreive Babylon Material dependency node
                    babylonAttributesDependencyNode = getBabylonMaterialNode(materialDependencyNode);
                }

                if (babylonAttributesDependencyNode != null)
                {
                    // Ensure all attributes are setup
                    babylonAiStandardSurfaceMaterialNode.Init(babylonAttributesDependencyNode, babylonMaterial);

                    RaiseVerbose("Babylon Attributes of " + babylonAttributesDependencyNode.name, 2);

                    // Common attributes
                    ExportCommonBabylonAttributes(babylonAttributesDependencyNode, babylonMaterial);
                    babylonMaterial.doubleSided = !babylonMaterial.backFaceCulling;
                    babylonMaterial._unlit      = babylonMaterial.isUnlit;
                }

                if (fullPBR)
                {
                    var fullPBRMaterial = new BabylonPBRMaterial(babylonMaterial);
                    babylonScene.MaterialsList.Add(fullPBRMaterial);
                }
                else
                {
                    babylonScene.MaterialsList.Add(babylonMaterial);
                }
            }
            else
            {
                RaiseWarning("Unsupported material type '" + materialObject.apiType + "' for material named '" + materialDependencyNode.name + "'", 2);
            }
        }
Esempio n. 5
0
		public override void doIt(MArgList args)
		{
			MSelectionList list = new MSelectionList();

			if ( args.length > 0 ) {
				// Arg list is > 0 so use objects that were passes in
				//
				uint last = args.length;
				for ( uint i = 0; i < last; i++ ) {
					// Attempt to find all of the objects matched
					// by the string and add them to the list
					//
					string argStr = args.asString(i);
					list.add(argStr);
				}
			} else {
				// Get arguments from Maya's selection list.
				MGlobal.getActiveSelectionList(list);
			}

			MObject node = new MObject();
			MObjectArray nodePath = new MObjectArray();
			MFnDependencyNode nodeFn = new MFnDependencyNode();
			MFnDependencyNode dgNodeFnSet = new MFnDependencyNode();

			for (MItSelectionList iter = new MItSelectionList(list); !iter.isDone; iter.next()) {

				iter.getDependNode(node);

				//
				// The following code shows how to navigate the DG manually without
				// using an iterator.  First, find the attribute that you are
				// interested.  Then connect a plug to it and see where the plug
				// connected to.  Once you get all the connections, you can choose
				// which route you want to go.
				//
				// In here, we wanted to get to the nodes that instObjGroups connected
				// to since we know that the shadingEngine connects to the instObjGroup
				// attribute.
				//

				nodeFn.setObject( node );
				MObject iogAttr = null;
				try {
					iogAttr = nodeFn.attribute("instObjGroups");
				} catch (Exception) {
					MGlobal.displayInfo(nodeFn.name + ": is not a renderable object, skipping");
					continue;
				}

				MPlug iogPlug = new MPlug(node, iogAttr);
				MPlugArray iogConnections = new MPlugArray();

				//
				// instObjGroups is a multi attribute.  In this example, just the
				// first connection will be tried.
				//
				if (!iogPlug.elementByLogicalIndex(0).connectedTo(iogConnections, false, true)) {
					MGlobal.displayInfo(nodeFn.name + ": is not in a shading group, skipping");
					continue;
				}

				//
				// Now we would like to traverse the DG starting from the shadingEngine
				// since most likely all file texture nodes will be found.  Note the
				// filter used to initialize the DG iterator.  There are lots of filter
				// type available in MF.Type that you can choose to suite your needs.
				//
				bool foundATexture = false;
				for ( int i=0; i < iogConnections.length; i++ ) {

					MObject currentNode = iogConnections[i].node;

					//
					// Note that upon initialization, the current pointer of the
					// iterator already points to the first valid node.
					//
					MItDependencyGraph dgIt = new MItDependencyGraph(currentNode,
																	 MFn.Type.kFileTexture,
																	 MItDependencyGraph.Direction.kUpstream,
																	 MItDependencyGraph.Traversal.kBreadthFirst,
																	 MItDependencyGraph.Level.kNodeLevel);
					if (dgIt == null)
					{
						continue;
					}

					dgIt.disablePruningOnFilter();

					for ( ; !dgIt.isDone; dgIt.next() ) {

						MObject thisNode = dgIt.thisNode();
						dgNodeFnSet.setObject(thisNode);
						try {
							dgIt.getNodePath(nodePath);
						} catch (Exception) {
							MGlobal.displayInfo("getNodePath");
							continue;
						}

						//
						// append the starting node.
						//
						nodePath.append(node);
						dumpInfo( thisNode, dgNodeFnSet, nodePath );
						foundATexture = true;
					}
				}

				if ( !foundATexture ) {
					MGlobal.displayInfo(nodeFn.name + ": is not connected to a file texture");
				}
			}
			return;
		}
Esempio n. 6
0
		private void dumpInfo(MObject fileNode, MFnDependencyNode nodeFn, MObjectArray nodePath)
		{
			MObject fileAttr = nodeFn.attribute("fileTextureName");
			MPlug plugToFile = new MPlug(fileNode, fileAttr);
			MFnDependencyNode dgFn = new MFnDependencyNode();

			MGlobal.displayInfo("Name:    " + nodeFn.name);

			MObject fnameValue = new MObject();
			try
			{
				plugToFile.getValue(fnameValue);
			}
			catch (Exception)
			{
				MGlobal.displayInfo("error getting value from plug");
				return;
			}

			MFnStringData stringFn = new MFnStringData(fnameValue);
			MGlobal.displayInfo("Texture: " + stringFn.stringProperty);

			string path = "Path:    ";
			for (int i = (int)nodePath.length - 1; i >= 0; i--)
			{
				MObject currentNode = nodePath[i];
				dgFn.setObject(currentNode);

				path += dgFn.name + "(" + dgFn.typeName + ")";
				if (i > 0) path += " -> ";
			}
			MGlobal.displayInfo(path);
		}
Esempio n. 7
0
        public override void doIt(MArgList args)
        {
            MSelectionList list = new MSelectionList();

            if (args.length > 0)
            {
                // Arg list is > 0 so use objects that were passes in
                //
                uint last = args.length;
                for (uint i = 0; i < last; i++)
                {
                    // Attempt to find all of the objects matched
                    // by the string and add them to the list
                    //
                    string argStr = args.asString(i);
                    list.add(argStr);
                }
            }
            else
            {
                // Get arguments from Maya's selection list.
                MGlobal.getActiveSelectionList(list);
            }

            MObject           node        = new MObject();
            MObjectArray      nodePath    = new MObjectArray();
            MFnDependencyNode nodeFn      = new MFnDependencyNode();
            MFnDependencyNode dgNodeFnSet = new MFnDependencyNode();

            for (MItSelectionList iter = new MItSelectionList(list); !iter.isDone; iter.next())
            {
                iter.getDependNode(node);

                //
                // The following code shows how to navigate the DG manually without
                // using an iterator.  First, find the attribute that you are
                // interested.  Then connect a plug to it and see where the plug
                // connected to.  Once you get all the connections, you can choose
                // which route you want to go.
                //
                // In here, we wanted to get to the nodes that instObjGroups connected
                // to since we know that the shadingEngine connects to the instObjGroup
                // attribute.
                //

                nodeFn.setObject(node);
                MObject iogAttr = null;
                try {
                    iogAttr = nodeFn.attribute("instObjGroups");
                } catch (Exception) {
                    MGlobal.displayInfo(nodeFn.name + ": is not a renderable object, skipping");
                    continue;
                }

                MPlug      iogPlug        = new MPlug(node, iogAttr);
                MPlugArray iogConnections = new MPlugArray();

                //
                // instObjGroups is a multi attribute.  In this example, just the
                // first connection will be tried.
                //
                if (!iogPlug.elementByLogicalIndex(0).connectedTo(iogConnections, false, true))
                {
                    MGlobal.displayInfo(nodeFn.name + ": is not in a shading group, skipping");
                    continue;
                }

                //
                // Now we would like to traverse the DG starting from the shadingEngine
                // since most likely all file texture nodes will be found.  Note the
                // filter used to initialize the DG iterator.  There are lots of filter
                // type available in MF.Type that you can choose to suite your needs.
                //
                bool foundATexture = false;
                for (int i = 0; i < iogConnections.length; i++)
                {
                    MObject currentNode = iogConnections[i].node;

                    //
                    // Note that upon initialization, the current pointer of the
                    // iterator already points to the first valid node.
                    //
                    MItDependencyGraph dgIt = new MItDependencyGraph(currentNode,
                                                                     MFn.Type.kFileTexture,
                                                                     MItDependencyGraph.Direction.kUpstream,
                                                                     MItDependencyGraph.Traversal.kBreadthFirst,
                                                                     MItDependencyGraph.Level.kNodeLevel);
                    if (dgIt == null)
                    {
                        continue;
                    }

                    dgIt.disablePruningOnFilter();

                    for ( ; !dgIt.isDone; dgIt.next())
                    {
                        MObject thisNode = dgIt.thisNode();
                        dgNodeFnSet.setObject(thisNode);
                        try {
                            dgIt.getNodePath(nodePath);
                        } catch (Exception) {
                            MGlobal.displayInfo("getNodePath");
                            continue;
                        }

                        //
                        // append the starting node.
                        //
                        nodePath.append(node);
                        dumpInfo(thisNode, dgNodeFnSet, nodePath);
                        foundATexture = true;
                    }
                }

                if (!foundATexture)
                {
                    MGlobal.displayInfo(nodeFn.name + ": is not connected to a file texture");
                }
            }
            return;
        }