Used for indexing 2-dimensional lists and arrays Implements +, -, ==, and !=
 /// <summary>
 /// Initializes a new instance of geometric descriptor for a plane.
 /// </summary>
 public PlaneProceduralModel()
 {
     Normal = NormalDirection.UpY;
     Size = new Vector2(1.0f);
     Tessellation = new Int2(1);
     UVScales = new Vector2(1);
 }
Beispiel #2
0
        /// <summary>
        /// Upload a character's bitmap into the current cache.
        /// </summary>
        /// <param name="character">The character specifications corresponding to the bitmap</param>
        public void UploadCharacterBitmap(CharacterSpecification character)
        {
            if(character.Bitmap == null)
                throw new ArgumentNullException("character");

            if(character.IsBitmapUploaded)
                throw new InvalidOperationException("The character '"+character.Character+"' upload has been requested while its current glyph is valid.");

            var targetSize = new Int2(character.Bitmap.Width, character.Bitmap.Rows);
            if (!packer.Insert(targetSize.X, targetSize.Y, ref character.Glyph.Subrect))
            {
                // not enough space to place the new character -> remove less used characters and try again
                RemoveLessUsedCharacters();
                if (!packer.Insert(targetSize.X, targetSize.Y, ref character.Glyph.Subrect))
                {
                    // memory is too fragmented in order to place the new character -> clear all the characters and restart.
                    ClearCache();
                    if (!packer.Insert(targetSize.X, targetSize.Y, ref character.Glyph.Subrect))
                        throw new InvalidOperationException("The rendered character is too big for the cache texture");
                }
            }
            // updload the bitmap on the texture (if the size in the bitmap is not null)
            if (character.Bitmap.Rows != 0 && character.Bitmap.Width != 0)
            {
                var dataBox = new DataBox(character.Bitmap.Buffer, character.Bitmap.Pitch, character.Bitmap.Pitch * character.Bitmap.Rows);
                var region = new ResourceRegion(character.Glyph.Subrect.Left, character.Glyph.Subrect.Top, 0, character.Glyph.Subrect.Right, character.Glyph.Subrect.Bottom, 1);
                system.GraphicsDevice.UpdateSubresource(cacheTextures[0], 0, dataBox, region);
            }

            // update the glyph data
            character.IsBitmapUploaded = true;
            character.Glyph.BitmapIndex = 0;
        }
Beispiel #3
0
    public static Int2[] getPath(Int2 current, Int2 final, GridSystem grid)
    {
        int width = grid.gridSizeX;
        int height = grid.gridSizeZ;
        if (width <= current._x || width <= final._x) {
            return null;
        }
        if (height <= current._z || height <= final._z) {
            return null;
        }
        if (grid[current._x, current._z] == null || grid[final._x,final._z] == null)
        {
            return null;
        }
        int[,] distanceGrid = new int[width, height];
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                distanceGrid[i,j] = -1;
            }
        }

        distanceGrid [current._x, current._z] = 0;
        Int2[] path =  DFS (current, final, grid, distanceGrid);
        Debug.Log ("Path");
        for (int i = 0; i < path.Length; i++) {
            Debug.Log (path[i]);
        }
        return path;
    }
Beispiel #4
0
 public bool RemoveBlock(int x, int y)
 {
     Int2 coord = new Int2(x, y);
     if (blocks.ContainsKey(coord))
     {
         blocks.Remove(coord);
         return true;
     }
     return false;
 }
Beispiel #5
0
        /// <summary>
        /// Creates a default instance of packing attributes.
        /// </summary>
        public PackingAttributes()
        {
            Enabled = true;
            PackingAlgorithm = TexturePackingMethod.Best;

            AllowMultipacking = true;
            AllowRotations = true;

            AtlasMaximumSize = new Int2(2048);

            BorderSize = 2;
        }
        protected override void DrawCore(RenderContext context)
        {
            var output = PrefilteredRadiance;
            if(output == null || (output.Dimension != TextureDimension.Texture2D && output.Dimension != TextureDimension.TextureCube) || output.ArraySize != 6)
                throw new NotSupportedException("Only array of 2D textures are currently supported as output");

            var input = RadianceMap;
            if(input == null || input.Dimension != TextureDimension.TextureCube)
                throw new NotSupportedException("Only cubemaps are currently supported as input");

            var roughness = 0f;
            var faceCount = output.ArraySize;
            var levelSize = new Int2(output.Width, output.Height);
            var mipCount = MipmapGenerationCount == 0 ? output.MipLevels : MipmapGenerationCount;

            for (int l = 0; l < mipCount; l++)
            {
                if (l == 0 && DoNotFilterHighestLevel && input.Width >= output.Width)
                {
                    var inputLevel = MathUtil.Log2(input.Width / output.Width);
                    for (int f = 0; f < 6; f++)
                    {
                        var inputSubresource = inputLevel + f * input.MipLevels;
                        var outputSubresource = 0 + f * output.MipLevels;
                        GraphicsDevice.CopyRegion(input, inputSubresource, null, output, outputSubresource);
                    }
                }
                else
                {
                    var outputView = output.ToTextureView(ViewType.MipBand, 0, l);

                    computeShader.ThreadGroupCounts = new Int3(levelSize.X, levelSize.Y, faceCount);
                    computeShader.ThreadNumbers = new Int3(SamplingsCount, 1, 1);
                    computeShader.Parameters.Set(RadiancePrefilteringGGXShaderKeys.Roughness, roughness);
                    computeShader.Parameters.Set(RadiancePrefilteringGGXShaderKeys.MipmapCount, input.MipLevels - 1);
                    computeShader.Parameters.Set(RadiancePrefilteringGGXShaderKeys.RadianceMap, input);
                    computeShader.Parameters.Set(RadiancePrefilteringGGXShaderKeys.RadianceMapSize, input.Width);
                    computeShader.Parameters.Set(RadiancePrefilteringGGXShaderKeys.FilteredRadiance, outputView);
                    computeShader.Parameters.Set(RadiancePrefilteringGGXParams.NbOfSamplings, SamplingsCount);
                    computeShader.Draw(context);

                    outputView.Dispose();
                }

                if (mipCount > 1)
                {
                    roughness += 1f / (mipCount - 1);
                    levelSize /= 2;
                }
            }
        }
Beispiel #7
0
 /// <summary>
 /// Draws to the specified cube at the specified position.
 /// </summary>
 /// <param name='position'>
 /// Position (from bottom left).
 /// </param>
 /// <param name='cube'>
 /// Cube.
 /// </param>
 public override void DrawTo(Int2 position, Cube cube)
 {
     base.DrawTo(position, cube);
     switch (id)
     {
     case 0:
         cube.FillRect(new Color(128,128,255), Cube.SCREEN_WIDTH/2, Cube.SCREEN_HEIGHT/2-10, 1, 20);
         break;
     case 1:
         cube.FillRect(new Color(128,128,255), Cube.SCREEN_WIDTH/2-4, Cube.SCREEN_HEIGHT/2-10, 1, 20);
         cube.FillRect(new Color(128,128,255), Cube.SCREEN_WIDTH/2+4, Cube.SCREEN_HEIGHT/2-10, 1, 20);
         break;
     }
 }
        public BackgroundSection(Sprite backgroundSprite, Vector3 screenVirtualResolution, float scrollSpeed, float depth, Vector2 startPos = default(Vector2))
        {
            screenResolution = new Int2((int)screenVirtualResolution.X, (int)screenVirtualResolution.Y);
            screenCenter = new Vector2(screenVirtualResolution.X / 2, screenVirtualResolution.Y /2);

            this.depth = depth;
            firstQuadPos = startPos;
            secondQuadPos = startPos;

            ScrollSpeed = scrollSpeed;
            ScrollPos = 0;

            CreateBackground(backgroundSprite.Texture, backgroundSprite.Region);
        }
Beispiel #9
0
        public BeadSelectorDlg(FloatImg image, int ROI, Int2[] positions)
        {
            InitializeComponent();

            if (!DesignMode)
            {
                dispImage = image.ToImage();
                this.image = image;
                pictureBox.Image = dispImage;
                roiPositions = positions.ToList();
            }
            DialogResult = System.Windows.Forms.DialogResult.Cancel;
            textBoxROI.Text = ROI.ToString();
        }
Beispiel #10
0
    void FixedUpdate() {
        mousePos = Input.mousePosition;
        foreach (var town in Towns)
        {
            Int2 mousePosInt = new Int2();
            Tile.ScreenToMapPosition(mousePos, out mousePosInt);

            if (Vector2.Distance(town.location.ToVector2(), mousePosInt.ToVector2()) < .32f)
            {
                selectedTownPos = Tile.MapToWorldPosition(town.location);
                selectedTownName = town.name;
                print(town.name);
            }
        }
    }
	// Update is called once per frame
	void Update () {

		// Calculate the tile the target is standing on
		Int2 p = new Int2 ( Mathf.RoundToInt ((target.position.x - tileSize*0.5f) / tileSize), Mathf.RoundToInt ((target.position.z - tileSize*0.5f) / tileSize) );

		// Clamp range
		range = range < 1 ? 1 : range;

		// Remove tiles which are out of range
		bool changed = true;
		while ( changed ) {
			changed = false;
			foreach (KeyValuePair<Int2,ProceduralTile> pair in tiles ) {
				if ( Mathf.Abs (pair.Key.x-p.x) > range || Mathf.Abs (pair.Key.y-p.y) > range ) {
					pair.Value.Destroy ();
					tiles.Remove ( pair.Key );
					changed = true;
					break;
				}
			}
		}

		// Add tiles which have come in range
		// and start calculating them
		for ( int x = p.x-range; x <= p.x+range; x++ ) {
			for ( int z = p.y-range; z <= p.y+range; z++ ) {
				if ( !tiles.ContainsKey ( new Int2(x,z) ) ) {
					ProceduralTile tile = new ProceduralTile ( this, x, z );
					var generator = tile.Generate ();
					// Tick it one step forward
					generator.MoveNext ();
					// Calculate the rest later
					tileGenerationQueue.Enqueue (generator);
					tiles.Add ( new Int2(x,z), tile );
				}
			}
		}

		// The ones directly adjacent to the current one
		// should always be completely calculated
		// make sure they are
		for ( int x = p.x-1; x <= p.x+1; x++ ) {
			for ( int z = p.y-1; z <= p.y+1; z++ ) {
				tiles[new Int2(x,z)].ForceFinish();
			}
		}

	}
Beispiel #12
0
 public void SetUp()
 {
     var x = 50;
     var y = 75;
     var width = 100;
     var height = 125;
     _aabb = new AABB(x, y, width, height);
     _top = y;
     _left = x;
     _right = x + width;
     _bottom = y + height;
     _topLeft = new Int2(_left, _top);
     _topRight = new Int2(_right, _top);
     _bottomLeft = new Int2(_left, _bottom);
     _bottomRight = new Int2(_right, _bottom);
 }
    public static PlatformGroup Combine(PlatformGroup lhs, PlatformGroup rhs, Int2 playerIdx)
    {
        GameObject output = new GameObject("PlatformGroup");
        PlatformGroup outputGroup = output.AddComponent<PlatformGroup>();
        outputGroup.container = new HashSet<Platform>();
        //outputGroup.OnGroupMoved += robot.replanPath;

        //transfer ownership
        outputGroup.container.UnionWith(lhs.container);
        outputGroup.container.UnionWith(rhs.container);

        //transfer childObjs
        List<Transform> children = new List<Transform>();
        for (int i = 0; i < lhs.gameObject.transform.childCount; i++)
            children.Add(lhs.gameObject.transform.GetChild(i));
        foreach (Transform child in children)
            child.transform.parent = output.transform;

        children.Clear();
        for (int i = 0; i < rhs.gameObject.transform.childCount; i++)
            children.Add(rhs.gameObject.transform.GetChild(i));
        foreach (Transform child in children)
            child.transform.parent = output.transform;

        //Vector2 robotPos2d = new Vector2(robot.transform.position.x, robot.transform.position.z);
        if (ReferenceEquals(lhs, gridSystem.ComputeGroup(playerIdx)) ||
            ReferenceEquals(rhs, gridSystem.ComputeGroup(playerIdx)) ||
            ReferenceEquals(lhs, gridSystem.ComputeGroup(gridSystem.goal)) ||
            ReferenceEquals(rhs, gridSystem.ComputeGroup(gridSystem.goal)))
        {
            foreach (Transform child in output.transform)
                child.gameObject.layer = Utility.ToLayerNumber(gridSystem.lockedPfLayer);//?

        }

        foreach (Platform pf in outputGroup.container)
            pf.group = outputGroup;

        lhs.container.Clear();
        rhs.container.Clear();
        Destroy(lhs.gameObject);
        Destroy(rhs.gameObject);

        return outputGroup;
    }
Beispiel #14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CharacterBitmap"/> class from a data array.
        /// </summary>
        /// <param name="pixelMode">The data format of the bitmap data</param>
        /// <param name="data">The bitmap data</param>
        /// <param name="borderSize">The size of the border around the image</param>
        /// <param name="width">The width of the bitmap </param>
        /// <param name="rows">The height of the bitmap</param>
        /// <param name="pitch">The pitch of the bitmap</param>
        /// <param name="grayLevels">The number of gray levels of the bitmap</param>
        public CharacterBitmap(IntPtr data, ref Int2 borderSize, int width, int rows, int pitch, int grayLevels, PixelMode pixelMode)
        {
            // add one empty border to each side of the bitmap
            width += 2 * borderSize.X;
            rows += 2 * borderSize.Y;

            buffer = Utilities.AllocateMemory(width * rows, 1);

            if (pixelMode == PixelMode.Mono)
                CopyAndAddBordersFromMono(data, buffer, ref borderSize, width, rows, pitch);
            else
                CopyAndAddBordersFromGrays(data, buffer, ref borderSize, width, rows);

            this.width = width;
            this.rows = rows;
            this.pitch = width;
            this.grayLevels = grayLevels;
            this.pixelMode = pixelMode;
        }
    public int[,] ExecuteAlgorithm(int numTiles, out List<Vector2> openPositions, out Vector3 playerSpawn)
    {
        openPositions = new List<Vector2>();

        int[,] level = new int[numTiles * 2, numTiles * 2];

        set2DArrayDefaults(level, 2);

        int startingX = numTiles, startingY = numTiles;

        Int2 current = new Int2(startingX, startingY);
        Int2 directionLastMoved = new Int2(0, 0);
        int numTilesPlaced = 0;

        // For resizing the level
        int leftX = current.x;
        int rightX = current.x;
        int topY = current.y;
        int bottomY = current.y;

        while (numTilesPlaced < numTiles)
        {
            leftX = current.x < leftX ? current.x : leftX;
            rightX = current.x > rightX ? current.x : rightX;
            topY = current.y > topY ? current.y : topY;
            bottomY = current.y < bottomY ? current.y : bottomY;

            if (level[current.x, current.y] == 2)
            {
                level[current.x, current.y] = 1;
                numTilesPlaced++;
            }

            current += getRandomDirection(new int[] { 25, 25, 25, 25 });
        }

        playerSpawn = new Vector3((startingY - bottomY + 1) * LoadLevel.TileSize, (startingX - leftX + 1) * LoadLevel.TileSize, 0);

        return cropLevel(level, leftX, rightX, topY, bottomY, openPositions);
    }
Beispiel #16
0
        public FieldPlane(Plane plane, Texture2D field, Int2 texSize, float timeSlice = 0, float invalidValue = float.MaxValue, RenderEffect effect = RenderEffect.DEFAULT, Colormap map = Colormap.Parula)
        {
            this._effect = _planeEffect;
            this._vertexSizeBytes = 32;
            this._numVertices = 6;
            this.UsedMap = map;
            this._width = texSize.X;
            this._height = texSize.Y;
            this._invalid = invalidValue;

            // Setting up the vertex buffer.
            GenerateGeometry(plane, texSize, timeSlice);

            // Generating Textures from the fields.
            _fieldTextures = new ShaderResourceView[1];
            _fieldTextures[0] = new ShaderResourceView(_device, field);

            this.SetRenderEffect(effect);
            this._vertexLayout = new InputLayout(_device, _technique.GetPassByIndex(0).Description.Signature, new[] {
                new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
                new InputElement("TEXTURE", 0, Format.R32G32B32A32_Float, 16, 0)
            });
        }
    void setTiles(int[,] generatedLevel, Vector3 playerSpawn, GameObject player)
    {
        Int2 mapDimensions = new Int2(generatedLevel.GetLength(1), generatedLevel.GetLength(0));

        // create level
        Tile.NewLevel(mapDimensions, 0, TILE_SIZE, 0, LayerLock.None);
        Tile.AddLayer(mapDimensions, 0, TILE_SIZE, 0, LayerLock.None);

        // set sorting layers
        Tile.SetLayerSorting(0, 0);
        Tile.SetLayerSorting(1, 1);

        // set collider layer so that walls can be detected by raycasting
        Tile.SetColliderLayer(WALL_LAYER);

        for (int row = 0; row < generatedLevel.GetLength(0); row++)
        {
            for (int col = 0; col < generatedLevel.GetLength(1); col++)
            {
                Int2 tileLocation = new Int2(col, row);
                bool isWall = WALL_INDICES.Contains(generatedLevel[row, col]);
                int tileIndex = generatedLevel[row, col];
                int spriteTileLayerIndex = isWall ? 1 : 0;

                Tile.SetTile(tileLocation, spriteTileLayerIndex, 0, tileIndex, false);

                if (isWall && hasAdjacentFloor(generatedLevel, row, col))
                {
                    Tile.SetCollider(tileLocation, 1, true);
                }
            }
        }

        StartCoroutine("ConfigureColliders");
        player.GetComponent<Rigidbody2D>().position = playerSpawn;
    }
Beispiel #18
0
        private static unsafe void CopyAndAddBordersFromGrays(IntPtr data, IntPtr dataBytes, ref Int2 borderSize, int width, int rows)
        {
            var widthLessBorders = width - (borderSize.X << 1);
            var rowsLessBorders = rows - (borderSize.Y << 1);

            var resetBorderLineSize = width * borderSize.Y;
            Utilities.ClearMemory(dataBytes, 0, resetBorderLineSize);
            Utilities.ClearMemory(dataBytes + width * rows - resetBorderLineSize, 0, resetBorderLineSize); // set last border lines to null
            
            var src = (byte*)data;
            var dst = (byte*)dataBytes + resetBorderLineSize;

            // set the middle of the image
            for (int row = 0; row < rowsLessBorders; row++)
            {
                for (int c = 0; c < borderSize.X; c++)
                {
                    *dst = 0;
                    ++dst;
                }

                for (int c = 0; c < widthLessBorders; c++)
                {
                    *dst = *src;

                    ++dst;
                    ++src;
                }

                for (int c = 0; c < borderSize.X; c++)
                {
                    *dst = 0;
                    ++dst;
                }
            }
        }
Beispiel #19
0
 public GridEntity Peek(Int2 u)
 {
     return(Peek(u.row, u.col));
 }
Beispiel #20
0
 public bool Contains(Int2 point)
 {
     return(point.x >= this.xMin && point.x < this.xMax && point.y >= this.yMin && point.y < this.yMax);
 }
Beispiel #21
0
        /// <summary>
        /// Determine the output format of the texture depending on the platform and asset properties.
        /// </summary>
        /// <param name="parameters">The conversion request parameters</param>
        /// <param name="imageSize">The texture output size</param>
        /// <param name="inputImageFormat">The pixel format of the input image</param>
        /// <returns>The pixel format to use as output</returns>
        public static PixelFormat DetermineOutputFormat(ImportParameters parameters, Int2 imageSize, PixelFormat inputImageFormat)
        {
            var hint      = parameters.TextureHint;
            var alphaMode = parameters.DesiredAlpha;

            // Default output format
            var outputFormat = PixelFormat.R8G8B8A8_UNorm;

            switch (parameters.DesiredFormat)
            {
            case TextureFormat.Compressed:
                switch (parameters.Platform)
                {
                case PlatformType.Android:
                    if (inputImageFormat.IsHDR())
                    {
                        outputFormat = inputImageFormat;
                    }
                    else
                    {
                        switch (parameters.GraphicsProfile)
                        {
                        case GraphicsProfile.Level_9_1:
                        case GraphicsProfile.Level_9_2:
                        case GraphicsProfile.Level_9_3:
                            outputFormat = alphaMode == AlphaFormat.None && !parameters.IsSRgb ? PixelFormat.ETC1 : parameters.IsSRgb ? PixelFormat.R8G8B8A8_UNorm_SRgb : PixelFormat.R8G8B8A8_UNorm;
                            break;

                        case GraphicsProfile.Level_10_0:
                        case GraphicsProfile.Level_10_1:
                        case GraphicsProfile.Level_11_0:
                        case GraphicsProfile.Level_11_1:
                        case GraphicsProfile.Level_11_2:
                            // GLES3.0 starting from Level_10_0, this profile enables ETC2 compression on Android
                            outputFormat = alphaMode == AlphaFormat.None && !parameters.IsSRgb ? PixelFormat.ETC1 : parameters.IsSRgb ? PixelFormat.ETC2_RGBA_SRgb : PixelFormat.ETC2_RGBA;
                            break;

                        default:
                            throw new ArgumentOutOfRangeException("GraphicsProfile");
                        }
                    }
                    break;

                case PlatformType.iOS:
                    // PVRTC works only for square POT textures
                    if (inputImageFormat.IsHDR())
                    {
                        outputFormat = inputImageFormat;
                    }
                    else if (SupportPVRTC(imageSize))
                    {
                        switch (alphaMode)
                        {
                        case AlphaFormat.None:
                            outputFormat = parameters.IsSRgb ? PixelFormat.PVRTC_4bpp_RGB_SRgb : PixelFormat.PVRTC_4bpp_RGB;
                            break;

                        case AlphaFormat.Mask:
                            // DXT1 handles 1-bit alpha channel
                            // TODO: Not sure about the equivalent here?
                            outputFormat = parameters.IsSRgb ? PixelFormat.PVRTC_4bpp_RGBA_SRgb : PixelFormat.PVRTC_4bpp_RGBA;
                            break;

                        case AlphaFormat.Explicit:
                        case AlphaFormat.Interpolated:
                            // DXT3 is good at sharp alpha transitions
                            // TODO: Not sure about the equivalent here?
                            outputFormat = parameters.IsSRgb ? PixelFormat.PVRTC_4bpp_RGBA_SRgb : PixelFormat.PVRTC_4bpp_RGBA;
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                    }
                    else
                    {
                        outputFormat = parameters.IsSRgb ? PixelFormat.R8G8B8A8_UNorm_SRgb : PixelFormat.R8G8B8A8_UNorm;
                    }
                    break;

                case PlatformType.Windows:
                case PlatformType.WindowsPhone:
                case PlatformType.WindowsStore:
                case PlatformType.Windows10:
                    switch (parameters.GraphicsPlatform)
                    {
                    case GraphicsPlatform.Direct3D11:


                        // https://msdn.microsoft.com/en-us/library/windows/desktop/hh308955%28v=vs.85%29.aspx
                        // http://www.reedbeta.com/blog/2012/02/12/understanding-bcn-texture-compression-formats/
                        // ----------------------------------------------    ----------------------------------------------------                        ---    ---------------------------------
                        // Source data                                       Minimum required data compression resolution                     Recommended format	Minimum supported feature level
                        // ----------------------------------------------    ----------------------------------------------------                        ---    ---------------------------------
                        // Three-channel color with alpha channel            Three color channels (5 bits:6 bits:5 bits), with 0 or 1 bit(s) of alpha    BC1    Direct3D 9.1     (color maps, cutout color maps - 1 bit alpha, normal maps if memory is tight)
                        // Three-channel color with alpha channel            Three color channels (5 bits:6 bits:5 bits), with 4 bits of alpha           BC2    Direct3D 9.1     (idem)
                        // Three-channel color with alpha channel            Three color channels (5 bits:6 bits:5 bits) with 8 bits of alpha            BC3    Direct3D 9.1     (color maps with alpha, packing color and mono maps together)
                        // One-channel color                                 One color channel (8 bits)                                                  BC4    Direct3D 10      (Height maps, gloss maps, font atlases, any gray scales image)
                        // Two-channel color	                             Two color channels (8 bits:8 bits)                                          BC5    Direct3D 10      (Tangent space normal maps)
                        // Three-channel high dynamic range (HDR) color      Three color channels (16 bits:16 bits:16 bits) in "half" floating point*    BC6H   Direct3D 11      (HDR images)
                        // Three-channel color, alpha channel optional       Three color channels (4 to 7 bits per channel) with 0 to 8 bits of alpha    BC7    Direct3D 11      (High quality color maps, Color maps with full alpha)

                        switch (alphaMode)
                        {
                        case AlphaFormat.None:
                        case AlphaFormat.Mask:
                            // DXT1 handles 1-bit alpha channel
                            outputFormat = parameters.IsSRgb ? PixelFormat.BC1_UNorm_SRgb : PixelFormat.BC1_UNorm;
                            break;

                        case AlphaFormat.Explicit:
                            // DXT3 is good at sharp alpha transitions
                            outputFormat = parameters.IsSRgb ? PixelFormat.BC2_UNorm_SRgb : PixelFormat.BC2_UNorm;
                            break;

                        case AlphaFormat.Interpolated:
                            // DXT5 is good at alpha gradients
                            outputFormat = parameters.IsSRgb ? PixelFormat.BC3_UNorm_SRgb : PixelFormat.BC3_UNorm;
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }

                        // Overrides the format when profile is >= 10.0
                        // Support some specific optimized formats based on the hint or input type
                        if (parameters.GraphicsProfile >= GraphicsProfile.Level_10_0)
                        {
                            if (hint == TextureHint.NormalMap)
                            {
                                outputFormat = PixelFormat.BC5_SNorm;
                            }
                            else if (hint == TextureHint.Grayscale)
                            {
                                outputFormat = PixelFormat.BC4_UNorm;
                            }
                            else if (inputImageFormat.IsHDR())
                            {
                                // BC6H is too slow to compile
                                //outputFormat = parameters.GraphicsProfile >= GraphicsProfile.Level_11_0 && alphaMode == AlphaFormat.None ? PixelFormat.BC6H_Uf16 : inputImageFormat;
                                outputFormat = inputImageFormat;
                            }
                            // TODO support the BC6/BC7 but they are so slow to compile that we can't use them right now
                        }
                        break;

                    case GraphicsPlatform.OpenGLES:             // OpenGLES on Windows
                        if (inputImageFormat.IsHDR())
                        {
                            outputFormat = inputImageFormat;
                        }
                        else if (parameters.IsSRgb)
                        {
                            outputFormat = PixelFormat.R8G8B8A8_UNorm_SRgb;
                        }
                        else
                        {
                            switch (parameters.GraphicsProfile)
                            {
                            case GraphicsProfile.Level_9_1:
                            case GraphicsProfile.Level_9_2:
                            case GraphicsProfile.Level_9_3:
                                outputFormat = alphaMode == AlphaFormat.None ? PixelFormat.ETC1 : PixelFormat.R8G8B8A8_UNorm;
                                break;

                            case GraphicsProfile.Level_10_0:
                            case GraphicsProfile.Level_10_1:
                            case GraphicsProfile.Level_11_0:
                            case GraphicsProfile.Level_11_1:
                            case GraphicsProfile.Level_11_2:
                                // GLES3.0 starting from Level_10_0, this profile enables ETC2 compression on Android
                                outputFormat = alphaMode == AlphaFormat.None ? PixelFormat.ETC1 : PixelFormat.ETC2_RGBA;
                                break;

                            default:
                                throw new ArgumentOutOfRangeException("GraphicsProfile");
                            }
                        }
                        break;

                    default:
                        // OpenGL on Windows
                        // TODO: Need to handle OpenGL Desktop compression
                        outputFormat = parameters.IsSRgb ? PixelFormat.R8G8B8A8_UNorm_SRgb : PixelFormat.R8G8B8A8_UNorm;
                        break;
                    }
                    break;

                case PlatformType.Linux:
                    // OpenGL on Linux
                    // TODO: Need to handle OpenGL Desktop compression
                    outputFormat = parameters.IsSRgb ? PixelFormat.R8G8B8A8_UNorm_SRgb : PixelFormat.R8G8B8A8_UNorm;
                    break;

                default:
                    throw new NotSupportedException("Platform " + parameters.Platform + " is not supported by TextureTool");
                }
                break;

            case TextureFormat.Color16Bits:
                if (parameters.IsSRgb)
                {
                    outputFormat = PixelFormat.R8G8B8A8_UNorm_SRgb;
                }
                else
                {
                    if (alphaMode == AlphaFormat.None)
                    {
                        outputFormat = PixelFormat.B5G6R5_UNorm;
                    }
                    else if (alphaMode == AlphaFormat.Mask)
                    {
                        outputFormat = PixelFormat.B5G5R5A1_UNorm;
                    }
                }
                break;

            case TextureFormat.Color32Bits:
                if (parameters.IsSRgb)
                {
                    outputFormat = PixelFormat.R8G8B8A8_UNorm_SRgb;
                }
                break;

            case TextureFormat.AsIs:
                outputFormat = inputImageFormat;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            return(outputFormat);
        }
Beispiel #22
0
        public static Int2 AlignedDown(this Int2 s, int alignment)
        {
            int as1 = ~(alignment - 1);

            return(new Int2(s.X & as1, s.Y & as1));
        }
Beispiel #23
0
 public IEnumerable <Actor> RenderableActorsInBox(Int2 a, Int2 b)
 {
     //return ActorsInBox(RectWithCorners(a, b));
     return(partitionedRenderableActors.InBox(RectWithCorners(a, b)).Where(actorIsInWorld));
 }
Beispiel #24
0
 // 坐标检查
 public bool IsValidCoord(Int2 coord)
 {
     return(coord.x >= 0 && coord.x < cellCountX && coord.y >= 0 && coord.y < cellCountY);
 }
Beispiel #25
0
 public Repeater(Int2 mainPosition, int rotation, Archetype archetype) : base(mainPosition, rotation, archetype)
 {
     InPorts  = new[] { new Port(this, PortType.input, Int2.zero, Int2.left) };
     OutPorts = new[] { new Port(this, PortType.output, Int2.zero, Int2.right) };
 }
Beispiel #26
0
    IEnumerator UpdateGraphCoroutine()
    {
        // Find the direction
        // that we want to move the graph in
        Vector3 dir = target.position - graph.center;

        // Snap to a whole number of nodes
        dir.x = Mathf.Round(dir.x / graph.nodeSize) * graph.nodeSize;
        dir.z = Mathf.Round(dir.z / graph.nodeSize) * graph.nodeSize;
        dir.y = 0;

        // Nothing do to
        if (dir == Vector3.zero)
        {
            yield break;
        }

        // Number of nodes to offset in each
        // direction
        Int2 offset = new Int2(-Mathf.RoundToInt(dir.x / graph.nodeSize), -Mathf.RoundToInt(dir.z / graph.nodeSize));

        // Move the center
        graph.center += dir;
        graph.GenerateMatrix();

        // Create a temporary buffer
        // required for the calculations
        if (tmp == null || tmp.Length != graph.nodes.Length)
        {
            tmp = new GridNode[graph.nodes.Length];
        }

        // Cache some variables for easier access
        int width = graph.width;
        int depth = graph.depth;

        GridNode[] nodes = graph.nodes;

        // Check if we have moved
        // less than a whole graph
        // width in any direction
        if (Mathf.Abs(offset.x) <= width && Mathf.Abs(offset.y) <= depth)
        {
            // Offset each node by the #offset variable
            // nodes which would end up outside the graph
            // will wrap around to the other side of it
            for (int z = 0; z < depth; z++)
            {
                int pz = z * width;
                int tz = ((z + offset.y + depth) % depth) * width;
                for (int x = 0; x < width; x++)
                {
                    tmp[tz + ((x + offset.x + width) % width)] = nodes[pz + x];
                }
            }

            yield return(null);

            // Copy the nodes back to the graph
            // and set the correct indices
            for (int z = 0; z < depth; z++)
            {
                int pz = z * width;
                for (int x = 0; x < width; x++)
                {
                    GridNode node = tmp[pz + x];
                    node.NodeInGridIndex = pz + x;
                    nodes[pz + x]        = node;
                }
            }


            IntRect r    = new IntRect(0, 0, offset.x, offset.y);
            int     minz = r.ymax;
            int     maxz = depth;

            // If offset.x < 0, adjust the rect
            if (r.xmin > r.xmax)
            {
                int tmp2 = r.xmax;
                r.xmax = width + r.xmin;
                r.xmin = width + tmp2;
            }

            // If offset.y < 0, adjust the rect
            if (r.ymin > r.ymax)
            {
                int tmp2 = r.ymax;
                r.ymax = depth + r.ymin;
                r.ymin = depth + tmp2;

                minz = 0;
                maxz = r.ymin;
            }

            // Make sure erosion is taken into account
            // Otherwise we would end up with ugly artifacts
            r = r.Expand(graph.erodeIterations + 1);

            // Makes sure the rect stays inside the grid
            r = IntRect.Intersection(r, new IntRect(0, 0, width, depth));

            yield return(null);

            // Update all nodes along one edge of the graph
            // With the same width as the rect
            for (int z = r.ymin; z < r.ymax; z++)
            {
                for (int x = 0; x < width; x++)
                {
                    graph.UpdateNodePositionCollision(nodes[z * width + x], x, z, false);
                }
            }

            yield return(null);

            // Update all nodes along the other edge of the graph
            // With the same width as the rect
            for (int z = minz; z < maxz; z++)
            {
                for (int x = r.xmin; x < r.xmax; x++)
                {
                    graph.UpdateNodePositionCollision(nodes[z * width + x], x, z, false);
                }
            }

            yield return(null);

            // Calculate all connections for the nodes
            // that might have changed
            for (int z = r.ymin; z < r.ymax; z++)
            {
                for (int x = 0; x < width; x++)
                {
                    graph.CalculateConnections(nodes, x, z, nodes[z * width + x]);
                }
            }

            yield return(null);

            // Calculate all connections for the nodes
            // that might have changed
            for (int z = minz; z < maxz; z++)
            {
                for (int x = r.xmin; x < r.xmax; x++)
                {
                    graph.CalculateConnections(nodes, x, z, nodes[z * width + x]);
                }
            }

            yield return(null);

            // Calculate all connections for the nodes along the boundary
            // of the graph, these always need to be updated
            /** \todo Optimize to not traverse all nodes in the graph, only those at the edges */
            for (int z = 0; z < depth; z++)
            {
                for (int x = 0; x < width; x++)
                {
                    if (x == 0 || z == 0 || x >= width - 1 || z >= depth - 1)
                    {
                        graph.CalculateConnections(nodes, x, z, nodes[z * width + x]);
                    }
                }
            }
        }
        else
        {
            // Just update all nodes
            for (int z = 0; z < depth; z++)
            {
                for (int x = 0; x < width; x++)
                {
                    graph.UpdateNodePositionCollision(nodes[z * width + x], x, z, false);
                }
            }

            // Recalculate the connections of all nodes
            for (int z = 0; z < depth; z++)
            {
                for (int x = 0; x < width; x++)
                {
                    graph.CalculateConnections(nodes, x, z, nodes[z * width + x]);
                }
            }
        }

        if (floodFill)
        {
            yield return(null);

            // Make sure the areas for the graph
            // have been recalculated
            // not doing this can cause pathfinding to fail
            AstarPath.active.QueueWorkItemFloodFill();
        }
    }
Beispiel #27
0
 public void Uniform2(int location, Int2 value)
 {
     TKGL.Uniform2(location, value.X, value.Y);
 }
Beispiel #28
0
 public IEnumerable <ActorBoundsPair> ActorsInMouseBox(Int2 a, Int2 b)
 {
     return(ActorsInMouseBox(RectWithCorners(a, b)));
 }
Beispiel #29
0
        //public IEnumerable<FrozenActor> FrozenActorsInBox(Player p,Int2 a,Int2 b)
        //{
        //    return FrozenActorsInBox(p, RectWithCorners(a, b));
        //}

        public IEnumerable <FrozenActor> RenderableFrozenActorsInBox(Player p, Int2 a, Int2 b)
        {
            if (p == null)
            {
                return(NoFrozenActors);
            }
            return(partitionedRenderableFrozenActors[p].InBox(RectWithCorners(a, b)).Where(frozenActorIsValid));
        }
Beispiel #30
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="r"></param>
        /// <returns></returns>
        //public IEnumerable<Actor> ActorsInBox(Rectangle r)
        //{
        //    return partitionedActors.InBox(r).Where(actorIsInWorld);
        //}


        static Rectangle RectWithCorners(Int2 a, Int2 b)
        {
            return(Rectangle.FromLTRB(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y), Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)));
        }
 /// <inheritdoc/>
 public TPixel this[Int2 xy] => throw new InvalidExecutionContextException($"{typeof(ReadOnlyTexture2D<T,TPixel>)}[{typeof(Int2)}]");
Beispiel #32
0
 /// <summary>
 /// Returns true if the PVRTC can be used for the provided texture size.
 /// </summary>
 /// <param name="textureSize">the size of the texture</param>
 /// <returns>true if PVRTC is supported</returns>
 public static bool SupportPVRTC(Int2 textureSize)
 {
     return textureSize.X == textureSize.Y && MathUtil.IsPow2(textureSize.X);
 }
Beispiel #33
0
 public override Sprite GetSprite(Int2 localPosition) => repeaterSprite;
Beispiel #34
0
 /// <summary>
 /// Create a new thumbnail request from entity.
 /// </summary>
 /// <param name="thumbnailUrl">The Url of the thumbnail</param>
 /// <param name="scene">The scene describing the thumbnail to draw</param>
 /// <param name="provider">The provider to use for the request.</param>
 /// <param name="thumbnailSize">The desired size of the thumbnail</param>
 /// <param name="colorSpace">The color space.</param>
 /// <param name="renderingMode">the rendering mode (hdr or ldr).</param>
 /// <param name="logger">The logger</param>
 /// <param name="logLevel">The dependency build status log level</param>
 public ThumbnailBuildRequest(string thumbnailUrl, Scene scene, GraphicsCompositor graphicsCompositor, DatabaseFileProvider provider, Int2 thumbnailSize, ColorSpace colorSpace, RenderingMode renderingMode, ILogger logger, LogMessageType logLevel)
 {
     Logger                = logger;
     Url                   = thumbnailUrl;
     Size                  = thumbnailSize;
     Scene                 = scene;
     GraphicsCompositor    = graphicsCompositor;
     FileProvider          = provider;
     DependencyBuildStatus = logLevel;
     ColorSpace            = colorSpace;
     RenderingMode         = renderingMode;
 }
Beispiel #35
0
 bool HasAnyValueInSingle(Int2 single)
 {
     return(single.x >= 0 && single.y >= 0);
 }
Beispiel #36
0
            public EditChunkMaterialAction(FlaxEngine.Terrain terrain, ref Int2 patchCoord, ref Int2 chunkCoord, MaterialBase toSet)
            {
                if (terrain == null)
                {
                    throw new ArgumentException(nameof(terrain));
                }

                _terrainId      = terrain.ID;
                _patchCoord     = patchCoord;
                _chunkCoord     = chunkCoord;
                _beforeMaterial = terrain.GetChunkOverrideMaterial(ref patchCoord, ref chunkCoord)?.ID ?? Guid.Empty;
                _afterMaterial  = toSet?.ID ?? Guid.Empty;
            }
Beispiel #37
0
        public static ResultStatus ImportTextureImage(TextureTool textureTool, TexImage texImage, ImportParameters parameters, CancellationToken cancellationToken, Logger logger)
        {
            var assetManager = new AssetManager();

            // Apply transformations
            textureTool.Decompress(texImage, parameters.IsSRgb);

            // Special case when the input texture is monochromatic but it is supposed to be a color and we are working in SRGB
            // In that case, we need to transform it to a supported SRGB format (R8G8B8A8_UNorm_SRgb)
            // TODO: As part of a conversion phase, this code may be moved to a dedicated method in this class at some point
            if (parameters.TextureHint == TextureHint.Color && parameters.IsSRgb && (texImage.Format == PixelFormat.R8_UNorm || texImage.Format == PixelFormat.A8_UNorm))
            {
                textureTool.Convert(texImage, PixelFormat.R8G8B8A8_UNorm_SRgb);
            }

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
                return ResultStatus.Cancelled;

            var fromSize =  new Size2(texImage.Width, texImage.Height);
            var targetSize = parameters.DesiredSize;

            // Resize the image
            if (parameters.IsSizeInPercentage)
            {
                targetSize = new Size2((int)(fromSize.Width * targetSize.Width / 100.0f), (int)(fromSize.Height * targetSize.Height / 100.0f));
            }

            // Find the target size
            targetSize = FindBestTextureSize(parameters, targetSize, logger);

            // Resize the image only if needed
            if (targetSize != fromSize)
            {
                textureTool.Resize(texImage, targetSize.Width, targetSize.Height, Filter.Rescaling.Lanczos3);
            }

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
                return ResultStatus.Cancelled;

            // texture size is now determined, we can cache it
            var textureSize = new Int2(texImage.Width, texImage.Height);

            // determine the alpha format of the texture when set to Auto
            // Note: this has to be done before the ColorKey transformation in order to be able to take advantage of image file AlphaDepth information
            if(parameters.DesiredAlpha == AlphaFormat.Auto)
            {
                var colorKey = parameters.ColorKeyEnabled? (Color?)parameters.ColorKeyColor : null;
                var alphaLevel = textureTool.GetAlphaLevels(texImage, new Rectangle(0, 0, textureSize.X, textureSize.Y), colorKey, logger);
                parameters.DesiredAlpha = alphaLevel.ToAlphaFormat();
            }

            // Apply the color key
            if (parameters.ColorKeyEnabled)
                textureTool.ColorKey(texImage, parameters.ColorKeyColor);

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
                return ResultStatus.Cancelled;

            // Pre-multiply alpha only for relevant formats 
            if (parameters.PremultiplyAlpha && texImage.Format.HasAlpha32Bits())
                textureTool.PreMultiplyAlpha(texImage);

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
                return ResultStatus.Cancelled;


            // Generate mipmaps
            if (parameters.GenerateMipmaps)
            {
                var boxFilteringIsSupported = !texImage.Format.IsSRgb() || (MathUtil.IsPow2(textureSize.X) && MathUtil.IsPow2(textureSize.Y));
                textureTool.GenerateMipMaps(texImage, boxFilteringIsSupported? Filter.MipMapGeneration.Box: Filter.MipMapGeneration.Linear);
            }
                
            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
                return ResultStatus.Cancelled;


            // Convert/Compress to output format
            // TODO: Change alphaFormat depending on actual image content (auto-detection)?
            var outputFormat = DetermineOutputFormat(parameters, textureSize, texImage.Format);
            textureTool.Compress(texImage, outputFormat, (TextureConverter.Requests.TextureQuality)parameters.TextureQuality);

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
                return ResultStatus.Cancelled;

            // Save the texture
            using (var outputImage = textureTool.ConvertToParadoxImage(texImage))
            {
                if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
                    return ResultStatus.Cancelled;

                assetManager.Save(parameters.OutputUrl, outputImage.ToSerializableVersion());

                logger.Info("Compression successful [{3}] to ({0}x{1},{2})", outputImage.Description.Width, outputImage.Description.Height, outputImage.Description.Format, parameters.OutputUrl);
            }

            return ResultStatus.Successful;
        }
Beispiel #38
0
 public IEnumerable <IEffect> RenderableEffectsInBox(Int2 a, Int2 b)
 {
     return(partitionedRenderableEffects.InBox(RectWithCorners(a, b)));
 }
Beispiel #39
0
 /// <summary>
 /// Request a thumbnail build action to the preview game.
 /// </summary>
 /// <param name="thumbnailUrl">The url of the thumbnail on the storage</param>
 /// <param name="scene">The scene to use to draw the thumbnail</param>
 /// <param name="graphicsCompositor">The graphics compositor used to render the scene</param>
 /// <param name="provider">The file provider to use when executing the build request.</param>
 /// <param name="thumbnailSize">The size of the thumbnail to create</param>
 /// <param name="colorSpace"></param>
 /// <param name="renderingMode">the rendering mode (hdr or ldr).</param>
 /// <param name="logger">The logger</param>
 /// <param name="logLevel">The dependency build status log level</param>
 /// <param name="postProcessThumbnail">The post-process code to customize thumbnail.</param>
 /// <returns>A task on which the user can wait for the thumbnail completion</returns>
 public ResultStatus BuildThumbnail(string thumbnailUrl, Scene scene, GraphicsCompositor graphicsCompositor, DatabaseFileProvider provider, Int2 thumbnailSize, ColorSpace colorSpace, RenderingMode renderingMode, ILogger logger, LogMessageType logLevel, PostProcessThumbnailDelegate postProcessThumbnail = null)
 {
     return(ProcessThumbnailRequests(new ThumbnailBuildRequest(thumbnailUrl, scene, graphicsCompositor, provider, thumbnailSize, colorSpace, renderingMode, logger, logLevel)
     {
         PostProcessThumbnail = postProcessThumbnail
     }));
 }
Beispiel #40
0
 public abstract void CompleteRange(Int2 selection);
Beispiel #41
0
 /// <inheritdoc />
 protected override IntPtr GetData(ref Int2 patchCoord, object tag)
 {
     return(TerrainTools.GetSplatMapData(_terrain, ref patchCoord, (int)tag));
 }
Beispiel #42
0
        public void PickColorTest()
        {
            var pixelCoordinate1 = new Int2(4, 4);
            var theoreticalColor1 = new Color(0, 255, 46, 255);
            var pixelCoordinate2 = new Int2(3, 4);
            var theoreticalColor2 = new Color(222, 76, 255, 255);

            var images = new[] { "BgraSheet.dds", "RgbaSheet.dds" };

            foreach (var image in images)
            {
                using (var texTool = new TextureTool())
                using (var texImage = texTool.Load(Module.PathToInputImages + image))
                {
                    var foundColor = texTool.PickColor(texImage, pixelCoordinate1);
                    Assert.AreEqual(theoreticalColor1, foundColor);

                    foundColor = texTool.PickColor(texImage, pixelCoordinate2);
                    Assert.AreEqual(theoreticalColor2, foundColor);
                }
            }
        }
Beispiel #43
0
        public static ResultStatus ImportTextureImage(TextureTool textureTool, TexImage texImage, ImportParameters parameters, CancellationToken cancellationToken, Logger logger)
        {
            var assetManager = new AssetManager();

            // Apply transformations
            textureTool.Decompress(texImage, parameters.IsSRgb);

            // Special case when the input texture is monochromatic but it is supposed to be a color and we are working in SRGB
            // In that case, we need to transform it to a supported SRGB format (R8G8B8A8_UNorm_SRgb)
            // TODO: As part of a conversion phase, this code may be moved to a dedicated method in this class at some point
            if (parameters.TextureHint == TextureHint.Color && parameters.IsSRgb && (texImage.Format == PixelFormat.R8_UNorm || texImage.Format == PixelFormat.A8_UNorm))
            {
                textureTool.Convert(texImage, PixelFormat.R8G8B8A8_UNorm_SRgb);
            }

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
            {
                return(ResultStatus.Cancelled);
            }

            var fromSize   = new Size2(texImage.Width, texImage.Height);
            var targetSize = parameters.DesiredSize;

            // Resize the image
            if (parameters.IsSizeInPercentage)
            {
                targetSize = new Size2((int)(fromSize.Width * targetSize.Width / 100.0f), (int)(fromSize.Height * targetSize.Height / 100.0f));
            }

            // Find the target size
            targetSize = FindBestTextureSize(parameters, targetSize, logger);

            // Resize the image only if needed
            if (targetSize != fromSize)
            {
                textureTool.Resize(texImage, targetSize.Width, targetSize.Height, Filter.Rescaling.Lanczos3);
            }

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
            {
                return(ResultStatus.Cancelled);
            }

            // texture size is now determined, we can cache it
            var textureSize = new Int2(texImage.Width, texImage.Height);

            // determine the alpha format of the texture when set to Auto
            // Note: this has to be done before the ColorKey transformation in order to be able to take advantage of image file AlphaDepth information
            if (parameters.DesiredAlpha == AlphaFormat.Auto)
            {
                var colorKey   = parameters.ColorKeyEnabled? (Color?)parameters.ColorKeyColor : null;
                var alphaLevel = textureTool.GetAlphaLevels(texImage, new Rectangle(0, 0, textureSize.X, textureSize.Y), colorKey, logger);
                parameters.DesiredAlpha = alphaLevel.ToAlphaFormat();
            }

            // Apply the color key
            if (parameters.ColorKeyEnabled)
            {
                textureTool.ColorKey(texImage, parameters.ColorKeyColor);
            }

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
            {
                return(ResultStatus.Cancelled);
            }

            // Pre-multiply alpha only for relevant formats
            if (parameters.PremultiplyAlpha && texImage.Format.HasAlpha32Bits())
            {
                textureTool.PreMultiplyAlpha(texImage);
            }

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
            {
                return(ResultStatus.Cancelled);
            }


            // Generate mipmaps
            if (parameters.GenerateMipmaps)
            {
                var boxFilteringIsSupported = !texImage.Format.IsSRgb() || (MathUtil.IsPow2(textureSize.X) && MathUtil.IsPow2(textureSize.Y));
                textureTool.GenerateMipMaps(texImage, boxFilteringIsSupported? Filter.MipMapGeneration.Box: Filter.MipMapGeneration.Linear);
            }

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
            {
                return(ResultStatus.Cancelled);
            }


            // Convert/Compress to output format
            // TODO: Change alphaFormat depending on actual image content (auto-detection)?
            var outputFormat = DetermineOutputFormat(parameters, textureSize, texImage.Format);

            textureTool.Compress(texImage, outputFormat, (TextureConverter.Requests.TextureQuality)parameters.TextureQuality);

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
            {
                return(ResultStatus.Cancelled);
            }

            // Save the texture
            using (var outputImage = textureTool.ConvertToXenkoImage(texImage))
            {
                if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
                {
                    return(ResultStatus.Cancelled);
                }

                assetManager.Save(parameters.OutputUrl, outputImage.ToSerializableVersion());

                logger.Verbose("Compression successful [{3}] to ({0}x{1},{2})", outputImage.Description.Width, outputImage.Description.Height, outputImage.Description.Format, parameters.OutputUrl);
            }

            return(ResultStatus.Successful);
        }
Beispiel #44
0
        /// <summary>
        /// Pick the color under the specified pixel.
        /// </summary>
        /// <param name="texture">The texture</param>
        /// <param name="pixel">The coordinate of the pixel</param>
        public unsafe Color PickColor(TexImage texture, Int2 pixel)
        {
            if (texture == null) throw new ArgumentNullException(nameof(texture));

            var format = texture.Format;
            if (texture.Dimension != TexImage.TextureDimension.Texture2D || !(format.IsRGBAOrder() || format.IsBGRAOrder() || format.SizeInBytes() != 4))
                throw new NotImplementedException();

            // check that the pixel is inside the texture
            var textureRegion = new Rectangle(0, 0, texture.Width, texture.Height);
            if (!textureRegion.Contains(pixel))
                throw new ArgumentException("The provided pixel coordinate is outside of the texture");

            var ptr = (uint*)texture.Data;
            var stride = texture.RowPitch / 4;

            var pixelColorInt = ptr[stride*pixel.Y + pixel.X];
            var pixelColor = format.IsRGBAOrder() ? Color.FromRgba(pixelColorInt) : Color.FromBgra(pixelColorInt);

            return pixelColor;
        }
Beispiel #45
0
 /// <summary>
 /// Initializes a new instance of geometric descriptor for a plane.
 /// </summary>
 public PlaneProceduralModel()
 {
     Normal       = NormalDirection.UpY;
     Size         = new Vector2(1.0f);
     Tessellation = new Int2(1);
 }
 internal void SetPosition(Int2 pos)
 {
     Position = pos;
 }
Beispiel #47
0
 public Block GetBlock(int x, int y)
 {
     Int2 coord = new Int2(x, y);
     if (blocks.ContainsKey(coord)) return blocks[coord];
     return null;
 }
        private static IEnumerable <Int2> GetValidMovesByDirection(Player currentPlayer, Piece piece, Int2 step)
        {
            for (var nextStep = piece.Coordinate + step;
                 IsValidTarget(currentPlayer, nextStep);
                 nextStep += step)
            {
                yield return(nextStep);

                if (IsOccupiedByEnemy(currentPlayer, nextStep))
                {
                    yield break;
                }
            }
        }
        protected override void DrawCore(RenderContext context)
        {
            var inputTexture = RadianceMap;
            if (inputTexture == null)
                return;
            
            // Gets and checks the input texture
            if (inputTexture.Dimension != TextureDimension.TextureCube)
                throw new NotSupportedException("Only texture cube are currently supported as input of 'LambertianPrefilteringSH' effect.");

            const int FirstPassBlockSize = 4;
            const int FirstPassSumsCount = FirstPassBlockSize * FirstPassBlockSize;

            var faceCount = inputTexture.Dimension == TextureDimension.TextureCube ? 6 : 1;
            var inputSize = new Int2(inputTexture.Width, inputTexture.Height); // (Note: for cube maps width = height)
            var coefficientsCount = harmonicalOrder * harmonicalOrder;

            var sumsToPerfomRemaining = inputSize.X * inputSize.Y * faceCount / FirstPassSumsCount;
            var partialSumBuffer = NewScopedTypedBuffer(coefficientsCount * sumsToPerfomRemaining, PixelFormat.R32G32B32A32_Float, true);


            // Project the radiance on the SH basis and sum up the results along the 4x4 blocks
            firstPassEffect.ThreadNumbers = new Int3(FirstPassBlockSize, FirstPassBlockSize, 1);
            firstPassEffect.ThreadGroupCounts = new Int3(inputSize.X/FirstPassBlockSize, inputSize.Y/FirstPassBlockSize, faceCount);
            firstPassEffect.Parameters.Set(LambertianPrefilteringSHParameters.BlockSize, FirstPassBlockSize);
            firstPassEffect.Parameters.Set(SphericalHarmonicsParameters.HarmonicsOrder, harmonicalOrder);
            firstPassEffect.Parameters.Set(LambertianPrefilteringSHPass1Keys.RadianceMap, inputTexture);
            firstPassEffect.Parameters.Set(LambertianPrefilteringSHPass1Keys.OutputBuffer, partialSumBuffer);
            firstPassEffect.Draw(context);

            // Recursively applies the pass2 (sums the coefficients together) as long as needed. Swap input/output buffer at each iteration.
            var secondPassInputBuffer = partialSumBuffer;
            Buffer secondPassOutputBuffer = null;
            while (sumsToPerfomRemaining % 2 == 0)
            {
                // we are limited in the number of summing threads by the group-shared memory size.
                // determine the number of threads to use and update the number of sums remaining afterward.
                var sumsCount = 1;
                while (sumsCount < (1<<10) && sumsToPerfomRemaining % 2 == 0) // shader can perform only an 2^x number of sums.
                {
                    sumsCount <<= 1;
                    sumsToPerfomRemaining >>= 1;
                }

                // determine the numbers of groups (limited to 65535 groups by dimensions)
                var groupCountX = 1;
                var groupCountY = sumsToPerfomRemaining;
                while (groupCountX >= short.MaxValue)
                {
                    groupCountX <<= 1;
                    groupCountY >>= 1;
                }

                // create the output buffer if not existing yet
                if (secondPassOutputBuffer == null)
                    secondPassOutputBuffer = NewScopedTypedBuffer(coefficientsCount * sumsToPerfomRemaining, PixelFormat.R32G32B32A32_Float, true);

                // draw pass 2
                secondPassEffect.ThreadNumbers = new Int3(sumsCount, 1, 1);
                secondPassEffect.ThreadGroupCounts = new Int3(groupCountX, groupCountY, coefficientsCount);
                secondPassEffect.Parameters.Set(LambertianPrefilteringSHParameters.BlockSize, sumsCount);
                secondPassEffect.Parameters.Set(SphericalHarmonicsParameters.HarmonicsOrder, harmonicalOrder);
                secondPassEffect.Parameters.Set(LambertianPrefilteringSHPass2Keys.InputBuffer, secondPassInputBuffer);
                secondPassEffect.Parameters.Set(LambertianPrefilteringSHPass2Keys.OutputBuffer, secondPassOutputBuffer);
                secondPassEffect.Draw(context);

                // swap second pass input/output buffers.
                var swapTemp = secondPassOutputBuffer;
                secondPassOutputBuffer = secondPassInputBuffer;
                secondPassInputBuffer = swapTemp;
            }

            // create and initialize result SH
            prefilteredLambertianSH = new SphericalHarmonics(HarmonicOrder);

            // Get the data out of the final buffer
            var sizeResult = coefficientsCount * sumsToPerfomRemaining * PixelFormat.R32G32B32A32_Float.SizeInBytes();
            var stagedBuffer = NewScopedBuffer(new BufferDescription(sizeResult, BufferFlags.None, GraphicsResourceUsage.Staging));
            GraphicsDevice.CopyRegion(secondPassInputBuffer, 0, new ResourceRegion(0, 0, 0, sizeResult, 1, 1), stagedBuffer, 0);
            var finalsValues =  stagedBuffer.GetData<Vector4>();    
            
            // performs last possible additions, normalize the result and store it in the SH
            for (var c = 0; c < coefficientsCount; c++)
            {
                var coeff = Vector4.Zero;
                for (var f = 0; f < sumsToPerfomRemaining; ++f)
                {
                    coeff += finalsValues[coefficientsCount * f + c];
                }
                prefilteredLambertianSH.Coefficients[c] = 4 * MathUtil.Pi / coeff.W * new Color3(coeff.X, coeff.Y, coeff.Z);
            }
        }
 private static bool IsInBoundary(Int2 targetCell)
 => targetCell.X >= 0 && targetCell.X < 8 && targetCell.Y >= 0 && targetCell.Y < 8;
Beispiel #51
0
        /// <summary>
        /// Determine the output format of the texture depending on the platform and asset properties.
        /// </summary>
        /// <param name="parameters">The conversion request parameters</param>
        /// <param name="imageSize">The texture output size</param>
        /// <param name="inputImageFormat">The pixel format of the input image</param>
        /// <returns>The pixel format to use as output</returns>
        public static PixelFormat DetermineOutputFormat(ImportParameters parameters, Int2 imageSize, PixelFormat inputImageFormat)
        {
            var hint = parameters.TextureHint;
            var alphaMode = parameters.DesiredAlpha;

            // Default output format
            var outputFormat = PixelFormat.R8G8B8A8_UNorm;
            switch (parameters.DesiredFormat)
            {
                case TextureFormat.Compressed:
                    switch (parameters.Platform)
                    {
                        case PlatformType.Android:
                            if (inputImageFormat.IsHDR())
                            {
                                outputFormat = inputImageFormat;
                            }
                            else
                            {
                                switch (parameters.GraphicsProfile)
                                {
                                    case GraphicsProfile.Level_9_1:
                                    case GraphicsProfile.Level_9_2:
                                    case GraphicsProfile.Level_9_3:
                                        outputFormat = alphaMode == AlphaFormat.None && !parameters.IsSRgb ? PixelFormat.ETC1 : parameters.IsSRgb ? PixelFormat.R8G8B8A8_UNorm_SRgb : PixelFormat.R8G8B8A8_UNorm;
                                        break;
                                    case GraphicsProfile.Level_10_0:
                                    case GraphicsProfile.Level_10_1:
                                    case GraphicsProfile.Level_11_0:
                                    case GraphicsProfile.Level_11_1:
                                    case GraphicsProfile.Level_11_2:
                                        // GLES3.0 starting from Level_10_0, this profile enables ETC2 compression on Android
                                        outputFormat = alphaMode == AlphaFormat.None && !parameters.IsSRgb ? PixelFormat.ETC1 : parameters.IsSRgb ? PixelFormat.ETC2_RGBA_SRgb : PixelFormat.ETC2_RGBA;
                                        break;
                                    default:
                                        throw new ArgumentOutOfRangeException("GraphicsProfile");
                                }
                            }
                            break;
                        case PlatformType.iOS:
                            // PVRTC works only for square POT textures
                            if (inputImageFormat.IsHDR())
                            {
                                outputFormat = inputImageFormat;
                            }
                            else if (SupportPVRTC(imageSize))
                            {
                                switch (alphaMode)
                                {
                                    case AlphaFormat.None:
                                        outputFormat = parameters.IsSRgb ? PixelFormat.PVRTC_4bpp_RGB_SRgb : PixelFormat.PVRTC_4bpp_RGB;
                                        break;
                                    case AlphaFormat.Mask:
                                        // DXT1 handles 1-bit alpha channel
                                        // TODO: Not sure about the equivalent here?
                                        outputFormat = parameters.IsSRgb ? PixelFormat.PVRTC_4bpp_RGBA_SRgb : PixelFormat.PVRTC_4bpp_RGBA;
                                        break;
                                    case AlphaFormat.Explicit:
                                    case AlphaFormat.Interpolated:
                                        // DXT3 is good at sharp alpha transitions
                                        // TODO: Not sure about the equivalent here?
                                        outputFormat = parameters.IsSRgb ? PixelFormat.PVRTC_4bpp_RGBA_SRgb : PixelFormat.PVRTC_4bpp_RGBA;
                                        break;
                                    default:
                                        throw new ArgumentOutOfRangeException();
                                }
                            }
                            else
                            {
                                outputFormat = parameters.IsSRgb ? PixelFormat.R8G8B8A8_UNorm_SRgb : PixelFormat.R8G8B8A8_UNorm;
                            }
                            break;
                        case PlatformType.Windows:
                        case PlatformType.WindowsPhone:
                        case PlatformType.WindowsStore:
                        case PlatformType.Windows10:
                            switch (parameters.GraphicsPlatform)
                            {
                                case GraphicsPlatform.Direct3D11:


                                    // https://msdn.microsoft.com/en-us/library/windows/desktop/hh308955%28v=vs.85%29.aspx
                                    // http://www.reedbeta.com/blog/2012/02/12/understanding-bcn-texture-compression-formats/
                                    // ----------------------------------------------    ----------------------------------------------------                        ---    ---------------------------------
                                    // Source data                                       Minimum required data compression resolution 	                  Recommended format	Minimum supported feature level
                                    // ----------------------------------------------    ----------------------------------------------------                        ---    ---------------------------------
                                    // Three-channel color with alpha channel            Three color channels (5 bits:6 bits:5 bits), with 0 or 1 bit(s) of alpha    BC1    Direct3D 9.1     (color maps, cutout color maps - 1 bit alpha, normal maps if memory is tight)
                                    // Three-channel color with alpha channel            Three color channels (5 bits:6 bits:5 bits), with 4 bits of alpha           BC2    Direct3D 9.1     (idem)
                                    // Three-channel color with alpha channel            Three color channels (5 bits:6 bits:5 bits) with 8 bits of alpha            BC3    Direct3D 9.1     (color maps with alpha, packing color and mono maps together)
                                    // One-channel color                                 One color channel (8 bits)                                                  BC4    Direct3D 10      (Height maps, gloss maps, font atlases, any gray scales image)
                                    // Two-channel color	                             Two color channels (8 bits:8 bits)                                          BC5    Direct3D 10      (Tangent space normal maps)
                                    // Three-channel high dynamic range (HDR) color      Three color channels (16 bits:16 bits:16 bits) in "half" floating point*    BC6H   Direct3D 11      (HDR images)
                                    // Three-channel color, alpha channel optional       Three color channels (4 to 7 bits per channel) with 0 to 8 bits of alpha    BC7    Direct3D 11      (High quality color maps, Color maps with full alpha)

                                    switch (alphaMode)
                                    {
                                        case AlphaFormat.None:
                                        case AlphaFormat.Mask:
                                            // DXT1 handles 1-bit alpha channel
                                            outputFormat = parameters.IsSRgb ? PixelFormat.BC1_UNorm_SRgb : PixelFormat.BC1_UNorm;
                                            break;
                                        case AlphaFormat.Explicit:
                                            // DXT3 is good at sharp alpha transitions
                                            outputFormat = parameters.IsSRgb ? PixelFormat.BC2_UNorm_SRgb : PixelFormat.BC2_UNorm;
                                            break;
                                        case AlphaFormat.Interpolated:
                                            // DXT5 is good at alpha gradients
                                            outputFormat = parameters.IsSRgb ? PixelFormat.BC3_UNorm_SRgb : PixelFormat.BC3_UNorm;
                                            break;
                                        default:
                                            throw new ArgumentOutOfRangeException();
                                    }

                                    // Overrides the format when profile is >= 10.0
                                    // Support some specific optimized formats based on the hint or input type
                                    if (parameters.GraphicsProfile >= GraphicsProfile.Level_10_0)
                                    {
                                        if (hint == TextureHint.NormalMap)
                                        {
                                            outputFormat = PixelFormat.BC5_SNorm;
                                        }
                                        else if (hint == TextureHint.Grayscale)
                                        {
                                            outputFormat = PixelFormat.BC4_UNorm;
                                        }
                                        else if (inputImageFormat.IsHDR())
                                        {
                                            // BC6H is too slow to compile
                                            //outputFormat = parameters.GraphicsProfile >= GraphicsProfile.Level_11_0 && alphaMode == AlphaFormat.None ? PixelFormat.BC6H_Uf16 : inputImageFormat;
                                            outputFormat = inputImageFormat;
                                        }
                                        // TODO support the BC6/BC7 but they are so slow to compile that we can't use them right now
                                    }
                                    break;
                                case GraphicsPlatform.OpenGLES: // OpenGLES on Windows
                                    if (inputImageFormat.IsHDR())
                                    {
                                        outputFormat = inputImageFormat;
                                    }
                                    else if (parameters.IsSRgb)
                                    {
                                        outputFormat = PixelFormat.R8G8B8A8_UNorm_SRgb;
                                    }
                                    else
                                    {
                                        switch (parameters.GraphicsProfile)
                                        {
                                            case GraphicsProfile.Level_9_1:
                                            case GraphicsProfile.Level_9_2:
                                            case GraphicsProfile.Level_9_3:
                                                outputFormat = alphaMode == AlphaFormat.None ? PixelFormat.ETC1 : PixelFormat.R8G8B8A8_UNorm;
                                                break;
                                            case GraphicsProfile.Level_10_0:
                                            case GraphicsProfile.Level_10_1:
                                            case GraphicsProfile.Level_11_0:
                                            case GraphicsProfile.Level_11_1:
                                            case GraphicsProfile.Level_11_2:
                                                // GLES3.0 starting from Level_10_0, this profile enables ETC2 compression on Android
                                                outputFormat = alphaMode == AlphaFormat.None ? PixelFormat.ETC1 : PixelFormat.ETC2_RGBA;
                                                break;
                                            default:
                                                throw new ArgumentOutOfRangeException("GraphicsProfile");
                                        }
                                    }
                                    break;
                                default:
                                    // OpenGL on Windows
                                    // TODO: Need to handle OpenGL Desktop compression
                                    outputFormat = parameters.IsSRgb ? PixelFormat.R8G8B8A8_UNorm_SRgb : PixelFormat.R8G8B8A8_UNorm;
                                    break;
                            }
                            break;
                        default:
                            throw new NotSupportedException("Platform " + parameters.Platform + " is not supported by TextureTool");
                    }
                    break;
                case TextureFormat.Color16Bits:
                    if (parameters.IsSRgb)
                    {
                        outputFormat = PixelFormat.R8G8B8A8_UNorm_SRgb;
                    }
                    else
                    {
                        if (alphaMode == AlphaFormat.None)
                        {
                            outputFormat = PixelFormat.B5G6R5_UNorm;
                        }
                        else if (alphaMode == AlphaFormat.Mask)
                        {
                            outputFormat = PixelFormat.B5G5R5A1_UNorm;
                        }
                    }
                    break;
                case TextureFormat.Color32Bits:
                    if (parameters.IsSRgb)
                    {
                        outputFormat = PixelFormat.R8G8B8A8_UNorm_SRgb;
                    }
                    break;
                case TextureFormat.AsIs:
                    outputFormat = inputImageFormat;
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
            return outputFormat;
        }
 private static bool IsOccupiedByEnemy(Player currentPlayer, Int2 targetCell)
 => currentPlayer.Enemy.Pieces.Any(p =>
                                   p.Coordinate.X == targetCell.X && p.Coordinate.Y == targetCell.Y);
Beispiel #53
0
    private void GenerateRooms(int maxRoomCount, Vector2 minRoomSize, Vector2 maxRoomSize)
    {
        List<Int2> doors = new List<Int2>();

        for (int i = 0; i < maxRoomCount; i++)
        {
            int[,] room = CreateRoom(minRoomSize, maxRoomSize);

            //Position is so that room can't go over map boundaries
            Int2 positionForTheRoom = new Int2(Random.Range(0, map.GetLength(0) - (int)maxRoomSize.x), 
                                                Random.Range(0, map.GetLength(1) - (int)maxRoomSize.y));
            for (int j = 0; j < room.GetLength(0); j++)
            {
                for (int k = 0; k < room.GetLength(1); k++)
                {
                    map[positionForTheRoom.x + j, positionForTheRoom.y + k] = room[j, k];
                }
            }
        }
    }
 private static bool IsOccupied(Player currentPlayer, Int2 targetCell)
 => IsOccupiedByEnemy(currentPlayer, targetCell) || IsOccupiedByOwner(currentPlayer, targetCell);
Beispiel #55
0
 public abstract void Subrange(Int2 min, Int2 max, Int2 selection);
Beispiel #56
0
 public bool CheckBounds(Int2 p)
 {
     return(host.grid.CheckBounds(p.row, p.col));
 }
	/** Async method for moving the graph */
	IEnumerator UpdateGraphCoroutine () {

		// Find the direction
		// that we want to move the graph in.
		// Calcuculate this in graph space (where a distance of one is the size of one node)
		Vector3 dir = PointToGraphSpace(target.position) - PointToGraphSpace(graph.center);

		// Snap to a whole number of nodes
		dir.x = Mathf.Round(dir.x);
		dir.z = Mathf.Round(dir.z);
		dir.y = 0;

		// Nothing do to
		if ( dir == Vector3.zero ) yield break;

		// Number of nodes to offset in each direction
		Int2 offset = new Int2(-Mathf.RoundToInt(dir.x), -Mathf.RoundToInt(dir.z));

		// Move the center (this is in world units, so we need to convert it back from graph space)
		graph.center += graph.matrix.MultiplyVector (dir);
		graph.GenerateMatrix ();

		// Create a temporary buffer
		// required for the calculations
		if ( tmp == null || tmp.Length != graph.nodes.Length ) {
			tmp = new GridNode[graph.nodes.Length];
		}

		// Cache some variables for easier access
		int width = graph.width;
		int depth = graph.depth;
		GridNode[] nodes = graph.nodes;

		// Check if we have moved
		// less than a whole graph
		// width in any direction
		if ( Mathf.Abs(offset.x) <= width && Mathf.Abs(offset.y) <= depth ) {
		
			// Offset each node by the #offset variable
			// nodes which would end up outside the graph
			// will wrap around to the other side of it
			for ( int z=0; z < depth; z++ ) {
				int pz = z*width;
				int tz = ((z+offset.y + depth)%depth)*width;
				for ( int x=0; x < width; x++ ) {
					tmp[tz + ((x+offset.x + width) % width)] = nodes[pz + x];
				}
			}
			
			yield return null;

			// Copy the nodes back to the graph
			// and set the correct indices
			for ( int z=0; z < depth; z++ ) {
				int pz = z*width;
				for ( int x=0; x < width; x++ ) {
					GridNode node = tmp[pz + x];
					node.NodeInGridIndex = pz + x;
					nodes[pz + x] = node;
				}
			}


			IntRect r = new IntRect ( 0, 0, offset.x, offset.y );
			int minz = r.ymax;
			int maxz = depth;

			// If offset.x < 0, adjust the rect
			if ( r.xmin > r.xmax ) {
				int tmp2 = r.xmax;
				r.xmax = width + r.xmin;
				r.xmin = width + tmp2;
			}

			// If offset.y < 0, adjust the rect
			if ( r.ymin > r.ymax ) {
				int tmp2 = r.ymax;
				r.ymax = depth + r.ymin;
				r.ymin = depth + tmp2;
	
				minz = 0;
				maxz = r.ymin;
			}

			// Make sure erosion is taken into account
			// Otherwise we would end up with ugly artifacts
			r = r.Expand ( graph.erodeIterations + 1 );

			// Makes sure the rect stays inside the grid
			r = IntRect.Intersection ( r, new IntRect ( 0, 0, width, depth ) );
	
			yield return null;

			// Update all nodes along one edge of the graph
			// With the same width as the rect
			for ( int z = r.ymin; z < r.ymax; z++ ) {
				for ( int x = 0; x < width; x++ ) {
					graph.UpdateNodePositionCollision ( nodes[z*width + x], x, z, false );
				}
			}
	
			yield return null;
		
			// Update all nodes along the other edge of the graph
			// With the same width as the rect
			for ( int z = minz; z < maxz; z++ ) {
				for ( int x = r.xmin; x < r.xmax; x++ ) {
					graph.UpdateNodePositionCollision ( nodes[z*width + x], x, z, false );
				}
			}
	
			yield return null;

			// Calculate all connections for the nodes
			// that might have changed
			for ( int z = r.ymin; z < r.ymax; z++ ) {
				for ( int x = 0; x < width; x++ ) {
					graph.CalculateConnections (nodes, x, z, nodes[z*width+x]);
				}
			}
	
			yield return null;
	
			// Calculate all connections for the nodes
			// that might have changed
			for ( int z = minz; z < maxz; z++ ) {
				for ( int x = r.xmin; x < r.xmax; x++ ) {
					graph.CalculateConnections (nodes, x, z, nodes[z*width+x]);
				}
			}
	
			yield return null;

			// Calculate all connections for the nodes along the boundary
			// of the graph, these always need to be updated
			/** \todo Optimize to not traverse all nodes in the graph, only those at the edges */
			for ( int z = 0; z < depth; z++ ) {
				for ( int x = 0; x < width; x++ ) {
					if ( x == 0 || z == 0 || x >= width-1 || z >= depth-1 ) graph.CalculateConnections (nodes, x, z, nodes[z*width+x]);
				}
			}
			
		} else {

			// Just update all nodes
			for ( int z = 0; z < depth; z++ ) {
				for ( int x = 0; x < width; x++ ) {
					graph.UpdateNodePositionCollision ( nodes[z*width + x], x, z, false );
				}
			}

			// Recalculate the connections of all nodes
			for ( int z = 0; z < depth; z++ ) {
				for ( int x = 0; x < width; x++ ) {
					graph.CalculateConnections (nodes, x, z, nodes[z*width+x]);
				}
			}
		}
		
		if ( floodFill ) {
			yield return null;
			// Make sure the areas for the graph
			// have been recalculated
			// not doing this can cause pathfinding to fail
			AstarPath.active.QueueWorkItemFloodFill ();
		}
	}
Beispiel #58
0
 public bool CanMove(Int2 delta)
 {
     return(CanMove(delta.x, delta.y));
 }
Beispiel #59
0
        /// <summary>
        /// Find the region of the texture containing the sprite under the specified pixel.
        /// </summary>
        /// <param name="texture">The texture containing the sprite</param>
        /// <param name="pixel">The coordinate of the pixel specifying the sprite</param>
        /// <param name="separatorColor">The separator color that delimit the sprites. If null the <see cref="Color.Transparent"/> color is used</param>
        /// <param name="separatorMask">The mask specifying which bits of the color should be checked. The bits are ordered as AABBGGRR.</param>
        /// <returns></returns>
        public unsafe Rectangle FindSpriteRegion(TexImage texture, Int2 pixel, Color? separatorColor = null, uint separatorMask = 0xff000000)
        {
            if (texture == null) throw new ArgumentNullException(nameof(texture));

            var format = texture.Format;
            if (texture.Dimension != TexImage.TextureDimension.Texture2D || !(format.IsRGBAOrder() || format.IsBGRAOrder() || format.SizeInBytes() != 4))
                throw new NotImplementedException();

            // adjust the separator color the mask depending on the color format.
            var separator = (uint)(separatorColor ?? Color.Transparent).ToRgba();
            if(texture.Format.IsBGRAOrder())
            {
                separator = RgbaToBgra(separator);
                separatorMask = RgbaToBgra(separatorMask);
            }
            var maskedSeparator = separator & separatorMask;
            
            var ptr = (uint*)texture.Data;
            var stride = texture.RowPitch / 4;

            // check for empty region (provided pixel is not valid)
            var textureRegion = new Rectangle(0, 0, texture.Width, texture.Height);
            if (!textureRegion.Contains(pixel) || (ptr[pixel.Y * stride + pixel.X] & separatorMask) == maskedSeparator)
                return new Rectangle(pixel.X, pixel.Y, 0, 0);

            // initialize the region with the provided pixel
            var region = new Rectangle(pixel.X, pixel.Y, 1, 1);

            var nextSearchOffsets = new[,]
            {
                { new Int2(-1, -1),  new Int2( 0, -1) },
                { new Int2( 1, -1),  new Int2( 1,  0) },
                { new Int2( 1,  1),  new Int2( 0,  1) },
                { new Int2(-1,  1),  new Int2(-1,  0) }
            };

            var contourLeftEgde = pixel;
            var rotationDirection = 0;
            do
            {
                // Stage 1: Find an edge of the shape (look to the left of the provided pixel as long as possible)
                var startEdge = contourLeftEgde;
                var startEdgeDirection = EdgeDirection.Left;
                for (int x = startEdge.X; x >= 0; --x)
                {
                    if ((ptr[startEdge.Y * stride + x] & separatorMask) == maskedSeparator)
                        break;

                    startEdge.X = x;
                }

                // Stage 2: Determine the whole contour of the shape and update the region. 
                // Note: the found contour can correspond to an internal hole contour or the external shape contour.
                var currentEdge = startEdge;
                var currentEdgeDirection = startEdgeDirection;
                do
                {
                    var previousEdgeDirection = currentEdgeDirection;

                    var diagonalPixel = currentEdge + nextSearchOffsets[(int)currentEdgeDirection, 0];
                    var diagonalIsSeparator = !textureRegion.Contains(diagonalPixel) || (ptr[diagonalPixel.Y * stride + diagonalPixel.X] & separatorMask) == maskedSeparator;
                    var neighbourPixel = currentEdge + nextSearchOffsets[(int)currentEdgeDirection, 1];
                    var neighbourIsSeparator = !textureRegion.Contains(neighbourPixel) || (ptr[neighbourPixel.Y * stride + neighbourPixel.X] & separatorMask) == maskedSeparator;

                    // determine the next edge position
                    if (!diagonalIsSeparator)
                    {
                        currentEdge = diagonalPixel;
                        currentEdgeDirection = (EdgeDirection)(((int)currentEdgeDirection + 3) % 4);
                    }
                    else if (!neighbourIsSeparator)
                    {
                        currentEdge = neighbourPixel;
                    }
                    else
                    {
                        currentEdgeDirection = (EdgeDirection)(((int)currentEdgeDirection + 1) % 4);
                    }

                    // keep record of the point of the edge which is 
                    if (currentEdge.X < contourLeftEgde.X)
                        contourLeftEgde = currentEdge;

                    // increase or decrease the rotation counter based on the sequence of edge direction
                    rotationDirection += RotationDirection(previousEdgeDirection, currentEdgeDirection);

                    // update the rectangle
                    region = Rectangle.Union(region, currentEdge);
                }
                while (currentEdge != startEdge || currentEdgeDirection != startEdgeDirection); // as long as we do not close the contour continue to explore
                
            } // repeat the process as long as the edge found is not the shape external contour.
            while (rotationDirection != 4);

            return region;
        }
Beispiel #60
0
 public bool TryMove(Int2 delta)
 {
     return(TryMove(delta.row, delta.col));
 }