public TAMImageDiagram Generate(TAMImageDiagram baseDiagram, TAMTone tone, TAMMipmapLevel mipmapLevel, int seed)
        {
            _strokesGenerator.ResetSeed(seed);
            _random = new System.Random(seed);

            var   diagram         = baseDiagram.Copy();
            float currentCoverage = ComputeCoverage(diagram, mipmapLevel);
            float targetCoverage  = _generationConfiguration.TargetCoverages[tone];

            while (targetCoverage > currentCoverage)
            {
                List <RankedPossibleStroke> possibleStrokes = new List <RankedPossibleStroke>();
                for (int i = 0; i < _generationConfiguration.TriesCount[mipmapLevel]; i++)
                {
                    TAMStroke            newStroke       = _strokesGenerator.CreateRandomStroke(new Vector2(_random.Next(), _random.Next()), tone);
                    RankedPossibleStroke rankedNewStroke = RankStroke(newStroke, diagram);
                    possibleStrokes.Add(rankedNewStroke);
                }

                var bestStroke = possibleStrokes.OrderBy(p => p.Rank).First();
                diagram.AddStroke(bestStroke.Stroke);
                currentCoverage = ComputeCoverage(diagram, mipmapLevel);
            }

            return(diagram);
        }
예제 #2
0
        public void Start0()
        {
            var tonesCount  = 5;
            var levelsCount = 5;

            TaskUtils.SetGlobalMultithreading(false);
            var tones = TAMTone.CreateList(tonesCount, new Dictionary <int, TAMStrokeOrientation>()
            {
                { 0, TAMStrokeOrientation.Horizontal },
                { 3, TAMStrokeOrientation.Vertical },
                { 5, TAMStrokeOrientation.Both }
            });
            var levels = TAMMipmapLevel.CreateList(levelsCount);

            var fileManager    = new TAMPackFileManager();
            var soleImagesPack = fileManager.Load(@"C:\mgr\tmp\tam1\", tones, levels);

            var generator  = new TAMArrayGenerator();
            var tex2DArray = generator.Generate(soleImagesPack, tones, levels);

            var go       = GameObject.CreatePrimitive(PrimitiveType.Plane);
            var material = new Material(Shader.Find("Custom/Debug/TextureArrayLod"));

            material.SetTexture("_MainTex", tex2DArray);
            go.GetComponent <MeshRenderer>().material = material;
            MyAssetDatabase.CreateAndSaveAsset(tex2DArray, "Assets/Generated/TAM1.asset");
        }
예제 #3
0
        public TAMStroke UpdatePerMipmapLevelStrokeParameters(TAMStroke tamStroke, TAMMipmapLevel level)
        {
            var reverseIndex = level.MipmapLevelsCount - level.LevelIndex - 1;
            var newHeight    = tamStroke.Height * Mathf.Pow(_generationConfiguration.PerMipmapLevelHeightMultiplier, reverseIndex);

            return(new TAMStroke(tamStroke.Center, newHeight, tamStroke.Length, tamStroke.Rotation, tamStroke.Id));
        }
        public TAMImageDiagram Generate(TAMImageDiagram diagram, TAMTone tone, TAMMipmapLevel mipmapLevel, int seed)
        {
            List <Vector2> currentPoints = diagram.Strokes.Select(c => c.Center).ToList();
            var            newPoints     = _sampler.Generate(_configuration.GenerationCount, _configuration.ExclusionZoneValues[tone][mipmapLevel],
                                                             seed, currentPoints);

            return(new TAMImageDiagram(diagram.Strokes.Union(newPoints.Select(c => _strokesGenerator.CreateRandomStroke(c, tone))).ToList()));
        }
예제 #5
0
 private TAMImageDiagram GetPreviousToneImageDiagram(TAMTone tone, TAMMipmapLevel mipmapLevel)
 {
     if (tone.IsLowestTone)
     {
         return(TAMImageDiagram.CreateEmpty());
     }
     else
     {
         return(_columns[tone.LowerTone][mipmapLevel]);
     }
 }
예제 #6
0
        public static List <TAMMipmapLevel> CreateList(int count)
        {
            var            outList         = new List <TAMMipmapLevel>();
            TAMMipmapLevel lastMipmapLevel = null;

            for (int i = 0; i < count; i++)
            {
                var newMipmapLevel = new TAMMipmapLevel(i, count, lastMipmapLevel);
                outList.Add(newMipmapLevel);
                lastMipmapLevel = newMipmapLevel;
            }

            return(outList);
        }
예제 #7
0
        private Image CreateSoleImage(TAMImageDiagram diagram, TAMMipmapLevel level)
        {
            var margin = _configuration.Margin;
            var soleImageResolution            = _configuration.SoleImagesResolutionPerLevel[level].ToFloatVec();
            var soleImageResolutionWithMargins = soleImageResolution * (1 + margin * 2);

            using (ImageFactory imageFactory = new ImageFactory(preserveExifData: true))
            {
                var factory = imageFactory.Load(_blankImage)
                              .Resize(new Size((int)soleImageResolutionWithMargins.x, (int)soleImageResolutionWithMargins.y));
                foreach (var stroke in diagram.Strokes)
                {
                    using (ImageFactory strokeFactory = new ImageFactory(true))
                    {
                        var strokeSizeInPixels = VectorUtils.MemberwiseMultiply(
                            new Vector2(stroke.Length, stroke.Height * _configuration.StrokeHeightMultiplierPerLevel[level]), soleImageResolution).ToIntVector2();
                        var rotation = Mathf.Rad2Deg * stroke.Rotation;

                        var rotatedStrokeImageFactory = strokeFactory.Load(_strokeImage)
                                                        .Resize(new ResizeLayer(new Size(strokeSizeInPixels.X, strokeSizeInPixels.Y), ResizeMode.Stretch))
                                                        .Rotate(rotation);
                        //if (stroke.Id == 1)
                        //{
                        //    rotatedStrokeImageFactory = rotatedStrokeImageFactory.ReplaceColor(Color.Black, Color.Blue);
                        //}

                        var rotatedStrokeImage = rotatedStrokeImageFactory.Image;
                        var position           = VectorUtils.MemberwiseMultiply(UvToMarginUv(stroke.Center), soleImageResolutionWithMargins).ToIntVector2();
                        //todo przelicz tu aby brac pod uwage multiplier
                        position -= new IntVector2(rotatedStrokeImage.Width / 2, rotatedStrokeImage.Height / 2);

                        factory = factory.Overlay(new ImageLayer()
                        {
                            Image    = rotatedStrokeImage,
                            Opacity  = 100,
                            Position = new Point(position.X, position.Y)
                        });
                    }
                }

                using (Stream stream = new MemoryStream())
                {
                    factory.Save(stream);
                    return(Image.FromStream(stream));
                }
            }
        }
        private float ComputeCoverage(TAMImageDiagram diagram, TAMMipmapLevel mipmapLevel)
        {
            var areaSum = 0.0;

            for (int i = 0; i < diagram.Strokes.Count; i++)
            {
                var currentStroke = diagram.Strokes[i];
                var baseArea      = Mathf.PI * Mathf.Pow(currentStroke.Length, 2) * 0.2; //todo

                for (int k = 0; k < i; k++)
                {
                    var otherStroke      = diagram.Strokes[k];
                    var intersectionArea =
                        MyMathUtils.IntersectionAreaOfTwoCircles(currentStroke.Length, currentStroke.Center, otherStroke.Length, otherStroke.Center);
                    baseArea -= intersectionArea;
                }

                areaSum += Math.Max(0.001f, baseArea); //todo what to do with other mipmapLevels
            }
            return((float)areaSum);
        }
예제 #9
0
        public void StartDiagram()
        {
            var tonesCount  = 4;
            var levelsCount = 4;

            TaskUtils.SetGlobalMultithreading(false);

            var tones  = TAMTone.GenerateList(tonesCount, 3, 4);
            var levels = TAMMipmapLevel.CreateList(levelsCount);

            var tamPackGenerator = new TAMPackGenerator();
            var msw = new MyStopWatch();

            msw.StartSegment("Gen");
            var pack = tamPackGenerator.GenerateTamPack(GenerateDiagramConfiguration(tones, levels, 0.7f), true, Object.FindObjectOfType <ComputeShaderContainerGameObject>());

            Debug.Log(msw.CollectResults());
            var fileManager = new TAMPackFileManager();

            fileManager.Save(@"C:\mgr\tmp\tam2\", tones, levels, pack);
        }
 public TAMImageDiagram UpdatePerMipmapLevelStrokeParameters(TAMImageDiagram diagram, TAMMipmapLevel level)
 {
     return(new TAMImageDiagram(diagram.Strokes.Select(c => _strokesGenerator.UpdatePerMipmapLevelStrokeParameters(c, level)).ToList()));
 }
예제 #11
0
 public TAMMipmapLevel(int levelIndex, int mipmapLevelsCount, TAMMipmapLevel lowerLevel = null)
 {
     _levelIndex        = levelIndex;
     _lowerLevel        = lowerLevel;
     _mipmapLevelsCount = mipmapLevelsCount;
 }
예제 #12
0
 private void AddNewImageDiagram(TAMImageDiagram template, TAMTone tone, TAMMipmapLevel mipmapLevel)
 {
     _columns[tone][mipmapLevel] = template;
 }
예제 #13
0
 private TAMImageDiagram GenerateNewImageDiagram(TAMImageDiagram baseImageDiagram, TAMTone tone, TAMMipmapLevel mipmapLevel, int seed)
 {
     return(_imageDiagramGenerator.Generate(baseImageDiagram, tone, mipmapLevel, seed));
 }
예제 #14
0
        private List <Image> CreateSoleLayerImages(TAMImageDiagram diagram, TAMMipmapLevel level)
        {
            var margin = _configuration.Margin;
            var soleImageResolution            = _configuration.SoleImagesResolutionPerLevel[level];
            var soleImageResolutionWithMargins = (soleImageResolution * (1 + margin * 2)).ToIntVector2();
            var marginLength = (soleImageResolutionWithMargins - soleImageResolution) / 2;

            var outImages = Enumerable.Range(0, _layersCount)
                            .Select(c => new Bitmap((int)soleImageResolutionWithMargins.X, (int)soleImageResolutionWithMargins.Y, PixelFormat.Format32bppPArgb))
                            .ToList();

            var occupancyArray = new int[(int)soleImageResolutionWithMargins.X, (int)soleImageResolutionWithMargins.Y];

            //Debug.Log($"OutiMages: {outImages[0].Size} || SoleImageResolution {soleImageResolution} Sole with margins {soleImageResolutionWithMargins}");
            foreach (var stroke in diagram.Strokes)
            {
                using (ImageFactory strokeFactory = new ImageFactory(true))
                {
                    var strokeSizeInPixels = VectorUtils.MemberwiseMultiply(
                        new Vector2(stroke.Length, stroke.Height * _configuration.StrokeHeightMultiplierPerLevel[level]), soleImageResolution.ToFloatVec()).ToIntVector2();
                    var rotation = Mathf.Rad2Deg * stroke.Rotation;

                    var rotatedStrokeImage = strokeFactory.Load(_strokeImage)
                                             .Resize(new ResizeLayer(new Size(strokeSizeInPixels.X, strokeSizeInPixels.Y), ResizeMode.Stretch))
                                             .Rotate(rotation).Image;
                    var imageWithId = AddIdToStrokeImage(rotatedStrokeImage, (uint)stroke.Id);

                    var position = VectorUtils.MemberwiseMultiply(UvToMarginUv(stroke.Center), soleImageResolutionWithMargins.ToFloatVec()).ToIntVector2();
                    position -= new IntVector2(rotatedStrokeImage.Width / 2, rotatedStrokeImage.Height / 2);

                    for (int x = 0; x < imageWithId.Size.Width; x++)
                    {
                        for (int y = 0; y < imageWithId.Size.Height; y++)
                        {
                            var inImagePosition = position + new IntVector2(x, y);

                            uint offsetBitX = 0;
                            uint offsetBitY = 0;
                            if (inImagePosition.X - marginLength.X / 2 >= soleImageResolution.X || inImagePosition.X - marginLength.X * 1.5 < 0)
                            {
                                offsetBitX = 1;
                            }
                            if (inImagePosition.Y - marginLength.Y / 2 >= soleImageResolution.Y || inImagePosition.Y - marginLength.Y * 1.5 < 0)
                            {
                                offsetBitY = 1;
                            }

                            inImagePosition.X = inImagePosition.X % soleImageResolutionWithMargins.X; //probably not needed
                            inImagePosition.Y = inImagePosition.Y % soleImageResolutionWithMargins.Y;

                            var strokePixel = imageWithId.GetPixel(x, y);

                            byte newGColor = (byte)((strokePixel.G | (offsetBitX << 6)) | offsetBitY << 7);
                            strokePixel = Color.FromArgb(strokePixel.A, strokePixel.R, newGColor, strokePixel.B);

                            if (strokePixel.A > 0)
                            {
                                var layerIndex = 0;
                                var occupancy  = occupancyArray[inImagePosition.X, inImagePosition.Y];
                                if (occupancy != 0)
                                {
                                    layerIndex = (occupancy) % _layersCount;
                                }
                                occupancyArray[inImagePosition.X, inImagePosition.Y]++;

                                if (!_configuration.UseSmoothAlpha)
                                {
                                    var a = strokePixel.A;
                                    if (a > 0)
                                    {
                                        a = 255;
                                    }

                                    strokePixel = Color.FromArgb(a, strokePixel.R, strokePixel.G, strokePixel.B);
                                }

                                if (!_configuration.UseDithering)
                                {
                                    outImages[layerIndex].SetPixel(inImagePosition.X, inImagePosition.Y, strokePixel);
                                }
                                else
                                {
                                    var oldPixel = outImages[layerIndex].GetPixel(inImagePosition.X, inImagePosition.Y);
                                    if (_configuration.UseSmoothAlpha)
                                    {
                                        var oldAlpha = oldPixel.A;
                                        var maxAlpha = Mathf.Max(oldAlpha, strokePixel.A);
                                        strokePixel = Color.FromArgb(maxAlpha, strokePixel.R, strokePixel.G, strokePixel.B);

                                        if (layerIndex != 0)
                                        {
                                            var layer0Pixel    = outImages[0].GetPixel(inImagePosition.X, inImagePosition.Y);
                                            var layer0OldAlpha = layer0Pixel.A;
                                            if (layer0OldAlpha < strokePixel.A)
                                            {
                                                var newLayer0Pixel = Color.FromArgb(strokePixel.A, layer0Pixel.R, layer0Pixel.G, layer0Pixel.B);
                                                outImages[0].SetPixel(inImagePosition.X, inImagePosition.Y, newLayer0Pixel);
                                            }
                                        }
                                    }

                                    var  ditheringModuler  = Mathf.CeilToInt((float)occupancy / _layersCount) + 1;
                                    bool ditherPixelActive = (inImagePosition.X + inImagePosition.Y) % ditheringModuler == 0;

                                    if (ditherPixelActive)
                                    {
                                        outImages[layerIndex].SetPixel(inImagePosition.X, inImagePosition.Y, strokePixel);
                                    }
                                    else
                                    {
                                        var updatedOldPixel = Color.FromArgb(strokePixel.A, oldPixel.R, oldPixel.G, oldPixel.B);
                                        outImages[layerIndex].SetPixel(inImagePosition.X, inImagePosition.Y, updatedOldPixel);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(outImages.Cast <Image>().ToList());
        }