/// <summary>
        /// Create a Wardrobe Recipe from the slot (and optionally overlay)
        /// </summary>
        /// <param name="path"></param>
        /// <param name="sd"></param>
        /// <param name="od"></param>
        /// <param name="slotName"></param>
        /// <param name="addToGlobalLibrary"></param>
        public static UMAWardrobeRecipe CreateRecipe(string path, SlotDataAsset sd, OverlayDataAsset od, string slotName, bool addToGlobalLibrary)
        {
            // Generate an asset in memory
            UMAWardrobeRecipe asset = ScriptableObject.CreateInstance <CharacterSystem.UMAWardrobeRecipe>();

            UMAData.UMARecipe recipe = new UMAData.UMARecipe();
            recipe.ClearDna();
            SlotData mySlot = new SlotData(sd);

            if (od != null)
            {
                OverlayData myOverlay = new OverlayData(od);
                mySlot.AddOverlay(myOverlay);
            }
            recipe.SetSlot(0, mySlot);
            asset.Save(recipe, UMAContextBase.Instance);
            asset.DisplayValue = slotName;

            // Write the asset to disk
            AssetDatabase.CreateAsset(asset, path);
            AssetDatabase.SaveAssets();
            if (addToGlobalLibrary)
            {
                // Add it to the global libary
                UMAAssetIndexer.Instance.EvilAddAsset(typeof(CharacterSystem.UMAWardrobeRecipe), asset);
                EditorUtility.SetDirty(UMAAssetIndexer.Instance);
            }
            // Inform the asset database a file has changes
            AssetDatabase.Refresh();
            return(asset);
        }
Example #2
0
        public SlotData Duplicate()
        {
            SlotData tempSlotData = CreateInstance <SlotData>();

            tempSlotData.slotName       = slotName;
            tempSlotData.listID         = listID;
            tempSlotData.materialSample = materialSample;
            tempSlotData.overlayScale   = overlayScale;
            tempSlotData.slotDNA        = slotDNA;
            tempSlotData.subMeshIndex   = subMeshIndex;

            // All this data is passed as reference
            tempSlotData.boneWeights     = boneWeights;
            tempSlotData.animatedBones   = animatedBones;
            tempSlotData.meshRenderer    = meshRenderer;
            tempSlotData.boneWeights     = boneWeights;
            tempSlotData.umaBoneData     = umaBoneData;
            tempSlotData.textureNameList = textureNameList;
            //Overlays are duplicated, to lose reference
            for (int i = 0; i < overlayList.Count; i++)
            {
                tempSlotData.AddOverlay(overlayList[i].Duplicate());
            }

            return(tempSlotData);
        }
        protected override void Start()
        {
            if (generatedMaterialLookup == null)
            {
                generatedMaterialLookup = new Dictionary <GeneratedMaterialLookupKey, UMAData.GeneratedMaterial>(20);
            }
            else
            {
                generatedMaterialLookup.Clear();
            }
            backUpTexture = umaData.backUpTextures();
            umaData.CleanTextures();
            generatedMaterials = new List <UMAData.GeneratedMaterial>(20);
            atlassedMaterials.Clear();
            uniqueRenderers.Clear();

            SlotData[] slots = umaData.umaRecipe.slotDataList;

            for (int i = 0; i < slots.Length; i++)
            {
                SlotData slot = slots[i];
                if (slot == null)
                {
                    continue;
                }
                if (slot.Suppressed)
                {
                    continue;
                }

                //Keep a running list of unique RendererHashes from our slots
                //Null rendererAsset gets added, which is good, it is the default renderer.
                if (!uniqueRenderers.Contains(slot.rendererAsset))
                {
                    uniqueRenderers.Add(slot.rendererAsset);
                }

                // Let's only add the default overlay if the slot has meshData and NO overlays
                // This should be able to be removed if default overlay/textures are ever added to uma materials...
                if ((slot.asset.meshData != null) && (slot.OverlayCount == 0))
                {
                    if (umaGenerator.defaultOverlaydata != null)
                    {
                        slot.AddOverlay(umaGenerator.defaultOverlaydata);
                    }
                }

                OverlayData overlay0 = slot.GetOverlay(0);
                if ((slot.asset.material != null) && (overlay0 != null))
                {
                    GeneratedMaterialLookupKey lookupKey = new GeneratedMaterialLookupKey
                    {
                        overlayList   = slot.GetOverlayList(),
                        rendererAsset = slot.rendererAsset
                    };

                    UMAData.GeneratedMaterial generatedMaterial;
                    if (!generatedMaterialLookup.TryGetValue(lookupKey, out generatedMaterial))
                    {
                        generatedMaterial = FindOrCreateGeneratedMaterial(slot.asset.material, slot.rendererAsset);
                        generatedMaterialLookup.Add(lookupKey, generatedMaterial);
                    }

                    int validOverlayCount = 0;
                    for (int j = 0; j < slot.OverlayCount; j++)
                    {
                        var overlay = slot.GetOverlay(j);
                        if (overlay != null)
                        {
                            validOverlayCount++;
#if (UNITY_STANDALONE || UNITY_IOS || UNITY_ANDROID || UNITY_PS4 || UNITY_XBOXONE) && !UNITY_2017_3_OR_NEWER //supported platforms for procedural materials
                            if (overlay.isProcedural)
                            {
                                overlay.GenerateProceduralTextures();
                            }
#endif
                        }
                    }

                    UMAData.MaterialFragment tempMaterialDefinition = new UMAData.MaterialFragment();
                    tempMaterialDefinition.baseOverlay              = new UMAData.textureData();
                    tempMaterialDefinition.baseOverlay.textureList  = overlay0.textureArray;
                    tempMaterialDefinition.baseOverlay.alphaTexture = overlay0.alphaMask;
                    tempMaterialDefinition.baseOverlay.overlayType  = overlay0.overlayType;

                    tempMaterialDefinition.umaMaterial = slot.asset.material;
                    tempMaterialDefinition.baseColor   = overlay0.colorData.color;
                    tempMaterialDefinition.size        = overlay0.pixelCount;

                    tempMaterialDefinition.overlays               = new UMAData.textureData[validOverlayCount - 1];
                    tempMaterialDefinition.overlayColors          = new Color32[validOverlayCount - 1];
                    tempMaterialDefinition.rects                  = new Rect[validOverlayCount - 1];
                    tempMaterialDefinition.overlayData            = new OverlayData[validOverlayCount];
                    tempMaterialDefinition.channelMask            = new Color[validOverlayCount][];
                    tempMaterialDefinition.channelAdditiveMask    = new Color[validOverlayCount][];
                    tempMaterialDefinition.overlayData[0]         = slot.GetOverlay(0);
                    tempMaterialDefinition.channelMask[0]         = slot.GetOverlay(0).colorData.channelMask;
                    tempMaterialDefinition.channelAdditiveMask[0] = slot.GetOverlay(0).colorData.channelAdditiveMask;
                    tempMaterialDefinition.slotData               = slot;

                    int overlayID = 0;
                    for (int j = 1; j < slot.OverlayCount; j++)
                    {
                        OverlayData overlay = slot.GetOverlay(j);
                        if (overlay == null)
                        {
                            continue;
                        }

                        if (IsUVCoordinates(overlay.rect))
                        {
                            tempMaterialDefinition.rects[overlayID] = ScaleToBase(overlay.rect, overlay0.textureArray[0]);
                        }
                        else
                        {
                            tempMaterialDefinition.rects[overlayID] = overlay.rect;                             // JRRM: Convert here into base overlay coordinates?
                        }
                        tempMaterialDefinition.overlays[overlayID]              = new UMAData.textureData();
                        tempMaterialDefinition.overlays[overlayID].textureList  = overlay.textureArray;
                        tempMaterialDefinition.overlays[overlayID].alphaTexture = overlay.alphaMask;
                        tempMaterialDefinition.overlays[overlayID].overlayType  = overlay.overlayType;
                        tempMaterialDefinition.overlayColors[overlayID]         = overlay.colorData.color;

                        overlayID++;
                        tempMaterialDefinition.overlayData[overlayID]         = overlay;
                        tempMaterialDefinition.channelMask[overlayID]         = overlay.colorData.channelMask;
                        tempMaterialDefinition.channelAdditiveMask[overlayID] = overlay.colorData.channelAdditiveMask;
                    }

                    tempMaterialDefinition.overlayList  = lookupKey.overlayList;
                    tempMaterialDefinition.isRectShared = false;
                    for (int j = 0; j < generatedMaterial.materialFragments.Count; j++)
                    {
                        if (tempMaterialDefinition.overlayList == generatedMaterial.materialFragments[j].overlayList)
                        {
                            tempMaterialDefinition.isRectShared = true;
                            tempMaterialDefinition.rectFragment = generatedMaterial.materialFragments[j];
                            break;
                        }
                    }
                    generatedMaterial.materialFragments.Add(tempMaterialDefinition);
                }
            }

            //****************************************************
            //* Set parameters based on shader parameter mapping
            //****************************************************
            for (int i = 0; i < generatedMaterials.Count; i++)
            {
                UMAData.GeneratedMaterial ugm = generatedMaterials[i];
                if (ugm.umaMaterial.shaderParms != null)
                {
                    for (int j = 0; j < ugm.umaMaterial.shaderParms.Length; j++)
                    {
                        UMAMaterial.ShaderParms parm = ugm.umaMaterial.shaderParms[j];
                        if (ugm.material.HasProperty(parm.ParameterName))
                        {
                            foreach (OverlayColorData ocd in umaData.umaRecipe.sharedColors)
                            {
                                if (ocd.name == parm.ColorName)
                                {
                                    ugm.material.SetColor(parm.ParameterName, ocd.color);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            packTexture = new MaxRectsBinPack(umaGenerator.atlasResolution, umaGenerator.atlasResolution, false);
        }
Example #4
0
            /// <summary>
            /// Combine additional slot with current data.
            /// </summary>
            /// <param name="slot">Slot.</param>
            /// <param name="additional">If set to <c>true</c> slot will not be serialized.</param>
            public void MergeSlot(SlotData slot, bool additional)
            {
                if ((slot == null) || (slot.asset == null))
                {
                    return;
                }

                int overlayCount = 0;

                for (int i = 0; i < slotDataList.Length; i++)
                {
                    if (slotDataList[i] == null)
                    {
                        continue;
                    }
                    if (slot.asset == slotDataList[i].asset)
                    {
                        SlotData originalSlot = slotDataList[i];
                        overlayCount = slot.OverlayCount;
                        for (int j = 0; j < overlayCount; j++)
                        {
                            OverlayData overlay         = slot.GetOverlay(j);
                            OverlayData originalOverlay = originalSlot.GetEquivalentOverlay(overlay);
                            if (originalOverlay != null)
                            {
                                //								originalOverlay.CopyColors(overlay);
                            }
                            else
                            {
                                OverlayData overlayCopy = overlay.Duplicate();
                                if (overlayCopy.colorData.HasName())
                                {
                                    int sharedIndex;
                                    if (mergedSharedColors.TryGetValue(overlayCopy.colorData.name, out sharedIndex))
                                    {
                                        overlayCopy.colorData = sharedColors[sharedIndex];
                                    }
                                }
                                originalSlot.AddOverlay(overlayCopy);
                            }
                        }
                        return;
                    }
                }

                int insertIndex = slotDataList.Length;

                System.Array.Resize <SlotData>(ref slotDataList, slotDataList.Length + 1);
                if (additional)
                {
                    additionalSlotCount += 1;
                }
                else
                {
                    for (int i = 0; i < additionalSlotCount; i++)
                    {
                        slotDataList[insertIndex] = slotDataList[insertIndex - 1];
                        insertIndex--;
                    }
                }

                SlotData slotCopy = slot.Copy();

                overlayCount = slotCopy.OverlayCount;
                for (int j = 0; j < overlayCount; j++)
                {
                    OverlayData overlay = slotCopy.GetOverlay(j);
                    if (overlay.colorData.HasName())
                    {
                        int sharedIndex;
                        if (mergedSharedColors.TryGetValue(overlay.colorData.name, out sharedIndex))
                        {
                            overlay.colorData = sharedColors[sharedIndex];
                        }
                    }
                }
                slotDataList[insertIndex] = slotCopy;
                MergeMatchingOverlays();
            }
        protected override void Start()
        {
            if (generatedMaterialLookup == null)
            {
                generatedMaterialLookup = new Dictionary <List <OverlayData>, UMAData.GeneratedMaterial>(20);
            }
            else
            {
                generatedMaterialLookup.Clear();
            }
            backUpTexture = umaData.backUpTextures();
            umaData.CleanTextures();
            generatedMaterials = new List <UMAData.GeneratedMaterial>(20);
            atlassedMaterials.Clear();
            rendererCount = 0;

            SlotData[] slots = umaData.umaRecipe.slotDataList;

            for (int i = 0; i < slots.Length; i++)
            {
                var slot = slots[i];
                if (slot == null)
                {
                    continue;
                }

                if ((slot.asset.material != null) && (slot.GetOverlay(0) != null))
                {
                    if (!slot.asset.material.RequireSeperateRenderer)
                    {
                        // At least one slot that doesn't require a seperate renderer, so we reserve renderer 0 for those.
                        rendererCount = 1;
                        break;
                    }
                }
            }

            for (int i = 0; i < slots.Length; i++)
            {
                SlotData slot = slots[i];
                if (slot == null)
                {
                    continue;
                }

                // Let's only add the default overlay if the slot has overlays and NO meshData
                if ((slot.asset.meshData != null) && (slot.OverlayCount == 0))
                {
                    if (umaGenerator.defaultOverlaydata != null)
                    {
                        slot.AddOverlay(umaGenerator.defaultOverlaydata);
                    }
                }

                OverlayData overlay0 = slot.GetOverlay(0);
                if ((slot.asset.material != null) && (overlay0 != null))
                {
                    List <OverlayData>        overlayList = slot.GetOverlayList();
                    UMAData.GeneratedMaterial generatedMaterial;
                    if (!generatedMaterialLookup.TryGetValue(overlayList, out generatedMaterial))
                    {
                        generatedMaterial = FindOrCreateGeneratedMaterial(slot.asset.material);
                        generatedMaterialLookup.Add(overlayList, generatedMaterial);
                    }

                    int validOverlayCount = 0;
                    for (int j = 0; j < slot.OverlayCount; j++)
                    {
                        var overlay = slot.GetOverlay(j);
                        if (overlay != null)
                        {
                            validOverlayCount++;
                            #if UNITY_STANDALONE || UNITY_IOS || UNITY_ANDROID || UNITY_PS4 || UNITY_XBOXONE //supported platforms for procedural materials
                            if (overlay.isProcedural)
                            {
                                overlay.GenerateProceduralTextures();
                            }
                            #endif
                        }
                    }

                    UMAData.MaterialFragment tempMaterialDefinition = new UMAData.MaterialFragment();
                    tempMaterialDefinition.baseOverlay              = new UMAData.textureData();
                    tempMaterialDefinition.baseOverlay.textureList  = overlay0.textureArray;
                    tempMaterialDefinition.baseOverlay.alphaTexture = overlay0.alphaMask;
                    tempMaterialDefinition.baseOverlay.overlayType  = overlay0.overlayType;

                    tempMaterialDefinition.umaMaterial = slot.asset.material;
                    tempMaterialDefinition.baseColor   = overlay0.colorData.color;
                    tempMaterialDefinition.size        = overlay0.pixelCount;

                    tempMaterialDefinition.overlays               = new UMAData.textureData[validOverlayCount - 1];
                    tempMaterialDefinition.overlayColors          = new Color32[validOverlayCount - 1];
                    tempMaterialDefinition.rects                  = new Rect[validOverlayCount - 1];
                    tempMaterialDefinition.overlayData            = new OverlayData[validOverlayCount];
                    tempMaterialDefinition.channelMask            = new Color[validOverlayCount][];
                    tempMaterialDefinition.channelAdditiveMask    = new Color[validOverlayCount][];
                    tempMaterialDefinition.overlayData[0]         = slot.GetOverlay(0);
                    tempMaterialDefinition.channelMask[0]         = slot.GetOverlay(0).colorData.channelMask;
                    tempMaterialDefinition.channelAdditiveMask[0] = slot.GetOverlay(0).colorData.channelAdditiveMask;
                    tempMaterialDefinition.slotData               = slot;

                    int overlayID = 0;
                    for (int j = 1; j < slot.OverlayCount; j++)
                    {
                        OverlayData overlay = slot.GetOverlay(j);
                        if (overlay == null)
                        {
                            continue;
                        }

                        tempMaterialDefinition.rects[overlayID]                 = overlay.rect;
                        tempMaterialDefinition.overlays[overlayID]              = new UMAData.textureData();
                        tempMaterialDefinition.overlays[overlayID].textureList  = overlay.textureArray;
                        tempMaterialDefinition.overlays[overlayID].alphaTexture = overlay.alphaMask;
                        tempMaterialDefinition.overlays[overlayID].overlayType  = overlay.overlayType;
                        tempMaterialDefinition.overlayColors[overlayID]         = overlay.colorData.color;

                        overlayID++;
                        tempMaterialDefinition.overlayData[overlayID]         = overlay;
                        tempMaterialDefinition.channelMask[overlayID]         = overlay.colorData.channelMask;
                        tempMaterialDefinition.channelAdditiveMask[overlayID] = overlay.colorData.channelAdditiveMask;
                    }

                    tempMaterialDefinition.overlayList  = overlayList;
                    tempMaterialDefinition.isRectShared = false;
                    for (int j = 0; j < generatedMaterial.materialFragments.Count; j++)
                    {
                        if (tempMaterialDefinition.overlayList == generatedMaterial.materialFragments[j].overlayList)
                        {
                            tempMaterialDefinition.isRectShared = true;
                            tempMaterialDefinition.rectFragment = generatedMaterial.materialFragments[j];
                            break;
                        }
                    }
                    generatedMaterial.materialFragments.Add(tempMaterialDefinition);
                }
            }

            packTexture = new MaxRectsBinPack(umaGenerator.atlasResolution, umaGenerator.atlasResolution, false);
        }