private bool CalculateRects(UMAData.GeneratedMaterial material) { Rect nullRect = new Rect(0, 0, 0, 0); packTexture.Init(umaGenerator.atlasResolution, umaGenerator.atlasResolution, false); for (int atlasElementIndex = 0; atlasElementIndex < material.materialFragments.Count; atlasElementIndex++) { var tempMaterialDef = material.materialFragments[atlasElementIndex]; if (tempMaterialDef.isRectShared) { continue; } tempMaterialDef.atlasRegion = packTexture.Insert(Mathf.FloorToInt(tempMaterialDef.baseTexture[0].width * material.resolutionScale * tempMaterialDef.slotData.overlayScale), Mathf.FloorToInt(tempMaterialDef.baseTexture[0].height * material.resolutionScale * tempMaterialDef.slotData.overlayScale), MaxRectsBinPack.FreeRectChoiceHeuristic.RectBestLongSideFit); if (tempMaterialDef.atlasRegion == nullRect) { if (umaGenerator.fitAtlas) { Debug.LogWarning("Atlas resolution is too small, Textures will be reduced.", umaData.gameObject); return(false); } else { Debug.LogError("Atlas resolution is too small, not all textures will fit.", umaData.gameObject); } } } return(true); }
private UMAData.GeneratedMaterial FindOrCreateGeneratedMaterial(UMAMaterial umaMaterial, UMARendererAsset renderer = null) { if (umaMaterial.materialType == UMAMaterial.MaterialType.Atlas) { foreach (var atlassedMaterial in atlassedMaterials) { if (atlassedMaterial.umaMaterial == umaMaterial && atlassedMaterial.rendererAsset == renderer) { return(atlassedMaterial); } else { if (atlassedMaterial.umaMaterial.Equals(umaMaterial) && atlassedMaterial.rendererAsset == renderer) { return(atlassedMaterial); } } } } var res = new UMAData.GeneratedMaterial(); res.rendererAsset = renderer; res.umaMaterial = umaMaterial; res.material = UnityEngine.Object.Instantiate(umaMaterial.material) as Material; res.material.name = umaMaterial.material.name; #if UNITY_WEBGL res.material.shader = Shader.Find(res.material.shader.name); #endif res.material.CopyPropertiesFromMaterial(umaMaterial.material); atlassedMaterials.Add(res); generatedMaterials.Add(res); return(res); }
private UMAData.GeneratedMaterial FindOrCreateGeneratedMaterial(UMAMaterial umaMaterial) { if (umaMaterial.materialType == UMAMaterial.MaterialType.Atlas) { foreach (var atlassedMaterial in atlassedMaterials) { if (atlassedMaterial.umaMaterial == umaMaterial) { return(atlassedMaterial); } else { if (atlassedMaterial.umaMaterial.Equals(umaMaterial)) { return(atlassedMaterial); } } } } var res = new UMAData.GeneratedMaterial(); if (umaMaterial.RequireSeperateRenderer) { res.renderer = rendererCount++; } res.umaMaterial = umaMaterial; res.material = UnityEngine.Object.Instantiate(umaMaterial.material) as Material; res.material.name = umaMaterial.material.name; atlassedMaterials.Add(res); generatedMaterials.Add(res); return(res); }
private UMAData.GeneratedMaterial FindOrCreateGeneratedMaterial(UMAMaterial umaMaterial) { if (umaMaterial.materialType != UMAMaterial.MaterialType.Atlas) { var res = new UMAData.GeneratedMaterial(); res.umaMaterial = umaMaterial; res.material = UnityEngine.Object.Instantiate(umaMaterial.material) as Material; res.material.name = umaMaterial.material.name; generatedMaterials.Add(res); return(res); } else { foreach (var atlassedMaterial in atlassedMaterials) { if (atlassedMaterial.umaMaterial == umaMaterial) { return(atlassedMaterial); } } var res = new UMAData.GeneratedMaterial(); res.umaMaterial = umaMaterial; res.material = UnityEngine.Object.Instantiate(umaMaterial.material) as Material; res.material.name = umaMaterial.material.name; atlassedMaterials.Add(res); generatedMaterials.Add(res); return(res); } }
private void UpdateSharedRect(UMAData.GeneratedMaterial generatedMaterial) { for (int i = 0; i < generatedMaterial.materialFragments.Count; i++) { var fragment = generatedMaterial.materialFragments[i]; if (fragment.isRectShared) { fragment.atlasRegion = fragment.rectFragment.atlasRegion; } } }
private PackSize CalculateRects(UMAData.GeneratedMaterial material, PackSize area) { Rect nullRect = new Rect(0, 0, 0, 0); PackSize lastPackSize = new PackSize(); packTexture.Init(area.Width, area.Height, false); for (int atlasElementIndex = 0; atlasElementIndex < material.materialFragments.Count; atlasElementIndex++) { var tempMaterialDef = material.materialFragments[atlasElementIndex]; if (tempMaterialDef.isRectShared) { continue; } int width = Mathf.FloorToInt(tempMaterialDef.baseOverlay.textureList[0].width * material.resolutionScale.x * tempMaterialDef.slotData.overlayScale); int height = Mathf.FloorToInt(tempMaterialDef.baseOverlay.textureList[0].height * material.resolutionScale.y * tempMaterialDef.slotData.overlayScale); // If either width or height are 0 we will end up with nullRect and potentially loop forever if (width == 0 || height == 0) { tempMaterialDef.atlasRegion = nullRect; continue; } tempMaterialDef.atlasRegion = packTexture.Insert(width, height, MaxRectsBinPack.FreeRectChoiceHeuristic.RectBestLongSideFit); lastPackSize.Width = width; lastPackSize.Height = height; if (tempMaterialDef.atlasRegion == nullRect) { if (umaGenerator.fitAtlas) { //if (Debug.isDebugBuild) // JRRM : re-enable this // Debug.LogWarning("Atlas resolution is too small, Textures will be reduced.", umaData.gameObject); lastPackSize.success = false; return(lastPackSize); } else { if (Debug.isDebugBuild) { Debug.LogError("Atlas resolution is too small, not all textures will fit.", umaData.gameObject); } } } } lastPackSize.success = true; return(lastPackSize); }
private void UpdateAtlasRects(UMAData.GeneratedMaterial generatedMaterial, Vector2 Scale) { for (int i = 0; i < generatedMaterial.materialFragments.Count; i++) { var fragment = generatedMaterial.materialFragments[i]; Vector2 pos = fragment.atlasRegion.position * Scale; //ceil ? Vector2 size = fragment.atlasRegion.size *= Scale; // floor ? pos.x = Mathf.Ceil(pos.x); pos.y = Mathf.Ceil(pos.y); size.x = Mathf.Floor(size.x); size.y = Mathf.Floor(size.y); fragment.atlasRegion.Set(pos.x, pos.y, size.x, size.y); } }
public void SetupModule(UMAData.GeneratedMaterial atlas, int idx, int textureType) { var atlasElement = atlas.materialFragments[idx]; if (atlasElement.isRectShared) { return; } height = Mathf.FloorToInt(atlas.cropResolution.y); SetupModule(atlasElement, textureType); resolutionScale = atlas.resolutionScale * atlasElement.slotData.overlayScale; for (int i2 = 0; i2 < atlasElement.overlays.Length; i2++) { SetupOverlay(atlasElement, i2, textureType); } }
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); }
private bool CalculateBestFitSquare(SizeInt area, float atlasRes, ref Vector2 Scale, UMAData.GeneratedMaterial generatedMaterial) { while (true) { PackSize lastRect = CalculateRects(generatedMaterial, area); if (lastRect.success) { if (area.Width != umaGenerator.atlasResolution || area.Height != umaGenerator.atlasResolution) { float neww = lastRect.xMax; // was area.Width; float newh = lastRect.yMax; // was area.Height; Scale.x = atlasRes / neww; Scale.y = atlasRes / newh; return(true); } return(false); // Everything fit, let's leave. } int projectedWidth = lastRect.xMax + lastRect.Width; int projectedHeight = lastRect.yMax + lastRect.Height; if (area.Width < area.Height) { // increase width. if (projectedWidth <= area.Width) { // If projectedWidth < the area width, then it's not // increasing each loop, and it MUST. area.Width += lastRect.Width; } else { area.Width = projectedWidth; } } else { // increase height if (projectedHeight <= area.Height) { area.Height += lastRect.Height; } else { area.Height = projectedHeight; } } } // no exit here! :) }