public static bool HasRuntimeAccess(IMtl mat)
 {
     if (mat.IsMultiMtl)
     {
         for (int i = 0; i < mat.NumSubMtls; i++)
         {
             IMtl childMat = mat.GetSubMtl(i);
             if (childMat != null)
             {
                 if (class_ID.Equals(childMat.ClassID))
                 {
                     int p = Tools.GetMaterialProperty(childMat, "uniqueInContainer");
                     if (Convert.ToBoolean(p))
                     {
                         return(true);
                     }
                 }
             }
         }
     }
     else if (class_ID.Equals(mat.ClassID))
     {
         int p = Tools.GetMaterialProperty(mat, "uniqueInContainer");
         if (Convert.ToBoolean(p))
         {
             return(true);
         }
     }
     return(false);
 }
        private IIGameMaterial GetBakedMaterialFromShellMaterial(IIGameMaterial materialNode)
        {
            if (isShellMaterial(materialNode))
            {
                // Shell Material Parameters
                // Original Material not exported => only for the offline rendering in 3DS Max
                // Baked Material => used for the export
                IMtl bakedMtl = materialNode.IPropertyContainer.GetProperty(1).MaxParamBlock2.GetMtl(3, 0, 0);

                if (bakedMtl != null)
                {
                    Guid guid = bakedMtl.GetGuid();

                    for (int indexSubMaterial = 0; indexSubMaterial < materialNode.SubMaterialCount; indexSubMaterial++)
                    {
                        IIGameMaterial subMaterialNode = materialNode.GetSubMaterial(indexSubMaterial);
                        if (guid.Equals(subMaterialNode.MaxMaterial.GetGuid()))
                        {
                            return(subMaterialNode);
                        }
                    }
                }
            }

            return(null);
        }
Example #3
0
        /// <summary>
        /// Retrieve current selected material in slate material editor
        /// </summary>
        /// <returns></returns>
        public static IMtl GetSelectedMaterial()
        {
            string mxs = "viewNode = sme.GetView (sme.activeView)";

            mxs += "\r\n" + "smeSelMats = #()";
            mxs += "\r\n" + "if (trackViewNodes[#sme][(sme.activeView)] != undefined) then(";
            mxs += "\r\n" + "for n = 1 to trackViewNodes[#sme][(sme.activeView)].numSubs do (";
            mxs += "\r\n" + "m = trackViewNodes[#sme][(sme.activeView)][n].reference";
            mxs += "\r\n" + "b = viewNode.GetNodeByRef m";
            mxs += "\r\n" + "if b.selected do append smeSelMats m)";
            mxs += "\r\n" + "smeSelMats[1])";

            IFPValue mxsRetVal = Loader.Global.FPValue.Create();

            ScriptsUtilities.ExecuteMAXScriptScript(mxs, true, mxsRetVal);
            IMtl result = null;

            try
            {
                result = mxsRetVal.Mtl;
            }
            catch (Exception e)
            {
                //do nothing ,just retun a null material
            }

            return(result);
        }
Example #4
0
        /// <summary>
        /// fix the material ids
        /// sometimes inside a node more material ids are set on faces
        /// than materials are actually used
        /// </summary>
        /// <param name="nodeView"></param>
        private static void FixMaterialIDs(NodeView nodeView)
        {
            // get the used material from the node
            int  iNumMaterials = 0;
            IMtl nodeMaterial  = nodeView.Node.Mtl;

            // first check if a material is on the node
            // check as well if its a multimaterial
            if (nodeMaterial != null)
            {
                iNumMaterials = nodeMaterial.NumSubMtls > 0 ? nodeMaterial.NumSubMtls : 1;
            }


            // cycle through all face and check the MatID
            IFace[] arrFaces = nodeView.Mesh.Faces.ToArray();
            for (int i = 0; i < arrFaces.Length; i++)
            {
                if (arrFaces[i].MatID < iNumMaterials)
                {
                    continue;
                }

                arrFaces[i].MatID = iNumMaterials > 0 ? (ushort)(arrFaces[i].MatID % iNumMaterials) : (ushort)0;
            }

            // very important. call this to notify max that this node has changed
            // this is similar to events in c#
            nodeView.Node.NotifyDependents(Globals.FOREVER, Globals.PART_ALL, RefMessage.NodeMaterialChanged);
            nodeView.Node.NotifyDependents(Globals.FOREVER, Globals.PART_ALL, RefMessage.Change);
        }
Example #5
0
        /// <summary>
        /// fix the material ids
        /// sometimes inside a node more material ids are set on faces
        /// than materials are actually used
        /// </summary>
        /// <param name="nodeData"></param>
        private static async Task CheckMatIds(sNodeData nodeData)
        {
            await Task.Run(() =>
            {
                IMesh mesh = nodeData.ViewNode.Mesh;

                // get the used material from the node
                int iNumMaterials = 0;
                IMtl nodeMaterial = nodeData.ViewNode.Node.Mtl;

                // first check if a material is on the node
                // check as well if its a multimaterial
                if (nodeMaterial != null)
                {
                    iNumMaterials = nodeMaterial.NumSubMtls > 0 ? nodeMaterial.NumSubMtls : 1;
                }

                // cycle through all face and check the MatID
                IFace[] arrFaces = mesh.Faces.ToArray();
                for (int i = 0; i < arrFaces.Length; i++)
                {
                    if (arrFaces[i].MatID > iNumMaterials)
                    {
                        nodeData.ViewNode.WrongMatIDCount++;
                    }
                }
            });
        }
Example #6
0
    public bool GetGltfMaterial(BabylonMaterial babylonMaterial, GLTF gltf, ILoggingProvider logger, out GLTFMaterial gltfMaterial)
    {
        gltfMaterial = null;
        IIGameMaterial gameMtl = babylonMaterial.maxGameMaterial;

        if (gameMtl == null || gameMtl.MaxMaterial == null)
        {
            return(false);
        }

        IMtl maxMtl = gameMtl.MaxMaterial;

        IMaxMaterialExporter materialExporter;

        if (materialExporters.TryGetValue(new ClassIDWrapper(maxMtl.ClassID), out materialExporter) &&
            materialExporter is IMaxGLTFMaterialExporter)
        {
            gltfMaterial = ((IMaxGLTFMaterialExporter)materialExporter).ExportGLTFMaterial(this.exportParameters, gltf, gameMtl,
                                                                                           (string sourcePath, string textureName) => { return(this.TryWriteImage(gltf, sourcePath, textureName, exportParameters, logger)); },
                                                                                           (string message, Color color) => { logger.RaiseMessage(message, color, 2); },
                                                                                           (string message) => { logger.RaiseWarning(message, 2); },
                                                                                           (string message) => { logger.RaiseError(message, 2); });

            if (gltfMaterial == null)
            {
                string message = string.Format("Custom glTF material exporter failed to export | Exporter: '{0}' | Material Name: '{1}' | Material Class: '{2}'",
                                               materialExporter.GetType().ToString(), gameMtl.MaterialName, gameMtl.ClassName);
                logger.RaiseWarning(message, 2);
                return(false);
            }
            return(true);
        }
        return(false);
    }
Example #7
0
        private ListViewItem FillMaterialItem(IMtl material, Guid guid)
        {
            if (previousMaterialMap.ContainsKey(guid))
            {
                return(null);
            }
            ListViewItem item = new ListViewItem();

            item.Text = material.Name;
            Items.Add(item);
            return(item);
        }
Example #8
0
        MaterialInformation GetMaterialProperties(IMtl material, MessageMaterialRequest request)
        {
            if (material == null)
            {
                return null;
            }

            if (request.m_materialIndex < 0)
            {
                return GetMaterialProperties(material);
            }

            return GetMaterialProperties(material.GetSubMtl(request.m_materialIndex));
        }
Example #9
0
        public void FillMaterialsView(IList <Guid> infoMaterialGuids)
        {
            Items.Clear();
            foreach (var dicKeyValue in Tools.guids)
            {
                if (infoMaterialGuids.Contains(dicKeyValue.Key))
                {
                    IMtl animMat = dicKeyValue.Value as IMtl;
                    AddMaterial(animMat);
                }
            }

            currentMaterialMap = previousMaterialMap.ToDictionary(entry => entry.Key, entry => (ListViewItem)entry.Value.Clone());;
        }
        private IIGameMaterial GetRenderMaterialFromDirectXShader(IIGameMaterial materialNode)
        {
            IIGameMaterial renderMaterial = null;

            if (isDirectXShaderMaterial(materialNode))
            {
                var  gameScene = Loader.Global.IGameInterface;
                IMtl renderMtl = materialNode.IPropertyContainer.GetProperty(35).MaxParamBlock2.GetMtl(4, 0, 0);
                if (renderMtl != null)
                {
                    renderMaterial = gameScene.GetIGameMaterial(renderMtl);
                }
            }

            return(renderMaterial);
        }
Example #11
0
        public static bool IsMaterialAssignedInScene(IMtl mtl)
        {
            for (int i = 0; i < Loader.Core.SceneMtls.Count; i++)
            {
                IMtl sceneMtl = null;
#if MAX2015 || MAX2016
                sceneMtl = (IMtl)Loader.Core.SceneMtls[new IntPtr(i)];
#else
                sceneMtl = (IMtl)Loader.Core.SceneMtls[i];
#endif
                if (sceneMtl != null && mtl.GetNativeHandle() == sceneMtl.GetNativeHandle())
                {
                    return(true);
                }
            }
            return(false);
        }
Example #12
0
        public void AddMaterial(IMtl material)
        {
            if (material == null)
            {
                return;
            }
            if (!FlightSimMaterialUtilities.IsFlightSimMaterial(material))
            {
                return;
            }
            Guid         matGuid = material.GetGuid();
            ListViewItem item    = FillMaterialItem(material, matGuid);

            if (item != null)
            {
                previousMaterialMap.Add(matGuid, item);
            }
        }
Example #13
0
        public void RemoveMaterialFromSelection(IMtl material)
        {
            if (material == null)
            {
                return;
            }
            if (!FlightSimMaterialUtilities.IsFlightSimMaterial(material))
            {
                return;
            }
            Guid         matGuid = material.GetGuid();
            ListViewItem itemToRemove;

            if (previousMaterialMap.TryGetValue(matGuid, out itemToRemove))
            {
                itemToRemove.BackColor = Color.Red;
                currentMaterialMap.Remove(matGuid);
            }
        }
        public static bool HasFlightSimMaterials(IMtl mat)
        {
            if (mat.IsMultiMtl)
            {
                for (int i = 0; i < mat.NumSubMtls; i++)
                {
                    IMtl childMat = mat.GetSubMtl(i);
                    if (childMat != null && class_ID.Equals(childMat.ClassID))
                    {
                        return(true);
                    }
                }
            }
            else if (mat != null && class_ID.Equals(mat.ClassID))
            {
                return(true);
            }


            return(false);
        }
Example #15
0
        public static IMtl GetAnimatableMaterial(this IINode node)
        {
            IMtl material = node.Mtl;

            if (material == null)
            {
                MessageBox.Show("No Material found for the selected node");
                return(null);
            }
            if (material.IsMultiMtl)
            {
                MessageBox.Show("MultiMaterial animation is not supported, use a non-MultiMaterial material");
                return(null);
            }
            if (!FlightSimMaterialUtilities.IsFlightSimMaterial(material))
            {
                MessageBox.Show("Material animation is supported only for FlightSimMaterial");
                return(null);
            }
            return(material);
        }
Example #16
0
        MaterialInformation GetMaterialProperties(IMtl material)
        {
            if (material == null)
            {
                return null;
            }

            MaterialInformation m = new MaterialInformation();
            
            m.m_className = material.ClassName;
            m.m_materialName = material.Name;
            m.m_handle = _gi.Animatable.GetHandleByAnim(material).ToUInt64();

            var prps = EnumerateProperties(material).ToList();

            foreach (var p in EnumerateProperties(material))
            {
                m.MaterialProperties.Add(new MaterialProperty(p.m_parameterName, p.m_internalName, p.GetValue()));
            }

            return m;
        }
Example #17
0
        public void AddMaterialFromSelection(IMtl material)
        {
            if (material == null)
            {
                return;
            }
            if (!MaterialUtilities.IsMaterialAssignedInScene(material))
            {
                return;
            }
            if (!FlightSimMaterialUtilities.IsFlightSimMaterial(material))
            {
                return;
            }
            Guid         matGuid = material.GetGuid();
            ListViewItem item    = FillMaterialItem(material, matGuid);

            if (item != null)
            {
                currentMaterialMap.Add(matGuid, item);
                item.BackColor = Color.Green;
            }
        }
Example #18
0
        private IIGameMaterial GetRenderMaterialFromDirectXShader(IIGameMaterial materialNode)
        {
            IIGameMaterial renderMaterial = null;

            if (isDirectXShaderMaterial(materialNode))
            {
                var            gameScene = Loader.Global.IGameInterface;
                IIGameProperty property  = materialNode.IPropertyContainer.GetProperty(35);
                if (property != null)
                {
                    IMtl renderMtl = materialNode.IPropertyContainer.GetProperty(35).MaxParamBlock2.GetMtl(4, 0, 0);
                    if (renderMtl != null)
                    {
                        renderMaterial = gameScene.GetIGameMaterial(renderMtl);
                    }
                }
                else
                {
                    RaiseWarning($"DirectX material property for {materialNode.MaterialName} is null...", 2);
                }
            }

            return(renderMaterial);
        }
Example #19
0
        private void removeNodeButton_Click(object sender, EventArgs e)
        {
            if (currentInfo == null)
            {
                return;
            }

            if (currentAnimationParseType == AnimationParseType.Nodes)
            {
                MaxNodeTree.BeginUpdate();
                for (int i = 0; i < Loader.Core.SelNodeCount; ++i)
                {
                    IINode node = Loader.Core.GetSelNode(i);
                    MaxNodeTree.QueueRemoveNode(node);
                }
                MaxNodeTree.EndUpdate();
            }

            if (currentAnimationParseType == AnimationParseType.Materials)
            {
                if (Loader.Core.SelNodeCount < 1)
                {
                    MessageBox.Show("You need to select at least one Node");
                    return;
                }
                for (int i = 0; i < Loader.Core.SelNodeCount; ++i)
                {
                    IINode node     = Loader.Core.GetSelNode(i);
                    IMtl   material = node.GetAnimatableMaterial();
                    if (material != null)
                    {
                        maxMaterialView.RemoveMaterialFromSelection(material);
                    }
                }
            }
        }
Example #20
0
        private static void ResolveMultipleInheritedContainer(IIContainerObject container)
        {
            string helperPropBuffer = string.Empty;

            container.BabylonContainerHelper().GetUserPropBuffer(ref helperPropBuffer);

            List <IINode> containerHierarchy = new List <IINode>()
            {
                container.ContainerNode
            };

            containerHierarchy.AddRange(container.ContainerNode.ContainerNodeTree(false));

            int containerID = 1;

            container.ContainerNode.GetUserPropInt("babylonjs_ContainerID", ref containerID);

            //the first istance of the multiples containers, the one without _ID_*
            //mContainer ->referenceBrotherContainer
            //mContainer_ID_2
            int idIndex = container.ContainerNode.Name.IndexOf("_ID_");

            if (idIndex < 0)
            {
                return;
            }
            string refBrotherName            = container.ContainerNode.Name.Substring(0, idIndex);
            IINode refBrotherContainerObject = Loader.Core.GetINodeByName(refBrotherName);

            //if there is no brother, there is nothing to resolve
            if (refBrotherContainerObject == null)
            {
                return;
            }


            //manage multiple containers inherithed from the same source
            foreach (IINode n in containerHierarchy)
            {
                if (n.IsBabylonContainerHelper())
                {
                    continue;
                }

                //change the guid of the node
                //replace the guid in the babylon helper
                string oldGuid = n.GetStringProperty("babylonjs_GUID", Guid.NewGuid().ToString());
                n.DeleteProperty("babylonjs_GUID");
                Guid newGuid = n.GetGuid();
                helperPropBuffer = helperPropBuffer.Replace(oldGuid, newGuid.ToString());

                if (containerID > 1 && !n.Name.EndsWith("_ID_" + containerID))
                {
                    string originalName = n.Name;
                    n.Name = $"{n.Name}_ID_{containerID}";
                    IINode source = refBrotherContainerObject.FindChildNode(originalName);
                    IMtl   mat    = source.Mtl;
                    if (mat != null)
                    {
                        n.Mtl = mat;
                    }
                }
            }

            //replace animationList guid to have distinct list of AnimationGroup for each container
            string animationListStr = string.Empty;

            container.BabylonContainerHelper().GetUserPropString(s_AnimationListPropertyName, ref animationListStr);
            if (!string.IsNullOrEmpty(animationListStr))
            {
                string[] animationGroupGuid = animationListStr.Split(AnimationGroup.s_PropertySeparator);
                foreach (string guidStr in animationGroupGuid)
                {
                    Guid newAnimGroupGuid = Guid.NewGuid();
                    helperPropBuffer = helperPropBuffer.Replace(guidStr, newAnimGroupGuid.ToString());
                }

                container.BabylonContainerHelper().SetUserPropBuffer(helperPropBuffer);

                //add ID of container to animationGroup name to identify animation in viewer
                container.BabylonContainerHelper().GetUserPropString(s_AnimationListPropertyName, ref animationListStr);
                string[] newAnimationGroupGuid = animationListStr.Split(AnimationGroup.s_PropertySeparator);

                if (containerID > 1)
                {
                    foreach (string guidStr in newAnimationGroupGuid)
                    {
                        string propertiesString = string.Empty;
                        if (!container.BabylonContainerHelper().GetUserPropString(guidStr, ref propertiesString))
                        {
                            return;
                        }

                        string[] properties = propertiesString.Split(AnimationGroup.s_PropertySeparator);
                        if (properties.Length < 4)
                        {
                            throw new Exception("Invalid number of properties, can't deserialize.");
                        }

                        string name = properties[0];
                        if (!string.IsNullOrEmpty(name) && !name.EndsWith("_ID_" + containerID))
                        {
                            propertiesString = propertiesString.Replace(name, name + "_ID_" + containerID);
                            container.BabylonContainerHelper().SetUserPropString(guidStr, propertiesString);
                        }
                    }
                }
            }
        }
Example #21
0
 internal Material(IMtl x) : base(x)
 {
 }
 public MaterialObjectsWrapper(IMtl material)
 {
    this.Material = material;
 }
Example #23
0
        private void confirmButton_Click(object sender, EventArgs e)
        {
            if (currentInfo == null)
            {
                return;
            }

            AnimationGroup confirmedInfo = currentInfo;

            string newName = nameTextBox.Text;

            bool newKeepEmpty       = keepStaticAnimBox.Checked;
            bool newKeepNonAnimated = keepNonAnimatedBox.Checked;

            int newFrameStart;

            if (!int.TryParse(startTextBox.Text, out newFrameStart))
            {
                newFrameStart = confirmedInfo.FrameStart;
            }
            int newFrameEnd;

            if (!int.TryParse(endTextBox.Text, out newFrameEnd))
            {
                newFrameEnd = confirmedInfo.FrameEnd;
            }

            List <uint>  newHandles;
            bool         nodesChanged = MaxNodeTree.ApplyQueuedChanges(out newHandles);
            IList <Guid> newMaterialGUIDs;
            bool         materialsChanged = maxMaterialView.ApplyMaterialsChanges(out newMaterialGUIDs);

            bool changed = newKeepEmpty != confirmedInfo.KeepStaticAnimation ||
                           newName != confirmedInfo.Name ||
                           newFrameStart != confirmedInfo.FrameStart ||
                           newFrameEnd != confirmedInfo.FrameEnd ||
                           nodesChanged ||
                           materialsChanged ||
                           newKeepNonAnimated != confirmedInfo.KeepNonAnimated;

            if (!changed)
            {
                return;
            }

            confirmedInfo.Name                = newName;
            confirmedInfo.FrameStart          = newFrameStart;
            confirmedInfo.FrameEnd            = newFrameEnd;
            confirmedInfo.KeepStaticAnimation = newKeepEmpty;
            confirmedInfo.KeepNonAnimated     = newKeepNonAnimated;

            if (nodesChanged)
            {
                confirmedInfo.NodeGuids = newHandles.ToGuids();
                if (confirmedInfo.AnimationGroupNodes == null)
                {
                    confirmedInfo.AnimationGroupNodes = new List <AnimationGroupNode>();
                }

                foreach (uint handle in newHandles)
                {
                    IINode node = Loader.Core.GetINodeByHandle(handle);
                    if (node != null)
                    {
                        string             name       = node.Name;
                        string             parentName = node.ParentNode.Name;
                        AnimationGroupNode nodeData   = new AnimationGroupNode(node.GetGuid(), name, parentName);
                        confirmedInfo.AnimationGroupNodes.Add(nodeData);
                    }
                }
            }

            if (materialsChanged)
            {
                confirmedInfo.MaterialGuids = newMaterialGUIDs;

                if (confirmedInfo.AnimationGroupMaterials == null)
                {
                    confirmedInfo.AnimationGroupMaterials = new List <AnimationGroupMaterial>();
                }

                foreach (Guid guid in newMaterialGUIDs)
                {
                    IMtl mat = Tools.GetIMtlByGuid(guid);
                    if (mat != null)
                    {
                        string name = mat.Name;
                        AnimationGroupMaterial matData = new AnimationGroupMaterial(guid, name);
                        confirmedInfo.AnimationGroupMaterials.Add(matData);
                    }
                }
            }

            ResetChangedTextBoxColors();
            MaxNodeTree.SelectedNode = null;

            InfoChanged?.Invoke(confirmedInfo);
            ConfirmPressed?.Invoke(confirmedInfo);
        }
Example #24
0
        private void addSelectedButton_Click(object sender, EventArgs e)
        {
            if (currentInfo == null)
            {
                return;
            }

            if (currentAnimationParseType == AnimationParseType.Nodes)
            {
                MaxNodeTree.BeginUpdate();
                for (int i = 0; i < Loader.Core.SelNodeCount; ++i)
                {
                    IINode node = Loader.Core.GetSelNode(i);

                    //added in flightsim to add lod node "x0_name" and all other lod relative
                    // x1_name,x2_name etc
                    //todo expost addnode to maxscript and call this outside
                    if (node.Name.StartsWith("x"))
                    {
                        string lod_name   = node.Name.Substring(3);
                        string lod_prefix = node.Name.Replace(lod_name, "");
                        if (lod_prefix.ToCharArray()[0] == 'x' && lod_prefix.ToCharArray()[2] == '_')
                        {
                            for (int j = 0; j < 7; j++)
                            {
                                string relativeLodName = "x" + j + "_" + lod_name;
                                IINode relativeLodNode = Loader.Core.GetINodeByName(relativeLodName);
                                if (relativeLodNode != null)
                                {
                                    MaxNodeTree.QueueAddNode(relativeLodNode);
                                }
                            }
                        }
                        else
                        {
                            MaxNodeTree.QueueAddNode(node);
                        }
                    }
                    else
                    {
                        MaxNodeTree.QueueAddNode(node);
                    }
                }

                MaxNodeTree.EndUpdate();
            }


            if (currentAnimationParseType == AnimationParseType.Materials)
            {
                if (Loader.Core.SelNodeCount < 1)
                {
                    MessageBox.Show("You need to select at least one Node");
                    return;
                }
                for (int i = 0; i < Loader.Core.SelNodeCount; ++i)
                {
                    IINode node     = Loader.Core.GetSelNode(i);
                    IMtl   material = node.GetAnimatableMaterial();
                    if (material != null)
                    {
                        maxMaterialView.AddMaterialFromSelection(material);
                    }
                }
            }
        }
Example #25
0
        private void getMaterials(ref int geoIndex)
        {
            if (ReadUInt32() != (uint)secIDs.MATERIAL_LIST)
            {
                datIndex -= 4;
                return;
            }

            //get number of materials
            datIndex += 20;
            int matCount = ReadInt32();

            //skip trash FFFF data (one for each material)
            datIndex         += matCount * 4;
            mtlList[geoIndex] = (IMultiMtl)ip.CreateInstance(SClass_ID.Material, global.Class_ID.Create((uint)BuiltInClassIDA.MULTI_CLASS_ID, 0));
            mtlList[geoIndex].SetNumSubMtls(matCount);

            //read material data
            for (int i = 0; i < matCount; ++i)
            {
                IMtl leMat = (IMtl)ip.CreateInstance(SClass_ID.Material, global.Class_ID.Create((uint)custClassIDs.GTAMAT_A, (uint)custClassIDs.GTAMAT_B));
                //skip material header, struct header and integer
                datIndex += 28;
                //read color
                leMat.GetParamBlock(0).SetValue(3, 0, global.Color.Create(data[datIndex] / 255.0f, data[datIndex + 1] / 255.0f, data[datIndex + 2] / 255.0f), 0);
                leMat.GetParamBlock(0).SetValue(6, 0, (int)data[datIndex + 3], 0);
                //increment and skip unknown
                datIndex += 8;
                uint numTextures = ReadUInt32();
                //ambient, diffuse and specular?
                leMat.GetParamBlock(0).SetValue(0, 0, ReadSingle(), 0);
                leMat.GetParamBlock(0).SetValue(1, 0, ReadSingle(), 0);
                leMat.GetParamBlock(0).SetValue(2, 0, ReadSingle(), 0);
                mtlList[geoIndex].SetSubMtl(i, leMat);
                //read textures
                for (int ind = 0; ind < numTextures; ++ind)
                {
                    //skip texture and struct header
                    datIndex += 24;
                    int filtAddr = datIndex;
                    datIndex += 4;      //skip three bytes (used later)+1 unknown.

                    //read diffuse texture name
                    datIndex += 4;      //skip header
                    int size = ReadInt32();
                    datIndex += 4;      //skip RW version
                    IBitmapTex diffTex = (IBitmapTex)ip.CreateInstance(SClass_ID.Texmap, global.Class_ID.Create((uint)BuiltInClassIDA.BMTEX_CLASS_ID, 0));
                    diffTex.Name = ReadString(ref size);

                    //read alpha texture name
                    datIndex += 4;      //skip header
                    size      = ReadInt32();
                    datIndex += 4;      //skip RW version
                    IBitmapTex alphaTex = (IBitmapTex)ip.CreateInstance(SClass_ID.Texmap, global.Class_ID.Create((uint)BuiltInClassIDA.BMTEX_CLASS_ID, 0));
                    alphaTex.Name = ReadString(ref size);

                    //set tiling and mirror data from filter flags
                    switch (data[filtAddr])
                    {
                    case 1:
                        diffTex.FilterType  = 2;      //FILTER_NADA
                        alphaTex.FilterType = 2;
                        break;

                    case 2:
                        diffTex.FilterType  = 1;     //FILTER_SAT
                        alphaTex.FilterType = 1;     //FILTER_SAT
                        break;

                    default:
                        diffTex.FilterType  = 0;     //FILTER_PYR
                        alphaTex.FilterType = 0;     //FILTER_PYR
                        break;
                    }

                    diffTex.UVGen.SetFlag(1 << 2, ~(data[filtAddr + 1] | 0xfffffffe));
                    diffTex.UVGen.SetFlag(1 << 0, ~(data[filtAddr + 1] | 0xfffffffd));
                    diffTex.UVGen.SetFlag(1 << 3, ~(data[filtAddr + 1] | 0xffffffef));
                    diffTex.UVGen.SetFlag(1 << 1, ~(data[filtAddr + 1] | 0xffffffdf));

                    alphaTex.UVGen.SetFlag(1 << 2, ~(data[filtAddr + 1] | 0xfffffffe));
                    alphaTex.UVGen.SetFlag(1 << 0, ~(data[filtAddr + 1] | 0xfffffffd));
                    alphaTex.UVGen.SetFlag(1 << 3, ~(data[filtAddr + 1] | 0xffffffef));
                    alphaTex.UVGen.SetFlag(1 << 1, ~(data[filtAddr + 1] | 0xffffffdf));

                    leMat.GetParamBlock(0).SetValue(4, 0, diffTex, 0);
                    leMat.GetParamBlock(0).SetValue(7, 0, alphaTex, 0);
                    leMat.GetParamBlock(0).SetValue(8, 0, 0, 0);

                    //skip extension
                    if (ReadUInt32() == (uint)secIDs.EXTENSION)
                    {
                        int temp = ReadInt32();
                        datIndex += temp + 4;
                    }
                    else
                    {
                        datIndex -= 4;
                    }
                }
                //read material effects
                if (ReadUInt32() == (uint)secIDs.EXTENSION)
                {
                    datIndex += 8;      //skip section size and RW version
                    //check for material effects, reflection and specular material
                    for (int ind = 0; ind < 3; ++ind)
                    {
                        switch (ReadUInt32())
                        {
                        case (uint)secIDs.MATERIAL_EFFECTS_PLG:
                        {
                            datIndex += 16;                                                  //skip section size, RW version and starting ints (both 2)
                            leMat.GetParamBlock(0).SetValue(9, 0, 100.0f * ReadSingle(), 0); //reflection
                            leMat.GetParamBlock(0).SetValue(11, 0, 1, 0);
                            datIndex += 8;                                                   //skip unknown (= 0), skip texture ON/OFF switch 0/1
                            if (ReadUInt32() == (uint)secIDs.TEXTURE)
                            {
                                //skip texture and struct header
                                datIndex += 20;
                                int filtAddr = datIndex;
                                datIndex += 4;      //skip 3 filtering bytes + unkown

                                //read diffuse texture name
                                datIndex += 4;          //skip header
                                int size = ReadInt32();
                                datIndex += 4;          //skip RW version
                                IBitmapTex diffTex = (IBitmapTex)ip.CreateInstance(SClass_ID.Texmap, global.Class_ID.Create((uint)BuiltInClassIDA.BMTEX_CLASS_ID, 0));
                                diffTex.Name = ReadString(ref size);

                                //skip alpha texture
                                if (ReadUInt32() == 0x02)
                                {
                                    int temp = ReadInt32();
                                    datIndex += temp + 4;
                                }
                                else
                                {
                                    datIndex -= 4;
                                }

                                //set tiling and mirror data from filter flags
                                switch (data[filtAddr])
                                {
                                case 1:
                                    diffTex.FilterType = 2;           //FILTER_NADA
                                    break;

                                case 2:
                                    diffTex.FilterType = 1;          //FILTER_SAT
                                    break;

                                default:
                                    diffTex.FilterType = 0;          //FILTER_PYR
                                    break;
                                }
                                diffTex.UVGen.SetFlag(1 << 2, ~(data[filtAddr + 1] | 0xfffffffe));
                                diffTex.UVGen.SetFlag(1 << 0, ~(data[filtAddr + 1] | 0xfffffffd));
                                diffTex.UVGen.SetFlag(1 << 3, ~(data[filtAddr + 1] | 0xffffffef));
                                diffTex.UVGen.SetFlag(1 << 1, ~(data[filtAddr + 1] | 0xffffffdf));

                                leMat.GetParamBlock(0).SetValue(10, 0, diffTex, 0);
                                datIndex += 16;         //for some reason zero size extension contains data 00 00 00 00
                            }
                        }
                        break;

                        case (uint)secIDs.REFLECTION_MATERIAL:
                        {
                            datIndex += 8;
                            leMat.GetParamBlock(0).SetValue(12, 0, global.Color.Create(ReadSingle(), ReadSingle(), ReadSingle()), 0);
                            leMat.GetParamBlock(0).SetValue(15, 0, 255.0f * ReadSingle(), 0);
                            leMat.GetParamBlock(0).SetValue(17, 0, ReadSingle(), 0);
                            datIndex += 4;      //skip unknown
                        }
                        break;

                        case (uint)secIDs.SPECULAR_MATERIAL:
                        {
                            int secSize = ReadInt32() - 4;         //section size-4 because the float read in ReadSingle() takes up 4 bytes
                            datIndex += 4;
                            leMat.GetParamBlock(0).SetValue(16, 0, 255.0f * ReadSingle(), 0);
                            IBitmapTex diffTex = (IBitmapTex)ip.CreateInstance(SClass_ID.Texmap, global.Class_ID.Create((uint)BuiltInClassIDA.BMTEX_CLASS_ID, 0));
                            diffTex.Name = ReadString(ref secSize);     //-4 because the float read in ReadSingle() takes up 4 bytes
                            //MessageBox.Show(diffTex.Name);
                            //MessageBox.Show(datIndex.ToString());
                            leMat.GetParamBlock(0).SetValue(13, 0, diffTex, 0);
                        }
                        break;

                        default:
                            datIndex -= 4;
                            break;
                        }
                    }
                }
                else
                {
                    datIndex -= 4;
                }
            }
            // skip extension
            if (ReadUInt32() == (uint)secIDs.EXTENSION)
            {
                int temp = ReadInt32();
                datIndex += temp + 4;
            }
            else
            {
                datIndex -= 4;
            }
        }
Example #26
0
 /// <summary>
 /// Initializes a new instance of the MaterialWrapper class.
 /// </summary>
 /// <param name="material">The IMtl object to wrap.</param>
 public MaterialWrapper(IMtl material)
 {
    Throw.IfNull(material, "material");
    
    this.Material = material;
 }
        private void ExportMaterial(IMtl materialNode, BabylonScene babylonScene)
        {
            var name = materialNode.Name;
            var id   = materialNode.GetGuid().ToString();

            RaiseMessage(name, 1);

            if (materialNode.NumSubMtls > 0)
            {
                var babylonMultimaterial = new BabylonMultiMaterial {
                    name = name, id = id
                };

                var guids = new List <string>();

                for (var index = 0; index < materialNode.NumSubMtls; index++)
                {
                    var subMat = materialNode.GetSubMtl(index);

                    if (subMat != null)
                    {
                        guids.Add(subMat.GetGuid().ToString());

                        if (!referencedMaterials.Contains(subMat))
                        {
                            referencedMaterials.Add(subMat);
                            ExportMaterial(subMat, babylonScene);
                        }
                    }
                    else
                    {
                        guids.Add(Guid.Empty.ToString());
                    }
                }

                babylonMultimaterial.materials = guids.ToArray();

                babylonScene.MultiMaterialsList.Add(babylonMultimaterial);
                return;
            }


            var babylonMaterial = new BabylonMaterial
            {
                name          = name,
                id            = id,
                ambient       = materialNode.GetAmbient(0, false).ToArray(),
                diffuse       = materialNode.GetDiffuse(0, false).ToArray(),
                specular      = materialNode.GetSpecular(0, false).Scale(materialNode.GetShinStr(0, false)),
                specularPower = materialNode.GetShininess(0, false) * 256,
                emissive      =
                    materialNode.GetSelfIllumColorOn(0, false)
                        ? materialNode.GetSelfIllumColor(0, false).ToArray()
                        : materialNode.GetDiffuse(0, false).Scale(materialNode.GetSelfIllum(0, false)),
                alpha = 1.0f - materialNode.GetXParency(0, false)
            };


            var stdMat = materialNode.GetParamBlock(0).Owner as IStdMat2;

            if (stdMat != null)
            {
                babylonMaterial.backFaceCulling = !stdMat.TwoSided;
                babylonMaterial.wireframe       = stdMat.Wire;

                // Textures
                BabylonFresnelParameters fresnelParameters;

                babylonMaterial.ambientTexture = ExportTexture(stdMat, 0, out fresnelParameters, babylonScene);                // Ambient
                babylonMaterial.diffuseTexture = ExportTexture(stdMat, 1, out fresnelParameters, babylonScene);                // Diffuse
                if (fresnelParameters != null)
                {
                    babylonMaterial.diffuseFresnelParameters = fresnelParameters;
                }

                babylonMaterial.specularTexture = ExportTexture(stdMat, 2, out fresnelParameters, babylonScene);               // Specular
                babylonMaterial.emissiveTexture = ExportTexture(stdMat, 5, out fresnelParameters, babylonScene);               // Emissive
                if (fresnelParameters != null)
                {
                    babylonMaterial.emissiveFresnelParameters = fresnelParameters;
                    if (babylonMaterial.emissive[0] == 0 &&
                        babylonMaterial.emissive[1] == 0 &&
                        babylonMaterial.emissive[2] == 0)
                    {
                        babylonMaterial.emissive = new float[] { 1, 1, 1 };
                    }
                }

                babylonMaterial.opacityTexture = ExportTexture(stdMat, 6, out fresnelParameters, babylonScene, false, true);   // Opacity
                if (fresnelParameters != null)
                {
                    babylonMaterial.opacityFresnelParameters = fresnelParameters;
                }

                babylonMaterial.bumpTexture       = ExportTexture(stdMat, 8, out fresnelParameters, babylonScene);             // Bump
                babylonMaterial.reflectionTexture = ExportTexture(stdMat, 9, out fresnelParameters, babylonScene, true);       // Reflection
                if (fresnelParameters != null)
                {
                    if (babylonMaterial.reflectionTexture == null)
                    {
                        RaiseWarning("Fallout cannot be used with reflection channel without a texture", 2);
                    }
                    else
                    {
                        babylonMaterial.reflectionFresnelParameters = fresnelParameters;
                    }
                }

                // 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.opacityTexture != null && babylonMaterial.diffuseTexture != null &&
                    babylonMaterial.diffuseTexture.name == babylonMaterial.opacityTexture.name &&
                    babylonMaterial.diffuseTexture.hasAlpha && !babylonMaterial.opacityTexture.getAlphaFromRGB)
                {
                    // This is a alpha testing purpose
                    babylonMaterial.opacityTexture          = null;
                    babylonMaterial.diffuseTexture.hasAlpha = true;
                    RaiseWarning("Opacity texture was removed because alpha from diffuse texture can be use instead", 2);
                    RaiseWarning("If you do not want this behavior, just set Alpha Source = None on your diffuse texture", 2);
                }
            }

            babylonScene.MaterialsList.Add(babylonMaterial);
        }
 public static bool IsFlightSimMaterial(IMtl mat)
 {
     return(mat != null && class_ID.Equals(mat.ClassID));
 }
        private void ExportMaterial(IMtl materialNode, BabylonScene babylonScene)
        {
            var name = materialNode.Name;
            var id = materialNode.GetGuid().ToString();

            RaiseMessage(name, 1);

            if (materialNode.NumSubMtls > 0)
            {
                var babylonMultimaterial = new BabylonMultiMaterial();
                babylonMultimaterial.name = name;
                babylonMultimaterial.id = id;

                var guids = new List<string>();

                for (var index = 0; index < materialNode.NumSubMtls; index++)
                {
                    var subMat = materialNode.GetSubMtl(index);

                    if (subMat != null)
                    {
                        guids.Add(subMat.GetGuid().ToString());

                        if (!referencedMaterials.Contains(subMat))
                        {
                            referencedMaterials.Add(subMat);
                            ExportMaterial(subMat, babylonScene);
                        }
                    }
                    else
                    {
                        guids.Add(Guid.Empty.ToString());
                    }
                }

                babylonMultimaterial.materials = guids.ToArray();

                babylonScene.MultiMaterialsList.Add(babylonMultimaterial);
                return;
            }


            var babylonMaterial = new BabylonMaterial();
            babylonMaterial.name = name;
            babylonMaterial.id = id;

            

            babylonMaterial.ambient = materialNode.GetAmbient(0, false).ToArray();
            babylonMaterial.diffuse = materialNode.GetDiffuse(0, false).ToArray();
            babylonMaterial.specular = materialNode.GetSpecular(0, false).Scale(materialNode.GetShinStr(0, false));
            babylonMaterial.specularPower = materialNode.GetShininess(0, false) * 256;

            babylonMaterial.emissive = materialNode.GetSelfIllumColorOn(0, false) ? materialNode.GetSelfIllumColor(0, false).ToArray() : materialNode.GetDiffuse(0, false).Scale(materialNode.GetSelfIllum(0, false));
            babylonMaterial.alpha = 1.0f - materialNode.GetXParency(0, false);

            var stdMat = materialNode.GetParamBlock(0).Owner as IStdMat2;

            if (stdMat != null)
            {
                babylonMaterial.backFaceCulling = !stdMat.TwoSided;
                babylonMaterial.wireframe = stdMat.Wire;

                // Textures
                babylonMaterial.ambientTexture = ExportTexture(stdMat, 0, babylonScene);                // Ambient
                babylonMaterial.diffuseTexture = ExportTexture(stdMat, 1, babylonScene);                // Diffuse
                babylonMaterial.specularTexture = ExportTexture(stdMat, 2, babylonScene);               // Specular
                babylonMaterial.emissiveTexture = ExportTexture(stdMat, 5, babylonScene);               // Emissive
                babylonMaterial.opacityTexture = ExportTexture(stdMat, 6, babylonScene, false, true);   // Opacity
                babylonMaterial.bumpTexture = ExportTexture(stdMat, 8, babylonScene);                   // Bump
                babylonMaterial.reflectionTexture = ExportTexture(stdMat, 9, babylonScene, true);       // Reflection

                // 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.opacityTexture != null && babylonMaterial.diffuseTexture != null &&
                    babylonMaterial.diffuseTexture.name == babylonMaterial.opacityTexture.name &&
                    babylonMaterial.diffuseTexture.hasAlpha && !babylonMaterial.opacityTexture.getAlphaFromRGB)
                {
                    // This is a alpha testing purpose
                    babylonMaterial.opacityTexture = null;
                    babylonMaterial.diffuseTexture.hasAlpha = true;
                    RaiseWarning("Opacity texture was removed because alpha from diffuse texture can be use instead", 2);
                    RaiseWarning("If you do not want this behavior, just set Alpha Source = None on your diffuse texture", 2);
                }
            }

            babylonScene.MaterialsList.Add(babylonMaterial);
        }
        private void ExportMaterial(BabylonMaterial babylonMaterial, GLTF gltf)
        {
            var name = babylonMaterial.name;
            var id = babylonMaterial.id;
            RaiseMessage("GLTFExporter.Material | Export material named: " + name, 1);

            GLTFMaterial gltfMaterial = null;
            IIGameMaterial gameMtl = babylonMaterial.maxGameMaterial;
            IMtl maxMtl = gameMtl.MaxMaterial;

            IMaterialExporter materialExporter;
            if (materialExporters.TryGetValue(new ClassIDWrapper(maxMtl.ClassID), out materialExporter)
                && materialExporter is IGLTFMaterialExporter)
            {
                gltfMaterial = ((IGLTFMaterialExporter)materialExporter).ExportGLTFMaterial(this, gltf, gameMtl,
                    (string sourcePath, string textureName) => { return TryWriteImage(gltf, sourcePath, textureName); },
                    (string message, Color color) => { RaiseMessage(message, color, 2); },
                    (string message) => { RaiseWarning(message, 2); },
                    (string message) => { RaiseError(message, 2); });

                if (gltfMaterial == null)
                {
                    string message = string.Format("Custom glTF material exporter failed to export | Exporter: '{0}' | Material Name: '{1}' | Material Class: '{2}'",
                        materialExporter.GetType().ToString(), gameMtl.MaterialName, gameMtl.ClassName);
                    RaiseWarning(message, 2);
                }
                else
                {
                    gltfMaterial.index = gltf.MaterialsList.Count;
                    gltf.MaterialsList.Add(gltfMaterial);
                }
            }
            else if (babylonMaterial.GetType() == typeof(BabylonStandardMaterial))
            {
                var babylonStandardMaterial = babylonMaterial as BabylonStandardMaterial;


                // --- prints ---
                #region prints

                RaiseVerbose("GLTFExporter.Material | babylonMaterial data", 2);
                RaiseVerbose("GLTFExporter.Material | babylonMaterial.alpha=" + babylonMaterial.alpha, 3);
                RaiseVerbose("GLTFExporter.Material | babylonMaterial.alphaMode=" + babylonMaterial.alphaMode, 3);
                RaiseVerbose("GLTFExporter.Material | babylonMaterial.backFaceCulling=" + babylonMaterial.backFaceCulling, 3);
                RaiseVerbose("GLTFExporter.Material | babylonMaterial.wireframe=" + babylonMaterial.wireframe, 3);

                // Ambient
                for (int i = 0; i < babylonStandardMaterial.ambient.Length; i++)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.ambient[" + i + "]=" + babylonStandardMaterial.ambient[i], 3);
                }

                // Diffuse
                RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.diffuse.Length=" + babylonStandardMaterial.diffuse.Length, 3);
                for (int i = 0; i < babylonStandardMaterial.diffuse.Length; i++)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.diffuse[" + i + "]=" + babylonStandardMaterial.diffuse[i], 3);
                }
                if (babylonStandardMaterial.diffuseTexture == null)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.diffuseTexture=null", 3);
                }
                else
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.diffuseTexture.name=" + babylonStandardMaterial.diffuseTexture.name, 3);
                }

                // Normal / bump
                if (babylonStandardMaterial.bumpTexture == null)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.bumpTexture=null", 3);
                }
                else
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.bumpTexture.name=" + babylonStandardMaterial.bumpTexture.name, 3);
                }

                // Opacity
                if (babylonStandardMaterial.opacityTexture == null)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.opacityTexture=null", 3);
                }
                else
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.opacityTexture.name=" + babylonStandardMaterial.opacityTexture.name, 3);
                }

                // Specular
                for (int i = 0; i < babylonStandardMaterial.specular.Length; i++)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.specular[" + i + "]=" + babylonStandardMaterial.specular[i], 3);
                }
                RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.specularPower=" + babylonStandardMaterial.specularPower, 3);
                if (babylonStandardMaterial.specularTexture == null)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.specularTexture=null", 3);
                }
                else
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.specularTexture.name=" + babylonStandardMaterial.specularTexture.name, 3);
                }

                // Occlusion
                if (babylonStandardMaterial.ambientTexture == null)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.ambientTexture=null", 3);
                }
                else
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.ambientTexture.name=" + babylonStandardMaterial.ambientTexture.name, 3);
                }

                // Emissive
                for (int i = 0; i < babylonStandardMaterial.emissive.Length; i++)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.emissive[" + i + "]=" + babylonStandardMaterial.emissive[i], 3);
                }
                if (babylonStandardMaterial.emissiveTexture == null)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.emissiveTexture=null", 3);
                }
                else
                {
                    RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.emissiveTexture.name=" + babylonStandardMaterial.emissiveTexture.name, 3);
                }
                #endregion


                // --------------------------------
                // --------- gltfMaterial ---------
                // --------------------------------

                RaiseMessage("GLTFExporter.Material | create gltfMaterial", 2);
                gltfMaterial = new GLTFMaterial
                {
                    name = name
                };
                gltfMaterial.id = babylonMaterial.id;
                gltfMaterial.index = gltf.MaterialsList.Count;
                gltf.MaterialsList.Add(gltfMaterial);

                // Alpha
                string alphaMode;
                float? alphaCutoff;
                getAlphaMode(babylonStandardMaterial, out alphaMode, out alphaCutoff);
                gltfMaterial.alphaMode = alphaMode;
                gltfMaterial.alphaCutoff = alphaCutoff;

                // DoubleSided
                gltfMaterial.doubleSided = !babylonMaterial.backFaceCulling;

                // Normal
                gltfMaterial.normalTexture = ExportTexture(babylonStandardMaterial.bumpTexture, gltf);

                // Occulison
                gltfMaterial.occlusionTexture = ExportTexture(babylonStandardMaterial.ambientTexture, gltf);

                // Emissive
                gltfMaterial.emissiveFactor = babylonStandardMaterial.emissive;
                // linkEmissiveWithDiffuse attribute doesn't have an equivalent in gltf format
                // When true, the emissive texture needs to be manually multiplied with diffuse texture
                // Otherwise, the emissive texture is assumed to be already pre-multiplied
                if (babylonStandardMaterial.linkEmissiveWithDiffuse)
                {
                    // Even when no emissive texture is provided, the self illumination value needs to be multiplied to the diffuse texture in order to get the pre-multiplied emissive (texture)
                    if (babylonStandardMaterial.emissiveTexture != null || babylonStandardMaterial.selfIllum > 0)
                    {
                        // Default emissive is the raw value of the self illumination
                        // It is not the babylon emissive value which is already pre-multiplied with diffuse color
                        float[] defaultEmissive = new float[] { 1, 1, 1 }.Multiply(babylonStandardMaterial.selfIllum);
                        gltfMaterial.emissiveTexture = ExportEmissiveTexture(babylonStandardMaterial, gltf, defaultEmissive, babylonStandardMaterial.diffuse);
                    }
                }
                else
                {
                    gltfMaterial.emissiveTexture = ExportTexture(babylonStandardMaterial.emissiveTexture, gltf);
                }

                // Constraints
                if (gltfMaterial.emissiveTexture != null)
                {
                    gltfMaterial.emissiveFactor = new[] { 1.0f, 1.0f, 1.0f };
                }

                // --------------------------------
                // --- gltfPbrMetallicRoughness ---
                // --------------------------------

                RaiseMessage("GLTFExporter.Material | create gltfPbrMetallicRoughness", 2);
                var gltfPbrMetallicRoughness = new GLTFPBRMetallicRoughness();
                gltfMaterial.pbrMetallicRoughness = gltfPbrMetallicRoughness;

                // --- Global ---

                // Eye Ball correction to limit overall brightness from std to PBR.
                // This only impacts the factors.
                var correctedDiffuse = new BabylonColor3(babylonStandardMaterial.diffuse).scale(0.5f);

                SpecularGlossiness _specularGlossiness = new SpecularGlossiness
                {
                    diffuse = correctedDiffuse,
                    opacity = babylonMaterial.alpha,
                    specular = new BabylonColor3(babylonStandardMaterial.specular),
                    glossiness = babylonStandardMaterial.specularPower / 256
                };

                MetallicRoughness _metallicRoughness = ConvertToMetallicRoughness(_specularGlossiness, true);

                // Base color
                gltfPbrMetallicRoughness.baseColorFactor = new float[4]
                {
                    _metallicRoughness.baseColor.r,
                    _metallicRoughness.baseColor.g,
                    _metallicRoughness.baseColor.b,
                    _metallicRoughness.opacity
                };

                // Metallic roughness
                gltfPbrMetallicRoughness.metallicFactor = _metallicRoughness.metallic;
                gltfPbrMetallicRoughness.roughnessFactor = _metallicRoughness.roughness;


                // --- Textures ---
                var babylonTexture = babylonStandardMaterial.diffuseTexture != null ? babylonStandardMaterial.diffuseTexture :
                                     babylonStandardMaterial.specularTexture != null ? babylonStandardMaterial.specularTexture :
                                     babylonStandardMaterial.opacityTexture != null ? babylonStandardMaterial.opacityTexture :
                                     null;

                if (babylonTexture != null)
                {
                    //Check if the texture already exist
                    var _key = SetStandText(babylonStandardMaterial);

                    bool isAlphaInTexture = (isTextureOk(babylonStandardMaterial.diffuseTexture) && babylonStandardMaterial.diffuseTexture.hasAlpha) ||
                                              isTextureOk(babylonStandardMaterial.opacityTexture);

                    Bitmap baseColorBitmap = null;
                    Bitmap metallicRoughnessBitmap = null;

                    GLTFTextureInfo textureInfoBC = new GLTFTextureInfo();
                    GLTFTextureInfo textureInfoMR = new GLTFTextureInfo();

                    if (exportParameters.writeTextures)
                    {
                        // Diffuse
                        Bitmap diffuseBitmap = null;
                        if (babylonStandardMaterial.diffuseTexture != null)
                        {
                            diffuseBitmap = LoadTexture(babylonStandardMaterial.diffuseTexture.originalPath);
                        }

                        // Specular
                        Bitmap specularBitmap = null;
                        if (babylonStandardMaterial.specularTexture != null)
                        {
                            if (babylonStandardMaterial.specularTexture.bitmap != null)
                            {
                                // Specular color map has been computed by the exporter
                                specularBitmap = babylonStandardMaterial.specularTexture.bitmap;
                            }
                            else
                            {
                                // Specular color map is straight input
                                specularBitmap = LoadTexture(babylonStandardMaterial.specularTexture.originalPath);
                            }
                        }

                        // Opacity / Alpha / Transparency
                        Bitmap opacityBitmap = null;
                        if ((babylonStandardMaterial.diffuseTexture == null || babylonStandardMaterial.diffuseTexture.hasAlpha == false) && babylonStandardMaterial.opacityTexture != null)
                        {
                            opacityBitmap = LoadTexture(babylonStandardMaterial.opacityTexture.originalPath);
                        }

                        if (diffuseBitmap != null || specularBitmap != null || opacityBitmap != null)
                        {
                            // Retreive dimensions
                            int width = 0;
                            int height = 0;
                            var haveSameDimensions = _getMinimalBitmapDimensions(out width, out height, diffuseBitmap, specularBitmap, opacityBitmap);
                            if (!haveSameDimensions)
                            {
                                RaiseError("Diffuse, specular and opacity maps should have same dimensions", 2);
                            }

                            // Create baseColor+alpha and metallic+roughness maps
                            baseColorBitmap = new Bitmap(width, height);
                            metallicRoughnessBitmap = new Bitmap(width, height);
                            for (int x = 0; x < width; x++)
                            {
                                for (int y = 0; y < height; y++)
                                {
                                    SpecularGlossiness specularGlossinessTexture = new SpecularGlossiness
                                    {
                                        diffuse = diffuseBitmap != null ? new BabylonColor3(diffuseBitmap.GetPixel(x, y)) :
                                                    _specularGlossiness.diffuse,
                                        opacity = diffuseBitmap != null && babylonStandardMaterial.diffuseTexture.hasAlpha ? diffuseBitmap.GetPixel(x, y).A / 255.0f :
                                                    opacityBitmap != null && babylonStandardMaterial.opacityTexture.getAlphaFromRGB ? opacityBitmap.GetPixel(x, y).R / 255.0f :
                                                    opacityBitmap != null && babylonStandardMaterial.opacityTexture.getAlphaFromRGB == false ? opacityBitmap.GetPixel(x, y).A / 255.0f :
                                                    _specularGlossiness.opacity,
                                        specular = specularBitmap != null ? new BabylonColor3(specularBitmap.GetPixel(x, y)) :
                                                    _specularGlossiness.specular,
                                        glossiness = babylonStandardMaterial.useGlossinessFromSpecularMapAlpha && specularBitmap != null ? specularBitmap.GetPixel(x, y).A / 255.0f :
                                                        _specularGlossiness.glossiness
                                    };

                                    var displayPrints = x == width / 2 && y == height / 2;
                                    MetallicRoughness metallicRoughnessTexture = ConvertToMetallicRoughness(specularGlossinessTexture, displayPrints);

                                    Color colorBase = Color.FromArgb(
                                        (int)(metallicRoughnessTexture.opacity * 255),
                                        (int)(metallicRoughnessTexture.baseColor.r * 255),
                                        (int)(metallicRoughnessTexture.baseColor.g * 255),
                                        (int)(metallicRoughnessTexture.baseColor.b * 255)
                                    );
                                    baseColorBitmap.SetPixel(x, y, colorBase);

                                    // The metalness values are sampled from the B channel.
                                    // The roughness values are sampled from the G channel.
                                    // These values are linear. If other channels are present (R or A), they are ignored for metallic-roughness calculations.
                                    Color colorMetallicRoughness = Color.FromArgb(
                                        0,
                                        (int)(metallicRoughnessTexture.roughness * 255),
                                        (int)(metallicRoughnessTexture.metallic * 255)
                                    );
                                    metallicRoughnessBitmap.SetPixel(x, y, colorMetallicRoughness);
                                }
                            }
                        }
                    }

                    //export textures
                    textureInfoBC = ExportBitmapTexture(gltf, babylonTexture, baseColorBitmap, babylonTexture.name);
                    gltfPbrMetallicRoughness.baseColorTexture = textureInfoBC;

                    // If no specular map is defined, the metallic and roughness values are be driven by the global parameters
                    if (babylonStandardMaterial.specularTexture != null)
                    {
                        textureInfoMR = ExportBitmapTexture(gltf, babylonTexture, metallicRoughnessBitmap, babylonMaterial.name + "_metallicRoughness" + ".jpg");
                        gltfPbrMetallicRoughness.metallicRoughnessTexture = textureInfoMR;
                    }

                    //register the texture
                    AddStandText(_key, textureInfoBC, textureInfoMR);
                }
            }
            else if (babylonMaterial.GetType() == typeof(BabylonPBRMetallicRoughnessMaterial))
            {
                var babylonPBRMetallicRoughnessMaterial = babylonMaterial as BabylonPBRMetallicRoughnessMaterial;
                // --- prints ---
                #region prints

                RaiseVerbose("GLTFExporter.Material | babylonMaterial data", 2);
                RaiseVerbose("GLTFExporter.Material | babylonMaterial.alpha=" + babylonMaterial.alpha, 3);
                RaiseVerbose("GLTFExporter.Material | babylonMaterial.alphaMode=" + babylonMaterial.alphaMode, 3);
                RaiseVerbose("GLTFExporter.Material | babylonMaterial.backFaceCulling=" + babylonMaterial.backFaceCulling, 3);
                RaiseVerbose("GLTFExporter.Material | babylonMaterial.wireframe=" + babylonMaterial.wireframe, 3);

                // Global
                RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.maxSimultaneousLights=" + babylonPBRMetallicRoughnessMaterial.maxSimultaneousLights, 3);
                RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.disableLighting=" + babylonPBRMetallicRoughnessMaterial.disableLighting, 3);
                RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.alphaCutOff=" + babylonPBRMetallicRoughnessMaterial.alphaCutOff, 3);
                RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.transparencyMode=" + babylonPBRMetallicRoughnessMaterial.transparencyMode, 3);
                RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.doubleSided=" + babylonPBRMetallicRoughnessMaterial.doubleSided, 3);

                // Base color
                RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.baseColor.Length=" + babylonPBRMetallicRoughnessMaterial.baseColor.Length, 3);
                for (int i = 0; i < babylonPBRMetallicRoughnessMaterial.baseColor.Length; i++)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.baseColor[" + i + "]=" + babylonPBRMetallicRoughnessMaterial.baseColor[i], 3);
                }
                if (babylonPBRMetallicRoughnessMaterial.baseTexture == null)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.baseTexture=null", 3);
                }

                // Metallic+roughness
                RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.metallic=" + babylonPBRMetallicRoughnessMaterial.metallic, 3);
                RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.roughness=" + babylonPBRMetallicRoughnessMaterial.roughness, 3);
                if (babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture == null)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture=null", 3);
                }

                // Normal / bump
                if (babylonPBRMetallicRoughnessMaterial.normalTexture == null)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.normalTexture=null", 3);
                }
                RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.invertNormalMapX=" + babylonPBRMetallicRoughnessMaterial.invertNormalMapX, 3);
                RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.invertNormalMapY=" + babylonPBRMetallicRoughnessMaterial.invertNormalMapY, 3);

                // Emissive
                for (int i = 0; i < babylonPBRMetallicRoughnessMaterial.emissive.Length; i++)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.emissiveColor[" + i + "]=" + babylonPBRMetallicRoughnessMaterial.emissive[i], 3);
                }
                if (babylonPBRMetallicRoughnessMaterial.emissiveTexture == null)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.emissiveTexture=null", 3);
                }

                // Ambient occlusion
                RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.occlusionStrength=" + babylonPBRMetallicRoughnessMaterial.occlusionStrength, 3);
                if (babylonPBRMetallicRoughnessMaterial.occlusionTexture == null)
                {
                    RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.occlusionTexture=null", 3);
                }
                #endregion


                // --------------------------------
                // --------- gltfMaterial ---------
                // --------------------------------

                RaiseMessage("GLTFExporter.Material | create gltfMaterial", 2);
                gltfMaterial = new GLTFMaterial
                {
                    name = name
                };
                gltfMaterial.id = babylonMaterial.id;
                gltfMaterial.index = gltf.MaterialsList.Count;
                gltf.MaterialsList.Add(gltfMaterial);

                // Alpha
                string alphaMode;
                float? alphaCutoff;
                getAlphaMode(babylonPBRMetallicRoughnessMaterial, out alphaMode, out alphaCutoff);
                gltfMaterial.alphaMode = alphaMode;
                gltfMaterial.alphaCutoff = alphaCutoff;

                // DoubleSided
                gltfMaterial.doubleSided = babylonPBRMetallicRoughnessMaterial.doubleSided;

                // Normal
                gltfMaterial.normalTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.normalTexture, gltf);

                // Occlusion
                if (babylonPBRMetallicRoughnessMaterial.occlusionTexture != null)
                {
                    if (babylonPBRMetallicRoughnessMaterial.occlusionTexture.bitmap != null)
                    {
                        // ORM texture has been merged manually by the exporter
                        // Occlusion is defined as well as metallic and/or roughness
                        RaiseVerbose("Occlusion is defined as well as metallic and/or roughness", 2);
                        gltfMaterial.occlusionTexture = ExportBitmapTexture(gltf, babylonPBRMetallicRoughnessMaterial.occlusionTexture);
                    }
                    else
                    {
                        // ORM texture was already merged or only occlusion is defined
                        RaiseVerbose("ORM texture was already merged or only occlusion is defined", 2);
                        gltfMaterial.occlusionTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.occlusionTexture, gltf);
                    }
                }

                // Emissive
                gltfMaterial.emissiveFactor = babylonPBRMetallicRoughnessMaterial.emissive;
                gltfMaterial.emissiveTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.emissiveTexture, gltf);


                // --------------------------------
                // --- gltfPbrMetallicRoughness ---
                // --------------------------------

                RaiseMessage("GLTFExporter.Material | create gltfPbrMetallicRoughness", 2);
                var gltfPbrMetallicRoughness = new GLTFPBRMetallicRoughness();
                gltfMaterial.pbrMetallicRoughness = gltfPbrMetallicRoughness;

                // --- Global ---

                // Base color
                gltfPbrMetallicRoughness.baseColorFactor = new float[4]
                {
                    babylonPBRMetallicRoughnessMaterial.baseColor[0],
                    babylonPBRMetallicRoughnessMaterial.baseColor[1],
                    babylonPBRMetallicRoughnessMaterial.baseColor[2],
                    babylonPBRMetallicRoughnessMaterial.alpha
                };
                if (babylonPBRMetallicRoughnessMaterial.baseTexture != null)
                {
                    if (babylonPBRMetallicRoughnessMaterial.baseTexture.bitmap != null)
                    {
                        gltfPbrMetallicRoughness.baseColorTexture = ExportBitmapTexture(gltf, babylonPBRMetallicRoughnessMaterial.baseTexture);
                    }
                    else
                    {
                        gltfPbrMetallicRoughness.baseColorTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.baseTexture, gltf);
                    }
                }

                // Metallic roughness
                gltfPbrMetallicRoughness.metallicFactor = babylonPBRMetallicRoughnessMaterial.metallic;
                gltfPbrMetallicRoughness.roughnessFactor = babylonPBRMetallicRoughnessMaterial.roughness;
                if (babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture != null)
                {
                    if (babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture == babylonPBRMetallicRoughnessMaterial.occlusionTexture)
                    {
                        // Occlusion is defined as well as metallic and/or roughness
                        // Use same texture
                        RaiseVerbose("Occlusion is defined as well as metallic and/or roughness", 2);
                        gltfPbrMetallicRoughness.metallicRoughnessTexture = gltfMaterial.occlusionTexture;
                    }
                    else
                    {
                        // Occlusion is not defined, only metallic and/or roughness
                        RaiseVerbose("Occlusion is not defined, only metallic and/or roughness", 2);

                        if (babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture.bitmap != null)
                        {
                            // Metallic & roughness texture has been merged manually by the exporter
                            // Write bitmap file
                            RaiseVerbose("Metallic & roughness texture has been merged manually by the exporter", 2);
                            gltfPbrMetallicRoughness.metallicRoughnessTexture = ExportBitmapTexture(gltf, babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture);
                        }
                        else
                        {

                            // Metallic & roughness texture was already merged
                            // Copy file
                            RaiseVerbose("Metallic & roughness texture was already merged", 2);
                            gltfPbrMetallicRoughness.metallicRoughnessTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture, gltf);
                        }
                    }
                }
            }
            else
            {
                RaiseWarning("GLTFExporter.Material | Unsupported material type: " + babylonMaterial.GetType() + " | Max MaterialClass: " + babylonMaterial.maxGameMaterial.ClassName, 2);
            }

            if (gltfMaterial != null && babylonMaterial.isUnlit)
            {
                // Add Unlit extension
                if (!exportParameters.enableKHRMaterialsUnlit)
                {
                    RaiseWarning("GLTFExporter.Material | KHR_materials_unlit has not been enabled for export!", 2);
                }
                else
                {
                    if (gltfMaterial.extensions == null)
                    {
                        gltfMaterial.extensions = new GLTFExtensions();
                    }
                    if (gltf.extensionsUsed == null)
                    {
                        gltf.extensionsUsed = new System.Collections.Generic.List<string>();
                    }
                    if (!gltf.extensionsUsed.Contains("KHR_materials_unlit"))
                    {
                        gltf.extensionsUsed.Add("KHR_materials_unlit");
                    }
                    gltfMaterial.extensions["KHR_materials_unlit"] = new object();
                }
            }
        }
Example #31
0
 internal Material(IMtl x) : base(x) { }
Example #32
0
        public static IINode FlattenHierarchy(this IINode node)
        {
            IILayer nodeLayer = LayerUtilities.GetNodeLayer(node);

            if (nodeLayer != null)
            {
                Loader.Core.LayerManager.SetCurrentLayer(nodeLayer.Name);
            }


            List <IINode> children        = node.NodeTree().ToList();
            List <IINode> nonMeshChildren = children.Where(x => !x.IsMesh()).ToList();
            List <IINode> meshChildren    = children.Where(x => x.IsMesh()).ToList();

            IClass_ID cid    = Loader.Global.Class_ID.Create((uint)BuiltInClassIDA.SPHERE_CLASS_ID, 0);
            object    obj    = Loader.Core.CreateInstance(SClass_ID.Geomobject, cid as IClass_ID);
            IINode    result = Loader.Core.CreateObjectNode((IObject)obj);

            result.Name = node.Name;
            result.SetNodeTM(Loader.Core.Time, node.GetNodeTM(Loader.Core.Time, Forever));
            node.ParentNode.AttachChild(result, true);

            string convertToEditablePoly = $"ConvertTo (maxOps.getNodeByHandle {result.Handle}) Editable_Poly";

            ScriptsUtilities.ExecuteMaxScriptCommand(convertToEditablePoly);

            IPolyObject polyObject  = result.GetPolyObjectFromNode();
            IEPoly      nodeEPoly   = (IEPoly)polyObject.GetInterface(Loader.EditablePoly);
            List <IMtl> newMultiMat = new List <IMtl>();

            foreach (IINode n in meshChildren)
            {
                ITriObject triObject = n.GetTriObjectFromNode();
                IMesh      mesh      = triObject.Mesh;
                if (n.Mtl.IsMultiMtl)
                {
                    Dictionary <IMtl, List <IFace> > matIDtoFacesMap = new Dictionary <IMtl, List <IFace> >();
                    ////List<int> matIDsInUse = new List<int>();

                    foreach (IFace face in mesh.Faces)
                    {
                        int  faceMatID = face.MatID;
                        IMtl mat       = n.Mtl.GetSubMtl(faceMatID);
                        if (!matIDtoFacesMap.ContainsKey(mat))
                        {
                            List <IFace> facesOfMat = new List <IFace>();
                            matIDtoFacesMap.Add(mat, facesOfMat);
                        }
                        matIDtoFacesMap[mat].Add(face);
                    }

                    foreach (KeyValuePair <IMtl, List <IFace> > matToFaceKeyValue in matIDtoFacesMap)
                    {
                        IMtl faceMat = matToFaceKeyValue.Key; //get the material from the list of the multimaterial
                        if (!newMultiMat.Contains(faceMat))
                        {
                            newMultiMat.Add(faceMat);
                        }
                        ushort newId = (ushort)(newMultiMat.IndexOf(faceMat));
                        foreach (IFace face in matToFaceKeyValue.Value)
                        {
                            face.MatID = newId;
                        }
                    }
                }
                else
                {
                    //IMtl currentMat = n.Mtl;
                    //int matID = newMultiMat.IndexOf(currentMat);
                    //if (matID == -1)
                    //{
                    //    newMultiMat.Add(currentMat);
                    //    ushort newId = (ushort)newMultiMat.Count;
                    //    for (int fID = 0; fID < mesh.NumFaces; fID++)
                    //    {
                    //        mesh.SetFaceMtlIndex(fID, (ushort)newId);
                    //    }
                    //}
                    //else
                    //{
                    //    for (int fID = 0; fID < mesh.NumFaces; fID++)
                    //    {
                    //        mesh.SetFaceMtlIndex(fID, (ushort)matID);
                    //    }
                    //}
                }

                triObject.Mesh = mesh;
                n.ObjectRef    = triObject;
                //bool undo = false;
                //nodeEPoly.EpfnAttach(n, ref undo,result, Loader.Core.Time);
            }

            IClass_ID matCid   = Loader.Global.Class_ID.Create((uint)BuiltInClassIDA.MULTI_MATERIAL_CLASS_ID, 0);
            IMtl      finalMat = (IMtl)Loader.Core.CreateInstance(SClass_ID.Material, matCid);

            for (int i = 0; i < newMultiMat.Count; i++)
            {
                finalMat.SetSubMtl(i, newMultiMat[i]);
            }
            finalMat.Name = "final mat";
            result.Mtl    = finalMat;

            foreach (IINode n in nonMeshChildren)
            {
                result.AttachChild(n, true);
            }

            Loader.Core.DeleteNode(node, false, false);

            return(result);
        }
Example #33
0
        public void LoadFromData(string propertyName, IINode dataNode, Dictionary <string, string> rootNodePropDictionary = null)
        {
            if (!Guid.TryParse(propertyName, out serializedId))
            {
                throw new Exception("Invalid ID, can't deserialize.");
            }


            string propertiesString = string.Empty;

            if (rootNodePropDictionary == null)
            {
                if (!dataNode.GetUserPropString(propertyName, ref propertiesString))
                {
                    return;
                }
            }
            else
            {
                if (!rootNodePropDictionary.TryGetValue(propertyName, out propertiesString))
                {
                    return;
                }
            }


            int numFailed = 0;

            try // Try using the new way, if it's not working use the old way.
            {
                SerializableAnimationGroup serialAnimGroup = new SerializableAnimationGroup(propertiesString);
                serialAnimGroup.FillSerializedData(this);
            }
            catch
            {
                int indexOfguidPart = propertiesString
                                      .Select((c, i) => new { c, i })
                                      .Where(x => x.c == s_PropertySeparator)
                                      .Skip(2)
                                      .FirstOrDefault().i;
                string[] baseProperties = propertiesString.Substring(0, indexOfguidPart)?.Split(s_PropertySeparator);
                string   guidPart       = propertiesString.Substring(indexOfguidPart + 1);

                if (baseProperties.Length != 3)
                {
                    throw new Exception("Invalid number of properties, can't deserialize.");
                }

                // set dirty explicitly just before we start loading, set to false when loading is done
                // if any exception is thrown, it will have a correct value
                IsDirty = true;

                name = baseProperties[0];
                if (!int.TryParse(baseProperties[1], out ticksStart))
                {
                    throw new Exception("Failed to parse FrameStart property.");
                }
                if (!int.TryParse(baseProperties[2], out ticksEnd))
                {
                    throw new Exception("Failed to parse FrameEnd property.");
                }

                if (string.IsNullOrEmpty(guidPart) || guidPart == s_GUIDTypeSeparator.ToString())
                {
                    return;
                }


                if (!guidPart.Contains(s_GUIDTypeSeparator))
                {
                    // to grant retro-compatiblity
                    numFailed = ParseOldProperties(guidPart);
                }
                else
                {
                    //new format with nodes and node materials guid
                    numFailed = ParseNewProperties(guidPart);
                }
            }


            AnimationGroupNodes = new List <AnimationGroupNode>();
            foreach (Guid nodeGuid in nodeGuids)
            {
                IINode node = Tools.GetINodeByGuid(nodeGuid);

                if (node != null)
                {
                    string             name       = node.Name;
                    string             parentName = node.ParentNode.Name;
                    AnimationGroupNode nodeData   = new AnimationGroupNode(nodeGuid, name, parentName);
                    AnimationGroupNodes.Add(nodeData);
                }
            }

            AnimationGroupMaterials = new List <AnimationGroupMaterial>();
            foreach (Guid materialGUID in materialsGuids)
            {
                IMtl mat = Tools.GetIMtlByGuid(materialGUID);

                if (mat != null)
                {
                    string name = mat.Name;
                    AnimationGroupMaterial matData = new AnimationGroupMaterial(materialGUID, name);
                    AnimationGroupMaterials.Add(matData);
                }
            }

            if (numFailed > 0)
            {
                throw new Exception(string.Format("Failed to parse {0} node ids.", numFailed));
            }

            IsDirty = false;
        }
Example #34
0
        public void LoadFromJson(string jsonContent, bool merge = false)
        {
            List <string> animationPropertyNameList = Loader.Core.RootNode.GetStringArrayProperty(s_AnimationListPropertyName).ToList();

            if (!merge)
            {
                animationPropertyNameList = new List <string>();
                Clear();
            }

            List <AnimationGroup> animationGroupsData = JsonConvert.DeserializeObject <List <AnimationGroup> >(jsonContent);

            List <Guid> nodeGuids      = new List <Guid>();
            List <Guid> materialsGuids = new List <Guid>();

            foreach (AnimationGroup animData in animationGroupsData)
            {
                nodeGuids.Clear();

                if (animData.AnimationGroupNodes != null)
                {
                    string missingNodes = "";
                    string movedNodes   = "";
                    foreach (AnimationGroupNode nodeData in animData.AnimationGroupNodes)
                    {
                        //check here if something changed between export\import
                        // a node handle is reassigned the moment the node is created
                        // it is no possible to have consistency at 100% sure between two file
                        // we need to prevent artists
                        IINode node = Loader.Core.GetINodeByName(nodeData.Name);
                        if (node == null)
                        {
                            //node is missing
                            missingNodes += nodeData.Name + "\n";
                            continue;
                        }

                        if (node.ParentNode.Name != nodeData.ParentName)
                        {
                            //node has been moved in hierarchy
                            movedNodes += node.Name + "\n";
                            continue;
                        }

                        nodeGuids.Add(node.GetGuid());
                    }

                    if (!string.IsNullOrEmpty(movedNodes))
                    {
                        //skip restoration of evaluated animation group
                        nodeGuids = new List <Guid>();
                        MessageBox.Show(string.Format("{0} has been moved in hierarchy,{1} import skipped", movedNodes, animData.Name));
                    }

                    if (!string.IsNullOrEmpty(missingNodes))
                    {
                        //skip restoration of evaluated animation group
                        nodeGuids = new List <Guid>();
                        MessageBox.Show(string.Format("{0} does not exist,{1} import skipped", missingNodes, animData.Name));
                    }
                }

                if (animData.AnimationGroupMaterials != null)
                {
                    string missingMaterials = "";
                    foreach (AnimationGroupMaterial matData in animData.AnimationGroupMaterials)
                    {
                        //check here if something changed between export\import
                        // a material handle is reassigned the moment the node is created
                        // it is no possible to have consistency at 100% sure between two file
                        // we need to prevent artists
                        IMtl mtl = Tools.GetIMtlByGuid(matData.Guid);
                        if (mtl == null)
                        {
                            //material is missing
                            missingMaterials += matData.Name + "\n";
                            continue;
                        }
                        materialsGuids.Add(mtl.GetGuid());
                    }

                    if (!string.IsNullOrEmpty(missingMaterials))
                    {
                        //skip restoration of evaluated animation group
                        materialsGuids = new List <Guid>();
                        MessageBox.Show(string.Format("{0} does not exist,{1} import skipped", missingMaterials, animData.Name));
                    }
                }


                animData.NodeGuids     = nodeGuids;
                animData.MaterialGuids = materialsGuids;
                string nodes     = string.Join(AnimationGroup.s_PropertySeparator.ToString(), animData.NodeGuids);
                string materials = string.Join(AnimationGroup.s_PropertySeparator.ToString(), animData.MaterialGuids);
                string guids     = string.Join(AnimationGroup.s_GUIDTypeSeparator.ToString(), nodes, materials);

                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.AppendFormat(AnimationGroup.s_PropertyFormat, animData.Name, animData.TicksStart, animData.TicksEnd, guids);

                Loader.Core.RootNode.SetStringProperty(animData.SerializedId.ToString(), stringBuilder.ToString());

                string id = animData.SerializedId.ToString();

                if (merge)
                {
                    //if json are merged check if the same animgroup is already in list
                    //and skip in that case
                    if (!animationPropertyNameList.Contains(id))
                    {
                        animationPropertyNameList.Add(animData.SerializedId.ToString());
                    }
                }
                else
                {
                    animationPropertyNameList.Add(animData.SerializedId.ToString());
                }
            }

            Loader.Core.RootNode.SetStringArrayProperty(s_AnimationListPropertyName, animationPropertyNameList);

            LoadFromData(Loader.Core.RootNode);
        }
Example #35
0
        private IList <BabylonAnimationGroup> ExportAnimationGroups(BabylonScene babylonScene)
        {
            IList <BabylonAnimationGroup> animationGroups = new List <BabylonAnimationGroup>();

            // Retrieve and parse animation group data
            AnimationGroupList animationList = AnimationGroupList.InitAnimationGroups(logger);

            foreach (AnimationGroup animGroup in animationList)
            {
                logger?.RaiseMessage("Exporter.animationGroups | " + animGroup.Name, 1);
                BabylonAnimationGroup animationGroup = new BabylonAnimationGroup
                {
                    name               = animGroup.Name,
                    from               = animGroup.FrameStart,
                    to                 = animGroup.FrameEnd,
                    keepNonAnimated    = animGroup.KeepNonAnimated,
                    targetedAnimations = new List <BabylonTargetedAnimation>()
                };

                // add animations of each nodes contained in the animGroup
                foreach (Guid guid in animGroup.NodeGuids)
                {
                    IINode maxNode = Tools.GetINodeByGuid(guid);

                    // node could have been deleted, silently ignore it
                    if (maxNode == null)
                    {
                        continue;
                    }

                    if (exportParameters.exportAsSubmodel && !maxNode.Selected)
                    {
                        continue;
                    }


                    // Helpers can be exported as dummies and as bones
                    string nodeId = maxNode.GetGuid().ToString();
                    string boneId = isGltfExported?maxNode.GetGuid().ToString(): maxNode.GetGuid().ToString() + "-bone";   // the suffix "-bone" is added in babylon export format to assure the uniqueness of IDs

                    // Node
                    BabylonNode node = null;
                    babylonScene.NodeMap.TryGetValue(nodeId, out node);
                    if (node != null)
                    {
                        if (node.animations != null && node.animations.Length != 0)
                        {
                            IList <BabylonAnimation> animations = GetSubAnimations(node, animationGroup.from, animationGroup.to);

                            if (!animGroup.KeepStaticAnimation)
                            {
                                RemoveStaticAnimations(ref animations);
                            }

                            foreach (BabylonAnimation animation in animations)
                            {
                                BabylonTargetedAnimation targetedAnimation = new BabylonTargetedAnimation
                                {
                                    animation = animation,
                                    targetId  = nodeId
                                };

                                animationGroup.targetedAnimations.Add(targetedAnimation);
                            }
                        }
                    }

                    // bone
                    BabylonBone bone  = null;
                    int         index = 0;
                    while (index < babylonScene.SkeletonsList.Count && bone == null)
                    {
                        BabylonSkeleton skel = babylonScene.SkeletonsList[index];
                        bone = skel.bones.FirstOrDefault(b => b.id == boneId);
                        index++;
                    }

                    if (bone != null)
                    {
                        if (bone.animation != null)
                        {
                            IList <BabylonAnimation> animations = GetSubAnimations(bone, animationGroup.from, animationGroup.to);
                            foreach (BabylonAnimation animation in animations)
                            {
                                BabylonTargetedAnimation targetedAnimation = new BabylonTargetedAnimation
                                {
                                    animation = animation,
                                    targetId  = boneId
                                };

                                animationGroup.targetedAnimations.Add(targetedAnimation);
                            }
                        }
                    }
                }

                // add animations of each nodes contained in the animGroup
                foreach (Guid guid in animGroup.MaterialGuids)
                {
                    IMtl maxMtl = Tools.GetIMtlByGuid(guid);

                    // mat could have been deleted, silently ignore it
                    if (maxMtl == null)
                    {
                        continue;
                    }

                    string matId = maxMtl.GetGuid().ToString();

                    // Material
                    BabylonMaterial material = null;
                    material = babylonScene.MaterialsList.FirstOrDefault(x => x.id == matId);
                    if (material != null)
                    {
                        if (material.animations != null && material.animations.Length != 0)
                        {
                            IList <BabylonAnimation> animations = GetSubAnimations(material, animationGroup.from, animationGroup.to);
                            foreach (BabylonAnimation animation in animations)
                            {
                                BabylonTargetedAnimation targetedAnimation = new BabylonTargetedAnimation
                                {
                                    animation = animation,
                                    targetId  = matId
                                };

                                animationGroup.targetedAnimations.Add(targetedAnimation);
                            }
                        }
                    }
                }

                if (animationGroup.targetedAnimations.Count > 0)
                {
                    animationGroups.Add(animationGroup);
                }
            }

            return(animationGroups);
        }